xref: /aosp_15_r20/external/angle/src/tests/gl_tests/ShaderOpTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1*8975f5c5SAndroid Build Coastguard Worker //
2*8975f5c5SAndroid Build Coastguard Worker // Copyright 2024 The ANGLE Project Authors. All rights reserved.
3*8975f5c5SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
4*8975f5c5SAndroid Build Coastguard Worker // found in the LICENSE file.
5*8975f5c5SAndroid Build Coastguard Worker //
6*8975f5c5SAndroid Build Coastguard Worker // Tests for shader interpolation qualifiers
7*8975f5c5SAndroid Build Coastguard Worker //
8*8975f5c5SAndroid Build Coastguard Worker 
9*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/ANGLETest.h"
10*8975f5c5SAndroid Build Coastguard Worker #include "test_utils/gl_raii.h"
11*8975f5c5SAndroid Build Coastguard Worker 
12*8975f5c5SAndroid Build Coastguard Worker using namespace angle;
13*8975f5c5SAndroid Build Coastguard Worker 
14*8975f5c5SAndroid Build Coastguard Worker constexpr int kPixelColorThreshhold = 8;
15*8975f5c5SAndroid Build Coastguard Worker 
16*8975f5c5SAndroid Build Coastguard Worker class ShaderOpTest : public ANGLETest<>
17*8975f5c5SAndroid Build Coastguard Worker {
18*8975f5c5SAndroid Build Coastguard Worker   protected:
ShaderOpTest()19*8975f5c5SAndroid Build Coastguard Worker     ShaderOpTest() : ANGLETest()
20*8975f5c5SAndroid Build Coastguard Worker     {
21*8975f5c5SAndroid Build Coastguard Worker         setWindowWidth(256);
22*8975f5c5SAndroid Build Coastguard Worker         setWindowHeight(256);
23*8975f5c5SAndroid Build Coastguard Worker         setConfigRedBits(8);
24*8975f5c5SAndroid Build Coastguard Worker         setConfigGreenBits(8);
25*8975f5c5SAndroid Build Coastguard Worker         setConfigBlueBits(8);
26*8975f5c5SAndroid Build Coastguard Worker         setConfigAlphaBits(8);
27*8975f5c5SAndroid Build Coastguard Worker         setConfigDepthBits(24);
28*8975f5c5SAndroid Build Coastguard Worker         setConfigStencilBits(8);
29*8975f5c5SAndroid Build Coastguard Worker         setMultisampleEnabled(0);
30*8975f5c5SAndroid Build Coastguard Worker     }
31*8975f5c5SAndroid Build Coastguard Worker };
32*8975f5c5SAndroid Build Coastguard Worker 
33*8975f5c5SAndroid Build Coastguard Worker // Simplified test from dEQP-GLES2.functional.fragment_ops.interaction.basic_shader.22
34*8975f5c5SAndroid Build Coastguard Worker // Test that vulkan drivers correctly handle the constant expression spirv generated by ANGLE
TEST_P(ShaderOpTest,ConstantExpression)35*8975f5c5SAndroid Build Coastguard Worker TEST_P(ShaderOpTest, ConstantExpression)
36*8975f5c5SAndroid Build Coastguard Worker {
37*8975f5c5SAndroid Build Coastguard Worker     const char *vertSrc = R"(
38*8975f5c5SAndroid Build Coastguard Worker attribute vec4 pos;
39*8975f5c5SAndroid Build Coastguard Worker 
40*8975f5c5SAndroid Build Coastguard Worker void main()
41*8975f5c5SAndroid Build Coastguard Worker {
42*8975f5c5SAndroid Build Coastguard Worker     gl_Position = pos;
43*8975f5c5SAndroid Build Coastguard Worker }
44*8975f5c5SAndroid Build Coastguard Worker )";
45*8975f5c5SAndroid Build Coastguard Worker     // ANGLE and glslang translate below expression in fragment shader differently
46*8975f5c5SAndroid Build Coastguard Worker     // vec4 c = vec4(1.0, 0.5, 0.5, 0.75)
47*8975f5c5SAndroid Build Coastguard Worker 
48*8975f5c5SAndroid Build Coastguard Worker     // ANGLE:
49*8975f5c5SAndroid Build Coastguard Worker     // %constVec4 = OpConstantComposite %vec4 %const1 %const2 %const2 %const3
50*8975f5c5SAndroid Build Coastguard Worker     // %var = OpVariable %PrivateVec4Pointer Private %constVec4
51*8975f5c5SAndroid Build Coastguard Worker     // %loadedVal = OpLoad %vec4 %var
52*8975f5c5SAndroid Build Coastguard Worker     // OpStore %gl_fragColor %loadedVal
53*8975f5c5SAndroid Build Coastguard Worker 
54*8975f5c5SAndroid Build Coastguard Worker     // glslang:
55*8975f5c5SAndroid Build Coastguard Worker     // %constVec4 = OpConstantComposite %vec4 %const1 %const2 %const2 %const3
56*8975f5c5SAndroid Build Coastguard Worker     // %var = OpVariable %PrivateVec4Pointer Private
57*8975f5c5SAndroid Build Coastguard Worker     // OpStore %var %constVec4
58*8975f5c5SAndroid Build Coastguard Worker     // %loadedVal = OpLoad %vec4 %var
59*8975f5c5SAndroid Build Coastguard Worker     // OpStore %gl_fragColor %loadedVal
60*8975f5c5SAndroid Build Coastguard Worker 
61*8975f5c5SAndroid Build Coastguard Worker     // Both are valid spirv instructions.
62*8975f5c5SAndroid Build Coastguard Worker     // Tests should pass with spirv generated by ANGLE.
63*8975f5c5SAndroid Build Coastguard Worker 
64*8975f5c5SAndroid Build Coastguard Worker     // Note: setting forceDeferNonConstGlobalInitializers to true will make ANGLE generate the same
65*8975f5c5SAndroid Build Coastguard Worker     // spirv instruction for the constant expression as glslang.
66*8975f5c5SAndroid Build Coastguard Worker     const char *fragSrc = R"(
67*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
68*8975f5c5SAndroid Build Coastguard Worker vec4 c = vec4(1.0, 0.5, 0.5, 0.75);
69*8975f5c5SAndroid Build Coastguard Worker 
70*8975f5c5SAndroid Build Coastguard Worker void main()
71*8975f5c5SAndroid Build Coastguard Worker {
72*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = c;
73*8975f5c5SAndroid Build Coastguard Worker }
74*8975f5c5SAndroid Build Coastguard Worker )";
75*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
76*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
77*8975f5c5SAndroid Build Coastguard Worker 
78*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribPosData = {1, 1,  0.5, 1, -1, 1,  0.5, 1,
79*8975f5c5SAndroid Build Coastguard Worker                                              1, -1, 0.5, 1, -1, -1, 0.5, 1};
80*8975f5c5SAndroid Build Coastguard Worker     GLint attribPosLoc                    = glGetAttribLocation(1, "pos");
81*8975f5c5SAndroid Build Coastguard Worker     ASSERT(attribPosLoc >= 0);
82*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribPosLoc);
83*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
84*8975f5c5SAndroid Build Coastguard Worker 
85*8975f5c5SAndroid Build Coastguard Worker     const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
86*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
87*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(255, 125, 125, 190), kPixelColorThreshhold);
88*8975f5c5SAndroid Build Coastguard Worker }
89*8975f5c5SAndroid Build Coastguard Worker 
90*8975f5c5SAndroid Build Coastguard Worker // Simplified test from dEQP-GLES2.functional.shaders.random.all_features.fragment.12
91*8975f5c5SAndroid Build Coastguard Worker // Test that vulkan drivers correctly handle the constant expression spirv generated by ANGLE
92*8975f5c5SAndroid Build Coastguard Worker // Difference beween this test and ConstantExpression test is there is a uniform in fragment shader
93*8975f5c5SAndroid Build Coastguard Worker // in this test, and with this extra element the ANGLE spirv can trigger an error in
94*8975f5c5SAndroid Build Coastguard Worker // vkCreateGraphicsPipelines on some drivers.
TEST_P(ShaderOpTest,ConstantExpressionComparedWithUniform)95*8975f5c5SAndroid Build Coastguard Worker TEST_P(ShaderOpTest, ConstantExpressionComparedWithUniform)
96*8975f5c5SAndroid Build Coastguard Worker {
97*8975f5c5SAndroid Build Coastguard Worker     const char *vertSrc = R"(
98*8975f5c5SAndroid Build Coastguard Worker attribute vec4 pos;
99*8975f5c5SAndroid Build Coastguard Worker void main()
100*8975f5c5SAndroid Build Coastguard Worker {
101*8975f5c5SAndroid Build Coastguard Worker     gl_Position = pos;
102*8975f5c5SAndroid Build Coastguard Worker }
103*8975f5c5SAndroid Build Coastguard Worker )";
104*8975f5c5SAndroid Build Coastguard Worker 
105*8975f5c5SAndroid Build Coastguard Worker     // ANGLE and glslang translate below expression in fragment shader differently
106*8975f5c5SAndroid Build Coastguard Worker     // int k = (5) * (1)
107*8975f5c5SAndroid Build Coastguard Worker 
108*8975f5c5SAndroid Build Coastguard Worker     // ANGLE:
109*8975f5c5SAndroid Build Coastguard Worker     // %k = OpVariable %_ptr_Private_int_0 Private %int_5 // declare Private OpVariable with
110*8975f5c5SAndroid Build Coastguard Worker     // initializer
111*8975f5c5SAndroid Build Coastguard Worker     // ... some other instructions
112*8975f5c5SAndroid Build Coastguard Worker     // %main = OpFunction %void None %62
113*8975f5c5SAndroid Build Coastguard Worker     // %67 = OpLoad %int %k
114*8975f5c5SAndroid Build Coastguard Worker     // ... some other instructions
115*8975f5c5SAndroid Build Coastguard Worker 
116*8975f5c5SAndroid Build Coastguard Worker     // glslang:
117*8975f5c5SAndroid Build Coastguard Worker     // %k = OpVariable %_ptr_Private_int_0 Private // declare Private OpVariable without initializer
118*8975f5c5SAndroid Build Coastguard Worker     // ... some other instructions
119*8975f5c5SAndroid Build Coastguard Worker     // %main = OpFunction %void None %62
120*8975f5c5SAndroid Build Coastguard Worker     // OpStore %k %int_5 // Assign the value to the Private OpVariable in the main function
121*8975f5c5SAndroid Build Coastguard Worker     // %67 = OpLoad %int %k
122*8975f5c5SAndroid Build Coastguard Worker     // ... some other instructions
123*8975f5c5SAndroid Build Coastguard Worker 
124*8975f5c5SAndroid Build Coastguard Worker     // Both are valid spirv instructions.
125*8975f5c5SAndroid Build Coastguard Worker     // Tests should pass with spirv generated by ANGLE
126*8975f5c5SAndroid Build Coastguard Worker 
127*8975f5c5SAndroid Build Coastguard Worker     // Note: setting forceDeferNonConstGlobalInitializers to true will make ANGLE generate the same
128*8975f5c5SAndroid Build Coastguard Worker     // spirv instruction for the constant expression as glslang.
129*8975f5c5SAndroid Build Coastguard Worker 
130*8975f5c5SAndroid Build Coastguard Worker     const char *fragSrc = R"(
131*8975f5c5SAndroid Build Coastguard Worker precision mediump float;
132*8975f5c5SAndroid Build Coastguard Worker int k = (5) * (1);
133*8975f5c5SAndroid Build Coastguard Worker uniform mediump int o;
134*8975f5c5SAndroid Build Coastguard Worker void main()
135*8975f5c5SAndroid Build Coastguard Worker {
136*8975f5c5SAndroid Build Coastguard Worker     gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
137*8975f5c5SAndroid Build Coastguard Worker     if (o >= k)
138*8975f5c5SAndroid Build Coastguard Worker         gl_FragColor = vec4(0.0, 0.0, 1.0, 1.0);
139*8975f5c5SAndroid Build Coastguard Worker }
140*8975f5c5SAndroid Build Coastguard Worker )";
141*8975f5c5SAndroid Build Coastguard Worker     ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
142*8975f5c5SAndroid Build Coastguard Worker     glUseProgram(program);
143*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
144*8975f5c5SAndroid Build Coastguard Worker 
145*8975f5c5SAndroid Build Coastguard Worker     std::array<GLfloat, 16> attribPosData = {1, 1,  0.5, 1, -1, 1,  0.5, 1,
146*8975f5c5SAndroid Build Coastguard Worker                                              1, -1, 0.5, 1, -1, -1, 0.5, 1};
147*8975f5c5SAndroid Build Coastguard Worker     GLint attribPosLoc                    = glGetAttribLocation(1, "pos");
148*8975f5c5SAndroid Build Coastguard Worker     ASSERT(attribPosLoc >= 0);
149*8975f5c5SAndroid Build Coastguard Worker     glEnableVertexAttribArray(attribPosLoc);
150*8975f5c5SAndroid Build Coastguard Worker     glVertexAttribPointer(attribPosLoc, 4, GL_FLOAT, GL_FALSE, 0, attribPosData.data());
151*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
152*8975f5c5SAndroid Build Coastguard Worker 
153*8975f5c5SAndroid Build Coastguard Worker     GLint uniformOLocation = glGetUniformLocation(program, "o");
154*8975f5c5SAndroid Build Coastguard Worker     ASSERT(uniformOLocation >= 0);
155*8975f5c5SAndroid Build Coastguard Worker     GLint uniformOValue = 4;
156*8975f5c5SAndroid Build Coastguard Worker     glUniform1i(uniformOLocation, uniformOValue);
157*8975f5c5SAndroid Build Coastguard Worker 
158*8975f5c5SAndroid Build Coastguard Worker     const uint16_t indices[] = {0, 1, 2, 2, 1, 3};
159*8975f5c5SAndroid Build Coastguard Worker     glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, &indices[0]);
160*8975f5c5SAndroid Build Coastguard Worker     EXPECT_GL_NO_ERROR();
161*8975f5c5SAndroid Build Coastguard Worker     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(255, 255, 255, 255), kPixelColorThreshhold);
162*8975f5c5SAndroid Build Coastguard Worker }
163*8975f5c5SAndroid Build Coastguard Worker 
164*8975f5c5SAndroid Build Coastguard Worker GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShaderOpTest);
165*8975f5c5SAndroid Build Coastguard Worker ANGLE_INSTANTIATE_TEST_ES2(ShaderOpTest);
166