• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // SecondaryCommandBuffer:
7 //    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