• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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> &paramsInfo)
25 {
26     const ProgramInterfaceTestParams &params = 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