xref: /aosp_15_r20/external/angle/src/tests/gl_tests/ShaderInterpTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
1 //
2 // Copyright 2020 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // Tests for shader interpolation qualifiers
7 //
8 
9 #include "common/mathutil.h"
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12 
13 using namespace angle;
14 
15 constexpr int kPixelColorThreshhold = 8;
16 
17 class ShaderInterpTest : public ANGLETest<>
18 {
19   protected:
ShaderInterpTest()20     ShaderInterpTest() : ANGLETest()
21     {
22         setWindowWidth(128);
23         setWindowHeight(128);
24     }
25 
draw(GLuint program,float skew)26     void draw(GLuint program, float skew)
27     {
28         glUseProgram(program);
29 
30         std::array<Vector4, 3> vertices;
31         vertices[0] = {-1.0, -1.0, 0.0, 1.0};
32         vertices[1] = {1.0, -1.0, 0.0, 1.0};
33         vertices[2] = {0.0, 1.0 * skew, 0.0, skew};
34 
35         std::array<Vector4, 3> colors;
36         colors[0] = {1.0, 0.0, 0.0, 1.0};
37         colors[1] = {0.0, 1.0, 0.0, 1.0};
38         colors[2] = {0.0, 0.0, 1.0, 1.0};
39 
40         GLint positionLocation = glGetAttribLocation(program, "position");
41         GLint colorLocation    = glGetAttribLocation(program, "vertex_color");
42 
43         glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, vertices.data());
44         glVertexAttribPointer(colorLocation, 4, GL_FLOAT, GL_FALSE, 0, colors.data());
45 
46         glEnableVertexAttribArray(positionLocation);
47         glEnableVertexAttribArray(colorLocation);
48 
49         glDrawArrays(GL_TRIANGLES, 0, 3);
50     }
51 };
52 
53 // Test that regular "smooth" interpolation works correctly
TEST_P(ShaderInterpTest,Smooth)54 TEST_P(ShaderInterpTest, Smooth)
55 {
56     const char *vertSrc = R"(#version 300 es
57 precision highp float;
58 in vec4 position;
59 in vec4 vertex_color;
60 smooth out vec4 interp_color;
61 
62 void main()
63 {
64     gl_Position = position;
65     interp_color = vertex_color;
66 }
67 )";
68     const char *fragSrc = R"(#version 300 es
69 precision highp float;
70 smooth in vec4 interp_color;
71 out vec4 fragColor;
72 
73 void main()
74 {
75     fragColor = interp_color;
76 }
77 )";
78 
79     ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
80     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
81 
82     glClear(GL_COLOR_BUFFER_BIT);
83     draw(program, 1.0);
84     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(62, 64, 128, 255), kPixelColorThreshhold);
85 
86     glClear(GL_COLOR_BUFFER_BIT);
87     draw(program, 2.0);
88     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(83, 86, 86, 255), kPixelColorThreshhold);
89 }
90 
91 // Test that uninterpolated "Flat" interpolation works correctly
TEST_P(ShaderInterpTest,Flat)92 TEST_P(ShaderInterpTest, Flat)
93 {
94     // TODO: anglebug.com/42262721
95     // No vendors currently support VK_EXT_provoking_vertex, which is necessary for conformant flat
96     // shading. SwiftShader does technically support this extension, but as it has not yet been
97     // ratified by Khronos, the vulkan validation layers do not recognize the create info struct,
98     // causing it to be stripped and thus causing the extension to behave as if it is disabled.
99     ANGLE_SKIP_TEST_IF(IsVulkan());
100 
101     const char *vertSrc = R"(#version 300 es
102 precision highp float;
103 in vec4 position;
104 in vec4 vertex_color;
105 flat out vec4 interp_color;
106 
107 void main()
108 {
109     gl_Position = position;
110     interp_color = vertex_color;
111 }
112 )";
113     const char *fragSrc = R"(#version 300 es
114 precision highp float;
115 flat in vec4 interp_color;
116 out vec4 fragColor;
117 
118 void main()
119 {
120     fragColor = interp_color;
121 }
122 )";
123 
124     ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
125     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
126 
127     glClear(GL_COLOR_BUFFER_BIT);
128     draw(program, 1.0);
129     GLColor smooth_reference;
130     glReadPixels(64, 64, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &smooth_reference);
131     EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor(0, 0, 255, 255));
132 }
133 
134 // Test that "noperspective" interpolation correctly interpolates in screenspace
TEST_P(ShaderInterpTest,NoPerspective)135 TEST_P(ShaderInterpTest, NoPerspective)
136 {
137     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_shader_noperspective_interpolation"));
138 
139     const char *vertSrcSmooth = R"(#version 300 es
140 precision highp float;
141 in vec4 position;
142 in vec4 vertex_color;
143 smooth out vec4 interp_color;
144 
145 void main()
146 {
147     gl_Position = position;
148     interp_color = vertex_color;
149 }
150 )";
151     const char *fragSrcSmooth = R"(#version 300 es
152 precision highp float;
153 smooth in vec4 interp_color;
154 out vec4 fragColor;
155 
156 void main()
157 {
158     fragColor = interp_color;
159 }
160 )";
161     ANGLE_GL_PROGRAM(programSmooth, vertSrcSmooth, fragSrcSmooth);
162     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
163     glClear(GL_COLOR_BUFFER_BIT);
164     draw(programSmooth, 1.0);
165     GLColor smooth_reference;
166     glReadPixels(64, 64, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &smooth_reference);
167 
168     const char *vertSrcNoPerspective = R"(#version 300 es
169 #extension GL_NV_shader_noperspective_interpolation : require
170 
171 #ifndef GL_NV_shader_noperspective_interpolation
172 #error GL_NV_shader_noperspective_interpolation is not defined
173 #endif
174 
175 precision highp float;
176 in vec4 position;
177 in vec4 vertex_color;
178 noperspective out vec4 interp_color;
179 
180 void main()
181 {
182     gl_Position = position;
183     interp_color = vertex_color;
184 }
185 )";
186     const char *fragSrcNoPerspective = R"(#version 300 es
187 #extension GL_NV_shader_noperspective_interpolation : require
188 
189 #ifndef GL_NV_shader_noperspective_interpolation
190 #error GL_NV_shader_noperspective_interpolation is not defined
191 #endif
192 
193 precision highp float;
194 noperspective in vec4 interp_color;
195 out vec4 fragColor;
196 
197 void main()
198 {
199     fragColor = interp_color;
200 }
201 )";
202     ANGLE_GL_PROGRAM(programNoPerspective, vertSrcNoPerspective, fragSrcNoPerspective);
203     glClear(GL_COLOR_BUFFER_BIT);
204     draw(programNoPerspective, 1.0);
205     EXPECT_PIXEL_COLOR_EQ(64, 64, smooth_reference);
206 
207     glClear(GL_COLOR_BUFFER_BIT);
208     draw(programNoPerspective, 2.0);
209     EXPECT_PIXEL_COLOR_EQ(64, 64, smooth_reference);
210 }
211 
212 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShaderInterpTest);
213 ANGLE_INSTANTIATE_TEST_ES3(ShaderInterpTest);