1 /*------------------------------------------------------------------------
2 * Vulkan Conformance Tests
3 * ------------------------
5 * Copyright (c) 2016 The Khronos Group Inc.
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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.
21 * \brief Synchronization tests utilities
22 *//*--------------------------------------------------------------------*/
24 #include "vktSynchronizationUtil.hpp"
25 #include "vkTypeUtil.hpp"
26 #include "vkCmdUtil.hpp"
27 #include "vkBarrierUtil.hpp"
28 #include "deStringUtil.hpp"
32 namespace synchronization
36 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
38 const VkCommandBufferAllocateInfo info =
40 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
41 DE_NULL, // const void* pNext;
42 commandPool, // VkCommandPool commandPool;
43 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
44 1u, // deUint32 commandBufferCount;
46 return allocateCommandBuffer(vk, device, &info);
49 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
50 const VkDevice device,
51 const VkPipelineLayout pipelineLayout,
52 const VkShaderModule shaderModule,
53 const VkSpecializationInfo* specInfo,
54 PipelineCacheData& pipelineCacheData)
56 const VkPipelineShaderStageCreateInfo shaderStageInfo =
58 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
59 DE_NULL, // const void* pNext;
60 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
61 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
62 shaderModule, // VkShaderModule module;
63 "main", // const char* pName;
64 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
66 const VkComputePipelineCreateInfo pipelineInfo =
68 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
69 DE_NULL, // const void* pNext;
70 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
71 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
72 pipelineLayout, // VkPipelineLayout layout;
73 DE_NULL, // VkPipeline basePipelineHandle;
74 0, // deInt32 basePipelineIndex;
78 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
79 vk::Move<vk::VkPipeline> pipeline (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
81 // Refresh data from cache
82 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
88 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType, const VkExtent3D& extent, const VkFormat format, const VkImageUsageFlags usage)
90 const VkImageCreateInfo imageInfo =
92 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
93 DE_NULL, // const void* pNext;
94 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
95 imageType, // VkImageType imageType;
96 format, // VkFormat format;
97 extent, // VkExtent3D extent;
98 1u, // uint32_t mipLevels;
99 1u, // uint32_t arrayLayers;
100 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits samples;
101 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
102 usage, // VkImageUsageFlags usage;
103 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
104 0u, // uint32_t queueFamilyIndexCount;
105 DE_NULL, // const uint32_t* pQueueFamilyIndices;
106 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
111 void beginRenderPassWithRasterizationDisabled (const DeviceInterface& vk,
112 const VkCommandBuffer commandBuffer,
113 const VkRenderPass renderPass,
114 const VkFramebuffer framebuffer)
116 const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
118 beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea);
121 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk,
122 const VkDevice device,
123 const VkShaderStageFlagBits stage,
124 const ProgramBinary& binary,
125 const VkSpecializationInfo* specInfo)
127 VkShaderModule module;
130 case (VK_SHADER_STAGE_VERTEX_BIT):
131 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
132 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
133 module = *m_vertexShaderModule;
136 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
137 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
138 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
139 module = *m_tessControlShaderModule;
142 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
143 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
144 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
145 module = *m_tessEvaluationShaderModule;
148 case (VK_SHADER_STAGE_GEOMETRY_BIT):
149 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
150 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
151 module = *m_geometryShaderModule;
154 case (VK_SHADER_STAGE_FRAGMENT_BIT):
155 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
156 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
157 module = *m_fragmentShaderModule;
161 DE_FATAL("Invalid shader stage");
165 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
167 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
168 DE_NULL, // const void* pNext;
169 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
170 stage, // VkShaderStageFlagBits stage;
171 module, // VkShaderModule module;
172 "main", // const char* pName;
173 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
176 m_shaderStageFlags |= stage;
177 m_shaderStages.push_back(pipelineShaderStageInfo);
182 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
184 const VkVertexInputBindingDescription bindingDesc =
186 0u, // uint32_t binding;
187 stride, // uint32_t stride;
188 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
190 const VkVertexInputAttributeDescription attributeDesc =
192 0u, // uint32_t location;
193 0u, // uint32_t binding;
194 vertexFormat, // VkFormat format;
195 0u, // uint32_t offset;
198 m_vertexInputBindings.clear();
199 m_vertexInputBindings.push_back(bindingDesc);
201 m_vertexInputAttributes.clear();
202 m_vertexInputAttributes.push_back(attributeDesc);
208 inline const T* dataPointer (const std::vector<T>& vec)
210 return (vec.size() != 0 ? &vec[0] : DE_NULL);
213 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
214 const VkDevice device,
215 const VkPipelineLayout pipelineLayout,
216 const VkRenderPass renderPass,
217 PipelineCacheData& pipelineCacheData)
219 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
221 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
222 DE_NULL, // const void* pNext;
223 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
224 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount;
225 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
226 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount;
227 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
230 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
231 : m_primitiveTopology;
232 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
234 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
235 DE_NULL, // const void* pNext;
236 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
237 topology, // VkPrimitiveTopology topology;
238 VK_FALSE, // VkBool32 primitiveRestartEnable;
241 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
243 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
244 DE_NULL, // const void* pNext;
245 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
246 m_patchControlPoints, // uint32_t patchControlPoints;
249 const VkViewport viewport = makeViewport(m_renderSize);
250 const VkRect2D scissor = makeRect2D(m_renderSize);
252 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
254 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
255 DE_NULL, // const void* pNext;
256 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
257 1u, // uint32_t viewportCount;
258 &viewport, // const VkViewport* pViewports;
259 1u, // uint32_t scissorCount;
260 &scissor, // const VkRect2D* pScissors;
263 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
264 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
266 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
267 DE_NULL, // const void* pNext;
268 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
269 VK_FALSE, // VkBool32 depthClampEnable;
270 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable;
271 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
272 m_cullModeFlags, // VkCullModeFlags cullMode;
273 m_frontFace, // VkFrontFace frontFace;
274 VK_FALSE, // VkBool32 depthBiasEnable;
275 0.0f, // float depthBiasConstantFactor;
276 0.0f, // float depthBiasClamp;
277 0.0f, // float depthBiasSlopeFactor;
278 1.0f, // float lineWidth;
281 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
283 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
284 DE_NULL, // const void* pNext;
285 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
286 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
287 VK_FALSE, // VkBool32 sampleShadingEnable;
288 0.0f, // float minSampleShading;
289 DE_NULL, // const VkSampleMask* pSampleMask;
290 VK_FALSE, // VkBool32 alphaToCoverageEnable;
291 VK_FALSE // VkBool32 alphaToOneEnable;
294 const VkStencilOpState stencilOpState = makeStencilOpState(
295 VK_STENCIL_OP_KEEP, // stencil fail
296 VK_STENCIL_OP_KEEP, // depth & stencil pass
297 VK_STENCIL_OP_KEEP, // depth only fail
298 VK_COMPARE_OP_NEVER, // compare op
303 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
305 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
306 DE_NULL, // const void* pNext;
307 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
308 VK_FALSE, // VkBool32 depthTestEnable;
309 VK_FALSE, // VkBool32 depthWriteEnable;
310 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
311 VK_FALSE, // VkBool32 depthBoundsTestEnable;
312 VK_FALSE, // VkBool32 stencilTestEnable;
313 stencilOpState, // VkStencilOpState front;
314 stencilOpState, // VkStencilOpState back;
315 0.0f, // float minDepthBounds;
316 1.0f, // float maxDepthBounds;
319 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
320 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
322 m_blendEnable, // VkBool32 blendEnable;
323 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
324 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
325 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
326 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
327 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
328 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
329 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
332 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
334 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
335 DE_NULL, // const void* pNext;
336 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
337 VK_FALSE, // VkBool32 logicOpEnable;
338 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
339 1u, // deUint32 attachmentCount;
340 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
341 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
344 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
346 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
347 DE_NULL, // const void* pNext;
348 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
349 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount;
350 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
351 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
352 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
353 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
354 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState;
355 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
356 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
357 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
358 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
359 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
360 pipelineLayout, // VkPipelineLayout layout;
361 renderPass, // VkRenderPass renderPass;
362 0u, // deUint32 subpass;
363 DE_NULL, // VkPipeline basePipelineHandle;
364 0, // deInt32 basePipelineIndex;
368 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
369 vk::Move<vk::VkPipeline> pipeline (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
371 // Refresh data from cache
372 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
378 // Uses some structures added by VK_KHR_synchronization2 to fill legacy structures.
379 // With this approach we dont have to create branch in each test (one for legacy
380 // second for new synchronization), this helps to reduce code of some tests.
381 class LegacySynchronizationWrapper : public SynchronizationWrapperBase
385 struct SubmitInfoData
387 deUint32 waitSemaphoreCount;
388 std::size_t waitSemaphoreIndex;
389 std::size_t waitSemaphoreValueIndexPlusOne;
390 deUint32 commandBufferCount;
391 deUint32 commandBufferIndex;
392 deUint32 signalSemaphoreCount;
393 std::size_t signalSemaphoreIndex;
394 std::size_t signalSemaphoreValueIndexPlusOne;
398 LegacySynchronizationWrapper(const DeviceInterface& vk, bool usingTimelineSemaphores, deUint32 submitInfoCount = 1u)
399 : SynchronizationWrapperBase (vk)
400 , m_submited (DE_FALSE)
402 m_waitSemaphores.reserve(submitInfoCount);
403 m_signalSemaphores.reserve(submitInfoCount);
404 m_waitDstStageMasks.reserve(submitInfoCount);
405 m_commandBuffers.reserve(submitInfoCount);
406 m_submitInfoData.reserve(submitInfoCount);
408 if (usingTimelineSemaphores)
409 m_timelineSemaphoreValues.reserve(2 * submitInfoCount);
412 ~LegacySynchronizationWrapper() = default;
414 void addSubmitInfo(deUint32 waitSemaphoreInfoCount,
415 const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos,
416 deUint32 commandBufferInfoCount,
417 const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos,
418 deUint32 signalSemaphoreInfoCount,
419 const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos,
420 bool usingWaitTimelineSemaphore,
421 bool usingSignalTimelineSemaphore) override
423 m_submitInfoData.push_back(SubmitInfoData{ waitSemaphoreInfoCount, 0, 0, commandBufferInfoCount, 0u, signalSemaphoreInfoCount, 0, 0 });
424 SubmitInfoData& si = m_submitInfoData.back();
426 // memorize wait values
427 if (usingWaitTimelineSemaphore)
429 DE_ASSERT(pWaitSemaphoreInfos);
430 si.waitSemaphoreValueIndexPlusOne = m_timelineSemaphoreValues.size() + 1;
431 for (deUint32 i = 0; i < waitSemaphoreInfoCount; ++i)
432 m_timelineSemaphoreValues.push_back(pWaitSemaphoreInfos[i].value);
435 // memorize signal values
436 if (usingSignalTimelineSemaphore)
438 DE_ASSERT(pSignalSemaphoreInfos);
439 si.signalSemaphoreValueIndexPlusOne = m_timelineSemaphoreValues.size() + 1;
440 for (deUint32 i = 0; i < signalSemaphoreInfoCount; ++i)
441 m_timelineSemaphoreValues.push_back(pSignalSemaphoreInfos[i].value);
444 // construct list of semaphores that we need to wait on
445 if (waitSemaphoreInfoCount)
447 si.waitSemaphoreIndex = m_waitSemaphores.size();
448 for (deUint32 i = 0; i < waitSemaphoreInfoCount; ++i)
450 m_waitSemaphores.push_back(pWaitSemaphoreInfos[i].semaphore);
451 m_waitDstStageMasks.push_back(static_cast<VkPipelineStageFlags>(pWaitSemaphoreInfos[i].stageMask));
455 // construct list of command buffers
456 if (commandBufferInfoCount)
458 si.commandBufferIndex = static_cast<deUint32>(m_commandBuffers.size());
459 for (deUint32 i = 0; i < commandBufferInfoCount; ++i)
460 m_commandBuffers.push_back(pCommandBufferInfos[i].commandBuffer);
463 // construct list of semaphores that will be signaled
464 if (signalSemaphoreInfoCount)
466 si.signalSemaphoreIndex = m_signalSemaphores.size();
467 for (deUint32 i = 0; i < signalSemaphoreInfoCount; ++i)
468 m_signalSemaphores.push_back(pSignalSemaphoreInfos[i].semaphore);
472 void cmdPipelineBarrier(VkCommandBuffer commandBuffer, VkDependencyInfoKHR* pDependencyInfo) override
474 DE_ASSERT(pDependencyInfo);
476 VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_NONE_KHR;
477 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_NONE_KHR;
478 deUint32 memoryBarrierCount = pDependencyInfo->memoryBarrierCount;
479 VkMemoryBarrier* pMemoryBarriers = DE_NULL;
480 deUint32 bufferMemoryBarrierCount = pDependencyInfo->bufferMemoryBarrierCount;
481 VkBufferMemoryBarrier* pBufferMemoryBarriers = DE_NULL;
482 deUint32 imageMemoryBarrierCount = pDependencyInfo->imageMemoryBarrierCount;
483 VkImageMemoryBarrier* pImageMemoryBarriers = DE_NULL;
485 // translate VkMemoryBarrier2KHR to VkMemoryBarrier
486 std::vector<VkMemoryBarrier> memoryBarriers;
487 if (memoryBarrierCount)
489 memoryBarriers.reserve(memoryBarrierCount);
490 for (deUint32 i = 0; i < memoryBarrierCount; ++i)
492 const VkMemoryBarrier2KHR& pMemoryBarrier = pDependencyInfo->pMemoryBarriers[i];
493 srcStageMask |= static_cast<VkPipelineStageFlags>(pMemoryBarrier.srcStageMask);
494 dstStageMask |= static_cast<VkPipelineStageFlags>(pMemoryBarrier.dstStageMask);
495 memoryBarriers.push_back(makeMemoryBarrier(
496 static_cast<VkAccessFlags>(pMemoryBarrier.srcAccessMask),
497 static_cast<VkAccessFlags>(pMemoryBarrier.dstAccessMask)
500 pMemoryBarriers = &memoryBarriers[0];
503 // translate VkBufferMemoryBarrier2KHR to VkBufferMemoryBarrier
504 std::vector<VkBufferMemoryBarrier> bufferMemoryBarriers;
505 if (bufferMemoryBarrierCount)
507 bufferMemoryBarriers.reserve(bufferMemoryBarrierCount);
508 for (deUint32 i = 0; i < bufferMemoryBarrierCount; ++i)
510 const VkBufferMemoryBarrier2KHR& pBufferMemoryBarrier = pDependencyInfo->pBufferMemoryBarriers[i];
511 srcStageMask |= static_cast<VkPipelineStageFlags>(pBufferMemoryBarrier.srcStageMask);
512 dstStageMask |= static_cast<VkPipelineStageFlags>(pBufferMemoryBarrier.dstStageMask);
513 bufferMemoryBarriers.push_back(makeBufferMemoryBarrier(
514 static_cast<VkAccessFlags>(pBufferMemoryBarrier.srcAccessMask),
515 static_cast<VkAccessFlags>(pBufferMemoryBarrier.dstAccessMask),
516 pBufferMemoryBarrier.buffer,
517 pBufferMemoryBarrier.offset,
518 pBufferMemoryBarrier.size,
519 pBufferMemoryBarrier.srcQueueFamilyIndex,
520 pBufferMemoryBarrier.dstQueueFamilyIndex
523 pBufferMemoryBarriers = &bufferMemoryBarriers[0];
526 // translate VkImageMemoryBarrier2KHR to VkImageMemoryBarrier
527 std::vector<VkImageMemoryBarrier> imageMemoryBarriers;
528 if (imageMemoryBarrierCount)
530 imageMemoryBarriers.reserve(imageMemoryBarrierCount);
531 for (deUint32 i = 0; i < imageMemoryBarrierCount; ++i)
533 const VkImageMemoryBarrier2KHR& pImageMemoryBarrier = pDependencyInfo->pImageMemoryBarriers[i];
534 srcStageMask |= static_cast<VkPipelineStageFlags>(pImageMemoryBarrier.srcStageMask);
535 dstStageMask |= static_cast<VkPipelineStageFlags>(pImageMemoryBarrier.dstStageMask);
536 imageMemoryBarriers.push_back(makeImageMemoryBarrier(
537 static_cast<VkAccessFlags>(pImageMemoryBarrier.srcAccessMask),
538 static_cast<VkAccessFlags>(pImageMemoryBarrier.dstAccessMask),
539 pImageMemoryBarrier.oldLayout,
540 pImageMemoryBarrier.newLayout,
541 pImageMemoryBarrier.image,
542 pImageMemoryBarrier.subresourceRange,
543 pImageMemoryBarrier.srcQueueFamilyIndex,
544 pImageMemoryBarrier.dstQueueFamilyIndex
547 pImageMemoryBarriers = &imageMemoryBarriers[0];
550 m_vk.cmdPipelineBarrier(
554 (VkDependencyFlags)0,
557 bufferMemoryBarrierCount,
558 pBufferMemoryBarriers,
559 imageMemoryBarrierCount,
564 void cmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkDependencyInfoKHR* pDependencyInfo) override
566 DE_ASSERT(pDependencyInfo);
568 VkPipelineStageFlags2KHR srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
569 if (pDependencyInfo->pMemoryBarriers)
570 srcStageMask = pDependencyInfo->pMemoryBarriers[0].srcStageMask;
571 if (pDependencyInfo->pBufferMemoryBarriers)
572 srcStageMask = pDependencyInfo->pBufferMemoryBarriers[0].srcStageMask;
573 if (pDependencyInfo->pImageMemoryBarriers)
574 srcStageMask = pDependencyInfo->pImageMemoryBarriers[0].srcStageMask;
576 m_vk.cmdSetEvent(commandBuffer, event, static_cast<VkPipelineStageFlags>(srcStageMask));
579 void cmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR flag) override
581 VkPipelineStageFlags legacyStageMask = static_cast<VkPipelineStageFlags>(flag);
582 m_vk.cmdResetEvent(commandBuffer, event, legacyStageMask);
585 void cmdWaitEvents(VkCommandBuffer commandBuffer, deUint32 eventCount, const VkEvent* pEvents, VkDependencyInfoKHR* pDependencyInfo) override
587 DE_ASSERT(pDependencyInfo);
589 VkPipelineStageFlags2KHR srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
590 VkPipelineStageFlags2KHR dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
591 deUint32 memoryBarrierCount = pDependencyInfo->memoryBarrierCount;
592 deUint32 bufferMemoryBarrierCount = pDependencyInfo->bufferMemoryBarrierCount;
593 deUint32 imageMemoryBarrierCount = pDependencyInfo->imageMemoryBarrierCount;
594 VkMemoryBarrier* pMemoryBarriers = DE_NULL;
595 VkBufferMemoryBarrier* pBufferMemoryBarriers = DE_NULL;
596 VkImageMemoryBarrier* pImageMemoryBarriers = DE_NULL;
597 std::vector<VkMemoryBarrier> memoryBarriers;
598 std::vector<VkBufferMemoryBarrier> bufferMemoryBarriers;
599 std::vector<VkImageMemoryBarrier> imageMemoryBarriers;
601 if (pDependencyInfo->pMemoryBarriers)
603 srcStageMask = pDependencyInfo->pMemoryBarriers[0].srcStageMask;
604 dstStageMask = pDependencyInfo->pMemoryBarriers[0].dstStageMask;
606 memoryBarriers.reserve(memoryBarrierCount);
607 for (deUint32 i = 0; i < memoryBarrierCount; ++i)
609 const VkMemoryBarrier2KHR& mb = pDependencyInfo->pMemoryBarriers[i];
610 memoryBarriers.push_back(
612 static_cast<VkAccessFlags>(mb.srcAccessMask),
613 static_cast<VkAccessFlags>(mb.dstAccessMask)
617 pMemoryBarriers = &memoryBarriers[0];
619 if (pDependencyInfo->pBufferMemoryBarriers)
621 srcStageMask = pDependencyInfo->pBufferMemoryBarriers[0].srcStageMask;
622 dstStageMask = pDependencyInfo->pBufferMemoryBarriers[0].dstStageMask;
624 bufferMemoryBarriers.reserve(bufferMemoryBarrierCount);
625 for (deUint32 i = 0; i < bufferMemoryBarrierCount; ++i)
627 const VkBufferMemoryBarrier2KHR& bmb = pDependencyInfo->pBufferMemoryBarriers[i];
628 bufferMemoryBarriers.push_back(
629 makeBufferMemoryBarrier(
630 static_cast<VkAccessFlags>(bmb.srcAccessMask),
631 static_cast<VkAccessFlags>(bmb.dstAccessMask),
635 bmb.srcQueueFamilyIndex,
636 bmb.dstQueueFamilyIndex
640 pBufferMemoryBarriers = &bufferMemoryBarriers[0];
642 if (pDependencyInfo->pImageMemoryBarriers)
644 srcStageMask = pDependencyInfo->pImageMemoryBarriers[0].srcStageMask;
645 dstStageMask = pDependencyInfo->pImageMemoryBarriers[0].dstStageMask;
647 imageMemoryBarriers.reserve(imageMemoryBarrierCount);
648 for (deUint32 i = 0; i < imageMemoryBarrierCount; ++i)
650 const VkImageMemoryBarrier2KHR& imb = pDependencyInfo->pImageMemoryBarriers[i];
651 imageMemoryBarriers.push_back(
652 makeImageMemoryBarrier(
653 static_cast<VkAccessFlags>(imb.srcAccessMask),
654 static_cast<VkAccessFlags>(imb.dstAccessMask),
658 imb.subresourceRange,
659 imb.srcQueueFamilyIndex,
660 imb.dstQueueFamilyIndex
664 pImageMemoryBarriers = &imageMemoryBarriers[0];
667 m_vk.cmdWaitEvents(commandBuffer, eventCount, pEvents,
668 static_cast<VkPipelineStageFlags>(srcStageMask), static_cast<VkPipelineStageFlags>(dstStageMask),
669 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
672 VkResult queueSubmit(VkQueue queue, VkFence fence) override
674 // make sure submit info was added
675 DE_ASSERT(!m_submitInfoData.empty());
677 // make sure separate LegacySynchronizationWrapper is created per single submit
678 DE_ASSERT(!m_submited);
680 std::vector<VkSubmitInfo> submitInfo(m_submitInfoData.size(), { VK_STRUCTURE_TYPE_SUBMIT_INFO, DE_NULL, 0u, DE_NULL, DE_NULL, 0u, DE_NULL, 0u, DE_NULL });
682 std::vector<VkTimelineSemaphoreSubmitInfo> timelineSemaphoreSubmitInfo;
683 timelineSemaphoreSubmitInfo.reserve(m_submitInfoData.size());
685 // translate indexes from m_submitInfoData to pointers and construct VkSubmitInfo
686 for (deUint32 i = 0; i < m_submitInfoData.size(); ++i)
688 auto& data = m_submitInfoData[i];
689 VkSubmitInfo& si = submitInfo[i];
691 si.waitSemaphoreCount = data.waitSemaphoreCount;
692 si.commandBufferCount = data.commandBufferCount;
693 si.signalSemaphoreCount = data.signalSemaphoreCount;
695 if (data.waitSemaphoreValueIndexPlusOne || data.signalSemaphoreValueIndexPlusOne)
697 deUint64* pWaitSemaphoreValues = DE_NULL;
698 if (data.waitSemaphoreValueIndexPlusOne)
699 pWaitSemaphoreValues = &m_timelineSemaphoreValues[data.waitSemaphoreValueIndexPlusOne - 1];
701 deUint64* pSignalSemaphoreValues = DE_NULL;
702 if (data.signalSemaphoreValueIndexPlusOne)
703 pSignalSemaphoreValues = &m_timelineSemaphoreValues[data.signalSemaphoreValueIndexPlusOne - 1];
705 timelineSemaphoreSubmitInfo.push_back({
706 VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, // VkStructureType sType;
707 DE_NULL, // const void* pNext;
708 data.waitSemaphoreCount, // deUint32 waitSemaphoreValueCount
709 pWaitSemaphoreValues, // const deUint64* pWaitSemaphoreValues
710 data.signalSemaphoreCount, // deUint32 signalSemaphoreValueCount
711 pSignalSemaphoreValues // const deUint64* pSignalSemaphoreValues
713 si.pNext = &timelineSemaphoreSubmitInfo.back();
716 if (data.waitSemaphoreCount)
718 si.pWaitSemaphores = &m_waitSemaphores[data.waitSemaphoreIndex];
719 si.pWaitDstStageMask = &m_waitDstStageMasks[data.waitSemaphoreIndex];
722 if (data.commandBufferCount)
723 si.pCommandBuffers = &m_commandBuffers[data.commandBufferIndex];
725 if (data.signalSemaphoreCount)
726 si.pSignalSemaphores = &m_signalSemaphores[data.signalSemaphoreIndex];
729 m_submited = DE_TRUE;
730 return m_vk.queueSubmit(queue, static_cast<deUint32>(submitInfo.size()), &submitInfo[0], fence);
735 std::vector<VkSemaphore> m_waitSemaphores;
736 std::vector<VkSemaphore> m_signalSemaphores;
737 std::vector<VkPipelineStageFlags> m_waitDstStageMasks;
738 std::vector<VkCommandBuffer> m_commandBuffers;
739 std::vector<SubmitInfoData> m_submitInfoData;
740 std::vector<deUint64> m_timelineSemaphoreValues;
744 class Synchronization2Wrapper : public SynchronizationWrapperBase
747 Synchronization2Wrapper(const DeviceInterface& vk, deUint32 submitInfoCount)
748 : SynchronizationWrapperBase(vk)
750 m_submitInfo.reserve(submitInfoCount);
753 ~Synchronization2Wrapper() = default;
755 void addSubmitInfo(deUint32 waitSemaphoreInfoCount,
756 const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos,
757 deUint32 commandBufferInfoCount,
758 const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos,
759 deUint32 signalSemaphoreInfoCount,
760 const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos,
761 bool usingWaitTimelineSemaphore,
762 bool usingSignalTimelineSemaphore) override
764 DE_UNREF(usingWaitTimelineSemaphore);
765 DE_UNREF(usingSignalTimelineSemaphore);
767 m_submitInfo.push_back(VkSubmitInfo2KHR{
768 VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR, // VkStructureType sType
769 DE_NULL, // const void* pNext
770 0u, // VkSubmitFlagsKHR flags
771 waitSemaphoreInfoCount, // deUint32 waitSemaphoreInfoCount
772 pWaitSemaphoreInfos, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
773 commandBufferInfoCount, // deUint32 commandBufferInfoCount
774 pCommandBufferInfos, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
775 signalSemaphoreInfoCount, // deUint32 signalSemaphoreInfoCount
776 pSignalSemaphoreInfos // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
780 void cmdPipelineBarrier(VkCommandBuffer commandBuffer, VkDependencyInfoKHR* pDependencyInfo) override
782 m_vk.cmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo);
785 void cmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkDependencyInfoKHR* pDependencyInfo) override
787 m_vk.cmdSetEvent2KHR(commandBuffer, event, pDependencyInfo);
790 void cmdWaitEvents(VkCommandBuffer commandBuffer, deUint32 eventCount, const VkEvent* pEvents, VkDependencyInfoKHR* pDependencyInfo) override
792 m_vk.cmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfo);
795 void cmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR flag) override
797 m_vk.cmdResetEvent2KHR(commandBuffer, event, flag);
800 VkResult queueSubmit(VkQueue queue, VkFence fence) override
802 return m_vk.queueSubmit2KHR(queue, static_cast<deUint32>(m_submitInfo.size()), &m_submitInfo[0], fence);
807 std::vector<VkSubmitInfo2KHR> m_submitInfo;
810 SynchronizationWrapperPtr getSynchronizationWrapper(SynchronizationType type,
811 const DeviceInterface& vk,
812 bool usingTimelineSemaphores,
813 deUint32 submitInfoCount)
815 return (type == SynchronizationType::LEGACY)
816 ? SynchronizationWrapperPtr(new LegacySynchronizationWrapper(vk, usingTimelineSemaphores, submitInfoCount))
817 : SynchronizationWrapperPtr(new Synchronization2Wrapper(vk, submitInfoCount));
820 void submitCommandsAndWait(SynchronizationWrapperPtr synchronizationWrapper,
821 const DeviceInterface& vk,
822 const VkDevice device,
824 const VkCommandBuffer cmdBuffer)
826 VkCommandBufferSubmitInfoKHR commandBufferInfoCount = makeCommonCommandBufferSubmitInfo(cmdBuffer);
828 synchronizationWrapper->addSubmitInfo(
829 0u, // deUint32 waitSemaphoreInfoCount
830 DE_NULL, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
831 1u, // deUint32 commandBufferInfoCount
832 &commandBufferInfoCount, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
833 0u, // deUint32 signalSemaphoreInfoCount
834 DE_NULL // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
837 const Unique<VkFence> fence(createFence(vk, device));
838 VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
839 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
842 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
844 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
846 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
847 throw tcu::NotSupportedError("Tessellation shader not supported");
849 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
850 throw tcu::NotSupportedError("Geometry shader not supported");
852 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
853 throw tcu::NotSupportedError("Double-precision floats not supported");
855 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
856 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
858 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
859 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
861 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
862 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
865 void requireStorageImageSupport(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat fmt)
867 const VkFormatProperties p = getPhysicalDeviceFormatProperties(vki, physDevice, fmt);
868 if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
869 throw tcu::NotSupportedError("Storage image format not supported");
872 std::string getResourceName (const ResourceDescription& resource)
874 std::ostringstream str;
876 if (resource.type == RESOURCE_TYPE_BUFFER)
877 str << "buffer_" << resource.size.x();
878 else if (resource.type == RESOURCE_TYPE_IMAGE)
880 str << "image_" << resource.size.x()
881 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
882 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
883 << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
885 else if (isIndirectBuffer(resource.type))
886 str << "indirect_buffer";
893 bool isIndirectBuffer (const ResourceType type)
897 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
898 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
899 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
907 VkCommandBufferSubmitInfoKHR makeCommonCommandBufferSubmitInfo (const VkCommandBuffer cmdBuf)
911 VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR, // VkStructureType sType
912 DE_NULL, // const void* pNext
913 cmdBuf, // VkCommandBuffer commandBuffer
914 0u // uint32_t deviceMask
918 VkSemaphoreSubmitInfoKHR makeCommonSemaphoreSubmitInfo(VkSemaphore semaphore, deUint64 value, VkPipelineStageFlags2KHR stageMask)
922 VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR, // VkStructureType sType
923 DE_NULL, // const void* pNext
924 semaphore, // VkSemaphore semaphore
925 value, // deUint64 value
926 stageMask, // VkPipelineStageFlags2KHR stageMask
927 0u // deUint32 deviceIndex
931 VkDependencyInfoKHR makeCommonDependencyInfo(const VkMemoryBarrier2KHR* pMemoryBarrier, const VkBufferMemoryBarrier2KHR* pBufferMemoryBarrier, const VkImageMemoryBarrier2KHR* pImageMemoryBarrier)
935 VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR, // VkStructureType sType
936 DE_NULL, // const void* pNext
937 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags
938 !!pMemoryBarrier, // deUint32 memoryBarrierCount
939 pMemoryBarrier, // const VkMemoryBarrier2KHR* pMemoryBarriers
940 !!pBufferMemoryBarrier, // deUint32 bufferMemoryBarrierCount
941 pBufferMemoryBarrier, // const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers
942 !!pImageMemoryBarrier, // deUint32 imageMemoryBarrierCount
943 pImageMemoryBarrier // const VkImageMemoryBarrier2KHR* pImageMemoryBarriers
947 PipelineCacheData::PipelineCacheData (void)
951 PipelineCacheData::~PipelineCacheData (void)
955 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
957 const de::ScopedLock dataLock (m_lock);
958 const struct vk::VkPipelineCacheCreateInfo params =
960 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
962 (vk::VkPipelineCacheCreateFlags)0,
963 (deUintptr)m_data.size(),
964 (m_data.empty() ? DE_NULL : &m_data[0])
967 return vk::createPipelineCache(vk, device, ¶ms);
970 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
972 const de::ScopedLock dataLock (m_lock);
973 deUintptr dataSize = 0;
975 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
977 m_data.resize(dataSize);
980 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));