#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 GenerateData() const; std::vector 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; std::vector GetValidComponents() 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); static bool CanTypesShareLocation(TYPES first, TYPES second); /* 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 Vector; typedef std::vector 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 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 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 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 \ 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 \ 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 Vector; typedef std::vector 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 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 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& 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 bool coherent = false) 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 Vector; /* Fileds */ std::vector m_expected_data; std::vector 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 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 isSeparable(const glw::GLuint test_case_index); virtual bool testCase(glw::GLuint test_case_index); }; /** Base class for test doing Texture algorithm **/ 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 * is TRANSFORM_FEEDBACK_BUFFER and is * MAX_NAME_LENGTH; * - GetProgramResourceIndex should generate INVALID_ENUM when * is TRANSFORM_FEEDBACK_BUFFER; * - GetProgramResourceName should generate INVALID_ENUM when * 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 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 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 b; * layout(align = 48) vec4 a; * }; * * 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 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)> * * * 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 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 = b_offset) b_type b; * layout (offset = a_offset) a_type a; * }; * * 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_b_offset; Utils::Type m_b_type; glw::GLuint m_a_offset; Utils::Type m_a_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 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 b; * layout (align = a_alignment) type a; * }; * * It is expected that compilation will fail whenever a_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 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 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 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 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 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 m_first_data; std::vector 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 m_single_data; std::vector m_array_data; std::vector 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 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 m_third_data; std::vector m_fourth_data; std::vector m_fifth_data; std::vector 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 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 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 bool isSeparable(const 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 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: * - g64vec2 * - g64scalar, g64scalar * - 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 { G64VEC2, G64SCALAR_G64SCALAR, 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 m_test_cases; std::vector 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 VaryingInvalidValueComponent. Description follows: * * Test verifies that it is not allowed to use some component values * with specific types. * * 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 it is an invalid value either due the specific * restrictions of each type, eg. 2 for vec4, which overflows the * amount of components in a location. 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 VaryingInvalidValueComponentTest : public NegativeTestBase { public: /* Public methods */ VaryingInvalidValueComponentTest(deqp::Context& context); virtual ~VaryingInvalidValueComponentTest() { } 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 m_test_cases; }; /** Implementation of test VaryingExceedingComponents. Description follows: * * Test verifies that it is not allowed to use a value that exceeds * the amount of possible components in a location. * * Test following code snippets: * * layout (location = 1, component = 4) in type gohan; * * and * * layout (location = 1, component = 4) in type gohan[LENGTH]; * * 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 { bool m_is_input; bool m_is_array; Utils::Shader::STAGES m_stage; Utils::Type m_type; }; /* Private fields */ std::vector 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 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, DVEC3_DVEC4, 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 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 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 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 fields */ std::vector 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); /* Private fields */ std::vector 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; 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); /* Private fields */ std::vector 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 m_goku_data; std::vector m_gohan_data; std::vector m_goten_data; std::vector 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: * * layout (location = GOKU_LOCATION) out vec4 goku; * out vec4 gohan; * out vec4 goten; * out vec4 chichi; * * goku = EXPECTED_VALUE; * gohan = EXPECTED_VALUE; * goten = EXPECTED_VALUE; * chichi = EXPECTED_VALUE; * * After compilation, before program is linked, specify locations for goku, * and goten with glBindFragDataLocation. 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 FragmentDataLocationAPITest : public TextureTestBase { public: FragmentDataLocationAPITest(deqp::Context& context); ~FragmentDataLocationAPITest() { } protected: /* Protected methods */ virtual bool checkResults(glw::GLuint test_case_index, Utils::Texture& color_0); 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 void prepareFragmentDataLoc(Utils::Program& program, Utils::ProgramInterface& program_interface); virtual void prepareFramebuffer(Utils::Framebuffer& framebuffer, Utils::Texture& color_0_texture); private: /* Private fields */ Utils::Texture m_goku; Utils::Texture m_gohan; Utils::Texture m_goten; Utils::Texture m_chichi; glw::GLint m_goku_location; glw::GLint m_gohan_location; glw::GLint m_chichi_location; /* Private constants */ static const glw::GLuint m_goten_location; }; /** Implementation of test XFBInput. Description follows: * * Test verifies that using xfb_buffer, xfb_stride or xfb_offset qualifiers on * input variables will cause failure of build process. * * Test all shader stages. **/ class XFBInputTest : public NegativeTestBase { public: /* Public methods */ XFBInputTest(deqp::Context& context); virtual ~XFBInputTest() { } 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 QUALIFIERS { BUFFER = 0, STRIDE, OFFSET, /* */ QUALIFIERS_MAX }; /* Private types */ struct testCase { QUALIFIERS m_qualifier; Utils::Shader::STAGES m_stage; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBAllStages. Description follows: * * Test verifies that only outputs from last stage processing primitives can be * captured with XFB. * * This test implements Buffer algorithm. Rasterization can be discarded. * * At each stage declare a single active output variable qualified with * xfb_buffer and xfb_offset = 0. Use separate buffers for each stage. * * Test pass if outputs from geometry shader are captured, while outputs from: * vertex and tessellation stages are ignored. **/ class XFBAllStagesTest : public BufferTestBase { public: XFBAllStagesTest(deqp::Context& context); ~XFBAllStagesTest() { } protected: /* Protected methods */ virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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); private: /* Constants */ static const glw::GLuint m_gs_index; }; /** Implementation of test XFBStrideOfEmptyList. Description follows: * * Test verifies correct behavior when xfb_stride qualifier is specified * but no variables are qualified with xfb_offset. * * Test implements Buffer algorithm. Rasterization can be discarded. * * Test following code snippet: * * layout (xfb_buffer = 1, xfb_stride = 64) out; * * Moreover program should output something to xfb at index 0 * * Test following cases: * 1 Provide buffers to XFB at index 0 and 1 * 2 Provide buffer to XFB at index 1, index 0 should be missing * 3 Provide buffer to XFB at index 0, index 1 should be missing * * It is expected that: * - BeginTransformFeedback operation will report GL_INVALID_OPERATION in case 2 * - XFB at index 1 will not be modified in cases 1 and 3. **/ class XFBStrideOfEmptyListTest : public BufferTestBase { public: XFBStrideOfEmptyListTest(deqp::Context& context); ~XFBStrideOfEmptyListTest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index); virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); private: enum CASES { VALID = 0, FIRST_MISSING, SECOND_MISSING, }; /* Private constants */ static const glw::GLuint m_stride; }; /** Implementation of test XFBStrideOfEmptyListAndAPI. Description follows: * * Test verifies that xfb_stride qualifier is not overridden by API. * * Test implements Buffer algorithm. Rasterization can be discarded. * * Test following code snippet: * * layout (xfb_buffer = 0, xfb_stride = 64) out; * * Moreover program should output something to xfb at index 1 * Use TransformFeedbackVaryings to declare a single vec4 output variable to be * captured. * * Test following cases: * 1 Provide buffers to XFB at index 0 and 1 * 2 Provide buffer to XFB at index 1, index 0 should be missing * 3 Provide buffer to XFB at index 0, index 1 should be missing * * It is expected that: * - BeginTransformFeedback operation will report GL_INVALID_OPERATION in cases * 2 and 3, * - XFB at index 0 will not be modified in case 1. **/ class XFBStrideOfEmptyListAndAPITest : public BufferTestBase { public: XFBStrideOfEmptyListAndAPITest(deqp::Context& context); ~XFBStrideOfEmptyListAndAPITest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; 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 getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); private: enum CASES { VALID = 0, FIRST_MISSING, SECOND_MISSING, }; /* Private constants */ static const glw::GLuint m_stride; }; /** Implementation of test XFBTooSmallStride. Description follows: * * Test verifies that build process fails when xfb_stride qualifier sets not * enough space for all variables. * * Test following code snippets: * * layout (xfb_buffer = 0, xfb_stride = 40) out; * * layout (xfb_offset = 32) out vec4 goku; * * goku = EXPECTED_VALUE. * * , * * layout (xfb_buffer = 0, xfb_stride = 28) out; * * layout (xfb_offset = 16, xfb_stride = 28) out vec4 goku; * * goku = EXPECTED_VALUE. * * , * * layout (xfb_buffer = 0, xfb_stride = 32) out; * * layout (xfb_offset = 0) out Goku { * vec4 gohan; * vec4 goten; * vec4 chichi; * }; * * gohan = EXPECTED_VALUE; * goten = EXPECTED_VALUE; * chichi = EXPECTED_VALUE; * * , * * layout (xfb_buffer = 0, xfb_stride = 32) out; * * layout (xfb_offset = 16) out vec4 goku[4]; * * goku[0] = EXPECTED_VALUE. * goku[1] = EXPECTED_VALUE. * goku[2] = EXPECTED_VALUE. * goku[3] = EXPECTED_VALUE. * * It is expected that build process will fail. * * Test all shader stages. **/ class XFBTooSmallStrideTest : public NegativeTestBase { public: /* Public methods */ XFBTooSmallStrideTest(deqp::Context& context); virtual ~XFBTooSmallStrideTest() { } 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 CASES { OFFSET = 0, STRIDE, BLOCK, ARRAY, /* */ CASE_MAX }; /* Private types */ struct testCase { CASES m_case; Utils::Shader::STAGES m_stage; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBVariableStride. Description follows: * * Test verifies that xfb_stride qualifier change stride of output variable. * * Test following code snippets: * * layout (xfb_stride = sizeof(type)) out; * * layout (xfb_offset = 0) out type goku; * * and * * layout (xfb_stride = sizeof(type)) out; * * layout (xfb_offset = 0) out type goku; * layout (xfb_offset = sizeof(type)) out type vegeta; * * It is expected that: * - first snippet will build successfully, * - second snippet will fail to build. * * Test all types. Test all shader stages. **/ class XFBVariableStrideTest : public NegativeTestBase { public: /* Public methods */ XFBVariableStrideTest(deqp::Context& context); virtual ~XFBVariableStrideTest() { } 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: enum CASES { VALID = 0, INVALID, /* */ CASE_MAX }; /* Private types */ struct testCase { CASES m_case; Utils::Shader::STAGES m_stage; Utils::Type m_type; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBBlockStride. Description follows: * * Test verifies that xfb_stride qualifier change stride of output block. * * Test following code snippet: * * layout (xfb_offset = 0, xfb_stride = 128) out Goku { * vec4 gohan; * vec4 goten; * vec4 chichi; * }; * * Inspect program to check if Goku stride is 128 units. * * Test all shader stages. **/ class XFBBlockStrideTest : public TestBase { public: /* Public methods */ XFBBlockStrideTest(deqp::Context& context); virtual ~XFBBlockStrideTest() { } 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); virtual void testInit(); private: /* Private methods */ std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage); bool inspectProgram(Utils::Program& program); /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBBlockMemberStride. Description follows: * * Test verifies that xfb_stride qualifier change stride of output block * member. * * This test implements Buffer algorithm. Rasterization can be discarded. Test * following code snippet: * * layout (xfb_offset = 0) out Goku { * vec4 gohan; * layout (xfb_stride = 32) vec4 goten; * vec4 chichi; * }; * * gohan = EXPECTED_VALUE; * goten = EXPECTED_VALUE; * chichi = EXPECTED_VALUE; * * Test pass if: * - goten stride is reported as 32, * - chichi offset is reported as 48, * - values captured for all members match expected values, * - part of memory reserved for goten, that is not used, is not modified. **/ class XFBBlockMemberStrideTest : public BufferTestBase { public: XFBBlockMemberStrideTest(deqp::Context& context); ~XFBBlockMemberStrideTest() { } protected: /* Protected methods */ virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 bool inspectProgram(glw::GLuint test_case_index, Utils::Program& program, std::stringstream& out_stream); }; /** Implementation of test XFBDuplicatedStride. Description follows: * * Test verifies that conflicting xfb_stride qualifiers cause build process * failure. * * Test following code snippets: * * layout (xfb_buffer = 0, xfb_stride = 64) out; * layout (xfb_buffer = 0, xfb_stride = 64) out; * * and * * layout (xfb_buffer = 0, xfb_stride = 64) out; * layout (xfb_buffer = 0, xfb_stride = 128) out; * * It is expected that: * - first snippet will build successfully, * - second snippet will fail to build. **/ class XFBDuplicatedStrideTest : public NegativeTestBase { public: /* Public methods */ XFBDuplicatedStrideTest(deqp::Context& context); virtual ~XFBDuplicatedStrideTest() { } 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: enum CASES { VALID = 0, INVALID, /* */ CASE_MAX }; /* Private types */ struct testCase { CASES m_case; Utils::Shader::STAGES m_stage; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBGetProgramResourceAPI. Description follows: * * Test verifies that GetProgramResource* API work as expected for transform * feedback. * * Test results of following queries: * - OFFSET, * - TRANSFORM_FEEDBACK_BUFFER_INDEX, * - TRANSFORM_FEEDBACK_BUFFER_STRIDE, * - TYPE. * * Test following cases: * - captured varyings are declared with API, TransformFeedbackVaryings * with INTERLEAVED_ATTRIBS, * - captured varyings are declared with API, TransformFeedbackVaryings * with SEPARATE_ATTRIBS, * - captured varyings are declared with "xfb" qualifiers. * * Following layout should be used in cases of INTERLEAVED_ATTRIBS and "xfb" * qualifiers: * | var 0 | var 1 | var 2 | var 3 * buffer 0 | used | used | empty | used * buffer 1 | empty | used | empty | empty * * In "xfb" qualifiers case, use following snippet: * * layout (xfb_buffer = 1, xfb_stride = 4 * sizeof(type)) out; * * Declaration in shader should use following order: * buffer_0_var_1 * buffer_1_var_1 * buffer_0_var_3 * buffer_0_var_0 * * To make sure that captured varyings are active, they should be assigned. * * Test all types. Test all shader stages. **/ class XFBGetProgramResourceAPITest : public TestBase { public: /* Public methods */ XFBGetProgramResourceAPITest(deqp::Context& context); virtual ~XFBGetProgramResourceAPITest() { } 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); virtual void testInit(); virtual void insertSkipComponents(int num_components, Utils::Program::NameVector& varyings); private: /* Private enums */ enum CASES { INTERLEAVED, SEPARATED, XFB, }; /* Private types */ struct test_Case { CASES m_case; Utils::Shader::STAGES m_stage; Utils::Type m_type; }; /* Private methods */ std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage); bool inspectProgram(glw::GLuint test_case_index, Utils::Program& program); /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBOverrideQualifiersWithAPI. Description follows: * * Test verifies that API is ignored, when qualifiers are in use. * * This test follows Buffer algorithm. Rasterization can disabled. Test * following code snippet: * * layout (xfb_offset = 2 * sizeof(type)) out type vegeta; * out type trunks; * layout (xfb_offset = 0) out type goku; * out type gohan; * * vegeta = EXPECTED_VALUE; * trunks = EXPECTED_VALUE; * goku = EXPECTED_VALUE; * gohan = EXPECTED_VALUE; * * Use API, TransformFeedbackVaryings, to specify trunks and gohan as outputs * to be captured. * * Test pass if: * - correct values are captured for vegeta and goku, * - trunks and gohan are not captured, * - correct stride is reported. * * Test all types. Test all shader stages. **/ class XFBOverrideQualifiersWithAPITest : public BufferTestBase { public: XFBOverrideQualifiersWithAPITest(deqp::Context& context); ~XFBOverrideQualifiersWithAPITest() { } protected: /* Protected methods */ 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 getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); virtual bool inspectProgram(glw::GLuint test_case_index, Utils::Program& program, std::stringstream& out_stream); }; /** Implementation of test XFBVertexStreams. Description follows: * * Test verifies that "xfb" qualifiers work as expected with multiple output * streams. * * Test implements Buffer algorithm. Rasterization can be discarded. * * Test following code snippet: * * layout (xfb_buffer = 1, xfb_stride = 64) out; * layout (xfb_buffer = 2, xfb_stride = 64) out; * layout (xfb_buffer = 3, xfb_stride = 64) out; * * layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku; * layout (stream = 0, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan; * layout (stream = 0, xfb_buffer = 1, xfb_offset = 16) out vec4 goten; * layout (stream = 1, xfb_buffer = 3, xfb_offset = 48) out vec4 picolo; * layout (stream = 1, xfb_buffer = 3, xfb_offset = 32) out vec4 vegeta; * layout (stream = 2, xfb_buffer = 2, xfb_offset = 32) out vec4 bulma; * * goku = EXPECTED_VALUE; * gohan = EXPECTED_VALUE; * goten = EXPECTED_VALUE; * picolo = EXPECTED_VALUE; * vegeta = EXPECTED_VALUE; * bulma = EXPECTED_VALUE; * * Test pass if all captured outputs have expected values. **/ class XFBVertexStreamsTest : public BufferTestBase { public: XFBVertexStreamsTest(deqp::Context& context); ~XFBVertexStreamsTest() { } protected: /* Protected methods */ virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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); }; /** Implementation of test XFBMultipleVertexStreams. Description follows: * * Test verifies that outputs from single stream must be captured with single * xfb binding. * * Test following code snippet: * * layout (xfb_buffer = 1, xfb_stride = 64) out; * layout (xfb_buffer = 3, xfb_stride = 64) out; * * layout (stream = 0, xfb_buffer = 1, xfb_offset = 48) out vec4 goku; * layout (stream = 1, xfb_buffer = 1, xfb_offset = 32) out vec4 gohan; * layout (stream = 2, xfb_buffer = 1, xfb_offset = 16) out vec4 goten; * * It is expected that linking of program will fail. **/ class XFBMultipleVertexStreamsTest : public NegativeTestBase { public: /* Public methods */ XFBMultipleVertexStreamsTest(deqp::Context& context); virtual ~XFBMultipleVertexStreamsTest() { } protected: /* Methods to be implemented by child class */ virtual std::string getShaderSource(glw::GLuint test_case_index, Utils::Shader::STAGES stage); virtual bool isComputeRelevant(glw::GLuint test_case_index); }; /** Implementation of test XFBExceedBufferLimit. Description follows: * * Test verifies that MAX_TRANSFORM_FEEDBACK_BUFFERS limit is respected. * * Test following code snippets: * * layout (xfb_buffer = MAX_TRANSFORM_FEEDBACK_BUFFERS) out; * * , * * layout (xfb_buffer = MAX_TRANSFORM_FEEDBACK_BUFFERS) out vec4 output; * * and * * layout (xfb_buffer = MAX_TRANSFORM_FEEDBACK_BUFFERS) out Block { * vec4 member; * }; * * It is expected that build process will fail. * * Test all shader stages. **/ class XFBExceedBufferLimitTest : public NegativeTestBase { public: /* Public methods */ XFBExceedBufferLimitTest(deqp::Context& context); virtual ~XFBExceedBufferLimitTest() { } 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 CASES { BLOCK = 0, GLOBAL, VECTOR, /* */ CASE_MAX }; /* Private types */ struct testCase { CASES m_case; Utils::Shader::STAGES m_stage; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBExceedOffsetLimit. Description follows: * * Test verifies that MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS limit is * respected. * * Test following code snippets: * * layout (xfb_buffer = 0, xfb_stride = MAX_SIZE + 16) out; * * , * * layout (xfb_buffer = 0, xfb_offset = MAX_SIZE + 16) out vec4 output; * * and * * layout (xfb_buffer = 0, xfb_offset = MAX_SIZE + 16) out Block * { * vec4 member; * }; * * where MAX_SIZE is the maximum supported size of transform feedback buffer, * which should be equal to: * * MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS * sizeof(float) * * It is expected that build process will fail. * * Test all shader stages. **/ class XFBExceedOffsetLimitTest : public NegativeTestBase { public: /* Public methods */ XFBExceedOffsetLimitTest(deqp::Context& context); virtual ~XFBExceedOffsetLimitTest() { } 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 CASES { BLOCK = 0, GLOBAL, VECTOR, /* */ CASE_MAX }; /* Private types */ struct testCase { CASES m_case; Utils::Shader::STAGES m_stage; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBGlobalBuffer. Description follows: * * Test verifies that global setting of xfb_buffer qualifier work as expected. * * This test implements Buffer algorithm. Rasterization can be discarded. Test * following code snippet: * * layout (xfb_buffer = 3) out; * * layout ( xfb_offset = 2 * sizeof(type)) out type chichi; * layout (xfb_buffer = 1, xfb_offset = 0) out type bulma; * layout (xfb_buffer = 1, xfb_offset = sizeof(type)) out Vegeta { * type trunks; * type bra; * }; * layout ( xfb_offset = 0) out Goku { * type gohan; * type goten; * }; * * chichi = EXPECTED_VALUE; * bulma = EXPECTED_VALUE; * trunks = EXPECTED_VALUE; * bra = EXPECTED_VALUE; * gohan = EXPECTED_VALUE; * goten = EXPECTED_VALUE; * * Test pass if all captured outputs have expected values. * * Test all shader stages. Test all types. **/ class XFBGlobalBufferTest : public BufferTestBase { public: XFBGlobalBufferTest(deqp::Context& context); ~XFBGlobalBufferTest() { } protected: /* Protected methods */ virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 void testInit(); private: /* Private types */ struct _testCase { Utils::Shader::STAGES m_stage; Utils::Type m_type; }; /* Private fields */ std::vector<_testCase> m_test_cases; }; /** Implementation of test XFBStride. Description follows: * * Test verifies that expected stride values are used. * * Test following code snippet: * * layout (xfb_offset = 0) out type output; * * output = EXPECTED_VALUE; * * Test all types. Test all shader stages. **/ class XFBStrideTest : public BufferTestBase { public: XFBStrideTest(deqp::Context& context); ~XFBStrideTest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index); virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 std::string getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); virtual void testInit(); private: /* Private types */ struct testCase { Utils::Shader::STAGES m_stage; Utils::Type m_type; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBBlockMemberBuffer. Description follows: * * Test verifies that member of block have to use same buffer as block. * * Test following code snippet: * * layout (xfb_offset = 0) out Goku * { * vec4 gohan; * layout (xfb_buffer = 1) vec4 goten; * }; * * It is expected that compilation will fail. * * Test all shader stages. **/ class XFBBlockMemberBufferTest : public NegativeTestBase { public: /* Public methods */ XFBBlockMemberBufferTest(deqp::Context& context); virtual ~XFBBlockMemberBufferTest() { } 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 { Utils::Shader::STAGES m_stage; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBOutputOverlapping. Description follows: * * Test verifies that overlapped outputs are reported as errors by compiler. * * Test following code snippet: * * layout (xfb_offset = 0) out type gohan; * layout (xfb_offset = 0.5 * sizeof(type)) out type goten; * * gohan = EXPECTED_VALUE; * goten = EXPECTED_VALUE; * * It is expected that compilation will fail. * * Test all shader stages. Test all types. **/ class XFBOutputOverlappingTest : public NegativeTestBase { public: /* Public methods */ XFBOutputOverlappingTest(deqp::Context& context); virtual ~XFBOutputOverlappingTest() { } 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_offset; Utils::Shader::STAGES m_stage; Utils::Type m_type; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBInvalidOffsetAlignment. Description follows: * * Test verifies that invalidly aligned outputs cause a failure to build * process. * * Test following code snippet: * * layout (xfb_offset = OFFSET) out type goku; * * goku = EXPECTED_VALUE; * * Select OFFSET values so as to cause invalid alignment. Inspect program to * verify offset of goku. * * Test all shader stages. Test all types. Test all offsets in range: * (sizeof(type), 2 * sizeof(type)). **/ class XFBInvalidOffsetAlignmentTest : public NegativeTestBase { public: /* Public methods */ XFBInvalidOffsetAlignmentTest(deqp::Context& context); virtual ~XFBInvalidOffsetAlignmentTest() { } 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_offset; Utils::Shader::STAGES m_stage; Utils::Type m_type; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBCaptureInactiveOutputVariable. Description follows: * * Test verifies behavior of inactive outputs. * * This test implements Buffer algorithm. Rasterization can be disabled. Draw * two vertices instead of one. Test following code snippet: * * layout (xfb_offset = 16) out vec4 goku; * layout (xfb_offset = 32) out vec4 gohan; * layout (xfb_offset = 0) out vec4 goten; * * gohan = EXPECTED_VALUE; * goten = EXPECTED_VALUE; * * Test pass if: * - values captured for goten and gohan are as expected, * - goku value is undefined * - stride is 3 * sizeof(vec4) - 48 * * Test all shader stages. **/ class XFBCaptureInactiveOutputVariableTest : public BufferTestBase { public: XFBCaptureInactiveOutputVariableTest(deqp::Context& context); ~XFBCaptureInactiveOutputVariableTest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index); virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 std::string getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); virtual bool inspectProgram(glw::GLuint test_case_index, Utils::Program& program, std::stringstream& out_stream); virtual bool verifyBuffers(bufferCollection& buffers); private: enum test_cases { TEST_VS = 0, TEST_TES, TEST_GS, /* */ TEST_MAX }; }; /** Implementation of test XFBCaptureInactiveOutputComponent. Description follows: * * Test verifies behavior of inactive component. * * This test implements Buffer algorithm. Rasterization can be disabled. Draw * two vertices instead of one. Test following code snippet: * * layout (xfb_offset = 32) out vec4 goku; * layout (xfb_offset = 0) out vec4 gohan; * layout (xfb_offset = 16) out vec4 goten; * layout (xfb_offset = 48) out vec4 chichi; * layout (xfb_offset = 112) out vec4 vegeta; * layout (xfb_offset = 96) out vec4 trunks; * layout (xfb_offset = 80) out vec4 bra; * layout (xfb_offset = 64) out vec4 bulma; * * goku.x = EXPECTED_VALUE; * goku.z = EXPECTED_VALUE; * gohan.y = EXPECTED_VALUE; * gohan.w = EXPECTED_VALUE; * goten.x = EXPECTED_VALUE; * goten.y = EXPECTED_VALUE; * chichi.z = EXPECTED_VALUE; * chichi.w = EXPECTED_VALUE; * vegeta.x = EXPECTED_VALUE; * trunks.y = EXPECTED_VALUE; * bra.z = EXPECTED_VALUE; * bulma.w = EXPECTED_VALUE; * * Test pass when captured values of all assigned components match expected * values, while not assigned ones are undefined. * * Test all shader stages. **/ class XFBCaptureInactiveOutputComponentTest : public BufferTestBase { public: XFBCaptureInactiveOutputComponentTest(deqp::Context& context); ~XFBCaptureInactiveOutputComponentTest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index); virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 std::string getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); virtual bool verifyBuffers(bufferCollection& buffers); private: enum test_cases { TEST_VS = 0, TEST_TES, TEST_GS, /* */ TEST_MAX }; }; /** Implementation of test XFBCaptureInactiveOutputBlockMember. Description follows: * * Test verifies behaviour of inactive block member. * * This test implements Buffer algorithm. Rasterization can be disabled. Draw * two vertices instead of one. Test following code snippet: * * layout (xfb_offset = 16) out Goku { * vec4 gohan; * vec4 goten; * vec4 chichi; * }; * * gohan = EXPECTED_VALUE; * chichi = EXPECTED_VALUE; * * Test pass when captured values of gohan and chichi match expected values. * It is expected that goten will receive undefined value. * * Test all shader stages. **/ class XFBCaptureInactiveOutputBlockMemberTest : public BufferTestBase { public: XFBCaptureInactiveOutputBlockMemberTest(deqp::Context& context); ~XFBCaptureInactiveOutputBlockMemberTest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index); virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 std::string getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); virtual bool verifyBuffers(bufferCollection& buffers); private: enum test_cases { TEST_VS = 0, TEST_TES, TEST_GS, /* */ TEST_MAX }; }; /** Implementation of test XFBCaptureStruct. Description follows: * * Test verifies that structures are captured as expected. * * This test implements Buffer algorithm. Rasterization can be disabled. Draw * two vertices instead of one. Test following code snippet: * * struct Goku { * vec4 gohan; * vec4 goten; * vec4 chichi; * }; * * layout (xfb_offset = 16) out Goku goku; * * goku.gohan = EXPECTED_VALUE; * goku.chichi = EXPECTED_VALUE; * * Test pass when captured values of gohan and chichi match expected values. * It is expected that goten will receive undefined value. * * Test all shader stages. **/ class XFBCaptureStructTest : public BufferTestBase { public: XFBCaptureStructTest(deqp::Context& context); ~XFBCaptureStructTest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index); virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 std::string getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); virtual bool verifyBuffers(bufferCollection& buffers); private: enum test_cases { TEST_VS = 0, TEST_TES, TEST_GS, /* */ TEST_MAX }; }; /** Implementation of test XFBCaptureUnsizedArray. Description follows: * * Test verifies this is not allowed to qualify unsized array with "xfb". * * Test following code snippet: * * layout (xfb_offset = 0) out vec4 goku[]; * * goku[0] = EXPECTED_VALUE; * * It is expected that compilation will fail. * * Test all shader stages. **/ class XFBCaptureUnsizedArrayTest : public NegativeTestBase { public: /* Public methods */ XFBCaptureUnsizedArrayTest(deqp::Context& context); virtual ~XFBCaptureUnsizedArrayTest() { } 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 { Utils::Shader::STAGES m_stage; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBExplicitLocationTest. Description follows: * * Test verifies that explicit location on matrices and arrays does not impact xfb output. * * Test following code snippet: * * layout (location = 0, xfb_offset = 0) out vec2 goku[3]; * * Is expected to have the same output as: * * layout (xfb_offset = 0) out vec2 goku[3]; * * While explicit location does impact varyings layout of matrices and arrays, see * Ref. GLSL 4.60, Section 4.4.2. "Output Layout Qualifiers" - it shall not impact * xfb output. * * Test all shader stages. **/ class XFBExplicitLocationTest : public BufferTestBase { public: XFBExplicitLocationTest(deqp::Context& context); ~XFBExplicitLocationTest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index); virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 std::string getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); virtual void testInit(); private: /* Private types */ struct testCase { Utils::Shader::STAGES m_stage; Utils::Type m_type; glw::GLuint m_array_size; }; /* Private fields */ std::vector m_test_cases; }; /** Implementation of test XFBExplicitLocationStructTest. Description follows: * * Test verifies that explicit location on struct does not impact xfb output. * * Test following code snippet: * struct TestStruct { * float a; * double b; * }; * * layout (location = 0, xfb_offset = 0) flat out TestStruct goku; * * Is expected to have the same output as: * * layout (xfb_offset = 0) flat out TestStruct goku; * * While explicit location does impact varyings layout of structs, see * Ref. GLSL 4.60, Section 4.4.2. "Output Layout Qualifiers" - it shall not impact * xfb output. * * Test all shader stages. **/ class XFBExplicitLocationStructTest : public BufferTestBase { public: XFBExplicitLocationStructTest(deqp::Context& context); ~XFBExplicitLocationStructTest() { } protected: /* Protected methods */ using BufferTestBase::executeDrawCall; virtual bool executeDrawCall(bool tesEnabled, glw::GLuint test_case_index); virtual void getBufferDescriptors(glw::GLuint test_case_index, bufferDescriptor::Vector& out_descriptors); 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 std::string getTestCaseName(glw::GLuint test_case_index); virtual glw::GLuint getTestCaseNumber(); virtual void testInit(); private: /* Private types */ struct testType { Utils::Type m_type; glw::GLuint m_array_size; }; struct testCase { Utils::Shader::STAGES m_stage; std::vector m_types; bool m_nested_struct; }; /* Private fields */ std::vector m_test_cases; }; } /* EnhancedLayouts namespace */ /** Group class for Shader Language 420Pack conformance tests */ class EnhancedLayoutsTests : public deqp::TestCaseGroup { public: /* Public methods */ EnhancedLayoutsTests(deqp::Context& context); virtual ~EnhancedLayoutsTests(void) { } virtual void init(void); private: /* Private methods */ EnhancedLayoutsTests(const EnhancedLayoutsTests& other); EnhancedLayoutsTests& operator=(const EnhancedLayoutsTests& other); }; } // gl4cts #endif // _GL4CENHANCEDLAYOUTSTESTS_HPP