• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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::ClearAttachments:
338                 {
339                     const ClearAttachmentsParams *params =
340                         getParamPtr<ClearAttachmentsParams>(currentCommand);
341                     const VkClearAttachment *attachments =
342                         GetFirstArrayParameter<VkClearAttachment>(params);
343                     vkCmdClearAttachments(cmdBuffer, params->attachmentCount, attachments, 1,
344                                           &params->rect);
345                     break;
346                 }
347                 case CommandID::ClearColorImage:
348                 {
349                     const ClearColorImageParams *params =
350                         getParamPtr<ClearColorImageParams>(currentCommand);
351                     vkCmdClearColorImage(cmdBuffer, params->image, params->imageLayout,
352                                          &params->color, 1, &params->range);
353                     break;
354                 }
355                 case CommandID::ClearDepthStencilImage:
356                 {
357                     const ClearDepthStencilImageParams *params =
358                         getParamPtr<ClearDepthStencilImageParams>(currentCommand);
359                     vkCmdClearDepthStencilImage(cmdBuffer, params->image, params->imageLayout,
360                                                 &params->depthStencil, 1, &params->range);
361                     break;
362                 }
363                 case CommandID::CopyBuffer:
364                 {
365                     const CopyBufferParams *params = getParamPtr<CopyBufferParams>(currentCommand);
366                     const VkBufferCopy *regions    = GetFirstArrayParameter<VkBufferCopy>(params);
367                     vkCmdCopyBuffer(cmdBuffer, params->srcBuffer, params->destBuffer,
368                                     params->regionCount, regions);
369                     break;
370                 }
371                 case CommandID::CopyBufferToImage:
372                 {
373                     const CopyBufferToImageParams *params =
374                         getParamPtr<CopyBufferToImageParams>(currentCommand);
375                     vkCmdCopyBufferToImage(cmdBuffer, params->srcBuffer, params->dstImage,
376                                            params->dstImageLayout, 1, &params->region);
377                     break;
378                 }
379                 case CommandID::CopyImage:
380                 {
381                     const CopyImageParams *params = getParamPtr<CopyImageParams>(currentCommand);
382                     vkCmdCopyImage(cmdBuffer, params->srcImage, params->srcImageLayout,
383                                    params->dstImage, params->dstImageLayout, 1, &params->region);
384                     break;
385                 }
386                 case CommandID::CopyImageToBuffer:
387                 {
388                     const CopyImageToBufferParams *params =
389                         getParamPtr<CopyImageToBufferParams>(currentCommand);
390                     vkCmdCopyImageToBuffer(cmdBuffer, params->srcImage, params->srcImageLayout,
391                                            params->dstBuffer, 1, &params->region);
392                     break;
393                 }
394                 case CommandID::Dispatch:
395                 {
396                     const DispatchParams *params = getParamPtr<DispatchParams>(currentCommand);
397                     vkCmdDispatch(cmdBuffer, params->groupCountX, params->groupCountY,
398                                   params->groupCountZ);
399                     break;
400                 }
401                 case CommandID::DispatchIndirect:
402                 {
403                     const DispatchIndirectParams *params =
404                         getParamPtr<DispatchIndirectParams>(currentCommand);
405                     vkCmdDispatchIndirect(cmdBuffer, params->buffer, params->offset);
406                     break;
407                 }
408                 case CommandID::Draw:
409                 {
410                     const DrawParams *params = getParamPtr<DrawParams>(currentCommand);
411                     vkCmdDraw(cmdBuffer, params->vertexCount, 1, params->firstVertex, 0);
412                     break;
413                 }
414                 case CommandID::DrawIndexed:
415                 {
416                     const DrawIndexedParams *params =
417                         getParamPtr<DrawIndexedParams>(currentCommand);
418                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, 0, 0);
419                     break;
420                 }
421                 case CommandID::DrawIndexedBaseVertex:
422                 {
423                     const DrawIndexedBaseVertexParams *params =
424                         getParamPtr<DrawIndexedBaseVertexParams>(currentCommand);
425                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, params->vertexOffset, 0);
426                     break;
427                 }
428                 case CommandID::DrawIndexedIndirect:
429                 {
430                     const DrawIndexedIndirectParams *params =
431                         getParamPtr<DrawIndexedIndirectParams>(currentCommand);
432                     vkCmdDrawIndexedIndirect(cmdBuffer, params->buffer, params->offset,
433                                              params->drawCount, params->stride);
434                     break;
435                 }
436                 case CommandID::DrawIndexedInstanced:
437                 {
438                     const DrawIndexedInstancedParams *params =
439                         getParamPtr<DrawIndexedInstancedParams>(currentCommand);
440                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, 0, 0);
441                     break;
442                 }
443                 case CommandID::DrawIndexedInstancedBaseVertex:
444                 {
445                     const DrawIndexedInstancedBaseVertexParams *params =
446                         getParamPtr<DrawIndexedInstancedBaseVertexParams>(currentCommand);
447                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0,
448                                      params->vertexOffset, 0);
449                     break;
450                 }
451                 case CommandID::DrawIndexedInstancedBaseVertexBaseInstance:
452                 {
453                     const DrawIndexedInstancedBaseVertexBaseInstanceParams *params =
454                         getParamPtr<DrawIndexedInstancedBaseVertexBaseInstanceParams>(
455                             currentCommand);
456                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount,
457                                      params->firstIndex, params->vertexOffset,
458                                      params->firstInstance);
459                     break;
460                 }
461                 case CommandID::DrawIndirect:
462                 {
463                     const DrawIndirectParams *params =
464                         getParamPtr<DrawIndirectParams>(currentCommand);
465                     vkCmdDrawIndirect(cmdBuffer, params->buffer, params->offset, params->drawCount,
466                                       params->stride);
467                     break;
468                 }
469                 case CommandID::DrawInstanced:
470                 {
471                     const DrawInstancedParams *params =
472                         getParamPtr<DrawInstancedParams>(currentCommand);
473                     vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount,
474                               params->firstVertex, 0);
475                     break;
476                 }
477                 case CommandID::DrawInstancedBaseInstance:
478                 {
479                     const DrawInstancedBaseInstanceParams *params =
480                         getParamPtr<DrawInstancedBaseInstanceParams>(currentCommand);
481                     vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount,
482                               params->firstVertex, params->firstInstance);
483                     break;
484                 }
485                 case CommandID::EndDebugUtilsLabel:
486                 {
487                     ASSERT(vkCmdEndDebugUtilsLabelEXT);
488                     vkCmdEndDebugUtilsLabelEXT(cmdBuffer);
489                     break;
490                 }
491                 case CommandID::EndQuery:
492                 {
493                     const EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand);
494                     vkCmdEndQuery(cmdBuffer, params->queryPool, params->query);
495                     break;
496                 }
497                 case CommandID::EndTransformFeedback:
498                 {
499                     const EndTransformFeedbackParams *params =
500                         getParamPtr<EndTransformFeedbackParams>(currentCommand);
501                     const VkBuffer *counterBuffers = GetFirstArrayParameter<VkBuffer>(params);
502                     const VkDeviceSize *counterBufferOffsets =
503                         reinterpret_cast<const VkDeviceSize *>(counterBuffers +
504                                                                params->bufferCount);
505                     vkCmdEndTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount, counterBuffers,
506                                                  counterBufferOffsets);
507                     break;
508                 }
509                 case CommandID::FillBuffer:
510                 {
511                     const FillBufferParams *params = getParamPtr<FillBufferParams>(currentCommand);
512                     vkCmdFillBuffer(cmdBuffer, params->dstBuffer, params->dstOffset, params->size,
513                                     params->data);
514                     break;
515                 }
516                 case CommandID::ImageBarrier:
517                 {
518                     const ImageBarrierParams *params =
519                         getParamPtr<ImageBarrierParams>(currentCommand);
520                     const VkImageMemoryBarrier *imageMemoryBarriers =
521                         GetFirstArrayParameter<VkImageMemoryBarrier>(params);
522                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
523                                          0, nullptr, 0, nullptr, 1, imageMemoryBarriers);
524                     break;
525                 }
526                 case CommandID::ImageWaitEvent:
527                 {
528                     const ImageWaitEventParams *params =
529                         getParamPtr<ImageWaitEventParams>(currentCommand);
530                     const VkImageMemoryBarrier *imageMemoryBarriers =
531                         GetFirstArrayParameter<VkImageMemoryBarrier>(params);
532                     vkCmdWaitEvents(cmdBuffer, 1, &(params->event), params->srcStageMask,
533                                     params->dstStageMask, 0, nullptr, 0, nullptr, 1,
534                                     imageMemoryBarriers);
535                     break;
536                 }
537                 case CommandID::InsertDebugUtilsLabel:
538                 {
539                     const DebugUtilsLabelParams *params =
540                         getParamPtr<DebugUtilsLabelParams>(currentCommand);
541                     const char *pLabelName           = GetFirstArrayParameter<char>(params);
542                     const VkDebugUtilsLabelEXT label = {
543                         VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT,
544                         nullptr,
545                         pLabelName,
546                         {params->color[0], params->color[1], params->color[2], params->color[3]}};
547                     ASSERT(vkCmdInsertDebugUtilsLabelEXT);
548                     vkCmdInsertDebugUtilsLabelEXT(cmdBuffer, &label);
549                     break;
550                 }
551                 case CommandID::MemoryBarrier:
552                 {
553                     const MemoryBarrierParams *params =
554                         getParamPtr<MemoryBarrierParams>(currentCommand);
555                     const VkMemoryBarrier *memoryBarriers =
556                         GetFirstArrayParameter<VkMemoryBarrier>(params);
557                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
558                                          1, memoryBarriers, 0, nullptr, 0, nullptr);
559                     break;
560                 }
561                 case CommandID::NextSubpass:
562                 {
563                     vkCmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE);
564                     break;
565                 }
566                 case CommandID::PipelineBarrier:
567                 {
568                     const PipelineBarrierParams *params =
569                         getParamPtr<PipelineBarrierParams>(currentCommand);
570                     const VkMemoryBarrier *memoryBarriers =
571                         GetFirstArrayParameter<VkMemoryBarrier>(params);
572                     const VkImageMemoryBarrier *imageMemoryBarriers =
573                         GetNextArrayParameter<VkImageMemoryBarrier>(memoryBarriers,
574                                                                     params->memoryBarrierCount);
575                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask,
576                                          params->dependencyFlags, params->memoryBarrierCount,
577                                          memoryBarriers, 0, nullptr,
578                                          params->imageMemoryBarrierCount, imageMemoryBarriers);
579                     break;
580                 }
581                 case CommandID::PushConstants:
582                 {
583                     const PushConstantsParams *params =
584                         getParamPtr<PushConstantsParams>(currentCommand);
585                     const void *data = GetFirstArrayParameter<void>(params);
586                     vkCmdPushConstants(cmdBuffer, params->layout, params->flag, params->offset,
587                                        params->size, data);
588                     break;
589                 }
590                 case CommandID::ResetEvent:
591                 {
592                     const ResetEventParams *params = getParamPtr<ResetEventParams>(currentCommand);
593                     vkCmdResetEvent(cmdBuffer, params->event, params->stageMask);
594                     break;
595                 }
596                 case CommandID::ResetQueryPool:
597                 {
598                     const ResetQueryPoolParams *params =
599                         getParamPtr<ResetQueryPoolParams>(currentCommand);
600                     vkCmdResetQueryPool(cmdBuffer, params->queryPool, params->firstQuery,
601                                         params->queryCount);
602                     break;
603                 }
604                 case CommandID::ResolveImage:
605                 {
606                     const ResolveImageParams *params =
607                         getParamPtr<ResolveImageParams>(currentCommand);
608                     vkCmdResolveImage(cmdBuffer, params->srcImage,
609                                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, params->dstImage,
610                                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &params->region);
611                     break;
612                 }
613                 case CommandID::SetBlendConstants:
614                 {
615                     const SetBlendConstantsParams *params =
616                         getParamPtr<SetBlendConstantsParams>(currentCommand);
617                     vkCmdSetBlendConstants(cmdBuffer, params->blendConstants);
618                     break;
619                 }
620                 case CommandID::SetCullMode:
621                 {
622                     const SetCullModeParams *params =
623                         getParamPtr<SetCullModeParams>(currentCommand);
624                     vkCmdSetCullModeEXT(cmdBuffer, params->cullMode);
625                     break;
626                 }
627                 case CommandID::SetDepthBias:
628                 {
629                     const SetDepthBiasParams *params =
630                         getParamPtr<SetDepthBiasParams>(currentCommand);
631                     vkCmdSetDepthBias(cmdBuffer, params->depthBiasConstantFactor,
632                                       params->depthBiasClamp, params->depthBiasSlopeFactor);
633                     break;
634                 }
635                 case CommandID::SetDepthBiasEnable:
636                 {
637                     const SetDepthBiasEnableParams *params =
638                         getParamPtr<SetDepthBiasEnableParams>(currentCommand);
639                     vkCmdSetDepthBiasEnableEXT(cmdBuffer, params->depthBiasEnable);
640                     break;
641                 }
642                 case CommandID::SetDepthCompareOp:
643                 {
644                     const SetDepthCompareOpParams *params =
645                         getParamPtr<SetDepthCompareOpParams>(currentCommand);
646                     vkCmdSetDepthCompareOpEXT(cmdBuffer, params->depthCompareOp);
647                     break;
648                 }
649                 case CommandID::SetDepthTestEnable:
650                 {
651                     const SetDepthTestEnableParams *params =
652                         getParamPtr<SetDepthTestEnableParams>(currentCommand);
653                     vkCmdSetDepthTestEnableEXT(cmdBuffer, params->depthTestEnable);
654                     break;
655                 }
656                 case CommandID::SetDepthWriteEnable:
657                 {
658                     const SetDepthWriteEnableParams *params =
659                         getParamPtr<SetDepthWriteEnableParams>(currentCommand);
660                     vkCmdSetDepthWriteEnableEXT(cmdBuffer, params->depthWriteEnable);
661                     break;
662                 }
663                 case CommandID::SetEvent:
664                 {
665                     const SetEventParams *params = getParamPtr<SetEventParams>(currentCommand);
666                     vkCmdSetEvent(cmdBuffer, params->event, params->stageMask);
667                     break;
668                 }
669                 case CommandID::SetFragmentShadingRate:
670                 {
671                     const SetFragmentShadingRateParams *params =
672                         getParamPtr<SetFragmentShadingRateParams>(currentCommand);
673                     const VkExtent2D fragmentSize = {params->fragmentWidth, params->fragmentHeight};
674                     const VkFragmentShadingRateCombinerOpKHR ops[2] = {
675                         VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR,
676                         static_cast<VkFragmentShadingRateCombinerOpKHR>(
677                             params->vkFragmentShadingRateCombinerOp1)};
678                     vkCmdSetFragmentShadingRateKHR(cmdBuffer, &fragmentSize, ops);
679                     break;
680                 }
681                 case CommandID::SetFrontFace:
682                 {
683                     const SetFrontFaceParams *params =
684                         getParamPtr<SetFrontFaceParams>(currentCommand);
685                     vkCmdSetFrontFaceEXT(cmdBuffer, params->frontFace);
686                     break;
687                 }
688                 case CommandID::SetLineWidth:
689                 {
690                     const SetLineWidthParams *params =
691                         getParamPtr<SetLineWidthParams>(currentCommand);
692                     vkCmdSetLineWidth(cmdBuffer, params->lineWidth);
693                     break;
694                 }
695                 case CommandID::SetLogicOp:
696                 {
697                     const SetLogicOpParams *params = getParamPtr<SetLogicOpParams>(currentCommand);
698                     vkCmdSetLogicOpEXT(cmdBuffer, params->logicOp);
699                     break;
700                 }
701                 case CommandID::SetPrimitiveRestartEnable:
702                 {
703                     const SetPrimitiveRestartEnableParams *params =
704                         getParamPtr<SetPrimitiveRestartEnableParams>(currentCommand);
705                     vkCmdSetPrimitiveRestartEnableEXT(cmdBuffer, params->primitiveRestartEnable);
706                     break;
707                 }
708                 case CommandID::SetRasterizerDiscardEnable:
709                 {
710                     const SetRasterizerDiscardEnableParams *params =
711                         getParamPtr<SetRasterizerDiscardEnableParams>(currentCommand);
712                     vkCmdSetRasterizerDiscardEnableEXT(cmdBuffer, params->rasterizerDiscardEnable);
713                     break;
714                 }
715                 case CommandID::SetScissor:
716                 {
717                     const SetScissorParams *params = getParamPtr<SetScissorParams>(currentCommand);
718                     vkCmdSetScissor(cmdBuffer, 0, 1, &params->scissor);
719                     break;
720                 }
721                 case CommandID::SetStencilCompareMask:
722                 {
723                     const SetStencilCompareMaskParams *params =
724                         getParamPtr<SetStencilCompareMaskParams>(currentCommand);
725                     vkCmdSetStencilCompareMask(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT,
726                                                params->compareFrontMask);
727                     vkCmdSetStencilCompareMask(cmdBuffer, VK_STENCIL_FACE_BACK_BIT,
728                                                params->compareBackMask);
729                     break;
730                 }
731                 case CommandID::SetStencilOp:
732                 {
733                     const SetStencilOpParams *params =
734                         getParamPtr<SetStencilOpParams>(currentCommand);
735                     vkCmdSetStencilOpEXT(cmdBuffer,
736                                          static_cast<VkStencilFaceFlags>(params->faceMask),
737                                          static_cast<VkStencilOp>(params->failOp),
738                                          static_cast<VkStencilOp>(params->passOp),
739                                          static_cast<VkStencilOp>(params->depthFailOp),
740                                          static_cast<VkCompareOp>(params->compareOp));
741                     break;
742                 }
743                 case CommandID::SetStencilReference:
744                 {
745                     const SetStencilReferenceParams *params =
746                         getParamPtr<SetStencilReferenceParams>(currentCommand);
747                     vkCmdSetStencilReference(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT,
748                                              params->frontReference);
749                     vkCmdSetStencilReference(cmdBuffer, VK_STENCIL_FACE_BACK_BIT,
750                                              params->backReference);
751                     break;
752                 }
753                 case CommandID::SetStencilTestEnable:
754                 {
755                     const SetStencilTestEnableParams *params =
756                         getParamPtr<SetStencilTestEnableParams>(currentCommand);
757                     vkCmdSetStencilTestEnableEXT(cmdBuffer, params->stencilTestEnable);
758                     break;
759                 }
760                 case CommandID::SetStencilWriteMask:
761                 {
762                     const SetStencilWriteMaskParams *params =
763                         getParamPtr<SetStencilWriteMaskParams>(currentCommand);
764                     vkCmdSetStencilWriteMask(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT,
765                                              params->writeFrontMask);
766                     vkCmdSetStencilWriteMask(cmdBuffer, VK_STENCIL_FACE_BACK_BIT,
767                                              params->writeBackMask);
768                     break;
769                 }
770                 case CommandID::SetVertexInput:
771                 {
772                     const SetVertexInputParams *params =
773                         getParamPtr<SetVertexInputParams>(currentCommand);
774                     const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions =
775                         GetFirstArrayParameter<VkVertexInputBindingDescription2EXT>(params);
776                     const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions =
777                         GetNextArrayParameter<VkVertexInputAttributeDescription2EXT,
778                                               VkVertexInputBindingDescription2EXT>(
779                             vertexBindingDescriptions, params->vertexBindingDescriptionCount);
780 
781                     vkCmdSetVertexInputEXT(
782                         cmdBuffer, params->vertexBindingDescriptionCount, vertexBindingDescriptions,
783                         params->vertexAttributeDescriptionCount, vertexAttributeDescriptions);
784                     break;
785                 }
786                 case CommandID::SetViewport:
787                 {
788                     const SetViewportParams *params =
789                         getParamPtr<SetViewportParams>(currentCommand);
790                     vkCmdSetViewport(cmdBuffer, 0, 1, &params->viewport);
791                     break;
792                 }
793                 case CommandID::WaitEvents:
794                 {
795                     const WaitEventsParams *params = getParamPtr<WaitEventsParams>(currentCommand);
796                     const VkEvent *events          = GetFirstArrayParameter<VkEvent>(params);
797                     const VkMemoryBarrier *memoryBarriers =
798                         GetNextArrayParameter<VkMemoryBarrier>(events, params->eventCount);
799                     const VkImageMemoryBarrier *imageMemoryBarriers =
800                         GetNextArrayParameter<VkImageMemoryBarrier>(memoryBarriers,
801                                                                     params->memoryBarrierCount);
802                     vkCmdWaitEvents(cmdBuffer, params->eventCount, events, params->srcStageMask,
803                                     params->dstStageMask, params->memoryBarrierCount,
804                                     memoryBarriers, 0, nullptr, params->imageMemoryBarrierCount,
805                                     imageMemoryBarriers);
806                     break;
807                 }
808                 case CommandID::WriteTimestamp:
809                 {
810                     const WriteTimestampParams *params =
811                         getParamPtr<WriteTimestampParams>(currentCommand);
812                     vkCmdWriteTimestamp(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
813                                         params->queryPool, params->query);
814                     break;
815                 }
816                 default:
817                 {
818                     UNREACHABLE();
819                     break;
820                 }
821             }
822         }
823     }
824 }
825 
getMemoryUsageStats(size_t * usedMemoryOut,size_t * allocatedMemoryOut) const826 void SecondaryCommandBuffer::getMemoryUsageStats(size_t *usedMemoryOut,
827                                                  size_t *allocatedMemoryOut) const
828 {
829     mCommandAllocator.getMemoryUsageStats(usedMemoryOut, allocatedMemoryOut);
830 }
831 
getMemoryUsageStatsForPoolAlloc(size_t blockSize,size_t * usedMemoryOut,size_t * allocatedMemoryOut) const832 void SecondaryCommandBuffer::getMemoryUsageStatsForPoolAlloc(size_t blockSize,
833                                                              size_t *usedMemoryOut,
834                                                              size_t *allocatedMemoryOut) const
835 {
836     *allocatedMemoryOut = blockSize * mCommands.size();
837 
838     *usedMemoryOut = 0;
839     for (const CommandHeader *command : mCommands)
840     {
841         const CommandHeader *commandEnd = command;
842         while (commandEnd->id != CommandID::Invalid)
843         {
844             commandEnd = NextCommand(commandEnd);
845         }
846 
847         *usedMemoryOut += reinterpret_cast<const uint8_t *>(commandEnd) -
848                           reinterpret_cast<const uint8_t *>(command) + sizeof(CommandHeader::id);
849     }
850 
851     ASSERT(*usedMemoryOut <= *allocatedMemoryOut);
852 }
853 
dumpCommands(const char * separator) const854 std::string SecondaryCommandBuffer::dumpCommands(const char *separator) const
855 {
856     std::stringstream result;
857     for (const CommandHeader *command : mCommands)
858     {
859         for (const CommandHeader *currentCommand                      = command;
860              currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand))
861         {
862             result << GetCommandString(currentCommand->id) << separator;
863         }
864     }
865     return result.str();
866 }
867 
868 }  // namespace priv
869 }  // namespace vk
870 }  // namespace rx
871