diff --git a/src/tests/angle_end2end_tests_expectations.txt b/src/tests/angle_end2end_tests_expectations.txt index 4396d47c5..95cb31b86 100644 --- a/src/tests/angle_end2end_tests_expectations.txt +++ b/src/tests/angle_end2end_tests_expectations.txt @@ -103,6 +103,10 @@ 6977 NVIDIA GLES : MipmapTestES31.GenerateMipmapWithDraw/* = SKIP 6977 LINUX NVIDIA OpenGL : MipmapTestES31.GenerateLowerMipsWithDraw/* = SKIP +// Nvidia Vulkan +7236 NVIDIA VULKAN : GLSLTest_ES31.TessellationControlShaderMatrixCopyBug/* = SKIP +7236 NVIDIA VULKAN : GLSLTest_ES31.TessellationControlShaderMatrixMultiplicationBug/* = SKIP + // Intel Vulkan // On Intel/Vulkan/Linux, The following image is produced, failing the test on the corner of the diff --git a/src/tests/gl_tests/GLSLTest.cpp b/src/tests/gl_tests/GLSLTest.cpp index ee1a71042..9fb4ee293 100644 --- a/src/tests/gl_tests/GLSLTest.cpp +++ b/src/tests/gl_tests/GLSLTest.cpp @@ -15297,6 +15297,170 @@ void main() { CompileShader(GL_FRAGMENT_SHADER, kFS); ASSERT_GL_NO_ERROR(); } + +// Test for a driver bug with matrix multiplication in the tessellation control shader. +TEST_P(GLSLTest_ES31, TessellationControlShaderMatrixMultiplicationBug) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_tessellation_shader")); + + constexpr char kTCS[] = R"(#version 310 es +#extension GL_EXT_tessellation_shader : enable +layout(vertices = 1) out; +precision highp float; + +patch out mat4 x; + +void main() +{ + x = mat4( + 0.53455, 0.47307, 0.34935, 0.28717, + 0.67195, 0.59992, 0.48213, 0.43678, + 0.76376, 0.6772, 0.55361, 0.5165, + 0.77996, 0.68862, 0.56187, 0.52611 + ); + + const mat4 m = mat4( + vec4( -1.0, 3.0,-3.0, 1.0), + vec4( 3.0,-6.0, 3.0, 0.0), + vec4( -3.0, 3.0, 0.0, 0.0), + vec4( 1.0, 0.0, 0.0, 0.0) + ); + + x = m * x; + + gl_TessLevelInner[0u] = 1.; + gl_TessLevelInner[1u] = 1.; + gl_TessLevelOuter[0u] = 1.; + gl_TessLevelOuter[1u] = 1.; + gl_TessLevelOuter[2u] = 1.; + gl_TessLevelOuter[3u] = 1.; +})"; + + constexpr char kTES[] = R"(#version 310 es +#extension GL_EXT_tessellation_shader : enable +layout(quads, cw, fractional_odd_spacing) in; +precision highp float; + +patch in mat4 x; + +out mat4 x_fs; + +void main() +{ + x_fs = x; + gl_Position = vec4(gl_TessCoord.xy * 2. - 1., 0, 1); +})"; + + constexpr char kFS[] = R"(#version 310 es +precision highp float; + +in mat4 x_fs; +out vec4 color; + +void main() +{ + // Note: on the failing driver, .w of every column has the same value as .x of the same column. + + const mat4 expect = mat4( + 0.12378, -0.18672, -0.18444, 0.53455, + 0.1182, -0.13728, -0.21609, 0.67195, + 0.12351, -0.11109, -0.25968, 0.76376, + 0.1264, -0.10623, -0.27402, 0.77996 + ); + + color = vec4(all(lessThan(abs(x_fs[0] - expect[0]), vec4(0.01))), + all(lessThan(abs(x_fs[1] - expect[1]), vec4(0.01))), + all(lessThan(abs(x_fs[2] - expect[2]), vec4(0.01))), + all(lessThan(abs(x_fs[3] - expect[3]), vec4(0.01)))); +})"; + + ANGLE_GL_PROGRAM_WITH_TESS(program, essl31_shaders::vs::Simple(), kTCS, kTES, kFS); + drawPatches(program.get(), essl31_shaders::PositionAttrib(), 0.5f, 1.0f, GL_FALSE); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white); + ASSERT_GL_NO_ERROR(); +} + +// Test for a driver bug with matrix copy in the tessellation control shader. +TEST_P(GLSLTest_ES31, TessellationControlShaderMatrixCopyBug) +{ + ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_tessellation_shader")); + + constexpr char kTCS[] = R"(#version 310 es +#extension GL_EXT_tessellation_shader : enable +layout(vertices = 1) out; +precision highp float; + +patch out mat4 x; +patch out vec4 col0; + +void main() +{ + // Note: if |x| is not an |out| varying, the test passes. + x = mat4( + 0.53455, 0.47307, 0.34935, 0.28717, + 0.67195, 0.59992, 0.48213, 0.43678, + 0.76376, 0.6772, 0.55361, 0.5165, + 0.77996, 0.68862, 0.56187, 0.52611 + ); + + const mat4 m = mat4( + vec4( -1.0, 3.0,-3.0, 1.0), + vec4( 3.0,-6.0, 3.0, 0.0), + vec4( -3.0, 3.0, 0.0, 0.0), + vec4( 1.0, 0.0, 0.0, 0.0) + ); + + mat4 temp = x; + + // Note: On the failing driver, commenting this line makes the test pass. + // However, the output being tested is |temp|, assigned above, not |x|. + x = m * x; + + col0 = temp[0]; + + gl_TessLevelInner[0u] = 1.; + gl_TessLevelInner[1u] = 1.; + gl_TessLevelOuter[0u] = 1.; + gl_TessLevelOuter[1u] = 1.; + gl_TessLevelOuter[2u] = 1.; + gl_TessLevelOuter[3u] = 1.; +})"; + + constexpr char kTES[] = R"(#version 310 es +#extension GL_EXT_tessellation_shader : enable +layout(quads, cw, fractional_odd_spacing) in; +precision highp float; + +patch in vec4 col0; + +out vec4 col0_fs; + +void main() +{ + col0_fs = col0; + gl_Position = vec4(gl_TessCoord.xy * 2. - 1., 0, 1); +})"; + + constexpr char kFS[] = R"(#version 310 es +precision highp float; + +in vec4 col0_fs; +out vec4 color; + +void main() +{ + // Note: on the failing driver, |col0| has the value of |m * x|, not |temp|. + color = vec4(abs(col0_fs.x - 0.53455) < 0.01, + abs(col0_fs.y - 0.47307) < 0.01, + abs(col0_fs.z - 0.34935) < 0.01, + abs(col0_fs.w - 0.28717) < 0.01); +})"; + + ANGLE_GL_PROGRAM_WITH_TESS(program, essl31_shaders::vs::Simple(), kTCS, kTES, kFS); + drawPatches(program.get(), essl31_shaders::PositionAttrib(), 0.5f, 1.0f, GL_FALSE); + EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::white); + ASSERT_GL_NO_ERROR(); +} } // anonymous namespace ANGLE_INSTANTIATE_TEST_ES2_AND_ES3_AND(GLSLTest,