1 #ifndef _ESEXTCGEOMETRYSHADERPRIMITIVECOUNTER_HPP 2 #define _ESEXTCGEOMETRYSHADERPRIMITIVECOUNTER_HPP 3 /*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 2014-2016 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 */ /*! 22 * \file 23 * \brief 24 */ /*-------------------------------------------------------------------*/ 25 26 #include "../esextcTestCaseBase.hpp" 27 #include <string.h> 28 29 namespace glcts 30 { 31 32 struct DataPrimitiveIDInCounter 33 { 34 glw::GLenum m_drawMode; 35 std::string m_emitVertexCodeForGeometryShader; 36 glw::GLenum m_feedbackMode; 37 std::string m_layoutIn; 38 std::string m_layoutOut; 39 glw::GLuint m_numberOfVerticesPerOneOutputPrimitive; 40 glw::GLuint m_numberOfVerticesPerOneInputPrimitive; 41 glw::GLuint m_numberOfDrawnPrimitives; 42 }; 43 44 /** Implementation of "Group 6" from CTS_EXT_geometry_shader. 45 * Test Group for "Group 6" tests, storing configuration data and initializing the tests. 46 * All tests from "Group 6" and children of GeometryShaderPrimitiveCounterTestGroup. 47 */ 48 class GeometryShaderPrimitiveCounterTestGroup : public TestCaseGroupBase 49 { 50 public: 51 /* Public methods */ 52 GeometryShaderPrimitiveCounterTestGroup(Context& context, const ExtParameters& extParams, const char* name, 53 const char* description); 54 ~GeometryShaderPrimitiveCounterTestGroup()55 virtual ~GeometryShaderPrimitiveCounterTestGroup() 56 { 57 } 58 59 virtual void init(void); 60 }; 61 62 /** 63 * 1. Make sure that a built-in geometry shader's input variable 64 * gl_PrimitiveIDIn increments correctly for all valid <draw call mode, 65 * input primitive type, output primitive type> tuples. 66 " 67 * Category: API; 68 * Functional Test. 69 * 70 * Let N_VERTICES represent amount of vertices that must be emitted, given 71 * active geometry shader's output primitive type, to form a single 72 * primitive that can be passed to rasterization stage 73 * 74 * Use Transform Feedback functionality to capture gl_PrimitiveIDIn value 75 * as read in the geometry shader: 76 * 77 * - The shader should emit: 78 * 79 * floor(GL_MAX_GEOMETRY_OUTPUT_VERTICES_EXT / N_VERTICES) / (4 + 1) 80 * 81 * primitives. It should call EndPrimitive() every N_VERTICES vertices 82 * emitted. 83 * 84 * - The draw call should be made for 1024 primitives. 85 * 86 * Test should fail if the result data for any of the tuples is determined 87 * to be incorrect. 88 */ 89 class GeometryShaderPrimitiveCounter : public TestCaseBase 90 { 91 public: 92 /* Public methods */ 93 GeometryShaderPrimitiveCounter(Context& context, const ExtParameters& extParams, const char* name, 94 const char* description, const DataPrimitiveIDInCounter& testConfiguration); 95 ~GeometryShaderPrimitiveCounter(void)96 virtual ~GeometryShaderPrimitiveCounter(void) 97 { 98 } 99 100 virtual void deinit(void); 101 virtual IterateResult iterate(void); 102 103 protected: 104 /* Protected methods */ 105 bool checkResult(const glw::GLint* feedbackResult); 106 void createAndBuildProgramWithFeedback(void); 107 void drawAndGetFeedback(glw::GLint* feedbackResult); 108 void prepareBufferObjects(); 109 110 /* Protected virtual methods */ 111 virtual void drawFunction(); 112 113 /* Protected members */ 114 DataPrimitiveIDInCounter m_testConfiguration; 115 116 glw::GLuint m_nrVaryings; 117 glw::GLuint m_sizeOfDataArray; 118 glw::GLuint m_sizeOfFeedbackBuffer; 119 120 const glw::GLuint m_n_components; 121 122 private: 123 /* Private functions */ 124 std::string GetGeometryShaderCode(const std::string& max_vertices, const std::string& layout_in, 125 const std::string& layout_out, const std::string& emit_vertices, 126 const std::string& n_iterations); 127 128 /* Private variables */ 129 static const char* m_fragment_shader_code; 130 static const char* m_vertex_shader_code; 131 132 glw::GLint m_maxGeometryOutputVertices; 133 134 glw::GLuint m_fragment_shader_id; 135 glw::GLuint m_geometry_shader_id; 136 glw::GLuint m_vertex_shader_id; 137 glw::GLuint m_program_id; 138 139 glw::GLuint m_tbo; 140 glw::GLuint m_vao; 141 glw::GLuint m_vbo; 142 }; 143 144 /** 2. Make sure that restarting a primitive topology with a primitive restart 145 * index does not affect primitive ID counter, when a element-driven draw 146 * call is made. 147 * 148 * Category: API; 149 * Functional Test. 150 * 151 * Modify test case 6.1 so that it uses element-sourced data. Insert the 152 * restart primitive index right after first primitive is rendered but 153 * before indices for the second one start. 154 */ 155 class GeometryShaderPrimitiveCounterRestartingPrimitive : public GeometryShaderPrimitiveCounter 156 { 157 public: 158 /* Public methods */ 159 GeometryShaderPrimitiveCounterRestartingPrimitive(Context& context, const ExtParameters& extParams, 160 const char* name, const char* description, 161 const DataPrimitiveIDInCounter& testConfiguration); 162 ~GeometryShaderPrimitiveCounterRestartingPrimitive(void)163 virtual ~GeometryShaderPrimitiveCounterRestartingPrimitive(void) 164 { 165 } 166 167 virtual void deinit(void); 168 virtual IterateResult iterate(void); 169 170 protected: 171 /* Protected functions */ 172 virtual void drawFunction(); 173 void setUpVertexAttributeArrays(); 174 175 private: 176 /* Private fields */ 177 glw::GLuint m_bo_id; 178 glw::GLuint m_numberOfRestarts; 179 }; 180 181 /** 3. Make sure that gl_PrimitiveID built-in variable can be read correctly 182 * from a fragment shader, assuming geometry shader writes to it in 183 * previous stage. 184 * 185 * Category: API; 186 * Functional Test. 187 * 188 * Vertex shader should output an int variable called vs_vertex_id, to which 189 * gl_VertexID has been saved. 190 * 191 * Geometry shader should take points and output a triangle strip. It will 192 * emit up to 4 vertices. The geometry shader should define an input int 193 * variable called vs_vertex_id. Let: 194 * 195 * int column = vs_vertex_id % 64; 196 * int row = floor(vs_vertex_id / 64); 197 * 198 * The shader should emit the following vertices: 199 * 200 * 1) (-1.0 + (column+1) / 32.0, -1.0 + (row + 1) / 32.0, 0, 1) 201 * 2) (-1.0 + (column+1) / 32.0, -1.0 + (row) / 32.0, 0, 1) 202 * 3) (-1.0 + (column) / 32.0, -1.0 + (row + 1) / 32.0, 0, 1) 203 * 4) (-1.0 + (column) / 32.0, -1.0 + (row) / 32.0, 0, 1) 204 * 205 * Finally, the geometry shader should set gl_PrimitiveID for each of the 206 * vertices to vs_vertex_id. 207 * 208 * Fragment shader should set output variable's result value as follows: (*) 209 * 210 * result[0] = (gl_PrimitiveID % 64) / 64.0; 211 * result[1] = floor(gl_PrimitiveID / 64) / 64.0; 212 * result[2] = gl_PrimitiveID / 4096.0; 213 * result[3] = ((gl_PrimitiveID % 2) == 0) ? 1.0 : 0.0; 214 * 215 * Using a program object built of these shader, the test should issue 216 * a draw call for 4096 points. The test is considered to have passed 217 * successfully if the rendered data consists of 4096 rectangles of edge 218 * equal to 1/64th of the output resolution, centers of which have values 219 * as described in (*). 220 * 221 * Texture object used as color attachment should be at least of 1024x1024 222 * resolution, in which case quad edge will be 4px long. 223 */ 224 class GeometryShaderPrimitiveIDFromFragmentShader : public TestCaseBase 225 { 226 public: 227 /* Publi methods */ 228 GeometryShaderPrimitiveIDFromFragmentShader(Context& context, const ExtParameters& extParams, const char* name, 229 const char* description); 230 ~GeometryShaderPrimitiveIDFromFragmentShader(void)231 virtual ~GeometryShaderPrimitiveIDFromFragmentShader(void) 232 { 233 } 234 235 void deinit(void); 236 IterateResult iterate(void); 237 238 private: 239 /* Private fields */ 240 static const char* m_fragment_shader_code; 241 static const char* m_geometry_shader_code; 242 static const char* m_vertex_shader_code; 243 244 const glw::GLuint m_n_drawn_vertices; 245 const glw::GLuint m_squareEdgeSize; 246 const glw::GLuint m_texture_height; 247 const glw::GLuint m_texture_n_components; 248 const glw::GLuint m_texture_n_levels; 249 const glw::GLuint m_texture_width; 250 251 glw::GLuint m_fbo_id; 252 glw::GLuint m_fragment_shader_id; 253 glw::GLuint m_geometry_shader_id; 254 glw::GLuint m_program_id; 255 glw::GLuint m_texture_id; 256 glw::GLuint m_vao_id; 257 glw::GLuint m_vbo_id; 258 glw::GLuint m_vertex_shader_id; 259 }; 260 261 } // namespace glcts 262 263 #endif // _ESEXTCGEOMETRYSHADERPRIMITIVECOUNTER_HPP 264