1 //
2 // Copyright 2015 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 // DrawElementsTest:
7 // Tests for indexed draws.
8 //
9
10 #include "test_utils/ANGLETest.h"
11
12 using namespace angle;
13
14 namespace
15 {
16
17 class DrawElementsTest : public ANGLETest
18 {
19 protected:
DrawElementsTest()20 DrawElementsTest() : mProgram(0u)
21 {
22 setWindowWidth(64);
23 setWindowHeight(64);
24 setConfigRedBits(8);
25 setConfigGreenBits(8);
26 }
27
~DrawElementsTest()28 ~DrawElementsTest()
29 {
30 for (GLuint indexBuffer : mIndexBuffers)
31 {
32 if (indexBuffer != 0)
33 {
34 glDeleteBuffers(1, &indexBuffer);
35 }
36 }
37
38 for (GLuint vertexArray : mVertexArrays)
39 {
40 if (vertexArray != 0)
41 {
42 glDeleteVertexArrays(1, &vertexArray);
43 }
44 }
45
46 for (GLuint vertexBuffer : mVertexBuffers)
47 {
48 if (vertexBuffer != 0)
49 {
50 glDeleteBuffers(1, &vertexBuffer);
51 }
52 }
53
54 if (mProgram != 0u)
55 {
56 glDeleteProgram(mProgram);
57 }
58 }
59
60 std::vector<GLuint> mIndexBuffers;
61 std::vector<GLuint> mVertexArrays;
62 std::vector<GLuint> mVertexBuffers;
63 GLuint mProgram;
64 };
65
66 // Test a state desync that can occur when using a streaming index buffer in GL in concert with
67 // deleting the applied index buffer.
TEST_P(DrawElementsTest,DeletingAfterStreamingIndexes)68 TEST_P(DrawElementsTest, DeletingAfterStreamingIndexes)
69 {
70 // Init program
71 const std::string &vertexShader =
72 "attribute vec2 position;\n"
73 "attribute vec2 testFlag;\n"
74 "varying vec2 v_data;\n"
75 "void main() {\n"
76 " gl_Position = vec4(position, 0, 1);\n"
77 " v_data = testFlag;\n"
78 "}";
79
80 const std::string &fragmentShader =
81 "varying highp vec2 v_data;\n"
82 "void main() {\n"
83 " gl_FragColor = vec4(v_data, 0, 1);\n"
84 "}";
85
86 mProgram = CompileProgram(vertexShader, fragmentShader);
87 ASSERT_NE(0u, mProgram);
88 glUseProgram(mProgram);
89
90 GLint positionLocation = glGetAttribLocation(mProgram, "position");
91 ASSERT_NE(-1, positionLocation);
92
93 GLint testFlagLocation = glGetAttribLocation(mProgram, "testFlag");
94 ASSERT_NE(-1, testFlagLocation);
95
96 mIndexBuffers.resize(3u);
97 glGenBuffers(3, &mIndexBuffers[0]);
98
99 mVertexArrays.resize(2);
100 glGenVertexArrays(2, &mVertexArrays[0]);
101
102 mVertexBuffers.resize(2);
103 glGenBuffers(2, &mVertexBuffers[0]);
104
105 std::vector<GLuint> indexData[2];
106 indexData[0].push_back(0);
107 indexData[0].push_back(1);
108 indexData[0].push_back(2);
109 indexData[0].push_back(2);
110 indexData[0].push_back(3);
111 indexData[0].push_back(0);
112
113 indexData[1] = indexData[0];
114 for (GLuint &item : indexData[1])
115 {
116 item += 4u;
117 }
118
119 std::vector<GLfloat> positionData;
120 // quad verts
121 positionData.push_back(-1.0f);
122 positionData.push_back(1.0f);
123 positionData.push_back(-1.0f);
124 positionData.push_back(-1.0f);
125 positionData.push_back(1.0f);
126 positionData.push_back(-1.0f);
127 positionData.push_back(1.0f);
128 positionData.push_back(1.0f);
129
130 // Repeat position data
131 positionData.push_back(-1.0f);
132 positionData.push_back(1.0f);
133 positionData.push_back(-1.0f);
134 positionData.push_back(-1.0f);
135 positionData.push_back(1.0f);
136 positionData.push_back(-1.0f);
137 positionData.push_back(1.0f);
138 positionData.push_back(1.0f);
139
140 std::vector<GLfloat> testFlagData;
141 // red
142 testFlagData.push_back(1.0f);
143 testFlagData.push_back(0.0f);
144 testFlagData.push_back(1.0f);
145 testFlagData.push_back(0.0f);
146 testFlagData.push_back(1.0f);
147 testFlagData.push_back(0.0f);
148 testFlagData.push_back(1.0f);
149 testFlagData.push_back(0.0f);
150
151 // green
152 testFlagData.push_back(0.0f);
153 testFlagData.push_back(1.0f);
154 testFlagData.push_back(0.0f);
155 testFlagData.push_back(1.0f);
156 testFlagData.push_back(0.0f);
157 testFlagData.push_back(1.0f);
158 testFlagData.push_back(0.0f);
159 testFlagData.push_back(1.0f);
160
161 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
162 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0],
163 GL_STATIC_DRAW);
164
165 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[2]);
166 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[0].size(), &indexData[0][0],
167 GL_STATIC_DRAW);
168
169 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]);
170 glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(GLuint) * indexData[1].size(), &indexData[1][0],
171 GL_STATIC_DRAW);
172
173 // Initialize first vertex array with second index buffer
174 glBindVertexArray(mVertexArrays[0]);
175
176 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[1]);
177 glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
178 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * positionData.size(), &positionData[0],
179 GL_STATIC_DRAW);
180 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
181 glEnableVertexAttribArray(positionLocation);
182
183 glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
184 glBufferData(GL_ARRAY_BUFFER, sizeof(GLfloat) * testFlagData.size(), &testFlagData[0],
185 GL_STATIC_DRAW);
186 glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
187 glEnableVertexAttribArray(testFlagLocation);
188
189 // Initialize second vertex array with first index buffer
190 glBindVertexArray(mVertexArrays[1]);
191
192 glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mIndexBuffers[0]);
193
194 glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[0]);
195 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
196 glEnableVertexAttribArray(positionLocation);
197
198 glBindBuffer(GL_ARRAY_BUFFER, mVertexBuffers[1]);
199 glVertexAttribPointer(testFlagLocation, 2, GL_FLOAT, GL_FALSE, sizeof(GLfloat) * 2, nullptr);
200 glEnableVertexAttribArray(testFlagLocation);
201
202 ASSERT_GL_NO_ERROR();
203
204 glBindVertexArray(mVertexArrays[0]);
205 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
206 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
207
208 glBindVertexArray(mVertexArrays[1]);
209 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
210 EXPECT_PIXEL_EQ(0, 0, 255, 0, 0, 255);
211
212 glBindVertexArray(mVertexArrays[0]);
213 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
214 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
215
216 // Trigger the bug here.
217 glDeleteBuffers(1, &mIndexBuffers[2]);
218
219 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
220 EXPECT_PIXEL_EQ(0, 0, 0, 255, 0, 255);
221
222 ASSERT_GL_NO_ERROR();
223 }
224
225 ANGLE_INSTANTIATE_TEST(DrawElementsTest, ES3_OPENGL(), ES3_OPENGLES());
226 }
227