/*------------------------------------------------------------------------- * drawElements Quality Program OpenGL ES 2.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 "es2fNegativeStateApiTests.hpp" #include "es2fApiCase.hpp" #include "gluShaderProgram.hpp" #include "deMemory.h" #include "glwEnums.hpp" #include "glwDefs.hpp" using namespace glw; // GL types namespace deqp { namespace gles2 { namespace Functional { using tcu::TestLog; static const char* uniformTestVertSource = "uniform mediump vec4 vTest;\n" "void main (void)\n" "{\n" " gl_Position = vTest;\n" "}\n\0"; static const char* uniformTestFragSource = "uniform mediump ivec4 fTest;\n" "void main (void)\n" "{\n" " gl_FragColor = vec4(fTest);\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 ES2F_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; }); ES2F_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 ES2F_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[1] = { GL_FALSE }; glGetBooleanv(-1, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES2F_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[1] = { 0.0f }; glGetFloatv(-1, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES2F_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] = { 0 }; glGetIntegerv(-1, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); ES2F_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(0); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; }); // Enumerated state queries: Shaders ES2F_ADD_API_CASE(get_attached_shaders, "Invalid glGetAttachedShaders() usage", { GLuint shaders[1] = { 0 }; GLuint shaderObject = glCreateShader(GL_VERTEX_SHADER); GLuint program = glCreateProgram(); GLsizei count[1] = { -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); }); ES2F_ADD_API_CASE(get_shaderiv, "Invalid glGetShaderiv() usage", { GLboolean shaderCompilerSupported; glGetBooleanv(GL_SHADER_COMPILER, &shaderCompilerSupported); if (!shaderCompilerSupported) m_log << TestLog::Message << "// Shader compiler not supported, always expect GL_INVALID_OPERATION" << TestLog::EndMessage; else m_log << TestLog::Message << "// Shader compiler supported" << 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 pname is GL_COMPILE_STATUS, GL_INFO_LOG_LENGTH, or GL_SHADER_SOURCE_LENGTH but a shader compiler is not supported."); glGetShaderiv(shader, GL_COMPILE_STATUS, ¶m[0]); expectError(shaderCompilerSupported ? GL_NO_ERROR : GL_INVALID_OPERATION); glGetShaderiv(shader, GL_INFO_LOG_LENGTH, ¶m[0]); expectError(shaderCompilerSupported ? GL_NO_ERROR : GL_INVALID_OPERATION); glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, ¶m[0]); expectError(shaderCompilerSupported ? GL_NO_ERROR : GL_INVALID_OPERATION); 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); }); ES2F_ADD_API_CASE(get_shader_info_log, "Invalid glGetShaderInfoLog() usage", { GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLuint program = glCreateProgram(); GLsizei length[1] = { -1 }; char infoLog[128]; deMemset(&infoLog[0], 0, sizeof(infoLog)); 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); }); ES2F_ADD_API_CASE(get_shader_precision_format, "Invalid glGetShaderPrecisionFormat() usage", { GLboolean shaderCompilerSupported; glGetBooleanv(GL_SHADER_COMPILER, &shaderCompilerSupported); if (!shaderCompilerSupported) m_log << TestLog::Message << "// Shader compiler not supported, always expect GL_INVALID_OPERATION" << TestLog::EndMessage; else m_log << TestLog::Message << "// Shader compiler supported" << TestLog::EndMessage; GLint range[2]; range[0] = -1; range[1] = -1; GLint precision[1] = { -1 }; 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(shaderCompilerSupported ? GL_INVALID_ENUM : GL_INVALID_OPERATION); glGetShaderPrecisionFormat (GL_VERTEX_SHADER, -1, &range[0], &precision[0]); expectError(shaderCompilerSupported ? GL_INVALID_ENUM : GL_INVALID_OPERATION); glGetShaderPrecisionFormat (-1, -1, &range[0], &precision[0]); expectError(shaderCompilerSupported ? GL_INVALID_ENUM : GL_INVALID_OPERATION); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if a shader compiler is not supported."); glGetShaderPrecisionFormat (GL_VERTEX_SHADER, GL_MEDIUM_FLOAT, &range[0], &precision[0]); expectError(shaderCompilerSupported ? GL_NO_ERROR : GL_INVALID_OPERATION); m_log << TestLog::EndSection; }); ES2F_ADD_API_CASE(get_shader_source, "Invalid glGetShaderSource() usage", { GLsizei length[1] = { -1 }; 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 ES2F_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); }); ES2F_ADD_API_CASE(get_program_info_log, "Invalid glGetProgramInfoLog() usage", { GLuint program = glCreateProgram(); GLuint shader = glCreateShader(GL_VERTEX_SHADER); GLsizei length[1] = { -1 }; 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 ES2F_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; }); ES2F_ADD_API_CASE(get_tex_parameteriv, "Invalid glGetTexParameteriv() usage", { GLint params[1] = { -1 }; 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; }); ES2F_ADD_API_CASE(get_uniformfv, "Invalid glGetUniformfv() usage", { glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); glUseProgram(program.getProgram()); GLint vUnif = glGetUniformLocation(program.getProgram(), "vTest"); // vec4 GLint fUnif = glGetUniformLocation(program.getProgram(), "fTest"); // ivec4 if (vUnif == -1 || fUnif == -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]; deMemset(¶ms[0], 0, sizeof(params)); m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetUniformfv (-1, vUnif, ¶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, vUnif, ¶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, vUnif, ¶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(), de::max(vUnif, fUnif)+1, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteShader(shader); glDeleteProgram(programEmpty); }); ES2F_ADD_API_CASE(get_uniformiv, "Invalid glGetUniformiv() usage", { glu::ShaderProgram program(m_context.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource)); glUseProgram(program.getProgram()); GLint vUnif = glGetUniformLocation(program.getProgram(), "vTest"); // vec4 GLint fUnif = glGetUniformLocation(program.getProgram(), "fTest"); // ivec4 if (vUnif == -1 || fUnif == -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]; deMemset(¶ms[0], 0, sizeof(params)); m_log << TestLog::Section("", "GL_INVALID_VALUE is generated if program is not a value generated by OpenGL."); glGetUniformiv (-1, vUnif, ¶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, vUnif, ¶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, vUnif, ¶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(), de::max(vUnif, fUnif)+1, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteShader(shader); glDeleteProgram(programEmpty); }); ES2F_ADD_API_CASE(get_vertex_attribfv, "Invalid glGetVertexAttribfv() usage", { GLfloat params[1]; deMemset(¶ms[0], 0, sizeof(params)); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetVertexAttribfv(0, -1, ¶ms[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); glGetVertexAttribfv(maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_ENABLED, ¶ms[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES2F_ADD_API_CASE(get_vertex_attribiv, "Invalid glGetVertexAttribiv() usage", { GLint params[1]; deMemset(¶ms[0], 0, sizeof(params)); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if pname is not an accepted value."); glGetVertexAttribiv(0, -1, ¶ms[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); glGetVertexAttribiv(maxVertexAttribs, GL_VERTEX_ATTRIB_ARRAY_ENABLED, ¶ms[0]); expectError(GL_INVALID_VALUE); m_log << TestLog::EndSection; }); ES2F_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; }); // Enumerated state queries: Buffers ES2F_ADD_API_CASE(get_buffer_parameteriv, "Invalid glGetBufferParameteriv() usage", { GLint params[1]; GLuint buf; glGenBuffers(1, &buf); glBindBuffer(GL_ARRAY_BUFFER, buf); deMemset(¶ms[0], 0, sizeof(params)); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target or value is not an accepted value."); glGetBufferParameteriv(-1, GL_BUFFER_SIZE, ¶ms[0]); expectError(GL_INVALID_ENUM); glGetBufferParameteriv(GL_ARRAY_BUFFER , -1, ¶ms[0]); expectError(GL_INVALID_ENUM); glGetBufferParameteriv(-1, -1, ¶ms[0]); 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[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteBuffers(1, &buf); }); ES2F_ADD_API_CASE(get_framebuffer_attachment_parameteriv, "Invalid glGetFramebufferAttachmentParameteriv() usage", { // GL_MAJOR_VERSION query does not exist on GLES2 // so succeeding query implies GLES3+ hardware. bool isES3Compatible = false; glw::GLint majorVersion = 0; glGetIntegerv(GL_MAJOR_VERSION, &majorVersion); if (glGetError() == GL_NO_ERROR) isES3Compatible = true; GLint params[1] = { -1 }; GLuint fbo; glGenFramebuffers(1, &fbo); glBindFramebuffer(GL_FRAMEBUFFER, fbo); m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if target is not GL_FRAMEBUFFER."); glGetFramebufferAttachmentParameteriv(-1, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if there is no attached object at the named attachment point and pname is not GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE."); if (isES3Compatible) { 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); } else { glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ¶ms[0]); expectError(GL_INVALID_ENUM); } m_log << TestLog::EndSection; if (!isES3Compatible) { m_log << TestLog::Section("", "GL_INVALID_ENUM is generated if the attached object at the named attachment point is incompatible with pname."); GLint attachmentObjectType = -1; glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &attachmentObjectType); expectError(GL_NO_ERROR); if (attachmentObjectType == GL_RENDERBUFFER) glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL, ¶ms[0]); else if (attachmentObjectType == GL_TEXTURE) glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, -1, ¶ms[0]); else if (attachmentObjectType == GL_NONE) glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, ¶ms[0]); else m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Invalid return value from glGetFramebufferAttachmentParameteriv()"); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; } m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if the default framebuffer object name 0 is bound."); glBindFramebuffer(GL_FRAMEBUFFER, 0); glGetFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, ¶ms[0]); if (isES3Compatible) expectError(GL_INVALID_OPERATION, GL_INVALID_ENUM); else expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteFramebuffers(1, &fbo); }); ES2F_ADD_API_CASE(get_renderbuffer_parameteriv, "Invalid glGetRenderbufferParameteriv() usage", { GLint params[1]; GLuint rbo; glGenRenderbuffers(1, &rbo); glBindRenderbuffer(GL_RENDERBUFFER, rbo); deMemset(¶ms[0], 0, sizeof(params)); 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 allowed values."); glGetRenderbufferParameteriv(GL_RENDERBUFFER, -1, ¶ms[0]); expectError(GL_INVALID_ENUM); m_log << TestLog::EndSection; m_log << TestLog::Section("", "GL_INVALID_OPERATION is generated if the reserved renderbuffer object name 0 is bound."); glBindRenderbuffer(GL_RENDERBUFFER, 0); glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, ¶ms[0]); expectError(GL_INVALID_OPERATION); m_log << TestLog::EndSection; glDeleteRenderbuffers(1, &rbo); }); // Enumerated boolean state queries ES2F_ADD_API_CASE(get_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 ES2F_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 ES2F_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); }); ES2F_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); }); ES2F_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); }); ES2F_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); }); ES2F_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); }); ES2F_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); }); } } // Functional } // gles2 } // deqp