1 #ifndef _VKTSSBOLAYOUTCASE_HPP 2 #define _VKTSSBOLAYOUTCASE_HPP 3 /*------------------------------------------------------------------------ 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2015 The Khronos Group Inc. 8 * Copyright (c) 2015 Samsung Electronics Co., Ltd. 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 SSBO layout tests. 25 *//*--------------------------------------------------------------------*/ 26 27 #include "vktTestCase.hpp" 28 #include "tcuDefs.hpp" 29 #include "gluShaderUtil.hpp" 30 #include "gluVarType.hpp" 31 32 namespace vkt 33 { 34 35 namespace ssbo 36 { 37 38 enum BufferVarFlags 39 { 40 LAYOUT_STD140 = (1<<0), 41 LAYOUT_STD430 = (1<<1), 42 LAYOUT_ROW_MAJOR = (1<<2), 43 LAYOUT_COLUMN_MAJOR = (1<<3), //!< \note Lack of both flags means column-major matrix. 44 LAYOUT_MASK = LAYOUT_STD430|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR, 45 46 // \todo [2013-10-14 pyry] Investigate adding these. 47 /* QUALIFIER_COHERENT = (1<<4), 48 QUALIFIER_VOLATILE = (1<<5), 49 QUALIFIER_RESTRICT = (1<<6), 50 QUALIFIER_READONLY = (1<<7), 51 QUALIFIER_WRITEONLY = (1<<8),*/ 52 53 ACCESS_READ = (1<<9), //!< Buffer variable is read in the shader. 54 ACCESS_WRITE = (1<<10), //!< Buffer variable is written in the shader. 55 }; 56 57 enum MatrixLoadFlags 58 { 59 LOAD_FULL_MATRIX = 0, 60 LOAD_MATRIX_COMPONENTS = 1, 61 }; 62 63 class BufferVar 64 { 65 public: 66 BufferVar (const char* name, const glu::VarType& type, deUint32 flags); 67 68 const char* getName (void) const { return m_name.c_str(); } 69 const glu::VarType& getType (void) const { return m_type; } 70 deUint32 getFlags (void) const { return m_flags; } 71 72 private: 73 std::string m_name; 74 glu::VarType m_type; 75 deUint32 m_flags; 76 }; 77 78 class BufferBlock 79 { 80 public: 81 typedef std::vector<BufferVar>::iterator iterator; 82 typedef std::vector<BufferVar>::const_iterator const_iterator; 83 84 BufferBlock (const char* blockName); 85 86 const char* getBlockName (void) const { return m_blockName.c_str(); } 87 const char* getInstanceName (void) const { return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str(); } 88 bool isArray (void) const { return m_arraySize > 0; } 89 int getArraySize (void) const { return m_arraySize; } 90 deUint32 getFlags (void) const { return m_flags; } 91 92 void setInstanceName (const char* name) { m_instanceName = name; } 93 void setFlags (deUint32 flags) { m_flags = flags; } 94 void addMember (const BufferVar& var) { m_variables.push_back(var); } 95 void setArraySize (int arraySize); 96 97 int getLastUnsizedArraySize (int instanceNdx) const { return m_lastUnsizedArraySizes[instanceNdx]; } 98 void setLastUnsizedArraySize (int instanceNdx, int size) { m_lastUnsizedArraySizes[instanceNdx] = size; } 99 100 inline iterator begin (void) { return m_variables.begin(); } 101 inline const_iterator begin (void) const { return m_variables.begin(); } 102 inline iterator end (void) { return m_variables.end(); } 103 inline const_iterator end (void) const { return m_variables.end(); } 104 105 private: 106 std::string m_blockName; 107 std::string m_instanceName; 108 std::vector<BufferVar> m_variables; 109 int m_arraySize; //!< Array size or 0 if not interface block array. 110 std::vector<int> m_lastUnsizedArraySizes; //!< Sizes of last unsized array element, can be different per instance. 111 deUint32 m_flags; 112 }; 113 114 class ShaderInterface 115 { 116 public: 117 ShaderInterface (void); 118 ~ShaderInterface (void); 119 120 glu::StructType& allocStruct (const char* name); 121 const glu::StructType* findStruct (const char* name) const; 122 void getNamedStructs (std::vector<const glu::StructType*>& structs) const; 123 124 BufferBlock& allocBlock (const char* name); 125 126 int getNumBlocks (void) const { return (int)m_bufferBlocks.size(); } 127 const BufferBlock& getBlock (int ndx) const { return *m_bufferBlocks[ndx]; } 128 129 private: 130 ShaderInterface (const ShaderInterface&); 131 ShaderInterface& operator= (const ShaderInterface&); 132 133 std::vector<glu::StructType*> m_structs; 134 std::vector<BufferBlock*> m_bufferBlocks; 135 }; 136 137 struct BufferVarLayoutEntry 138 { 139 BufferVarLayoutEntry (void) 140 : type (glu::TYPE_LAST) 141 , blockNdx (-1) 142 , offset (-1) 143 , arraySize (-1) 144 , arrayStride (-1) 145 , matrixStride (-1) 146 , topLevelArraySize (-1) 147 , topLevelArrayStride (-1) 148 , isRowMajor (false) 149 { 150 } 151 152 std::string name; 153 glu::DataType type; 154 int blockNdx; 155 int offset; 156 int arraySize; 157 int arrayStride; 158 int matrixStride; 159 int topLevelArraySize; 160 int topLevelArrayStride; 161 bool isRowMajor; 162 }; 163 164 struct BlockLayoutEntry 165 { 166 BlockLayoutEntry (void) 167 : size(0) 168 { 169 } 170 171 std::string name; 172 int size; 173 std::vector<int> activeVarIndices; 174 }; 175 176 class BufferLayout 177 { 178 public: 179 std::vector<BlockLayoutEntry> blocks; 180 std::vector<BufferVarLayoutEntry> bufferVars; 181 182 int getVariableIndex (const std::string& name) const; 183 int getBlockIndex (const std::string& name) const; 184 }; 185 186 // BlockDataPtr 187 188 struct BlockDataPtr 189 { 190 void* ptr; 191 int size; //!< Redundant, for debugging purposes. 192 int lastUnsizedArraySize; 193 194 BlockDataPtr (void* ptr_, int size_, int lastUnsizedArraySize_) 195 : ptr (ptr_) 196 , size (size_) 197 , lastUnsizedArraySize (lastUnsizedArraySize_) 198 { 199 } 200 201 BlockDataPtr (void) 202 : ptr (DE_NULL) 203 , size (0) 204 , lastUnsizedArraySize (0) 205 { 206 } 207 }; 208 209 struct RefDataStorage 210 { 211 std::vector<deUint8> data; 212 std::vector<BlockDataPtr> pointers; 213 }; 214 215 class SSBOLayoutCase : public vkt::TestCase 216 { 217 public: 218 enum BufferMode 219 { 220 BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks. 221 BUFFERMODE_PER_BLOCK, //!< Per-block buffers 222 223 BUFFERMODE_LAST 224 }; 225 226 SSBOLayoutCase (tcu::TestContext& testCtx, const char* name, const char* description, BufferMode bufferMode, MatrixLoadFlags matrixLoadFlag); 227 virtual ~SSBOLayoutCase (void); 228 229 virtual void initPrograms (vk::SourceCollections& programCollection) const; 230 virtual TestInstance* createInstance (Context& context) const; 231 232 protected: 233 void init (void); 234 235 BufferMode m_bufferMode; 236 ShaderInterface m_interface; 237 MatrixLoadFlags m_matrixLoadFlag; 238 239 private: 240 SSBOLayoutCase (const SSBOLayoutCase&); 241 SSBOLayoutCase& operator= (const SSBOLayoutCase&); 242 243 BufferLayout m_refLayout; 244 RefDataStorage m_initialData; // Initial data stored in buffer. 245 RefDataStorage m_writeData; // Data written by compute shader. 246 std::string m_computeShaderSrc; 247 }; 248 249 } // ssbo 250 } // vkt 251 252 #endif // _VKTSSBOLAYOUTCASE_HPP 253