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