1 #ifndef _ESEXTCGEOMETRYSHADEROUTPUT_HPP 2 #define _ESEXTCGEOMETRYSHADEROUTPUT_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 28 namespace glcts 29 { 30 /** Base class for Geometry Shader Output test implementations. */ 31 class GeometryShaderOutput : public TestCaseBase 32 { 33 protected: 34 /* Protected methods */ 35 GeometryShaderOutput(Context& context, const ExtParameters& extParams, const char* name, const char* description); ~GeometryShaderOutput()36 virtual ~GeometryShaderOutput(){} 37 38 /* Protected variables */ 39 static const char* const m_fragment_shader_code_white_color; 40 static const char* const m_vertex_shader_code_two_vec4; 41 static const char* const m_vertex_shader_code_vec4_0_0_0_1; 42 }; 43 44 /** Implementation of test case 12.1. Test description follows: 45 * 46 * It is an error to use two conflicting output primitive type declarations 47 * in one geometry shader. 48 * 49 * Category: API; 50 * Negative Test. 51 * 52 * Create a program object, for which a boilerplate fragment and vertex 53 * shaders will be used. A geometry shader should also be attached to the 54 * program object. The shader should include the following incorrect output 55 * primitive type declarations: 56 * 57 * layout(triangle_strip, max_vertices = 60) out; 58 * layout(points) out; 59 * 60 * Linking of the program object is expected to fail under this 61 * configuration. 62 */ 63 class GeometryShaderDuplicateOutputLayoutQualifierTest : public GeometryShaderOutput 64 { 65 public: 66 /* Public methods */ 67 GeometryShaderDuplicateOutputLayoutQualifierTest(Context& context, const ExtParameters& extParams, const char* name, 68 const char* description); ~GeometryShaderDuplicateOutputLayoutQualifierTest()69 virtual ~GeometryShaderDuplicateOutputLayoutQualifierTest(){} 70 71 virtual IterateResult iterate(void); 72 73 protected: 74 /* Protected variables */ 75 static const char* const m_geometry_shader_code; 76 }; 77 78 /** Implementation of test case 12.2. Test description follows: 79 * 80 * It is an error to use two conflicting max_vertices declarations in one 81 * geometry shader. 82 * 83 * Category: API; 84 * Negative Test. 85 * 86 * Create a program object, for which a boilerplate fragment and vertex 87 * shaders will be used. A geometry shader should also be attached to the 88 * program object. The shader should include the following incorrect output 89 * primitive type declarations: 90 * 91 * layout(triangle_strip, max_vertices = 60) out; 92 * layout(max_vertices = 20) out; 93 * 94 * Linking of the program object is expected to fail under this 95 * configuration. 96 **/ 97 class GeometryShaderDuplicateMaxVerticesLayoutQualifierTest : public GeometryShaderOutput 98 { 99 public: 100 /* Public methods */ 101 GeometryShaderDuplicateMaxVerticesLayoutQualifierTest(Context& context, const ExtParameters& extParams, 102 const char* name, const char* description); ~GeometryShaderDuplicateMaxVerticesLayoutQualifierTest()103 virtual ~GeometryShaderDuplicateMaxVerticesLayoutQualifierTest(){} 104 105 virtual IterateResult iterate(void); 106 107 protected: 108 /* Protected variables */ 109 static const char* const m_geometry_shader_code; 110 }; 111 112 /** Base class for tests 12.3, 12.4 and 12.5. 113 * 114 * Test class have to: 115 - provide geometry shader code via constructor parameter, 116 - override method verifyResult. 117 **/ 118 class GeometryShaderOutputRenderingBase : public GeometryShaderOutput 119 { 120 public: 121 virtual void deinit(void); 122 virtual IterateResult iterate(void); 123 virtual bool verifyResult(const unsigned char* result_image, unsigned int width, unsigned int height, 124 unsigned int pixel_size) const = 0; 125 126 protected: 127 /* Protected methods */ 128 GeometryShaderOutputRenderingBase(Context& context, const ExtParameters& extParams, const char* name, 129 const char* description, const char* geometry_shader_code); ~GeometryShaderOutputRenderingBase()130 virtual ~GeometryShaderOutputRenderingBase(){} 131 132 void initTest(void); 133 134 private: 135 /* Private variables */ 136 const char* m_geometry_shader_code; 137 138 glw::GLuint m_program_object_id; 139 glw::GLuint m_vertex_shader_id; 140 glw::GLuint m_fragment_shader_id; 141 glw::GLuint m_geometry_shader_id; 142 143 glw::GLuint m_vao_id; 144 glw::GLuint m_fbo_id; 145 glw::GLuint m_color_tex_id; 146 }; 147 148 /** Implementation of test case 12.3. Test description follows: 149 * 150 * Make sure that EndPrimitive() does not emit a vertex. 151 * 152 * Category: API; 153 * Functional Test. 154 * 155 * Consider a FBO with a single 16x16 2D texture object attached to color 156 * attachment 0 and made active. 157 * 158 * The texture object should be filled with (0, 0, 0, 0). 159 * 160 * A boilerplate vertex shader should be assumed for the test case. 161 * 162 * Consider a geometry shader that takes a point as input and outputs 163 * a triangle strip (a max of 3 vertices will be emitted). The shader 164 * should: 165 * 166 * - Emit a vertex at (-1, -1, 0, 1). 167 * - Emit a vertex at (-1, 1, 0, 1). 168 * - Set gl_Position to ( 1, 1, 0, 1). 169 * - Do a EndPrimitive() call. 170 * 171 * A fragment shader should set the only output vec4 variable to 172 * (1, 1, 1, 1). 173 * 174 * A program object consisting of all three shaders should be created and 175 * linked. 176 * 177 * A single point draw call should be issued. 178 * 179 * At this point the test should verify that the texture object has not been 180 * modified, that is: all texels are set to (0, 0, 0, 0). 181 **/ 182 class GeometryShaderIfVertexEmitIsDoneAtEndTest : public GeometryShaderOutputRenderingBase 183 { 184 public: 185 /* Public methods */ 186 GeometryShaderIfVertexEmitIsDoneAtEndTest(Context& context, const ExtParameters& extParams, const char* name, 187 const char* description); ~GeometryShaderIfVertexEmitIsDoneAtEndTest()188 virtual ~GeometryShaderIfVertexEmitIsDoneAtEndTest(){} 189 190 virtual bool verifyResult(const unsigned char* result_image, unsigned int width, unsigned int height, 191 unsigned int pixel_size) const; 192 193 protected: 194 /* Protected variables */ 195 static const char* const m_geometry_shader_code; 196 }; 197 198 /** Implementation of test case 12.4. Test description follows: 199 * 200 * Make sure that a geometry shader completes current output primitive upon 201 * termination. 202 * 203 * Category: API; 204 * Functional Test. 205 * 206 * Modify test case 12.3 by: 207 * 208 * - Removing EndPrimitive() call the geometry shader should do at the end. 209 * - Changing the test check condition: test now succeeds if texels at 210 * bottom-left, top-left and top-right corners are set to 211 * (255, 255, 255, 255) and bottom-right corner is set to (0, 0, 0, 0), 212 * assuming glReadPixels() was called with GL_RGBA format and 213 * GL_UNSIGNED_BYTE type. 214 **/ 215 class GeometryShaderMissingEndPrimitiveCallTest : public GeometryShaderOutputRenderingBase 216 { 217 public: 218 /* Public methods */ 219 GeometryShaderMissingEndPrimitiveCallTest(Context& context, const ExtParameters& extParams, const char* name, 220 const char* description); ~GeometryShaderMissingEndPrimitiveCallTest()221 virtual ~GeometryShaderMissingEndPrimitiveCallTest(){} 222 223 virtual bool verifyResult(const unsigned char* result_image, unsigned int width, unsigned int height, 224 unsigned int pixel_size) const; 225 226 protected: 227 /* Protected variables */ 228 static const char* const m_geometry_shader_code; 229 }; 230 231 /** Implementation of test case 12.5. Test description follows: 232 * 233 * Make sure that it is not necessary to do an EndPrimitive() call if the 234 * geometry shader only writes a single primitive. 235 * 236 * Category: API; 237 * Functional Test. 238 * 239 * Modify test case 12.3 by: 240 * 241 * - Changing the logic in geometry shader to only set gl_Position to 242 * (-1, -1, 0, 1). 243 * - Changing input and output primitive types in a geometry shader to 244 * points. 245 * - Changing max_vertices to 1. 246 * - Pixel size should also be set to 2 prior to issuing the draw call. 247 * - Changing the test check condition: test now succeeds if texel at 248 * bottom-left corner is set to (255, 255, 255, 255) and remaining corners 249 * are set to (0, 0, 0, 0), assuming glReadPixels() was called with 250 * GL_RGBA format and GL_UNSIGNED_BYTE type. 251 **/ 252 class GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest : public GeometryShaderOutputRenderingBase 253 { 254 public: 255 /* Public methods */ 256 GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest(Context& context, const ExtParameters& extParams, 257 const char* name, const char* description); ~GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest()258 virtual ~GeometryShaderMissingEndPrimitiveCallForSinglePrimitiveTest(){} 259 260 virtual IterateResult iterate(void); 261 262 virtual bool verifyResult(const unsigned char* result_image, unsigned int width, unsigned int height, 263 unsigned int pixel_size) const; 264 265 protected: 266 /* Protected variables */ 267 static const char* const m_geometry_shader_code; 268 }; 269 } /* glcts */ 270 271 #endif // _ESEXTCGEOMETRYSHADEROUTPUT_HPP 272