1 #ifndef _ESEXTCGEOMETRYSHADERLAYEREDRENDERINGBOUNDARYCONDITION_HPP 2 #define _ESEXTCGEOMETRYSHADERLAYEREDRENDERINGBOUNDARYCONDITION_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 <vector> 28 29 namespace glcts 30 { 31 /** Implementation of "Group 10" from CTS_EXT_geometry_shader. */ 32 class GeometryShaderLayeredRenderingBoundaryCondition : public TestCaseBase 33 { 34 public: 35 /* Public methods */ 36 virtual void deinit(void); 37 virtual IterateResult iterate(void); 38 39 protected: 40 /* Protected data types */ 41 struct TextureInfo 42 { 43 glw::GLint m_depth; 44 glw::GLenum m_draw_buffer; 45 glw::GLuint m_id; 46 glw::GLenum m_texture_target; 47 }; 48 49 /* Protected methods */ 50 GeometryShaderLayeredRenderingBoundaryCondition(Context& context, const ExtParameters& extParams, const char* name, 51 const char* description); 52 53 virtual ~GeometryShaderLayeredRenderingBoundaryCondition(void); 54 55 virtual void initTest(void); 56 virtual const char* getFragmentShaderCode(); 57 virtual const char* getGeometryShaderCode(); 58 virtual const char* getVertexShaderCode(); 59 60 virtual bool comparePixels(glw::GLint width, glw::GLint height, glw::GLint pixelSize, 61 const unsigned char* textureData, const unsigned char* referencePixel, int att, 62 int layer); 63 64 virtual void getReferenceColor(glw::GLint layerIndex, unsigned char* colorBuffer, 65 int colorBufferSize = m_texture_components) = 0; 66 67 protected: 68 /* Protected variables */ 69 glw::GLenum m_draw_mode; 70 glw::GLuint m_n_points; 71 bool m_is_fbo_layered; 72 std::vector<TextureInfo> m_textures_info; 73 unsigned char* m_blue_color; 74 unsigned char* m_green_color; 75 unsigned char* m_red_color; 76 unsigned char* m_white_color; 77 78 private: 79 /* Private constants */ 80 static const glw::GLint m_height; 81 static const glw::GLint m_max_depth; 82 static const glw::GLint m_texture_components; 83 static const glw::GLint m_width; 84 85 /* Private variables */ 86 glw::GLuint m_fbo_draw_id; 87 glw::GLuint m_fbo_read_id; 88 glw::GLuint m_fs_id; 89 glw::GLuint m_gs_id; 90 glw::GLuint m_po_id; 91 glw::GLuint m_vao_id; 92 glw::GLuint m_vs_id; 93 }; 94 95 /** 96 * 1. Only the smallest number of layers of layered framebuffer's attachments 97 * should be affected by draw calls, if the number of layers of each 98 * attachment is not identical. 99 * 100 * Category: API; 101 * Functional Test. 102 * 103 * Consider a layered FBO with the following configuration: 104 * 105 * - A 3D texture object A (resolution: 4x4x2), whose base level was bound 106 * to color attachment 0; 107 * - A 3D texture object B (resolution: 4x4x4), whose base level was 108 * bound to color attachment 1; 109 * 110 * All slices/layers of these texture objects are filled with black color. 111 * 112 * A geometry shader should accept points on input and output triangle 113 * strips with a maximum of 4*16 vertices. The shader should emit 4 114 * "screen-space quads" (as described in test case 8.1, for instance), 115 * with each quad occupying layers at subsequently incremental indices. 116 * Each quad should have a different color (shared by all quad's vertices). 117 * 118 * The test should make a draw call for a single point and then check the 119 * texture objects. Test passes if only the first two layers of the texture 120 * objects were modified. 121 */ 122 class GeometryShaderLayeredRenderingBoundaryConditionVariousTextures 123 : public GeometryShaderLayeredRenderingBoundaryCondition 124 { 125 public: 126 /* Public methods */ 127 GeometryShaderLayeredRenderingBoundaryConditionVariousTextures(Context& context, const ExtParameters& extParams, 128 const char* name, const char* description); 129 ~GeometryShaderLayeredRenderingBoundaryConditionVariousTextures(void)130 virtual ~GeometryShaderLayeredRenderingBoundaryConditionVariousTextures(void) 131 { 132 } 133 134 protected: 135 /* Protected methods */ 136 const char* getFragmentShaderCode(); 137 const char* getGeometryShaderCode(); 138 void getReferenceColor(glw::GLint layerIndex, unsigned char* colorBuffer, int colorBufferSize); 139 }; 140 141 /** 142 * 2. Default layer number for fragments is zero if there is no geometry shader 143 * defined for the active pipeline. 144 * 145 * Category: API; 146 * Functional Test. 147 * 148 * Consider a layered FBO with the following configuration: 149 * 150 * - Base level of a 3D texture object A of resolution 4x4x4 attached to 151 * color attachment 0. 152 * 153 * All slices of texture object A should be filled with (0, 0, 0, 0). 154 * 155 * A program object A should consist of vertex shader B and fragment shader 156 * C. Vertex shader B should: 157 * 158 * - Set gl_Position to (-1, -1, 0, 1) if gl_VertexID == 0; 159 * - Set gl_Position to (-1, 1, 0, 1) if gl_VertexID == 1; 160 * - Set gl_Position to ( 1, 1, 0, 1) if gl_VertexID == 2; 161 * - Set gl_Position to ( 1, -1, 0, 1) otherwise. 162 * 163 * Fragment shader C should set the only output vec4 variable to 164 * (1, 1, 1, 1). 165 * 166 * Having bound the layered FBO to GL_FRAMEBUFFER targets, the test should 167 * draw a triangle fan made of 4 vertices.It should then read back first 168 * two slices of the texture object A: 169 * 170 * - All texels of the first slice should be set to (255, 255, 255, 255) 171 * (assuming glReadPixels() was called with GL_RGBA format & 172 * GL_UNSIGNED_BYTE type). 173 * - All texels of the second slice should be set to (0, 0, 0, 0) 174 * (assumption as above). 175 */ 176 class GeometryShaderLayeredRenderingBoundaryConditionNoGS : public GeometryShaderLayeredRenderingBoundaryCondition 177 { 178 public: 179 /* Public methods */ 180 GeometryShaderLayeredRenderingBoundaryConditionNoGS(Context& context, const ExtParameters& extParams, 181 const char* name, const char* description); 182 ~GeometryShaderLayeredRenderingBoundaryConditionNoGS(void)183 virtual ~GeometryShaderLayeredRenderingBoundaryConditionNoGS(void) 184 { 185 } 186 187 protected: 188 /* Protected methods */ 189 const char* getVertexShaderCode(); 190 void getReferenceColor(glw::GLint layerIndex, unsigned char* colorBuffer, int colorBufferSize); 191 }; 192 193 /** 194 * 3. Default layer number for fragments is zero if the geometry shader used 195 * for current pipeline does not set gl_Layer in any of the execution paths. 196 * 197 * Category: API; 198 * Functional Test. 199 * 200 * Modify test case 10.2 to introduce a boilerplate geometry shader that: 201 * 202 * - generates a triangle strip, takes the same input and emits the same 203 * output primitive types as in test case 8.1; 204 * - does NOT set layer id for any of the outputted vertices. 205 * 206 * Vertex shader can be boilerplate in this case. 207 * 208 * The test should draw a single point and perform the same check as in test 209 * case 10.2. 210 */ 211 class GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet : public GeometryShaderLayeredRenderingBoundaryCondition 212 { 213 public: 214 /* Public methods */ 215 GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet(Context& context, const ExtParameters& extParams, 216 const char* name, const char* description); 217 ~GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet(void)218 virtual ~GeometryShaderLayeredRenderingBoundaryConditionNoLayerSet(void) 219 { 220 } 221 222 protected: 223 /* Protected methods */ 224 const char* getGeometryShaderCode(); 225 void getReferenceColor(glw::GLint layerIndex, unsigned char* colorBuffer, int colorBufferSize); 226 }; 227 228 /** 4. Layer number specified by geometry shader is ignored if current draw 229 * FBO is not layered. 230 * 231 * Category: API; 232 * Functional Test. 233 * 234 * Consider a framebuffer object A with the following configuration: 235 * 236 * - 3D texture object A of resolution 4x4x4, with all slices filled with 237 * (0, 0, 0, 0), is bound to color attachment 0; 238 * 239 * Vertex shader can be boilerplate. 240 * Geometry shader should take form of the geometry shader described in test 241 * case 10.3. However, it should set gl_Layer to 1 for all vertices emitted. 242 * Fragment shader should take form of the vertex shader C described in test 243 * case 10.2. 244 * 245 * The test should then draw a single point, read first two slices of texture 246 * object A and: 247 * 248 * - make sure first slice is filled with (255, 255, 255, 255), assuming 249 * glReadPixels() call with GL_RGBA format and GL_UNSIGNED_BYTE type. 250 * - make sure second slice is filled with (0, 0, 0, 0) (assumptions as 251 * above) 252 * 253 */ 254 class GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO 255 : public GeometryShaderLayeredRenderingBoundaryCondition 256 { 257 public: 258 /* Public methods */ 259 GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO(Context& context, const ExtParameters& extParams, 260 const char* name, const char* description); 261 ~GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO(void)262 virtual ~GeometryShaderLayeredRenderingBoundaryConditionNoLayeredFBO(void) 263 { 264 } 265 266 protected: 267 /* Protected methods */ 268 virtual const char* getGeometryShaderCode(); 269 virtual void getReferenceColor(glw::GLint layerIndex, unsigned char* colorBuffer, int colorBufferSize); 270 }; 271 272 } // namespace glcts 273 274 #endif // _ESEXTCGEOMETRYSHADERLAYEREDRENDERINGBOUNDARYCONDITION_HPP 275