xref: /aosp_15_r20/external/deqp/modules/gles3/functional/es3fNegativeShaderApiTests.cpp (revision 35238bce31c2a825756842865a792f8cf7f89930)
1 /*-------------------------------------------------------------------------
2  * drawElements Quality Program OpenGL ES 3.0 Module
3  * -------------------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Negative Shader API tests.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "es3fNegativeShaderApiTests.hpp"
25 #include "es3fApiCase.hpp"
26 #include "gluShaderProgram.hpp"
27 #include "gluContextInfo.hpp"
28 #include "deUniquePtr.hpp"
29 
30 #include "glwDefs.hpp"
31 #include "glwEnums.hpp"
32 
33 using namespace glw; // GL types
34 
35 namespace deqp
36 {
37 namespace gles3
38 {
39 namespace Functional
40 {
41 
42 using tcu::TestLog;
43 
44 static const char *vertexShaderSource = "#version 300 es\n"
45                                         "void main (void)\n"
46                                         "{\n"
47                                         "    gl_Position = vec4(0.0);\n"
48                                         "}\n\0";
49 
50 static const char *fragmentShaderSource = "#version 300 es\n"
51                                           "layout(location = 0) out mediump vec4 fragColor;"
52                                           "void main (void)\n"
53                                           "{\n"
54                                           "    fragColor = vec4(0.0);\n"
55                                           "}\n\0";
56 
57 static const char *uniformTestVertSource = "#version 300 es\n"
58                                            "uniform mediump vec4 vec4_v;\n"
59                                            "uniform mediump mat4 mat4_v;\n"
60                                            "void main (void)\n"
61                                            "{\n"
62                                            "    gl_Position = mat4_v * vec4_v;\n"
63                                            "}\n\0";
64 
65 static const char *uniformTestFragSource = "#version 300 es\n"
66                                            "uniform mediump ivec4 ivec4_f;\n"
67                                            "uniform mediump uvec4 uvec4_f;\n"
68                                            "uniform sampler2D sampler_f;\n"
69                                            "layout(location = 0) out mediump vec4 fragColor;"
70                                            "void main (void)\n"
71                                            "{\n"
72                                            "    fragColor.xy = (vec4(uvec4_f) + vec4(ivec4_f)).xy;\n"
73                                            "    fragColor.zw = texture(sampler_f, vec2(0.0, 0.0)).zw;\n"
74                                            "}\n\0";
75 
76 static const char *uniformBlockVertSource = "#version 300 es\n"
77                                             "layout(shared) uniform Block { lowp float var; };\n"
78                                             "void main (void)\n"
79                                             "{\n"
80                                             "    gl_Position = vec4(var);\n"
81                                             "}\n\0";
82 
NegativeShaderApiTests(Context & context)83 NegativeShaderApiTests::NegativeShaderApiTests(Context &context)
84     : TestCaseGroup(context, "shader", "Negative Shader API Cases")
85 {
86 }
87 
~NegativeShaderApiTests(void)88 NegativeShaderApiTests::~NegativeShaderApiTests(void)
89 {
90 }
91 
init(void)92 void NegativeShaderApiTests::init(void)
93 {
94     // Shader control commands
95 
96     ES3F_ADD_API_CASE(create_shader, "Invalid glCreateShader() usage", {
97         m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if shaderType is not an accepted value.");
98         glCreateShader(-1);
99         expectError(GL_INVALID_ENUM);
100         m_log << TestLog::EndSection;
101     });
102     ES3F_ADD_API_CASE(shader_source, "Invalid glShaderSource() usage", {
103         // \note Shader compilation must be supported.
104 
105         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
106         glShaderSource(1, 0, 0, 0);
107         expectError(GL_INVALID_VALUE);
108         m_log << TestLog::EndSection;
109 
110         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if count is less than 0.");
111         GLuint shader = glCreateShader(GL_VERTEX_SHADER);
112         glShaderSource(shader, -1, 0, 0);
113         expectError(GL_INVALID_VALUE);
114         m_log << TestLog::EndSection;
115 
116         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
117         GLuint program = glCreateProgram();
118         glShaderSource(program, 0, 0, 0);
119         expectError(GL_INVALID_OPERATION);
120         m_log << TestLog::EndSection;
121 
122         glDeleteProgram(program);
123         glDeleteShader(shader);
124     });
125     ES3F_ADD_API_CASE(compile_shader, "Invalid glCompileShader() usage", {
126         // \note Shader compilation must be supported.
127 
128         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
129         glCompileShader(9);
130         expectError(GL_INVALID_VALUE);
131         m_log << TestLog::EndSection;
132 
133         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
134         GLuint program = glCreateProgram();
135         glCompileShader(program);
136         expectError(GL_INVALID_OPERATION);
137         m_log << TestLog::EndSection;
138 
139         glDeleteProgram(program);
140     });
141     ES3F_ADD_API_CASE(delete_shader, "Invalid glDeleteShader() usage", {
142         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
143         glDeleteShader(9);
144         expectError(GL_INVALID_VALUE);
145         m_log << TestLog::EndSection;
146     });
147     ES3F_ADD_API_CASE(shader_binary, "Invalid glShaderBinary() usage", {
148         std::vector<int32_t> binaryFormats;
149         getSupportedExtensions(GL_NUM_SHADER_BINARY_FORMATS, GL_SHADER_BINARY_FORMATS, binaryFormats);
150         bool shaderBinarySupported = !binaryFormats.empty();
151         if (!shaderBinarySupported)
152             m_log << TestLog::Message << "// Shader binaries not supported." << TestLog::EndMessage;
153         else
154             m_log << TestLog::Message << "// Shader binaries supported" << TestLog::EndMessage;
155 
156         GLuint shaders[2];
157         shaders[0] = glCreateShader(GL_VERTEX_SHADER);
158         shaders[1] = glCreateShader(GL_VERTEX_SHADER);
159 
160         m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if binaryFormat is not an accepted value.");
161         glShaderBinary(1, &shaders[0], -1, 0, 0);
162         expectError(GL_INVALID_ENUM);
163         m_log << TestLog::EndSection;
164 
165         if (shaderBinarySupported)
166         {
167             m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if the data pointed to by binary does not "
168                                           "match the format specified by binaryFormat.");
169             const GLbyte data = 0x005F;
170             glShaderBinary(1, &shaders[0], binaryFormats[0], &data, 1);
171             expectError(GL_INVALID_VALUE);
172             m_log << TestLog::EndSection;
173 
174             // Error handling is different in case of SPIRV.
175             const bool spirvBinary = binaryFormats[0] == GL_SHADER_BINARY_FORMAT_SPIR_V;
176             if (spirvBinary)
177                 m_log << TestLog::Section("", "GL_INVALID_VALUE due to invalid data pointer.");
178             else
179                 m_log << TestLog::Section(
180                     "", "GL_INVALID_OPERATION is generated if more than one of the handles in shaders refers to the "
181                         "same type of shader, or GL_INVALID_VALUE due to invalid data pointer.");
182 
183             glShaderBinary(2, &shaders[0], binaryFormats[0], 0, 0);
184 
185             if (spirvBinary)
186                 expectError(GL_INVALID_VALUE);
187             else
188                 expectError(GL_INVALID_OPERATION, GL_INVALID_VALUE);
189 
190             m_log << TestLog::EndSection;
191         }
192 
193         glDeleteShader(shaders[0]);
194         glDeleteShader(shaders[1]);
195     });
196     ES3F_ADD_API_CASE(attach_shader, "Invalid glAttachShader() usage", {
197         GLuint shader1 = glCreateShader(GL_VERTEX_SHADER);
198         GLuint shader2 = glCreateShader(GL_VERTEX_SHADER);
199         GLuint program = glCreateProgram();
200 
201         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
202         glAttachShader(shader1, shader1);
203         expectError(GL_INVALID_OPERATION);
204         m_log << TestLog::EndSection;
205 
206         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
207         glAttachShader(program, program);
208         expectError(GL_INVALID_OPERATION);
209         glAttachShader(shader1, program);
210         expectError(GL_INVALID_OPERATION);
211         m_log << TestLog::EndSection;
212 
213         m_log << TestLog::Section(
214             "", "GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
215         glAttachShader(program, -1);
216         expectError(GL_INVALID_VALUE);
217         glAttachShader(-1, shader1);
218         expectError(GL_INVALID_VALUE);
219         glAttachShader(-1, -1);
220         expectError(GL_INVALID_VALUE);
221         m_log << TestLog::EndSection;
222 
223         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is already attached to program.");
224         glAttachShader(program, shader1);
225         expectError(GL_NO_ERROR);
226         glAttachShader(program, shader1);
227         expectError(GL_INVALID_OPERATION);
228         m_log << TestLog::EndSection;
229 
230         if (glu::isContextTypeES(m_context.getRenderContext().getType()))
231         {
232             m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if a shader of the same type as shader is "
233                                           "already attached to program.");
234             glAttachShader(program, shader2);
235             expectError(GL_INVALID_OPERATION);
236             m_log << TestLog::EndSection;
237         }
238 
239         glDeleteProgram(program);
240         glDeleteShader(shader1);
241         glDeleteShader(shader2);
242     });
243     ES3F_ADD_API_CASE(detach_shader, "Invalid glDetachShader() usage", {
244         GLuint shader  = glCreateShader(GL_VERTEX_SHADER);
245         GLuint program = glCreateProgram();
246 
247         m_log << TestLog::Section(
248             "", "GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
249         glDetachShader(-1, shader);
250         expectError(GL_INVALID_VALUE);
251         glDetachShader(program, -1);
252         expectError(GL_INVALID_VALUE);
253         glDetachShader(-1, -1);
254         expectError(GL_INVALID_VALUE);
255         m_log << TestLog::EndSection;
256 
257         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
258         glDetachShader(shader, shader);
259         expectError(GL_INVALID_OPERATION);
260         m_log << TestLog::EndSection;
261 
262         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object.");
263         glDetachShader(program, program);
264         expectError(GL_INVALID_OPERATION);
265         glDetachShader(shader, program);
266         expectError(GL_INVALID_OPERATION);
267         m_log << TestLog::EndSection;
268 
269         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not attached to program.");
270         glDetachShader(program, shader);
271         expectError(GL_INVALID_OPERATION);
272         m_log << TestLog::EndSection;
273 
274         glDeleteProgram(program);
275         glDeleteShader(shader);
276     });
277     ES3F_ADD_API_CASE(link_program, "Invalid glLinkProgram() usage", {
278         GLuint shader = glCreateShader(GL_VERTEX_SHADER);
279 
280         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
281         glLinkProgram(-1);
282         expectError(GL_INVALID_VALUE);
283         m_log << TestLog::EndSection;
284 
285         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
286         glLinkProgram(shader);
287         expectError(GL_INVALID_OPERATION);
288         m_log << TestLog::EndSection;
289 
290         glDeleteShader(shader);
291 
292         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is the currently active program "
293                                       "object and transform feedback mode is active.");
294         glu::ShaderProgram program(m_context.getRenderContext(),
295                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
296         uint32_t buf;
297         uint32_t tfID;
298         const char *tfVarying = "gl_Position";
299 
300         glGenTransformFeedbacks(1, &tfID);
301         glGenBuffers(1, &buf);
302 
303         glUseProgram(program.getProgram());
304         glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
305         glLinkProgram(program.getProgram());
306         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
307         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
308         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
309         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
310         glBeginTransformFeedback(GL_TRIANGLES);
311         expectError(GL_NO_ERROR);
312 
313         glLinkProgram(program.getProgram());
314         expectError(GL_INVALID_OPERATION);
315 
316         glEndTransformFeedback();
317         glDeleteTransformFeedbacks(1, &tfID);
318         glDeleteBuffers(1, &buf);
319         expectError(GL_NO_ERROR);
320         m_log << TestLog::EndSection;
321     });
322     ES3F_ADD_API_CASE(use_program, "Invalid glUseProgram() usage", {
323         GLuint shader = glCreateShader(GL_VERTEX_SHADER);
324 
325         m_log << TestLog::Section(
326             "", "GL_INVALID_VALUE is generated if program is neither 0 nor a value generated by OpenGL.");
327         glUseProgram(-1);
328         expectError(GL_INVALID_VALUE);
329         m_log << TestLog::EndSection;
330 
331         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
332         glUseProgram(shader);
333         expectError(GL_INVALID_OPERATION);
334         m_log << TestLog::EndSection;
335 
336         m_log << TestLog::Section(
337             "", "GL_INVALID_OPERATION is generated if transform feedback mode is active and not paused.");
338         glu::ShaderProgram program1(m_context.getRenderContext(),
339                                     glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
340         glu::ShaderProgram program2(m_context.getRenderContext(),
341                                     glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
342         uint32_t buf;
343         uint32_t tfID;
344         const char *tfVarying = "gl_Position";
345 
346         glGenTransformFeedbacks(1, &tfID);
347         glGenBuffers(1, &buf);
348 
349         glUseProgram(program1.getProgram());
350         glTransformFeedbackVaryings(program1.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
351         glLinkProgram(program1.getProgram());
352         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
353         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
354         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
355         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
356         glBeginTransformFeedback(GL_TRIANGLES);
357         expectError(GL_NO_ERROR);
358 
359         glUseProgram(program2.getProgram());
360         expectError(GL_INVALID_OPERATION);
361 
362         glPauseTransformFeedback();
363         glUseProgram(program2.getProgram());
364         expectError(GL_NO_ERROR);
365 
366         glEndTransformFeedback();
367         glDeleteTransformFeedbacks(1, &tfID);
368         glDeleteBuffers(1, &buf);
369         expectError(GL_NO_ERROR);
370         m_log << TestLog::EndSection;
371 
372         glUseProgram(0);
373         glDeleteShader(shader);
374     });
375     ES3F_ADD_API_CASE(delete_program, "Invalid glDeleteProgram() usage", {
376         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
377         glDeleteProgram(-1);
378         expectError(GL_INVALID_VALUE);
379         m_log << TestLog::EndSection;
380     });
381     ES3F_ADD_API_CASE(validate_program, "Invalid glValidateProgram() usage", {
382         GLuint shader = glCreateShader(GL_VERTEX_SHADER);
383 
384         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
385         glValidateProgram(-1);
386         expectError(GL_INVALID_VALUE);
387         m_log << TestLog::EndSection;
388 
389         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
390         glValidateProgram(shader);
391         expectError(GL_INVALID_OPERATION);
392         m_log << TestLog::EndSection;
393 
394         glDeleteShader(shader);
395     });
396     if (glu::isContextTypeES(m_context.getRenderContext().getType()))
397     {
398         ES3F_ADD_API_CASE(get_program_binary, "Invalid glGetProgramBinary() usage", {
399             glu::ShaderProgram program(m_context.getRenderContext(),
400                                        glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
401             glu::ShaderProgram programInvalid(m_context.getRenderContext(),
402                                               glu::makeVtxFragSources(vertexShaderSource, ""));
403             GLenum binaryFormat  = -1;
404             GLsizei binaryLength = -1;
405             GLint binaryPtr      = -1;
406             GLint bufSize        = -1;
407             GLint linkStatus     = -1;
408 
409             m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if bufSize is less than the size of "
410                                           "GL_PROGRAM_BINARY_LENGTH for program.");
411             glGetProgramiv(program.getProgram(), GL_PROGRAM_BINARY_LENGTH, &bufSize);
412             expectError(GL_NO_ERROR);
413             glGetProgramiv(program.getProgram(), GL_LINK_STATUS, &linkStatus);
414             m_log << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
415             m_log << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
416             expectError(GL_NO_ERROR);
417 
418             glGetProgramBinary(program.getProgram(), 0, &binaryLength, &binaryFormat, &binaryPtr);
419             expectError(GL_INVALID_OPERATION);
420             if (bufSize > 0)
421             {
422                 glGetProgramBinary(program.getProgram(), bufSize - 1, &binaryLength, &binaryFormat, &binaryPtr);
423                 expectError(GL_INVALID_OPERATION);
424             }
425             m_log << TestLog::EndSection;
426 
427             m_log << TestLog::Section(
428                 "", "GL_INVALID_OPERATION is generated if GL_LINK_STATUS for the program object is false.");
429             glGetProgramiv(programInvalid.getProgram(), GL_PROGRAM_BINARY_LENGTH, &bufSize);
430             expectError(GL_NO_ERROR);
431             glGetProgramiv(programInvalid.getProgram(), GL_LINK_STATUS, &linkStatus);
432             m_log << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
433             m_log << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
434             expectError(GL_NO_ERROR);
435 
436             glGetProgramBinary(programInvalid.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryPtr);
437             expectError(GL_INVALID_OPERATION);
438             m_log << TestLog::EndSection;
439         });
440     }
441     ES3F_ADD_API_CASE(program_binary, "Invalid glProgramBinary() usage", {
442         glu::ShaderProgram srcProgram(m_context.getRenderContext(),
443                                       glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
444         GLuint dstProgram    = glCreateProgram();
445         GLuint unusedShader  = glCreateShader(GL_VERTEX_SHADER);
446         GLenum binaryFormat  = -1;
447         GLsizei binaryLength = -1;
448         std::vector<uint8_t> binaryBuf;
449         GLint bufSize    = -1;
450         GLint linkStatus = -1;
451 
452         glGetProgramiv(srcProgram.getProgram(), GL_PROGRAM_BINARY_LENGTH, &bufSize);
453         glGetProgramiv(srcProgram.getProgram(), GL_LINK_STATUS, &linkStatus);
454         m_log << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
455         m_log << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
456 
457         TCU_CHECK(bufSize >= 0);
458 
459         if (bufSize > 0)
460         {
461             binaryBuf.resize(bufSize);
462             glGetProgramBinary(srcProgram.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryBuf[0]);
463             expectError(GL_NO_ERROR);
464 
465             m_log << TestLog::Section(
466                 "", "GL_INVALID_OPERATION is generated if program is not the name of an existing program object.");
467             glProgramBinary(unusedShader, binaryFormat, &binaryBuf[0], binaryLength);
468             expectError(GL_INVALID_OPERATION);
469             m_log << TestLog::EndSection;
470 
471             m_log << TestLog::Section(
472                 "", "GL_INVALID_ENUM is generated if binaryFormat is not a value recognized by the implementation.");
473             glProgramBinary(dstProgram, -1, &binaryBuf[0], binaryLength);
474             expectError(GL_INVALID_ENUM);
475             m_log << TestLog::EndSection;
476         }
477 
478         glDeleteShader(unusedShader);
479         glDeleteProgram(dstProgram);
480     });
481     ES3F_ADD_API_CASE(program_parameteri, "Invalid glProgramParameteri() usage", {
482         GLuint program = glCreateProgram();
483 
484         m_log << TestLog::Section(
485             "", "GL_INVALID_VALUE is generated if program is not the name of an existing program object.");
486         glProgramParameteri(0, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
487         expectError(GL_INVALID_VALUE);
488         m_log << TestLog::EndSection;
489 
490         m_log << TestLog::Section("",
491                                   "GL_INVALID_ENUM is generated if pname is not GL_PROGRAM_BINARY_RETRIEVABLE_HINT.");
492         glProgramParameteri(program, -1, GL_TRUE);
493         expectError(GL_INVALID_ENUM);
494         m_log << TestLog::EndSection;
495 
496         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if value is not GL_FALSE or GL_TRUE.");
497         glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, 2);
498         expectError(GL_INVALID_VALUE);
499         m_log << TestLog::EndSection;
500 
501         glDeleteProgram(program);
502     });
503     ES3F_ADD_API_CASE(gen_samplers, "Invalid glGenSamplers() usage", {
504         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
505         GLuint sampler;
506         glGenSamplers(-1, &sampler);
507         expectError(GL_INVALID_VALUE);
508         m_log << TestLog::EndSection;
509     });
510     ES3F_ADD_API_CASE(bind_sampler, "Invalid glBindSampler() usage", {
511         int maxTexImageUnits;
512         GLuint sampler;
513         glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTexImageUnits);
514         glGenSamplers(1, &sampler);
515 
516         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if unit is greater than or equal to the value of "
517                                       "GL_MAX_COMBIED_TEXTURE_IMAGE_UNITS.");
518         glBindSampler(maxTexImageUnits, sampler);
519         expectError(GL_INVALID_VALUE);
520         m_log << TestLog::EndSection;
521 
522         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not zero or a name previously "
523                                       "returned from a call to glGenSamplers.");
524         glBindSampler(1, -1);
525         expectError(GL_INVALID_OPERATION);
526         m_log << TestLog::EndSection;
527 
528         m_log << TestLog::Section(
529             "", "GL_INVALID_OPERATION is generated if sampler has been deleted by a call to glDeleteSamplers.");
530         glDeleteSamplers(1, &sampler);
531         glBindSampler(1, sampler);
532         expectError(GL_INVALID_OPERATION);
533         m_log << TestLog::EndSection;
534     });
535     ES3F_ADD_API_CASE(delete_samplers, "Invalid glDeleteSamplers() usage", {
536         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
537         glDeleteSamplers(-1, 0);
538         expectError(GL_INVALID_VALUE);
539         m_log << TestLog::EndSection;
540     });
541     ES3F_ADD_API_CASE(get_sampler_parameteriv, "Invalid glGetSamplerParameteriv() usage", {
542         int params = -1;
543         GLuint sampler;
544         glGenSamplers(1, &sampler);
545 
546         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler "
547                                       "object returned from a previous call to glGenSamplers.");
548         glGetSamplerParameteriv(-1, GL_TEXTURE_MAG_FILTER, &params);
549         expectError(GL_INVALID_OPERATION);
550         m_log << TestLog::EndSection;
551 
552         m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value.");
553         glGetSamplerParameteriv(sampler, -1, &params);
554         expectError(GL_INVALID_ENUM);
555         m_log << TestLog::EndSection;
556 
557         glDeleteSamplers(1, &sampler);
558     });
559     ES3F_ADD_API_CASE(get_sampler_parameterfv, "Invalid glGetSamplerParameterfv() usage", {
560         float params = 0.0f;
561         GLuint sampler;
562         glGenSamplers(1, &sampler);
563 
564         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler "
565                                       "object returned from a previous call to glGenSamplers.");
566         glGetSamplerParameterfv(-1, GL_TEXTURE_MAG_FILTER, &params);
567         expectError(GL_INVALID_OPERATION);
568         m_log << TestLog::EndSection;
569 
570         m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value.");
571         glGetSamplerParameterfv(sampler, -1, &params);
572         expectError(GL_INVALID_ENUM);
573         m_log << TestLog::EndSection;
574 
575         glDeleteSamplers(1, &sampler);
576     });
577     ES3F_ADD_API_CASE(sampler_parameteri, "Invalid glSamplerParameteri() usage", {
578         GLuint sampler;
579         glGenSamplers(1, &sampler);
580 
581         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler "
582                                       "object previously returned from a call to glGenSamplers.");
583         glSamplerParameteri(-1, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
584         expectError(GL_INVALID_OPERATION);
585         m_log << TestLog::EndSection;
586 
587         m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if params should have a defined constant value "
588                                       "(based on the value of pname) and does not.");
589         glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, -1);
590         expectError(GL_INVALID_ENUM);
591         m_log << TestLog::EndSection;
592 
593         glDeleteSamplers(1, &sampler);
594     });
595     ES3F_ADD_API_CASE(sampler_parameteriv, "Invalid glSamplerParameteriv() usage", {
596         int params = -1;
597         GLuint sampler;
598         glGenSamplers(1, &sampler);
599 
600         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler "
601                                       "object previously returned from a call to glGenSamplers.");
602         params = GL_CLAMP_TO_EDGE;
603         glSamplerParameteriv(-1, GL_TEXTURE_WRAP_S, &params);
604         expectError(GL_INVALID_OPERATION);
605         m_log << TestLog::EndSection;
606 
607         m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if params should have a defined constant value "
608                                       "(based on the value of pname) and does not.");
609         params = -1;
610         glSamplerParameteriv(sampler, GL_TEXTURE_WRAP_S, &params);
611         expectError(GL_INVALID_ENUM);
612         m_log << TestLog::EndSection;
613 
614         glDeleteSamplers(1, &sampler);
615     });
616     ES3F_ADD_API_CASE(sampler_parameterf, "Invalid glSamplerParameterf() usage", {
617         GLuint sampler;
618         glGenSamplers(1, &sampler);
619 
620         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler "
621                                       "object previously returned from a call to glGenSamplers.");
622         glSamplerParameterf(-1, GL_TEXTURE_MIN_LOD, -1000.0f);
623         expectError(GL_INVALID_OPERATION);
624         m_log << TestLog::EndSection;
625 
626         m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if params should have a defined constant value "
627                                       "(based on the value of pname) and does not.");
628         glSamplerParameterf(sampler, GL_TEXTURE_WRAP_S, -1.0f);
629         expectError(GL_INVALID_ENUM);
630         m_log << TestLog::EndSection;
631 
632         glDeleteSamplers(1, &sampler);
633     });
634     ES3F_ADD_API_CASE(sampler_parameterfv, "Invalid glSamplerParameterfv() usage", {
635         float params = 0.0f;
636         GLuint sampler;
637         glGenSamplers(1, &sampler);
638 
639         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if sampler is not the name of a sampler "
640                                       "object previously returned from a call to glGenSamplers.");
641         params = -1000.0f;
642         glSamplerParameterfv(-1, GL_TEXTURE_WRAP_S, &params);
643         expectError(GL_INVALID_OPERATION);
644         m_log << TestLog::EndSection;
645 
646         m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if params should have a defined constant value "
647                                       "(based on the value of pname) and does not.");
648         params = -1.0f;
649         glSamplerParameterfv(sampler, GL_TEXTURE_WRAP_S, &params);
650         expectError(GL_INVALID_ENUM);
651         m_log << TestLog::EndSection;
652 
653         glDeleteSamplers(1, &sampler);
654     });
655 
656     // Shader data commands
657 
658     ES3F_ADD_API_CASE(get_attrib_location, "Invalid glGetAttribLocation() usage", {
659         GLuint programEmpty = glCreateProgram();
660         GLuint shader       = glCreateShader(GL_VERTEX_SHADER);
661 
662         glu::ShaderProgram program(m_context.getRenderContext(),
663                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
664 
665         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked.");
666         glBindAttribLocation(programEmpty, 0, "test");
667         glGetAttribLocation(programEmpty, "test");
668         expectError(GL_INVALID_OPERATION);
669         m_log << TestLog::EndSection;
670 
671         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a program or shader object.");
672         glUseProgram(program.getProgram());
673         glBindAttribLocation(program.getProgram(), 0, "test");
674         expectError(GL_NO_ERROR);
675         glGetAttribLocation(program.getProgram(), "test");
676         expectError(GL_NO_ERROR);
677         glGetAttribLocation(-2, "test");
678         expectError(GL_INVALID_VALUE);
679         m_log << TestLog::EndSection;
680 
681         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
682         glGetAttribLocation(shader, "test");
683         expectError(GL_INVALID_OPERATION);
684         m_log << TestLog::EndSection;
685 
686         glUseProgram(0);
687         glDeleteShader(shader);
688         glDeleteProgram(programEmpty);
689     });
690     ES3F_ADD_API_CASE(get_uniform_location, "Invalid glGetUniformLocation() usage", {
691         GLuint programEmpty = glCreateProgram();
692         GLuint shader       = glCreateShader(GL_VERTEX_SHADER);
693 
694         glu::ShaderProgram program(m_context.getRenderContext(),
695                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
696 
697         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked.");
698         glGetUniformLocation(programEmpty, "test");
699         expectError(GL_INVALID_OPERATION);
700         m_log << TestLog::EndSection;
701 
702         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
703         glUseProgram(program.getProgram());
704         glGetUniformLocation(-2, "test");
705         expectError(GL_INVALID_VALUE);
706         m_log << TestLog::EndSection;
707 
708         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
709         glGetAttribLocation(shader, "test");
710         expectError(GL_INVALID_OPERATION);
711         m_log << TestLog::EndSection;
712 
713         glUseProgram(0);
714         glDeleteProgram(programEmpty);
715         glDeleteShader(shader);
716     });
717     ES3F_ADD_API_CASE(bind_attrib_location, "Invalid glBindAttribLocation() usage", {
718         GLuint program  = glCreateProgram();
719         GLuint maxIndex = m_context.getContextInfo().getInt(GL_MAX_VERTEX_ATTRIBS);
720         GLuint shader   = glCreateShader(GL_VERTEX_SHADER);
721 
722         m_log << TestLog::Section(
723             "", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
724         glBindAttribLocation(program, maxIndex, "test");
725         expectError(GL_INVALID_VALUE);
726         m_log << TestLog::EndSection;
727 
728         m_log << TestLog::Section("",
729                                   "GL_INVALID_OPERATION is generated if name starts with the reserved prefix \"gl_\".");
730         glBindAttribLocation(program, maxIndex - 1, "gl_test");
731         expectError(GL_INVALID_OPERATION);
732         m_log << TestLog::EndSection;
733 
734         m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
735         glBindAttribLocation(-1, maxIndex - 1, "test");
736         expectError(GL_INVALID_VALUE);
737         m_log << TestLog::EndSection;
738 
739         m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object.");
740         glBindAttribLocation(shader, maxIndex - 1, "test");
741         expectError(GL_INVALID_OPERATION);
742         m_log << TestLog::EndSection;
743 
744         glDeleteProgram(program);
745         glDeleteShader(shader);
746     });
747     ES3F_ADD_API_CASE(uniform_block_binding, "Invalid glUniformBlockBinding() usage", {
748         glu::ShaderProgram program(m_context.getRenderContext(),
749                                    glu::makeVtxFragSources(uniformBlockVertSource, uniformTestFragSource));
750 
751         glUseProgram(program.getProgram());
752 
753         GLint maxUniformBufferBindings;
754         GLint numActiveUniforms = -1;
755         GLint numActiveBlocks   = -1;
756         glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
757         glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORMS, &numActiveUniforms);
758         glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCKS, &numActiveBlocks);
759         m_log << TestLog::Message << "// GL_MAX_UNIFORM_BUFFER_BINDINGS = " << maxUniformBufferBindings
760               << TestLog::EndMessage;
761         m_log << TestLog::Message << "// GL_ACTIVE_UNIFORMS = " << numActiveUniforms << TestLog::EndMessage;
762         m_log << TestLog::Message << "// GL_ACTIVE_UNIFORM_BLOCKS = " << numActiveBlocks << TestLog::EndMessage;
763         expectError(GL_NO_ERROR);
764 
765         m_log << tcu::TestLog::Section(
766             "", "GL_INVALID_VALUE is generated if uniformBlockIndex is not an active uniform block index of program.");
767         glUniformBlockBinding(program.getProgram(), -1, 0);
768         expectError(GL_INVALID_VALUE);
769         glUniformBlockBinding(program.getProgram(), 5, 0);
770         expectError(GL_INVALID_VALUE);
771         m_log << tcu::TestLog::EndSection;
772 
773         m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if uniformBlockBinding is greater than or "
774                                            "equal to the value of GL_MAX_UNIFORM_BUFFER_BINDINGS.");
775         glUniformBlockBinding(program.getProgram(), maxUniformBufferBindings, 0);
776         expectError(GL_INVALID_VALUE);
777         m_log << tcu::TestLog::EndSection;
778 
779         m_log << tcu::TestLog::Section(
780             "", "GL_INVALID_VALUE is generated if program is not the name of a program object generated by the GL.");
781         glUniformBlockBinding(-1, 0, 0);
782         expectError(GL_INVALID_VALUE);
783         m_log << tcu::TestLog::EndSection;
784     });
785 
786     // glUniform*f
787 
788     ES3F_ADD_API_CASE(uniformf_invalid_program, "Invalid glUniform{1234}f() usage", {
789         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
790         glUseProgram(0);
791         glUniform1f(-1, 0.0f);
792         expectError(GL_INVALID_OPERATION);
793         glUniform2f(-1, 0.0f, 0.0f);
794         expectError(GL_INVALID_OPERATION);
795         glUniform3f(-1, 0.0f, 0.0f, 0.0f);
796         expectError(GL_INVALID_OPERATION);
797         glUniform4f(-1, 0.0f, 0.0f, 0.0f, 0.0f);
798         expectError(GL_INVALID_OPERATION);
799         m_log << tcu::TestLog::EndSection;
800     });
801     ES3F_ADD_API_CASE(uniformf_incompatible_type, "Invalid glUniform{1234}f() usage", {
802         glu::ShaderProgram program(m_context.getRenderContext(),
803                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
804 
805         glUseProgram(program.getProgram());
806         GLint vec4_v    = glGetUniformLocation(program.getProgram(), "vec4_v");    // vec4
807         GLint ivec4_f   = glGetUniformLocation(program.getProgram(), "ivec4_f");   // ivec4
808         GLint uvec4_f   = glGetUniformLocation(program.getProgram(), "uvec4_f");   // uvec4
809         GLint sampler_f = glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
810         expectError(GL_NO_ERROR);
811 
812         if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
813         {
814             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
815             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
816         }
817 
818         m_log << tcu::TestLog::Section("",
819                                        "GL_INVALID_OPERATION is generated if the size of the uniform variable declared "
820                                        "in the shader does not match the size indicated by the glUniform command.");
821         glUseProgram(program.getProgram());
822         glUniform1f(vec4_v, 0.0f);
823         expectError(GL_INVALID_OPERATION);
824         glUniform2f(vec4_v, 0.0f, 0.0f);
825         expectError(GL_INVALID_OPERATION);
826         glUniform3f(vec4_v, 0.0f, 0.0f, 0.0f);
827         expectError(GL_INVALID_OPERATION);
828         glUniform4f(vec4_v, 0.0f, 0.0f, 0.0f, 0.0f);
829         expectError(GL_NO_ERROR);
830         m_log << tcu::TestLog::EndSection;
831 
832         m_log << tcu::TestLog::Section(
833             "", "GL_INVALID_OPERATION is generated if glUniform{1234}f is used to load a uniform variable of type int, "
834                 "ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4.");
835         glUseProgram(program.getProgram());
836         glUniform4f(ivec4_f, 0.0f, 0.0f, 0.0f, 0.0f);
837         expectError(GL_INVALID_OPERATION);
838         glUniform4f(uvec4_f, 0.0f, 0.0f, 0.0f, 0.0f);
839         expectError(GL_INVALID_OPERATION);
840         m_log << tcu::TestLog::EndSection;
841 
842         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command "
843                                            "other than glUniform1i and glUniform1iv.");
844         glUseProgram(program.getProgram());
845         glUniform1f(sampler_f, 0.0f);
846         expectError(GL_INVALID_OPERATION);
847         m_log << tcu::TestLog::EndSection;
848 
849         glUseProgram(0);
850     });
851     ES3F_ADD_API_CASE(uniformf_invalid_location, "Invalid glUniform{1234}f() usage", {
852         glu::ShaderProgram program(m_context.getRenderContext(),
853                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
854 
855         glUseProgram(program.getProgram());
856         expectError(GL_NO_ERROR);
857 
858         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform "
859                                            "location for the current program object and location is not equal to -1.");
860         glUseProgram(program.getProgram());
861         glUniform1f(-2, 0.0f);
862         expectError(GL_INVALID_OPERATION);
863         glUniform2f(-2, 0.0f, 0.0f);
864         expectError(GL_INVALID_OPERATION);
865         glUniform3f(-2, 0.0f, 0.0f, 0.0f);
866         expectError(GL_INVALID_OPERATION);
867         glUniform4f(-2, 0.0f, 0.0f, 0.0f, 0.0f);
868         expectError(GL_INVALID_OPERATION);
869 
870         glUseProgram(program.getProgram());
871         glUniform1f(-1, 0.0f);
872         expectError(GL_NO_ERROR);
873         glUniform2f(-1, 0.0f, 0.0f);
874         expectError(GL_NO_ERROR);
875         glUniform3f(-1, 0.0f, 0.0f, 0.0f);
876         expectError(GL_NO_ERROR);
877         glUniform4f(-1, 0.0f, 0.0f, 0.0f, 0.0f);
878         expectError(GL_NO_ERROR);
879         m_log << tcu::TestLog::EndSection;
880 
881         glUseProgram(0);
882     });
883 
884     // glUniform*fv
885 
886     ES3F_ADD_API_CASE(uniformfv_invalid_program, "Invalid glUniform{1234}fv() usage", {
887         std::vector<GLfloat> data(4);
888 
889         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
890         glUseProgram(0);
891         glUniform1fv(-1, 1, &data[0]);
892         expectError(GL_INVALID_OPERATION);
893         glUniform2fv(-1, 1, &data[0]);
894         expectError(GL_INVALID_OPERATION);
895         glUniform3fv(-1, 1, &data[0]);
896         expectError(GL_INVALID_OPERATION);
897         glUniform4fv(-1, 1, &data[0]);
898         expectError(GL_INVALID_OPERATION);
899         m_log << tcu::TestLog::EndSection;
900     });
901     ES3F_ADD_API_CASE(uniformfv_incompatible_type, "Invalid glUniform{1234}fv() usage", {
902         glu::ShaderProgram program(m_context.getRenderContext(),
903                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
904 
905         glUseProgram(program.getProgram());
906         GLint vec4_v    = glGetUniformLocation(program.getProgram(), "vec4_v");    // vec4
907         GLint ivec4_f   = glGetUniformLocation(program.getProgram(), "ivec4_f");   // ivec4
908         GLint uvec4_f   = glGetUniformLocation(program.getProgram(), "uvec4_f");   // uvec4
909         GLint sampler_f = glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
910         expectError(GL_NO_ERROR);
911 
912         if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
913         {
914             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
915             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
916         }
917 
918         std::vector<GLfloat> data(4);
919 
920         m_log << tcu::TestLog::Section("",
921                                        "GL_INVALID_OPERATION is generated if the size of the uniform variable declared "
922                                        "in the shader does not match the size indicated by the glUniform command.");
923         glUseProgram(program.getProgram());
924         glUniform1fv(vec4_v, 1, &data[0]);
925         expectError(GL_INVALID_OPERATION);
926         glUniform2fv(vec4_v, 1, &data[0]);
927         expectError(GL_INVALID_OPERATION);
928         glUniform3fv(vec4_v, 1, &data[0]);
929         expectError(GL_INVALID_OPERATION);
930         glUniform4fv(vec4_v, 1, &data[0]);
931         expectError(GL_NO_ERROR);
932         m_log << tcu::TestLog::EndSection;
933 
934         m_log << tcu::TestLog::Section(
935             "", "GL_INVALID_OPERATION is generated if glUniform{1234}fv is used to load a uniform variable of type "
936                 "int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4.");
937         glUseProgram(program.getProgram());
938         glUniform4fv(ivec4_f, 1, &data[0]);
939         expectError(GL_INVALID_OPERATION);
940         glUniform4fv(uvec4_f, 1, &data[0]);
941         expectError(GL_INVALID_OPERATION);
942         m_log << tcu::TestLog::EndSection;
943 
944         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command "
945                                            "other than glUniform1i and glUniform1iv.");
946         glUseProgram(program.getProgram());
947         glUniform1fv(sampler_f, 1, &data[0]);
948         expectError(GL_INVALID_OPERATION);
949         m_log << tcu::TestLog::EndSection;
950 
951         glUseProgram(0);
952     });
953     ES3F_ADD_API_CASE(uniformfv_invalid_location, "Invalid glUniform{1234}fv() usage", {
954         glu::ShaderProgram program(m_context.getRenderContext(),
955                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
956 
957         glUseProgram(program.getProgram());
958         expectError(GL_NO_ERROR);
959 
960         std::vector<GLfloat> data(4);
961 
962         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform "
963                                            "location for the current program object and location is not equal to -1.");
964         glUseProgram(program.getProgram());
965         glUniform1fv(-2, 1, &data[0]);
966         expectError(GL_INVALID_OPERATION);
967         glUniform2fv(-2, 1, &data[0]);
968         expectError(GL_INVALID_OPERATION);
969         glUniform3fv(-2, 1, &data[0]);
970         expectError(GL_INVALID_OPERATION);
971         glUniform4fv(-2, 1, &data[0]);
972         expectError(GL_INVALID_OPERATION);
973 
974         glUseProgram(program.getProgram());
975         glUniform1fv(-1, 1, &data[0]);
976         expectError(GL_NO_ERROR);
977         glUniform2fv(-1, 1, &data[0]);
978         expectError(GL_NO_ERROR);
979         glUniform3fv(-1, 1, &data[0]);
980         expectError(GL_NO_ERROR);
981         glUniform4fv(-1, 1, &data[0]);
982         expectError(GL_NO_ERROR);
983         m_log << tcu::TestLog::EndSection;
984 
985         glUseProgram(0);
986     });
987     ES3F_ADD_API_CASE(uniformfv_invalid_count, "Invalid glUniform{1234}fv() usage", {
988         glu::ShaderProgram program(m_context.getRenderContext(),
989                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
990 
991         glUseProgram(program.getProgram());
992         GLint vec4_v = glGetUniformLocation(program.getProgram(), "vec4_v"); // vec4
993         expectError(GL_NO_ERROR);
994 
995         if (vec4_v == -1)
996         {
997             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
998             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
999         }
1000 
1001         std::vector<GLfloat> data(8);
1002 
1003         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if count is greater than 1 and the "
1004                                            "indicated uniform variable is not an array variable.");
1005         glUseProgram(program.getProgram());
1006         glUniform1fv(vec4_v, 2, &data[0]);
1007         expectError(GL_INVALID_OPERATION);
1008         glUniform2fv(vec4_v, 2, &data[0]);
1009         expectError(GL_INVALID_OPERATION);
1010         glUniform3fv(vec4_v, 2, &data[0]);
1011         expectError(GL_INVALID_OPERATION);
1012         glUniform4fv(vec4_v, 2, &data[0]);
1013         expectError(GL_INVALID_OPERATION);
1014         m_log << tcu::TestLog::EndSection;
1015 
1016         glUseProgram(0);
1017     });
1018 
1019     // glUniform*i
1020 
1021     ES3F_ADD_API_CASE(uniformi_invalid_program, "Invalid glUniform{1234}i() usage", {
1022         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1023         glUseProgram(0);
1024         glUniform1i(-1, 0);
1025         expectError(GL_INVALID_OPERATION);
1026         glUniform2i(-1, 0, 0);
1027         expectError(GL_INVALID_OPERATION);
1028         glUniform3i(-1, 0, 0, 0);
1029         expectError(GL_INVALID_OPERATION);
1030         glUniform4i(-1, 0, 0, 0, 0);
1031         expectError(GL_INVALID_OPERATION);
1032         m_log << tcu::TestLog::EndSection;
1033     });
1034     ES3F_ADD_API_CASE(uniformi_incompatible_type, "Invalid glUniform{1234}i() usage", {
1035         glu::ShaderProgram program(m_context.getRenderContext(),
1036                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1037 
1038         glUseProgram(program.getProgram());
1039         GLint vec4_v    = glGetUniformLocation(program.getProgram(), "vec4_v");    // vec4
1040         GLint ivec4_f   = glGetUniformLocation(program.getProgram(), "ivec4_f");   // ivec4
1041         GLint uvec4_f   = glGetUniformLocation(program.getProgram(), "uvec4_f");   // uvec4
1042         GLint sampler_f = glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
1043         expectError(GL_NO_ERROR);
1044 
1045         if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
1046         {
1047             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1048             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1049         }
1050 
1051         m_log << tcu::TestLog::Section("",
1052                                        "GL_INVALID_OPERATION is generated if the size of the uniform variable declared "
1053                                        "in the shader does not match the size indicated by the glUniform command.");
1054         glUseProgram(program.getProgram());
1055         glUniform1i(ivec4_f, 0);
1056         expectError(GL_INVALID_OPERATION);
1057         glUniform2i(ivec4_f, 0, 0);
1058         expectError(GL_INVALID_OPERATION);
1059         glUniform3i(ivec4_f, 0, 0, 0);
1060         expectError(GL_INVALID_OPERATION);
1061         glUniform4i(ivec4_f, 0, 0, 0, 0);
1062         expectError(GL_NO_ERROR);
1063         m_log << tcu::TestLog::EndSection;
1064 
1065         m_log << tcu::TestLog::Section(
1066             "", "GL_INVALID_OPERATION is generated if glUniform{1234}i is used to load a uniform variable of type "
1067                 "unsigned int, uvec2, uvec3, uvec4, or an array of these.");
1068         glUseProgram(program.getProgram());
1069         glUniform1i(uvec4_f, 0);
1070         expectError(GL_INVALID_OPERATION);
1071         glUniform2i(uvec4_f, 0, 0);
1072         expectError(GL_INVALID_OPERATION);
1073         glUniform3i(uvec4_f, 0, 0, 0);
1074         expectError(GL_INVALID_OPERATION);
1075         glUniform4i(uvec4_f, 0, 0, 0, 0);
1076         expectError(GL_INVALID_OPERATION);
1077         m_log << tcu::TestLog::EndSection;
1078 
1079         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}i is used to load a "
1080                                            "uniform variable of type float, vec2, vec3, or vec4.");
1081         glUseProgram(program.getProgram());
1082         glUniform1i(vec4_v, 0);
1083         expectError(GL_INVALID_OPERATION);
1084         glUniform2i(vec4_v, 0, 0);
1085         expectError(GL_INVALID_OPERATION);
1086         glUniform3i(vec4_v, 0, 0, 0);
1087         expectError(GL_INVALID_OPERATION);
1088         glUniform4i(vec4_v, 0, 0, 0, 0);
1089         expectError(GL_INVALID_OPERATION);
1090         m_log << tcu::TestLog::EndSection;
1091 
1092         glUseProgram(0);
1093     });
1094     ES3F_ADD_API_CASE(uniformi_invalid_location, "Invalid glUniform{1234}i() usage", {
1095         glu::ShaderProgram program(m_context.getRenderContext(),
1096                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1097 
1098         glUseProgram(program.getProgram());
1099         expectError(GL_NO_ERROR);
1100 
1101         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform "
1102                                            "location for the current program object and location is not equal to -1.");
1103         glUseProgram(program.getProgram());
1104         glUniform1i(-2, 0);
1105         expectError(GL_INVALID_OPERATION);
1106         glUniform2i(-2, 0, 0);
1107         expectError(GL_INVALID_OPERATION);
1108         glUniform3i(-2, 0, 0, 0);
1109         expectError(GL_INVALID_OPERATION);
1110         glUniform4i(-2, 0, 0, 0, 0);
1111         expectError(GL_INVALID_OPERATION);
1112 
1113         glUseProgram(program.getProgram());
1114         glUniform1i(-1, 0);
1115         expectError(GL_NO_ERROR);
1116         glUniform2i(-1, 0, 0);
1117         expectError(GL_NO_ERROR);
1118         glUniform3i(-1, 0, 0, 0);
1119         expectError(GL_NO_ERROR);
1120         glUniform4i(-1, 0, 0, 0, 0);
1121         expectError(GL_NO_ERROR);
1122         m_log << tcu::TestLog::EndSection;
1123 
1124         glUseProgram(0);
1125     });
1126 
1127     // glUniform*iv
1128 
1129     ES3F_ADD_API_CASE(uniformiv_invalid_program, "Invalid glUniform{1234}iv() usage", {
1130         std::vector<GLint> data(4);
1131 
1132         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1133         glUseProgram(0);
1134         glUniform1iv(-1, 1, &data[0]);
1135         expectError(GL_INVALID_OPERATION);
1136         glUniform2iv(-1, 1, &data[0]);
1137         expectError(GL_INVALID_OPERATION);
1138         glUniform3iv(-1, 1, &data[0]);
1139         expectError(GL_INVALID_OPERATION);
1140         glUniform4iv(-1, 1, &data[0]);
1141         expectError(GL_INVALID_OPERATION);
1142         m_log << tcu::TestLog::EndSection;
1143     });
1144     ES3F_ADD_API_CASE(uniformiv_incompatible_type, "Invalid glUniform{1234}iv() usage", {
1145         glu::ShaderProgram program(m_context.getRenderContext(),
1146                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1147 
1148         glUseProgram(program.getProgram());
1149         GLint vec4_v    = glGetUniformLocation(program.getProgram(), "vec4_v");    // vec4
1150         GLint ivec4_f   = glGetUniformLocation(program.getProgram(), "ivec4_f");   // ivec4
1151         GLint uvec4_f   = glGetUniformLocation(program.getProgram(), "uvec4_f");   // uvec4
1152         GLint sampler_f = glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
1153         expectError(GL_NO_ERROR);
1154 
1155         if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
1156         {
1157             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1158             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1159         }
1160 
1161         std::vector<GLint> data(4);
1162 
1163         m_log << tcu::TestLog::Section("",
1164                                        "GL_INVALID_OPERATION is generated if the size of the uniform variable declared "
1165                                        "in the shader does not match the size indicated by the glUniform command.");
1166         glUseProgram(program.getProgram());
1167         glUniform1iv(ivec4_f, 1, &data[0]);
1168         expectError(GL_INVALID_OPERATION);
1169         glUniform2iv(ivec4_f, 1, &data[0]);
1170         expectError(GL_INVALID_OPERATION);
1171         glUniform3iv(ivec4_f, 1, &data[0]);
1172         expectError(GL_INVALID_OPERATION);
1173         glUniform4iv(ivec4_f, 1, &data[0]);
1174         expectError(GL_NO_ERROR);
1175         m_log << tcu::TestLog::EndSection;
1176 
1177         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}iv is used to load a "
1178                                            "uniform variable of type float, vec2, vec3, or vec4.");
1179         glUseProgram(program.getProgram());
1180         glUniform1iv(vec4_v, 1, &data[0]);
1181         expectError(GL_INVALID_OPERATION);
1182         glUniform2iv(vec4_v, 1, &data[0]);
1183         expectError(GL_INVALID_OPERATION);
1184         glUniform3iv(vec4_v, 1, &data[0]);
1185         expectError(GL_INVALID_OPERATION);
1186         glUniform4iv(vec4_v, 1, &data[0]);
1187         expectError(GL_INVALID_OPERATION);
1188         m_log << tcu::TestLog::EndSection;
1189 
1190         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}iv is used to load a "
1191                                            "uniform variable of type unsigned int, uvec2, uvec3 or uvec4.");
1192         glUseProgram(program.getProgram());
1193         glUniform1iv(uvec4_f, 1, &data[0]);
1194         expectError(GL_INVALID_OPERATION);
1195         glUniform2iv(uvec4_f, 1, &data[0]);
1196         expectError(GL_INVALID_OPERATION);
1197         glUniform3iv(uvec4_f, 1, &data[0]);
1198         expectError(GL_INVALID_OPERATION);
1199         glUniform4iv(uvec4_f, 1, &data[0]);
1200         expectError(GL_INVALID_OPERATION);
1201         m_log << tcu::TestLog::EndSection;
1202 
1203         glUseProgram(0);
1204     });
1205     ES3F_ADD_API_CASE(uniformiv_invalid_location, "Invalid glUniform{1234}iv() usage", {
1206         glu::ShaderProgram program(m_context.getRenderContext(),
1207                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1208 
1209         glUseProgram(program.getProgram());
1210         expectError(GL_NO_ERROR);
1211 
1212         std::vector<GLint> data(4);
1213 
1214         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform "
1215                                            "location for the current program object and location is not equal to -1.");
1216         glUseProgram(program.getProgram());
1217         glUniform1iv(-2, 1, &data[0]);
1218         expectError(GL_INVALID_OPERATION);
1219         glUniform2iv(-2, 1, &data[0]);
1220         expectError(GL_INVALID_OPERATION);
1221         glUniform3iv(-2, 1, &data[0]);
1222         expectError(GL_INVALID_OPERATION);
1223         glUniform4iv(-2, 1, &data[0]);
1224         expectError(GL_INVALID_OPERATION);
1225 
1226         glUseProgram(program.getProgram());
1227         glUniform1iv(-1, 1, &data[0]);
1228         expectError(GL_NO_ERROR);
1229         glUniform2iv(-1, 1, &data[0]);
1230         expectError(GL_NO_ERROR);
1231         glUniform3iv(-1, 1, &data[0]);
1232         expectError(GL_NO_ERROR);
1233         glUniform4iv(-1, 1, &data[0]);
1234         expectError(GL_NO_ERROR);
1235         m_log << tcu::TestLog::EndSection;
1236 
1237         glUseProgram(0);
1238     });
1239     ES3F_ADD_API_CASE(uniformiv_invalid_count, "Invalid glUniform{1234}iv() usage", {
1240         glu::ShaderProgram program(m_context.getRenderContext(),
1241                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1242 
1243         glUseProgram(program.getProgram());
1244         GLint ivec4_f = glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
1245         expectError(GL_NO_ERROR);
1246 
1247         if (ivec4_f == -1)
1248         {
1249             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1250             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1251         }
1252 
1253         std::vector<GLint> data(8);
1254 
1255         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if count is greater than 1 and the "
1256                                            "indicated uniform variable is not an array variable.");
1257         glUseProgram(program.getProgram());
1258         glUniform1iv(ivec4_f, 2, &data[0]);
1259         expectError(GL_INVALID_OPERATION);
1260         glUniform2iv(ivec4_f, 2, &data[0]);
1261         expectError(GL_INVALID_OPERATION);
1262         glUniform3iv(ivec4_f, 2, &data[0]);
1263         expectError(GL_INVALID_OPERATION);
1264         glUniform4iv(ivec4_f, 2, &data[0]);
1265         expectError(GL_INVALID_OPERATION);
1266         m_log << tcu::TestLog::EndSection;
1267 
1268         glUseProgram(0);
1269     });
1270 
1271     // glUniform{1234}ui
1272 
1273     ES3F_ADD_API_CASE(uniformui_invalid_program, "Invalid glUniform{234}ui() usage", {
1274         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1275         glUseProgram(0);
1276         glUniform1ui(-1, 0);
1277         expectError(GL_INVALID_OPERATION);
1278         glUniform2ui(-1, 0, 0);
1279         expectError(GL_INVALID_OPERATION);
1280         glUniform3ui(-1, 0, 0, 0);
1281         expectError(GL_INVALID_OPERATION);
1282         glUniform4ui(-1, 0, 0, 0, 0);
1283         expectError(GL_INVALID_OPERATION);
1284         m_log << tcu::TestLog::EndSection;
1285     });
1286     ES3F_ADD_API_CASE(uniformui_incompatible_type, "Invalid glUniform{1234}ui() usage", {
1287         glu::ShaderProgram program(m_context.getRenderContext(),
1288                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1289 
1290         glUseProgram(program.getProgram());
1291         GLint vec4_v    = glGetUniformLocation(program.getProgram(), "vec4_v");    // vec4
1292         GLint ivec4_f   = glGetUniformLocation(program.getProgram(), "ivec4_f");   // ivec4
1293         GLint uvec4_f   = glGetUniformLocation(program.getProgram(), "uvec4_f");   // uvec4
1294         GLint sampler_f = glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
1295         expectError(GL_NO_ERROR);
1296 
1297         if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
1298         {
1299             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1300             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1301         }
1302 
1303         m_log << tcu::TestLog::Section("",
1304                                        "GL_INVALID_OPERATION is generated if the size of the uniform variable declared "
1305                                        "in the shader does not match the size indicated by the glUniform command.");
1306         glUseProgram(program.getProgram());
1307         glUniform1ui(uvec4_f, 0);
1308         expectError(GL_INVALID_OPERATION);
1309         glUniform2ui(uvec4_f, 0, 0);
1310         expectError(GL_INVALID_OPERATION);
1311         glUniform3ui(uvec4_f, 0, 0, 0);
1312         expectError(GL_INVALID_OPERATION);
1313         glUniform4ui(uvec4_f, 0, 0, 0, 0);
1314         expectError(GL_NO_ERROR);
1315         m_log << tcu::TestLog::EndSection;
1316 
1317         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}i is used to load a "
1318                                            "uniform variable of type int, ivec2, ivec3, ivec4, or an array of these.");
1319         glUseProgram(program.getProgram());
1320         glUniform1ui(ivec4_f, 0);
1321         expectError(GL_INVALID_OPERATION);
1322         glUniform2ui(ivec4_f, 0, 0);
1323         expectError(GL_INVALID_OPERATION);
1324         glUniform3ui(ivec4_f, 0, 0, 0);
1325         expectError(GL_INVALID_OPERATION);
1326         glUniform4ui(ivec4_f, 0, 0, 0, 0);
1327         expectError(GL_INVALID_OPERATION);
1328         m_log << tcu::TestLog::EndSection;
1329 
1330         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}i is used to load a "
1331                                            "uniform variable of type float, vec2, vec3, or vec4.");
1332         glUseProgram(program.getProgram());
1333         glUniform1ui(vec4_v, 0);
1334         expectError(GL_INVALID_OPERATION);
1335         glUniform2ui(vec4_v, 0, 0);
1336         expectError(GL_INVALID_OPERATION);
1337         glUniform3ui(vec4_v, 0, 0, 0);
1338         expectError(GL_INVALID_OPERATION);
1339         glUniform4ui(vec4_v, 0, 0, 0, 0);
1340         expectError(GL_INVALID_OPERATION);
1341         m_log << tcu::TestLog::EndSection;
1342 
1343         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command "
1344                                            "other than glUniform1i and glUniform1iv.");
1345         glUseProgram(program.getProgram());
1346         glUniform1ui(sampler_f, 0);
1347         expectError(GL_INVALID_OPERATION);
1348         m_log << tcu::TestLog::EndSection;
1349 
1350         glUseProgram(0);
1351     });
1352     ES3F_ADD_API_CASE(uniformui_invalid_location, "Invalid glUniform{1234}ui() usage", {
1353         glu::ShaderProgram program(m_context.getRenderContext(),
1354                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1355 
1356         glUseProgram(program.getProgram());
1357         expectError(GL_NO_ERROR);
1358 
1359         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform "
1360                                            "location for the current program object and location is not equal to -1.");
1361         glUseProgram(program.getProgram());
1362         glUniform1i(-2, 0);
1363         expectError(GL_INVALID_OPERATION);
1364         glUniform2i(-2, 0, 0);
1365         expectError(GL_INVALID_OPERATION);
1366         glUniform3i(-2, 0, 0, 0);
1367         expectError(GL_INVALID_OPERATION);
1368         glUniform4i(-2, 0, 0, 0, 0);
1369         expectError(GL_INVALID_OPERATION);
1370 
1371         glUseProgram(program.getProgram());
1372         glUniform1i(-1, 0);
1373         expectError(GL_NO_ERROR);
1374         glUniform2i(-1, 0, 0);
1375         expectError(GL_NO_ERROR);
1376         glUniform3i(-1, 0, 0, 0);
1377         expectError(GL_NO_ERROR);
1378         glUniform4i(-1, 0, 0, 0, 0);
1379         expectError(GL_NO_ERROR);
1380         m_log << tcu::TestLog::EndSection;
1381 
1382         glUseProgram(0);
1383     });
1384 
1385     // glUniform{1234}uiv
1386 
1387     ES3F_ADD_API_CASE(uniformuiv_invalid_program, "Invalid glUniform{234}uiv() usage", {
1388         std::vector<GLuint> data(4);
1389 
1390         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1391         glUseProgram(0);
1392         glUniform1uiv(-1, 1, &data[0]);
1393         expectError(GL_INVALID_OPERATION);
1394         glUniform2uiv(-1, 1, &data[0]);
1395         expectError(GL_INVALID_OPERATION);
1396         glUniform3uiv(-1, 1, &data[0]);
1397         expectError(GL_INVALID_OPERATION);
1398         glUniform4uiv(-1, 1, &data[0]);
1399         expectError(GL_INVALID_OPERATION);
1400         m_log << tcu::TestLog::EndSection;
1401     });
1402     ES3F_ADD_API_CASE(uniformuiv_incompatible_type, "Invalid glUniform{1234}uiv() usage", {
1403         glu::ShaderProgram program(m_context.getRenderContext(),
1404                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1405 
1406         glUseProgram(program.getProgram());
1407         GLint vec4_v    = glGetUniformLocation(program.getProgram(), "vec4_v");    // vec4
1408         GLint ivec4_f   = glGetUniformLocation(program.getProgram(), "ivec4_f");   // ivec4
1409         GLint uvec4_f   = glGetUniformLocation(program.getProgram(), "uvec4_f");   // uvec4
1410         GLint sampler_f = glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
1411         expectError(GL_NO_ERROR);
1412 
1413         if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
1414         {
1415             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1416             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1417         }
1418 
1419         std::vector<GLuint> data(4);
1420 
1421         m_log << tcu::TestLog::Section("",
1422                                        "GL_INVALID_OPERATION is generated if the size of the uniform variable declared "
1423                                        "in the shader does not match the size indicated by the glUniform command.");
1424         glUseProgram(program.getProgram());
1425         glUniform1uiv(uvec4_f, 1, &data[0]);
1426         expectError(GL_INVALID_OPERATION);
1427         glUniform2uiv(uvec4_f, 1, &data[0]);
1428         expectError(GL_INVALID_OPERATION);
1429         glUniform3uiv(uvec4_f, 1, &data[0]);
1430         expectError(GL_INVALID_OPERATION);
1431         glUniform4uiv(uvec4_f, 1, &data[0]);
1432         expectError(GL_NO_ERROR);
1433         m_log << tcu::TestLog::EndSection;
1434 
1435         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}uiv is used to load a "
1436                                            "uniform variable of type float, vec2, vec3, or vec4.");
1437         glUseProgram(program.getProgram());
1438         glUniform1uiv(vec4_v, 1, &data[0]);
1439         expectError(GL_INVALID_OPERATION);
1440         glUniform2uiv(vec4_v, 1, &data[0]);
1441         expectError(GL_INVALID_OPERATION);
1442         glUniform3uiv(vec4_v, 1, &data[0]);
1443         expectError(GL_INVALID_OPERATION);
1444         glUniform4uiv(vec4_v, 1, &data[0]);
1445         expectError(GL_INVALID_OPERATION);
1446         m_log << tcu::TestLog::EndSection;
1447 
1448         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if glUniform{1234}uiv is used to load a "
1449                                            "uniform variable of type int, ivec2, ivec3 or ivec4.");
1450         glUseProgram(program.getProgram());
1451         glUniform1uiv(ivec4_f, 1, &data[0]);
1452         expectError(GL_INVALID_OPERATION);
1453         glUniform2uiv(ivec4_f, 1, &data[0]);
1454         expectError(GL_INVALID_OPERATION);
1455         glUniform3uiv(ivec4_f, 1, &data[0]);
1456         expectError(GL_INVALID_OPERATION);
1457         glUniform4uiv(ivec4_f, 1, &data[0]);
1458         expectError(GL_INVALID_OPERATION);
1459         m_log << tcu::TestLog::EndSection;
1460 
1461         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command "
1462                                            "other than glUniform1i and glUniform1iv.");
1463         glUseProgram(program.getProgram());
1464         glUniform1uiv(sampler_f, 1, &data[0]);
1465         expectError(GL_INVALID_OPERATION);
1466         m_log << tcu::TestLog::EndSection;
1467 
1468         glUseProgram(0);
1469     });
1470     ES3F_ADD_API_CASE(uniformuiv_invalid_location, "Invalid glUniform{1234}uiv() usage", {
1471         glu::ShaderProgram program(m_context.getRenderContext(),
1472                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1473 
1474         glUseProgram(program.getProgram());
1475         expectError(GL_NO_ERROR);
1476 
1477         std::vector<GLuint> data(4);
1478 
1479         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform "
1480                                            "location for the current program object and location is not equal to -1.");
1481         glUseProgram(program.getProgram());
1482         glUniform1uiv(-2, 1, &data[0]);
1483         expectError(GL_INVALID_OPERATION);
1484         glUniform2uiv(-2, 1, &data[0]);
1485         expectError(GL_INVALID_OPERATION);
1486         glUniform3uiv(-2, 1, &data[0]);
1487         expectError(GL_INVALID_OPERATION);
1488         glUniform4uiv(-2, 1, &data[0]);
1489         expectError(GL_INVALID_OPERATION);
1490 
1491         glUseProgram(program.getProgram());
1492         glUniform1uiv(-1, 1, &data[0]);
1493         expectError(GL_NO_ERROR);
1494         glUniform2uiv(-1, 1, &data[0]);
1495         expectError(GL_NO_ERROR);
1496         glUniform3uiv(-1, 1, &data[0]);
1497         expectError(GL_NO_ERROR);
1498         glUniform4uiv(-1, 1, &data[0]);
1499         expectError(GL_NO_ERROR);
1500         m_log << tcu::TestLog::EndSection;
1501 
1502         glUseProgram(0);
1503     });
1504     ES3F_ADD_API_CASE(uniformuiv_invalid_count, "Invalid glUniform{1234}uiv() usage", {
1505         glu::ShaderProgram program(m_context.getRenderContext(),
1506                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1507 
1508         glUseProgram(program.getProgram());
1509         int uvec4_f = glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
1510         expectError(GL_NO_ERROR);
1511 
1512         if (uvec4_f == -1)
1513         {
1514             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1515             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1516         }
1517 
1518         std::vector<GLuint> data(8);
1519 
1520         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if count is greater than 1 and the "
1521                                            "indicated uniform variable is not an array variable.");
1522         glUseProgram(program.getProgram());
1523         glUniform1uiv(uvec4_f, 2, &data[0]);
1524         expectError(GL_INVALID_OPERATION);
1525         glUniform2uiv(uvec4_f, 2, &data[0]);
1526         expectError(GL_INVALID_OPERATION);
1527         glUniform3uiv(uvec4_f, 2, &data[0]);
1528         expectError(GL_INVALID_OPERATION);
1529         glUniform4uiv(uvec4_f, 2, &data[0]);
1530         expectError(GL_INVALID_OPERATION);
1531         m_log << tcu::TestLog::EndSection;
1532 
1533         glUseProgram(0);
1534     });
1535 
1536     // glUniformMatrix*fv
1537 
1538     ES3F_ADD_API_CASE(uniform_matrixfv_invalid_program, "Invalid glUniformMatrix{234}fv() usage", {
1539         std::vector<GLfloat> data(16);
1540 
1541         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if there is no current program object.");
1542         glUseProgram(0);
1543         glUniformMatrix2fv(-1, 1, GL_FALSE, &data[0]);
1544         expectError(GL_INVALID_OPERATION);
1545         glUniformMatrix3fv(-1, 1, GL_FALSE, &data[0]);
1546         expectError(GL_INVALID_OPERATION);
1547         glUniformMatrix4fv(-1, 1, GL_FALSE, &data[0]);
1548         expectError(GL_INVALID_OPERATION);
1549 
1550         glUniformMatrix2x3fv(-1, 1, GL_FALSE, &data[0]);
1551         expectError(GL_INVALID_OPERATION);
1552         glUniformMatrix3x2fv(-1, 1, GL_FALSE, &data[0]);
1553         expectError(GL_INVALID_OPERATION);
1554         glUniformMatrix2x4fv(-1, 1, GL_FALSE, &data[0]);
1555         expectError(GL_INVALID_OPERATION);
1556         glUniformMatrix4x2fv(-1, 1, GL_FALSE, &data[0]);
1557         expectError(GL_INVALID_OPERATION);
1558         glUniformMatrix3x4fv(-1, 1, GL_FALSE, &data[0]);
1559         expectError(GL_INVALID_OPERATION);
1560         glUniformMatrix4x3fv(-1, 1, GL_FALSE, &data[0]);
1561         expectError(GL_INVALID_OPERATION);
1562         m_log << tcu::TestLog::EndSection;
1563     });
1564     ES3F_ADD_API_CASE(uniform_matrixfv_incompatible_type, "Invalid glUniformMatrix{234}fv() usage", {
1565         glu::ShaderProgram program(m_context.getRenderContext(),
1566                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1567 
1568         glUseProgram(program.getProgram());
1569         GLint mat4_v    = glGetUniformLocation(program.getProgram(), "mat4_v");    // mat4
1570         GLint sampler_f = glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
1571         expectError(GL_NO_ERROR);
1572 
1573         if (mat4_v == -1 || sampler_f == -1)
1574         {
1575             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1576             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1577         }
1578 
1579         std::vector<GLfloat> data(16);
1580 
1581         m_log << tcu::TestLog::Section("",
1582                                        "GL_INVALID_OPERATION is generated if the size of the uniform variable declared "
1583                                        "in the shader does not match the size indicated by the glUniform command.");
1584         glUseProgram(program.getProgram());
1585         glUniformMatrix2fv(mat4_v, 1, GL_FALSE, &data[0]);
1586         expectError(GL_INVALID_OPERATION);
1587         glUniformMatrix3fv(mat4_v, 1, GL_FALSE, &data[0]);
1588         expectError(GL_INVALID_OPERATION);
1589         glUniformMatrix4fv(mat4_v, 1, GL_FALSE, &data[0]);
1590         expectError(GL_NO_ERROR);
1591 
1592         glUniformMatrix2x3fv(mat4_v, 1, GL_FALSE, &data[0]);
1593         expectError(GL_INVALID_OPERATION);
1594         glUniformMatrix3x2fv(mat4_v, 1, GL_FALSE, &data[0]);
1595         expectError(GL_INVALID_OPERATION);
1596         glUniformMatrix2x4fv(mat4_v, 1, GL_FALSE, &data[0]);
1597         expectError(GL_INVALID_OPERATION);
1598         glUniformMatrix4x2fv(mat4_v, 1, GL_FALSE, &data[0]);
1599         expectError(GL_INVALID_OPERATION);
1600         glUniformMatrix3x4fv(mat4_v, 1, GL_FALSE, &data[0]);
1601         expectError(GL_INVALID_OPERATION);
1602         glUniformMatrix4x3fv(mat4_v, 1, GL_FALSE, &data[0]);
1603         expectError(GL_INVALID_OPERATION);
1604         m_log << tcu::TestLog::EndSection;
1605 
1606         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if a sampler is loaded using a command "
1607                                            "other than glUniform1i and glUniform1iv.");
1608         glUseProgram(program.getProgram());
1609         glUniformMatrix2fv(sampler_f, 1, GL_FALSE, &data[0]);
1610         expectError(GL_INVALID_OPERATION);
1611         glUniformMatrix3fv(sampler_f, 1, GL_FALSE, &data[0]);
1612         expectError(GL_INVALID_OPERATION);
1613         glUniformMatrix4fv(sampler_f, 1, GL_FALSE, &data[0]);
1614         expectError(GL_INVALID_OPERATION);
1615 
1616         glUniformMatrix2x3fv(sampler_f, 1, GL_FALSE, &data[0]);
1617         expectError(GL_INVALID_OPERATION);
1618         glUniformMatrix3x2fv(sampler_f, 1, GL_FALSE, &data[0]);
1619         expectError(GL_INVALID_OPERATION);
1620         glUniformMatrix2x4fv(sampler_f, 1, GL_FALSE, &data[0]);
1621         expectError(GL_INVALID_OPERATION);
1622         glUniformMatrix4x2fv(sampler_f, 1, GL_FALSE, &data[0]);
1623         expectError(GL_INVALID_OPERATION);
1624         glUniformMatrix3x4fv(sampler_f, 1, GL_FALSE, &data[0]);
1625         expectError(GL_INVALID_OPERATION);
1626         glUniformMatrix4x3fv(sampler_f, 1, GL_FALSE, &data[0]);
1627         expectError(GL_INVALID_OPERATION);
1628         m_log << tcu::TestLog::EndSection;
1629 
1630         glUseProgram(0);
1631     });
1632     ES3F_ADD_API_CASE(uniform_matrixfv_invalid_location, "Invalid glUniformMatrix{234}fv() usage", {
1633         glu::ShaderProgram program(m_context.getRenderContext(),
1634                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1635 
1636         glUseProgram(program.getProgram());
1637         expectError(GL_NO_ERROR);
1638 
1639         std::vector<GLfloat> data(16);
1640 
1641         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if location is an invalid uniform "
1642                                            "location for the current program object and location is not equal to -1.");
1643         glUseProgram(program.getProgram());
1644         glUniformMatrix2fv(-2, 1, GL_FALSE, &data[0]);
1645         expectError(GL_INVALID_OPERATION);
1646         glUniformMatrix3fv(-2, 1, GL_FALSE, &data[0]);
1647         expectError(GL_INVALID_OPERATION);
1648         glUniformMatrix4fv(-2, 1, GL_FALSE, &data[0]);
1649         expectError(GL_INVALID_OPERATION);
1650 
1651         glUniformMatrix2x3fv(-2, 1, GL_FALSE, &data[0]);
1652         expectError(GL_INVALID_OPERATION);
1653         glUniformMatrix3x2fv(-2, 1, GL_FALSE, &data[0]);
1654         expectError(GL_INVALID_OPERATION);
1655         glUniformMatrix2x4fv(-2, 1, GL_FALSE, &data[0]);
1656         expectError(GL_INVALID_OPERATION);
1657         glUniformMatrix4x2fv(-2, 1, GL_FALSE, &data[0]);
1658         expectError(GL_INVALID_OPERATION);
1659         glUniformMatrix3x4fv(-2, 1, GL_FALSE, &data[0]);
1660         expectError(GL_INVALID_OPERATION);
1661         glUniformMatrix4x3fv(-2, 1, GL_FALSE, &data[0]);
1662         expectError(GL_INVALID_OPERATION);
1663 
1664         glUseProgram(program.getProgram());
1665         glUniformMatrix2fv(-1, 1, GL_FALSE, &data[0]);
1666         expectError(GL_NO_ERROR);
1667         glUniformMatrix3fv(-1, 1, GL_FALSE, &data[0]);
1668         expectError(GL_NO_ERROR);
1669         glUniformMatrix4fv(-1, 1, GL_FALSE, &data[0]);
1670         expectError(GL_NO_ERROR);
1671 
1672         glUniformMatrix2x3fv(-1, 1, GL_FALSE, &data[0]);
1673         expectError(GL_NO_ERROR);
1674         glUniformMatrix3x2fv(-1, 1, GL_FALSE, &data[0]);
1675         expectError(GL_NO_ERROR);
1676         glUniformMatrix2x4fv(-1, 1, GL_FALSE, &data[0]);
1677         expectError(GL_NO_ERROR);
1678         glUniformMatrix4x2fv(-1, 1, GL_FALSE, &data[0]);
1679         expectError(GL_NO_ERROR);
1680         glUniformMatrix3x4fv(-1, 1, GL_FALSE, &data[0]);
1681         expectError(GL_NO_ERROR);
1682         glUniformMatrix4x3fv(-1, 1, GL_FALSE, &data[0]);
1683         expectError(GL_NO_ERROR);
1684         m_log << tcu::TestLog::EndSection;
1685 
1686         glUseProgram(0);
1687     });
1688     ES3F_ADD_API_CASE(uniform_matrixfv_invalid_count, "Invalid glUniformMatrix{234}fv() usage", {
1689         glu::ShaderProgram program(m_context.getRenderContext(),
1690                                    glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
1691 
1692         glUseProgram(program.getProgram());
1693         GLint mat4_v = glGetUniformLocation(program.getProgram(), "mat4_v"); // mat4
1694         expectError(GL_NO_ERROR);
1695 
1696         if (mat4_v == -1)
1697         {
1698             m_log << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
1699             m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location");
1700         }
1701 
1702         std::vector<GLfloat> data(32);
1703 
1704         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if count is greater than 1 and the "
1705                                            "indicated uniform variable is not an array variable.");
1706         glUseProgram(program.getProgram());
1707         glUniformMatrix2fv(mat4_v, 2, GL_FALSE, &data[0]);
1708         expectError(GL_INVALID_OPERATION);
1709         glUniformMatrix3fv(mat4_v, 2, GL_FALSE, &data[0]);
1710         expectError(GL_INVALID_OPERATION);
1711         glUniformMatrix4fv(mat4_v, 2, GL_FALSE, &data[0]);
1712         expectError(GL_INVALID_OPERATION);
1713 
1714         glUniformMatrix2x3fv(mat4_v, 1, GL_FALSE, &data[0]);
1715         expectError(GL_INVALID_OPERATION);
1716         glUniformMatrix3x2fv(mat4_v, 1, GL_FALSE, &data[0]);
1717         expectError(GL_INVALID_OPERATION);
1718         glUniformMatrix2x4fv(mat4_v, 1, GL_FALSE, &data[0]);
1719         expectError(GL_INVALID_OPERATION);
1720         glUniformMatrix4x2fv(mat4_v, 1, GL_FALSE, &data[0]);
1721         expectError(GL_INVALID_OPERATION);
1722         glUniformMatrix3x4fv(mat4_v, 1, GL_FALSE, &data[0]);
1723         expectError(GL_INVALID_OPERATION);
1724         glUniformMatrix4x3fv(mat4_v, 1, GL_FALSE, &data[0]);
1725         expectError(GL_INVALID_OPERATION);
1726         m_log << tcu::TestLog::EndSection;
1727 
1728         glUseProgram(0);
1729     });
1730 
1731     // Transform feedback
1732 
1733     ES3F_ADD_API_CASE(gen_transform_feedbacks, "Invalid glGenTransformFeedbacks() usage", {
1734         m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
1735         GLuint id;
1736         glGenTransformFeedbacks(-1, &id);
1737         expectError(GL_INVALID_VALUE);
1738         m_log << tcu::TestLog::EndSection;
1739     });
1740     ES3F_ADD_API_CASE(bind_transform_feedback, "Invalid glBindTransformFeedback() usage", {
1741         GLuint tfID[2];
1742         glu::ShaderProgram program(m_context.getRenderContext(),
1743                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1744         uint32_t buf;
1745         const char *tfVarying = "gl_Position";
1746 
1747         glGenBuffers(1, &buf);
1748         glGenTransformFeedbacks(2, tfID);
1749 
1750         m_log << tcu::TestLog::Section("", "GL_INVALID_ENUM is generated if target is not GL_TRANSFORM_FEEDBACK.");
1751         glBindTransformFeedback(-1, tfID[0]);
1752         expectError(GL_INVALID_ENUM);
1753         m_log << tcu::TestLog::EndSection;
1754 
1755         m_log << tcu::TestLog::Section("",
1756                                        "GL_INVALID_OPERATION is generated if the transform feedback operation is "
1757                                        "active on the currently bound transform feedback object, and is not paused.");
1758         glUseProgram(program.getProgram());
1759         glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1760         glLinkProgram(program.getProgram());
1761         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID[0]);
1762         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1763         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1764         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1765         glBeginTransformFeedback(GL_TRIANGLES);
1766         expectError(GL_NO_ERROR);
1767 
1768         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID[1]);
1769         expectError(GL_INVALID_OPERATION);
1770 
1771         glEndTransformFeedback();
1772         expectError(GL_NO_ERROR);
1773         m_log << tcu::TestLog::EndSection;
1774 
1775         glUseProgram(0);
1776         glDeleteBuffers(1, &buf);
1777         glDeleteTransformFeedbacks(2, tfID);
1778         expectError(GL_NO_ERROR);
1779     });
1780     ES3F_ADD_API_CASE(delete_transform_feedbacks, "Invalid glDeleteTransformFeedbacks() usage", {
1781         GLuint id;
1782         glGenTransformFeedbacks(1, &id);
1783 
1784         m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if n is negative.");
1785         glDeleteTransformFeedbacks(-1, &id);
1786         expectError(GL_INVALID_VALUE);
1787         m_log << tcu::TestLog::EndSection;
1788 
1789         glDeleteTransformFeedbacks(1, &id);
1790     });
1791     ES3F_ADD_API_CASE(begin_transform_feedback, "Invalid glBeginTransformFeedback() usage", {
1792         GLuint tfID[2];
1793         glu::ShaderProgram program(m_context.getRenderContext(),
1794                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1795         uint32_t buf;
1796         const char *tfVarying = "gl_Position";
1797 
1798         glGenBuffers(1, &buf);
1799         glGenTransformFeedbacks(2, tfID);
1800 
1801         glUseProgram(program.getProgram());
1802         glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1803         glLinkProgram(program.getProgram());
1804         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID[0]);
1805         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1806         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1807         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1808         expectError(GL_NO_ERROR);
1809 
1810         m_log << tcu::TestLog::Section(
1811             "", "GL_INVALID_ENUM is generated if primitiveMode is not one of GL_POINTS, GL_LINES, or GL_TRIANGLES.");
1812         glBeginTransformFeedback(-1);
1813         expectError(GL_INVALID_ENUM);
1814         m_log << tcu::TestLog::EndSection;
1815 
1816         m_log << tcu::TestLog::Section("",
1817                                        "GL_INVALID_OPERATION is generated if transform feedback is already active.");
1818         glBeginTransformFeedback(GL_TRIANGLES);
1819         expectError(GL_NO_ERROR);
1820         glBeginTransformFeedback(GL_POINTS);
1821         expectError(GL_INVALID_OPERATION);
1822         m_log << tcu::TestLog::EndSection;
1823 
1824         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if any binding point used in transform "
1825                                            "feedback mode does not have a buffer object bound.");
1826         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
1827         glBeginTransformFeedback(GL_TRIANGLES);
1828         expectError(GL_INVALID_OPERATION);
1829         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1830         m_log << tcu::TestLog::EndSection;
1831 
1832         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if no binding points would be used "
1833                                            "because no program object is active.");
1834         glUseProgram(0);
1835         glBeginTransformFeedback(GL_TRIANGLES);
1836         expectError(GL_INVALID_OPERATION);
1837         glUseProgram(program.getProgram());
1838         m_log << tcu::TestLog::EndSection;
1839 
1840         m_log << tcu::TestLog::Section("",
1841                                        "GL_INVALID_OPERATION is generated if no binding points would be used because "
1842                                        "the active program object has specified no varying variables to record.");
1843         glTransformFeedbackVaryings(program.getProgram(), 0, 0, GL_INTERLEAVED_ATTRIBS);
1844         glBeginTransformFeedback(GL_TRIANGLES);
1845         expectError(GL_INVALID_OPERATION);
1846         m_log << tcu::TestLog::EndSection;
1847 
1848         glEndTransformFeedback();
1849         glDeleteBuffers(1, &buf);
1850         glDeleteTransformFeedbacks(2, tfID);
1851         expectError(GL_NO_ERROR);
1852     });
1853     ES3F_ADD_API_CASE(pause_transform_feedback, "Invalid glPauseTransformFeedback() usage", {
1854         GLuint tfID[2];
1855         glu::ShaderProgram program(m_context.getRenderContext(),
1856                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1857         uint32_t buf;
1858         const char *tfVarying = "gl_Position";
1859 
1860         glGenBuffers(1, &buf);
1861         glGenTransformFeedbacks(2, tfID);
1862 
1863         glUseProgram(program.getProgram());
1864         glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1865         glLinkProgram(program.getProgram());
1866         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID[0]);
1867         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1868         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1869         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1870         expectError(GL_NO_ERROR);
1871 
1872         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the currently bound transform "
1873                                            "feedback object is not active or is paused.");
1874         glPauseTransformFeedback();
1875         expectError(GL_INVALID_OPERATION);
1876         glBeginTransformFeedback(GL_TRIANGLES);
1877         glPauseTransformFeedback();
1878         expectError(GL_NO_ERROR);
1879         glPauseTransformFeedback();
1880         expectError(GL_INVALID_OPERATION);
1881         m_log << tcu::TestLog::EndSection;
1882 
1883         glEndTransformFeedback();
1884         glDeleteBuffers(1, &buf);
1885         glDeleteTransformFeedbacks(2, tfID);
1886         expectError(GL_NO_ERROR);
1887     });
1888     ES3F_ADD_API_CASE(resume_transform_feedback, "Invalid glResumeTransformFeedback() usage", {
1889         GLuint tfID[2];
1890         glu::ShaderProgram program(m_context.getRenderContext(),
1891                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1892         uint32_t buf;
1893         const char *tfVarying = "gl_Position";
1894 
1895         glGenBuffers(1, &buf);
1896         glGenTransformFeedbacks(2, tfID);
1897 
1898         glUseProgram(program.getProgram());
1899         glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1900         glLinkProgram(program.getProgram());
1901         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID[0]);
1902         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1903         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1904         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1905         expectError(GL_NO_ERROR);
1906 
1907         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if the currently bound transform "
1908                                            "feedback object is not active or is not paused.");
1909         glResumeTransformFeedback();
1910         expectError(GL_INVALID_OPERATION);
1911         glBeginTransformFeedback(GL_TRIANGLES);
1912         glResumeTransformFeedback();
1913         expectError(GL_INVALID_OPERATION);
1914         glPauseTransformFeedback();
1915         glResumeTransformFeedback();
1916         expectError(GL_NO_ERROR);
1917         m_log << tcu::TestLog::EndSection;
1918 
1919         glEndTransformFeedback();
1920         glDeleteBuffers(1, &buf);
1921         glDeleteTransformFeedbacks(2, tfID);
1922         expectError(GL_NO_ERROR);
1923     });
1924     ES3F_ADD_API_CASE(end_transform_feedback, "Invalid glEndTransformFeedback() usage", {
1925         GLuint tfID;
1926         glu::ShaderProgram program(m_context.getRenderContext(),
1927                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1928         uint32_t buf;
1929         const char *tfVarying = "gl_Position";
1930 
1931         glGenBuffers(1, &buf);
1932         glGenTransformFeedbacks(1, &tfID);
1933 
1934         glUseProgram(program.getProgram());
1935         glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1936         glLinkProgram(program.getProgram());
1937         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
1938         glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
1939         glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
1940         glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
1941         expectError(GL_NO_ERROR);
1942 
1943         m_log << tcu::TestLog::Section("", "GL_INVALID_OPERATION is generated if transform feedback is not active.");
1944         glEndTransformFeedback();
1945         expectError(GL_INVALID_OPERATION);
1946         glBeginTransformFeedback(GL_TRIANGLES);
1947         glEndTransformFeedback();
1948         expectError(GL_NO_ERROR);
1949         m_log << tcu::TestLog::EndSection;
1950 
1951         glDeleteBuffers(1, &buf);
1952         glDeleteTransformFeedbacks(1, &tfID);
1953         expectError(GL_NO_ERROR);
1954     });
1955     ES3F_ADD_API_CASE(get_transform_feedback_varying, "Invalid glGetTransformFeedbackVarying() usage", {
1956         GLuint tfID;
1957         glu::ShaderProgram program(m_context.getRenderContext(),
1958                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
1959         glu::ShaderProgram programInvalid(m_context.getRenderContext(),
1960                                           glu::makeVtxFragSources(vertexShaderSource, ""));
1961         const char *tfVarying            = "gl_Position";
1962         int maxTransformFeedbackVaryings = 0;
1963 
1964         GLsizei length;
1965         GLsizei size;
1966         GLenum type;
1967         char name[32];
1968 
1969         glGenTransformFeedbacks(1, &tfID);
1970 
1971         glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
1972         expectError(GL_NO_ERROR);
1973         glLinkProgram(program.getProgram());
1974         expectError(GL_NO_ERROR);
1975 
1976         glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID);
1977         expectError(GL_NO_ERROR);
1978 
1979         m_log << tcu::TestLog::Section("",
1980                                        "GL_INVALID_VALUE is generated if program is not the name of a program object.");
1981         glGetTransformFeedbackVarying(-1, 0, 32, &length, &size, &type, &name[0]);
1982         expectError(GL_INVALID_VALUE);
1983         m_log << tcu::TestLog::EndSection;
1984 
1985         m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater or equal to the value of "
1986                                            "GL_TRANSFORM_FEEDBACK_VARYINGS.");
1987         glGetProgramiv(program.getProgram(), GL_TRANSFORM_FEEDBACK_VARYINGS, &maxTransformFeedbackVaryings);
1988         glGetTransformFeedbackVarying(program.getProgram(), maxTransformFeedbackVaryings, 32, &length, &size, &type,
1989                                       &name[0]);
1990         expectError(GL_INVALID_VALUE);
1991         m_log << tcu::TestLog::EndSection;
1992 
1993         m_log << tcu::TestLog::Section(
1994             "", "GL_INVALID_OPERATION or GL_INVALID_VALUE is generated program has not been linked.");
1995         glGetTransformFeedbackVarying(programInvalid.getProgram(), 0, 32, &length, &size, &type, &name[0]);
1996         expectError(GL_INVALID_OPERATION, GL_INVALID_VALUE);
1997         m_log << tcu::TestLog::EndSection;
1998 
1999         glDeleteTransformFeedbacks(1, &tfID);
2000         expectError(GL_NO_ERROR);
2001     });
2002     ES3F_ADD_API_CASE(transform_feedback_varyings, "Invalid glTransformFeedbackVaryings() usage", {
2003         GLuint tfID;
2004         glu::ShaderProgram program(m_context.getRenderContext(),
2005                                    glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
2006         const char *tfVarying                     = "gl_Position";
2007         GLint maxTransformFeedbackSeparateAttribs = 0;
2008 
2009         glGenTransformFeedbacks(1, &tfID);
2010         expectError(GL_NO_ERROR);
2011 
2012         m_log << tcu::TestLog::Section("",
2013                                        "GL_INVALID_VALUE is generated if program is not the name of a program object.");
2014         glTransformFeedbackVaryings(0, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
2015         expectError(GL_INVALID_VALUE);
2016         m_log << tcu::TestLog::EndSection;
2017 
2018         m_log << tcu::TestLog::Section("", "GL_INVALID_VALUE is generated if bufferMode is GL_SEPARATE_ATTRIBS and "
2019                                            "count is greater than GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.");
2020         glGetIntegerv(GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxTransformFeedbackSeparateAttribs);
2021         glTransformFeedbackVaryings(program.getProgram(), maxTransformFeedbackSeparateAttribs + 1, &tfVarying,
2022                                     GL_SEPARATE_ATTRIBS);
2023         expectError(GL_INVALID_VALUE);
2024         m_log << tcu::TestLog::EndSection;
2025 
2026         glDeleteTransformFeedbacks(1, &tfID);
2027         expectError(GL_NO_ERROR);
2028     });
2029 }
2030 
2031 } // namespace Functional
2032 } // namespace gles3
2033 } // namespace deqp
2034