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