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 // Lightweight, CPU-Side command buffers used to hold command state until
8 // it has to be submitted to GPU.
9 //
10
11 #ifndef LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
12 #define LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
13
14 #include "common/vulkan/vk_headers.h"
15 #include "libANGLE/renderer/vulkan/vk_command_buffer_utils.h"
16 #include "libANGLE/renderer/vulkan/vk_wrapper.h"
17
18 #if ANGLE_ENABLE_VULKAN_SHARED_RING_BUFFER_CMD_ALLOC
19 # include "libANGLE/renderer/vulkan/AllocatorHelperRing.h"
20 #else
21 # include "libANGLE/renderer/vulkan/AllocatorHelperPool.h"
22 #endif
23
24 namespace rx
25 {
26 class ContextVk;
27
28 namespace vk
29 {
30 class Context;
31 class RenderPassDesc;
32 class SecondaryCommandPool;
33
34 #if ANGLE_ENABLE_VULKAN_SHARED_RING_BUFFER_CMD_ALLOC
35 using SecondaryCommandMemoryAllocator = SharedCommandMemoryAllocator;
36 using SecondaryCommandBlockPool = SharedCommandBlockPool;
37 using SecondaryCommandBlockAllocator = SharedCommandBlockAllocator;
38 #else
39 using SecondaryCommandMemoryAllocator = DedicatedCommandMemoryAllocator;
40 using SecondaryCommandBlockPool = DedicatedCommandBlockPool;
41 using SecondaryCommandBlockAllocator = DedicatedCommandBlockAllocator;
42 #endif
43
44 namespace priv
45 {
46
47 // NOTE: Please keep command-related enums, structs, functions and other code dealing with commands
48 // in alphabetical order.
49 // This simplifies searching and updating commands.
50 enum class CommandID : uint16_t
51 {
52 // Invalid cmd used to mark end of sequence of commands
53 Invalid = 0,
54 BeginDebugUtilsLabel,
55 BeginQuery,
56 BeginTransformFeedback,
57 BindComputePipeline,
58 BindDescriptorSets,
59 BindGraphicsPipeline,
60 BindIndexBuffer,
61 BindTransformFeedbackBuffers,
62 BindVertexBuffers,
63 BindVertexBuffers2,
64 BlitImage,
65 BufferBarrier,
66 ClearAttachments,
67 ClearColorImage,
68 ClearDepthStencilImage,
69 CopyBuffer,
70 CopyBufferToImage,
71 CopyImage,
72 CopyImageToBuffer,
73 Dispatch,
74 DispatchIndirect,
75 Draw,
76 DrawIndexed,
77 DrawIndexedBaseVertex,
78 DrawIndexedIndirect,
79 DrawIndexedInstanced,
80 DrawIndexedInstancedBaseVertex,
81 DrawIndexedInstancedBaseVertexBaseInstance,
82 DrawIndirect,
83 DrawInstanced,
84 DrawInstancedBaseInstance,
85 EndDebugUtilsLabel,
86 EndQuery,
87 EndTransformFeedback,
88 FillBuffer,
89 ImageBarrier,
90 ImageWaitEvent,
91 InsertDebugUtilsLabel,
92 MemoryBarrier,
93 NextSubpass,
94 PipelineBarrier,
95 PushConstants,
96 ResetEvent,
97 ResetQueryPool,
98 ResolveImage,
99 SetBlendConstants,
100 SetCullMode,
101 SetDepthBias,
102 SetDepthBiasEnable,
103 SetDepthCompareOp,
104 SetDepthTestEnable,
105 SetDepthWriteEnable,
106 SetEvent,
107 SetFragmentShadingRate,
108 SetFrontFace,
109 SetLineWidth,
110 SetLogicOp,
111 SetPrimitiveRestartEnable,
112 SetRasterizerDiscardEnable,
113 SetScissor,
114 SetStencilCompareMask,
115 SetStencilOp,
116 SetStencilReference,
117 SetStencilTestEnable,
118 SetStencilWriteMask,
119 SetVertexInput,
120 SetViewport,
121 WaitEvents,
122 WriteTimestamp,
123 };
124
125 // Header for every cmd in custom cmd buffer
126 struct CommandHeader
127 {
128 CommandID id;
129 uint16_t size;
130 };
131 static_assert(sizeof(CommandHeader) == 4, "Check CommandHeader size");
132
133 #define VERIFY_8_BYTE_ALIGNMENT(StructName) \
134 static_assert((sizeof(StructName) % 8) == 0, "Check " #StructName " alignment");
135
136 ANGLE_ENABLE_STRUCT_PADDING_WARNINGS
137
138 // Structs to encapsulate parameters for different commands. This makes it easy to know the size of
139 // params & to copy params. Each struct must be prefixed by a CommandHeader (which is 4 bytes) and
140 // must be aligned to 8 bytes.
141 struct BeginQueryParams
142 {
143 CommandHeader header;
144
145 uint32_t query;
146 VkQueryPool queryPool;
147 };
148 VERIFY_8_BYTE_ALIGNMENT(BeginQueryParams)
149
150 struct BeginTransformFeedbackParams
151 {
152 CommandHeader header;
153
154 uint32_t bufferCount;
155 };
156 VERIFY_8_BYTE_ALIGNMENT(BeginTransformFeedbackParams)
157
158 struct BindDescriptorSetParams
159 {
160 CommandHeader header;
161
162 VkPipelineBindPoint pipelineBindPoint : 8;
163 uint32_t firstSet : 8;
164 uint32_t descriptorSetCount : 8;
165 uint32_t dynamicOffsetCount : 8;
166
167 VkPipelineLayout layout;
168 };
169 VERIFY_8_BYTE_ALIGNMENT(BindDescriptorSetParams)
170
171 struct BindIndexBufferParams
172 {
173 CommandHeader header;
174
175 VkIndexType indexType;
176 VkBuffer buffer;
177 VkDeviceSize offset;
178 };
179 VERIFY_8_BYTE_ALIGNMENT(BindIndexBufferParams)
180
181 struct BindPipelineParams
182 {
183 CommandHeader header;
184
185 uint32_t padding;
186 VkPipeline pipeline;
187 };
188 VERIFY_8_BYTE_ALIGNMENT(BindPipelineParams)
189
190 struct BindTransformFeedbackBuffersParams
191 {
192 CommandHeader header;
193
194 // ANGLE always has firstBinding of 0 so not storing that currently
195 uint32_t bindingCount;
196 };
197 VERIFY_8_BYTE_ALIGNMENT(BindTransformFeedbackBuffersParams)
198
199 using BindVertexBuffersParams = BindTransformFeedbackBuffersParams;
200 using BindVertexBuffers2Params = BindVertexBuffersParams;
201
202 struct BlitImageParams
203 {
204 CommandHeader header;
205
206 VkFilter filter;
207 VkImage srcImage;
208 VkImage dstImage;
209 VkImageBlit region;
210 };
211 VERIFY_8_BYTE_ALIGNMENT(BlitImageParams)
212
213 struct BufferBarrierParams
214 {
215 CommandHeader header;
216
217 uint32_t padding;
218 VkBufferMemoryBarrier bufferMemoryBarrier;
219 };
220 VERIFY_8_BYTE_ALIGNMENT(BufferBarrierParams)
221
222 struct ClearAttachmentsParams
223 {
224 CommandHeader header;
225
226 uint32_t attachmentCount;
227 VkClearRect rect;
228 };
229 VERIFY_8_BYTE_ALIGNMENT(ClearAttachmentsParams)
230
231 struct ClearColorImageParams
232 {
233 CommandHeader header;
234
235 VkImageLayout imageLayout;
236 VkImage image;
237 VkClearColorValue color;
238 VkImageSubresourceRange range;
239 uint32_t padding;
240 };
241 VERIFY_8_BYTE_ALIGNMENT(ClearColorImageParams)
242
243 struct ClearDepthStencilImageParams
244 {
245 CommandHeader header;
246
247 VkImageLayout imageLayout;
248 VkImage image;
249 VkClearDepthStencilValue depthStencil;
250 VkImageSubresourceRange range;
251 uint32_t padding;
252 };
253 VERIFY_8_BYTE_ALIGNMENT(ClearDepthStencilImageParams)
254
255 struct CopyBufferParams
256 {
257 CommandHeader header;
258
259 uint32_t regionCount;
260 VkBuffer srcBuffer;
261 VkBuffer destBuffer;
262 };
263 VERIFY_8_BYTE_ALIGNMENT(CopyBufferParams)
264
265 struct CopyBufferToImageParams
266 {
267 CommandHeader header;
268
269 VkImageLayout dstImageLayout;
270 VkBuffer srcBuffer;
271 VkImage dstImage;
272 VkBufferImageCopy region;
273 };
274 VERIFY_8_BYTE_ALIGNMENT(CopyBufferToImageParams)
275
276 struct CopyImageParams
277 {
278 CommandHeader header;
279
280 VkImageCopy region;
281 VkImageLayout srcImageLayout;
282 VkImageLayout dstImageLayout;
283 VkImage srcImage;
284 VkImage dstImage;
285 };
286 VERIFY_8_BYTE_ALIGNMENT(CopyImageParams)
287
288 struct CopyImageToBufferParams
289 {
290 CommandHeader header;
291
292 VkImageLayout srcImageLayout;
293 VkImage srcImage;
294 VkBuffer dstBuffer;
295 VkBufferImageCopy region;
296 };
297 VERIFY_8_BYTE_ALIGNMENT(CopyImageToBufferParams)
298
299 // This is a common struct used by both begin & insert DebugUtilsLabelEXT() functions
300 struct DebugUtilsLabelParams
301 {
302 CommandHeader header;
303
304 uint32_t padding;
305 float color[4];
306 };
307 VERIFY_8_BYTE_ALIGNMENT(DebugUtilsLabelParams)
308
309 struct DispatchParams
310 {
311 CommandHeader header;
312
313 uint32_t groupCountX;
314 uint32_t groupCountY;
315 uint32_t groupCountZ;
316 };
317 VERIFY_8_BYTE_ALIGNMENT(DispatchParams)
318
319 struct DispatchIndirectParams
320 {
321 CommandHeader header;
322
323 uint32_t padding;
324 VkBuffer buffer;
325 VkDeviceSize offset;
326 };
327 VERIFY_8_BYTE_ALIGNMENT(DispatchIndirectParams)
328
329 struct DrawParams
330 {
331 CommandHeader header;
332
333 uint32_t padding;
334 uint32_t vertexCount;
335 uint32_t firstVertex;
336 };
337 VERIFY_8_BYTE_ALIGNMENT(DrawParams)
338
339 struct DrawIndexedParams
340 {
341 CommandHeader header;
342
343 uint32_t indexCount;
344 };
345 VERIFY_8_BYTE_ALIGNMENT(DrawIndexedParams)
346
347 struct DrawIndexedBaseVertexParams
348 {
349 CommandHeader header;
350
351 uint32_t padding;
352 uint32_t indexCount;
353 uint32_t vertexOffset;
354 };
355 VERIFY_8_BYTE_ALIGNMENT(DrawIndexedBaseVertexParams)
356
357 struct DrawIndexedIndirectParams
358 {
359 CommandHeader header;
360
361 uint32_t padding;
362 uint32_t drawCount;
363 uint32_t stride;
364 VkBuffer buffer;
365 VkDeviceSize offset;
366 };
367 VERIFY_8_BYTE_ALIGNMENT(DrawIndexedIndirectParams)
368
369 struct DrawIndexedInstancedParams
370 {
371 CommandHeader header;
372
373 uint32_t padding;
374 uint32_t indexCount;
375 uint32_t instanceCount;
376 };
377 VERIFY_8_BYTE_ALIGNMENT(DrawIndexedInstancedParams)
378
379 struct DrawIndexedInstancedBaseVertexParams
380 {
381 CommandHeader header;
382
383 uint32_t indexCount;
384 uint32_t instanceCount;
385 uint32_t vertexOffset;
386 };
387 VERIFY_8_BYTE_ALIGNMENT(DrawIndexedInstancedBaseVertexParams)
388
389 struct DrawIndexedInstancedBaseVertexBaseInstanceParams
390 {
391 CommandHeader header;
392
393 uint32_t indexCount;
394 uint32_t instanceCount;
395 uint32_t firstIndex;
396 int32_t vertexOffset;
397 uint32_t firstInstance;
398 };
399 VERIFY_8_BYTE_ALIGNMENT(DrawIndexedInstancedBaseVertexBaseInstanceParams)
400
401 struct DrawIndirectParams
402 {
403 CommandHeader header;
404
405 uint32_t padding;
406 uint32_t drawCount;
407 uint32_t stride;
408 VkBuffer buffer;
409 VkDeviceSize offset;
410 };
411 VERIFY_8_BYTE_ALIGNMENT(DrawIndirectParams)
412
413 struct DrawInstancedParams
414 {
415 CommandHeader header;
416
417 uint32_t vertexCount;
418 uint32_t instanceCount;
419 uint32_t firstVertex;
420 };
421 VERIFY_8_BYTE_ALIGNMENT(DrawInstancedParams)
422
423 struct DrawInstancedBaseInstanceParams
424 {
425 CommandHeader header;
426
427 uint32_t padding;
428 uint32_t vertexCount;
429 uint32_t instanceCount;
430 uint32_t firstVertex;
431 uint32_t firstInstance;
432 };
433 VERIFY_8_BYTE_ALIGNMENT(DrawInstancedBaseInstanceParams)
434
435 // A special struct used with commands that don't have params
436 struct EmptyParams
437 {
438 CommandHeader header;
439 uint32_t padding;
440 };
441 VERIFY_8_BYTE_ALIGNMENT(EmptyParams)
442
443 struct EndQueryParams
444 {
445 CommandHeader header;
446
447 uint32_t query;
448 VkQueryPool queryPool;
449 };
450 VERIFY_8_BYTE_ALIGNMENT(EndQueryParams)
451
452 struct EndTransformFeedbackParams
453 {
454 CommandHeader header;
455
456 uint32_t bufferCount;
457 };
458 VERIFY_8_BYTE_ALIGNMENT(EndTransformFeedbackParams)
459
460 struct FillBufferParams
461 {
462 CommandHeader header;
463
464 uint32_t data;
465 VkBuffer dstBuffer;
466 VkDeviceSize dstOffset;
467 VkDeviceSize size;
468 };
469 VERIFY_8_BYTE_ALIGNMENT(FillBufferParams)
470
471 struct ImageBarrierParams
472 {
473 CommandHeader header;
474
475 uint32_t padding;
476 VkPipelineStageFlags srcStageMask;
477 VkPipelineStageFlags dstStageMask;
478 };
479 VERIFY_8_BYTE_ALIGNMENT(ImageBarrierParams)
480
481 struct ImageWaitEventParams
482 {
483 CommandHeader header;
484
485 uint32_t padding;
486 VkEvent event;
487 VkPipelineStageFlags srcStageMask;
488 VkPipelineStageFlags dstStageMask;
489 };
490 VERIFY_8_BYTE_ALIGNMENT(ImageWaitEventParams)
491
492 struct MemoryBarrierParams
493 {
494 CommandHeader header;
495
496 uint32_t padding;
497 VkPipelineStageFlags srcStageMask;
498 VkPipelineStageFlags dstStageMask;
499 };
500 VERIFY_8_BYTE_ALIGNMENT(MemoryBarrierParams)
501
502 struct PipelineBarrierParams
503 {
504 CommandHeader header;
505
506 VkPipelineStageFlags srcStageMask;
507 VkPipelineStageFlags dstStageMask;
508 VkDependencyFlags dependencyFlags;
509 uint32_t memoryBarrierCount;
510 uint32_t imageMemoryBarrierCount;
511 };
512 VERIFY_8_BYTE_ALIGNMENT(PipelineBarrierParams)
513
514 struct PushConstantsParams
515 {
516 CommandHeader header;
517
518 VkShaderStageFlags flag;
519 VkPipelineLayout layout;
520 uint32_t offset;
521 uint32_t size;
522 };
523 VERIFY_8_BYTE_ALIGNMENT(PushConstantsParams)
524
525 struct ResetEventParams
526 {
527 CommandHeader header;
528
529 VkPipelineStageFlags stageMask;
530 VkEvent event;
531 };
532 VERIFY_8_BYTE_ALIGNMENT(ResetEventParams)
533
534 struct ResetQueryPoolParams
535 {
536 CommandHeader header;
537
538 uint32_t firstQuery : 24;
539 uint32_t queryCount : 8;
540 VkQueryPool queryPool;
541 };
542 VERIFY_8_BYTE_ALIGNMENT(ResetQueryPoolParams)
543
544 struct ResolveImageParams
545 {
546 CommandHeader header;
547
548 VkImageResolve region;
549 VkImage srcImage;
550 VkImage dstImage;
551 };
552 VERIFY_8_BYTE_ALIGNMENT(ResolveImageParams)
553
554 struct SetBlendConstantsParams
555 {
556 CommandHeader header;
557
558 uint32_t padding;
559 float blendConstants[4];
560 };
561 VERIFY_8_BYTE_ALIGNMENT(SetBlendConstantsParams)
562
563 struct SetCullModeParams
564 {
565 CommandHeader header;
566
567 VkCullModeFlags cullMode;
568 };
569 VERIFY_8_BYTE_ALIGNMENT(SetCullModeParams)
570
571 struct SetDepthBiasParams
572 {
573 CommandHeader header;
574
575 float depthBiasConstantFactor;
576 float depthBiasClamp;
577 float depthBiasSlopeFactor;
578 };
579 VERIFY_8_BYTE_ALIGNMENT(SetDepthBiasParams)
580
581 struct SetDepthBiasEnableParams
582 {
583 CommandHeader header;
584
585 VkBool32 depthBiasEnable;
586 };
587 VERIFY_8_BYTE_ALIGNMENT(SetDepthBiasEnableParams)
588
589 struct SetDepthCompareOpParams
590 {
591 CommandHeader header;
592
593 VkCompareOp depthCompareOp;
594 };
595 VERIFY_8_BYTE_ALIGNMENT(SetDepthCompareOpParams)
596
597 struct SetDepthTestEnableParams
598 {
599 CommandHeader header;
600
601 VkBool32 depthTestEnable;
602 };
603 VERIFY_8_BYTE_ALIGNMENT(SetDepthTestEnableParams)
604
605 struct SetDepthWriteEnableParams
606 {
607 CommandHeader header;
608
609 VkBool32 depthWriteEnable;
610 };
611 VERIFY_8_BYTE_ALIGNMENT(SetDepthWriteEnableParams)
612
613 struct SetEventParams
614 {
615 CommandHeader header;
616
617 VkPipelineStageFlags stageMask;
618 VkEvent event;
619 };
620 VERIFY_8_BYTE_ALIGNMENT(SetEventParams)
621
622 struct SetFragmentShadingRateParams
623 {
624 CommandHeader header;
625
626 uint32_t fragmentWidth : 8;
627 uint32_t fragmentHeight : 8;
628 uint32_t vkFragmentShadingRateCombinerOp1 : 16;
629 };
630 VERIFY_8_BYTE_ALIGNMENT(SetFragmentShadingRateParams)
631
632 struct SetFrontFaceParams
633 {
634 CommandHeader header;
635
636 VkFrontFace frontFace;
637 };
638 VERIFY_8_BYTE_ALIGNMENT(SetFrontFaceParams)
639
640 struct SetLineWidthParams
641 {
642 CommandHeader header;
643
644 float lineWidth;
645 };
646 VERIFY_8_BYTE_ALIGNMENT(SetLineWidthParams)
647
648 struct SetLogicOpParams
649 {
650 CommandHeader header;
651
652 VkLogicOp logicOp;
653 };
654 VERIFY_8_BYTE_ALIGNMENT(SetLogicOpParams)
655
656 struct SetPrimitiveRestartEnableParams
657 {
658 CommandHeader header;
659
660 VkBool32 primitiveRestartEnable;
661 };
662 VERIFY_8_BYTE_ALIGNMENT(SetPrimitiveRestartEnableParams)
663
664 struct SetRasterizerDiscardEnableParams
665 {
666 CommandHeader header;
667
668 VkBool32 rasterizerDiscardEnable;
669 };
670 VERIFY_8_BYTE_ALIGNMENT(SetRasterizerDiscardEnableParams)
671
672 struct SetScissorParams
673 {
674 CommandHeader header;
675
676 uint32_t padding;
677 VkRect2D scissor;
678 };
679 VERIFY_8_BYTE_ALIGNMENT(SetScissorParams)
680
681 struct SetStencilCompareMaskParams
682 {
683 CommandHeader header;
684
685 uint16_t compareFrontMask;
686 uint16_t compareBackMask;
687 };
688 VERIFY_8_BYTE_ALIGNMENT(SetStencilCompareMaskParams)
689
690 struct SetStencilOpParams
691 {
692 CommandHeader header;
693
694 uint32_t faceMask : 4;
695 uint32_t failOp : 3;
696 uint32_t passOp : 3;
697 uint32_t depthFailOp : 3;
698 uint32_t compareOp : 3;
699 uint32_t padding : 16;
700 };
701 VERIFY_8_BYTE_ALIGNMENT(SetStencilOpParams)
702
703 struct SetStencilReferenceParams
704 {
705 CommandHeader header;
706
707 uint16_t frontReference;
708 uint16_t backReference;
709 };
710 VERIFY_8_BYTE_ALIGNMENT(SetStencilReferenceParams)
711
712 struct SetStencilTestEnableParams
713 {
714 CommandHeader header;
715
716 VkBool32 stencilTestEnable;
717 };
718 VERIFY_8_BYTE_ALIGNMENT(SetStencilTestEnableParams)
719
720 struct SetStencilWriteMaskParams
721 {
722 CommandHeader header;
723
724 uint16_t writeFrontMask;
725 uint16_t writeBackMask;
726 };
727 VERIFY_8_BYTE_ALIGNMENT(SetStencilWriteMaskParams)
728
729 struct SetVertexInputParams
730 {
731 CommandHeader header;
732
733 uint16_t vertexBindingDescriptionCount;
734 uint16_t vertexAttributeDescriptionCount;
735 };
736 VERIFY_8_BYTE_ALIGNMENT(SetVertexInputParams)
737
738 struct SetViewportParams
739 {
740 CommandHeader header;
741
742 uint32_t padding;
743 VkViewport viewport;
744 };
745 VERIFY_8_BYTE_ALIGNMENT(SetViewportParams)
746
747 struct WaitEventsParams
748 {
749 CommandHeader header;
750
751 uint32_t eventCount;
752 VkPipelineStageFlags srcStageMask;
753 VkPipelineStageFlags dstStageMask;
754 uint32_t memoryBarrierCount;
755 uint32_t imageMemoryBarrierCount;
756 };
757 VERIFY_8_BYTE_ALIGNMENT(WaitEventsParams)
758
759 struct WriteTimestampParams
760 {
761 CommandHeader header;
762
763 uint32_t query;
764 VkQueryPool queryPool;
765 };
VERIFY_8_BYTE_ALIGNMENT(WriteTimestampParams)766 VERIFY_8_BYTE_ALIGNMENT(WriteTimestampParams)
767
768 #undef VERIFY_8_BYTE_ALIGNMENT
769
770 ANGLE_DISABLE_STRUCT_PADDING_WARNINGS
771
772 template <typename DestT, typename T>
773 ANGLE_INLINE DestT *Offset(T *ptr, size_t bytes)
774 {
775 return reinterpret_cast<DestT *>((reinterpret_cast<uint8_t *>(ptr) + bytes));
776 }
777
778 template <typename DestT, typename T>
Offset(const T * ptr,size_t bytes)779 ANGLE_INLINE const DestT *Offset(const T *ptr, size_t bytes)
780 {
781 return reinterpret_cast<const DestT *>((reinterpret_cast<const uint8_t *>(ptr) + bytes));
782 }
783
784 class SecondaryCommandBuffer final : angle::NonCopyable
785 {
786 public:
787 SecondaryCommandBuffer();
788 ~SecondaryCommandBuffer();
789
SupportsQueries(const VkPhysicalDeviceFeatures & features)790 static bool SupportsQueries(const VkPhysicalDeviceFeatures &features) { return true; }
791
792 // SecondaryCommandBuffer replays its commands inline when executed on the primary command
793 // buffer.
ExecutesInline()794 static constexpr bool ExecutesInline() { return true; }
795
InitializeCommandPool(Context * context,SecondaryCommandPool * pool,uint32_t queueFamilyIndex,ProtectionType protectionType)796 static angle::Result InitializeCommandPool(Context *context,
797 SecondaryCommandPool *pool,
798 uint32_t queueFamilyIndex,
799 ProtectionType protectionType)
800 {
801 return angle::Result::Continue;
802 }
InitializeRenderPassInheritanceInfo(ContextVk * contextVk,const Framebuffer & framebuffer,const RenderPassDesc & renderPassDesc,VkCommandBufferInheritanceInfo * inheritanceInfoOut)803 static angle::Result InitializeRenderPassInheritanceInfo(
804 ContextVk *contextVk,
805 const Framebuffer &framebuffer,
806 const RenderPassDesc &renderPassDesc,
807 VkCommandBufferInheritanceInfo *inheritanceInfoOut)
808 {
809 return angle::Result::Continue;
810 }
811
812 // Add commands
813 void beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label);
814
815 void beginQuery(const QueryPool &queryPool, uint32_t query, VkQueryControlFlags flags);
816
817 void beginTransformFeedback(uint32_t firstCounterBuffer,
818 uint32_t bufferCount,
819 const VkBuffer *counterBuffers,
820 const VkDeviceSize *counterBufferOffsets);
821
822 void bindComputePipeline(const Pipeline &pipeline);
823
824 void bindDescriptorSets(const PipelineLayout &layout,
825 VkPipelineBindPoint pipelineBindPoint,
826 DescriptorSetIndex firstSet,
827 uint32_t descriptorSetCount,
828 const VkDescriptorSet *descriptorSets,
829 uint32_t dynamicOffsetCount,
830 const uint32_t *dynamicOffsets);
831
832 void bindGraphicsPipeline(const Pipeline &pipeline);
833
834 void bindIndexBuffer(const Buffer &buffer, VkDeviceSize offset, VkIndexType indexType);
835
836 void bindTransformFeedbackBuffers(uint32_t firstBinding,
837 uint32_t bindingCount,
838 const VkBuffer *buffers,
839 const VkDeviceSize *offsets,
840 const VkDeviceSize *sizes);
841
842 void bindVertexBuffers(uint32_t firstBinding,
843 uint32_t bindingCount,
844 const VkBuffer *buffers,
845 const VkDeviceSize *offsets);
846
847 void bindVertexBuffers2(uint32_t firstBinding,
848 uint32_t bindingCount,
849 const VkBuffer *buffers,
850 const VkDeviceSize *offsets,
851 const VkDeviceSize *sizes,
852 const VkDeviceSize *strides);
853
854 void blitImage(const Image &srcImage,
855 VkImageLayout srcImageLayout,
856 const Image &dstImage,
857 VkImageLayout dstImageLayout,
858 uint32_t regionCount,
859 const VkImageBlit *regions,
860 VkFilter filter);
861
862 void bufferBarrier(VkPipelineStageFlags srcStageMask,
863 VkPipelineStageFlags dstStageMask,
864 const VkBufferMemoryBarrier *bufferMemoryBarrier);
865
866 void clearAttachments(uint32_t attachmentCount,
867 const VkClearAttachment *attachments,
868 uint32_t rectCount,
869 const VkClearRect *rects);
870
871 void clearColorImage(const Image &image,
872 VkImageLayout imageLayout,
873 const VkClearColorValue &color,
874 uint32_t rangeCount,
875 const VkImageSubresourceRange *ranges);
876
877 void clearDepthStencilImage(const Image &image,
878 VkImageLayout imageLayout,
879 const VkClearDepthStencilValue &depthStencil,
880 uint32_t rangeCount,
881 const VkImageSubresourceRange *ranges);
882
883 void copyBuffer(const Buffer &srcBuffer,
884 const Buffer &destBuffer,
885 uint32_t regionCount,
886 const VkBufferCopy *regions);
887
888 void copyBufferToImage(VkBuffer srcBuffer,
889 const Image &dstImage,
890 VkImageLayout dstImageLayout,
891 uint32_t regionCount,
892 const VkBufferImageCopy *regions);
893
894 void copyImage(const Image &srcImage,
895 VkImageLayout srcImageLayout,
896 const Image &dstImage,
897 VkImageLayout dstImageLayout,
898 uint32_t regionCount,
899 const VkImageCopy *regions);
900
901 void copyImageToBuffer(const Image &srcImage,
902 VkImageLayout srcImageLayout,
903 VkBuffer dstBuffer,
904 uint32_t regionCount,
905 const VkBufferImageCopy *regions);
906
907 void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
908
909 void dispatchIndirect(const Buffer &buffer, VkDeviceSize offset);
910
911 void draw(uint32_t vertexCount, uint32_t firstVertex);
912
913 void drawIndexed(uint32_t indexCount);
914 void drawIndexedBaseVertex(uint32_t indexCount, uint32_t vertexOffset);
915 void drawIndexedIndirect(const Buffer &buffer,
916 VkDeviceSize offset,
917 uint32_t drawCount,
918 uint32_t stride);
919 void drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount);
920 void drawIndexedInstancedBaseVertex(uint32_t indexCount,
921 uint32_t instanceCount,
922 uint32_t vertexOffset);
923 void drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,
924 uint32_t instanceCount,
925 uint32_t firstIndex,
926 int32_t vertexOffset,
927 uint32_t firstInstance);
928
929 void drawIndirect(const Buffer &buffer,
930 VkDeviceSize offset,
931 uint32_t drawCount,
932 uint32_t stride);
933
934 void drawInstanced(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex);
935 void drawInstancedBaseInstance(uint32_t vertexCount,
936 uint32_t instanceCount,
937 uint32_t firstVertex,
938 uint32_t firstInstance);
939
940 void endDebugUtilsLabelEXT();
941
942 void endQuery(const QueryPool &queryPool, uint32_t query);
943
944 void endTransformFeedback(uint32_t firstCounterBuffer,
945 uint32_t counterBufferCount,
946 const VkBuffer *counterBuffers,
947 const VkDeviceSize *counterBufferOffsets);
948
949 void fillBuffer(const Buffer &dstBuffer,
950 VkDeviceSize dstOffset,
951 VkDeviceSize size,
952 uint32_t data);
953
954 void imageBarrier(VkPipelineStageFlags srcStageMask,
955 VkPipelineStageFlags dstStageMask,
956 const VkImageMemoryBarrier &imageMemoryBarrier);
957
958 void imageWaitEvent(const VkEvent &event,
959 VkPipelineStageFlags srcStageMask,
960 VkPipelineStageFlags dstStageMask,
961 const VkImageMemoryBarrier &imageMemoryBarrier);
962
963 void insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label);
964
965 void memoryBarrier(VkPipelineStageFlags srcStageMask,
966 VkPipelineStageFlags dstStageMask,
967 const VkMemoryBarrier &memoryBarrier);
968
969 void nextSubpass(VkSubpassContents subpassContents);
970
971 void pipelineBarrier(VkPipelineStageFlags srcStageMask,
972 VkPipelineStageFlags dstStageMask,
973 VkDependencyFlags dependencyFlags,
974 uint32_t memoryBarrierCount,
975 const VkMemoryBarrier *memoryBarriers,
976 uint32_t bufferMemoryBarrierCount,
977 const VkBufferMemoryBarrier *bufferMemoryBarriers,
978 uint32_t imageMemoryBarrierCount,
979 const VkImageMemoryBarrier *imageMemoryBarriers);
980
981 void pushConstants(const PipelineLayout &layout,
982 VkShaderStageFlags flag,
983 uint32_t offset,
984 uint32_t size,
985 const void *data);
986
987 void resetEvent(VkEvent event, VkPipelineStageFlags stageMask);
988
989 void resetQueryPool(const QueryPool &queryPool, uint32_t firstQuery, uint32_t queryCount);
990
991 void resolveImage(const Image &srcImage,
992 VkImageLayout srcImageLayout,
993 const Image &dstImage,
994 VkImageLayout dstImageLayout,
995 uint32_t regionCount,
996 const VkImageResolve *regions);
997
998 void setBlendConstants(const float blendConstants[4]);
999 void setCullMode(VkCullModeFlags cullMode);
1000 void setDepthBias(float depthBiasConstantFactor,
1001 float depthBiasClamp,
1002 float depthBiasSlopeFactor);
1003 void setDepthBiasEnable(VkBool32 depthBiasEnable);
1004 void setDepthCompareOp(VkCompareOp depthCompareOp);
1005 void setDepthTestEnable(VkBool32 depthTestEnable);
1006 void setDepthWriteEnable(VkBool32 depthWriteEnable);
1007 void setEvent(VkEvent event, VkPipelineStageFlags stageMask);
1008 void setFragmentShadingRate(const VkExtent2D *fragmentSize,
1009 VkFragmentShadingRateCombinerOpKHR ops[2]);
1010 void setFrontFace(VkFrontFace frontFace);
1011 void setLineWidth(float lineWidth);
1012 void setLogicOp(VkLogicOp logicOp);
1013 void setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable);
1014 void setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable);
1015 void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *scissors);
1016 void setStencilCompareMask(uint32_t compareFrontMask, uint32_t compareBackMask);
1017 void setStencilOp(VkStencilFaceFlags faceMask,
1018 VkStencilOp failOp,
1019 VkStencilOp passOp,
1020 VkStencilOp depthFailOp,
1021 VkCompareOp compareOp);
1022 void setStencilReference(uint32_t frontReference, uint32_t backReference);
1023 void setStencilTestEnable(VkBool32 stencilTestEnable);
1024 void setStencilWriteMask(uint32_t writeFrontMask, uint32_t writeBackMask);
1025 void setVertexInput(uint32_t vertexBindingDescriptionCount,
1026 const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions,
1027 uint32_t vertexAttributeDescriptionCount,
1028 const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions);
1029 void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *viewports);
1030
1031 void waitEvents(uint32_t eventCount,
1032 const VkEvent *events,
1033 VkPipelineStageFlags srcStageMask,
1034 VkPipelineStageFlags dstStageMask,
1035 uint32_t memoryBarrierCount,
1036 const VkMemoryBarrier *memoryBarriers,
1037 uint32_t bufferMemoryBarrierCount,
1038 const VkBufferMemoryBarrier *bufferMemoryBarriers,
1039 uint32_t imageMemoryBarrierCount,
1040 const VkImageMemoryBarrier *imageMemoryBarriers);
1041
1042 void writeTimestamp(VkPipelineStageFlagBits pipelineStage,
1043 const QueryPool &queryPool,
1044 uint32_t query);
1045
1046 // No-op for compatibility
end()1047 VkResult end() { return VK_SUCCESS; }
1048
1049 // Parse the cmds in this cmd buffer into given primary cmd buffer for execution
1050 void executeCommands(PrimaryCommandBuffer *primary);
1051
1052 // Calculate memory usage of this command buffer for diagnostics.
1053 void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const;
1054 void getMemoryUsageStatsForPoolAlloc(size_t blockSize,
1055 size_t *usedMemoryOut,
1056 size_t *allocatedMemoryOut) const;
1057
1058 // Traverse the list of commands and build a summary for diagnostics.
1059 std::string dumpCommands(const char *separator) const;
1060
1061 // Initialize the SecondaryCommandBuffer by setting the allocator it will use
initialize(vk::Context * context,vk::SecondaryCommandPool * pool,bool isRenderPassCommandBuffer,SecondaryCommandMemoryAllocator * allocator)1062 angle::Result initialize(vk::Context *context,
1063 vk::SecondaryCommandPool *pool,
1064 bool isRenderPassCommandBuffer,
1065 SecondaryCommandMemoryAllocator *allocator)
1066 {
1067 return mCommandAllocator.initialize(allocator);
1068 }
1069
attachAllocator(vk::SecondaryCommandMemoryAllocator * source)1070 void attachAllocator(vk::SecondaryCommandMemoryAllocator *source)
1071 {
1072 mCommandAllocator.attachAllocator(source);
1073 }
1074
detachAllocator(vk::SecondaryCommandMemoryAllocator * destination)1075 void detachAllocator(vk::SecondaryCommandMemoryAllocator *destination)
1076 {
1077 mCommandAllocator.detachAllocator(destination);
1078 }
1079
begin(Context * context,const VkCommandBufferInheritanceInfo & inheritanceInfo)1080 angle::Result begin(Context *context, const VkCommandBufferInheritanceInfo &inheritanceInfo)
1081 {
1082 return angle::Result::Continue;
1083 }
end(Context * context)1084 angle::Result end(Context *context) { return angle::Result::Continue; }
1085
open()1086 void open() { mIsOpen = true; }
close()1087 void close() { mIsOpen = false; }
1088
reset()1089 void reset()
1090 {
1091 mCommands.clear();
1092 mCommandAllocator.reset(&mCommandTracker);
1093 }
1094
1095 // The SecondaryCommandBuffer is valid if it's been initialized
valid()1096 bool valid() const { return mCommandAllocator.valid(); }
1097
empty()1098 bool empty() const { return mCommandAllocator.empty(); }
checkEmptyForPoolAlloc()1099 bool checkEmptyForPoolAlloc() const
1100 {
1101 return mCommands.size() == 0 || mCommands[0]->id == CommandID::Invalid;
1102 }
1103
getRenderPassWriteCommandCount()1104 uint32_t getRenderPassWriteCommandCount() const
1105 {
1106 return mCommandTracker.getRenderPassWriteCommandCount();
1107 }
1108
clearCommands()1109 void clearCommands() { mCommands.clear(); }
hasEmptyCommands()1110 bool hasEmptyCommands() { return mCommands.empty(); }
pushToCommands(uint8_t * command)1111 void pushToCommands(uint8_t *command)
1112 {
1113 mCommands.push_back(reinterpret_cast<priv::CommandHeader *>(command));
1114 }
1115
1116 private:
1117 void commonDebugUtilsLabel(CommandID cmd, const VkDebugUtilsLabelEXT &label);
1118 template <class StructType>
commonInit(CommandID cmdID,size_t allocationSize,uint8_t * commandMemory)1119 ANGLE_INLINE StructType *commonInit(CommandID cmdID,
1120 size_t allocationSize,
1121 uint8_t *commandMemory)
1122 {
1123 ASSERT(mIsOpen);
1124 ASSERT(allocationSize <= std::numeric_limits<uint16_t>::max());
1125
1126 StructType *command = reinterpret_cast<StructType *>(commandMemory);
1127 command->header.id = cmdID;
1128 command->header.size = static_cast<uint16_t>(allocationSize);
1129
1130 return command;
1131 }
1132
1133 // Allocate and initialize memory for given commandID & variable param size, setting
1134 // variableDataOut to the byte following fixed cmd data where variable-sized ptr data will
1135 // be written and returning a pointer to the start of the command's parameter data
1136 template <class StructType>
initCommand(CommandID cmdID,size_t variableSize,uint8_t ** variableDataOut)1137 ANGLE_INLINE StructType *initCommand(CommandID cmdID,
1138 size_t variableSize,
1139 uint8_t **variableDataOut)
1140 {
1141 constexpr size_t fixedAllocationSize = sizeof(StructType);
1142 const size_t allocationSize = fixedAllocationSize + variableSize;
1143
1144 // Make sure we have enough room to mark follow-on header "Invalid"
1145 const size_t requiredSize = allocationSize + sizeof(CommandHeader);
1146 uint8_t *commandMemory = nullptr;
1147
1148 mCommandAllocator.onNewVariableSizedCommand(requiredSize, allocationSize, &commandMemory);
1149 StructType *command = commonInit<StructType>(cmdID, allocationSize, commandMemory);
1150 *variableDataOut = Offset<uint8_t>(commandMemory, fixedAllocationSize);
1151 return command;
1152 }
1153
1154 // Initialize a command that doesn't have variable-sized ptr data
1155 template <class StructType>
initCommand(CommandID cmdID)1156 ANGLE_INLINE StructType *initCommand(CommandID cmdID)
1157 {
1158 constexpr size_t allocationSize = sizeof(StructType);
1159
1160 // Make sure we have enough room to mark follow-on header "Invalid"
1161 const size_t requiredSize = allocationSize + sizeof(CommandHeader);
1162 uint8_t *commandMemory = nullptr;
1163 mCommandAllocator.onNewCommand(requiredSize, allocationSize, &commandMemory);
1164
1165 return commonInit<StructType>(cmdID, allocationSize, commandMemory);
1166 }
1167
1168 // Return a pointer to the parameter type. Note that every param struct has the header as its
1169 // first member, so in fact the parameter type pointer is identical to the header pointer.
1170 template <class StructType>
getParamPtr(const CommandHeader * header)1171 const StructType *getParamPtr(const CommandHeader *header) const
1172 {
1173 return reinterpret_cast<const StructType *>(header);
1174 }
1175 struct ArrayParamSize
1176 {
1177 // Given an array of N elements of type T, N*sizeof(T) bytes need to be copied, but due to
1178 // alignment requirements, roundUp(size, 8) bytes need to be allocated for the array.
1179 size_t copyBytes;
1180 size_t allocateBytes;
1181 };
1182 template <class T>
calculateArrayParameterSize(size_t count)1183 ANGLE_INLINE ArrayParamSize calculateArrayParameterSize(size_t count)
1184 {
1185 ArrayParamSize size;
1186 size.copyBytes = sizeof(T) * count;
1187 size.allocateBytes = roundUpPow2<size_t>(size.copyBytes, 8u);
1188 return size;
1189 }
1190 // Copy size.copyBytes data from paramData to writePointer and return writePointer plus
1191 // size.allocateBytes.
1192 template <class T>
storeArrayParameter(uint8_t * writePointer,const T * data,const ArrayParamSize & size)1193 ANGLE_INLINE uint8_t *storeArrayParameter(uint8_t *writePointer,
1194 const T *data,
1195 const ArrayParamSize &size)
1196 {
1197 // See |PointerParamSize|. The size should always be calculated with
1198 // |calculatePointerParameterSize|, and that satisfies this condition.
1199 ASSERT(size.allocateBytes == roundUpPow2<size_t>(size.copyBytes, 8u));
1200
1201 memcpy(writePointer, data, size.copyBytes);
1202 return writePointer + size.allocateBytes;
1203 }
1204
1205 // Flag to indicate that commandBuffer is open for new commands. Initially open.
1206 bool mIsOpen;
1207
1208 std::vector<CommandHeader *> mCommands;
1209
1210 // Allocator used by this class. If non-null then the class is valid.
1211 SecondaryCommandBlockPool mCommandAllocator;
1212
1213 CommandBufferCommandTracker mCommandTracker;
1214 };
1215
SecondaryCommandBuffer()1216 ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer() : mIsOpen(true)
1217 {
1218 mCommandAllocator.setCommandBuffer(this);
1219 }
1220
~SecondaryCommandBuffer()1221 ANGLE_INLINE SecondaryCommandBuffer::~SecondaryCommandBuffer()
1222 {
1223 mCommandAllocator.resetCommandBuffer();
1224 }
1225
1226 // begin and insert DebugUtilsLabelEXT funcs share this same function body
commonDebugUtilsLabel(CommandID cmd,const VkDebugUtilsLabelEXT & label)1227 ANGLE_INLINE void SecondaryCommandBuffer::commonDebugUtilsLabel(CommandID cmd,
1228 const VkDebugUtilsLabelEXT &label)
1229 {
1230 uint8_t *writePtr;
1231 const ArrayParamSize stringSize =
1232 calculateArrayParameterSize<char>(strlen(label.pLabelName) + 1);
1233 DebugUtilsLabelParams *paramStruct =
1234 initCommand<DebugUtilsLabelParams>(cmd, stringSize.allocateBytes, &writePtr);
1235 paramStruct->color[0] = label.color[0];
1236 paramStruct->color[1] = label.color[1];
1237 paramStruct->color[2] = label.color[2];
1238 paramStruct->color[3] = label.color[3];
1239 storeArrayParameter(writePtr, label.pLabelName, stringSize);
1240 }
1241
beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT & label)1242 ANGLE_INLINE void SecondaryCommandBuffer::beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label)
1243 {
1244 commonDebugUtilsLabel(CommandID::BeginDebugUtilsLabel, label);
1245 }
1246
beginQuery(const QueryPool & queryPool,uint32_t query,VkQueryControlFlags flags)1247 ANGLE_INLINE void SecondaryCommandBuffer::beginQuery(const QueryPool &queryPool,
1248 uint32_t query,
1249 VkQueryControlFlags flags)
1250 {
1251 ASSERT(flags == 0);
1252 BeginQueryParams *paramStruct = initCommand<BeginQueryParams>(CommandID::BeginQuery);
1253 paramStruct->queryPool = queryPool.getHandle();
1254 paramStruct->query = query;
1255 }
1256
beginTransformFeedback(uint32_t firstCounterBuffer,uint32_t bufferCount,const VkBuffer * counterBuffers,const VkDeviceSize * counterBufferOffsets)1257 ANGLE_INLINE void SecondaryCommandBuffer::beginTransformFeedback(
1258 uint32_t firstCounterBuffer,
1259 uint32_t bufferCount,
1260 const VkBuffer *counterBuffers,
1261 const VkDeviceSize *counterBufferOffsets)
1262 {
1263 ASSERT(firstCounterBuffer == 0);
1264 uint8_t *writePtr;
1265 const ArrayParamSize bufferSize = calculateArrayParameterSize<VkBuffer>(bufferCount);
1266 const ArrayParamSize offsetSize = calculateArrayParameterSize<VkDeviceSize>(bufferCount);
1267 BeginTransformFeedbackParams *paramStruct = initCommand<BeginTransformFeedbackParams>(
1268 CommandID::BeginTransformFeedback, bufferSize.allocateBytes + offsetSize.allocateBytes,
1269 &writePtr);
1270 paramStruct->bufferCount = bufferCount;
1271 writePtr = storeArrayParameter(writePtr, counterBuffers, bufferSize);
1272 storeArrayParameter(writePtr, counterBufferOffsets, offsetSize);
1273 }
1274
bindComputePipeline(const Pipeline & pipeline)1275 ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pipeline)
1276 {
1277 BindPipelineParams *paramStruct =
1278 initCommand<BindPipelineParams>(CommandID::BindComputePipeline);
1279 paramStruct->pipeline = pipeline.getHandle();
1280 }
1281
bindDescriptorSets(const PipelineLayout & layout,VkPipelineBindPoint pipelineBindPoint,DescriptorSetIndex firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * descriptorSets,uint32_t dynamicOffsetCount,const uint32_t * dynamicOffsets)1282 ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
1283 VkPipelineBindPoint pipelineBindPoint,
1284 DescriptorSetIndex firstSet,
1285 uint32_t descriptorSetCount,
1286 const VkDescriptorSet *descriptorSets,
1287 uint32_t dynamicOffsetCount,
1288 const uint32_t *dynamicOffsets)
1289 {
1290 const ArrayParamSize descSize =
1291 calculateArrayParameterSize<VkDescriptorSet>(descriptorSetCount);
1292 const ArrayParamSize offsetSize = calculateArrayParameterSize<uint32_t>(dynamicOffsetCount);
1293 uint8_t *writePtr;
1294 BindDescriptorSetParams *paramStruct = initCommand<BindDescriptorSetParams>(
1295 CommandID::BindDescriptorSets, descSize.allocateBytes + offsetSize.allocateBytes,
1296 &writePtr);
1297 // Copy params into memory
1298 paramStruct->layout = layout.getHandle();
1299 SetBitField(paramStruct->pipelineBindPoint, pipelineBindPoint);
1300 SetBitField(paramStruct->firstSet, ToUnderlying(firstSet));
1301 SetBitField(paramStruct->descriptorSetCount, descriptorSetCount);
1302 SetBitField(paramStruct->dynamicOffsetCount, dynamicOffsetCount);
1303 // Copy variable sized data
1304 writePtr = storeArrayParameter(writePtr, descriptorSets, descSize);
1305 if (dynamicOffsetCount > 0)
1306 {
1307 storeArrayParameter(writePtr, dynamicOffsets, offsetSize);
1308 }
1309 }
1310
bindGraphicsPipeline(const Pipeline & pipeline)1311 ANGLE_INLINE void SecondaryCommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
1312 {
1313 BindPipelineParams *paramStruct =
1314 initCommand<BindPipelineParams>(CommandID::BindGraphicsPipeline);
1315 paramStruct->pipeline = pipeline.getHandle();
1316 }
1317
bindIndexBuffer(const Buffer & buffer,VkDeviceSize offset,VkIndexType indexType)1318 ANGLE_INLINE void SecondaryCommandBuffer::bindIndexBuffer(const Buffer &buffer,
1319 VkDeviceSize offset,
1320 VkIndexType indexType)
1321 {
1322 BindIndexBufferParams *paramStruct =
1323 initCommand<BindIndexBufferParams>(CommandID::BindIndexBuffer);
1324 paramStruct->buffer = buffer.getHandle();
1325 paramStruct->offset = offset;
1326 paramStruct->indexType = indexType;
1327 }
1328
bindTransformFeedbackBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets,const VkDeviceSize * sizes)1329 ANGLE_INLINE void SecondaryCommandBuffer::bindTransformFeedbackBuffers(uint32_t firstBinding,
1330 uint32_t bindingCount,
1331 const VkBuffer *buffers,
1332 const VkDeviceSize *offsets,
1333 const VkDeviceSize *sizes)
1334 {
1335 ASSERT(firstBinding == 0);
1336 uint8_t *writePtr;
1337 const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(bindingCount);
1338 const ArrayParamSize offsetsSize = calculateArrayParameterSize<VkDeviceSize>(bindingCount);
1339 const ArrayParamSize sizesSize = offsetsSize;
1340 BindTransformFeedbackBuffersParams *paramStruct =
1341 initCommand<BindTransformFeedbackBuffersParams>(
1342 CommandID::BindTransformFeedbackBuffers,
1343 buffersSize.allocateBytes + offsetsSize.allocateBytes + sizesSize.allocateBytes,
1344 &writePtr);
1345 // Copy params
1346 paramStruct->bindingCount = bindingCount;
1347 writePtr = storeArrayParameter(writePtr, buffers, buffersSize);
1348 writePtr = storeArrayParameter(writePtr, offsets, offsetsSize);
1349 storeArrayParameter(writePtr, sizes, sizesSize);
1350 }
1351
bindVertexBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets)1352 ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers(uint32_t firstBinding,
1353 uint32_t bindingCount,
1354 const VkBuffer *buffers,
1355 const VkDeviceSize *offsets)
1356 {
1357 ASSERT(firstBinding == 0);
1358 uint8_t *writePtr;
1359 const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(bindingCount);
1360 const ArrayParamSize offsetsSize = calculateArrayParameterSize<VkDeviceSize>(bindingCount);
1361 BindVertexBuffersParams *paramStruct = initCommand<BindVertexBuffersParams>(
1362 CommandID::BindVertexBuffers, buffersSize.allocateBytes + offsetsSize.allocateBytes,
1363 &writePtr);
1364 // Copy params
1365 paramStruct->bindingCount = bindingCount;
1366 writePtr = storeArrayParameter(writePtr, buffers, buffersSize);
1367 storeArrayParameter(writePtr, offsets, offsetsSize);
1368 }
1369
bindVertexBuffers2(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets,const VkDeviceSize * sizes,const VkDeviceSize * strides)1370 ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers2(uint32_t firstBinding,
1371 uint32_t bindingCount,
1372 const VkBuffer *buffers,
1373 const VkDeviceSize *offsets,
1374 const VkDeviceSize *sizes,
1375 const VkDeviceSize *strides)
1376 {
1377 ASSERT(firstBinding == 0);
1378 ASSERT(sizes == nullptr);
1379 uint8_t *writePtr;
1380 const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(bindingCount);
1381 const ArrayParamSize offsetsSize = calculateArrayParameterSize<VkDeviceSize>(bindingCount);
1382 const ArrayParamSize stridesSize = offsetsSize;
1383 BindVertexBuffers2Params *paramStruct = initCommand<BindVertexBuffers2Params>(
1384 CommandID::BindVertexBuffers2,
1385 buffersSize.allocateBytes + offsetsSize.allocateBytes + stridesSize.allocateBytes,
1386 &writePtr);
1387 // Copy params
1388 paramStruct->bindingCount = bindingCount;
1389 writePtr = storeArrayParameter(writePtr, buffers, buffersSize);
1390 writePtr = storeArrayParameter(writePtr, offsets, offsetsSize);
1391 storeArrayParameter(writePtr, strides, stridesSize);
1392 }
1393
blitImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * regions,VkFilter filter)1394 ANGLE_INLINE void SecondaryCommandBuffer::blitImage(const Image &srcImage,
1395 VkImageLayout srcImageLayout,
1396 const Image &dstImage,
1397 VkImageLayout dstImageLayout,
1398 uint32_t regionCount,
1399 const VkImageBlit *regions,
1400 VkFilter filter)
1401 {
1402 // Currently ANGLE uses limited params so verify those assumptions and update if they change
1403 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1404 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1405 ASSERT(regionCount == 1);
1406 BlitImageParams *paramStruct = initCommand<BlitImageParams>(CommandID::BlitImage);
1407 paramStruct->srcImage = srcImage.getHandle();
1408 paramStruct->dstImage = dstImage.getHandle();
1409 paramStruct->filter = filter;
1410 paramStruct->region = regions[0];
1411 }
1412
bufferBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkBufferMemoryBarrier * bufferMemoryBarrier)1413 ANGLE_INLINE void SecondaryCommandBuffer::bufferBarrier(
1414 VkPipelineStageFlags srcStageMask,
1415 VkPipelineStageFlags dstStageMask,
1416 const VkBufferMemoryBarrier *bufferMemoryBarrier)
1417 {
1418 // Used only during queue family ownership transfers
1419 ASSERT(srcStageMask == VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1420 ASSERT(dstStageMask == VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1421
1422 BufferBarrierParams *paramStruct = initCommand<BufferBarrierParams>(CommandID::BufferBarrier);
1423 paramStruct->bufferMemoryBarrier = *bufferMemoryBarrier;
1424 }
1425
clearAttachments(uint32_t attachmentCount,const VkClearAttachment * attachments,uint32_t rectCount,const VkClearRect * rects)1426 ANGLE_INLINE void SecondaryCommandBuffer::clearAttachments(uint32_t attachmentCount,
1427 const VkClearAttachment *attachments,
1428 uint32_t rectCount,
1429 const VkClearRect *rects)
1430 {
1431 ASSERT(rectCount == 1);
1432 uint8_t *writePtr;
1433 const ArrayParamSize attachmentSize =
1434 calculateArrayParameterSize<VkClearAttachment>(attachmentCount);
1435 ClearAttachmentsParams *paramStruct = initCommand<ClearAttachmentsParams>(
1436 CommandID::ClearAttachments, attachmentSize.allocateBytes, &writePtr);
1437 paramStruct->attachmentCount = attachmentCount;
1438 paramStruct->rect = rects[0];
1439 // Copy variable sized data
1440 storeArrayParameter(writePtr, attachments, attachmentSize);
1441
1442 mCommandTracker.onClearAttachments();
1443 }
1444
clearColorImage(const Image & image,VkImageLayout imageLayout,const VkClearColorValue & color,uint32_t rangeCount,const VkImageSubresourceRange * ranges)1445 ANGLE_INLINE void SecondaryCommandBuffer::clearColorImage(const Image &image,
1446 VkImageLayout imageLayout,
1447 const VkClearColorValue &color,
1448 uint32_t rangeCount,
1449 const VkImageSubresourceRange *ranges)
1450 {
1451 ASSERT(rangeCount == 1);
1452 ClearColorImageParams *paramStruct =
1453 initCommand<ClearColorImageParams>(CommandID::ClearColorImage);
1454 paramStruct->image = image.getHandle();
1455 paramStruct->imageLayout = imageLayout;
1456 paramStruct->color = color;
1457 paramStruct->range = ranges[0];
1458 }
1459
clearDepthStencilImage(const Image & image,VkImageLayout imageLayout,const VkClearDepthStencilValue & depthStencil,uint32_t rangeCount,const VkImageSubresourceRange * ranges)1460 ANGLE_INLINE void SecondaryCommandBuffer::clearDepthStencilImage(
1461 const Image &image,
1462 VkImageLayout imageLayout,
1463 const VkClearDepthStencilValue &depthStencil,
1464 uint32_t rangeCount,
1465 const VkImageSubresourceRange *ranges)
1466 {
1467 ASSERT(rangeCount == 1);
1468 ClearDepthStencilImageParams *paramStruct =
1469 initCommand<ClearDepthStencilImageParams>(CommandID::ClearDepthStencilImage);
1470 paramStruct->image = image.getHandle();
1471 paramStruct->imageLayout = imageLayout;
1472 paramStruct->depthStencil = depthStencil;
1473 paramStruct->range = ranges[0];
1474 }
1475
copyBuffer(const Buffer & srcBuffer,const Buffer & destBuffer,uint32_t regionCount,const VkBufferCopy * regions)1476 ANGLE_INLINE void SecondaryCommandBuffer::copyBuffer(const Buffer &srcBuffer,
1477 const Buffer &destBuffer,
1478 uint32_t regionCount,
1479 const VkBufferCopy *regions)
1480 {
1481 uint8_t *writePtr;
1482 const ArrayParamSize regionSize = calculateArrayParameterSize<VkBufferCopy>(regionCount);
1483 CopyBufferParams *paramStruct =
1484 initCommand<CopyBufferParams>(CommandID::CopyBuffer, regionSize.allocateBytes, &writePtr);
1485 paramStruct->srcBuffer = srcBuffer.getHandle();
1486 paramStruct->destBuffer = destBuffer.getHandle();
1487 paramStruct->regionCount = regionCount;
1488 // Copy variable sized data
1489 storeArrayParameter(writePtr, regions, regionSize);
1490 }
1491
copyBufferToImage(VkBuffer srcBuffer,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * regions)1492 ANGLE_INLINE void SecondaryCommandBuffer::copyBufferToImage(VkBuffer srcBuffer,
1493 const Image &dstImage,
1494 VkImageLayout dstImageLayout,
1495 uint32_t regionCount,
1496 const VkBufferImageCopy *regions)
1497 {
1498 ASSERT(regionCount == 1);
1499 CopyBufferToImageParams *paramStruct =
1500 initCommand<CopyBufferToImageParams>(CommandID::CopyBufferToImage);
1501 paramStruct->srcBuffer = srcBuffer;
1502 paramStruct->dstImage = dstImage.getHandle();
1503 paramStruct->dstImageLayout = dstImageLayout;
1504 paramStruct->region = regions[0];
1505 }
1506
copyImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * regions)1507 ANGLE_INLINE void SecondaryCommandBuffer::copyImage(const Image &srcImage,
1508 VkImageLayout srcImageLayout,
1509 const Image &dstImage,
1510 VkImageLayout dstImageLayout,
1511 uint32_t regionCount,
1512 const VkImageCopy *regions)
1513 {
1514 ASSERT(regionCount == 1);
1515 CopyImageParams *paramStruct = initCommand<CopyImageParams>(CommandID::CopyImage);
1516 paramStruct->srcImage = srcImage.getHandle();
1517 paramStruct->srcImageLayout = srcImageLayout;
1518 paramStruct->dstImage = dstImage.getHandle();
1519 paramStruct->dstImageLayout = dstImageLayout;
1520 paramStruct->region = regions[0];
1521 }
1522
copyImageToBuffer(const Image & srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * regions)1523 ANGLE_INLINE void SecondaryCommandBuffer::copyImageToBuffer(const Image &srcImage,
1524 VkImageLayout srcImageLayout,
1525 VkBuffer dstBuffer,
1526 uint32_t regionCount,
1527 const VkBufferImageCopy *regions)
1528 {
1529 ASSERT(regionCount == 1);
1530 CopyImageToBufferParams *paramStruct =
1531 initCommand<CopyImageToBufferParams>(CommandID::CopyImageToBuffer);
1532 paramStruct->srcImage = srcImage.getHandle();
1533 paramStruct->srcImageLayout = srcImageLayout;
1534 paramStruct->dstBuffer = dstBuffer;
1535 paramStruct->region = regions[0];
1536 }
1537
dispatch(uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)1538 ANGLE_INLINE void SecondaryCommandBuffer::dispatch(uint32_t groupCountX,
1539 uint32_t groupCountY,
1540 uint32_t groupCountZ)
1541 {
1542 DispatchParams *paramStruct = initCommand<DispatchParams>(CommandID::Dispatch);
1543 paramStruct->groupCountX = groupCountX;
1544 paramStruct->groupCountY = groupCountY;
1545 paramStruct->groupCountZ = groupCountZ;
1546 }
1547
dispatchIndirect(const Buffer & buffer,VkDeviceSize offset)1548 ANGLE_INLINE void SecondaryCommandBuffer::dispatchIndirect(const Buffer &buffer,
1549 VkDeviceSize offset)
1550 {
1551 DispatchIndirectParams *paramStruct =
1552 initCommand<DispatchIndirectParams>(CommandID::DispatchIndirect);
1553 paramStruct->buffer = buffer.getHandle();
1554 paramStruct->offset = offset;
1555 }
1556
draw(uint32_t vertexCount,uint32_t firstVertex)1557 ANGLE_INLINE void SecondaryCommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
1558 {
1559 DrawParams *paramStruct = initCommand<DrawParams>(CommandID::Draw);
1560 paramStruct->vertexCount = vertexCount;
1561 paramStruct->firstVertex = firstVertex;
1562
1563 mCommandTracker.onDraw();
1564 }
1565
drawIndexed(uint32_t indexCount)1566 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount)
1567 {
1568 DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed);
1569 paramStruct->indexCount = indexCount;
1570
1571 mCommandTracker.onDraw();
1572 }
1573
drawIndexedBaseVertex(uint32_t indexCount,uint32_t vertexOffset)1574 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedBaseVertex(uint32_t indexCount,
1575 uint32_t vertexOffset)
1576 {
1577 DrawIndexedBaseVertexParams *paramStruct =
1578 initCommand<DrawIndexedBaseVertexParams>(CommandID::DrawIndexedBaseVertex);
1579 paramStruct->indexCount = indexCount;
1580 paramStruct->vertexOffset = vertexOffset;
1581
1582 mCommandTracker.onDraw();
1583 }
1584
drawIndexedIndirect(const Buffer & buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1585 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedIndirect(const Buffer &buffer,
1586 VkDeviceSize offset,
1587 uint32_t drawCount,
1588 uint32_t stride)
1589 {
1590 DrawIndexedIndirectParams *paramStruct =
1591 initCommand<DrawIndexedIndirectParams>(CommandID::DrawIndexedIndirect);
1592 paramStruct->buffer = buffer.getHandle();
1593 paramStruct->offset = offset;
1594 paramStruct->drawCount = drawCount;
1595 paramStruct->stride = stride;
1596
1597 mCommandTracker.onDraw();
1598 }
1599
drawIndexedInstanced(uint32_t indexCount,uint32_t instanceCount)1600 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstanced(uint32_t indexCount,
1601 uint32_t instanceCount)
1602 {
1603 DrawIndexedInstancedParams *paramStruct =
1604 initCommand<DrawIndexedInstancedParams>(CommandID::DrawIndexedInstanced);
1605 paramStruct->indexCount = indexCount;
1606 paramStruct->instanceCount = instanceCount;
1607
1608 mCommandTracker.onDraw();
1609 }
1610
drawIndexedInstancedBaseVertex(uint32_t indexCount,uint32_t instanceCount,uint32_t vertexOffset)1611 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertex(uint32_t indexCount,
1612 uint32_t instanceCount,
1613 uint32_t vertexOffset)
1614 {
1615 DrawIndexedInstancedBaseVertexParams *paramStruct =
1616 initCommand<DrawIndexedInstancedBaseVertexParams>(
1617 CommandID::DrawIndexedInstancedBaseVertex);
1618 paramStruct->indexCount = indexCount;
1619 paramStruct->instanceCount = instanceCount;
1620 paramStruct->vertexOffset = vertexOffset;
1621
1622 mCommandTracker.onDraw();
1623 }
1624
drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,uint32_t instanceCount,uint32_t firstIndex,int32_t vertexOffset,uint32_t firstInstance)1625 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertexBaseInstance(
1626 uint32_t indexCount,
1627 uint32_t instanceCount,
1628 uint32_t firstIndex,
1629 int32_t vertexOffset,
1630 uint32_t firstInstance)
1631 {
1632 DrawIndexedInstancedBaseVertexBaseInstanceParams *paramStruct =
1633 initCommand<DrawIndexedInstancedBaseVertexBaseInstanceParams>(
1634 CommandID::DrawIndexedInstancedBaseVertexBaseInstance);
1635 paramStruct->indexCount = indexCount;
1636 paramStruct->instanceCount = instanceCount;
1637 paramStruct->firstIndex = firstIndex;
1638 paramStruct->vertexOffset = vertexOffset;
1639 paramStruct->firstInstance = firstInstance;
1640
1641 mCommandTracker.onDraw();
1642 }
1643
drawIndirect(const Buffer & buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1644 ANGLE_INLINE void SecondaryCommandBuffer::drawIndirect(const Buffer &buffer,
1645 VkDeviceSize offset,
1646 uint32_t drawCount,
1647 uint32_t stride)
1648 {
1649 DrawIndirectParams *paramStruct = initCommand<DrawIndirectParams>(CommandID::DrawIndirect);
1650 paramStruct->buffer = buffer.getHandle();
1651 paramStruct->offset = offset;
1652 paramStruct->drawCount = drawCount;
1653 paramStruct->stride = stride;
1654
1655 mCommandTracker.onDraw();
1656 }
1657
drawInstanced(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex)1658 ANGLE_INLINE void SecondaryCommandBuffer::drawInstanced(uint32_t vertexCount,
1659 uint32_t instanceCount,
1660 uint32_t firstVertex)
1661 {
1662 DrawInstancedParams *paramStruct = initCommand<DrawInstancedParams>(CommandID::DrawInstanced);
1663 paramStruct->vertexCount = vertexCount;
1664 paramStruct->instanceCount = instanceCount;
1665 paramStruct->firstVertex = firstVertex;
1666
1667 mCommandTracker.onDraw();
1668 }
1669
drawInstancedBaseInstance(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)1670 ANGLE_INLINE void SecondaryCommandBuffer::drawInstancedBaseInstance(uint32_t vertexCount,
1671 uint32_t instanceCount,
1672 uint32_t firstVertex,
1673 uint32_t firstInstance)
1674 {
1675 DrawInstancedBaseInstanceParams *paramStruct =
1676 initCommand<DrawInstancedBaseInstanceParams>(CommandID::DrawInstancedBaseInstance);
1677 paramStruct->vertexCount = vertexCount;
1678 paramStruct->instanceCount = instanceCount;
1679 paramStruct->firstVertex = firstVertex;
1680 paramStruct->firstInstance = firstInstance;
1681
1682 mCommandTracker.onDraw();
1683 }
1684
endDebugUtilsLabelEXT()1685 ANGLE_INLINE void SecondaryCommandBuffer::endDebugUtilsLabelEXT()
1686 {
1687 initCommand<EmptyParams>(CommandID::EndDebugUtilsLabel);
1688 }
1689
endQuery(const QueryPool & queryPool,uint32_t query)1690 ANGLE_INLINE void SecondaryCommandBuffer::endQuery(const QueryPool &queryPool, uint32_t query)
1691 {
1692 EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery);
1693 paramStruct->queryPool = queryPool.getHandle();
1694 paramStruct->query = query;
1695 }
1696
endTransformFeedback(uint32_t firstCounterBuffer,uint32_t counterBufferCount,const VkBuffer * counterBuffers,const VkDeviceSize * counterBufferOffsets)1697 ANGLE_INLINE void SecondaryCommandBuffer::endTransformFeedback(
1698 uint32_t firstCounterBuffer,
1699 uint32_t counterBufferCount,
1700 const VkBuffer *counterBuffers,
1701 const VkDeviceSize *counterBufferOffsets)
1702 {
1703 ASSERT(firstCounterBuffer == 0);
1704 uint8_t *writePtr;
1705 const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(counterBufferCount);
1706 const ArrayParamSize offsetsSize =
1707 calculateArrayParameterSize<VkDeviceSize>(counterBufferCount);
1708 EndTransformFeedbackParams *paramStruct = initCommand<EndTransformFeedbackParams>(
1709 CommandID::EndTransformFeedback, buffersSize.allocateBytes + offsetsSize.allocateBytes,
1710 &writePtr);
1711 paramStruct->bufferCount = counterBufferCount;
1712 writePtr = storeArrayParameter(writePtr, counterBuffers, buffersSize);
1713 storeArrayParameter(writePtr, counterBufferOffsets, offsetsSize);
1714 }
1715
fillBuffer(const Buffer & dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)1716 ANGLE_INLINE void SecondaryCommandBuffer::fillBuffer(const Buffer &dstBuffer,
1717 VkDeviceSize dstOffset,
1718 VkDeviceSize size,
1719 uint32_t data)
1720 {
1721 FillBufferParams *paramStruct = initCommand<FillBufferParams>(CommandID::FillBuffer);
1722 paramStruct->dstBuffer = dstBuffer.getHandle();
1723 paramStruct->dstOffset = dstOffset;
1724 paramStruct->size = size;
1725 paramStruct->data = data;
1726 }
1727
imageBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkImageMemoryBarrier & imageMemoryBarrier)1728 ANGLE_INLINE void SecondaryCommandBuffer::imageBarrier(
1729 VkPipelineStageFlags srcStageMask,
1730 VkPipelineStageFlags dstStageMask,
1731 const VkImageMemoryBarrier &imageMemoryBarrier)
1732 {
1733 ASSERT(imageMemoryBarrier.pNext == nullptr);
1734
1735 uint8_t *writePtr;
1736 const ArrayParamSize imgBarrierSize = calculateArrayParameterSize<VkImageMemoryBarrier>(1);
1737 ImageBarrierParams *paramStruct = initCommand<ImageBarrierParams>(
1738 CommandID::ImageBarrier, imgBarrierSize.allocateBytes, &writePtr);
1739 paramStruct->srcStageMask = srcStageMask;
1740 paramStruct->dstStageMask = dstStageMask;
1741 storeArrayParameter(writePtr, &imageMemoryBarrier, imgBarrierSize);
1742 }
1743
imageWaitEvent(const VkEvent & event,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkImageMemoryBarrier & imageMemoryBarrier)1744 ANGLE_INLINE void SecondaryCommandBuffer::imageWaitEvent(
1745 const VkEvent &event,
1746 VkPipelineStageFlags srcStageMask,
1747 VkPipelineStageFlags dstStageMask,
1748 const VkImageMemoryBarrier &imageMemoryBarrier)
1749 {
1750 ASSERT(imageMemoryBarrier.pNext == nullptr);
1751
1752 uint8_t *writePtr;
1753 const ArrayParamSize imgBarrierSize = calculateArrayParameterSize<VkImageMemoryBarrier>(1);
1754
1755 ImageWaitEventParams *paramStruct = initCommand<ImageWaitEventParams>(
1756 CommandID::ImageWaitEvent, imgBarrierSize.allocateBytes, &writePtr);
1757 paramStruct->event = event;
1758 paramStruct->srcStageMask = srcStageMask;
1759 paramStruct->dstStageMask = dstStageMask;
1760 storeArrayParameter(writePtr, &imageMemoryBarrier, imgBarrierSize);
1761 }
1762
insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT & label)1763 ANGLE_INLINE void SecondaryCommandBuffer::insertDebugUtilsLabelEXT(
1764 const VkDebugUtilsLabelEXT &label)
1765 {
1766 commonDebugUtilsLabel(CommandID::InsertDebugUtilsLabel, label);
1767 }
1768
memoryBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkMemoryBarrier & memoryBarrier)1769 ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask,
1770 VkPipelineStageFlags dstStageMask,
1771 const VkMemoryBarrier &memoryBarrier)
1772 {
1773 ASSERT(memoryBarrier.pNext == nullptr);
1774
1775 uint8_t *writePtr;
1776 const ArrayParamSize memBarrierSize = calculateArrayParameterSize<VkMemoryBarrier>(1);
1777 MemoryBarrierParams *paramStruct = initCommand<MemoryBarrierParams>(
1778 CommandID::MemoryBarrier, memBarrierSize.allocateBytes, &writePtr);
1779 paramStruct->srcStageMask = srcStageMask;
1780 paramStruct->dstStageMask = dstStageMask;
1781 storeArrayParameter(writePtr, &memoryBarrier, memBarrierSize);
1782 }
1783
nextSubpass(VkSubpassContents subpassContents)1784 ANGLE_INLINE void SecondaryCommandBuffer::nextSubpass(VkSubpassContents subpassContents)
1785 {
1786 ASSERT(subpassContents == VK_SUBPASS_CONTENTS_INLINE);
1787 initCommand<EmptyParams>(CommandID::NextSubpass);
1788 }
1789
pipelineBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,VkDependencyFlags dependencyFlags,uint32_t memoryBarrierCount,const VkMemoryBarrier * memoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * bufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * imageMemoryBarriers)1790 ANGLE_INLINE void SecondaryCommandBuffer::pipelineBarrier(
1791 VkPipelineStageFlags srcStageMask,
1792 VkPipelineStageFlags dstStageMask,
1793 VkDependencyFlags dependencyFlags,
1794 uint32_t memoryBarrierCount,
1795 const VkMemoryBarrier *memoryBarriers,
1796 uint32_t bufferMemoryBarrierCount,
1797 const VkBufferMemoryBarrier *bufferMemoryBarriers,
1798 uint32_t imageMemoryBarrierCount,
1799 const VkImageMemoryBarrier *imageMemoryBarriers)
1800 {
1801 // Other than for QFOT (where bufferBarrier() is used), ANGLE doesn't use buffer barriers.
1802 // Memory barriers are used instead.
1803 ASSERT(bufferMemoryBarrierCount == 0);
1804 ASSERT(bufferMemoryBarriers == nullptr);
1805
1806 uint8_t *writePtr;
1807 const ArrayParamSize memBarrierSize =
1808 calculateArrayParameterSize<VkMemoryBarrier>(memoryBarrierCount);
1809 const ArrayParamSize imgBarrierSize =
1810 calculateArrayParameterSize<VkImageMemoryBarrier>(imageMemoryBarrierCount);
1811 PipelineBarrierParams *paramStruct = initCommand<PipelineBarrierParams>(
1812 CommandID::PipelineBarrier, memBarrierSize.allocateBytes + imgBarrierSize.allocateBytes,
1813 &writePtr);
1814 paramStruct->srcStageMask = srcStageMask;
1815 paramStruct->dstStageMask = dstStageMask;
1816 paramStruct->dependencyFlags = dependencyFlags;
1817 paramStruct->memoryBarrierCount = memoryBarrierCount;
1818 paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount;
1819 // Copy variable sized data
1820 if (memoryBarrierCount > 0)
1821 {
1822 writePtr = storeArrayParameter(writePtr, memoryBarriers, memBarrierSize);
1823 }
1824 if (imageMemoryBarrierCount > 0)
1825 {
1826 storeArrayParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
1827 }
1828 }
1829
pushConstants(const PipelineLayout & layout,VkShaderStageFlags flag,uint32_t offset,uint32_t size,const void * data)1830 ANGLE_INLINE void SecondaryCommandBuffer::pushConstants(const PipelineLayout &layout,
1831 VkShaderStageFlags flag,
1832 uint32_t offset,
1833 uint32_t size,
1834 const void *data)
1835 {
1836 ASSERT(size == static_cast<size_t>(size));
1837 uint8_t *writePtr;
1838 const ArrayParamSize dataSize = calculateArrayParameterSize<uint8_t>(size);
1839 PushConstantsParams *paramStruct = initCommand<PushConstantsParams>(
1840 CommandID::PushConstants, dataSize.allocateBytes, &writePtr);
1841 paramStruct->layout = layout.getHandle();
1842 paramStruct->flag = flag;
1843 paramStruct->offset = offset;
1844 paramStruct->size = size;
1845 // Copy variable sized data
1846 storeArrayParameter(writePtr, data, dataSize);
1847 }
1848
resetEvent(VkEvent event,VkPipelineStageFlags stageMask)1849 ANGLE_INLINE void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
1850 {
1851 ResetEventParams *paramStruct = initCommand<ResetEventParams>(CommandID::ResetEvent);
1852 paramStruct->event = event;
1853 paramStruct->stageMask = stageMask;
1854 }
1855
resetQueryPool(const QueryPool & queryPool,uint32_t firstQuery,uint32_t queryCount)1856 ANGLE_INLINE void SecondaryCommandBuffer::resetQueryPool(const QueryPool &queryPool,
1857 uint32_t firstQuery,
1858 uint32_t queryCount)
1859 {
1860 ResetQueryPoolParams *paramStruct =
1861 initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool);
1862 paramStruct->queryPool = queryPool.getHandle();
1863 SetBitField(paramStruct->firstQuery, firstQuery);
1864 SetBitField(paramStruct->queryCount, queryCount);
1865 }
1866
resolveImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageResolve * regions)1867 ANGLE_INLINE void SecondaryCommandBuffer::resolveImage(const Image &srcImage,
1868 VkImageLayout srcImageLayout,
1869 const Image &dstImage,
1870 VkImageLayout dstImageLayout,
1871 uint32_t regionCount,
1872 const VkImageResolve *regions)
1873 {
1874 // Currently ANGLE uses limited params so verify those assumptions and update if they change.
1875 ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1876 ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1877 ASSERT(regionCount == 1);
1878 ResolveImageParams *paramStruct = initCommand<ResolveImageParams>(CommandID::ResolveImage);
1879 paramStruct->srcImage = srcImage.getHandle();
1880 paramStruct->dstImage = dstImage.getHandle();
1881 paramStruct->region = regions[0];
1882 }
1883
setBlendConstants(const float blendConstants[4])1884 ANGLE_INLINE void SecondaryCommandBuffer::setBlendConstants(const float blendConstants[4])
1885 {
1886 SetBlendConstantsParams *paramStruct =
1887 initCommand<SetBlendConstantsParams>(CommandID::SetBlendConstants);
1888 for (uint32_t channel = 0; channel < 4; ++channel)
1889 {
1890 paramStruct->blendConstants[channel] = blendConstants[channel];
1891 }
1892 }
1893
setCullMode(VkCullModeFlags cullMode)1894 ANGLE_INLINE void SecondaryCommandBuffer::setCullMode(VkCullModeFlags cullMode)
1895 {
1896 SetCullModeParams *paramStruct = initCommand<SetCullModeParams>(CommandID::SetCullMode);
1897 paramStruct->cullMode = cullMode;
1898 }
1899
setDepthBias(float depthBiasConstantFactor,float depthBiasClamp,float depthBiasSlopeFactor)1900 ANGLE_INLINE void SecondaryCommandBuffer::setDepthBias(float depthBiasConstantFactor,
1901 float depthBiasClamp,
1902 float depthBiasSlopeFactor)
1903 {
1904 SetDepthBiasParams *paramStruct = initCommand<SetDepthBiasParams>(CommandID::SetDepthBias);
1905 paramStruct->depthBiasConstantFactor = depthBiasConstantFactor;
1906 paramStruct->depthBiasClamp = depthBiasClamp;
1907 paramStruct->depthBiasSlopeFactor = depthBiasSlopeFactor;
1908 }
1909
setDepthBiasEnable(VkBool32 depthBiasEnable)1910 ANGLE_INLINE void SecondaryCommandBuffer::setDepthBiasEnable(VkBool32 depthBiasEnable)
1911 {
1912 SetDepthBiasEnableParams *paramStruct =
1913 initCommand<SetDepthBiasEnableParams>(CommandID::SetDepthBiasEnable);
1914 paramStruct->depthBiasEnable = depthBiasEnable;
1915 }
1916
setDepthCompareOp(VkCompareOp depthCompareOp)1917 ANGLE_INLINE void SecondaryCommandBuffer::setDepthCompareOp(VkCompareOp depthCompareOp)
1918 {
1919 SetDepthCompareOpParams *paramStruct =
1920 initCommand<SetDepthCompareOpParams>(CommandID::SetDepthCompareOp);
1921 paramStruct->depthCompareOp = depthCompareOp;
1922 }
1923
setDepthTestEnable(VkBool32 depthTestEnable)1924 ANGLE_INLINE void SecondaryCommandBuffer::setDepthTestEnable(VkBool32 depthTestEnable)
1925 {
1926 SetDepthTestEnableParams *paramStruct =
1927 initCommand<SetDepthTestEnableParams>(CommandID::SetDepthTestEnable);
1928 paramStruct->depthTestEnable = depthTestEnable;
1929 }
1930
setDepthWriteEnable(VkBool32 depthWriteEnable)1931 ANGLE_INLINE void SecondaryCommandBuffer::setDepthWriteEnable(VkBool32 depthWriteEnable)
1932 {
1933 SetDepthWriteEnableParams *paramStruct =
1934 initCommand<SetDepthWriteEnableParams>(CommandID::SetDepthWriteEnable);
1935 paramStruct->depthWriteEnable = depthWriteEnable;
1936 }
1937
setEvent(VkEvent event,VkPipelineStageFlags stageMask)1938 ANGLE_INLINE void SecondaryCommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
1939 {
1940 SetEventParams *paramStruct = initCommand<SetEventParams>(CommandID::SetEvent);
1941 paramStruct->event = event;
1942 paramStruct->stageMask = stageMask;
1943 }
1944
setFragmentShadingRate(const VkExtent2D * fragmentSize,VkFragmentShadingRateCombinerOpKHR ops[2])1945 ANGLE_INLINE void SecondaryCommandBuffer::setFragmentShadingRate(
1946 const VkExtent2D *fragmentSize,
1947 VkFragmentShadingRateCombinerOpKHR ops[2])
1948 {
1949 ASSERT(fragmentSize != nullptr);
1950
1951 // Supported parameter values -
1952 // 1. CombinerOp for ops[0] needs to be VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
1953 // as there are no current usecases in ANGLE to use primitive fragment shading rates
1954 // 2. The largest fragment size supported is 4x4
1955 ASSERT(ops[0] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR);
1956 ASSERT(fragmentSize->width <= 4);
1957 ASSERT(fragmentSize->height <= 4);
1958
1959 SetFragmentShadingRateParams *paramStruct =
1960 initCommand<SetFragmentShadingRateParams>(CommandID::SetFragmentShadingRate);
1961 paramStruct->fragmentWidth = static_cast<uint16_t>(fragmentSize->width);
1962 paramStruct->fragmentHeight = static_cast<uint16_t>(fragmentSize->height);
1963 paramStruct->vkFragmentShadingRateCombinerOp1 = static_cast<uint16_t>(ops[1]);
1964 }
1965
setFrontFace(VkFrontFace frontFace)1966 ANGLE_INLINE void SecondaryCommandBuffer::setFrontFace(VkFrontFace frontFace)
1967 {
1968 SetFrontFaceParams *paramStruct = initCommand<SetFrontFaceParams>(CommandID::SetFrontFace);
1969 paramStruct->frontFace = frontFace;
1970 }
1971
setLineWidth(float lineWidth)1972 ANGLE_INLINE void SecondaryCommandBuffer::setLineWidth(float lineWidth)
1973 {
1974 SetLineWidthParams *paramStruct = initCommand<SetLineWidthParams>(CommandID::SetLineWidth);
1975 paramStruct->lineWidth = lineWidth;
1976 }
1977
setLogicOp(VkLogicOp logicOp)1978 ANGLE_INLINE void SecondaryCommandBuffer::setLogicOp(VkLogicOp logicOp)
1979 {
1980 SetLogicOpParams *paramStruct = initCommand<SetLogicOpParams>(CommandID::SetLogicOp);
1981 paramStruct->logicOp = logicOp;
1982 }
1983
setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable)1984 ANGLE_INLINE void SecondaryCommandBuffer::setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable)
1985 {
1986 SetPrimitiveRestartEnableParams *paramStruct =
1987 initCommand<SetPrimitiveRestartEnableParams>(CommandID::SetPrimitiveRestartEnable);
1988 paramStruct->primitiveRestartEnable = primitiveRestartEnable;
1989 }
1990
setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable)1991 ANGLE_INLINE void SecondaryCommandBuffer::setRasterizerDiscardEnable(
1992 VkBool32 rasterizerDiscardEnable)
1993 {
1994 SetRasterizerDiscardEnableParams *paramStruct =
1995 initCommand<SetRasterizerDiscardEnableParams>(CommandID::SetRasterizerDiscardEnable);
1996 paramStruct->rasterizerDiscardEnable = rasterizerDiscardEnable;
1997 }
1998
setScissor(uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * scissors)1999 ANGLE_INLINE void SecondaryCommandBuffer::setScissor(uint32_t firstScissor,
2000 uint32_t scissorCount,
2001 const VkRect2D *scissors)
2002 {
2003 ASSERT(firstScissor == 0);
2004 ASSERT(scissorCount == 1);
2005 ASSERT(scissors != nullptr);
2006 SetScissorParams *paramStruct = initCommand<SetScissorParams>(CommandID::SetScissor);
2007 paramStruct->scissor = scissors[0];
2008 }
2009
setStencilCompareMask(uint32_t compareFrontMask,uint32_t compareBackMask)2010 ANGLE_INLINE void SecondaryCommandBuffer::setStencilCompareMask(uint32_t compareFrontMask,
2011 uint32_t compareBackMask)
2012 {
2013 SetStencilCompareMaskParams *paramStruct =
2014 initCommand<SetStencilCompareMaskParams>(CommandID::SetStencilCompareMask);
2015 paramStruct->compareFrontMask = static_cast<uint16_t>(compareFrontMask);
2016 paramStruct->compareBackMask = static_cast<uint16_t>(compareBackMask);
2017 }
2018
setStencilOp(VkStencilFaceFlags faceMask,VkStencilOp failOp,VkStencilOp passOp,VkStencilOp depthFailOp,VkCompareOp compareOp)2019 ANGLE_INLINE void SecondaryCommandBuffer::setStencilOp(VkStencilFaceFlags faceMask,
2020 VkStencilOp failOp,
2021 VkStencilOp passOp,
2022 VkStencilOp depthFailOp,
2023 VkCompareOp compareOp)
2024 {
2025 SetStencilOpParams *paramStruct = initCommand<SetStencilOpParams>(CommandID::SetStencilOp);
2026 SetBitField(paramStruct->faceMask, faceMask);
2027 SetBitField(paramStruct->failOp, failOp);
2028 SetBitField(paramStruct->passOp, passOp);
2029 SetBitField(paramStruct->depthFailOp, depthFailOp);
2030 SetBitField(paramStruct->compareOp, compareOp);
2031 }
2032
setStencilReference(uint32_t frontReference,uint32_t backReference)2033 ANGLE_INLINE void SecondaryCommandBuffer::setStencilReference(uint32_t frontReference,
2034 uint32_t backReference)
2035 {
2036 SetStencilReferenceParams *paramStruct =
2037 initCommand<SetStencilReferenceParams>(CommandID::SetStencilReference);
2038 paramStruct->frontReference = static_cast<uint16_t>(frontReference);
2039 paramStruct->backReference = static_cast<uint16_t>(backReference);
2040 }
2041
setStencilTestEnable(VkBool32 stencilTestEnable)2042 ANGLE_INLINE void SecondaryCommandBuffer::setStencilTestEnable(VkBool32 stencilTestEnable)
2043 {
2044 SetStencilTestEnableParams *paramStruct =
2045 initCommand<SetStencilTestEnableParams>(CommandID::SetStencilTestEnable);
2046 paramStruct->stencilTestEnable = stencilTestEnable;
2047 }
2048
setStencilWriteMask(uint32_t writeFrontMask,uint32_t writeBackMask)2049 ANGLE_INLINE void SecondaryCommandBuffer::setStencilWriteMask(uint32_t writeFrontMask,
2050 uint32_t writeBackMask)
2051 {
2052 SetStencilWriteMaskParams *paramStruct =
2053 initCommand<SetStencilWriteMaskParams>(CommandID::SetStencilWriteMask);
2054 paramStruct->writeFrontMask = static_cast<uint16_t>(writeFrontMask);
2055 paramStruct->writeBackMask = static_cast<uint16_t>(writeBackMask);
2056 }
2057
setVertexInput(uint32_t vertexBindingDescriptionCount,const VkVertexInputBindingDescription2EXT * vertexBindingDescriptions,uint32_t vertexAttributeDescriptionCount,const VkVertexInputAttributeDescription2EXT * vertexAttributeDescriptions)2058 ANGLE_INLINE void SecondaryCommandBuffer::setVertexInput(
2059 uint32_t vertexBindingDescriptionCount,
2060 const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions,
2061 uint32_t vertexAttributeDescriptionCount,
2062 const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions)
2063 {
2064 uint8_t *writePtr;
2065 const ArrayParamSize vertexBindingDescriptionSize =
2066 calculateArrayParameterSize<VkVertexInputBindingDescription2EXT>(
2067 vertexBindingDescriptionCount);
2068 const ArrayParamSize vertexAttributeDescriptionSize =
2069 calculateArrayParameterSize<VkVertexInputAttributeDescription2EXT>(
2070 vertexAttributeDescriptionCount);
2071
2072 SetVertexInputParams *paramStruct = initCommand<SetVertexInputParams>(
2073 CommandID::SetVertexInput,
2074 vertexBindingDescriptionSize.allocateBytes + vertexAttributeDescriptionSize.allocateBytes,
2075 &writePtr);
2076
2077 // Copy params
2078 SetBitField(paramStruct->vertexBindingDescriptionCount, vertexBindingDescriptionCount);
2079 SetBitField(paramStruct->vertexAttributeDescriptionCount, vertexAttributeDescriptionCount);
2080
2081 if (vertexBindingDescriptionSize.copyBytes)
2082 {
2083 writePtr =
2084 storeArrayParameter(writePtr, vertexBindingDescriptions, vertexBindingDescriptionSize);
2085 }
2086 if (vertexAttributeDescriptionSize.copyBytes)
2087 {
2088 storeArrayParameter(writePtr, vertexAttributeDescriptions, vertexAttributeDescriptionSize);
2089 }
2090 }
2091
setViewport(uint32_t firstViewport,uint32_t viewportCount,const VkViewport * viewports)2092 ANGLE_INLINE void SecondaryCommandBuffer::setViewport(uint32_t firstViewport,
2093 uint32_t viewportCount,
2094 const VkViewport *viewports)
2095 {
2096 ASSERT(firstViewport == 0);
2097 ASSERT(viewportCount == 1);
2098 ASSERT(viewports != nullptr);
2099 SetViewportParams *paramStruct = initCommand<SetViewportParams>(CommandID::SetViewport);
2100 paramStruct->viewport = viewports[0];
2101 }
2102
waitEvents(uint32_t eventCount,const VkEvent * events,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,uint32_t memoryBarrierCount,const VkMemoryBarrier * memoryBarriers,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier * bufferMemoryBarriers,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier * imageMemoryBarriers)2103 ANGLE_INLINE void SecondaryCommandBuffer::waitEvents(
2104 uint32_t eventCount,
2105 const VkEvent *events,
2106 VkPipelineStageFlags srcStageMask,
2107 VkPipelineStageFlags dstStageMask,
2108 uint32_t memoryBarrierCount,
2109 const VkMemoryBarrier *memoryBarriers,
2110 uint32_t bufferMemoryBarrierCount,
2111 const VkBufferMemoryBarrier *bufferMemoryBarriers,
2112 uint32_t imageMemoryBarrierCount,
2113 const VkImageMemoryBarrier *imageMemoryBarriers)
2114 {
2115 // Other than for QFOT (where bufferBarrier() is used), ANGLE doesn't use buffer barriers.
2116 // Memory barriers are used instead.
2117 ASSERT(bufferMemoryBarrierCount == 0);
2118 ASSERT(bufferMemoryBarriers == nullptr);
2119
2120 uint8_t *writePtr;
2121 const ArrayParamSize eventSize = calculateArrayParameterSize<VkEvent>(eventCount);
2122 const ArrayParamSize memBarrierSize =
2123 calculateArrayParameterSize<VkMemoryBarrier>(memoryBarrierCount);
2124 const ArrayParamSize imgBarrierSize =
2125 calculateArrayParameterSize<VkImageMemoryBarrier>(imageMemoryBarrierCount);
2126 WaitEventsParams *paramStruct = initCommand<WaitEventsParams>(
2127 CommandID::WaitEvents,
2128 eventSize.allocateBytes + memBarrierSize.allocateBytes + imgBarrierSize.allocateBytes,
2129 &writePtr);
2130 paramStruct->eventCount = eventCount;
2131 paramStruct->srcStageMask = srcStageMask;
2132 paramStruct->dstStageMask = dstStageMask;
2133 paramStruct->memoryBarrierCount = memoryBarrierCount;
2134 paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount;
2135 // Copy variable sized data
2136 writePtr = storeArrayParameter(writePtr, events, eventSize);
2137 writePtr = storeArrayParameter(writePtr, memoryBarriers, memBarrierSize);
2138 storeArrayParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
2139 }
2140
writeTimestamp(VkPipelineStageFlagBits pipelineStage,const QueryPool & queryPool,uint32_t query)2141 ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
2142 const QueryPool &queryPool,
2143 uint32_t query)
2144 {
2145 ASSERT(pipelineStage == VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
2146
2147 WriteTimestampParams *paramStruct =
2148 initCommand<WriteTimestampParams>(CommandID::WriteTimestamp);
2149 paramStruct->queryPool = queryPool.getHandle();
2150 paramStruct->query = query;
2151 }
2152 } // namespace priv
2153 } // namespace vk
2154 } // namespace rx
2155
2156 #endif // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
2157