1 #ifndef _GLCUNIFORMBLOCKCASE_HPP 2 #define _GLCUNIFORMBLOCKCASE_HPP 3 /*------------------------------------------------------------------------- 4 * OpenGL Conformance Test Suite 5 * ----------------------------- 6 * 7 * Copyright (c) 2016 Google Inc. 8 * Copyright (c) 2016 The Khronos Group Inc. 9 * 10 * Licensed under the Apache License, Version 2.0 (the "License"); 11 * you may not use this file except in compliance with the License. 12 * You may obtain a copy of the License at 13 * 14 * http://www.apache.org/licenses/LICENSE-2.0 15 * 16 * Unless required by applicable law or agreed to in writing, software 17 * distributed under the License is distributed on an "AS IS" BASIS, 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 19 * See the License for the specific language governing permissions and 20 * limitations under the License. 21 * 22 */ /*! 23 * \file 24 * \brief Uniform block tests. 25 */ /*-------------------------------------------------------------------*/ 26 27 #include "glcTestCase.hpp" 28 #include "gluShaderProgram.hpp" 29 #include "gluShaderUtil.hpp" 30 #include "tcuDefs.hpp" 31 32 namespace deqp 33 { 34 35 // Uniform block details. 36 namespace ub 37 { 38 39 enum UniformFlags 40 { 41 PRECISION_LOW = (1 << 0), 42 PRECISION_MEDIUM = (1 << 1), 43 PRECISION_HIGH = (1 << 2), 44 PRECISION_MASK = PRECISION_LOW | PRECISION_MEDIUM | PRECISION_HIGH, 45 46 LAYOUT_SHARED = (1 << 3), 47 LAYOUT_PACKED = (1 << 4), 48 LAYOUT_STD140 = (1 << 5), 49 LAYOUT_ROW_MAJOR = (1 << 6), 50 LAYOUT_COLUMN_MAJOR = (1 << 7), //!< \note Lack of both flags means column-major matrix. 51 LAYOUT_MASK = LAYOUT_SHARED | LAYOUT_PACKED | LAYOUT_STD140 | LAYOUT_ROW_MAJOR | LAYOUT_COLUMN_MAJOR, 52 53 DECLARE_VERTEX = (1 << 8), 54 DECLARE_FRAGMENT = (1 << 9), 55 DECLARE_BOTH = DECLARE_VERTEX | DECLARE_FRAGMENT, 56 57 UNUSED_VERTEX = (1 << 10), //!< Uniform or struct member is not read in vertex shader. 58 UNUSED_FRAGMENT = (1 << 11), //!< Uniform or struct member is not read in fragment shader. 59 UNUSED_BOTH = UNUSED_VERTEX | UNUSED_FRAGMENT 60 }; 61 62 // \todo [2012-07-25 pyry] Use glu::VarType. 63 64 class StructType; 65 66 class VarType 67 { 68 public: 69 VarType(void); 70 VarType(const VarType& other); 71 VarType(glu::DataType basicType, deUint32 flags); 72 VarType(const VarType& elementType, int arraySize); 73 explicit VarType(const StructType* structPtr); 74 ~VarType(void); 75 isBasicType(void) const76 bool isBasicType(void) const 77 { 78 return m_type == TYPE_BASIC; 79 } isArrayType(void) const80 bool isArrayType(void) const 81 { 82 return m_type == TYPE_ARRAY; 83 } isStructType(void) const84 bool isStructType(void) const 85 { 86 return m_type == TYPE_STRUCT; 87 } 88 getFlags(void) const89 deUint32 getFlags(void) const 90 { 91 return m_flags; 92 } getBasicType(void) const93 glu::DataType getBasicType(void) const 94 { 95 return m_data.basicType; 96 } 97 getElementType(void) const98 const VarType& getElementType(void) const 99 { 100 return *m_data.array.elementType; 101 } getArraySize(void) const102 int getArraySize(void) const 103 { 104 return m_data.array.size; 105 } 106 getStruct(void) const107 const StructType& getStruct(void) const 108 { 109 return *m_data.structPtr; 110 } 111 112 VarType& operator=(const VarType& other); 113 114 private: 115 enum Type 116 { 117 TYPE_BASIC, 118 TYPE_ARRAY, 119 TYPE_STRUCT, 120 121 TYPE_LAST 122 }; 123 124 Type m_type; 125 deUint32 m_flags; 126 union Data { 127 glu::DataType basicType; 128 struct 129 { 130 VarType* elementType; 131 int size; 132 } array; 133 const StructType* structPtr; 134 Data(void)135 Data(void) 136 { 137 array.elementType = DE_NULL; 138 array.size = 0; 139 } 140 } m_data; 141 }; 142 143 class StructMember 144 { 145 public: StructMember(const char * name,const VarType & type,deUint32 flags)146 StructMember(const char* name, const VarType& type, deUint32 flags) : m_name(name), m_type(type), m_flags(flags) 147 { 148 } StructMember(void)149 StructMember(void) : m_flags(0) 150 { 151 } 152 getName(void) const153 const char* getName(void) const 154 { 155 return m_name.c_str(); 156 } getType(void) const157 const VarType& getType(void) const 158 { 159 return m_type; 160 } getFlags(void) const161 deUint32 getFlags(void) const 162 { 163 return m_flags; 164 } 165 166 private: 167 std::string m_name; 168 VarType m_type; 169 deUint32 m_flags; 170 }; 171 172 class StructType 173 { 174 public: 175 typedef std::vector<StructMember>::iterator Iterator; 176 typedef std::vector<StructMember>::const_iterator ConstIterator; 177 StructType(const char * typeName)178 StructType(const char* typeName) : m_typeName(typeName) 179 { 180 } ~StructType(void)181 ~StructType(void) 182 { 183 } 184 getTypeName(void) const185 const char* getTypeName(void) const 186 { 187 return m_typeName.empty() ? DE_NULL : m_typeName.c_str(); 188 } 189 begin(void)190 inline Iterator begin(void) 191 { 192 return m_members.begin(); 193 } begin(void) const194 inline ConstIterator begin(void) const 195 { 196 return m_members.begin(); 197 } end(void)198 inline Iterator end(void) 199 { 200 return m_members.end(); 201 } end(void) const202 inline ConstIterator end(void) const 203 { 204 return m_members.end(); 205 } 206 207 void addMember(const char* name, const VarType& type, deUint32 flags = 0); 208 209 private: 210 std::string m_typeName; 211 std::vector<StructMember> m_members; 212 }; 213 214 class Uniform 215 { 216 public: 217 Uniform(const char* name, const VarType& type, deUint32 flags = 0); 218 getName(void) const219 const char* getName(void) const 220 { 221 return m_name.c_str(); 222 } getType(void) const223 const VarType& getType(void) const 224 { 225 return m_type; 226 } getFlags(void) const227 deUint32 getFlags(void) const 228 { 229 return m_flags; 230 } 231 232 private: 233 std::string m_name; 234 VarType m_type; 235 deUint32 m_flags; 236 }; 237 238 class UniformBlock 239 { 240 public: 241 typedef std::vector<Uniform>::iterator Iterator; 242 typedef std::vector<Uniform>::const_iterator ConstIterator; 243 244 UniformBlock(const char* blockName); 245 getBlockName(void) const246 const char* getBlockName(void) const 247 { 248 return m_blockName.c_str(); 249 } getInstanceName(void) const250 const char* getInstanceName(void) const 251 { 252 return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str(); 253 } isArray(void) const254 bool isArray(void) const 255 { 256 return m_arraySize > 0; 257 } getArraySize(void) const258 int getArraySize(void) const 259 { 260 return m_arraySize; 261 } getFlags(void) const262 deUint32 getFlags(void) const 263 { 264 return m_flags; 265 } 266 setInstanceName(const char * name)267 void setInstanceName(const char* name) 268 { 269 m_instanceName = name; 270 } setFlags(deUint32 flags)271 void setFlags(deUint32 flags) 272 { 273 m_flags = flags; 274 } setArraySize(int arraySize)275 void setArraySize(int arraySize) 276 { 277 m_arraySize = arraySize; 278 } addUniform(const Uniform & uniform)279 void addUniform(const Uniform& uniform) 280 { 281 m_uniforms.push_back(uniform); 282 } 283 begin(void)284 inline Iterator begin(void) 285 { 286 return m_uniforms.begin(); 287 } begin(void) const288 inline ConstIterator begin(void) const 289 { 290 return m_uniforms.begin(); 291 } end(void)292 inline Iterator end(void) 293 { 294 return m_uniforms.end(); 295 } end(void) const296 inline ConstIterator end(void) const 297 { 298 return m_uniforms.end(); 299 } 300 301 private: 302 std::string m_blockName; 303 std::string m_instanceName; 304 std::vector<Uniform> m_uniforms; 305 int m_arraySize; //!< Array size or 0 if not interface block array. 306 deUint32 m_flags; 307 }; 308 309 class ShaderInterface 310 { 311 public: 312 ShaderInterface(void); 313 ~ShaderInterface(void); 314 315 StructType& allocStruct(const char* name); 316 const StructType* findStruct(const char* name) const; 317 void getNamedStructs(std::vector<const StructType*>& structs) const; 318 319 UniformBlock& allocBlock(const char* name); 320 getNumUniformBlocks(void) const321 int getNumUniformBlocks(void) const 322 { 323 return (int)m_uniformBlocks.size(); 324 } getUniformBlock(int ndx) const325 const UniformBlock& getUniformBlock(int ndx) const 326 { 327 return *m_uniformBlocks[ndx]; 328 } 329 330 private: 331 std::vector<StructType*> m_structs; 332 std::vector<UniformBlock*> m_uniformBlocks; 333 }; 334 335 class UniformLayout; 336 337 } // ub 338 339 class UniformBlockCase : public TestCase 340 { 341 public: 342 enum BufferMode 343 { 344 BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks. 345 BUFFERMODE_PER_BLOCK, //!< Per-block buffers 346 347 BUFFERMODE_LAST 348 }; 349 350 UniformBlockCase(Context& context, const char* name, const char* description, glu::GLSLVersion glslVersion, 351 BufferMode bufferMode); 352 ~UniformBlockCase(void); 353 354 IterateResult iterate(void); 355 356 protected: 357 bool compareStd140Blocks(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const; 358 bool compareSharedBlocks(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const; 359 bool compareTypes(const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const; 360 bool checkLayoutIndices(const ub::UniformLayout& layout) const; 361 bool checkLayoutBounds(const ub::UniformLayout& layout) const; 362 bool checkIndexQueries(deUint32 program, const ub::UniformLayout& layout) const; 363 364 bool render(glu::ShaderProgram& program) const; 365 366 glu::GLSLVersion m_glslVersion; 367 BufferMode m_bufferMode; 368 ub::ShaderInterface m_interface; 369 }; 370 371 } // deqp 372 373 #endif // _GLCUNIFORMBLOCKCASE_HPP 374