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 30namespace glu 31{ 32class RenderContext; 33} 34 35namespace deqp 36{ 37namespace gls 38{ 39 40// Uniform block details. 41namespace ub 42{ 43 44enum 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 69class StructType; 70 71class VarType 72{ 73public: 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); 79 ~VarType (void); 80 81 bool isBasicType (void) const { return m_type == TYPE_BASIC; } 82 bool isArrayType (void) const { return m_type == TYPE_ARRAY; } 83 bool isStructType (void) const { return m_type == TYPE_STRUCT; } 84 85 deUint32 getFlags (void) const { return m_flags; } 86 glu::DataType getBasicType (void) const { return m_data.basicType; } 87 88 const VarType& getElementType (void) const { return *m_data.array.elementType; } 89 int getArraySize (void) const { return m_data.array.size; } 90 91 const StructType& getStruct (void) const { return *m_data.structPtr; } 92 93 VarType& operator= (const VarType& other); 94 95private: 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 117 Data (void) 118 { 119 array.elementType = DE_NULL; 120 array.size = 0; 121 }; 122 } m_data; 123}; 124 125class StructMember 126{ 127public: 128 StructMember (const char* name, const VarType& type, deUint32 flags) : m_name(name), m_type(type), m_flags(flags) {} 129 StructMember (void) : m_flags(0) {} 130 131 const char* getName (void) const { return m_name.c_str(); } 132 const VarType& getType (void) const { return m_type; } 133 deUint32 getFlags (void) const { return m_flags; } 134 135private: 136 std::string m_name; 137 VarType m_type; 138 deUint32 m_flags; 139}; 140 141class StructType 142{ 143public: 144 typedef std::vector<StructMember>::iterator Iterator; 145 typedef std::vector<StructMember>::const_iterator ConstIterator; 146 147 StructType (const char* typeName) : m_typeName(typeName) {} 148 ~StructType (void) {} 149 150 const char* getTypeName (void) const { return m_typeName.empty() ? DE_NULL : m_typeName.c_str(); } 151 152 inline Iterator begin (void) { return m_members.begin(); } 153 inline ConstIterator begin (void) const { return m_members.begin(); } 154 inline Iterator end (void) { return m_members.end(); } 155 inline ConstIterator end (void) const { return m_members.end(); } 156 157 void addMember (const char* name, const VarType& type, deUint32 flags = 0); 158 159private: 160 std::string m_typeName; 161 std::vector<StructMember> m_members; 162}; 163 164class Uniform 165{ 166public: 167 Uniform (const char* name, const VarType& type, deUint32 flags = 0); 168 169 const char* getName (void) const { return m_name.c_str(); } 170 const VarType& getType (void) const { return m_type; } 171 deUint32 getFlags (void) const { return m_flags; } 172 173private: 174 std::string m_name; 175 VarType m_type; 176 deUint32 m_flags; 177}; 178 179class UniformBlock 180{ 181public: 182 typedef std::vector<Uniform>::iterator Iterator; 183 typedef std::vector<Uniform>::const_iterator ConstIterator; 184 185 UniformBlock (const char* blockName); 186 187 const char* getBlockName (void) const { return m_blockName.c_str(); } 188 const char* getInstanceName (void) const { return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str(); } 189 bool isArray (void) const { return m_arraySize > 0; } 190 int getArraySize (void) const { return m_arraySize; } 191 deUint32 getFlags (void) const { return m_flags; } 192 193 void setInstanceName (const char* name) { m_instanceName = name; } 194 void setFlags (deUint32 flags) { m_flags = flags; } 195 void setArraySize (int arraySize) { m_arraySize = arraySize; } 196 void addUniform (const Uniform& uniform) { m_uniforms.push_back(uniform); } 197 198 inline Iterator begin (void) { return m_uniforms.begin(); } 199 inline ConstIterator begin (void) const { return m_uniforms.begin(); } 200 inline Iterator end (void) { return m_uniforms.end(); } 201 inline ConstIterator end (void) const { return m_uniforms.end(); } 202 203private: 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 211class ShaderInterface 212{ 213public: 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 223 int getNumUniformBlocks (void) const { return (int)m_uniformBlocks.size(); } 224 const UniformBlock& getUniformBlock (int ndx) const { return *m_uniformBlocks[ndx]; } 225 226private: 227 std::vector<StructType*> m_structs; 228 std::vector<UniformBlock*> m_uniformBlocks; 229}; 230 231class UniformLayout; 232 233} // ub 234 235class UniformBlockCase : public tcu::TestCase 236{ 237public: 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 251protected: 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