1 //
2 // Copyright 2016 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 // BuiltinVariableTest:
7 // Tests the correctness of the builtin GLSL variables.
8 //
9
10 #include "test_utils/ANGLETest.h"
11
12 using namespace angle;
13
14 class BuiltinVariableVertexIdTest : public ANGLETest
15 {
16 protected:
BuiltinVariableVertexIdTest()17 BuiltinVariableVertexIdTest()
18 {
19 setWindowWidth(64);
20 setWindowHeight(64);
21 setConfigRedBits(8);
22 setConfigGreenBits(8);
23 setConfigBlueBits(8);
24 setConfigAlphaBits(8);
25 setConfigDepthBits(24);
26 }
27
SetUp()28 void SetUp() override
29 {
30 ANGLETest::SetUp();
31
32 const std::string vsSource =
33 "#version 300 es\n"
34 "precision highp float;\n"
35 "in vec4 position;\n"
36 "in int expectedID;"
37 "out vec4 color;\n"
38 "\n"
39 "void main()\n"
40 "{\n"
41 " gl_Position = position;\n"
42 " color = vec4(gl_VertexID != expectedID, gl_VertexID == expectedID, 0.0, 1.0);"
43 "}\n";
44
45 const std::string fsSource =
46 "#version 300 es\n"
47 "precision highp float;\n"
48 "in vec4 color;\n"
49 "out vec4 fragColor;\n"
50 "void main()\n"
51 "{\n"
52 " fragColor = color;\n"
53 "}\n";
54
55 mProgram = CompileProgram(vsSource, fsSource);
56 ASSERT_NE(0u, mProgram);
57
58 mPositionLocation = glGetAttribLocation(mProgram, "position");
59 ASSERT_NE(-1, mPositionLocation);
60 mExpectedIdLocation = glGetAttribLocation(mProgram, "expectedID");
61 ASSERT_NE(-1, mExpectedIdLocation);
62
63 static const float positions[] =
64 {
65 0.5, 0.5,
66 -0.5, 0.5,
67 0.5, -0.5,
68 -0.5, -0.5
69 };
70 glGenBuffers(1, &mPositionBuffer);
71 glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer);
72 glBufferData(GL_ARRAY_BUFFER, sizeof(positions), positions, GL_STATIC_DRAW);
73
74 ASSERT_GL_NO_ERROR();
75 }
76
TearDown()77 void TearDown() override
78 {
79 glDeleteBuffers(1, &mPositionBuffer);
80 glDeleteBuffers(1, &mExpectedIdBuffer);
81 glDeleteBuffers(1, &mIndexBuffer);
82 glDeleteProgram(mProgram);
83
84 ANGLETest::TearDown();
85 }
86
87 // Renders a primitive using the specified mode, each vertex color will
88 // be green if gl_VertexID is correct, red otherwise.
runTest(GLuint drawMode,const std::vector<GLint> & indices,int count)89 void runTest(GLuint drawMode, const std::vector<GLint> &indices, int count)
90 {
91 glClearColor(0.0, 0.0, 0.0, 1.0);
92 glClear(GL_COLOR_BUFFER_BIT);
93
94 glGenBuffers(1, &mIndexBuffer);
95 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
96 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLint) * indices.size(), indices.data(),
97 GL_STATIC_DRAW);
98
99 std::vector<GLint> expectedIds = makeRange(count);
100
101 glGenBuffers(1, &mExpectedIdBuffer);
102 glBindBuffer(GL_ARRAY_BUFFER, mExpectedIdBuffer);
103 glBufferData(GL_ARRAY_BUFFER, sizeof(GLint) * expectedIds.size(), expectedIds.data(),
104 GL_STATIC_DRAW);
105
106 glBindBuffer(GL_ARRAY_BUFFER, mPositionBuffer);
107 glVertexAttribPointer(mPositionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
108 glEnableVertexAttribArray(mPositionLocation);
109
110 glBindBuffer(GL_ARRAY_BUFFER, mExpectedIdBuffer);
111 glVertexAttribIPointer(mExpectedIdLocation, 1, GL_INT, 0, 0);
112 glEnableVertexAttribArray(mExpectedIdLocation);
113
114 glUseProgram(mProgram);
115 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffer);
116 glDrawElements(drawMode, count, GL_UNSIGNED_INT, 0);
117
118 std::vector<GLColor> pixels(getWindowWidth() * getWindowHeight());
119 glReadPixels(0, 0, getWindowWidth(), getWindowHeight(), GL_RGBA, GL_UNSIGNED_BYTE,
120 pixels.data());
121
122 ASSERT_GL_NO_ERROR();
123
124 const GLColor green(0, 255, 0, 255);
125 const GLColor black(0, 0, 0, 255);
126
127 for (const auto &pixel : pixels)
128 {
129 EXPECT_TRUE(pixel == green || pixel == black);
130 }
131 }
132
makeRange(int n) const133 std::vector<GLint> makeRange(int n) const
134 {
135 std::vector<GLint> result;
136 for (int i = 0; i < n; i++)
137 {
138 result.push_back(i);
139 }
140
141 return result;
142 }
143
144 GLuint mPositionBuffer = 0;
145 GLuint mExpectedIdBuffer = 0;
146 GLuint mIndexBuffer = 0;
147
148 GLuint mProgram = 0;
149 GLint mPositionLocation = -1;
150 GLint mExpectedIdLocation = -1;
151 };
152
153 // Test gl_VertexID when rendering points
TEST_P(BuiltinVariableVertexIdTest,Points)154 TEST_P(BuiltinVariableVertexIdTest, Points)
155 {
156 runTest(GL_POINTS, makeRange(4), 4);
157 }
158
159 // Test gl_VertexID when rendering line strips
TEST_P(BuiltinVariableVertexIdTest,LineStrip)160 TEST_P(BuiltinVariableVertexIdTest, LineStrip)
161 {
162 runTest(GL_LINE_STRIP, makeRange(4), 4);
163 }
164
165 // Test gl_VertexID when rendering line loops
TEST_P(BuiltinVariableVertexIdTest,LineLoop)166 TEST_P(BuiltinVariableVertexIdTest, LineLoop)
167 {
168 runTest(GL_LINE_LOOP, makeRange(4), 4);
169 }
170
171 // Test gl_VertexID when rendering lines
TEST_P(BuiltinVariableVertexIdTest,Lines)172 TEST_P(BuiltinVariableVertexIdTest, Lines)
173 {
174 runTest(GL_LINES, makeRange(4), 4);
175 }
176
177 // Test gl_VertexID when rendering triangle strips
TEST_P(BuiltinVariableVertexIdTest,TriangleStrip)178 TEST_P(BuiltinVariableVertexIdTest, TriangleStrip)
179 {
180 runTest(GL_TRIANGLE_STRIP, makeRange(4), 4);
181 }
182
183 // Test gl_VertexID when rendering triangle fans
TEST_P(BuiltinVariableVertexIdTest,TriangleFan)184 TEST_P(BuiltinVariableVertexIdTest, TriangleFan)
185 {
186 std::vector<GLint> indices;
187 indices.push_back(0);
188 indices.push_back(1);
189 indices.push_back(3);
190 indices.push_back(2);
191 runTest(GL_TRIANGLE_FAN, indices, 4);
192 }
193
194 // Test gl_VertexID when rendering triangles
TEST_P(BuiltinVariableVertexIdTest,Triangles)195 TEST_P(BuiltinVariableVertexIdTest, Triangles)
196 {
197 std::vector<GLint> indices;
198 indices.push_back(0);
199 indices.push_back(1);
200 indices.push_back(2);
201 indices.push_back(1);
202 indices.push_back(2);
203 indices.push_back(3);
204 runTest(GL_TRIANGLES, indices, 6);
205 }
206
207 // Use this to select which configurations (e.g. which renderer, which GLES major version) these
208 // tests should be run against.
209 ANGLE_INSTANTIATE_TEST(BuiltinVariableVertexIdTest, ES3_D3D11(), ES3_OPENGL(), ES3_OPENGLES());
210