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