• 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                     // 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,
361                                              params->drawCount, params->stride);
362                     break;
363                 }
364                 case CommandID::DrawIndexedInstanced:
365                 {
366                     const DrawIndexedInstancedParams *params =
367                         getParamPtr<DrawIndexedInstancedParams>(currentCommand);
368                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, 0, 0);
369                     break;
370                 }
371                 case CommandID::DrawIndexedInstancedBaseVertex:
372                 {
373                     const DrawIndexedInstancedBaseVertexParams *params =
374                         getParamPtr<DrawIndexedInstancedBaseVertexParams>(currentCommand);
375                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0,
376                                      params->vertexOffset, 0);
377                     break;
378                 }
379                 case CommandID::DrawIndexedInstancedBaseVertexBaseInstance:
380                 {
381                     const DrawIndexedInstancedBaseVertexBaseInstanceParams *params =
382                         getParamPtr<DrawIndexedInstancedBaseVertexBaseInstanceParams>(
383                             currentCommand);
384                     vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount,
385                                      params->firstIndex, params->vertexOffset,
386                                      params->firstInstance);
387                     break;
388                 }
389                 case CommandID::DrawIndirect:
390                 {
391                     const DrawIndirectParams *params =
392                         getParamPtr<DrawIndirectParams>(currentCommand);
393                     vkCmdDrawIndirect(cmdBuffer, params->buffer, params->offset, params->drawCount,
394                                       params->stride);
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::FillBuffer:
440                 {
441                     const FillBufferParams *params = getParamPtr<FillBufferParams>(currentCommand);
442                     vkCmdFillBuffer(cmdBuffer, params->dstBuffer, params->dstOffset, params->size,
443                                     params->data);
444                     break;
445                 }
446                 case CommandID::ImageBarrier:
447                 {
448                     const ImageBarrierParams *params =
449                         getParamPtr<ImageBarrierParams>(currentCommand);
450                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
451                                          0, nullptr, 0, nullptr, 1, &params->imageMemoryBarrier);
452                     break;
453                 }
454                 case CommandID::InsertDebugUtilsLabel:
455                 {
456                     const DebugUtilsLabelParams *params =
457                         getParamPtr<DebugUtilsLabelParams>(currentCommand);
458                     const char *pLabelName = Offset<char>(params, sizeof(DebugUtilsLabelParams));
459                     const VkDebugUtilsLabelEXT label = {
460                         VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT,
461                         nullptr,
462                         pLabelName,
463                         {params->color[0], params->color[1], params->color[2], params->color[3]}};
464                     ASSERT(vkCmdInsertDebugUtilsLabelEXT);
465                     vkCmdInsertDebugUtilsLabelEXT(cmdBuffer, &label);
466                     break;
467                 }
468                 case CommandID::MemoryBarrier:
469                 {
470                     const MemoryBarrierParams *params =
471                         getParamPtr<MemoryBarrierParams>(currentCommand);
472                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0,
473                                          1, &params->memoryBarrier, 0, nullptr, 0, nullptr);
474                     break;
475                 }
476                 case CommandID::NextSubpass:
477                 {
478                     const NextSubpassParams *params =
479                         getParamPtr<NextSubpassParams>(currentCommand);
480                     vkCmdNextSubpass(cmdBuffer, params->subpassContents);
481                     break;
482                 }
483                 case CommandID::PipelineBarrier:
484                 {
485                     const PipelineBarrierParams *params =
486                         getParamPtr<PipelineBarrierParams>(currentCommand);
487                     const VkMemoryBarrier *memoryBarriers =
488                         Offset<VkMemoryBarrier>(params, sizeof(PipelineBarrierParams));
489                     const VkBufferMemoryBarrier *bufferMemoryBarriers =
490                         Offset<VkBufferMemoryBarrier>(
491                             memoryBarriers, params->memoryBarrierCount * sizeof(VkMemoryBarrier));
492                     const VkImageMemoryBarrier *imageMemoryBarriers = Offset<VkImageMemoryBarrier>(
493                         bufferMemoryBarriers,
494                         params->bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier));
495                     vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask,
496                                          params->dependencyFlags, params->memoryBarrierCount,
497                                          memoryBarriers, params->bufferMemoryBarrierCount,
498                                          bufferMemoryBarriers, params->imageMemoryBarrierCount,
499                                          imageMemoryBarriers);
500                     break;
501                 }
502                 case CommandID::PushConstants:
503                 {
504                     const PushConstantsParams *params =
505                         getParamPtr<PushConstantsParams>(currentCommand);
506                     const void *data = Offset<void>(params, sizeof(PushConstantsParams));
507                     vkCmdPushConstants(cmdBuffer, params->layout, params->flag, params->offset,
508                                        params->size, data);
509                     break;
510                 }
511                 case CommandID::ResetEvent:
512                 {
513                     const ResetEventParams *params = getParamPtr<ResetEventParams>(currentCommand);
514                     vkCmdResetEvent(cmdBuffer, params->event, params->stageMask);
515                     break;
516                 }
517                 case CommandID::ResetQueryPool:
518                 {
519                     const ResetQueryPoolParams *params =
520                         getParamPtr<ResetQueryPoolParams>(currentCommand);
521                     vkCmdResetQueryPool(cmdBuffer, params->queryPool, params->firstQuery,
522                                         params->queryCount);
523                     break;
524                 }
525                 case CommandID::ResolveImage:
526                 {
527                     const ResolveImageParams *params =
528                         getParamPtr<ResolveImageParams>(currentCommand);
529                     vkCmdResolveImage(cmdBuffer, params->srcImage,
530                                       VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, params->dstImage,
531                                       VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &params->region);
532                     break;
533                 }
534                 case CommandID::SetEvent:
535                 {
536                     const SetEventParams *params = getParamPtr<SetEventParams>(currentCommand);
537                     vkCmdSetEvent(cmdBuffer, params->event, params->stageMask);
538                     break;
539                 }
540                 case CommandID::SetScissor:
541                 {
542                     const SetScissorParams *params = getParamPtr<SetScissorParams>(currentCommand);
543                     vkCmdSetScissor(cmdBuffer, 0, 1, &params->scissor);
544                     break;
545                 }
546                 case CommandID::SetViewport:
547                 {
548                     const SetViewportParams *params =
549                         getParamPtr<SetViewportParams>(currentCommand);
550                     vkCmdSetViewport(cmdBuffer, 0, 1, &params->viewport);
551                     break;
552                 }
553                 case CommandID::WaitEvents:
554                 {
555                     const WaitEventsParams *params = getParamPtr<WaitEventsParams>(currentCommand);
556                     const VkEvent *events = Offset<VkEvent>(params, sizeof(WaitEventsParams));
557                     const VkMemoryBarrier *memoryBarriers =
558                         Offset<VkMemoryBarrier>(events, params->eventCount * sizeof(VkEvent));
559                     const VkBufferMemoryBarrier *bufferMemoryBarriers =
560                         Offset<VkBufferMemoryBarrier>(
561                             memoryBarriers, params->memoryBarrierCount * sizeof(VkMemoryBarrier));
562                     const VkImageMemoryBarrier *imageMemoryBarriers = Offset<VkImageMemoryBarrier>(
563                         bufferMemoryBarriers,
564                         params->bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier));
565                     vkCmdWaitEvents(cmdBuffer, params->eventCount, events, params->srcStageMask,
566                                     params->dstStageMask, params->memoryBarrierCount,
567                                     memoryBarriers, params->bufferMemoryBarrierCount,
568                                     bufferMemoryBarriers, params->imageMemoryBarrierCount,
569                                     imageMemoryBarriers);
570                     break;
571                 }
572                 case CommandID::WriteTimestamp:
573                 {
574                     const WriteTimestampParams *params =
575                         getParamPtr<WriteTimestampParams>(currentCommand);
576                     vkCmdWriteTimestamp(cmdBuffer, params->pipelineStage, params->queryPool,
577                                         params->query);
578                     break;
579                 }
580                 default:
581                 {
582                     UNREACHABLE();
583                     break;
584                 }
585             }
586         }
587     }
588 }
589 
getMemoryUsageStats(size_t * usedMemoryOut,size_t * allocatedMemoryOut) const590 void SecondaryCommandBuffer::getMemoryUsageStats(size_t *usedMemoryOut,
591                                                  size_t *allocatedMemoryOut) const
592 {
593     *allocatedMemoryOut = kBlockSize * mCommands.size();
594 
595     *usedMemoryOut = 0;
596     for (const CommandHeader *command : mCommands)
597     {
598         const CommandHeader *commandEnd = command;
599         while (commandEnd->id != CommandID::Invalid)
600         {
601             commandEnd = NextCommand(commandEnd);
602         }
603 
604         *usedMemoryOut += reinterpret_cast<const uint8_t *>(commandEnd) -
605                           reinterpret_cast<const uint8_t *>(command) + sizeof(CommandHeader::id);
606     }
607 
608     ASSERT(*usedMemoryOut <= *allocatedMemoryOut);
609 }
610 
dumpCommands(const char * separator) const611 std::string SecondaryCommandBuffer::dumpCommands(const char *separator) const
612 {
613     std::stringstream result;
614     for (const CommandHeader *command : mCommands)
615     {
616         for (const CommandHeader *currentCommand                      = command;
617              currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand))
618         {
619             result << GetCommandString(currentCommand->id) << separator;
620         }
621     }
622     return result.str();
623 }
624 
625 }  // namespace priv
626 }  // namespace vk
627 }  // namespace rx
628