Commit 0a56f0e3 by Tim Van Patten Committed by Commit Bot

Vulkan: Update front face mode during syncState()

When handling DIRTY_BIT_DRAW_FRAMEBUFFER_BINDING in syncState(), the call to update the front face was missing, so culling could be enabled for the wrong front faces. Bug: angleproject:3237 Test: Verify 3D apps render (more) correctly Test: New SimpleStateChangeTest end2end tests Change-Id: I1d94a977bea9e48d90b5346861e5565d2371cadd Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1611753 Commit-Queue: Tim Van Patten <timvp@google.com> Reviewed-by: 's avatarShahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 35fa85ba
......@@ -1532,8 +1532,9 @@ angle::Result ContextVk::syncState(const gl::Context *context,
updateSampleMask(glState);
mGraphicsPipelineDesc->updateRasterizationSamples(&mGraphicsPipelineTransition,
mDrawFramebuffer->getSamples());
mGraphicsPipelineDesc->updateCullMode(&mGraphicsPipelineTransition,
glState.getRasterizerState());
mGraphicsPipelineDesc->updateFrontFace(&mGraphicsPipelineTransition,
glState.getRasterizerState(),
isViewportFlipEnabledForDrawFBO());
updateScissor(glState);
mGraphicsPipelineDesc->updateDepthTestEnabled(&mGraphicsPipelineTransition,
glState.getDepthStencilState(),
......
......@@ -1270,6 +1270,8 @@ class SimpleStateChangeTest : public ANGLETest
using UpdateFunc = std::function<void(GLenum, GLTexture *, GLint, GLint, const GLColor &)>;
void updateTextureBoundToFramebufferHelper(UpdateFunc updateFunc);
void bindTextureToFbo(GLFramebuffer &fbo, GLTexture &texture);
void drawToFboWithCulling(const GLenum frontFace, bool earlyFrontFaceDirty);
};
class SimpleStateChangeTestES3 : public SimpleStateChangeTest
......@@ -3621,6 +3623,109 @@ TEST_P(SimpleStateChangeTest, DeleteTextureThenDraw)
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::black);
}
void SimpleStateChangeTest::bindTextureToFbo(GLFramebuffer &fbo, GLTexture &texture)
{
glBindFramebuffer(GL_FRAMEBUFFER, fbo);
glBindTexture(GL_TEXTURE_2D, texture);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, getWindowWidth(), getWindowHeight(), 0, GL_RGBA,
GL_UNSIGNED_BYTE, nullptr);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
ASSERT_GLENUM_EQ(GL_FRAMEBUFFER_COMPLETE, glCheckFramebufferStatus(GL_FRAMEBUFFER));
}
void SimpleStateChangeTest::drawToFboWithCulling(const GLenum frontFace, bool earlyFrontFaceDirty)
{
// Render to an FBO
GLFramebuffer fbo1;
GLTexture texture1;
ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
ANGLE_GL_PROGRAM(textureProgram, essl1_shaders::vs::Texture(), essl1_shaders::fs::Texture());
bindTextureToFbo(fbo1, texture1);
// Clear the surface FBO to initialize it to a known value
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glClearColor(GLColor::red.R, GLColor::red.G, GLColor::red.B, GLColor::red.A);
glClear(GL_COLOR_BUFFER_BIT);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
glFlush();
// Draw to FBO 1 to initialize it to a known value
glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
if (earlyFrontFaceDirty)
{
glEnable(GL_CULL_FACE);
// Make sure we don't cull
glCullFace(frontFace == GL_CCW ? GL_BACK : GL_FRONT);
glFrontFace(frontFace);
}
else
{
glDisable(GL_CULL_FACE);
}
glUseProgram(greenProgram);
drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
// Draw into FBO 0 using FBO 1's texture to determine if culling is working or not
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, texture1);
glCullFace(GL_BACK);
if (!earlyFrontFaceDirty)
{
// Set the culling we want to test
glEnable(GL_CULL_FACE);
glFrontFace(frontFace);
}
glUseProgram(textureProgram);
drawQuad(textureProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
ASSERT_GL_NO_ERROR();
if (frontFace == GL_CCW)
{
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
else
{
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
}
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glBindTexture(GL_TEXTURE_2D, 0);
}
// Validates if culling rasterization states work with FBOs using CCW winding.
TEST_P(SimpleStateChangeTest, FboEarlyCullFaceBackCCWState)
{
drawToFboWithCulling(GL_CCW, true);
}
// Validates if culling rasterization states work with FBOs using CW winding.
TEST_P(SimpleStateChangeTest, FboEarlyCullFaceBackCWState)
{
drawToFboWithCulling(GL_CW, true);
}
TEST_P(SimpleStateChangeTest, FboLateCullFaceBackCCWState)
{
drawToFboWithCulling(GL_CCW, false);
}
// Validates if culling rasterization states work with FBOs using CW winding.
TEST_P(SimpleStateChangeTest, FboLateCullFaceBackCWState)
{
drawToFboWithCulling(GL_CW, false);
}
} // anonymous namespace
ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
......
......@@ -316,6 +316,21 @@ void main()
})";
}
// A shader that simply passes through attribute a_position, setting it to gl_Position and varying
// texcoord.
const char *Texture()
{
return R"(precision highp float;
attribute vec4 a_position;
varying vec2 texcoord;
void main()
{
gl_Position = vec4(a_position.xy, 0.0, 1.0);
texcoord = a_position.xy;
})";
}
} // namespace vs
namespace fs
......@@ -384,6 +399,19 @@ void main()
})";
}
// A shader that samples the texture.
const char *Texture()
{
return R"(precision highp float;
uniform sampler2D tex;
varying vec2 texcoord;
void main()
{
gl_FragColor = vec4(texture2D(tex, texcoord).rgb, 1.0);
})";
}
} // namespace fs
} // namespace essl1_shaders
......
......@@ -66,6 +66,8 @@ ANGLE_UTIL_EXPORT const char *Simple();
// v_position.
ANGLE_UTIL_EXPORT const char *Passthrough();
ANGLE_UTIL_EXPORT const char *Texture();
} // namespace vs
namespace fs
......@@ -87,6 +89,9 @@ ANGLE_UTIL_EXPORT const char *Green();
// A shader that fills with 100% opaque blue.
ANGLE_UTIL_EXPORT const char *Blue();
// A shader that samples the texture
ANGLE_UTIL_EXPORT const char *Texture();
} // namespace fs
} // namespace essl1_shaders
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment