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, ¶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, 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, ¶ms->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, ¶ms->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, ¶ms->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, ¶ms->scissor);
550 break;
551 }
552 case CommandID::SetViewport:
553 {
554 const SetViewportParams *params =
555 getParamPtr<SetViewportParams>(currentCommand);
556 vkCmdSetViewport(cmdBuffer, 0, 1, ¶ms->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