Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 70642e4

Browse files
timvpGoogleCommit Bot
authored andcommitted
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: Shahbaz Youssefi <syoussefi@chromium.org> Reviewed-by: Jamie Madill <jmadill@chromium.org>
1 parent 35b25fc commit 70642e4

File tree

5 files changed

+52
-3
lines changed

5 files changed

+52
-3
lines changed

src/libANGLE/renderer/vulkan/ContextVk.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1495,6 +1495,8 @@ angle::Result ContextVk::syncState(const gl::Context *context,
14951495
glState.getRasterizerState());
14961496
break;
14971497
case gl::State::DIRTY_BIT_RASTERIZER_DISCARD_ENABLED:
1498+
mGraphicsPipelineDesc->updateRasterizerDiscardEnabled(
1499+
&mGraphicsPipelineTransition, glState.isRasterizerDiscardEnabled());
14981500
break;
14991501
case gl::State::DIRTY_BIT_LINE_WIDTH:
15001502
mGraphicsPipelineDesc->updateLineWidth(&mGraphicsPipelineTransition,

src/libANGLE/renderer/vulkan/vk_cache_utils.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -595,7 +595,8 @@ angle::Result GraphicsPipelineDesc::initializePipeline(
595595
shaderStages.push_back(vertexStage);
596596

597597
// Fragment shader is optional.
598-
if (fragmentModule)
598+
// anglebug.com/3509 - Don't compile the fragment shader if rasterizationDiscardEnable = true
599+
if (fragmentModule && !mRasterizationAndMultisampleStateInfo.bits.rasterizationDiscardEnable)
599600
{
600601
VkPipelineShaderStageCreateInfo fragmentStage = {};
601602
fragmentStage.sType = VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO;
@@ -853,6 +854,15 @@ void GraphicsPipelineDesc::updateLineWidth(GraphicsPipelineTransitionBits *trans
853854
transition->set(ANGLE_GET_TRANSITION_BIT(mRasterizationAndMultisampleStateInfo, lineWidth));
854855
}
855856

857+
void GraphicsPipelineDesc::updateRasterizerDiscardEnabled(
858+
GraphicsPipelineTransitionBits *transition,
859+
bool rasterizerDiscardEnabled)
860+
{
861+
mRasterizationAndMultisampleStateInfo.bits.rasterizationDiscardEnable =
862+
static_cast<uint32_t>(rasterizerDiscardEnabled);
863+
transition->set(ANGLE_GET_TRANSITION_BIT(mRasterizationAndMultisampleStateInfo, bits));
864+
}
865+
856866
void GraphicsPipelineDesc::setRasterizationSamples(uint32_t rasterizationSamples)
857867
{
858868
mRasterizationAndMultisampleStateInfo.bits.rasterizationSamples = rasterizationSamples;

src/libANGLE/renderer/vulkan/vk_cache_utils.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,8 @@ class GraphicsPipelineDesc final
383383
const gl::RasterizerState &rasterState,
384384
bool invertFrontFace);
385385
void updateLineWidth(GraphicsPipelineTransitionBits *transition, float lineWidth);
386+
void updateRasterizerDiscardEnabled(GraphicsPipelineTransitionBits *transition,
387+
bool rasterizerDiscardEnabled);
386388

387389
// Multisample states
388390
void setRasterizationSamples(uint32_t rasterizationSamples);

src/tests/deqp_support/deqp_gles3_test_expectations.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -685,7 +685,6 @@
685685
2976 VULKAN NVIDIA : dEQP-GLES3.functional.shaders.invariance.* = FAIL
686686

687687
// To be triaged:
688-
2950 VULKAN : dEQP-GLES3.functional.rasterizer_discard.* = SKIP
689688
2950 VULKAN : dEQP-GLES3.functional.negative_api.vertex_array.draw_element* = SKIP
690689

691690
// Android Vulkan failures

src/tests/gl_tests/StateChangeTest.cpp

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2385,6 +2385,9 @@ TEST_P(SimpleStateChangeTest, ReleaseShaderInUseThatReadsFromUniforms)
23852385
// Tests that sampler sync isn't masked by program textures.
23862386
TEST_P(SimpleStateChangeTestES3, SamplerSyncNotTiedToProgram)
23872387
{
2388+
// glBindSampler is available only if the GLES version is 3.0 or higher - anglebug.com/3208
2389+
ANGLE_SKIP_TEST_IF(IsVulkan());
2390+
23882391
// Create a sampler with NEAREST filtering.
23892392
GLSampler sampler;
23902393
glBindSampler(0, sampler);
@@ -3726,6 +3729,39 @@ TEST_P(SimpleStateChangeTest, FboLateCullFaceBackCWState)
37263729
{
37273730
drawToFboWithCulling(GL_CW, false);
37283731
}
3732+
3733+
// Validates GL_RASTERIZER_DISCARD state is tracked correctly
3734+
TEST_P(SimpleStateChangeTestES3, RasterizerDiscardState)
3735+
{
3736+
glClearColor(GLColor::red.R, GLColor::red.G, GLColor::red.B, GLColor::red.A);
3737+
glClear(GL_COLOR_BUFFER_BIT);
3738+
ASSERT_GL_NO_ERROR();
3739+
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3740+
3741+
ANGLE_GL_PROGRAM(greenProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Green());
3742+
ANGLE_GL_PROGRAM(blueProgram, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
3743+
3744+
// The drawQuad() should have no effect with GL_RASTERIZER_DISCARD enabled
3745+
glEnable(GL_RASTERIZER_DISCARD);
3746+
glUseProgram(greenProgram);
3747+
drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3748+
ASSERT_GL_NO_ERROR();
3749+
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::red);
3750+
3751+
// The drawQuad() should draw something with GL_RASTERIZER_DISCARD disabled
3752+
glDisable(GL_RASTERIZER_DISCARD);
3753+
glUseProgram(greenProgram);
3754+
drawQuad(greenProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3755+
ASSERT_GL_NO_ERROR();
3756+
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3757+
3758+
// The drawQuad() should have no effect with GL_RASTERIZER_DISCARD enabled
3759+
glEnable(GL_RASTERIZER_DISCARD);
3760+
glUseProgram(blueProgram);
3761+
drawQuad(blueProgram.get(), std::string(essl1_shaders::PositionAttrib()), 0.0f);
3762+
ASSERT_GL_NO_ERROR();
3763+
EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
3764+
}
37293765
} // anonymous namespace
37303766

37313767
ANGLE_INSTANTIATE_TEST(StateChangeTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
@@ -3737,7 +3773,7 @@ ANGLE_INSTANTIATE_TEST(LineLoopStateChangeTest,
37373773
ANGLE_INSTANTIATE_TEST(StateChangeRenderTest, ES2_D3D9(), ES2_D3D11(), ES2_OPENGL(), ES2_VULKAN());
37383774
ANGLE_INSTANTIATE_TEST(StateChangeTestES3, ES3_D3D11(), ES3_OPENGL());
37393775
ANGLE_INSTANTIATE_TEST(SimpleStateChangeTest, ES2_D3D11(), ES2_VULKAN(), ES2_OPENGL());
3740-
ANGLE_INSTANTIATE_TEST(SimpleStateChangeTestES3, ES3_OPENGL(), ES3_D3D11());
3776+
ANGLE_INSTANTIATE_TEST(SimpleStateChangeTestES3, ES3_OPENGL(), ES3_D3D11(), ES3_VULKAN());
37413777
ANGLE_INSTANTIATE_TEST(SimpleStateChangeTestES31, ES31_OPENGL(), ES31_D3D11());
37423778
ANGLE_INSTANTIATE_TEST(ValidationStateChangeTest, ES3_D3D11(), ES3_OPENGL());
37433779
ANGLE_INSTANTIATE_TEST(WebGL2ValidationStateChangeTest, ES3_D3D11(), ES3_OPENGL());

0 commit comments

Comments
 (0)