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 "vkCmdUtil.hpp"
27 #include "vkBarrierUtil.hpp"
28 #include "deStringUtil.hpp"
29 #include <set>
30 #include <limits>
31
32 namespace vkt
33 {
34 namespace synchronization
35 {
36 using namespace vk;
37
makeCommandBuffer(const DeviceInterface & vk,const VkDevice device,const VkCommandPool commandPool)38 Move<VkCommandBuffer> makeCommandBuffer (const DeviceInterface& vk, const VkDevice device, const VkCommandPool commandPool)
39 {
40 const VkCommandBufferAllocateInfo info =
41 {
42 VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO, // VkStructureType sType;
43 DE_NULL, // const void* pNext;
44 commandPool, // VkCommandPool commandPool;
45 VK_COMMAND_BUFFER_LEVEL_PRIMARY, // VkCommandBufferLevel level;
46 1u, // deUint32 commandBufferCount;
47 };
48 return allocateCommandBuffer(vk, device, &info);
49 }
50
makeComputePipeline(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkShaderModule shaderModule,const VkSpecializationInfo * specInfo,PipelineCacheData & pipelineCacheData)51 Move<VkPipeline> makeComputePipeline (const DeviceInterface& vk,
52 const VkDevice device,
53 const VkPipelineLayout pipelineLayout,
54 const VkShaderModule shaderModule,
55 const VkSpecializationInfo* specInfo,
56 PipelineCacheData& pipelineCacheData)
57 {
58 const VkPipelineShaderStageCreateInfo shaderStageInfo =
59 {
60 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
61 DE_NULL, // const void* pNext;
62 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
63 VK_SHADER_STAGE_COMPUTE_BIT, // VkShaderStageFlagBits stage;
64 shaderModule, // VkShaderModule module;
65 "main", // const char* pName;
66 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
67 };
68 const VkComputePipelineCreateInfo pipelineInfo =
69 {
70 VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO, // VkStructureType sType;
71 DE_NULL, // const void* pNext;
72 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
73 shaderStageInfo, // VkPipelineShaderStageCreateInfo stage;
74 pipelineLayout, // VkPipelineLayout layout;
75 DE_NULL, // VkPipeline basePipelineHandle;
76 0, // deInt32 basePipelineIndex;
77 };
78
79 {
80 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
81 vk::Move<vk::VkPipeline> pipeline (createComputePipeline(vk, device, *pipelineCache, &pipelineInfo));
82
83 // Refresh data from cache
84 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
85
86 return pipeline;
87 }
88 }
89
makeImageCreateInfo(const VkImageType imageType,const VkExtent3D & extent,const VkFormat format,const VkImageUsageFlags usage,const VkSampleCountFlagBits samples)90 VkImageCreateInfo makeImageCreateInfo (const VkImageType imageType,
91 const VkExtent3D& extent,
92 const VkFormat format,
93 const VkImageUsageFlags usage,
94 const VkSampleCountFlagBits samples)
95 {
96 return
97 {
98 VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO, // VkStructureType sType;
99 DE_NULL, // const void* pNext;
100 (VkImageCreateFlags)0, // VkImageCreateFlags flags;
101 imageType, // VkImageType imageType;
102 format, // VkFormat format;
103 extent, // VkExtent3D extent;
104 1u, // uint32_t mipLevels;
105 1u, // uint32_t arrayLayers;
106 samples, // VkSampleCountFlagBits samples;
107 VK_IMAGE_TILING_OPTIMAL, // VkImageTiling tiling;
108 usage, // VkImageUsageFlags usage;
109 VK_SHARING_MODE_EXCLUSIVE, // VkSharingMode sharingMode;
110 0u, // uint32_t queueFamilyIndexCount;
111 DE_NULL, // const uint32_t* pQueueFamilyIndices;
112 VK_IMAGE_LAYOUT_UNDEFINED, // VkImageLayout initialLayout;
113 };
114 }
115
beginRenderPassWithRasterizationDisabled(const DeviceInterface & vk,const VkCommandBuffer commandBuffer,const VkRenderPass renderPass,const VkFramebuffer framebuffer)116 void beginRenderPassWithRasterizationDisabled (const DeviceInterface& vk,
117 const VkCommandBuffer commandBuffer,
118 const VkRenderPass renderPass,
119 const VkFramebuffer framebuffer)
120 {
121 const VkRect2D renderArea = {{ 0, 0 }, { 0, 0 }};
122
123 beginRenderPass(vk, commandBuffer, renderPass, framebuffer, renderArea);
124 }
125
setShader(const DeviceInterface & vk,const VkDevice device,const VkShaderStageFlagBits stage,const ProgramBinary & binary,const VkSpecializationInfo * specInfo)126 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setShader (const DeviceInterface& vk,
127 const VkDevice device,
128 const VkShaderStageFlagBits stage,
129 const ProgramBinary& binary,
130 const VkSpecializationInfo* specInfo)
131 {
132 VkShaderModule module;
133 switch (stage)
134 {
135 case (VK_SHADER_STAGE_VERTEX_BIT):
136 DE_ASSERT(m_vertexShaderModule.get() == DE_NULL);
137 m_vertexShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
138 module = *m_vertexShaderModule;
139 break;
140
141 case (VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT):
142 DE_ASSERT(m_tessControlShaderModule.get() == DE_NULL);
143 m_tessControlShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
144 module = *m_tessControlShaderModule;
145 break;
146
147 case (VK_SHADER_STAGE_TESSELLATION_EVALUATION_BIT):
148 DE_ASSERT(m_tessEvaluationShaderModule.get() == DE_NULL);
149 m_tessEvaluationShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
150 module = *m_tessEvaluationShaderModule;
151 break;
152
153 case (VK_SHADER_STAGE_GEOMETRY_BIT):
154 DE_ASSERT(m_geometryShaderModule.get() == DE_NULL);
155 m_geometryShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
156 module = *m_geometryShaderModule;
157 break;
158
159 case (VK_SHADER_STAGE_FRAGMENT_BIT):
160 DE_ASSERT(m_fragmentShaderModule.get() == DE_NULL);
161 m_fragmentShaderModule = createShaderModule(vk, device, binary, (VkShaderModuleCreateFlags)0);
162 module = *m_fragmentShaderModule;
163 break;
164
165 default:
166 DE_FATAL("Invalid shader stage");
167 return *this;
168 }
169
170 const VkPipelineShaderStageCreateInfo pipelineShaderStageInfo =
171 {
172 VK_STRUCTURE_TYPE_PIPELINE_SHADER_STAGE_CREATE_INFO, // VkStructureType sType;
173 DE_NULL, // const void* pNext;
174 (VkPipelineShaderStageCreateFlags)0, // VkPipelineShaderStageCreateFlags flags;
175 stage, // VkShaderStageFlagBits stage;
176 module, // VkShaderModule module;
177 "main", // const char* pName;
178 specInfo, // const VkSpecializationInfo* pSpecializationInfo;
179 };
180
181 m_shaderStageFlags |= stage;
182 m_shaderStages.push_back(pipelineShaderStageInfo);
183
184 return *this;
185 }
186
setVertexInputSingleAttribute(const VkFormat vertexFormat,const deUint32 stride)187 GraphicsPipelineBuilder& GraphicsPipelineBuilder::setVertexInputSingleAttribute (const VkFormat vertexFormat, const deUint32 stride)
188 {
189 const VkVertexInputBindingDescription bindingDesc =
190 {
191 0u, // uint32_t binding;
192 stride, // uint32_t stride;
193 VK_VERTEX_INPUT_RATE_VERTEX, // VkVertexInputRate inputRate;
194 };
195 const VkVertexInputAttributeDescription attributeDesc =
196 {
197 0u, // uint32_t location;
198 0u, // uint32_t binding;
199 vertexFormat, // VkFormat format;
200 0u, // uint32_t offset;
201 };
202
203 m_vertexInputBindings.clear();
204 m_vertexInputBindings.push_back(bindingDesc);
205
206 m_vertexInputAttributes.clear();
207 m_vertexInputAttributes.push_back(attributeDesc);
208
209 return *this;
210 }
211
212 template<typename T>
dataPointer(const std::vector<T> & vec)213 inline const T* dataPointer (const std::vector<T>& vec)
214 {
215 return (vec.size() != 0 ? &vec[0] : DE_NULL);
216 }
217
build(const DeviceInterface & vk,const VkDevice device,const VkPipelineLayout pipelineLayout,const VkRenderPass renderPass,PipelineCacheData & pipelineCacheData)218 Move<VkPipeline> GraphicsPipelineBuilder::build (const DeviceInterface& vk,
219 const VkDevice device,
220 const VkPipelineLayout pipelineLayout,
221 const VkRenderPass renderPass,
222 PipelineCacheData& pipelineCacheData)
223 {
224 const VkPipelineVertexInputStateCreateInfo vertexInputStateInfo =
225 {
226 VK_STRUCTURE_TYPE_PIPELINE_VERTEX_INPUT_STATE_CREATE_INFO, // VkStructureType sType;
227 DE_NULL, // const void* pNext;
228 (VkPipelineVertexInputStateCreateFlags)0, // VkPipelineVertexInputStateCreateFlags flags;
229 static_cast<deUint32>(m_vertexInputBindings.size()), // uint32_t vertexBindingDescriptionCount;
230 dataPointer(m_vertexInputBindings), // const VkVertexInputBindingDescription* pVertexBindingDescriptions;
231 static_cast<deUint32>(m_vertexInputAttributes.size()), // uint32_t vertexAttributeDescriptionCount;
232 dataPointer(m_vertexInputAttributes), // const VkVertexInputAttributeDescription* pVertexAttributeDescriptions;
233 };
234
235 const VkPrimitiveTopology topology = (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT) ? VK_PRIMITIVE_TOPOLOGY_PATCH_LIST
236 : m_primitiveTopology;
237 const VkPipelineInputAssemblyStateCreateInfo pipelineInputAssemblyStateInfo =
238 {
239 VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO, // VkStructureType sType;
240 DE_NULL, // const void* pNext;
241 (VkPipelineInputAssemblyStateCreateFlags)0, // VkPipelineInputAssemblyStateCreateFlags flags;
242 topology, // VkPrimitiveTopology topology;
243 VK_FALSE, // VkBool32 primitiveRestartEnable;
244 };
245
246 const VkPipelineTessellationStateCreateInfo pipelineTessellationStateInfo =
247 {
248 VK_STRUCTURE_TYPE_PIPELINE_TESSELLATION_STATE_CREATE_INFO, // VkStructureType sType;
249 DE_NULL, // const void* pNext;
250 (VkPipelineTessellationStateCreateFlags)0, // VkPipelineTessellationStateCreateFlags flags;
251 m_patchControlPoints, // uint32_t patchControlPoints;
252 };
253
254 const VkViewport viewport = makeViewport(m_renderSize);
255 const VkRect2D scissor = makeRect2D(m_renderSize);
256
257 const VkPipelineViewportStateCreateInfo pipelineViewportStateInfo =
258 {
259 VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO, // VkStructureType sType;
260 DE_NULL, // const void* pNext;
261 (VkPipelineViewportStateCreateFlags)0, // VkPipelineViewportStateCreateFlags flags;
262 1u, // uint32_t viewportCount;
263 &viewport, // const VkViewport* pViewports;
264 1u, // uint32_t scissorCount;
265 &scissor, // const VkRect2D* pScissors;
266 };
267
268 const bool isRasterizationDisabled = ((m_shaderStageFlags & VK_SHADER_STAGE_FRAGMENT_BIT) == 0);
269 const VkPipelineRasterizationStateCreateInfo pipelineRasterizationStateInfo =
270 {
271 VK_STRUCTURE_TYPE_PIPELINE_RASTERIZATION_STATE_CREATE_INFO, // VkStructureType sType;
272 DE_NULL, // const void* pNext;
273 (VkPipelineRasterizationStateCreateFlags)0, // VkPipelineRasterizationStateCreateFlags flags;
274 VK_FALSE, // VkBool32 depthClampEnable;
275 isRasterizationDisabled, // VkBool32 rasterizerDiscardEnable;
276 VK_POLYGON_MODE_FILL, // VkPolygonMode polygonMode;
277 m_cullModeFlags, // VkCullModeFlags cullMode;
278 m_frontFace, // VkFrontFace frontFace;
279 VK_FALSE, // VkBool32 depthBiasEnable;
280 0.0f, // float depthBiasConstantFactor;
281 0.0f, // float depthBiasClamp;
282 0.0f, // float depthBiasSlopeFactor;
283 1.0f, // float lineWidth;
284 };
285
286 const VkPipelineMultisampleStateCreateInfo pipelineMultisampleStateInfo =
287 {
288 VK_STRUCTURE_TYPE_PIPELINE_MULTISAMPLE_STATE_CREATE_INFO, // VkStructureType sType;
289 DE_NULL, // const void* pNext;
290 (VkPipelineMultisampleStateCreateFlags)0, // VkPipelineMultisampleStateCreateFlags flags;
291 VK_SAMPLE_COUNT_1_BIT, // VkSampleCountFlagBits rasterizationSamples;
292 VK_FALSE, // VkBool32 sampleShadingEnable;
293 0.0f, // float minSampleShading;
294 DE_NULL, // const VkSampleMask* pSampleMask;
295 VK_FALSE, // VkBool32 alphaToCoverageEnable;
296 VK_FALSE // VkBool32 alphaToOneEnable;
297 };
298
299 const VkStencilOpState stencilOpState = makeStencilOpState(
300 VK_STENCIL_OP_KEEP, // stencil fail
301 VK_STENCIL_OP_KEEP, // depth & stencil pass
302 VK_STENCIL_OP_KEEP, // depth only fail
303 VK_COMPARE_OP_NEVER, // compare op
304 0u, // compare mask
305 0u, // write mask
306 0u); // reference
307
308 const VkPipelineDepthStencilStateCreateInfo pipelineDepthStencilStateInfo =
309 {
310 VK_STRUCTURE_TYPE_PIPELINE_DEPTH_STENCIL_STATE_CREATE_INFO, // VkStructureType sType;
311 DE_NULL, // const void* pNext;
312 (VkPipelineDepthStencilStateCreateFlags)0, // VkPipelineDepthStencilStateCreateFlags flags;
313 VK_FALSE, // VkBool32 depthTestEnable;
314 VK_FALSE, // VkBool32 depthWriteEnable;
315 VK_COMPARE_OP_LESS, // VkCompareOp depthCompareOp;
316 VK_FALSE, // VkBool32 depthBoundsTestEnable;
317 VK_FALSE, // VkBool32 stencilTestEnable;
318 stencilOpState, // VkStencilOpState front;
319 stencilOpState, // VkStencilOpState back;
320 0.0f, // float minDepthBounds;
321 1.0f, // float maxDepthBounds;
322 };
323
324 const VkColorComponentFlags colorComponentsAll = VK_COLOR_COMPONENT_R_BIT | VK_COLOR_COMPONENT_G_BIT | VK_COLOR_COMPONENT_B_BIT | VK_COLOR_COMPONENT_A_BIT;
325 const VkPipelineColorBlendAttachmentState pipelineColorBlendAttachmentState =
326 {
327 m_blendEnable, // VkBool32 blendEnable;
328 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcColorBlendFactor;
329 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstColorBlendFactor;
330 VK_BLEND_OP_ADD, // VkBlendOp colorBlendOp;
331 VK_BLEND_FACTOR_SRC_ALPHA, // VkBlendFactor srcAlphaBlendFactor;
332 VK_BLEND_FACTOR_ONE, // VkBlendFactor dstAlphaBlendFactor;
333 VK_BLEND_OP_ADD, // VkBlendOp alphaBlendOp;
334 colorComponentsAll, // VkColorComponentFlags colorWriteMask;
335 };
336
337 const VkPipelineColorBlendStateCreateInfo pipelineColorBlendStateInfo =
338 {
339 VK_STRUCTURE_TYPE_PIPELINE_COLOR_BLEND_STATE_CREATE_INFO, // VkStructureType sType;
340 DE_NULL, // const void* pNext;
341 (VkPipelineColorBlendStateCreateFlags)0, // VkPipelineColorBlendStateCreateFlags flags;
342 VK_FALSE, // VkBool32 logicOpEnable;
343 VK_LOGIC_OP_COPY, // VkLogicOp logicOp;
344 1u, // deUint32 attachmentCount;
345 &pipelineColorBlendAttachmentState, // const VkPipelineColorBlendAttachmentState* pAttachments;
346 { 0.0f, 0.0f, 0.0f, 0.0f }, // float blendConstants[4];
347 };
348
349 const VkGraphicsPipelineCreateInfo graphicsPipelineInfo =
350 {
351 VK_STRUCTURE_TYPE_GRAPHICS_PIPELINE_CREATE_INFO, // VkStructureType sType;
352 DE_NULL, // const void* pNext;
353 (VkPipelineCreateFlags)0, // VkPipelineCreateFlags flags;
354 static_cast<deUint32>(m_shaderStages.size()), // deUint32 stageCount;
355 &m_shaderStages[0], // const VkPipelineShaderStageCreateInfo* pStages;
356 &vertexInputStateInfo, // const VkPipelineVertexInputStateCreateInfo* pVertexInputState;
357 &pipelineInputAssemblyStateInfo, // const VkPipelineInputAssemblyStateCreateInfo* pInputAssemblyState;
358 (m_shaderStageFlags & VK_SHADER_STAGE_TESSELLATION_CONTROL_BIT ? &pipelineTessellationStateInfo : DE_NULL), // const VkPipelineTessellationStateCreateInfo* pTessellationState;
359 (isRasterizationDisabled ? DE_NULL : &pipelineViewportStateInfo), // const VkPipelineViewportStateCreateInfo* pViewportState;
360 &pipelineRasterizationStateInfo, // const VkPipelineRasterizationStateCreateInfo* pRasterizationState;
361 (isRasterizationDisabled ? DE_NULL : &pipelineMultisampleStateInfo), // const VkPipelineMultisampleStateCreateInfo* pMultisampleState;
362 (isRasterizationDisabled ? DE_NULL : &pipelineDepthStencilStateInfo), // const VkPipelineDepthStencilStateCreateInfo* pDepthStencilState;
363 (isRasterizationDisabled ? DE_NULL : &pipelineColorBlendStateInfo), // const VkPipelineColorBlendStateCreateInfo* pColorBlendState;
364 DE_NULL, // const VkPipelineDynamicStateCreateInfo* pDynamicState;
365 pipelineLayout, // VkPipelineLayout layout;
366 renderPass, // VkRenderPass renderPass;
367 0u, // deUint32 subpass;
368 DE_NULL, // VkPipeline basePipelineHandle;
369 0, // deInt32 basePipelineIndex;
370 };
371
372 {
373 const vk::Unique<vk::VkPipelineCache> pipelineCache (pipelineCacheData.createPipelineCache(vk, device));
374 vk::Move<vk::VkPipeline> pipeline (createGraphicsPipeline(vk, device, *pipelineCache, &graphicsPipelineInfo));
375
376 // Refresh data from cache
377 pipelineCacheData.setFromPipelineCache(vk, device, *pipelineCache);
378
379 return pipeline;
380 }
381 }
382
383 // Uses some structures added by VK_KHR_synchronization2 to fill legacy structures.
384 // With this approach we dont have to create branch in each test (one for legacy
385 // second for new synchronization), this helps to reduce code of some tests.
386 class LegacySynchronizationWrapper : public SynchronizationWrapperBase
387 {
388 protected:
389
390 struct SubmitInfoData
391 {
392 deUint32 waitSemaphoreCount;
393 std::size_t waitSemaphoreIndex;
394 std::size_t waitSemaphoreValueIndexPlusOne;
395 deUint32 commandBufferCount;
396 deUint32 commandBufferIndex;
397 deUint32 signalSemaphoreCount;
398 std::size_t signalSemaphoreIndex;
399 std::size_t signalSemaphoreValueIndexPlusOne;
400 };
401
isStageFlagAllowed(VkPipelineStageFlags2KHR stage) const402 bool isStageFlagAllowed(VkPipelineStageFlags2KHR stage) const
403 {
404 // synchronization2 suports more stages then legacy synchronization
405 // and so SynchronizationWrapper can only be used for cases that
406 // operate on stages also supported by legacy synchronization
407 // NOTE: if some tests hits assertion that uses this method then this
408 // test should not use synchronizationWrapper - it should be synchronization2 exclusive
409
410 static const std::set<deUint32> allowedStages
411 {
412 VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT,
413 VK_PIPELINE_STAGE_DRAW_INDIRECT_BIT,
414 VK_PIPELINE_STAGE_VERTEX_INPUT_BIT,
415 VK_PIPELINE_STAGE_VERTEX_SHADER_BIT,
416 VK_PIPELINE_STAGE_TESSELLATION_CONTROL_SHADER_BIT,
417 VK_PIPELINE_STAGE_TESSELLATION_EVALUATION_SHADER_BIT,
418 VK_PIPELINE_STAGE_GEOMETRY_SHADER_BIT,
419 VK_PIPELINE_STAGE_FRAGMENT_SHADER_BIT,
420 VK_PIPELINE_STAGE_EARLY_FRAGMENT_TESTS_BIT,
421 VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT,
422 VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT,
423 VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT,
424 VK_PIPELINE_STAGE_TRANSFER_BIT,
425 VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
426 VK_PIPELINE_STAGE_HOST_BIT,
427 VK_PIPELINE_STAGE_ALL_GRAPHICS_BIT,
428 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
429 VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT,
430 VK_PIPELINE_STAGE_CONDITIONAL_RENDERING_BIT_EXT,
431 VK_PIPELINE_STAGE_RAY_TRACING_SHADER_BIT_KHR,
432 VK_PIPELINE_STAGE_ACCELERATION_STRUCTURE_BUILD_BIT_KHR,
433 VK_PIPELINE_STAGE_SHADING_RATE_IMAGE_BIT_NV,
434 VK_PIPELINE_STAGE_TASK_SHADER_BIT_NV,
435 VK_PIPELINE_STAGE_MESH_SHADER_BIT_NV,
436 VK_PIPELINE_STAGE_FRAGMENT_DENSITY_PROCESS_BIT_EXT,
437 VK_PIPELINE_STAGE_COMMAND_PREPROCESS_BIT_NV,
438 VK_PIPELINE_STAGE_NONE_KHR,
439 };
440
441 if (stage > static_cast<deUint64>(std::numeric_limits<deUint32>::max()))
442 return false;
443
444 return (allowedStages.find(static_cast<deUint32>(stage)) != allowedStages.end());
445 }
446
isAccessFlagAllowed(VkAccessFlags2KHR access) const447 bool isAccessFlagAllowed(VkAccessFlags2KHR access) const
448 {
449 // synchronization2 suports more access flags then legacy synchronization
450 // and so SynchronizationWrapper can only be used for cases that
451 // operate on access flags also supported by legacy synchronization
452 // NOTE: if some tests hits assertion that uses this method then this
453 // test should not use synchronizationWrapper - it should be synchronization2 exclusive
454
455 static const std::set<deUint32> allowedAccessFlags
456 {
457 VK_ACCESS_INDIRECT_COMMAND_READ_BIT,
458 VK_ACCESS_INDEX_READ_BIT,
459 VK_ACCESS_VERTEX_ATTRIBUTE_READ_BIT,
460 VK_ACCESS_UNIFORM_READ_BIT,
461 VK_ACCESS_INPUT_ATTACHMENT_READ_BIT,
462 VK_ACCESS_SHADER_READ_BIT,
463 VK_ACCESS_SHADER_WRITE_BIT,
464 VK_ACCESS_COLOR_ATTACHMENT_READ_BIT,
465 VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT,
466 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT,
467 VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
468 VK_ACCESS_TRANSFER_READ_BIT,
469 VK_ACCESS_TRANSFER_WRITE_BIT,
470 VK_ACCESS_HOST_READ_BIT,
471 VK_ACCESS_HOST_WRITE_BIT,
472 VK_ACCESS_MEMORY_READ_BIT,
473 VK_ACCESS_MEMORY_WRITE_BIT,
474 VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT,
475 VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_READ_BIT_EXT,
476 VK_ACCESS_TRANSFORM_FEEDBACK_COUNTER_WRITE_BIT_EXT,
477 VK_ACCESS_CONDITIONAL_RENDERING_READ_BIT_EXT,
478 VK_ACCESS_COLOR_ATTACHMENT_READ_NONCOHERENT_BIT_EXT,
479 VK_ACCESS_ACCELERATION_STRUCTURE_READ_BIT_KHR,
480 VK_ACCESS_ACCELERATION_STRUCTURE_WRITE_BIT_KHR,
481 VK_ACCESS_SHADING_RATE_IMAGE_READ_BIT_NV ,
482 VK_ACCESS_FRAGMENT_DENSITY_MAP_READ_BIT_EXT,
483 VK_ACCESS_COMMAND_PREPROCESS_READ_BIT_NV,
484 VK_ACCESS_COMMAND_PREPROCESS_WRITE_BIT_NV,
485 VK_ACCESS_NONE_KHR,
486 };
487
488 if (access > static_cast<deUint64>(std::numeric_limits<deUint32>::max()))
489 return false;
490
491 return (allowedAccessFlags.find(static_cast<deUint32>(access)) != allowedAccessFlags.end());
492 }
493
494 public:
LegacySynchronizationWrapper(const DeviceInterface & vk,bool usingTimelineSemaphores,deUint32 submitInfoCount=1u)495 LegacySynchronizationWrapper(const DeviceInterface& vk, bool usingTimelineSemaphores, deUint32 submitInfoCount = 1u)
496 : SynchronizationWrapperBase (vk)
497 , m_submited (DE_FALSE)
498 {
499 m_waitSemaphores.reserve(submitInfoCount);
500 m_signalSemaphores.reserve(submitInfoCount);
501 m_waitDstStageMasks.reserve(submitInfoCount);
502 m_commandBuffers.reserve(submitInfoCount);
503 m_submitInfoData.reserve(submitInfoCount);
504
505 if (usingTimelineSemaphores)
506 m_timelineSemaphoreValues.reserve(2 * submitInfoCount);
507 }
508
509 ~LegacySynchronizationWrapper() = default;
510
addSubmitInfo(deUint32 waitSemaphoreInfoCount,const VkSemaphoreSubmitInfoKHR * pWaitSemaphoreInfos,deUint32 commandBufferInfoCount,const VkCommandBufferSubmitInfoKHR * pCommandBufferInfos,deUint32 signalSemaphoreInfoCount,const VkSemaphoreSubmitInfoKHR * pSignalSemaphoreInfos,bool usingWaitTimelineSemaphore,bool usingSignalTimelineSemaphore)511 void addSubmitInfo(deUint32 waitSemaphoreInfoCount,
512 const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos,
513 deUint32 commandBufferInfoCount,
514 const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos,
515 deUint32 signalSemaphoreInfoCount,
516 const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos,
517 bool usingWaitTimelineSemaphore,
518 bool usingSignalTimelineSemaphore) override
519 {
520 m_submitInfoData.push_back(SubmitInfoData{ waitSemaphoreInfoCount, 0, 0, commandBufferInfoCount, 0u, signalSemaphoreInfoCount, 0, 0 });
521 SubmitInfoData& si = m_submitInfoData.back();
522
523 // memorize wait values
524 if (usingWaitTimelineSemaphore)
525 {
526 DE_ASSERT(pWaitSemaphoreInfos);
527 si.waitSemaphoreValueIndexPlusOne = m_timelineSemaphoreValues.size() + 1;
528 for (deUint32 i = 0; i < waitSemaphoreInfoCount; ++i)
529 m_timelineSemaphoreValues.push_back(pWaitSemaphoreInfos[i].value);
530 }
531
532 // memorize signal values
533 if (usingSignalTimelineSemaphore)
534 {
535 DE_ASSERT(pSignalSemaphoreInfos);
536 si.signalSemaphoreValueIndexPlusOne = m_timelineSemaphoreValues.size() + 1;
537 for (deUint32 i = 0; i < signalSemaphoreInfoCount; ++i)
538 m_timelineSemaphoreValues.push_back(pSignalSemaphoreInfos[i].value);
539 }
540
541 // construct list of semaphores that we need to wait on
542 if (waitSemaphoreInfoCount)
543 {
544 si.waitSemaphoreIndex = m_waitSemaphores.size();
545 for (deUint32 i = 0; i < waitSemaphoreInfoCount; ++i)
546 {
547 DE_ASSERT(isStageFlagAllowed(pWaitSemaphoreInfos[i].stageMask));
548 m_waitSemaphores.push_back(pWaitSemaphoreInfos[i].semaphore);
549 m_waitDstStageMasks.push_back(static_cast<VkPipelineStageFlags>(pWaitSemaphoreInfos[i].stageMask));
550 }
551 }
552
553 // construct list of command buffers
554 if (commandBufferInfoCount)
555 {
556 si.commandBufferIndex = static_cast<deUint32>(m_commandBuffers.size());
557 for (deUint32 i = 0; i < commandBufferInfoCount; ++i)
558 m_commandBuffers.push_back(pCommandBufferInfos[i].commandBuffer);
559 }
560
561 // construct list of semaphores that will be signaled
562 if (signalSemaphoreInfoCount)
563 {
564 si.signalSemaphoreIndex = m_signalSemaphores.size();
565 for (deUint32 i = 0; i < signalSemaphoreInfoCount; ++i)
566 m_signalSemaphores.push_back(pSignalSemaphoreInfos[i].semaphore);
567 }
568 }
569
cmdPipelineBarrier(VkCommandBuffer commandBuffer,const VkDependencyInfoKHR * pDependencyInfo) const570 void cmdPipelineBarrier(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo) const override
571 {
572 DE_ASSERT(pDependencyInfo);
573
574 VkPipelineStageFlags srcStageMask = VK_PIPELINE_STAGE_NONE_KHR;
575 VkPipelineStageFlags dstStageMask = VK_PIPELINE_STAGE_NONE_KHR;
576 deUint32 memoryBarrierCount = pDependencyInfo->memoryBarrierCount;
577 VkMemoryBarrier* pMemoryBarriers = DE_NULL;
578 deUint32 bufferMemoryBarrierCount = pDependencyInfo->bufferMemoryBarrierCount;
579 VkBufferMemoryBarrier* pBufferMemoryBarriers = DE_NULL;
580 deUint32 imageMemoryBarrierCount = pDependencyInfo->imageMemoryBarrierCount;
581 VkImageMemoryBarrier* pImageMemoryBarriers = DE_NULL;
582
583 // translate VkMemoryBarrier2KHR to VkMemoryBarrier
584 std::vector<VkMemoryBarrier> memoryBarriers;
585 if (memoryBarrierCount)
586 {
587 memoryBarriers.reserve(memoryBarrierCount);
588 for (deUint32 i = 0; i < memoryBarrierCount; ++i)
589 {
590 const VkMemoryBarrier2KHR& pMemoryBarrier = pDependencyInfo->pMemoryBarriers[i];
591
592 DE_ASSERT(isStageFlagAllowed(pMemoryBarrier.srcStageMask));
593 DE_ASSERT(isStageFlagAllowed(pMemoryBarrier.dstStageMask));
594 DE_ASSERT(isAccessFlagAllowed(pMemoryBarrier.srcAccessMask));
595 DE_ASSERT(isAccessFlagAllowed(pMemoryBarrier.dstAccessMask));
596
597 srcStageMask |= static_cast<VkPipelineStageFlags>(pMemoryBarrier.srcStageMask);
598 dstStageMask |= static_cast<VkPipelineStageFlags>(pMemoryBarrier.dstStageMask);
599 memoryBarriers.push_back(makeMemoryBarrier(
600 static_cast<VkAccessFlags>(pMemoryBarrier.srcAccessMask),
601 static_cast<VkAccessFlags>(pMemoryBarrier.dstAccessMask)
602 ));
603 }
604 pMemoryBarriers = &memoryBarriers[0];
605 }
606
607 // translate VkBufferMemoryBarrier2KHR to VkBufferMemoryBarrier
608 std::vector<VkBufferMemoryBarrier> bufferMemoryBarriers;
609 if (bufferMemoryBarrierCount)
610 {
611 bufferMemoryBarriers.reserve(bufferMemoryBarrierCount);
612 for (deUint32 i = 0; i < bufferMemoryBarrierCount; ++i)
613 {
614 const VkBufferMemoryBarrier2KHR& pBufferMemoryBarrier = pDependencyInfo->pBufferMemoryBarriers[i];
615
616 DE_ASSERT(isStageFlagAllowed(pBufferMemoryBarrier.srcStageMask));
617 DE_ASSERT(isStageFlagAllowed(pBufferMemoryBarrier.dstStageMask));
618 DE_ASSERT(isAccessFlagAllowed(pBufferMemoryBarrier.srcAccessMask));
619 DE_ASSERT(isAccessFlagAllowed(pBufferMemoryBarrier.dstAccessMask));
620
621 srcStageMask |= static_cast<VkPipelineStageFlags>(pBufferMemoryBarrier.srcStageMask);
622 dstStageMask |= static_cast<VkPipelineStageFlags>(pBufferMemoryBarrier.dstStageMask);
623 bufferMemoryBarriers.push_back(makeBufferMemoryBarrier(
624 static_cast<VkAccessFlags>(pBufferMemoryBarrier.srcAccessMask),
625 static_cast<VkAccessFlags>(pBufferMemoryBarrier.dstAccessMask),
626 pBufferMemoryBarrier.buffer,
627 pBufferMemoryBarrier.offset,
628 pBufferMemoryBarrier.size,
629 pBufferMemoryBarrier.srcQueueFamilyIndex,
630 pBufferMemoryBarrier.dstQueueFamilyIndex
631 ));
632 }
633 pBufferMemoryBarriers = &bufferMemoryBarriers[0];
634 }
635
636 // translate VkImageMemoryBarrier2KHR to VkImageMemoryBarrier
637 std::vector<VkImageMemoryBarrier> imageMemoryBarriers;
638 if (imageMemoryBarrierCount)
639 {
640 imageMemoryBarriers.reserve(imageMemoryBarrierCount);
641 for (deUint32 i = 0; i < imageMemoryBarrierCount; ++i)
642 {
643 const VkImageMemoryBarrier2KHR& pImageMemoryBarrier = pDependencyInfo->pImageMemoryBarriers[i];
644
645 DE_ASSERT(isStageFlagAllowed(pImageMemoryBarrier.srcStageMask));
646 DE_ASSERT(isStageFlagAllowed(pImageMemoryBarrier.dstStageMask));
647 DE_ASSERT(isAccessFlagAllowed(pImageMemoryBarrier.srcAccessMask));
648 DE_ASSERT(isAccessFlagAllowed(pImageMemoryBarrier.dstAccessMask));
649
650 srcStageMask |= static_cast<VkPipelineStageFlags>(pImageMemoryBarrier.srcStageMask);
651 dstStageMask |= static_cast<VkPipelineStageFlags>(pImageMemoryBarrier.dstStageMask);
652 imageMemoryBarriers.push_back(makeImageMemoryBarrier(
653 static_cast<VkAccessFlags>(pImageMemoryBarrier.srcAccessMask),
654 static_cast<VkAccessFlags>(pImageMemoryBarrier.dstAccessMask),
655 pImageMemoryBarrier.oldLayout,
656 pImageMemoryBarrier.newLayout,
657 pImageMemoryBarrier.image,
658 pImageMemoryBarrier.subresourceRange,
659 pImageMemoryBarrier.srcQueueFamilyIndex,
660 pImageMemoryBarrier.dstQueueFamilyIndex
661 ));
662 }
663 pImageMemoryBarriers = &imageMemoryBarriers[0];
664 }
665
666 m_vk.cmdPipelineBarrier(
667 commandBuffer,
668 srcStageMask,
669 dstStageMask,
670 (VkDependencyFlags)0,
671 memoryBarrierCount,
672 pMemoryBarriers,
673 bufferMemoryBarrierCount,
674 pBufferMemoryBarriers,
675 imageMemoryBarrierCount,
676 pImageMemoryBarriers
677 );
678 }
679
cmdSetEvent(VkCommandBuffer commandBuffer,VkEvent event,const VkDependencyInfoKHR * pDependencyInfo) const680 void cmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo) const override
681 {
682 DE_ASSERT(pDependencyInfo);
683
684 VkPipelineStageFlags2KHR srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
685 if (pDependencyInfo->pMemoryBarriers)
686 srcStageMask = pDependencyInfo->pMemoryBarriers[0].srcStageMask;
687 if (pDependencyInfo->pBufferMemoryBarriers)
688 srcStageMask = pDependencyInfo->pBufferMemoryBarriers[0].srcStageMask;
689 if (pDependencyInfo->pImageMemoryBarriers)
690 srcStageMask = pDependencyInfo->pImageMemoryBarriers[0].srcStageMask;
691
692 DE_ASSERT(isStageFlagAllowed(srcStageMask));
693 m_vk.cmdSetEvent(commandBuffer, event, static_cast<VkPipelineStageFlags>(srcStageMask));
694 }
695
cmdResetEvent(VkCommandBuffer commandBuffer,VkEvent event,VkPipelineStageFlags2KHR flag) const696 void cmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR flag) const override
697 {
698 DE_ASSERT(isStageFlagAllowed(flag));
699 VkPipelineStageFlags legacyStageMask = static_cast<VkPipelineStageFlags>(flag);
700 m_vk.cmdResetEvent(commandBuffer, event, legacyStageMask);
701 }
702
cmdWaitEvents(VkCommandBuffer commandBuffer,deUint32 eventCount,const VkEvent * pEvents,const VkDependencyInfoKHR * pDependencyInfo) const703 void cmdWaitEvents(VkCommandBuffer commandBuffer, deUint32 eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfo) const override
704 {
705 DE_ASSERT(pDependencyInfo);
706
707 VkPipelineStageFlags2KHR srcStageMask = VK_PIPELINE_STAGE_2_TOP_OF_PIPE_BIT_KHR;
708 VkPipelineStageFlags2KHR dstStageMask = VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT_KHR;
709 deUint32 memoryBarrierCount = pDependencyInfo->memoryBarrierCount;
710 deUint32 bufferMemoryBarrierCount = pDependencyInfo->bufferMemoryBarrierCount;
711 deUint32 imageMemoryBarrierCount = pDependencyInfo->imageMemoryBarrierCount;
712 VkMemoryBarrier* pMemoryBarriers = DE_NULL;
713 VkBufferMemoryBarrier* pBufferMemoryBarriers = DE_NULL;
714 VkImageMemoryBarrier* pImageMemoryBarriers = DE_NULL;
715 std::vector<VkMemoryBarrier> memoryBarriers;
716 std::vector<VkBufferMemoryBarrier> bufferMemoryBarriers;
717 std::vector<VkImageMemoryBarrier> imageMemoryBarriers;
718
719 if (pDependencyInfo->pMemoryBarriers)
720 {
721 srcStageMask = pDependencyInfo->pMemoryBarriers[0].srcStageMask;
722 dstStageMask = pDependencyInfo->pMemoryBarriers[0].dstStageMask;
723
724 memoryBarriers.reserve(memoryBarrierCount);
725 for (deUint32 i = 0; i < memoryBarrierCount; ++i)
726 {
727 const VkMemoryBarrier2KHR& mb = pDependencyInfo->pMemoryBarriers[i];
728 DE_ASSERT(isAccessFlagAllowed(mb.srcAccessMask));
729 DE_ASSERT(isAccessFlagAllowed(mb.dstAccessMask));
730 memoryBarriers.push_back(
731 makeMemoryBarrier(
732 static_cast<VkAccessFlags>(mb.srcAccessMask),
733 static_cast<VkAccessFlags>(mb.dstAccessMask)
734 )
735 );
736 }
737 pMemoryBarriers = &memoryBarriers[0];
738 }
739 if (pDependencyInfo->pBufferMemoryBarriers)
740 {
741 srcStageMask = pDependencyInfo->pBufferMemoryBarriers[0].srcStageMask;
742 dstStageMask = pDependencyInfo->pBufferMemoryBarriers[0].dstStageMask;
743
744 bufferMemoryBarriers.reserve(bufferMemoryBarrierCount);
745 for (deUint32 i = 0; i < bufferMemoryBarrierCount; ++i)
746 {
747 const VkBufferMemoryBarrier2KHR& bmb = pDependencyInfo->pBufferMemoryBarriers[i];
748 DE_ASSERT(isAccessFlagAllowed(bmb.srcAccessMask));
749 DE_ASSERT(isAccessFlagAllowed(bmb.dstAccessMask));
750 bufferMemoryBarriers.push_back(
751 makeBufferMemoryBarrier(
752 static_cast<VkAccessFlags>(bmb.srcAccessMask),
753 static_cast<VkAccessFlags>(bmb.dstAccessMask),
754 bmb.buffer,
755 bmb.offset,
756 bmb.size,
757 bmb.srcQueueFamilyIndex,
758 bmb.dstQueueFamilyIndex
759 )
760 );
761 }
762 pBufferMemoryBarriers = &bufferMemoryBarriers[0];
763 }
764 if (pDependencyInfo->pImageMemoryBarriers)
765 {
766 srcStageMask = pDependencyInfo->pImageMemoryBarriers[0].srcStageMask;
767 dstStageMask = pDependencyInfo->pImageMemoryBarriers[0].dstStageMask;
768
769 imageMemoryBarriers.reserve(imageMemoryBarrierCount);
770 for (deUint32 i = 0; i < imageMemoryBarrierCount; ++i)
771 {
772 const VkImageMemoryBarrier2KHR& imb = pDependencyInfo->pImageMemoryBarriers[i];
773 DE_ASSERT(isAccessFlagAllowed(imb.srcAccessMask));
774 DE_ASSERT(isAccessFlagAllowed(imb.dstAccessMask));
775 imageMemoryBarriers.push_back(
776 makeImageMemoryBarrier(
777 static_cast<VkAccessFlags>(imb.srcAccessMask),
778 static_cast<VkAccessFlags>(imb.dstAccessMask),
779 imb.oldLayout,
780 imb.newLayout,
781 imb.image,
782 imb.subresourceRange,
783 imb.srcQueueFamilyIndex,
784 imb.dstQueueFamilyIndex
785 )
786 );
787 }
788 pImageMemoryBarriers = &imageMemoryBarriers[0];
789 }
790
791 DE_ASSERT(isStageFlagAllowed(srcStageMask));
792 DE_ASSERT(isStageFlagAllowed(dstStageMask));
793 m_vk.cmdWaitEvents(commandBuffer, eventCount, pEvents,
794 static_cast<VkPipelineStageFlags>(srcStageMask), static_cast<VkPipelineStageFlags>(dstStageMask),
795 memoryBarrierCount, pMemoryBarriers, bufferMemoryBarrierCount, pBufferMemoryBarriers, imageMemoryBarrierCount, pImageMemoryBarriers);
796 }
797
queueSubmit(VkQueue queue,VkFence fence)798 VkResult queueSubmit(VkQueue queue, VkFence fence) override
799 {
800 // make sure submit info was added
801 DE_ASSERT(!m_submitInfoData.empty());
802
803 // make sure separate LegacySynchronizationWrapper is created per single submit
804 DE_ASSERT(!m_submited);
805
806 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 });
807
808 std::vector<VkTimelineSemaphoreSubmitInfo> timelineSemaphoreSubmitInfo;
809 timelineSemaphoreSubmitInfo.reserve(m_submitInfoData.size());
810
811 // translate indexes from m_submitInfoData to pointers and construct VkSubmitInfo
812 for (deUint32 i = 0; i < m_submitInfoData.size(); ++i)
813 {
814 auto& data = m_submitInfoData[i];
815 VkSubmitInfo& si = submitInfo[i];
816
817 si.waitSemaphoreCount = data.waitSemaphoreCount;
818 si.commandBufferCount = data.commandBufferCount;
819 si.signalSemaphoreCount = data.signalSemaphoreCount;
820
821 if (data.waitSemaphoreValueIndexPlusOne || data.signalSemaphoreValueIndexPlusOne)
822 {
823 deUint64* pWaitSemaphoreValues = DE_NULL;
824 if (data.waitSemaphoreValueIndexPlusOne)
825 pWaitSemaphoreValues = &m_timelineSemaphoreValues[data.waitSemaphoreValueIndexPlusOne - 1];
826
827 deUint64* pSignalSemaphoreValues = DE_NULL;
828 if (data.signalSemaphoreValueIndexPlusOne)
829 pSignalSemaphoreValues = &m_timelineSemaphoreValues[data.signalSemaphoreValueIndexPlusOne - 1];
830
831 timelineSemaphoreSubmitInfo.push_back({
832 VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, // VkStructureType sType;
833 DE_NULL, // const void* pNext;
834 data.waitSemaphoreCount, // deUint32 waitSemaphoreValueCount
835 pWaitSemaphoreValues, // const deUint64* pWaitSemaphoreValues
836 data.signalSemaphoreCount, // deUint32 signalSemaphoreValueCount
837 pSignalSemaphoreValues // const deUint64* pSignalSemaphoreValues
838 });
839 si.pNext = &timelineSemaphoreSubmitInfo.back();
840 }
841
842 if (data.waitSemaphoreCount)
843 {
844 si.pWaitSemaphores = &m_waitSemaphores[data.waitSemaphoreIndex];
845 si.pWaitDstStageMask = &m_waitDstStageMasks[data.waitSemaphoreIndex];
846 }
847
848 if (data.commandBufferCount)
849 si.pCommandBuffers = &m_commandBuffers[data.commandBufferIndex];
850
851 if (data.signalSemaphoreCount)
852 si.pSignalSemaphores = &m_signalSemaphores[data.signalSemaphoreIndex];
853 }
854
855 m_submited = DE_TRUE;
856 return m_vk.queueSubmit(queue, static_cast<deUint32>(submitInfo.size()), &submitInfo[0], fence);
857 }
858
859 protected:
860
861 std::vector<VkSemaphore> m_waitSemaphores;
862 std::vector<VkSemaphore> m_signalSemaphores;
863 std::vector<VkPipelineStageFlags> m_waitDstStageMasks;
864 std::vector<VkCommandBuffer> m_commandBuffers;
865 std::vector<SubmitInfoData> m_submitInfoData;
866 std::vector<deUint64> m_timelineSemaphoreValues;
867 bool m_submited;
868 };
869
870 class Synchronization2Wrapper : public SynchronizationWrapperBase
871 {
872 public:
Synchronization2Wrapper(const DeviceInterface & vk,deUint32 submitInfoCount)873 Synchronization2Wrapper(const DeviceInterface& vk, deUint32 submitInfoCount)
874 : SynchronizationWrapperBase(vk)
875 {
876 m_submitInfo.reserve(submitInfoCount);
877 }
878
879 ~Synchronization2Wrapper() = default;
880
addSubmitInfo(deUint32 waitSemaphoreInfoCount,const VkSemaphoreSubmitInfoKHR * pWaitSemaphoreInfos,deUint32 commandBufferInfoCount,const VkCommandBufferSubmitInfoKHR * pCommandBufferInfos,deUint32 signalSemaphoreInfoCount,const VkSemaphoreSubmitInfoKHR * pSignalSemaphoreInfos,bool usingWaitTimelineSemaphore,bool usingSignalTimelineSemaphore)881 void addSubmitInfo(deUint32 waitSemaphoreInfoCount,
882 const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos,
883 deUint32 commandBufferInfoCount,
884 const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos,
885 deUint32 signalSemaphoreInfoCount,
886 const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos,
887 bool usingWaitTimelineSemaphore,
888 bool usingSignalTimelineSemaphore) override
889 {
890 DE_UNREF(usingWaitTimelineSemaphore);
891 DE_UNREF(usingSignalTimelineSemaphore);
892
893 m_submitInfo.push_back(VkSubmitInfo2KHR{
894 VK_STRUCTURE_TYPE_SUBMIT_INFO_2_KHR, // VkStructureType sType
895 DE_NULL, // const void* pNext
896 0u, // VkSubmitFlagsKHR flags
897 waitSemaphoreInfoCount, // deUint32 waitSemaphoreInfoCount
898 pWaitSemaphoreInfos, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
899 commandBufferInfoCount, // deUint32 commandBufferInfoCount
900 pCommandBufferInfos, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
901 signalSemaphoreInfoCount, // deUint32 signalSemaphoreInfoCount
902 pSignalSemaphoreInfos // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
903 });
904 }
905
cmdPipelineBarrier(VkCommandBuffer commandBuffer,const VkDependencyInfoKHR * pDependencyInfo) const906 void cmdPipelineBarrier(VkCommandBuffer commandBuffer, const VkDependencyInfoKHR* pDependencyInfo) const override
907 {
908 m_vk.cmdPipelineBarrier2KHR(commandBuffer, pDependencyInfo);
909 }
910
cmdSetEvent(VkCommandBuffer commandBuffer,VkEvent event,const VkDependencyInfoKHR * pDependencyInfo) const911 void cmdSetEvent(VkCommandBuffer commandBuffer, VkEvent event, const VkDependencyInfoKHR* pDependencyInfo) const override
912 {
913 m_vk.cmdSetEvent2KHR(commandBuffer, event, pDependencyInfo);
914 }
915
cmdWaitEvents(VkCommandBuffer commandBuffer,deUint32 eventCount,const VkEvent * pEvents,const VkDependencyInfoKHR * pDependencyInfo) const916 void cmdWaitEvents(VkCommandBuffer commandBuffer, deUint32 eventCount, const VkEvent* pEvents, const VkDependencyInfoKHR* pDependencyInfo) const override
917 {
918 m_vk.cmdWaitEvents2KHR(commandBuffer, eventCount, pEvents, pDependencyInfo);
919 }
920
cmdResetEvent(VkCommandBuffer commandBuffer,VkEvent event,VkPipelineStageFlags2KHR flag) const921 void cmdResetEvent(VkCommandBuffer commandBuffer, VkEvent event, VkPipelineStageFlags2KHR flag) const override
922 {
923 m_vk.cmdResetEvent2KHR(commandBuffer, event, flag);
924 }
925
queueSubmit(VkQueue queue,VkFence fence)926 VkResult queueSubmit(VkQueue queue, VkFence fence) override
927 {
928 return m_vk.queueSubmit2KHR(queue, static_cast<deUint32>(m_submitInfo.size()), &m_submitInfo[0], fence);
929 }
930
931 protected:
932
933 std::vector<VkSubmitInfo2KHR> m_submitInfo;
934 };
935
getSynchronizationWrapper(SynchronizationType type,const DeviceInterface & vk,bool usingTimelineSemaphores,deUint32 submitInfoCount)936 SynchronizationWrapperPtr getSynchronizationWrapper(SynchronizationType type,
937 const DeviceInterface& vk,
938 bool usingTimelineSemaphores,
939 deUint32 submitInfoCount)
940 {
941 return (type == SynchronizationType::LEGACY)
942 ? SynchronizationWrapperPtr(new LegacySynchronizationWrapper(vk, usingTimelineSemaphores, submitInfoCount))
943 : SynchronizationWrapperPtr(new Synchronization2Wrapper(vk, submitInfoCount));
944 }
945
submitCommandsAndWait(SynchronizationWrapperPtr synchronizationWrapper,const DeviceInterface & vk,const VkDevice device,const VkQueue queue,const VkCommandBuffer cmdBuffer)946 void submitCommandsAndWait(SynchronizationWrapperPtr synchronizationWrapper,
947 const DeviceInterface& vk,
948 const VkDevice device,
949 const VkQueue queue,
950 const VkCommandBuffer cmdBuffer)
951 {
952 VkCommandBufferSubmitInfoKHR commandBufferInfoCount = makeCommonCommandBufferSubmitInfo(cmdBuffer);
953
954 synchronizationWrapper->addSubmitInfo(
955 0u, // deUint32 waitSemaphoreInfoCount
956 DE_NULL, // const VkSemaphoreSubmitInfoKHR* pWaitSemaphoreInfos
957 1u, // deUint32 commandBufferInfoCount
958 &commandBufferInfoCount, // const VkCommandBufferSubmitInfoKHR* pCommandBufferInfos
959 0u, // deUint32 signalSemaphoreInfoCount
960 DE_NULL // const VkSemaphoreSubmitInfoKHR* pSignalSemaphoreInfos
961 );
962
963 const Unique<VkFence> fence(createFence(vk, device));
964 VK_CHECK(synchronizationWrapper->queueSubmit(queue, *fence));
965 VK_CHECK(vk.waitForFences(device, 1u, &fence.get(), DE_TRUE, ~0ull));
966 }
967
requireFeatures(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const FeatureFlags flags)968 void requireFeatures (const InstanceInterface& vki, const VkPhysicalDevice physDevice, const FeatureFlags flags)
969 {
970 const VkPhysicalDeviceFeatures features = getPhysicalDeviceFeatures(vki, physDevice);
971
972 if (((flags & FEATURE_TESSELLATION_SHADER) != 0) && !features.tessellationShader)
973 throw tcu::NotSupportedError("Tessellation shader not supported");
974
975 if (((flags & FEATURE_GEOMETRY_SHADER) != 0) && !features.geometryShader)
976 throw tcu::NotSupportedError("Geometry shader not supported");
977
978 if (((flags & FEATURE_SHADER_FLOAT_64) != 0) && !features.shaderFloat64)
979 throw tcu::NotSupportedError("Double-precision floats not supported");
980
981 if (((flags & FEATURE_VERTEX_PIPELINE_STORES_AND_ATOMICS) != 0) && !features.vertexPipelineStoresAndAtomics)
982 throw tcu::NotSupportedError("SSBO and image writes not supported in vertex pipeline");
983
984 if (((flags & FEATURE_FRAGMENT_STORES_AND_ATOMICS) != 0) && !features.fragmentStoresAndAtomics)
985 throw tcu::NotSupportedError("SSBO and image writes not supported in fragment shader");
986
987 if (((flags & FEATURE_SHADER_TESSELLATION_AND_GEOMETRY_POINT_SIZE) != 0) && !features.shaderTessellationAndGeometryPointSize)
988 throw tcu::NotSupportedError("Tessellation and geometry shaders don't support PointSize built-in");
989 }
990
requireStorageImageSupport(const InstanceInterface & vki,const VkPhysicalDevice physDevice,const VkFormat fmt)991 void requireStorageImageSupport(const InstanceInterface& vki, const VkPhysicalDevice physDevice, const VkFormat fmt)
992 {
993 const VkFormatProperties p = getPhysicalDeviceFormatProperties(vki, physDevice, fmt);
994 if ((p.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT) == 0)
995 throw tcu::NotSupportedError("Storage image format not supported");
996 }
997
getResourceName(const ResourceDescription & resource)998 std::string getResourceName (const ResourceDescription& resource)
999 {
1000 std::ostringstream str;
1001
1002 if ((resource.type == RESOURCE_TYPE_BUFFER) ||
1003 (resource.type == RESOURCE_TYPE_INDEX_BUFFER))
1004 {
1005 str << "buffer_" << resource.size.x();
1006 }
1007 else if (resource.type == RESOURCE_TYPE_IMAGE)
1008 {
1009 str << "image_" << resource.size.x()
1010 << (resource.size.y() > 0 ? "x" + de::toString(resource.size.y()) : "")
1011 << (resource.size.z() > 0 ? "x" + de::toString(resource.size.z()) : "")
1012 << "_" << de::toLower(getFormatName(resource.imageFormat)).substr(10);
1013 }
1014 else if (isIndirectBuffer(resource.type))
1015 str << "indirect_buffer";
1016 else
1017 DE_ASSERT(0);
1018
1019 return str.str();
1020 }
1021
isIndirectBuffer(const ResourceType type)1022 bool isIndirectBuffer (const ResourceType type)
1023 {
1024 switch (type)
1025 {
1026 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW:
1027 case RESOURCE_TYPE_INDIRECT_BUFFER_DRAW_INDEXED:
1028 case RESOURCE_TYPE_INDIRECT_BUFFER_DISPATCH:
1029 return true;
1030
1031 default:
1032 return false;
1033 }
1034 }
1035
makeCommonCommandBufferSubmitInfo(const VkCommandBuffer cmdBuf)1036 VkCommandBufferSubmitInfoKHR makeCommonCommandBufferSubmitInfo (const VkCommandBuffer cmdBuf)
1037 {
1038 return
1039 {
1040 VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO_KHR, // VkStructureType sType
1041 DE_NULL, // const void* pNext
1042 cmdBuf, // VkCommandBuffer commandBuffer
1043 0u // uint32_t deviceMask
1044 };
1045 }
1046
makeCommonSemaphoreSubmitInfo(VkSemaphore semaphore,deUint64 value,VkPipelineStageFlags2KHR stageMask)1047 VkSemaphoreSubmitInfoKHR makeCommonSemaphoreSubmitInfo(VkSemaphore semaphore, deUint64 value, VkPipelineStageFlags2KHR stageMask)
1048 {
1049 return
1050 {
1051 VK_STRUCTURE_TYPE_SEMAPHORE_SUBMIT_INFO_KHR, // VkStructureType sType
1052 DE_NULL, // const void* pNext
1053 semaphore, // VkSemaphore semaphore
1054 value, // deUint64 value
1055 stageMask, // VkPipelineStageFlags2KHR stageMask
1056 0u // deUint32 deviceIndex
1057 };
1058 }
1059
makeCommonDependencyInfo(const VkMemoryBarrier2KHR * pMemoryBarrier,const VkBufferMemoryBarrier2KHR * pBufferMemoryBarrier,const VkImageMemoryBarrier2KHR * pImageMemoryBarrier)1060 VkDependencyInfoKHR makeCommonDependencyInfo(const VkMemoryBarrier2KHR* pMemoryBarrier, const VkBufferMemoryBarrier2KHR* pBufferMemoryBarrier, const VkImageMemoryBarrier2KHR* pImageMemoryBarrier)
1061 {
1062 return
1063 {
1064 VK_STRUCTURE_TYPE_DEPENDENCY_INFO_KHR, // VkStructureType sType
1065 DE_NULL, // const void* pNext
1066 VK_DEPENDENCY_BY_REGION_BIT, // VkDependencyFlags dependencyFlags
1067 !!pMemoryBarrier, // deUint32 memoryBarrierCount
1068 pMemoryBarrier, // const VkMemoryBarrier2KHR* pMemoryBarriers
1069 !!pBufferMemoryBarrier, // deUint32 bufferMemoryBarrierCount
1070 pBufferMemoryBarrier, // const VkBufferMemoryBarrier2KHR* pBufferMemoryBarriers
1071 !!pImageMemoryBarrier, // deUint32 imageMemoryBarrierCount
1072 pImageMemoryBarrier // const VkImageMemoryBarrier2KHR* pImageMemoryBarriers
1073 };
1074 }
1075
PipelineCacheData(void)1076 PipelineCacheData::PipelineCacheData (void)
1077 {
1078 }
1079
~PipelineCacheData(void)1080 PipelineCacheData::~PipelineCacheData (void)
1081 {
1082 }
1083
createPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device) const1084 vk::Move<VkPipelineCache> PipelineCacheData::createPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device) const
1085 {
1086 const de::ScopedLock dataLock (m_lock);
1087 const struct vk::VkPipelineCacheCreateInfo params =
1088 {
1089 vk::VK_STRUCTURE_TYPE_PIPELINE_CACHE_CREATE_INFO,
1090 DE_NULL,
1091 (vk::VkPipelineCacheCreateFlags)0,
1092 (deUintptr)m_data.size(),
1093 (m_data.empty() ? DE_NULL : &m_data[0])
1094 };
1095
1096 return vk::createPipelineCache(vk, device, ¶ms);
1097 }
1098
setFromPipelineCache(const vk::DeviceInterface & vk,const vk::VkDevice device,const vk::VkPipelineCache pipelineCache)1099 void PipelineCacheData::setFromPipelineCache (const vk::DeviceInterface& vk, const vk::VkDevice device, const vk::VkPipelineCache pipelineCache)
1100 {
1101 const de::ScopedLock dataLock (m_lock);
1102 deUintptr dataSize = 0;
1103
1104 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, DE_NULL));
1105
1106 m_data.resize(dataSize);
1107
1108 if (dataSize > 0)
1109 VK_CHECK(vk.getPipelineCacheData(device, pipelineCache, &dataSize, &m_data[0]));
1110 }
1111
1112 } // synchronization
1113 } // vkt
1114