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
Buffer(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkBufferCreateInfo & bufferCreateInfo,const vk::MemoryRequirement memoryRequirement)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
Image(const vk::DeviceInterface & vk,const vk::VkDevice device,vk::Allocator & allocator,const vk::VkImageCreateInfo & imageCreateInfo,const vk::MemoryRequirement memoryRequirement)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
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)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
makeBufferMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkBuffer buffer,const VkDeviceSize offset,const VkDeviceSize bufferSizeBytes)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
makeImageMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange subresourceRange)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
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)119 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
120 {
121 const VkCommandPoolCreateInfo info =
122 {
123 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
124 DE_NULL, // const void* pNext;
125 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags;
126 queueFamilyIndex, // deUint32 queueFamilyIndex;
127 };
128 return createCommandPool(vk, device, &info);
129 }
130
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)131 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
132 {
133 const VkCommandBufferAllocateInfo info =
134 {
135 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
136 DE_NULL, // const void* pNext;
137 commandPool, // VkCommandPool commandPool;
138 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
139 1u, // deUint32 commandBufferCount;
140 };
141 return allocateCommandBuffer(vk, device, &info);
142 }
143
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)144 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk,
145 const VkDevice device,
146 const VkDescriptorPool descriptorPool,
147 const VkDescriptorSetLayout setLayout)
148 {
149 const VkDescriptorSetAllocateInfo info =
150 {
151 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
152 DE_NULL, // const void* pNext;
153 descriptorPool, // VkDescriptorPool descriptorPool;
154 1u, // deUint32 descriptorSetCount;
155 &setLayout, // const VkDescriptorSetLayout* pSetLayouts;
156 };
157 return allocateDescriptorSet(vk, device, &info);
158 }
159
makePipelineLayout(const DeviceInterface & vk,const VkDevice device)160 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
161 const VkDevice device)
162 {
163 const VkPipelineLayoutCreateInfo info =
164 {
165 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
166 DE_NULL, // const void* pNext;
167 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
168 0u, // deUint32 setLayoutCount;
169 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
170 0u, // deUint32 pushConstantRangeCount;
171 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
172 };
173 return createPipelineLayout(vk, device, &info);
174 }
175
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)176 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
177 const VkDevice device,
178 const VkDescriptorSetLayout descriptorSetLayout)
179 {
180 const VkPipelineLayoutCreateInfo info =
181 {
182 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
183 DE_NULL, // const void* pNext;
184 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
185 1u, // deUint32 setLayoutCount;
186 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
187 0u, // deUint32 pushConstantRangeCount;
188 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
189 };
190 return createPipelineLayout(vk, device, &info);
191 }
192
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specInfo)193 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
194 const VkDevice device,
195 const VkPipelineLayout pipelineLayout,
196 const VkShaderModule shaderModule,
197 const VkSpecializationInfo* specInfo)
198 {
199 const VkPipelineShaderStageCreateInfo shaderStageInfo =
200 {
201 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
202 DE_NULL, // const void* pNext;
203 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
204 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
205 shaderModule, // VkShaderModule module;
206 "main", // const char* pName;
207 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
208 };
209 const VkComputePipelineCreateInfo pipelineInfo =
210 {
211 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
212 DE_NULL, // const void* pNext;
213 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
214 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
215 pipelineLayout, // VkPipelineLayout layout;
216 DE_NULL, // VkPipeline basePipelineHandle;
217 0, // deInt32 basePipelineIndex;
218 };
219 return createComputePipeline(vk, device, DE_NULL , &pipelineInfo);
220 }
221
makeImageView(const DeviceInterface & vk,const VkDevice vkDevice,const VkImage image,const VkImageViewType viewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)222 Move<VkImageView> makeImageView (const DeviceInterface& vk,
223 const VkDevice vkDevice,
224 const VkImage image,
225 const VkImageViewType viewType,
226 const VkFormat format,
227 const VkImageSubresourceRange subresourceRange)
228 {
229 const VkImageViewCreateInfo imageViewParams =
230 {
231 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
232 DE_NULL, // const void* pNext;
233 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
234 image, // VkImage image;
235 viewType, // VkImageViewType viewType;
236 format, // VkFormat format;
237 makeComponentMappingRGBA(), // VkComponentMapping components;
238 subresourceRange, // VkImageSubresourceRange subresourceRange;
239 };
240 return createImageView(vk, vkDevice, &imageViewParams);
241 }
242
beginCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)243 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
244 {
245 const VkCommandBufferBeginInfo info =
246 {
247 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
248 DE_NULL, // const void* pNext;
249 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
250 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
251 };
252 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
253 }
254
submitCommandsAndWait(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer commandBuffer)255 void submitCommandsAndWait (const DeviceInterface& vk,
256 const VkDevice device,
257 const VkQueue queue,
258 const VkCommandBuffer commandBuffer)
259 {
260 const VkFenceCreateInfo fenceInfo =
261 {
262 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
263 DE_NULL, // const void* pNext;
264 (VkFenceCreateFlags)0, // VkFenceCreateFlags flags;
265 };
266 const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
267
268 const VkSubmitInfo submitInfo =
269 {
270 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
271 DE_NULL, // const void* pNext;
272 0u, // uint32_t waitSemaphoreCount;
273 DE_NULL, // const VkSemaphore* pWaitSemaphores;
274 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
275 1u, // uint32_t commandBufferCount;
276 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
277 0u, // uint32_t signalSemaphoreCount;
278 DE_NULL, // const VkSemaphore* pSignalSemaphores;
279 };
280 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
281 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
282 }
283
makeFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkRenderPass renderPass,const deUint32 attachmentCount,const VkImageView * pAttachments,const deUint32 width,const deUint32 height,const deUint32 layers)284 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
285 const VkDevice device,
286 const VkRenderPass renderPass,
287 const deUint32 attachmentCount,
288 const VkImageView* pAttachments,
289 const deUint32 width,
290 const deUint32 height,
291 const deUint32 layers)
292 {
293 const VkFramebufferCreateInfo framebufferInfo = {
294 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
295 DE_NULL, // const void* pNext;
296 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
297 renderPass, // VkRenderPass renderPass;
298 attachmentCount, // uint32_t attachmentCount;
299 pAttachments, // const VkImageView* pAttachments;
300 width, // uint32_t width;
301 height, // uint32_t height;
302 layers, // uint32_t layers;
303 };
304
305 return createFramebuffer(vk, device, &framebufferInfo);
306 }
307
bindImage(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkImage image,const MemoryRequirement requirement)308 MovePtr<Allocation> bindImage (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkImage image, const MemoryRequirement requirement)
309 {
310 MovePtr<Allocation> alloc = allocator.allocate(getImageMemoryRequirements(vk, device, image), requirement);
311 VK_CHECK(vk.bindImageMemory(device, image, alloc->getMemory(), alloc->getOffset()));
312 return alloc;
313 }
314
bindBuffer(const DeviceInterface & vk,const VkDevice device,Allocator & allocator,const VkBuffer buffer,const MemoryRequirement requirement)315 MovePtr<Allocation> bindBuffer (const DeviceInterface& vk, const VkDevice device, Allocator& allocator, const VkBuffer buffer, const MemoryRequirement requirement)
316 {
317 MovePtr<Allocation> alloc(allocator.allocate(getBufferMemoryRequirements(vk, device, buffer), requirement));
318 VK_CHECK(vk.bindBufferMemory(device, buffer, alloc->getMemory(), alloc->getOffset()));
319 return alloc;
320 }
321
322 } // pipeline
323 } // vkt
324