| #ifndef _ESEXTCGEOMETRYSHADERRENDERING_HPP |
| #define _ESEXTCGEOMETRYSHADERRENDERING_HPP |
| /*------------------------------------------------------------------------- |
| * OpenGL Conformance Test Suite |
| * ----------------------------- |
| * |
| * Copyright (c) 2014-2016 The Khronos Group Inc. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ /*! |
| * \file |
| * \brief |
| */ /*-------------------------------------------------------------------*/ |
| |
| #include "../esextcTestCaseBase.hpp" |
| |
| namespace glcts |
| { |
| |
| /** Supported geometry shader output layout qualifiers */ |
| typedef enum { |
| /* points */ |
| SHADER_OUTPUT_TYPE_POINTS, |
| /* lines */ |
| SHADER_OUTPUT_TYPE_LINE_STRIP, |
| /* triangles */ |
| SHADER_OUTPUT_TYPE_TRIANGLE_STRIP, |
| |
| /* Always last */ |
| SHADER_OUTPUT_TYPE_COUNT |
| } _shader_output_type; |
| |
| /** Implements Geometry Shader conformance test group 1. |
| * |
| * Note that actual testing is handled by classes implementing GeometryShaderRenderingCase |
| * interface. This class implements DEQP CTS test case interface, meaning it is only |
| * responsible for executing the test and reporting the results back to CTS. |
| * |
| **/ |
| class GeometryShaderRendering : public TestCaseGroupBase |
| { |
| public: |
| /* Public methods */ |
| GeometryShaderRendering(Context& context, const ExtParameters& extParams, const char* name, |
| const char* description); |
| |
| virtual ~GeometryShaderRendering() |
| { |
| } |
| |
| virtual void init(void); |
| |
| private: |
| /* Private type definitions */ |
| typedef enum { |
| /* points */ |
| SHADER_INPUT_POINTS, |
| |
| /* lines */ |
| SHADER_INPUT_LINES, |
| |
| /* lines_with_adjacency */ |
| SHADER_INPUT_LINES_WITH_ADJACENCY, |
| |
| /* triangles */ |
| SHADER_INPUT_TRIANGLES, |
| |
| /* triangles_with_adjacency */ |
| SHADER_INPUT_TRIANGLES_WITH_ADJACENCY, |
| |
| /* Always last */ |
| SHADER_INPUT_UNKNOWN |
| } _shader_input; |
| |
| /* Private methods */ |
| const char* getTestName(_shader_input input, _shader_output_type output_type, glw::GLenum drawcall_mode); |
| }; |
| |
| /* Defines an interface that all test case classes must implement. |
| * |
| * Base implementation initializes GLES objects later used in the specific test |
| * and fills them with content, as reported by actual test case implementations. |
| * |
| * Instances matching this interface are used by GeometryShaderRendering class |
| * to execute a set of all the tests as defined in the test specification. |
| */ |
| class GeometryShaderRenderingCase : public TestCaseBase |
| { |
| public: |
| /* Public type definitions */ |
| /** Supported draw call types. */ |
| typedef enum { |
| /* glDrawArrays() */ |
| DRAW_CALL_TYPE_GL_DRAW_ARRAYS, |
| |
| /* glDrawArraysInstanced() */ |
| DRAW_CALL_TYPE_GL_DRAW_ARRAYS_INSTANCED, |
| |
| /* glDrawElements() */ |
| DRAW_CALL_TYPE_GL_DRAW_ELEMENTS, |
| |
| /* glDrawElementsInstanced() */ |
| DRAW_CALL_TYPE_GL_DRAW_ELEMENTS_INSTANCED, |
| |
| /* glDrawRangeElements() */ |
| DRAW_CALL_TYPE_GL_DRAW_RANGE_ELEMENTS |
| |
| } _draw_call_type; |
| |
| /* Public methods */ |
| GeometryShaderRenderingCase(Context& Context, const ExtParameters& extParams, const char* name, |
| const char* description); |
| |
| virtual ~GeometryShaderRenderingCase() |
| { |
| } |
| |
| virtual void deinit(); |
| void executeTest(_draw_call_type type); |
| virtual IterateResult iterate(); |
| |
| protected: |
| /* Protected methods */ |
| void initTest(); |
| virtual unsigned int getAmountOfDrawInstances() = 0; |
| virtual unsigned int getAmountOfElementsPerInstance() = 0; |
| virtual unsigned int getAmountOfVerticesPerInstance() = 0; |
| virtual glw::GLenum getDrawCallMode() = 0; |
| virtual std::string getFragmentShaderCode() = 0; |
| virtual std::string getGeometryShaderCode() = 0; |
| virtual glw::GLuint getRawArraysDataBufferSize(bool instanced) = 0; |
| virtual const void* getRawArraysDataBuffer(bool instanced) = 0; |
| virtual void getRenderTargetSize(unsigned int n_instances, unsigned int* out_width, unsigned int* out_height) = 0; |
| virtual glw::GLuint getUnorderedArraysDataBufferSize(bool instanced) = 0; |
| virtual const void* getUnorderedArraysDataBuffer(bool instanced) = 0; |
| virtual glw::GLuint getUnorderedElementsDataBufferSize(bool instanced) = 0; |
| virtual const void* getUnorderedElementsDataBuffer(bool instanced) = 0; |
| virtual glw::GLenum getUnorderedElementsDataType() = 0; |
| virtual glw::GLubyte getUnorderedElementsMaxIndex() = 0; |
| virtual glw::GLubyte getUnorderedElementsMinIndex() = 0; |
| virtual std::string getVertexShaderCode() = 0; |
| virtual void verify(_draw_call_type drawcall_type, unsigned int instance_id, const unsigned char* data) = 0; |
| |
| virtual void setUniformsBeforeDrawCall(_draw_call_type /*drawcall_type*/) |
| { |
| } |
| |
| /* Protected variables */ |
| deqp::Context& m_context; |
| glw::GLuint m_instanced_raw_arrays_bo_id; |
| glw::GLuint m_instanced_unordered_arrays_bo_id; |
| glw::GLuint m_instanced_unordered_elements_bo_id; |
| glw::GLuint m_noninstanced_raw_arrays_bo_id; |
| glw::GLuint m_noninstanced_unordered_arrays_bo_id; |
| glw::GLuint m_noninstanced_unordered_elements_bo_id; |
| glw::GLuint m_fs_id; |
| glw::GLuint m_gs_id; |
| glw::GLuint m_po_id; |
| glw::GLuint m_renderingTargetSize_uniform_location; |
| glw::GLuint m_singleRenderingTargetSize_uniform_location; |
| glw::GLuint m_vao_id; |
| glw::GLuint m_vs_id; |
| |
| glw::GLuint m_fbo_id; |
| glw::GLuint m_read_fbo_id; |
| glw::GLuint m_to_id; |
| |
| glw::GLuint m_instanced_fbo_id; |
| glw::GLuint m_instanced_read_fbo_id; |
| glw::GLuint m_instanced_to_id; |
| }; |
| |
| /** Implements Geometry Shader conformance test group 1, 'points' input primitive type case. |
| * Test specification for this case follows: |
| * |
| * All sub-tests assume point size & line width of 1 pixel, which is the |
| * minimum maximum value for both properties in GLES 3.0. |
| * |
| * Let (R, G, B, A) be the color of the input point that is to be amplified. |
| * Color buffer should be cleared with (0, 0, 0, 0) prior to executing each |
| * of the scenarios. |
| * |
| * 1.1. If "points" output primitive type is used: |
| * |
| * The geometry shader should emit 9 points in total for a single input. |
| * Each point should be assigned a size of 1. The points should be |
| * positioned, so that they tightly surround the "input" point from left / |
| * right / top / left sides, as well as from top-left / top-right / |
| * bottom-left / bottom-right corners but do *not* overlap in screen-space. |
| * |
| * Additional points should also use (R, G, B, A) color. |
| * |
| * The test should draw 8 points (one after another, assume a horizontal |
| * delta of 2 pixels) of varying colors to a 2D texture of resolution 38x3. |
| * Test succeeds if centers of all emitted points have colors different than |
| * the background color. |
| * |
| * 1.2. If "lines" output primitive type is used: |
| * |
| * The geometry shader should draw outlines (built of line segments) of |
| * three quads nested within each other, as depicted below: |
| * |
| * 1 1 1 1 1 1 1 |
| * 1 2 2 2 2 2 1 |
| * 1 2 3 3 3 2 1 |
| * 1 2 3 * 3 2 1 |
| * 1 2 3 3 3 2 1 |
| * 1 2 2 2 2 2 1 |
| * 1 1 1 1 1 1 1 |
| * |
| * where each number corresponds to index of the quad and * indicates |
| * position of the input point which is not drawn. |
| * |
| * Each quad should be drawn with (R, G, B, A) color. |
| * The test should draw 8 points (one after another) of varying colors to |
| * a 2D texture of resolution 54x7. Test succeeds if all pixels making up |
| * the central quad 2 have valid colors. |
| * |
| * 1.3. If "triangles" output primitive type is used: |
| * |
| * The geometry shader should generate 2 triangle primitives for a single |
| * input point: |
| * |
| * * A) (Bottom-left corner, top-left corner, bottom-right corner), use |
| * (R, 0, 0, 0) color; |
| * * B) (Bottom-right corner, top-left corner, top-right corner), use |
| * (0, G, 0, 0) color; |
| * |
| * The test should draw 8 points (one after another) of varying colors to |
| * a 2D texture of resolution of resolution 48x6. Test succeeds if centers |
| * of the rendered triangles have valid colors. |
| * |
| **/ |
| class GeometryShaderRenderingPointsCase : public GeometryShaderRenderingCase |
| { |
| public: |
| /* Public methods */ |
| GeometryShaderRenderingPointsCase(Context& context, const ExtParameters& extParams, const char* name, |
| glw::GLenum drawcall_mode, _shader_output_type output_type); |
| |
| virtual ~GeometryShaderRenderingPointsCase(); |
| |
| protected: |
| /* GeometryShaderRenderingCase interface implementation */ |
| unsigned int getAmountOfDrawInstances(); |
| unsigned int getAmountOfElementsPerInstance(); |
| unsigned int getAmountOfVerticesPerInstance(); |
| glw::GLenum getDrawCallMode(); |
| std::string getFragmentShaderCode(); |
| std::string getGeometryShaderCode(); |
| glw::GLuint getRawArraysDataBufferSize(bool instanced); |
| const void* getRawArraysDataBuffer(bool instanced); |
| void getRenderTargetSize(unsigned int n_instances, unsigned int* out_width, unsigned int* out_height); |
| glw::GLuint getUnorderedArraysDataBufferSize(bool instanced); |
| const void* getUnorderedArraysDataBuffer(bool instanced); |
| glw::GLuint getUnorderedElementsDataBufferSize(bool instanced); |
| const void* getUnorderedElementsDataBuffer(bool instanced); |
| glw::GLenum getUnorderedElementsDataType(); |
| glw::GLubyte getUnorderedElementsMaxIndex(); |
| glw::GLubyte getUnorderedElementsMinIndex(); |
| std::string getVertexShaderCode(); |
| void verify(_draw_call_type drawcall_type, unsigned int instance_id, const unsigned char* data); |
| |
| private: |
| /* Private variables */ |
| _shader_output_type m_output_type; |
| |
| float* m_raw_array_data; |
| float* m_unordered_array_data; |
| unsigned char* m_unordered_elements_data; |
| }; |
| |
| /** Implements Geometry Shader conformance test group 1, 'lines' and |
| * 'lines_adjacency' input primitive type cases. |
| * |
| * Test specification for this case follows: |
| * |
| * Assume a point size of 1 pixel and line width of 1 pixel, where |
| * appropriate. |
| * Let (R, G, B, A) be the color of start point of the input line and |
| * (R', G', B', A') be the color of end point of the input line. |
| * |
| * 2.1. If "points" output primitive type is used: |
| * |
| * The geometry shader should generate 8 points for a single input line segment, |
| * where each point consists of 9 sub-points tightly forming a quad (with |
| * the actual point located in the center) in order to emulate larger point |
| * size. The points should be uniformly distributed over the primitive |
| * (first point positioned at the start point and the last one located at |
| * the end point) and their color should linearly interpolate from the |
| * (R, G, B, A) to (R', G', B', A'). All sub-points should use the same |
| * color as the parent point. |
| * |
| * The test should draw the points over a square outline. Each instance should |
| * draw a set of points occupying a separate outline. Each rectangle should |
| * occupy a block of 45x45. |
| * |
| * Test succeeds if centers of generated points have valid colors. |
| * |
| * 2.2. If "lines" output primitive type is used: |
| * |
| * Expanding on the idea presenting in 2.1, for each line segment the GS |
| * should generate three line segments, as presented below: |
| * |
| * Upper/left helper line segment |
| * Line segment |
| * Bottom/right helper line segment |
| * |
| * This is to emulate a larger line width than the minimum maximum line |
| * width all GLES implementations must support. |
| * |
| * Upper helper line segment should use start point's color; |
| * Middle line segment should take mix(start_color, end_color, 0.5) color; |
| * Bottom helper line segment should use end point's color; |
| * |
| * Test succeeds if all pixels of generated middle line segments have valid |
| * colors. Do not test corners. |
| * |
| * 2.3. If "triangles" output primitive type is used: |
| * |
| * Expanding on the idea presented in 2.1: for each input line segment, |
| * the GS should generate a triangle, using two vertices provided and |
| * (0, 0, 0, 1). By drawing a quad outline, whole screen-space should be |
| * covered with four triangles. |
| * The test passes if centroids of the generated triangles carry valid colors. |
| * |
| **/ |
| class GeometryShaderRenderingLinesCase : public GeometryShaderRenderingCase |
| { |
| public: |
| /* Public methods */ |
| GeometryShaderRenderingLinesCase(Context& context, const ExtParameters& extParams, const char* name, |
| bool use_adjacency_data, glw::GLenum drawcall_mode, |
| _shader_output_type output_type); |
| |
| virtual ~GeometryShaderRenderingLinesCase(); |
| |
| protected: |
| /* GeometryShaderRenderingCase interface implementation */ |
| unsigned int getAmountOfDrawInstances(); |
| unsigned int getAmountOfElementsPerInstance(); |
| unsigned int getAmountOfVerticesPerInstance(); |
| glw::GLenum getDrawCallMode(); |
| std::string getFragmentShaderCode(); |
| std::string getGeometryShaderCode(); |
| glw::GLuint getRawArraysDataBufferSize(bool instanced); |
| const void* getRawArraysDataBuffer(bool instanced); |
| void getRenderTargetSize(unsigned int n_instances, unsigned int* out_width, unsigned int* out_height); |
| glw::GLuint getUnorderedArraysDataBufferSize(bool instanced); |
| const void* getUnorderedArraysDataBuffer(bool instanced); |
| glw::GLuint getUnorderedElementsDataBufferSize(bool instanced); |
| const void* getUnorderedElementsDataBuffer(bool instanced); |
| glw::GLenum getUnorderedElementsDataType(); |
| glw::GLubyte getUnorderedElementsMaxIndex(); |
| glw::GLubyte getUnorderedElementsMinIndex(); |
| std::string getVertexShaderCode(); |
| void setUniformsBeforeDrawCall(_draw_call_type drawcall_type); |
| void verify(_draw_call_type drawcall_type, unsigned int instance_id, const unsigned char* data); |
| |
| private: |
| /* Private variables */ |
| _shader_output_type m_output_type; |
| |
| glw::GLenum m_drawcall_mode; |
| bool m_use_adjacency_data; |
| |
| float* m_raw_array_instanced_data; |
| unsigned int m_raw_array_instanced_data_size; |
| float* m_raw_array_noninstanced_data; |
| unsigned int m_raw_array_noninstanced_data_size; |
| |
| float* m_unordered_array_instanced_data; |
| unsigned int m_unordered_array_instanced_data_size; |
| float* m_unordered_array_noninstanced_data; |
| unsigned int m_unordered_array_noninstanced_data_size; |
| |
| unsigned char* m_unordered_elements_instanced_data; |
| unsigned int m_unordered_elements_instanced_data_size; |
| unsigned char* m_unordered_elements_noninstanced_data; |
| unsigned int m_unordered_elements_noninstanced_data_size; |
| |
| unsigned char m_unordered_elements_max_index; |
| unsigned char m_unordered_elements_min_index; |
| }; |
| |
| /** Implements Geometry Shader conformance test group 1, 'triangles' and |
| * 'triangles_adjacency' input primitive type cases. Test specification |
| * for this case follows: |
| * |
| * All tests should draw a 45-degree rotated square shape consisting of four |
| * separate triangles, as depicted in the picture below: |
| * |
| * |
| * C |
| * / \ |
| * / \ |
| * B--A--D |
| * \ / |
| * \_/ |
| * E |
| * |
| * For GL_TRIANGLES data, the rendering order is: ABC, ACD, ADE, AEB; |
| * For GL_TRIANGLE_FAN, the rendering order is: ABCDEB; |
| * For GL_TRIANGLE_STRIP, the rendering order is: BACDAEB; |
| * |
| * Note that for triangle strips, a degenerate triangle will be rendered. |
| * Test implementation should not test the first triangle rendered in the |
| * top-right quarter, as it will be overwritten by the triangle that follows |
| * right after. |
| * |
| * Subsequent draw call instances should draw the geometry one after another, |
| * in vertical direction. |
| * |
| * Each of the tests should use 29x(29 * number of instances) resolution for |
| * the rendertarget. |
| * |
| * 3.1. If "points" output primitive type is used: |
| * |
| * The geometry shader should generate 3 points for a single input triangle. |
| * These points should be emitted for each of the triangle's vertex |
| * locations and: |
| * |
| * * First vertex should be of (R, G, B, A) color; |
| * * Second vertex should be of (R', G', B', A') color; |
| * * Third vertex should be of (R'', G'', B'', A'') color; |
| * |
| * Each point should actually consist of 9 emitted points of size 1 (as |
| * described in test scenario 1.1), with the middle point being positioned |
| * at exact vertex location. This is to emulate larger point size than the |
| * minimum maximum allows. All emitted points should use the same color as |
| * parent point's. |
| * |
| * Test succeeds if centers of the rendered points have valid colors. |
| * |
| * 3.2. If "lines" output primitive type is used: |
| * |
| * Let: |
| * |
| * * TL represent top-left corner of the triangle's bounding box; |
| * * TR represent top-right corner of the triangle's bounding box; |
| * * BL represent bottom-left corner of the triangle's bounding box; |
| * * BR represent bottom-right corner of the triangle's bounding box; |
| * |
| * The geometry shader should draw 4 line segments for a single input |
| * triangle: |
| * |
| * * First line segment should start at BL and end at TL and use a static |
| * (R, G, B, A) color; |
| * * Second line segment should start at TL and end at TR and use a static |
| * (R', G', B', A') color; |
| * * Third line segment should start at TR and end at BR and use a static |
| * (R'', G'', B'', A'') color; |
| * * Fourth line segment should start at BR and end at BL and use a static |
| * (R, G', B'', A) color; |
| * |
| * Each line segment should actually consist of 3 separate line segments |
| * "stacked" on top of each other, with the middle segment being positioned |
| * as described above (as described in test scenario 2.2). This is to |
| * emulate line width that is larger than the minimum maximum allows. All |
| * emitted line segments should use the same color as parent line segment's. |
| * |
| * Test succeeds if centers of the rendered line segments have valid colors. |
| * |
| * 3.3. If "triangles" output primitive type is used: |
| * |
| * Test should take incoming triangle vertex locations and order them in the |
| * following order: |
| * |
| * a) A - vertex in the origin; |
| * b) B - the other vertex located on the same height as A; |
| * c) C - remaining vertex; |
| * |
| * Let D = BC/2. |
| * |
| * The test should emit ABD and ACD triangles for input ABC triangle data. |
| * First triangle emitted should take color of the first input vertex |
| * (not necessarily A!). |
| * The second one should use third vertex's color (not necessarily C!), |
| * with the first channel being multiplied by two. |
| * |
| * Test succeeds if centers of the rendered triangles have valid colors; |
| * |
| **/ |
| class GeometryShaderRenderingTrianglesCase : public GeometryShaderRenderingCase |
| { |
| public: |
| /* Public methods */ |
| GeometryShaderRenderingTrianglesCase(Context& context, const ExtParameters& extParams, const char* name, |
| bool use_adjacency_data, glw::GLenum drawcall_mode, |
| _shader_output_type output_type); |
| |
| virtual ~GeometryShaderRenderingTrianglesCase(); |
| |
| protected: |
| /* GeometryShaderRenderingCase interface implementation */ |
| unsigned int getAmountOfDrawInstances(); |
| unsigned int getAmountOfElementsPerInstance(); |
| unsigned int getAmountOfVerticesPerInstance(); |
| glw::GLenum getDrawCallMode(); |
| std::string getFragmentShaderCode(); |
| std::string getGeometryShaderCode(); |
| glw::GLuint getRawArraysDataBufferSize(bool instanced); |
| const void* getRawArraysDataBuffer(bool instanced); |
| void getRenderTargetSize(unsigned int n_instances, unsigned int* out_width, unsigned int* out_height); |
| glw::GLuint getUnorderedArraysDataBufferSize(bool instanced); |
| const void* getUnorderedArraysDataBuffer(bool instanced); |
| glw::GLuint getUnorderedElementsDataBufferSize(bool instanced); |
| const void* getUnorderedElementsDataBuffer(bool instanced); |
| glw::GLenum getUnorderedElementsDataType(); |
| glw::GLubyte getUnorderedElementsMaxIndex(); |
| glw::GLubyte getUnorderedElementsMinIndex(); |
| std::string getVertexShaderCode(); |
| void setUniformsBeforeDrawCall(_draw_call_type drawcall_type); |
| void verify(_draw_call_type drawcall_type, unsigned int instance_id, const unsigned char* data); |
| |
| private: |
| /* Private variables */ |
| _shader_output_type m_output_type; |
| |
| glw::GLenum m_drawcall_mode; |
| bool m_use_adjacency_data; |
| |
| float* m_raw_array_instanced_data; |
| unsigned int m_raw_array_instanced_data_size; |
| float* m_raw_array_noninstanced_data; |
| unsigned int m_raw_array_noninstanced_data_size; |
| |
| float* m_unordered_array_instanced_data; |
| unsigned int m_unordered_array_instanced_data_size; |
| float* m_unordered_array_noninstanced_data; |
| unsigned int m_unordered_array_noninstanced_data_size; |
| |
| unsigned char* m_unordered_elements_instanced_data; |
| unsigned int m_unordered_elements_instanced_data_size; |
| unsigned char* m_unordered_elements_noninstanced_data; |
| unsigned int m_unordered_elements_noninstanced_data_size; |
| |
| unsigned char m_unordered_elements_max_index; |
| unsigned char m_unordered_elements_min_index; |
| }; |
| |
| } // namespace glcts |
| |
| #endif // _ESEXTCGEOMETRYSHADERRENDERING_HPP |