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 48 : m_buffer (createBuffer(vk, device, &bufferCreateInfo)) 49 , m_allocation (allocator.allocate(getBufferMemoryRequirements(vk, device, *m_buffer), memoryRequirement)) 50 { 51 VK_CHECK(vk.bindBufferMemory(device, *m_buffer, m_allocation->getMemory(), m_allocation->getOffset())); 52 } 53 get(void) const54 const vk::VkBuffer& get (void) const { return *m_buffer; } operator *(void) const55 const vk::VkBuffer& operator* (void) const { return get(); } getAllocation(void) const56 vk::Allocation& getAllocation (void) const { return *m_allocation; } 57 58 private: 59 const vk::Unique<vk::VkBuffer> m_buffer; 60 const de::UniquePtr<vk::Allocation> m_allocation; 61 62 // "deleted" 63 Buffer (const Buffer&); 64 Buffer& operator= (const Buffer&); 65 }; 66 67 class Image 68 { 69 public: Image(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkImageCreateInfo & imageCreateInfo,const vk::MemoryRequirement memoryRequirement)70 Image (const vk::DeviceInterface& vk, 71 const vk::VkDevice device, 72 vk::Allocator& allocator, 73 const vk::VkImageCreateInfo& imageCreateInfo, 74 const vk::MemoryRequirement memoryRequirement) 75 76 : m_image (createImage(vk, device, &imageCreateInfo)) 77 , m_allocation (allocator.allocate(getImageMemoryRequirements(vk, device, *m_image), memoryRequirement)) 78 { 79 VK_CHECK(vk.bindImageMemory(device, *m_image, m_allocation->getMemory(), m_allocation->getOffset())); 80 } 81 get(void) const82 const vk::VkImage& get (void) const { return *m_image; } operator *(void) const83 const vk::VkImage& operator* (void) const { return get(); } getAllocation(void) const84 vk::Allocation& getAllocation (void) const { return *m_allocation; } 85 86 private: 87 const vk::Unique<vk::VkImage> m_image; 88 const de::UniquePtr<vk::Allocation> m_allocation; 89 90 // "deleted" 91 Image (const Image&); 92 Image& operator= (const Image&); 93 }; 94 95 class PipelineCacheData 96 { 97 public: 98 PipelineCacheData (void); 99 ~PipelineCacheData (void); 100 101 vk::Move<vk::VkPipelineCache> createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const; 102 void setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache); 103 104 private: 105 mutable de::Mutex m_lock; 106 std::vector<deUint8> m_data; 107 }; 108 109 class GraphicsPipelineBuilder 110 { 111 public: GraphicsPipelineBuilder(void)112 GraphicsPipelineBuilder (void) : m_renderSize (0, 0) 113 , m_shaderStageFlags (0u) 114 , m_cullModeFlags (vk::VK_CULL_MODE_NONE) 115 , m_frontFace (vk::VK_FRONT_FACE_COUNTER_CLOCKWISE) 116 , m_patchControlPoints (1u) 117 , m_blendEnable (false) 118 , m_primitiveTopology (vk::VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) {} 119 setRenderSize(const tcu::IVec2 & size)120 GraphicsPipelineBuilder& setRenderSize (const tcu::IVec2& size) { m_renderSize = size; return *this; } 121 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)122 GraphicsPipelineBuilder& setPatchControlPoints (const deUint32 controlPoints) { m_patchControlPoints = controlPoints; return *this; } setCullModeFlags(const vk::VkCullModeFlags cullModeFlags)123 GraphicsPipelineBuilder& setCullModeFlags (const vk::VkCullModeFlags cullModeFlags) { m_cullModeFlags = cullModeFlags; return *this; } setFrontFace(const vk::VkFrontFace frontFace)124 GraphicsPipelineBuilder& setFrontFace (const vk::VkFrontFace frontFace) { m_frontFace = frontFace; return *this; } setBlend(const bool enable)125 GraphicsPipelineBuilder& setBlend (const bool enable) { m_blendEnable = enable; return *this; } 126 127 //! Applies only to pipelines without tessellation shaders. setPrimitiveTopology(const vk::VkPrimitiveTopology topology)128 GraphicsPipelineBuilder& setPrimitiveTopology (const vk::VkPrimitiveTopology topology) { m_primitiveTopology = topology; return *this; } 129 addVertexBinding(const vk::VkVertexInputBindingDescription vertexBinding)130 GraphicsPipelineBuilder& addVertexBinding (const vk::VkVertexInputBindingDescription vertexBinding) { m_vertexInputBindings.push_back(vertexBinding); return *this; } addVertexAttribute(const vk::VkVertexInputAttributeDescription vertexAttribute)131 GraphicsPipelineBuilder& addVertexAttribute (const vk::VkVertexInputAttributeDescription vertexAttribute) { m_vertexInputAttributes.push_back(vertexAttribute); return *this; } 132 133 //! Basic vertex input configuration (uses biding 0, location 0, etc.) 134 GraphicsPipelineBuilder& setVertexInputSingleAttribute (const vk::VkFormat vertexFormat, const deUint32 stride); 135 136 vk::Move<vk::VkPipeline> build (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineLayout pipelineLayout, const vk::VkRenderPass renderPass, PipelineCacheData& pipelineCacheData); 137 138 private: 139 tcu::IVec2 m_renderSize; 140 vk::Move<vk::VkShaderModule> m_vertexShaderModule; 141 vk::Move<vk::VkShaderModule> m_fragmentShaderModule; 142 vk::Move<vk::VkShaderModule> m_geometryShaderModule; 143 vk::Move<vk::VkShaderModule> m_tessControlShaderModule; 144 vk::Move<vk::VkShaderModule> m_tessEvaluationShaderModule; 145 std::vector<vk::VkPipelineShaderStageCreateInfo> m_shaderStages; 146 std::vector<vk::VkVertexInputBindingDescription> m_vertexInputBindings; 147 std::vector<vk::VkVertexInputAttributeDescription> m_vertexInputAttributes; 148 vk::VkShaderStageFlags m_shaderStageFlags; 149 vk::VkCullModeFlags m_cullModeFlags; 150 vk::VkFrontFace m_frontFace; 151 deUint32 m_patchControlPoints; 152 bool m_blendEnable; 153 vk::VkPrimitiveTopology m_primitiveTopology; 154 155 GraphicsPipelineBuilder (const GraphicsPipelineBuilder&); // "deleted" 156 GraphicsPipelineBuilder& operator= (const GraphicsPipelineBuilder&); 157 }; 158 159 enum FeatureFlagBits 160 { 161 FEATURE_TESSELLATION_SHADER = 1u << 0, 162 FEATURE_GEOMETRY_SHADER = 1u << 1, 163 FEATURE_SHADER_FLOAT_64 = 1u << 2, 164 FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS = 1u << 3, 165 FEATURE_FRAGMENT_STORES_AND_ATOMICS = 1u << 4, 166 FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE = 1u << 5, 167 FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS = 1u << 6, 168 }; 169 typedef deUint32 FeatureFlags; 170 171 enum SyncPrimitive 172 { 173 SYNC_PRIMITIVE_FENCE, 174 SYNC_PRIMITIVE_SEMAPHORE, 175 SYNC_PRIMITIVE_BARRIER, 176 SYNC_PRIMITIVE_EVENT, 177 }; 178 179 enum ResourceType 180 { 181 RESOURCE_TYPE_BUFFER, 182 RESOURCE_TYPE_IMAGE, 183 RESOURCE_TYPE_INDIRECT_BUFFER_DRAW, 184 RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED, 185 RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH, 186 }; 187 188 struct ResourceDescription 189 { 190 ResourceType type; 191 tcu::IVec4 size; //!< unused components are 0, e.g. for buffers only x is meaningful 192 vk::VkImageType imageType; 193 vk::VkFormat imageFormat; 194 vk::VkImageAspectFlags imageAspect; 195 }; 196 197 struct BufferResource 198 { 199 vk::VkBuffer handle; 200 vk::VkDeviceSize offset; 201 vk::VkDeviceSize size; 202 }; 203 204 struct ImageResource 205 { 206 vk::VkImage handle; 207 vk::VkExtent3D extent; 208 vk::VkImageType imageType; 209 vk::VkFormat format; 210 vk::VkImageSubresourceRange subresourceRange; 211 vk::VkImageSubresourceLayers subresourceLayers; 212 }; 213 214 vk::VkBufferCreateInfo makeBufferCreateInfo (const vk::VkDeviceSize bufferSize, const vk::VkBufferUsageFlags usage); 215 vk::VkImageCreateInfo makeImageCreateInfo (const vk::VkImageType imageType, const vk::VkExtent3D& extent, const vk::VkFormat format, const vk::VkImageUsageFlags usage); 216 vk::Move<vk::VkCommandPool> makeCommandPool (const vk::DeviceInterface& vk, const vk::VkDevice device, const deUint32 queueFamilyIndex); 217 vk::Move<vk::VkCommandBuffer> makeCommandBuffer (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkCommandPool commandPool); 218 vk::Move<vk::VkDescriptorSet> makeDescriptorSet (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorPool descriptorPool, const vk::VkDescriptorSetLayout setLayout); 219 vk::Move<vk::VkPipelineLayout> makePipelineLayout (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkDescriptorSetLayout descriptorSetLayout); 220 vk::Move<vk::VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const vk::DeviceInterface& vk, const vk::VkDevice device); 221 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); 222 vk::Move<vk::VkRenderPass> makeRenderPass (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkFormat colorFormat); 223 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); 224 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); 225 vk::Move<vk::VkEvent> makeEvent (const vk::DeviceInterface& vk, const vk::VkDevice device); 226 vk::VkBufferImageCopy makeBufferImageCopy (const vk::VkImageSubresourceLayers subresourceLayers, const vk::VkExtent3D extent); 227 vk::VkMemoryBarrier makeMemoryBarrier (const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask); 228 vk::VkBufferMemoryBarrier makeBufferMemoryBarrier (const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask, const vk::VkBuffer buffer, const vk::VkDeviceSize offset, const vk::VkDeviceSize bufferSizeBytes); 229 vk::VkImageMemoryBarrier makeImageMemoryBarrier (const vk::VkAccessFlags srcAccessMask, const vk::VkAccessFlags dstAccessMask, const vk::VkImageLayout oldLayout, const vk::VkImageLayout newLayout, const vk::VkImage image, const vk::VkImageSubresourceRange subresourceRange); 230 231 void beginCommandBuffer (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer); 232 void endCommandBuffer (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer); 233 void submitCommandsAndWait (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkQueue queue, const vk::VkCommandBuffer commandBuffer); 234 void beginRenderPass (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer, const vk::VkRenderPass renderPass, const vk::VkFramebuffer framebuffer, const vk::VkRect2D& renderArea, const tcu::Vec4& clearColor); 235 void beginRenderPassWithRasterizationDisabled (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer, const vk::VkRenderPass renderPass, const vk::VkFramebuffer framebuffer); 236 void endRenderPass (const vk::DeviceInterface& vk, const vk::VkCommandBuffer commandBuffer); 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