OpenGL: Unconditionally set glFrontFace
Previously glFrontFace was called only if some cull mode was set. This was incorrect because the front face also influences whether a triangle uses stencilFront or stencilBack. Because OpenGL default to GL_CCW (which with the Y-flip is the inverse of wgpu::FrontFace::CCW that's default in the descriptor), if stencilFront != stencilBack and cull mode is none, then the incorrect stencil face descriptor was used. Also adds a regression test for this issue. Bug: dawn:508 Change-Id: I00d93bda6d4f030cf9db472a9f2b0deefc72707f Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/26880 Reviewed-by: Corentin Wallez <cwallez@chromium.org> Reviewed-by: Austin Eng <enga@chromium.org> Commit-Queue: Corentin Wallez <cwallez@chromium.org>
This commit is contained in:
parent
d95180dede
commit
7268e7d36f
src
|
@ -43,14 +43,15 @@ namespace dawn_native { namespace opengl {
|
||||||
void ApplyFrontFaceAndCulling(const OpenGLFunctions& gl,
|
void ApplyFrontFaceAndCulling(const OpenGLFunctions& gl,
|
||||||
wgpu::FrontFace face,
|
wgpu::FrontFace face,
|
||||||
wgpu::CullMode mode) {
|
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) {
|
if (mode == wgpu::CullMode::None) {
|
||||||
gl.Disable(GL_CULL_FACE);
|
gl.Disable(GL_CULL_FACE);
|
||||||
} else {
|
} else {
|
||||||
gl.Enable(GL_CULL_FACE);
|
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;
|
GLenum cullMode = (mode == wgpu::CullMode::Front) ? GL_FRONT : GL_BACK;
|
||||||
gl.CullFace(cullMode);
|
gl.CullFace(cullMode);
|
||||||
|
|
|
@ -85,6 +85,7 @@ class DepthStencilStateTest : public DawnTest {
|
||||||
RGBA8 color;
|
RGBA8 color;
|
||||||
float depth;
|
float depth;
|
||||||
uint32_t stencil;
|
uint32_t stencil;
|
||||||
|
wgpu::FrontFace frontFace = wgpu::FrontFace::CCW;
|
||||||
};
|
};
|
||||||
|
|
||||||
// Check whether a depth comparison function works as expected
|
// Check whether a depth comparison function works as expected
|
||||||
|
@ -288,6 +289,7 @@ class DepthStencilStateTest : public DawnTest {
|
||||||
descriptor.cFragmentStage.module = fsModule;
|
descriptor.cFragmentStage.module = fsModule;
|
||||||
descriptor.cDepthStencilState = test.depthStencilState;
|
descriptor.cDepthStencilState = test.depthStencilState;
|
||||||
descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
descriptor.cDepthStencilState.format = wgpu::TextureFormat::Depth24PlusStencil8;
|
||||||
|
descriptor.cRasterizationState.frontFace = test.frontFace;
|
||||||
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
descriptor.depthStencilState = &descriptor.cDepthStencilState;
|
||||||
|
|
||||||
wgpu::RenderPipeline pipeline = device.CreateRenderPipeline(&descriptor);
|
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,
|
DAWN_INSTANTIATE_TEST(DepthStencilStateTest,
|
||||||
D3D12Backend(),
|
D3D12Backend(),
|
||||||
MetalBackend(),
|
MetalBackend(),
|
||||||
|
|
Loading…
Reference in New Issue