已开启
[ArkWeb][安全][自动提交] 修复 Chromium issue 513048462: Fix robust resource init bypass for packed depth/stencil #462
[ArkWeb][安全][自动提交] 修复 Chromium issue 513048462: Fix robust resource init bypass for packed depth/stencil #462
已开启
ringking0创建于 2 天前
2 个文件变更+137-4
@@ -1677,8 +1677,26 @@ bool Framebuffer::partialClearNeedsInit(const Context *context,
1677 return true;1677 return true;
1678 }1678 }
1679 1679 
1680+ // Clearing only one aspect of a packed depth-stencil attachment is a partial
1681+ // clear of the underlying resource. While the framebuffer tracks depth and
1682+ // stencil initialization needs separately in mState.mResourceNeedsInit, the
1683+ // underlying resource (texture level or renderbuffer) has a single shared
1684+ // InitState. Marking one aspect as Initialized updates the shared resource state,
1685+ // which would incorrectly suppress robust-init of the other aspect.
1686+ if (depth && !stencil && mState.mDepthAttachment.isAttached() &&
1687+ mState.mDepthAttachment.getStencilSize() > 0 &&
1688+ mState.mResourceNeedsInit[DIRTY_BIT_DEPTH_ATTACHMENT])
1689+ {
1690+ return true;
1691+ }
1692+ if (stencil && !depth && mState.mStencilAttachment.isAttached() &&
1693+ mState.mStencilAttachment.getDepthSize() > 0 &&
1694+ mState.mResourceNeedsInit[DIRTY_BIT_STENCIL_ATTACHMENT])
1695+ {
1696+ return true;
1697+ }
1698+ 
1680 // Scissors can affect clearing.1699 // Scissors can affect clearing.
1681- // TODO(jmadill): Check for complete scissor overlap.
1682 if (glState.isScissorTestEnabled())1700 if (glState.isScissorTestEnabled())
1683 {1701 {
1684 return true;1702 return true;
@@ -3241,12 +3241,127 @@ TEST_P(RobustResourceInitTest, AttachToBoundReadFramebufferBypass)
3241 EXPECT_GL_NO_ERROR();3241 EXPECT_GL_NO_ERROR();
3242}3242}
3243 3243 
3244+// Tests that partial clear of a packed depth-stencil attachment doesn't
3245+// incorrectly bypass robust initialization for the other aspect.
3246+TEST_P(RobustResourceInitTestES3, DepthClearWithStencilInit)
3247+{
3248+ ANGLE_SKIP_TEST_IF(!hasGLExtension());
3249+ 
3250+ constexpr int kSize = 16;
3251+ 
3252+ // Create a new FBO with a packed depth-stencil texture.
3253+ GLTexture dsTex;
3254+ glBindTexture(GL_TEXTURE_2D, dsTex);
3255+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
3256+ 
3257+ GLTexture colorTex;
3258+ glBindTexture(GL_TEXTURE_2D, colorTex);
3259+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
3260+ 
3261+ GLFramebuffer fbo;
3262+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3263+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
3264+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, dsTex, 0);
3265+ EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3266+ 
3267+ // Clear only depth. This should leave the stencil aspect in MayNeedInit state,
3268+ // which shouldn't be overridden to Initialized.
3269+ glClear(GL_DEPTH_BUFFER_BIT);
3270+ 
3271+ // Then bind the stencil attachment here so that we can verify it was initialized:
3272+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dsTex, 0);
3273+ 
3274+ // Verify stencil is initialized to 0. We can do this by using the stencil side channel.
3275+ // robust-init mandates 0.
3276+ glEnable(GL_STENCIL_TEST);
3277+ glStencilFunc(GL_EQUAL, 0x00, 0xFF);
3278+ glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
3279+ 
3280+ ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
3281+ drawQuad(drawRed, essl1_shaders::PositionAttrib(), 0.95f, 1.0f, true);
3282+ 
3283+ // Read the color buffer to verify that stencil test passed for all pixels.
3284+ EXPECT_PIXEL_RECT_EQ(0, 0, kSize, kSize, GLColor::red);
3285+ EXPECT_GL_NO_ERROR();
3286+}
3287+ 
3288+// Tests that partial clear of a packed depth-stencil attachment (stencil-only) doesn't
3289+// incorrectly bypass robust initialization for the depth aspect.
3290+TEST_P(RobustResourceInitTestES3, StencilClearWithDepthInit)
3291+{
3292+ ANGLE_SKIP_TEST_IF(!hasGLExtension());
3293+ 
3294+ constexpr int kSize = 16;
3295+ 
3296+ // Create a new FBO with a packed depth-stencil texture.
3297+ GLTexture dsTex;
3298+ glBindTexture(GL_TEXTURE_2D, dsTex);
3299+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_DEPTH24_STENCIL8, kSize, kSize);
3300+ 
3301+ GLTexture colorTex;
3302+ glBindTexture(GL_TEXTURE_2D, colorTex);
3303+ glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kSize, kSize);
3304+ 
3305+ GLFramebuffer fbo;
3306+ glBindFramebuffer(GL_FRAMEBUFFER, fbo);
3307+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, colorTex, 0);
3308+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, dsTex, 0);
3309+ EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
3310+ 
3311+ // Clear only stencil. This should leave the depth aspect in MayNeedInit state,
3312+ // which shouldn't be overridden to Initialized.
3313+ glClear(GL_STENCIL_BUFFER_BIT);
3314+ 
3315+ // Unbind the depth-stencil texture from the FBO so we can sample it as a texture.
3316+ glFramebufferTexture2D(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_TEXTURE_2D, 0, 0);
3317+ 
3318+ // Bind the texture to texture unit 0 and set filters.
3319+ glActiveTexture(GL_TEXTURE0);
3320+ glBindTexture(GL_TEXTURE_2D, dsTex);
3321+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
3322+ glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
3323+ 
3324+ // Verify depth == 1.0 via shader sampling
3325+ constexpr char kVS[] = R"(#version 300 es
3326+in vec4 aPosition;
3327+void main()
3328+{
3329+ gl_Position = aPosition;
3330+})";
3331+ 
3332+ constexpr char kFS[] = R"(#version 300 es
3333+precision highp float;
3334+uniform highp sampler2D uDepthTex;
3335+out vec4 outColor;
3336+void main()
3337+{
3338+ float depth = texture(uDepthTex, vec2(0.5, 0.5)).r;
3339+ if (abs(depth - 1.0) < 0.001)
3340+ {
3341+ outColor = vec4(0.0, 1.0, 0.0, 1.0); // green
3342+ }
3343+ else
3344+ {
3345+ outColor = vec4(1.0, 0.0, 0.0, 1.0); // red
3346+ }
3347+})";
3348+ 
3349+ ANGLE_GL_PROGRAM(depthSampleProg, kVS, kFS);
3350+ glUseProgram(depthSampleProg);
3351+ GLint texLoc = glGetUniformLocation(depthSampleProg, "uDepthTex");
3352+ ASSERT_NE(texLoc, -1);
3353+ glUniform1i(texLoc, 0);
3354+ 
3355+ drawQuad(depthSampleProg, "aPosition", 0.0f);
3356+ 
3357+ // Read the color buffer to verify that depth was successfully initialized to 1.0f.
3358+ EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3359+ EXPECT_GL_NO_ERROR();
3360+}
3361+ 
3244ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(3362ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(
3245 RobustResourceInitTest,3363 RobustResourceInitTest,
3246 ES3_METAL().enable(Feature::EmulateDontCareLoadWithRandomClear),3364 ES3_METAL().enable(Feature::EmulateDontCareLoadWithRandomClear),
3247- ES3_METAL().enable(Feature::AllocateNonZeroTextures),
3248- ES2_METAL().enable(Feature::AllocateNonZeroTextures),
3249- ES2_VULKAN().enable(Feature::AllocateNonZeroMemory));
3250 3365 
3251GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RobustResourceInitTestES3);3366GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(RobustResourceInitTestES3);
3252ANGLE_INSTANTIATE_TEST_ES3_AND(RobustResourceInitTestES3,3367ANGLE_INSTANTIATE_TEST_ES3_AND(RobustResourceInitTestES3,