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