Commit 70642e42 by Tim Van Patten Committed by Commit Bot

Vulkan: Implement ES 3.0 rasterizer discard

Rasterizer discard is a feature that allows the graphics pipeline to skip the fragment shader stage. Implementing rasterizer discard in Vulkan is as easy as not binding a fragment shader binary. Tests for rasterizer discard live in dEQP-GLES3.functional.rasterizer_discard.*. Bug: angleproject:3214 Test: dEQP-GLES3.functional.rasterizer_discard.* Change-Id: I0815df3b70f6f9cdc6c8c87ec4813bb629d8bd5f Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/1646692 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 35b25fc6
...@@ -1495,6 +1495,8 @@ angle::Result ContextVk::syncState(const gl::Context *context, ...@@ -1495,6 +1495,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
glState.getRasterizerState()); glState.getRasterizerState());
break; break;
case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED: case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
mGraphicsPipelineDesc->updateRasterizerDiscardEnabled(
&mGraphicsPipelineTransition, glState.isRasterizerDiscardEnabled());
break; break;
case gl::State::DIRTY_BIT_LINE_WIDTH: case gl::State::DIRTY_BIT_LINE_WIDTH:
mGraphicsPipelineDesc->updateLineWidth(&mGraphicsPipelineTransition, mGraphicsPipelineDesc->updateLineWidth(&mGraphicsPipelineTransition,
......
...@@ -595,7 +595,8 @@ angle::Result GraphicsPipelineDesc::initializePipeline( ...@@ -595,7 +595,8 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
shaderStages.push_back(vertexStage); shaderStages.push_back(vertexStage);
// Fragment shader is optional. // Fragment shader is optional.
if (fragmentModule) // anglebug.com/3509 - Don't compile the fragment shader if rasterizationDiscardEnable = true
if (fragmentModule && !mRasterizationAndMultisampleStateInfo.bits.rasterizationDiscardEnable)
{ {
VkPipelineShaderStageCreateInfo fragmentStage = {}; VkPipelineShaderStageCreateInfo fragmentStage = {};
fragmentStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO; fragmentStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
...@@ -853,6 +854,15 @@ void GraphicsPipelineDesc::updateLineWidth(GraphicsPipelineTransitionBits *trans ...@@ -853,6 +854,15 @@ void GraphicsPipelineDesc::updateLineWidth(GraphicsPipelineTransitionBits *trans
transition->set(ANGLE_GET_TRANSITION_BIT(mRasterizationAndMultisampleStateInfo, lineWidth)); transition->set(ANGLE_GET_TRANSITION_BIT(mRasterizationAndMultisampleStateInfo, lineWidth));
} }
void GraphicsPipelineDesc::updateRasterizerDiscardEnabled(
GraphicsPipelineTransitionBits *transition,
bool rasterizerDiscardEnabled)
{
mRasterizationAndMultisampleStateInfo.bits.rasterizationDiscardEnable =
static_cast<uint32_t>(rasterizerDiscardEnabled);
transition->set(ANGLE_GET_TRANSITION_BIT(mRasterizationAndMultisampleStateInfo, bits));
}
void GraphicsPipelineDesc::setRasterizationSamples(uint32_t rasterizationSamples) void GraphicsPipelineDesc::setRasterizationSamples(uint32_t rasterizationSamples)
{ {
mRasterizationAndMultisampleStateInfo.bits.rasterizationSamples = rasterizationSamples; mRasterizationAndMultisampleStateInfo.bits.rasterizationSamples = rasterizationSamples;
......
...@@ -383,6 +383,8 @@ class GraphicsPipelineDesc final ...@@ -383,6 +383,8 @@ class GraphicsPipelineDesc final
const gl::RasterizerState &rasterState, const gl::RasterizerState &rasterState,
bool invertFrontFace); bool invertFrontFace);
void updateLineWidth(GraphicsPipelineTransitionBits *transition, float lineWidth); void updateLineWidth(GraphicsPipelineTransitionBits *transition, float lineWidth);
void updateRasterizerDiscardEnabled(GraphicsPipelineTransitionBits *transition,
bool rasterizerDiscardEnabled);
// Multisample states // Multisample states
void setRasterizationSamples(uint32_t rasterizationSamples); void setRasterizationSamples(uint32_t rasterizationSamples);
......
...@@ -685,7 +685,6 @@ ...@@ -685,7 +685,6 @@
2976 VULKAN NVIDIA : dEQP-GLES3.functional.shaders.invariance.* = FAIL 2976 VULKAN NVIDIA : dEQP-GLES3.functional.shaders.invariance.* = FAIL
// To be triaged: // To be triaged:
2950 VULKAN : dEQP-GLES3.functional.rasterizer_discard.* = SKIP
2950 VULKAN : dEQP-GLES3.functional.negative_api.vertex_array.draw_element* = SKIP 2950 VULKAN : dEQP-GLES3.functional.negative_api.vertex_array.draw_element* = SKIP
// Android Vulkan failures // Android Vulkan failures
......
...@@ -2385,6 +2385,9 @@ TEST_P(SimpleStateChangeTest, ReleaseShaderInUseThatReadsFromUniforms) ...@@ -2385,6 +2385,9 @@ TEST_P(SimpleStateChangeTest, ReleaseShaderInUseThatReadsFromUniforms)
// Tests that sampler sync isn't masked by program textures. // Tests that sampler sync isn't masked by program textures.
TEST_P(SimpleStateChangeTestES3, SamplerSyncNotTiedToProgram) TEST_P(SimpleStateChangeTestES3, SamplerSyncNotTiedToProgram)
{ {
// glBindSampler is available only if the GLES version is 3.0 or higher - anglebug.com/3208
ANGLE_SKIP_TEST_IF(IsVulkan());
// Create a sampler with NEAREST filtering. // Create a sampler with NEAREST filtering.
GLSampler sampler; GLSampler sampler;
glBindSampler(0, sampler); glBindSampler(0, sampler);
...@@ -3726,6 +3729,39 @@ TEST_P(SimpleStateChangeTest, FboLateCullFaceBackCWState) ...@@ -3726,6 +3729,39 @@ TEST_P(SimpleStateChangeTest, FboLateCullFaceBackCWState)
{ {
drawToFboWithCulling(GL_CW, false); drawToFboWithCulling(GL_CW, false);
} }
// Validates GL_RASTERIZER_DISCARD state is tracked correctly
TEST_P(SimpleStateChangeTestES3, RasterizerDiscardState)
{
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);
ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
// The drawQuad() should have no effect with GL_RASTERIZER_DISCARD enabled
glEnable(GL_RASTERIZER_DISCARD);
glUseProgram(greenProgram);
drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
// The drawQuad() should draw something with GL_RASTERIZER_DISCARD disabled
glDisable(GL_RASTERIZER_DISCARD);
glUseProgram(greenProgram);
drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
// The drawQuad() should have no effect with GL_RASTERIZER_DISCARD enabled
glEnable(GL_RASTERIZER_DISCARD);
glUseProgram(blueProgram);
drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
ASSERT_GL_NO_ERROR();
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
}
} // anonymous namespace } // anonymous namespace
ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN()); ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
...@@ -3737,7 +3773,7 @@ ANGLE_INSTANTIATE_TEST(LineLoopStateChangeTest, ...@@ -3737,7 +3773,7 @@ ANGLE_INSTANTIATE_TEST(LineLoopStateChangeTest,
ANGLE_INSTANTIATE_TEST(StateChangeRenderTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN()); ANGLE_INSTANTIATE_TEST(StateChangeRenderTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
ANGLE_INSTANTIATE_TEST(StateChangeTestES3, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(StateChangeTestES3, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(SimpleStateChangeTest, ES2_D3D11(), ES2_VULKAN(), ES2_OPENGL()); ANGLE_INSTANTIATE_TEST(SimpleStateChangeTest, ES2_D3D11(), ES2_VULKAN(), ES2_OPENGL());
ANGLE_INSTANTIATE_TEST(SimpleStateChangeTestES3, ES3_OPENGL(), ES3_D3D11()); ANGLE_INSTANTIATE_TEST(SimpleStateChangeTestES3, ES3_OPENGL(), ES3_D3D11(), ES3_VULKAN());
ANGLE_INSTANTIATE_TEST(SimpleStateChangeTestES31, ES31_OPENGL(), ES31_D3D11()); ANGLE_INSTANTIATE_TEST(SimpleStateChangeTestES31, ES31_OPENGL(), ES31_D3D11());
ANGLE_INSTANTIATE_TEST(ValidationStateChangeTest, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(ValidationStateChangeTest, ES3_D3D11(), ES3_OPENGL());
ANGLE_INSTANTIATE_TEST(WebGL2ValidationStateChangeTest, ES3_D3D11(), ES3_OPENGL()); ANGLE_INSTANTIATE_TEST(WebGL2ValidationStateChangeTest, ES3_D3D11(), ES3_OPENGL());
......
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