1 /*------------------------------------------------------------------------ 2 * Vulkan Conformance Tests 3 * ------------------------ 4 * 5 * Copyright (c) 2016 The Khronos Group Inc. 6 * 7 * Licensed under the Apache License, Version 2.0 (the "License"); 8 * you may not use this file except in compliance with the License. 9 * You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, software 14 * distributed under the License is distributed on an "AS IS" BASIS, 15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 * See the License for the specific language governing permissions and 17 * limitations under the License. 18 * 19 *//*! 20 * \file 21 * \brief Object creation utilities 22 *//*--------------------------------------------------------------------*/ 23 24 #include "vktPipelineMakeUtil.hpp" 25 #include "vkTypeUtil.hpp" 26 #include "vkPrograms.hpp" 27 #include "vkRefUtil.hpp" 28 #include "vkQueryUtil.hpp" 29 #include <vector> 30 31 namespace vkt 32 { 33 namespace pipeline 34 { 35 using namespace vk; 36 using de::MovePtr; 37 38 Buffer::Buffer (const vk::DeviceInterface& vk, 39 const vk::VkDevice device, 40 vk::Allocator& allocator, 41 const vk::VkBufferCreateInfo& bufferCreateInfo, 42 const vk::MemoryRequirement memoryRequirement) 43 : m_buffer (createBuffer(vk, device, &bufferCreateInfo)) 44 , m_allocation (bindBuffer(vk, device, allocator, *m_buffer, memoryRequirement)) 45 { 46 } 47 48 Image::Image (const vk::DeviceInterface& vk, 49 const vk::VkDevice device, 50 vk::Allocator& allocator, 51 const vk::VkImageCreateInfo& imageCreateInfo, 52 const vk::MemoryRequirement memoryRequirement) 53 : m_image (createImage(vk, device, &imageCreateInfo)) 54 , m_allocation (bindImage(vk, device, allocator, *m_image, memoryRequirement)) 55 { 56 } 57 58 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize, 59 const VkBufferUsageFlags usage) 60 { 61 const VkBufferCreateInfo bufferCreateInfo = 62 { 63 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType; 64 DE_NULL, // const void* pNext; 65 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags; 66 bufferSize, // VkDeviceSize size; 67 usage, // VkBufferUsageFlags usage; 68 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode; 69 0u, // deUint32 queueFamilyIndexCount; 70 DE_NULL, // const deUint32* pQueueFamilyIndices; 71 }; 72 return bufferCreateInfo; 73 } 74 75 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask, 76 const VkAccessFlags dstAccessMask, 77 const VkBuffer buffer, 78 const VkDeviceSize offset, 79 const VkDeviceSize bufferSizeBytes) 80 { 81 const VkBufferMemoryBarrier barrier = 82 { 83 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType; 84 DE_NULL, // const void* pNext; 85 srcAccessMask, // VkAccessFlags srcAccessMask; 86 dstAccessMask, // VkAccessFlags dstAccessMask; 87 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 88 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 89 buffer, // VkBuffer buffer; 90 offset, // VkDeviceSize offset; 91 bufferSizeBytes, // VkDeviceSize size; 92 }; 93 return barrier; 94 } 95 96 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask, 97 const VkAccessFlags dstAccessMask, 98 const VkImageLayout oldLayout, 99 const VkImageLayout newLayout, 100 const VkImage image, 101 const VkImageSubresourceRange subresourceRange) 102 { 103 const VkImageMemoryBarrier barrier = 104 { 105 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType; 106 DE_NULL, // const void* pNext; 107 srcAccessMask, // VkAccessFlags outputMask; 108 dstAccessMask, // VkAccessFlags inputMask; 109 oldLayout, // VkImageLayout oldLayout; 110 newLayout, // VkImageLayout newLayout; 111 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex; 112 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex; 113 image, // VkImage image; 114 subresourceRange, // VkImageSubresourceRange subresourceRange; 115 }; 116 return barrier; 117 } 118 119 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool) 120 { 121 return allocateCommandBuffer(vk, device, commandPool, VK_COMMAND_BUFFER_LEVEL_PRIMARY); 122 } 123 124 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk, 125 const VkDevice device, 126 const VkDescriptorPool descriptorPool, 127 const VkDescriptorSetLayout setLayout) 128 { 129 const VkDescriptorSetAllocateInfo info = 130 { 131 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType; 132 DE_NULL, // const void* pNext; 133 descriptorPool, // VkDescriptorPool descriptorPool; 134 1u, // deUint32 descriptorSetCount; 135 &setLayout, // const VkDescriptorSetLayout* pSetLayouts; 136 }; 137 return allocateDescriptorSet(vk, device, &info); 138 } 139 140 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 141 const VkDevice device) 142 { 143 const VkPipelineLayoutCreateInfo info = 144 { 145 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 146 DE_NULL, // const void* pNext; 147 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 148 0u, // deUint32 setLayoutCount; 149 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts; 150 0u, // deUint32 pushConstantRangeCount; 151 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 152 }; 153 return createPipelineLayout(vk, device, &info); 154 } 155 156 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk, 157 const VkDevice device, 158 const VkDescriptorSetLayout descriptorSetLayout) 159 { 160 const VkPipelineLayoutCreateInfo info = 161 { 162 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType; 163 DE_NULL, // const void* pNext; 164 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags; 165 1u, // deUint32 setLayoutCount; 166 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts; 167 0u, // deUint32 pushConstantRangeCount; 168 DE_NULL, // const VkPushConstantRange* pPushConstantRanges; 169 }; 170 return createPipelineLayout(vk, device, &info); 171 } 172 173 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk, 174 const VkDevice device, 175 const VkPipelineLayout pipelineLayout, 176 const VkShaderModule shaderModule, 177 const VkSpecializationInfo* specInfo) 178 { 179 const VkPipelineShaderStageCreateInfo shaderStageInfo = 180 { 181 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType; 182 DE_NULL, // const void* pNext; 183 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags; 184 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage; 185 shaderModule, // VkShaderModule module; 186 "main", // const char* pName; 187 specInfo, // const VkSpecializationInfo* pSpecializationInfo; 188 }; 189 const VkComputePipelineCreateInfo pipelineInfo = 190 { 191 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType; 192 DE_NULL, // const void* pNext; 193 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags; 194 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage; 195 pipelineLayout, // VkPipelineLayout layout; 196 DE_NULL, // VkPipeline basePipelineHandle; 197 0, // deInt32 basePipelineIndex; 198 }; 199 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo); 200 } 201 202 Move<VkImageView> makeImageView (const DeviceInterface& vk, 203 const VkDevice vkDevice, 204 const VkImage image, 205 const VkImageViewType viewType, 206 const VkFormat format, 207 const VkImageSubresourceRange subresourceRange) 208 { 209 const VkImageViewCreateInfo imageViewParams = 210 { 211 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType; 212 DE_NULL, // const void* pNext; 213 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags; 214 image, // VkImage image; 215 viewType, // VkImageViewType viewType; 216 format, // VkFormat format; 217 makeComponentMappingRGBA(), // VkComponentMapping components; 218 subresourceRange, // VkImageSubresourceRange subresourceRange; 219 }; 220 return createImageView(vk, vkDevice, &imageViewParams); 221 } 222 223 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer) 224 { 225 const VkCommandBufferBeginInfo info = 226 { 227 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType; 228 DE_NULL, // const void* pNext; 229 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags; 230 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo; 231 }; 232 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info)); 233 } 234 235 void submitCommandsAndWait (const DeviceInterface& vk, 236 const VkDevice device, 237 const VkQueue queue, 238 const VkCommandBuffer commandBuffer) 239 { 240 const Unique<VkFence> fence(createFence(vk, device)); 241 242 const VkSubmitInfo submitInfo = 243 { 244 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType; 245 DE_NULL, // const void* pNext; 246 0u, // uint32_t waitSemaphoreCount; 247 DE_NULL, // const VkSemaphore* pWaitSemaphores; 248 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask; 249 1u, // uint32_t commandBufferCount; 250 &commandBuffer, // const VkCommandBuffer* pCommandBuffers; 251 0u, // uint32_t signalSemaphoreCount; 252 DE_NULL, // const VkSemaphore* pSignalSemaphores; 253 }; 254 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence)); 255 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull)); 256 } 257 258 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk, 259 const VkDevice device, 260 const VkRenderPass renderPass, 261 const deUint32 attachmentCount, 262 const VkImageView* pAttachments, 263 const deUint32 width, 264 const deUint32 height, 265 const deUint32 layers) 266 { 267 const VkFramebufferCreateInfo framebufferInfo = { 268 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType; 269 DE_NULL, // const void* pNext; 270 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags; 271 renderPass, // VkRenderPass renderPass; 272 attachmentCount, // uint32_t attachmentCount; 273 pAttachments, // const VkImageView* pAttachments; 274 width, // uint32_t width; 275 height, // uint32_t height; 276 layers, // uint32_t layers; 277 }; 278 279 return createFramebuffer(vk, device, &framebufferInfo); 280 } 281 282 MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement) 283 { 284 MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement); 285 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset())); 286 return alloc; 287 } 288 289 MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement) 290 { 291 MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement)); 292 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset())); 293 return alloc; 294 } 295 296 MovePtr<Allocation> bindImageDedicated (const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice physDevice, const VkDevice device, const VkImage image, const MemoryRequirement requirement) 297 { 298 MovePtr<Allocation> alloc(allocateDedicated(vki, vkd, physDevice, device, image, requirement)); 299 VK_CHECK(vkd.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset())); 300 return alloc; 301 } 302 303 MovePtr<Allocation> bindBufferDedicated (const InstanceInterface& vki, const DeviceInterface& vkd, const VkPhysicalDevice physDevice, const VkDevice device, const VkBuffer buffer, const MemoryRequirement requirement) 304 { 305 MovePtr<Allocation> alloc(allocateDedicated(vki, vkd, physDevice, device, buffer, requirement)); 306 VK_CHECK(vkd.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset())); 307 return alloc; 308 } 309 310 } // pipeline 311 } // vkt 312