| #ifndef _GL3CTRANSFORMFEEDBACKTESTS_HPP |
| #define _GL3CTRANSFORMFEEDBACKTESTS_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 gl3cTransformFeedback.hpp |
| * \brief Transform Feedback Test Suite Interface |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "glcTestCase.hpp" |
| #include "glwDefs.hpp" |
| #include "tcuDefs.hpp" |
| |
| /* Includes. */ |
| #include <map> |
| #include <string> |
| #include <typeinfo> |
| #include <vector> |
| |
| #include "glwEnums.hpp" |
| #include "glwFunctions.hpp" |
| |
| namespace gl3cts |
| { |
| namespace TransformFeedback |
| { |
| class Tests : public deqp::TestCaseGroup |
| { |
| public: |
| Tests(deqp::Context& context); |
| ~Tests(void); |
| virtual void init(void); |
| |
| private: |
| Tests(const Tests& other); |
| Tests& operator=(const Tests& other); |
| }; |
| |
| /** APIErrors |
| * |
| * Verifies if errors are generated as specified. |
| * Four test shall be run: |
| * - Test api errors defined in GL_EXT_transform_feedback. |
| * - Test api errors defined in GL_ARB_transform_feedback2. |
| * - Test api errors defined in GL_ARB_transform_feedback3. |
| * - Test api errors defined in GL_ARB_transform_feedback_instanced. |
| */ |
| class APIErrors : public deqp::TestCase |
| { |
| public: |
| APIErrors(deqp::Context& context); |
| ~APIErrors(void); |
| IterateResult iterate(void); |
| |
| private: |
| deqp::Context& m_context; |
| |
| static const glw::GLchar* m_tessellation_control_shader; |
| static const glw::GLchar* m_tessellation_evaluation_shader; |
| static const glw::GLchar* m_geometry_shader; |
| static const glw::GLchar* s_vertex_shader_with_input_output; |
| static const glw::GLchar* s_vertex_shader_with_output; |
| static const glw::GLchar* s_vertex_shader_without_output; |
| static const glw::GLchar* s_fragment_shader; |
| static const glw::GLchar* m_varying_name; |
| |
| static const glw::GLfloat m_buffer_1_data[]; |
| static const glw::GLsizei m_buffer_1_size; |
| |
| glw::GLuint m_buffer_0; |
| glw::GLuint m_buffer_1; |
| |
| glw::GLuint m_vertex_array_object; |
| |
| glw::GLuint m_transform_feedback_object_0; |
| glw::GLuint m_transform_feedback_object_1; |
| |
| glw::GLuint m_query_object; |
| |
| glw::GLuint m_program_id_with_input_output; |
| glw::GLuint m_program_id_with_output; |
| glw::GLuint m_program_id_without_output; |
| glw::GLuint m_program_id_with_geometry_shader; |
| glw::GLuint m_program_id_with_tessellation_shaders; |
| |
| /** Check the following if EXT_transform_feedback is supported or context is |
| * at least 3.0: |
| * |
| * - INVALID_VALUE is generated by BindBufferRange, BindBufferOffset and |
| * BindBufferBase when <index> is greater or equal to |
| * MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS; |
| * - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset |
| * when <size> is less or equal to zero; |
| * - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset |
| * when <offset> is not word-aligned; |
| * - INVALID_VALUE is generated by BindBufferRange and BindBufferOffset |
| * when <size> is not word-aligned; |
| * - INVALID_OPERATION is generated by BindBufferRange, BindBufferOffset and |
| * BindBufferBase when <target> is TRANSFORM_FEEDBACK_BUFFER and transform |
| * feedback is active; |
| * - INVALID_OPERATION is generated by UseProgram when transform feedback is |
| * active; |
| * - INVALID_OPERATION is generated by LinkProgram when <program> is currently |
| * active and transform feedback is active; |
| * - INVALID_OPERATION is generated by BeginTransformFeedback when transform |
| * feedback is active; |
| * - INVALID_OPERATION is generated by EndTransformFeedback when transform |
| * feedback is inactive; |
| * - INVALID_OPERATION is generated by draw command when generated primitives |
| * type does not match <primitiveMode>; |
| * - INVALID_OPERATION is generated by BeginTransformFeedback when any binding |
| * point used by XFB does not have buffer bound; |
| * - INVALID_OPERATION is generated by BeginTransformFeedback when no program |
| * is active; |
| * - INVALID_OPERATION is generated by BeginTransformFeedback when no variable |
| * are specified to be captured in the active program; |
| * - INVALID_VALUE is generated by TransformFeedbackVaryings when <program> is |
| * not id of the program object; |
| * - INVALID_VALUE is generated by TransformFeedbackVaryings when <bufferMode> |
| * is SEPARATE_ATTRIBS and <count> is exceeds limits; |
| * - IVALID_VALUE is generated by GetTransformFeedbackVarying when <index> is |
| * greater than or equal to TRANSFORM_FEEDBACK_VARYINGS; |
| * - INVALID_VALUE is generated by GetIntegerIndexdv when <index> exceeds the |
| * limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is one of the |
| * following: |
| * * TRANSFORM_FEEDBACK_BUFFER_BINDING, |
| * * TRANSFORM_FEEDBACK_BUFFER_START, |
| * * TRANSFORM_FEEDBACK_BUFFER_SIZE; |
| * - INVALID_VALUE is generated by GetBooleanIndexedv when <index> exceeds the |
| * limits of MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS and <param> is |
| * TRANSFORM_FEEDBACK_BUFFER_BINDING. |
| */ |
| bool testExtension1(void); |
| |
| /** Check the following if ARB_transform_feedback2 is supported or context is |
| * at least 4.0: |
| * |
| * - INVALID_OPERATION is generated by BindTransformFeedback if current |
| * transform feedback is active and not paused; |
| * - INVALID_OPERATION is generated by DeleteTransformFeedbacks if any of <ids> |
| * is active; |
| * - INVALID_OPERATION is generated by PauseTransformFeedback if current |
| * transform feedback is not active or paused; |
| * - INVALID_OPERATION is generated by ResumeTransformFeedback if current |
| * transform feedback is not active or not paused; |
| * - No error is generated by draw command when transform feedback is paused |
| * and primitive modes do not match; |
| * - No error is generated by UseProgram when transform feedback is paused; |
| * - INVALID_OPERATION is generated by LinkProgram when <program> is used by |
| * some transform feedback object that is currently not active; |
| * - INVALID_VALUE is generated by DrawTransformFeedback if <id> is not name of |
| * transform feedback object; |
| * - INVALID_OPERATION is generated by DrawTransformFeedback when |
| * EndTransformFeedback was never called for the object named <id>. |
| */ |
| bool testExtension2(void); |
| |
| /** Check the following if ARB_transform_feedback3 is supported or context is |
| * at least 4.0: |
| * |
| * - INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and |
| * GetQueryIndexediv when <target> is TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN and |
| * <index> exceeds limits of MAX_VERTEX_STREAMS; |
| * - INVALID_VALUE is generated by BeginQueryIndexed, EndQueryIndexed and |
| * GetQueryIndexediv when <target> is PRIMITIVES_GENERATED and <index> exceeds |
| * limits of MAX_VERTEX_STREAMS; |
| * - INVALID_OPERATION is generated by EndQueryIndexed when name of active |
| * query at <index> of <target> is zero; |
| * - INVALID_VALUE is generated by DrawTransformFeedbackStream when <stream> |
| * exceeds limits of MAX_VERTEX_STREAMS; |
| * - INVALID_OPERATION is generated by TransformFeedbackVaryings when |
| * <varyings> contains any of the special names while <bufferMode> is not |
| * INTERLEAVED_ATTRIBS; |
| * - INVALID_OPERATION is generated by TransformFeedbackVaryings when |
| * <varyings> contains more "gl_NextBuffer" entries than allowed limit of |
| * MAX_TRANSFORM_FEEDBACK_BUFFERS; |
| */ |
| bool testExtension3(void); |
| |
| /** Check the following if ARB_transform_feedback_instanced is supported or |
| * context is at least 4.2: |
| * |
| * - INVALID_ENUM is generated by DrawTransformFeedbackInstanced and |
| * DrawTransformFeedbackStreamInstanced if <mode> is invalid; |
| * - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and |
| * DrawTransformFeedbackStreamInstanced if <mode> does not match geometry |
| * shader; |
| * - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and |
| * DrawTransformFeedbackStreamInstanced if <mode> does not match tessellation; |
| * - INVALID_VALUE is generated by DrawTransformFeedbackStreamInstanced if |
| * <stream> is greater than or equal to MAX_VERTEX_STREAMS; |
| * - INVALID_VALUE is generated by DrawTransformFeedbackInstanced and |
| * DrawTransformFeedbackStreamInstanced if <id> is not name of transform |
| * feedback object; |
| * - INVALID_OPERATION is generated by DrawTransformFeedbackInstanced and |
| * DrawTransformFeedbackStreamInstanced if a non-zero buffer object name is |
| * bound to an enabled array and the buffer object's data store is currently |
| * mapped; |
| * - INVALID_OPERATION is generated if by DrawTransformFeedbackStreamInstanced |
| * if EndTransformFeedback was never called for the object named <id>. |
| */ |
| bool testInstanced(void); |
| |
| typedef GLW_APICALL void (GLW_APIENTRY *BindBufferOffsetEXT_ProcAddress)(glw::GLenum target, glw::GLuint index, glw::GLuint buffer, |
| glw::GLintptr offset); |
| typedef GLW_APICALL void (GLW_APIENTRY *GetIntegerIndexedvEXT_ProcAddress)(glw::GLenum param, glw::GLuint index, glw::GLint* values); |
| typedef GLW_APICALL void (GLW_APIENTRY *GetBooleanIndexedvEXT_ProcAddress)(glw::GLenum param, glw::GLuint index, glw::GLboolean* values); |
| |
| BindBufferOffsetEXT_ProcAddress m_glBindBufferOffsetEXT; |
| GetIntegerIndexedvEXT_ProcAddress m_glGetIntegerIndexedvEXT; |
| GetBooleanIndexedvEXT_ProcAddress m_glGetBooleanIndexedvEXT; |
| }; |
| |
| /** LinkingErrors |
| * |
| * Verifies that linker reports errors as specified. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is |
| * at least 3.0. |
| * |
| * Check if link process fails under the following conditions: |
| * - <count> specified by TransformFeedbackVaryings is non-zero and program has |
| * neither vertex nor geometry shader; |
| * - <varyings> specified by TransformFeedbackVaryings contains name of |
| * variable that is not available for capture; |
| * - <varyings> specified by TransformFeedbackVaryings contains name of |
| * variable more than once; |
| * - number of components specified to capture exceeds limits |
| * MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS or |
| * MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS. |
| */ |
| class LinkingErrors : public deqp::TestCase |
| { |
| public: |
| LinkingErrors(deqp::Context& context); |
| ~LinkingErrors(void); |
| IterateResult iterate(void); |
| |
| private: |
| deqp::Context& m_context; |
| |
| static const glw::GLchar* s_fragment_shader; |
| static const glw::GLchar* s_vertex_shader_template; |
| static const glw::GLchar* s_valid_transform_feedback_varying; |
| static const glw::GLchar* s_invalid_transform_feedback_varying; |
| static const glw::GLchar* s_repeated_transform_feedback_varying[]; |
| static const glw::GLsizei s_repeated_transform_feedback_varying_count; |
| |
| bool testNoVertexNoGeometry(void); |
| bool testInvalidVarying(void); |
| bool testRepeatedVarying(void); |
| bool testTooManyVaryings(void); |
| }; |
| |
| /** Limits |
| * |
| * Verifies that limits reported by API are as expected. |
| * |
| * Check the following if EXT_transform_feedback is supported or context is at |
| * least 3.0: |
| * - MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS is at least 64, |
| * - MAX_TRANSFORM_FEEDBACK_SEPARATE_ATTRIBS is at least 4, |
| * - MAX_TRANSFORM_FEEDBACK_SEPARATE_COMPONENTS is at least 4. |
| * |
| * Check the following if ARB_transform_feedback3 is supported or context is at |
| * least 4.0: |
| * - MAX_TRANSFORM_FEEDBACK_BUFFERS is at least 4, |
| * - MAX_VERTEX_STREAMS is at least 1. |
| */ |
| class Limits : public deqp::TestCase |
| { |
| public: |
| Limits(deqp::Context& context); |
| ~Limits(void); |
| IterateResult iterate(void); |
| |
| private: |
| deqp::Context& m_context; |
| |
| static const glw::GLchar* s_fragment_shader; |
| static const glw::GLchar* s_vertex_shader; |
| |
| static const glw::GLint s_min_value_of_max_transform_feedback_interleaved_components; |
| static const glw::GLint s_min_value_of_max_transform_feedback_separate_attribs; |
| static const glw::GLint s_min_value_of_max_transform_feedback_separate_components; |
| static const glw::GLint s_min_value_of_max_transform_feedback_buffers; |
| static const glw::GLint s_min_value_of_max_vertex_streams; |
| |
| bool test_max_transform_feedback_interleaved_components(void); |
| bool test_max_transform_feedback_separate_attribs(void); |
| bool test_max_transform_feedback_separate_components(void); |
| bool test_max_transform_feedback_buffers(void); |
| bool test_max_vertex_streams(void); |
| }; |
| |
| /** CaptureVertexInterleaved |
| * |
| * Verifies if geometry processed with vertex shader is captured as expected in |
| * interleaved mode. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is |
| * at least 3.0. |
| * |
| * Steps: |
| * - prepare program consisting of vertex and fragment shader; Vertex shader |
| * should assign all MAX_TRANSFORM_FEEDBACK_INTERLEAVED_COMPONENTS components; |
| * One of the variables must be a position; Position should be set to one of |
| * corners, based on gl_VertexID: 0 - top left, 1 - top right, 2 - bottom left |
| * and 3 - bottom right; Rest of components should be covered with output |
| * variables of type vec4; Fragment shader should accept all outputs from |
| * vertex shader as inputs and use them to calculate non-black output color; |
| * - instruct implementation to capture all outputs defined by vertex shader; |
| * Use interleaved mode; |
| * - prepare and set buffer to store captured geometry; |
| * - prepare, set and clean frame-buffer with black color; |
| * - execute BeginTransformFeedback; |
| * - execute DrawElements; |
| * - execute EndTransformFeedback; |
| * - inspect contents of frame-buffer to check if rasterization was done |
| * correctly; |
| * - inspect TRANSFORM_FEEDBACK_BUFFER_START and |
| * TRANSFORM_FEEDBACK_BUFFER_SIZE; |
| * - inspect contents of the buffer to check if geometry was captured |
| * correctly. |
| * |
| * Test the following BindBuffer routines: |
| * - BindBufferRange - use non-zero offset, |
| * - BindBufferOffset - use non-zero offset, |
| * - BindBufferBase. |
| * |
| * Test the following primitive types: |
| * - GL_POINTS - use these indices: [0, 1, 2, 3]; All corner pixels should be |
| * set to specific colors; XFB should contain four vertices; |
| * - GL_LINES - use these indices: [0, 1, 2, 3]; Top and bottom edges should be |
| * drawn; XFB should contain four vertices; |
| * - GL_LINE_LOOP - use these indices: [0, 1, 3, 2]; All four edges should be |
| * drawn; XFB should contain eight vertices; |
| * - GL_LINE_STRIP - use these indices: [0, 1, 3, 2]; Top, right and bottom |
| * edge should be drawn; XFB should contain six vertices; |
| * - GL_TRIANGLES - use these indices: [2, 0, 1, 2, 1, 3]; Whole image should |
| * be drawn; XFB should contain six vertices; |
| * - GL_TRIANGLE_STRIP - use these indices: [0, 1, 2, 3]; Whole image should |
| * be drawn; XFB should contain six vertices; |
| * - GL_TRIANGLE_FAN - use these indices: [2, 0, 1, 3]; Whole image should |
| * be drawn; XFB should contain six vertices. |
| * |
| * Number of components that can be passed to rasterization must not exceed |
| * MAX_VARYING_COMPONENTS. |
| */ |
| class CaptureVertexInterleaved : public deqp::TestCase |
| { |
| public: |
| CaptureVertexInterleaved(deqp::Context& context, const char* test_name, const char* test_description); |
| ~CaptureVertexInterleaved(void); |
| virtual IterateResult iterate(void); |
| |
| protected: |
| deqp::Context& m_context; |
| glw::GLuint m_program; |
| glw::GLuint m_framebuffer; |
| glw::GLuint m_renderbuffer; |
| glw::GLuint m_buffer; |
| glw::GLuint m_buffer_size; |
| glw::GLuint m_vertex_array_object; |
| glw::GLint m_max_transform_feedback_components; |
| glw::GLenum m_attrib_type; |
| glw::GLuint m_max_vertices_drawn; |
| |
| typedef GLW_APICALL void (GLW_APIENTRY *BindBufferOffsetEXT_ProcAddress)(glw::GLenum target, glw::GLuint index, glw::GLuint buffer, |
| glw::GLintptr offset); |
| |
| BindBufferOffsetEXT_ProcAddress m_glBindBufferOffsetEXT; |
| |
| static const glw::GLchar* s_vertex_shader_source_code_template; |
| static const glw::GLchar* s_fragment_shader_source_code; |
| |
| static const glw::GLuint s_max_element_indices_count = 6; |
| static const glw::GLuint s_element_indices[][s_max_element_indices_count]; |
| static const glw::GLuint s_primitive_cases_count; |
| static const glw::GLuint s_element_indices_counts[]; |
| static const glw::GLenum s_primitive_cases[]; |
| static const glw::GLenum s_primitive_cases_xfb[]; |
| static const glw::GLuint s_framebuffer_size; |
| static const glw::GLfloat s_rasterization_epsilon; |
| static const glw::GLuint s_max_vertex_id = 4; |
| |
| enum BindBufferCase |
| { |
| BIND_BUFFER_BASE_CASE, |
| BIND_BUFFER_RANGE_CASE, |
| BIND_BUFFER_OFFSET_CASE, |
| BIND_BUFFER_CASES_COUNT |
| }; |
| |
| virtual void fetchLimits(void); |
| virtual void buildProgram(void); |
| void createFramebuffer(void); |
| virtual void createTransformFeedbackBuffer(void); |
| void createVertexArrayObject(void); |
| virtual void draw(glw::GLuint primitive_case); |
| virtual bool checkFramebuffer(glw::GLuint primitive_case); |
| virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); |
| virtual void bindBuffer(BindBufferCase bind_case); |
| virtual void clean(void); |
| virtual void cleanBuffer(void); |
| }; |
| |
| /** CaptureGeometryInterleaved |
| * |
| * Verifies if geometry processed with geometry shader is captured as expected |
| * in interleaved mode. |
| * |
| * Test should be run if either EXT_transform_feedback is supported or context |
| * is at least 3.0 and either ARB_geometry_shader4 is supported or context is |
| * at least 3.2. |
| * |
| * Modify CaptureVertexInterleaved test in the following aspects: |
| * - outputs definition and assignment is done in geometry instead of |
| * vertex shader; |
| * - vertex shader can be blank; |
| * - use DrawArrays instead of DrawElements, draw single vertex with GL_POINTS. |
| * |
| * Test the following output primitive types for geometry shader: |
| * - points - emit vertices as in GL_POINTS case; |
| * - line_strip - emit vertices as in GL_LINE_STRIP case; |
| * - triangle_strip - emit vertices as in GL_TRIANGLE_STRIP case. |
| * |
| * Number of components written by geometry shader must not exceed |
| * MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS. |
| */ |
| class CaptureGeometryInterleaved : virtual public CaptureVertexInterleaved |
| { |
| public: |
| CaptureGeometryInterleaved(deqp::Context& context, const char* test_name, const char* test_description); |
| ~CaptureGeometryInterleaved(void); |
| virtual IterateResult iterate(void); |
| |
| protected: |
| virtual void fetchLimits(void); |
| using CaptureVertexInterleaved::buildProgram; |
| virtual void buildProgram(glw::GLuint primitive_case); |
| virtual void draw(glw::GLuint primitive_case); |
| |
| static const glw::GLchar* s_geometry_shader_source_code_template; |
| static const glw::GLchar* s_blank_vertex_shader_source_code; |
| |
| static const glw::GLchar* s_geometry_interleaved_primitive_cases[]; |
| static const glw::GLenum s_geometry_interleaved_primitive_cases_xfb[]; |
| static const glw::GLuint s_geometry_interleaved_primitive_cases_count; |
| }; |
| |
| /** CaptureVertexSeparate |
| * |
| * Verifies if geometry processed with vertex shader is captured as expected in |
| * separate mode. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is |
| * at least 3.0. |
| * |
| * Modify CaptureVertexInterleaved test in the following aspects: |
| * - use transform feedback in separate mode. |
| * |
| * Separate mode require one buffer per captured variable. |
| * |
| * Number of attributes and components that can be captured is limited by: |
| * - MAX TRANSFORM FEEDBACK SEPARATE ATTRIBS, |
| * - MAX TRANSFORM FEEDBACK SEPARATE COMPONENTS. |
| */ |
| class CaptureVertexSeparate : virtual public CaptureVertexInterleaved |
| { |
| public: |
| CaptureVertexSeparate(deqp::Context& context, const char* test_name, const char* test_description); |
| |
| protected: |
| glw::GLuint* m_buffers; |
| glw::GLint m_max_transform_feedback_separate_attribs; |
| |
| virtual void fetchLimits(void); |
| virtual void createTransformFeedbackBuffer(void); |
| virtual void bindBuffer(BindBufferCase bind_case); |
| virtual void cleanBuffer(void); |
| virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); |
| }; |
| |
| /** CaptureGeometrySeparate |
| * |
| * Verifies if geometry processed with geometry shader is captured as expected |
| * in separate mode. |
| * |
| * Test should be run if either EXT_transform_feedback is supported or context |
| * is at least 3.0 and either ARB_geometry_shader4 is supported or context is |
| * at least 3.2. |
| * |
| * Modify CaptureGeometryInterleaved test in the following aspects: |
| * - use transform feedback in separate mode. |
| * |
| * Separate mode require one buffer per captured variable. |
| * |
| * Number of attributes and components that can be captured is limited by: |
| * - MAX TRANSFORM FEEDBACK SEPARATE ATTRIBS, |
| * - MAX TRANSFORM FEEDBACK SEPARATE COMPONENTS. |
| */ |
| class CaptureGeometrySeparate : public CaptureGeometryInterleaved, virtual public CaptureVertexSeparate |
| { |
| public: |
| CaptureGeometrySeparate(deqp::Context& context, const char* test_name, const char* test_description); |
| virtual IterateResult iterate(void) |
| { |
| return CaptureGeometryInterleaved::iterate(); |
| }; |
| |
| protected: |
| glw::GLuint* m_buffers; |
| glw::GLint m_max_transform_feedback_separate_attribs; |
| |
| virtual void draw(glw::GLenum primitive_type) |
| { |
| CaptureGeometryInterleaved::draw(primitive_type); |
| }; |
| virtual void fetchLimits(void) |
| { |
| CaptureVertexSeparate::fetchLimits(); |
| }; |
| virtual void createTransformFeedbackBuffer(void) |
| { |
| CaptureVertexSeparate::createTransformFeedbackBuffer(); |
| }; |
| virtual void bindBuffer(BindBufferCase bind_case) |
| { |
| CaptureVertexSeparate::bindBuffer(bind_case); |
| }; |
| virtual void cleanBuffer(void) |
| { |
| CaptureVertexSeparate::cleanBuffer(); |
| }; |
| virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type) |
| { |
| return CaptureVertexSeparate::checkTransformFeedbackBuffer(bind_case, primitive_type); |
| }; |
| }; |
| |
| /** GetXFBVaryingVertexInterleaved |
| * |
| * Verifies if varyings captured from vertex stage are correctly reported in |
| * interleaved mode. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is |
| * at least 3.0. |
| * |
| * Steps: |
| * - prepare program consisting of vertex and fragment shader; Vertex shader |
| * should define and assign maximum allowed number of varyings of tested type; |
| * Fragment shader can be blank; |
| * - instruct implementation to capture all outputs defined by vertex shader; |
| * Use interleaved mode; |
| * - inspect all captured varying with GetTransformFeedbackVarying; |
| * - inspect TRANSFORM_FEEDBACK_VARYINGS; |
| * - inspect TRANSFORM_FEEDBACK_BUFFER_MODE; |
| * - inspect TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH. |
| * |
| * Test all valid types. |
| * |
| * |
| * GetXFBVaryingGeometryInterleaved |
| * |
| * Verifies if varyings captured from geometry stage are correctly reported in |
| * interleaved mode. |
| * |
| * Test should be run if either EXT_transform_feedback is supported or context |
| * is at least 3.0 and either ARB_geometry_shader4 is supported or context is |
| * at least 3.2. |
| * |
| * Modify GetXFBVaryingVertexInterleaved test in the following aspects: |
| * - outputs definition and assignment is done in geometry instead of |
| * vertex shader; |
| * - vertex shader can be blank; |
| * |
| * |
| * GetXFBVaryingVertexSeparate |
| * |
| * Verifies if varyings captured from vertex stage are correctly reported in |
| * separate mode. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is |
| * at least 3.0. |
| * |
| * Modify CaptureGeometryInterleaved test in the following aspects: |
| * - use transform feedback in separate mode. |
| * |
| * Separate mode require one buffer per captured variable. |
| * |
| * |
| * GetXFBVaryingGeometrySeparate |
| * |
| * Verifies if varyings captured from geometry stage are correctly reported in |
| * separate mode. |
| * |
| * Test should be run if either EXT_transform_feedback is supported or context |
| * is at least 3.0 and either ARB_geometry_shader4 is supported or context is |
| * at least 3.2. |
| * |
| * Modify GetXFBVaryingGeometryInterleaved test in the following aspects: |
| * - use transform feedback in separate mode. |
| * |
| * Separate mode require one buffer per captured variable. |
| */ |
| class CheckGetXFBVarying : public deqp::TestCase |
| { |
| public: |
| CheckGetXFBVarying(deqp::Context& context, const char* test_name, const char* test_description); |
| ~CheckGetXFBVarying(void); |
| virtual IterateResult iterate(void); |
| |
| private: |
| deqp::Context& m_context; |
| glw::GLint m_max_xfb_interleaved_components; |
| glw::GLint m_max_xfb_separate_attributes; |
| glw::GLint m_max_xfb_separate_components; |
| glw::GLint m_max_varying_components; |
| glw::GLint m_max_varying_vectors; |
| glw::GLint m_max_geometry_total_output_components; |
| |
| void fetchLimits(void); |
| glw::GLuint numberOfAttributes(glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type); |
| |
| glw::GLuint buildProgram(glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type, |
| glw::GLuint number_of_attributes); |
| |
| bool check(glw::GLuint program, glw::GLuint capture_way, glw::GLuint shader_case, glw::GLuint varying_type, |
| glw::GLuint number_of_attributes); |
| |
| static const glw::GLchar* s_generic_fragment_shader; |
| |
| static const struct ShaderCase |
| { |
| const glw::GLchar* vertex_shader; |
| const glw::GLchar* geometry_shader; |
| } s_shader_cases[]; |
| |
| static const glw::GLuint s_shader_cases_count; |
| |
| static const struct VaryingType |
| { |
| const glw::GLenum type; |
| const glw::GLchar* name; |
| const glw::GLuint components_count; |
| const bool float_component; |
| } s_varying_types[]; |
| |
| static const glw::GLuint s_varying_types_count; |
| |
| static const glw::GLenum s_capture_ways[]; |
| static const glw::GLuint s_capture_ways_count; |
| }; |
| |
| /** QueryVertexInterleaved |
| * |
| * Verifies if queries are performed as expected when geometry is captured from |
| * vertex stage in interleaved mode. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is |
| * at least 3.0. |
| * |
| * Modify CaptureVertexInterleaved test in the following aspects: |
| * - buffer used as storage for captured geometry should be too small to fit |
| * all emitted vertices; |
| * - execute BeginQuery for PRIMITIVES_GENERATED and |
| * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries |
| * after draw call. |
| * |
| * Test pass if results of queries are correct. |
| */ |
| class QueryVertexInterleaved : public CaptureVertexInterleaved |
| { |
| public: |
| QueryVertexInterleaved(deqp::Context& context, const char* test_name, const char* test_description); |
| |
| protected: |
| glw::GLuint m_query_object; |
| |
| virtual void createTransformFeedbackBuffer(void); |
| virtual void draw(glw::GLuint primitive_case); |
| virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); |
| virtual void clean(void); |
| }; |
| |
| /** QueryGeometryInterleaved |
| * |
| * Verifies if queries are performed as expected when geometry is captured from |
| * geometry stage in interleaved mode. |
| * |
| * Test should be run if either EXT_transform_feedback is supported or context |
| * is at least 3.0 and either ARB_geometry_shader4 is supported or context is |
| * at least 3.2. |
| * |
| * Modify CaptureGeometryInterleaved test in the following aspects: |
| * - buffer used as storage for captured geometry should be too small to fit |
| * all emitted vertices; |
| * - execute BeginQuery for PRIMITIVES_GENERATED and |
| * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries |
| * after draw call. |
| * |
| * Test pass if results of queries are correct. |
| */ |
| class QueryGeometryInterleaved : public CaptureGeometryInterleaved |
| { |
| public: |
| QueryGeometryInterleaved(deqp::Context& context, const char* test_name, const char* test_description); |
| |
| protected: |
| glw::GLuint m_query_object; |
| |
| virtual void createTransformFeedbackBuffer(void); |
| virtual void draw(glw::GLuint primitive_case); |
| virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); |
| virtual void clean(void); |
| }; |
| |
| /** QueryVertexSeparate |
| * |
| * Verifies if queries are performed as expected when geometry is captured from |
| * vertex stage in separate mode. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is |
| * at least 3.0. |
| * |
| * Modify CaptureVertexSeparate test in the following aspects: |
| * - buffers used as storage for captured geometry should be too small to fit |
| * all emitted vertices; |
| * - execute BeginQuery for PRIMITIVES_GENERATED and |
| * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries |
| * after draw call; |
| * - use transform feedback in separate mode. |
| * |
| * Separate mode require one buffer per captured variable. |
| * |
| * Test pass if results of queries are correct. |
| */ |
| class QueryVertexSeparate : public CaptureVertexSeparate |
| { |
| public: |
| QueryVertexSeparate(deqp::Context& context, const char* test_name, const char* test_description); |
| |
| protected: |
| glw::GLuint m_query_object; |
| |
| virtual void createTransformFeedbackBuffer(void); |
| virtual void draw(glw::GLuint primitive_case); |
| virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); |
| virtual void clean(void); |
| }; |
| |
| /** QueryGeometrySeparate |
| * |
| * Verifies if queries are performed as expected when geometry is captured from |
| * geometry stage in separate mode. |
| * |
| * Test should be run if either EXT_transform_feedback is supported or context |
| * is at least 3.0 and either ARB_geometry_shader4 is supported or context is |
| * at least 3.2. |
| * |
| * Modify CaptureGeometrySeparate test in the following aspects: |
| * - buffers used as storage for captured geometry should be too small to fit |
| * all emitted vertices; |
| * - execute BeginQuery for PRIMITIVES_GENERATED and |
| * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN before draw is executed; End queries |
| * after draw call; |
| * - use transform feedback in separate mode. |
| * |
| * Separate mode require one buffer per captured variable. |
| * |
| * Test pass if results of queries are correct. |
| */ |
| class QueryGeometrySeparate : public CaptureGeometrySeparate |
| { |
| public: |
| QueryGeometrySeparate(deqp::Context& context, const char* test_name, const char* test_description); |
| |
| protected: |
| glw::GLuint m_query_object; |
| |
| virtual void createTransformFeedbackBuffer(void); |
| virtual void draw(glw::GLuint primitive_case); |
| virtual bool checkTransformFeedbackBuffer(BindBufferCase bind_case, glw::GLenum primitive_type); |
| virtual void clean(void); |
| }; |
| |
| /** DiscardVertex |
| * |
| * Verifies if rasterization is discarded when geometry is captured from vertex |
| * stage. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is |
| * at least 3.0. |
| * |
| * Modify CaptureVertexInterleaved test in the following aspects: |
| * - disable rasterization before draw call; |
| * - it is expected that framebuffer contents will not change, while XFB buffer |
| * is modified. |
| */ |
| class DiscardVertex : public CaptureVertexInterleaved |
| { |
| public: |
| DiscardVertex(deqp::Context& context, const char* test_name, const char* test_description); |
| |
| protected: |
| virtual void draw(glw::GLuint primitive_case); |
| virtual bool checkFramebuffer(glw::GLuint primitive_case); |
| }; |
| |
| /** DiscardGeometry |
| * |
| * Verifies if rasterization is discarded when geometry is captured from |
| * geometry stage. |
| * |
| * Test should be run if EXT_transform_feedback is supported or context is at least 3.0. |
| * Test should be run if ARB_geometry_shader4 is supported or context is at least 3.2. |
| * |
| * Modify CaptureGeometryInterleaved test in the following aspects: |
| * - disable rasterization before draw call; |
| * - it is expected that framebuffer contents will not change, while XFB buffer |
| * is modified. |
| */ |
| class DiscardGeometry : public CaptureGeometryInterleaved |
| { |
| public: |
| DiscardGeometry(deqp::Context& context, const char* test_name, const char* test_description); |
| |
| protected: |
| virtual void draw(glw::GLuint primitive_case); |
| virtual bool checkFramebuffer(glw::GLuint primitive_case); |
| }; |
| |
| /** DrawXFB |
| * |
| * Verifies that transform feedback objects can be used to draw. |
| * |
| * Test should be executed if ARB_transform_feedback2 is supported or context |
| * is at least 4.0. |
| * |
| * Steps: |
| * - prepare two programs consisting of vertex shader which will: |
| * * output position based on gl_VertexID: |
| * * output color by passing value of uniform; |
| * First program should use the following positions: |
| * ID | X | Y |
| * 0 | -1 | -1 |
| * 1 | -1 | 1 |
| * 2 | 1 | 1 |
| * Second program should use the following positions: |
| * 0 | -1 | -1 |
| * 1 | 1 | 1 |
| * 2 | 1 | -1 |
| * - prepare three XFB objects and corresponding buffers for captured geometry; |
| * Each XFB should capture position and color from both programs; |
| * - activate first program; |
| * - for each XFB object: |
| * * set uniform to color corresponding with XFB; |
| * * activate XFB; |
| * * execute DrawArrays to draw three points starting at 0; |
| * * pause XFB; |
| * - inspect TRANSFORM_FEEDBACK_BUFFER_PAUSED and |
| * TRANSFORM_FEEDBACK_BUFFER_ACTIVE; |
| * - activate second program; |
| * - for each XFB object: |
| * * set uniform to color corresponding with XFB; |
| * * resume XFB; |
| * * execute DrawArrays to draw three points starting at 0; |
| * * end XFB; |
| * - inspect TRANSFORM_FEEDBACK_BUFFER_PAUSED and |
| * TRANSFORM_FEEDBACK_BUFFER_ACTIVE; |
| * - prepare program consisting of vertex and fragment stage; Vertex shader |
| * should pass position and color; Fragment stage should pass color; |
| * - set program; |
| * - set vertex array to match layout of XFB; |
| * - for each XFB: |
| * * prepare and clean framebuffer; |
| * * execute DrawTransformFeedback to draw triangles; |
| * * inspect contents of framebuffer; |
| * |
| * It is expected that drawn images will be filled with color set via uniform |
| * variables. |
| * |
| * Repeat steps for both interleaved and separate modes. |
| */ |
| class DrawXFB : public deqp::TestCase |
| { |
| public: |
| DrawXFB(deqp::Context& context, const char* test_name, const char* test_description); |
| ~DrawXFB(void); |
| virtual IterateResult iterate(void); |
| |
| protected: |
| static const glw::GLchar* s_vertex_shader_xfb; |
| static const glw::GLchar* s_vertex_shader_draw; |
| static const glw::GLchar* s_fragment_shader; |
| |
| static const glw::GLuint s_xfb_varyings_count = 2; |
| static const glw::GLchar* s_xfb_varyings[s_xfb_varyings_count]; |
| static const glw::GLuint s_vertex_count = 3; |
| static const glw::GLenum s_capture_modes[]; |
| static const glw::GLuint s_capture_modes_count; |
| static const glw::GLuint s_capture_size = s_vertex_count * sizeof(glw::GLfloat) * 4 /* number of components */ * |
| s_xfb_varyings_count * 2 /* number of programs */; |
| static const glw::GLuint s_view_size = 2; |
| static const glw::GLuint s_xfb_count = 3; |
| static const glw::GLfloat s_colours[s_xfb_count][4]; |
| |
| deqp::Context& m_context; |
| glw::GLuint m_program_id_xfb; |
| glw::GLuint m_program_id_draw; |
| glw::GLuint m_xfb_id[s_xfb_count]; |
| glw::GLuint m_bo_id[s_xfb_count]; |
| glw::GLuint m_fbo_id; |
| glw::GLuint m_rbo_id; |
| glw::GLuint m_vao_id; |
| |
| void prepare(glw::GLenum capture_mode); |
| void bindXFB(glw::GLuint xfb_id); |
| void bindVAO(glw::GLuint vao_id); |
| void bindBOForXFB(glw::GLenum capture_mode, glw::GLuint bo_id); |
| void bindBOForDraw(glw::GLuint program_id, glw::GLenum capture_mode, glw::GLuint bo_id); |
| void useProgram(glw::GLuint program_id); |
| void useColour(glw::GLuint program_id, glw::GLfloat r, glw::GLfloat g, glw::GLfloat b, glw::GLfloat a); |
| void useGeometrySet(glw::GLuint program_id, bool invert_sign); |
| void drawForCapture(bool begin_xfb, bool pause_xfb, bool resume_xfb, bool end_xfb); |
| void drawToFramebuffer(glw::GLuint xfb_id); |
| bool checkFramebuffer(glw::GLfloat r, glw::GLfloat g, glw::GLfloat b, glw::GLfloat a); |
| bool inspectXFBState(bool shall_be_paused, bool shall_be_active); |
| void clean(); |
| }; |
| |
| /** DrawXFBFeedback |
| * |
| * Verifies that data captured with XFB can be used as source for next capture. |
| * |
| * Test should be executed if ARB_transform_feedback2 is supported or context |
| * is at least 4.0. |
| * |
| * Steps: |
| * - prepare program consisting of vertex shader which pass position from input |
| * attribute to gl_Position multiplying it by 2.0; |
| * - instruct implementation to capture geometry in interleaved mode; |
| * - prepare source buffer; |
| * - prepare buffer to capture geometry; |
| * - begin transform feedback; |
| * - draw one vertex using DrawArrays; |
| * - end transform feedback; |
| * - swap buffer |
| * - begin transform feedback; |
| * - draw using DrawTransformFeedback; |
| * - end transform feedback; |
| * - swap buffer |
| * - begin transform feedback; |
| * - draw using DrawTransformFeedback; |
| * - end transform feedback; |
| * - map last captured buffer, expect position vector multiplied by value 8; |
| */ |
| class DrawXFBFeedback : public deqp::TestCase |
| { |
| public: |
| DrawXFBFeedback(deqp::Context& context, const char* test_name, const char* test_description); |
| ~DrawXFBFeedback(void); |
| virtual IterateResult iterate(void); |
| |
| protected: |
| static const glw::GLchar* s_vertex_shader; |
| static const glw::GLchar* s_fragment_shader; |
| static const glw::GLchar* s_xfb_varying; |
| static const glw::GLchar* s_attrib; |
| static const glw::GLuint s_draw_vertex_count; |
| static const glw::GLfloat s_initial_data[]; |
| static const glw::GLuint s_bo_count = 2; |
| static const glw::GLuint s_bo_size; |
| |
| deqp::Context& m_context; |
| glw::GLuint m_program_id; |
| glw::GLuint m_vao_id[s_bo_count]; |
| glw::GLuint m_xfb_id; |
| glw::GLuint m_bo_id[s_bo_count]; |
| glw::GLuint m_source_bo_index; |
| |
| void prepareAndBind(); |
| void draw(bool is_first_draw); |
| void swapBuffers(); |
| bool check(); |
| void clean(); |
| }; |
| |
| /** DrawXFBStream |
| * |
| * Verifies that vertex stream captured with transform feedback can be used to |
| * draw. |
| * |
| * Test should be executed if both ARB_transform_feedback3 and ARB_gpu_shader5 |
| * are supported or context is at least 4.0. |
| * This test is not supported if MAX_VERTEX_STREAMS is less than 2. |
| * |
| * Steps: |
| * - prepare program consisting of vertex and geometry shaders; Geometry shader |
| * should output full-screen quad made of two triangles; First triangle should |
| * be emitted to first vertex stream; Second triangle should be emitted to the |
| * second vertex stream; Vertex shader can be blank; |
| * - prepare buffers to capture geometry; |
| * - instruct implementation to capture geometry in interleaved mode; |
| * - begin XFB; |
| * - begin indexed query for PRIMITIVES_GENERATED and |
| * TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN for both vertex streams; |
| * - draw single vertex; |
| * - end queries; |
| * - end XFB; |
| * - inspect results of queries; |
| * - prepare program consisting of vertex and fragment shaders; Vertex stage |
| * should pass position from input to output; Fragment shader should output |
| * white color; |
| * - prepare and clean framebuffer; |
| * - set vertex array layout to match data captured by XFB; |
| * - execute DrawTransformFeedbackStream to draw triangle from first stream; |
| * - execute DrawTransformFeedbackStream to draw triangle from second stream; |
| * - inspect contents of framebuffer, it is expected to be filled with white |
| * color. |
| */ |
| class DrawXFBStream : public deqp::TestCase |
| { |
| public: |
| DrawXFBStream(deqp::Context& context, const char* test_name, const char* test_description); |
| ~DrawXFBStream(void); |
| virtual IterateResult iterate(void); |
| |
| private: |
| static const glw::GLchar* s_vertex_shader_pass; |
| static const glw::GLchar* s_vertex_shader_blank; |
| static const glw::GLchar* s_geometry_shader; |
| static const glw::GLchar* s_fragment_shader; |
| static const glw::GLchar* s_xfb_varyings[]; |
| static const glw::GLuint s_xfb_varyings_count; |
| static const glw::GLuint s_bo_ids_count = 2; |
| static const glw::GLuint s_qo_ids_count = 4; |
| static const glw::GLuint s_bo_size; |
| static const glw::GLuint s_view_size; |
| |
| deqp::Context& m_context; |
| glw::GLuint m_program_id_generate; |
| glw::GLuint m_program_id_draw; |
| glw::GLuint m_vao_id; |
| glw::GLuint m_xfb_id; |
| glw::GLuint m_bo_id[s_bo_ids_count]; |
| glw::GLuint m_fbo_id; |
| glw::GLuint m_rbo_id; |
| glw::GLuint m_qo_id[s_qo_ids_count]; |
| |
| void prepareObjects(); |
| void setupVertexArray(glw::GLuint bo_id); |
| void useProgram(glw::GLuint program_id); |
| void drawForXFB(); |
| bool inspectQueries(); |
| void drawForFramebuffer(glw::GLuint stream); |
| bool check(); |
| void clean(); |
| }; |
| |
| /** CaptureSpecialInterleaved |
| * |
| * Verifies that special variable names are respected. |
| * |
| * Test should be executed if ARB_transform_feedback3 is supported or context |
| * is at least 4.0. |
| * |
| * Steps: |
| * - prepare program consisting of vertex shader which outputs four variables; |
| * - set up XFB to capture the following <varyings>: |
| * * variable_1, |
| * * gl_SkipComponents4, |
| * * variable_2, |
| * * gl_NextBuffer, |
| * * variable_3, |
| * * gl_SkipComponents4, |
| * * variable_4; |
| * - begin XFB; |
| * - draw two vertices; |
| * - end XFB; |
| * - verify that captured geometry is correct. |
| */ |
| class CaptureSpecialInterleaved : public deqp::TestCase |
| { |
| public: |
| CaptureSpecialInterleaved(deqp::Context& context, const char* test_name, const char* test_description); |
| ~CaptureSpecialInterleaved(void); |
| virtual IterateResult iterate(void); |
| |
| private: |
| static const glw::GLchar* s_vertex_shader; |
| static const glw::GLchar* s_fragment_shader; |
| static const glw::GLchar* s_xfb_varyings[]; |
| static const glw::GLuint s_xfb_varyings_count; |
| static const glw::GLuint s_bo_ids_count = 2; |
| static const glw::GLuint s_bo_size; |
| |
| deqp::Context& m_context; |
| glw::GLuint m_program_id; |
| glw::GLuint m_vao_id; |
| glw::GLuint m_xfb_id; |
| glw::GLuint m_bo_id[s_bo_ids_count]; |
| |
| void prepareAndBind(); |
| void draw(); |
| bool check(); |
| void clean(); |
| }; |
| |
| /** DrawXFBInstanced |
| * |
| * Verifies that transform feedback objects can used with instanced draws. |
| * |
| * Test should be executed if context is at least 3.1 and either |
| * ARB_transform_feedback_instanced is supported or context is at least 4.2. |
| * |
| * Steps: |
| * - prepare program consisting of vertex shader which outputs positions of |
| * full-screen quad made of triangle strip based on gl_VertexID; |
| * - instruct implementation to capture geometry in interleaved mode; |
| * - prepare buffer to capture geometry; |
| * - begin transform feedback; |
| * - draw four vertices; |
| * - end transform feedback; |
| * - prepare program consisting of vertex and fragment shaders; Vertex stage |
| * should calculate position as follows: |
| * |
| * gl_Position = in_position * uni_matrices[gl_InstanceID]; |
| * |
| * Fragment shader should output white color; |
| * - prepare UNIFORM_BUFFER filled with four mat4; Select data so matrices |
| * transforms quad [-1, -1] : [1, 1] as follows: |
| * * 0 - [-1, 0] : [0, 1] - left top, |
| * * 1 - [ 0, 0] : [1, 1] - right top, |
| * * 2 - [-1, -1] : [0, 0] - left bottom, |
| * * 3 - [ 0, -1] : [1, 0] - right bottom; |
| * - prepare and clean framebuffer; |
| * - set up layout of vertex data in XFB; |
| * - execute DrawTransformFeedbackInstanced to draw four instances of quad from XFB; |
| * - it is expected that framebuffer is filled with white color; |
| */ |
| class DrawXFBInstanced : public deqp::TestCase |
| { |
| public: |
| DrawXFBInstanced(deqp::Context& context, const char* test_name, const char* test_description); |
| ~DrawXFBInstanced(void); |
| virtual IterateResult iterate(void); |
| |
| private: |
| static const glw::GLchar* s_vertex_shader_generate; |
| static const glw::GLchar* s_vertex_shader_draw; |
| static const glw::GLchar* s_fragment_shader; |
| static const glw::GLchar* s_xfb_varying; |
| static const glw::GLchar* s_uniform; |
| static const glw::GLuint s_bo_xfb_size; |
| static const glw::GLfloat s_bo_uniform_data[]; |
| static const glw::GLuint s_bo_uniform_size; |
| static const glw::GLuint s_view_size; |
| |
| deqp::Context& m_context; |
| glw::GLuint m_program_id_generate; |
| glw::GLuint m_program_id_draw; |
| glw::GLuint m_vao_id; |
| glw::GLuint m_xfb_id; |
| glw::GLuint m_bo_id_xfb; |
| glw::GLuint m_bo_id_uniform; |
| glw::GLuint m_fbo_id; |
| glw::GLuint m_rbo_id; |
| |
| void prepareObjects(); |
| void drawForXFB(); |
| void drawInstanced(); |
| bool check(); |
| void clean(); |
| |
| typedef GLW_APICALL glw::GLuint (GLW_APIENTRY *GetUniformBlockIndex_ProcAddress)(glw::GLuint program, const glw::GLchar* uniformBlockName); |
| typedef GLW_APICALL void (GLW_APIENTRY *UniformBlockBinding_ProcAddress)(glw::GLuint program, |
| glw::GLuint uniformIndex, |
| glw::GLuint uniformBlockBinding); |
| |
| GetUniformBlockIndex_ProcAddress m_glGetUniformBlockIndex; |
| UniformBlockBinding_ProcAddress m_glUniformBlockBinding; |
| }; |
| |
| /** DrawXFBStreamInstanced |
| * |
| * Verifies that transform feedback objects can used with instanced draws. |
| * |
| * Test should be executed if context is at least 3.1 and either |
| * ARB_gpu_shader5 is supported or context is at least 4.0 and either |
| * ARB_transform_feedback_instanced is supported or context is at least 4.2. |
| * |
| * Steps: |
| * - prepare program consisting of vertex shader which based on gl_VertexID |
| * outputs: |
| * * to stream 0 - color, |
| * * to stream 1 - positions |
| * for a full-screen quad made of triangle strip; |
| * - instruct implementation to capture geometry in interleaved mode; |
| * - prepare buffers to capture geometry; |
| * - begin transform feedback; |
| * - draw four vertices; |
| * - end transform feedback; |
| * - prepare program consisting of vertex and fragment shaders; Vertex stage |
| * should calculate position as follows: |
| * |
| * gl_Position = in_position * uni_matrices[gl_InstanceID]; |
| * |
| * Fragment shader should output white color; |
| * - prepare UNIFORM_BUFFER filled with four mat4; Select data so matrices |
| * transforms quad [-1, -1] : [1, 1] as follows: |
| * * 0 - [-1, 0] : [0, 1] - left top, |
| * * 1 - [ 0, 0] : [1, 1] - right top, |
| * * 2 - [-1, -1] : [0, 0] - left bottom, |
| * * 3 - [ 0, -1] : [1, 0] - right bottom; |
| * - prepare and clean framebuffer; |
| * - set up layout of vertex data in XFB; |
| * - execute DrawTransformFeedbackStreamInstanced to draw four instances of |
| * quad from XFB, stream 1; |
| * - it is expected that framebuffer is filled with white color; |
| */ |
| class DrawXFBStreamInstanced : public deqp::TestCase |
| { |
| public: |
| DrawXFBStreamInstanced(deqp::Context& context, const char* test_name, const char* test_description); |
| ~DrawXFBStreamInstanced(void); |
| virtual IterateResult iterate(void); |
| |
| private: |
| static const glw::GLchar* s_vertex_shader_blank; |
| static const glw::GLchar* s_geometry_shader_generate; |
| static const glw::GLchar* s_vertex_shader_draw; |
| static const glw::GLchar* s_fragment_shader_blank; |
| static const glw::GLchar* s_fragment_shader_draw; |
| static const glw::GLchar* s_xfb_varyings[]; |
| static const glw::GLuint s_xfb_varyings_count; |
| static const glw::GLchar* s_uniform; |
| static const glw::GLuint s_bo_xfb_size; |
| static const glw::GLfloat s_bo_uniform_data[]; |
| static const glw::GLuint s_bo_uniform_size; |
| static const glw::GLuint s_view_size; |
| |
| deqp::Context& m_context; |
| glw::GLuint m_program_id_generate; |
| glw::GLuint m_program_id_draw; |
| glw::GLuint m_vao_id; |
| glw::GLuint m_xfb_id; |
| glw::GLuint m_bo_id_xfb_position; |
| glw::GLuint m_bo_id_xfb_color; |
| glw::GLuint m_bo_id_uniform; |
| glw::GLuint m_fbo_id; |
| glw::GLuint m_rbo_id; |
| |
| void prepareObjects(); |
| void drawForXFB(); |
| void drawStreamInstanced(); |
| bool check(); |
| void clean(); |
| |
| typedef GLW_APICALL glw::GLuint (GLW_APIENTRY *GetUniformBlockIndex_ProcAddress)(glw::GLuint program, const glw::GLchar* uniformBlockName); |
| typedef GLW_APICALL void (GLW_APIENTRY *UniformBlockBinding_ProcAddress)(glw::GLuint program, |
| glw::GLuint uniformIndex, |
| glw::GLuint uniformBlockBinding); |
| |
| GetUniformBlockIndex_ProcAddress m_glGetUniformBlockIndex; |
| UniformBlockBinding_ProcAddress m_glUniformBlockBinding; |
| }; |
| |
| namespace Utilities |
| { |
| /** Build a GLSL program |
| * |
| * @param [in] gl OpenGL Functions Access. |
| * @param [in] log Log outut. |
| * @param [in] geometry_shader_source Pointer to C string of the geometry shader or NULL if not used. |
| * @param [in] tessellation_control_shader_source Pointer to C string of the tessellation control shader or NULL if not used. |
| * @param [in] tessellation_evaluation_shader_source Pointer to C string of the tessellation evaluation shader or NULL if not used. |
| * @param [in] vertex_shader_source Pointer to C string of the vertex shader or NULL if not used. |
| * @param [in] geometry_shader_source Pointer to C string of the fragment shader or NULL if not used. |
| * @param [in] transform_feedback_varyings C array of transform feedback varyings names. |
| * @param [in] transform_feedback_varyings_count Count of transform feedback varyings names. |
| * @param [in] transform_feedback_varyings_mode Transform feedback capture mode - GL_SEPARATE_ATTRIBS or GL_INTERLEAVED_ATTRIBS. |
| * @param [in] do_not_detach Do not detach shaders - default is faulse. |
| * @param [out] linking_status Return pointer to store linking status or NULL if not needed. |
| * |
| * @return OpenGL program shader ID or zero if error had occured. |
| */ |
| glw::GLuint buildProgram(glw::Functions const& gl, tcu::TestLog& log, glw::GLchar const* const geometry_shader_source, |
| glw::GLchar const* const tessellation_control_shader_source, |
| glw::GLchar const* const tessellation_evaluation_shader_source, |
| glw::GLchar const* const vertex_shader_source, glw::GLchar const* const fragment_shader_source, |
| glw::GLchar const* const* const transform_feedback_varyings, |
| glw::GLsizei const transform_feedback_varyings_count, |
| glw::GLenum const transform_feedback_varyings_mode, bool const do_not_detach = false, |
| glw::GLint* linking_status = DE_NULL); |
| |
| /** Preprocess source string by replacing key tokens with new values. |
| * |
| * @param [in] source Source string. |
| * @param [in] key Key, substring to be replaced. |
| * @param [in] value Value, substring to be substituted in place of key. |
| * |
| * @return Preprocessed string. |
| */ |
| std::string preprocessCode(std::string source, std::string key, std::string value); |
| |
| /** Change integer number to string |
| * |
| * @param [in] i Integer number. |
| * |
| * @return String represnting integer number. |
| */ |
| std::string itoa(glw::GLint i); |
| |
| /** Change floating point number to string |
| * |
| * @param [in] f Floating point number. |
| * |
| * @return String represnting floating point number. |
| */ |
| std::string ftoa(glw::GLfloat f); |
| } /* Utilities namespace */ |
| } /* TransformFeedback namespace */ |
| |
| } /* gl3cts namespace */ |
| |
| #endif // _GL3CTRANSFORMFEEDBACKTESTS_HPP |