blob: 879efc0c461b3e1468fef00808f40d6699dddac1 [file] [log] [blame]
/*-------------------------------------------------------------------------
* OpenGL Conformance Test Suite
* -----------------------------
*
* Copyright (c) 2014-2016 The Khronos Group Inc.
*
* 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
*/ /*-------------------------------------------------------------------*/
/**
* \file gl4GPUShaderFP64Tests.cpp
* \brief Implements conformance tests for "GPU Shader FP64" functionality.
*/ /*-------------------------------------------------------------------*/
#include "gl4cGPUShaderFP64Tests.hpp"
#include "gluContextInfo.hpp"
#include "glwFunctions.hpp"
#include "tcuMatrix.hpp"
#include "tcuTestLog.hpp"
#include <iomanip>
#include "deMath.h"
#include "deUniquePtr.hpp"
#include "tcuMatrixUtil.hpp"
#include "tcuVectorUtil.hpp"
#include <cstdlib>
#include <cstring>
#include <limits>
#include <memory>
namespace gl4cts
{
const glw::GLenum Utils::programInfo::ARB_COMPUTE_SHADER = 0x91B9;
/** Constructor
*
* @param context Test context
**/
Utils::programInfo::programInfo(deqp::Context& context)
: m_context(context)
, m_compute_shader_id(0)
, m_fragment_shader_id(0)
, m_geometry_shader_id(0)
, m_program_object_id(0)
, m_tesselation_control_shader_id(0)
, m_tesselation_evaluation_shader_id(0)
, m_vertex_shader_id(0)
{
/* Nothing to be done here */
}
/** Destructor
*
**/
Utils::programInfo::~programInfo()
{
/* GL entry points */
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Make sure program object is no longer used by GL */
gl.useProgram(0);
/* Clean program object */
if (0 != m_program_object_id)
{
gl.deleteProgram(m_program_object_id);
m_program_object_id = 0;
}
/* Clean shaders */
if (0 != m_compute_shader_id)
{
gl.deleteShader(m_compute_shader_id);
m_compute_shader_id = 0;
}
if (0 != m_fragment_shader_id)
{
gl.deleteShader(m_fragment_shader_id);
m_fragment_shader_id = 0;
}
if (0 != m_geometry_shader_id)
{
gl.deleteShader(m_geometry_shader_id);
m_geometry_shader_id = 0;
}
if (0 != m_tesselation_control_shader_id)
{
gl.deleteShader(m_tesselation_control_shader_id);
m_tesselation_control_shader_id = 0;
}
if (0 != m_tesselation_evaluation_shader_id)
{
gl.deleteShader(m_tesselation_evaluation_shader_id);
m_tesselation_evaluation_shader_id = 0;
}
if (0 != m_vertex_shader_id)
{
gl.deleteShader(m_vertex_shader_id);
m_vertex_shader_id = 0;
}
}
/** Build program
*
* @param compute_shader_code Compute shader source code
* @param fragment_shader_code Fragment shader source code
* @param geometry_shader_code Geometry shader source code
* @param tesselation_control_shader_code Tesselation control shader source code
* @param tesselation_evaluation_shader_code Tesselation evaluation shader source code
* @param vertex_shader_code Vertex shader source code
* @param varying_names Array of strings containing names of varyings to be captured with transfrom feedback
* @param n_varying_names Number of varyings to be captured with transfrom feedback
**/
void Utils::programInfo::build(const glw::GLchar* compute_shader_code, const glw::GLchar* fragment_shader_code,
const glw::GLchar* geometry_shader_code,
const glw::GLchar* tesselation_control_shader_code,
const glw::GLchar* tesselation_evaluation_shader_code,
const glw::GLchar* vertex_shader_code, const glw::GLchar* const* varying_names,
glw::GLuint n_varying_names)
{
/* GL entry points */
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Create shader objects and compile */
if (0 != compute_shader_code)
{
m_compute_shader_id = gl.createShader(ARB_COMPUTE_SHADER);
GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
compile(m_compute_shader_id, compute_shader_code);
}
if (0 != fragment_shader_code)
{
m_fragment_shader_id = gl.createShader(GL_FRAGMENT_SHADER);
GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
compile(m_fragment_shader_id, fragment_shader_code);
}
if (0 != geometry_shader_code)
{
m_geometry_shader_id = gl.createShader(GL_GEOMETRY_SHADER);
GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
compile(m_geometry_shader_id, geometry_shader_code);
}
if (0 != tesselation_control_shader_code)
{
m_tesselation_control_shader_id = gl.createShader(GL_TESS_CONTROL_SHADER);
GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
compile(m_tesselation_control_shader_id, tesselation_control_shader_code);
}
if (0 != tesselation_evaluation_shader_code)
{
m_tesselation_evaluation_shader_id = gl.createShader(GL_TESS_EVALUATION_SHADER);
GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
compile(m_tesselation_evaluation_shader_id, tesselation_evaluation_shader_code);
}
if (0 != vertex_shader_code)
{
m_vertex_shader_id = gl.createShader(GL_VERTEX_SHADER);
GLU_EXPECT_NO_ERROR(gl.getError(), "CreateShader");
compile(m_vertex_shader_id, vertex_shader_code);
}
/* Create program object */
m_program_object_id = gl.createProgram();
GLU_EXPECT_NO_ERROR(gl.getError(), "CreateProgram");
/* Set up captyured varyings' names */
if (0 != n_varying_names)
{
gl.transformFeedbackVaryings(m_program_object_id, n_varying_names, varying_names, GL_INTERLEAVED_ATTRIBS);
GLU_EXPECT_NO_ERROR(gl.getError(), "TransformFeedbackVaryings");
}
/* Link program */
link();
}
/** Compile shader
*
* @param shader_id Shader object id
* @param shader_code Shader source code
**/
void Utils::programInfo::compile(glw::GLuint shader_id, const glw::GLchar* shader_code) const
{
/* GL entry points */
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Compilation status */
glw::GLint status = GL_FALSE;
/* Set source code */
gl.shaderSource(shader_id, 1 /* count */, &shader_code, 0);
GLU_EXPECT_NO_ERROR(gl.getError(), "ShaderSource");
/* Compile */
gl.compileShader(shader_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "CompileShader");
/* Get compilation status */
gl.getShaderiv(shader_id, GL_COMPILE_STATUS, &status);
GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
/* Log compilation error */
if (GL_TRUE != status)
{
glw::GLint length = 0;
std::vector<glw::GLchar> message;
/* Error log length */
gl.getShaderiv(shader_id, GL_INFO_LOG_LENGTH, &length);
GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderiv");
/* Prepare storage */
message.resize(length);
/* Get error log */
gl.getShaderInfoLog(shader_id, length, 0, &message[0]);
GLU_EXPECT_NO_ERROR(gl.getError(), "GetShaderInfoLog");
/* Log */
m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to compile shader:\n"
<< &message[0] << "\nShader source\n"
<< shader_code << tcu::TestLog::EndMessage;
TCU_FAIL("Failed to compile shader");
}
}
/** Attach shaders and link program
*
**/
void Utils::programInfo::link() const
{
/* GL entry points */
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
/* Link status */
glw::GLint status = GL_FALSE;
/* Attach shaders */
if (0 != m_compute_shader_id)
{
gl.attachShader(m_program_object_id, m_compute_shader_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
}
if (0 != m_fragment_shader_id)
{
gl.attachShader(m_program_object_id, m_fragment_shader_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
}
if (0 != m_geometry_shader_id)
{
gl.attachShader(m_program_object_id, m_geometry_shader_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
}
if (0 != m_tesselation_control_shader_id)
{
gl.attachShader(m_program_object_id, m_tesselation_control_shader_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
}
if (0 != m_tesselation_evaluation_shader_id)
{
gl.attachShader(m_program_object_id, m_tesselation_evaluation_shader_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
}
if (0 != m_vertex_shader_id)
{
gl.attachShader(m_program_object_id, m_vertex_shader_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "AttachShader");
}
/* Link */
gl.linkProgram(m_program_object_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "LinkProgram");
/* Get link status */
gl.getProgramiv(m_program_object_id, GL_LINK_STATUS, &status);
GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
/* Log link error */
if (GL_TRUE != status)
{
glw::GLint length = 0;
std::vector<glw::GLchar> message;
/* Get error log length */
gl.getProgramiv(m_program_object_id, GL_INFO_LOG_LENGTH, &length);
GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramiv");
message.resize(length);
/* Get error log */
gl.getProgramInfoLog(m_program_object_id, length, 0, &message[0]);
GLU_EXPECT_NO_ERROR(gl.getError(), "GetProgramInfoLog");
/* Log */
m_context.getTestContext().getLog() << tcu::TestLog::Message << "Failed to link program:\n"
<< &message[0] << tcu::TestLog::EndMessage;
TCU_FAIL("Failed to link program");
}
}
/** Retrieves base type of user-provided variable type. (eg. VARIABLE_TYPE_DOUBLE for double-precision
* matrix types.
*
* @param type Variable type to return base type for.
*
* @return Requested value or VARAIBLE_TYPE_UNKNOWN if @param type was not recognized.
**/
Utils::_variable_type Utils::getBaseVariableType(_variable_type type)
{
_variable_type result = VARIABLE_TYPE_UNKNOWN;
switch (type)
{
case VARIABLE_TYPE_BOOL:
{
result = VARIABLE_TYPE_BOOL;
break;
}
case VARIABLE_TYPE_DOUBLE:
case VARIABLE_TYPE_DMAT2:
case VARIABLE_TYPE_DMAT2X3:
case VARIABLE_TYPE_DMAT2X4:
case VARIABLE_TYPE_DMAT3:
case VARIABLE_TYPE_DMAT3X2:
case VARIABLE_TYPE_DMAT3X4:
case VARIABLE_TYPE_DMAT4:
case VARIABLE_TYPE_DMAT4X2:
case VARIABLE_TYPE_DMAT4X3:
case VARIABLE_TYPE_DVEC2:
case VARIABLE_TYPE_DVEC3:
case VARIABLE_TYPE_DVEC4:
{
result = VARIABLE_TYPE_DOUBLE;
break;
}
case VARIABLE_TYPE_INT:
case VARIABLE_TYPE_IVEC2:
case VARIABLE_TYPE_IVEC3:
case VARIABLE_TYPE_IVEC4:
{
result = VARIABLE_TYPE_INT;
break;
}
case VARIABLE_TYPE_UINT:
case VARIABLE_TYPE_UVEC2:
case VARIABLE_TYPE_UVEC3:
case VARIABLE_TYPE_UVEC4:
{
result = VARIABLE_TYPE_UINT;
break;
}
case VARIABLE_TYPE_FLOAT:
case VARIABLE_TYPE_MAT2:
case VARIABLE_TYPE_MAT2X3:
case VARIABLE_TYPE_MAT2X4:
case VARIABLE_TYPE_MAT3:
case VARIABLE_TYPE_MAT3X2:
case VARIABLE_TYPE_MAT3X4:
case VARIABLE_TYPE_MAT4:
case VARIABLE_TYPE_MAT4X2:
case VARIABLE_TYPE_MAT4X3:
case VARIABLE_TYPE_VEC2:
case VARIABLE_TYPE_VEC3:
case VARIABLE_TYPE_VEC4:
{
result = VARIABLE_TYPE_FLOAT;
break;
}
default:
{
TCU_FAIL("Unrecognized variable type");
}
} /* switch (type) */
return result;
}
/** Returns size (in bytes) of a single component of a base variable type.
*
* @param type Base variable type to use for the query.
*
* @return Requested value or 0 if @param type was not recognized.
**/
unsigned int Utils::getBaseVariableTypeComponentSize(_variable_type type)
{
unsigned int result = 0;
switch (type)
{
case VARIABLE_TYPE_BOOL:
result = sizeof(bool);
break;
case VARIABLE_TYPE_DOUBLE:
result = sizeof(double);
break;
case VARIABLE_TYPE_FLOAT:
result = sizeof(float);
break;
case VARIABLE_TYPE_INT:
result = sizeof(int);
break;
case VARIABLE_TYPE_UINT:
result = sizeof(unsigned int);
break;
default:
{
TCU_FAIL("Unrecognized variable type");
}
} /* switch (type) */
return result;
}
/** Returns component, corresponding to user-specified index
* (eg. index:0 corresponds to 'x', index:1 corresponds to 'y',
* and so on.
*
* @param index Component index.
*
* @return As per description.
**/
unsigned char Utils::getComponentAtIndex(unsigned int index)
{
unsigned char result = '?';
switch (index)
{
case 0:
result = 'x';
break;
case 1:
result = 'y';
break;
case 2:
result = 'z';
break;
case 3:
result = 'w';
break;
default:
{
TCU_FAIL("Unrecognized component index");
}
}
return result;
}
/** Get _variable_type representing double-precision type with given dimmensions
*
* @param n_columns Number of columns
* @param n_row Number of rows
*
* @return Corresponding _variable_type
**/
Utils::_variable_type Utils::getDoubleVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
{
Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
static const _variable_type types[4][4] = {
{ VARIABLE_TYPE_DOUBLE, VARIABLE_TYPE_DVEC2, VARIABLE_TYPE_DVEC3, VARIABLE_TYPE_DVEC4 },
{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT2, VARIABLE_TYPE_DMAT2X3, VARIABLE_TYPE_DMAT2X4 },
{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT3X2, VARIABLE_TYPE_DMAT3, VARIABLE_TYPE_DMAT3X4 },
{ VARIABLE_TYPE_UNKNOWN, VARIABLE_TYPE_DMAT4X2, VARIABLE_TYPE_DMAT4X3, VARIABLE_TYPE_DMAT4 }
};
type = types[n_columns - 1][n_rows - 1];
return type;
}
/** Returns a single-precision equivalent of a double-precision floating-point variable
* type.
*
* @param type Double-precision variable type. Only VARIABLE_TYPE_D* variable types
* are accepted.
*
* @return Requested GLSL type.
**/
std::string Utils::getFPVariableTypeStringForVariableType(_variable_type type)
{
std::string result = "[?]";
switch (type)
{
case VARIABLE_TYPE_DOUBLE:
result = "float";
break;
case VARIABLE_TYPE_DMAT2:
result = "mat2";
break;
case VARIABLE_TYPE_DMAT2X3:
result = "mat2x3";
break;
case VARIABLE_TYPE_DMAT2X4:
result = "mat2x4";
break;
case VARIABLE_TYPE_DMAT3:
result = "mat3";
break;
case VARIABLE_TYPE_DMAT3X2:
result = "mat3x2";
break;
case VARIABLE_TYPE_DMAT3X4:
result = "mat3x4";
break;
case VARIABLE_TYPE_DMAT4:
result = "mat4";
break;
case VARIABLE_TYPE_DMAT4X2:
result = "mat4x2";
break;
case VARIABLE_TYPE_DMAT4X3:
result = "mat4x3";
break;
case VARIABLE_TYPE_DVEC2:
result = "vec2";
break;
case VARIABLE_TYPE_DVEC3:
result = "vec3";
break;
case VARIABLE_TYPE_DVEC4:
result = "vec4";
break;
default:
{
TCU_FAIL("Unrecognized variable type");
}
} /* switch (type) */
return result;
}
/** Returns GL data type enum corresponding to user-provided base variable type.
*
* @param type Base variable type to return corresponding GLenum value for.
*
* @return Corresponding GLenum value or GL_NONE if the input value was not
* recognized.
**/
glw::GLenum Utils::getGLDataTypeOfBaseVariableType(_variable_type type)
{
glw::GLenum result = GL_NONE;
switch (type)
{
case VARIABLE_TYPE_BOOL:
result = GL_BOOL;
break;
case VARIABLE_TYPE_DOUBLE:
result = GL_DOUBLE;
break;
case VARIABLE_TYPE_FLOAT:
result = GL_FLOAT;
break;
case VARIABLE_TYPE_INT:
result = GL_INT;
break;
case VARIABLE_TYPE_UINT:
result = GL_UNSIGNED_INT;
break;
default:
{
TCU_FAIL("Unrecognized variable type");
}
}
return result;
}
/** Return GLenum representing given <type>
*
* @param type Type of variable
*
* @return GL enumeration
**/
glw::GLenum Utils::getGLDataTypeOfVariableType(_variable_type type)
{
glw::GLenum result = GL_NONE;
switch (type)
{
case VARIABLE_TYPE_BOOL:
result = GL_BOOL;
break;
case VARIABLE_TYPE_DOUBLE:
result = GL_DOUBLE;
break;
case VARIABLE_TYPE_DMAT2:
result = GL_DOUBLE_MAT2;
break;
case VARIABLE_TYPE_DMAT2X3:
result = GL_DOUBLE_MAT2x3;
break;
case VARIABLE_TYPE_DMAT2X4:
result = GL_DOUBLE_MAT2x4;
break;
case VARIABLE_TYPE_DMAT3:
result = GL_DOUBLE_MAT3;
break;
case VARIABLE_TYPE_DMAT3X2:
result = GL_DOUBLE_MAT3x2;
break;
case VARIABLE_TYPE_DMAT3X4:
result = GL_DOUBLE_MAT3x4;
break;
case VARIABLE_TYPE_DMAT4:
result = GL_DOUBLE_MAT4;
break;
case VARIABLE_TYPE_DMAT4X2:
result = GL_DOUBLE_MAT4x2;
break;
case VARIABLE_TYPE_DMAT4X3:
result = GL_DOUBLE_MAT4x3;
break;
case VARIABLE_TYPE_DVEC2:
result = GL_DOUBLE_VEC2;
break;
case VARIABLE_TYPE_DVEC3:
result = GL_DOUBLE_VEC3;
break;
case VARIABLE_TYPE_DVEC4:
result = GL_DOUBLE_VEC4;
break;
case VARIABLE_TYPE_FLOAT:
result = GL_FLOAT;
break;
case VARIABLE_TYPE_INT:
result = GL_INT;
break;
case VARIABLE_TYPE_IVEC2:
result = GL_INT_VEC2;
break;
case VARIABLE_TYPE_IVEC3:
result = GL_INT_VEC3;
break;
case VARIABLE_TYPE_IVEC4:
result = GL_INT_VEC4;
break;
case VARIABLE_TYPE_MAT2:
result = GL_FLOAT_MAT2;
break;
case VARIABLE_TYPE_MAT2X3:
result = GL_FLOAT_MAT2x3;
break;
case VARIABLE_TYPE_MAT2X4:
result = GL_FLOAT_MAT2x4;
break;
case VARIABLE_TYPE_MAT3:
result = GL_FLOAT_MAT3;
break;
case VARIABLE_TYPE_MAT3X2:
result = GL_FLOAT_MAT3x2;
break;
case VARIABLE_TYPE_MAT3X4:
result = GL_FLOAT_MAT3x4;
break;
case VARIABLE_TYPE_MAT4:
result = GL_FLOAT_MAT4;
break;
case VARIABLE_TYPE_MAT4X2:
result = GL_FLOAT_MAT4x2;
break;
case VARIABLE_TYPE_MAT4X3:
result = GL_FLOAT_MAT4x3;
break;
case VARIABLE_TYPE_UINT:
result = GL_UNSIGNED_INT;
break;
case VARIABLE_TYPE_UVEC2:
result = GL_UNSIGNED_INT_VEC2;
break;
case VARIABLE_TYPE_UVEC3:
result = GL_UNSIGNED_INT_VEC3;
break;
case VARIABLE_TYPE_UVEC4:
result = GL_UNSIGNED_INT_VEC4;
break;
case VARIABLE_TYPE_VEC2:
result = GL_FLOAT_VEC2;
break;
case VARIABLE_TYPE_VEC3:
result = GL_FLOAT_VEC3;
break;
case VARIABLE_TYPE_VEC4:
result = GL_FLOAT_VEC4;
break;
default:
{
TCU_FAIL("Unrecognized variable type");
}
}
return result;
}
/** Get _variable_type representing integer type with given dimmensions
*
* @param n_columns Number of columns
* @param n_row Number of rows
*
* @return Corresponding _variable_type
**/
Utils::_variable_type Utils::getIntVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
{
Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
static const _variable_type types[4] = { VARIABLE_TYPE_INT, VARIABLE_TYPE_IVEC2, VARIABLE_TYPE_IVEC3,
VARIABLE_TYPE_IVEC4 };
if (1 != n_columns)
{
TCU_FAIL("Not implemented");
}
else
{
type = types[n_rows - 1];
}
return type;
}
/** Returns te number of components that variables defined with user-specified type
* support. For matrix types, total amount of values accessible for the type will be
* returned.
*
* @param type Variable type to return the described vale for.
*
* @return As per description or 0 if @param type was not recognized.
*/
unsigned int Utils::getNumberOfComponentsForVariableType(_variable_type type)
{
unsigned int result = 0;
switch (type)
{
case VARIABLE_TYPE_BOOL:
case VARIABLE_TYPE_DOUBLE:
case VARIABLE_TYPE_FLOAT:
case VARIABLE_TYPE_INT:
case VARIABLE_TYPE_UINT:
{
result = 1;
break;
}
case VARIABLE_TYPE_DVEC2:
case VARIABLE_TYPE_IVEC2:
case VARIABLE_TYPE_UVEC2:
case VARIABLE_TYPE_VEC2:
{
result = 2;
break;
}
case VARIABLE_TYPE_DVEC3:
case VARIABLE_TYPE_IVEC3:
case VARIABLE_TYPE_UVEC3:
case VARIABLE_TYPE_VEC3:
{
result = 3;
break;
}
case VARIABLE_TYPE_DVEC4:
case VARIABLE_TYPE_IVEC4:
case VARIABLE_TYPE_UVEC4:
case VARIABLE_TYPE_VEC4:
{
result = 4;
break;
}
case VARIABLE_TYPE_DMAT2:
case VARIABLE_TYPE_MAT2:
{
result = 2 * 2;
break;
}
case VARIABLE_TYPE_DMAT2X3:
case VARIABLE_TYPE_DMAT3X2:
case VARIABLE_TYPE_MAT2X3:
case VARIABLE_TYPE_MAT3X2:
{
result = 2 * 3;
break;
}
case VARIABLE_TYPE_DMAT2X4:
case VARIABLE_TYPE_DMAT4X2:
case VARIABLE_TYPE_MAT2X4:
case VARIABLE_TYPE_MAT4X2:
{
result = 2 * 4;
break;
}
case VARIABLE_TYPE_DMAT3:
case VARIABLE_TYPE_MAT3:
{
result = 3 * 3;
break;
}
case VARIABLE_TYPE_DMAT3X4:
case VARIABLE_TYPE_DMAT4X3:
case VARIABLE_TYPE_MAT3X4:
case VARIABLE_TYPE_MAT4X3:
{
result = 3 * 4;
break;
}
case VARIABLE_TYPE_DMAT4:
case VARIABLE_TYPE_MAT4:
{
result = 4 * 4;
break;
}
default:
{
TCU_FAIL("Unrecognized type");
}
} /* switch (type) */
return result;
}
/** Returns number of columns user-specified matrix variable type describes.
*
* @param type Variable type to use for the query. Only VARIABLE_TYPE_DMAT*
* values are valid.
*
* @return As per description.
**/
unsigned int Utils::getNumberOfColumnsForVariableType(_variable_type type)
{
unsigned int result = 0;
switch (type)
{
case VARIABLE_TYPE_BOOL:
case VARIABLE_TYPE_DOUBLE:
case VARIABLE_TYPE_FLOAT:
case VARIABLE_TYPE_INT:
case VARIABLE_TYPE_UINT:
case VARIABLE_TYPE_DVEC2:
case VARIABLE_TYPE_IVEC2:
case VARIABLE_TYPE_UVEC2:
case VARIABLE_TYPE_VEC2:
case VARIABLE_TYPE_DVEC3:
case VARIABLE_TYPE_IVEC3:
case VARIABLE_TYPE_UVEC3:
case VARIABLE_TYPE_VEC3:
case VARIABLE_TYPE_DVEC4:
case VARIABLE_TYPE_IVEC4:
case VARIABLE_TYPE_UVEC4:
case VARIABLE_TYPE_VEC4:
{
result = 1;
break;
}
case VARIABLE_TYPE_DMAT2:
case VARIABLE_TYPE_DMAT2X3:
case VARIABLE_TYPE_DMAT2X4:
case VARIABLE_TYPE_MAT2:
case VARIABLE_TYPE_MAT2X3:
case VARIABLE_TYPE_MAT2X4:
{
result = 2;
break;
}
case VARIABLE_TYPE_DMAT3:
case VARIABLE_TYPE_DMAT3X2:
case VARIABLE_TYPE_DMAT3X4:
case VARIABLE_TYPE_MAT3:
case VARIABLE_TYPE_MAT3X2:
case VARIABLE_TYPE_MAT3X4:
{
result = 3;
break;
}
case VARIABLE_TYPE_DMAT4:
case VARIABLE_TYPE_DMAT4X2:
case VARIABLE_TYPE_DMAT4X3:
case VARIABLE_TYPE_MAT4:
case VARIABLE_TYPE_MAT4X2:
case VARIABLE_TYPE_MAT4X3:
{
result = 4;
break;
}
default:
{
TCU_FAIL("Unrecognized type");
}
} /* switch (type) */
return result;
}
/** Returns maximum number of uniform locations taken by user-specified double-precision
* variable type.
*
* @param type Variable type to use for the query. Only VARIABLE_TYPE_D* values are valid.
*
* @return As per description.
**/
unsigned int Utils::getNumberOfLocationsUsedByDoublePrecisionVariableType(_variable_type type)
{
unsigned int result = 0;
switch (type)
{
case VARIABLE_TYPE_DOUBLE:
result = 1;
break;
case VARIABLE_TYPE_DVEC2:
result = 1;
break;
case VARIABLE_TYPE_DVEC3:
result = 2;
break;
case VARIABLE_TYPE_DVEC4:
result = 2;
break;
case VARIABLE_TYPE_DMAT2:
result = 2;
break;
case VARIABLE_TYPE_DMAT2X3:
result = 6;
break;
case VARIABLE_TYPE_DMAT2X4:
result = 8;
break;
case VARIABLE_TYPE_DMAT3:
result = 6;
break;
case VARIABLE_TYPE_DMAT3X2:
result = 4;
break;
case VARIABLE_TYPE_DMAT3X4:
result = 8;
break;
case VARIABLE_TYPE_DMAT4:
result = 8;
break;
case VARIABLE_TYPE_DMAT4X2:
result = 4;
break;
case VARIABLE_TYPE_DMAT4X3:
result = 6;
break;
default:
{
TCU_FAIL("Unrecognized type");
}
} /* switch (type) */
return result;
}
/** Get number of rows for given variable type
*
* @param type Type of variable
*
* @return Number of rows
**/
unsigned int Utils::getNumberOfRowsForVariableType(_variable_type type)
{
unsigned int result = 0;
switch (type)
{
case VARIABLE_TYPE_BOOL:
case VARIABLE_TYPE_DOUBLE:
case VARIABLE_TYPE_FLOAT:
case VARIABLE_TYPE_INT:
case VARIABLE_TYPE_UINT:
{
result = 1;
break;
}
case VARIABLE_TYPE_DVEC2:
case VARIABLE_TYPE_IVEC2:
case VARIABLE_TYPE_UVEC2:
case VARIABLE_TYPE_VEC2:
case VARIABLE_TYPE_DMAT2:
case VARIABLE_TYPE_DMAT3X2:
case VARIABLE_TYPE_DMAT4X2:
case VARIABLE_TYPE_MAT2:
case VARIABLE_TYPE_MAT3X2:
case VARIABLE_TYPE_MAT4X2:
{
result = 2;
break;
}
case VARIABLE_TYPE_DVEC3:
case VARIABLE_TYPE_IVEC3:
case VARIABLE_TYPE_UVEC3:
case VARIABLE_TYPE_VEC3:
case VARIABLE_TYPE_DMAT2X3:
case VARIABLE_TYPE_DMAT3:
case VARIABLE_TYPE_DMAT4X3:
case VARIABLE_TYPE_MAT2X3:
case VARIABLE_TYPE_MAT3:
case VARIABLE_TYPE_MAT4X3:
{
result = 3;
break;
}
case VARIABLE_TYPE_DVEC4:
case VARIABLE_TYPE_IVEC4:
case VARIABLE_TYPE_UVEC4:
case VARIABLE_TYPE_VEC4:
case VARIABLE_TYPE_DMAT2X4:
case VARIABLE_TYPE_DMAT3X4:
case VARIABLE_TYPE_DMAT4:
case VARIABLE_TYPE_MAT2X4:
case VARIABLE_TYPE_MAT3X4:
case VARIABLE_TYPE_MAT4:
{
result = 4;
break;
}
default:
{
TCU_FAIL("Unrecognized type");
}
} /* switch (type) */
return result;
}
/** Returns variable type of a matrix constructed by multiplying two matrices.
*
* @param type_matrix_a L-side matrix type.
* @param type_matrix_b R-side matrix type.
*
* @return As per description.
**/
Utils::_variable_type Utils::getPostMatrixMultiplicationVariableType(_variable_type type_matrix_a,
_variable_type type_matrix_b)
{
const unsigned int n_a_columns = Utils::getNumberOfColumnsForVariableType(type_matrix_a);
const unsigned int n_a_components = Utils::getNumberOfComponentsForVariableType(type_matrix_a);
const unsigned int n_a_rows = n_a_components / n_a_columns;
const unsigned int n_b_columns = Utils::getNumberOfColumnsForVariableType(type_matrix_b);
const unsigned int n_result_columns = n_b_columns;
const unsigned int n_result_rows = n_a_rows;
Utils::_variable_type result;
switch (n_result_columns)
{
case 2:
{
switch (n_result_rows)
{
case 2:
result = VARIABLE_TYPE_DMAT2;
break;
case 3:
result = VARIABLE_TYPE_DMAT2X3;
break;
case 4:
result = VARIABLE_TYPE_DMAT2X4;
break;
default:
{
TCU_FAIL("Unrecognized amount of rows in result variable");
}
} /* switch (n_result_rows) */
break;
} /* case 2: */
case 3:
{
switch (n_result_rows)
{
case 2:
result = VARIABLE_TYPE_DMAT3X2;
break;
case 3:
result = VARIABLE_TYPE_DMAT3;
break;
case 4:
result = VARIABLE_TYPE_DMAT3X4;
break;
default:
{
TCU_FAIL("Unrecognized amount of rows in result variable");
}
} /* switch (n_result_rows) */
break;
} /* case 3: */
case 4:
{
switch (n_result_rows)
{
case 2:
result = VARIABLE_TYPE_DMAT4X2;
break;
case 3:
result = VARIABLE_TYPE_DMAT4X3;
break;
case 4:
result = VARIABLE_TYPE_DMAT4;
break;
default:
{
TCU_FAIL("Unrecognized amount of rows in result variable");
}
} /* switch (n_result_rows) */
break;
} /* case 4: */
default:
{
TCU_FAIL("Unrecognized amount of columns in result variable");
}
} /* switch (n_result_columns) */
/* Done */
return result;
}
/** Returns a string holding the value represented by user-provided variable, for which
* the data are represented in @param type variable type.
*
* @return As per description.
**/
std::string Utils::getStringForVariableTypeValue(_variable_type type, const unsigned char* data_ptr)
{
std::stringstream result_sstream;
switch (type)
{
case VARIABLE_TYPE_BOOL:
result_sstream << *((bool*)data_ptr);
break;
case VARIABLE_TYPE_DOUBLE:
result_sstream << *((double*)data_ptr);
break;
case VARIABLE_TYPE_FLOAT:
result_sstream << *((float*)data_ptr);
break;
case VARIABLE_TYPE_INT:
result_sstream << *((int*)data_ptr);
break;
case VARIABLE_TYPE_UINT:
result_sstream << *((unsigned int*)data_ptr);
break;
default:
{
TCU_FAIL("Unrecognized variable type requested");
}
} /* switch (type) */
return result_sstream.str();
}
/** Returns variable type of a transposed matrix of user-specified variable type.
*
* @param type Variable type of the matrix to be transposed.
*
* @return Transposed matrix variable type.
**/
Utils::_variable_type Utils::getTransposedMatrixVariableType(Utils::_variable_type type)
{
Utils::_variable_type result;
switch (type)
{
case VARIABLE_TYPE_DMAT2:
result = VARIABLE_TYPE_DMAT2;
break;
case VARIABLE_TYPE_DMAT2X3:
result = VARIABLE_TYPE_DMAT3X2;
break;
case VARIABLE_TYPE_DMAT2X4:
result = VARIABLE_TYPE_DMAT4X2;
break;
case VARIABLE_TYPE_DMAT3:
result = VARIABLE_TYPE_DMAT3;
break;
case VARIABLE_TYPE_DMAT3X2:
result = VARIABLE_TYPE_DMAT2X3;
break;
case VARIABLE_TYPE_DMAT3X4:
result = VARIABLE_TYPE_DMAT4X3;
break;
case VARIABLE_TYPE_DMAT4:
result = VARIABLE_TYPE_DMAT4;
break;
case VARIABLE_TYPE_DMAT4X2:
result = VARIABLE_TYPE_DMAT2X4;
break;
case VARIABLE_TYPE_DMAT4X3:
result = VARIABLE_TYPE_DMAT3X4;
break;
default:
{
TCU_FAIL("Unrecognized double-precision matrix variable type.");
}
} /* switch (type) */
return result;
}
/** Get _variable_type representing unsigned integer type with given dimmensions
*
* @param n_columns Number of columns
* @param n_row Number of rows
*
* @return Corresponding _variable_type
**/
Utils::_variable_type Utils::getUintVariableType(glw::GLuint n_columns, glw::GLuint n_rows)
{
Utils::_variable_type type = VARIABLE_TYPE_UNKNOWN;
static const _variable_type types[4] = { VARIABLE_TYPE_UINT, VARIABLE_TYPE_UVEC2, VARIABLE_TYPE_UVEC3,
VARIABLE_TYPE_UVEC4 };
if (1 != n_columns)
{
TCU_FAIL("Not implemented");
}
else
{
type = types[n_rows - 1];
}
return type;
}
/** Returns a literal corresponding to a GLSL keyword describing user-specified
* variable type.
*
* @param type Variable type to use for the query.
*
* @return Requested GLSL keyword or [?] if @param type was not recognized.
**/
std::string Utils::getVariableTypeString(_variable_type type)
{
std::string result = "[?]";
switch (type)
{
case VARIABLE_TYPE_BOOL:
result = "bool";
break;
case VARIABLE_TYPE_BVEC2:
result = "bvec2";
break;
case VARIABLE_TYPE_BVEC3:
result = "bvec3";
break;
case VARIABLE_TYPE_BVEC4:
result = "bvec4";
break;
case VARIABLE_TYPE_DOUBLE:
result = "double";
break;
case VARIABLE_TYPE_DMAT2:
result = "dmat2";
break;
case VARIABLE_TYPE_DMAT2X3:
result = "dmat2x3";
break;
case VARIABLE_TYPE_DMAT2X4:
result = "dmat2x4";
break;
case VARIABLE_TYPE_DMAT3:
result = "dmat3";
break;
case VARIABLE_TYPE_DMAT3X2:
result = "dmat3x2";
break;
case VARIABLE_TYPE_DMAT3X4:
result = "dmat3x4";
break;
case VARIABLE_TYPE_DMAT4:
result = "dmat4";
break;
case VARIABLE_TYPE_DMAT4X2:
result = "dmat4x2";
break;
case VARIABLE_TYPE_DMAT4X3:
result = "dmat4x3";
break;
case VARIABLE_TYPE_DVEC2:
result = "dvec2";
break;
case VARIABLE_TYPE_DVEC3:
result = "dvec3";
break;
case VARIABLE_TYPE_DVEC4:
result = "dvec4";
break;
case VARIABLE_TYPE_FLOAT:
result = "float";
break;
case VARIABLE_TYPE_INT:
result = "int";
break;
case VARIABLE_TYPE_IVEC2:
result = "ivec2";
break;
case VARIABLE_TYPE_IVEC3:
result = "ivec3";
break;
case VARIABLE_TYPE_IVEC4:
result = "ivec4";
break;
case VARIABLE_TYPE_MAT2:
result = "mat2";
break;
case VARIABLE_TYPE_MAT2X3:
result = "mat2x3";
break;
case VARIABLE_TYPE_MAT2X4:
result = "mat2x4";
break;
case VARIABLE_TYPE_MAT3:
result = "mat3";
break;
case VARIABLE_TYPE_MAT3X2:
result = "mat3x2";
break;
case VARIABLE_TYPE_MAT3X4:
result = "mat3x4";
break;
case VARIABLE_TYPE_MAT4:
result = "mat4";
break;
case VARIABLE_TYPE_MAT4X2:
result = "mat4x2";
break;
case VARIABLE_TYPE_MAT4X3:
result = "mat4x3";
break;
case VARIABLE_TYPE_UINT:
result = "uint";
break;
case VARIABLE_TYPE_UVEC2:
result = "uvec2";
break;
case VARIABLE_TYPE_UVEC3:
result = "uvec3";
break;
case VARIABLE_TYPE_UVEC4:
result = "uvec4";
break;
case VARIABLE_TYPE_VEC2:
result = "vec2";
break;
case VARIABLE_TYPE_VEC3:
result = "vec3";
break;
case VARIABLE_TYPE_VEC4:
result = "vec4";
break;
default:
{
TCU_FAIL("Unrecognized variable type");
}
} /* switch (type) */
return result;
}
/** Check if GL context meets version requirements
*
* @param gl Functions
* @param required_major Minimum required MAJOR_VERSION
* @param required_minor Minimum required MINOR_VERSION
*
* @return true if GL context version is at least as requested, false otherwise
**/
bool Utils::isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor)
{
glw::GLint major = 0;
glw::GLint minor = 0;
gl.getIntegerv(GL_MAJOR_VERSION, &major);
gl.getIntegerv(GL_MINOR_VERSION, &minor);
GLU_EXPECT_NO_ERROR(gl.getError(), "GetIntegerv");
if (major > required_major)
{
/* Major is higher than required one */
return true;
}
else if (major == required_major)
{
if (minor >= required_minor)
{
/* Major is equal to required one */
/* Minor is higher than or equal to required one */
return true;
}
else
{
/* Major is equal to required one */
/* Minor is lower than required one */
return false;
}
}
else
{
/* Major is lower than required one */
return false;
}
}
/** Tells whether user-specified variable type corresponds to a matrix type.
*
* @param type Variable type to use for the query.
*
* @return true if the variable type describes a matrix, false otherwise.
**/
bool Utils::isMatrixVariableType(_variable_type type)
{
return (type == VARIABLE_TYPE_MAT2 || type == VARIABLE_TYPE_MAT3 || type == VARIABLE_TYPE_MAT4 ||
type == VARIABLE_TYPE_MAT2X3 || type == VARIABLE_TYPE_MAT2X4 || type == VARIABLE_TYPE_MAT3X2 ||
type == VARIABLE_TYPE_MAT3X4 || type == VARIABLE_TYPE_MAT4X2 || type == VARIABLE_TYPE_MAT4X3 ||
type == VARIABLE_TYPE_DMAT2 || type == VARIABLE_TYPE_DMAT3 || type == VARIABLE_TYPE_DMAT4 ||
type == VARIABLE_TYPE_DMAT2X3 || type == VARIABLE_TYPE_DMAT2X4 || type == VARIABLE_TYPE_DMAT3X2 ||
type == VARIABLE_TYPE_DMAT3X4 || type == VARIABLE_TYPE_DMAT4X2 || type == VARIABLE_TYPE_DMAT4X3);
}
/** Tells whether user-specified variable type is scalar.
*
* @return true if @param type is a scalar variable type, false otherwise.
**/
bool Utils::isScalarVariableType(_variable_type type)
{
bool result = false;
switch (type)
{
case VARIABLE_TYPE_BOOL:
result = true;
break;
case VARIABLE_TYPE_DOUBLE:
result = true;
break;
case VARIABLE_TYPE_FLOAT:
result = true;
break;
case VARIABLE_TYPE_INT:
result = true;
break;
case VARIABLE_TYPE_UINT:
result = true;
break;
default:
break;
} /* switch (type) */
return result;
}
/** Replace first occurance of <token> with <text> in <string> starting at <search_posistion>
*
* @param token Token string
* @param search_position Position at which find will start, it is updated to position at which replaced text ends
* @param text String that will be used as replacement for <token>
* @param string String to work on
**/
void Utils::replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text,
std::string& string)
{
const size_t text_length = strlen(text);
const size_t token_length = strlen(token);
const size_t token_position = string.find(token, search_position);
string.replace(token_position, token_length, text, text_length);
search_position = token_position + text_length;
}
/** Constructor.
*
* @param context Rendering context.
*
**/
GPUShaderFP64Test1::GPUShaderFP64Test1(deqp::Context& context)
: TestCase(context, "errors", "Verifies that various erroneous conditions related to double-precision "
"float uniform support & glUniform*() / glUniformMatrix*() API "
" are reported correctly.")
, m_has_test_passed(true)
, m_po_bool_arr_uniform_location(0)
, m_po_bool_uniform_location(0)
, m_po_bvec2_arr_uniform_location(0)
, m_po_bvec2_uniform_location(0)
, m_po_bvec3_arr_uniform_location(0)
, m_po_bvec3_uniform_location(0)
, m_po_bvec4_arr_uniform_location(0)
, m_po_bvec4_uniform_location(0)
, m_po_dmat2_arr_uniform_location(0)
, m_po_dmat2_uniform_location(0)
, m_po_dmat2x3_arr_uniform_location(0)
, m_po_dmat2x3_uniform_location(0)
, m_po_dmat2x4_arr_uniform_location(0)
, m_po_dmat2x4_uniform_location(0)
, m_po_dmat3_arr_uniform_location(0)
, m_po_dmat3_uniform_location(0)
, m_po_dmat3x2_arr_uniform_location(0)
, m_po_dmat3x2_uniform_location(0)
, m_po_dmat3x4_arr_uniform_location(0)
, m_po_dmat3x4_uniform_location(0)
, m_po_dmat4_arr_uniform_location(0)
, m_po_dmat4_uniform_location(0)
, m_po_dmat4x2_arr_uniform_location(0)
, m_po_dmat4x2_uniform_location(0)
, m_po_dmat4x3_arr_uniform_location(0)
, m_po_dmat4x3_uniform_location(0)
, m_po_double_arr_uniform_location(0)
, m_po_double_uniform_location(0)
, m_po_dvec2_arr_uniform_location(0)
, m_po_dvec2_uniform_location(0)
, m_po_dvec3_arr_uniform_location(0)
, m_po_dvec3_uniform_location(0)
, m_po_dvec4_arr_uniform_location(0)
, m_po_dvec4_uniform_location(0)
, m_po_float_arr_uniform_location(0)
, m_po_float_uniform_location(0)
, m_po_int_arr_uniform_location(0)
, m_po_int_uniform_location(0)
, m_po_ivec2_arr_uniform_location(0)
, m_po_ivec2_uniform_location(0)
, m_po_ivec3_arr_uniform_location(0)
, m_po_ivec3_uniform_location(0)
, m_po_ivec4_arr_uniform_location(0)
, m_po_ivec4_uniform_location(0)
, m_po_sampler_uniform_location(0)
, m_po_uint_arr_uniform_location(0)
, m_po_uint_uniform_location(0)
, m_po_uvec2_arr_uniform_location(0)
, m_po_uvec2_uniform_location(0)
, m_po_uvec3_arr_uniform_location(0)
, m_po_uvec3_uniform_location(0)
, m_po_uvec4_arr_uniform_location(0)
, m_po_uvec4_uniform_location(0)
, m_po_vec2_arr_uniform_location(0)
, m_po_vec2_uniform_location(0)
, m_po_vec3_arr_uniform_location(0)
, m_po_vec3_uniform_location(0)
, m_po_vec4_arr_uniform_location(0)
, m_po_vec4_uniform_location(0)
, m_po_id(0)
, m_vs_id(0)
{
/* Left blank intentionally */
}
/** Deinitializes all GL objects that may have been created during
* test execution.
**/
void GPUShaderFP64Test1::deinit()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
if (m_po_id != 0)
{
gl.deleteProgram(m_po_id);
m_po_id = 0;
}
if (m_vs_id != 0)
{
gl.deleteShader(m_vs_id);
m_vs_id = 0;
}
}
/** Returns a string describing GL API function represented by user-provided enum.
*
* @param func Uniform function to return the string for.
*
* @return As per description. [?] will be returned if the function was not recognized.
**/
const char* GPUShaderFP64Test1::getUniformFunctionString(_uniform_function func)
{
const char* result = "[?]";
switch (func)
{
case UNIFORM_FUNCTION_1D:
result = "glUniform1d";
break;
case UNIFORM_FUNCTION_1DV:
result = "glUniform1dv";
break;
case UNIFORM_FUNCTION_2D:
result = "glUniform2d";
break;
case UNIFORM_FUNCTION_2DV:
result = "glUniform2dv";
break;
case UNIFORM_FUNCTION_3D:
result = "glUniform3d";
break;
case UNIFORM_FUNCTION_3DV:
result = "glUniform3dv";
break;
case UNIFORM_FUNCTION_4D:
result = "glUniform4d";
break;
case UNIFORM_FUNCTION_4DV:
result = "glUniform4dv";
break;
case UNIFORM_FUNCTION_MATRIX2DV:
result = "glUniformMatrix2dv";
break;
case UNIFORM_FUNCTION_MATRIX2X3DV:
result = "glUniformMatrix2x3dv";
break;
case UNIFORM_FUNCTION_MATRIX2X4DV:
result = "glUniformMatrix2x4dv";
break;
case UNIFORM_FUNCTION_MATRIX3DV:
result = "glUniformMatrix3dv";
break;
case UNIFORM_FUNCTION_MATRIX3X2DV:
result = "glUniformMatrix3x2dv";
break;
case UNIFORM_FUNCTION_MATRIX3X4DV:
result = "glUniformMatrix3x4dv";
break;
case UNIFORM_FUNCTION_MATRIX4DV:
result = "glUniformMatrix4dv";
break;
case UNIFORM_FUNCTION_MATRIX4X2DV:
result = "glUniformMatrix4x2dv";
break;
case UNIFORM_FUNCTION_MATRIX4X3DV:
result = "glUniformMatrix4x3dv";
break;
default:
break;
}
return result;
}
/** Returns name of an uniform bound to user-provided location.
*
* @param location Location of the uniform to return the name for.
*
* @return As per description. [?] will be returned if the location was not
* recognized.
**/
const char* GPUShaderFP64Test1::getUniformNameForLocation(glw::GLint location)
{
const char* result = "[?]";
if (location == m_po_bool_arr_uniform_location)
result = "uniform_bool_arr";
else if (location == m_po_bool_uniform_location)
result = "uniform_bool";
else if (location == m_po_bvec2_arr_uniform_location)
result = "uniform_bvec2_arr";
else if (location == m_po_bvec2_uniform_location)
result = "uniform_bvec2";
else if (location == m_po_bvec3_arr_uniform_location)
result = "uniform_bvec3_arr";
else if (location == m_po_bvec3_uniform_location)
result = "uniform_bvec3";
else if (location == m_po_bvec4_arr_uniform_location)
result = "uniform_bvec4_arr";
else if (location == m_po_bvec4_uniform_location)
result = "uniform_bvec4";
else if (location == m_po_dmat2_arr_uniform_location)
result = "uniform_dmat2_arr";
else if (location == m_po_dmat2_uniform_location)
result = "uniform_dmat2";
else if (location == m_po_dmat2x3_arr_uniform_location)
result = "uniform_dmat2x3_arr";
else if (location == m_po_dmat2x3_uniform_location)
result = "uniform_dmat2x3";
else if (location == m_po_dmat2x4_arr_uniform_location)
result = "uniform_dmat2x4_arr";
else if (location == m_po_dmat2x4_uniform_location)
result = "uniform_dmat2x4";
else if (location == m_po_dmat3_arr_uniform_location)
result = "uniform_dmat3_arr";
else if (location == m_po_dmat3_uniform_location)
result = "uniform_dmat3";
else if (location == m_po_dmat3x2_arr_uniform_location)
result = "uniform_dmat3x2_arr";
else if (location == m_po_dmat3x2_uniform_location)
result = "uniform_dmat3x2";
else if (location == m_po_dmat3x4_arr_uniform_location)
result = "uniform_dmat3x4_arr";
else if (location == m_po_dmat3x4_uniform_location)
result = "uniform_dmat3x4";
else if (location == m_po_dmat4_arr_uniform_location)
result = "uniform_dmat4_arr";
else if (location == m_po_dmat4_uniform_location)
result = "uniform_dmat4";
else if (location == m_po_dmat4x2_arr_uniform_location)
result = "uniform_dmat4x2_arr";
else if (location == m_po_dmat4x2_uniform_location)
result = "uniform_dmat4x2";
else if (location == m_po_dmat4x3_arr_uniform_location)
result = "uniform_dmat4x3_arr";
else if (location == m_po_dmat4x3_uniform_location)
result = "uniform_dmat4x3";
else if (location == m_po_double_arr_uniform_location)
result = "uniform_double_arr";
else if (location == m_po_double_uniform_location)
result = "uniform_double";
else if (location == m_po_dvec2_arr_uniform_location)
result = "uniform_dvec2_arr";
else if (location == m_po_dvec2_uniform_location)
result = "uniform_dvec2";
else if (location == m_po_dvec3_arr_uniform_location)
result = "uniform_dvec3_arr";
else if (location == m_po_dvec3_uniform_location)
result = "uniform_dvec3";
else if (location == m_po_dvec4_arr_uniform_location)
result = "uniform_dvec4_arr";
else if (location == m_po_dvec4_uniform_location)
result = "uniform_dvec4";
else if (location == m_po_float_arr_uniform_location)
result = "uniform_float_arr";
else if (location == m_po_float_uniform_location)
result = "uniform_float";
else if (location == m_po_int_arr_uniform_location)
result = "uniform_int_arr";
else if (location == m_po_int_uniform_location)
result = "uniform_int";
else if (location == m_po_ivec2_arr_uniform_location)
result = "uniform_ivec2_arr";
else if (location == m_po_ivec2_uniform_location)
result = "uniform_ivec2";
else if (location == m_po_ivec3_arr_uniform_location)
result = "uniform_ivec3_arr";
else if (location == m_po_ivec3_uniform_location)
result = "uniform_ivec3";
else if (location == m_po_ivec4_arr_uniform_location)
result = "uniform_ivec4_arr";
else if (location == m_po_ivec4_uniform_location)
result = "uniform_ivec4";
else if (location == m_po_uint_arr_uniform_location)
result = "uniform_uint_arr";
else if (location == m_po_uint_uniform_location)
result = "uniform_uint";
else if (location == m_po_uvec2_arr_uniform_location)
result = "uniform_uvec2_arr";
else if (location == m_po_uvec2_uniform_location)
result = "uniform_uvec2";
else if (location == m_po_uvec3_arr_uniform_location)
result = "uniform_uvec3_arr";
else if (location == m_po_uvec3_uniform_location)
result = "uniform_uvec3";
else if (location == m_po_uvec4_arr_uniform_location)
result = "uniform_uvec4_arr";
else if (location == m_po_uvec4_uniform_location)
result = "uniform_uvec4";
else if (location == m_po_vec2_arr_uniform_location)
result = "uniform_vec2_arr";
else if (location == m_po_vec2_uniform_location)
result = "uniform_vec2";
else if (location == m_po_vec3_arr_uniform_location)
result = "uniform_vec3_arr";
else if (location == m_po_vec3_uniform_location)
result = "uniform_vec3";
else if (location == m_po_vec4_arr_uniform_location)
result = "uniform_vec4_arr";
else if (location == m_po_vec4_uniform_location)
result = "uniform_vec4";
return result;
}
/** Initializes all GL objects required to run the test. Also extracts locations of all
* uniforms used by the test.
*
* This function can throw a TestError exception if the implementation misbehaves.
*/
void GPUShaderFP64Test1::initTest()
{
glw::GLint compile_status = GL_FALSE;
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
glw::GLint link_status = GL_FALSE;
/* Set up a program object using all new double-precision types */
const char* vs_body =
"#version 400\n"
"\n"
"uniform bool uniform_bool;\n"
"uniform bvec2 uniform_bvec2;\n"
"uniform bvec3 uniform_bvec3;\n"
"uniform bvec4 uniform_bvec4;\n"
"uniform dmat2 uniform_dmat2;\n"
"uniform dmat2x3 uniform_dmat2x3;\n"
"uniform dmat2x4 uniform_dmat2x4;\n"
"uniform dmat3 uniform_dmat3;\n"
"uniform dmat3x2 uniform_dmat3x2;\n"
"uniform dmat3x4 uniform_dmat3x4;\n"
"uniform dmat4 uniform_dmat4;\n"
"uniform dmat4x2 uniform_dmat4x2;\n"
"uniform dmat4x3 uniform_dmat4x3;\n"
"uniform double uniform_double;\n"
"uniform dvec2 uniform_dvec2;\n"
"uniform dvec3 uniform_dvec3;\n"
"uniform dvec4 uniform_dvec4;\n"
"uniform float uniform_float;\n"
"uniform int uniform_int;\n"
"uniform ivec2 uniform_ivec2;\n"
"uniform ivec3 uniform_ivec3;\n"
"uniform ivec4 uniform_ivec4;\n"
"uniform sampler2D uniform_sampler;\n"
"uniform uint uniform_uint;\n"
"uniform uvec2 uniform_uvec2;\n"
"uniform uvec3 uniform_uvec3;\n"
"uniform uvec4 uniform_uvec4;\n"
"uniform vec2 uniform_vec2;\n"
"uniform vec3 uniform_vec3;\n"
"uniform vec4 uniform_vec4;\n"
"uniform bool uniform_bool_arr [2];\n"
"uniform bvec2 uniform_bvec2_arr [2];\n"
"uniform bvec3 uniform_bvec3_arr [2];\n"
"uniform bvec4 uniform_bvec4_arr [2];\n"
"uniform dmat2 uniform_dmat2_arr [2];\n"
"uniform dmat2x3 uniform_dmat2x3_arr[2];\n"
"uniform dmat2x4 uniform_dmat2x4_arr[2];\n"
"uniform dmat3 uniform_dmat3_arr [2];\n"
"uniform dmat3x2 uniform_dmat3x2_arr[2];\n"
"uniform dmat3x4 uniform_dmat3x4_arr[2];\n"
"uniform dmat4 uniform_dmat4_arr [2];\n"
"uniform dmat4x2 uniform_dmat4x2_arr[2];\n"
"uniform dmat4x3 uniform_dmat4x3_arr[2];\n"
"uniform double uniform_double_arr [2];\n"
"uniform dvec2 uniform_dvec2_arr [2];\n"
"uniform dvec3 uniform_dvec3_arr [2];\n"
"uniform dvec4 uniform_dvec4_arr [2];\n"
"uniform float uniform_float_arr [2];\n"
"uniform int uniform_int_arr [2];\n"
"uniform ivec2 uniform_ivec2_arr [2];\n"
"uniform ivec3 uniform_ivec3_arr [2];\n"
"uniform ivec4 uniform_ivec4_arr [2];\n"
"uniform uint uniform_uint_arr [2];\n"
"uniform uvec2 uniform_uvec2_arr [2];\n"
"uniform uvec3 uniform_uvec3_arr [2];\n"
"uniform uvec4 uniform_uvec4_arr [2];\n"
"uniform vec2 uniform_vec2_arr [2];\n"
"uniform vec3 uniform_vec3_arr [2];\n"
"uniform vec4 uniform_vec4_arr [2];\n"
"\n"
"void main()\n"
"{\n"
" gl_Position = vec4(0) + texture(uniform_sampler, vec2(0) );\n"
"\n"
" if (uniform_bool && uniform_bvec2.y && uniform_bvec3.z && uniform_bvec4.w &&\n"
" uniform_bool_arr[1] && uniform_bvec2_arr[1].y && uniform_bvec3_arr[1].z && uniform_bvec4_arr[1].w)\n"
" {\n"
" double sum = uniform_dmat2 [0].x + uniform_dmat2x3 [0].x + uniform_dmat2x4 [0].x +\n"
" uniform_dmat3 [0].x + uniform_dmat3x2 [0].x + uniform_dmat3x4 [0].x +\n"
" uniform_dmat4 [0].x + uniform_dmat4x2 [0].x + uniform_dmat4x3 [0].x +\n"
" uniform_dmat2_arr[0][0].x + uniform_dmat2x3_arr[0][0].x + uniform_dmat2x4_arr[0][0].x +\n"
" uniform_dmat3_arr[0][0].x + uniform_dmat3x2_arr[0][0].x + uniform_dmat3x4_arr[0][0].x +\n"
" uniform_dmat4_arr[0][0].x + uniform_dmat4x2_arr[0][0].x + uniform_dmat4x3_arr[0][0].x +\n"
" uniform_double + uniform_double_arr [0] +\n"
" uniform_dvec2.x + uniform_dvec3.x + uniform_dvec4.x +\n"
" uniform_dvec2_arr[0].x + uniform_dvec3_arr[0].x + uniform_dvec4_arr[0].x;\n"
" int sum2 = uniform_int + uniform_ivec2.x + uniform_ivec3.x +\n"
" uniform_ivec4.x + uniform_ivec2_arr[0].x + uniform_ivec3_arr[0].x +\n"
" uniform_ivec4_arr[0].x + uniform_int_arr[0];\n"
" uint sum3 = uniform_uint + uniform_uvec2.x + uniform_uvec3.x +\n"
" uniform_uvec4.x + uniform_uint_arr[0] + uniform_uvec2_arr[0].x +\n"
" uniform_uvec3_arr[0].x + uniform_uvec4_arr[0].x;\n"
" float sum4 = uniform_float + uniform_float_arr[0] + \n"
" uniform_vec2.x + uniform_vec2_arr[0].x + \n"
" uniform_vec3.x + uniform_vec3_arr[0].x + \n"
" uniform_vec4.x + uniform_vec4_arr[0].x;\n"
"\n"
" if (sum * sum4 > intBitsToFloat(sum2) * uintBitsToFloat(sum3) )\n"
" {\n"
" gl_Position = vec4(1);\n"
" }\n"
" }\n"
"}\n";
m_po_id = gl.createProgram();
GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateProgram() call failed.");
m_vs_id = gl.createShader(GL_VERTEX_SHADER);
GLU_EXPECT_NO_ERROR(gl.getError(), "glCreateShader() call failed.");
gl.shaderSource(m_vs_id, 1 /* count */, &vs_body, DE_NULL /* length */);
GLU_EXPECT_NO_ERROR(gl.getError(), "glShaderSource() call failed.");
gl.compileShader(m_vs_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glCompileShader() call failed.");
gl.getShaderiv(m_vs_id, GL_COMPILE_STATUS, &compile_status);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetShaderiv() call failed.");
if (compile_status != GL_TRUE)
{
TCU_FAIL("Shader compilation failed.");
}
gl.attachShader(m_po_id, m_vs_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glAttachShader() call failed.");
gl.linkProgram(m_po_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glLinkProgram() call failed.");
gl.getProgramiv(m_po_id, GL_LINK_STATUS, &link_status);
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetProgramiv() call failed.");
if (link_status != GL_TRUE)
{
TCU_FAIL("Program linking failed.");
}
m_po_bool_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bool_arr[0]");
m_po_bool_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bool");
m_po_bvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec2_arr[0]");
m_po_bvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec2");
m_po_bvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec3_arr[0]");
m_po_bvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec3");
m_po_bvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec4_arr[0]");
m_po_bvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_bvec4");
m_po_dmat2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2_arr[0]");
m_po_dmat2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2");
m_po_dmat2x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x3_arr[0]");
m_po_dmat2x3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x3");
m_po_dmat2x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x4_arr[0]");
m_po_dmat2x4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat2x4");
m_po_dmat3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3_arr[0]");
m_po_dmat3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3");
m_po_dmat3x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x2_arr[0]");
m_po_dmat3x2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x2");
m_po_dmat3x4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x4_arr[0]");
m_po_dmat3x4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat3x4");
m_po_dmat4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4_arr[0]");
m_po_dmat4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4");
m_po_dmat4x2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x2_arr[0]");
m_po_dmat4x2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x2");
m_po_dmat4x3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x3_arr[0]");
m_po_dmat4x3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dmat4x3");
m_po_double_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_double_arr[0]");
m_po_double_uniform_location = gl.getUniformLocation(m_po_id, "uniform_double");
m_po_dvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec2_arr[0]");
m_po_dvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec2");
m_po_dvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec3_arr[0]");
m_po_dvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec3");
m_po_dvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec4_arr[0]");
m_po_dvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_dvec4");
m_po_float_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_float_arr[0]");
m_po_float_uniform_location = gl.getUniformLocation(m_po_id, "uniform_float");
m_po_int_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_int_arr[0]");
m_po_int_uniform_location = gl.getUniformLocation(m_po_id, "uniform_int");
m_po_ivec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec2_arr[0]");
m_po_ivec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec2");
m_po_ivec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec3_arr[0]");
m_po_ivec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec3");
m_po_ivec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec4_arr[0]");
m_po_ivec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_ivec4");
m_po_sampler_uniform_location = gl.getUniformLocation(m_po_id, "uniform_sampler");
m_po_uint_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uint_arr[0]");
m_po_uint_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uint");
m_po_uvec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec2_arr[0]");
m_po_uvec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec2");
m_po_uvec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec3_arr[0]");
m_po_uvec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec3");
m_po_uvec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec4_arr[0]");
m_po_uvec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_uvec4");
m_po_vec2_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec2_arr[0]");
m_po_vec2_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec2");
m_po_vec3_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec3_arr[0]");
m_po_vec3_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec3");
m_po_vec4_arr_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec4_arr[0]");
m_po_vec4_uniform_location = gl.getUniformLocation(m_po_id, "uniform_vec4");
GLU_EXPECT_NO_ERROR(gl.getError(), "glGetUniformLocation() call(s) failed.");
if (m_po_bool_arr_uniform_location == -1 || m_po_bool_uniform_location == -1 ||
m_po_bvec2_arr_uniform_location == -1 || m_po_bvec2_uniform_location == -1 ||
m_po_bvec3_arr_uniform_location == -1 || m_po_bvec3_uniform_location == -1 ||
m_po_bvec4_arr_uniform_location == -1 || m_po_bvec4_uniform_location == -1 ||
m_po_dmat2_arr_uniform_location == -1 || m_po_dmat2_uniform_location == -1 ||
m_po_dmat2x3_arr_uniform_location == -1 || m_po_dmat2x3_uniform_location == -1 ||
m_po_dmat2x4_arr_uniform_location == -1 || m_po_dmat2x4_uniform_location == -1 ||
m_po_dmat3_arr_uniform_location == -1 || m_po_dmat3_uniform_location == -1 ||
m_po_dmat3x2_arr_uniform_location == -1 || m_po_dmat3x2_uniform_location == -1 ||
m_po_dmat3x4_arr_uniform_location == -1 || m_po_dmat3x4_uniform_location == -1 ||
m_po_dmat4_arr_uniform_location == -1 || m_po_dmat4_uniform_location == -1 ||
m_po_dmat4x2_arr_uniform_location == -1 || m_po_dmat4x2_uniform_location == -1 ||
m_po_dmat4x3_arr_uniform_location == -1 || m_po_dmat4x3_uniform_location == -1 ||
m_po_double_arr_uniform_location == -1 || m_po_double_uniform_location == -1 ||
m_po_dvec2_arr_uniform_location == -1 || m_po_dvec2_uniform_location == -1 ||
m_po_dvec3_arr_uniform_location == -1 || m_po_dvec3_uniform_location == -1 ||
m_po_dvec4_arr_uniform_location == -1 || m_po_dvec4_uniform_location == -1 ||
m_po_float_arr_uniform_location == -1 || m_po_float_uniform_location == -1 ||
m_po_int_arr_uniform_location == -1 || m_po_int_uniform_location == -1 ||
m_po_ivec2_arr_uniform_location == -1 || m_po_ivec2_uniform_location == -1 ||
m_po_ivec3_arr_uniform_location == -1 || m_po_ivec3_uniform_location == -1 ||
m_po_ivec4_arr_uniform_location == -1 || m_po_ivec4_uniform_location == -1 ||
m_po_sampler_uniform_location == -1 || m_po_uint_arr_uniform_location == -1 ||
m_po_uint_uniform_location == -1 || m_po_uvec2_arr_uniform_location == -1 ||
m_po_uvec2_uniform_location == -1 || m_po_uvec3_arr_uniform_location == -1 ||
m_po_uvec3_uniform_location == -1 || m_po_uvec4_arr_uniform_location == -1 ||
m_po_uvec4_uniform_location == -1 || m_po_vec2_arr_uniform_location == -1 || m_po_vec2_uniform_location == -1 ||
m_po_vec3_arr_uniform_location == -1 || m_po_vec3_uniform_location == -1 ||
m_po_vec4_arr_uniform_location == -1 || m_po_vec4_uniform_location == -1)
{
TCU_FAIL("At last one of the required uniforms is considered inactive.");
}
}
/** Tells wheter uniform at user-specified location represents a double-precision
* matrix uniform.
*
* @param uniform_location Location of the uniform to use for the query.
*
* @return Requested information.
**/
bool GPUShaderFP64Test1::isMatrixUniform(glw::GLint uniform_location)
{
return (uniform_location == m_po_dmat2_uniform_location || uniform_location == m_po_dmat2x3_uniform_location ||
uniform_location == m_po_dmat2x4_uniform_location || uniform_location == m_po_dmat3_uniform_location ||
uniform_location == m_po_dmat3x2_uniform_location || uniform_location == m_po_dmat3x4_uniform_location ||
uniform_location == m_po_dmat4_uniform_location || uniform_location == m_po_dmat4x2_uniform_location ||
uniform_location == m_po_dmat4x3_uniform_location);
}
/** Tells whether user-specified uniform function corresponds to one of the
* functions in glUniformMatrix*() class.
*
* @param func Uniform function enum to use for the query.
*
* @return true if the specified enum represents one of the glUniformMatrix*() functions,
* false otherwise.
**/
bool GPUShaderFP64Test1::isMatrixUniformFunction(_uniform_function func)
{
return (func == UNIFORM_FUNCTION_MATRIX2DV || func == UNIFORM_FUNCTION_MATRIX2X3DV ||
func == UNIFORM_FUNCTION_MATRIX2X4DV || func == UNIFORM_FUNCTION_MATRIX3DV ||
func == UNIFORM_FUNCTION_MATRIX3X2DV || func == UNIFORM_FUNCTION_MATRIX3X4DV ||
func == UNIFORM_FUNCTION_MATRIX4DV || func == UNIFORM_FUNCTION_MATRIX4X2DV ||
func == UNIFORM_FUNCTION_MATRIX4X3DV);
}
/** Executes test iteration.
*
* @return Returns STOP when test has finished executing, CONTINUE if more iterations are needed.
*/
tcu::TestNode::IterateResult GPUShaderFP64Test1::iterate()
{
/* Do not execute the test if GL_ARB_texture_view is not supported */
if (!m_context.getContextInfo().isExtensionSupported("GL_ARB_gpu_shader_fp64"))
{
throw tcu::NotSupportedError("GL_ARB_gpu_shader_fp64 is not supported.");
}
/* Initialize all ES objects required to run all the checks */
initTest();
/* Make sure GL_INVALID_OPERATION is generated by glUniform*() and
* glUniformMatrix*() functions if there is no current program object.
*/
m_has_test_passed &= verifyErrorGenerationWhenUniformFunctionsCalledWithoutActivePO();
/* Make sure GL_INVALID_OPERATION is generated by glUniform*() if
* the size of the uniform variable declared in the shader does not
* match the size indicated by the command.
*/
m_has_test_passed &= verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions();
/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
* glUniformMatrix*() are used to load a uniform variable of type
* bool, bvec2, bvec3, bvec4, float, int, ivec2, ivec3, ivec4,
* unsigned int, uvec2, uvec3, uvec4, vec2, vec3, vec4 or an array
* of these.
*/
m_has_test_passed &= verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions();
/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
* glUniformMatrix*() are used to load incompatible double-typed
* uniforms, as presented below:
*
* I. double-typed uniform configured by glUniform2d();
* II. double-typed uniform configured by glUniform3d();
* III. double-typed uniform configured by glUniform4d();
* IV. double-typed uniform configured by glUniformMatrix*();
* V. dvec2-typed uniform configured by glUniform1d();
* VI. dvec2-typed uniform configured by glUniform3d();
* VII. dvec2-typed uniform configured by glUniform4d();
* VIII. dvec2-typed uniform configured by glUniformMatrix*();
*
* (etc.)
*
*/
m_has_test_passed &= verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions();
/* Make sure GL_INVALID_OPERATION is generated if <location> of
* glUniform*() and glUniformMatrix*() is an invalid uniform
* location for the current program object and location is not
* equal to -1.
*/
m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation();
/* Make sure GL_INVALID_VALUE is generated if <count> of
* glUniform*() (*dv() functions only) and glUniformMatrix*() is
* negative.
*/
m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount();
/* Make sure GL_INVALID_OPERATION is generated if <count> of
* glUniform*() (*dv() functions only) and glUniformMatrix*() is
* greater than 1 and the indicated uniform variable is not an
* array variable.
*/
m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount();
/* Make sure GL_INVALID_OPERATION is generated if a sampler is
* loaded by glUniform*() and glUniformMatrix*().
*/
m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers();
/* Make sure GL_INVALID_OPERATION is generated if glUniform*() and
* glUniformMatrix*() is used to load values for uniforms of
* boolean types.
*/
m_has_test_passed &= verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans();
if (m_has_test_passed)
{
m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Pass");
}
else
{
m_testCtx.setTestResult(QP_TEST_RESULT_FAIL, "Fail");
}
return STOP;
}
/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
* glUniformMatrix*dv() functions is used to load a boolean uniform.
*
* @return true if the implementation was found to behave as expected, false otherwise.
**/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForBooleans()
{
const double double_data[] = {
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
};
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
bool result = true;
glw::GLint uniform_locations[] = { m_po_bool_arr_uniform_location, m_po_bool_uniform_location,
m_po_bvec2_arr_uniform_location, m_po_bvec2_uniform_location,
m_po_bvec3_arr_uniform_location, m_po_bvec3_uniform_location,
m_po_bvec4_arr_uniform_location, m_po_bvec4_uniform_location };
const unsigned int n_uniform_locations = sizeof(uniform_locations) / sizeof(uniform_locations[0]);
for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
++n_uniform_function)
{
const _uniform_function uniform_function = (_uniform_function)n_uniform_function;
for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location)
{
const glw::GLint uniform_location = uniform_locations[n_uniform_location];
switch (uniform_function)
{
case UNIFORM_FUNCTION_1D:
gl.uniform1d(uniform_location, 0.0);
break;
case UNIFORM_FUNCTION_2D:
gl.uniform2d(uniform_location, 0.0, 1.0);
break;
case UNIFORM_FUNCTION_3D:
gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
break;
case UNIFORM_FUNCTION_4D:
gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
break;
case UNIFORM_FUNCTION_1DV:
gl.uniform1dv(uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_2DV:
gl.uniform2dv(uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_3DV:
gl.uniform3dv(uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_4DV:
gl.uniform4dv(uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2DV:
gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2X3DV:
gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2X4DV:
gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3DV:
gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3X2DV:
gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3X4DV:
gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4DV:
gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4X2DV:
gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4X3DV:
gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
default:
{
TCU_FAIL("Unrecognized uniform function");
}
}
/* Make sure GL_INVALID_OPERATION was generated by the call */
const glw::GLenum error_code = gl.getError();
if (error_code != GL_INVALID_OPERATION)
{
m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
<< "() did not generate an error"
" when applied against a boolean uniform."
<< tcu::TestLog::EndMessage;
result = false;
}
} /* for (all bool uniforms) */
} /* for (all uniform functions) */
return result;
}
/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
* glUniformMatrix*dv() functions is used to load a sampler2D uniform.
*
* @return true if the implementation was found to behave as expected, false otherwise.
**/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsForSamplers()
{
const double double_data[] = {
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
};
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
bool result = true;
for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
++n_uniform_function)
{
_uniform_function uniform_function = (_uniform_function)n_uniform_function;
switch (uniform_function)
{
case UNIFORM_FUNCTION_1D:
gl.uniform1d(m_po_sampler_uniform_location, 0.0);
break;
case UNIFORM_FUNCTION_2D:
gl.uniform2d(m_po_sampler_uniform_location, 0.0, 1.0);
break;
case UNIFORM_FUNCTION_3D:
gl.uniform3d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0);
break;
case UNIFORM_FUNCTION_4D:
gl.uniform4d(m_po_sampler_uniform_location, 0.0, 1.0, 2.0, 3.0);
break;
case UNIFORM_FUNCTION_1DV:
gl.uniform1dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_2DV:
gl.uniform2dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_3DV:
gl.uniform3dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_4DV:
gl.uniform4dv(m_po_sampler_uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2DV:
gl.uniformMatrix2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2X3DV:
gl.uniformMatrix2x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2X4DV:
gl.uniformMatrix2x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3DV:
gl.uniformMatrix3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3X2DV:
gl.uniformMatrix3x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3X4DV:
gl.uniformMatrix3x4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4DV:
gl.uniformMatrix4dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4X2DV:
gl.uniformMatrix4x2dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4X3DV:
gl.uniformMatrix4x3dv(m_po_sampler_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
default:
{
TCU_FAIL("Unrecognized uniform function");
}
}
/* Make sure GL_INVALID_OPERATION was generated by the call */
const glw::GLenum error_code = gl.getError();
if (error_code != GL_INVALID_OPERATION)
{
m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
<< "() did not generate an error"
" when applied against a sampler uniform."
<< tcu::TestLog::EndMessage;
result = false;
}
} /* for (all uniform functions) */
return result;
}
/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*dv() or
* glUniformMatrix*dv() functions is used to load a compatible uniform using an
* invalid <count> argument.
*
* @return true if the implementation was found to behave as expected, false otherwise.
**/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidCount()
{
const glw::GLdouble double_values[16] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
bool result = true;
const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV, UNIFORM_FUNCTION_2DV,
UNIFORM_FUNCTION_3DV, UNIFORM_FUNCTION_4DV,
UNIFORM_FUNCTION_MATRIX2DV, UNIFORM_FUNCTION_MATRIX2X3DV,
UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV,
UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV,
UNIFORM_FUNCTION_MATRIX4DV, UNIFORM_FUNCTION_MATRIX4X2DV,
UNIFORM_FUNCTION_MATRIX4X3DV };
const glw::GLint uniforms[] = {
m_po_bool_uniform_location, m_po_bvec2_uniform_location, m_po_bvec3_uniform_location,
m_po_bvec4_uniform_location, m_po_dmat2_uniform_location, m_po_dmat2x3_uniform_location,
m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location, m_po_dmat3x2_uniform_location,
m_po_dmat3x4_uniform_location, m_po_dmat4_uniform_location, m_po_dmat4x2_uniform_location,
m_po_dmat4x3_uniform_location, m_po_double_uniform_location, m_po_dvec2_uniform_location,
m_po_dvec3_uniform_location, m_po_dvec4_uniform_location, m_po_float_uniform_location,
m_po_int_uniform_location, m_po_ivec2_uniform_location, m_po_ivec3_uniform_location,
m_po_ivec4_uniform_location, m_po_uint_uniform_location, m_po_uvec2_uniform_location,
m_po_uvec3_uniform_location, m_po_uvec4_uniform_location, m_po_vec2_uniform_location,
m_po_vec3_uniform_location, m_po_vec4_uniform_location
};
const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]);
const unsigned int n_uniforms = sizeof(uniforms) / sizeof(uniforms[0]);
for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function)
{
_uniform_function uniform_function = uniform_functions[n_uniform_function];
for (unsigned int n_uniform = 0; n_uniform < n_uniforms; ++n_uniform)
{
glw::GLint uniform_location = uniforms[n_uniform];
/* Make sure we only use glUniformMatrix*() functions with matrix uniforms,
* and glUniform*() functions with vector uniforms.
*/
bool is_matrix_uniform = isMatrixUniform(uniform_location);
if (((false == is_matrix_uniform) && (true == isMatrixUniformFunction(uniform_function))) ||
((true == is_matrix_uniform) && (false == isMatrixUniformFunction(uniform_function))))
{
continue;
}
/* Issue the call with an invalid <count> argument */
switch (uniform_function)
{
case UNIFORM_FUNCTION_1DV:
gl.uniform1dv(uniform_location, 2, double_values);
break;
case UNIFORM_FUNCTION_2DV:
gl.uniform2dv(uniform_location, 2, double_values);
break;
case UNIFORM_FUNCTION_3DV:
gl.uniform3dv(uniform_location, 2, double_values);
break;
case UNIFORM_FUNCTION_4DV:
gl.uniform4dv(uniform_location, 2, double_values);
break;
case UNIFORM_FUNCTION_MATRIX2DV:
gl.uniformMatrix2dv(uniform_location, 2, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX2X3DV:
gl.uniformMatrix2x3dv(uniform_location, 2, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX2X4DV:
gl.uniformMatrix2x4dv(uniform_location, 2, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX3DV:
gl.uniformMatrix3dv(uniform_location, 2, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX3X2DV:
gl.uniformMatrix3x2dv(uniform_location, 2, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX3X4DV:
gl.uniformMatrix3x4dv(uniform_location, 2, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX4DV:
gl.uniformMatrix4dv(uniform_location, 2, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX4X2DV:
gl.uniformMatrix4x2dv(uniform_location, 2, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX4X3DV:
gl.uniformMatrix4x3dv(uniform_location, 2, GL_FALSE, double_values);
break;
default:
{
TCU_FAIL("Unrecognized uniform function");
}
} /* switch (uniform_function) */
/* Make sure GL_INVALID_VALUE was generated */
glw::GLenum error_code = gl.getError();
if (error_code != GL_INVALID_OPERATION)
{
m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
<< "() "
"was called with an invalid count argument but did not generate a "
"GL_INVALID_OPERATION error"
<< tcu::TestLog::EndMessage;
result = false;
}
} /* for (all non-arrayed uniforms) */
} /* for (all uniform functions) */
return result;
}
/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
* glUniformMatrix*dv() functions is used to load an uniform at an invalid location.
*
* @return true if the implementation was found to behave as expected, false otherwise.
**/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithInvalidLocation()
{
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
bool result = true;
/* Find the largest valid uniform location */
const glw::GLint uniform_locations[] = {
m_po_bool_arr_uniform_location, m_po_bool_uniform_location, m_po_bvec2_arr_uniform_location,
m_po_bvec2_uniform_location, m_po_bvec3_arr_uniform_location, m_po_bvec3_uniform_location,
m_po_bvec4_arr_uniform_location, m_po_bvec4_uniform_location, m_po_dmat2_arr_uniform_location,
m_po_dmat2_uniform_location, m_po_dmat2x3_arr_uniform_location, m_po_dmat2x3_uniform_location,
m_po_dmat2x4_arr_uniform_location, m_po_dmat2x4_uniform_location, m_po_dmat3_arr_uniform_location,
m_po_dmat3_uniform_location, m_po_dmat3x2_arr_uniform_location, m_po_dmat3x2_uniform_location,
m_po_dmat3x4_arr_uniform_location, m_po_dmat3x4_uniform_location, m_po_dmat4_arr_uniform_location,
m_po_dmat4_uniform_location, m_po_dmat4x2_arr_uniform_location, m_po_dmat4x2_uniform_location,
m_po_dmat4x3_arr_uniform_location, m_po_dmat4x3_uniform_location, m_po_double_arr_uniform_location,
m_po_double_uniform_location, m_po_dvec2_arr_uniform_location, m_po_dvec2_uniform_location,
m_po_dvec3_arr_uniform_location, m_po_dvec3_uniform_location, m_po_dvec4_arr_uniform_location,
m_po_dvec4_uniform_location, m_po_float_arr_uniform_location, m_po_float_uniform_location,
m_po_int_arr_uniform_location, m_po_int_uniform_location, m_po_ivec2_arr_uniform_location,
m_po_ivec2_uniform_location, m_po_ivec3_arr_uniform_location, m_po_ivec3_uniform_location,
m_po_ivec4_arr_uniform_location, m_po_ivec4_uniform_location, m_po_uint_arr_uniform_location,
m_po_uint_uniform_location, m_po_uvec2_arr_uniform_location, m_po_uvec2_uniform_location,
m_po_uvec3_arr_uniform_location, m_po_uvec3_uniform_location, m_po_uvec4_arr_uniform_location,
m_po_uvec4_uniform_location, m_po_vec2_arr_uniform_location, m_po_vec2_uniform_location,
m_po_vec3_arr_uniform_location, m_po_vec3_uniform_location, m_po_vec4_arr_uniform_location,
m_po_vec4_uniform_location
};
const unsigned int n_uniform_locations = sizeof(uniform_locations) / sizeof(uniform_locations[0]);
glw::GLint valid_uniform_location = -1;
for (unsigned int n_uniform_location = 0; n_uniform_location < n_uniform_locations; ++n_uniform_location)
{
glw::GLint uniform_location = uniform_locations[n_uniform_location];
if (uniform_location > valid_uniform_location)
{
valid_uniform_location = uniform_location;
}
} /* for (all uniform locations) */
/* Iterate through all uniform functions and make sure GL_INVALID_OPERATION error is always generated
* for invalid uniform location that is != -1
*/
const double double_data[] = {
1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0
};
const glw::GLint invalid_uniform_location = valid_uniform_location + 1;
for (unsigned int n_uniform_function = UNIFORM_FUNCTION_FIRST; n_uniform_function < UNIFORM_FUNCTION_COUNT;
++n_uniform_function)
{
_uniform_function uniform_function = (_uniform_function)n_uniform_function;
switch (uniform_function)
{
case UNIFORM_FUNCTION_1D:
gl.uniform1d(invalid_uniform_location, 0.0);
break;
case UNIFORM_FUNCTION_2D:
gl.uniform2d(invalid_uniform_location, 0.0, 1.0);
break;
case UNIFORM_FUNCTION_3D:
gl.uniform3d(invalid_uniform_location, 0.0, 1.0, 2.0);
break;
case UNIFORM_FUNCTION_4D:
gl.uniform4d(invalid_uniform_location, 0.0, 1.0, 2.0, 3.0);
break;
case UNIFORM_FUNCTION_1DV:
gl.uniform1dv(invalid_uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_2DV:
gl.uniform2dv(invalid_uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_3DV:
gl.uniform3dv(invalid_uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_4DV:
gl.uniform4dv(invalid_uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2DV:
gl.uniformMatrix2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2X3DV:
gl.uniformMatrix2x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2X4DV:
gl.uniformMatrix2x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3DV:
gl.uniformMatrix3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3X2DV:
gl.uniformMatrix3x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3X4DV:
gl.uniformMatrix3x4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4DV:
gl.uniformMatrix4dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4X2DV:
gl.uniformMatrix4x2dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4X3DV:
gl.uniformMatrix4x3dv(invalid_uniform_location, 1 /* count */, GL_FALSE /* transpose */, double_data);
break;
default:
{
TCU_FAIL("Unrecognized uniform function");
}
}
const glw::GLenum error_code = gl.getError();
if (error_code != GL_INVALID_OPERATION)
{
m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
<< "() did not generate an error"
" when passed an invalid uniform location different from -1."
<< tcu::TestLog::EndMessage;
result = false;
}
} /* for (all uniform functions) */
return result;
}
/** Verifies GL_INVALID_VALUE is generated if any of the glUniform*dv() or
* glUniformMatrix*dv() functions is used to load a compatible uniform using an
* invalid <count> argument of -1.
*
* @return true if the implementation was found to behave as expected, false otherwise.
**/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingDoubleUniformFunctionsWithNegativeCount()
{
const glw::GLdouble double_values[16] = { 1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0,
9.0, 10.0, 11.0, 12.0, 13.0, 14.0, 15.0, 16.0 };
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
bool result = true;
const _uniform_function uniform_functions[] = { UNIFORM_FUNCTION_1DV, UNIFORM_FUNCTION_2DV,
UNIFORM_FUNCTION_3DV, UNIFORM_FUNCTION_4DV,
UNIFORM_FUNCTION_MATRIX2DV, UNIFORM_FUNCTION_MATRIX2X3DV,
UNIFORM_FUNCTION_MATRIX2X4DV, UNIFORM_FUNCTION_MATRIX3DV,
UNIFORM_FUNCTION_MATRIX3X2DV, UNIFORM_FUNCTION_MATRIX3X4DV,
UNIFORM_FUNCTION_MATRIX4DV, UNIFORM_FUNCTION_MATRIX4X2DV,
UNIFORM_FUNCTION_MATRIX4X3DV };
const unsigned int n_uniform_functions = sizeof(uniform_functions) / sizeof(uniform_functions[0]);
for (unsigned int n_uniform_function = 0; n_uniform_function < n_uniform_functions; ++n_uniform_function)
{
_uniform_function uniform_function = uniform_functions[n_uniform_function];
switch (uniform_function)
{
case UNIFORM_FUNCTION_1DV:
gl.uniform1dv(m_po_double_arr_uniform_location, -1, double_values);
break;
case UNIFORM_FUNCTION_2DV:
gl.uniform2dv(m_po_dvec2_arr_uniform_location, -1, double_values);
break;
case UNIFORM_FUNCTION_3DV:
gl.uniform3dv(m_po_dvec3_arr_uniform_location, -1, double_values);
break;
case UNIFORM_FUNCTION_4DV:
gl.uniform4dv(m_po_dvec4_arr_uniform_location, -1, double_values);
break;
case UNIFORM_FUNCTION_MATRIX2DV:
gl.uniformMatrix2dv(m_po_dmat2_arr_uniform_location, -1, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX2X3DV:
gl.uniformMatrix2x3dv(m_po_dmat2x3_arr_uniform_location, -1, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX2X4DV:
gl.uniformMatrix2x4dv(m_po_dmat2x4_arr_uniform_location, -1, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX3DV:
gl.uniformMatrix3dv(m_po_dmat3_arr_uniform_location, -1, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX3X2DV:
gl.uniformMatrix3x2dv(m_po_dmat3x2_arr_uniform_location, -1, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX3X4DV:
gl.uniformMatrix3x4dv(m_po_dmat3x4_arr_uniform_location, -1, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX4DV:
gl.uniformMatrix4dv(m_po_dmat4_arr_uniform_location, -1, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX4X2DV:
gl.uniformMatrix4x2dv(m_po_dmat4x2_arr_uniform_location, -1, GL_FALSE, double_values);
break;
case UNIFORM_FUNCTION_MATRIX4X3DV:
gl.uniformMatrix4x3dv(m_po_dmat4x3_arr_uniform_location, -1, GL_FALSE, double_values);
break;
default:
{
TCU_FAIL("Unrecognized uniform function");
}
} /* switch (uniform_function) */
/* Make sure GL_INVALID_VALUE was generated */
glw::GLenum error_code = gl.getError();
if (error_code != GL_INVALID_VALUE)
{
m_testCtx.getLog() << tcu::TestLog::Message << "Function " << getUniformFunctionString(uniform_function)
<< "() "
"was called with a negative count argument but did not generate a "
"GL_INVALID_VALUE error"
<< tcu::TestLog::EndMessage;
result = false;
}
} /* for (all uniform functions) */
return result;
}
/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d(), glUniform*dv() or
* glUniformMatrix*dv() functions is used to load an uniform that's incompatible with the
* function (as per spec).
*
* @return true if the implementation was found to behave as expected, false otherwise.
**/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingMismatchedDoubleUniformFunctions()
{
const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
glw::GLenum error_code = GL_NO_ERROR;
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
bool result = true;
const glw::GLint double_uniform_locations[] = { m_po_dmat2_uniform_location, m_po_dmat2x3_uniform_location,
m_po_dmat2x4_uniform_location, m_po_dmat3_uniform_location,
m_po_dmat3x2_uniform_location, m_po_dmat3x4_uniform_location,
m_po_dmat4_uniform_location, m_po_dmat4x2_uniform_location,
m_po_dmat4x3_uniform_location, m_po_double_uniform_location,
m_po_dvec2_uniform_location, m_po_dvec3_uniform_location,
m_po_dvec4_uniform_location };
const unsigned int n_double_uniform_locations =
sizeof(double_uniform_locations) / sizeof(double_uniform_locations[0]);
gl.useProgram(m_po_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
for (unsigned int n_uniform_location = 0; n_uniform_location < n_double_uniform_locations; ++n_uniform_location)
{
glw::GLint uniform_location = double_uniform_locations[n_uniform_location];
for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST);
function < static_cast<int>(UNIFORM_FUNCTION_COUNT); function++)
{
_uniform_function e_function = static_cast<_uniform_function>(function);
/* Exclude valid combinations */
if (((uniform_location == m_po_dmat2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2DV)) ||
((uniform_location == m_po_dmat2x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X3DV)) ||
((uniform_location == m_po_dmat2x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX2X4DV)) ||
((uniform_location == m_po_dmat3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3DV)) ||
((uniform_location == m_po_dmat3x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X2DV)) ||
((uniform_location == m_po_dmat3x4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX3X4DV)) ||
((uniform_location == m_po_dmat4_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4DV)) ||
((uniform_location == m_po_dmat4x2_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X2DV)) ||
((uniform_location == m_po_dmat4x3_uniform_location) && (e_function == UNIFORM_FUNCTION_MATRIX4X3DV)) ||
((uniform_location == m_po_double_uniform_location) &&
((e_function == UNIFORM_FUNCTION_1D) || (e_function == UNIFORM_FUNCTION_1DV))) ||
((uniform_location == m_po_dvec2_uniform_location) &&
((e_function == UNIFORM_FUNCTION_2D) || (e_function == UNIFORM_FUNCTION_2DV))) ||
((uniform_location == m_po_dvec3_uniform_location) &&
((e_function == UNIFORM_FUNCTION_3D) || (e_function == UNIFORM_FUNCTION_3DV))) ||
((uniform_location == m_po_dvec4_uniform_location) &&
((e_function == UNIFORM_FUNCTION_4D) || (e_function == UNIFORM_FUNCTION_4DV))))
{
continue;
}
switch (e_function)
{
case UNIFORM_FUNCTION_1D:
{
gl.uniform1d(uniform_location, double_data[0]);
break;
}
case UNIFORM_FUNCTION_2D:
{
gl.uniform2d(uniform_location, double_data[0], double_data[1]);
break;
}
case UNIFORM_FUNCTION_3D:
{
gl.uniform3d(uniform_location, double_data[0], double_data[1], double_data[2]);
break;
}
case UNIFORM_FUNCTION_4D:
{
gl.uniform4d(uniform_location, double_data[0], double_data[1], double_data[2], double_data[3]);
break;
}
case UNIFORM_FUNCTION_1DV:
gl.uniform1dv(uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_2DV:
gl.uniform2dv(uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_3DV:
gl.uniform3dv(uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_4DV:
gl.uniform4dv(uniform_location, 1 /* count */, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2DV:
gl.uniformMatrix2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2X3DV:
gl.uniformMatrix2x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
case UNIFORM_FUNCTION_MATRIX2X4DV:
gl.uniformMatrix2x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3DV:
gl.uniformMatrix3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3X2DV:
gl.uniformMatrix3x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
case UNIFORM_FUNCTION_MATRIX3X4DV:
gl.uniformMatrix3x4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4DV:
gl.uniformMatrix4dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4X2DV:
gl.uniformMatrix4x2dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
case UNIFORM_FUNCTION_MATRIX4X3DV:
gl.uniformMatrix4x3dv(uniform_location, 1 /* count */, GL_FALSE, double_data);
break;
default:
{
TCU_FAIL("Unrecognized function");
}
} /* switch (function) */
/* Make sure GL_INVALID_OPERATION error was generated */
error_code = gl.getError();
if (error_code != GL_INVALID_OPERATION)
{
m_testCtx.getLog() << tcu::TestLog::Message << "Invalid error [" << error_code
<< "] was generated when a mismatched "
"double-precision uniform function "
<< getUniformFunctionString(e_function) << "() was used to configure uniform "
<< getUniformNameForLocation(uniform_location) << "." << tcu::TestLog::EndMessage;
result = false;
}
} /* for (all uniform functions) */
} /* for (all uniform locations) */
return result;
}
/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
* glUniform*dv() functions is used to load an uniform, size of which is incompatible
* with the function.
*
* @return true if the implementation was found to behave as expected, false otherwise.
**/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingSizeMismatchedUniformFunctions()
{
const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
glw::GLenum error_code = GL_NO_ERROR;
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
bool result = true;
const int data[] = {
/* API function */ /* Uniform location */ /* Count (dv functions only) */
(int)UNIFORM_FUNCTION_2D, m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_2DV,
m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_double_uniform_location, 0,
(int)UNIFORM_FUNCTION_3DV, m_po_double_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
m_po_double_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_double_uniform_location, 2,
(int)UNIFORM_FUNCTION_1D, m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_3D, m_po_dvec2_uniform_location, 0,
(int)UNIFORM_FUNCTION_3DV, m_po_dvec2_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
m_po_dvec2_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec2_uniform_location, 2,
(int)UNIFORM_FUNCTION_1D, m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec3_uniform_location, 0,
(int)UNIFORM_FUNCTION_2DV, m_po_dvec3_uniform_location, 2, (int)UNIFORM_FUNCTION_4D,
m_po_dvec3_uniform_location, 0, (int)UNIFORM_FUNCTION_4DV, m_po_dvec3_uniform_location, 2,
(int)UNIFORM_FUNCTION_1D, m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_1DV,
m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_2D, m_po_dvec4_uniform_location, 0,
(int)UNIFORM_FUNCTION_2DV, m_po_dvec4_uniform_location, 2, (int)UNIFORM_FUNCTION_3D,
m_po_dvec4_uniform_location, 0, (int)UNIFORM_FUNCTION_3DV, m_po_dvec4_uniform_location, 2,
};
const unsigned int n_checks = sizeof(data) / sizeof(data[0]) / 3 /* entries per row */;
gl.useProgram(m_po_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
for (unsigned int n_check = 0; n_check < n_checks; ++n_check)
{
_uniform_function function = (_uniform_function)data[n_check * 3 + 0];
int uniform_location = data[n_check * 3 + 1];
int uniform_count = data[n_check * 3 + 2];
switch (function)
{
case UNIFORM_FUNCTION_1D:
gl.uniform1d(uniform_location, 0.0);
break;
case UNIFORM_FUNCTION_1DV:
gl.uniform1dv(uniform_location, uniform_count, double_data);
break;
case UNIFORM_FUNCTION_2D:
gl.uniform2d(uniform_location, 0.0, 1.0);
break;
case UNIFORM_FUNCTION_2DV:
gl.uniform2dv(uniform_location, uniform_count, double_data);
break;
case UNIFORM_FUNCTION_3D:
gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
break;
case UNIFORM_FUNCTION_3DV:
gl.uniform3dv(uniform_location, uniform_count, double_data);
break;
case UNIFORM_FUNCTION_4D:
gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
break;
case UNIFORM_FUNCTION_4DV:
gl.uniform4dv(uniform_location, uniform_count, double_data);
break;
default:
{
DE_ASSERT(false);
}
} /* switch (function) */
error_code = gl.getError();
if (error_code != GL_INVALID_OPERATION)
{
m_testCtx.getLog() << tcu::TestLog::Message << getUniformFunctionString(function)
<< "() function did not generate GL_INVALID_OPERATION error when called for"
" a uniform of incompatible size. (check index: "
<< n_check << ")" << tcu::TestLog::EndMessage;
result = false;
}
} /* for (all checks) */
return result;
}
/** Verifies GL_INVALID_OPERATION is generated if any of the glUniform*d() or
* glUniform*dv() functions is used to load an uniform, type of which is incompatible
* with the function.
*
* @return true if the implementation was found to behave as expected, false otherwise.
**/
bool GPUShaderFP64Test1::verifyErrorGenerationWhenCallingTypeMismatchedUniformFunctions()
{
const double double_data[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16 };
glw::GLenum error_code = GL_NO_ERROR;
const glw::Functions& gl = m_context.getRenderContext().getFunctions();
bool result = true;
const glw::GLint nondouble_uniform_locations[] = { m_po_bool_uniform_location, m_po_bvec2_uniform_location,
m_po_bvec3_uniform_location, m_po_bvec4_uniform_location,
m_po_float_uniform_location, m_po_int_uniform_location,
m_po_ivec2_uniform_location, m_po_ivec3_uniform_location,
m_po_ivec4_uniform_location, m_po_uint_uniform_location,
m_po_uvec2_uniform_location, m_po_uvec3_uniform_location,
m_po_uvec4_uniform_location, m_po_vec2_uniform_location,
m_po_vec3_uniform_location, m_po_vec4_uniform_location };
const unsigned int n_nondouble_uniform_locations =
sizeof(nondouble_uniform_locations) / sizeof(nondouble_uniform_locations[0]);
gl.useProgram(m_po_id);
GLU_EXPECT_NO_ERROR(gl.getError(), "glUseProgram() call failed.");
for (unsigned int n_uniform_location = 0; n_uniform_location < n_nondouble_uniform_locations; ++n_uniform_location)
{
glw::GLint uniform_location = nondouble_uniform_locations[n_uniform_location];
for (int function = static_cast<int>(UNIFORM_FUNCTION_FIRST);
function < static_cast<int>(UNIFORM_FUNCTION_COUNT); ++function)
{
switch (static_cast<_uniform_function>(function))
{
case UNIFORM_FUNCTION_1D:
gl.uniform1d(uniform_location, 0.0);
break;
case UNIFORM_FUNCTION_1DV:
gl.uniform1dv(uniform_location, 1, double_data);
break;
case UNIFORM_FUNCTION_2D:
gl.uniform2d(uniform_location, 0.0, 1.0);
break;
case UNIFORM_FUNCTION_2DV:
gl.uniform2dv(uniform_location, 1, double_data);
break;
case UNIFORM_FUNCTION_3D:
gl.uniform3d(uniform_location, 0.0, 1.0, 2.0);
break;
case UNIFORM_FUNCTION_3DV:
gl.uniform3dv(uniform_location, 1, double_data);
break;
case UNIFORM_FUNCTION_4D:
gl.uniform4d(uniform_location, 0.0, 1.0, 2.0, 3.0);
break;
case UNIFORM_FUNCTION_4DV:
gl.uniform4dv(uniform_location, 1, double_data);
break;