xref: /aosp_15_r20/external/deqp/modules/gles31/functional/es31fNegativeTessellationTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1*35238bceSAndroid Build Coastguard Worker /*-------------------------------------------------------------------------
2*35238bceSAndroid Build Coastguard Worker  * drawElements Quality Program OpenGL ES 3.1 Module
3*35238bceSAndroid Build Coastguard Worker  * -------------------------------------------------
4*35238bceSAndroid Build Coastguard Worker  *
5*35238bceSAndroid Build Coastguard Worker  * Copyright 2016 The Android Open Source Project
6*35238bceSAndroid Build Coastguard Worker  *
7*35238bceSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
8*35238bceSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
9*35238bceSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
10*35238bceSAndroid Build Coastguard Worker  *
11*35238bceSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
12*35238bceSAndroid Build Coastguard Worker  *
13*35238bceSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
14*35238bceSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
15*35238bceSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16*35238bceSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
17*35238bceSAndroid Build Coastguard Worker  * limitations under the License.
18*35238bceSAndroid Build Coastguard Worker  *
19*35238bceSAndroid Build Coastguard Worker  *//*!
20*35238bceSAndroid Build Coastguard Worker  * \file
21*35238bceSAndroid Build Coastguard Worker  * \brief Negative Tessellation tests.
22*35238bceSAndroid Build Coastguard Worker  *//*--------------------------------------------------------------------*/
23*35238bceSAndroid Build Coastguard Worker 
24*35238bceSAndroid Build Coastguard Worker #include "es31fNegativeTessellationTests.hpp"
25*35238bceSAndroid Build Coastguard Worker #include "gluContextInfo.hpp"
26*35238bceSAndroid Build Coastguard Worker #include "gluShaderProgram.hpp"
27*35238bceSAndroid Build Coastguard Worker #include "glwDefs.hpp"
28*35238bceSAndroid Build Coastguard Worker #include "glwEnums.hpp"
29*35238bceSAndroid Build Coastguard Worker #include "tcuStringTemplate.hpp"
30*35238bceSAndroid Build Coastguard Worker 
31*35238bceSAndroid Build Coastguard Worker namespace deqp
32*35238bceSAndroid Build Coastguard Worker {
33*35238bceSAndroid Build Coastguard Worker 
34*35238bceSAndroid Build Coastguard Worker using std::map;
35*35238bceSAndroid Build Coastguard Worker using std::string;
36*35238bceSAndroid Build Coastguard Worker 
37*35238bceSAndroid Build Coastguard Worker namespace gles31
38*35238bceSAndroid Build Coastguard Worker {
39*35238bceSAndroid Build Coastguard Worker namespace Functional
40*35238bceSAndroid Build Coastguard Worker {
41*35238bceSAndroid Build Coastguard Worker namespace NegativeTestShared
42*35238bceSAndroid Build Coastguard Worker {
43*35238bceSAndroid Build Coastguard Worker 
44*35238bceSAndroid Build Coastguard Worker using tcu::TestLog;
45*35238bceSAndroid Build Coastguard Worker using namespace glw;
46*35238bceSAndroid Build Coastguard Worker 
47*35238bceSAndroid Build Coastguard Worker static const char *vertexShaderSource = "${GLSL_VERSION_STRING}\n"
48*35238bceSAndroid Build Coastguard Worker                                         "${GLSL_PER_VERTEX_OUT}\n"
49*35238bceSAndroid Build Coastguard Worker                                         "void main (void)\n"
50*35238bceSAndroid Build Coastguard Worker                                         "{\n"
51*35238bceSAndroid Build Coastguard Worker                                         "    gl_Position = vec4(0.0);\n"
52*35238bceSAndroid Build Coastguard Worker                                         "}\n";
53*35238bceSAndroid Build Coastguard Worker 
54*35238bceSAndroid Build Coastguard Worker static const char *fragmentShaderSource = "${GLSL_VERSION_STRING}\n"
55*35238bceSAndroid Build Coastguard Worker                                           "precision mediump float;\n"
56*35238bceSAndroid Build Coastguard Worker                                           "layout(location = 0) out mediump vec4 fragColor;\n"
57*35238bceSAndroid Build Coastguard Worker                                           "\n"
58*35238bceSAndroid Build Coastguard Worker                                           "void main (void)\n"
59*35238bceSAndroid Build Coastguard Worker                                           "{\n"
60*35238bceSAndroid Build Coastguard Worker                                           "    fragColor = vec4(1.0);\n"
61*35238bceSAndroid Build Coastguard Worker                                           "}\n";
62*35238bceSAndroid Build Coastguard Worker 
63*35238bceSAndroid Build Coastguard Worker static const char *tessControlShaderSource =
64*35238bceSAndroid Build Coastguard Worker     "${GLSL_VERSION_STRING}\n"
65*35238bceSAndroid Build Coastguard Worker     "${GLSL_TESS_EXTENSION_STRING}\n"
66*35238bceSAndroid Build Coastguard Worker     "${GLSL_PER_VERTEX_IN_ARR}\n"
67*35238bceSAndroid Build Coastguard Worker     "${GLSL_PER_VERTEX_OUT_ARR}\n"
68*35238bceSAndroid Build Coastguard Worker     "layout (vertices=3) out;\n"
69*35238bceSAndroid Build Coastguard Worker     "\n"
70*35238bceSAndroid Build Coastguard Worker     "void main()\n"
71*35238bceSAndroid Build Coastguard Worker     "{\n"
72*35238bceSAndroid Build Coastguard Worker     "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
73*35238bceSAndroid Build Coastguard Worker     "}\n";
74*35238bceSAndroid Build Coastguard Worker 
75*35238bceSAndroid Build Coastguard Worker static const char *tessEvalShaderSource = "${GLSL_VERSION_STRING}\n"
76*35238bceSAndroid Build Coastguard Worker                                           "${GLSL_TESS_EXTENSION_STRING}\n"
77*35238bceSAndroid Build Coastguard Worker                                           "${GLSL_PER_VERTEX_IN_ARR}\n"
78*35238bceSAndroid Build Coastguard Worker                                           "${GLSL_PER_VERTEX_OUT}\n"
79*35238bceSAndroid Build Coastguard Worker                                           "layout(triangles) in;\n"
80*35238bceSAndroid Build Coastguard Worker                                           "\n"
81*35238bceSAndroid Build Coastguard Worker                                           "void main()\n"
82*35238bceSAndroid Build Coastguard Worker                                           "{\n"
83*35238bceSAndroid Build Coastguard Worker                                           "    gl_Position = gl_TessCoord[0] * gl_in[0].gl_Position;\n"
84*35238bceSAndroid Build Coastguard Worker                                           "}\n";
85*35238bceSAndroid Build Coastguard Worker 
checkExtensionSupport(NegativeTestContext & ctx,const char * extName)86*35238bceSAndroid Build Coastguard Worker static void checkExtensionSupport(NegativeTestContext &ctx, const char *extName)
87*35238bceSAndroid Build Coastguard Worker {
88*35238bceSAndroid Build Coastguard Worker     if (!ctx.getContextInfo().isExtensionSupported(extName))
89*35238bceSAndroid Build Coastguard Worker         throw tcu::NotSupportedError(string(extName) + " not supported");
90*35238bceSAndroid Build Coastguard Worker }
91*35238bceSAndroid Build Coastguard Worker 
checkTessellationSupport(NegativeTestContext & ctx)92*35238bceSAndroid Build Coastguard Worker static void checkTessellationSupport(NegativeTestContext &ctx)
93*35238bceSAndroid Build Coastguard Worker {
94*35238bceSAndroid Build Coastguard Worker     if (glu::isContextTypeES(ctx.getRenderContext().getType()))
95*35238bceSAndroid Build Coastguard Worker         checkExtensionSupport(ctx, "GL_EXT_tessellation_shader");
96*35238bceSAndroid Build Coastguard Worker }
97*35238bceSAndroid Build Coastguard Worker 
98*35238bceSAndroid Build Coastguard Worker // Helper for constructing tessellation pipeline sources.
makeTessPipelineSources(const std::string & vertexSrc,const std::string & fragmentSrc,const std::string & tessCtrlSrc,const std::string & tessEvalSrc)99*35238bceSAndroid Build Coastguard Worker static glu::ProgramSources makeTessPipelineSources(const std::string &vertexSrc, const std::string &fragmentSrc,
100*35238bceSAndroid Build Coastguard Worker                                                    const std::string &tessCtrlSrc, const std::string &tessEvalSrc)
101*35238bceSAndroid Build Coastguard Worker {
102*35238bceSAndroid Build Coastguard Worker     glu::ProgramSources sources;
103*35238bceSAndroid Build Coastguard Worker     sources.sources[glu::SHADERTYPE_VERTEX].push_back(vertexSrc);
104*35238bceSAndroid Build Coastguard Worker     sources.sources[glu::SHADERTYPE_FRAGMENT].push_back(fragmentSrc);
105*35238bceSAndroid Build Coastguard Worker 
106*35238bceSAndroid Build Coastguard Worker     if (!tessCtrlSrc.empty())
107*35238bceSAndroid Build Coastguard Worker         sources.sources[glu::SHADERTYPE_TESSELLATION_CONTROL].push_back(tessCtrlSrc);
108*35238bceSAndroid Build Coastguard Worker 
109*35238bceSAndroid Build Coastguard Worker     if (!tessEvalSrc.empty())
110*35238bceSAndroid Build Coastguard Worker         sources.sources[glu::SHADERTYPE_TESSELLATION_EVALUATION].push_back(tessEvalSrc);
111*35238bceSAndroid Build Coastguard Worker 
112*35238bceSAndroid Build Coastguard Worker     return sources;
113*35238bceSAndroid Build Coastguard Worker }
114*35238bceSAndroid Build Coastguard Worker 
constructSpecializationMap(NegativeTestContext & ctx)115*35238bceSAndroid Build Coastguard Worker map<string, string> constructSpecializationMap(NegativeTestContext &ctx)
116*35238bceSAndroid Build Coastguard Worker {
117*35238bceSAndroid Build Coastguard Worker     glu::GLSLVersion glslVersion = glu::getContextTypeGLSLVersion(ctx.getRenderContext().getType());
118*35238bceSAndroid Build Coastguard Worker     bool isES31                  = (glslVersion == glu::GLSL_VERSION_310_ES);
119*35238bceSAndroid Build Coastguard Worker     string ext                   = isES31 ? "#extension GL_EXT_tessellation_shader : require" : "";
120*35238bceSAndroid Build Coastguard Worker     return {{"GLSL_VERSION_STRING", getGLSLVersionDeclaration(glslVersion)},
121*35238bceSAndroid Build Coastguard Worker             {"GLSL_TESS_EXTENSION_STRING", ext},
122*35238bceSAndroid Build Coastguard Worker             {"GLSL_PER_VERTEX_OUT", ""}, // needed for GL4.5
123*35238bceSAndroid Build Coastguard Worker             {"GLSL_PER_VERTEX_IN_ARR", ""},
124*35238bceSAndroid Build Coastguard Worker             {"GLSL_PER_VERTEX_OUT_ARR", ""}};
125*35238bceSAndroid Build Coastguard Worker }
126*35238bceSAndroid Build Coastguard Worker 
127*35238bceSAndroid Build Coastguard Worker // Incomplete active tess shaders
single_tessellation_stage(NegativeTestContext & ctx)128*35238bceSAndroid Build Coastguard Worker void single_tessellation_stage(NegativeTestContext &ctx)
129*35238bceSAndroid Build Coastguard Worker {
130*35238bceSAndroid Build Coastguard Worker     // this case does not apply to GL4.5
131*35238bceSAndroid Build Coastguard Worker     if (!glu::isContextTypeES(ctx.getRenderContext().getType()))
132*35238bceSAndroid Build Coastguard Worker         return;
133*35238bceSAndroid Build Coastguard Worker 
134*35238bceSAndroid Build Coastguard Worker     const bool requireTES    = !ctx.getContextInfo().isExtensionSupported("GL_NV_gpu_shader5");
135*35238bceSAndroid Build Coastguard Worker     map<string, string> args = constructSpecializationMap(ctx);
136*35238bceSAndroid Build Coastguard Worker 
137*35238bceSAndroid Build Coastguard Worker     checkTessellationSupport(ctx);
138*35238bceSAndroid Build Coastguard Worker 
139*35238bceSAndroid Build Coastguard Worker     {
140*35238bceSAndroid Build Coastguard Worker         glu::ShaderProgram program(
141*35238bceSAndroid Build Coastguard Worker             ctx.getRenderContext(),
142*35238bceSAndroid Build Coastguard Worker             makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
143*35238bceSAndroid Build Coastguard Worker                                     tcu::StringTemplate(fragmentShaderSource).specialize(args),
144*35238bceSAndroid Build Coastguard Worker                                     tcu::StringTemplate(tessControlShaderSource).specialize(args),
145*35238bceSAndroid Build Coastguard Worker                                     "")); // missing tessEvalShaderSource
146*35238bceSAndroid Build Coastguard Worker         tcu::TestLog &log = ctx.getLog();
147*35238bceSAndroid Build Coastguard Worker         log << program;
148*35238bceSAndroid Build Coastguard Worker 
149*35238bceSAndroid Build Coastguard Worker         ctx.beginSection("A link error is generated if a non-separable program has a tessellation control shader but "
150*35238bceSAndroid Build Coastguard Worker                          "no tessellation evaluation shader, unless GL_NV_gpu_shader5 is supported.");
151*35238bceSAndroid Build Coastguard Worker 
152*35238bceSAndroid Build Coastguard Worker         if (requireTES && program.isOk())
153*35238bceSAndroid Build Coastguard Worker             ctx.fail("Program was not expected to link");
154*35238bceSAndroid Build Coastguard Worker         else if (!requireTES && !program.isOk())
155*35238bceSAndroid Build Coastguard Worker             ctx.fail("Program was expected to link");
156*35238bceSAndroid Build Coastguard Worker 
157*35238bceSAndroid Build Coastguard Worker         ctx.endSection();
158*35238bceSAndroid Build Coastguard Worker     }
159*35238bceSAndroid Build Coastguard Worker 
160*35238bceSAndroid Build Coastguard Worker     {
161*35238bceSAndroid Build Coastguard Worker         glu::ShaderProgram program(
162*35238bceSAndroid Build Coastguard Worker             ctx.getRenderContext(),
163*35238bceSAndroid Build Coastguard Worker             makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
164*35238bceSAndroid Build Coastguard Worker                                     tcu::StringTemplate(fragmentShaderSource).specialize(args),
165*35238bceSAndroid Build Coastguard Worker                                     tcu::StringTemplate(tessControlShaderSource).specialize(args),
166*35238bceSAndroid Build Coastguard Worker                                     "") // missing tessEvalShaderSource
167*35238bceSAndroid Build Coastguard Worker                 << glu::ProgramSeparable(true));
168*35238bceSAndroid Build Coastguard Worker         tcu::TestLog &log = ctx.getLog();
169*35238bceSAndroid Build Coastguard Worker         log << program;
170*35238bceSAndroid Build Coastguard Worker 
171*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
172*35238bceSAndroid Build Coastguard Worker             TCU_THROW(TestError, "failed to build program");
173*35238bceSAndroid Build Coastguard Worker 
174*35238bceSAndroid Build Coastguard Worker         ctx.glUseProgram(program.getProgram());
175*35238bceSAndroid Build Coastguard Worker         ctx.expectError(GL_NO_ERROR);
176*35238bceSAndroid Build Coastguard Worker 
177*35238bceSAndroid Build Coastguard Worker         ctx.beginSection("GL_INVALID_OPERATION is generated if current program state has tessellation control shader "
178*35238bceSAndroid Build Coastguard Worker                          "but no tessellation evaluation shader, unless GL_NV_gpu_shader5 is supported.");
179*35238bceSAndroid Build Coastguard Worker         ctx.glDrawArrays(GL_PATCHES, 0, 3);
180*35238bceSAndroid Build Coastguard Worker         ctx.expectError(requireTES ? GL_INVALID_OPERATION : GL_NO_ERROR);
181*35238bceSAndroid Build Coastguard Worker         ctx.endSection();
182*35238bceSAndroid Build Coastguard Worker 
183*35238bceSAndroid Build Coastguard Worker         ctx.glUseProgram(0);
184*35238bceSAndroid Build Coastguard Worker     }
185*35238bceSAndroid Build Coastguard Worker 
186*35238bceSAndroid Build Coastguard Worker     {
187*35238bceSAndroid Build Coastguard Worker         glu::ShaderProgram program(ctx.getRenderContext(),
188*35238bceSAndroid Build Coastguard Worker                                    makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
189*35238bceSAndroid Build Coastguard Worker                                                            tcu::StringTemplate(fragmentShaderSource).specialize(args),
190*35238bceSAndroid Build Coastguard Worker                                                            "", // missing tessControlShaderSource
191*35238bceSAndroid Build Coastguard Worker                                                            tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
192*35238bceSAndroid Build Coastguard Worker         tcu::TestLog &log = ctx.getLog();
193*35238bceSAndroid Build Coastguard Worker         log << program;
194*35238bceSAndroid Build Coastguard Worker 
195*35238bceSAndroid Build Coastguard Worker         ctx.beginSection("A link error is generated if a non-separable program has a tessellation evaluation shader "
196*35238bceSAndroid Build Coastguard Worker                          "but no tessellation control shader.");
197*35238bceSAndroid Build Coastguard Worker 
198*35238bceSAndroid Build Coastguard Worker         if (program.isOk())
199*35238bceSAndroid Build Coastguard Worker             ctx.fail("Program was not expected to link");
200*35238bceSAndroid Build Coastguard Worker 
201*35238bceSAndroid Build Coastguard Worker         ctx.endSection();
202*35238bceSAndroid Build Coastguard Worker     }
203*35238bceSAndroid Build Coastguard Worker 
204*35238bceSAndroid Build Coastguard Worker     {
205*35238bceSAndroid Build Coastguard Worker         glu::ShaderProgram program(ctx.getRenderContext(),
206*35238bceSAndroid Build Coastguard Worker                                    makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
207*35238bceSAndroid Build Coastguard Worker                                                            tcu::StringTemplate(fragmentShaderSource).specialize(args),
208*35238bceSAndroid Build Coastguard Worker                                                            "", // missing tessControlShaderSource
209*35238bceSAndroid Build Coastguard Worker                                                            tcu::StringTemplate(tessEvalShaderSource).specialize(args))
210*35238bceSAndroid Build Coastguard Worker                                        << glu::ProgramSeparable(true));
211*35238bceSAndroid Build Coastguard Worker         tcu::TestLog &log = ctx.getLog();
212*35238bceSAndroid Build Coastguard Worker         log << program;
213*35238bceSAndroid Build Coastguard Worker 
214*35238bceSAndroid Build Coastguard Worker         if (!program.isOk())
215*35238bceSAndroid Build Coastguard Worker             TCU_THROW(TestError, "failed to build program");
216*35238bceSAndroid Build Coastguard Worker 
217*35238bceSAndroid Build Coastguard Worker         ctx.glUseProgram(program.getProgram());
218*35238bceSAndroid Build Coastguard Worker         ctx.expectError(GL_NO_ERROR);
219*35238bceSAndroid Build Coastguard Worker 
220*35238bceSAndroid Build Coastguard Worker         ctx.beginSection("GL_INVALID_OPERATION is generated if current program state has tessellation evaluation "
221*35238bceSAndroid Build Coastguard Worker                          "shader but no tessellation control shader.");
222*35238bceSAndroid Build Coastguard Worker         ctx.glDrawArrays(GL_PATCHES, 0, 3);
223*35238bceSAndroid Build Coastguard Worker         ctx.expectError(GL_INVALID_OPERATION);
224*35238bceSAndroid Build Coastguard Worker         ctx.endSection();
225*35238bceSAndroid Build Coastguard Worker 
226*35238bceSAndroid Build Coastguard Worker         ctx.glUseProgram(0);
227*35238bceSAndroid Build Coastguard Worker     }
228*35238bceSAndroid Build Coastguard Worker }
229*35238bceSAndroid Build Coastguard Worker 
230*35238bceSAndroid Build Coastguard Worker // Complete active tess shaders invalid primitive mode
invalid_primitive_mode(NegativeTestContext & ctx)231*35238bceSAndroid Build Coastguard Worker void invalid_primitive_mode(NegativeTestContext &ctx)
232*35238bceSAndroid Build Coastguard Worker {
233*35238bceSAndroid Build Coastguard Worker     checkTessellationSupport(ctx);
234*35238bceSAndroid Build Coastguard Worker 
235*35238bceSAndroid Build Coastguard Worker     map<string, string> args = constructSpecializationMap(ctx);
236*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(ctx.getRenderContext(),
237*35238bceSAndroid Build Coastguard Worker                                makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
238*35238bceSAndroid Build Coastguard Worker                                                        tcu::StringTemplate(fragmentShaderSource).specialize(args),
239*35238bceSAndroid Build Coastguard Worker                                                        tcu::StringTemplate(tessControlShaderSource).specialize(args),
240*35238bceSAndroid Build Coastguard Worker                                                        tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
241*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = ctx.getLog();
242*35238bceSAndroid Build Coastguard Worker     log << program;
243*35238bceSAndroid Build Coastguard Worker 
244*35238bceSAndroid Build Coastguard Worker     ctx.glUseProgram(program.getProgram());
245*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_NO_ERROR);
246*35238bceSAndroid Build Coastguard Worker 
247*35238bceSAndroid Build Coastguard Worker     ctx.beginSection(
248*35238bceSAndroid Build Coastguard Worker         "GL_INVALID_OPERATION is generated if tessellation is active and primitive mode is not GL_PATCHES.");
249*35238bceSAndroid Build Coastguard Worker     ctx.glDrawArrays(GL_TRIANGLES, 0, 3);
250*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_OPERATION);
251*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
252*35238bceSAndroid Build Coastguard Worker 
253*35238bceSAndroid Build Coastguard Worker     ctx.glUseProgram(0);
254*35238bceSAndroid Build Coastguard Worker }
255*35238bceSAndroid Build Coastguard Worker 
tessellation_not_active(NegativeTestContext & ctx)256*35238bceSAndroid Build Coastguard Worker void tessellation_not_active(NegativeTestContext &ctx)
257*35238bceSAndroid Build Coastguard Worker {
258*35238bceSAndroid Build Coastguard Worker     checkTessellationSupport(ctx);
259*35238bceSAndroid Build Coastguard Worker 
260*35238bceSAndroid Build Coastguard Worker     const glw::GLenum tessErr =
261*35238bceSAndroid Build Coastguard Worker         ctx.getContextInfo().isExtensionSupported("GL_NV_gpu_shader5") ? GL_NO_ERROR : GL_INVALID_OPERATION;
262*35238bceSAndroid Build Coastguard Worker     map<string, string> args = constructSpecializationMap(ctx);
263*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(ctx.getRenderContext(),
264*35238bceSAndroid Build Coastguard Worker                                makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
265*35238bceSAndroid Build Coastguard Worker                                                        tcu::StringTemplate(fragmentShaderSource).specialize(args),
266*35238bceSAndroid Build Coastguard Worker                                                        "",   // missing tessControlShaderSource
267*35238bceSAndroid Build Coastguard Worker                                                        "")); // missing tessEvalShaderSource
268*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = ctx.getLog();
269*35238bceSAndroid Build Coastguard Worker     log << program;
270*35238bceSAndroid Build Coastguard Worker 
271*35238bceSAndroid Build Coastguard Worker     GLuint vao = 0;
272*35238bceSAndroid Build Coastguard Worker     if (!glu::isContextTypeES(ctx.getRenderContext().getType()))
273*35238bceSAndroid Build Coastguard Worker     {
274*35238bceSAndroid Build Coastguard Worker         ctx.glGenVertexArrays(1, &vao);
275*35238bceSAndroid Build Coastguard Worker         ctx.glBindVertexArray(vao);
276*35238bceSAndroid Build Coastguard Worker     }
277*35238bceSAndroid Build Coastguard Worker 
278*35238bceSAndroid Build Coastguard Worker     ctx.glUseProgram(program.getProgram());
279*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_NO_ERROR);
280*35238bceSAndroid Build Coastguard Worker 
281*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_OPERATION is generated if tessellation is not active and primitive mode is "
282*35238bceSAndroid Build Coastguard Worker                      "GL_PATCHES, unless GL_NV_gpu_shader5 is supported.");
283*35238bceSAndroid Build Coastguard Worker     ctx.glDrawArrays(GL_PATCHES, 0, 3);
284*35238bceSAndroid Build Coastguard Worker     ctx.expectError(tessErr);
285*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
286*35238bceSAndroid Build Coastguard Worker 
287*35238bceSAndroid Build Coastguard Worker     ctx.glUseProgram(0);
288*35238bceSAndroid Build Coastguard Worker 
289*35238bceSAndroid Build Coastguard Worker     if (vao)
290*35238bceSAndroid Build Coastguard Worker         ctx.glDeleteVertexArrays(1, &vao);
291*35238bceSAndroid Build Coastguard Worker }
292*35238bceSAndroid Build Coastguard Worker 
invalid_program_state(NegativeTestContext & ctx)293*35238bceSAndroid Build Coastguard Worker void invalid_program_state(NegativeTestContext &ctx)
294*35238bceSAndroid Build Coastguard Worker {
295*35238bceSAndroid Build Coastguard Worker     checkTessellationSupport(ctx);
296*35238bceSAndroid Build Coastguard Worker 
297*35238bceSAndroid Build Coastguard Worker     const glu::RenderContext &rc = ctx.getRenderContext();
298*35238bceSAndroid Build Coastguard Worker     map<string, string> args     = constructSpecializationMap(ctx);
299*35238bceSAndroid Build Coastguard Worker 
300*35238bceSAndroid Build Coastguard Worker     // for gl4.5 we need to add per vertex sections
301*35238bceSAndroid Build Coastguard Worker     if (!glu::isContextTypeES(rc.getType()))
302*35238bceSAndroid Build Coastguard Worker     {
303*35238bceSAndroid Build Coastguard Worker         args["GLSL_PER_VERTEX_OUT"]     = "out gl_PerVertex { vec4 gl_Position; };\n";
304*35238bceSAndroid Build Coastguard Worker         args["GLSL_PER_VERTEX_IN_ARR"]  = "in gl_PerVertex { vec4 gl_Position; } gl_in[];\n";
305*35238bceSAndroid Build Coastguard Worker         args["GLSL_PER_VERTEX_OUT_ARR"] = "out gl_PerVertex { vec4 gl_Position; } gl_out[];\n";
306*35238bceSAndroid Build Coastguard Worker     }
307*35238bceSAndroid Build Coastguard Worker 
308*35238bceSAndroid Build Coastguard Worker     glu::FragmentSource frgSource(tcu::StringTemplate(fragmentShaderSource).specialize(args));
309*35238bceSAndroid Build Coastguard Worker     glu::TessellationControlSource tessCtrlSource(tcu::StringTemplate(tessControlShaderSource).specialize(args));
310*35238bceSAndroid Build Coastguard Worker     glu::TessellationEvaluationSource tessEvalSource(tcu::StringTemplate(tessEvalShaderSource).specialize(args));
311*35238bceSAndroid Build Coastguard Worker 
312*35238bceSAndroid Build Coastguard Worker     glu::ProgramPipeline pipeline(rc);
313*35238bceSAndroid Build Coastguard Worker 
314*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram fragProgram(rc, glu::ProgramSources() << glu::ProgramSeparable(true) << frgSource);
315*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram tessCtrlProgram(rc, glu::ProgramSources() << glu::ProgramSeparable(true) << tessCtrlSource);
316*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram tessEvalProgram(rc, glu::ProgramSources() << glu::ProgramSeparable(true) << tessEvalSource);
317*35238bceSAndroid Build Coastguard Worker 
318*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = ctx.getLog();
319*35238bceSAndroid Build Coastguard Worker     log << fragProgram << tessCtrlProgram << tessEvalProgram;
320*35238bceSAndroid Build Coastguard Worker 
321*35238bceSAndroid Build Coastguard Worker     if (!fragProgram.isOk() || !tessCtrlProgram.isOk() || !tessEvalProgram.isOk())
322*35238bceSAndroid Build Coastguard Worker         throw tcu::TestError("failed to build program");
323*35238bceSAndroid Build Coastguard Worker 
324*35238bceSAndroid Build Coastguard Worker     ctx.glBindProgramPipeline(pipeline.getPipeline());
325*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_NO_ERROR);
326*35238bceSAndroid Build Coastguard Worker 
327*35238bceSAndroid Build Coastguard Worker     ctx.glUseProgramStages(pipeline.getPipeline(), GL_FRAGMENT_SHADER_BIT, fragProgram.getProgram());
328*35238bceSAndroid Build Coastguard Worker     ctx.glUseProgramStages(pipeline.getPipeline(), GL_TESS_CONTROL_SHADER_BIT, tessCtrlProgram.getProgram());
329*35238bceSAndroid Build Coastguard Worker     ctx.glUseProgramStages(pipeline.getPipeline(), GL_TESS_EVALUATION_SHADER_BIT, tessEvalProgram.getProgram());
330*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_NO_ERROR);
331*35238bceSAndroid Build Coastguard Worker 
332*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_OPERATION is generated if tessellation is active and vertex shader is missing.");
333*35238bceSAndroid Build Coastguard Worker     ctx.glDrawArrays(GL_PATCHES, 0, 3);
334*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_OPERATION);
335*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
336*35238bceSAndroid Build Coastguard Worker 
337*35238bceSAndroid Build Coastguard Worker     ctx.glBindProgramPipeline(0);
338*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_NO_ERROR);
339*35238bceSAndroid Build Coastguard Worker }
340*35238bceSAndroid Build Coastguard Worker 
tessellation_control_invalid_vertex_count(NegativeTestContext & ctx)341*35238bceSAndroid Build Coastguard Worker void tessellation_control_invalid_vertex_count(NegativeTestContext &ctx)
342*35238bceSAndroid Build Coastguard Worker {
343*35238bceSAndroid Build Coastguard Worker     checkTessellationSupport(ctx);
344*35238bceSAndroid Build Coastguard Worker 
345*35238bceSAndroid Build Coastguard Worker     const char *const tessControlVertLimitSource =
346*35238bceSAndroid Build Coastguard Worker         "${GLSL_VERSION_STRING}\n"
347*35238bceSAndroid Build Coastguard Worker         "${GLSL_TESS_EXTENSION_STRING}\n"
348*35238bceSAndroid Build Coastguard Worker         "layout (vertices=${GL_MAX_PATCH_LIMIT}) out;\n"
349*35238bceSAndroid Build Coastguard Worker         "void main()\n"
350*35238bceSAndroid Build Coastguard Worker         "{\n"
351*35238bceSAndroid Build Coastguard Worker         "    gl_out[gl_InvocationID].gl_Position = gl_in[gl_InvocationID].gl_Position;\n"
352*35238bceSAndroid Build Coastguard Worker         "}\n";
353*35238bceSAndroid Build Coastguard Worker 
354*35238bceSAndroid Build Coastguard Worker     map<string, string> args = constructSpecializationMap(ctx);
355*35238bceSAndroid Build Coastguard Worker     int maxPatchVertices     = 0;
356*35238bceSAndroid Build Coastguard Worker 
357*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("Output vertex count exceeds GL_MAX_PATCH_VERTICES.");
358*35238bceSAndroid Build Coastguard Worker     ctx.glGetIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices);
359*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_NO_ERROR);
360*35238bceSAndroid Build Coastguard Worker 
361*35238bceSAndroid Build Coastguard Worker     std::ostringstream oss;
362*35238bceSAndroid Build Coastguard Worker     oss << (maxPatchVertices + 1);
363*35238bceSAndroid Build Coastguard Worker     args["GL_MAX_PATCH_LIMIT"] = oss.str();
364*35238bceSAndroid Build Coastguard Worker 
365*35238bceSAndroid Build Coastguard Worker     glu::ShaderProgram program(ctx.getRenderContext(),
366*35238bceSAndroid Build Coastguard Worker                                makeTessPipelineSources(tcu::StringTemplate(vertexShaderSource).specialize(args),
367*35238bceSAndroid Build Coastguard Worker                                                        tcu::StringTemplate(fragmentShaderSource).specialize(args),
368*35238bceSAndroid Build Coastguard Worker                                                        tcu::StringTemplate(tessControlVertLimitSource).specialize(args),
369*35238bceSAndroid Build Coastguard Worker                                                        tcu::StringTemplate(tessEvalShaderSource).specialize(args)));
370*35238bceSAndroid Build Coastguard Worker     tcu::TestLog &log = ctx.getLog();
371*35238bceSAndroid Build Coastguard Worker     log << program;
372*35238bceSAndroid Build Coastguard Worker 
373*35238bceSAndroid Build Coastguard Worker     bool testFailed = program.getProgramInfo().linkOk;
374*35238bceSAndroid Build Coastguard Worker 
375*35238bceSAndroid Build Coastguard Worker     if (testFailed)
376*35238bceSAndroid Build Coastguard Worker         ctx.fail("Program was not expected to link");
377*35238bceSAndroid Build Coastguard Worker 
378*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
379*35238bceSAndroid Build Coastguard Worker }
380*35238bceSAndroid Build Coastguard Worker 
invalid_get_programiv(NegativeTestContext & ctx)381*35238bceSAndroid Build Coastguard Worker void invalid_get_programiv(NegativeTestContext &ctx)
382*35238bceSAndroid Build Coastguard Worker {
383*35238bceSAndroid Build Coastguard Worker     checkTessellationSupport(ctx);
384*35238bceSAndroid Build Coastguard Worker 
385*35238bceSAndroid Build Coastguard Worker     GLuint program  = ctx.glCreateProgram();
386*35238bceSAndroid Build Coastguard Worker     GLint params[1] = {0};
387*35238bceSAndroid Build Coastguard Worker 
388*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_CONTROL_OUTPUT_VERTICES is queried for a program "
389*35238bceSAndroid Build Coastguard Worker                      "which has not been linked properly.");
390*35238bceSAndroid Build Coastguard Worker     ctx.glGetProgramiv(program, GL_TESS_CONTROL_OUTPUT_VERTICES, &params[0]);
391*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_OPERATION);
392*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
393*35238bceSAndroid Build Coastguard Worker 
394*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_MODE is queried for a program which has not "
395*35238bceSAndroid Build Coastguard Worker                      "been linked properly.");
396*35238bceSAndroid Build Coastguard Worker     ctx.glGetProgramiv(program, GL_TESS_GEN_MODE, &params[0]);
397*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_OPERATION);
398*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
399*35238bceSAndroid Build Coastguard Worker 
400*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_SPACING is queried for a program which has not "
401*35238bceSAndroid Build Coastguard Worker                      "been linked properly.");
402*35238bceSAndroid Build Coastguard Worker     ctx.glGetProgramiv(program, GL_TESS_GEN_SPACING, &params[0]);
403*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_OPERATION);
404*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
405*35238bceSAndroid Build Coastguard Worker 
406*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_VERTEX_ORDER is queried for a program which has "
407*35238bceSAndroid Build Coastguard Worker                      "not been linked properly.");
408*35238bceSAndroid Build Coastguard Worker     ctx.glGetProgramiv(program, GL_TESS_GEN_VERTEX_ORDER, &params[0]);
409*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_OPERATION);
410*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
411*35238bceSAndroid Build Coastguard Worker 
412*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_OPERATION is generated if GL_TESS_GEN_POINT_MODE is queried for a program which has "
413*35238bceSAndroid Build Coastguard Worker                      "not been linked properly.");
414*35238bceSAndroid Build Coastguard Worker     ctx.glGetProgramiv(program, GL_TESS_GEN_POINT_MODE, &params[0]);
415*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_OPERATION);
416*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
417*35238bceSAndroid Build Coastguard Worker 
418*35238bceSAndroid Build Coastguard Worker     ctx.glDeleteProgram(program);
419*35238bceSAndroid Build Coastguard Worker }
420*35238bceSAndroid Build Coastguard Worker 
invalid_patch_parameteri(NegativeTestContext & ctx)421*35238bceSAndroid Build Coastguard Worker void invalid_patch_parameteri(NegativeTestContext &ctx)
422*35238bceSAndroid Build Coastguard Worker {
423*35238bceSAndroid Build Coastguard Worker     checkTessellationSupport(ctx);
424*35238bceSAndroid Build Coastguard Worker 
425*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_ENUM is generated if pname is not GL_PATCH_VERTICES.");
426*35238bceSAndroid Build Coastguard Worker     ctx.glPatchParameteri(-1, 1);
427*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_ENUM);
428*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
429*35238bceSAndroid Build Coastguard Worker 
430*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_VALUE is generated if value is less than or equal to zero.");
431*35238bceSAndroid Build Coastguard Worker     ctx.glPatchParameteri(GL_PATCH_VERTICES, 0);
432*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_VALUE);
433*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
434*35238bceSAndroid Build Coastguard Worker 
435*35238bceSAndroid Build Coastguard Worker     int maxPatchVertices = 0;
436*35238bceSAndroid Build Coastguard Worker     ctx.glGetIntegerv(GL_MAX_PATCH_VERTICES, &maxPatchVertices);
437*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_NO_ERROR);
438*35238bceSAndroid Build Coastguard Worker 
439*35238bceSAndroid Build Coastguard Worker     ctx.beginSection("GL_INVALID_VALUE is generated if value is greater than GL_MAX_PATCH_VERTICES.");
440*35238bceSAndroid Build Coastguard Worker     ctx.glPatchParameteri(GL_PATCH_VERTICES, maxPatchVertices + 1);
441*35238bceSAndroid Build Coastguard Worker     ctx.expectError(GL_INVALID_VALUE);
442*35238bceSAndroid Build Coastguard Worker     ctx.endSection();
443*35238bceSAndroid Build Coastguard Worker }
444*35238bceSAndroid Build Coastguard Worker 
getNegativeTessellationTestFunctions(void)445*35238bceSAndroid Build Coastguard Worker std::vector<FunctionContainer> getNegativeTessellationTestFunctions(void)
446*35238bceSAndroid Build Coastguard Worker {
447*35238bceSAndroid Build Coastguard Worker     const FunctionContainer funcs[] = {
448*35238bceSAndroid Build Coastguard Worker         {single_tessellation_stage, "single_tessellation_stage",
449*35238bceSAndroid Build Coastguard Worker          "Invalid program state with single tessellation stage"},
450*35238bceSAndroid Build Coastguard Worker         {invalid_primitive_mode, "invalid_primitive_mode", "Invalid primitive mode when tessellation is active"},
451*35238bceSAndroid Build Coastguard Worker         {tessellation_not_active, "tessellation_not_active", "Use of GL_PATCHES when tessellation is not active"},
452*35238bceSAndroid Build Coastguard Worker         {invalid_program_state, "invalid_program_state",
453*35238bceSAndroid Build Coastguard Worker          "Invalid program state when tessellation active but no vertex shader present"},
454*35238bceSAndroid Build Coastguard Worker         {invalid_get_programiv, "get_programiv", "Invalid glGetProgramiv() usage"},
455*35238bceSAndroid Build Coastguard Worker         {invalid_patch_parameteri, "invalid_program_queries", "Invalid glPatchParameteri() usage"},
456*35238bceSAndroid Build Coastguard Worker         {tessellation_control_invalid_vertex_count, "tessellation_control_invalid_vertex_count",
457*35238bceSAndroid Build Coastguard Worker          "Exceed vertex count limit in tessellation control shader"},
458*35238bceSAndroid Build Coastguard Worker     };
459*35238bceSAndroid Build Coastguard Worker 
460*35238bceSAndroid Build Coastguard Worker     return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
461*35238bceSAndroid Build Coastguard Worker }
462*35238bceSAndroid Build Coastguard Worker 
463*35238bceSAndroid Build Coastguard Worker } // namespace NegativeTestShared
464*35238bceSAndroid Build Coastguard Worker } // namespace Functional
465*35238bceSAndroid Build Coastguard Worker } // namespace gles31
466*35238bceSAndroid Build Coastguard Worker } // namespace deqp
467