You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
2728 lines
106 KiB
2728 lines
106 KiB
/*-------------------------------------------------------------------------
|
|
* drawElements Quality Program OpenGL ES 3.1 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 Shader API tests.
|
|
*//*--------------------------------------------------------------------*/
|
|
|
|
#include "es31fNegativeShaderApiTests.hpp"
|
|
|
|
#include "deUniquePtr.hpp"
|
|
|
|
#include "glwDefs.hpp"
|
|
#include "glwEnums.hpp"
|
|
|
|
#include "gluShaderProgram.hpp"
|
|
#include "gluCallLogWrapper.hpp"
|
|
|
|
#include "gluContextInfo.hpp"
|
|
#include "gluRenderContext.hpp"
|
|
|
|
|
|
namespace deqp
|
|
{
|
|
namespace gles31
|
|
{
|
|
namespace Functional
|
|
{
|
|
namespace NegativeTestShared
|
|
{
|
|
using tcu::TestLog;
|
|
using glu::CallLogWrapper;
|
|
using namespace glw;
|
|
|
|
static const char* vertexShaderSource = "#version 300 es\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = vec4(0.0);\n"
|
|
"}\n\0";
|
|
|
|
static const char* fragmentShaderSource = "#version 300 es\n"
|
|
"layout(location = 0) out mediump vec4 fragColor;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" fragColor = vec4(0.0);\n"
|
|
"}\n\0";
|
|
|
|
static const char* uniformTestVertSource = "#version 300 es\n"
|
|
"uniform mediump vec4 vec4_v;\n"
|
|
"uniform mediump mat4 mat4_v;\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = mat4_v * vec4_v;\n"
|
|
"}\n\0";
|
|
|
|
static const char* uniformTestFragSource = "#version 300 es\n"
|
|
"uniform mediump ivec4 ivec4_f;\n"
|
|
"uniform mediump uvec4 uvec4_f;\n"
|
|
"uniform sampler2D sampler_f;\n"
|
|
"layout(location = 0) out mediump vec4 fragColor;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" fragColor.xy = (vec4(uvec4_f) + vec4(ivec4_f)).xy;\n"
|
|
" fragColor.zw = texture(sampler_f, vec2(0.0, 0.0)).zw;\n"
|
|
"}\n\0";
|
|
|
|
static const char* uniformBlockVertSource = "#version 300 es\n"
|
|
"layout(shared) uniform Block { lowp float var; };\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" gl_Position = vec4(var);\n"
|
|
"}\n\0";
|
|
|
|
static bool supportsES32orGL45(NegativeTestContext& ctx)
|
|
{
|
|
return contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)) ||
|
|
contextSupports(ctx.getRenderContext().getType(), glu::ApiType::core(4, 5));
|
|
}
|
|
|
|
// Shader control commands
|
|
void create_shader (NegativeTestContext& ctx)
|
|
{
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if shaderType is not an accepted value.");
|
|
ctx.glCreateShader(-1);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void shader_source (NegativeTestContext& ctx)
|
|
{
|
|
// make notAShader not a shader id
|
|
const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
ctx.glDeleteShader(notAShader);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
|
|
ctx.glShaderSource(notAShader, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if count is less than 0.");
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
ctx.glShaderSource(shader, -1, 0, 0);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if shader is not a shader object.");
|
|
GLuint program = ctx.glCreateProgram();
|
|
ctx.glShaderSource(program, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteProgram(program);
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void compile_shader (NegativeTestContext& ctx)
|
|
{
|
|
const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
ctx.glDeleteShader(notAShader);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
|
|
ctx.glCompileShader(notAShader);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if shader is not a shader object.");
|
|
GLuint program = ctx.glCreateProgram();
|
|
ctx.glCompileShader(program);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteProgram(program);
|
|
}
|
|
|
|
void delete_shader (NegativeTestContext& ctx)
|
|
{
|
|
const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
ctx.glDeleteShader(notAShader);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if shader is not a value generated by OpenGL.");
|
|
ctx.glDeleteShader(notAShader);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void shader_binary (NegativeTestContext& ctx)
|
|
{
|
|
std::vector<deInt32> binaryFormats;
|
|
deBool shaderBinarySupported = !binaryFormats.empty();
|
|
GLuint shaders[2];
|
|
GLuint shaderPair[2];
|
|
GLuint nonProgram[2];
|
|
GLuint shaderProgram[2];
|
|
|
|
{
|
|
deInt32 numFormats = 0x1234;
|
|
ctx.glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &numFormats);
|
|
|
|
if (numFormats == 0)
|
|
ctx.getLog() << TestLog::Message << "// No supported extensions available." << TestLog::EndMessage;
|
|
else
|
|
{
|
|
binaryFormats.resize(numFormats);
|
|
ctx.glGetIntegerv(GL_SHADER_BINARY_FORMATS, &binaryFormats[0]);
|
|
}
|
|
}
|
|
|
|
if (!shaderBinarySupported)
|
|
ctx.getLog() << TestLog::Message << "// Shader binaries not supported." << TestLog::EndMessage;
|
|
else
|
|
ctx.getLog() << TestLog::Message << "// Shader binaries supported" << TestLog::EndMessage;
|
|
|
|
shaders[0] = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
shaders[1] = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
shaderPair[0] = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
shaderPair[1] = ctx.glCreateShader(GL_FRAGMENT_SHADER);
|
|
nonProgram[0] = -1;
|
|
nonProgram[1] = -1;
|
|
shaderProgram[0] = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
shaderProgram[1] = ctx.glCreateProgram();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if binaryFormat is not an accepted value.");
|
|
ctx.glShaderBinary(1, &shaders[0], -1, 0, 0);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
if (shaderBinarySupported)
|
|
{
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if the data pointed to by binary does not match the format specified by binaryFormat.");
|
|
const GLbyte data = 0x005F;
|
|
ctx.glShaderBinary(1, &shaders[0], binaryFormats[0], &data, 1);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if more than one of the handles in shaders refers to the same type of shader, or GL_INVALID_VALUE due to invalid data pointer.");
|
|
ctx.glShaderBinary(2, &shaders[0], binaryFormats[0], 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION, GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if count or length is negative.");
|
|
ctx.glShaderBinary(2, &shaderPair[0], binaryFormats[0], 0, -1);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.glShaderBinary(-1, &shaderPair[0], binaryFormats[0], 0, 0);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if shaders contains anything other than shader or program objects.");
|
|
ctx.glShaderBinary(2, &nonProgram[0], binaryFormats[0], 0, 0);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if shaders refers to a program object.");
|
|
ctx.glShaderBinary(2, &shaderProgram[0], binaryFormats[0], 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
ctx.glDeleteShader(shaders[0]);
|
|
ctx.glDeleteShader(shaders[1]);
|
|
}
|
|
|
|
void attach_shader (NegativeTestContext& ctx)
|
|
{
|
|
GLuint shader1 = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
GLuint shader2 = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
GLuint program = ctx.glCreateProgram();
|
|
|
|
const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
|
|
ctx.glDeleteShader(notAShader);
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
|
|
ctx.glAttachShader(shader1, shader1);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if shader is not a shader object.");
|
|
ctx.glAttachShader(program, program);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glAttachShader(shader1, program);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
|
|
ctx.glAttachShader(program, notAShader);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.glAttachShader(notAProgram, shader1);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.glAttachShader(notAProgram, notAShader);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if shader is already attached to program.");
|
|
ctx.glAttachShader(program, shader1);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glAttachShader(program, shader1);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
if (glu::isContextTypeES(ctx.getRenderContext().getType()))
|
|
{
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if a shader of the same type as shader is already attached to program.");
|
|
ctx.glAttachShader(program, shader2);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
ctx.glDeleteProgram(program);
|
|
ctx.glDeleteShader(shader1);
|
|
ctx.glDeleteShader(shader2);
|
|
}
|
|
|
|
void detach_shader (NegativeTestContext& ctx)
|
|
{
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
GLuint program = ctx.glCreateProgram();
|
|
|
|
const GLuint notAShader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
|
|
ctx.glDeleteShader(notAShader);
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if either program or shader is not a value generated by OpenGL.");
|
|
ctx.glDetachShader(notAProgram, shader);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.glDetachShader(program, notAShader);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.glDetachShader(notAProgram, notAShader);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
|
|
ctx.glDetachShader(shader, shader);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if shader is not a shader object.");
|
|
ctx.glDetachShader(program, program);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glDetachShader(shader, program);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if shader is not attached to program.");
|
|
ctx.glDetachShader(program, shader);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteProgram(program);
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void link_program (NegativeTestContext& ctx)
|
|
{
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
|
|
ctx.glLinkProgram(notAProgram);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
|
|
ctx.glLinkProgram(shader);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteShader(shader);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is the currently active program object and transform feedback mode is active.");
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
deUint32 buf = 0x1234;
|
|
deUint32 tfID = 0x1234;
|
|
const char* tfVarying = "gl_Position";
|
|
|
|
ctx.glGenTransformFeedbacks (1, &tfID);
|
|
ctx.glGenBuffers (1, &buf);
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glLinkProgram (program.getProgram());
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID);
|
|
ctx.glBindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, buf);
|
|
ctx.glBufferData (GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.glLinkProgram (program.getProgram());
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
|
|
ctx.glEndTransformFeedback ();
|
|
ctx.glDeleteTransformFeedbacks (1, &tfID);
|
|
ctx.glDeleteBuffers (1, &buf);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void use_program (NegativeTestContext& ctx)
|
|
{
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is neither 0 nor a value generated by OpenGL.");
|
|
ctx.glUseProgram(notAProgram);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
|
|
ctx.glUseProgram(shader);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback mode is active and not paused.");
|
|
glu::ShaderProgram program1(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
glu::ShaderProgram program2(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
deUint32 buf = 0x1234;
|
|
deUint32 tfID = 0x1234;
|
|
const char* tfVarying = "gl_Position";
|
|
|
|
ctx.glGenTransformFeedbacks (1, &tfID);
|
|
ctx.glGenBuffers (1, &buf);
|
|
|
|
ctx.glUseProgram (program1.getProgram());
|
|
ctx.glTransformFeedbackVaryings (program1.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glLinkProgram (program1.getProgram());
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID);
|
|
ctx.glBindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, buf);
|
|
ctx.glBufferData (GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.glUseProgram (program2.getProgram());
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
|
|
ctx.glPauseTransformFeedback ();
|
|
ctx.glUseProgram (program2.getProgram());
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.glEndTransformFeedback ();
|
|
ctx.glDeleteTransformFeedbacks (1, &tfID);
|
|
ctx.glDeleteBuffers (1, &buf);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void delete_program (NegativeTestContext& ctx)
|
|
{
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
|
|
ctx.glDeleteProgram(notAProgram);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not zero and is the name of a shader object.");
|
|
ctx.glDeleteProgram(shader);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void validate_program (NegativeTestContext& ctx)
|
|
{
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
|
|
ctx.glValidateProgram(notAProgram);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
|
|
ctx.glValidateProgram(shader);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void get_program_binary (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program (ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
glu::ShaderProgram programInvalid (ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, ""));
|
|
GLenum binaryFormat = -1;
|
|
GLsizei binaryLength = -1;
|
|
GLint binaryPtr = -1;
|
|
GLint bufSize = -1;
|
|
GLint linkStatus = -1;
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if bufSize is less than the size of GL_PROGRAM_BINARY_LENGTH for program.");
|
|
ctx.glGetProgramiv (program.getProgram(), GL_PROGRAM_BINARY_LENGTH, &bufSize);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.glGetProgramiv (program.getProgram(), GL_LINK_STATUS, &linkStatus);
|
|
ctx.getLog() << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
|
|
ctx.getLog() << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.glGetProgramBinary (program.getProgram(), 0, &binaryLength, &binaryFormat, &binaryPtr);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
if (bufSize > 0)
|
|
{
|
|
ctx.glGetProgramBinary (program.getProgram(), bufSize-1, &binaryLength, &binaryFormat, &binaryPtr);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
}
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if GL_LINK_STATUS for the program object is false.");
|
|
ctx.glGetProgramiv (programInvalid.getProgram(), GL_PROGRAM_BINARY_LENGTH, &bufSize);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.glGetProgramiv (programInvalid.getProgram(), GL_LINK_STATUS, &linkStatus);
|
|
ctx.getLog() << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
|
|
ctx.getLog() << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
if (!linkStatus)
|
|
{
|
|
ctx.glGetProgramBinary (programInvalid.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryPtr);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
else
|
|
{
|
|
if (isContextTypeES(ctx.getRenderContext().getType()))
|
|
ctx.fail("Program should not have linked");
|
|
}
|
|
}
|
|
|
|
void program_binary (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram srcProgram (ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
GLuint dstProgram = ctx.glCreateProgram();
|
|
GLuint dummyShader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
GLenum binaryFormat = -1;
|
|
GLsizei binaryLength = -1;
|
|
std::vector<deUint8> binaryBuf;
|
|
GLint bufSize = -1;
|
|
GLint linkStatus = -1;
|
|
|
|
ctx.glGetProgramiv (srcProgram.getProgram(), GL_PROGRAM_BINARY_LENGTH, &bufSize);
|
|
ctx.glGetProgramiv (srcProgram.getProgram(), GL_LINK_STATUS, &linkStatus);
|
|
ctx.getLog() << TestLog::Message << "// GL_PROGRAM_BINARY_LENGTH = " << bufSize << TestLog::EndMessage;
|
|
ctx.getLog() << TestLog::Message << "// GL_LINK_STATUS = " << linkStatus << TestLog::EndMessage;
|
|
|
|
TCU_CHECK(bufSize >= 0);
|
|
if (bufSize > 0)
|
|
{
|
|
binaryBuf.resize(bufSize);
|
|
ctx.glGetProgramBinary (srcProgram.getProgram(), bufSize, &binaryLength, &binaryFormat, &binaryBuf[0]);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not the name of an existing program object.");
|
|
ctx.glProgramBinary (dummyShader, binaryFormat, &binaryBuf[0], binaryLength);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if binaryFormat is not a value recognized by the implementation.");
|
|
ctx.glProgramBinary (dstProgram, -1, &binaryBuf[0], binaryLength);
|
|
ctx.expectError (GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
}
|
|
|
|
ctx.glDeleteShader(dummyShader);
|
|
ctx.glDeleteProgram(dstProgram);
|
|
}
|
|
|
|
void program_parameteri (NegativeTestContext& ctx)
|
|
{
|
|
GLuint program = ctx.glCreateProgram();
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of an existing program object.");
|
|
ctx.glProgramParameteri(notAProgram, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is the name of a shader object.");
|
|
ctx.glProgramParameteri(shader, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, GL_TRUE);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is not GL_PROGRAM_BINARY_RETRIEVABLE_HINT or PROGRAM_SEPARABLE.");
|
|
ctx.glProgramParameteri(program, -1, GL_TRUE);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if value is not GL_FALSE or GL_TRUE.");
|
|
ctx.glProgramParameteri(program, GL_PROGRAM_BINARY_RETRIEVABLE_HINT, 2);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteProgram(program);
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void gen_samplers (NegativeTestContext& ctx)
|
|
{
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if n is negative.");
|
|
GLuint sampler = 0;
|
|
ctx.glGenSamplers (-1, &sampler);
|
|
ctx.expectError (GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void bind_sampler (NegativeTestContext& ctx)
|
|
{
|
|
int maxTexImageUnits = 0x1234;
|
|
GLuint sampler = 0;
|
|
ctx.glGetIntegerv (GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &maxTexImageUnits);
|
|
ctx.glGenSamplers (1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if unit is greater than or equal to the value of GL_MAX_COMBIED_TEXTURE_IMAGE_UNITS.");
|
|
ctx.glBindSampler (maxTexImageUnits, sampler);
|
|
ctx.expectError (GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not zero or a name previously returned from a call to ctx.glGenSamplers.");
|
|
ctx.glBindSampler (1, -1);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler has been deleted by a call to ctx.glDeleteSamplers.");
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
ctx.glBindSampler (1, sampler);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void delete_samplers (NegativeTestContext& ctx)
|
|
{
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if n is negative.");
|
|
ctx.glDeleteSamplers(-1, 0);
|
|
ctx.expectError (GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void get_sampler_parameteriv (NegativeTestContext& ctx)
|
|
{
|
|
int params = 0x1234;
|
|
GLuint sampler = 0;
|
|
ctx.glGenSamplers (1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object returned from a previous call to ctx.glGenSamplers.");
|
|
ctx.glGetSamplerParameteriv (-1, GL_TEXTURE_MAG_FILTER, ¶ms);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is not an accepted value.");
|
|
ctx.glGetSamplerParameteriv (sampler, -1, ¶ms);
|
|
ctx.expectError (GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void get_sampler_parameterfv (NegativeTestContext& ctx)
|
|
{
|
|
float params = 0.0f;
|
|
GLuint sampler = 0;
|
|
ctx.glGenSamplers (1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object returned from a previous call to ctx.glGenSamplers.");
|
|
ctx.glGetSamplerParameterfv (-1, GL_TEXTURE_MAG_FILTER, ¶ms);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is not an accepted value.");
|
|
ctx.glGetSamplerParameterfv (sampler, -1, ¶ms);
|
|
ctx.expectError (GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void get_sampler_parameterIiv (NegativeTestContext& ctx)
|
|
{
|
|
if (!supportsES32orGL45(ctx))
|
|
throw tcu::NotSupportedError("glGetSamplerParameterIiv is not supported.", DE_NULL, __FILE__, __LINE__);
|
|
|
|
GLuint sampler = 0x1234;
|
|
GLint borderColor = 0x1234;
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object returned from a previous call to ctx.glGenSamplers.");
|
|
ctx.glGetSamplerParameterIiv(sampler, GL_TEXTURE_BORDER_COLOR, &borderColor);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is not an accepted value.");
|
|
ctx.glGetSamplerParameterIiv(sampler, -1, &borderColor);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void get_sampler_parameterIuiv (NegativeTestContext& ctx)
|
|
{
|
|
if (!supportsES32orGL45(ctx))
|
|
throw tcu::NotSupportedError("glGetSamplerParameterIuiv is not supported.", DE_NULL, __FILE__, __LINE__);
|
|
|
|
GLuint sampler = 0x1234;
|
|
GLuint borderColor = 0x1234;
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object returned from a previous call to ctx.glGenSamplers.");
|
|
ctx.glGetSamplerParameterIuiv(sampler, GL_TEXTURE_BORDER_COLOR, &borderColor);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is not an accepted value.");
|
|
ctx.glGetSamplerParameterIuiv(sampler, -1, &borderColor);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void sampler_parameteri (NegativeTestContext& ctx)
|
|
{
|
|
GLuint sampler = 0;
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to ctx.glGenSamplers.");
|
|
ctx.glSamplerParameteri(-1, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.");
|
|
ctx.glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, -1);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
if (supportsES32orGL45(ctx))
|
|
{
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if glSamplerParameteri is called for a non-scalar parameter.");
|
|
ctx.glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, 0);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
}
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void sampler_parameteriv (NegativeTestContext& ctx)
|
|
{
|
|
int params = 0x1234;
|
|
GLuint sampler = 0;
|
|
ctx.glGenSamplers (1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to ctx.glGenSamplers.");
|
|
params = GL_CLAMP_TO_EDGE;
|
|
ctx.glSamplerParameteriv (-1, GL_TEXTURE_WRAP_S, ¶ms);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.");
|
|
params = -1;
|
|
ctx.glSamplerParameteriv (sampler, GL_TEXTURE_WRAP_S, ¶ms);
|
|
ctx.expectError (GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void sampler_parameterf (NegativeTestContext& ctx)
|
|
{
|
|
GLuint sampler = 0;
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to ctx.glGenSamplers.");
|
|
ctx.glSamplerParameterf(-1, GL_TEXTURE_MIN_LOD, -1000.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.");
|
|
ctx.glSamplerParameterf(sampler, GL_TEXTURE_WRAP_S, -1.0f);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
if (supportsES32orGL45(ctx))
|
|
{
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if glSamplerParameterf is called for a non-scalar parameter.");
|
|
ctx.glSamplerParameteri(sampler, GL_TEXTURE_BORDER_COLOR, 0);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
}
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void sampler_parameterfv (NegativeTestContext& ctx)
|
|
{
|
|
float params;
|
|
GLuint sampler = 0;
|
|
ctx.glGenSamplers (1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to ctx.glGenSamplers.");
|
|
params = -1000.0f;
|
|
ctx.glSamplerParameterfv (-1, GL_TEXTURE_WRAP_S, ¶ms);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if params should have a defined constant value (based on the value of pname) and does not.");
|
|
params = -1.0f;
|
|
ctx.glSamplerParameterfv (sampler, GL_TEXTURE_WRAP_S, ¶ms);
|
|
ctx.expectError (GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void sampler_parameterIiv (NegativeTestContext& ctx)
|
|
{
|
|
if (!supportsES32orGL45(ctx))
|
|
throw tcu::NotSupportedError("glSamplerParameterIiv is not supported.", DE_NULL, __FILE__, __LINE__);
|
|
|
|
GLuint sampler;
|
|
GLint color[] = {0, 0, 0, 0};
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to ctx.glGenSamplers.");
|
|
ctx.glSamplerParameterIiv(-1, GL_TEXTURE_BORDER_COLOR, color);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is not an accepted sampler state name.");
|
|
ctx.glSamplerParameterIiv(sampler, -1, color);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void sampler_parameterIuiv (NegativeTestContext& ctx)
|
|
{
|
|
if (!supportsES32orGL45(ctx))
|
|
throw tcu::NotSupportedError("glSamplerParameterIuiv is not supported.", DE_NULL, __FILE__, __LINE__);
|
|
|
|
GLuint sampler;
|
|
GLuint color[] = {0, 0, 0, 0};
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if sampler is not the name of a sampler object previously returned from a call to ctx.glGenSamplers.");
|
|
ctx.glSamplerParameterIuiv(-1, GL_TEXTURE_BORDER_COLOR, color);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is not an accepted sampler state name.");
|
|
ctx.glSamplerParameterIuiv(sampler, -1, color);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
}
|
|
|
|
// Shader data commands
|
|
|
|
void get_attrib_location (NegativeTestContext& ctx)
|
|
{
|
|
GLuint programEmpty = ctx.glCreateProgram();
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program has not been successfully linked.");
|
|
ctx.glBindAttribLocation (programEmpty, 0, "test");
|
|
ctx.glGetAttribLocation (programEmpty, "test");
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not a program or shader object.");
|
|
ctx.glUseProgram (program.getProgram());
|
|
ctx.glBindAttribLocation (program.getProgram(), 0, "test");
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.glGetAttribLocation (program.getProgram(), "test");
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.glGetAttribLocation (notAProgram, "test");
|
|
ctx.expectError (GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
|
|
ctx.glGetAttribLocation (shader, "test");
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram (0);
|
|
ctx.glDeleteShader (shader);
|
|
ctx.glDeleteProgram (programEmpty);
|
|
}
|
|
|
|
void get_uniform_location (NegativeTestContext& ctx)
|
|
{
|
|
GLuint programEmpty = ctx.glCreateProgram();
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program has not been successfully linked.");
|
|
ctx.glGetUniformLocation(programEmpty, "test");
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glGetUniformLocation(notAProgram, "test");
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
|
|
ctx.glGetAttribLocation(shader, "test");
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
ctx.glDeleteProgram(programEmpty);
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void bind_attrib_location (NegativeTestContext& ctx)
|
|
{
|
|
GLuint program = ctx.glCreateProgram();
|
|
GLuint maxIndex = ctx.getInteger(GL_MAX_VERTEX_ATTRIBS);
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if index is greater than or equal to GL_MAX_VERTEX_ATTRIBS.");
|
|
ctx.glBindAttribLocation(program, maxIndex, "test");
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if name starts with the reserved prefix \"gl_\".");
|
|
ctx.glBindAttribLocation(program, maxIndex-1, "gl_test");
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not a value generated by OpenGL.");
|
|
ctx.glBindAttribLocation(-1, maxIndex-1, "test");
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is not a program object.");
|
|
ctx.glBindAttribLocation(shader, maxIndex-1, "test");
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteProgram(program);
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void uniform_block_binding (NegativeTestContext& ctx)
|
|
{
|
|
GLint maxUniformBufferBindings = -1;
|
|
GLint numActiveUniforms = -1;
|
|
GLint numActiveBlocks = -1;
|
|
GLuint shader = -1;
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformBlockVertSource, uniformTestFragSource));
|
|
|
|
shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
ctx.glUseProgram(program.getProgram());
|
|
|
|
ctx.glGetIntegerv(GL_MAX_UNIFORM_BUFFER_BINDINGS, &maxUniformBufferBindings);
|
|
ctx.glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORMS, &numActiveUniforms);
|
|
ctx.glGetProgramiv(program.getProgram(), GL_ACTIVE_UNIFORM_BLOCKS, &numActiveBlocks);
|
|
ctx.getLog() << TestLog::Message << "// GL_MAX_UNIFORM_BUFFER_BINDINGS = " << maxUniformBufferBindings << TestLog::EndMessage;
|
|
ctx.getLog() << TestLog::Message << "// GL_ACTIVE_UNIFORMS = " << numActiveUniforms << TestLog::EndMessage;
|
|
ctx.getLog() << TestLog::Message << "// GL_ACTIVE_UNIFORM_BLOCKS = " << numActiveBlocks << TestLog::EndMessage;
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if uniformBlockIndex is not an active uniform block index of program.");
|
|
ctx.glUniformBlockBinding(program.getProgram(), -1, 0);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.glUniformBlockBinding(program.getProgram(), 5, 0);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if uniformBlockBinding is greater than or equal to the value of GL_MAX_UNIFORM_BUFFER_BINDINGS.");
|
|
ctx.glUniformBlockBinding(program.getProgram(), maxUniformBufferBindings, 0);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of a program object generated by the GL.");
|
|
ctx.glUniformBlockBinding(-1, 0, 0);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is the name of a shader object.");
|
|
ctx.glUniformBlockBinding(shader, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
// ctx.glUniform*f
|
|
|
|
void uniformf_invalid_program (NegativeTestContext& ctx)
|
|
{
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if there is no current program object.");
|
|
ctx.glUseProgram(0);
|
|
ctx.glUniform1f(-1, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2f(-1, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3f(-1, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4f(-1, 0.0f, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void uniformf_incompatible_type (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
GLint vec4_v = ctx.glGetUniformLocation(program.getProgram(), "vec4_v"); // vec4
|
|
GLint ivec4_f = ctx.glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
|
|
GLint uvec4_f = ctx.glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
|
|
GLint sampler_f = ctx.glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the ctx.glUniform command.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1f(vec4_v, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2f(vec4_v, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3f(vec4_v, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4f(vec4_v, 0.0f, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}f is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform4f(ivec4_f, 0.0f, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4f(uvec4_f, 0.0f, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than ctx.glUniform1i and ctx.glUniform1iv.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1f(sampler_f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformf_invalid_location (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1f(-2, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2f(-2, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3f(-2, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4f(-2, 0.0f, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1f(-1, 0.0f);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform2f(-1, 0.0f, 0.0f);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform3f(-1, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform4f(-1, 0.0f, 0.0f, 0.0f, 0.0f);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
// ctx.glUniform*fv
|
|
|
|
void uniformfv_invalid_program (NegativeTestContext& ctx)
|
|
{
|
|
std::vector<GLfloat> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if there is no current program object.");
|
|
ctx.glUseProgram(0);
|
|
ctx.glUniform1fv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2fv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3fv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4fv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void uniformfv_incompatible_type (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
GLint vec4_v = ctx.glGetUniformLocation(program.getProgram(), "vec4_v"); // vec4
|
|
GLint ivec4_f = ctx.glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
|
|
GLint uvec4_f = ctx.glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
|
|
GLint sampler_f = ctx.glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
std::vector<GLfloat> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the ctx.glUniform command.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1fv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2fv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3fv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4fv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}fv is used to load a uniform variable of type int, ivec2, ivec3, ivec4, unsigned int, uvec2, uvec3, uvec4.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform4fv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4fv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than ctx.glUniform1i and ctx.glUniform1iv.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1fv(sampler_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformfv_invalid_location (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
std::vector<GLfloat> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1fv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2fv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3fv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4fv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1fv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform2fv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform3fv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform4fv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformfv_invalid_count (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
GLint vec4_v = ctx.glGetUniformLocation(program.getProgram(), "vec4_v"); // vec4
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (vec4_v == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
std::vector<GLfloat> data(8);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1fv(vec4_v, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2fv(vec4_v, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3fv(vec4_v, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4fv(vec4_v, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
// ctx.glUniform*i
|
|
|
|
void uniformi_invalid_program (NegativeTestContext& ctx)
|
|
{
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if there is no current program object.");
|
|
ctx.glUseProgram(0);
|
|
ctx.glUniform1i(-1, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2i(-1, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3i(-1, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4i(-1, 0, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void uniformi_incompatible_type (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
GLint vec4_v = ctx.glGetUniformLocation(program.getProgram(), "vec4_v"); // vec4
|
|
GLint ivec4_f = ctx.glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
|
|
GLint uvec4_f = ctx.glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
|
|
GLint sampler_f = ctx.glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the ctx.glUniform command.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1i(ivec4_f, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2i(ivec4_f, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3i(ivec4_f, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4i(ivec4_f, 0, 0, 0, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}i is used to load a uniform variable of type unsigned int, uvec2, uvec3, uvec4, or an array of these.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1i(uvec4_f, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2i(uvec4_f, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3i(uvec4_f, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4i(uvec4_f, 0, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}i is used to load a uniform variable of type float, vec2, vec3, or vec4.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1i(vec4_v, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2i(vec4_v, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3i(vec4_v, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4i(vec4_v, 0, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformi_invalid_location (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1i(-2, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2i(-2, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3i(-2, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4i(-2, 0, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1i(-1, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform2i(-1, 0, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform3i(-1, 0, 0, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform4i(-1, 0, 0, 0, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
// ctx.glUniform*iv
|
|
|
|
void uniformiv_invalid_program (NegativeTestContext& ctx)
|
|
{
|
|
std::vector<GLint> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if there is no current program object.");
|
|
ctx.glUseProgram(0);
|
|
ctx.glUniform1iv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2iv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3iv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4iv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void uniformiv_incompatible_type (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
GLint vec4_v = ctx.glGetUniformLocation(program.getProgram(), "vec4_v"); // vec4
|
|
GLint ivec4_f = ctx.glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
|
|
GLint uvec4_f = ctx.glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
|
|
GLint sampler_f = ctx.glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
std::vector<GLint> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the ctx.glUniform command.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1iv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2iv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3iv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4iv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}iv is used to load a uniform variable of type float, vec2, vec3, or vec4.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1iv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2iv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3iv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4iv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}iv is used to load a uniform variable of type unsigned int, uvec2, uvec3 or uvec4.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1iv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2iv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3iv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4iv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformiv_invalid_location (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
std::vector<GLint> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1iv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2iv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3iv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4iv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1iv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform2iv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform3iv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform4iv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformiv_invalid_count (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
GLint ivec4_f = ctx.glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (ivec4_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
std::vector<GLint> data(8);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1iv(ivec4_f, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2iv(ivec4_f, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3iv(ivec4_f, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4iv(ivec4_f, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
// ctx.glUniform{1234}ui
|
|
|
|
void uniformui_invalid_program (NegativeTestContext& ctx)
|
|
{
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if there is no current program object.");
|
|
ctx.glUseProgram(0);
|
|
ctx.glUniform1ui(-1, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2ui(-1, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3ui(-1, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4ui(-1, 0, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void uniformui_incompatible_type (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
GLint vec4_v = ctx.glGetUniformLocation(program.getProgram(), "vec4_v"); // vec4
|
|
GLint ivec4_f = ctx.glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
|
|
GLint uvec4_f = ctx.glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
|
|
GLint sampler_f = ctx.glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the ctx.glUniform command.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1ui(uvec4_f, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2ui(uvec4_f, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3ui(uvec4_f, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4ui(uvec4_f, 0, 0, 0, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}i is used to load a uniform variable of type int, ivec2, ivec3, ivec4, or an array of these.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1ui(ivec4_f, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2ui(ivec4_f, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3ui(ivec4_f, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4ui(ivec4_f, 0, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}i is used to load a uniform variable of type float, vec2, vec3, or vec4.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1ui(vec4_v, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2ui(vec4_v, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3ui(vec4_v, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4ui(vec4_v, 0, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than ctx.glUniform1i and ctx.glUniform1iv.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1ui(sampler_f, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformui_invalid_location (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1i(-2, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2i(-2, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3i(-2, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4i(-2, 0, 0, 0, 0);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1i(-1, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform2i(-1, 0, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform3i(-1, 0, 0, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform4i(-1, 0, 0, 0, 0);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
// ctx.glUniform{1234}uiv
|
|
|
|
void uniformuiv_invalid_program (NegativeTestContext& ctx)
|
|
{
|
|
std::vector<GLuint> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if there is no current program object.");
|
|
ctx.glUseProgram(0);
|
|
ctx.glUniform1uiv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2uiv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3uiv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4uiv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void uniformuiv_incompatible_type (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
GLint vec4_v = ctx.glGetUniformLocation(program.getProgram(), "vec4_v"); // vec4
|
|
GLint ivec4_f = ctx.glGetUniformLocation(program.getProgram(), "ivec4_f"); // ivec4
|
|
GLint uvec4_f = ctx.glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
|
|
GLint sampler_f = ctx.glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (vec4_v == -1 || ivec4_f == -1 || uvec4_f == -1 || sampler_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
std::vector<GLuint> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the ctx.glUniform command.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1uiv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2uiv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3uiv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4uiv(uvec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}uiv is used to load a uniform variable of type float, vec2, vec3, or vec4.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1uiv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2uiv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3uiv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4uiv(vec4_v, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if ctx.glUniform{1234}uiv is used to load a uniform variable of type int, ivec2, ivec3 or ivec4.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1uiv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2uiv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3uiv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4uiv(ivec4_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than ctx.glUniform1i and ctx.glUniform1iv.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1uiv(sampler_f, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformuiv_invalid_location (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
std::vector<GLuint> data(4);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1uiv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2uiv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3uiv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4uiv(-2, 1, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1uiv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform2uiv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform3uiv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniform4uiv(-1, 1, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniformuiv_invalid_count (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
int uvec4_f = ctx.glGetUniformLocation(program.getProgram(), "uvec4_f"); // uvec4
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (uvec4_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
std::vector<GLuint> data(8);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniform1uiv(uvec4_f, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform2uiv(uvec4_f, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform3uiv(uvec4_f, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniform4uiv(uvec4_f, 2, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
|
|
// ctx.glUniformMatrix*fv
|
|
|
|
void uniform_matrixfv_invalid_program (NegativeTestContext& ctx)
|
|
{
|
|
std::vector<GLfloat> data(16);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if there is no current program object.");
|
|
ctx.glUseProgram(0);
|
|
ctx.glUniformMatrix2fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUniformMatrix2x3fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x2fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix2x4fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x2fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x4fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x3fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void uniform_matrixfv_incompatible_type (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
GLint mat4_v = ctx.glGetUniformLocation(program.getProgram(), "mat4_v"); // mat4
|
|
GLint sampler_f = ctx.glGetUniformLocation(program.getProgram(), "sampler_f"); // sampler2D
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (mat4_v == -1 || sampler_f == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
std::vector<GLfloat> data(16);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the size of the uniform variable declared in the shader does not match the size indicated by the ctx.glUniform command.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniformMatrix2fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
ctx.glUniformMatrix2x3fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x2fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix2x4fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x2fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x4fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x3fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if a sampler is loaded using a command other than ctx.glUniform1i and ctx.glUniform1iv.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniformMatrix2fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUniformMatrix2x3fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x2fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix2x4fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x2fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x4fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x3fv(sampler_f, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniform_matrixfv_invalid_location (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
std::vector<GLfloat> data(16);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if location is an invalid uniform location for the current program object and location is not equal to -1.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniformMatrix2fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUniformMatrix2x3fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x2fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix2x4fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x2fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x4fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x3fv(-2, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniformMatrix2fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniformMatrix3fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniformMatrix4fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
ctx.glUniformMatrix2x3fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniformMatrix3x2fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniformMatrix2x4fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniformMatrix4x2fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniformMatrix3x4fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.glUniformMatrix4x3fv(-1, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
void uniform_matrixfv_invalid_count (NegativeTestContext& ctx)
|
|
{
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(uniformTestVertSource, uniformTestFragSource));
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
GLint mat4_v = ctx.glGetUniformLocation(program.getProgram(), "mat4_v"); // mat4
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
if (mat4_v == -1)
|
|
{
|
|
ctx.getLog() << TestLog::Message << "// ERROR: Failed to retrieve uniform location" << TestLog::EndMessage;
|
|
ctx.fail("Failed to retrieve uniform location");
|
|
}
|
|
|
|
std::vector<GLfloat> data(32);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if count is greater than 1 and the indicated uniform variable is not an array variable.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glUniformMatrix2fv(mat4_v, 2, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3fv(mat4_v, 2, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4fv(mat4_v, 2, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glUniformMatrix2x3fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x2fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix2x4fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x2fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix3x4fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glUniformMatrix4x3fv(mat4_v, 1, GL_FALSE, &data[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram(0);
|
|
}
|
|
|
|
// Transform feedback
|
|
void gen_transform_feedbacks (NegativeTestContext& ctx)
|
|
{
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if n is negative.");
|
|
GLuint id = 0;
|
|
ctx.glGenTransformFeedbacks(-1, &id);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void bind_transform_feedback (NegativeTestContext& ctx)
|
|
{
|
|
GLuint tfID[2];
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
deUint32 buf = 0x1234;
|
|
const char* tfVarying = "gl_Position";
|
|
|
|
ctx.glGenBuffers (1, &buf);
|
|
ctx.glGenTransformFeedbacks (2, tfID);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if target is not GL_TRANSFORM_FEEDBACK.");
|
|
ctx.glBindTransformFeedback(-1, tfID[0]);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the transform feedback operation is active on the currently bound transform feedback object, and is not paused.");
|
|
ctx.glUseProgram (program.getProgram());
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glLinkProgram (program.getProgram());
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID[0]);
|
|
ctx.glBindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, buf);
|
|
ctx.glBufferData (GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID[1]);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
|
|
ctx.glEndTransformFeedback ();
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glUseProgram (0);
|
|
ctx.glDeleteBuffers (1, &buf);
|
|
ctx.glDeleteTransformFeedbacks (2, tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if id has been deleted with glDeleteTransformFeedback().");
|
|
ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID[0]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if id is not 0 or a value returned from glGenTransformFeedbacks().");
|
|
ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, -1);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
}
|
|
|
|
void delete_transform_feedbacks (NegativeTestContext& ctx)
|
|
{
|
|
GLuint id = 0;
|
|
GLuint tfID[2];
|
|
deUint32 buf = 0x1234;
|
|
const char* tfVarying = "gl_Position";
|
|
glu::ShaderProgram program (ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
|
|
ctx.glGenBuffers(1, &buf);
|
|
ctx.glGenTransformFeedbacks(1, &id);
|
|
ctx.glGenTransformFeedbacks(2, tfID);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if n is negative.");
|
|
ctx.glDeleteTransformFeedbacks(-1, &id);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the transform feedback operation for any object named by ids is currently active.");
|
|
ctx.glUseProgram(program.getProgram());
|
|
ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glLinkProgram(program.getProgram());
|
|
ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID[0]);
|
|
ctx.glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, buf);
|
|
ctx.glBufferData(GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
|
|
ctx.glBindBufferBase(GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.glBeginTransformFeedback(GL_TRIANGLES);
|
|
ctx.expectError(GL_NO_ERROR);
|
|
|
|
ctx.glBindTransformFeedback(GL_TRANSFORM_FEEDBACK, tfID[1]);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glDeleteTransformFeedbacks(2, tfID);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
|
|
ctx.glEndTransformFeedback();
|
|
ctx.expectError(GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
|
|
ctx.glDeleteTransformFeedbacks(1, &id);
|
|
ctx.glDeleteTransformFeedbacks(2, tfID);
|
|
ctx.glDeleteBuffers(1, &buf);
|
|
|
|
}
|
|
|
|
void begin_transform_feedback (NegativeTestContext& ctx)
|
|
{
|
|
GLuint tfID[2];
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
deUint32 buf = 0x1234;
|
|
const char* tfVarying = "gl_Position";
|
|
|
|
ctx.glGenBuffers (1, &buf);
|
|
ctx.glGenTransformFeedbacks (2, tfID);
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glLinkProgram (program.getProgram());
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID[0]);
|
|
ctx.glBindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, buf);
|
|
ctx.glBufferData (GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if primitiveMode is not one of GL_POINTS, GL_LINES, or GL_TRIANGLES.");
|
|
ctx.glBeginTransformFeedback (-1);
|
|
ctx.expectError (GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is already active.");
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.glBeginTransformFeedback (GL_POINTS);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if any binding point used in transform feedback mode does not have a buffer object bound.");
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, 0);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if no binding points would be used because no program object is active.");
|
|
ctx.glUseProgram (0);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.glUseProgram (program.getProgram());
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if no binding points would be used because the active program object has specified no varying variables to record.");
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), 0, 0, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glEndTransformFeedback ();
|
|
ctx.glDeleteBuffers (1, &buf);
|
|
ctx.glDeleteTransformFeedbacks (2, tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
}
|
|
|
|
void pause_transform_feedback (NegativeTestContext& ctx)
|
|
{
|
|
GLuint tfID[2];
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
deUint32 buf = 0x1234;
|
|
const char* tfVarying = "gl_Position";
|
|
|
|
ctx.glGenBuffers (1, &buf);
|
|
ctx.glGenTransformFeedbacks (2, tfID);
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glLinkProgram (program.getProgram());
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID[0]);
|
|
ctx.glBindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, buf);
|
|
ctx.glBufferData (GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the currently bound transform feedback object is not active or is paused.");
|
|
ctx.glPauseTransformFeedback ();
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.glPauseTransformFeedback ();
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.glPauseTransformFeedback ();
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.endSection();
|
|
|
|
ctx.glEndTransformFeedback ();
|
|
ctx.glDeleteBuffers (1, &buf);
|
|
ctx.glDeleteTransformFeedbacks (2, tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
}
|
|
|
|
void resume_transform_feedback (NegativeTestContext& ctx)
|
|
{
|
|
GLuint tfID[2];
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
deUint32 buf = 0x1234;
|
|
const char* tfVarying = "gl_Position";
|
|
|
|
ctx.glGenBuffers (1, &buf);
|
|
ctx.glGenTransformFeedbacks (2, tfID);
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glLinkProgram (program.getProgram());
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID[0]);
|
|
ctx.glBindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, buf);
|
|
ctx.glBufferData (GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if the currently bound transform feedback object is not active or is not paused.");
|
|
ctx.glResumeTransformFeedback ();
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.glResumeTransformFeedback ();
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.glPauseTransformFeedback ();
|
|
ctx.glResumeTransformFeedback ();
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glEndTransformFeedback ();
|
|
ctx.glDeleteBuffers (1, &buf);
|
|
ctx.glDeleteTransformFeedbacks (2, tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
}
|
|
|
|
void end_transform_feedback (NegativeTestContext& ctx)
|
|
{
|
|
GLuint tfID = 0;
|
|
glu::ShaderProgram program(ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
deUint32 buf = 0x1234;
|
|
const char* tfVarying = "gl_Position";
|
|
|
|
ctx.glGenBuffers (1, &buf);
|
|
ctx.glGenTransformFeedbacks (1, &tfID);
|
|
|
|
ctx.glUseProgram (program.getProgram());
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.glLinkProgram (program.getProgram());
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID);
|
|
ctx.glBindBuffer (GL_TRANSFORM_FEEDBACK_BUFFER, buf);
|
|
ctx.glBufferData (GL_TRANSFORM_FEEDBACK_BUFFER, 32, DE_NULL, GL_DYNAMIC_DRAW);
|
|
ctx.glBindBufferBase (GL_TRANSFORM_FEEDBACK_BUFFER, 0, buf);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if transform feedback is not active.");
|
|
ctx.glEndTransformFeedback ();
|
|
ctx.expectError (GL_INVALID_OPERATION);
|
|
ctx.glBeginTransformFeedback (GL_TRIANGLES);
|
|
ctx.glEndTransformFeedback ();
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteBuffers (1, &buf);
|
|
ctx.glDeleteTransformFeedbacks (1, &tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
}
|
|
|
|
void get_transform_feedback_varying (NegativeTestContext& ctx)
|
|
{
|
|
GLuint tfID = 0;
|
|
glu::ShaderProgram program (ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
glu::ShaderProgram programInvalid (ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, ""));
|
|
const char* tfVarying = "gl_Position";
|
|
int maxTransformFeedbackVaryings = 0;
|
|
|
|
GLsizei length;
|
|
GLsizei size;
|
|
GLenum type;
|
|
char name[32];
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.glGenTransformFeedbacks (1, &tfID);
|
|
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
ctx.glLinkProgram (program.getProgram());
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.glBindTransformFeedback (GL_TRANSFORM_FEEDBACK, tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of a program object.");
|
|
ctx.glGetTransformFeedbackVarying (notAProgram, 0, 32, &length, &size, &type, &name[0]);
|
|
ctx.expectError (GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if index is greater or equal to the value of GL_TRANSFORM_FEEDBACK_VARYINGS.");
|
|
ctx.glGetProgramiv (program.getProgram(), GL_TRANSFORM_FEEDBACK_VARYINGS, &maxTransformFeedbackVaryings);
|
|
ctx.glGetTransformFeedbackVarying (program.getProgram(), maxTransformFeedbackVaryings, 32, &length, &size, &type, &name[0]);
|
|
ctx.expectError (GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION or GL_INVALID_VALUE is generated program has not been linked.");
|
|
ctx.glGetTransformFeedbackVarying (programInvalid.getProgram(), 0, 32, &length, &size, &type, &name[0]);
|
|
ctx.expectError (GL_INVALID_OPERATION, GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteTransformFeedbacks (1, &tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
}
|
|
|
|
void transform_feedback_varyings (NegativeTestContext& ctx)
|
|
{
|
|
GLuint tfID = 0;
|
|
GLuint shader = ctx.glCreateShader(GL_VERTEX_SHADER);
|
|
glu::ShaderProgram program (ctx.getRenderContext(), glu::makeVtxFragSources(vertexShaderSource, fragmentShaderSource));
|
|
const char* tfVarying = "gl_Position";
|
|
GLint maxTransformFeedbackSeparateAttribs = 0;
|
|
|
|
const GLuint notAProgram = ctx.glCreateProgram();
|
|
ctx.glDeleteProgram(notAProgram);
|
|
|
|
ctx.glGenTransformFeedbacks (1, &tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if program is not the name of a program object.");
|
|
ctx.glTransformFeedbackVaryings (notAProgram, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.expectError (GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_OPERATION is generated if program is the name of a shader object.");
|
|
ctx.glTransformFeedbackVaryings(shader, 1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.expectError(GL_INVALID_OPERATION);
|
|
ctx.glDeleteShader(shader);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if count is negative.");
|
|
ctx.glTransformFeedbackVaryings(program.getProgram(), -1, &tfVarying, GL_INTERLEAVED_ATTRIBS);
|
|
ctx.expectError(GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if bufferMode is not SEPARATE_ATTRIBS or INTERLEAVED_ATTRIBS.");
|
|
ctx.glTransformFeedbackVaryings(program.getProgram(), 1, &tfVarying, 0);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.beginSection("GL_INVALID_VALUE is generated if bufferMode is GL_SEPARATE_ATTRIBS and count is greater than GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS.");
|
|
ctx.glGetIntegerv (GL_MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS, &maxTransformFeedbackSeparateAttribs);
|
|
ctx.glTransformFeedbackVaryings (program.getProgram(), maxTransformFeedbackSeparateAttribs+1, &tfVarying, GL_SEPARATE_ATTRIBS);
|
|
ctx.expectError (GL_INVALID_VALUE);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteTransformFeedbacks (1, &tfID);
|
|
ctx.expectError (GL_NO_ERROR);
|
|
|
|
}
|
|
|
|
void link_compute_shader (NegativeTestContext& ctx)
|
|
{
|
|
const char* computeShaderSource = "#version 320 es\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n\0";
|
|
{
|
|
const GLenum shaderTypes[] = {
|
|
GL_VERTEX_SHADER,
|
|
GL_FRAGMENT_SHADER,
|
|
GL_GEOMETRY_SHADER,
|
|
GL_TESS_CONTROL_SHADER,
|
|
GL_TESS_EVALUATION_SHADER
|
|
};
|
|
|
|
ctx.beginSection("Compute Shader linked with shader of other kind.");
|
|
for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(shaderTypes); ndx++)
|
|
{
|
|
GLint linkStatus = -1;
|
|
GLuint program = ctx.glCreateProgram();
|
|
GLuint computeShader = ctx.glCreateShader(GL_COMPUTE_SHADER);
|
|
GLuint otherShader = ctx.glCreateShader(shaderTypes[ndx]);
|
|
const char* otherShaderSource = (shaderTypes[ndx] != GL_GEOMETRY_SHADER) ?
|
|
computeShaderSource :
|
|
"#version 320 es\n"
|
|
"layout(max_vertices = 3) out;\n"
|
|
"void main(void){}\n\0";
|
|
|
|
ctx.glShaderSource(computeShader, 1, &computeShaderSource, DE_NULL);
|
|
ctx.glShaderSource(otherShader, 1, &otherShaderSource, DE_NULL);
|
|
ctx.glCompileShader(computeShader);
|
|
ctx.glCompileShader(otherShader);
|
|
ctx.glAttachShader(program, computeShader);
|
|
ctx.glAttachShader(program, otherShader);
|
|
ctx.glLinkProgram(program);
|
|
ctx.glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
|
|
ctx.glDeleteShader(otherShader);
|
|
ctx.glDeleteShader(computeShader);
|
|
ctx.glDeleteProgram(program);
|
|
if (linkStatus != GL_FALSE)
|
|
ctx.fail("Program should not have linked");
|
|
}
|
|
ctx.endSection();
|
|
}
|
|
{
|
|
const char* computeShaderSource310 = "#version 310 es\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n\0";
|
|
GLint linkStatus = -1;
|
|
GLuint program = ctx.glCreateProgram();
|
|
GLuint computeShader = ctx.glCreateShader(GL_COMPUTE_SHADER);
|
|
GLuint computeShader310 = ctx.glCreateShader(GL_FRAGMENT_SHADER);
|
|
|
|
ctx.glShaderSource(computeShader, 1, &computeShaderSource, DE_NULL);
|
|
ctx.glShaderSource(computeShader310, 1, &computeShaderSource310, DE_NULL);
|
|
ctx.beginSection("Compute Shader should not be linked with shaders of different version.");
|
|
ctx.glCompileShader(computeShader);
|
|
ctx.glCompileShader(computeShader310);
|
|
ctx.glAttachShader(program, computeShader);
|
|
ctx.glAttachShader(program, computeShader310);
|
|
ctx.glLinkProgram(program);
|
|
ctx.glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
|
|
ctx.glDeleteShader(computeShader310);
|
|
ctx.glDeleteShader(computeShader);
|
|
ctx.glDeleteProgram(program);
|
|
if (linkStatus != GL_FALSE)
|
|
ctx.fail("Program should not have linked");
|
|
ctx.endSection();
|
|
}
|
|
}
|
|
|
|
void compile_compute_shader_helper (NegativeTestContext& ctx, const char* const* computeShaderSource, GLint* compileStatus)
|
|
{
|
|
GLuint shader = ctx.glCreateShader(GL_COMPUTE_SHADER);
|
|
|
|
*compileStatus = -1;
|
|
ctx.glShaderSource(shader, 1, computeShaderSource, DE_NULL);
|
|
ctx.glCompileShader(shader);
|
|
ctx.glGetShaderiv(shader, GL_COMPILE_STATUS, compileStatus);
|
|
ctx.glDeleteShader(shader);
|
|
}
|
|
|
|
void compile_compute_shader (NegativeTestContext& ctx)
|
|
{
|
|
GLint compileStatus;
|
|
ctx.beginSection("Compile Computer Shader");
|
|
|
|
{
|
|
const char* const computeShaderSource = "#version 300 es\n"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled with #version 300 es.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"buffer SSBO { vec4 data }"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: incorrect SSBO syntax.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"buffer SSBO { vec4 data;};"
|
|
"uniform mat4 data;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: buffer variable redefinition.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"buffer SSBO { vec4 data[]; vec4 moreData;};"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: unspecified length buffer member not at the end.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"in vec4 data;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: input qualifier used.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"shared uint data = 0;";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: shared-qualified variable initialized.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"buffer SSBO { vec4 data; vec4 moreData[];} ssbo;"
|
|
"void test (vec4 data[10]) {}"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" test(ssbo.moreData);"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: unspecified length buffer member passed as argument to function.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"buffer SSBO { vec4 data; vec4 moreData[];} ssbo;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
" vec4 var = ssbo.moreData[-1];"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: unspecified length buffer member indexed with negative constant expression.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"layout(binding=-1) buffer SSBO { vec4 data;};"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: binding point less than zero.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"layout(binding=1) buffer;"
|
|
"layout(binding=2) buffer SSBO { vec4 data;};"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: binding point specified for global scope.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"buffer SSBO {"
|
|
" layout(binding=1) vec4 data;"
|
|
" layout(binding=2) vec4 moreData[];"
|
|
"} ssbo;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: binding point specified for block member declarations.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"readonly buffer SSBO {vec4 data;} ssbo;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"ssbo.data = vec4(1, 1, 1, 1);"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: writing to buffer block qualified with readonly.");
|
|
}
|
|
{
|
|
const char* const computeShaderSource = "#version 310 es\n"
|
|
"writeonly buffer SSBO {vec4 data;} ssbo;"
|
|
"void main (void)\n"
|
|
"{\n"
|
|
"vec4 var = ssbo.data;"
|
|
"}\n";
|
|
|
|
compile_compute_shader_helper(ctx, &computeShaderSource, &compileStatus);
|
|
if (compileStatus != GL_FALSE)
|
|
ctx.fail("Compute Shader should not have compiled: reading from buffer block qualified with writeonly.");
|
|
}
|
|
|
|
ctx.endSection();
|
|
}
|
|
|
|
void srgb_decode_samplerparameteri (NegativeTestContext& ctx)
|
|
{
|
|
if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
|
|
TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
|
|
|
|
GLuint sampler = 0x1234;
|
|
GLint samplerMode = -1;
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
|
|
ctx.glSamplerParameteri(sampler, GL_TEXTURE_SRGB_DECODE_EXT, samplerMode);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void srgb_decode_samplerparameterf (NegativeTestContext& ctx)
|
|
{
|
|
if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
|
|
TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
|
|
|
|
GLuint sampler = 0x1234;
|
|
GLfloat samplerMode = -1.0f;
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
|
|
ctx.glSamplerParameterf(sampler, GL_TEXTURE_SRGB_DECODE_EXT, samplerMode);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void srgb_decode_samplerparameteriv (NegativeTestContext& ctx)
|
|
{
|
|
if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
|
|
TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
|
|
|
|
int params[1] = { GL_LINEAR };
|
|
GLuint sampler = 0x1234;
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
|
|
params[0] = -1;
|
|
ctx.glSamplerParameteriv(sampler, GL_TEXTURE_SRGB_DECODE_EXT, ¶ms[0]);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void srgb_decode_samplerparameterfv (NegativeTestContext& ctx)
|
|
{
|
|
if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
|
|
TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
|
|
|
|
float params[1] = { GL_LINEAR };
|
|
GLuint sampler = 0x1234;
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
params[0] = -1.0f;
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
|
|
ctx.glSamplerParameterfv(sampler, GL_TEXTURE_SRGB_DECODE_EXT, ¶ms[0]);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void srgb_decode_samplerparameterIiv (NegativeTestContext& ctx)
|
|
{
|
|
if (!supportsES32orGL45(ctx))
|
|
TCU_THROW(NotSupportedError, "glSamplerParameterIiv is not supported.");
|
|
|
|
if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
|
|
TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
|
|
|
|
GLint samplerMode[] = {GL_DEPTH_COMPONENT, GL_STENCIL_INDEX};
|
|
GLuint sampler = 0x1234;
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
|
|
samplerMode[0] = -1;
|
|
samplerMode[1] = -1;
|
|
ctx.glSamplerParameterIiv(sampler, GL_TEXTURE_SRGB_DECODE_EXT, samplerMode);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
void srgb_decode_samplerparameterIuiv (NegativeTestContext& ctx)
|
|
{
|
|
if (!supportsES32orGL45(ctx))
|
|
TCU_THROW(NotSupportedError, "glSamplerParameterIuiv is not supported.");
|
|
|
|
if (!ctx.isExtensionSupported("GL_EXT_texture_sRGB_decode"))
|
|
TCU_THROW(NotSupportedError, "GL_EXT_texture_sRGB_decode is not supported.");
|
|
|
|
GLuint samplerMode[] = {GL_DEPTH_COMPONENT, GL_STENCIL_INDEX};
|
|
GLuint sampler = 0x1234;
|
|
|
|
ctx.glGenSamplers(1, &sampler);
|
|
|
|
ctx.beginSection("GL_INVALID_ENUM is generated if pname is GL_TEXTURE_SRGB_DECODE_EXT and the value of param(s) is not a valid value (one of DECODE_EXT, or SKIP_DECODE_EXT).");
|
|
samplerMode[0] = GL_DONT_CARE;
|
|
samplerMode[1] = GL_DONT_CARE;
|
|
ctx.glSamplerParameterIuiv(sampler, GL_TEXTURE_SRGB_DECODE_EXT, samplerMode);
|
|
ctx.expectError(GL_INVALID_ENUM);
|
|
ctx.endSection();
|
|
|
|
ctx.glDeleteSamplers(1, &sampler);
|
|
}
|
|
|
|
std::vector<FunctionContainer> getNegativeShaderApiTestFunctions ()
|
|
{
|
|
FunctionContainer funcs[] =
|
|
{
|
|
{create_shader, "create_shader", "Invalid glCreateShader() usage" },
|
|
{shader_source, "shader_source", "Invalid glShaderSource() usage" },
|
|
{compile_shader, "compile_shader", "Invalid glCompileShader() usage" },
|
|
{delete_shader, "delete_shader", "Invalid glDeleteShader() usage" },
|
|
{shader_binary, "shader_binary", "Invalid glShaderBinary() usage" },
|
|
{attach_shader, "attach_shader", "Invalid glAttachShader() usage" },
|
|
{detach_shader, "detach_shader", "Invalid glDetachShader() usage" },
|
|
{link_program, "link_program", "Invalid glLinkProgram() usage" },
|
|
{use_program, "use_program", "Invalid glUseProgram() usage" },
|
|
{delete_program, "delete_program", "Invalid glDeleteProgram() usage" },
|
|
{validate_program, "validate_program", "Invalid glValidateProgram() usage" },
|
|
{get_program_binary, "get_program_binary", "Invalid glGetProgramBinary() usage" },
|
|
{program_binary, "program_binary", "Invalid glProgramBinary() usage" },
|
|
{program_parameteri, "program_parameteri", "Invalid glProgramParameteri() usage" },
|
|
{gen_samplers, "gen_samplers", "Invalid glGenSamplers() usage" },
|
|
{bind_sampler, "bind_sampler", "Invalid glBindSampler() usage" },
|
|
{delete_samplers, "delete_samplers", "Invalid glDeleteSamplers() usage" },
|
|
{get_sampler_parameteriv, "get_sampler_parameteriv", "Invalid glGetSamplerParameteriv() usage" },
|
|
{get_sampler_parameterfv, "get_sampler_parameterfv", "Invalid glGetSamplerParameterfv() usage" },
|
|
{get_sampler_parameterIiv, "get_sampler_parameterIiv", "Invalid glGetSamplerParameterIiv() usage" },
|
|
{get_sampler_parameterIuiv, "get_sampler_parameterIuiv", "Invalid glGetSamplerParameterIuiv() usage" },
|
|
{sampler_parameteri, "sampler_parameteri", "Invalid glSamplerParameteri() usage" },
|
|
{sampler_parameteriv, "sampler_parameteriv", "Invalid glSamplerParameteriv() usage" },
|
|
{sampler_parameterf, "sampler_parameterf", "Invalid glSamplerParameterf() usage" },
|
|
{sampler_parameterfv, "sampler_parameterfv", "Invalid glSamplerParameterfv() usage" },
|
|
{sampler_parameterIiv, "sampler_parameterIiv", "Invalid glSamplerParameterIiv() usage" },
|
|
{sampler_parameterIuiv, "sampler_parameterIuiv", "Invalid glSamplerParameterIuiv() usage" },
|
|
{get_attrib_location, "get_attrib_location", "Invalid glGetAttribLocation() usage" },
|
|
{get_uniform_location, "get_uniform_location", "Invalid glGetUniformLocation() usage" },
|
|
{bind_attrib_location, "bind_attrib_location", "Invalid glBindAttribLocation() usage" },
|
|
{uniform_block_binding, "uniform_block_binding", "Invalid glUniformBlockBinding() usage" },
|
|
{uniformf_invalid_program, "uniformf_invalid_program", "Invalid glUniform{1234}f() usage" },
|
|
{uniformf_incompatible_type, "uniformf_incompatible_type", "Invalid glUniform{1234}f() usage" },
|
|
{uniformf_invalid_location, "uniformf_invalid_location", "Invalid glUniform{1234}f() usage" },
|
|
{uniformfv_invalid_program, "uniformfv_invalid_program", "Invalid glUniform{1234}fv() usage" },
|
|
{uniformfv_incompatible_type, "uniformfv_incompatible_type", "Invalid glUniform{1234}fv() usage" },
|
|
{uniformfv_invalid_location, "uniformfv_invalid_location", "Invalid glUniform{1234}fv() usage" },
|
|
{uniformfv_invalid_count, "uniformfv_invalid_count", "Invalid glUniform{1234}fv() usage" },
|
|
{uniformi_invalid_program, "uniformi_invalid_program", "Invalid glUniform{1234}i() usage" },
|
|
{uniformi_incompatible_type, "uniformi_incompatible_type", "Invalid glUniform{1234}i() usage" },
|
|
{uniformi_invalid_location, "uniformi_invalid_location", "Invalid glUniform{1234}i() usage" },
|
|
{uniformiv_invalid_program, "uniformiv_invalid_program", "Invalid glUniform{1234}iv() usage" },
|
|
{uniformiv_incompatible_type, "uniformiv_incompatible_type", "Invalid glUniform{1234}iv() usage" },
|
|
{uniformiv_invalid_location, "uniformiv_invalid_location", "Invalid glUniform{1234}iv() usage" },
|
|
{uniformiv_invalid_count, "uniformiv_invalid_count", "Invalid glUniform{1234}iv() usage" },
|
|
{uniformui_invalid_program, "uniformui_invalid_program", "Invalid glUniform{234}ui() usage" },
|
|
{uniformui_incompatible_type, "uniformui_incompatible_type", "Invalid glUniform{1234}ui() usage" },
|
|
{uniformui_invalid_location, "uniformui_invalid_location", "Invalid glUniform{1234}ui() usage" },
|
|
{uniformuiv_invalid_program, "uniformuiv_invalid_program", "Invalid glUniform{234}uiv() usage" },
|
|
{uniformuiv_incompatible_type, "uniformuiv_incompatible_type", "Invalid glUniform{1234}uiv() usage" },
|
|
{uniformuiv_invalid_location, "uniformuiv_invalid_location", "Invalid glUniform{1234}uiv() usage" },
|
|
{uniformuiv_invalid_count, "uniformuiv_invalid_count", "Invalid glUniform{1234}uiv() usage" },
|
|
{uniform_matrixfv_invalid_program, "uniform_matrixfv_invalid_program", "Invalid glUniformMatrix{234}fv() usage" },
|
|
{uniform_matrixfv_incompatible_type, "uniform_matrixfv_incompatible_type", "Invalid glUniformMatrix{234}fv() usage" },
|
|
{uniform_matrixfv_invalid_location, "uniform_matrixfv_invalid_location", "Invalid glUniformMatrix{234}fv() usage" },
|
|
{uniform_matrixfv_invalid_count, "uniform_matrixfv_invalid_count", "Invalid glUniformMatrix{234}fv() usage" },
|
|
{gen_transform_feedbacks, "gen_transform_feedbacks", "Invalid glGenTransformFeedbacks() usage" },
|
|
{bind_transform_feedback, "bind_transform_feedback", "Invalid glBindTransformFeedback() usage" },
|
|
{delete_transform_feedbacks, "delete_transform_feedbacks", "Invalid glDeleteTransformFeedbacks() usage" },
|
|
{begin_transform_feedback, "begin_transform_feedback", "Invalid glBeginTransformFeedback() usage" },
|
|
{pause_transform_feedback, "pause_transform_feedback", "Invalid glPauseTransformFeedback() usage" },
|
|
{resume_transform_feedback, "resume_transform_feedback", "Invalid glResumeTransformFeedback() usage" },
|
|
{end_transform_feedback, "end_transform_feedback", "Invalid glEndTransformFeedback() usage" },
|
|
{get_transform_feedback_varying, "get_transform_feedback_varying", "Invalid glGetTransformFeedbackVarying() usage"},
|
|
{transform_feedback_varyings, "transform_feedback_varyings", "Invalid glTransformFeedbackVaryings() usage" },
|
|
{compile_compute_shader, "compile_compute_shader", "Invalid Compute Shader compilation" },
|
|
{link_compute_shader, "link_compute_shader", "Invalid Compute Shader linkage" },
|
|
{srgb_decode_samplerparameteri, "srgb_decode_samplerparameteri", "Invalid glSamplerParameteri() usage srgb" },
|
|
{srgb_decode_samplerparameterf, "srgb_decode_samplerparameterf", "Invalid glSamplerParameterf() usage srgb" },
|
|
{srgb_decode_samplerparameteriv, "srgb_decode_samplerparameteriv", "Invalid glSamplerParameteriv() usage srgb" },
|
|
{srgb_decode_samplerparameterfv, "srgb_decode_samplerparameterfv", "Invalid glSamplerParameterfv() usage srgb" },
|
|
{srgb_decode_samplerparameterIiv, "srgb_decode_samplerparameterIiv", "Invalid glSamplerParameterIiv() usage srgb" },
|
|
{srgb_decode_samplerparameterIuiv, "srgb_decode_samplerparameterIuiv", "Invalid glSamplerParameterIiuv() usage srgb" },
|
|
};
|
|
|
|
return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
|
|
}
|
|
|
|
} // NegativeTestShared
|
|
} // Functional
|
|
} // gles31
|
|
} // deqp
|