1 #ifndef _VKTSYNCHRONIZATIONUTIL_HPP 2 #define _VKTSYNCHRONIZATIONUTIL_HPP 3 /*------------------------------------------------------------------------ 4 * Vulkan Conformance Tests 5 * ------------------------ 6 * 7 * Copyright (c) 2016 The Khronos Group Inc. 8 * 9 * Licensed under the Apache License, Version 2.0 (the "License"); 10 * you may not use this file except in compliance with the License. 11 * You may obtain a copy of the License at 12 * 13 * http://www.apache.org/licenses/LICENSE-2.0 14 * 15 * Unless required by applicable law or agreed to in writing, software 16 * distributed under the License is distributed on an "AS IS" BASIS, 17 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 * 21 *//*! 22 * \file 23 * \brief Synchronization tests utilities 24 *//*--------------------------------------------------------------------*/ 25 26 #include "vkDefs.hpp" 27 #include "vkQueryUtil.hpp" 28 #include "vkMemUtil.hpp" 29 #include "vkRefUtil.hpp" 30 #include "vkPrograms.hpp" 31 #include "tcuVector.hpp" 32 #include "deMutex.hpp" 33 34 namespace vkt 35 { 36 namespace synchronization 37 { 38 39 class Buffer 40 { 41 public: Buffer(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkBufferCreateInfo & bufferCreateInfo,const vk::MemoryRequirement memoryRequirement)42 Buffer (const vk::DeviceInterface& vk, 43 const vk::VkDevice device, 44 vk::Allocator& allocator, 45 const vk::VkBufferCreateInfo& bufferCreateInfo, 46 const vk::MemoryRequirement memoryRequirement) 47 : m_buffer (createBuffer(vk, device, &bufferCreateInfo)) 48 , m_allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement)) 49 { 50 VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset())); 51 } 52 Buffer(vk::Move<vk::VkBuffer> buffer,de::MovePtr<vk::Allocation> allocation)53 Buffer (vk::Move<vk::VkBuffer> buffer, 54 de::MovePtr<vk::Allocation> allocation) 55 : m_buffer (buffer) 56 , m_allocation (allocation) 57 { 58 } 59 get(void) const60 const vk::VkBuffer& get (void) const { return *m_buffer; } operator *(void) const61 const vk::VkBuffer& operator* (void) const { return get(); } getAllocation(void) const62 vk::Allocation& getAllocation (void) const { return *m_allocation; } 63 64 private: 65 const vk::Unique<vk::VkBuffer> m_buffer; 66 const de::UniquePtr<vk::Allocation> m_allocation; 67 68 // "deleted" 69 Buffer (const Buffer&); 70 Buffer& operator= (const Buffer&); 71 }; 72 73 class Image 74 { 75 public: Image(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkImageCreateInfo & imageCreateInfo,const vk::MemoryRequirement memoryRequirement)76 Image (const vk::DeviceInterface& vk, 77 const vk::VkDevice device, 78 vk::Allocator& allocator, 79 const vk::VkImageCreateInfo& imageCreateInfo, 80 const vk::MemoryRequirement memoryRequirement) 81 : m_image (createImage(vk, device, &imageCreateInfo)) 82 , m_allocation (allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement)) 83 { 84 VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset())); 85 } Image(vk::Move<vk::VkImage> & image,de::MovePtr<vk::Allocation> & allocation)86 Image (vk::Move<vk::VkImage>& image, 87 de::MovePtr<vk::Allocation>& allocation) 88 : m_image (image) 89 , m_allocation (allocation) 90 { 91 } 92 get(void) const93 const vk::VkImage& get (void) const { return *m_image; } operator *(void) const94 const vk::VkImage& operator* (void) const { return get(); } getAllocation(void) const95 vk::Allocation& getAllocation (void) const { return *m_allocation; } 96 97 private: 98 const vk::Unique<vk::VkImage> m_image; 99 const de::UniquePtr<vk::Allocation> m_allocation; 100 101 // "deleted" 102 Image (const Image&); 103 Image& operator= (const Image&); 104 }; 105 106 class PipelineCacheData 107 { 108 public: 109 PipelineCacheData (void); 110 ~PipelineCacheData (void); 111 112 vk::Move<vk::VkPipelineCache> createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const; 113 void setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache); 114 115 private: 116 mutable de::Mutex m_lock; 117 std::vector<deUint8> m_data; 118 }; 119 120 class GraphicsPipelineBuilder 121 { 122 public: GraphicsPipelineBuilder(void)123 GraphicsPipelineBuilder (void) : m_renderSize (0, 0) 124 , m_shaderStageFlags (0u) 125 , m_cullModeFlags (vk::VK_CULL_MODE_NONE) 126 , m_frontFace (vk::VK_FRONT_FACE_COUNTER_CLOCKWISE) 127 , m_patchControlPoints (1u) 128 , m_blendEnable (false) 129 , m_primitiveTopology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) {} 130 setRenderSize(const tcu::IVec2 & size)131 GraphicsPipelineBuilder& setRenderSize (const tcu::IVec2& size) { m_renderSize = size; return *this; } 132 GraphicsPipelineBuilder& setShader (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkShaderStageFlagBits stage, const vk::ProgramBinary& binary, const vk::VkSpecializationInfo* specInfo); setPatchControlPoints(const deUint32 controlPoints)133 GraphicsPipelineBuilder& setPatchControlPoints (const deUint32 controlPoints) { m_patchControlPoints = controlPoints; return *this; } setCullModeFlags(const vk::VkCullModeFlags cullModeFlags)134 GraphicsPipelineBuilder& setCullModeFlags (const vk::VkCullModeFlags cullModeFlags) { m_cullModeFlags = cullModeFlags; return *this; } setFrontFace(const vk::VkFrontFace frontFace)135 GraphicsPipelineBuilder& setFrontFace (const vk::VkFrontFace frontFace) { m_frontFace = frontFace; return *this; } setBlend(const bool enable)136 GraphicsPipelineBuilder& setBlend (const bool enable) { m_blendEnable = enable; return *this; } 137 138 //! Applies only to pipelines without tessellation shaders. setPrimitiveTopology(const vk::VkPrimitiveTopology topology)139 GraphicsPipelineBuilder& setPrimitiveTopology (const vk::VkPrimitiveTopology topology) { m_primitiveTopology = topology; return *this; } 140 addVertexBinding(const vk::VkVertexInputBindingDescription vertexBinding)141 GraphicsPipelineBuilder& addVertexBinding (const vk::VkVertexInputBindingDescription vertexBinding) { m_vertexInputBindings.push_back(vertexBinding); return *this; } addVertexAttribute(const vk::VkVertexInputAttributeDescription vertexAttribute)142 GraphicsPipelineBuilder& addVertexAttribute (const vk::VkVertexInputAttributeDescription vertexAttribute) { m_vertexInputAttributes.push_back(vertexAttribute); return *this; } 143 144 //! Basic vertex input configuration (uses biding 0, location 0, etc.) 145 GraphicsPipelineBuilder& setVertexInputSingleAttribute (const vk::VkFormat vertexFormat, const deUint32 stride); 146 147 vk::Move<vk::VkPipeline> build (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineLayout pipelineLayout, const vk::VkRenderPass renderPass, PipelineCacheData& pipelineCacheData); 148 149 private: 150 tcu::IVec2 m_renderSize; 151 vk::Move<vk::VkShaderModule> m_vertexShaderModule; 152 vk::Move<vk::VkShaderModule> m_fragmentShaderModule; 153 vk::Move<vk::VkShaderModule> m_geometryShaderModule; 154 vk::Move<vk::VkShaderModule> m_tessControlShaderModule; 155 vk::Move<vk::VkShaderModule> m_tessEvaluationShaderModule; 156 std::vector<vk::VkPipelineShaderStageCreateInfo> m_shaderStages; 157 std::vector<vk::VkVertexInputBindingDescription> m_vertexInputBindings; 158 std::vector<vk::VkVertexInputAttributeDescription> m_vertexInputAttributes; 159 vk::VkShaderStageFlags m_shaderStageFlags; 160 vk::VkCullModeFlags m_cullModeFlags; 161 vk::VkFrontFace m_frontFace; 162 deUint32 m_patchControlPoints; 163 bool m_blendEnable; 164 vk::VkPrimitiveTopology m_primitiveTopology; 165 166 GraphicsPipelineBuilder (const GraphicsPipelineBuilder&); // "deleted" 167 GraphicsPipelineBuilder& operator= (const GraphicsPipelineBuilder&); 168 }; 169 170 enum FeatureFlagBits 171 { 172 FEATURE_TESSELLATION_SHADER = 1u << 0, 173 FEATURE_GEOMETRY_SHADER = 1u << 1, 174 FEATURE_SHADER_FLOAT_64 = 1u << 2, 175 FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS = 1u << 3, 176 FEATURE_FRAGMENT_STORES_AND_ATOMICS = 1u << 4, 177 FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE = 1u << 5, 178 FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS = 1u << 6, 179 }; 180 typedef deUint32 FeatureFlags; 181 182 enum SyncPrimitive 183 { 184 SYNC_PRIMITIVE_FENCE, 185 SYNC_PRIMITIVE_SEMAPHORE, 186 SYNC_PRIMITIVE_BARRIER, 187 SYNC_PRIMITIVE_EVENT, 188 }; 189 190 enum ResourceType 191 { 192 RESOURCE_TYPE_BUFFER, 193 RESOURCE_TYPE_IMAGE, 194 RESOURCE_TYPE_INDIRECT_BUFFER_DRAW, 195 RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED, 196 RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH, 197 }; 198 199 struct ResourceDescription 200 { 201 ResourceType type; 202 tcu::IVec4 size; //!< unused components are 0, e.g. for buffers only x is meaningful 203 vk::VkImageType imageType; 204 vk::VkFormat imageFormat; 205 vk::VkImageAspectFlags imageAspect; 206 }; 207 208 struct BufferResource 209 { 210 vk::VkBuffer handle; 211 vk::VkDeviceSize offset; 212 vk::VkDeviceSize size; 213 }; 214 215 struct ImageResource 216 { 217 vk::VkImage handle; 218 vk::VkExtent3D extent; 219 vk::VkImageType imageType; 220 vk::VkFormat format; 221 vk::VkImageSubresourceRange subresourceRange; 222 vk::VkImageSubresourceLayers subresourceLayers; 223 }; 224 225 vk::VkBufferCreateInfo makeBufferCreateInfo (const vk::VkDeviceSize bufferSize, const vk::VkBufferUsageFlags usage); 226 vk::VkImageCreateInfo makeImageCreateInfo (const vk::VkImageType imageType, const vk::VkExtent3D& extent, const vk::VkFormat format, const vk::VkImageUsageFlags usage); 227 vk::Move<vk::VkCommandBuffer> makeCommandBuffer (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkCommandPool commandPool); 228 vk::Move<vk::VkDescriptorSet> makeDescriptorSet (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorPool descriptorPool, const vk::VkDescriptorSetLayout setLayout); 229 vk::Move<vk::VkPipelineLayout> makePipelineLayout (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorSetLayout descriptorSetLayout); 230 vk::Move<vk::VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const vk::DeviceInterface& vk, const vk::VkDevice device); 231 vk::Move<vk::VkPipeline> makeComputePipeline (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineLayout pipelineLayout, const vk::VkShaderModule shaderModule, const vk::VkSpecializationInfo* specInfo, PipelineCacheData& pipelineCacheData); 232 vk::Move<vk::VkFramebuffer> makeFramebuffer (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkRenderPass renderPass, const vk::VkImageView colorAttachment, const deUint32 width, const deUint32 height, const deUint32 layers); 233 vk::Move<vk::VkImageView> makeImageView (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkImage image, const vk::VkImageViewType viewType, const vk::VkFormat format, const vk::VkImageSubresourceRange subresourceRange); 234 vk::VkBufferImageCopy makeBufferImageCopy (const vk::VkImageSubresourceLayers subresourceLayers, const vk::VkExtent3D extent); 235 vk::VkMemoryBarrier makeMemoryBarrier (const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask); 236 void beginRenderPassWithRasterizationDisabled (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer, const vk::VkRenderPass renderPass, const vk::VkFramebuffer framebuffer); 237 void requireFeatures (const vk::InstanceInterface& vki, const vk::VkPhysicalDevice physDevice, const FeatureFlags flags); 238 std::string getResourceName (const ResourceDescription& resource); 239 bool isIndirectBuffer (const ResourceType type); 240 241 } // synchronization 242 } // vkt 243 244 #endif // _VKTSYNCHRONIZATIONUTIL_HPP 245