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