diff --git a/src/dawn_native/opengl/RenderPipelineGL.cpp b/src/dawn_native/opengl/RenderPipelineGL.cpp index 943dfbb984..7c70396f21 100644 --- a/src/dawn_native/opengl/RenderPipelineGL.cpp +++ b/src/dawn_native/opengl/RenderPipelineGL.cpp @@ -43,14 +43,15 @@ namespace dawn_native { namespace opengl { void ApplyFrontFaceAndCulling(const OpenGLFunctions& gl, wgpu::FrontFace face, wgpu::CullMode mode) { + // Note that we invert winding direction in OpenGL. Because Y axis is up in OpenGL, + // which is different from WebGPU and other backends (Y axis is down). + GLenum direction = (face == wgpu::FrontFace::CCW) ? GL_CW : GL_CCW; + gl.FrontFace(direction); + if (mode == wgpu::CullMode::None) { gl.Disable(GL_CULL_FACE); } else { gl.Enable(GL_CULL_FACE); - // Note that we invert winding direction in OpenGL. Because Y axis is up in OpenGL, - // which is different from WebGPU and other backends (Y axis is down). - GLenum direction = (face == wgpu::FrontFace::CCW) ? GL_CW : GL_CCW; - gl.FrontFace(direction); GLenum cullMode = (mode == wgpu::CullMode::Front) ? GL_FRONT : GL_BACK; gl.CullFace(cullMode); diff --git a/src/tests/end2end/DepthStencilStateTests.cpp b/src/tests/end2end/DepthStencilStateTests.cpp index 4788094e59..5f5895a113 100644 --- a/src/tests/end2end/DepthStencilStateTests.cpp +++ b/src/tests/end2end/DepthStencilStateTests.cpp @@ -85,6 +85,7 @@ class DepthStencilStateTest : public DawnTest { RGBA8 color; float depth; uint32_t stencil; + wgpu::FrontFace frontFace = wgpu::FrontFace::CCW; }; // Check whether a depth comparison function works as expected @@ -288,6 +289,7 @@ class DepthStencilStateTest : public DawnTest { descriptor.cFragmentStage.module = fsModule; descriptor.cDepthStencilState = test.depthStencilState; descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8; + descriptor.cRasterizationState.frontFace = test.frontFace; descriptor.depthStencilState = &descriptor.cDepthStencilState; wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor); @@ -734,6 +736,17 @@ TEST_P(DepthStencilStateTest, CreatePipelineWithAllFormats) { } } +// Test that the front and back stencil states are set correctly (and take frontFace into account) +TEST_P(DepthStencilStateTest, StencilFrontAndBackFace) { + wgpu::DepthStencilStateDescriptor state; + state.stencilFront.compare = wgpu::CompareFunction::Always; + state.stencilBack.compare = wgpu::CompareFunction::Never; + + // The front facing triangle passes the stencil comparison but the back facing one doesn't. + DoTest({{state, RGBA8::kRed, 0.f, 0u, wgpu::FrontFace::CCW}}, RGBA8::kRed, RGBA8::kZero); + DoTest({{state, RGBA8::kRed, 0.f, 0u, wgpu::FrontFace::CW}}, RGBA8::kZero, RGBA8::kRed); +} + DAWN_INSTANTIATE_TEST(DepthStencilStateTest, D3D12Backend(), MetalBackend(),