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, deUint32 flags); 77 VarType (const VarType& elementType, int arraySize); 78 explicit VarType (const StructType* structPtr, deUint32 flags = 0u); 79 ~VarType (void); 80 isBasicType(void) const81 bool isBasicType (void) const { return m_type == TYPE_BASIC; } isArrayType(void) const82 bool isArrayType (void) const { return m_type == TYPE_ARRAY; } isStructType(void) const83 bool isStructType (void) const { return m_type == TYPE_STRUCT; } 84 getFlags(void) const85 deUint32 getFlags (void) const { return m_flags; } getBasicType(void) const86 glu::DataType getBasicType (void) const { return m_data.basicType; } 87 getElementType(void) const88 const VarType& getElementType (void) const { return *m_data.array.elementType; } getArraySize(void) const89 int getArraySize (void) const { return m_data.array.size; } 90 getStruct(void) const91 const StructType& getStruct (void) const { return *m_data.structPtr; } 92 93 VarType& operator= (const VarType& other); 94 95 private: 96 enum Type 97 { 98 TYPE_BASIC, 99 TYPE_ARRAY, 100 TYPE_STRUCT, 101 102 TYPE_LAST 103 }; 104 105 Type m_type; 106 deUint32 m_flags; 107 union Data 108 { 109 glu::DataType basicType; 110 struct 111 { 112 VarType* elementType; 113 int size; 114 } array; 115 const StructType* structPtr; 116 Data(void)117 Data (void) 118 { 119 array.elementType = DE_NULL; 120 array.size = 0; 121 }; 122 } m_data; 123 }; 124 125 class StructMember 126 { 127 public: StructMember(const char * name,const VarType & type,deUint32 flags)128 StructMember (const char* name, const VarType& type, deUint32 flags) : m_name(name), m_type(type), m_flags(flags) {} StructMember(void)129 StructMember (void) : m_flags(0) {} 130 getName(void) const131 const char* getName (void) const { return m_name.c_str(); } getType(void) const132 const VarType& getType (void) const { return m_type; } getFlags(void) const133 deUint32 getFlags (void) const { return m_flags; } 134 135 private: 136 std::string m_name; 137 VarType m_type; 138 deUint32 m_flags; 139 }; 140 141 class StructType 142 { 143 public: 144 typedef std::vector<StructMember>::iterator Iterator; 145 typedef std::vector<StructMember>::const_iterator ConstIterator; 146 StructType(const char * typeName)147 StructType (const char* typeName) : m_typeName(typeName) {} ~StructType(void)148 ~StructType (void) {} 149 getTypeName(void) const150 const char* getTypeName (void) const { return m_typeName.empty() ? DE_NULL : m_typeName.c_str(); } 151 begin(void)152 inline Iterator begin (void) { return m_members.begin(); } begin(void) const153 inline ConstIterator begin (void) const { return m_members.begin(); } end(void)154 inline Iterator end (void) { return m_members.end(); } end(void) const155 inline ConstIterator end (void) const { return m_members.end(); } 156 157 void addMember (const char* name, const VarType& type, deUint32 flags = 0); 158 159 private: 160 std::string m_typeName; 161 std::vector<StructMember> m_members; 162 }; 163 164 class Uniform 165 { 166 public: 167 Uniform (const char* name, const VarType& type, deUint32 flags = 0); 168 getName(void) const169 const char* getName (void) const { return m_name.c_str(); } getType(void) const170 const VarType& getType (void) const { return m_type; } getFlags(void) const171 deUint32 getFlags (void) const { return m_flags; } 172 173 private: 174 std::string m_name; 175 VarType m_type; 176 deUint32 m_flags; 177 }; 178 179 class UniformBlock 180 { 181 public: 182 typedef std::vector<Uniform>::iterator Iterator; 183 typedef std::vector<Uniform>::const_iterator ConstIterator; 184 185 UniformBlock (const char* blockName); 186 getBlockName(void) const187 const char* getBlockName (void) const { return m_blockName.c_str(); } getInstanceName(void) const188 const char* getInstanceName (void) const { return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str(); } isArray(void) const189 bool isArray (void) const { return m_arraySize > 0; } getArraySize(void) const190 int getArraySize (void) const { return m_arraySize; } getFlags(void) const191 deUint32 getFlags (void) const { return m_flags; } 192 setInstanceName(const char * name)193 void setInstanceName (const char* name) { m_instanceName = name; } setFlags(deUint32 flags)194 void setFlags (deUint32 flags) { m_flags = flags; } setArraySize(int arraySize)195 void setArraySize (int arraySize) { m_arraySize = arraySize; } addUniform(const Uniform & uniform)196 void addUniform (const Uniform& uniform) { m_uniforms.push_back(uniform); } 197 begin(void)198 inline Iterator begin (void) { return m_uniforms.begin(); } begin(void) const199 inline ConstIterator begin (void) const { return m_uniforms.begin(); } end(void)200 inline Iterator end (void) { return m_uniforms.end(); } end(void) const201 inline ConstIterator end (void) const { return m_uniforms.end(); } 202 203 private: 204 std::string m_blockName; 205 std::string m_instanceName; 206 std::vector<Uniform> m_uniforms; 207 int m_arraySize; //!< Array size or 0 if not interface block array. 208 deUint32 m_flags; 209 }; 210 211 class ShaderInterface 212 { 213 public: 214 ShaderInterface (void); 215 ~ShaderInterface (void); 216 217 StructType& allocStruct (const char* name); 218 const StructType* findStruct (const char* name) const; 219 void getNamedStructs (std::vector<const StructType*>& structs) const; 220 221 UniformBlock& allocBlock (const char* name); 222 getNumUniformBlocks(void) const223 int getNumUniformBlocks (void) const { return (int)m_uniformBlocks.size(); } getUniformBlock(int ndx) const224 const UniformBlock& getUniformBlock (int ndx) const { return *m_uniformBlocks[ndx]; } 225 226 private: 227 std::vector<StructType*> m_structs; 228 std::vector<UniformBlock*> m_uniformBlocks; 229 }; 230 231 class UniformLayout; 232 233 } // ub 234 235 class UniformBlockCase : public tcu::TestCase 236 { 237 public: 238 enum BufferMode 239 { 240 BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks. 241 BUFFERMODE_PER_BLOCK, //!< Per-block buffers 242 243 BUFFERMODE_LAST 244 }; 245 246 UniformBlockCase (tcu::TestContext& testCtx, glu::RenderContext& renderCtx, const char* name, const char* description, glu::GLSLVersion glslVersion, BufferMode bufferMode); 247 ~UniformBlockCase (void); 248 249 IterateResult iterate (void); 250 251 protected: 252 bool compareStd140Blocks (const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const; 253 bool compareSharedBlocks (const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const; 254 bool compareTypes (const ub::UniformLayout& refLayout, const ub::UniformLayout& cmpLayout) const; 255 bool checkLayoutIndices (const ub::UniformLayout& layout) const; 256 bool checkLayoutBounds (const ub::UniformLayout& layout) const; 257 bool checkIndexQueries (deUint32 program, const ub::UniformLayout& layout) const; 258 259 bool render (deUint32 program) const; 260 261 glu::RenderContext& m_renderCtx; 262 glu::GLSLVersion m_glslVersion; 263 BufferMode m_bufferMode; 264 ub::ShaderInterface m_interface; 265 }; 266 267 } // gls 268 } // deqp 269 270 #endif // _GLSUNIFORMBLOCKCASE_HPP 271