• 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 
14 namespace rx
15 {
16 namespace vk
17 {
18 namespace priv
19 {
20 namespace
21 {
GetCommandString(CommandID id)22 const char *GetCommandString(CommandID id)
23 {
24     switch (id)
25     {
26         case CommandID::Invalid:
27             return "--Invalid--";
28         case CommandID::BeginQuery:
29             return "BeginQuery";
30         case CommandID::BeginTransformFeedback:
31             return "BeginTransformFeedback";
32         case CommandID::BindComputePipeline:
33             return "BindComputePipeline";
34         case CommandID::BindDescriptorSets:
35             return "BindDescriptorSets";
36         case CommandID::BindGraphicsPipeline:
37             return "BindGraphicsPipeline";
38         case CommandID::BindIndexBuffer:
39             return "BindIndexBuffer";
40         case CommandID::BindTransformFeedbackBuffers:
41             return "BindTransformFeedbackBuffers";
42         case CommandID::BindVertexBuffers:
43             return "BindVertexBuffers";
44         case CommandID::BlitImage:
45             return "BlitImage";
46         case CommandID::BufferBarrier:
47             return "BufferBarrier";
48         case CommandID::ClearAttachments:
49             return "ClearAttachments";
50         case CommandID::ClearColorImage:
51             return "ClearColorImage";
52         case CommandID::ClearDepthStencilImage:
53             return "ClearDepthStencilImage";
54         case CommandID::CopyBuffer:
55             return "CopyBuffer";
56         case CommandID::CopyBufferToImage:
57             return "CopyBufferToImage";
58         case CommandID::CopyImage:
59             return "CopyImage";
60         case CommandID::CopyImageToBuffer:
61             return "CopyImageToBuffer";
62         case CommandID::Dispatch:
63             return "Dispatch";
64         case CommandID::DispatchIndirect:
65             return "DispatchIndirect";
66         case CommandID::Draw:
67             return "Draw";
68         case CommandID::DrawIndexed:
69             return "DrawIndexed";
70         case CommandID::DrawIndexedBaseVertex:
71             return "DrawIndexedBaseVertex";
72         case CommandID::DrawIndexedIndirect:
73             return "DrawIndexedIndirect";
74         case CommandID::DrawIndexedInstanced:
75             return "DrawIndexedInstanced";
76         case CommandID::DrawIndexedInstancedBaseVertex:
77             return "DrawIndexedInstancedBaseVertex";
78         case CommandID::DrawIndexedInstancedBaseVertexBaseInstance:
79             return "DrawIndexedInstancedBaseVertexBaseInstance";
80         case CommandID::DrawIndirect:
81             return "DrawIndirect";
82         case CommandID::DrawInstanced:
83             return "DrawInstanced";
84         case CommandID::DrawInstancedBaseInstance:
85             return "DrawInstancedBaseInstance";
86         case CommandID::EndQuery:
87             return "EndQuery";
88         case CommandID::EndTransformFeedback:
89             return "EndTransformFeedback";
90         case CommandID::ExecutionBarrier:
91             return "ExecutionBarrier";
92         case CommandID::FillBuffer:
93             return "FillBuffer";
94         case CommandID::ImageBarrier:
95             return "ImageBarrier";
96         case CommandID::MemoryBarrier:
97             return "MemoryBarrier";
98         case CommandID::PipelineBarrier:
99             return "PipelineBarrier";
100         case CommandID::PushConstants:
101             return "PushConstants";
102         case CommandID::ResetEvent:
103             return "ResetEvent";
104         case CommandID::ResetQueryPool:
105             return "ResetQueryPool";
106         case CommandID::ResolveImage:
107             return "ResolveImage";
108         case CommandID::SetEvent:
109             return "SetEvent";
110         case CommandID::WaitEvents:
111             return "WaitEvents";
112         case CommandID::WriteTimestamp:
113             return "WriteTimestamp";
114         default:
115             // Need this to work around MSVC warning 4715.
116             UNREACHABLE();
117             return "--unreachable--";
118     }
119 }
120 }  // namespace
121 
NextCommand(const CommandHeader * command)122 ANGLE_INLINE const CommandHeader *NextCommand(const CommandHeader *command)
123 {
124     return reinterpret_cast<const CommandHeader *>(reinterpret_cast<const uint8_t *>(command) +
125                                                    command->size);
126 }
127 
128 // Parse the cmds in this cmd buffer into given primary cmd buffer
executeCommands(VkCommandBuffer cmdBuffer)129 void SecondaryCommandBuffer::executeCommands(VkCommandBuffer cmdBuffer)
130 {
131     for (const CommandHeader *command : mCommands)
132     {
133         for (const CommandHeader *currentCommand                      = command;
134              currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand))
135         {
136             switch (currentCommand->id)
137             {
138                 case CommandID::BeginQuery:
139                 {
140                     const BeginQueryParams *params = getParamPtr<BeginQueryParams>(currentCommand);
141                     vkCmdBeginQuery(cmdBuffer, params->queryPool, params->query, params->flags);
142                     break;
143                 }
144                 case CommandID::BeginTransformFeedback:
145                 {
146                     const BeginTransformFeedbackParams *params =
147                         getParamPtr<BeginTransformFeedbackParams>(currentCommand);
148                     const VkBuffer *counterBuffers =
149                         Offset<VkBuffer>(params, sizeof(BeginTransformFeedbackParams));
150                     // Workaround for AMD driver bug where it expects the offsets array to be
151                     // non-null
152                     gl::TransformFeedbackBuffersArray<VkDeviceSize> offsets;
153                     offsets.fill(0);
154                     vkCmdBeginTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount,
155                                                    counterBuffers, offsets.data());
156                     break;
157                 }
158                 case CommandID::BindComputePipeline:
159                 {
160                     const BindPipelineParams *params =
161                         getParamPtr<BindPipelineParams>(currentCommand);
162                     vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, params->pipeline);
163                     break;
164                 }
165                 case CommandID::BindDescriptorSets:
166                 {
167                     const BindDescriptorSetParams *params =
168                         getParamPtr<BindDescriptorSetParams>(currentCommand);
169                     const VkDescriptorSet *descriptorSets =
170                         Offset<VkDescriptorSet>(params, sizeof(BindDescriptorSetParams));
171                     const uint32_t *dynamicOffsets = Offset<uint32_t>(
172                         descriptorSets, sizeof(VkDescriptorSet) * params->descriptorSetCount);
173                     vkCmdBindDescriptorSets(cmdBuffer, params->pipelineBindPoint, params->layout,
174                                             params->firstSet, params->descriptorSetCount,
175                                             descriptorSets, params->dynamicOffsetCount,
176                                             dynamicOffsets);
177                     break;
178                 }
179                 case CommandID::BindGraphicsPipeline:
180                 {
181                     const BindPipelineParams *params =
182                         getParamPtr<BindPipelineParams>(currentCommand);
183                     vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, params->pipeline);
184                     break;
185                 }
186                 case CommandID::BindIndexBuffer:
187                 {
188                     const BindIndexBufferParams *params =
189                         getParamPtr<BindIndexBufferParams>(currentCommand);
190                     vkCmdBindIndexBuffer(cmdBuffer, params->buffer, params->offset,
191                                          params->indexType);
192                     break;
193                 }
194                 case CommandID::BindTransformFeedbackBuffers:
195                 {
196                     const BindTransformFeedbackBuffersParams *params =
197                         getParamPtr<BindTransformFeedbackBuffersParams>(currentCommand);
198                     const VkBuffer *buffers =
199                         Offset<VkBuffer>(params, sizeof(BindTransformFeedbackBuffersParams));
200                     const VkDeviceSize *offsets =
201                         Offset<VkDeviceSize>(buffers, sizeof(VkBuffer) * params->bindingCount);
202                     const VkDeviceSize *sizes =
203                         Offset<VkDeviceSize>(offsets, sizeof(VkDeviceSize) * params->bindingCount);
204                     vkCmdBindTransformFeedbackBuffersEXT(cmdBuffer, 0, params->bindingCount,
205                                                          buffers, offsets, sizes);
206                     break;
207                 }
208                 case CommandID::BindVertexBuffers:
209                 {
210                     const BindVertexBuffersParams *params =
211                         getParamPtr<BindVertexBuffersParams>(currentCommand);
212                     const VkBuffer *buffers =
213                         Offset<VkBuffer>(params, sizeof(BindVertexBuffersParams));
214                     const VkDeviceSize *offsets =
215                         Offset<VkDeviceSize>(buffers, sizeof(VkBuffer) * params->bindingCount);
216                     vkCmdBindVertexBuffers(cmdBuffer, 0, params->bindingCount, buffers, offsets);
217                     break;
218                 }
219                 case CommandID::BlitImage:
220                 {
221                     const BlitImageParams *params = getParamPtr<BlitImageParams>(currentCommand);
222                     vkCmdBlitImage(cmdBuffer, params->srcImage,
223                                    VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, params->dstImage,
224                                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &params->region,
225                                    params->filter);
226                     break;
227                 }
228                 case CommandID::BufferBarrier:
229                 {
230                     const BufferBarrierParams *params =
231                         getParamPtr<BufferBarrierParams>(currentCommand);
232                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
233                                          0, nullptr, 1, &params->bufferMemoryBarrier, 0, nullptr);
234                     break;
235                 }
236                 case CommandID::ClearAttachments:
237                 {
238                     const ClearAttachmentsParams *params =
239                         getParamPtr<ClearAttachmentsParams>(currentCommand);
240                     const VkClearAttachment *attachments =
241                         Offset<VkClearAttachment>(params, sizeof(ClearAttachmentsParams));
242                     vkCmdClearAttachments(cmdBuffer, params->attachmentCount, attachments, 1,
243                                           &params->rect);
244                     break;
245                 }
246                 case CommandID::ClearColorImage:
247                 {
248                     const ClearColorImageParams *params =
249                         getParamPtr<ClearColorImageParams>(currentCommand);
250                     vkCmdClearColorImage(cmdBuffer, params->image, params->imageLayout,
251                                          &params->color, 1, &params->range);
252                     break;
253                 }
254                 case CommandID::ClearDepthStencilImage:
255                 {
256                     const ClearDepthStencilImageParams *params =
257                         getParamPtr<ClearDepthStencilImageParams>(currentCommand);
258                     vkCmdClearDepthStencilImage(cmdBuffer, params->image, params->imageLayout,
259                                                 &params->depthStencil, 1, &params->range);
260                     break;
261                 }
262                 case CommandID::CopyBuffer:
263                 {
264                     const CopyBufferParams *params = getParamPtr<CopyBufferParams>(currentCommand);
265                     const VkBufferCopy *regions =
266                         Offset<VkBufferCopy>(params, sizeof(CopyBufferParams));
267                     vkCmdCopyBuffer(cmdBuffer, params->srcBuffer, params->destBuffer,
268                                     params->regionCount, regions);
269                     break;
270                 }
271                 case CommandID::CopyBufferToImage:
272                 {
273                     const CopyBufferToImageParams *params =
274                         getParamPtr<CopyBufferToImageParams>(currentCommand);
275                     vkCmdCopyBufferToImage(cmdBuffer, params->srcBuffer, params->dstImage,
276                                            params->dstImageLayout, 1, &params->region);
277                     break;
278                 }
279                 case CommandID::CopyImage:
280                 {
281                     const CopyImageParams *params = getParamPtr<CopyImageParams>(currentCommand);
282                     vkCmdCopyImage(cmdBuffer, params->srcImage, params->srcImageLayout,
283                                    params->dstImage, params->dstImageLayout, 1, &params->region);
284                     break;
285                 }
286                 case CommandID::CopyImageToBuffer:
287                 {
288                     const CopyImageToBufferParams *params =
289                         getParamPtr<CopyImageToBufferParams>(currentCommand);
290                     vkCmdCopyImageToBuffer(cmdBuffer, params->srcImage, params->srcImageLayout,
291                                            params->dstBuffer, 1, &params->region);
292                     break;
293                 }
294                 case CommandID::Dispatch:
295                 {
296                     const DispatchParams *params = getParamPtr<DispatchParams>(currentCommand);
297                     vkCmdDispatch(cmdBuffer, params->groupCountX, params->groupCountY,
298                                   params->groupCountZ);
299                     break;
300                 }
301                 case CommandID::DispatchIndirect:
302                 {
303                     const DispatchIndirectParams *params =
304                         getParamPtr<DispatchIndirectParams>(currentCommand);
305                     vkCmdDispatchIndirect(cmdBuffer, params->buffer, params->offset);
306                     break;
307                 }
308                 case CommandID::Draw:
309                 {
310                     const DrawParams *params = getParamPtr<DrawParams>(currentCommand);
311                     vkCmdDraw(cmdBuffer, params->vertexCount, 1, params->firstVertex, 0);
312                     break;
313                 }
314                 case CommandID::DrawIndexed:
315                 {
316                     const DrawIndexedParams *params =
317                         getParamPtr<DrawIndexedParams>(currentCommand);
318                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, 0, 0);
319                     break;
320                 }
321                 case CommandID::DrawIndexedBaseVertex:
322                 {
323                     const DrawIndexedBaseVertexParams *params =
324                         getParamPtr<DrawIndexedBaseVertexParams>(currentCommand);
325                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, params->vertexOffset, 0);
326                     break;
327                 }
328                 case CommandID::DrawIndexedIndirect:
329                 {
330                     const DrawIndexedIndirectParams *params =
331                         getParamPtr<DrawIndexedIndirectParams>(currentCommand);
332                     vkCmdDrawIndexedIndirect(cmdBuffer, params->buffer, params->offset, 1, 0);
333                     break;
334                 }
335                 case CommandID::DrawIndexedInstanced:
336                 {
337                     const DrawIndexedInstancedParams *params =
338                         getParamPtr<DrawIndexedInstancedParams>(currentCommand);
339                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, 0, 0);
340                     break;
341                 }
342                 case CommandID::DrawIndexedInstancedBaseVertex:
343                 {
344                     const DrawIndexedInstancedBaseVertexParams *params =
345                         getParamPtr<DrawIndexedInstancedBaseVertexParams>(currentCommand);
346                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0,
347                                      params->vertexOffset, 0);
348                     break;
349                 }
350                 case CommandID::DrawIndexedInstancedBaseVertexBaseInstance:
351                 {
352                     const DrawIndexedInstancedBaseVertexBaseInstanceParams *params =
353                         getParamPtr<DrawIndexedInstancedBaseVertexBaseInstanceParams>(
354                             currentCommand);
355                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount,
356                                      params->firstIndex, params->vertexOffset,
357                                      params->firstInstance);
358                     break;
359                 }
360                 case CommandID::DrawIndirect:
361                 {
362                     const DrawIndirectParams *params =
363                         getParamPtr<DrawIndirectParams>(currentCommand);
364                     vkCmdDrawIndirect(cmdBuffer, params->buffer, params->offset, 1, 0);
365                     break;
366                 }
367                 case CommandID::DrawInstanced:
368                 {
369                     const DrawInstancedParams *params =
370                         getParamPtr<DrawInstancedParams>(currentCommand);
371                     vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount,
372                               params->firstVertex, 0);
373                     break;
374                 }
375                 case CommandID::DrawInstancedBaseInstance:
376                 {
377                     const DrawInstancedBaseInstanceParams *params =
378                         getParamPtr<DrawInstancedBaseInstanceParams>(currentCommand);
379                     vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount,
380                               params->firstVertex, params->firstInstance);
381                     break;
382                 }
383                 case CommandID::EndQuery:
384                 {
385                     const EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand);
386                     vkCmdEndQuery(cmdBuffer, params->queryPool, params->query);
387                     break;
388                 }
389                 case CommandID::EndTransformFeedback:
390                 {
391                     const EndTransformFeedbackParams *params =
392                         getParamPtr<EndTransformFeedbackParams>(currentCommand);
393                     const VkBuffer *counterBuffers =
394                         Offset<VkBuffer>(params, sizeof(EndTransformFeedbackParams));
395                     // Workaround for AMD driver bug where it expects the offsets array to be
396                     // non-null
397                     gl::TransformFeedbackBuffersArray<VkDeviceSize> offsets;
398                     offsets.fill(0);
399                     vkCmdEndTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount, counterBuffers,
400                                                  offsets.data());
401                     break;
402                 }
403                 case CommandID::ExecutionBarrier:
404                 {
405                     const ExecutionBarrierParams *params =
406                         getParamPtr<ExecutionBarrierParams>(currentCommand);
407                     vkCmdPipelineBarrier(cmdBuffer, params->stageMask, params->stageMask, 0, 0,
408                                          nullptr, 0, nullptr, 0, nullptr);
409                     break;
410                 }
411                 case CommandID::FillBuffer:
412                 {
413                     const FillBufferParams *params = getParamPtr<FillBufferParams>(currentCommand);
414                     vkCmdFillBuffer(cmdBuffer, params->dstBuffer, params->dstOffset, params->size,
415                                     params->data);
416                     break;
417                 }
418                 case CommandID::ImageBarrier:
419                 {
420                     const ImageBarrierParams *params =
421                         getParamPtr<ImageBarrierParams>(currentCommand);
422                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
423                                          0, nullptr, 0, nullptr, 1, &params->imageMemoryBarrier);
424                     break;
425                 }
426                 case CommandID::MemoryBarrier:
427                 {
428                     const MemoryBarrierParams *params =
429                         getParamPtr<MemoryBarrierParams>(currentCommand);
430                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
431                                          1, &params->memoryBarrier, 0, nullptr, 0, nullptr);
432                     break;
433                 }
434                 case CommandID::PipelineBarrier:
435                 {
436                     const PipelineBarrierParams *params =
437                         getParamPtr<PipelineBarrierParams>(currentCommand);
438                     const VkMemoryBarrier *memoryBarriers =
439                         Offset<VkMemoryBarrier>(params, sizeof(PipelineBarrierParams));
440                     const VkBufferMemoryBarrier *bufferMemoryBarriers =
441                         Offset<VkBufferMemoryBarrier>(
442                             memoryBarriers, params->memoryBarrierCount * sizeof(VkMemoryBarrier));
443                     const VkImageMemoryBarrier *imageMemoryBarriers = Offset<VkImageMemoryBarrier>(
444                         bufferMemoryBarriers,
445                         params->bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier));
446                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask,
447                                          params->dependencyFlags, params->memoryBarrierCount,
448                                          memoryBarriers, params->bufferMemoryBarrierCount,
449                                          bufferMemoryBarriers, params->imageMemoryBarrierCount,
450                                          imageMemoryBarriers);
451                     break;
452                 }
453                 case CommandID::PushConstants:
454                 {
455                     const PushConstantsParams *params =
456                         getParamPtr<PushConstantsParams>(currentCommand);
457                     const void *data = Offset<void>(params, sizeof(PushConstantsParams));
458                     vkCmdPushConstants(cmdBuffer, params->layout, params->flag, params->offset,
459                                        params->size, data);
460                     break;
461                 }
462                 case CommandID::ResetEvent:
463                 {
464                     const ResetEventParams *params = getParamPtr<ResetEventParams>(currentCommand);
465                     vkCmdResetEvent(cmdBuffer, params->event, params->stageMask);
466                     break;
467                 }
468                 case CommandID::ResetQueryPool:
469                 {
470                     const ResetQueryPoolParams *params =
471                         getParamPtr<ResetQueryPoolParams>(currentCommand);
472                     vkCmdResetQueryPool(cmdBuffer, params->queryPool, params->firstQuery,
473                                         params->queryCount);
474                     break;
475                 }
476                 case CommandID::ResolveImage:
477                 {
478                     const ResolveImageParams *params =
479                         getParamPtr<ResolveImageParams>(currentCommand);
480                     vkCmdResolveImage(cmdBuffer, params->srcImage,
481                                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, params->dstImage,
482                                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &params->region);
483                     break;
484                 }
485                 case CommandID::SetEvent:
486                 {
487                     const SetEventParams *params = getParamPtr<SetEventParams>(currentCommand);
488                     vkCmdSetEvent(cmdBuffer, params->event, params->stageMask);
489                     break;
490                 }
491                 case CommandID::WaitEvents:
492                 {
493                     const WaitEventsParams *params = getParamPtr<WaitEventsParams>(currentCommand);
494                     const VkEvent *events = Offset<VkEvent>(params, sizeof(WaitEventsParams));
495                     const VkMemoryBarrier *memoryBarriers =
496                         Offset<VkMemoryBarrier>(events, params->eventCount * sizeof(VkEvent));
497                     const VkBufferMemoryBarrier *bufferMemoryBarriers =
498                         Offset<VkBufferMemoryBarrier>(
499                             memoryBarriers, params->memoryBarrierCount * sizeof(VkMemoryBarrier));
500                     const VkImageMemoryBarrier *imageMemoryBarriers = Offset<VkImageMemoryBarrier>(
501                         bufferMemoryBarriers,
502                         params->bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier));
503                     vkCmdWaitEvents(cmdBuffer, params->eventCount, events, params->srcStageMask,
504                                     params->dstStageMask, params->memoryBarrierCount,
505                                     memoryBarriers, params->bufferMemoryBarrierCount,
506                                     bufferMemoryBarriers, params->imageMemoryBarrierCount,
507                                     imageMemoryBarriers);
508                     break;
509                 }
510                 case CommandID::WriteTimestamp:
511                 {
512                     const WriteTimestampParams *params =
513                         getParamPtr<WriteTimestampParams>(currentCommand);
514                     vkCmdWriteTimestamp(cmdBuffer, params->pipelineStage, params->queryPool,
515                                         params->query);
516                     break;
517                 }
518                 default:
519                 {
520                     UNREACHABLE();
521                     break;
522                 }
523             }
524         }
525     }
526 }
527 
getMemoryUsageStats(size_t * usedMemoryOut,size_t * allocatedMemoryOut) const528 void SecondaryCommandBuffer::getMemoryUsageStats(size_t *usedMemoryOut,
529                                                  size_t *allocatedMemoryOut) const
530 {
531     *allocatedMemoryOut = kBlockSize * mCommands.size();
532 
533     *usedMemoryOut = 0;
534     for (const CommandHeader *command : mCommands)
535     {
536         const CommandHeader *commandEnd = command;
537         while (commandEnd->id != CommandID::Invalid)
538         {
539             commandEnd = NextCommand(commandEnd);
540         }
541 
542         *usedMemoryOut += reinterpret_cast<const uint8_t *>(commandEnd) -
543                           reinterpret_cast<const uint8_t *>(command) + sizeof(CommandHeader::id);
544     }
545 
546     ASSERT(*usedMemoryOut <= *allocatedMemoryOut);
547 }
548 
dumpCommands(const char * separator) const549 std::string SecondaryCommandBuffer::dumpCommands(const char *separator) const
550 {
551     std::stringstream result;
552     for (const CommandHeader *command : mCommands)
553     {
554         for (const CommandHeader *currentCommand                      = command;
555              currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand))
556         {
557             result << GetCommandString(currentCommand->id) << separator;
558         }
559     }
560     return result.str();
561 }
562 
563 }  // namespace priv
564 }  // namespace vk
565 }  // namespace rx
566