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