/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 3.0 Module * ------------------------------------------------- * * Copyright 2014 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * *//*! * \file * \brief Negative GL State API tests. *//*--------------------------------------------------------------------*/ #include "es3fNegativeStateApiTests.hpp" #include "es3fApiCase.hpp" #include "gluShaderProgram.hpp" #include "gluContextInfo.hpp" #include "deMemory.h" #include "glwDefs.hpp" #include "glwEnums.hpp" using namespace glw; // GL types namespace deqp { namespace gles3 { namespace Functional { using tcu::TestLog; static const char *uniformTestVertSource = "#version 300 es\n" "uniform mediump vec4 vUnif_vec4;\n" "in mediump vec4 attr;" "layout(shared) uniform Block { mediump vec4 blockVar; };\n" "void main (void)\n" "{\n" " gl_Position = vUnif_vec4 + blockVar + attr;\n" "}\n\0"; static const char *uniformTestFragSource = "#version 300 es\n" "uniform mediump ivec4 fUnif_ivec4;\n" "uniform mediump uvec4 fUnif_uvec4;\n" "layout(location = 0) out mediump vec4 fragColor;" "void main (void)\n" "{\n" " fragColor = vec4(vec4(fUnif_ivec4) + vec4(fUnif_uvec4));\n" "}\n\0"; NegativeStateApiTests::NegativeStateApiTests(Context &context) : TestCaseGroup(context, "state", "Negative GL State API Cases") { } NegativeStateApiTests::~NegativeStateApiTests(void) { } void NegativeStateApiTests::init(void) { // Enabling & disabling states ES3F_ADD_API_CASE(enable, "Invalid glEnable() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if cap is not one of the allowed values."); glEnable(-1); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(disable, "Invalid glDisable() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if cap is not one of the allowed values."); glDisable(-1); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); // Simple state queries ES3F_ADD_API_CASE(get_booleanv, "Invalid glGetBooleanv() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not one of the allowed values."); GLboolean params = GL_FALSE; glGetBooleanv(-1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_floatv, "Invalid glGetFloatv() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not one of the allowed values."); GLfloat params = 0.0f; glGetFloatv(-1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_integerv, "Invalid glGetIntegerv() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not one of the allowed values."); GLint params = -1; glGetIntegerv(-1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_integer64v, "Invalid glGetInteger64v() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not one of the allowed values."); GLint64 params = -1; glGetInteger64v(-1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_integeri_v, "Invalid glGetIntegeri_v() usage", { GLint data = -1; GLint maxUniformBufferBindings; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if name is not an accepted value."); glGetIntegeri_v(-1, 0, &data); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is outside of the valid range for the indexed state target."); glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings); expectError(GL_NO_ERROR); glGetIntegeri_v(GL_UNIFORM_BUFFER_BINDING, maxUniformBufferBindings, &data); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_integer64i_v, "Invalid glGetInteger64i_v() usage", { GLint64 data = (GLint64)-1; ; GLint maxUniformBufferBindings; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if name is not an accepted value."); glGetInteger64i_v(-1, 0, &data); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is outside of the valid range for the indexed state target."); glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings); expectError(GL_NO_ERROR); glGetInteger64i_v(GL_UNIFORM_BUFFER_START, maxUniformBufferBindings, &data); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_string, "Invalid glGetString() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if name is not an accepted value."); glGetString(-1); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_stringi, "Invalid glGetStringi() usage", { GLint numExtensions; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if name is not an accepted value."); glGetStringi(-1, 0); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is outside the valid range for indexed state name."); glGetIntegerv(GL_NUM_EXTENSIONS, &numExtensions); glGetStringi(GL_EXTENSIONS, numExtensions); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); // Enumerated state queries: Shaders ES3F_ADD_API_CASE(get_attached_shaders, "Invalid glGetAttachedShaders() usage", { GLuint shaders[1]; GLuint shaderObject = glCreateShader(GL_VERTEX_SHADER); GLuint program = glCreateProgram(); GLsizei count[1]; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetAttachedShaders(-1, 1, &count[0], &shaders[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object."); glGetAttachedShaders(shaderObject, 1, &count[0], &shaders[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if maxCount is less than 0."); glGetAttachedShaders(program, -1, &count[0], &shaders[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; glDeleteShader(shaderObject); glDeleteProgram(program); }); ES3F_ADD_API_CASE(get_shaderiv, "Invalid glGetShaderiv() usage", { GLboolean shaderCompilerSupported; glGetBooleanv(GL_SHADER_COMPILER, &shaderCompilerSupported); m_log << TestLog::Message << "// GL_SHADER_COMPILER = " << (shaderCompilerSupported ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage; GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLuint program = glCreateProgram(); GLint param[1] = {-1}; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetShaderiv(shader, -1, ¶m[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL."); glGetShaderiv(-1, GL_SHADER_TYPE, ¶m[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader does not refer to a shader object."); glGetShaderiv(program, GL_SHADER_TYPE, ¶m[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteShader(shader); glDeleteProgram(program); }); ES3F_ADD_API_CASE(get_shader_info_log, "Invalid glGetShaderInfoLog() usage", { GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLuint program = glCreateProgram(); GLsizei length[1] = {0}; char infoLog[128] = {0}; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL."); glGetShaderInfoLog(-1, 128, &length[0], &infoLog[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object."); glGetShaderInfoLog(program, 128, &length[0], &infoLog[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if maxLength is less than 0."); glGetShaderInfoLog(shader, -1, &length[0], &infoLog[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; glDeleteShader(shader); glDeleteProgram(program); }); ES3F_ADD_API_CASE(get_shader_precision_format, "Invalid glGetShaderPrecisionFormat() usage", { GLboolean shaderCompilerSupported; glGetBooleanv(GL_SHADER_COMPILER, &shaderCompilerSupported); m_log << TestLog::Message << "// GL_SHADER_COMPILER = " << (shaderCompilerSupported ? "GL_TRUE" : "GL_FALSE") << TestLog::EndMessage; GLint range[2]; GLint precision[1]; deMemset(&range[0], 0xcd, sizeof(range)); deMemset(&precision[0], 0xcd, sizeof(precision)); m_log << TestLog::Section( "", "GL_INVALID_ENUM is generated if shaderType or precisionType is not an accepted value."); glGetShaderPrecisionFormat(-1, GL_MEDIUM_FLOAT, &range[0], &precision[0]); expectError(GL_INVALID_ENUM); glGetShaderPrecisionFormat(GL_VERTEX_SHADER, -1, &range[0], &precision[0]); expectError(GL_INVALID_ENUM); glGetShaderPrecisionFormat(-1, -1, &range[0], &precision[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_shader_source, "Invalid glGetShaderSource() usage", { GLsizei length[1] = {0}; char source[1] = {0}; GLuint program = glCreateProgram(); GLuint shader = glCreateShader(GL_VERTEX_SHADER); m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL."); glGetShaderSource(-1, 1, &length[0], &source[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if shader is not a shader object."); glGetShaderSource(program, 1, &length[0], &source[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if bufSize is less than 0."); glGetShaderSource(shader, -1, &length[0], &source[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; glDeleteProgram(program); glDeleteShader(shader); }); // Enumerated state queries: Programs ES3F_ADD_API_CASE(get_programiv, "Invalid glGetProgramiv() usage", { GLuint program = glCreateProgram(); GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLint params[1] = {-1}; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetProgramiv(program, -1, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetProgramiv(-1, GL_LINK_STATUS, ¶ms[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program does not refer to a program object."); glGetProgramiv(shader, GL_LINK_STATUS, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteProgram(program); glDeleteShader(shader); }); ES3F_ADD_API_CASE(get_program_info_log, "Invalid glGetProgramInfoLog() usage", { GLuint program = glCreateProgram(); GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLsizei length[1] = {0}; char infoLog[1] = {0}; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetProgramInfoLog(-1, 1, &length[0], &infoLog[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object."); glGetProgramInfoLog(shader, 1, &length[0], &infoLog[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if maxLength is less than 0."); glGetProgramInfoLog(program, -1, &length[0], &infoLog[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; glDeleteProgram(program); glDeleteShader(shader); }); // Enumerated state queries: Shader variables ES3F_ADD_API_CASE(get_tex_parameterfv, "Invalid glGetTexParameterfv() usage", { GLfloat params[1] = {0.0f}; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target or pname is not an accepted value."); glGetTexParameterfv(-1, GL_TEXTURE_MAG_FILTER, ¶ms[0]); expectError(GL_INVALID_ENUM); glGetTexParameterfv(GL_TEXTURE_2D, -1, ¶ms[0]); expectError(GL_INVALID_ENUM); glGetTexParameterfv(-1, -1, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_tex_parameteriv, "Invalid glGetTexParameteriv() usage", { GLint params[1] = {0}; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target or pname is not an accepted value."); glGetTexParameteriv(-1, GL_TEXTURE_MAG_FILTER, ¶ms[0]); expectError(GL_INVALID_ENUM); glGetTexParameteriv(GL_TEXTURE_2D, -1, ¶ms[0]); expectError(GL_INVALID_ENUM); glGetTexParameteriv(-1, -1, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_uniformfv, "Invalid glGetUniformfv() usage", { glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); glUseProgram(program.getProgram()); GLint unif = glGetUniformLocation(program.getProgram(), "vUnif_vec4"); // vec4 if (unif == -1) m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location"); GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLuint programEmpty = glCreateProgram(); GLfloat params[4] = {0.0f}; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetUniformfv(-1, unif, ¶ms[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object."); glGetUniformfv(shader, unif, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked."); glGetUniformfv(programEmpty, unif, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if location does not correspond to a valid " "uniform variable location for the specified program object."); glGetUniformfv(program.getProgram(), -1, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteShader(shader); glDeleteProgram(programEmpty); }); ES3F_ADD_API_CASE(get_uniformiv, "Invalid glGetUniformiv() usage", { glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); glUseProgram(program.getProgram()); GLint unif = glGetUniformLocation(program.getProgram(), "fUnif_ivec4"); // ivec4 if (unif == -1) m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location"); GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLuint programEmpty = glCreateProgram(); GLint params[4] = {0}; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetUniformiv(-1, unif, ¶ms[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object."); glGetUniformiv(shader, unif, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked."); glGetUniformiv(programEmpty, unif, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if location does not correspond to a valid " "uniform variable location for the specified program object."); glGetUniformiv(program.getProgram(), -1, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteShader(shader); glDeleteProgram(programEmpty); }); ES3F_ADD_API_CASE(get_uniformuiv, "Invalid glGetUniformuiv() usage", { glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); glUseProgram(program.getProgram()); GLint unif = glGetUniformLocation(program.getProgram(), "fUnif_uvec4"); // uvec4 if (unif == -1) m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Failed to retrieve uniform location"); GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLuint programEmpty = glCreateProgram(); GLuint params[4] = {0}; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetUniformuiv(-1, unif, ¶ms[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object."); glGetUniformuiv(shader, unif, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been successfully linked."); glGetUniformuiv(programEmpty, unif, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if location does not correspond to a valid " "uniform variable location for the specified program object."); glGetUniformuiv(program.getProgram(), -1, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteShader(shader); glDeleteProgram(programEmpty); }); ES3F_ADD_API_CASE(get_active_uniform, "Invalid glGetActiveUniform() usage", { GLuint shader = glCreateShader(GL_VERTEX_SHADER); glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); GLint numActiveUniforms = -1; glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORMS, &numActiveUniforms); m_log << TestLog::Message << "// GL_ACTIVE_UNIFORMS = " << numActiveUniforms << " (expected 4)." << TestLog::EndMessage; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetActiveUniform(-1, 0, 0, 0, 0, 0, 0); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object."); glGetActiveUniform(shader, 0, 0, 0, 0, 0, 0); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if index is greater than or equal to the number " "of active uniform variables in program."); glUseProgram(program.getProgram()); glGetActiveUniform(program.getProgram(), numActiveUniforms, 0, 0, 0, 0, 0); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if bufSize is less than 0."); glGetActiveUniform(program.getProgram(), 0, -1, 0, 0, 0, 0); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; glUseProgram(0); glDeleteShader(shader); }); ES3F_ADD_API_CASE(get_active_uniformsiv, "Invalid glGetActiveUniformsiv() usage", { GLuint shader = glCreateShader(GL_VERTEX_SHADER); glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); GLuint unusedUniformIndex = 1; GLint unusedParamDst = -1; GLint numActiveUniforms = -1; glUseProgram(program.getProgram()); glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORMS, &numActiveUniforms); m_log << TestLog::Message << "// GL_ACTIVE_UNIFORMS = " << numActiveUniforms << " (expected 4)." << TestLog::EndMessage; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetActiveUniformsiv(-1, 1, &unusedUniformIndex, GL_UNIFORM_TYPE, &unusedParamDst); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object."); glGetActiveUniformsiv(shader, 1, &unusedUniformIndex, GL_UNIFORM_TYPE, &unusedParamDst); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if any value in uniformIndices is greater than or " "equal to the value of GL_ACTIVE_UNIFORMS for program."); for (int excess = 0; excess <= 2; excess++) { std::vector invalidUniformIndices; invalidUniformIndices.push_back(1); invalidUniformIndices.push_back(numActiveUniforms - 1 + excess); invalidUniformIndices.push_back(1); std::vector unusedParamsDst(invalidUniformIndices.size()); glGetActiveUniformsiv(program.getProgram(), (GLsizei)invalidUniformIndices.size(), &invalidUniformIndices[0], GL_UNIFORM_TYPE, &unusedParamsDst[0]); expectError(excess == 0 ? GL_NO_ERROR : GL_INVALID_VALUE); } m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted token."); glGetActiveUniformsiv(program.getProgram(), 1, &unusedUniformIndex, -1, &unusedParamDst); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; glUseProgram(0); glDeleteShader(shader); }); ES3F_ADD_API_CASE(get_active_uniform_blockiv, "Invalid glGetActiveUniformBlockiv() usage", { glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); GLint params = -1; GLint numActiveBlocks = -1; glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCKS, &numActiveBlocks); m_log << TestLog::Message << "// GL_ACTIVE_UNIFORM_BLOCKS = " << numActiveBlocks << " (expected 1)." << TestLog::EndMessage; expectError(GL_NO_ERROR); m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if uniformBlockIndex is greater than or equal to the value of " "GL_ACTIVE_UNIFORM_BLOCKS or is not the index of an active uniform block in program."); glUseProgram(program.getProgram()); expectError(GL_NO_ERROR); glGetActiveUniformBlockiv(program.getProgram(), numActiveBlocks, GL_UNIFORM_BLOCK_BINDING, ¶ms); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not one of the accepted tokens."); glGetActiveUniformBlockiv(program.getProgram(), 0, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; glUseProgram(0); }); ES3F_ADD_API_CASE(get_active_uniform_block_name, "Invalid glGetActiveUniformBlockName() usage", { glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); GLsizei length = -1; GLint numActiveBlocks = -1; GLchar uniformBlockName[128]; deMemset(&uniformBlockName[0], 0, sizeof(uniformBlockName)); glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCKS, &numActiveBlocks); m_log << TestLog::Message << "// GL_ACTIVE_UNIFORM_BLOCKS = " << numActiveBlocks << " (expected 1)." << TestLog::EndMessage; expectError(GL_NO_ERROR); m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if uniformBlockIndex is greater than or equal to the value of " "GL_ACTIVE_UNIFORM_BLOCKS or is not the index of an active uniform block in program."); glUseProgram(program.getProgram()); expectError(GL_NO_ERROR); glGetActiveUniformBlockName(program.getProgram(), numActiveBlocks, (int)sizeof(uniformBlockName), &length, &uniformBlockName[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; glUseProgram(0); }); ES3F_ADD_API_CASE(get_active_attrib, "Invalid glGetActiveAttrib() usage", { GLuint shader = glCreateShader(GL_VERTEX_SHADER); glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); GLint numActiveAttributes = -1; GLsizei length = -1; GLint size = -1; GLenum type = -1; GLchar name[32]; deMemset(&name[0], 0, sizeof(name)); glGetProgramiv(program.getProgram(), GL_ACTIVE_ATTRIBUTES, &numActiveAttributes); m_log << TestLog::Message << "// GL_ACTIVE_ATTRIBUTES = " << numActiveAttributes << " (expected 1)." << TestLog::EndMessage; glUseProgram(program.getProgram()); m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetActiveAttrib(-1, 0, 32, &length, &size, &type, &name[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is not a program object."); glGetActiveAttrib(shader, 0, 32, &length, &size, &type, &name[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_ACTIVE_ATTRIBUTES."); glGetActiveAttrib(program.getProgram(), numActiveAttributes, (int)sizeof(name), &length, &size, &type, &name[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if bufSize is less than 0."); glGetActiveAttrib(program.getProgram(), 0, -1, &length, &size, &type, &name[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; glUseProgram(0); glDeleteShader(shader); }); ES3F_ADD_API_CASE(get_uniform_indices, "Invalid glGetUniformIndices() usage", { GLuint shader = glCreateShader(GL_VERTEX_SHADER); glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); GLint numActiveBlocks = -1; const GLchar *uniformName = "Block.blockVar"; GLuint uniformIndices = -1; glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCKS, &numActiveBlocks); m_log << TestLog::Message << "// GL_ACTIVE_UNIFORM_BLOCKS = " << numActiveBlocks << TestLog::EndMessage; expectError(GL_NO_ERROR); m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is a name of shader object."); glGetUniformIndices(shader, 1, &uniformName, &uniformIndices); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not name of program or shader object."); GLuint invalid = -1; glGetUniformIndices(invalid, 1, &uniformName, &uniformIndices); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; glUseProgram(0); glDeleteShader(shader); }); ES3F_ADD_API_CASE(get_vertex_attribfv, "Invalid glGetVertexAttribfv() usage", { GLfloat params = 0.0f; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetVertexAttribfv(0, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS."); GLint maxVertexAttribs; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); glGetVertexAttribfv(maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_ENABLED, ¶ms); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_vertex_attribiv, "Invalid glGetVertexAttribiv() usage", { GLint params = -1; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetVertexAttribiv(0, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS."); GLint maxVertexAttribs; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); glGetVertexAttribiv(maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_ENABLED, ¶ms); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_vertex_attribi_iv, "Invalid glGetVertexAttribIiv() usage", { GLint params = -1; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetVertexAttribIiv(0, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS."); GLint maxVertexAttribs; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); glGetVertexAttribIiv(maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_ENABLED, ¶ms); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_vertex_attribi_uiv, "Invalid glGetVertexAttribIuiv() usage", { GLuint params = (GLuint)-1; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetVertexAttribIuiv(0, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS."); GLint maxVertexAttribs; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); glGetVertexAttribIuiv(maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_ENABLED, ¶ms); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_vertex_attrib_pointerv, "Invalid glGetVertexAttribPointerv() usage", { GLvoid *ptr[1] = {DE_NULL}; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetVertexAttribPointerv(0, -1, &ptr[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS."); GLint maxVertexAttribs; glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs); glGetVertexAttribPointerv(maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_POINTER, &ptr[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_frag_data_location, "Invalid glGetFragDataLocation() usage", { GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLuint program = glCreateProgram(); m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program is the name of a shader object."); glGetFragDataLocation(shader, "gl_FragColor"); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if program has not been linked."); glGetFragDataLocation(program, "gl_FragColor"); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteProgram(program); glDeleteShader(shader); }); // Enumerated state queries: Buffers ES3F_ADD_API_CASE(get_buffer_parameteriv, "Invalid glGetBufferParameteriv() usage", { GLint params = -1; GLuint buf; glGenBuffers(1, &buf); glBindBuffer(GL_ARRAY_BUFFER, buf); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target or value is not an accepted value."); glGetBufferParameteriv(-1, GL_BUFFER_SIZE, ¶ms); expectError(GL_INVALID_ENUM); glGetBufferParameteriv(GL_ARRAY_BUFFER, -1, ¶ms); expectError(GL_INVALID_ENUM); glGetBufferParameteriv(-1, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_OPERATION is generated if the reserved buffer object name 0 is bound to target."); glBindBuffer(GL_ARRAY_BUFFER, 0); glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, ¶ms); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteBuffers(1, &buf); }); ES3F_ADD_API_CASE(get_buffer_parameteri64v, "Invalid glGetBufferParameteri64v() usage", { GLint64 params = -1; GLuint buf; glGenBuffers(1, &buf); glBindBuffer(GL_ARRAY_BUFFER, buf); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target or value is not an accepted value."); glGetBufferParameteri64v(-1, GL_BUFFER_SIZE, ¶ms); expectError(GL_INVALID_ENUM); glGetBufferParameteri64v(GL_ARRAY_BUFFER, -1, ¶ms); expectError(GL_INVALID_ENUM); glGetBufferParameteri64v(-1, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_OPERATION is generated if the reserved buffer object name 0 is bound to target."); glBindBuffer(GL_ARRAY_BUFFER, 0); glGetBufferParameteri64v(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, ¶ms); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteBuffers(1, &buf); }); ES3F_ADD_API_CASE(get_buffer_pointerv, "Invalid glGetBufferPointerv() usage", { GLvoid *params = DE_NULL; GLuint buf; glGenBuffers(1, &buf); glBindBuffer(GL_ARRAY_BUFFER, buf); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target or pname is not an accepted value."); glGetBufferPointerv(GL_ARRAY_BUFFER, -1, ¶ms); expectError(GL_INVALID_ENUM); glGetBufferPointerv(-1, GL_BUFFER_MAP_POINTER, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_OPERATION is generated if the reserved buffer object name 0 is bound to target."); glBindBuffer(GL_ARRAY_BUFFER, 0); glGetBufferPointerv(GL_ARRAY_BUFFER, GL_BUFFER_MAP_POINTER, ¶ms); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteBuffers(1, &buf); }); ES3F_ADD_API_CASE(get_framebuffer_attachment_parameteriv, "Invalid glGetFramebufferAttachmentParameteriv() usage", { GLint params[1] = {-1}; GLuint fbo; GLuint rbo[2]; glGenFramebuffers(1, &fbo); glGenRenderbuffers(2, rbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo[0]); glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16, 16, 16); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, rbo[0]); glBindRenderbuffer(GL_RENDERBUFFER, rbo[1]); glRenderbufferStorage(GL_RENDERBUFFER, GL_STENCIL_INDEX8, 16, 16); glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, rbo[1]); glCheckFramebufferStatus(GL_FRAMEBUFFER); expectError(GL_NO_ERROR); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target is not one of the accepted tokens."); glGetFramebufferAttachmentParameteriv(-1, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, ¶ms[0]); // TYPE is GL_RENDERBUFFER expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not valid for the value of " "GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE."); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, ¶ms[0]); // TYPE is GL_RENDERBUFFER expectError(GL_INVALID_ENUM); glBindFramebuffer(GL_FRAMEBUFFER, 0); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ¶ms[0]); // TYPE is GL_FRAMEBUFFER_DEFAULT expectError(GL_INVALID_ENUM); glBindFramebuffer(GL_FRAMEBUFFER, fbo); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if attachment is GL_DEPTH_STENCIL_ATTACHMENT and " "different objects are bound to the depth and stencil attachment points of target."); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_OPERATION is generated if the value of GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is GL_NONE " "and pname is not GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME."); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ¶ms[0]); // TYPE is GL_NONE expectError(GL_NO_ERROR); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE, ¶ms[0]); // TYPE is GL_NONE expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION or GL_INVALID_ENUM is generated if attachment is not one " "of the accepted values for the current binding of target."); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_BACK, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ¶ms[0]); // A FBO is bound so GL_BACK is invalid expectError(GL_INVALID_OPERATION, GL_INVALID_ENUM); glBindFramebuffer(GL_FRAMEBUFFER, 0); glGetFramebufferAttachmentParameteriv( GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ¶ms[0]); // Default framebuffer is bound so GL_COLOR_ATTACHMENT0 is invalid expectError(GL_INVALID_OPERATION, GL_INVALID_ENUM); m_log << TestLog::EndSection; glDeleteFramebuffers(1, &fbo); }); ES3F_ADD_API_CASE(get_renderbuffer_parameteriv, "Invalid glGetRenderbufferParameteriv() usage", { GLint params[1] = {-1}; GLuint rbo; glGenRenderbuffers(1, &rbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target is not GL_RENDERBUFFER."); glGetRenderbufferParameteriv(-1, GL_RENDERBUFFER_WIDTH, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not one of the accepted tokens."); glGetRenderbufferParameteriv(GL_RENDERBUFFER, -1, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; glDeleteRenderbuffers(1, &rbo); glBindRenderbuffer(GL_RENDERBUFFER, 0); }); ES3F_ADD_API_CASE(get_internalformativ, "Invalid glGetInternalformativ() usage", { const bool isES = glu::isContextTypeES(m_context.getRenderContext().getType()); GLint params[16]; deMemset(¶ms[0], 0xcd, sizeof(params)); m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if bufSize is negative."); glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, -1, ¶ms[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not GL_SAMPLES or GL_NUM_SAMPLE_COUNTS."); glGetInternalformativ(GL_RENDERBUFFER, GL_RGBA8, -1, 16, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; if (isES) { m_log << TestLog::Section( "", "GL_INVALID_ENUM is generated if internalformat is not color-, depth-, or stencil-renderable."); if (!m_context.getContextInfo().isExtensionSupported("GL_EXT_render_snorm")) { glGetInternalformativ(GL_RENDERBUFFER, GL_RG8_SNORM, GL_NUM_SAMPLE_COUNTS, 16, ¶ms[0]); expectError(GL_INVALID_ENUM); } glGetInternalformativ(GL_RENDERBUFFER, GL_COMPRESSED_RGB8_ETC2, GL_NUM_SAMPLE_COUNTS, 16, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; } m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target is not GL_RENDERBUFFER."); glGetInternalformativ(-1, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 16, ¶ms[0]); expectError(GL_INVALID_ENUM); glGetInternalformativ(GL_FRAMEBUFFER, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 16, ¶ms[0]); expectError(GL_INVALID_ENUM); if (isES && !m_context.getContextInfo().isExtensionSupported("GL_EXT_sparse_texture")) { glGetInternalformativ(GL_TEXTURE_2D, GL_RGBA8, GL_NUM_SAMPLE_COUNTS, 16, ¶ms[0]); expectError(GL_INVALID_ENUM); } m_log << TestLog::EndSection; }); // Query object queries ES3F_ADD_API_CASE(get_queryiv, "Invalid glGetQueryiv() usage", { GLint params = -1; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target or pname is not an accepted value."); glGetQueryiv(GL_ANY_SAMPLES_PASSED, -1, ¶ms); expectError(GL_INVALID_ENUM); glGetQueryiv(-1, GL_CURRENT_QUERY, ¶ms); expectError(GL_INVALID_ENUM); glGetQueryiv(-1, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES3F_ADD_API_CASE(get_query_objectuiv, "Invalid glGetQueryObjectuiv() usage", { GLuint params = -1; GLuint id; glGenQueries(1, &id); m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if id is not the name of a query object."); glGetQueryObjectuiv(-1, GL_QUERY_RESULT_AVAILABLE, ¶ms); expectError(GL_INVALID_OPERATION); m_log << TestLog::Message << "// Note: " << id << " is not a query object yet, since it hasn't been used by glBeginQuery" << TestLog::EndMessage; glGetQueryObjectuiv(id, GL_QUERY_RESULT_AVAILABLE, ¶ms); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glBeginQuery(GL_ANY_SAMPLES_PASSED, id); glEndQuery(GL_ANY_SAMPLES_PASSED); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetQueryObjectuiv(id, -1, ¶ms); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section( "", "GL_INVALID_OPERATION is generated if id is the name of a currently active query object."); glBeginQuery(GL_ANY_SAMPLES_PASSED, id); expectError(GL_NO_ERROR); glGetQueryObjectuiv(id, GL_QUERY_RESULT_AVAILABLE, ¶ms); expectError(GL_INVALID_OPERATION); glEndQuery(GL_ANY_SAMPLES_PASSED); expectError(GL_NO_ERROR); m_log << TestLog::EndSection; glDeleteQueries(1, &id); }); // Sync object queries ES3F_ADD_API_CASE(get_synciv, "Invalid glGetSynciv() usage", { GLsizei length = -1; GLint values[32]; GLsync sync; deMemset(&values[0], 0xcd, sizeof(values)); m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if sync is not the name of a sync object."); glGetSynciv(0, GL_OBJECT_TYPE, 32, &length, &values[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not one of the accepted tokens."); sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); expectError(GL_NO_ERROR); glGetSynciv(sync, -1, 32, &length, &values[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); // Enumerated boolean state queries ES3F_ADD_API_CASE(is_enabled, "Invalid glIsEnabled() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if cap is not an accepted value."); glIsEnabled(-1); expectError(GL_INVALID_ENUM); glIsEnabled(GL_TRIANGLES); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); // Hints ES3F_ADD_API_CASE(hint, "Invalid glHint() usage", { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if either target or mode is not an accepted value."); glHint(GL_GENERATE_MIPMAP_HINT, -1); expectError(GL_INVALID_ENUM); glHint(-1, GL_FASTEST); expectError(GL_INVALID_ENUM); glHint(-1, -1); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); // Named Object Usage ES3F_ADD_API_CASE(is_buffer, "Invalid glIsBuffer() usage", { GLuint buffer = 0; GLboolean isBuffer; m_log << TestLog::Section("", "A name returned by glGenBuffers, but not yet associated with a buffer object by " "calling glBindBuffer, is not the name of a buffer object."); isBuffer = glIsBuffer(buffer); checkBooleans(isBuffer, GL_FALSE); glGenBuffers(1, &buffer); isBuffer = glIsBuffer(buffer); checkBooleans(isBuffer, GL_FALSE); glBindBuffer(GL_ARRAY_BUFFER, buffer); isBuffer = glIsBuffer(buffer); checkBooleans(isBuffer, GL_TRUE); glBindBuffer(GL_ARRAY_BUFFER, 0); glDeleteBuffers(1, &buffer); isBuffer = glIsBuffer(buffer); checkBooleans(isBuffer, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_framebuffer, "Invalid glIsFramebuffer() usage", { GLuint fbo = 0; GLboolean isFbo; m_log << TestLog::Section("", "A name returned by glGenFramebuffers, but not yet bound through a call to " "glBindFramebuffer is not the name of a framebuffer object."); isFbo = glIsFramebuffer(fbo); checkBooleans(isFbo, GL_FALSE); glGenFramebuffers(1, &fbo); isFbo = glIsFramebuffer(fbo); checkBooleans(isFbo, GL_FALSE); glBindFramebuffer(GL_FRAMEBUFFER, fbo); isFbo = glIsFramebuffer(fbo); checkBooleans(isFbo, GL_TRUE); glBindFramebuffer(GL_FRAMEBUFFER, 0); glDeleteFramebuffers(1, &fbo); isFbo = glIsFramebuffer(fbo); checkBooleans(isFbo, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_program, "Invalid glIsProgram() usage", { GLuint program = 0; GLboolean isProgram; m_log << TestLog::Section("", "A name created with glCreateProgram, and not yet deleted with glDeleteProgram " "is a name of a program object."); isProgram = glIsProgram(program); checkBooleans(isProgram, GL_FALSE); program = glCreateProgram(); isProgram = glIsProgram(program); checkBooleans(isProgram, GL_TRUE); glDeleteProgram(program); isProgram = glIsProgram(program); checkBooleans(isProgram, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_renderbuffer, "Invalid glIsRenderbuffer() usage", { GLuint rbo = 0; GLboolean isRbo; m_log << TestLog::Section( "", "A name returned by glGenRenderbuffers, but not yet bound through a call to glBindRenderbuffer or " "glFramebufferRenderbuffer is not the name of a renderbuffer object."); isRbo = glIsRenderbuffer(rbo); checkBooleans(isRbo, GL_FALSE); glGenRenderbuffers(1, &rbo); isRbo = glIsRenderbuffer(rbo); checkBooleans(isRbo, GL_FALSE); glBindRenderbuffer(GL_RENDERBUFFER, rbo); isRbo = glIsRenderbuffer(rbo); checkBooleans(isRbo, GL_TRUE); glBindRenderbuffer(GL_RENDERBUFFER, 0); glDeleteRenderbuffers(1, &rbo); isRbo = glIsRenderbuffer(rbo); checkBooleans(isRbo, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_shader, "Invalid glIsShader() usage", { GLuint shader = 0; GLboolean isShader; m_log << TestLog::Section("", "A name created with glCreateShader, and not yet deleted with glDeleteShader is " "a name of a shader object."); isShader = glIsProgram(shader); checkBooleans(isShader, GL_FALSE); shader = glCreateShader(GL_VERTEX_SHADER); isShader = glIsShader(shader); checkBooleans(isShader, GL_TRUE); glDeleteShader(shader); isShader = glIsShader(shader); checkBooleans(isShader, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_texture, "Invalid glIsTexture() usage", { GLuint texture = 0; GLboolean isTexture; m_log << TestLog::Section("", "A name returned by glGenTextures, but not yet bound through a call to " "glBindTexture is not the name of a texture."); isTexture = glIsTexture(texture); checkBooleans(isTexture, GL_FALSE); glGenTextures(1, &texture); isTexture = glIsTexture(texture); checkBooleans(isTexture, GL_FALSE); glBindTexture(GL_TEXTURE_2D, texture); isTexture = glIsTexture(texture); checkBooleans(isTexture, GL_TRUE); glBindTexture(GL_TEXTURE_2D, 0); glDeleteTextures(1, &texture); isTexture = glIsTexture(texture); checkBooleans(isTexture, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_query, "Invalid glIsQuery() usage", { GLuint query = 0; GLboolean isQuery; m_log << TestLog::Section("", "A name returned by glGenQueries, but not yet associated with a query object by " "calling glBeginQuery, is not the name of a query object."); isQuery = glIsQuery(query); checkBooleans(isQuery, GL_FALSE); glGenQueries(1, &query); isQuery = glIsQuery(query); checkBooleans(isQuery, GL_FALSE); glBeginQuery(GL_ANY_SAMPLES_PASSED, query); isQuery = glIsQuery(query); checkBooleans(isQuery, GL_TRUE); glEndQuery(GL_ANY_SAMPLES_PASSED); glDeleteQueries(1, &query); isQuery = glIsQuery(query); checkBooleans(isQuery, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_sampler, "Invalid glIsSampler() usage", { GLuint sampler = 0; GLboolean isSampler; m_log << TestLog::Section("", "A name returned by glGenSamplers is the name of a sampler object."); isSampler = glIsSampler(sampler); checkBooleans(isSampler, GL_FALSE); glGenSamplers(1, &sampler); isSampler = glIsSampler(sampler); checkBooleans(isSampler, GL_TRUE); glBindSampler(0, sampler); isSampler = glIsSampler(sampler); checkBooleans(isSampler, GL_TRUE); glDeleteSamplers(1, &sampler); isSampler = glIsSampler(sampler); checkBooleans(isSampler, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_sync, "Invalid glIsSync() usage", { GLsync sync = 0; GLboolean isSync; m_log << TestLog::Section("", "A name returned by glFenceSync is the name of a sync object."); isSync = glIsSync(sync); checkBooleans(isSync, GL_FALSE); sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); isSync = glIsSync(sync); checkBooleans(isSync, GL_TRUE); glDeleteSync(sync); isSync = glIsSync(sync); checkBooleans(isSync, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_transform_feedback, "Invalid glIsTransformFeedback() usage", { GLuint tf = 0; GLboolean isTF; m_log << TestLog::Section("", "A name returned by glGenTransformFeedbacks, but not yet bound using " "glBindTransformFeedback, is not the name of a transform feedback object."); isTF = glIsTransformFeedback(tf); checkBooleans(isTF, GL_FALSE); glGenTransformFeedbacks(1, &tf); isTF = glIsTransformFeedback(tf); checkBooleans(isTF, GL_FALSE); glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tf); isTF = glIsTransformFeedback(tf); checkBooleans(isTF, GL_TRUE); glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, 0); glDeleteTransformFeedbacks(1, &tf); isTF = glIsTransformFeedback(tf); checkBooleans(isTF, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); ES3F_ADD_API_CASE(is_vertex_array, "Invalid glIsVertexArray() usage", { GLuint vao = 0; GLboolean isVao; m_log << TestLog::Section("", "A name returned by glGenVertexArrays, but not yet bound using " "glBindVertexArray, is not the name of a vertex array object."); isVao = glIsVertexArray(vao); checkBooleans(isVao, GL_FALSE); glGenVertexArrays(1, &vao); isVao = glIsVertexArray(vao); checkBooleans(isVao, GL_FALSE); glBindVertexArray(vao); isVao = glIsVertexArray(vao); checkBooleans(isVao, GL_TRUE); glBindVertexArray(0); glDeleteVertexArrays(1, &vao); isVao = glIsVertexArray(vao); checkBooleans(isVao, GL_FALSE); m_log << TestLog::EndSection; expectError(GL_NO_ERROR); }); } } // namespace Functional } // namespace gles3 } // namespace deqp