xref: /aosp_15_r20/external/angle/src/tests/gl_tests/GeometryShaderTest.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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 // GeometryShaderTest.cpp : Tests of the implementation of geometry shader
8 
9 #include "test_utils/ANGLETest.h"
10 #include "test_utils/gl_raii.h"
11 
12 using namespace angle;
13 
14 namespace
15 {
16 
17 class GeometryShaderTest : public ANGLETest<>
18 {
19   protected:
GeometryShaderTest()20     GeometryShaderTest()
21     {
22         setWindowWidth(64);
23         setWindowHeight(32);
24         setConfigRedBits(8);
25         setConfigGreenBits(8);
26         setConfigBlueBits(8);
27         setConfigAlphaBits(8);
28         setConfigDepthBits(24);
29         setConfigStencilBits(8);
30     }
31 
CreateEmptyGeometryShader(const std::string & inputPrimitive,const std::string & outputPrimitive,int invocations,int maxVertices)32     static std::string CreateEmptyGeometryShader(const std::string &inputPrimitive,
33                                                  const std::string &outputPrimitive,
34                                                  int invocations,
35                                                  int maxVertices)
36     {
37         std::ostringstream ostream;
38         ostream << "#version 310 es\n"
39                    "#extension GL_EXT_geometry_shader : require\n";
40         if (!inputPrimitive.empty())
41         {
42             ostream << "layout (" << inputPrimitive << ") in;\n";
43         }
44         if (!outputPrimitive.empty())
45         {
46             ostream << "layout (" << outputPrimitive << ") out;\n";
47         }
48         if (invocations > 0)
49         {
50             ostream << "layout (invocations = " << invocations << ") in;\n";
51         }
52         if (maxVertices >= 0)
53         {
54             ostream << "layout (max_vertices = " << maxVertices << ") out;\n";
55         }
56         ostream << "void main()\n"
57                    "{\n"
58                    "}";
59         return ostream.str();
60     }
61 
62     void setupLayeredFramebuffer(GLuint framebuffer,
63                                  GLuint color0,
64                                  GLuint color1,
65                                  GLuint depthStencil,
66                                  GLenum colorTarget,
67                                  const GLColor &color0InitialColor,
68                                  const GLColor &color1InitialColor,
69                                  float depthInitialValue,
70                                  GLint stencilInitialValue);
71     void setupLayeredFramebufferProgram(GLProgram *program);
72     void verifyLayeredFramebufferColor(GLuint colorTexture,
73                                        GLenum colorTarget,
74                                        const GLColor expected[],
75                                        GLsizei layerCount);
76     void verifyLayeredFramebufferDepthStencil(GLuint depthStencilTexture,
77                                               const float expectedDepth[],
78                                               const GLint expectedStencil[],
79                                               GLsizei layerCount);
80 
81     void layeredFramebufferClearTest(GLenum colorTarget);
82     void layeredFramebufferPreRenderClearTest(GLenum colorTarget, bool doubleClear);
83     void layeredFramebufferMidRenderClearTest(GLenum colorTarget);
84     void callFramebufferTextureAPI(APIExtensionVersion usedExtension,
85                                    GLenum target,
86                                    GLenum attachment,
87                                    GLuint texture,
88                                    GLint level);
89     void testNegativeFramebufferTexture(APIExtensionVersion usedExtension);
90     void testCreateAndAttachGeometryShader(APIExtensionVersion usedExtension);
91 
92     static constexpr GLsizei kWidth              = 16;
93     static constexpr GLsizei kHeight             = 16;
94     static constexpr GLsizei kColor0Layers       = 4;
95     static constexpr GLsizei kColor1Layers       = 3;
96     static constexpr GLsizei kDepthStencilLayers = 5;
97     static constexpr GLsizei kFramebufferLayers =
98         std::min({kColor0Layers, kColor1Layers, kDepthStencilLayers});
99 };
100 
101 class GeometryShaderTestES3 : public ANGLETest<>
102 {};
103 
104 class GeometryShaderTestES32 : public GeometryShaderTest
105 {};
106 
107 // Verify that a geometry shader cannot be created in an OpenGL ES 3.0 context, since at least
108 // ES 3.1 is required.
TEST_P(GeometryShaderTestES3,CreateGeometryShaderInES3)109 TEST_P(GeometryShaderTestES3, CreateGeometryShaderInES3)
110 {
111     EXPECT_TRUE(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
112     GLuint geometryShader = glCreateShader(GL_GEOMETRY_SHADER_EXT);
113     EXPECT_EQ(0u, geometryShader);
114     EXPECT_GL_ERROR(GL_INVALID_ENUM);
115 }
116 
testCreateAndAttachGeometryShader(APIExtensionVersion usedExtension)117 void GeometryShaderTest::testCreateAndAttachGeometryShader(APIExtensionVersion usedExtension)
118 {
119     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES ||
120            usedExtension == APIExtensionVersion::Core);
121 
122     std::string gs;
123 
124     constexpr char kGLSLVersion31[] = R"(#version 310 es
125 )";
126     constexpr char kGLSLVersion32[] = R"(#version 320 es
127 )";
128     constexpr char kGeometryEXT[]   = R"(#extension GL_EXT_geometry_shader : require
129 )";
130     constexpr char kGeometryOES[]   = R"(#extension GL_OES_geometry_shader : require
131 )";
132 
133     if (usedExtension == APIExtensionVersion::EXT)
134     {
135         gs.append(kGLSLVersion31);
136         gs.append(kGeometryEXT);
137     }
138     else if (usedExtension == APIExtensionVersion::OES)
139     {
140         gs.append(kGLSLVersion31);
141         gs.append(kGeometryOES);
142     }
143     else
144     {
145         gs.append(kGLSLVersion32);
146     }
147 
148     constexpr char kGSBody[] = R"(
149 layout (invocations = 3, triangles) in;
150 layout (triangle_strip, max_vertices = 3) out;
151 in vec4 texcoord[];
152 out vec4 o_texcoord;
153 void main()
154 {
155     int n;
156     for (n = 0; n < gl_in.length(); n++)
157     {
158         gl_Position = gl_in[n].gl_Position;
159         gl_Layer   = gl_InvocationID;
160         o_texcoord = texcoord[n];
161         EmitVertex();
162     }
163     EndPrimitive();
164 })";
165     gs.append(kGSBody);
166 
167     GLuint geometryShader = CompileShader(GL_GEOMETRY_SHADER_EXT, gs.c_str());
168     EXPECT_NE(0u, geometryShader);
169 
170     GLuint programID = glCreateProgram();
171     glAttachShader(programID, geometryShader);
172 
173     glDetachShader(programID, geometryShader);
174     glDeleteShader(geometryShader);
175     glDeleteProgram(programID);
176 
177     EXPECT_GL_NO_ERROR();
178 }
179 
180 // Verify that a geometry shader can be created and attached to a program using the EXT extension.
TEST_P(GeometryShaderTest,CreateAndAttachGeometryShaderEXT)181 TEST_P(GeometryShaderTest, CreateAndAttachGeometryShaderEXT)
182 {
183     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
184     testCreateAndAttachGeometryShader(APIExtensionVersion::EXT);
185 }
186 
187 // Verify that a geometry shader can be created and attached to a program using the OES extension.
TEST_P(GeometryShaderTest,CreateAndAttachGeometryShaderOES)188 TEST_P(GeometryShaderTest, CreateAndAttachGeometryShaderOES)
189 {
190     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_geometry_shader"));
191     testCreateAndAttachGeometryShader(APIExtensionVersion::OES);
192 }
193 
194 // Verify that a geometry shader can be created and attached to a program in GLES 3.2.
TEST_P(GeometryShaderTestES32,CreateAndAttachGeometryShader)195 TEST_P(GeometryShaderTestES32, CreateAndAttachGeometryShader)
196 {
197     testCreateAndAttachGeometryShader(APIExtensionVersion::Core);
198 }
199 
200 // Verify that Geometry Shader can be compiled when geometry shader array input size
201 // is set after shader input variables.
202 // http://anglebug.com/42265598 GFXBench Car Chase uses this pattern
TEST_P(GeometryShaderTest,DeferredSetOfArrayInputSize)203 TEST_P(GeometryShaderTest, DeferredSetOfArrayInputSize)
204 {
205     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
206     // "layout (invocations = 3, triangles) in;" should be declared before "in vec4 texcoord [];",
207     // but here it is declared later.
208     constexpr char kGS[]  = R"(#version 310 es
209 #extension GL_EXT_geometry_shader : require
210 in vec4 texcoord[];
211 out vec4 o_texcoord;
212 layout (invocations = 3, triangles_adjacency) in;
213 layout (triangle_strip, max_vertices = 3) out;
214 void main()
215 {
216     int n;
217     for (n = 0; n < gl_in.length(); n++)
218     {
219         gl_Position = gl_in[n].gl_Position;
220         gl_Layer   = gl_InvocationID;
221         o_texcoord = texcoord[n];
222         EmitVertex();
223     }
224     EndPrimitive();
225 })";
226     GLuint geometryShader = CompileShader(GL_GEOMETRY_SHADER_EXT, kGS);
227     EXPECT_NE(0u, geometryShader);
228     GLuint programID = glCreateProgram();
229     glAttachShader(programID, geometryShader);
230     glDetachShader(programID, geometryShader);
231     glDeleteShader(geometryShader);
232     glDeleteProgram(programID);
233     EXPECT_GL_NO_ERROR();
234 }
235 
236 // Verify that all the implementation dependent geometry shader related resource limits meet the
237 // requirement of GL_EXT_geometry_shader SPEC.
TEST_P(GeometryShaderTest,GeometryShaderImplementationDependentLimits)238 TEST_P(GeometryShaderTest, GeometryShaderImplementationDependentLimits)
239 {
240     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
241 
242     // http://anglebug.com/42264048
243     ANGLE_SKIP_TEST_IF(IsIntel() && IsVulkan() && IsLinux());
244 
245     const std::map<GLenum, int> limits = {{GL_MAX_FRAMEBUFFER_LAYERS_EXT, 256},
246                                           {GL_MAX_GEOMETRY_UNIFORM_COMPONENTS_EXT, 1024},
247                                           {GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT, 12},
248                                           {GL_MAX_GEOMETRY_INPUT_COMPONENTS_EXT, 64},
249                                           {GL_MAX_GEOMETRY_OUTPUT_COMPONENTS_EXT, 64},
250                                           {GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT, 256},
251                                           {GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS_EXT, 1024},
252                                           {GL_MAX_GEOMETRY_TEXTURE_IMAGE_UNITS_EXT, 16},
253                                           {GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT, 0},
254                                           {GL_MAX_GEOMETRY_ATOMIC_COUNTERS_EXT, 0},
255                                           {GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT, 0},
256                                           {GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT, 0},
257                                           {GL_MAX_GEOMETRY_SHADER_INVOCATIONS_EXT, 32}};
258 
259     GLint value;
260     for (const auto &limit : limits)
261     {
262         value = 0;
263         glGetIntegerv(limit.first, &value);
264         EXPECT_GL_NO_ERROR();
265         EXPECT_GE(value, limit.second);
266     }
267 
268     value = 0;
269     glGetIntegerv(GL_LAYER_PROVOKING_VERTEX_EXT, &value);
270     EXPECT_GL_NO_ERROR();
271     EXPECT_TRUE(value == GL_FIRST_VERTEX_CONVENTION_EXT || value == GL_LAST_VERTEX_CONVENTION_EXT ||
272                 value == GL_UNDEFINED_VERTEX_EXT);
273 }
274 
275 // Verify that all the combined resource limits meet the requirement of GL_EXT_geometry_shader SPEC.
TEST_P(GeometryShaderTest,CombinedResourceLimits)276 TEST_P(GeometryShaderTest, CombinedResourceLimits)
277 {
278     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
279 
280     // See http://anglebug.com/42260977.
281     ANGLE_SKIP_TEST_IF(IsAndroid());
282 
283     const std::map<GLenum, int> limits = {{GL_MAX_UNIFORM_BUFFER_BINDINGS, 48},
284                                           {GL_MAX_COMBINED_UNIFORM_BLOCKS, 36},
285                                           {GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, 64}};
286 
287     GLint value;
288     for (const auto &limit : limits)
289     {
290         value = 0;
291         glGetIntegerv(limit.first, &value);
292         EXPECT_GL_NO_ERROR();
293         EXPECT_GE(value, limit.second);
294     }
295 }
296 
297 // Verify that linking a program with an uncompiled geometry shader causes a link failure.
TEST_P(GeometryShaderTest,LinkWithUncompiledGeometryShader)298 TEST_P(GeometryShaderTest, LinkWithUncompiledGeometryShader)
299 {
300     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
301 
302     GLuint vertexShader   = CompileShader(GL_VERTEX_SHADER, essl31_shaders::vs::Simple());
303     GLuint fragmentShader = CompileShader(GL_FRAGMENT_SHADER, essl31_shaders::fs::Red());
304     ASSERT_NE(0u, vertexShader);
305     ASSERT_NE(0u, fragmentShader);
306 
307     GLuint geometryShader = glCreateShader(GL_GEOMETRY_SHADER_EXT);
308 
309     GLuint program = glCreateProgram();
310     glAttachShader(program, vertexShader);
311     glAttachShader(program, fragmentShader);
312     glAttachShader(program, geometryShader);
313     glDeleteShader(vertexShader);
314     glDeleteShader(fragmentShader);
315     glDeleteShader(geometryShader);
316 
317     glLinkProgram(program);
318 
319     GLint linkStatus;
320     glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
321     EXPECT_EQ(0, linkStatus);
322 
323     glDeleteProgram(program);
324     ASSERT_GL_NO_ERROR();
325 }
326 
327 // Verify that linking a program with geometry shader whose version is different from other shaders
328 // in this program causes a link error.
TEST_P(GeometryShaderTest,LinkWhenShaderVersionMismatch)329 TEST_P(GeometryShaderTest, LinkWhenShaderVersionMismatch)
330 {
331     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
332 
333     const std::string &emptyGeometryShader = CreateEmptyGeometryShader("points", "points", 2, 1);
334 
335     GLuint program = CompileProgramWithGS(essl3_shaders::vs::Simple(), emptyGeometryShader.c_str(),
336                                           essl3_shaders::fs::Red());
337     EXPECT_EQ(0u, program);
338 }
339 
340 // Verify that linking a program with geometry shader that lacks input primitive,
341 // output primitive, or declaration on 'max_vertices' causes a link failure.
TEST_P(GeometryShaderTest,LinkValidationOnGeometryShaderLayouts)342 TEST_P(GeometryShaderTest, LinkValidationOnGeometryShaderLayouts)
343 {
344     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
345 
346     const std::string gsWithoutInputPrimitive  = CreateEmptyGeometryShader("", "points", 2, 1);
347     const std::string gsWithoutOutputPrimitive = CreateEmptyGeometryShader("points", "", 2, 1);
348     const std::string gsWithoutInvocations = CreateEmptyGeometryShader("points", "points", -1, 1);
349     const std::string gsWithoutMaxVertices = CreateEmptyGeometryShader("points", "points", 2, -1);
350 
351     // Linking a program with a geometry shader that only lacks 'invocations' should not cause a
352     // link failure.
353     GLuint program = CompileProgramWithGS(essl31_shaders::vs::Simple(),
354                                           gsWithoutInvocations.c_str(), essl31_shaders::fs::Red());
355     EXPECT_NE(0u, program);
356 
357     glDeleteProgram(program);
358 
359     // Linking a program with a geometry shader that lacks input primitive, output primitive or
360     // 'max_vertices' causes a link failure.
361     program = CompileProgramWithGS(essl31_shaders::vs::Simple(), gsWithoutInputPrimitive.c_str(),
362                                    essl31_shaders::fs::Red());
363     EXPECT_EQ(0u, program);
364 
365     program = CompileProgramWithGS(essl31_shaders::vs::Simple(), gsWithoutOutputPrimitive.c_str(),
366                                    essl31_shaders::fs::Red());
367     EXPECT_EQ(0u, program);
368 
369     program = CompileProgramWithGS(essl31_shaders::vs::Simple(), gsWithoutMaxVertices.c_str(),
370                                    essl31_shaders::fs::Red());
371     EXPECT_EQ(0u, program);
372 
373     ASSERT_GL_NO_ERROR();
374 }
375 
376 // Verify that an link error occurs when the vertex shader has an array output and there is a
377 // geometry shader in the program.
TEST_P(GeometryShaderTest,VertexShaderArrayOutput)378 TEST_P(GeometryShaderTest, VertexShaderArrayOutput)
379 {
380     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
381 
382     constexpr char kVS[] = R"(#version 310 es
383 in vec4 vertex_in;
384 out vec4 vertex_out[3];
385 void main()
386 {
387     gl_Position = vertex_in;
388     vertex_out[0] = vec4(1.0, 0.0, 0.0, 1.0);
389     vertex_out[1] = vec4(0.0, 1.0, 0.0, 1.0);
390     vertex_out[2] = vec4(0.0, 0.0, 1.0, 1.0);
391 })";
392 
393     constexpr char kGS[] = R"(#version 310 es
394 #extension GL_EXT_geometry_shader : require
395 layout (invocations = 3, triangles) in;
396 layout (points, max_vertices = 3) out;
397 in vec4 vertex_out[];
398 out vec4 geometry_color;
399 void main()
400 {
401     gl_Position = gl_in[0].gl_Position;
402     geometry_color = vertex_out[0];
403     EmitVertex();
404 })";
405 
406     constexpr char kFS[] = R"(#version 310 es
407 precision mediump float;
408 in vec4 geometry_color;
409 layout (location = 0) out vec4 output_color;
410 void main()
411 {
412     output_color = geometry_color;
413 })";
414 
415     GLuint program = CompileProgramWithGS(kVS, kGS, kFS);
416     EXPECT_EQ(0u, program);
417 
418     EXPECT_GL_NO_ERROR();
419 }
420 
421 // Verify that an link error occurs when the definition of a unform in fragment shader is different
422 // from those in a geometry shader.
TEST_P(GeometryShaderTest,UniformMismatchBetweenGeometryAndFragmentShader)423 TEST_P(GeometryShaderTest, UniformMismatchBetweenGeometryAndFragmentShader)
424 {
425     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
426 
427     constexpr char kVS[] = R"(#version 310 es
428 uniform highp vec4 uniform_value_vert;
429 in vec4 vertex_in;
430 out vec4 vertex_out;
431 void main()
432 {
433     gl_Position = vertex_in;
434     vertex_out = uniform_value_vert;
435 })";
436 
437     constexpr char kGS[] = R"(#version 310 es
438 #extension GL_EXT_geometry_shader : require
439 uniform vec4 uniform_value;
440 layout (invocations = 3, triangles) in;
441 layout (points, max_vertices = 3) out;
442 in vec4 vertex_out[];
443 out vec4 geometry_color;
444 void main()
445 {
446     gl_Position = gl_in[0].gl_Position;
447     geometry_color = vertex_out[0] + uniform_value;
448     EmitVertex();
449 })";
450 
451     constexpr char kFS[] = R"(#version 310 es
452 precision highp float;
453 uniform float uniform_value;
454 in vec4 geometry_color;
455 layout (location = 0) out vec4 output_color;
456 void main()
457 {
458     output_color = vec4(geometry_color.rgb, uniform_value);
459 })";
460 
461     GLuint program = CompileProgramWithGS(kVS, kGS, kFS);
462     EXPECT_EQ(0u, program);
463 
464     EXPECT_GL_NO_ERROR();
465 }
466 
467 // Verify that an link error occurs when the number of uniform blocks in a geometry shader exceeds
468 // MAX_GEOMETRY_UNIFORM_BLOCKS_EXT.
TEST_P(GeometryShaderTest,TooManyUniformBlocks)469 TEST_P(GeometryShaderTest, TooManyUniformBlocks)
470 {
471     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
472 
473     GLint maxGeometryUniformBlocks = 0;
474     glGetIntegerv(GL_MAX_GEOMETRY_UNIFORM_BLOCKS_EXT, &maxGeometryUniformBlocks);
475 
476     GLint numUniformBlocks = maxGeometryUniformBlocks + 1;
477     std::ostringstream stream;
478     stream << "#version 310 es\n"
479               "#extension GL_EXT_geometry_shader : require\n"
480               "uniform ubo\n"
481               "{\n"
482               "    vec4 value1;\n"
483               "} block0["
484            << numUniformBlocks
485            << "];\n"
486               "layout (triangles) in;\n"
487               "layout (points, max_vertices = 1) out;\n"
488               "void main()\n"
489               "{\n"
490               "    gl_Position = gl_in[0].gl_Position;\n";
491 
492     for (GLint i = 0; i < numUniformBlocks; ++i)
493     {
494         stream << "    gl_Position += block0[" << i << "].value1;\n";
495     }
496     stream << "    EmitVertex();\n"
497               "}\n";
498 
499     GLuint program = CompileProgramWithGS(essl31_shaders::vs::Simple(), stream.str().c_str(),
500                                           essl31_shaders::fs::Red());
501     EXPECT_EQ(0u, program);
502 
503     EXPECT_GL_NO_ERROR();
504 }
505 
506 // Verify that an link error occurs when the number of shader storage blocks in a geometry shader
507 // exceeds MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT.
TEST_P(GeometryShaderTest,TooManyShaderStorageBlocks)508 TEST_P(GeometryShaderTest, TooManyShaderStorageBlocks)
509 {
510     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
511 
512     GLint maxGeometryShaderStorageBlocks = 0;
513     glGetIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT, &maxGeometryShaderStorageBlocks);
514 
515     GLint numSSBOs = maxGeometryShaderStorageBlocks + 1;
516     std::ostringstream stream;
517     stream << "#version 310 es\n"
518               "#extension GL_EXT_geometry_shader : require\n"
519               "buffer ssbo\n"
520               "{\n"
521               "    vec4 value1;\n"
522               "} block0["
523            << numSSBOs
524            << "];\n"
525               "layout (triangles) in;\n"
526               "layout (points, max_vertices = 1) out;\n"
527               "void main()\n"
528               "{\n"
529               "    gl_Position = gl_in[0].gl_Position;\n";
530 
531     for (GLint i = 0; i < numSSBOs; ++i)
532     {
533         stream << "    gl_Position += block0[" << i << "].value1;\n";
534     }
535     stream << "    EmitVertex();\n"
536               "}\n";
537 
538     GLuint program = CompileProgramWithGS(essl31_shaders::vs::Simple(), stream.str().c_str(),
539                                           essl31_shaders::fs::Red());
540     EXPECT_EQ(0u, program);
541 
542     EXPECT_GL_NO_ERROR();
543 }
544 
545 // Verify that an link error occurs when the definition of a unform block in the vertex shader is
546 // different from that in a geometry shader.
TEST_P(GeometryShaderTest,UniformBlockMismatchBetweenVertexAndGeometryShader)547 TEST_P(GeometryShaderTest, UniformBlockMismatchBetweenVertexAndGeometryShader)
548 {
549     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
550 
551     constexpr char kVS[] = R"(#version 310 es
552 uniform ubo
553 {
554     vec4 uniform_value_vert;
555 } block0;
556 in vec4 vertex_in;
557 out vec4 vertex_out;
558 void main()
559 {
560     gl_Position = vertex_in;
561     vertex_out = block0.uniform_value_vert;
562 })";
563 
564     constexpr char kGS[] = R"(#version 310 es
565 #extension GL_EXT_geometry_shader : require
566 uniform ubo
567 {
568     vec4 uniform_value_geom;
569 } block0;
570 layout (triangles) in;
571 layout (points, max_vertices = 1) out;
572 in vec4 vertex_out[];
573 void main()
574 {
575     gl_Position = gl_in[0].gl_Position + vertex_out[0];
576     gl_Position += block0.uniform_value_geom;
577     EmitVertex();
578 })";
579 
580     GLuint program = CompileProgramWithGS(kVS, kGS, essl31_shaders::fs::Red());
581     EXPECT_EQ(0u, program);
582 
583     EXPECT_GL_NO_ERROR();
584 }
585 
586 // Verify that an link error occurs when the definition of a shader storage block in the geometry
587 // shader is different from that in a fragment shader.
TEST_P(GeometryShaderTest,ShaderStorageBlockMismatchBetweenGeometryAndFragmentShader)588 TEST_P(GeometryShaderTest, ShaderStorageBlockMismatchBetweenGeometryAndFragmentShader)
589 {
590     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
591 
592     GLint maxGeometryShaderStorageBlocks = 0;
593     glGetIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT, &maxGeometryShaderStorageBlocks);
594 
595     // The minimun value of MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT can be 0.
596     // [EXT_geometry_shader] Table 20.43gs
597     ANGLE_SKIP_TEST_IF(maxGeometryShaderStorageBlocks == 0);
598 
599     GLint maxFragmentShaderStorageBlocks = 0;
600     glGetIntegerv(GL_MAX_FRAGMENT_SHADER_STORAGE_BLOCKS, &maxFragmentShaderStorageBlocks);
601 
602     // The minimun value of MAX_FRAGMENT_SHADER_STORAGE_BLOCKS can be 0.
603     // [OpenGL ES 3.1] Table 20.44
604     ANGLE_SKIP_TEST_IF(maxFragmentShaderStorageBlocks == 0);
605 
606     constexpr char kGS[] = R"(#version 310 es
607 #extension GL_EXT_geometry_shader : require
608 buffer ssbo
609 {
610     vec4 ssbo_value;
611 } block0;
612 layout (triangles) in;
613 layout (points, max_vertices = 1) out;
614 void main()
615 {
616     gl_Position = gl_in[0].gl_Position + block0.ssbo_value;
617     EmitVertex();
618 })";
619 
620     constexpr char kFS[] = R"(#version 310 es
621 precision highp float;
622 buffer ssbo
623 {
624     vec3 ssbo_value;
625 } block0;
626 layout (location = 0) out vec4 output_color;
627 void main()
628 {
629     output_color = vec4(block0.ssbo_value, 1);
630 })";
631 
632     GLuint program = CompileProgramWithGS(essl31_shaders::vs::Simple(), kGS, kFS);
633     EXPECT_EQ(0u, program);
634 
635     EXPECT_GL_NO_ERROR();
636 }
637 
638 // Verify GL_REFERENCED_BY_GEOMETRY_SHADER_EXT cannot be used on platforms that don't support
639 // EXT_geometry_shader, or we will get an INVALID_ENUM error.
TEST_P(GeometryShaderTest,ReferencedByGeometryShaderWithoutExtensionEnabled)640 TEST_P(GeometryShaderTest, ReferencedByGeometryShaderWithoutExtensionEnabled)
641 {
642     ANGLE_SKIP_TEST_IF(IsGLExtensionEnabled("GL_EXT_geometry_shader"));
643 
644     constexpr char kFS[] = R"(#version 310 es
645 precision highp float;
646 uniform vec4 color;
647 layout(location = 0) out vec4 oColor;
648 void main()
649 {
650     oColor = color;
651 })";
652 
653     ANGLE_GL_PROGRAM(program, essl31_shaders::vs::Simple(), kFS);
654 
655     const GLuint index = glGetProgramResourceIndex(program, GL_UNIFORM, "color");
656     ASSERT_GL_NO_ERROR();
657     ASSERT_NE(GL_INVALID_INDEX, index);
658 
659     constexpr GLenum kProps[]    = {GL_REFERENCED_BY_GEOMETRY_SHADER_EXT};
660     constexpr GLsizei kPropCount = static_cast<GLsizei>(ArraySize(kProps));
661     GLint params[ArraySize(kProps)];
662     GLsizei length;
663 
664     glGetProgramResourceiv(program, GL_UNIFORM, index, kPropCount, kProps, kPropCount, &length,
665                            params);
666     EXPECT_GL_ERROR(GL_INVALID_ENUM);
667 }
668 
669 // Verify GL_REFERENCED_BY_GEOMETRY_SHADER_EXT can work correctly on platforms that support
670 // EXT_geometry_shader.
TEST_P(GeometryShaderTest,ReferencedByGeometryShader)671 TEST_P(GeometryShaderTest, ReferencedByGeometryShader)
672 {
673     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
674 
675     constexpr char kVS[] = R"(#version 310 es
676 precision highp float;
677 layout(location = 0) in highp vec4 position;
678 void main()
679 {
680     gl_Position = position;
681 })";
682 
683     constexpr char kGS[] = R"(#version 310 es
684 #extension GL_EXT_geometry_shader : require
685 layout (binding = 3) uniform ubo0
686 {
687     vec4 ubo0_location;
688 } block0;
689 layout (binding = 4) uniform ubo1
690 {
691     vec4 ubo1_location;
692 } block1;
693 uniform vec4 u_color;
694 layout (triangles) in;
695 layout (points, max_vertices = 1) out;
696 out vec4 gs_out;
697 void main()
698 {
699     gl_Position = gl_in[0].gl_Position;
700     gl_Position += block0.ubo0_location + block1.ubo1_location;
701     gs_out = u_color;
702     EmitVertex();
703 })";
704 
705     constexpr char kFS[] = R"(#version 310 es
706 precision highp float;
707 in vec4 gs_out;
708 layout(location = 0) out vec4 oColor;
709 void main()
710 {
711     oColor = gs_out;
712 })";
713 
714     ANGLE_GL_PROGRAM_WITH_GS(program, kVS, kGS, kFS);
715 
716     constexpr GLenum kProps[]    = {GL_REFERENCED_BY_GEOMETRY_SHADER_EXT};
717     constexpr GLsizei kPropCount = static_cast<GLsizei>(ArraySize(kProps));
718     std::array<GLint, ArraySize(kProps)> params;
719     GLsizei length;
720 
721     params.fill(1);
722     GLuint index = glGetProgramResourceIndex(program, GL_PROGRAM_INPUT, "position");
723     glGetProgramResourceiv(program, GL_PROGRAM_INPUT, index, kPropCount, kProps, kPropCount,
724                            &length, params.data());
725     EXPECT_GL_NO_ERROR();
726     EXPECT_EQ(0, params[0]);
727 
728     params.fill(1);
729     index = glGetProgramResourceIndex(program, GL_PROGRAM_OUTPUT, "oColor");
730     glGetProgramResourceiv(program, GL_PROGRAM_OUTPUT, index, kPropCount, kProps, kPropCount,
731                            &length, params.data());
732     EXPECT_GL_NO_ERROR();
733     EXPECT_EQ(0, params[0]);
734 
735     index = glGetProgramResourceIndex(program, GL_UNIFORM, "u_color");
736     glGetProgramResourceiv(program, GL_UNIFORM, index, kPropCount, kProps, kPropCount, &length,
737                            params.data());
738     EXPECT_GL_NO_ERROR();
739     EXPECT_EQ(1, params[0]);
740 
741     params.fill(0);
742     index = glGetProgramResourceIndex(program, GL_UNIFORM_BLOCK, "ubo1");
743     glGetProgramResourceiv(program, GL_UNIFORM_BLOCK, index, kPropCount, kProps, kPropCount,
744                            &length, params.data());
745     EXPECT_GL_NO_ERROR();
746     EXPECT_EQ(1, params[0]);
747 
748     GLint maxGeometryShaderStorageBlocks = 0;
749     glGetIntegerv(GL_MAX_GEOMETRY_SHADER_STORAGE_BLOCKS_EXT, &maxGeometryShaderStorageBlocks);
750     // The maximum number of shader storage blocks in a geometry shader can be 0.
751     // [EXT_geometry_shader] Table 20.43gs
752     if (maxGeometryShaderStorageBlocks > 0)
753     {
754         constexpr char kGSWithSSBO[] = R"(#version 310 es
755 #extension GL_EXT_geometry_shader : require
756 layout (binding = 2) buffer ssbo
757 {
758     vec4 ssbo_value;
759 } block0;
760 layout (triangles) in;
761 layout (points, max_vertices = 1) out;
762 out vec4 gs_out;
763 void main()
764 {
765     gl_Position = gl_in[0].gl_Position + block0.ssbo_value;
766     gs_out = block0.ssbo_value;
767     EmitVertex();
768 })";
769 
770         ANGLE_GL_PROGRAM_WITH_GS(programWithSSBO, kVS, kGSWithSSBO, kFS);
771 
772         params.fill(0);
773         index = glGetProgramResourceIndex(programWithSSBO, GL_SHADER_STORAGE_BLOCK, "ssbo");
774         glGetProgramResourceiv(programWithSSBO, GL_SHADER_STORAGE_BLOCK, index, kPropCount, kProps,
775                                kPropCount, &length, params.data());
776         EXPECT_GL_NO_ERROR();
777         EXPECT_EQ(1, params[0]);
778 
779         params.fill(0);
780         index = glGetProgramResourceIndex(programWithSSBO, GL_BUFFER_VARIABLE, "ssbo.ssbo_value");
781         glGetProgramResourceiv(programWithSSBO, GL_BUFFER_VARIABLE, index, kPropCount, kProps,
782                                kPropCount, &length, params.data());
783         EXPECT_GL_NO_ERROR();
784         EXPECT_EQ(1, params[0]);
785     }
786 
787     GLint maxGeometryAtomicCounterBuffers = 0;
788     glGetIntegerv(GL_MAX_GEOMETRY_ATOMIC_COUNTER_BUFFERS_EXT, &maxGeometryAtomicCounterBuffers);
789     // The maximum number of atomic counter buffers in a geometry shader can be 0.
790     // [EXT_geometry_shader] Table 20.43gs
791     if (maxGeometryAtomicCounterBuffers > 0)
792     {
793         constexpr char kGSWithAtomicCounters[] = R"(#version 310 es
794 #extension GL_EXT_geometry_shader : require
795 layout(binding = 1, offset = 0) uniform atomic_uint gs_counter;
796 layout (triangles) in;
797 layout (points, max_vertices = 1) out;
798 out vec4 gs_out;
799 void main()
800 {
801     atomicCounterIncrement(gs_counter);
802     gl_Position = gl_in[0].gl_Position;
803     gs_out = vec4(1.0, 0.0, 0.0, 1.0);
804     EmitVertex();
805 })";
806 
807         ANGLE_GL_PROGRAM_WITH_GS(programWithAtomicCounter, kVS, kGSWithAtomicCounters, kFS);
808 
809         params.fill(0);
810         index = glGetProgramResourceIndex(programWithAtomicCounter, GL_UNIFORM, "gs_counter");
811         EXPECT_GL_NO_ERROR();
812         glGetProgramResourceiv(programWithAtomicCounter, GL_ATOMIC_COUNTER_BUFFER, index,
813                                kPropCount, kProps, kPropCount, &length, params.data());
814         EXPECT_GL_NO_ERROR();
815         EXPECT_EQ(1, params[0]);
816     }
817 }
818 
callFramebufferTextureAPI(APIExtensionVersion usedExtension,GLenum target,GLenum attachment,GLuint texture,GLint level)819 void GeometryShaderTest::callFramebufferTextureAPI(APIExtensionVersion usedExtension,
820                                                    GLenum target,
821                                                    GLenum attachment,
822                                                    GLuint texture,
823                                                    GLint level)
824 {
825     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES ||
826            usedExtension == APIExtensionVersion::Core);
827     if (usedExtension == APIExtensionVersion::EXT)
828     {
829         glFramebufferTextureEXT(target, attachment, texture, level);
830     }
831     else if (usedExtension == APIExtensionVersion::OES)
832     {
833         glFramebufferTextureOES(target, attachment, texture, level);
834     }
835     else
836     {
837         glFramebufferTexture(target, attachment, texture, level);
838     }
839 }
840 
testNegativeFramebufferTexture(APIExtensionVersion usedExtension)841 void GeometryShaderTest::testNegativeFramebufferTexture(APIExtensionVersion usedExtension)
842 {
843     ASSERT(usedExtension == APIExtensionVersion::EXT || usedExtension == APIExtensionVersion::OES ||
844            usedExtension == APIExtensionVersion::Core);
845 
846     GLFramebuffer fbo;
847     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
848 
849     GLTexture tex;
850     glBindTexture(GL_TEXTURE_3D, tex);
851     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 32, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, nullptr);
852 
853     // [EXT_geometry_shader] Section 9.2.8, "Attaching Texture Images to a Framebuffer"
854     // An INVALID_ENUM error is generated if <target> is not DRAW_FRAMEBUFFER, READ_FRAMEBUFFER, or
855     // FRAMEBUFFER.
856     callFramebufferTextureAPI(usedExtension, GL_TEXTURE_2D, GL_COLOR_ATTACHMENT0, tex, 0);
857     EXPECT_GL_ERROR(GL_INVALID_ENUM);
858 
859     // An INVALID_ENUM error is generated if <attachment> is not one of the attachments in Table
860     // 9.1.
861     callFramebufferTextureAPI(usedExtension, GL_FRAMEBUFFER, GL_TEXTURE_2D, tex, 0);
862     EXPECT_GL_ERROR(GL_INVALID_ENUM);
863 
864     // An INVALID_OPERATION error is generated if zero is bound to <target>.
865     glBindFramebuffer(GL_FRAMEBUFFER, 0);
866     callFramebufferTextureAPI(usedExtension, GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
867     EXPECT_GL_ERROR(GL_INVALID_OPERATION);
868 
869     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
870 
871     // An INVALID_VALUE error is generated if <texture> is not the name of a texture object, or if
872     // <level> is not a supported texture level for <texture>.
873     GLuint tex2;
874     glGenTextures(1, &tex2);
875     glDeleteTextures(1, &tex2);
876     ASSERT_FALSE(glIsTexture(tex2));
877     callFramebufferTextureAPI(usedExtension, GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex2, 0);
878     EXPECT_GL_ERROR(GL_INVALID_VALUE);
879 
880     GLint max3DSize;
881     glGetIntegerv(GL_MAX_3D_TEXTURE_SIZE, &max3DSize);
882     GLint max3DLevel = static_cast<GLint>(std::log2(max3DSize));
883     callFramebufferTextureAPI(usedExtension, GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex,
884                               max3DLevel + 1);
885     EXPECT_GL_ERROR(GL_INVALID_VALUE);
886 }
887 
888 // Verify that correct errors are reported when we use illegal parameters in FramebufferTextureEXT.
TEST_P(GeometryShaderTest,NegativeFramebufferTextureEXT)889 TEST_P(GeometryShaderTest, NegativeFramebufferTextureEXT)
890 {
891     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
892     testNegativeFramebufferTexture(APIExtensionVersion::EXT);
893 }
894 
895 // Verify that correct errors are reported when we use illegal parameters in FramebufferTextureOES.
TEST_P(GeometryShaderTest,NegativeFramebufferTextureOES)896 TEST_P(GeometryShaderTest, NegativeFramebufferTextureOES)
897 {
898     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_OES_geometry_shader"));
899     testNegativeFramebufferTexture(APIExtensionVersion::OES);
900 }
901 
902 // Verify CheckFramebufferStatus can work correctly on layered depth and stencil attachments.
TEST_P(GeometryShaderTest,LayeredFramebufferCompletenessWithDepthAttachment)903 TEST_P(GeometryShaderTest, LayeredFramebufferCompletenessWithDepthAttachment)
904 {
905     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
906 
907     GLint maxFramebufferLayers;
908     glGetIntegerv(GL_MAX_FRAMEBUFFER_LAYERS_EXT, &maxFramebufferLayers);
909 
910     constexpr GLint kTexLayers = 2;
911     ASSERT_LT(kTexLayers, maxFramebufferLayers);
912 
913     GLTexture layeredColorTex;
914     glBindTexture(GL_TEXTURE_3D, layeredColorTex);
915     glTexImage3D(GL_TEXTURE_3D, 0, GL_RGBA8, 32, 32, kTexLayers, 0, GL_RGBA, GL_UNSIGNED_BYTE,
916                  nullptr);
917 
918     // [EXT_geometry_shader] section 9.4.1, "Framebuffer Completeness"
919     // If any framebuffer attachment is layered, all populated attachments must be layered.
920     // {FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT }
921     GLTexture layeredDepthStencilTex;
922     glBindTexture(GL_TEXTURE_2D_ARRAY, layeredDepthStencilTex);
923     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH24_STENCIL8, 32, 32, kTexLayers, 0,
924                  GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
925 
926     // 1. Color attachment is layered, while depth attachment is not layered.
927     GLFramebuffer fbo1;
928     glBindFramebuffer(GL_FRAMEBUFFER, fbo1);
929     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, layeredColorTex, 0);
930     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, layeredDepthStencilTex, 0, 0);
931     GLenum status1 = glCheckFramebufferStatus(GL_FRAMEBUFFER);
932     ASSERT_GL_NO_ERROR();
933     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT, status1);
934 
935     // 2. Color attachment is not layered, while depth attachment is layered.
936     GLFramebuffer fbo2;
937     glBindFramebuffer(GL_FRAMEBUFFER, fbo2);
938     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, layeredColorTex, 0, 0);
939     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, layeredDepthStencilTex, 0);
940     GLenum status2 = glCheckFramebufferStatus(GL_FRAMEBUFFER);
941     ASSERT_GL_NO_ERROR();
942     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT, status2);
943 
944     // 3. Color attachment is not layered, while stencil attachment is layered.
945     GLFramebuffer fbo3;
946     glBindFramebuffer(GL_FRAMEBUFFER, fbo3);
947     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, layeredColorTex, 0, 0);
948     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, layeredDepthStencilTex, 0);
949     GLenum status3 = glCheckFramebufferStatus(GL_FRAMEBUFFER);
950     ASSERT_GL_NO_ERROR();
951     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT, status3);
952 
953     // [EXT_geometry_shader] section 9.4.1, "Framebuffer Completeness"
954     // If <image> is a three-dimensional texture or a two-dimensional array texture and the
955     // attachment is layered, the depth or layer count, respectively, of the texture is less than or
956     // equal to the value of MAX_FRAMEBUFFER_LAYERS_EXT.
957     GLint maxArrayTextureLayers;
958     glGetIntegerv(GL_MAX_ARRAY_TEXTURE_LAYERS, &maxArrayTextureLayers);
959     GLint depthTexLayer4 = maxFramebufferLayers + 1;
960     ANGLE_SKIP_TEST_IF(maxArrayTextureLayers < depthTexLayer4);
961 
962     // Use a depth attachment whose layer count exceeds MAX_FRAMEBUFFER_LAYERS
963     GLTexture depthTex4;
964     glBindTexture(GL_TEXTURE_2D_ARRAY, depthTex4);
965     glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_DEPTH24_STENCIL8, 32, 32, depthTexLayer4, 0,
966                  GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, nullptr);
967     GLFramebuffer fbo4;
968     glBindFramebuffer(GL_FRAMEBUFFER, fbo4);
969     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthTex4, 0);
970     GLenum status4 = glCheckFramebufferStatus(GL_FRAMEBUFFER);
971     ASSERT_GL_NO_ERROR();
972     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, status4);
973 }
974 
975 // Verify correct errors can be reported when we use layered cube map attachments on a framebuffer.
TEST_P(GeometryShaderTest,NegativeLayeredFramebufferCompletenessWithCubeMapTextures)976 TEST_P(GeometryShaderTest, NegativeLayeredFramebufferCompletenessWithCubeMapTextures)
977 {
978     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
979 
980     GLTexture tex;
981     glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
982 
983     GLFramebuffer fbo;
984     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
985     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
986     GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
987     ASSERT_GL_NO_ERROR();
988     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, status);
989 
990     glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, 64, 64, 0, GL_RGBA, GL_UNSIGNED_BYTE,
991                  nullptr);
992     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, tex, 0);
993     ASSERT_GL_NO_ERROR();
994     EXPECT_GLENUM_EQ(GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT, status);
995 }
996 
997 // Verify that we can use default interpolation in the GS.
TEST_P(GeometryShaderTest,FlatQualifierNotRequired)998 TEST_P(GeometryShaderTest, FlatQualifierNotRequired)
999 {
1000     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1001 
1002     constexpr char kGS[] = R"(#version 310 es
1003 #extension GL_EXT_geometry_shader : require
1004 layout(points) in;
1005 layout(points, max_vertices=1) out;
1006 
1007 in highp int target[];
1008 highp uniform vec4 dummyZero; // Default value is vec4(0.0).
1009 
1010 void main()
1011 {
1012     highp vec4 retValue = dummyZero;
1013     retValue += vec4(float(target[0]));
1014     retValue += gl_in[0].gl_Position;
1015     gl_Position = retValue;
1016     EmitVertex();
1017 })";
1018 
1019     GLuint geometryShader = CompileShader(GL_GEOMETRY_SHADER_EXT, kGS);
1020 
1021     EXPECT_NE(0u, geometryShader);
1022 
1023     GLuint programID = glCreateProgram();
1024     glAttachShader(programID, geometryShader);
1025 
1026     glDetachShader(programID, geometryShader);
1027     glDeleteShader(geometryShader);
1028     glDeleteProgram(programID);
1029 
1030     EXPECT_GL_NO_ERROR();
1031 }
1032 
setupLayeredFramebuffer(GLuint framebuffer,GLuint color0,GLuint color1,GLuint depthStencil,GLenum colorTarget,const GLColor & color0InitialColor,const GLColor & color1InitialColor,float depthInitialValue,GLint stencilInitialValue)1033 void GeometryShaderTest::setupLayeredFramebuffer(GLuint framebuffer,
1034                                                  GLuint color0,
1035                                                  GLuint color1,
1036                                                  GLuint depthStencil,
1037                                                  GLenum colorTarget,
1038                                                  const GLColor &color0InitialColor,
1039                                                  const GLColor &color1InitialColor,
1040                                                  float depthInitialValue,
1041                                                  GLint stencilInitialValue)
1042 {
1043     const uint32_t depthInitialValueUnorm   = static_cast<uint32_t>(depthInitialValue * 0xFFFFFF);
1044     const uint32_t depthStencilInitialValue = depthInitialValueUnorm << 8 | stencilInitialValue;
1045 
1046     const std::vector<GLColor> kColor0InitData(kWidth * kHeight * kColor0Layers,
1047                                                color0InitialColor);
1048     const std::vector<GLColor> kColor1InitData(kWidth * kHeight * kColor1Layers,
1049                                                color1InitialColor);
1050     const std::vector<uint32_t> kDepthStencilInitData(kWidth * kHeight * kDepthStencilLayers,
1051                                                       depthStencilInitialValue);
1052 
1053     glBindFramebuffer(GL_FRAMEBUFFER, framebuffer);
1054     ASSERT_GL_NO_ERROR();
1055 
1056     glBindTexture(colorTarget, color0);
1057     glTexStorage3D(colorTarget, 1, GL_RGBA8, kWidth, kHeight, kColor0Layers);
1058     glTexSubImage3D(colorTarget, 0, 0, 0, 0, kWidth, kHeight, kColor0Layers, GL_RGBA,
1059                     GL_UNSIGNED_BYTE, kColor0InitData.data());
1060     ASSERT_GL_NO_ERROR();
1061 
1062     glBindTexture(colorTarget, color1);
1063     glTexStorage3D(colorTarget, 1, GL_RGBA8, kWidth, kHeight, kColor1Layers);
1064     glTexSubImage3D(colorTarget, 0, 0, 0, 0, kWidth, kHeight, kColor1Layers, GL_RGBA,
1065                     GL_UNSIGNED_BYTE, kColor1InitData.data());
1066     ASSERT_GL_NO_ERROR();
1067 
1068     glBindTexture(GL_TEXTURE_2D_ARRAY, depthStencil);
1069     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_DEPTH24_STENCIL8, kWidth, kHeight,
1070                    kDepthStencilLayers);
1071     glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, 0, kWidth, kHeight, kDepthStencilLayers,
1072                     GL_DEPTH_STENCIL, GL_UNSIGNED_INT_24_8, kDepthStencilInitData.data());
1073     ASSERT_GL_NO_ERROR();
1074 
1075     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color0, 0);
1076     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, color1, 0);
1077     glFramebufferTextureEXT(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencil, 0);
1078 
1079     constexpr GLenum kDrawBuffers[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
1080     glDrawBuffers(2, kDrawBuffers);
1081 
1082     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1083 }
1084 
setupLayeredFramebufferProgram(GLProgram * program)1085 void GeometryShaderTest::setupLayeredFramebufferProgram(GLProgram *program)
1086 {
1087     constexpr char kVS[] = R"(#version 310 es
1088 
1089 in highp vec4 position;
1090 
1091 void main()
1092 {
1093     gl_Position = position;
1094 })";
1095 
1096     static_assert(kFramebufferLayers == 3,
1097                   "Adjust the invocations parameter in the geometry shader, and color arrays in "
1098                   "fragment shader");
1099 
1100     constexpr char kGS[] = R"(#version 310 es
1101 #extension GL_EXT_geometry_shader : require
1102 layout (invocations = 3, triangles) in;
1103 layout (triangle_strip, max_vertices = 3) out;
1104 
1105 void main()
1106 {
1107     for (int n = 0; n < gl_in.length(); n++)
1108     {
1109         gl_Position = gl_in[n].gl_Position;
1110         gl_Layer = gl_InvocationID;
1111         EmitVertex();
1112     }
1113     EndPrimitive();
1114 })";
1115 
1116     constexpr char kFS[] = R"(#version 310 es
1117 #extension GL_EXT_geometry_shader : require
1118 precision mediump float;
1119 
1120 layout(location = 0) out mediump vec4 color0;
1121 layout(location = 1) out mediump vec4 color1;
1122 
1123 const vec4 color0Layers[3] = vec4[](
1124     vec4(1, 0, 0, 1),
1125     vec4(0, 1, 0, 1),
1126     vec4(0, 0, 1, 1)
1127 );
1128 
1129 const vec4 color1Layers[3] = vec4[](
1130     vec4(1, 1, 0, 1),
1131     vec4(0, 1, 1, 1),
1132     vec4(1, 0, 1, 1)
1133 );
1134 
1135 void main()
1136 {
1137     color0 = color0Layers[gl_Layer];
1138     color1 = color1Layers[gl_Layer];
1139 })";
1140 
1141     program->makeRaster(kVS, kGS, kFS);
1142     ASSERT_TRUE(program->valid());
1143 }
1144 
verifyLayeredFramebufferColor(GLuint colorTexture,GLenum colorTarget,const GLColor expected[],GLsizei layerCount)1145 void GeometryShaderTest::verifyLayeredFramebufferColor(GLuint colorTexture,
1146                                                        GLenum colorTarget,
1147                                                        const GLColor expected[],
1148                                                        GLsizei layerCount)
1149 {
1150     // Note: the OpenGL and Vulkan specs are unclear regarding whether clear should affect all
1151     // layers of the framebuffer or the attachment.  The GL spec says:
1152     //
1153     // > When the Clear or ClearBuffer* commands described in section 15.2.3 are
1154     // > used to clear a layered framebuffer attachment, all layers of the attachment are
1155     // > cleared.
1156     //
1157     // Which implies that all layers are cleared.  However, it's common among vendors to consider
1158     // only the attachments accessible to a draw call to be affected by clear (otherwise
1159     // clear-through-draw cannot be done).
1160     //
1161     // There is inconsistency between implementations in both the OpenGL and Vulkan implementations
1162     // in this regard.  In OpenGL, Qualcomm and Intel drivers clear all layers while Nvidia drivers
1163     // clear only the framebuffer layers.  In Vulkan, Intel and AMD windows drivers clear all layers
1164     // with loadOp=CLEAR, while the other implementations (including Intel mesa) only clear the
1165     // framebuffer layers.
1166     //
1167     // Due to this inconsistency, only the framebuffer layers are verified.  The other layers, if
1168     // the texture has them will either contain the initial or the cleared color, but is not
1169     // verified by these tests.
1170     layerCount = kFramebufferLayers;
1171 
1172     GLFramebuffer fbo;
1173     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1174 
1175     glBindTexture(colorTarget, colorTexture);
1176 
1177     for (GLsizei layer = 0; layer < layerCount; ++layer)
1178     {
1179         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colorTexture, 0, layer);
1180         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1181 
1182         EXPECT_PIXEL_COLOR_NEAR(0, 0, expected[layer], 1);
1183         EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, 0, expected[layer], 1);
1184         EXPECT_PIXEL_COLOR_NEAR(0, kHeight - 1, expected[layer], 1);
1185         EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, kHeight - 1, expected[layer], 1);
1186     }
1187 }
1188 
verifyLayeredFramebufferDepthStencil(GLuint depthStencilTexture,const float expectedDepth[],const GLint expectedStencil[],GLsizei layerCount)1189 void GeometryShaderTest::verifyLayeredFramebufferDepthStencil(GLuint depthStencilTexture,
1190                                                               const float expectedDepth[],
1191                                                               const GLint expectedStencil[],
1192                                                               GLsizei layerCount)
1193 {
1194     // See comment in verifyLayeredFramebufferColor
1195     layerCount = kFramebufferLayers;
1196 
1197     // Setup program
1198     ANGLE_GL_PROGRAM(drawColor, essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
1199     glUseProgram(drawColor);
1200     GLint colorUniformLocation =
1201         glGetUniformLocation(drawColor, angle::essl1_shaders::ColorUniform());
1202     ASSERT_NE(colorUniformLocation, -1);
1203 
1204     // Set up state to validate depth and stencil
1205     glEnable(GL_DEPTH_TEST);
1206     glEnable(GL_STENCIL_TEST);
1207     glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
1208     glStencilMask(0xFF);
1209     glClearColor(0, 0, 0, 0);
1210 
1211     // Set up framebuffer
1212     GLFramebuffer fbo;
1213     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1214 
1215     GLTexture color;
1216     glBindTexture(GL_TEXTURE_2D, color);
1217     glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, kWidth, kHeight);
1218 
1219     glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, color, 0);
1220 
1221     glBindTexture(GL_TEXTURE_2D_ARRAY, depthStencilTexture);
1222 
1223     for (GLsizei layer = 0; layer < layerCount; ++layer)
1224     {
1225         glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, depthStencilTexture,
1226                                   0, layer);
1227         EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1228 
1229         glClear(GL_COLOR_BUFFER_BIT);
1230 
1231         glStencilFunc(GL_EQUAL, expectedStencil[layer], 0xFF);
1232 
1233         // Pass depth slightly less than expected
1234         glDepthFunc(GL_LESS);
1235         glUniform4f(colorUniformLocation, 0.1f, 0.2f, 0.3f, 0.4f);
1236         drawQuad(drawColor, essl1_shaders::PositionAttrib(), expectedDepth[layer] * 2 - 1 - 0.01f);
1237 
1238         // Fail depth slightly greater than expected
1239         glUniform4f(colorUniformLocation, 0.5f, 0.6f, 0.7f, 0.8f);
1240         drawQuad(drawColor, essl1_shaders::PositionAttrib(), expectedDepth[layer] * 2 - 1 + 0.01f);
1241 
1242         ASSERT_GL_NO_ERROR();
1243 
1244         // Verify results
1245         const GLColor kExpected(25, 51, 76, 102);
1246 
1247         EXPECT_PIXEL_COLOR_NEAR(0, 0, kExpected, 1);
1248         EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, 0, kExpected, 1);
1249         EXPECT_PIXEL_COLOR_NEAR(0, kHeight - 1, kExpected, 1);
1250         EXPECT_PIXEL_COLOR_NEAR(kWidth - 1, kHeight - 1, kExpected, 1);
1251     }
1252 }
1253 
layeredFramebufferClearTest(GLenum colorTarget)1254 void GeometryShaderTest::layeredFramebufferClearTest(GLenum colorTarget)
1255 {
1256     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1257 
1258     const GLColor kColor0InitColor(10, 20, 30, 40);
1259     const GLColor kColor1InitColor(200, 210, 220, 230);
1260     constexpr float kDepthInitValue   = 0.35f;
1261     constexpr GLint kStencilInitValue = 0x33;
1262 
1263     GLFramebuffer framebuffer;
1264     GLTexture color0;
1265     GLTexture color1;
1266     GLTexture depthStencil;
1267     GLProgram program;
1268 
1269     setupLayeredFramebuffer(framebuffer, color0, color1, depthStencil, colorTarget,
1270                             kColor0InitColor, kColor1InitColor, kDepthInitValue, kStencilInitValue);
1271     setupLayeredFramebufferProgram(&program);
1272 
1273     glClearColor(0.5, 0.5, 0.5, 0.5);
1274     glClearDepthf(1.0f);
1275     glClearStencil(0x55);
1276     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1277 
1278     const GLColor kClearColor(127, 127, 127, 127);
1279     const GLColor kExpectedColor0[kColor0Layers] = {
1280         kClearColor,
1281         kClearColor,
1282         kClearColor,
1283         kColor0InitColor,
1284     };
1285     const GLColor kExpectedColor1[kColor1Layers] = {
1286         kClearColor,
1287         kClearColor,
1288         kClearColor,
1289     };
1290     const float kExpectedDepth[kDepthStencilLayers] = {
1291         1.0f, 1.0f, 1.0f, kDepthInitValue, kDepthInitValue,
1292     };
1293     const GLint kExpectedStencil[kDepthStencilLayers] = {
1294         0x55, 0x55, 0x55, kStencilInitValue, kStencilInitValue,
1295     };
1296 
1297     verifyLayeredFramebufferColor(color0, colorTarget, kExpectedColor0, kColor0Layers);
1298     verifyLayeredFramebufferColor(color1, colorTarget, kExpectedColor1, kColor1Layers);
1299     verifyLayeredFramebufferDepthStencil(depthStencil, kExpectedDepth, kExpectedStencil,
1300                                          kDepthStencilLayers);
1301 }
1302 
1303 // Verify clear of layered attachments.  Uses 3D color textures.
TEST_P(GeometryShaderTest,LayeredFramebufferClear3DColor)1304 TEST_P(GeometryShaderTest, LayeredFramebufferClear3DColor)
1305 {
1306     // Mesa considers the framebuffer with mixed 3D and 2D array attachments to be incomplete.
1307     // http://anglebug.com/42264003
1308     ANGLE_SKIP_TEST_IF((IsAMD() || IsIntel()) && IsOpenGL() && IsLinux());
1309 
1310     layeredFramebufferClearTest(GL_TEXTURE_3D);
1311 }
1312 
1313 // Verify clear of layered attachments.  Uses 2D array color textures.
TEST_P(GeometryShaderTest,LayeredFramebufferClear2DArrayColor)1314 TEST_P(GeometryShaderTest, LayeredFramebufferClear2DArrayColor)
1315 {
1316     layeredFramebufferClearTest(GL_TEXTURE_2D_ARRAY);
1317 }
1318 
layeredFramebufferPreRenderClearTest(GLenum colorTarget,bool doubleClear)1319 void GeometryShaderTest::layeredFramebufferPreRenderClearTest(GLenum colorTarget, bool doubleClear)
1320 {
1321     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1322 
1323     const GLColor kColor0InitColor(10, 20, 30, 40);
1324     const GLColor kColor1InitColor(200, 210, 220, 230);
1325     constexpr float kDepthInitValue   = 0.35f;
1326     constexpr GLint kStencilInitValue = 0x33;
1327 
1328     GLFramebuffer framebuffer;
1329     GLTexture color0;
1330     GLTexture color1;
1331     GLTexture depthStencil;
1332     GLProgram program;
1333 
1334     setupLayeredFramebuffer(framebuffer, color0, color1, depthStencil, colorTarget,
1335                             kColor0InitColor, kColor1InitColor, kDepthInitValue, kStencilInitValue);
1336     setupLayeredFramebufferProgram(&program);
1337 
1338     if (doubleClear)
1339     {
1340         glClearColor(0.1, 0.2, 0.8, 0.9);
1341         glClearDepthf(0.2f);
1342         glClearStencil(0x99);
1343         glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1344     }
1345 
1346     glClearColor(0.5, 0.5, 0.5, 0.5);
1347     glClearDepthf(1.0f);
1348     glClearStencil(0x55);
1349     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1350 
1351     glEnable(GL_DEPTH_TEST);
1352     glDepthFunc(GL_LESS);
1353 
1354     glEnable(GL_STENCIL_TEST);
1355     glStencilFunc(GL_EQUAL, 0x5A, 0xF0);
1356     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1357     glStencilMask(0xFF);
1358 
1359     drawQuad(program, "position", 0.9f);
1360 
1361     const GLColor kExpectedColor0[kColor0Layers] = {
1362         GLColor::red,
1363         GLColor::green,
1364         GLColor::blue,
1365         kColor0InitColor,
1366     };
1367     const GLColor kExpectedColor1[kColor1Layers] = {
1368         GLColor::yellow,
1369         GLColor::cyan,
1370         GLColor::magenta,
1371     };
1372     const float kExpectedDepth[kDepthStencilLayers] = {
1373         0.95f, 0.95f, 0.95f, kDepthInitValue, kDepthInitValue,
1374     };
1375     const GLint kExpectedStencil[kDepthStencilLayers] = {
1376         0x5A, 0x5A, 0x5A, kStencilInitValue, kStencilInitValue,
1377     };
1378 
1379     verifyLayeredFramebufferColor(color0, colorTarget, kExpectedColor0, kColor0Layers);
1380     verifyLayeredFramebufferColor(color1, colorTarget, kExpectedColor1, kColor1Layers);
1381     verifyLayeredFramebufferDepthStencil(depthStencil, kExpectedDepth, kExpectedStencil,
1382                                          kDepthStencilLayers);
1383 }
1384 
1385 // Verify pre-render clear of layered attachments.  Uses 3D color textures.
TEST_P(GeometryShaderTest,LayeredFramebufferPreRenderClear3DColor)1386 TEST_P(GeometryShaderTest, LayeredFramebufferPreRenderClear3DColor)
1387 {
1388     // Mesa considers the framebuffer with mixed 3D and 2D array attachments to be incomplete.
1389     // http://anglebug.com/42264003
1390     ANGLE_SKIP_TEST_IF((IsAMD() || IsIntel()) && IsOpenGL() && IsLinux());
1391 
1392     layeredFramebufferPreRenderClearTest(GL_TEXTURE_3D, false);
1393 }
1394 
1395 // Same as LayeredFramebufferPreRenderClear3DColor, but clears twice.
TEST_P(GeometryShaderTest,LayeredFramebufferPreRenderDoubleClear3DColor)1396 TEST_P(GeometryShaderTest, LayeredFramebufferPreRenderDoubleClear3DColor)
1397 {
1398     // Mesa considers the framebuffer with mixed 3D and 2D array attachments to be incomplete.
1399     // http://anglebug.com/42264003
1400     ANGLE_SKIP_TEST_IF((IsAMD() || IsIntel()) && IsOpenGL() && IsLinux());
1401 
1402     layeredFramebufferPreRenderClearTest(GL_TEXTURE_3D, true);
1403 }
1404 
1405 // Verify pre-render clear of layered attachments.  Uses 2D array color textures.
TEST_P(GeometryShaderTest,LayeredFramebufferPreRenderClear2DArrayColor)1406 TEST_P(GeometryShaderTest, LayeredFramebufferPreRenderClear2DArrayColor)
1407 {
1408     layeredFramebufferPreRenderClearTest(GL_TEXTURE_2D_ARRAY, false);
1409 }
1410 
1411 // Same as LayeredFramebufferPreRenderClear2DArrayColor, but clears twice.
TEST_P(GeometryShaderTest,LayeredFramebufferPreRenderDoubleClear2DArrayColor)1412 TEST_P(GeometryShaderTest, LayeredFramebufferPreRenderDoubleClear2DArrayColor)
1413 {
1414     layeredFramebufferPreRenderClearTest(GL_TEXTURE_2D_ARRAY, true);
1415 }
1416 
layeredFramebufferMidRenderClearTest(GLenum colorTarget)1417 void GeometryShaderTest::layeredFramebufferMidRenderClearTest(GLenum colorTarget)
1418 {
1419     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1420 
1421     // Vulkan's draw path for clear doesn't support layered framebuffers.
1422     // http://anglebug.com/42263992
1423     ANGLE_SKIP_TEST_IF(IsVulkan());
1424 
1425     const GLColor kColor0InitColor(10, 20, 30, 40);
1426     const GLColor kColor1InitColor(200, 210, 220, 230);
1427     constexpr float kDepthInitValue   = 0.35f;
1428     constexpr GLint kStencilInitValue = 0x33;
1429 
1430     GLFramebuffer framebuffer;
1431     GLTexture color0;
1432     GLTexture color1;
1433     GLTexture depthStencil;
1434     GLProgram program;
1435 
1436     setupLayeredFramebuffer(framebuffer, color0, color1, depthStencil, colorTarget,
1437                             kColor0InitColor, kColor1InitColor, kDepthInitValue, kStencilInitValue);
1438     setupLayeredFramebufferProgram(&program);
1439 
1440     glEnable(GL_DEPTH_TEST);
1441     glDepthFunc(GL_ALWAYS);
1442 
1443     glEnable(GL_STENCIL_TEST);
1444     glStencilFunc(GL_ALWAYS, 0x55, 0xF0);
1445     glStencilOp(GL_REPLACE, GL_REPLACE, GL_REPLACE);
1446     glStencilMask(0xFF);
1447 
1448     drawQuad(program, "position", 0.3f);
1449 
1450     glColorMask(GL_FALSE, GL_FALSE, GL_TRUE, GL_TRUE);
1451     glClearColor(0.5, 0.5, 0.5, 0.5);
1452     glClearDepthf(0.8f);
1453     glStencilMask(0xF0);
1454     glClearStencil(0xAA);
1455     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
1456 
1457     glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
1458     glStencilMask(0xFF);
1459 
1460     const GLColor kExpectedColor0[kColor0Layers] = {
1461         GLColor(255, 0, 127, 127),
1462         GLColor(0, 255, 127, 127),
1463         GLColor(0, 0, 127, 127),
1464         kColor0InitColor,
1465     };
1466     const GLColor kExpectedColor1[kColor1Layers] = {
1467         GLColor(255, 255, 127, 127),
1468         GLColor(0, 255, 127, 127),
1469         GLColor(255, 0, 127, 127),
1470     };
1471     const float kExpectedDepth[kDepthStencilLayers] = {
1472         0.6f, 0.6f, 0.6f, kDepthInitValue, kDepthInitValue,
1473     };
1474     const GLint kExpectedStencil[kDepthStencilLayers] = {
1475         0xA5, 0xA5, 0xA5, kStencilInitValue, kStencilInitValue,
1476     };
1477 
1478     verifyLayeredFramebufferColor(color0, colorTarget, kExpectedColor0, kColor0Layers);
1479     verifyLayeredFramebufferColor(color1, colorTarget, kExpectedColor1, kColor1Layers);
1480     verifyLayeredFramebufferDepthStencil(depthStencil, kExpectedDepth, kExpectedStencil,
1481                                          kDepthStencilLayers);
1482 }
1483 
1484 // Verify that Geometry Shader's gl_Layer is ineffective when the framebuffer is not layered.
TEST_P(GeometryShaderTest,GLLayerIneffectiveWithoutLayeredFramebuffer)1485 TEST_P(GeometryShaderTest, GLLayerIneffectiveWithoutLayeredFramebuffer)
1486 {
1487     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1488 
1489     constexpr char kVS[] = R"(#version 310 es
1490 in highp vec4 position;
1491 void main()
1492 {
1493     gl_Position = position;
1494 })";
1495 
1496     constexpr char kGS[] = R"(#version 310 es
1497 #extension GL_EXT_geometry_shader : require
1498 layout (invocations = 3, triangles) in;
1499 layout (triangle_strip, max_vertices = 3) out;
1500 
1501 void main()
1502 {
1503     for (int n = 0; n < gl_in.length(); n++)
1504     {
1505         gl_Position = gl_in[n].gl_Position;
1506         gl_Layer = gl_InvocationID;
1507         EmitVertex();
1508     }
1509     EndPrimitive();
1510 })";
1511 
1512     constexpr char kFS[] = R"(#version 310 es
1513 #extension GL_EXT_geometry_shader : require
1514 precision mediump float;
1515 
1516 layout(location = 0) out mediump vec4 color;
1517 
1518 void main()
1519 {
1520     if (gl_Layer == 0)
1521         color = vec4(0, 1, 0, 1);
1522     else
1523         color = vec4(1, 0, 0, 1);
1524 })";
1525 
1526     ANGLE_GL_PROGRAM_WITH_GS(program, kVS, kGS, kFS);
1527     EXPECT_GL_NO_ERROR();
1528 
1529     GLFramebuffer fbo;
1530     GLTexture color;
1531 
1532     glBindTexture(GL_TEXTURE_2D_ARRAY, color);
1533     glTexStorage3D(GL_TEXTURE_2D_ARRAY, 1, GL_RGBA8, kWidth, kHeight, 4);
1534 
1535     glBindFramebuffer(GL_FRAMEBUFFER, fbo);
1536     glFramebufferTextureLayer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, color, 0, 1);
1537     EXPECT_GL_FRAMEBUFFER_COMPLETE(GL_FRAMEBUFFER);
1538 
1539     drawQuad(program, "position", 0.3f);
1540 
1541     EXPECT_PIXEL_RECT_EQ(0, 0, kWidth, kHeight, GLColor::green);
1542     ASSERT_GL_NO_ERROR();
1543 }
1544 
1545 // Verify mid-render clear of layered attachments.  Uses 3D color textures.
TEST_P(GeometryShaderTest,LayeredFramebufferMidRenderClear3DColor)1546 TEST_P(GeometryShaderTest, LayeredFramebufferMidRenderClear3DColor)
1547 {
1548     // Mesa considers the framebuffer with mixed 3D and 2D array attachments to be incomplete.
1549     // http://anglebug.com/42264003
1550     ANGLE_SKIP_TEST_IF((IsAMD() || IsIntel()) && IsOpenGL() && IsLinux());
1551 
1552     layeredFramebufferMidRenderClearTest(GL_TEXTURE_3D);
1553 }
1554 
1555 // Verify mid-render clear of layered attachments.  Uses 2D array color textures.
TEST_P(GeometryShaderTest,LayeredFramebufferMidRenderClear2DArrayColor)1556 TEST_P(GeometryShaderTest, LayeredFramebufferMidRenderClear2DArrayColor)
1557 {
1558     layeredFramebufferMidRenderClearTest(GL_TEXTURE_2D_ARRAY);
1559 }
1560 
1561 // Verify that prerotation applies to the geometry shader stage if present.
TEST_P(GeometryShaderTest,Prerotation)1562 TEST_P(GeometryShaderTest, Prerotation)
1563 {
1564     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1565 
1566     constexpr char kVS[] = R"(#version 310 es
1567 void main()
1568 {
1569     // Geometry shader will output fixed positions, so this is ignored.
1570     gl_Position = vec4(0);
1571 })";
1572 
1573     constexpr char kGS[] = R"(#version 310 es
1574 #extension GL_EXT_geometry_shader : require
1575 layout (triangles) in;
1576 layout (triangle_strip, max_vertices = 4) out;
1577 
1578 void main()
1579 {
1580     // Generate two triangles to cover the lower-left quarter of the screen.
1581     gl_Position = vec4(0, -1, 0, 1);
1582     EmitVertex();
1583 
1584     gl_Position = vec4(0, 0, 0, 1);
1585     EmitVertex();
1586 
1587     gl_Position = vec4(-1, -1, 0, 1);
1588     EmitVertex();
1589 
1590     gl_Position = vec4(-1, 0, 0, 1);
1591     EmitVertex();
1592 
1593     EndPrimitive();
1594 })";
1595 
1596     constexpr char kFS[] = R"(#version 310 es
1597 #extension GL_EXT_shader_io_blocks : require
1598 precision mediump float;
1599 
1600 layout(location = 0) out mediump vec4 color;
1601 
1602 void main()
1603 {
1604     // Output solid green
1605     color = vec4(0, 1.0, 0, 1.0);
1606 })";
1607 
1608     ANGLE_GL_PROGRAM_WITH_GS(program, kVS, kGS, kFS);
1609     EXPECT_GL_NO_ERROR();
1610 
1611     glClearColor(1.0, 0, 0, 1.0);
1612     glClear(GL_COLOR_BUFFER_BIT);
1613 
1614     glUseProgram(program);
1615     glDrawArrays(GL_TRIANGLES, 0, 3);
1616 
1617     const int w = getWindowWidth();
1618     const int h = getWindowHeight();
1619 
1620     EXPECT_PIXEL_RECT_EQ(0, 0, w / 2, h / 2, GLColor::green);
1621     EXPECT_PIXEL_RECT_EQ(0, h / 2, w, h / 2, GLColor::red);
1622     EXPECT_PIXEL_RECT_EQ(w / 2, 0, w / 2, h / 2, GLColor::red);
1623 }
1624 
1625 // Verify that correct errors are reported when we use illegal parameters in FramebufferTexture.
TEST_P(GeometryShaderTestES32,NegativeFramebufferTexture)1626 TEST_P(GeometryShaderTestES32, NegativeFramebufferTexture)
1627 {
1628     testNegativeFramebufferTexture(APIExtensionVersion::Core);
1629 }
1630 
1631 // Verify that we can have the max amount of uniforms with a geometry shader.
TEST_P(GeometryShaderTestES32,MaxGeometryImageUniforms)1632 TEST_P(GeometryShaderTestES32, MaxGeometryImageUniforms)
1633 {
1634     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1635 
1636     GLint maxGeometryImageUnits;
1637     glGetIntegerv(GL_MAX_GEOMETRY_IMAGE_UNIFORMS_EXT, &maxGeometryImageUnits);
1638 
1639     const GLchar *vertString = essl31_shaders::vs::Simple();
1640     const GLchar *fragString = R"(#version 310 es
1641 precision highp float;
1642 out vec4 my_FragColor;
1643 void main()
1644 {
1645     my_FragColor = vec4(1.0);
1646 })";
1647 
1648     std::stringstream geomStringStream;
1649 
1650     geomStringStream << R"(#version 310 es
1651 #extension GL_OES_geometry_shader : require
1652 layout (points)                   in;
1653 layout (points, max_vertices = 1) out;
1654 
1655 precision highp iimage2D;
1656 
1657 ivec4 counter = ivec4(0);
1658 )";
1659 
1660     for (GLint index = 0; index < maxGeometryImageUnits; ++index)
1661     {
1662         geomStringStream << "layout(binding = " << index << ", r32i) uniform iimage2D img" << index
1663                          << ";" << std::endl;
1664     }
1665 
1666     geomStringStream << R"(
1667 void main()
1668 {
1669 )";
1670 
1671     for (GLint index = 0; index < maxGeometryImageUnits; ++index)
1672     {
1673         geomStringStream << "counter += imageLoad(img" << index << ", ivec2(0, 0));" << std::endl;
1674     }
1675 
1676     geomStringStream << R"(
1677     gl_Position = vec4(float(counter.x), 0.0, 0.0, 1.0);
1678     EmitVertex();
1679 }
1680 )";
1681 
1682     ANGLE_GL_PROGRAM_WITH_GS(program, vertString, geomStringStream.str().c_str(), fragString);
1683     EXPECT_GL_NO_ERROR();
1684 
1685     glClearColor(1.0, 0, 0, 1.0);
1686     glClear(GL_COLOR_BUFFER_BIT);
1687 
1688     glUseProgram(program);
1689 
1690     std::vector<GLTexture> textures(maxGeometryImageUnits);
1691     for (GLint index = 0; index < maxGeometryImageUnits; ++index)
1692     {
1693         GLint value = index + 1;
1694 
1695         glBindTexture(GL_TEXTURE_2D, textures[index]);
1696 
1697         glTexStorage2D(GL_TEXTURE_2D, 1 /*levels*/, GL_R32I, 1 /*width*/, 1 /*height*/);
1698 
1699         glTexSubImage2D(GL_TEXTURE_2D, 0 /*level*/, 0 /*xoffset*/, 0 /*yoffset*/, 1 /*width*/,
1700                         1 /*height*/, GL_RED_INTEGER, GL_INT, &value);
1701 
1702         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
1703 
1704         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
1705 
1706         glBindImageTexture(index, textures[index], 0 /*level*/, GL_FALSE /*is layered?*/,
1707                            0 /*layer*/, GL_READ_ONLY, GL_R32I);
1708     }
1709 
1710     glDrawArrays(GL_POINTS, 0, 3);
1711     EXPECT_GL_NO_ERROR();
1712 }
1713 
1714 // Verify that depth viewport transform applies to the geometry shader stage if present.
TEST_P(GeometryShaderTest,DepthViewportTransform)1715 TEST_P(GeometryShaderTest, DepthViewportTransform)
1716 {
1717     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1718 
1719     constexpr char kVS[] = R"(#version 310 es
1720 void main()
1721 {
1722     // Geometry shader will output fixed positions, so this is ignored.
1723     gl_Position = vec4(0);
1724 })";
1725 
1726     constexpr char kGS[] = R"(#version 310 es
1727 #extension GL_EXT_geometry_shader : require
1728 layout (triangles) in;
1729 layout (triangle_strip, max_vertices = 4) out;
1730 
1731 void main()
1732 {
1733     // Generate two triangles to cover the whole screen, with depth at -0.5.  After viewport
1734     // transformation, the depth buffer should contain 0.25.
1735     gl_Position = vec4(1, -1, -0.5, 1);
1736     EmitVertex();
1737 
1738     gl_Position = vec4(1, 1, -0.5, 1);
1739     EmitVertex();
1740 
1741     gl_Position = vec4(-1, -1, -0.5, 1);
1742     EmitVertex();
1743 
1744     gl_Position = vec4(-1, 1, -0.5, 1);
1745     EmitVertex();
1746 
1747     EndPrimitive();
1748 })";
1749 
1750     constexpr char kFS[] = R"(#version 310 es
1751 #extension GL_EXT_shader_io_blocks : require
1752 precision mediump float;
1753 
1754 layout(location = 0) out mediump vec4 color;
1755 
1756 void main()
1757 {
1758     // Output solid green
1759     color = vec4(0, 1.0, 0, 1.0);
1760 })";
1761 
1762     ANGLE_GL_PROGRAM_WITH_GS(program, kVS, kGS, kFS);
1763     EXPECT_GL_NO_ERROR();
1764 
1765     glClearColor(1.0, 0, 0, 1.0);
1766     glClear(GL_COLOR_BUFFER_BIT);
1767 
1768     glEnable(GL_DEPTH_TEST);
1769     glDepthFunc(GL_ALWAYS);
1770 
1771     glUseProgram(program);
1772     glDrawArrays(GL_TRIANGLES, 0, 3);
1773 
1774     const int w = getWindowWidth();
1775     const int h = getWindowHeight();
1776 
1777     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::green);
1778 
1779     // Verify depth
1780     glDepthFunc(GL_LESS);
1781 
1782     // An epsilon below the depth value should pass the depth test
1783     ANGLE_GL_PROGRAM(drawBlue, essl1_shaders::vs::Simple(), essl1_shaders::fs::Blue());
1784     drawQuad(drawBlue, essl1_shaders::PositionAttrib(), -0.5f - 0.01f);
1785 
1786     // An epsilon above the depth value should fail the depth test
1787     ANGLE_GL_PROGRAM(drawRed, essl1_shaders::vs::Simple(), essl1_shaders::fs::Red());
1788     drawQuad(drawRed, essl1_shaders::PositionAttrib(), -0.5f + 0.01f);
1789 
1790     EXPECT_PIXEL_RECT_EQ(0, 0, w, h, GLColor::blue);
1791 }
1792 
1793 // Tests separating the VS from the GS/FS and then modifying the shader.
TEST_P(GeometryShaderTest,RecompileSeparableVSWithVaryings)1794 TEST_P(GeometryShaderTest, RecompileSeparableVSWithVaryings)
1795 {
1796     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1797 
1798     // Errors in D3D11/GL. No plans to fix this.
1799     ANGLE_SKIP_TEST_IF(!IsVulkan());
1800 
1801     const char *kVS = R"(#version 310 es
1802 precision mediump float;
1803 in vec4 position;
1804 out vec4 vgVarying;
1805 uniform vec4 uniVec;
1806 void main()
1807 {
1808    vgVarying = uniVec;
1809    gl_Position = position;
1810 })";
1811 
1812     const char *kGS = R"(#version 310 es
1813 #extension GL_EXT_geometry_shader : require
1814 
1815 precision mediump float;
1816 
1817 layout (triangles) in;
1818 layout (triangle_strip, max_vertices = 4) out;
1819 
1820 in vec4 vgVarying[];
1821 layout(location = 5) out vec4 gfVarying;
1822 
1823 void main()
1824 {
1825     for (int n = 0; n < gl_in.length(); n++)
1826     {
1827         gl_Position = gl_in[n].gl_Position;
1828         gfVarying = vgVarying[n];
1829         EmitVertex();
1830     }
1831     EndPrimitive();
1832 })";
1833 
1834     const char *kFS = R"(#version 310 es
1835 precision mediump float;
1836 
1837 layout(location = 5) in vec4 gfVarying;
1838 out vec4 fOut;
1839 
1840 void main()
1841 {
1842     fOut = gfVarying;
1843 })";
1844 
1845     GLShader vertShader(GL_VERTEX_SHADER);
1846     glShaderSource(vertShader, 1, &kVS, nullptr);
1847     glCompileShader(vertShader);
1848 
1849     GLProgram vertProg;
1850     glProgramParameteri(vertProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
1851     glAttachShader(vertProg, vertShader);
1852     glLinkProgram(vertProg);
1853     ASSERT_GL_NO_ERROR();
1854 
1855     GLShader geomShader(GL_GEOMETRY_SHADER);
1856     glShaderSource(geomShader, 1, &kGS, nullptr);
1857     glCompileShader(geomShader);
1858 
1859     GLShader fragShader(GL_FRAGMENT_SHADER);
1860     glShaderSource(fragShader, 1, &kFS, nullptr);
1861     glCompileShader(fragShader);
1862 
1863     GLProgram geomFragProg;
1864     glProgramParameteri(geomFragProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
1865     glAttachShader(geomFragProg, geomShader);
1866     glAttachShader(geomFragProg, fragShader);
1867     glLinkProgram(geomFragProg);
1868     ASSERT_GL_NO_ERROR();
1869 
1870     GLProgramPipeline pipeline;
1871     glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vertProg);
1872     glUseProgramStages(pipeline, GL_GEOMETRY_SHADER_BIT, geomFragProg);
1873     glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, geomFragProg);
1874     glBindProgramPipeline(pipeline);
1875 
1876     glActiveShaderProgram(pipeline, vertProg);
1877     GLint uniLoc = glGetUniformLocation(vertProg, "uniVec");
1878     ASSERT_NE(-1, uniLoc);
1879     glUniform4f(uniLoc, 0, 1, 0, 1);
1880     ASSERT_GL_NO_ERROR();
1881 
1882     drawQuadPPO(vertProg, "position", 0.5f, 1.0f);
1883     EXPECT_GL_NO_ERROR();
1884     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1885 
1886     // Do it again with deleted shaders.
1887     vertProg.reset();
1888     geomFragProg.reset();
1889     pipeline.reset();
1890 
1891     glProgramParameteri(vertProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
1892     glAttachShader(vertProg, vertShader);
1893     glLinkProgram(vertProg);
1894 
1895     // Mess up the VS.
1896     const char *otherVS = essl1_shaders::vs::Texture2D();
1897     glShaderSource(vertShader, 1, &otherVS, nullptr);
1898     glCompileShader(vertShader);
1899 
1900     ASSERT_GL_NO_ERROR();
1901 
1902     glProgramParameteri(geomFragProg, GL_PROGRAM_SEPARABLE, GL_TRUE);
1903     glAttachShader(geomFragProg, geomShader);
1904     glAttachShader(geomFragProg, fragShader);
1905     glLinkProgram(geomFragProg);
1906 
1907     // Mess up the FS.
1908     const char *otherFS = essl1_shaders::fs::Texture2D();
1909     glShaderSource(fragShader, 1, &otherFS, nullptr);
1910     glCompileShader(fragShader);
1911 
1912     ASSERT_GL_NO_ERROR();
1913 
1914     glUseProgramStages(pipeline, GL_VERTEX_SHADER_BIT, vertProg);
1915     glUseProgramStages(pipeline, GL_GEOMETRY_SHADER_BIT, geomFragProg);
1916     glUseProgramStages(pipeline, GL_FRAGMENT_SHADER_BIT, geomFragProg);
1917     glBindProgramPipeline(pipeline);
1918 
1919     glActiveShaderProgram(pipeline, vertProg);
1920     uniLoc = glGetUniformLocation(vertProg, "uniVec");
1921     ASSERT_NE(-1, uniLoc);
1922     glUniform4f(uniLoc, 0, 1, 0, 1);
1923     ASSERT_GL_NO_ERROR();
1924 
1925     drawQuadPPO(vertProg, "position", 0.5f, 1.0f);
1926     EXPECT_GL_NO_ERROR();
1927     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
1928 }
1929 
1930 // Tests that varying limits work as expected with geometry shaders.
TEST_P(GeometryShaderTest,MaxVaryings)1931 TEST_P(GeometryShaderTest, MaxVaryings)
1932 {
1933     ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_geometry_shader"));
1934 
1935     // Get appropriate limitations.
1936     GLint maxVertexOutputComponents = 0;
1937     glGetIntegerv(GL_MAX_VERTEX_OUTPUT_COMPONENTS, &maxVertexOutputComponents);
1938     ASSERT_GT(maxVertexOutputComponents, 0);
1939 
1940     GLint maxGeometryInputComponents = 0;
1941     glGetIntegerv(GL_MAX_GEOMETRY_INPUT_COMPONENTS, &maxGeometryInputComponents);
1942     ASSERT_GT(maxGeometryInputComponents, 0);
1943 
1944     GLint maxGeometryOutputComponents = 0;
1945     glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_COMPONENTS, &maxGeometryOutputComponents);
1946     ASSERT_GT(maxGeometryOutputComponents, 0);
1947 
1948     GLint maxFragmentInputComponents = 0;
1949     glGetIntegerv(GL_MAX_FRAGMENT_INPUT_COMPONENTS, &maxFragmentInputComponents);
1950     ASSERT_GT(maxFragmentInputComponents, 0);
1951 
1952     GLint vertexToGeometryVaryings =
1953         std::min(maxVertexOutputComponents, maxGeometryInputComponents) / 4;
1954     GLint geometryToFragmentVaryings =
1955         std::min(maxGeometryOutputComponents, maxFragmentInputComponents) / 4;
1956 
1957     GLint varyingCount = std::min(vertexToGeometryVaryings, geometryToFragmentVaryings);
1958 
1959     // Reserve gl_Position;
1960     varyingCount--;
1961 
1962     // Create a vertex shader with "varyingCount" outputs.
1963     std::stringstream vsStream;
1964     vsStream << R"(#version 310 es
1965 uniform vec4 uniOne;
1966 in vec4 position;
1967 )";
1968 
1969     for (GLint varyingIndex = 0; varyingIndex < varyingCount; ++varyingIndex)
1970     {
1971         vsStream << "out vec4 v" << varyingIndex << ";\n";
1972     }
1973 
1974     vsStream << R"(
1975 void main()
1976 {
1977     gl_Position = position;
1978 )";
1979 
1980     for (GLint varyingIndex = 0; varyingIndex < varyingCount; ++varyingIndex)
1981     {
1982         vsStream << "    v" << varyingIndex << " = uniOne * " << varyingIndex << ".0;\n";
1983     }
1984 
1985     vsStream << "}";
1986 
1987     // Create a GS with "varyingCount" inputs and "varyingCount" outputs.
1988     std::stringstream gsStream;
1989     gsStream << R"(#version 310 es
1990 #extension GL_EXT_geometry_shader : require
1991 layout (triangles) in;
1992 layout (triangle_strip, max_vertices = 4) out;
1993 )";
1994 
1995     for (GLint varyingIndex = 0; varyingIndex < varyingCount; ++varyingIndex)
1996     {
1997         gsStream << "in vec4 v" << varyingIndex << "[];\n";
1998     }
1999 
2000     for (GLint varyingIndex = 0; varyingIndex < varyingCount; ++varyingIndex)
2001     {
2002         gsStream << "out vec4 o" << varyingIndex << ";\n";
2003     }
2004 
2005     gsStream << R"(
2006 void main()
2007 {
2008     for (int n = 0; n < gl_in.length(); n++)
2009     {
2010         gl_Position = gl_in[n].gl_Position;
2011 )";
2012 
2013     for (GLint varyingIndex = 0; varyingIndex < varyingCount; ++varyingIndex)
2014     {
2015         gsStream << "        o" << varyingIndex << " = v" << varyingIndex << "[n];\n";
2016     }
2017 
2018     gsStream << R"(
2019         EmitVertex();
2020     }
2021     EndPrimitive();
2022 }
2023 )";
2024 
2025     // Create a FS with "varyingCount" inputs.
2026     std::stringstream fsStream;
2027     fsStream << R"(#version 310 es
2028 precision mediump float;
2029 out vec4 color;
2030 )";
2031 
2032     for (GLint varyingIndex = 0; varyingIndex < varyingCount; ++varyingIndex)
2033     {
2034         fsStream << "in vec4 o" << varyingIndex << ";\n";
2035     }
2036 
2037     fsStream << R"(
2038 void main()
2039 {
2040     color = vec4(0, 1, 0, 1);
2041 )";
2042 
2043     for (GLint varyingIndex = 0; varyingIndex < varyingCount; ++varyingIndex)
2044     {
2045         fsStream << "    if (o" << varyingIndex << " != vec4(" << varyingIndex << ".0))\n"
2046                  << "        color = vec4(1, 0, 0, 1);\n";
2047     }
2048 
2049     fsStream << "}";
2050 
2051     const std::string vs = vsStream.str();
2052     const std::string gs = gsStream.str();
2053     const std::string fs = fsStream.str();
2054 
2055     ANGLE_GL_PROGRAM_WITH_GS(program, vs.c_str(), gs.c_str(), fs.c_str());
2056     glUseProgram(program);
2057 
2058     GLint uniLoc = glGetUniformLocation(program, "uniOne");
2059     ASSERT_NE(-1, uniLoc);
2060     glUniform4f(uniLoc, 1.0f, 1.0f, 1.0f, 1.0f);
2061 
2062     drawQuad(program, "position", 0.5f, 1.0f, true);
2063     ASSERT_GL_NO_ERROR();
2064 
2065     EXPECT_PIXEL_COLOR_EQ(0, 0, GLColor::green);
2066 }
2067 
2068 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GeometryShaderTestES3);
2069 ANGLE_INSTANTIATE_TEST_ES3(GeometryShaderTestES3);
2070 
2071 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GeometryShaderTest);
2072 ANGLE_INSTANTIATE_TEST_ES31_AND(GeometryShaderTest,
2073                                 ES31_VULKAN().enable(Feature::EmulatedPrerotation90),
2074                                 ES31_VULKAN().enable(Feature::EmulatedPrerotation180),
2075                                 ES31_VULKAN().enable(Feature::EmulatedPrerotation270));
2076 
2077 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(GeometryShaderTestES32);
2078 ANGLE_INSTANTIATE_TEST_ES32(GeometryShaderTestES32);
2079 }  // namespace
2080