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