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 Synchronization tests utilities
22 *//*--------------------------------------------------------------------*/
23
24 #include "vktSynchronizationUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include "deStringUtil.hpp"
27
28 namespace vkt
29 {
30 namespace synchronization
31 {
32 using namespace vk;
33
makeBufferCreateInfo(const VkDeviceSize bufferSize,const VkBufferUsageFlags usage)34 VkBufferCreateInfo makeBufferCreateInfo (const VkDeviceSize bufferSize,
35 const VkBufferUsageFlags usage)
36 {
37 const VkBufferCreateInfo bufferCreateInfo =
38 {
39 VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO, // VkStructureType sType;
40 DE_NULL, // const void* pNext;
41 (VkBufferCreateFlags)0, // VkBufferCreateFlags flags;
42 bufferSize, // VkDeviceSize size;
43 usage, // VkBufferUsageFlags usage;
44 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
45 0u, // deUint32 queueFamilyIndexCount;
46 DE_NULL, // const deUint32* pQueueFamilyIndices;
47 };
48 return bufferCreateInfo;
49 }
50
makeMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask)51 VkMemoryBarrier makeMemoryBarrier (const VkAccessFlags srcAccessMask,
52 const VkAccessFlags dstAccessMask)
53 {
54 const VkMemoryBarrier barrier =
55 {
56 VK_STRUCTURE_TYPE_MEMORY_BARRIER, // VkStructureType sType;
57 DE_NULL, // const void* pNext;
58 srcAccessMask, // VkAccessFlags srcAccessMask;
59 dstAccessMask, // VkAccessFlags dstAccessMask;
60 };
61 return barrier;
62 }
63
makeBufferMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkBuffer buffer,const VkDeviceSize offset,const VkDeviceSize bufferSizeBytes)64 VkBufferMemoryBarrier makeBufferMemoryBarrier (const VkAccessFlags srcAccessMask,
65 const VkAccessFlags dstAccessMask,
66 const VkBuffer buffer,
67 const VkDeviceSize offset,
68 const VkDeviceSize bufferSizeBytes)
69 {
70 const VkBufferMemoryBarrier barrier =
71 {
72 VK_STRUCTURE_TYPE_BUFFER_MEMORY_BARRIER, // VkStructureType sType;
73 DE_NULL, // const void* pNext;
74 srcAccessMask, // VkAccessFlags srcAccessMask;
75 dstAccessMask, // VkAccessFlags dstAccessMask;
76 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
77 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
78 buffer, // VkBuffer buffer;
79 offset, // VkDeviceSize offset;
80 bufferSizeBytes, // VkDeviceSize size;
81 };
82 return barrier;
83 }
84
makeImageMemoryBarrier(const VkAccessFlags srcAccessMask,const VkAccessFlags dstAccessMask,const VkImageLayout oldLayout,const VkImageLayout newLayout,const VkImage image,const VkImageSubresourceRange subresourceRange)85 VkImageMemoryBarrier makeImageMemoryBarrier (const VkAccessFlags srcAccessMask,
86 const VkAccessFlags dstAccessMask,
87 const VkImageLayout oldLayout,
88 const VkImageLayout newLayout,
89 const VkImage image,
90 const VkImageSubresourceRange subresourceRange)
91 {
92 const VkImageMemoryBarrier barrier =
93 {
94 VK_STRUCTURE_TYPE_IMAGE_MEMORY_BARRIER, // VkStructureType sType;
95 DE_NULL, // const void* pNext;
96 srcAccessMask, // VkAccessFlags outputMask;
97 dstAccessMask, // VkAccessFlags inputMask;
98 oldLayout, // VkImageLayout oldLayout;
99 newLayout, // VkImageLayout newLayout;
100 VK_QUEUE_FAMILY_IGNORED, // deUint32 srcQueueFamilyIndex;
101 VK_QUEUE_FAMILY_IGNORED, // deUint32 destQueueFamilyIndex;
102 image, // VkImage image;
103 subresourceRange, // VkImageSubresourceRange subresourceRange;
104 };
105 return barrier;
106 }
107
makeCommandPool(const DeviceInterface & vk,const VkDevice device,const deUint32 queueFamilyIndex)108 Move<VkCommandPool> makeCommandPool (const DeviceInterface& vk, const VkDevice device, const deUint32 queueFamilyIndex)
109 {
110 const VkCommandPoolCreateInfo info =
111 {
112 VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO, // VkStructureType sType;
113 DE_NULL, // const void* pNext;
114 VK_COMMAND_POOL_CREATE_RESET_COMMAND_BUFFER_BIT, // VkCommandPoolCreateFlags flags;
115 queueFamilyIndex, // deUint32 queueFamilyIndex;
116 };
117 return createCommandPool(vk, device, &info);
118 }
119
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)120 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
121 {
122 const VkCommandBufferAllocateInfo info =
123 {
124 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
125 DE_NULL, // const void* pNext;
126 commandPool, // VkCommandPool commandPool;
127 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
128 1u, // deUint32 commandBufferCount;
129 };
130 return allocateCommandBuffer(vk, device, &info);
131 }
132
makeDescriptorSet(const DeviceInterface & vk,const VkDevice device,const VkDescriptorPool descriptorPool,const VkDescriptorSetLayout setLayout)133 Move<VkDescriptorSet> makeDescriptorSet (const DeviceInterface& vk,
134 const VkDevice device,
135 const VkDescriptorPool descriptorPool,
136 const VkDescriptorSetLayout setLayout)
137 {
138 const VkDescriptorSetAllocateInfo info =
139 {
140 VK_STRUCTURE_TYPE_DESCRIPTOR_SET_ALLOCATE_INFO, // VkStructureType sType;
141 DE_NULL, // const void* pNext;
142 descriptorPool, // VkDescriptorPool descriptorPool;
143 1u, // deUint32 descriptorSetCount;
144 &setLayout, // const VkDescriptorSetLayout* pSetLayouts;
145 };
146 return allocateDescriptorSet(vk, device, &info);
147 }
148
makePipelineLayout(const DeviceInterface & vk,const VkDevice device,const VkDescriptorSetLayout descriptorSetLayout)149 Move<VkPipelineLayout> makePipelineLayout (const DeviceInterface& vk,
150 const VkDevice device,
151 const VkDescriptorSetLayout descriptorSetLayout)
152 {
153 const VkPipelineLayoutCreateInfo info =
154 {
155 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
156 DE_NULL, // const void* pNext;
157 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
158 1u, // deUint32 setLayoutCount;
159 &descriptorSetLayout, // const VkDescriptorSetLayout* pSetLayouts;
160 0u, // deUint32 pushConstantRangeCount;
161 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
162 };
163 return createPipelineLayout(vk, device, &info);
164 }
165
makePipelineLayoutWithoutDescriptors(const DeviceInterface & vk,const VkDevice device)166 Move<VkPipelineLayout> makePipelineLayoutWithoutDescriptors (const DeviceInterface& vk,
167 const VkDevice device)
168 {
169 const VkPipelineLayoutCreateInfo info =
170 {
171 VK_STRUCTURE_TYPE_PIPELINE_LAYOUT_CREATE_INFO, // VkStructureType sType;
172 DE_NULL, // const void* pNext;
173 (VkPipelineLayoutCreateFlags)0, // VkPipelineLayoutCreateFlags flags;
174 0u, // deUint32 setLayoutCount;
175 DE_NULL, // const VkDescriptorSetLayout* pSetLayouts;
176 0u, // deUint32 pushConstantRangeCount;
177 DE_NULL, // const VkPushConstantRange* pPushConstantRanges;
178 };
179 return createPipelineLayout(vk, device, &info);
180 }
181
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specInfo,PipelineCacheData & pipelineCacheData)182 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
183 const VkDevice device,
184 const VkPipelineLayout pipelineLayout,
185 const VkShaderModule shaderModule,
186 const VkSpecializationInfo* specInfo,
187 PipelineCacheData& pipelineCacheData)
188 {
189 const VkPipelineShaderStageCreateInfo shaderStageInfo =
190 {
191 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
192 DE_NULL, // const void* pNext;
193 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
194 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
195 shaderModule, // VkShaderModule module;
196 "main", // const char* pName;
197 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
198 };
199 const VkComputePipelineCreateInfo pipelineInfo =
200 {
201 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
202 DE_NULL, // const void* pNext;
203 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
204 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
205 pipelineLayout, // VkPipelineLayout layout;
206 DE_NULL, // VkPipeline basePipelineHandle;
207 0, // deInt32 basePipelineIndex;
208 };
209
210 {
211 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
212 vk::Move<vk::VkPipeline> pipeline (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
213
214 // Refresh data from cache
215 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
216
217 return pipeline;
218 }
219 }
220
makeImageCreateInfo(const VkImageType imageType,const VkExtent3D & extent,const VkFormat format,const VkImageUsageFlags usage)221 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
222 {
223 const VkImageCreateInfo imageInfo =
224 {
225 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
226 DE_NULL, // const void* pNext;
227 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
228 imageType, // VkImageType imageType;
229 format, // VkFormat format;
230 extent, // VkExtent3D extent;
231 1u, // uint32_t mipLevels;
232 1u, // uint32_t arrayLayers;
233 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
234 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
235 usage, // VkImageUsageFlags usage;
236 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
237 0u, // uint32_t queueFamilyIndexCount;
238 DE_NULL, // const uint32_t* pQueueFamilyIndices;
239 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
240 };
241 return imageInfo;
242 }
243
makeImageView(const DeviceInterface & vk,const VkDevice device,const VkImage image,const VkImageViewType viewType,const VkFormat format,const VkImageSubresourceRange subresourceRange)244 Move<VkImageView> makeImageView (const DeviceInterface& vk,
245 const VkDevice device,
246 const VkImage image,
247 const VkImageViewType viewType,
248 const VkFormat format,
249 const VkImageSubresourceRange subresourceRange)
250 {
251 const VkImageViewCreateInfo imageViewParams =
252 {
253 VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO, // VkStructureType sType;
254 DE_NULL, // const void* pNext;
255 (VkImageViewCreateFlags)0, // VkImageViewCreateFlags flags;
256 image, // VkImage image;
257 viewType, // VkImageViewType viewType;
258 format, // VkFormat format;
259 makeComponentMappingRGBA(), // VkComponentMapping components;
260 subresourceRange, // VkImageSubresourceRange subresourceRange;
261 };
262 return createImageView(vk, device, &imageViewParams);
263 }
264
makeBufferImageCopy(const VkImageSubresourceLayers subresourceLayers,const VkExtent3D extent)265 VkBufferImageCopy makeBufferImageCopy (const VkImageSubresourceLayers subresourceLayers,
266 const VkExtent3D extent)
267 {
268 const VkBufferImageCopy copyParams =
269 {
270 0ull, // VkDeviceSize bufferOffset;
271 0u, // deUint32 bufferRowLength;
272 0u, // deUint32 bufferImageHeight;
273 subresourceLayers, // VkImageSubresourceLayers imageSubresource;
274 makeOffset3D(0, 0, 0), // VkOffset3D imageOffset;
275 extent, // VkExtent3D imageExtent;
276 };
277 return copyParams;
278 }
279
makeEvent(const DeviceInterface & vk,const VkDevice device)280 Move<VkEvent> makeEvent (const DeviceInterface& vk, const VkDevice device)
281 {
282 const VkEventCreateInfo eventParams =
283 {
284 VK_STRUCTURE_TYPE_EVENT_CREATE_INFO, // VkStructureType sType;
285 DE_NULL, // const void* pNext;
286 (VkEventCreateFlags)0, // VkEventCreateFlags flags;
287 };
288 return createEvent(vk, device, &eventParams);
289 }
290
beginCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)291 void beginCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
292 {
293 const VkCommandBufferBeginInfo info =
294 {
295 VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO, // VkStructureType sType;
296 DE_NULL, // const void* pNext;
297 VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT, // VkCommandBufferUsageFlags flags;
298 DE_NULL, // const VkCommandBufferInheritanceInfo* pInheritanceInfo;
299 };
300 VK_CHECK(vk.beginCommandBuffer(commandBuffer, &info));
301 }
302
endCommandBuffer(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)303 void endCommandBuffer (const DeviceInterface& vk, const VkCommandBuffer commandBuffer)
304 {
305 VK_CHECK(vk.endCommandBuffer(commandBuffer));
306 }
307
submitCommandsAndWait(const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer commandBuffer)308 void submitCommandsAndWait (const DeviceInterface& vk,
309 const VkDevice device,
310 const VkQueue queue,
311 const VkCommandBuffer commandBuffer)
312 {
313 const VkFenceCreateInfo fenceInfo =
314 {
315 VK_STRUCTURE_TYPE_FENCE_CREATE_INFO, // VkStructureType sType;
316 DE_NULL, // const void* pNext;
317 (VkFenceCreateFlags)0, // VkFenceCreateFlags flags;
318 };
319 const Unique<VkFence> fence(createFence(vk, device, &fenceInfo));
320
321 const VkSubmitInfo submitInfo =
322 {
323 VK_STRUCTURE_TYPE_SUBMIT_INFO, // VkStructureType sType;
324 DE_NULL, // const void* pNext;
325 0u, // uint32_t waitSemaphoreCount;
326 DE_NULL, // const VkSemaphore* pWaitSemaphores;
327 DE_NULL, // const VkPipelineStageFlags* pWaitDstStageMask;
328 1u, // uint32_t commandBufferCount;
329 &commandBuffer, // const VkCommandBuffer* pCommandBuffers;
330 0u, // uint32_t signalSemaphoreCount;
331 DE_NULL, // const VkSemaphore* pSignalSemaphores;
332 };
333 VK_CHECK(vk.queueSubmit(queue, 1u, &submitInfo, *fence));
334 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
335 }
336
beginRenderPass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer,const VkRect2D & renderArea,const tcu::Vec4 & clearColor)337 void beginRenderPass (const DeviceInterface& vk,
338 const VkCommandBuffer commandBuffer,
339 const VkRenderPass renderPass,
340 const VkFramebuffer framebuffer,
341 const VkRect2D& renderArea,
342 const tcu::Vec4& clearColor)
343 {
344 const VkClearValue clearValue = makeClearValueColor(clearColor);
345
346 const VkRenderPassBeginInfo renderPassBeginInfo = {
347 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
348 DE_NULL, // const void* pNext;
349 renderPass, // VkRenderPass renderPass;
350 framebuffer, // VkFramebuffer framebuffer;
351 renderArea, // VkRect2D renderArea;
352 1u, // uint32_t clearValueCount;
353 &clearValue, // const VkClearValue* pClearValues;
354 };
355
356 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
357 }
358
beginRenderPassWithRasterizationDisabled(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer)359 void beginRenderPassWithRasterizationDisabled (const DeviceInterface& vk,
360 const VkCommandBuffer commandBuffer,
361 const VkRenderPass renderPass,
362 const VkFramebuffer framebuffer)
363 {
364 const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
365
366 const VkRenderPassBeginInfo renderPassBeginInfo = {
367 VK_STRUCTURE_TYPE_RENDER_PASS_BEGIN_INFO, // VkStructureType sType;
368 DE_NULL, // const void* pNext;
369 renderPass, // VkRenderPass renderPass;
370 framebuffer, // VkFramebuffer framebuffer;
371 renderArea, // VkRect2D renderArea;
372 0u, // uint32_t clearValueCount;
373 DE_NULL, // const VkClearValue* pClearValues;
374 };
375
376 vk.cmdBeginRenderPass(commandBuffer, &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE);
377 }
378
endRenderPass(const DeviceInterface & vk,const VkCommandBuffer commandBuffer)379 void endRenderPass (const DeviceInterface& vk,
380 const VkCommandBuffer commandBuffer)
381 {
382 vk.cmdEndRenderPass(commandBuffer);
383 }
384
makeRenderPass(const DeviceInterface & vk,const VkDevice device,const VkFormat colorFormat)385 Move<VkRenderPass> makeRenderPass (const DeviceInterface& vk,
386 const VkDevice device,
387 const VkFormat colorFormat)
388 {
389 const VkAttachmentDescription colorAttachmentDescription =
390 {
391 (VkAttachmentDescriptionFlags)0, // VkAttachmentDescriptionFlags flags;
392 colorFormat, // VkFormat format;
393 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
394 VK_ATTACHMENT_LOAD_OP_CLEAR, // VkAttachmentLoadOp loadOp;
395 VK_ATTACHMENT_STORE_OP_STORE, // VkAttachmentStoreOp storeOp;
396 VK_ATTACHMENT_LOAD_OP_DONT_CARE, // VkAttachmentLoadOp stencilLoadOp;
397 VK_ATTACHMENT_STORE_OP_DONT_CARE, // VkAttachmentStoreOp stencilStoreOp;
398 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL, // VkImageLayout initialLayout;
399 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout finalLayout;
400 };
401
402 const VkAttachmentReference colorAttachmentReference =
403 {
404 0u, // deUint32 attachment;
405 VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL // VkImageLayout layout;
406 };
407
408 const VkAttachmentReference depthAttachmentReference =
409 {
410 VK_ATTACHMENT_UNUSED, // deUint32 attachment;
411 VK_IMAGE_LAYOUT_UNDEFINED // VkImageLayout layout;
412 };
413
414 const VkSubpassDescription subpassDescription =
415 {
416 (VkSubpassDescriptionFlags)0, // VkSubpassDescriptionFlags flags;
417 VK_PIPELINE_BIND_POINT_GRAPHICS, // VkPipelineBindPoint pipelineBindPoint;
418 0u, // deUint32 inputAttachmentCount;
419 DE_NULL, // const VkAttachmentReference* pInputAttachments;
420 1u, // deUint32 colorAttachmentCount;
421 &colorAttachmentReference, // const VkAttachmentReference* pColorAttachments;
422 DE_NULL, // const VkAttachmentReference* pResolveAttachments;
423 &depthAttachmentReference, // const VkAttachmentReference* pDepthStencilAttachment;
424 0u, // deUint32 preserveAttachmentCount;
425 DE_NULL // const deUint32* pPreserveAttachments;
426 };
427
428 const VkRenderPassCreateInfo renderPassInfo =
429 {
430 VK_STRUCTURE_TYPE_RENDER_PASS_CREATE_INFO, // VkStructureType sType;
431 DE_NULL, // const void* pNext;
432 (VkRenderPassCreateFlags)0, // VkRenderPassCreateFlags flags;
433 1u, // deUint32 attachmentCount;
434 &colorAttachmentDescription, // const VkAttachmentDescription* pAttachments;
435 1u, // deUint32 subpassCount;
436 &subpassDescription, // const VkSubpassDescription* pSubpasses;
437 0u, // deUint32 dependencyCount;
438 DE_NULL // const VkSubpassDependency* pDependencies;
439 };
440
441 return createRenderPass(vk, device, &renderPassInfo);
442 }
443
makeFramebuffer(const DeviceInterface & vk,const VkDevice device,const VkRenderPass renderPass,const VkImageView colorAttachment,const deUint32 width,const deUint32 height,const deUint32 layers)444 Move<VkFramebuffer> makeFramebuffer (const DeviceInterface& vk,
445 const VkDevice device,
446 const VkRenderPass renderPass,
447 const VkImageView colorAttachment,
448 const deUint32 width,
449 const deUint32 height,
450 const deUint32 layers)
451 {
452 const VkFramebufferCreateInfo framebufferInfo = {
453 VK_STRUCTURE_TYPE_FRAMEBUFFER_CREATE_INFO, // VkStructureType sType;
454 DE_NULL, // const void* pNext;
455 (VkFramebufferCreateFlags)0, // VkFramebufferCreateFlags flags;
456 renderPass, // VkRenderPass renderPass;
457 1u, // uint32_t attachmentCount;
458 &colorAttachment, // const VkImageView* pAttachments;
459 width, // uint32_t width;
460 height, // uint32_t height;
461 layers, // uint32_t layers;
462 };
463
464 return createFramebuffer(vk, device, &framebufferInfo);
465 }
466
setShader(const DeviceInterface & vk,const VkDevice device,const VkShaderStageFlagBits stage,const ProgramBinary & binary,const VkSpecializationInfo * specInfo)467 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk,
468 const VkDevice device,
469 const VkShaderStageFlagBits stage,
470 const ProgramBinary& binary,
471 const VkSpecializationInfo* specInfo)
472 {
473 VkShaderModule module;
474 switch (stage)
475 {
476 case (VK_SHADER_STAGE_VERTEX_BIT):
477 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
478 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
479 module = *m_vertexShaderModule;
480 break;
481
482 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
483 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
484 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
485 module = *m_tessControlShaderModule;
486 break;
487
488 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
489 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
490 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
491 module = *m_tessEvaluationShaderModule;
492 break;
493
494 case (VK_SHADER_STAGE_GEOMETRY_BIT):
495 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
496 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
497 module = *m_geometryShaderModule;
498 break;
499
500 case (VK_SHADER_STAGE_FRAGMENT_BIT):
501 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
502 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
503 module = *m_fragmentShaderModule;
504 break;
505
506 default:
507 DE_FATAL("Invalid shader stage");
508 return *this;
509 }
510
511 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
512 {
513 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
514 DE_NULL, // const void* pNext;
515 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
516 stage, // VkShaderStageFlagBits stage;
517 module, // VkShaderModule module;
518 "main", // const char* pName;
519 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
520 };
521
522 m_shaderStageFlags |= stage;
523 m_shaderStages.push_back(pipelineShaderStageInfo);
524
525 return *this;
526 }
527
setVertexInputSingleAttribute(const VkFormat vertexFormat,const deUint32 stride)528 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
529 {
530 const VkVertexInputBindingDescription bindingDesc =
531 {
532 0u, // uint32_t binding;
533 stride, // uint32_t stride;
534 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
535 };
536 const VkVertexInputAttributeDescription attributeDesc =
537 {
538 0u, // uint32_t location;
539 0u, // uint32_t binding;
540 vertexFormat, // VkFormat format;
541 0u, // uint32_t offset;
542 };
543
544 m_vertexInputBindings.clear();
545 m_vertexInputBindings.push_back(bindingDesc);
546
547 m_vertexInputAttributes.clear();
548 m_vertexInputAttributes.push_back(attributeDesc);
549
550 return *this;
551 }
552
553 template<typename T>
dataPointer(const std::vector<T> & vec)554 inline const T* dataPointer (const std::vector<T>& vec)
555 {
556 return (vec.size() != 0 ? &vec[0] : DE_NULL);
557 }
558
build(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,PipelineCacheData & pipelineCacheData)559 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
560 const VkDevice device,
561 const VkPipelineLayout pipelineLayout,
562 const VkRenderPass renderPass,
563 PipelineCacheData& pipelineCacheData)
564 {
565 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
566 {
567 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
568 DE_NULL, // const void* pNext;
569 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
570 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount;
571 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
572 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount;
573 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
574 };
575
576 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
577 : m_primitiveTopology;
578 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
579 {
580 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
581 DE_NULL, // const void* pNext;
582 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
583 topology, // VkPrimitiveTopology topology;
584 VK_FALSE, // VkBool32 primitiveRestartEnable;
585 };
586
587 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
588 {
589 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
590 DE_NULL, // const void* pNext;
591 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
592 m_patchControlPoints, // uint32_t patchControlPoints;
593 };
594
595 const VkViewport viewport = makeViewport(
596 0.0f, 0.0f,
597 static_cast<float>(m_renderSize.x()), static_cast<float>(m_renderSize.y()),
598 0.0f, 1.0f);
599
600 const VkRect2D scissor = {
601 makeOffset2D(0, 0),
602 makeExtent2D(m_renderSize.x(), m_renderSize.y()),
603 };
604
605 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
606 {
607 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
608 DE_NULL, // const void* pNext;
609 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
610 1u, // uint32_t viewportCount;
611 &viewport, // const VkViewport* pViewports;
612 1u, // uint32_t scissorCount;
613 &scissor, // const VkRect2D* pScissors;
614 };
615
616 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
617 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
618 {
619 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
620 DE_NULL, // const void* pNext;
621 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
622 VK_FALSE, // VkBool32 depthClampEnable;
623 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable;
624 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
625 m_cullModeFlags, // VkCullModeFlags cullMode;
626 m_frontFace, // VkFrontFace frontFace;
627 VK_FALSE, // VkBool32 depthBiasEnable;
628 0.0f, // float depthBiasConstantFactor;
629 0.0f, // float depthBiasClamp;
630 0.0f, // float depthBiasSlopeFactor;
631 1.0f, // float lineWidth;
632 };
633
634 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
635 {
636 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
637 DE_NULL, // const void* pNext;
638 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
639 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
640 VK_FALSE, // VkBool32 sampleShadingEnable;
641 0.0f, // float minSampleShading;
642 DE_NULL, // const VkSampleMask* pSampleMask;
643 VK_FALSE, // VkBool32 alphaToCoverageEnable;
644 VK_FALSE // VkBool32 alphaToOneEnable;
645 };
646
647 const VkStencilOpState stencilOpState = makeStencilOpState(
648 VK_STENCIL_OP_KEEP, // stencil fail
649 VK_STENCIL_OP_KEEP, // depth & stencil pass
650 VK_STENCIL_OP_KEEP, // depth only fail
651 VK_COMPARE_OP_NEVER, // compare op
652 0u, // compare mask
653 0u, // write mask
654 0u); // reference
655
656 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
657 {
658 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
659 DE_NULL, // const void* pNext;
660 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
661 VK_FALSE, // VkBool32 depthTestEnable;
662 VK_FALSE, // VkBool32 depthWriteEnable;
663 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
664 VK_FALSE, // VkBool32 depthBoundsTestEnable;
665 VK_FALSE, // VkBool32 stencilTestEnable;
666 stencilOpState, // VkStencilOpState front;
667 stencilOpState, // VkStencilOpState back;
668 0.0f, // float minDepthBounds;
669 1.0f, // float maxDepthBounds;
670 };
671
672 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
673 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
674 {
675 m_blendEnable, // VkBool32 blendEnable;
676 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
677 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
678 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
679 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
680 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
681 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
682 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
683 };
684
685 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
686 {
687 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
688 DE_NULL, // const void* pNext;
689 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
690 VK_FALSE, // VkBool32 logicOpEnable;
691 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
692 1u, // deUint32 attachmentCount;
693 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
694 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
695 };
696
697 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
698 {
699 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
700 DE_NULL, // const void* pNext;
701 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
702 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount;
703 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
704 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
705 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
706 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
707 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState;
708 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
709 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
710 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
711 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
712 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
713 pipelineLayout, // VkPipelineLayout layout;
714 renderPass, // VkRenderPass renderPass;
715 0u, // deUint32 subpass;
716 DE_NULL, // VkPipeline basePipelineHandle;
717 0, // deInt32 basePipelineIndex;
718 };
719
720 {
721 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
722 vk::Move<vk::VkPipeline> pipeline (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
723
724 // Refresh data from cache
725 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
726
727 return pipeline;
728 }
729 }
730
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)731 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
732 {
733 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
734
735 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
736 throw tcu::NotSupportedError("Tessellation shader not supported");
737
738 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
739 throw tcu::NotSupportedError("Geometry shader not supported");
740
741 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
742 throw tcu::NotSupportedError("Double-precision floats not supported");
743
744 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
745 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
746
747 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
748 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
749
750 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
751 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
752
753 if (((flags & FEATURE_SHADER_STORAGE_IMAGE_EXTENDED_FORMATS) != 0) && !features.shaderStorageImageExtendedFormats)
754 throw tcu::NotSupportedError("Storage image extended formats not supported");
755 }
756
getResourceName(const ResourceDescription & resource)757 std::string getResourceName (const ResourceDescription& resource)
758 {
759 std::ostringstream str;
760
761 if (resource.type == RESOURCE_TYPE_BUFFER)
762 str << "buffer_" << resource.size.x();
763 else if (resource.type == RESOURCE_TYPE_IMAGE)
764 {
765 str << "image_" << resource.size.x()
766 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
767 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
768 << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
769 }
770 else if (isIndirectBuffer(resource.type))
771 str << "indirect_buffer";
772 else
773 DE_ASSERT(0);
774
775 return str.str();
776 }
777
isIndirectBuffer(const ResourceType type)778 bool isIndirectBuffer (const ResourceType type)
779 {
780 switch (type)
781 {
782 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
783 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
784 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
785 return true;
786
787 default:
788 return false;
789 }
790 }
791
PipelineCacheData(void)792 PipelineCacheData::PipelineCacheData (void)
793 {
794 }
795
~PipelineCacheData(void)796 PipelineCacheData::~PipelineCacheData (void)
797 {
798 }
799
createPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device) const800 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
801 {
802 const de::ScopedLock dataLock (m_lock);
803 const struct vk::VkPipelineCacheCreateInfo params =
804 {
805 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
806 DE_NULL,
807 (vk::VkPipelineCacheCreateFlags)0,
808 (deUintptr)m_data.size(),
809 (m_data.empty() ? DE_NULL : &m_data[0])
810 };
811
812 return vk::createPipelineCache(vk, device, ¶ms);
813 }
814
setFromPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device,const vk::VkPipelineCache pipelineCache)815 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
816 {
817 const de::ScopedLock dataLock (m_lock);
818 deUintptr dataSize = 0;
819
820 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
821
822 m_data.resize(dataSize);
823
824 if (dataSize > 0)
825 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));
826 }
827
828 } // synchronization
829 } // vkt
830