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, ¶ms->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, ¶ms->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 ¶ms->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 ¶ms->color, 1, ¶ms->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 ¶ms->depthStencil, 1, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->scissor);
544 break;
545 }
546 case CommandID::SetViewport:
547 {
548 const SetViewportParams *params =
549 getParamPtr<SetViewportParams>(currentCommand);
550 vkCmdSetViewport(cmdBuffer, 0, 1, ¶ms->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