1 #ifndef _GLSUNIFORMBLOCKCASE_HPP 2 #define _GLSUNIFORMBLOCKCASE_HPP 3 /*------------------------------------------------------------------------- 4 * drawElements Quality Program OpenGL (ES) Module 5 * ----------------------------------------------- 6 * 7 * Copyright 2014 The Android Open Source Project 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 Uniform block tests. 24 *//*--------------------------------------------------------------------*/ 25 26 #include "tcuDefs.hpp" 27 #include "tcuTestCase.hpp" 28 #include "gluShaderUtil.hpp" 29 30 namespace glu 31 { 32 class RenderContext; 33 } 34 35 namespace deqp 36 { 37 namespace gls 38 { 39 40 // Uniform block details. 41 namespace ub 42 { 43 44 enum UniformFlags 45 { 46 PRECISION_LOW = (1 << 0), 47 PRECISION_MEDIUM = (1 << 1), 48 PRECISION_HIGH = (1 << 2), 49 PRECISION_MASK = PRECISION_LOW | PRECISION_MEDIUM | PRECISION_HIGH, 50 51 LAYOUT_SHARED = (1 << 3), 52 LAYOUT_PACKED = (1 << 4), 53 LAYOUT_STD140 = (1 << 5), 54 LAYOUT_ROW_MAJOR = (1 << 6), 55 LAYOUT_COLUMN_MAJOR = (1 << 7), //!< \note Lack of both flags means column-major matrix. 56 LAYOUT_MASK = LAYOUT_SHARED | LAYOUT_PACKED | LAYOUT_STD140 | LAYOUT_ROW_MAJOR | LAYOUT_COLUMN_MAJOR, 57 58 DECLARE_VERTEX = (1 << 8), 59 DECLARE_FRAGMENT = (1 << 9), 60 DECLARE_BOTH = DECLARE_VERTEX | DECLARE_FRAGMENT, 61 62 UNUSED_VERTEX = (1 << 10), //!< Uniform or struct member is not read in vertex shader. 63 UNUSED_FRAGMENT = (1 << 11), //!< Uniform or struct member is not read in fragment shader. 64 UNUSED_BOTH = UNUSED_VERTEX | UNUSED_FRAGMENT 65 }; 66 67 // \todo [2012-07-25 pyry] Use glu::VarType. 68 69 class StructType; 70 71 class VarType 72 { 73 public: 74 VarType(void); 75 VarType(const VarType &other); 76 VarType(glu::DataType basicType, uint32_t flags); 77 VarType(const VarType &elementType, int arraySize); 78 explicit VarType(const StructType *structPtr, uint32_t flags = 0u); 79 ~VarType(void); 80 isBasicType(void) const81 bool isBasicType(void) const 82 { 83 return m_type == TYPE_BASIC; 84 } isArrayType(void) const85 bool isArrayType(void) const 86 { 87 return m_type == TYPE_ARRAY; 88 } isStructType(void) const89 bool isStructType(void) const 90 { 91 return m_type == TYPE_STRUCT; 92 } 93 getFlags(void) const94 uint32_t getFlags(void) const 95 { 96 return m_flags; 97 } getBasicType(void) const98 glu::DataType getBasicType(void) const 99 { 100 return m_data.basicType; 101 } 102 getElementType(void) const103 const VarType &getElementType(void) const 104 { 105 return *m_data.array.elementType; 106 } getArraySize(void) const107 int getArraySize(void) const 108 { 109 return m_data.array.size; 110 } 111 getStruct(void) const112 const StructType &getStruct(void) const 113 { 114 return *m_data.structPtr; 115 } 116 117 VarType &operator=(const VarType &other); 118 119 private: 120 enum Type 121 { 122 TYPE_BASIC, 123 TYPE_ARRAY, 124 TYPE_STRUCT, 125 126 TYPE_LAST 127 }; 128 129 Type m_type; 130 uint32_t m_flags; 131 union Data 132 { 133 glu::DataType basicType; 134 struct 135 { 136 VarType *elementType; 137 int size; 138 } array; 139 const StructType *structPtr; 140 Data(void)141 Data(void) 142 { 143 array.elementType = DE_NULL; 144 array.size = 0; 145 } 146 } m_data; 147 }; 148 149 class StructMember 150 { 151 public: StructMember(const char * name,const VarType & type,uint32_t flags)152 StructMember(const char *name, const VarType &type, uint32_t flags) : m_name(name), m_type(type), m_flags(flags) 153 { 154 } StructMember(void)155 StructMember(void) : m_flags(0) 156 { 157 } 158 getName(void) const159 const char *getName(void) const 160 { 161 return m_name.c_str(); 162 } getType(void) const163 const VarType &getType(void) const 164 { 165 return m_type; 166 } getFlags(void) const167 uint32_t getFlags(void) const 168 { 169 return m_flags; 170 } 171 172 private: 173 std::string m_name; 174 VarType m_type; 175 uint32_t m_flags; 176 }; 177 178 class StructType 179 { 180 public: 181 typedef std::vector<StructMember>::iterator Iterator; 182 typedef std::vector<StructMember>::const_iterator ConstIterator; 183 StructType(const char * typeName)184 StructType(const char *typeName) : m_typeName(typeName) 185 { 186 } ~StructType(void)187 ~StructType(void) 188 { 189 } 190 getTypeName(void) const191 const char *getTypeName(void) const 192 { 193 return m_typeName.empty() ? DE_NULL : m_typeName.c_str(); 194 } 195 begin(void)196 inline Iterator begin(void) 197 { 198 return m_members.begin(); 199 } begin(void) const200 inline ConstIterator begin(void) const 201 { 202 return m_members.begin(); 203 } end(void)204 inline Iterator end(void) 205 { 206 return m_members.end(); 207 } end(void) const208 inline ConstIterator end(void) const 209 { 210 return m_members.end(); 211 } 212 213 void addMember(const char *name, const VarType &type, uint32_t flags = 0); 214 215 private: 216 std::string m_typeName; 217 std::vector<StructMember> m_members; 218 }; 219 220 class Uniform 221 { 222 public: 223 Uniform(const char *name, const VarType &type, uint32_t flags = 0); 224 getName(void) const225 const char *getName(void) const 226 { 227 return m_name.c_str(); 228 } getType(void) const229 const VarType &getType(void) const 230 { 231 return m_type; 232 } getFlags(void) const233 uint32_t getFlags(void) const 234 { 235 return m_flags; 236 } 237 238 private: 239 std::string m_name; 240 VarType m_type; 241 uint32_t m_flags; 242 }; 243 244 class UniformBlock 245 { 246 public: 247 typedef std::vector<Uniform>::iterator Iterator; 248 typedef std::vector<Uniform>::const_iterator ConstIterator; 249 250 UniformBlock(const char *blockName); 251 getBlockName(void) const252 const char *getBlockName(void) const 253 { 254 return m_blockName.c_str(); 255 } getInstanceName(void) const256 const char *getInstanceName(void) const 257 { 258 return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str(); 259 } isArray(void) const260 bool isArray(void) const 261 { 262 return m_arraySize > 0; 263 } getArraySize(void) const264 int getArraySize(void) const 265 { 266 return m_arraySize; 267 } getFlags(void) const268 uint32_t getFlags(void) const 269 { 270 return m_flags; 271 } 272 setInstanceName(const char * name)273 void setInstanceName(const char *name) 274 { 275 m_instanceName = name; 276 } setFlags(uint32_t flags)277 void setFlags(uint32_t flags) 278 { 279 m_flags = flags; 280 } setArraySize(int arraySize)281 void setArraySize(int arraySize) 282 { 283 m_arraySize = arraySize; 284 } addUniform(const Uniform & uniform)285 void addUniform(const Uniform &uniform) 286 { 287 m_uniforms.push_back(uniform); 288 } 289 begin(void)290 inline Iterator begin(void) 291 { 292 return m_uniforms.begin(); 293 } begin(void) const294 inline ConstIterator begin(void) const 295 { 296 return m_uniforms.begin(); 297 } end(void)298 inline Iterator end(void) 299 { 300 return m_uniforms.end(); 301 } end(void) const302 inline ConstIterator end(void) const 303 { 304 return m_uniforms.end(); 305 } 306 307 private: 308 std::string m_blockName; 309 std::string m_instanceName; 310 std::vector<Uniform> m_uniforms; 311 int m_arraySize; //!< Array size or 0 if not interface block array. 312 uint32_t m_flags; 313 }; 314 315 class ShaderInterface 316 { 317 public: 318 ShaderInterface(void); 319 ~ShaderInterface(void); 320 321 StructType &allocStruct(const char *name); 322 const StructType *findStruct(const char *name) const; 323 void getNamedStructs(std::vector<const StructType *> &structs) const; 324 325 UniformBlock &allocBlock(const char *name); 326 getNumUniformBlocks(void) const327 int getNumUniformBlocks(void) const 328 { 329 return (int)m_uniformBlocks.size(); 330 } getUniformBlock(int ndx) const331 const UniformBlock &getUniformBlock(int ndx) const 332 { 333 return *m_uniformBlocks[ndx]; 334 } 335 336 private: 337 std::vector<StructType *> m_structs; 338 std::vector<UniformBlock *> m_uniformBlocks; 339 }; 340 341 class UniformLayout; 342 343 } // namespace ub 344 345 class UniformBlockCase : public tcu::TestCase 346 { 347 public: 348 enum BufferMode 349 { 350 BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks. 351 BUFFERMODE_PER_BLOCK, //!< Per-block buffers 352 353 BUFFERMODE_LAST 354 }; 355 356 UniformBlockCase(tcu::TestContext &testCtx, glu::RenderContext &renderCtx, const char *name, 357 const char *description, glu::GLSLVersion glslVersion, BufferMode bufferMode); 358 ~UniformBlockCase(void); 359 360 IterateResult iterate(void); 361 362 protected: 363 bool compareStd140Blocks(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const; 364 bool compareSharedBlocks(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const; 365 bool compareTypes(const ub::UniformLayout &refLayout, const ub::UniformLayout &cmpLayout) const; 366 bool checkLayoutIndices(const ub::UniformLayout &layout) const; 367 bool checkLayoutBounds(const ub::UniformLayout &layout) const; 368 bool checkIndexQueries(uint32_t program, const ub::UniformLayout &layout) const; 369 370 bool render(uint32_t program) const; 371 372 glu::RenderContext &m_renderCtx; 373 glu::GLSLVersion m_glslVersion; 374 BufferMode m_bufferMode; 375 ub::ShaderInterface m_interface; 376 }; 377 378 } // namespace gls 379 } // namespace deqp 380 381 #endif // _GLSUNIFORMBLOCKCASE_HPP 382