1 //
2 // Copyright 2017 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
7 // ProgramInterfaceTest: Tests of program interfaces.
8
9 #include "common/string_utils.h"
10 #include "test_utils/ANGLETest.h"
11 #include "test_utils/gl_raii.h"
12
13 using namespace angle;
14
15 namespace
16 {
17
18 // Variations:
19 //
20 // - bool: whether the program must be created and recreated, so that it's reloaded from cache.
21 using ProgramInterfaceTestParams = std::tuple<angle::PlatformParameters, bool>;
22
ProgramInterfaceTestPrint(const::testing::TestParamInfo<ProgramInterfaceTestParams> & paramsInfo)23 std::string ProgramInterfaceTestPrint(
24 const ::testing::TestParamInfo<ProgramInterfaceTestParams> ¶msInfo)
25 {
26 const ProgramInterfaceTestParams ¶ms = paramsInfo.param;
27 std::ostringstream out;
28
29 out << std::get<0>(params);
30
31 if (std::get<1>(params))
32 {
33 out << "__cached";
34 }
35
36 return out.str();
37 }
38
39 class ProgramInterfaceTestES31 : public ANGLETestWithParam<ProgramInterfaceTestParams>
40 {
41 protected:
ProgramInterfaceTestES31()42 ProgramInterfaceTestES31()
43 {
44 setWindowWidth(64);
45 setWindowHeight(64);
46 setConfigRedBits(8);
47 setConfigGreenBits(8);
48 setConfigBlueBits(8);
49 setConfigAlphaBits(8);
50 }
51
52 void createGraphicsProgram(GLProgram &program,
53 const char *vs,
54 const char *fs,
55 bool cacheAndReload);
56 void createComputeProgram(GLProgram &program, const char *cs, bool cacheAndReload);
57 };
58
createGraphicsProgram(GLProgram & program,const char * vs,const char * fs,bool cacheAndReload)59 void ProgramInterfaceTestES31::createGraphicsProgram(GLProgram &program,
60 const char *vs,
61 const char *fs,
62 bool cacheAndReload)
63 {
64 program.makeRaster(vs, fs);
65 ASSERT_TRUE(program.valid());
66
67 if (cacheAndReload)
68 {
69 program.reset();
70 program.makeRaster(vs, fs);
71 ASSERT_TRUE(program.valid());
72 }
73 }
74
createComputeProgram(GLProgram & program,const char * cs,bool cacheAndReload)75 void ProgramInterfaceTestES31::createComputeProgram(GLProgram &program,
76 const char *cs,
77 bool cacheAndReload)
78 {
79 program.makeCompute(cs);
80 ASSERT_TRUE(program.valid());
81
82 if (cacheAndReload)
83 {
84 program.reset();
85 program.makeCompute(cs);
86 ASSERT_TRUE(program.valid());
87 }
88 }
89
90 // Tests glGetProgramResourceIndex.
TEST_P(ProgramInterfaceTestES31,GetResourceIndex)91 TEST_P(ProgramInterfaceTestES31, GetResourceIndex)
92 {
93 constexpr char kFS[] =
94 "#version 310 es\n"
95 "precision highp float;\n"
96 "uniform vec4 color;\n"
97 "out vec4 oColor;\n"
98 "void main()\n"
99 "{\n"
100 " oColor = color;\n"
101 "}";
102
103 GLProgram program;
104 createGraphicsProgram(program, essl31_shaders::vs::Simple(), kFS, std::get<1>(GetParam()));
105
106 GLuint index =
107 glGetProgramResourceIndex(program, GL_PROGRAM_INPUT, essl31_shaders::PositionAttrib());
108 EXPECT_GL_NO_ERROR();
109 EXPECT_NE(GL_INVALID_INDEX, index);
110
111 index = glGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "missing");
112 EXPECT_GL_NO_ERROR();
113 EXPECT_EQ(GL_INVALID_INDEX, index);
114
115 index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "oColor");
116 EXPECT_GL_NO_ERROR();
117 EXPECT_NE(GL_INVALID_INDEX, index);
118
119 index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "missing");
120 EXPECT_GL_NO_ERROR();
121 EXPECT_EQ(GL_INVALID_INDEX, index);
122
123 index = glGetProgramResourceIndex(program, GL_ATOMIC_COUNTER_BUFFER, "missing");
124 EXPECT_GL_ERROR(GL_INVALID_ENUM);
125 }
126
127 // Tests glGetProgramResourceName.
TEST_P(ProgramInterfaceTestES31,GetResourceName)128 TEST_P(ProgramInterfaceTestES31, GetResourceName)
129 {
130 constexpr char kFS[] =
131 "#version 310 es\n"
132 "precision highp float;\n"
133 "uniform vec4 color;\n"
134 "out vec4 oColor[4];\n"
135 "void main()\n"
136 "{\n"
137 " oColor[0] = color;\n"
138 "}";
139
140 GLProgram program;
141 createGraphicsProgram(program, essl31_shaders::vs::Simple(), kFS, std::get<1>(GetParam()));
142
143 GLuint index =
144 glGetProgramResourceIndex(program, GL_PROGRAM_INPUT, essl31_shaders::PositionAttrib());
145 EXPECT_GL_NO_ERROR();
146 EXPECT_NE(GL_INVALID_INDEX, index);
147
148 GLchar name[64];
149 GLsizei length;
150 glGetProgramResourceName(program, GL_PROGRAM_INPUT, index, sizeof(name), &length, name);
151 EXPECT_GL_NO_ERROR();
152 EXPECT_EQ(static_cast<int>(strlen(essl31_shaders::PositionAttrib())), length);
153 EXPECT_EQ(essl31_shaders::PositionAttrib(), std::string(name));
154
155 glGetProgramResourceName(program, GL_PROGRAM_INPUT, index, 4, &length, name);
156 EXPECT_GL_NO_ERROR();
157 EXPECT_EQ(3, length);
158 EXPECT_TRUE(angle::BeginsWith(essl31_shaders::PositionAttrib(), name));
159
160 glGetProgramResourceName(program, GL_PROGRAM_INPUT, index, -1, &length, name);
161 EXPECT_GL_ERROR(GL_INVALID_VALUE);
162
163 glGetProgramResourceName(program, GL_PROGRAM_INPUT, GL_INVALID_INDEX, sizeof(name), &length,
164 name);
165 EXPECT_GL_ERROR(GL_INVALID_VALUE);
166
167 index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "oColor");
168 EXPECT_GL_NO_ERROR();
169 EXPECT_NE(GL_INVALID_INDEX, index);
170
171 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, index, sizeof(name), &length, name);
172 EXPECT_GL_NO_ERROR();
173 EXPECT_EQ(9, length);
174 EXPECT_EQ("oColor[0]", std::string(name));
175
176 glGetProgramResourceName(program, GL_PROGRAM_OUTPUT, index, 8, &length, name);
177 EXPECT_GL_NO_ERROR();
178 EXPECT_EQ(7, length);
179 EXPECT_EQ("oColor[", std::string(name));
180 }
181
182 // Tests glGetProgramResourceLocation.
TEST_P(ProgramInterfaceTestES31,GetResourceLocation)183 TEST_P(ProgramInterfaceTestES31, GetResourceLocation)
184 {
185 // http://anglebug.com/4092
186 ANGLE_SKIP_TEST_IF(isSwiftshader());
187 constexpr char kVS[] =
188 "#version 310 es\n"
189 "precision highp float;\n"
190 "layout(location = 3) in highp vec4 position;\n"
191 "in highp vec4 noLocationSpecified;\n"
192 "void main()\n"
193 "{\n"
194 " gl_Position = position;\n"
195 "}";
196
197 constexpr char kFS[] =
198 "#version 310 es\n"
199 "precision highp float;\n"
200 "uniform vec4 color;\n"
201 "layout(location = 2) out vec4 oColor[4];\n"
202 "void main()\n"
203 "{\n"
204 " oColor[0] = color;\n"
205 "}";
206
207 GLProgram program;
208 createGraphicsProgram(program, kVS, kFS, std::get<1>(GetParam()));
209
210 GLenum invalidInterfaces[] = {GL_UNIFORM_BLOCK, GL_TRANSFORM_FEEDBACK_VARYING,
211 GL_BUFFER_VARIABLE, GL_SHADER_STORAGE_BLOCK,
212 GL_ATOMIC_COUNTER_BUFFER};
213 GLint location;
214 for (auto &invalidInterface : invalidInterfaces)
215 {
216 location = glGetProgramResourceLocation(program, invalidInterface, "any");
217 EXPECT_GL_ERROR(GL_INVALID_ENUM);
218 EXPECT_EQ(-1, location);
219 }
220
221 location = glGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "position");
222 EXPECT_GL_NO_ERROR();
223 EXPECT_EQ(3, location);
224
225 location = glGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "noLocationSpecified");
226 EXPECT_GL_NO_ERROR();
227 EXPECT_EQ(-1, location);
228
229 location = glGetProgramResourceLocation(program, GL_PROGRAM_INPUT, "missing");
230 EXPECT_GL_NO_ERROR();
231 EXPECT_EQ(-1, location);
232
233 location = glGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "oColor");
234 EXPECT_GL_NO_ERROR();
235 EXPECT_EQ(2, location);
236 location = glGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "oColor[0]");
237 EXPECT_GL_NO_ERROR();
238 EXPECT_EQ(2, location);
239 location = glGetProgramResourceLocation(program, GL_PROGRAM_OUTPUT, "oColor[3]");
240 EXPECT_GL_NO_ERROR();
241 EXPECT_EQ(5, location);
242 }
243
244 // Tests glGetProgramResource.
TEST_P(ProgramInterfaceTestES31,GetResource)245 TEST_P(ProgramInterfaceTestES31, GetResource)
246 {
247 // http://anglebug.com/4092
248 ANGLE_SKIP_TEST_IF(isSwiftshader());
249 constexpr char kVS[] =
250 "#version 310 es\n"
251 "precision highp float;\n"
252 "layout(location = 3) in highp vec4 position;\n"
253 "void main()\n"
254 "{\n"
255 " gl_Position = position;\n"
256 "}";
257
258 constexpr char kFS[] =
259 "#version 310 es\n"
260 "precision highp float;\n"
261 "uniform vec4 color;\n"
262 "layout(location = 2) out vec4 oColor[4];\n"
263 "void main()\n"
264 "{\n"
265 " oColor[0] = color;\n"
266 "}";
267
268 GLProgram program;
269 createGraphicsProgram(program, kVS, kFS, std::get<1>(GetParam()));
270
271 GLuint index = glGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position");
272 EXPECT_GL_NO_ERROR();
273 EXPECT_NE(GL_INVALID_INDEX, index);
274
275 GLenum props[] = {GL_TYPE,
276 GL_ARRAY_SIZE,
277 GL_LOCATION,
278 GL_NAME_LENGTH,
279 GL_REFERENCED_BY_VERTEX_SHADER,
280 GL_REFERENCED_BY_FRAGMENT_SHADER,
281 GL_REFERENCED_BY_COMPUTE_SHADER};
282 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
283 GLint params[ArraySize(props)];
284 GLsizei length;
285
286 glGetProgramResourceiv(program, GL_PROGRAM_INPUT, index, propCount, props, propCount, &length,
287 params);
288 EXPECT_GL_NO_ERROR();
289 EXPECT_EQ(propCount, length);
290 EXPECT_EQ(GL_FLOAT_VEC4, params[0]); // type
291 EXPECT_EQ(1, params[1]); // array_size
292 EXPECT_EQ(3, params[2]); // location
293 EXPECT_EQ(9, params[3]); // name_length
294 EXPECT_EQ(1, params[4]); // referenced_by_vertex_shader
295 EXPECT_EQ(0, params[5]); // referenced_by_fragment_shader
296 EXPECT_EQ(0, params[6]); // referenced_by_compute_shader
297
298 index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "oColor[0]");
299 EXPECT_GL_NO_ERROR();
300 EXPECT_NE(index, GL_INVALID_INDEX);
301 // bufSize is smaller than propCount.
302 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, propCount, props, propCount - 1,
303 &length, params);
304 EXPECT_GL_NO_ERROR();
305 EXPECT_EQ(propCount - 1, length);
306 EXPECT_EQ(GL_FLOAT_VEC4, params[0]); // type
307 EXPECT_EQ(4, params[1]); // array_size
308 EXPECT_EQ(2, params[2]); // location
309 EXPECT_EQ(10, params[3]); // name_length
310 EXPECT_EQ(0, params[4]); // referenced_by_vertex_shader
311 EXPECT_EQ(1, params[5]); // referenced_by_fragment_shader
312
313 GLenum invalidOutputProp = GL_OFFSET;
314 glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, 1, &invalidOutputProp, 1, &length,
315 params);
316 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
317 }
318
319 // Tests glGetProgramInterfaceiv.
TEST_P(ProgramInterfaceTestES31,GetProgramInterface)320 TEST_P(ProgramInterfaceTestES31, GetProgramInterface)
321 {
322 // TODO(jiajia.qin@intel.com): Don't skip this test once SSBO are supported on render pipeline.
323 // http://anglebug.com/1951
324 ANGLE_SKIP_TEST_IF(IsD3D11());
325
326 constexpr char kFS[] =
327 "#version 310 es\n"
328 "precision highp float;\n"
329 "uniform vec4 color;\n"
330 "out vec4 oColor;\n"
331 "uniform ub {\n"
332 " vec4 mem0;\n"
333 " vec4 mem1;\n"
334 "} instance;\n"
335 "layout(std430) buffer shaderStorageBlock1 {\n"
336 " vec3 target;\n"
337 "};\n"
338 "layout(std430) buffer shaderStorageBlock2 {\n"
339 " vec3 target;\n"
340 "} blockInstance2[1];\n"
341 "void main()\n"
342 "{\n"
343 " oColor = color;\n"
344 " target = vec3(0, 0, 0);\n"
345 " blockInstance2[0].target = vec3(1, 1, 1);\n"
346 "}";
347
348 GLProgram program;
349 createGraphicsProgram(program, essl31_shaders::vs::Simple(), kFS, std::get<1>(GetParam()));
350
351 GLint num;
352 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_ACTIVE_RESOURCES, &num);
353 EXPECT_GL_NO_ERROR();
354 EXPECT_EQ(1, num);
355
356 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NAME_LENGTH, &num);
357 EXPECT_GL_NO_ERROR();
358 EXPECT_EQ(static_cast<GLint>(strlen(essl3_shaders::PositionAttrib())) + 1, num);
359
360 glGetProgramInterfaceiv(program, GL_PROGRAM_INPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &num);
361 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
362
363 glGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_ACTIVE_RESOURCES, &num);
364 EXPECT_GL_NO_ERROR();
365 EXPECT_EQ(1, num);
366
367 glGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NAME_LENGTH, &num);
368 EXPECT_GL_NO_ERROR();
369 EXPECT_EQ(7, num);
370
371 glGetProgramInterfaceiv(program, GL_PROGRAM_OUTPUT, GL_MAX_NUM_ACTIVE_VARIABLES, &num);
372 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
373
374 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_ACTIVE_RESOURCES, &num);
375 EXPECT_GL_NO_ERROR();
376 EXPECT_EQ(1, num);
377
378 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NAME_LENGTH, &num);
379 EXPECT_GL_NO_ERROR();
380 EXPECT_EQ(3, num);
381
382 glGetProgramInterfaceiv(program, GL_UNIFORM_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &num);
383 EXPECT_GL_NO_ERROR();
384 EXPECT_EQ(2, num); // mem0, mem1
385
386 glGetProgramInterfaceiv(program, GL_UNIFORM, GL_ACTIVE_RESOURCES, &num);
387 EXPECT_GL_NO_ERROR();
388 EXPECT_EQ(3, num);
389
390 glGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NAME_LENGTH, &num);
391 EXPECT_GL_NO_ERROR();
392 EXPECT_EQ(8, num); // "ub.mem0"
393
394 glGetProgramInterfaceiv(program, GL_UNIFORM, GL_MAX_NUM_ACTIVE_VARIABLES, &num);
395 EXPECT_GL_ERROR(GL_INVALID_OPERATION);
396
397 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_ACTIVE_RESOURCES, &num);
398 EXPECT_GL_NO_ERROR();
399 EXPECT_EQ(2, num);
400
401 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NAME_LENGTH, &num);
402 EXPECT_GL_NO_ERROR();
403 EXPECT_EQ(23, num); // "shaderStorageBlock2[0]"
404
405 glGetProgramInterfaceiv(program, GL_SHADER_STORAGE_BLOCK, GL_MAX_NUM_ACTIVE_VARIABLES, &num);
406 EXPECT_GL_NO_ERROR();
407 EXPECT_EQ(1, num);
408 }
409
410 // Tests the resource property query for uniform can be done correctly.
TEST_P(ProgramInterfaceTestES31,GetUniformProperties)411 TEST_P(ProgramInterfaceTestES31, GetUniformProperties)
412 {
413 // Check atomic support.
414 GLint numSupported;
415 glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &numSupported);
416 EXPECT_GL_NO_ERROR();
417 ANGLE_SKIP_TEST_IF(numSupported < 1);
418
419 constexpr char kVS[] =
420 "#version 310 es\n"
421 "precision highp float;\n"
422 "uniform layout(location=12) vec4 color;\n"
423 "layout(binding = 2, offset = 4) uniform atomic_uint foo;\n"
424 "void main()\n"
425 "{\n"
426 " atomicCounterIncrement(foo);\n"
427 "}";
428
429 constexpr char kFS[] =
430 "#version 310 es\n"
431 "precision highp float;\n"
432 "uniform vec4 color;\n"
433 "out vec4 oColor;\n"
434 "void main()\n"
435 "{\n"
436 " oColor = color;\n"
437 "}";
438
439 GLProgram program;
440 createGraphicsProgram(program, kVS, kFS, std::get<1>(GetParam()));
441
442 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "color");
443 EXPECT_GL_NO_ERROR();
444 EXPECT_NE(GL_INVALID_INDEX, index);
445
446 GLchar name[64];
447 GLsizei length;
448 glGetProgramResourceName(program, GL_UNIFORM, index, sizeof(name), &length, name);
449 EXPECT_GL_NO_ERROR();
450 EXPECT_EQ(5, length);
451 EXPECT_EQ("color", std::string(name));
452
453 GLint location = glGetProgramResourceLocation(program, GL_UNIFORM, "color");
454 EXPECT_GL_NO_ERROR();
455 EXPECT_EQ(12, location);
456
457 GLenum props[] = {GL_TYPE,
458 GL_ARRAY_SIZE,
459 GL_LOCATION,
460 GL_NAME_LENGTH,
461 GL_REFERENCED_BY_VERTEX_SHADER,
462 GL_REFERENCED_BY_FRAGMENT_SHADER,
463 GL_REFERENCED_BY_COMPUTE_SHADER,
464 GL_ARRAY_STRIDE,
465 GL_BLOCK_INDEX,
466 GL_IS_ROW_MAJOR,
467 GL_MATRIX_STRIDE,
468 GL_OFFSET,
469 GL_ATOMIC_COUNTER_BUFFER_INDEX};
470 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
471 GLint params[ArraySize(props)];
472 glGetProgramResourceiv(program, GL_UNIFORM, index, propCount, props, propCount, &length,
473 params);
474 EXPECT_GL_NO_ERROR();
475 EXPECT_EQ(propCount, length);
476 EXPECT_EQ(GL_FLOAT_VEC4, params[0]); // type
477 EXPECT_EQ(1, params[1]); // array_size
478 EXPECT_EQ(12, params[2]); // location
479 EXPECT_EQ(6, params[3]); // name_length
480 EXPECT_EQ(0, params[4]); // referenced_by_vertex_shader
481 EXPECT_EQ(1, params[5]); // referenced_by_fragment_shader
482 EXPECT_EQ(0, params[6]); // referenced_by_compute_shader
483 EXPECT_EQ(-1, params[7]); // array_stride
484 EXPECT_EQ(-1, params[8]); // block_index
485 EXPECT_EQ(0, params[9]); // is_row_major
486 EXPECT_EQ(-1, params[10]); // matrix_stride
487 EXPECT_EQ(-1, params[11]); // offset
488 EXPECT_EQ(-1, params[12]); // atomic_counter_buffer_index
489
490 index = glGetProgramResourceIndex(program, GL_UNIFORM, "foo");
491 EXPECT_GL_NO_ERROR();
492 EXPECT_NE(GL_INVALID_INDEX, index);
493
494 glGetProgramResourceName(program, GL_UNIFORM, index, sizeof(name), &length, name);
495 EXPECT_GL_NO_ERROR();
496 EXPECT_EQ(3, length);
497 EXPECT_EQ("foo", std::string(name));
498
499 location = glGetProgramResourceLocation(program, GL_UNIFORM, "foo");
500 EXPECT_GL_NO_ERROR();
501 EXPECT_EQ(-1, location);
502
503 glGetProgramResourceiv(program, GL_UNIFORM, index, propCount, props, propCount, &length,
504 params);
505 EXPECT_GL_NO_ERROR();
506 EXPECT_EQ(propCount, length);
507 EXPECT_EQ(GL_UNSIGNED_INT_ATOMIC_COUNTER, params[0]); // type
508 EXPECT_EQ(1, params[1]); // array_size
509 EXPECT_EQ(-1, params[2]); // location
510 EXPECT_EQ(4, params[3]); // name_length
511 EXPECT_EQ(1, params[4]); // referenced_by_vertex_shader
512 EXPECT_EQ(0, params[5]); // referenced_by_fragment_shader
513 EXPECT_EQ(0, params[6]); // referenced_by_compute_shader
514 EXPECT_EQ(0, params[7]); // array_stride
515 EXPECT_EQ(-1, params[8]); // block_index
516 EXPECT_EQ(0, params[9]); // is_row_major
517 EXPECT_EQ(0, params[10]); // matrix_stride
518 EXPECT_EQ(4, params[11]); // offset
519 EXPECT_NE(-1, params[12]); // atomic_counter_buffer_index
520 }
521
522 // Tests the resource property query for uniform block can be done correctly.
TEST_P(ProgramInterfaceTestES31,GetUniformBlockProperties)523 TEST_P(ProgramInterfaceTestES31, GetUniformBlockProperties)
524 {
525 constexpr char kVS[] =
526 "#version 310 es\n"
527 "in vec2 position;\n"
528 "out vec2 v;\n"
529 "layout(binding = 2) uniform blockName {\n"
530 " float f1;\n"
531 " float f2;\n"
532 "} instanceName;\n"
533 "void main() {\n"
534 " v = vec2(instanceName.f1, instanceName.f2);\n"
535 " gl_Position = vec4(position, 0, 1);\n"
536 "}";
537
538 constexpr char kFS[] =
539 "#version 310 es\n"
540 "precision highp float;\n"
541 "in vec2 v;\n"
542 "out vec4 color;\n"
543 "void main() {\n"
544 " color = vec4(v, 0, 1);\n"
545 "}";
546
547 GLProgram program;
548 createGraphicsProgram(program, kVS, kFS, std::get<1>(GetParam()));
549
550 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, "blockName");
551 EXPECT_GL_NO_ERROR();
552 EXPECT_NE(GL_INVALID_INDEX, index);
553
554 GLchar name[64];
555 GLsizei length;
556 glGetProgramResourceName(program, GL_UNIFORM_BLOCK, index, sizeof(name), &length, name);
557 EXPECT_GL_NO_ERROR();
558 EXPECT_EQ(9, length);
559 EXPECT_EQ("blockName", std::string(name));
560
561 GLenum props[] = {GL_BUFFER_BINDING,
562 GL_BUFFER_DATA_SIZE,
563 GL_NAME_LENGTH,
564 GL_NUM_ACTIVE_VARIABLES,
565 GL_ACTIVE_VARIABLES,
566 GL_REFERENCED_BY_VERTEX_SHADER,
567 GL_REFERENCED_BY_FRAGMENT_SHADER,
568 GL_REFERENCED_BY_COMPUTE_SHADER};
569 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
570 constexpr int kBufSize = 256;
571 GLint params[kBufSize];
572 GLint magic = 0xBEEF;
573
574 // Tests bufSize is respected even some prop returns more than one value.
575 params[propCount] = magic;
576 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, index, propCount, props, propCount, &length,
577 params);
578 EXPECT_GL_NO_ERROR();
579 EXPECT_EQ(propCount, length);
580 EXPECT_EQ(2, params[0]); // buffer_binding
581 EXPECT_NE(0, params[1]); // buffer_data_size
582 EXPECT_EQ(10, params[2]); // name_length
583 EXPECT_EQ(2, params[3]); // num_active_variables
584 EXPECT_LE(0, params[4]); // index of 'f1' or 'f2'
585 EXPECT_LE(0, params[5]); // index of 'f1' or 'f2'
586 EXPECT_EQ(1, params[6]); // referenced_by_vertex_shader
587 EXPECT_EQ(0, params[7]); // referenced_by_fragment_shader
588 EXPECT_EQ(magic, params[8]);
589
590 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, index, propCount, props, kBufSize, &length,
591 params);
592 EXPECT_GL_NO_ERROR();
593 EXPECT_EQ(propCount + 1, length);
594 EXPECT_EQ(0, params[8]); // referenced_by_compute_shader
595
596 // bufSize is reached in middle of outputting values for GL_ACTIVE_VARIABLES.
597 GLenum actvieVariablesProperty = GL_ACTIVE_VARIABLES;
598 params[1] = magic;
599 glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, index, 1, &actvieVariablesProperty, 1,
600 &length, params);
601 EXPECT_GL_NO_ERROR();
602 EXPECT_EQ(1, length);
603 EXPECT_LE(0, params[0]); // index of 'f1' or 'f2'
604 EXPECT_EQ(magic, params[1]);
605 }
606
607 // Tests atomic counter buffer qeury works correctly.
TEST_P(ProgramInterfaceTestES31,QueryAtomicCounteBuffer)608 TEST_P(ProgramInterfaceTestES31, QueryAtomicCounteBuffer)
609 {
610 // Check atomic support.
611 GLint numSupportedInVertex;
612 GLint numSupportedInFragment;
613 glGetIntegerv(GL_MAX_VERTEX_ATOMIC_COUNTERS, &numSupportedInVertex);
614 glGetIntegerv(GL_MAX_FRAGMENT_ATOMIC_COUNTERS, &numSupportedInFragment);
615 EXPECT_GL_NO_ERROR();
616 ANGLE_SKIP_TEST_IF(numSupportedInVertex < 1 || numSupportedInFragment < 1);
617
618 constexpr char kVS[] =
619 "#version 310 es\n"
620 "precision highp float;\n"
621 "layout(binding = 2, offset = 0) uniform atomic_uint vcounter;\n"
622 "in highp vec4 a_position;\n"
623 "void main()\n"
624 "{\n"
625 " atomicCounterIncrement(vcounter);\n"
626 " gl_Position = a_position;\n"
627 "}\n";
628
629 constexpr char kFS[] =
630 "#version 310 es\n"
631 "precision highp float;\n"
632 "layout(binding = 2, offset = 4) uniform atomic_uint fcounter;\n"
633 "out highp vec4 my_color;\n"
634 "void main()\n"
635 "{\n"
636 " atomicCounterDecrement(fcounter);\n"
637 " my_color = vec4(0.0);\n"
638 "}\n";
639
640 GLProgram program;
641 createGraphicsProgram(program, kVS, kFS, std::get<1>(GetParam()));
642
643 GLint num;
644 glGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_ACTIVE_RESOURCES, &num);
645 EXPECT_GL_NO_ERROR();
646 EXPECT_EQ(1, num);
647
648 glGetProgramInterfaceiv(program, GL_ATOMIC_COUNTER_BUFFER, GL_MAX_NUM_ACTIVE_VARIABLES, &num);
649 EXPECT_GL_NO_ERROR();
650 EXPECT_EQ(2, num);
651
652 GLenum props[] = {GL_BUFFER_BINDING, GL_NUM_ACTIVE_VARIABLES, GL_REFERENCED_BY_VERTEX_SHADER,
653 GL_REFERENCED_BY_FRAGMENT_SHADER, GL_REFERENCED_BY_COMPUTE_SHADER};
654 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
655 GLint params[ArraySize(props)];
656 GLsizei length = 0;
657 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, 0, propCount, props, propCount,
658 &length, params);
659 EXPECT_GL_NO_ERROR();
660 EXPECT_EQ(propCount, length);
661 EXPECT_EQ(2, params[0]); // buffer_binding
662 EXPECT_EQ(2, params[1]); // num_active_variables
663 EXPECT_EQ(1, params[2]); // referenced_by_vertex_shader
664 EXPECT_EQ(1, params[3]); // referenced_by_fragment_shader
665 EXPECT_EQ(0, params[4]); // referenced_by_compute_shader
666 }
667
668 // Tests the resource property query for buffer variable can be done correctly.
TEST_P(ProgramInterfaceTestES31,GetBufferVariableProperties)669 TEST_P(ProgramInterfaceTestES31, GetBufferVariableProperties)
670 {
671 // TODO(jiajia.qin@intel.com): Don't skip this test once non-simple SSBO sentences are supported
672 // on d3d backend. http://anglebug.com/1951
673 ANGLE_SKIP_TEST_IF(IsD3D11());
674
675 // Check SSBO support
676 GLint numSupported;
677 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &numSupported);
678 EXPECT_GL_NO_ERROR();
679 ANGLE_SKIP_TEST_IF(numSupported < 2);
680
681 constexpr char kVS[] =
682 "#version 310 es\n"
683 "precision highp float;\n"
684 "struct S {\n"
685 " vec3 a;\n"
686 " ivec2 b[4];\n"
687 "};\n"
688 "layout(std140) buffer blockName0 {\n"
689 " S s0;\n"
690 " vec2 v0;\n"
691 " S s1[2];\n"
692 " uint u0;\n"
693 "};\n"
694 "layout(binding = 1) buffer blockName1 {\n"
695 " uint u1[2];\n"
696 " float f1;\n"
697 "} instanceName1[2];\n"
698 "void main()\n"
699 "{\n"
700 " gl_Position = vec4(instanceName1[0].f1, s1[0].a);\n"
701 "}\n";
702
703 constexpr char kFS[] =
704 "#version 310 es\n"
705 "precision highp float;\n"
706 "layout(binding = 1) buffer blockName1 {\n"
707 " uint u1[2];\n"
708 " float f1;\n"
709 "} instanceName1[2];\n"
710 "out vec4 oColor;\n"
711 "void main()\n"
712 "{\n"
713 " oColor = vec4(instanceName1[0].f1, 0, 0, 1);\n"
714 "}";
715
716 GLProgram program;
717 createGraphicsProgram(program, kVS, kFS, std::get<1>(GetParam()));
718
719 GLuint index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "blockName1.f1");
720 EXPECT_GL_NO_ERROR();
721 EXPECT_NE(GL_INVALID_INDEX, index);
722
723 GLchar name[64];
724 GLsizei length;
725 glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
726 EXPECT_GL_NO_ERROR();
727 EXPECT_EQ(13, length);
728 EXPECT_EQ("blockName1.f1", std::string(name));
729
730 GLenum props[] = {GL_ARRAY_SIZE,
731 GL_ARRAY_STRIDE,
732 GL_BLOCK_INDEX,
733 GL_IS_ROW_MAJOR,
734 GL_MATRIX_STRIDE,
735 GL_NAME_LENGTH,
736 GL_OFFSET,
737 GL_REFERENCED_BY_VERTEX_SHADER,
738 GL_REFERENCED_BY_FRAGMENT_SHADER,
739 GL_REFERENCED_BY_COMPUTE_SHADER,
740 GL_TOP_LEVEL_ARRAY_SIZE,
741 GL_TOP_LEVEL_ARRAY_STRIDE,
742 GL_TYPE};
743 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
744 constexpr int kBufSize = 256;
745 GLint params[kBufSize];
746
747 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
748 params);
749 EXPECT_GL_NO_ERROR();
750 EXPECT_EQ(propCount, length);
751 EXPECT_EQ(1, params[0]); // array_size
752 EXPECT_LE(0, params[1]); // array_stride
753 EXPECT_LE(0, params[2]); // block_index
754 EXPECT_EQ(0, params[3]); // is_row_major
755 EXPECT_EQ(0, params[4]); // matrix_stride
756 EXPECT_EQ(14, params[5]); // name_length
757 EXPECT_LE(0, params[6]); // offset
758
759 EXPECT_EQ(1, params[7]); // referenced_by_vertex_shader
760 EXPECT_EQ(1, params[8]); // referenced_by_fragment_shader
761 EXPECT_EQ(0, params[9]); // referenced_by_compute_shader
762
763 EXPECT_EQ(1, params[10]); // top_level_array_size
764 EXPECT_LE(0, params[11]); // top_level_array_stride
765
766 EXPECT_EQ(GL_FLOAT, params[12]); // type
767
768 index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "s1[0].a");
769 EXPECT_GL_NO_ERROR();
770 EXPECT_NE(GL_INVALID_INDEX, index);
771
772 glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
773 EXPECT_GL_NO_ERROR();
774 EXPECT_EQ(7, length);
775 EXPECT_EQ("s1[0].a", std::string(name));
776
777 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
778 params);
779 EXPECT_GL_NO_ERROR();
780 EXPECT_EQ(propCount, length);
781 EXPECT_EQ(1, params[0]); // array_size
782 EXPECT_LE(0, params[1]); // array_stride
783 EXPECT_LE(0, params[2]); // block_index
784 EXPECT_EQ(0, params[3]); // is_row_major
785 EXPECT_EQ(0, params[4]); // matrix_stride
786 EXPECT_EQ(8, params[5]); // name_length
787 EXPECT_LE(0, params[6]); // offset
788
789 EXPECT_EQ(1, params[7]); // referenced_by_vertex_shader
790 EXPECT_EQ(0, params[8]); // referenced_by_fragment_shader
791 EXPECT_EQ(0, params[9]); // referenced_by_compute_shader
792
793 EXPECT_EQ(2, params[10]); // top_level_array_size
794 EXPECT_EQ(80, params[11]); // top_level_array_stride
795
796 EXPECT_EQ(GL_FLOAT_VEC3, params[12]); // type
797 }
798
799 // Tests the resource property querying for buffer variable in std430 SSBO works correctly.
TEST_P(ProgramInterfaceTestES31,GetStd430BufferVariableProperties)800 TEST_P(ProgramInterfaceTestES31, GetStd430BufferVariableProperties)
801 {
802 ANGLE_SKIP_TEST_IF(IsAMD() && IsWindows() && IsOpenGL());
803
804 constexpr char kComputeShaderSource[] =
805 R"(#version 310 es
806 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
807 struct S
808 {
809 uvec2 v;
810 mat2 m;
811 };
812 layout(std430, binding = 0) buffer blockIn {
813 uint u;
814 uint a[2];
815 S s;
816 } instanceIn;
817 layout(std430, binding = 1) buffer blockOut {
818 uint u;
819 uint a[2];
820 S s;
821 } instanceOut;
822 void main()
823 {
824 instanceOut.u = instanceIn.u;
825 instanceOut.a[0] = instanceIn.a[0];
826 instanceOut.a[1] = instanceIn.a[1];
827 instanceOut.s.v = instanceIn.s.v;
828 instanceOut.s.m = instanceIn.s.m;
829 }
830 )";
831
832 GLProgram program;
833 createComputeProgram(program, kComputeShaderSource, std::get<1>(GetParam()));
834
835 GLuint index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "blockIn.a");
836 EXPECT_GL_NO_ERROR();
837 EXPECT_NE(GL_INVALID_INDEX, index);
838
839 GLchar name[64];
840 GLsizei length;
841 glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
842 EXPECT_GL_NO_ERROR();
843 EXPECT_EQ(12, length);
844 EXPECT_EQ("blockIn.a[0]", std::string(name));
845
846 GLenum props[] = {GL_ARRAY_SIZE,
847 GL_ARRAY_STRIDE,
848 GL_BLOCK_INDEX,
849 GL_IS_ROW_MAJOR,
850 GL_MATRIX_STRIDE,
851 GL_NAME_LENGTH,
852 GL_OFFSET,
853 GL_REFERENCED_BY_VERTEX_SHADER,
854 GL_REFERENCED_BY_FRAGMENT_SHADER,
855 GL_REFERENCED_BY_COMPUTE_SHADER,
856 GL_TOP_LEVEL_ARRAY_SIZE,
857 GL_TOP_LEVEL_ARRAY_STRIDE,
858 GL_TYPE};
859 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
860 constexpr int kBufSize = 256;
861 GLint params[kBufSize];
862
863 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
864 params);
865 EXPECT_GL_NO_ERROR();
866 EXPECT_EQ(propCount, length);
867 EXPECT_EQ(2, params[0]); // array_size
868 EXPECT_LE(4, params[1]); // array_stride
869 EXPECT_LE(0, params[2]); // block_index
870 EXPECT_EQ(0, params[3]); // is_row_major
871 EXPECT_EQ(0, params[4]); // matrix_stride
872 EXPECT_EQ(13, params[5]); // name_length
873 EXPECT_EQ(4, params[6]); // offset
874
875 EXPECT_EQ(0, params[7]); // referenced_by_vertex_shader
876 EXPECT_EQ(0, params[8]); // referenced_by_fragment_shader
877 EXPECT_EQ(1, params[9]); // referenced_by_compute_shader
878
879 EXPECT_EQ(1, params[10]); // top_level_array_size
880 EXPECT_EQ(0, params[11]); // top_level_array_stride
881 EXPECT_EQ(GL_UNSIGNED_INT, params[12]); // type
882
883 index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "blockIn.s.m");
884 EXPECT_GL_NO_ERROR();
885 EXPECT_NE(GL_INVALID_INDEX, index);
886
887 glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
888 EXPECT_GL_NO_ERROR();
889 EXPECT_EQ(11, length);
890 EXPECT_EQ("blockIn.s.m", std::string(name));
891
892 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
893 params);
894 EXPECT_GL_NO_ERROR();
895 EXPECT_EQ(propCount, length);
896 EXPECT_EQ(1, params[0]); // array_size
897 EXPECT_LE(0, params[1]); // array_stride
898 EXPECT_LE(0, params[2]); // block_index
899 EXPECT_EQ(0, params[3]); // is_row_major
900 EXPECT_EQ(8, params[4]); // matrix_stride
901 EXPECT_EQ(12, params[5]); // name_length
902 EXPECT_EQ(24, params[6]); // offset
903
904 EXPECT_EQ(0, params[7]); // referenced_by_vertex_shader
905 EXPECT_EQ(0, params[8]); // referenced_by_fragment_shader
906 // TODO(jiajia.qin@intel.com): referenced_by_compute_shader is not
907 // correctly handled. http://anglebug.com/1920.
908 // EXPECT_EQ(1, params[9]); // referenced_by_compute_shader
909
910 EXPECT_EQ(1, params[10]); // top_level_array_size
911 EXPECT_EQ(0, params[11]); // top_level_array_stride
912 EXPECT_EQ(GL_FLOAT_MAT2, params[12]); // type
913 }
914
915 // Test that TOP_LEVEL_ARRAY_STRIDE for buffer variable with aggregate type works correctly.
TEST_P(ProgramInterfaceTestES31,TopLevelArrayStrideWithAggregateType)916 TEST_P(ProgramInterfaceTestES31, TopLevelArrayStrideWithAggregateType)
917 {
918 constexpr char kComputeShaderSource[] =
919 R"(#version 310 es
920 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
921 struct S
922 {
923 uvec2 v;
924 mat2 m;
925 };
926 layout(std430, binding = 0) buffer blockIn {
927 uint u;
928 uint a[2];
929 S s;
930 } instanceIn;
931 layout(std430, binding = 1) buffer blockOut {
932 uint u;
933 uint a[4][3];
934 S s[3][2];
935 } instanceOut;
936 void main()
937 {
938 instanceOut.u = instanceIn.u;
939 instanceOut.a[0][0] = instanceIn.a[0];
940 instanceOut.a[0][1] = instanceIn.a[1];
941 instanceOut.s[0][0].v = instanceIn.s.v;
942 instanceOut.s[0][0].m = instanceIn.s.m;
943 }
944 )";
945
946 GLProgram program;
947 createComputeProgram(program, kComputeShaderSource, std::get<1>(GetParam()));
948
949 GLuint index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "blockOut.s[0][0].m");
950 EXPECT_GL_NO_ERROR();
951 EXPECT_NE(GL_INVALID_INDEX, index);
952
953 GLchar name[64];
954 GLsizei length;
955 glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
956 EXPECT_GL_NO_ERROR();
957 EXPECT_EQ(18, length);
958 EXPECT_EQ("blockOut.s[0][0].m", std::string(name));
959
960 GLenum props[] = {GL_ARRAY_SIZE,
961 GL_ARRAY_STRIDE,
962 GL_BLOCK_INDEX,
963 GL_IS_ROW_MAJOR,
964 GL_MATRIX_STRIDE,
965 GL_NAME_LENGTH,
966 GL_OFFSET,
967 GL_REFERENCED_BY_VERTEX_SHADER,
968 GL_REFERENCED_BY_FRAGMENT_SHADER,
969 GL_REFERENCED_BY_COMPUTE_SHADER,
970 GL_TOP_LEVEL_ARRAY_SIZE,
971 GL_TOP_LEVEL_ARRAY_STRIDE,
972 GL_TYPE};
973 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
974 constexpr int kBufSize = 256;
975 GLint params[kBufSize];
976 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
977 params);
978 EXPECT_GL_NO_ERROR();
979 EXPECT_EQ(propCount, length);
980 EXPECT_EQ(1, params[0]); // array_size
981 EXPECT_LE(0, params[1]); // array_stride
982 EXPECT_LE(0, params[2]); // block_index
983 EXPECT_EQ(0, params[3]); // is_row_major
984 EXPECT_EQ(8, params[4]); // matrix_stride
985 EXPECT_EQ(19, params[5]); // name_length
986 EXPECT_EQ(64, params[6]); // offset
987
988 EXPECT_EQ(0, params[7]); // referenced_by_vertex_shader
989 EXPECT_EQ(0, params[8]); // referenced_by_fragment_shader
990 // TODO(jiajia.qin@intel.com): referenced_by_compute_shader is not
991 // correctly handled. http://anglebug.com/1920.
992 // EXPECT_EQ(1, params[9]); // referenced_by_compute_shader
993 EXPECT_EQ(3, params[10]); // top_level_array_size
994 EXPECT_EQ(48, params[11]); // top_level_array_stride
995 EXPECT_EQ(GL_FLOAT_MAT2, params[12]); // type
996
997 index = glGetProgramResourceIndex(program, GL_BUFFER_VARIABLE, "blockOut.a[0][0]");
998 EXPECT_GL_NO_ERROR();
999 EXPECT_NE(GL_INVALID_INDEX, index);
1000
1001 glGetProgramResourceName(program, GL_BUFFER_VARIABLE, index, sizeof(name), &length, name);
1002 EXPECT_GL_NO_ERROR();
1003 EXPECT_EQ(16, length);
1004 EXPECT_EQ("blockOut.a[0][0]", std::string(name));
1005
1006 glGetProgramResourceiv(program, GL_BUFFER_VARIABLE, index, propCount, props, kBufSize, &length,
1007 params);
1008 EXPECT_GL_NO_ERROR();
1009 EXPECT_EQ(propCount, length);
1010 EXPECT_EQ(3, params[0]); // array_size
1011 EXPECT_LE(0, params[1]); // array_stride
1012 EXPECT_LE(0, params[2]); // block_index
1013 EXPECT_EQ(0, params[3]); // is_row_major
1014 EXPECT_EQ(0, params[4]); // matrix_stride
1015 EXPECT_EQ(17, params[5]); // name_length
1016 EXPECT_EQ(4, params[6]); // offset
1017
1018 EXPECT_EQ(0, params[7]); // referenced_by_vertex_shader
1019 EXPECT_EQ(0, params[8]); // referenced_by_fragment_shader
1020 EXPECT_EQ(1, params[9]); // referenced_by_compute_shader
1021 EXPECT_EQ(4, params[10]); // top_level_array_size
1022 EXPECT_EQ(12, params[11]); // top_level_array_stride
1023 EXPECT_EQ(GL_UNSIGNED_INT, params[12]); // type
1024 }
1025
1026 // Tests the resource property query for shader storage block can be done correctly.
TEST_P(ProgramInterfaceTestES31,GetShaderStorageBlockProperties)1027 TEST_P(ProgramInterfaceTestES31, GetShaderStorageBlockProperties)
1028 {
1029 // TODO(jiajia.qin@intel.com): Don't skip this test once non-simple SSBO sentences are supported
1030 // on d3d backend. http://anglebug.com/1951
1031 ANGLE_SKIP_TEST_IF(IsD3D11());
1032
1033 // Check SSBO support
1034 GLint numSupported;
1035 glGetIntegerv(GL_MAX_VERTEX_SHADER_STORAGE_BLOCKS, &numSupported);
1036 EXPECT_GL_NO_ERROR();
1037 ANGLE_SKIP_TEST_IF(numSupported < 3);
1038
1039 constexpr char kVS[] =
1040 "#version 310 es\n"
1041 "precision highp float;\n"
1042 "struct S {\n"
1043 " vec3 a;\n"
1044 " ivec2 b[4];\n"
1045 "};\n"
1046 "layout(std140) buffer blockName0 {\n"
1047 " S s0;\n"
1048 " vec2 v0;\n"
1049 " S s1[2];\n"
1050 " uint u0;\n"
1051 "};\n"
1052 "layout(binding = 1) buffer blockName1 {\n"
1053 " uint u1[2];\n"
1054 " float f1;\n"
1055 "} instanceName1[2];\n"
1056 "layout(binding = 2) buffer blockName2 {\n"
1057 " uint u2;\n"
1058 " float f2;\n"
1059 "};\n"
1060 "void main()\n"
1061 "{\n"
1062 " gl_Position = vec4(instanceName1[0].f1, s1[0].a);\n"
1063 "}\n";
1064
1065 constexpr char kFS[] =
1066 "#version 310 es\n"
1067 "precision highp float;\n"
1068 "uniform vec4 color;\n"
1069 "out vec4 oColor;\n"
1070 "void main()\n"
1071 "{\n"
1072 " oColor = color;\n"
1073 "}";
1074
1075 GLProgram program;
1076 createGraphicsProgram(program, kVS, kFS, std::get<1>(GetParam()));
1077
1078 GLuint index = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "blockName0");
1079 EXPECT_GL_NO_ERROR();
1080 EXPECT_NE(GL_INVALID_INDEX, index);
1081
1082 GLchar name[64];
1083 GLsizei length;
1084 glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, index, sizeof(name), &length, name);
1085 EXPECT_GL_NO_ERROR();
1086 EXPECT_EQ(10, length);
1087 EXPECT_EQ("blockName0", std::string(name));
1088
1089 GLenum props[] = {GL_ACTIVE_VARIABLES,
1090 GL_BUFFER_BINDING,
1091 GL_NUM_ACTIVE_VARIABLES,
1092 GL_BUFFER_DATA_SIZE,
1093 GL_NAME_LENGTH,
1094 GL_REFERENCED_BY_VERTEX_SHADER,
1095 GL_REFERENCED_BY_FRAGMENT_SHADER,
1096 GL_REFERENCED_BY_COMPUTE_SHADER};
1097 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
1098 constexpr int kBufSize = 256;
1099 GLint params[kBufSize];
1100
1101 glGetProgramResourceiv(program, GL_SHADER_STORAGE_BLOCK, index, propCount, props, kBufSize,
1102 &length, params);
1103 EXPECT_GL_NO_ERROR();
1104 EXPECT_EQ(13, length);
1105 EXPECT_LE(0, params[0]); // active_variables s0.a
1106 EXPECT_LE(0, params[1]); // active_variables s0.b
1107 EXPECT_LE(0, params[2]); // active_variables v0
1108 EXPECT_LE(0, params[3]); // active_variables s1[0].a
1109 EXPECT_LE(0, params[4]); // active_variables s1[0].b
1110 EXPECT_LE(0, params[5]); // active_variables u0
1111 EXPECT_EQ(0, params[6]); // buffer_binding
1112 EXPECT_EQ(6, params[7]); // num_active_variables
1113 EXPECT_LE(0, params[8]); // buffer_data_size
1114 EXPECT_EQ(11, params[9]); // name_length
1115
1116 EXPECT_EQ(1, params[10]); // referenced_by_vertex_shader
1117 EXPECT_EQ(0, params[11]); // referenced_by_fragment_shader
1118 EXPECT_EQ(0, params[12]); // referenced_by_compute_shader
1119
1120 index = glGetProgramResourceIndex(program, GL_SHADER_STORAGE_BLOCK, "blockName1");
1121 EXPECT_GL_NO_ERROR();
1122 EXPECT_NE(GL_INVALID_INDEX, index);
1123
1124 glGetProgramResourceName(program, GL_SHADER_STORAGE_BLOCK, index, sizeof(name), &length, name);
1125 EXPECT_GL_NO_ERROR();
1126 EXPECT_EQ(13, length);
1127 EXPECT_EQ("blockName1[0]", std::string(name));
1128 }
1129
1130 // Tests querying the program resources of atomic counter buffers.
TEST_P(ProgramInterfaceTestES31,GetAtomicCounterProperties)1131 TEST_P(ProgramInterfaceTestES31, GetAtomicCounterProperties)
1132 {
1133 constexpr char kCSSource[] = R"(#version 310 es
1134 layout(local_size_x=1, local_size_y=1, local_size_z=1) in;
1135 layout(binding = 0) uniform atomic_uint acbase;
1136 layout(binding = 0, offset = 8) uniform atomic_uint ac[1];
1137 layout(binding = 0) uniform atomic_uint ac2;
1138
1139 void main()
1140 {
1141 atomicCounterIncrement(acbase);
1142 atomicCounterIncrement(ac[0]);
1143 atomicCounterIncrement(ac2);
1144 })";
1145
1146 GLProgram program;
1147 createComputeProgram(program, kCSSource, std::get<1>(GetParam()));
1148
1149 GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "ac");
1150 EXPECT_GL_NO_ERROR();
1151 EXPECT_NE(GL_INVALID_INDEX, index);
1152
1153 GLenum props[] = {GL_ATOMIC_COUNTER_BUFFER_INDEX};
1154 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
1155 GLint atomicIndex;
1156 GLsizei length;
1157
1158 glGetProgramResourceiv(program, GL_UNIFORM, index, propCount, props, 1, &length, &atomicIndex);
1159 EXPECT_GL_NO_ERROR();
1160 EXPECT_EQ(1, length);
1161 EXPECT_LE(0, atomicIndex);
1162
1163 GLenum atomicProps[] = {GL_ACTIVE_VARIABLES,
1164 GL_BUFFER_BINDING,
1165 GL_NUM_ACTIVE_VARIABLES,
1166 GL_BUFFER_DATA_SIZE,
1167 GL_REFERENCED_BY_VERTEX_SHADER,
1168 GL_REFERENCED_BY_FRAGMENT_SHADER,
1169 GL_REFERENCED_BY_COMPUTE_SHADER};
1170
1171 GLsizei atomicPropsCount = static_cast<GLsizei>(ArraySize(atomicProps));
1172 constexpr int kBufSize = 256;
1173 GLint params[kBufSize];
1174 GLsizei length2;
1175
1176 glGetProgramResourceiv(program, GL_ATOMIC_COUNTER_BUFFER, atomicIndex, atomicPropsCount,
1177 atomicProps, kBufSize, &length2, params);
1178 EXPECT_GL_NO_ERROR();
1179 EXPECT_EQ(9, length2);
1180
1181 EXPECT_LE(0, params[0]); // active_variables acbase
1182 EXPECT_LE(0, params[1]); // active_variables ac[1]
1183 EXPECT_LE(0, params[2]); // active_variables ac2
1184 EXPECT_EQ(0, params[3]); // buffer_binding
1185 EXPECT_EQ(3, params[4]); // num_active_variables
1186 EXPECT_EQ(16, params[5]); // buffer_data_size
1187
1188 EXPECT_EQ(0, params[6]); // referenced_by_vertex_shader
1189 EXPECT_EQ(0, params[7]); // referenced_by_fragment_shader
1190 EXPECT_EQ(1, params[8]); // referenced_by_compute_shader
1191 }
1192
1193 // Tests transform feedback varying qeury works correctly.
TEST_P(ProgramInterfaceTestES31,QueryTransformFeedbackVarying)1194 TEST_P(ProgramInterfaceTestES31, QueryTransformFeedbackVarying)
1195 {
1196 constexpr char kVS[] = R"(#version 310 es
1197 in vec3 position;
1198 out float outSingleType;
1199 out vec2 outWholeArray[2];
1200 out vec3 outArrayElements[16];
1201 void main() {
1202 outSingleType = 0.0;
1203 outWholeArray[0] = vec2(position);
1204 outArrayElements[7] = vec3(0, 0, 0);
1205 outArrayElements[15] = position;
1206 gl_Position = vec4(position, 1);
1207 })";
1208
1209 constexpr char kFS[] = R"(#version 310 es
1210 precision mediump float;
1211 out vec4 color;
1212 in float outSingleType;
1213 in vec2 outWholeArray[2];
1214 in vec3 outArrayElements[16];
1215 void main() {
1216 color = vec4(0);
1217 })";
1218
1219 std::vector<std::string> tfVaryings;
1220 tfVaryings.push_back("outArrayElements[7]");
1221 tfVaryings.push_back("outArrayElements[15]");
1222 tfVaryings.push_back("outSingleType");
1223 tfVaryings.push_back("outWholeArray");
1224
1225 GLuint program =
1226 CompileProgramWithTransformFeedback(kVS, kFS, tfVaryings, GL_INTERLEAVED_ATTRIBS);
1227 ASSERT_NE(0u, program);
1228
1229 GLint num;
1230 glGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_ACTIVE_RESOURCES, &num);
1231 EXPECT_GL_NO_ERROR();
1232 EXPECT_EQ(4, num);
1233
1234 glGetProgramInterfaceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, GL_MAX_NAME_LENGTH, &num);
1235 EXPECT_GL_NO_ERROR();
1236 EXPECT_EQ(21, num); // outArrayElements[15]
1237
1238 // GLES 3.10, Page 77:
1239 // For TRANSFORM_FEEDBACK_VARYING, the active resource list will use the variable order
1240 // specified in the most recent call to TransformFeedbackVaryings before the last call to
1241 // LinkProgram.
1242 GLuint index =
1243 glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outArrayElements[7]");
1244 EXPECT_GL_NO_ERROR();
1245 EXPECT_EQ(0u, index);
1246 index =
1247 glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outArrayElements[15]");
1248 EXPECT_GL_NO_ERROR();
1249 EXPECT_EQ(1u, index);
1250 index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outSingleType");
1251 EXPECT_GL_NO_ERROR();
1252 EXPECT_EQ(2u, index);
1253 index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outWholeArray");
1254 EXPECT_GL_NO_ERROR();
1255 EXPECT_EQ(3u, index);
1256
1257 // GLES 3.10, Page 80:
1258 // For TRANSFORM_FEEDBACK_VARYING resources, name must match one of the variables to be captured
1259 // as specified by a previous call to TransformFeedbackVaryings. Otherwise, INVALID_INDEX is
1260 // returned.
1261 // If name does not match a resource as described above, the value INVALID_INDEX is returned,
1262 // but no GL error is generated.
1263 index = glGetProgramResourceIndex(program, GL_TRANSFORM_FEEDBACK_VARYING, "outWholeArray[0]");
1264 EXPECT_GL_NO_ERROR();
1265 EXPECT_EQ(GL_INVALID_INDEX, index);
1266
1267 GLenum props[] = {GL_TYPE, GL_ARRAY_SIZE, GL_NAME_LENGTH};
1268 GLsizei propCount = static_cast<GLsizei>(ArraySize(props));
1269 GLint params[ArraySize(props)];
1270 GLsizei length = 0;
1271 // Query properties of 'outArrayElements[15]'.
1272 glGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, 1, propCount, props, propCount,
1273 &length, params);
1274 EXPECT_GL_NO_ERROR();
1275 EXPECT_EQ(propCount, length);
1276 EXPECT_EQ(GL_FLOAT_VEC3, params[0]); // type
1277 EXPECT_EQ(1, params[1]); // array_size
1278 EXPECT_EQ(21, params[2]); // name_length
1279
1280 // Query properties of 'outWholeArray'.
1281 glGetProgramResourceiv(program, GL_TRANSFORM_FEEDBACK_VARYING, 3, propCount, props, propCount,
1282 &length, params);
1283 EXPECT_GL_NO_ERROR();
1284 EXPECT_EQ(propCount, length);
1285 EXPECT_EQ(GL_FLOAT_VEC2, params[0]); // type
1286 EXPECT_EQ(2, params[1]); // array_size
1287 EXPECT_EQ(14, params[2]); // name_length
1288
1289 glDeleteProgram(program);
1290 }
1291
1292 // Regression test for crash report in http://anglebug.com/6073.
TEST_P(ProgramInterfaceTestES31,ReloadFromCacheShouldNotCrash)1293 TEST_P(ProgramInterfaceTestES31, ReloadFromCacheShouldNotCrash)
1294 {
1295 // TODO(jiajia.qin@intel.com): Don't skip this test once non-simple SSBO sentences are supported
1296 // on d3d backend. http://anglebug.com/1951
1297 ANGLE_SKIP_TEST_IF(IsD3D11());
1298
1299 constexpr char kVS[] = R"(#version 310 es
1300 #extension GL_ANGLE_multi_draw : require
1301 precision highp int;
1302 precision highp float;
1303 layout(std140) buffer;
1304 struct TransformInfo
1305 {
1306 mat4 mvp;
1307 };
1308 layout(binding = 0) buffer pe_transforms
1309 {
1310 TransformInfo transforms[];
1311 };
1312 out vec2 texCoord;
1313 uniform int pe_base_draw_id;
1314 layout(location = 0) in vec3 pe_vertex;
1315 layout(location = 1) in vec3 pe_normal;
1316 layout(location = 2) in vec2 pe_tex_coord;
1317 void main()
1318 {
1319 vec4 v = vec4(pe_vertex, 1.0);
1320 texCoord = pe_tex_coord;
1321 gl_Position = transforms[(gl_DrawID + pe_base_draw_id)].mvp * v;
1322 })";
1323
1324 constexpr char kFS[] = R"(#version 310 es
1325 #extension GL_ANGLE_multi_draw : require
1326 precision highp int;
1327 precision highp float;
1328 layout(std140) buffer;
1329 in vec2 texCoord;
1330 layout(binding = 0) uniform sampler2D pe_tex_main;
1331 out vec4 pe_frag_color;
1332 void main()
1333 {
1334 vec4 u = texture(pe_tex_main, texCoord);
1335 if(u.a < 0.05)
1336 discard;
1337 pe_frag_color = u;
1338 }
1339 )";
1340
1341 GLProgram program;
1342 createGraphicsProgram(program, kVS, kFS, std::get<1>(GetParam()));
1343 EXPECT_GL_NO_ERROR();
1344 }
1345
1346 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ProgramInterfaceTestES31);
1347 ANGLE_INSTANTIATE_TEST_COMBINE_1(ProgramInterfaceTestES31,
1348 ProgramInterfaceTestPrint,
1349 testing::Bool(),
1350 ANGLE_ALL_TEST_PLATFORMS_ES31);
1351
1352 } // anonymous namespace
1353