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