1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // SecondaryCommandBuffer:
7 // CPU-side storage of commands to delay GPU-side allocation until commands are submitted.
8 //
9
10 #include "libANGLE/renderer/vulkan/SecondaryCommandBuffer.h"
11 #include "common/debug.h"
12 #include "libANGLE/renderer/vulkan/vk_utils.h"
13 #include "libANGLE/trace.h"
14
15 namespace rx
16 {
17 namespace vk
18 {
19 namespace priv
20 {
21 namespace
22 {
GetCommandString(CommandID id)23 const char *GetCommandString(CommandID id)
24 {
25 switch (id)
26 {
27 case CommandID::Invalid:
28 return "--Invalid--";
29 case CommandID::BeginDebugUtilsLabel:
30 return "BeginDebugUtilsLabel";
31 case CommandID::BeginQuery:
32 return "BeginQuery";
33 case CommandID::BeginTransformFeedback:
34 return "BeginTransformFeedback";
35 case CommandID::BindComputePipeline:
36 return "BindComputePipeline";
37 case CommandID::BindDescriptorSets:
38 return "BindDescriptorSets";
39 case CommandID::BindGraphicsPipeline:
40 return "BindGraphicsPipeline";
41 case CommandID::BindIndexBuffer:
42 return "BindIndexBuffer";
43 case CommandID::BindTransformFeedbackBuffers:
44 return "BindTransformFeedbackBuffers";
45 case CommandID::BindVertexBuffers:
46 return "BindVertexBuffers";
47 case CommandID::BindVertexBuffers2:
48 return "BindVertexBuffers2";
49 case CommandID::BlitImage:
50 return "BlitImage";
51 case CommandID::BufferBarrier:
52 return "BufferBarrier";
53 case CommandID::ClearAttachments:
54 return "ClearAttachments";
55 case CommandID::ClearColorImage:
56 return "ClearColorImage";
57 case CommandID::ClearDepthStencilImage:
58 return "ClearDepthStencilImage";
59 case CommandID::CopyBuffer:
60 return "CopyBuffer";
61 case CommandID::CopyBufferToImage:
62 return "CopyBufferToImage";
63 case CommandID::CopyImage:
64 return "CopyImage";
65 case CommandID::CopyImageToBuffer:
66 return "CopyImageToBuffer";
67 case CommandID::Dispatch:
68 return "Dispatch";
69 case CommandID::DispatchIndirect:
70 return "DispatchIndirect";
71 case CommandID::Draw:
72 return "Draw";
73 case CommandID::DrawIndexed:
74 return "DrawIndexed";
75 case CommandID::DrawIndexedBaseVertex:
76 return "DrawIndexedBaseVertex";
77 case CommandID::DrawIndexedIndirect:
78 return "DrawIndexedIndirect";
79 case CommandID::DrawIndexedInstanced:
80 return "DrawIndexedInstanced";
81 case CommandID::DrawIndexedInstancedBaseVertex:
82 return "DrawIndexedInstancedBaseVertex";
83 case CommandID::DrawIndexedInstancedBaseVertexBaseInstance:
84 return "DrawIndexedInstancedBaseVertexBaseInstance";
85 case CommandID::DrawIndirect:
86 return "DrawIndirect";
87 case CommandID::DrawInstanced:
88 return "DrawInstanced";
89 case CommandID::DrawInstancedBaseInstance:
90 return "DrawInstancedBaseInstance";
91 case CommandID::EndDebugUtilsLabel:
92 return "EndDebugUtilsLabel";
93 case CommandID::EndQuery:
94 return "EndQuery";
95 case CommandID::EndTransformFeedback:
96 return "EndTransformFeedback";
97 case CommandID::FillBuffer:
98 return "FillBuffer";
99 case CommandID::ImageBarrier:
100 return "ImageBarrier";
101 case CommandID::ImageWaitEvent:
102 return "ImageWaitEvent";
103 case CommandID::InsertDebugUtilsLabel:
104 return "InsertDebugUtilsLabel";
105 case CommandID::MemoryBarrier:
106 return "MemoryBarrier";
107 case CommandID::NextSubpass:
108 return "NextSubpass";
109 case CommandID::PipelineBarrier:
110 return "PipelineBarrier";
111 case CommandID::PushConstants:
112 return "PushConstants";
113 case CommandID::ResetEvent:
114 return "ResetEvent";
115 case CommandID::ResetQueryPool:
116 return "ResetQueryPool";
117 case CommandID::ResolveImage:
118 return "ResolveImage";
119 case CommandID::SetBlendConstants:
120 return "SetBlendConstants";
121 case CommandID::SetCullMode:
122 return "SetCullMode";
123 case CommandID::SetDepthBias:
124 return "SetDepthBias";
125 case CommandID::SetDepthBiasEnable:
126 return "SetDepthBiasEnable";
127 case CommandID::SetDepthCompareOp:
128 return "SetDepthCompareOp";
129 case CommandID::SetDepthTestEnable:
130 return "SetDepthTestEnable";
131 case CommandID::SetDepthWriteEnable:
132 return "SetDepthWriteEnable";
133 case CommandID::SetEvent:
134 return "SetEvent";
135 case CommandID::SetFragmentShadingRate:
136 return "SetFragmentShadingRate";
137 case CommandID::SetFrontFace:
138 return "SetFrontFace";
139 case CommandID::SetLineWidth:
140 return "SetLineWidth";
141 case CommandID::SetLogicOp:
142 return "SetLogicOp";
143 case CommandID::SetPrimitiveRestartEnable:
144 return "SetPrimitiveRestartEnable";
145 case CommandID::SetRasterizerDiscardEnable:
146 return "SetRasterizerDiscardEnable";
147 case CommandID::SetScissor:
148 return "SetScissor";
149 case CommandID::SetStencilCompareMask:
150 return "SetStencilCompareMask";
151 case CommandID::SetStencilOp:
152 return "SetStencilOp";
153 case CommandID::SetStencilReference:
154 return "SetStencilReference";
155 case CommandID::SetStencilTestEnable:
156 return "SetStencilTestEnable";
157 case CommandID::SetStencilWriteMask:
158 return "SetStencilWriteMask";
159 case CommandID::SetVertexInput:
160 return "SetVertexInput";
161 case CommandID::SetViewport:
162 return "SetViewport";
163 case CommandID::WaitEvents:
164 return "WaitEvents";
165 case CommandID::WriteTimestamp:
166 return "WriteTimestamp";
167 default:
168 // Need this to work around MSVC warning 4715.
169 UNREACHABLE();
170 return "--unreachable--";
171 }
172 }
173
174 // Given the pointer to the parameter struct, returns the pointer to the first array parameter.
175 template <typename T, typename StructType>
GetFirstArrayParameter(StructType * param)176 ANGLE_INLINE const T *GetFirstArrayParameter(StructType *param)
177 {
178 // The first array parameter is always right after the struct itself.
179 return Offset<T>(param, sizeof(*param));
180 }
181
182 // Given the pointer to one array parameter (and its array count), returns the pointer to the next
183 // array parameter.
184 template <typename NextT, typename PrevT>
GetNextArrayParameter(const PrevT * array,size_t arrayLen)185 ANGLE_INLINE const NextT *GetNextArrayParameter(const PrevT *array, size_t arrayLen)
186 {
187 const size_t arrayAllocateBytes = roundUpPow2<size_t>(sizeof(*array) * arrayLen, 8u);
188 return Offset<NextT>(array, arrayAllocateBytes);
189 }
190 } // namespace
191
NextCommand(const CommandHeader * command)192 ANGLE_INLINE const CommandHeader *NextCommand(const CommandHeader *command)
193 {
194 return reinterpret_cast<const CommandHeader *>(reinterpret_cast<const uint8_t *>(command) +
195 command->size);
196 }
197
198 // Parse the cmds in this cmd buffer into given primary cmd buffer
executeCommands(PrimaryCommandBuffer * primary)199 void SecondaryCommandBuffer::executeCommands(PrimaryCommandBuffer *primary)
200 {
201 VkCommandBuffer cmdBuffer = primary->getHandle();
202
203 ANGLE_TRACE_EVENT0("gpu.angle", "SecondaryCommandBuffer::executeCommands");
204
205 // Used for ring buffer allocators only.
206 mCommandAllocator.terminateLastCommandBlock();
207
208 for (const CommandHeader *command : mCommands)
209 {
210 for (const CommandHeader *currentCommand = command;
211 currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand))
212 {
213 switch (currentCommand->id)
214 {
215 case CommandID::BeginDebugUtilsLabel:
216 {
217 const DebugUtilsLabelParams *params =
218 getParamPtr<DebugUtilsLabelParams>(currentCommand);
219 const char *pLabelName = GetFirstArrayParameter<char>(params);
220 const VkDebugUtilsLabelEXT label = {
221 VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT,
222 nullptr,
223 pLabelName,
224 {params->color[0], params->color[1], params->color[2], params->color[3]}};
225 ASSERT(vkCmdBeginDebugUtilsLabelEXT);
226 vkCmdBeginDebugUtilsLabelEXT(cmdBuffer, &label);
227 break;
228 }
229 case CommandID::BeginQuery:
230 {
231 const BeginQueryParams *params = getParamPtr<BeginQueryParams>(currentCommand);
232 vkCmdBeginQuery(cmdBuffer, params->queryPool, params->query, 0);
233 break;
234 }
235 case CommandID::BeginTransformFeedback:
236 {
237 const BeginTransformFeedbackParams *params =
238 getParamPtr<BeginTransformFeedbackParams>(currentCommand);
239 const VkBuffer *counterBuffers = GetFirstArrayParameter<VkBuffer>(params);
240 const VkDeviceSize *counterBufferOffsets =
241 reinterpret_cast<const VkDeviceSize *>(counterBuffers +
242 params->bufferCount);
243 vkCmdBeginTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount,
244 counterBuffers, counterBufferOffsets);
245 break;
246 }
247 case CommandID::BindComputePipeline:
248 {
249 const BindPipelineParams *params =
250 getParamPtr<BindPipelineParams>(currentCommand);
251 vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, params->pipeline);
252 break;
253 }
254 case CommandID::BindDescriptorSets:
255 {
256 const BindDescriptorSetParams *params =
257 getParamPtr<BindDescriptorSetParams>(currentCommand);
258 const VkDescriptorSet *descriptorSets =
259 GetFirstArrayParameter<VkDescriptorSet>(params);
260 const uint32_t *dynamicOffsets =
261 GetNextArrayParameter<uint32_t>(descriptorSets, params->descriptorSetCount);
262 vkCmdBindDescriptorSets(cmdBuffer, params->pipelineBindPoint, params->layout,
263 params->firstSet, params->descriptorSetCount,
264 descriptorSets, params->dynamicOffsetCount,
265 dynamicOffsets);
266 break;
267 }
268 case CommandID::BindGraphicsPipeline:
269 {
270 const BindPipelineParams *params =
271 getParamPtr<BindPipelineParams>(currentCommand);
272 vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, params->pipeline);
273 break;
274 }
275 case CommandID::BindIndexBuffer:
276 {
277 const BindIndexBufferParams *params =
278 getParamPtr<BindIndexBufferParams>(currentCommand);
279 vkCmdBindIndexBuffer(cmdBuffer, params->buffer, params->offset,
280 params->indexType);
281 break;
282 }
283 case CommandID::BindTransformFeedbackBuffers:
284 {
285 const BindTransformFeedbackBuffersParams *params =
286 getParamPtr<BindTransformFeedbackBuffersParams>(currentCommand);
287 const VkBuffer *buffers = GetFirstArrayParameter<VkBuffer>(params);
288 const VkDeviceSize *offsets =
289 GetNextArrayParameter<VkDeviceSize>(buffers, params->bindingCount);
290 const VkDeviceSize *sizes =
291 GetNextArrayParameter<VkDeviceSize>(offsets, params->bindingCount);
292 vkCmdBindTransformFeedbackBuffersEXT(cmdBuffer, 0, params->bindingCount,
293 buffers, offsets, sizes);
294 break;
295 }
296 case CommandID::BindVertexBuffers:
297 {
298 const BindVertexBuffersParams *params =
299 getParamPtr<BindVertexBuffersParams>(currentCommand);
300 const VkBuffer *buffers = GetFirstArrayParameter<VkBuffer>(params);
301 const VkDeviceSize *offsets =
302 GetNextArrayParameter<VkDeviceSize>(buffers, params->bindingCount);
303 vkCmdBindVertexBuffers(cmdBuffer, 0, params->bindingCount, buffers, offsets);
304 break;
305 }
306 case CommandID::BindVertexBuffers2:
307 {
308 const BindVertexBuffers2Params *params =
309 getParamPtr<BindVertexBuffers2Params>(currentCommand);
310 const VkBuffer *buffers = GetFirstArrayParameter<VkBuffer>(params);
311 const VkDeviceSize *offsets =
312 GetNextArrayParameter<VkDeviceSize>(buffers, params->bindingCount);
313 const VkDeviceSize *strides =
314 GetNextArrayParameter<VkDeviceSize>(offsets, params->bindingCount);
315 vkCmdBindVertexBuffers2EXT(cmdBuffer, 0, params->bindingCount, buffers, offsets,
316 nullptr, strides);
317 break;
318 }
319 case CommandID::BlitImage:
320 {
321 const BlitImageParams *params = getParamPtr<BlitImageParams>(currentCommand);
322 vkCmdBlitImage(cmdBuffer, params->srcImage,
323 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, params->dstImage,
324 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ¶ms->region,
325 params->filter);
326 break;
327 }
328 case CommandID::BufferBarrier:
329 {
330 const BufferBarrierParams *params =
331 getParamPtr<BufferBarrierParams>(currentCommand);
332 vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
333 VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1,
334 ¶ms->bufferMemoryBarrier, 0, nullptr);
335 break;
336 }
337 case CommandID::BufferBarrier2:
338 {
339 const BufferBarrier2Params *params =
340 getParamPtr<BufferBarrier2Params>(currentCommand);
341
342 const VkDependencyInfo dependencyInfo = {
343 VK_STRUCTURE_TYPE_DEPENDENCY_INFO, nullptr, 0, 0, nullptr, 1,
344 ¶ms->bufferMemoryBarrier2, 0, nullptr};
345
346 vkCmdPipelineBarrier2KHR(cmdBuffer, &dependencyInfo);
347 break;
348 }
349 case CommandID::ClearAttachments:
350 {
351 const ClearAttachmentsParams *params =
352 getParamPtr<ClearAttachmentsParams>(currentCommand);
353 const VkClearAttachment *attachments =
354 GetFirstArrayParameter<VkClearAttachment>(params);
355 vkCmdClearAttachments(cmdBuffer, params->attachmentCount, attachments, 1,
356 ¶ms->rect);
357 break;
358 }
359 case CommandID::ClearColorImage:
360 {
361 const ClearColorImageParams *params =
362 getParamPtr<ClearColorImageParams>(currentCommand);
363 vkCmdClearColorImage(cmdBuffer, params->image, params->imageLayout,
364 ¶ms->color, 1, ¶ms->range);
365 break;
366 }
367 case CommandID::ClearDepthStencilImage:
368 {
369 const ClearDepthStencilImageParams *params =
370 getParamPtr<ClearDepthStencilImageParams>(currentCommand);
371 vkCmdClearDepthStencilImage(cmdBuffer, params->image, params->imageLayout,
372 ¶ms->depthStencil, 1, ¶ms->range);
373 break;
374 }
375 case CommandID::CopyBuffer:
376 {
377 const CopyBufferParams *params = getParamPtr<CopyBufferParams>(currentCommand);
378 const VkBufferCopy *regions = GetFirstArrayParameter<VkBufferCopy>(params);
379 vkCmdCopyBuffer(cmdBuffer, params->srcBuffer, params->destBuffer,
380 params->regionCount, regions);
381 break;
382 }
383 case CommandID::CopyBufferToImage:
384 {
385 const CopyBufferToImageParams *params =
386 getParamPtr<CopyBufferToImageParams>(currentCommand);
387 vkCmdCopyBufferToImage(cmdBuffer, params->srcBuffer, params->dstImage,
388 params->dstImageLayout, 1, ¶ms->region);
389 break;
390 }
391 case CommandID::CopyImage:
392 {
393 const CopyImageParams *params = getParamPtr<CopyImageParams>(currentCommand);
394 vkCmdCopyImage(cmdBuffer, params->srcImage, params->srcImageLayout,
395 params->dstImage, params->dstImageLayout, 1, ¶ms->region);
396 break;
397 }
398 case CommandID::CopyImageToBuffer:
399 {
400 const CopyImageToBufferParams *params =
401 getParamPtr<CopyImageToBufferParams>(currentCommand);
402 vkCmdCopyImageToBuffer(cmdBuffer, params->srcImage, params->srcImageLayout,
403 params->dstBuffer, 1, ¶ms->region);
404 break;
405 }
406 case CommandID::Dispatch:
407 {
408 const DispatchParams *params = getParamPtr<DispatchParams>(currentCommand);
409 vkCmdDispatch(cmdBuffer, params->groupCountX, params->groupCountY,
410 params->groupCountZ);
411 break;
412 }
413 case CommandID::DispatchIndirect:
414 {
415 const DispatchIndirectParams *params =
416 getParamPtr<DispatchIndirectParams>(currentCommand);
417 vkCmdDispatchIndirect(cmdBuffer, params->buffer, params->offset);
418 break;
419 }
420 case CommandID::Draw:
421 {
422 const DrawParams *params = getParamPtr<DrawParams>(currentCommand);
423 vkCmdDraw(cmdBuffer, params->vertexCount, 1, params->firstVertex, 0);
424 break;
425 }
426 case CommandID::DrawIndexed:
427 {
428 const DrawIndexedParams *params =
429 getParamPtr<DrawIndexedParams>(currentCommand);
430 vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, 0, 0);
431 break;
432 }
433 case CommandID::DrawIndexedBaseVertex:
434 {
435 const DrawIndexedBaseVertexParams *params =
436 getParamPtr<DrawIndexedBaseVertexParams>(currentCommand);
437 vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, params->vertexOffset, 0);
438 break;
439 }
440 case CommandID::DrawIndexedIndirect:
441 {
442 const DrawIndexedIndirectParams *params =
443 getParamPtr<DrawIndexedIndirectParams>(currentCommand);
444 vkCmdDrawIndexedIndirect(cmdBuffer, params->buffer, params->offset,
445 params->drawCount, params->stride);
446 break;
447 }
448 case CommandID::DrawIndexedInstanced:
449 {
450 const DrawIndexedInstancedParams *params =
451 getParamPtr<DrawIndexedInstancedParams>(currentCommand);
452 vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, 0, 0);
453 break;
454 }
455 case CommandID::DrawIndexedInstancedBaseVertex:
456 {
457 const DrawIndexedInstancedBaseVertexParams *params =
458 getParamPtr<DrawIndexedInstancedBaseVertexParams>(currentCommand);
459 vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0,
460 params->vertexOffset, 0);
461 break;
462 }
463 case CommandID::DrawIndexedInstancedBaseVertexBaseInstance:
464 {
465 const DrawIndexedInstancedBaseVertexBaseInstanceParams *params =
466 getParamPtr<DrawIndexedInstancedBaseVertexBaseInstanceParams>(
467 currentCommand);
468 vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount,
469 params->firstIndex, params->vertexOffset,
470 params->firstInstance);
471 break;
472 }
473 case CommandID::DrawIndirect:
474 {
475 const DrawIndirectParams *params =
476 getParamPtr<DrawIndirectParams>(currentCommand);
477 vkCmdDrawIndirect(cmdBuffer, params->buffer, params->offset, params->drawCount,
478 params->stride);
479 break;
480 }
481 case CommandID::DrawInstanced:
482 {
483 const DrawInstancedParams *params =
484 getParamPtr<DrawInstancedParams>(currentCommand);
485 vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount,
486 params->firstVertex, 0);
487 break;
488 }
489 case CommandID::DrawInstancedBaseInstance:
490 {
491 const DrawInstancedBaseInstanceParams *params =
492 getParamPtr<DrawInstancedBaseInstanceParams>(currentCommand);
493 vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount,
494 params->firstVertex, params->firstInstance);
495 break;
496 }
497 case CommandID::EndDebugUtilsLabel:
498 {
499 ASSERT(vkCmdEndDebugUtilsLabelEXT);
500 vkCmdEndDebugUtilsLabelEXT(cmdBuffer);
501 break;
502 }
503 case CommandID::EndQuery:
504 {
505 const EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand);
506 vkCmdEndQuery(cmdBuffer, params->queryPool, params->query);
507 break;
508 }
509 case CommandID::EndTransformFeedback:
510 {
511 const EndTransformFeedbackParams *params =
512 getParamPtr<EndTransformFeedbackParams>(currentCommand);
513 const VkBuffer *counterBuffers = GetFirstArrayParameter<VkBuffer>(params);
514 const VkDeviceSize *counterBufferOffsets =
515 reinterpret_cast<const VkDeviceSize *>(counterBuffers +
516 params->bufferCount);
517 vkCmdEndTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount, counterBuffers,
518 counterBufferOffsets);
519 break;
520 }
521 case CommandID::FillBuffer:
522 {
523 const FillBufferParams *params = getParamPtr<FillBufferParams>(currentCommand);
524 vkCmdFillBuffer(cmdBuffer, params->dstBuffer, params->dstOffset, params->size,
525 params->data);
526 break;
527 }
528 case CommandID::ImageBarrier:
529 {
530 const ImageBarrierParams *params =
531 getParamPtr<ImageBarrierParams>(currentCommand);
532 const VkImageMemoryBarrier *imageMemoryBarriers =
533 GetFirstArrayParameter<VkImageMemoryBarrier>(params);
534 vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
535 0, nullptr, 0, nullptr, 1, imageMemoryBarriers);
536 break;
537 }
538 case CommandID::ImageBarrier2:
539 {
540 const ImageBarrier2Params *params =
541 getParamPtr<ImageBarrier2Params>(currentCommand);
542 const VkImageMemoryBarrier2 *imageMemoryBarriers2 =
543 GetFirstArrayParameter<VkImageMemoryBarrier2>(params);
544 VkDependencyInfo pDependencyInfo = {};
545 pDependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
546 pDependencyInfo.dependencyFlags = 0;
547 pDependencyInfo.memoryBarrierCount = 0;
548 pDependencyInfo.pMemoryBarriers = nullptr;
549 pDependencyInfo.bufferMemoryBarrierCount = 0;
550 pDependencyInfo.pBufferMemoryBarriers = nullptr;
551 pDependencyInfo.imageMemoryBarrierCount = 1;
552 pDependencyInfo.pImageMemoryBarriers = imageMemoryBarriers2;
553 vkCmdPipelineBarrier2KHR(cmdBuffer, &pDependencyInfo);
554 break;
555 }
556 case CommandID::ImageWaitEvent:
557 {
558 const ImageWaitEventParams *params =
559 getParamPtr<ImageWaitEventParams>(currentCommand);
560 const VkImageMemoryBarrier *imageMemoryBarriers =
561 GetFirstArrayParameter<VkImageMemoryBarrier>(params);
562 vkCmdWaitEvents(cmdBuffer, 1, &(params->event), params->srcStageMask,
563 params->dstStageMask, 0, nullptr, 0, nullptr, 1,
564 imageMemoryBarriers);
565 break;
566 }
567 case CommandID::InsertDebugUtilsLabel:
568 {
569 const DebugUtilsLabelParams *params =
570 getParamPtr<DebugUtilsLabelParams>(currentCommand);
571 const char *pLabelName = GetFirstArrayParameter<char>(params);
572 const VkDebugUtilsLabelEXT label = {
573 VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT,
574 nullptr,
575 pLabelName,
576 {params->color[0], params->color[1], params->color[2], params->color[3]}};
577 ASSERT(vkCmdInsertDebugUtilsLabelEXT);
578 vkCmdInsertDebugUtilsLabelEXT(cmdBuffer, &label);
579 break;
580 }
581 case CommandID::MemoryBarrier:
582 {
583 const MemoryBarrierParams *params =
584 getParamPtr<MemoryBarrierParams>(currentCommand);
585 const VkMemoryBarrier *memoryBarriers =
586 GetFirstArrayParameter<VkMemoryBarrier>(params);
587 vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
588 1, memoryBarriers, 0, nullptr, 0, nullptr);
589 break;
590 }
591 case CommandID::MemoryBarrier2:
592 {
593 const MemoryBarrier2Params *params =
594 getParamPtr<MemoryBarrier2Params>(currentCommand);
595
596 const VkMemoryBarrier2 *memoryBarriers2 =
597 GetFirstArrayParameter<VkMemoryBarrier2>(params);
598 VkDependencyInfo pDependencyInfo = {};
599 pDependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
600 pDependencyInfo.memoryBarrierCount = 1;
601 pDependencyInfo.pMemoryBarriers = memoryBarriers2;
602 pDependencyInfo.bufferMemoryBarrierCount = 0;
603 pDependencyInfo.pBufferMemoryBarriers = nullptr;
604 pDependencyInfo.imageMemoryBarrierCount = 0;
605 pDependencyInfo.pImageMemoryBarriers = nullptr;
606 vkCmdPipelineBarrier2KHR(cmdBuffer, &pDependencyInfo);
607 break;
608 }
609 case CommandID::NextSubpass:
610 {
611 vkCmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
612 break;
613 }
614 case CommandID::PipelineBarrier:
615 {
616 const PipelineBarrierParams *params =
617 getParamPtr<PipelineBarrierParams>(currentCommand);
618 const VkMemoryBarrier *memoryBarriers =
619 GetFirstArrayParameter<VkMemoryBarrier>(params);
620 const VkImageMemoryBarrier *imageMemoryBarriers =
621 GetNextArrayParameter<VkImageMemoryBarrier>(memoryBarriers,
622 params->memoryBarrierCount);
623 vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask,
624 params->dependencyFlags, params->memoryBarrierCount,
625 memoryBarriers, 0, nullptr,
626 params->imageMemoryBarrierCount, imageMemoryBarriers);
627 break;
628 }
629 case CommandID::PipelineBarrier2:
630 {
631 const PipelineBarrierParams2 *params =
632 getParamPtr<PipelineBarrierParams2>(currentCommand);
633 const VkMemoryBarrier2 *memoryBarriers2 =
634 GetFirstArrayParameter<VkMemoryBarrier2>(params);
635 const VkImageMemoryBarrier2 *imageMemoryBarriers2 =
636 GetNextArrayParameter<VkImageMemoryBarrier2>(memoryBarriers2,
637 params->memoryBarrierCount);
638 VkDependencyInfo dependencyInfo = {};
639 dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO;
640 dependencyInfo.pNext = nullptr;
641 dependencyInfo.dependencyFlags = params->dependencyFlags;
642 dependencyInfo.memoryBarrierCount = params->memoryBarrierCount;
643 dependencyInfo.pMemoryBarriers = memoryBarriers2;
644 dependencyInfo.bufferMemoryBarrierCount = 0;
645 dependencyInfo.pBufferMemoryBarriers = nullptr;
646 dependencyInfo.imageMemoryBarrierCount = params->imageMemoryBarrierCount;
647 dependencyInfo.pImageMemoryBarriers = imageMemoryBarriers2;
648 vkCmdPipelineBarrier2KHR(cmdBuffer, &dependencyInfo);
649 break;
650 }
651 case CommandID::PushConstants:
652 {
653 const PushConstantsParams *params =
654 getParamPtr<PushConstantsParams>(currentCommand);
655 const void *data = GetFirstArrayParameter<void>(params);
656 vkCmdPushConstants(cmdBuffer, params->layout, params->flag, params->offset,
657 params->size, data);
658 break;
659 }
660 case CommandID::ResetEvent:
661 {
662 const ResetEventParams *params = getParamPtr<ResetEventParams>(currentCommand);
663 vkCmdResetEvent(cmdBuffer, params->event, params->stageMask);
664 break;
665 }
666 case CommandID::ResetQueryPool:
667 {
668 const ResetQueryPoolParams *params =
669 getParamPtr<ResetQueryPoolParams>(currentCommand);
670 vkCmdResetQueryPool(cmdBuffer, params->queryPool, params->firstQuery,
671 params->queryCount);
672 break;
673 }
674 case CommandID::ResolveImage:
675 {
676 const ResolveImageParams *params =
677 getParamPtr<ResolveImageParams>(currentCommand);
678 vkCmdResolveImage(cmdBuffer, params->srcImage,
679 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, params->dstImage,
680 VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ¶ms->region);
681 break;
682 }
683 case CommandID::SetBlendConstants:
684 {
685 const SetBlendConstantsParams *params =
686 getParamPtr<SetBlendConstantsParams>(currentCommand);
687 vkCmdSetBlendConstants(cmdBuffer, params->blendConstants);
688 break;
689 }
690 case CommandID::SetCullMode:
691 {
692 const SetCullModeParams *params =
693 getParamPtr<SetCullModeParams>(currentCommand);
694 vkCmdSetCullModeEXT(cmdBuffer, params->cullMode);
695 break;
696 }
697 case CommandID::SetDepthBias:
698 {
699 const SetDepthBiasParams *params =
700 getParamPtr<SetDepthBiasParams>(currentCommand);
701 vkCmdSetDepthBias(cmdBuffer, params->depthBiasConstantFactor,
702 params->depthBiasClamp, params->depthBiasSlopeFactor);
703 break;
704 }
705 case CommandID::SetDepthBiasEnable:
706 {
707 const SetDepthBiasEnableParams *params =
708 getParamPtr<SetDepthBiasEnableParams>(currentCommand);
709 vkCmdSetDepthBiasEnableEXT(cmdBuffer, params->depthBiasEnable);
710 break;
711 }
712 case CommandID::SetDepthCompareOp:
713 {
714 const SetDepthCompareOpParams *params =
715 getParamPtr<SetDepthCompareOpParams>(currentCommand);
716 vkCmdSetDepthCompareOpEXT(cmdBuffer, params->depthCompareOp);
717 break;
718 }
719 case CommandID::SetDepthTestEnable:
720 {
721 const SetDepthTestEnableParams *params =
722 getParamPtr<SetDepthTestEnableParams>(currentCommand);
723 vkCmdSetDepthTestEnableEXT(cmdBuffer, params->depthTestEnable);
724 break;
725 }
726 case CommandID::SetDepthWriteEnable:
727 {
728 const SetDepthWriteEnableParams *params =
729 getParamPtr<SetDepthWriteEnableParams>(currentCommand);
730 vkCmdSetDepthWriteEnableEXT(cmdBuffer, params->depthWriteEnable);
731 break;
732 }
733 case CommandID::SetEvent:
734 {
735 const SetEventParams *params = getParamPtr<SetEventParams>(currentCommand);
736 vkCmdSetEvent(cmdBuffer, params->event, params->stageMask);
737 break;
738 }
739 case CommandID::SetFragmentShadingRate:
740 {
741 const SetFragmentShadingRateParams *params =
742 getParamPtr<SetFragmentShadingRateParams>(currentCommand);
743 const VkExtent2D fragmentSize = {params->fragmentWidth, params->fragmentHeight};
744 const VkFragmentShadingRateCombinerOpKHR ops[2] = {
745 VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
746 static_cast<VkFragmentShadingRateCombinerOpKHR>(
747 params->vkFragmentShadingRateCombinerOp1)};
748 vkCmdSetFragmentShadingRateKHR(cmdBuffer, &fragmentSize, ops);
749 break;
750 }
751 case CommandID::SetFrontFace:
752 {
753 const SetFrontFaceParams *params =
754 getParamPtr<SetFrontFaceParams>(currentCommand);
755 vkCmdSetFrontFaceEXT(cmdBuffer, params->frontFace);
756 break;
757 }
758 case CommandID::SetLineWidth:
759 {
760 const SetLineWidthParams *params =
761 getParamPtr<SetLineWidthParams>(currentCommand);
762 vkCmdSetLineWidth(cmdBuffer, params->lineWidth);
763 break;
764 }
765 case CommandID::SetLogicOp:
766 {
767 const SetLogicOpParams *params = getParamPtr<SetLogicOpParams>(currentCommand);
768 vkCmdSetLogicOpEXT(cmdBuffer, params->logicOp);
769 break;
770 }
771 case CommandID::SetPrimitiveRestartEnable:
772 {
773 const SetPrimitiveRestartEnableParams *params =
774 getParamPtr<SetPrimitiveRestartEnableParams>(currentCommand);
775 vkCmdSetPrimitiveRestartEnableEXT(cmdBuffer, params->primitiveRestartEnable);
776 break;
777 }
778 case CommandID::SetRasterizerDiscardEnable:
779 {
780 const SetRasterizerDiscardEnableParams *params =
781 getParamPtr<SetRasterizerDiscardEnableParams>(currentCommand);
782 vkCmdSetRasterizerDiscardEnableEXT(cmdBuffer, params->rasterizerDiscardEnable);
783 break;
784 }
785 case CommandID::SetScissor:
786 {
787 const SetScissorParams *params = getParamPtr<SetScissorParams>(currentCommand);
788 vkCmdSetScissor(cmdBuffer, 0, 1, ¶ms->scissor);
789 break;
790 }
791 case CommandID::SetStencilCompareMask:
792 {
793 const SetStencilCompareMaskParams *params =
794 getParamPtr<SetStencilCompareMaskParams>(currentCommand);
795 vkCmdSetStencilCompareMask(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT,
796 params->compareFrontMask);
797 vkCmdSetStencilCompareMask(cmdBuffer, VK_STENCIL_FACE_BACK_BIT,
798 params->compareBackMask);
799 break;
800 }
801 case CommandID::SetStencilOp:
802 {
803 const SetStencilOpParams *params =
804 getParamPtr<SetStencilOpParams>(currentCommand);
805 vkCmdSetStencilOpEXT(cmdBuffer,
806 static_cast<VkStencilFaceFlags>(params->faceMask),
807 static_cast<VkStencilOp>(params->failOp),
808 static_cast<VkStencilOp>(params->passOp),
809 static_cast<VkStencilOp>(params->depthFailOp),
810 static_cast<VkCompareOp>(params->compareOp));
811 break;
812 }
813 case CommandID::SetStencilReference:
814 {
815 const SetStencilReferenceParams *params =
816 getParamPtr<SetStencilReferenceParams>(currentCommand);
817 vkCmdSetStencilReference(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT,
818 params->frontReference);
819 vkCmdSetStencilReference(cmdBuffer, VK_STENCIL_FACE_BACK_BIT,
820 params->backReference);
821 break;
822 }
823 case CommandID::SetStencilTestEnable:
824 {
825 const SetStencilTestEnableParams *params =
826 getParamPtr<SetStencilTestEnableParams>(currentCommand);
827 vkCmdSetStencilTestEnableEXT(cmdBuffer, params->stencilTestEnable);
828 break;
829 }
830 case CommandID::SetStencilWriteMask:
831 {
832 const SetStencilWriteMaskParams *params =
833 getParamPtr<SetStencilWriteMaskParams>(currentCommand);
834 vkCmdSetStencilWriteMask(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT,
835 params->writeFrontMask);
836 vkCmdSetStencilWriteMask(cmdBuffer, VK_STENCIL_FACE_BACK_BIT,
837 params->writeBackMask);
838 break;
839 }
840 case CommandID::SetVertexInput:
841 {
842 const SetVertexInputParams *params =
843 getParamPtr<SetVertexInputParams>(currentCommand);
844 const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions =
845 GetFirstArrayParameter<VkVertexInputBindingDescription2EXT>(params);
846 const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions =
847 GetNextArrayParameter<VkVertexInputAttributeDescription2EXT,
848 VkVertexInputBindingDescription2EXT>(
849 vertexBindingDescriptions, params->vertexBindingDescriptionCount);
850
851 vkCmdSetVertexInputEXT(
852 cmdBuffer, params->vertexBindingDescriptionCount, vertexBindingDescriptions,
853 params->vertexAttributeDescriptionCount, vertexAttributeDescriptions);
854 break;
855 }
856 case CommandID::SetViewport:
857 {
858 const SetViewportParams *params =
859 getParamPtr<SetViewportParams>(currentCommand);
860 vkCmdSetViewport(cmdBuffer, 0, 1, ¶ms->viewport);
861 break;
862 }
863 case CommandID::WaitEvents:
864 {
865 const WaitEventsParams *params = getParamPtr<WaitEventsParams>(currentCommand);
866 const VkEvent *events = GetFirstArrayParameter<VkEvent>(params);
867 const VkMemoryBarrier *memoryBarriers =
868 GetNextArrayParameter<VkMemoryBarrier>(events, params->eventCount);
869 const VkImageMemoryBarrier *imageMemoryBarriers =
870 GetNextArrayParameter<VkImageMemoryBarrier>(memoryBarriers,
871 params->memoryBarrierCount);
872 vkCmdWaitEvents(cmdBuffer, params->eventCount, events, params->srcStageMask,
873 params->dstStageMask, params->memoryBarrierCount,
874 memoryBarriers, 0, nullptr, params->imageMemoryBarrierCount,
875 imageMemoryBarriers);
876 break;
877 }
878 case CommandID::WriteTimestamp:
879 {
880 const WriteTimestampParams *params =
881 getParamPtr<WriteTimestampParams>(currentCommand);
882 vkCmdWriteTimestamp(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
883 params->queryPool, params->query);
884 break;
885 }
886 case CommandID::WriteTimestamp2:
887 {
888 const WriteTimestampParams *params =
889 getParamPtr<WriteTimestampParams>(currentCommand);
890 vkCmdWriteTimestamp2KHR(cmdBuffer, VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT,
891 params->queryPool, params->query);
892 break;
893 }
894 default:
895 {
896 UNREACHABLE();
897 break;
898 }
899 }
900 }
901 }
902 }
903
getMemoryUsageStats(size_t * usedMemoryOut,size_t * allocatedMemoryOut) const904 void SecondaryCommandBuffer::getMemoryUsageStats(size_t *usedMemoryOut,
905 size_t *allocatedMemoryOut) const
906 {
907 mCommandAllocator.getMemoryUsageStats(usedMemoryOut, allocatedMemoryOut);
908 }
909
getMemoryUsageStatsForPoolAlloc(size_t blockSize,size_t * usedMemoryOut,size_t * allocatedMemoryOut) const910 void SecondaryCommandBuffer::getMemoryUsageStatsForPoolAlloc(size_t blockSize,
911 size_t *usedMemoryOut,
912 size_t *allocatedMemoryOut) const
913 {
914 *allocatedMemoryOut = blockSize * mCommands.size();
915
916 *usedMemoryOut = 0;
917 for (const CommandHeader *command : mCommands)
918 {
919 const CommandHeader *commandEnd = command;
920 while (commandEnd->id != CommandID::Invalid)
921 {
922 commandEnd = NextCommand(commandEnd);
923 }
924
925 *usedMemoryOut += reinterpret_cast<const uint8_t *>(commandEnd) -
926 reinterpret_cast<const uint8_t *>(command) + sizeof(CommandHeader::id);
927 }
928
929 ASSERT(*usedMemoryOut <= *allocatedMemoryOut);
930 }
931
dumpCommands(const char * separator) const932 std::string SecondaryCommandBuffer::dumpCommands(const char *separator) const
933 {
934 std::stringstream result;
935 for (const CommandHeader *command : mCommands)
936 {
937 for (const CommandHeader *currentCommand = command;
938 currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand))
939 {
940 result << GetCommandString(currentCommand->id) << separator;
941 }
942 }
943 return result.str();
944 }
945
946 } // namespace priv
947 } // namespace vk
948 } // namespace rx
949