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