• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     // iOS chokes on the "smooth" qualifier.
80     // TODO(anglebug.com/5491): Add shader compiler workaround that omits "smooth".
81     ANGLE_SKIP_TEST_IF(IsIOS() && IsOpenGLES());
82 
83     ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
84     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
85 
86     glClear(GL_COLOR_BUFFER_BIT);
87     draw(program, 1.0);
88     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(62, 64, 128, 255), kPixelColorThreshhold);
89 
90     glClear(GL_COLOR_BUFFER_BIT);
91     draw(program, 2.0);
92     EXPECT_PIXEL_COLOR_NEAR(64, 64, GLColor(83, 86, 86, 255), kPixelColorThreshhold);
93 }
94 
95 // Test that uninterpolated "Flat" interpolation works correctly
TEST_P(ShaderInterpTest,Flat)96 TEST_P(ShaderInterpTest, Flat)
97 {
98     // TODO: anglebug.com/4085
99     // No vendors currently support VK_EXT_provoking_vertex, which is necessary for conformant flat
100     // shading. SwiftShader does technically support this extension, but as it has not yet been
101     // ratified by Khronos, the vulkan validation layers do not recognize the create info struct,
102     // causing it to be stripped and thus causing the extension to behave as if it is disabled.
103     ANGLE_SKIP_TEST_IF(IsVulkan());
104 
105     const char *vertSrc = R"(#version 300 es
106 precision highp float;
107 in vec4 position;
108 in vec4 vertex_color;
109 flat out vec4 interp_color;
110 
111 void main()
112 {
113     gl_Position = position;
114     interp_color = vertex_color;
115 }
116 )";
117     const char *fragSrc = R"(#version 300 es
118 precision highp float;
119 flat in vec4 interp_color;
120 out vec4 fragColor;
121 
122 void main()
123 {
124     fragColor = interp_color;
125 }
126 )";
127 
128     ANGLE_GL_PROGRAM(program, vertSrc, fragSrc);
129     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
130 
131     glClear(GL_COLOR_BUFFER_BIT);
132     draw(program, 1.0);
133     GLColor smooth_reference;
134     glReadPixels(64, 64, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &smooth_reference);
135     EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor(0, 0, 255, 255));
136 }
137 
138 // Test that "noperspective" interpolation correctly interpolates in screenspace
TEST_P(ShaderInterpTest,NoPerspective)139 TEST_P(ShaderInterpTest, NoPerspective)
140 {
141     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_NV_shader_noperspective_interpolation"));
142 
143     const char *vertSrcSmooth = R"(#version 300 es
144 precision highp float;
145 in vec4 position;
146 in vec4 vertex_color;
147 smooth out vec4 interp_color;
148 
149 void main()
150 {
151     gl_Position = position;
152     interp_color = vertex_color;
153 }
154 )";
155     const char *fragSrcSmooth = R"(#version 300 es
156 precision highp float;
157 smooth in vec4 interp_color;
158 out vec4 fragColor;
159 
160 void main()
161 {
162     fragColor = interp_color;
163 }
164 )";
165     ANGLE_GL_PROGRAM(programSmooth, vertSrcSmooth, fragSrcSmooth);
166     glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
167     glClear(GL_COLOR_BUFFER_BIT);
168     draw(programSmooth, 1.0);
169     GLColor smooth_reference;
170     glReadPixels(64, 64, 1, 1, GL_RGBA, GL_UNSIGNED_BYTE, &smooth_reference);
171 
172     const char *vertSrcNoPerspective = R"(#version 300 es
173 #extension GL_NV_shader_noperspective_interpolation : require
174 
175 #ifndef GL_NV_shader_noperspective_interpolation
176 #error GL_NV_shader_noperspective_interpolation is not defined
177 #endif
178 
179 precision highp float;
180 in vec4 position;
181 in vec4 vertex_color;
182 noperspective out vec4 interp_color;
183 
184 void main()
185 {
186     gl_Position = position;
187     interp_color = vertex_color;
188 }
189 )";
190     const char *fragSrcNoPerspective = R"(#version 300 es
191 #extension GL_NV_shader_noperspective_interpolation : require
192 
193 #ifndef GL_NV_shader_noperspective_interpolation
194 #error GL_NV_shader_noperspective_interpolation is not defined
195 #endif
196 
197 precision highp float;
198 noperspective in vec4 interp_color;
199 out vec4 fragColor;
200 
201 void main()
202 {
203     fragColor = interp_color;
204 }
205 )";
206     ANGLE_GL_PROGRAM(programNoPerspective, vertSrcNoPerspective, fragSrcNoPerspective);
207     glClear(GL_COLOR_BUFFER_BIT);
208     draw(programNoPerspective, 1.0);
209     EXPECT_PIXEL_COLOR_EQ(64, 64, smooth_reference);
210 
211     glClear(GL_COLOR_BUFFER_BIT);
212     draw(programNoPerspective, 2.0);
213     EXPECT_PIXEL_COLOR_EQ(64, 64, smooth_reference);
214 }
215 
216 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ShaderInterpTest);
217 ANGLE_INSTANTIATE_TEST_ES3(ShaderInterpTest);