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