blob: 31d798283e654fe61484a6e7f32ca430c9cac298 [file] [log] [blame]
#ifndef _GL4CENHANCEDLAYOUTSTESTS_HPP
#define _GL4CENHANCEDLAYOUTSTESTS_HPP
/*-------------------------------------------------------------------------
* OpenGL Conformance Test Suite
* -----------------------------
*
* Copyright (c) 2015-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 gl4cEnhancedLayoutsTests.hpp
* \brief Declares test classes for "Enhanced Layouts" functionality.
*/ /*-------------------------------------------------------------------*/
#include "glcTestCase.hpp"
#include "glwDefs.hpp"
namespace tcu
{
class MessageBuilder;
} /* namespace tcu */
namespace gl4cts
{
namespace EnhancedLayouts
{
namespace Utils
{
/** Represents data type
*
**/
struct Type
{
public:
enum TYPES
{
Float,
Double,
Int,
Uint,
};
/* Public methods */
/* Functionality */
std::vector<glw::GLubyte> GenerateData() const;
std::vector<glw::GLubyte> GenerateDataPacked() const;
glw::GLuint GetActualAlignment(glw::GLuint align, bool is_array) const;
glw::GLuint GetBaseAlignment(bool is_array) const;
std::string GetGLSLConstructor(const glw::GLvoid* data) const;
const glw::GLchar* GetGLSLTypeName() const;
glw::GLuint GetLocations(bool is_vs_input = false) const;
glw::GLuint GetSize(const bool is_std140 = false) const;
glw::GLenum GetTypeGLenum() const;
glw::GLuint GetNumComponents() const;
/* Public static routines */
/* Functionality */
static glw::GLuint CalculateStd140Stride(glw::GLuint alignment, glw::GLuint n_columns,
glw::GLuint n_array_elements);
static bool DoesTypeSupportMatrix(TYPES type);
static glw::GLuint GetActualOffset(glw::GLuint start_offset, glw::GLuint actual_alignment);
static Type GetType(TYPES basic_type, glw::GLuint n_columns, glw::GLuint n_rows);
static glw::GLuint GetTypeSize(TYPES type);
/* GL gets */
static glw::GLenum GetTypeGLenum(TYPES type);
/* Public fields */
TYPES m_basic_type;
glw::GLuint m_n_columns;
glw::GLuint m_n_rows;
/* Public constants */
static const Type _double;
static const Type dmat2;
static const Type dmat2x3;
static const Type dmat2x4;
static const Type dmat3x2;
static const Type dmat3;
static const Type dmat3x4;
static const Type dmat4x2;
static const Type dmat4x3;
static const Type dmat4;
static const Type dvec2;
static const Type dvec3;
static const Type dvec4;
static const Type _float;
static const Type _int;
static const Type ivec2;
static const Type ivec3;
static const Type ivec4;
static const Type mat2;
static const Type mat2x3;
static const Type mat2x4;
static const Type mat3x2;
static const Type mat3;
static const Type mat3x4;
static const Type mat4x2;
static const Type mat4x3;
static const Type mat4;
static const Type vec2;
static const Type vec3;
static const Type vec4;
static const Type uint;
static const Type uvec2;
static const Type uvec3;
static const Type uvec4;
};
/** Represents buffer instance
* Provides basic buffer functionality
**/
class Buffer
{
public:
/* Public enums */
enum BUFFERS
{
Array,
Element,
Shader_Storage,
Texture,
Transform_feedback,
Uniform,
};
enum USAGE
{
DynamicCopy,
DynamicDraw,
DynamicRead,
StaticCopy,
StaticDraw,
StaticRead,
StreamCopy,
StreamDraw,
StreamRead,
};
enum ACCESS
{
ReadOnly,
WriteOnly,
ReadWrite,
};
/* Public methods */
/* Ctr & Dtr */
Buffer(deqp::Context& context);
~Buffer();
/* Init & Release */
void Init(BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data);
void Release();
/* Functionality */
void Bind() const;
void BindBase(glw::GLuint index) const;
void BindRange(glw::GLuint index, glw::GLintptr offset, glw::GLsizeiptr size) const;
void Data(USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data);
glw::GLvoid* Map(ACCESS access);
void SubData(glw::GLintptr offset, glw::GLsizeiptr size, glw::GLvoid* data);
void UnMap();
/* Public static routines */
/* Functionality */
static void Bind(const glw::Functions& gl, glw::GLuint id, BUFFERS buffer);
static void BindBase(const glw::Functions& gl, glw::GLuint id, BUFFERS buffer, glw::GLuint index);
static void BindRange(const glw::Functions& gl, glw::GLuint id, BUFFERS buffer, glw::GLuint index,
glw::GLintptr offset, glw::GLsizeiptr size);
static void Data(const glw::Functions& gl, BUFFERS buffer, USAGE usage, glw::GLsizeiptr size, glw::GLvoid* data);
static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
static void* Map(const glw::Functions& gl, BUFFERS buffer, ACCESS access);
static void SubData(const glw::Functions& gl, BUFFERS buffer, glw::GLintptr offset, glw::GLsizeiptr size,
glw::GLvoid* data);
static void UnMap(const glw::Functions& gl, BUFFERS buffer);
/* GL gets */
static glw::GLenum GetAccessGLenum(ACCESS access);
static glw::GLenum GetBufferGLenum(BUFFERS buffer);
static glw::GLenum GetUsageGLenum(USAGE usage);
/* Gets */
static const glw::GLchar* GetBufferName(BUFFERS buffer);
/* Public fields */
glw::GLuint m_id;
/* Public constants */
static const glw::GLuint m_invalid_id;
/* Buffer type maybe changed for different cases*/
BUFFERS m_buffer;
private:
/* Private fields */
deqp::Context& m_context;
};
/** Represents framebuffer
* Provides basic functionality
**/
class Framebuffer
{
public:
/* Public methods */
/* Ctr & Dtr */
Framebuffer(deqp::Context& context);
~Framebuffer();
/* Init & Release */
void Init();
void Release();
/* Functionality */
void AttachTexture(glw::GLenum attachment, glw::GLuint texture_id, glw::GLuint width, glw::GLuint height);
void Bind();
void Clear(glw::GLenum mask);
void ClearColor(glw::GLfloat red, glw::GLfloat green, glw::GLfloat blue, glw::GLfloat alpha);
/* Public static routines */
static void AttachTexture(const glw::Functions& gl, glw::GLenum attachment, glw::GLuint texture_id,
glw::GLuint width, glw::GLuint height);
static void Bind(const glw::Functions& gl, glw::GLuint id);
static void Clear(const glw::Functions& gl, glw::GLenum mask);
static void ClearColor(const glw::Functions& gl, glw::GLfloat red, glw::GLfloat green, glw::GLfloat blue,
glw::GLfloat alpha);
static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
/* Public fields */
glw::GLuint m_id;
/* Public constants */
static const glw::GLuint m_invalid_id;
private:
/* Private fields */
deqp::Context& m_context;
};
/** Represents shader instance.
* Provides basic functionality for shaders.
**/
class Shader
{
public:
/* Public enums */
enum STAGES
{
COMPUTE = 0,
VERTEX,
TESS_CTRL,
TESS_EVAL,
GEOMETRY,
FRAGMENT,
/* */
STAGE_MAX
};
/* Public types */
class InvalidSourceException : public std::exception
{
public:
InvalidSourceException(const glw::GLchar* error_message, const std::string& source, STAGES stage);
virtual ~InvalidSourceException() throw()
{
}
virtual const char* what() const throw();
void log(deqp::Context& context) const;
std::string m_message;
std::string m_source;
STAGES m_stage;
};
/* Public methods */
/* Ctr & Dtr */
Shader(deqp::Context& context);
~Shader();
/* Init & Realese */
void Init(STAGES stage, const std::string& source);
void Release();
/* Public static routines */
/* Functionality */
static void Compile(const glw::Functions& gl, glw::GLuint id);
static void Create(const glw::Functions& gl, STAGES stage, glw::GLuint& out_id);
static void Source(const glw::Functions& gl, glw::GLuint id, const std::string& source);
/* GL gets */
static glw::GLenum GetShaderStageGLenum(STAGES stage);
/* Get stage name */
static const glw::GLchar* GetStageName(STAGES stage);
/* Logs sources */
static void LogSource(deqp::Context& context, const std::string& source, STAGES stage);
/* Public fields */
glw::GLuint m_id;
/* Public constants */
static const glw::GLuint m_invalid_id;
private:
/* Private types */
class CompilationException : public std::exception
{
public:
CompilationException(const glw::GLchar* message);
virtual ~CompilationException() throw()
{
}
virtual const char* what() const throw();
std::string m_message;
};
/* Private fields */
deqp::Context& m_context;
};
/* Forward declaration */
struct Interface;
/** Represents GLSL variable
*
**/
struct Variable
{
public:
/* Typedefs */
typedef std::vector<Variable> Vector;
typedef std::vector<Variable*> PtrVector;
/* Enums */
enum STORAGE
{
VARYING_INPUT,
VARYING_OUTPUT,
UNIFORM,
SSB,
MEMBER,
/* */
STORAGE_MAX
};
enum VARYING_DIRECTION
{
INPUT,
OUTPUT,
};
enum FLAVOUR
{
BASIC,
ARRAY,
INDEXED_BY_INVOCATION_ID,
};
/**/
enum TYPE
{
BUILTIN,
INTERFACE,
};
/* Types */
struct Descriptor
{
/* */
typedef std::vector<Descriptor> Vector;
/* */
Descriptor(const glw::GLchar* name, const glw::GLchar* qualifiers, glw::GLint expected_component,
glw::GLint expected_location, const Type& type, glw::GLboolean normalized,
glw::GLuint n_array_elements, glw::GLint expected_stride_of_element, glw::GLuint offset);
Descriptor(const glw::GLchar* name, const glw::GLchar* qualifiers, glw::GLint expected_componenet,
glw::GLint expected_location, Interface* interface, glw::GLuint n_array_elements,
glw::GLint expected_stride_of_element, glw::GLuint offset);
/* */
std::string GetDefinition(FLAVOUR flavour, STORAGE storage) const;
/* */
glw::GLint m_expected_component;
glw::GLint m_expected_location;
glw::GLint m_expected_stride_of_element;
glw::GLuint m_n_array_elements;
std::string m_name;
glw::GLboolean m_normalized;
glw::GLuint m_offset;
std::string m_qualifiers;
TYPE m_type;
union {
Type m_builtin;
Interface* m_interface;
};
};
/* Constructors */
template <typename T>
Variable(const glw::GLchar* name, const glw::GLchar* qualifiers, glw::GLint expected_component,
glw::GLint expected_location, const Type& type, glw::GLboolean normalized, glw::GLuint n_array_elements,
glw::GLint expected_stride_of_element, glw::GLuint offset, const T* data, size_t data_size,
STORAGE storage)
: m_data((glw::GLvoid*)data)
, m_data_size(data_size)
, m_descriptor(name, qualifiers, expected_component, expected_location, type, normalized, n_array_elements,
expected_stride_of_element, offset)
, m_storage(storage)
{
}
template <typename T>
Variable(const glw::GLchar* name, const glw::GLchar* qualifiers, glw::GLint expected_component,
glw::GLint expected_location, Interface* interface, glw::GLuint n_array_elements,
glw::GLint expected_stride_of_element, glw::GLuint offset, const T* data, size_t data_size,
STORAGE storage)
: m_data((glw::GLvoid*)data)
, m_data_size(data_size)
, m_descriptor(name, qualifiers, expected_component, expected_location, interface, n_array_elements,
expected_stride_of_element, offset)
, m_storage(storage)
{
}
Variable(const Variable& var);
/* Functionality */
std::string GetDefinition(FLAVOUR flavour) const;
glw::GLuint GetSize() const;
glw::GLuint GetStride() const;
bool IsBlock() const;
bool IsStruct() const;
/* Static routines */
static FLAVOUR GetFlavour(Shader::STAGES stage, VARYING_DIRECTION direction);
static std::string GetReference(const std::string& parent_name, const Descriptor& variable, FLAVOUR flavour,
glw::GLuint array_index);
/* Fields */
glw::GLvoid* m_data;
size_t m_data_size;
Descriptor m_descriptor;
STORAGE m_storage;
/* Constants */
static const glw::GLint m_automatic_location;
};
/* Define the methods NAME, that will add new variable to VECTOR with STORAGE set */
#define DEFINE_VARIABLE_CLASS(NAME, STORAGE, VECTOR) \
template <typename T> \
Variable* NAME(const glw::GLchar* name, const glw::GLchar* qualifiers, glw::GLint expected_component, \
glw::GLint expected_location, const Type& type, glw::GLboolean normalized, \
glw::GLuint n_array_elements, glw::GLint expected_stride_of_element, glw::GLuint offset, \
const T* data, size_t data_size) \
{ \
Variable* var = new Variable(name, qualifiers, expected_component, expected_location, type, normalized, \
n_array_elements, expected_stride_of_element, offset, data, data_size, STORAGE); \
if (0 == var) \
{ \
TCU_FAIL("Memory allocation"); \
} \
VECTOR.push_back(var); \
return VECTOR.back(); \
} \
\
template <typename T> \
Variable* NAME(const glw::GLchar* name, const glw::GLchar* qualifiers, glw::GLint expected_component, \
glw::GLint expected_location, Interface* interface, glw::GLuint n_array_elements, \
glw::GLint expected_stride_of_element, glw::GLuint offset, const T* data, size_t data_size) \
{ \
Variable* var = new Variable(name, qualifiers, expected_component, expected_location, interface, \
n_array_elements, expected_stride_of_element, offset, data, data_size, STORAGE); \
if (0 == var) \
{ \
TCU_FAIL("Memory allocation"); \
} \
VECTOR.push_back(var); \
return VECTOR.back(); \
}
/** Represents structures and block
*
**/
struct Interface
{
public:
/* Typedefs */
typedef std::vector<Interface> Vector;
typedef std::vector<Interface*> PtrVector;
/**/
enum TYPE
{
STRUCT,
BLOCK
};
/* Constructor */
Interface(const glw::GLchar* name, TYPE type);
/* */
Variable::Descriptor* Member(const glw::GLchar* name, const glw::GLchar* qualifiers, glw::GLint expected_component,
glw::GLint expected_location, const Type& type, glw::GLboolean normalized,
glw::GLuint n_array_elements, glw::GLint expected_stride_of_element,
glw::GLuint offset);
Variable::Descriptor* Member(const glw::GLchar* name, const glw::GLchar* qualifiers, glw::GLint expected_component,
glw::GLint expected_location, Interface* interface, glw::GLuint n_array_elements,
glw::GLint expected_stride_of_element, glw::GLuint offset);
/**/
Variable::Descriptor* AddMember(const Variable::Descriptor& member);
std::string GetDefinition() const;
/**/
Variable::Descriptor::Vector m_members;
std::string m_name;
TYPE m_type;
};
struct ShaderInterface
{
ShaderInterface(Shader::STAGES stage);
DEFINE_VARIABLE_CLASS(Input, Variable::VARYING_INPUT, m_inputs);
DEFINE_VARIABLE_CLASS(Output, Variable::VARYING_OUTPUT, m_outputs);
DEFINE_VARIABLE_CLASS(Uniform, Variable::UNIFORM, m_uniforms);
DEFINE_VARIABLE_CLASS(SSB, Variable::SSB, m_ssb_blocks);
/**/
std::string GetDefinitionsGlobals() const;
std::string GetDefinitionsInputs() const;
std::string GetDefinitionsOutputs() const;
std::string GetDefinitionsSSBs() const;
std::string GetDefinitionsUniforms() const;
std::string m_globals;
Variable::PtrVector m_inputs;
Variable::PtrVector m_outputs;
Variable::PtrVector m_uniforms;
Variable::PtrVector m_ssb_blocks;
Shader::STAGES m_stage;
};
struct VaryingConnection
{
/* */
typedef std::vector<VaryingConnection> Vector;
/* */
VaryingConnection(Variable* in, Variable* out);
/* */
Variable* m_in;
Variable* m_out;
};
struct VaryingPassthrough
{
/* */
void Add(Shader::STAGES stage, Variable* in, Variable* out);
VaryingConnection::Vector& Get(Shader::STAGES stage);
/**/
VaryingConnection::Vector m_fragment;
VaryingConnection::Vector m_geometry;
VaryingConnection::Vector m_tess_ctrl;
VaryingConnection::Vector m_tess_eval;
VaryingConnection::Vector m_vertex;
};
struct ProgramInterface
{
/* */
ProgramInterface();
~ProgramInterface();
/* */
Interface* AddInterface(const glw::GLchar* name, Interface::TYPE type);
Interface* Block(const glw::GLchar* name);
Interface* GetBlock(const glw::GLchar* name);
ShaderInterface& GetShaderInterface(Shader::STAGES stage);
const ShaderInterface& GetShaderInterface(Shader::STAGES stage) const;
Interface* GetStructure(const glw::GLchar* name);
Interface* Structure(const glw::GLchar* name);
/**/
std::string GetDefinitionsStructures() const;
std::string GetInterfaceForStage(Shader::STAGES stage) const;
/* */
Interface* CloneBlockForStage(const Interface& block, Shader::STAGES stage, Variable::STORAGE storage,
const glw::GLchar* prefix);
void CloneVertexInterface(VaryingPassthrough& variable_pass);
/* */
static const glw::GLchar* GetStagePrefix(Shader::STAGES stage, Variable::STORAGE storage);
/* */
Interface::PtrVector m_structures;
Interface::PtrVector m_blocks;
ShaderInterface m_compute;
ShaderInterface m_vertex;
ShaderInterface m_tess_ctrl;
ShaderInterface m_tess_eval;
ShaderInterface m_geometry;
ShaderInterface m_fragment;
//Variable::Vector m_fragment_outputs;
//Variable::PtrVector m_captured_varyings;
private:
/* */
void cloneVariableForStage(const Variable& variable, Shader::STAGES stage, const glw::GLchar* prefix,
VaryingPassthrough& varying_passthrough);
Variable* cloneVariableForStage(const Variable& variable, Shader::STAGES stage, Variable::STORAGE storage,
const glw::GLchar* prefix);
void replaceBinding(Variable& variable, Shader::STAGES stage);
};
/** Represents program pipeline
*
**/
class Pipeline
{
public:
/* Public methods */
/* Ctr & Dtr */
Pipeline(deqp::Context& context);
~Pipeline();
/* Init & Release */
void Init();
void Release();
/* Functionality */
void Bind();
void UseProgramStages(glw::GLuint program_id, glw::GLenum stages);
/* Public static routines */
/* Functionality */
void Bind(const glw::Functions& gl, glw::GLuint id);
void UseProgramStages(const glw::Functions& gl, glw::GLuint id, glw::GLuint program_id, glw::GLenum stages);
/* Public fields */
glw::GLuint m_id;
/* Public constants */
static const glw::GLuint m_invalid_id;
private:
/* Private fields */
deqp::Context& m_context;
};
/** Represents program instance.
* Provides basic functionality
**/
class Program
{
public:
/* Public types */
class BuildException : public std::exception
{
public:
BuildException(const glw::GLchar* error_message, const std::string compute_shader,
const std::string fragment_shader, const std::string geometry_shader,
const std::string tess_ctrl_shader, const std::string tess_eval_shader,
const std::string vertex_shader);
virtual ~BuildException() throw()
{
}
virtual const char* what() const throw();
void log(deqp::Context& context) const;
std::string m_error_message;
std::string m_compute_shader;
std::string m_fragment_shader;
std::string m_geometry_shader;
std::string m_tess_ctrl_shader;
std::string m_tess_eval_shader;
std::string m_vertex_shader;
};
typedef std::vector<std::string> NameVector;
/* Public methods */
/* Ctr & Dtr */
Program(deqp::Context& context);
~Program();
/* Init & Release */
void Init(const std::string& compute_shader, const std::string& fragment_shader, const std::string& geometry_shader,
const std::string& tessellation_control_shader, const std::string& tessellation_evaluation_shader,
const std::string& vertex_shader, const NameVector& captured_varyings, bool capture_interleaved,
bool is_separable);
void Init(const std::string& compute_shader, const std::string& fragment_shader, const std::string& geometry_shader,
const std::string& tessellation_control_shader, const std::string& tessellation_evaluation_shader,
const std::string& vertex_shader, bool is_separable);
void Release();
/* Functionality */
void GetActiveUniformsiv(glw::GLsizei count, const glw::GLuint* indices, glw::GLenum pname,
glw::GLint* params) const;
glw::GLint GetAttribLocation(const std::string& name) const;
void GetResource(glw::GLenum interface, glw::GLuint index, glw::GLenum property, glw::GLsizei buf_size,
glw::GLint* params) const;
glw::GLuint GetResourceIndex(const std::string& name, glw::GLenum interface) const;
void GetUniformIndices(glw::GLsizei count, const glw::GLchar** names, glw::GLuint* indices) const;
glw::GLint GetUniformLocation(const std::string& name) const;
void Use() const;
/* Public static routines */
/* Functionality */
static void Attach(const glw::Functions& gl, glw::GLuint program_id, glw::GLuint shader_id);
static void Capture(const glw::Functions& gl, glw::GLuint id, const NameVector& captured_varyings,
bool capture_interleaved);
static void Create(const glw::Functions& gl, glw::GLuint& out_id);
static void GetActiveUniformsiv(const glw::Functions& gl, glw::GLuint program_id, glw::GLsizei count,
const glw::GLuint* indices, glw::GLenum pname, glw::GLint* params);
static void GetUniformIndices(const glw::Functions& gl, glw::GLuint program_id, glw::GLsizei count,
const glw::GLchar** names, glw::GLuint* indices);
static void Link(const glw::Functions& gl, glw::GLuint id);
static void Uniform(const glw::Functions& gl, const Type& type, glw::GLsizei count, glw::GLint location,
const glw::GLvoid* data);
static void Use(const glw::Functions& gl, glw::GLuint id);
/* Get locations */
static glw::GLint GetAttribLocation(const glw::Functions& gl, glw::GLuint id, const std::string& name);
static void GetResource(const glw::Functions& gl, glw::GLuint id, glw::GLenum interface, glw::GLuint index,
glw::GLenum property, glw::GLsizei buf_size, glw::GLint* params);
static glw::GLuint GetResourceIndex(const glw::Functions& gl, glw::GLuint id, const std::string& name,
glw::GLenum interface);
static glw::GLint GetUniformLocation(const glw::Functions& gl, glw::GLuint id, const std::string& name);
/* Public fields */
glw::GLuint m_id;
Shader m_compute;
Shader m_fragment;
Shader m_geometry;
Shader m_tess_ctrl;
Shader m_tess_eval;
Shader m_vertex;
/* Public constants */
static const glw::GLuint m_invalid_id;
private:
/* Private types */
class LinkageException : public std::exception
{
public:
LinkageException(const glw::GLchar* error_message);
virtual ~LinkageException() throw()
{
}
virtual const char* what() const throw();
std::string m_error_message;
};
/* Private fields */
deqp::Context& m_context;
};
class Texture
{
public:
/* Public enums */
enum TYPES
{
TEX_BUFFER,
TEX_2D,
TEX_2D_RECT,
TEX_2D_ARRAY,
TEX_3D,
TEX_CUBE,
TEX_1D,
TEX_1D_ARRAY,
};
/* Public methods */
/* Ctr & Dtr */
Texture(deqp::Context& context);
~Texture();
/* Init & Release */
void Init(TYPES tex_type, glw::GLuint width, glw::GLuint height, glw::GLuint depth, glw::GLenum internal_format,
glw::GLenum format, glw::GLenum type, glw::GLvoid* data);
void Init(glw::GLenum internal_format, glw::GLuint buffer_id);
void Release();
/* Functionality */
void Bind() const;
void Get(glw::GLenum format, glw::GLenum type, glw::GLvoid* out_data) const;
/* Public static routines */
/* Functionality */
static void Bind(const glw::Functions& gl, glw::GLuint id, TYPES tex_type);
static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
static void Get(const glw::Functions& gl, TYPES tex_type, glw::GLenum format, glw::GLenum type,
glw::GLvoid* out_data);
static void Storage(const glw::Functions& gl, TYPES tex_type, glw::GLuint width, glw::GLuint height,
glw::GLuint depth, glw::GLenum internal_format);
static void TexBuffer(const glw::Functions& gl, glw::GLenum internal_format, glw::GLuint& buffer_id);
static void Update(const glw::Functions& gl, TYPES tex_type, glw::GLuint width, glw::GLuint height,
glw::GLuint depth, glw::GLenum format, glw::GLenum type, glw::GLvoid* data);
/* GL gets */
static glw::GLenum GetTargetGLenum(TYPES tex_type);
/* Public fields */
glw::GLuint m_id;
/* Public constants */
static const glw::GLuint m_invalid_id;
private:
deqp::Context& m_context;
TYPES m_type;
};
/** Represents Vertex array object
* Provides basic functionality
**/
class VertexArray
{
public:
/* Public methods */
/* Ctr & Dtr */
VertexArray(deqp::Context& Context);
~VertexArray();
/* Init & Release */
void Init();
//void Init(const ProgramInterface& program_interface,
// glw::GLuint vertex_buffer,
// glw::GLuint index_buffer);
void Release();
void Attribute(glw::GLuint index, const Type& type, glw::GLuint n_array_elements, glw::GLboolean normalized,
glw::GLsizei stride, const glw::GLvoid* pointer);
void Bind();
/* Public static methods */
static void AttribPointer(const glw::Functions& gl, glw::GLuint index, const Type& type,
glw::GLuint n_array_elements, glw::GLboolean normalized, glw::GLsizei stride,
const glw::GLvoid* pointer);
static void Bind(const glw::Functions& gl, glw::GLuint id);
static void Disable(const glw::Functions& gl, glw::GLuint index, const Type& type, glw::GLuint n_array_elements);
static void Divisor(const glw::Functions& gl, glw::GLuint index, glw::GLuint divisor);
static void Enable(const glw::Functions& gl, glw::GLuint index, const Type& type, glw::GLuint n_array_elements);
static void Generate(const glw::Functions& gl, glw::GLuint& out_id);
/* Public fields */
glw::GLuint m_id;
/* Public constants */
static const glw::GLuint m_invalid_id;
private:
deqp::Context& m_context;
};
/* UniformN*v prototypes */
typedef GLW_APICALL void(GLW_APIENTRY* uniformNdv)(glw::GLint, glw::GLsizei, const glw::GLdouble*);
typedef GLW_APICALL void(GLW_APIENTRY* uniformNfv)(glw::GLint, glw::GLsizei, const glw::GLfloat*);
typedef GLW_APICALL void(GLW_APIENTRY* uniformNiv)(glw::GLint, glw::GLsizei, const glw::GLint*);
typedef GLW_APICALL void(GLW_APIENTRY* uniformNuiv)(glw::GLint, glw::GLsizei, const glw::GLuint*);
typedef GLW_APICALL void(GLW_APIENTRY* uniformMatrixNdv)(glw::GLint, glw::GLsizei, glw::GLboolean,
const glw::GLdouble*);
typedef GLW_APICALL void(GLW_APIENTRY* uniformMatrixNfv)(glw::GLint, glw::GLsizei, glw::GLboolean, const glw::GLfloat*);
/* Public static methods */
/* UniformN*v routine getters */
uniformNdv getUniformNdv(const glw::Functions& gl, glw::GLuint n_rows);
uniformNfv getUniformNfv(const glw::Functions& gl, glw::GLuint n_rows);
uniformNiv getUniformNiv(const glw::Functions& gl, glw::GLuint n_rows);
uniformNuiv getUniformNuiv(const glw::Functions& gl, glw::GLuint n_rows);
uniformMatrixNdv getUniformMatrixNdv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows);
uniformMatrixNfv getUniformMatrixNfv(const glw::Functions& gl, glw::GLuint n_columns, glw::GLuint n_rows);
/* Stuff */
bool checkProgramInterface(const ProgramInterface& program_interface, Program& program, std::stringstream& stream);
bool isExtensionSupported(deqp::Context& context, const glw::GLchar* extension_name);
bool isGLVersionAtLeast(const glw::Functions& gl, glw::GLint required_major, glw::GLint required_minor);
void replaceToken(const glw::GLchar* token, size_t& search_position, const glw::GLchar* text, std::string& string);
void replaceAllTokens(const glw::GLchar* token, const glw::GLchar* text, std::string& string);
glw::GLuint roundUpToPowerOf2(glw::GLuint value);
void insertElementOfList(const glw::GLchar* element, const glw::GLchar* separator, size_t& search_position,
std::string& string);
void endList(const glw::GLchar* separator, size_t& search_position, std::string& string);
} /* Utils namespace */
/** Base class for tests **/
class TestBase : public deqp::TestCase
{
public:
/* Public methods */
TestBase(deqp::Context& context, const glw::GLchar* test_name, const glw::GLchar* test_description);
virtual ~TestBase()
{
}
/* Public methods inherited from TestCase */
virtual tcu::TestNode::IterateResult iterate(void);
protected:
/* Methods to be implemented by child class */
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool testCase(glw::GLuint test_case_index) = 0;
virtual void testInit();
/* Routines avaiable for children */
glw::GLuint calculateStride(const Utils::Interface& interface) const;
void generateData(const Utils::Interface& interface, glw::GLuint offset, std::vector<glw::GLubyte>& out_data) const;
glw::GLint getLastInputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, glw::GLuint array_lenth, bool ignore_prev_stage);
glw::GLint getLastOutputLocation(Utils::Shader::STAGES stage, const Utils::Type& type, glw::GLuint array_lenth, bool ignore_next_stage);
Utils::Type getType(glw::GLuint index) const;
std::string getTypeName(glw::GLuint index) const;
glw::GLuint getTypesNumber() const;
bool isFlatRequired(Utils::Shader::STAGES stage, const Utils::Type& type, Utils::Variable::STORAGE storage) const;
private:
/* Private methods */
bool test();
};
/** Base class for test doing Buffer alghorithm **/
class BufferTestBase : public TestBase
{
public:
/* Public methods */
BufferTestBase(deqp::Context& context, const glw::GLchar* test_name, const glw::GLchar* test_description);
virtual ~BufferTestBase()
{
}
protected:
/* */
struct bufferDescriptor
{
/* Typedefs */
typedef std::vector<bufferDescriptor> Vector;
/* Fileds */
std::vector<glw::GLubyte> m_expected_data;
std::vector<glw::GLubyte> m_initial_data;
glw::GLuint m_index;
Utils::Buffer::BUFFERS m_target;
/* Constants */
static const glw::GLuint m_non_indexed;
};
class bufferCollection
{
public:
struct pair
{
Utils::Buffer* m_buffer;
bufferDescriptor* m_descriptor;
};
~bufferCollection();
typedef std::vector<pair> Vector;
Vector m_vector;
};
virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index);
virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors);
virtual void getCapturedVaryings(glw::GLuint test_case_index, Utils::Program::NameVector& captured_varyings, glw::GLint* xfb_components);
virtual void getShaderBody(glw::GLuint test_case_index, Utils::Shader::STAGES stage, std::string& out_assignments,
std::string& out_calculations);
virtual void getShaderInterface(glw::GLuint test_case_index, Utils::Shader::STAGES stage,
std::string& out_interface);
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual bool inspectProgram(glw::GLuint test_case_index, Utils::Program& program, std::stringstream& out_stream);
virtual bool testCase(glw::GLuint test_case_index);
virtual bool verifyBuffers(bufferCollection& buffers);
private:
void cleanBuffers();
std::string getShaderTemplate(Utils::Shader::STAGES stage);
void prepareBuffer(Utils::Buffer& buffer, bufferDescriptor& descriptor);
void prepareBuffers(bufferDescriptor::Vector& descriptors, bufferCollection& out_buffers);
/* */
};
class NegativeTestBase : public TestBase
{
public:
/* Public methods */
NegativeTestBase(deqp::Context& context, const glw::GLchar* test_name, const glw::GLchar* test_description);
virtual ~NegativeTestBase()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage) = 0;
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isFailureExpected(glw::GLuint test_case_index);
virtual bool testCase(glw::GLuint test_case_index);
};
/** Base class for test doing Texture alghorithm **/
class TextureTestBase : public TestBase
{
public:
/* Public methods */
TextureTestBase(deqp::Context& context, const glw::GLchar* test_name, const glw::GLchar* test_description);
virtual ~TextureTestBase()
{
}
protected:
/* Methods to be implemented by child class */
virtual bool checkResults(glw::GLuint test_case_index, Utils::Texture& color_0);
virtual void executeDispatchCall(glw::GLuint test_case_index);
virtual void executeDrawCall(glw::GLuint test_case_index);
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual std::string getPassSnippet(glw::GLuint test_case_index, Utils::VaryingPassthrough& varying_passthrough,
Utils::Shader::STAGES stage);
virtual std::string getVerificationSnippet(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Shader::STAGES stage);
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isDrawRelevant(glw::GLuint test_case_index);
virtual void prepareAttributes(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Buffer& buffer, Utils::VertexArray& vao);
virtual void prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface);
virtual void prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface);
virtual void prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture);
virtual void prepareImage(glw::GLint location, Utils::Texture& image_texture) const;
virtual void prepareSSBs(glw::GLuint test_case_index, Utils::ShaderInterface& si, Utils::Program& program,
Utils::Buffer& buffer);
virtual void prepareSSBs(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Program& program, Utils::Buffer& cs_buffer);
virtual void prepareSSBs(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer);
virtual void prepareUniforms(glw::GLuint test_case_index, Utils::ShaderInterface& si, Utils::Program& program,
Utils::Buffer& buffer);
virtual void prepareUniforms(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Program& program, Utils::Buffer& cs_buffer);
virtual void prepareUniforms(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer);
virtual void prepareUniforms(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Program& fs_program, Utils::Program& gs_program, Utils::Program& tcs_program,
Utils::Program& tes_program, Utils::Program& vs_program, Utils::Buffer& fs_buffer,
Utils::Buffer& gs_buffer, Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer,
Utils::Buffer& vs_buffer);
//virtual void prepareDrawPrograms (glw::GLuint test_case_index,
// Utils::Program& fragment,
// Utils::Program& geometry,
// Utils::Program& tess_ctrl,
// Utils::Program& tess_eval,
// Utils::Program& vertex);
virtual bool testCase(glw::GLuint test_case_index);
virtual bool testMonolithic(glw::GLuint test_case_index);
virtual bool testSeparable(glw::GLuint test_case_index);
virtual bool useComponentQualifier(glw::GLuint test_case_index);
virtual bool useMonolithicProgram(glw::GLuint test_case_index);
/* Protected constants */
static const glw::GLuint m_width;
static const glw::GLuint m_height;
private:
std::string getShaderSource(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough, Utils::Shader::STAGES stage);
const glw::GLchar* getShaderTemplate(Utils::Shader::STAGES stage);
std::string getVariablePassthrough(const std::string& in_parent_name,
const Utils::Variable::Descriptor& in_variable,
Utils::Variable::FLAVOUR in_flavour, const std::string& out_parent_name,
const Utils::Variable::Descriptor& out_variable,
Utils::Variable::FLAVOUR out_flavour);
std::string getVariableVerification(const std::string& parent_name, const glw::GLvoid* data,
const Utils::Variable::Descriptor& variable, Utils::Variable::FLAVOUR flavour);
void prepareSSB(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer);
void prepareUniform(Utils::Program& program, Utils::Variable& variable, Utils::Buffer& buffer);
};
/** Implementation of test APIConstantValues. Description follows:
*
* Test verifies values of the following constants are at least as specified:
* - MAX_TRANSFORM_FEEDBACK_BUFFERS - 4,
* - MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS - 64.
**/
class APIConstantValuesTest : public deqp::TestCase
{
public:
/* Public methods */
APIConstantValuesTest(deqp::Context& context);
virtual ~APIConstantValuesTest()
{
}
/* Public methods inherited from TestCase */
virtual tcu::TestNode::IterateResult iterate(void);
};
/** Implementation of test APIErrors. Description follows:
*
* Test verifies that errors are generated as specified:
* - GetProgramInterfaceiv should generate INVALID_OPERATION when
* <programInterface> is TRANSFORM_FEEDBACK_BUFFER and <pname> is
* MAX_NAME_LENGTH;
* - GetProgramResourceIndex should generate INVALID_ENUM when
* <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
* - GetProgramResourceName should generate INVALID_ENUM when
* <programInterface> is TRANSFORM_FEEDBACK_BUFFER;
**/
class APIErrorsTest : public deqp::TestCase
{
public:
/* Public methods */
APIErrorsTest(deqp::Context& context);
virtual ~APIErrorsTest()
{
}
/* Public methods inherited from TestCase */
virtual tcu::TestNode::IterateResult iterate(void);
private:
void checkError(glw::GLenum expected_error, const glw::GLchar* message, bool& test_result);
};
/** Implementation of test GLSLContantValues. Description follows:
*
* Test verifies values of the following symbols:
*
* GL_ARB_enhanced_layouts,
* gl_MaxTransformFeedbackBuffers,
* gl_MaxTransformFeedbackInterleavedComponents.
*
* This test implements Texture algorithm. Test following code snippet:
*
* if (1 != GL_ARB_enhanced_layouts)
* {
* result = 0;
* }
* else if (MAX_TRANSFORM_FEEDBACK_BUFFERS
* != gl_MaxTransformFeedbackBuffers)
* {
* result = 0;
* }
* else if (MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS
* != gl_MaxTransformFeedbackInterleavedComponents)
* {
* result = 0;
* }
**/
class GLSLContantValuesTest : public TextureTestBase
{
public:
GLSLContantValuesTest(deqp::Context& context);
~GLSLContantValuesTest()
{
}
protected:
virtual std::string getVerificationSnippet(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Shader::STAGES stage);
virtual bool isComputeRelevant(glw::GLuint test_case_index);
};
/** Implementation of test GLSLContantImmutablity. Description follows:
*
* Test verifies that values of the following symbols cannot be changed in
* shader:
*
* GL_ARB_enhanced_layouts,
* gl_MaxTransformFeedbackBuffers,
* gl_MaxTransformFeedbackInterleavedComponents.
*
* Compile following code snippet:
*
* CONSTANT = 3;
*
* It is expected that compilation will fail. Test each shader stage
* separately. Test each constant separately.
**/
class GLSLContantImmutablityTest : public NegativeTestBase
{
public:
/* Public methods */
GLSLContantImmutablityTest(deqp::Context& context);
virtual ~GLSLContantImmutablityTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private enums */
enum CONSTANTS
{
GL_ARB_ENHANCED_LAYOUTS,
GL_MAX_XFB,
GL_MAX_XFB_INT_COMP,
/* */
CONSTANTS_MAX,
};
/* Private types */
struct testCase
{
CONSTANTS m_constant;
Utils::Shader::STAGES m_stage;
};
/* Private methods */
const glw::GLchar* getConstantName(CONSTANTS constant);
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test GLSLConstantIntegralExpression. Description follows:
*
* Check that following symbols can be used as integral constant expressions:
*
* GL_ARB_enhanced_layouts,
* gl_MaxTransformFeedbackBuffers,
* gl_MaxTransformFeedbackInterleavedComponents.
*
* Test implement Texture algorithm. Test following code snippet:
*
* uniform uint goku [GL_ARB_enhanced_layouts / GOKU_DIV];
* uniform uint gohan[gl_MaxTransformFeedbackBuffers / GOHAN_DIV];
* uniform uint goten[gl_MaxTransformFeedbackInterleavedComponents /
* GOTEN_DIV];
*
* for (i = 0; i < goku.length; ++i)
* goku_sum += goku[i];
*
* for (i = 0; i < gohan.length; ++i)
* gohan_sum += gohan[i];
*
* for (i = 0; i < goten.length; ++i)
* goten_sum += goten[i];
*
* if ( (expected_goku_sum == goku_sum) &&
* (expected_gohan_sum == gohan_sum) &&
* (expected_goten_sum == goten_sum) )
* result = 1;
* else
* result = 0;
*
* Select DIV values so as array lengths are below 16.
**/
class GLSLConstantIntegralExpressionTest : public TextureTestBase
{
public:
/* Public methods */
GLSLConstantIntegralExpressionTest(deqp::Context& context);
virtual ~GLSLConstantIntegralExpressionTest()
{
}
protected:
/* Protected methods */
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual std::string getVerificationSnippet(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Shader::STAGES stage);
virtual void prepareUniforms(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Program& program, Utils::Buffer& cs_buffer);
virtual void prepareUniforms(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Program& program, Utils::Buffer& fs_buffer, Utils::Buffer& gs_buffer,
Utils::Buffer& tcs_buffer, Utils::Buffer& tes_buffer, Utils::Buffer& vs_buffer);
private:
glw::GLint m_gohan_length;
glw::GLint m_goten_length;
};
/** Implementation of test UniformBlockMemberOffsetAndAlign. Description follows:
*
* Test verifies that:
* - offset and align qualifiers are respected for uniform block members,
* - align qualifier is ignored if value is too small,
* - align qualifier accepts values bigger than size of base type,
* - manual and automatic offsets and alignments can be mixed.
*
* This test implement Texture algorithm. Test following code snippet:
*
* const int basic_size = sizeof(basic_type_of(type));
* const int type_size = sizeof(type);
* const int type_align = roundUpToPowerOf2(type_size);
*
* layout (std140, offset = 0) uniform Block {
* layout(align = 8 * basic_size) type at_first_offset;
* layout(offset = type_size, align = basic_size / 2)
* type at_second_offset;
* layout(align = 2 * type_align) type at_third_offset;
* layout(offset = 3 * type_align + type_size)
* type at_fourth_offset;
* type at_fifth_offset;
* type at_sixth_offset[2];
* layout(align = 8 * basic_size) type at_eight_offset;
* };
*
* if ( (at_first_offset == at_eight_offset ) &&
* (at_second_offset == at_sixth_offset[1]) &&
* (at_third_offset == at_sixth_offset[0]) &&
* (at_fourth_offset == at_fifth_offset ) )
* result = 1;
* else
* result = 0;
*
* Additionally inspect program to verify that all block members:
* - are reported,
* - have correct offsets.
*
* Test should be executed for all types.
**/
class UniformBlockMemberOffsetAndAlignTest : public TextureTestBase
{
public:
/* Public methods */
UniformBlockMemberOffsetAndAlignTest(deqp::Context& context);
virtual ~UniformBlockMemberOffsetAndAlignTest()
{
}
protected:
/* Protected methods */
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual std::string getVerificationSnippet(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Shader::STAGES stage);
private:
std::vector<glw::GLubyte> m_data;
};
/** Implementation of test UniformBlockLayoutQualifierConflict. Description follows:
*
* Test verifies that offset and align can only be used on members of blocks
* declared as std140.
*
* Test following code snippet with all shader stages:
*
* layout(QUALIFIER) uniform Block {
* layout(offset = 16) vec4 boy;
* layout(align = 48) vec4 man;
* };
*
* Test following block qualifiers and all types:
*
* default - meaning not declared by shader
* std140,
* shared,
* packed.
*
* Qualifier std430 is not allowed for uniform blocks.
*
* Test expect that only case using std140 will compile and link successfully,
* while the rest will fail to compile or link.
**/
class UniformBlockLayoutQualifierConflictTest : public NegativeTestBase
{
public:
/* Public methods */
UniformBlockLayoutQualifierConflictTest(deqp::Context& context);
virtual ~UniformBlockLayoutQualifierConflictTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isFailureExpected(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private enums */
enum QUALIFIERS
{
DEFAULT,
STD140,
SHARED,
PACKED,
/* */
QUALIFIERS_MAX,
};
/* Private types */
struct testCase
{
QUALIFIERS m_qualifier;
Utils::Shader::STAGES m_stage;
};
/* Private methods */
const glw::GLchar* getQualifierName(QUALIFIERS qualifier);
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test UniformBlockMemberInvalidOffsetAlignment. Description follows:
*
* Test verifies that offset alignment rules are enforced.
*
* Declare uniform block, which contains following member declaration:
*
* layout(offset = X) type block_member
*
* Shader compilation is expected to fail for any X that is not a multiple of
* the base alignment of type.
* Test all offsets covering locations first and one before last:
*
* <0, sizeof(type)>
* <MAX_UNIFORM_BLOCK_SIZE - 2 * sizeof(type),
* MAX_UNIFORM_BLOCK_SIZE - sizeof(type)>
*
* Test all shader stages. Test all types. Each case should be tested
* separately.
**/
class UniformBlockMemberInvalidOffsetAlignmentTest : public NegativeTestBase
{
public:
/* Public methods */
UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context);
UniformBlockMemberInvalidOffsetAlignmentTest(deqp::Context& context, const glw::GLchar* name,
const glw::GLchar* description);
virtual ~UniformBlockMemberInvalidOffsetAlignmentTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual glw::GLint getMaxBlockSize();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isFailureExpected(glw::GLuint test_case_index);
virtual bool isStageSupported(Utils::Shader::STAGES stage);
virtual void testInit();
protected:
/* Protected types */
struct testCase
{
glw::GLuint m_offset;
bool m_should_fail;
Utils::Shader::STAGES m_stage;
Utils::Type m_type;
};
/* Protected fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test UniformBlockMemberOverlappingOffsets. Description follows:
*
* Test verifies that block members cannot overlap.
*
* Use following code snippet:
*
* layout (std140) uniform Block {
* layout (offset = boy_offset) boy_type boy;
* layout (offset = man_offset) man_type man;
* };
*
* It is expected that overlapping members will cause compilation failure.
*
* There are three cases to test:
*
* - when member is declared with the same offset as already declared
* member,
* - when member is declared with offset that lay in the middle of already
* declared member,
* - when member is declared with offset just before already declared
* member and there is not enough space.
*
* Test all shader stages. Test all types. Test cases separately.
*
* Note that not all type combinations let to test all three cases, e.g.
* vec4 and float.
**/
class UniformBlockMemberOverlappingOffsetsTest : public NegativeTestBase
{
public:
/* Public methods */
UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context);
UniformBlockMemberOverlappingOffsetsTest(deqp::Context& context, const glw::GLchar* name,
const glw::GLchar* description);
virtual ~UniformBlockMemberOverlappingOffsetsTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isStageSupported(Utils::Shader::STAGES stage);
virtual void testInit();
protected:
/* Protected types */
struct testCase
{
glw::GLuint m_boy_offset;
Utils::Type m_boy_type;
glw::GLuint m_man_offset;
Utils::Type m_man_type;
Utils::Shader::STAGES m_stage;
};
/* Protected methods */
glw::GLuint gcd(glw::GLuint a, glw::GLuint b);
glw::GLuint lcm(glw::GLuint a, glw::GLuint b);
/* Protected fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test UniformBlockMemberAlignNonPowerOf2. Description follows:
*
* Test verifies that align qualifier must use power of 2.
*
* Test following code snippet:
*
* layout (std140, offset = 8) uniform Block {
* vec4 boy;
* layout (align = man_alignment) type man;
* };
*
* It is expected that compilation will fail whenever man_alignment is not
* a power of 2.
*
* Test all alignment in range <0, sizeof(dmat4)>. Test all shader stages.
* Test all types.
**/
class UniformBlockMemberAlignNonPowerOf2Test : public NegativeTestBase
{
public:
/* Public methods */
UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context);
UniformBlockMemberAlignNonPowerOf2Test(deqp::Context& context, const glw::GLchar* name,
const glw::GLchar* description);
virtual ~UniformBlockMemberAlignNonPowerOf2Test()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isFailureExpected(glw::GLuint test_case_index);
virtual bool isStageSupported(Utils::Shader::STAGES stage);
virtual void testInit();
protected:
/* Protected types */
struct testCase
{
glw::GLuint m_alignment;
Utils::Type m_type;
bool m_should_fail;
Utils::Shader::STAGES m_stage;
};
/* Protected methods */
bool isPowerOf2(glw::GLuint val);
/* Protected fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test UniformBlockAlignment. Description follows:
*
* UniformBlockAlignment
*
* Test verifies that align qualifier is applied to block members as specified.
*
* This test implements Texture algorithm. Test following code snippet:
*
* struct Data {
* vec4 vector;
* float scalar;
* };
*
* layout (std140, offset = 8, align = 64) uniform Block {
* vec4 first;
* Data second;
* Data third[2];
* vec4 fourth[3];
* layout (align = 16) vec4 fifth[2];
* Data sixth;
* };
*
* Verify that all uniforms have correct values. Additionally inspect program
* to check that all offsets are as expected.
**/
class UniformBlockAlignmentTest : public TextureTestBase
{
public:
/* Public methods */
UniformBlockAlignmentTest(deqp::Context& context);
virtual ~UniformBlockAlignmentTest()
{
}
protected:
/* Protected methods */
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
private:
std::vector<glw::GLubyte> m_data;
};
/** Implementation of test SSBMemberOffsetAndAlign. Description follows:
*
* Test verifies that:
* - offset and align qualifiers are respected for shader storage block
* members,
* - align qualifier is ignored if value is too small,
* - align qualifier accepts values bigger than size of base type,
* - manual and automatic offsets and alignments can be mixed.
*
* Modify UniformBlockMemberOffsetAndAlign to test shader storage block instead
* of uniform block.
**/
class SSBMemberOffsetAndAlignTest : public TextureTestBase
{
public:
/* Public methods */
SSBMemberOffsetAndAlignTest(deqp::Context& context);
virtual ~SSBMemberOffsetAndAlignTest()
{
}
protected:
/* Protected methods */
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual std::string getVerificationSnippet(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Shader::STAGES stage);
virtual bool isDrawRelevant(glw::GLuint test_case_index);
private:
std::vector<glw::GLubyte> m_data;
};
/** Implementation of test SSBLayoutQualifierConflict. Description follows:
*
* Test verifies that offset and align can only be used on members of blocks
* declared as std140 or std430.
*
* Modify UniformBlockMemberOffsetAndAlign to test shader storage block instead
* of uniform block.
*
* Qualifier std430 is allowed for shader storage blocks, it should be included
* in test. It is expected that std430 case will build successfully.
**/
class SSBLayoutQualifierConflictTest : public NegativeTestBase
{
public:
/* Public methods */
SSBLayoutQualifierConflictTest(deqp::Context& context);
virtual ~SSBLayoutQualifierConflictTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isFailureExpected(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private enums */
enum QUALIFIERS
{
DEFAULT,
STD140,
STD430,
SHARED,
PACKED,
/* */
QUALIFIERS_MAX,
};
/* Private types */
struct testCase
{
QUALIFIERS m_qualifier;
Utils::Shader::STAGES m_stage;
};
/* Private methods */
const glw::GLchar* getQualifierName(QUALIFIERS qualifier);
bool isStageSupported(Utils::Shader::STAGES stage);
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test SSBMemberInvalidOffsetAlignment. Description follows:
*
* Test verifies that offset alignment rules are enforced.
*
* Modify UniformBlockMemberInvalidOffsetAlignment to test shader
* storage block against MAX_SHADER_STORAGE_BLOCK_SIZE instead of
* uniform block
**/
class SSBMemberInvalidOffsetAlignmentTest : public UniformBlockMemberInvalidOffsetAlignmentTest
{
public:
/* Public methods */
SSBMemberInvalidOffsetAlignmentTest(deqp::Context& context);
virtual ~SSBMemberInvalidOffsetAlignmentTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual glw::GLint getMaxBlockSize();
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual bool isStageSupported(Utils::Shader::STAGES stage);
};
/** Implementation of test SSBMemberOverlappingOffsets. Description follows:
*
* Test verifies that block members cannot overlap.
*
* Modify UniformBlockMemberOverlappingOffsets to test shader storage block
* instead of uniform block.
**/
class SSBMemberOverlappingOffsetsTest : public UniformBlockMemberOverlappingOffsetsTest
{
public:
/* Public methods */
SSBMemberOverlappingOffsetsTest(deqp::Context& context);
virtual ~SSBMemberOverlappingOffsetsTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual bool isStageSupported(Utils::Shader::STAGES stage);
};
/** Implementation of test SSBMemberAlignNonPowerOf2. Description follows:
*
* Test verifies that align qualifier must use power of 2.
*
* Modify UniformBlockMemberAlignNonPowerOf2 to test shader storage block
* instead of uniform block.
**/
class SSBMemberAlignNonPowerOf2Test : public UniformBlockMemberAlignNonPowerOf2Test
{
public:
/* Public methods */
SSBMemberAlignNonPowerOf2Test(deqp::Context& context);
virtual ~SSBMemberAlignNonPowerOf2Test()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual bool isStageSupported(Utils::Shader::STAGES stage);
};
/** Implementation of test SSBAlignment. Description follows:
*
* Test verifies that align qualifier is applied to block members as specified.
*
* Modify UniformBlockAlignment to test shader storage block instead
* of uniform block.
**/
class SSBAlignmentTest : public TextureTestBase
{
public:
/* Public methods */
SSBAlignmentTest(deqp::Context& context);
virtual ~SSBAlignmentTest()
{
}
protected:
/* Protected methods */
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual bool isDrawRelevant(glw::GLuint test_case_index);
private:
std::vector<glw::GLubyte> m_data;
};
/** Implementation of test VaryingLocations. Description follows:
*
* Test verifies that "varying" locations are assigned as declared in shader.
*
* This test implements Texture algorithm. Use separate shader objects instead
* of monolithic program. Test following code snippet:
*
* layout(location = 0) in type input_at_first_location;
* layout(location = last_input) in type input_at_last_location;
* layout(location = 1) out type output_at_first_location;
* layout(location = last_output) out type output_at_last_location;
*
* output_at_first_location = input_at_first_location;
* output_at_last_location = input_at_last_location;
*
* if ( (EXPECTED_VALUE == input_at_first_location) &&
* (EXPECTED_VALUE == input_at_last_location) )
* {
* result = 1;
* }
*
* Additionally inspect program to check that all locations are as expected.
*
* Test all types. Test all shader stages.
**/
class VaryingLocationsTest : public TextureTestBase
{
public:
VaryingLocationsTest(deqp::Context& context);
VaryingLocationsTest(deqp::Context& context, const glw::GLchar* test_name, const glw::GLchar* test_description);
~VaryingLocationsTest()
{
}
protected:
/* Protected methods */
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool useMonolithicProgram(glw::GLuint test_case_index);
/* To be implemented by children */
virtual void prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
/* Protected methods */
std::string prepareGlobals(glw::GLint last_in_loc, glw::GLint last_out_loc);
/* Protected fields */
std::vector<glw::GLubyte> m_first_data;
std::vector<glw::GLubyte> m_last_data;
};
/** Implementation of test VertexAttribLocations. Description follows:
*
* Test verifies that drawing operations provide vertex attributes at expected
* locations.
*
* This test implements Texture algorithm. Use separate shader objects instead
* of monolithic program. Tessellation stages are not necessary and can be
* omitted. Test following code snippet:
*
* layout (location = 2) in uint vertex_index;
* layout (location = 5) in uint instance_index;
*
* if ( (gl_VertexID == vertex_index) &&
* (gl_InstanceID == instance_index) )
* {
* result = 1;
* }
*
* Test following Draw* operations:
* - DrawArrays,
* - DrawArraysInstanced,
* - DrawElements,
* - DrawElementsBaseVertex,
* - DrawElementsInstanced,
* - DrawElementsInstancedBaseInstance,
* - DrawElementsInstancedBaseVertex,
* - DrawElementsInstancedBaseVertexBaseInstance.
*
* Number of drawn instances should be equal 4. base_vertex parameter should be
* set to 4. base_instance should be set to 2.
*
* Values provided for "vertex_index" should match index of vertex. Values
* provided for "instance_index" should match index of instance
* (use VertexAttribDivisor).
**/
class VertexAttribLocationsTest : public TextureTestBase
{
public:
VertexAttribLocationsTest(deqp::Context& context);
~VertexAttribLocationsTest()
{
}
protected:
/* Protected methods */
virtual void executeDrawCall(glw::GLuint test_case_index);
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual std::string getVerificationSnippet(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Shader::STAGES stage);
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void prepareAttributes(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::Buffer& buffer, Utils::VertexArray& vao);
virtual bool useMonolithicProgram(glw::GLuint test_case_index);
private:
/* Private enums */
enum TESTCASES
{
DRAWARRAYS,
DRAWARRAYSINSTANCED,
DRAWELEMENTS,
DRAWELEMENTSBASEVERTEX,
DRAWELEMENTSINSTANCED,
DRAWELEMENTSINSTANCEDBASEINSTANCE,
DRAWELEMENTSINSTANCEDBASEVERTEX,
DRAWELEMENTSINSTANCEDBASEVERTEXBASEINSTANCE,
/* */
TESTCASES_MAX
};
/* Private constants */
static const glw::GLuint m_base_vertex;
static const glw::GLuint m_base_instance;
static const glw::GLuint m_loc_vertex;
static const glw::GLuint m_loc_instance;
static const glw::GLuint m_n_instances;
};
/** Implementation of test VaryingArrayLocations. Description follows:
*
* VaryingArrayLocations
*
* Test verifies that locations of arrays of "varying" are assigned as declared
* in shader.
*
* This test implements Texture algorithm. Use separate shader objects instead
* of monolithic program. Test following code snippet:
*
* layout(location = 0) in type in_at_first_loc[FIRST_LENGTH];
* layout(location = last_input) in type in_at_last_loc[LAST_LENGTH];
* layout(location = 1) out type out_at_first_loc[FIRST_LENGTH];
* layout(location = last_output) out type out_at_last_loc[LAST_LENGTH];
*
* for (uint i = 0u; i < in_at_first_loc.length(); ++i)
* {
* out_at_first_loc[i] = in_at_first_loc[i];
*
* if (EXPECTED_VALUE[i] != in_at_first_loc[i])
* {
* result = 0;
* }
* }
*
* for (uint i = 0u; i < in_at_last_loc.length(); ++i)
* {
* out_at_last_loc[i] = in_at_last_loc[i];
*
* if (EXPECTED_VALUE[i] != in_at_last_loc[i])
* {
* result = 0;
* }
* }
*
* FIRST_LENGTH and LAST_LENGTH values should be selected so as not to exceed
* limits.
*
* Additionally inspect program to check that all locations are as expected.
*
* Test all types. Test all shader stages.
**/
class VaryingArrayLocationsTest : public VaryingLocationsTest
{
public:
VaryingArrayLocationsTest(deqp::Context& context);
~VaryingArrayLocationsTest()
{
}
protected:
/* Protected methods */
virtual void prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& type,
Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
};
/** Implementation of test VaryingStructureLocations. Description follows:
*
* Test verifies that structures locations are as expected.
*
* This test implements Texture algorithm. Use separate shader objects instead
* of monolithic program. Test following code snippet:
*
* struct Data
* {
* type single;
* type array[ARRAY_LENGTH];
* };
*
* layout (location = INPUT_LOCATION) in Data input[VARYING_LENGTH];
* layout (location = OUTPUT_LOCATION) out Data output[VARYING_LENGTH];
*
* if ( (EXPECTED_VALUE == input[0].single) &&
* (EXPECTED_VALUE == input[0].array[0]) &&
* (EXPECTED_VALUE == input[0].array[last]) &&
* (EXPECTED_VALUE == input[last].single) &&
* (EXPECTED_VALUE == input[last].array[0]) &&
* (EXPECTED_VALUE == input[last].array[last]) )
* {
* result = 1;
* }
*
* output[0].single = input[0].single;
* output[0].array[0] = input[0].array[0];
* output[0].array[last] = input[0].array[last];
* output[last].single = input[last].single;
* output[last].array[0] = input[last].array[0];
* output[last].array[last] = input[last].array[last];
*
* Select array lengths and locations so as no limits are exceeded.
**/
class VaryingStructureLocationsTest : public TextureTestBase
{
public:
VaryingStructureLocationsTest(deqp::Context& context);
~VaryingStructureLocationsTest()
{
}
protected:
/* Protected methods */
virtual std::string getPassSnippet(glw::GLuint test_case_index, Utils::VaryingPassthrough& varying_passthrough,
Utils::Shader::STAGES stage);
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool useMonolithicProgram(glw::GLuint test_case_index);
/* Protected fields */
std::vector<glw::GLubyte> m_single_data;
std::vector<glw::GLubyte> m_array_data;
std::vector<glw::GLubyte> m_data;
};
/** Implementation of test VaryingStructureMemberLocation. Description follows:
*
* Test verifies that it is not allowed to declare structure member at specific
* location.
*
* Test following code snippet:
*
* struct Data
* {
* vec4 gohan;
* layout (location = LOCATION) vec4 goten;
* }
*
* in Data goku;
*
* Select LOCATION so as not to exceed limits. Test all shader stages. Test
* both in and out varyings.
*
* It is expected that compilation will fail.
**/
class VaryingStructureMemberLocationTest : public NegativeTestBase
{
public:
VaryingStructureMemberLocationTest(deqp::Context& context);
~VaryingStructureMemberLocationTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
bool m_is_input;
Utils::Shader::STAGES m_stage;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingBlockLocations. Description follows:
*
* Test verifies that "block varyings" locations are as expected.
*
* This test implements Texture algorithm. Use separate shader objects instead
* of monolithic program. Test following code snippet:
*
* layout (location = GOKU_LOCATION) in Goku
* {
* vec4 gohan;
* layout (location = GOTEN_LOCATION) vec4 goten;
* vec4 chichi;
* };
*
* layout (location = VEGETA_LOCATION) out Vegeta
* {
* vec4 trunks;
* layout (location = BRA_LOCATION) vec4 bra;
* vec4 bulma;
* };
*
* if ( (EXPECTED_VALUE == gohan) &&
* (EXPECTED_VALUE == goten) &&
* (EXPECTED_VALUE == chichi) )
* {
* result = 1;
* }
*
* trunks = gohan;
* bra = goten;
* bulma = chichi;
*
* Select all locations so as not to cause any conflicts or exceed limits.
**/
class VaryingBlockLocationsTest : public TextureTestBase
{
public:
VaryingBlockLocationsTest(deqp::Context& context);
~VaryingBlockLocationsTest()
{
}
protected:
/* Protected methods */
virtual std::string getPassSnippet(glw::GLuint test_case_index, Utils::VaryingPassthrough& varying_passthrough,
Utils::Shader::STAGES stage);
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool useMonolithicProgram(glw::GLuint test_case_index);
/* Protected fields */
std::vector<glw::GLubyte> m_third_data;
std::vector<glw::GLubyte> m_fourth_data;
std::vector<glw::GLubyte> m_fifth_data;
std::vector<glw::GLubyte> m_data;
};
/** Implementation of test VaryingBlockMemberLocations. Description follows:
*
* Test verifies that it is a compilation error to declare some of block
* members with location qualifier, but not all, when there is no "block level"
* location qualifier.
*
* Test following code snippets:
*
* in Goku
* {
* vec4 gohan;
* layout (location = GOTEN_LOCATION) vec4 goten;
* vec4 chichi;
* };
*
* ,
*
* in Goku
* {
* layout (location = GOHAN_LOCATION) vec4 gohan;
* layout (location = GOTEN_LOCATION) vec4 goten;
* layout (location = CHICHI_LOCATION) vec4 chichi;
* };
*
* Select all locations so as not to exceed any limits.
*
* It is expected that compilation of first snippet will fail. Compilation of
* second snippet should be successful.
*
* Test all shader stages. Test both in and out blocks.
**/
class VaryingBlockMemberLocationsTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingBlockMemberLocationsTest(deqp::Context& context);
virtual ~VaryingBlockMemberLocationsTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isFailureExpected(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
bool m_is_input;
bool m_qualify_all;
Utils::Shader::STAGES m_stage;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingBlockAutomaticMemberLocations. Description follows:
*
* Test verifies that compiler will assign subsequent locations to block
* members.
*
* Test following code snippet:
*
* layout (location = 2) in DBZ
* {
* vec4 goku; // 2
* vec4 gohan[GOHAN_LENGTH]; // 3
* vec4 goten; // 3 + GOHAN_LENGTH
* layout (location = 1) vec4 chichi; // 1
* vec4 pan; // 2; ERROR location 2 used twice
* };
*
* Test all shader stages. Test both in and out blocks.
*
* It is expected that build process will fail.
**/
class VaryingBlockAutomaticMemberLocationsTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingBlockAutomaticMemberLocationsTest(deqp::Context& context);
virtual ~VaryingBlockAutomaticMemberLocationsTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
bool m_is_input;
Utils::Shader::STAGES m_stage;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingLocationLimit. Description follows:
*
* Test verifies that "location" qualifier cannot exceed limits.
*
* Test following code snippet:
*
* layout (location = LAST + 1) in type goku;
*
* LAST should be set to index of last available location.
*
* Test all types. Test all shader stages. Test both in and out varyings.
*
* It is expected that shader compilation will fail.
**/
class VaryingLocationLimitTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingLocationLimitTest(deqp::Context& context);
virtual ~VaryingLocationLimitTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
bool m_is_input;
Utils::Type m_type;
Utils::Shader::STAGES m_stage;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingComponents. Description follows:
*
* VaryingComponents
*
* Test verifies that "varying" can be assigned to specific components.
*
* Modify VaryingLocations to test all possible combinations of components
* layout:
* - gvec4
* - scalar, gvec3
* - gvec3, scalar
* - gvec2, gvec2
* - gvec2, scalar, scalar
* - scalar, gvec2, scalar
* - scalar, scalar, gvec2
* - scalar, scalar, scalar, scalar.
*
* Additionally inspect program to check that all locations and components are
* as expected.
**/
class VaryingComponentsTest : public VaryingLocationsTest
{
public:
VaryingComponentsTest(deqp::Context& context);
VaryingComponentsTest(deqp::Context& context, const glw::GLchar* test_name, const glw::GLchar* test_description);
~VaryingComponentsTest()
{
}
protected:
/* Protected methods */
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual void testInit();
virtual bool useComponentQualifier(glw::GLuint test_case_index);
/* To be implemented by children */
virtual glw::GLuint getArrayLength();
private:
/* Private enums */
enum COMPONENTS_LAYOUT
{
GVEC4,
SCALAR_GVEC3,
GVEC3_SCALAR,
GVEC2_GVEC2,
GVEC2_SCALAR_SCALAR,
SCALAR_GVEC2_SCALAR,
SCALAR_SCALAR_GVEC2,
SCALAR_SCALAR_SCALAR_SCALAR,
};
/* Private struct */
struct descriptor
{
void assign(glw::GLint component, const glw::GLchar* component_str, glw::GLint location,
const glw::GLchar* location_str, glw::GLuint n_rows, const glw::GLchar* name);
glw::GLint m_component;
const glw::GLchar* m_component_str;
glw::GLint m_location;
const glw::GLchar* m_location_str;
glw::GLuint m_n_rows;
const glw::GLchar* m_name;
};
struct testCase
{
testCase(COMPONENTS_LAYOUT layout, Utils::Type::TYPES type);
COMPONENTS_LAYOUT m_layout;
Utils::Type::TYPES m_type;
};
/* Private routines */
std::string prepareGlobals(glw::GLuint last_in_location, glw::GLuint last_out_location);
std::string prepareName(const glw::GLchar* name, glw::GLint location, glw::GLint component,
Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage);
std::string prepareQualifiers(const glw::GLchar* location, const glw::GLchar* component,
const glw::GLchar* interpolation);
using VaryingLocationsTest::prepareShaderStage;
void prepareShaderStage(Utils::Shader::STAGES stage, const Utils::Type& vector_type,
Utils::ProgramInterface& program_interface, const testCase& test_case,
Utils::VaryingPassthrough& varying_passthrough);
Utils::Variable* prepareVarying(const Utils::Type& basic_type, const descriptor& desc,
const glw::GLchar* interpolation, Utils::ShaderInterface& si,
Utils::Shader::STAGES stage, Utils::Variable::STORAGE storage);
/* Private fields */
std::vector<testCase> m_test_cases;
std::vector<glw::GLubyte> m_data;
};
/** Implementation of test VaryingArrayComponents. Description follows:
*
* Test verifies that arrays of "varyings" can be assigned to specific
* components.
*
* Modify VaryingComponents similarly to VaryingArrayLocations.
**/
class VaryingArrayComponentsTest : public VaryingComponentsTest
{
public:
VaryingArrayComponentsTest(deqp::Context& context);
~VaryingArrayComponentsTest()
{
}
protected:
/* Protected methods */
virtual glw::GLuint getArrayLength();
};
/** Implementation of test VaryingExceedingComponents. Description follows:
*
* Test verifies that it is not allowed to exceed components.
*
* Test following code snippets:
*
* layout (location = 1, component = COMPONENT) in type gohan;
*
* and
*
* layout (location = 1, component = COMPONENT) in type gohan[LENGTH];
*
* Select COMPONENT so as to exceed space available at location, eg. 2 for
* vec4. Select array length so as to not exceed limits of available locations.
*
* Test all types. Test all shader stages. Test both in and out varyings.
*
* It is expected that build process will fail.
**/
class VaryingExceedingComponentsTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingExceedingComponentsTest(deqp::Context& context);
virtual ~VaryingExceedingComponentsTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
glw::GLuint m_component;
bool m_is_input;
bool m_is_array;
Utils::Shader::STAGES m_stage;
Utils::Type m_type;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingComponentWithoutLocation. Description follows:
*
* Test verifies that "component" qualifier cannot be used without "location"
* qualifier.
*
* Test following code snippet:
*
* layout (component = COMPONENT) in type goku;
*
* Test all types. Test all valid COMPONENT values. Test all shader stages.
* Test both in and out varyings.
*
* It is expected that shader compilation will fail.
**/
class VaryingComponentWithoutLocationTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingComponentWithoutLocationTest(deqp::Context& context);
virtual ~VaryingComponentWithoutLocationTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
glw::GLuint m_component;
bool m_is_input;
Utils::Shader::STAGES m_stage;
Utils::Type m_type;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingComponentOfInvalidType. Description follows:
*
* Test verifies that it is not allowed to declare matrix, struct, block and
* array of those at specific component.
*
* Test following code snippets:
*
* layout (location = 0, component = COMPONENT) in matrix_type varying;
*
* ,
*
* layout (location = 0, component = COMPONENT)
* in matrix_type varying[LENGTH];
*
* ,
*
* layout (location = 0, component = COMPONENT) in Block
* {
* type member;
* };
*
* ,
*
* layout (location = 0, component = COMPONENT) in Block
* {
* type member;
* } block[LENGTH];
*
* ,
*
* struct Data
* {
* type member;
* };
*
* layout (location = 0, component = COMPONENT) in Data varying;
*
* and
*
* struct Data
* {
* type member;
* };
*
* layout (location = 0, component = COMPONENT) in Data varying[LENGTH];
*
* Test all types. Test all shader stages. Test both in and out varyings.
*
* It is expected that build process will fail.
**/
class VaryingComponentOfInvalidTypeTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingComponentOfInvalidTypeTest(deqp::Context& context);
virtual ~VaryingComponentOfInvalidTypeTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private enums */
enum CASES
{
MATRIX = 0,
BLOCK,
STRUCT,
/* */
MAX_CASES
};
/* Private types */
struct testCase
{
CASES m_case;
glw::GLuint m_component;
bool m_is_array;
bool m_is_input;
Utils::Shader::STAGES m_stage;
Utils::Type m_type;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test InputComponentAliasing. Description follows:
*
* Test verifies that component aliasing cause compilation or linking error.
*
* Test following code snippet:
*
* layout (location = 1, component = GOHAN_COMPONENT) in type gohan;
* layout (location = 1, component = GOTEN_COMPONENT) in type goten;
*
* if (EXPECTED_VALUE == gohan)
* {
* result = 1;
* }
*
* Test all components combinations that cause aliasing. Test all types. Test
* all shader stages. It is expected that build process will fail.
*
* Vertex shader allows component aliasing on input as long as only one of the
* attributes is used in each execution path. Test vertex shader stage with two
* variants:
* - first as presented above,
* - second, where "result = 1;" is replaced with "result = goten;".
* In first case build process should succeed, in the second case build process
* should fail.
**/
class InputComponentAliasingTest : public NegativeTestBase
{
public:
/* Public methods */
InputComponentAliasingTest(deqp::Context& context);
virtual ~InputComponentAliasingTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual bool isFailureExpected(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
glw::GLuint m_component_gohan;
glw::GLuint m_component_goten;
Utils::Shader::STAGES m_stage;
Utils::Type m_type;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test OutputComponentAliasing. Description follows:
*
* Test verifies that component aliasing cause compilation or linking error.
*
* Test following code snippet:
*
* layout (location = 1, component = GOHAN_COMPONENT) out type gohan;
* layout (location = 1, component = GOTEN_COMPONENT) out type goten;
*
* gohan = GOHAN_VALUE;
* goten = GOTEN_VALUE;
*
* Test all components combinations that cause aliasing. Test all types. Test
* all shader stages. It is expected that build process will fail.
**/
class OutputComponentAliasingTest : public NegativeTestBase
{
public:
/* Public methods */
OutputComponentAliasingTest(deqp::Context& context);
virtual ~OutputComponentAliasingTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
glw::GLuint m_component_gohan;
glw::GLuint m_component_goten;
Utils::Shader::STAGES m_stage;
Utils::Type m_type;
};
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingLocationAliasingWithMixedTypes. Description follows:
*
* Test verifies that it is not allowed to mix integer and float base types at
* aliased location.
*
* Test following code snippet:
*
* layout (location = 1, component = GOHAN_COMPONENT) in gohan_type gohan;
* layout (location = 1, component = GOTEN_COMPONENT) in goten_type goten;
*
* Test all components combinations that do not cause component aliasing. Test
* all types combinations that cause float/integer conflict. Test all shader
* stages. Test both in and out varyings.
*
* It is expected that build process will fail.
**/
class VaryingLocationAliasingWithMixedTypesTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingLocationAliasingWithMixedTypesTest(deqp::Context& context);
virtual ~VaryingLocationAliasingWithMixedTypesTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
/* Private types */
struct testCase
{
glw::GLuint m_component_gohan;
glw::GLuint m_component_goten;
bool m_is_input;
Utils::Shader::STAGES m_stage;
Utils::Type m_type_gohan;
Utils::Type m_type_goten;
};
/* Private routines */
bool isFloatType(const Utils::Type& type);
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingLocationAliasingWithMixedInterpolation. Description follows:
*
* Test verifies that it is not allowed to mix interpolation methods at aliased
* location.
*
* Test following code snippet:
*
* layout (location = 1, component = GOHAN_COMPONENT)
* GOHAN_INTERPOLATION in type gohan;
* layout (location = 1, component = GOTEN_COMPONENT)
* GOTEN_INTERPOLATION in type goten;
*
* Test all interpolation combinations that cause conflict. Select components
* so as not to cause component aliasing. Test all types. Test all shader
* stages. Test both in and out varyings.
*
* Note, that vertex shader's input and fragment shader's output cannot be
* qualified with interpolation method.
*
* It is expected that build process will fail.
**/
class VaryingLocationAliasingWithMixedInterpolationTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingLocationAliasingWithMixedInterpolationTest(deqp::Context& context);
virtual ~VaryingLocationAliasingWithMixedInterpolationTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
enum INTERPOLATIONS
{
SMOOTH = 0,
FLAT,
NO_PERSPECTIVE,
/* */
INTERPOLATION_MAX
};
/* Private types */
struct testCase
{
glw::GLuint m_component_gohan;
glw::GLuint m_component_goten;
INTERPOLATIONS m_interpolation_gohan;
INTERPOLATIONS m_interpolation_goten;
bool m_is_input;
Utils::Shader::STAGES m_stage;
Utils::Type m_type_gohan;
Utils::Type m_type_goten;
};
/* Private routines */
const glw::GLchar* getInterpolationQualifier(INTERPOLATIONS interpolation);
bool isFloatType(const Utils::Type& type);
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VaryingLocationAliasingWithMixedAuxiliaryStorage. Description follows:
*
* Test verifies that it is not allowed to mix auxiliary storage at aliased
* location.
*
* Test following code snippet:
*
* layout (location = 1, component = GOHAN_COMPONENT)
* GOHAN_AUXILIARY in type gohan;
* layout (location = 1, component = GOTEN_COMPONENT)
* GOTEN_AUXILIARY in type goten;
*
* Test all auxiliary storage combinations that cause conflict. Select
* components so as not to cause component aliasing. Test all types. Test all
* shader stages. Test both in and out varyings.
*
* It is expected that build process will fail.
**/
class VaryingLocationAliasingWithMixedAuxiliaryStorageTest : public NegativeTestBase
{
public:
/* Public methods */
VaryingLocationAliasingWithMixedAuxiliaryStorageTest(deqp::Context& context);
virtual ~VaryingLocationAliasingWithMixedAuxiliaryStorageTest()
{
}
protected:
/* Methods to be implemented by child class */
virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage);
virtual std::string getTestCaseName(glw::GLuint test_case_index);
virtual glw::GLuint getTestCaseNumber();
virtual bool isComputeRelevant(glw::GLuint test_case_index);
virtual void testInit();
private:
enum AUXILIARIES
{
NONE = 0,
PATCH,
CENTROID,
SAMPLE,
/* */
AUXILIARY_MAX
};
/* Private types */
struct testCase
{
glw::GLuint m_component_gohan;
glw::GLuint m_component_goten;
AUXILIARIES m_aux_gohan;
AUXILIARIES m_aux_goten;
const glw::GLchar* m_int_gohan;
const glw::GLchar* m_int_goten;
bool m_is_input;
Utils::Shader::STAGES m_stage;
Utils::Type m_type_gohan;
Utils::Type m_type_goten;
};
/* Private routines */
const glw::GLchar* getAuxiliaryQualifier(AUXILIARIES aux);
bool isFloatType(const Utils::Type& type);
/* Private fields */
std::vector<testCase> m_test_cases;
};
/** Implementation of test VertexAttribLocationAPI. Description follows:
*
* Test verifies that vertex attribute location API works as expected.
*
* This test implements Texture algorithm. Tessellation shaders are not
* necessary and can be omitted. Test following code snippet in vertex shader:
*
* layout (location = GOKU_LOCATION) in vec4 goku;
* in vec4 gohan;
* in vec4 goten;
* in vec4 chichi;
*
* if ( (EXPECTED_VALUE == goku) &&
* (EXPECTED_VALUE == gohan) &&
* (EXPECTED_VALUE == gotan) &&
* (EXPECTED_VALUE == chichi) )
* {
* result = 1;
* }
*
* After compilation, before program is linked, specify locations for goku,
* and goten with glBindAttribLocation. Specify different location than the one
* used in shader.
*
* Select all locations so as not to exceed any limits.
*
* Additionally inspect program to verify that:
* - goku location is as specified in shader text,
* - goten location is as specified with API.
**/
class VertexAttribLocationAPITest : public TextureTestBase
{
public:
VertexAttribLocationAPITest(deqp::Context& context);
~VertexAttribLocationAPITest()
{
}
protected:
/* Protected methods */
virtual void prepareAttribLocation(Utils::Program& program, Utils::ProgramInterface& program_interface);
virtual void getProgramInterface(glw::GLuint test_case_index, Utils::ProgramInterface& program_interface,
Utils::VaryingPassthrough& varying_passthrough);
virtual bool isComputeRelevant(glw::GLuint test_case_index);
private:
/* Private fields */
std::vector<glw::GLubyte> m_goku_data;
std::vector<glw::GLubyte> m_gohan_data;
std::vector<glw::GLubyte> m_goten_data;
std::vector<glw::GLubyte> m_chichi_data;
/* Private constants */
static const glw::GLuint m_goten_location;
};
/** Implementation of test FragmentDataLocationAPI. Description follows:
*
* Test verifies that fragment data location API works as expected.
*
* This test implements Texture algorithm. Tessellation shaders are not
* necessary and can be omitted. "result" is not necessary and can be omitted.
* Test following code snippet in fragment shader: