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