xref: /aosp_15_r20/external/angle/src/libANGLE/renderer/vulkan/SecondaryCommandBuffer.cpp (revision 8975f5c5ed3d1c378011245431ada316dfb6f244)
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, &params->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                                          &params->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                         &params->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                                           &params->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                                          &params->color, 1, &params->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                                                 &params->depthStencil, 1, &params->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, &params->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, &params->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, &params->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, &params->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, &params->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, &params->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