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_SCALAR = (1<<4), 45 LAYOUT_MASK = LAYOUT_STD430|LAYOUT_STD140|LAYOUT_ROW_MAJOR|LAYOUT_COLUMN_MAJOR|LAYOUT_SCALAR, 46 47 // \todo [2013-10-14 pyry] Investigate adding these. 48 /* QUALIFIER_COHERENT = (1<<4), 49 QUALIFIER_VOLATILE = (1<<5), 50 QUALIFIER_RESTRICT = (1<<6), 51 QUALIFIER_READONLY = (1<<7), 52 QUALIFIER_WRITEONLY = (1<<8),*/ 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 LAYOUT_RELAXED = (1<<11), //!< Support VK_KHR_relaxed_block_layout extension 56 LAYOUT_16BIT_STORAGE = (1<<12), //!< Support VK_KHR_16bit_storage extension 57 LAYOUT_8BIT_STORAGE = (1 << 13), //!< Support VK_KHR_8bit_storage extension 58 LAYOUT_DESCRIPTOR_INDEXING = (1 << 14), //!< Support VK_KHR_descriptor_indexing extension 59 }; 60 61 enum MatrixLoadFlags 62 { 63 LOAD_FULL_MATRIX = 0, 64 LOAD_MATRIX_COMPONENTS = 1, 65 }; 66 67 enum MatrixStoreFlags 68 { 69 STORE_FULL_MATRIX = 0, 70 STORE_MATRIX_COLUMNS = 1, 71 }; 72 73 class BufferVar 74 { 75 public: 76 BufferVar (const char* name, const glu::VarType& type, deUint32 flags); 77 getName(void) const78 const char* getName (void) const { return m_name.c_str(); } getType(void) const79 const glu::VarType& getType (void) const { return m_type; } getFlags(void) const80 deUint32 getFlags (void) const { return m_flags; } getOffset(void) const81 deUint32 getOffset (void) const { return m_offset; } 82 setOffset(deUint32 offset)83 void setOffset (deUint32 offset) { m_offset = offset; } 84 85 private: 86 std::string m_name; 87 glu::VarType m_type; 88 deUint32 m_flags; 89 deUint32 m_offset; 90 }; 91 92 class BufferBlock 93 { 94 public: 95 typedef std::vector<BufferVar>::iterator iterator; 96 typedef std::vector<BufferVar>::const_iterator const_iterator; 97 98 BufferBlock (const char* blockName); 99 getBlockName(void) const100 const char* getBlockName (void) const { return m_blockName.c_str(); } getInstanceName(void) const101 const char* getInstanceName (void) const { return m_instanceName.empty() ? DE_NULL : m_instanceName.c_str(); } isArray(void) const102 bool isArray (void) const { return m_arraySize > 0; } getArraySize(void) const103 int getArraySize (void) const { return m_arraySize; } getFlags(void) const104 deUint32 getFlags (void) const { return m_flags; } 105 setInstanceName(const char * name)106 void setInstanceName (const char* name) { m_instanceName = name; } setFlags(deUint32 flags)107 void setFlags (deUint32 flags) { m_flags = flags; } addMember(const BufferVar & var)108 void addMember (const BufferVar& var) { m_variables.push_back(var); } 109 void setArraySize (int arraySize); 110 getLastUnsizedArraySize(int instanceNdx) const111 int getLastUnsizedArraySize (int instanceNdx) const { return m_lastUnsizedArraySizes[instanceNdx]; } setLastUnsizedArraySize(int instanceNdx,int size)112 void setLastUnsizedArraySize (int instanceNdx, int size) { m_lastUnsizedArraySizes[instanceNdx] = size; } 113 begin(void)114 inline iterator begin (void) { return m_variables.begin(); } begin(void) const115 inline const_iterator begin (void) const { return m_variables.begin(); } end(void)116 inline iterator end (void) { return m_variables.end(); } end(void) const117 inline const_iterator end (void) const { return m_variables.end(); } 118 119 private: 120 std::string m_blockName; 121 std::string m_instanceName; 122 std::vector<BufferVar> m_variables; 123 int m_arraySize; //!< Array size or 0 if not interface block array. 124 std::vector<int> m_lastUnsizedArraySizes; //!< Sizes of last unsized array element, can be different per instance. 125 deUint32 m_flags; 126 }; 127 128 class ShaderInterface 129 { 130 public: 131 ShaderInterface (void); 132 ~ShaderInterface (void); 133 134 glu::StructType& allocStruct (const char* name); 135 const glu::StructType* findStruct (const char* name) const; 136 void getNamedStructs (std::vector<const glu::StructType*>& structs) const; 137 138 BufferBlock& allocBlock (const char* name); 139 getNumBlocks(void) const140 int getNumBlocks (void) const { return (int)m_bufferBlocks.size(); } getBlock(int ndx) const141 const BufferBlock& getBlock (int ndx) const { return *m_bufferBlocks[ndx]; } getBlock(int ndx)142 BufferBlock& getBlock (int ndx) { return *m_bufferBlocks[ndx]; } 143 144 private: 145 ShaderInterface (const ShaderInterface&); 146 ShaderInterface& operator= (const ShaderInterface&); 147 148 std::vector<glu::StructType*> m_structs; 149 std::vector<BufferBlock*> m_bufferBlocks; 150 }; 151 152 struct BufferVarLayoutEntry 153 { BufferVarLayoutEntryvkt::ssbo::BufferVarLayoutEntry154 BufferVarLayoutEntry (void) 155 : type (glu::TYPE_LAST) 156 , blockNdx (-1) 157 , offset (-1) 158 , arraySize (-1) 159 , arrayStride (-1) 160 , matrixStride (-1) 161 , topLevelArraySize (-1) 162 , topLevelArrayStride (-1) 163 , isRowMajor (false) 164 { 165 } 166 167 std::string name; 168 glu::DataType type; 169 int blockNdx; 170 int offset; 171 int arraySize; 172 int arrayStride; 173 int matrixStride; 174 int topLevelArraySize; 175 int topLevelArrayStride; 176 bool isRowMajor; 177 }; 178 179 struct BlockLayoutEntry 180 { BlockLayoutEntryvkt::ssbo::BlockLayoutEntry181 BlockLayoutEntry (void) 182 : size(0) 183 { 184 } 185 186 std::string name; 187 int size; 188 std::vector<int> activeVarIndices; 189 }; 190 191 class BufferLayout 192 { 193 public: 194 std::vector<BlockLayoutEntry> blocks; 195 std::vector<BufferVarLayoutEntry> bufferVars; 196 197 int getVariableIndex (const std::string& name) const; 198 int getBlockIndex (const std::string& name) const; 199 }; 200 201 // BlockDataPtr 202 203 struct BlockDataPtr 204 { 205 void* ptr; 206 int size; //!< Redundant, for debugging purposes. 207 int lastUnsizedArraySize; 208 BlockDataPtrvkt::ssbo::BlockDataPtr209 BlockDataPtr (void* ptr_, int size_, int lastUnsizedArraySize_) 210 : ptr (ptr_) 211 , size (size_) 212 , lastUnsizedArraySize (lastUnsizedArraySize_) 213 { 214 } 215 BlockDataPtrvkt::ssbo::BlockDataPtr216 BlockDataPtr (void) 217 : ptr (DE_NULL) 218 , size (0) 219 , lastUnsizedArraySize (0) 220 { 221 } 222 }; 223 224 struct RefDataStorage 225 { 226 std::vector<deUint8> data; 227 std::vector<BlockDataPtr> pointers; 228 }; 229 230 class SSBOLayoutCase : public vkt::TestCase 231 { 232 public: 233 enum BufferMode 234 { 235 BUFFERMODE_SINGLE = 0, //!< Single buffer shared between uniform blocks. 236 BUFFERMODE_PER_BLOCK, //!< Per-block buffers 237 238 BUFFERMODE_LAST 239 }; 240 241 SSBOLayoutCase (tcu::TestContext& testCtx, const char* name, const char* description, BufferMode bufferMode, MatrixLoadFlags matrixLoadFlag, MatrixStoreFlags matrixStoreFlag, bool usePhysStorageBuffer); 242 virtual ~SSBOLayoutCase (void); 243 244 virtual void delayedInit (void); 245 virtual void initPrograms (vk::SourceCollections& programCollection) const; 246 virtual TestInstance* createInstance (Context& context) const; 247 virtual void checkSupport (Context &context) const; 248 249 protected: 250 BufferMode m_bufferMode; 251 ShaderInterface m_interface; 252 MatrixLoadFlags m_matrixLoadFlag; 253 MatrixStoreFlags m_matrixStoreFlag; 254 std::string m_computeShaderSrc; 255 bool m_usePhysStorageBuffer; 256 257 private: 258 SSBOLayoutCase (const SSBOLayoutCase&); 259 SSBOLayoutCase& operator= (const SSBOLayoutCase&); 260 261 BufferLayout m_refLayout; 262 RefDataStorage m_initialData; // Initial data stored in buffer. 263 RefDataStorage m_writeData; // Data written by compute shader. 264 }; 265 266 } // ssbo 267 } // vkt 268 269 #endif // _VKTSSBOLAYOUTCASE_HPP 270