1 #ifndef _VKTSHADEREXECUTOR_HPP 2 #define _VKTSHADEREXECUTOR_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 Vulkan ShaderExecutor 25 *//*--------------------------------------------------------------------*/ 26 27 #include "deSharedPtr.hpp" 28 29 #include "vktTestCase.hpp" 30 #include "vkMemUtil.hpp" 31 #include "vkBuilderUtil.hpp" 32 33 #include "gluVarType.hpp" 34 35 #include "tcuTexture.hpp" 36 37 #include <vector> 38 39 namespace vkt 40 { 41 namespace shaderexecutor 42 { 43 44 using namespace vk; 45 46 //! Shader input / output variable declaration. 47 struct Symbol 48 { 49 std::string name; //!< Symbol name. 50 glu::VarType varType; //!< Symbol type. 51 52 Symbol (void) {} 53 Symbol (const std::string& name_, const glu::VarType& varType_) : name(name_), varType(varType_) {} 54 }; 55 56 //! Complete shader specification. 57 struct ShaderSpec 58 { 59 std::vector<Symbol> inputs; 60 std::vector<Symbol> outputs; 61 std::string globalDeclarations; //!< These are placed into global scope. Can contain uniform declarations for example. 62 std::string source; //!< Source snippet to be executed. 63 64 ShaderSpec (void) {} 65 }; 66 67 // UniformSetup 68 69 class UniformDataBase; 70 class ShaderExecutor; 71 72 typedef de::SharedPtr<de::UniquePtr<UniformDataBase> > UniformDataSp; 73 74 class UniformSetup 75 { 76 public: 77 UniformSetup (void) {} 78 virtual ~UniformSetup (void) {} 79 80 void addData (UniformDataBase* uniformData) 81 { 82 m_uniforms.push_back(UniformDataSp(new de::UniquePtr<UniformDataBase>(uniformData))); 83 } 84 85 const std::vector<UniformDataSp>& uniforms (void) const 86 { 87 return m_uniforms; 88 } 89 90 private: 91 UniformSetup (const UniformSetup&); // not allowed! 92 UniformSetup& operator= (const UniformSetup&); // not allowed! 93 94 std::vector<UniformDataSp> m_uniforms; 95 }; 96 97 //! Base class for shader executor. 98 class ShaderExecutor 99 { 100 public: 101 virtual ~ShaderExecutor (void); 102 103 //! Log executor details (program etc.). 104 virtual void log (tcu::TestLog& log) const = 0; 105 106 //! Execute 107 virtual void execute (const Context& ctx, int numValues, const void* const* inputs, void* const* outputs) = 0; 108 109 virtual void setShaderSources (SourceCollections& programCollection) const = 0; 110 111 void setUniforms (const UniformSetup* uniformSetup) 112 { 113 m_uniformSetup = de::MovePtr<const UniformSetup>(uniformSetup); 114 }; 115 116 void setupUniformData (const VkDevice& vkDevice, 117 const DeviceInterface& vk, 118 const VkQueue queue, 119 const deUint32 queueFamilyIndex, 120 Allocator& memAlloc, 121 deUint32 bindingLocation, 122 VkDescriptorType descriptorType, 123 deUint32 size, 124 const void* dataPtr); 125 126 void setupUniformArray (const VkDevice& vkDevice, 127 const DeviceInterface& vk, 128 const VkQueue queue, 129 const deUint32 queueFamilyIndex, 130 Allocator& memAlloc, 131 deUint32 bindingLocation, 132 VkDescriptorType descriptorType, 133 deUint32 arraySize, 134 deUint32 size, 135 const void* dataPtr); 136 137 void setupSamplerData (const VkDevice& vkDevice, 138 const DeviceInterface& vk, 139 const VkQueue queue, 140 const deUint32 queueFamilyIndex, 141 Allocator& memAlloc, 142 deUint32 bindingLocation, 143 deUint32 numSamplers, 144 const tcu::Sampler& refSampler, 145 const tcu::TextureFormat& texFormat, 146 const tcu::IVec3& texSize, 147 VkImageType imageType, 148 VkImageViewType imageViewType, 149 const void* data); 150 151 const void* getBufferPtr (const deUint32 bindingLocation) const; 152 153 protected: 154 ShaderExecutor (const ShaderSpec& shaderSpec, glu::ShaderType shaderType); 155 156 void addUniforms (const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc); 157 158 void uploadUniforms (DescriptorSetUpdateBuilder& descriptorSetUpdateBuilder, VkDescriptorSet descriptorSet); 159 160 class UniformInfo; 161 typedef de::SharedPtr<de::UniquePtr<UniformInfo> > UniformInfoSp; 162 class BufferUniform; 163 typedef de::SharedPtr<de::UniquePtr<BufferUniform> > BufferUniformSp; 164 class SamplerUniform; 165 typedef de::SharedPtr<de::UniquePtr<SamplerUniform> > SamplerUniformSp; 166 167 typedef de::SharedPtr<Unique<VkBuffer> > VkBufferSp; 168 typedef de::SharedPtr<Unique<VkImage> > VkImageSp; 169 typedef de::SharedPtr<Unique<VkImageView> > VkImageViewSp; 170 typedef de::SharedPtr<Unique<VkSampler> > VkSamplerSp; 171 typedef de::SharedPtr<Allocation> AllocationSp; 172 173 class UniformInfo 174 { 175 public: 176 enum UniformType 177 { 178 UNIFORM_TYPE_BUFFER = 0, 179 UNIFORM_TYPE_SAMPLER, 180 UNIFORM_TYPE_BUFFER_ARRAY, 181 UNIFORM_TYPE_SAMPLER_ARRAY, 182 183 UNIFORM_TYPE_LAST 184 }; 185 186 UniformInfo (void) {} 187 virtual ~UniformInfo (void) {} 188 virtual UniformType getType (void) const = 0; 189 190 VkDescriptorType type; 191 deUint32 location; 192 }; 193 194 class BufferUniform : public UniformInfo 195 { 196 public: 197 BufferUniform (void) {} 198 virtual ~BufferUniform (void) {} 199 virtual UniformType getType (void) const { return UNIFORM_TYPE_BUFFER; } 200 201 VkBufferSp buffer; 202 AllocationSp alloc; 203 VkDescriptorBufferInfo descriptor; 204 }; 205 206 class SamplerUniform : public UniformInfo 207 { 208 public: 209 SamplerUniform (void) {} 210 virtual ~SamplerUniform (void) {} 211 virtual UniformType getType (void) const { return UNIFORM_TYPE_SAMPLER; } 212 213 VkImageSp image; 214 VkImageViewSp imageView; 215 VkSamplerSp sampler; 216 AllocationSp alloc; 217 VkDescriptorImageInfo descriptor; 218 }; 219 220 class BufferArrayUniform : public UniformInfo 221 { 222 public: 223 BufferArrayUniform (void) {} 224 virtual ~BufferArrayUniform (void) {} 225 virtual UniformType getType (void) const { return UNIFORM_TYPE_BUFFER_ARRAY; } 226 227 std::vector<BufferUniformSp> uniforms; 228 }; 229 230 class SamplerArrayUniform : public UniformInfo 231 { 232 public: 233 SamplerArrayUniform (void) {} 234 virtual ~SamplerArrayUniform (void) {} 235 virtual UniformType getType (void) const { return UNIFORM_TYPE_SAMPLER_ARRAY; } 236 237 std::vector<SamplerUniformSp> uniforms; 238 }; 239 240 void uploadImage (const VkDevice& vkDevice, 241 const DeviceInterface& vk, 242 const VkQueue queue, 243 const deUint32 queueFamilyIndex, 244 Allocator& memAlloc, 245 const tcu::TextureFormat& texFormat, 246 const tcu::IVec3& texSize, 247 const void* data, 248 const deUint32 arraySize, 249 const VkImageAspectFlags aspectMask, 250 VkImage destImage); 251 252 de::MovePtr<SamplerUniform> createSamplerUniform (const VkDevice& vkDevice, 253 const DeviceInterface& vk, 254 const VkQueue queue, 255 const deUint32 queueFamilyIndex, 256 Allocator& memAlloc, 257 deUint32 bindingLocation, 258 const tcu::Sampler& refSampler, 259 const tcu::TextureFormat& texFormat, 260 const tcu::IVec3& texSize, 261 VkImageType imageType, 262 VkImageViewType imageViewType, 263 const void* data); 264 265 de::MovePtr<BufferUniform> createBufferUniform (const VkDevice& vkDevice, 266 const DeviceInterface& vk, 267 const VkQueue queue, 268 const deUint32 queueFamilyIndex, 269 Allocator& memAlloc, 270 deUint32 bindingLocation, 271 VkDescriptorType descriptorType, 272 deUint32 size, 273 const void* dataPtr); 274 275 const ShaderSpec m_shaderSpec; 276 const glu::ShaderType m_shaderType; 277 278 std::vector<UniformInfoSp> m_uniformInfos; 279 de::MovePtr<const UniformSetup> m_uniformSetup; 280 DescriptorSetLayoutBuilder m_descriptorSetLayoutBuilder; 281 DescriptorPoolBuilder m_descriptorPoolBuilder; 282 283 }; 284 285 inline tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderExecutor* executor) { executor->log(log); return log; } 286 inline tcu::TestLog& operator<< (tcu::TestLog& log, const ShaderExecutor& executor) { executor.log(log); return log; } 287 288 ShaderExecutor* createExecutor(glu::ShaderType shaderType, const ShaderSpec& shaderSpec); 289 290 class UniformDataBase 291 { 292 public: 293 UniformDataBase (deUint32 bindingLocation) 294 : m_bindingLocation (bindingLocation) 295 { 296 } 297 virtual ~UniformDataBase (void) {} 298 virtual void setup (ShaderExecutor&, const VkDevice&, const DeviceInterface&, const VkQueue, const deUint32, Allocator&) const = 0; 299 300 protected: 301 const deUint32 m_bindingLocation; 302 }; 303 304 template<typename T> 305 class UniformData : public UniformDataBase 306 { 307 public: 308 UniformData (deUint32 bindingLocation, VkDescriptorType descriptorType, const T data); 309 virtual ~UniformData (void); 310 virtual void setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const; 311 312 private: 313 VkDescriptorType m_descriptorType; 314 T m_data; 315 }; 316 317 template<typename T> 318 UniformData<T>::UniformData (deUint32 bindingLocation, VkDescriptorType descriptorType, const T data) 319 : UniformDataBase (bindingLocation) 320 , m_descriptorType (descriptorType) 321 , m_data (data) 322 { 323 } 324 325 template<typename T> 326 UniformData<T>::~UniformData (void) 327 { 328 } 329 330 template<typename T> 331 void UniformData<T>::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const 332 { 333 executor.setupUniformData(vkDevice, vk, queue, queueFamilyIndex, memAlloc, m_bindingLocation, m_descriptorType, sizeof(T), &m_data); 334 } 335 336 template<typename T> 337 class UniformArrayData : public UniformDataBase 338 { 339 public: 340 UniformArrayData (deUint32 bindingLocation, VkDescriptorType descriptorType, const std::vector<T>& data); 341 virtual ~UniformArrayData (void); 342 virtual void setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const; 343 344 private: 345 VkDescriptorType m_descriptorType; 346 std::vector<T> m_data; 347 }; 348 349 template<typename T> 350 UniformArrayData<T>::UniformArrayData (deUint32 bindingLocation, VkDescriptorType descriptorType, const std::vector<T>& data) 351 : UniformDataBase (bindingLocation) 352 , m_descriptorType (descriptorType) 353 , m_data (data) 354 { 355 } 356 357 template<typename T> 358 UniformArrayData<T>::~UniformArrayData (void) 359 { 360 } 361 362 template<typename T> 363 void UniformArrayData<T>::setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const 364 { 365 DE_ASSERT(!m_data.empty()); 366 executor.setupUniformArray(vkDevice, vk, queue, queueFamilyIndex, memAlloc, m_bindingLocation, m_descriptorType, (deUint32)m_data.size(), sizeof(T), &m_data[0]); 367 } 368 369 class SamplerUniformData : public UniformDataBase 370 { 371 public: 372 SamplerUniformData (deUint32 bindingLocation, 373 deUint32 numSamplers, 374 const tcu::Sampler& refSampler, 375 const tcu::TextureFormat& texFormat, 376 const tcu::IVec3& texSize, 377 VkImageType imageType, 378 VkImageViewType imageViewType, 379 const void* data); 380 virtual ~SamplerUniformData (void); 381 virtual void setup (ShaderExecutor& executor, const VkDevice& vkDevice, const DeviceInterface& vk, const VkQueue queue, const deUint32 queueFamilyIndex, Allocator& memAlloc) const; 382 383 private: 384 deUint32 m_numSamplers; 385 const tcu::Sampler m_refSampler; 386 const tcu::TextureFormat m_texFormat; 387 const tcu::IVec3 m_texSize; 388 VkImageType m_imageType; 389 VkImageViewType m_imageViewType; 390 const void* m_data; 391 }; 392 393 } // shaderexecutor 394 } // vkt 395 396 #endif // _VKTSHADEREXECUTOR_HPP 397