• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 // Copyright 2019 The ANGLE Project Authors. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
5 //
6 // SecondaryCommandBuffer:
7 //    Lightweight, CPU-Side command buffers used to hold command state until
8 //    it has to be submitted to GPU.
9 //
10 
11 #ifndef LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
12 #define LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
13 
14 #include "common/vulkan/vk_headers.h"
15 #include "libANGLE/renderer/vulkan/vk_command_buffer_utils.h"
16 #include "libANGLE/renderer/vulkan/vk_wrapper.h"
17 
18 #if ANGLE_ENABLE_VULKAN_SHARED_RING_BUFFER_CMD_ALLOC
19 #    include "libANGLE/renderer/vulkan/AllocatorHelperRing.h"
20 #else
21 #    include "libANGLE/renderer/vulkan/AllocatorHelperPool.h"
22 #endif
23 
24 namespace rx
25 {
26 class ContextVk;
27 
28 namespace vk
29 {
30 class ErrorContext;
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(ErrorContext * context,SecondaryCommandPool * pool,uint32_t queueFamilyIndex,ProtectionType protectionType)834     static angle::Result InitializeCommandPool(ErrorContext *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::ErrorContext * context,vk::SecondaryCommandPool * pool,bool isRenderPassCommandBuffer,SecondaryCommandMemoryAllocator * allocator)1122     angle::Result initialize(vk::ErrorContext *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(ErrorContext * context,const VkCommandBufferInheritanceInfo & inheritanceInfo)1140     angle::Result begin(ErrorContext *context,
1141                         const VkCommandBufferInheritanceInfo &inheritanceInfo)
1142     {
1143         return angle::Result::Continue;
1144     }
end(ErrorContext * context)1145     angle::Result end(ErrorContext *context) { return angle::Result::Continue; }
1146 
open()1147     void open() { mIsOpen = true; }
close()1148     void close() { mIsOpen = false; }
1149 
reset()1150     void reset()
1151     {
1152         mCommands.clear();
1153         mCommandAllocator.reset(&mCommandTracker);
1154     }
1155 
1156     // The SecondaryCommandBuffer is valid if it's been initialized
valid()1157     bool valid() const { return mCommandAllocator.valid(); }
1158 
empty()1159     bool empty() const { return mCommandAllocator.empty(); }
checkEmptyForPoolAlloc()1160     bool checkEmptyForPoolAlloc() const
1161     {
1162         return mCommands.size() == 0 || mCommands[0]->id == CommandID::Invalid;
1163     }
1164 
getRenderPassWriteCommandCount()1165     uint32_t getRenderPassWriteCommandCount() const
1166     {
1167         return mCommandTracker.getRenderPassWriteCommandCount();
1168     }
1169 
clearCommands()1170     void clearCommands() { mCommands.clear(); }
hasEmptyCommands()1171     bool hasEmptyCommands() { return mCommands.empty(); }
pushToCommands(uint8_t * command)1172     void pushToCommands(uint8_t *command)
1173     {
1174         mCommands.push_back(reinterpret_cast<priv::CommandHeader *>(command));
1175     }
1176 
1177   private:
1178     void commonDebugUtilsLabel(CommandID cmd, const VkDebugUtilsLabelEXT &label);
1179     template <class StructType>
commonInit(CommandID cmdID,size_t allocationSize,uint8_t * commandMemory)1180     ANGLE_INLINE StructType *commonInit(CommandID cmdID,
1181                                         size_t allocationSize,
1182                                         uint8_t *commandMemory)
1183     {
1184         ASSERT(mIsOpen);
1185         ASSERT(allocationSize <= std::numeric_limits<uint16_t>::max());
1186 
1187         StructType *command  = reinterpret_cast<StructType *>(commandMemory);
1188         command->header.id   = cmdID;
1189         command->header.size = static_cast<uint16_t>(allocationSize);
1190 
1191         return command;
1192     }
1193 
1194     // Allocate and initialize memory for given commandID & variable param size, setting
1195     // variableDataOut to the byte following fixed cmd data where variable-sized ptr data will
1196     // be written and returning a pointer to the start of the command's parameter data
1197     template <class StructType>
initCommand(CommandID cmdID,size_t variableSize,uint8_t ** variableDataOut)1198     ANGLE_INLINE StructType *initCommand(CommandID cmdID,
1199                                          size_t variableSize,
1200                                          uint8_t **variableDataOut)
1201     {
1202         constexpr size_t fixedAllocationSize = sizeof(StructType);
1203         const size_t allocationSize          = fixedAllocationSize + variableSize;
1204 
1205         // Make sure we have enough room to mark follow-on header "Invalid"
1206         const size_t requiredSize = allocationSize + sizeof(CommandHeader);
1207         uint8_t *commandMemory    = nullptr;
1208 
1209         mCommandAllocator.onNewVariableSizedCommand(requiredSize, allocationSize, &commandMemory);
1210         StructType *command = commonInit<StructType>(cmdID, allocationSize, commandMemory);
1211         *variableDataOut    = Offset<uint8_t>(commandMemory, fixedAllocationSize);
1212         return command;
1213     }
1214 
1215     // Initialize a command that doesn't have variable-sized ptr data
1216     template <class StructType>
initCommand(CommandID cmdID)1217     ANGLE_INLINE StructType *initCommand(CommandID cmdID)
1218     {
1219         constexpr size_t allocationSize = sizeof(StructType);
1220 
1221         // Make sure we have enough room to mark follow-on header "Invalid"
1222         const size_t requiredSize = allocationSize + sizeof(CommandHeader);
1223         uint8_t *commandMemory    = nullptr;
1224         mCommandAllocator.onNewCommand(requiredSize, allocationSize, &commandMemory);
1225 
1226         return commonInit<StructType>(cmdID, allocationSize, commandMemory);
1227     }
1228 
1229     // Return a pointer to the parameter type.  Note that every param struct has the header as its
1230     // first member, so in fact the parameter type pointer is identical to the header pointer.
1231     template <class StructType>
getParamPtr(const CommandHeader * header)1232     const StructType *getParamPtr(const CommandHeader *header) const
1233     {
1234         return reinterpret_cast<const StructType *>(header);
1235     }
1236     struct ArrayParamSize
1237     {
1238         // Given an array of N elements of type T, N*sizeof(T) bytes need to be copied, but due to
1239         // alignment requirements, roundUp(size, 8) bytes need to be allocated for the array.
1240         size_t copyBytes;
1241         size_t allocateBytes;
1242     };
1243     template <class T>
calculateArrayParameterSize(size_t count)1244     ANGLE_INLINE ArrayParamSize calculateArrayParameterSize(size_t count)
1245     {
1246         ArrayParamSize size;
1247         size.copyBytes     = sizeof(T) * count;
1248         size.allocateBytes = roundUpPow2<size_t>(size.copyBytes, 8u);
1249         return size;
1250     }
1251     // Copy size.copyBytes data from paramData to writePointer and return writePointer plus
1252     // size.allocateBytes.
1253     template <class T>
storeArrayParameter(uint8_t * writePointer,const T * data,const ArrayParamSize & size)1254     ANGLE_INLINE uint8_t *storeArrayParameter(uint8_t *writePointer,
1255                                               const T *data,
1256                                               const ArrayParamSize &size)
1257     {
1258         // See |PointerParamSize|.  The size should always be calculated with
1259         // |calculatePointerParameterSize|, and that satisfies this condition.
1260         ASSERT(size.allocateBytes == roundUpPow2<size_t>(size.copyBytes, 8u));
1261 
1262         memcpy(writePointer, data, size.copyBytes);
1263         return writePointer + size.allocateBytes;
1264     }
1265 
1266     // Flag to indicate that commandBuffer is open for new commands. Initially open.
1267     bool mIsOpen;
1268 
1269     std::vector<CommandHeader *> mCommands;
1270 
1271     // Allocator used by this class. If non-null then the class is valid.
1272     SecondaryCommandBlockPool mCommandAllocator;
1273 
1274     CommandBufferCommandTracker mCommandTracker;
1275 };
1276 
SecondaryCommandBuffer()1277 ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer() : mIsOpen(true)
1278 {
1279     mCommandAllocator.setCommandBuffer(this);
1280 }
1281 
~SecondaryCommandBuffer()1282 ANGLE_INLINE SecondaryCommandBuffer::~SecondaryCommandBuffer()
1283 {
1284     mCommandAllocator.resetCommandBuffer();
1285 }
1286 
1287 // begin and insert DebugUtilsLabelEXT funcs share this same function body
commonDebugUtilsLabel(CommandID cmd,const VkDebugUtilsLabelEXT & label)1288 ANGLE_INLINE void SecondaryCommandBuffer::commonDebugUtilsLabel(CommandID cmd,
1289                                                                 const VkDebugUtilsLabelEXT &label)
1290 {
1291     uint8_t *writePtr;
1292     const ArrayParamSize stringSize =
1293         calculateArrayParameterSize<char>(strlen(label.pLabelName) + 1);
1294     DebugUtilsLabelParams *paramStruct =
1295         initCommand<DebugUtilsLabelParams>(cmd, stringSize.allocateBytes, &writePtr);
1296     paramStruct->color[0] = label.color[0];
1297     paramStruct->color[1] = label.color[1];
1298     paramStruct->color[2] = label.color[2];
1299     paramStruct->color[3] = label.color[3];
1300     storeArrayParameter(writePtr, label.pLabelName, stringSize);
1301 }
1302 
beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT & label)1303 ANGLE_INLINE void SecondaryCommandBuffer::beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label)
1304 {
1305     commonDebugUtilsLabel(CommandID::BeginDebugUtilsLabel, label);
1306 }
1307 
beginQuery(const QueryPool & queryPool,uint32_t query,VkQueryControlFlags flags)1308 ANGLE_INLINE void SecondaryCommandBuffer::beginQuery(const QueryPool &queryPool,
1309                                                      uint32_t query,
1310                                                      VkQueryControlFlags flags)
1311 {
1312     ASSERT(flags == 0);
1313     BeginQueryParams *paramStruct = initCommand<BeginQueryParams>(CommandID::BeginQuery);
1314     paramStruct->queryPool        = queryPool.getHandle();
1315     paramStruct->query            = query;
1316 }
1317 
beginTransformFeedback(uint32_t firstCounterBuffer,uint32_t bufferCount,const VkBuffer * counterBuffers,const VkDeviceSize * counterBufferOffsets)1318 ANGLE_INLINE void SecondaryCommandBuffer::beginTransformFeedback(
1319     uint32_t firstCounterBuffer,
1320     uint32_t bufferCount,
1321     const VkBuffer *counterBuffers,
1322     const VkDeviceSize *counterBufferOffsets)
1323 {
1324     ASSERT(firstCounterBuffer == 0);
1325     uint8_t *writePtr;
1326     const ArrayParamSize bufferSize = calculateArrayParameterSize<VkBuffer>(bufferCount);
1327     const ArrayParamSize offsetSize = calculateArrayParameterSize<VkDeviceSize>(bufferCount);
1328     BeginTransformFeedbackParams *paramStruct = initCommand<BeginTransformFeedbackParams>(
1329         CommandID::BeginTransformFeedback, bufferSize.allocateBytes + offsetSize.allocateBytes,
1330         &writePtr);
1331     paramStruct->bufferCount = bufferCount;
1332     writePtr                 = storeArrayParameter(writePtr, counterBuffers, bufferSize);
1333     storeArrayParameter(writePtr, counterBufferOffsets, offsetSize);
1334 }
1335 
bindComputePipeline(const Pipeline & pipeline)1336 ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pipeline)
1337 {
1338     BindPipelineParams *paramStruct =
1339         initCommand<BindPipelineParams>(CommandID::BindComputePipeline);
1340     paramStruct->pipeline = pipeline.getHandle();
1341 }
1342 
bindDescriptorSets(const PipelineLayout & layout,VkPipelineBindPoint pipelineBindPoint,DescriptorSetIndex firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * descriptorSets,uint32_t dynamicOffsetCount,const uint32_t * dynamicOffsets)1343 ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
1344                                                              VkPipelineBindPoint pipelineBindPoint,
1345                                                              DescriptorSetIndex firstSet,
1346                                                              uint32_t descriptorSetCount,
1347                                                              const VkDescriptorSet *descriptorSets,
1348                                                              uint32_t dynamicOffsetCount,
1349                                                              const uint32_t *dynamicOffsets)
1350 {
1351     const ArrayParamSize descSize =
1352         calculateArrayParameterSize<VkDescriptorSet>(descriptorSetCount);
1353     const ArrayParamSize offsetSize = calculateArrayParameterSize<uint32_t>(dynamicOffsetCount);
1354     uint8_t *writePtr;
1355     BindDescriptorSetParams *paramStruct = initCommand<BindDescriptorSetParams>(
1356         CommandID::BindDescriptorSets, descSize.allocateBytes + offsetSize.allocateBytes,
1357         &writePtr);
1358     // Copy params into memory
1359     paramStruct->layout = layout.getHandle();
1360     SetBitField(paramStruct->pipelineBindPoint, pipelineBindPoint);
1361     SetBitField(paramStruct->firstSet, ToUnderlying(firstSet));
1362     SetBitField(paramStruct->descriptorSetCount, descriptorSetCount);
1363     SetBitField(paramStruct->dynamicOffsetCount, dynamicOffsetCount);
1364     // Copy variable sized data
1365     writePtr = storeArrayParameter(writePtr, descriptorSets, descSize);
1366     if (dynamicOffsetCount > 0)
1367     {
1368         storeArrayParameter(writePtr, dynamicOffsets, offsetSize);
1369     }
1370 }
1371 
bindGraphicsPipeline(const Pipeline & pipeline)1372 ANGLE_INLINE void SecondaryCommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
1373 {
1374     BindPipelineParams *paramStruct =
1375         initCommand<BindPipelineParams>(CommandID::BindGraphicsPipeline);
1376     paramStruct->pipeline = pipeline.getHandle();
1377 }
1378 
bindIndexBuffer(const Buffer & buffer,VkDeviceSize offset,VkIndexType indexType)1379 ANGLE_INLINE void SecondaryCommandBuffer::bindIndexBuffer(const Buffer &buffer,
1380                                                           VkDeviceSize offset,
1381                                                           VkIndexType indexType)
1382 {
1383     BindIndexBufferParams *paramStruct =
1384         initCommand<BindIndexBufferParams>(CommandID::BindIndexBuffer);
1385     paramStruct->buffer    = buffer.getHandle();
1386     paramStruct->offset    = offset;
1387     paramStruct->indexType = indexType;
1388 }
1389 
bindTransformFeedbackBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets,const VkDeviceSize * sizes)1390 ANGLE_INLINE void SecondaryCommandBuffer::bindTransformFeedbackBuffers(uint32_t firstBinding,
1391                                                                        uint32_t bindingCount,
1392                                                                        const VkBuffer *buffers,
1393                                                                        const VkDeviceSize *offsets,
1394                                                                        const VkDeviceSize *sizes)
1395 {
1396     ASSERT(firstBinding == 0);
1397     uint8_t *writePtr;
1398     const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(bindingCount);
1399     const ArrayParamSize offsetsSize = calculateArrayParameterSize<VkDeviceSize>(bindingCount);
1400     const ArrayParamSize sizesSize   = offsetsSize;
1401     BindTransformFeedbackBuffersParams *paramStruct =
1402         initCommand<BindTransformFeedbackBuffersParams>(
1403             CommandID::BindTransformFeedbackBuffers,
1404             buffersSize.allocateBytes + offsetsSize.allocateBytes + sizesSize.allocateBytes,
1405             &writePtr);
1406     // Copy params
1407     paramStruct->bindingCount = bindingCount;
1408     writePtr                  = storeArrayParameter(writePtr, buffers, buffersSize);
1409     writePtr                  = storeArrayParameter(writePtr, offsets, offsetsSize);
1410     storeArrayParameter(writePtr, sizes, sizesSize);
1411 }
1412 
bindVertexBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets)1413 ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers(uint32_t firstBinding,
1414                                                             uint32_t bindingCount,
1415                                                             const VkBuffer *buffers,
1416                                                             const VkDeviceSize *offsets)
1417 {
1418     ASSERT(firstBinding == 0);
1419     uint8_t *writePtr;
1420     const ArrayParamSize buffersSize     = calculateArrayParameterSize<VkBuffer>(bindingCount);
1421     const ArrayParamSize offsetsSize     = calculateArrayParameterSize<VkDeviceSize>(bindingCount);
1422     BindVertexBuffersParams *paramStruct = initCommand<BindVertexBuffersParams>(
1423         CommandID::BindVertexBuffers, buffersSize.allocateBytes + offsetsSize.allocateBytes,
1424         &writePtr);
1425     // Copy params
1426     paramStruct->bindingCount = bindingCount;
1427     writePtr                  = storeArrayParameter(writePtr, buffers, buffersSize);
1428     storeArrayParameter(writePtr, offsets, offsetsSize);
1429 }
1430 
bindVertexBuffers2(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets,const VkDeviceSize * sizes,const VkDeviceSize * strides)1431 ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers2(uint32_t firstBinding,
1432                                                              uint32_t bindingCount,
1433                                                              const VkBuffer *buffers,
1434                                                              const VkDeviceSize *offsets,
1435                                                              const VkDeviceSize *sizes,
1436                                                              const VkDeviceSize *strides)
1437 {
1438     ASSERT(firstBinding == 0);
1439     ASSERT(sizes == nullptr);
1440     uint8_t *writePtr;
1441     const ArrayParamSize buffersSize      = calculateArrayParameterSize<VkBuffer>(bindingCount);
1442     const ArrayParamSize offsetsSize      = calculateArrayParameterSize<VkDeviceSize>(bindingCount);
1443     const ArrayParamSize stridesSize      = offsetsSize;
1444     BindVertexBuffers2Params *paramStruct = initCommand<BindVertexBuffers2Params>(
1445         CommandID::BindVertexBuffers2,
1446         buffersSize.allocateBytes + offsetsSize.allocateBytes + stridesSize.allocateBytes,
1447         &writePtr);
1448     // Copy params
1449     paramStruct->bindingCount = bindingCount;
1450     writePtr                  = storeArrayParameter(writePtr, buffers, buffersSize);
1451     writePtr                  = storeArrayParameter(writePtr, offsets, offsetsSize);
1452     storeArrayParameter(writePtr, strides, stridesSize);
1453 }
1454 
blitImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * regions,VkFilter filter)1455 ANGLE_INLINE void SecondaryCommandBuffer::blitImage(const Image &srcImage,
1456                                                     VkImageLayout srcImageLayout,
1457                                                     const Image &dstImage,
1458                                                     VkImageLayout dstImageLayout,
1459                                                     uint32_t regionCount,
1460                                                     const VkImageBlit *regions,
1461                                                     VkFilter filter)
1462 {
1463     // Currently ANGLE uses limited params so verify those assumptions and update if they change
1464     ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1465     ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1466     ASSERT(regionCount == 1);
1467     BlitImageParams *paramStruct = initCommand<BlitImageParams>(CommandID::BlitImage);
1468     paramStruct->srcImage        = srcImage.getHandle();
1469     paramStruct->dstImage        = dstImage.getHandle();
1470     paramStruct->filter          = filter;
1471     paramStruct->region          = regions[0];
1472 }
1473 
bufferBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkBufferMemoryBarrier * bufferMemoryBarrier)1474 ANGLE_INLINE void SecondaryCommandBuffer::bufferBarrier(
1475     VkPipelineStageFlags srcStageMask,
1476     VkPipelineStageFlags dstStageMask,
1477     const VkBufferMemoryBarrier *bufferMemoryBarrier)
1478 {
1479     // Used only during queue family ownership transfers
1480     ASSERT(srcStageMask == VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1481     ASSERT(dstStageMask == VK_PIPELINE_STAGE_ALL_COMMANDS_BIT);
1482 
1483     BufferBarrierParams *paramStruct = initCommand<BufferBarrierParams>(CommandID::BufferBarrier);
1484     paramStruct->bufferMemoryBarrier = *bufferMemoryBarrier;
1485 }
1486 
bufferBarrier2(const VkBufferMemoryBarrier2 * bufferMemoryBarrier2)1487 ANGLE_INLINE void SecondaryCommandBuffer::bufferBarrier2(
1488     const VkBufferMemoryBarrier2 *bufferMemoryBarrier2)
1489 {
1490     ASSERT(bufferMemoryBarrier2->srcStageMask == VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
1491     ASSERT(bufferMemoryBarrier2->dstStageMask == VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT);
1492 
1493     BufferBarrier2Params *paramStruct =
1494         initCommand<BufferBarrier2Params>(CommandID::BufferBarrier2);
1495     paramStruct->bufferMemoryBarrier2 = *bufferMemoryBarrier2;
1496 }
1497 
clearAttachments(uint32_t attachmentCount,const VkClearAttachment * attachments,uint32_t rectCount,const VkClearRect * rects)1498 ANGLE_INLINE void SecondaryCommandBuffer::clearAttachments(uint32_t attachmentCount,
1499                                                            const VkClearAttachment *attachments,
1500                                                            uint32_t rectCount,
1501                                                            const VkClearRect *rects)
1502 {
1503     ASSERT(rectCount == 1);
1504     uint8_t *writePtr;
1505     const ArrayParamSize attachmentSize =
1506         calculateArrayParameterSize<VkClearAttachment>(attachmentCount);
1507     ClearAttachmentsParams *paramStruct = initCommand<ClearAttachmentsParams>(
1508         CommandID::ClearAttachments, attachmentSize.allocateBytes, &writePtr);
1509     paramStruct->attachmentCount = attachmentCount;
1510     paramStruct->rect            = rects[0];
1511     // Copy variable sized data
1512     storeArrayParameter(writePtr, attachments, attachmentSize);
1513 
1514     mCommandTracker.onClearAttachments();
1515 }
1516 
clearColorImage(const Image & image,VkImageLayout imageLayout,const VkClearColorValue & color,uint32_t rangeCount,const VkImageSubresourceRange * ranges)1517 ANGLE_INLINE void SecondaryCommandBuffer::clearColorImage(const Image &image,
1518                                                           VkImageLayout imageLayout,
1519                                                           const VkClearColorValue &color,
1520                                                           uint32_t rangeCount,
1521                                                           const VkImageSubresourceRange *ranges)
1522 {
1523     ASSERT(rangeCount == 1);
1524     ClearColorImageParams *paramStruct =
1525         initCommand<ClearColorImageParams>(CommandID::ClearColorImage);
1526     paramStruct->image       = image.getHandle();
1527     paramStruct->imageLayout = imageLayout;
1528     paramStruct->color       = color;
1529     paramStruct->range       = ranges[0];
1530 }
1531 
clearDepthStencilImage(const Image & image,VkImageLayout imageLayout,const VkClearDepthStencilValue & depthStencil,uint32_t rangeCount,const VkImageSubresourceRange * ranges)1532 ANGLE_INLINE void SecondaryCommandBuffer::clearDepthStencilImage(
1533     const Image &image,
1534     VkImageLayout imageLayout,
1535     const VkClearDepthStencilValue &depthStencil,
1536     uint32_t rangeCount,
1537     const VkImageSubresourceRange *ranges)
1538 {
1539     ASSERT(rangeCount == 1);
1540     ClearDepthStencilImageParams *paramStruct =
1541         initCommand<ClearDepthStencilImageParams>(CommandID::ClearDepthStencilImage);
1542     paramStruct->image        = image.getHandle();
1543     paramStruct->imageLayout  = imageLayout;
1544     paramStruct->depthStencil = depthStencil;
1545     paramStruct->range        = ranges[0];
1546 }
1547 
copyBuffer(const Buffer & srcBuffer,const Buffer & destBuffer,uint32_t regionCount,const VkBufferCopy * regions)1548 ANGLE_INLINE void SecondaryCommandBuffer::copyBuffer(const Buffer &srcBuffer,
1549                                                      const Buffer &destBuffer,
1550                                                      uint32_t regionCount,
1551                                                      const VkBufferCopy *regions)
1552 {
1553     uint8_t *writePtr;
1554     const ArrayParamSize regionSize = calculateArrayParameterSize<VkBufferCopy>(regionCount);
1555     CopyBufferParams *paramStruct =
1556         initCommand<CopyBufferParams>(CommandID::CopyBuffer, regionSize.allocateBytes, &writePtr);
1557     paramStruct->srcBuffer   = srcBuffer.getHandle();
1558     paramStruct->destBuffer  = destBuffer.getHandle();
1559     paramStruct->regionCount = regionCount;
1560     // Copy variable sized data
1561     storeArrayParameter(writePtr, regions, regionSize);
1562 }
1563 
copyBufferToImage(VkBuffer srcBuffer,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * regions)1564 ANGLE_INLINE void SecondaryCommandBuffer::copyBufferToImage(VkBuffer srcBuffer,
1565                                                             const Image &dstImage,
1566                                                             VkImageLayout dstImageLayout,
1567                                                             uint32_t regionCount,
1568                                                             const VkBufferImageCopy *regions)
1569 {
1570     ASSERT(regionCount == 1);
1571     CopyBufferToImageParams *paramStruct =
1572         initCommand<CopyBufferToImageParams>(CommandID::CopyBufferToImage);
1573     paramStruct->srcBuffer      = srcBuffer;
1574     paramStruct->dstImage       = dstImage.getHandle();
1575     paramStruct->dstImageLayout = dstImageLayout;
1576     paramStruct->region         = regions[0];
1577 }
1578 
copyImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * regions)1579 ANGLE_INLINE void SecondaryCommandBuffer::copyImage(const Image &srcImage,
1580                                                     VkImageLayout srcImageLayout,
1581                                                     const Image &dstImage,
1582                                                     VkImageLayout dstImageLayout,
1583                                                     uint32_t regionCount,
1584                                                     const VkImageCopy *regions)
1585 {
1586     ASSERT(regionCount == 1);
1587     CopyImageParams *paramStruct = initCommand<CopyImageParams>(CommandID::CopyImage);
1588     paramStruct->srcImage        = srcImage.getHandle();
1589     paramStruct->srcImageLayout  = srcImageLayout;
1590     paramStruct->dstImage        = dstImage.getHandle();
1591     paramStruct->dstImageLayout  = dstImageLayout;
1592     paramStruct->region          = regions[0];
1593 }
1594 
copyImageToBuffer(const Image & srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * regions)1595 ANGLE_INLINE void SecondaryCommandBuffer::copyImageToBuffer(const Image &srcImage,
1596                                                             VkImageLayout srcImageLayout,
1597                                                             VkBuffer dstBuffer,
1598                                                             uint32_t regionCount,
1599                                                             const VkBufferImageCopy *regions)
1600 {
1601     ASSERT(regionCount == 1);
1602     CopyImageToBufferParams *paramStruct =
1603         initCommand<CopyImageToBufferParams>(CommandID::CopyImageToBuffer);
1604     paramStruct->srcImage       = srcImage.getHandle();
1605     paramStruct->srcImageLayout = srcImageLayout;
1606     paramStruct->dstBuffer      = dstBuffer;
1607     paramStruct->region         = regions[0];
1608 }
1609 
dispatch(uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)1610 ANGLE_INLINE void SecondaryCommandBuffer::dispatch(uint32_t groupCountX,
1611                                                    uint32_t groupCountY,
1612                                                    uint32_t groupCountZ)
1613 {
1614     DispatchParams *paramStruct = initCommand<DispatchParams>(CommandID::Dispatch);
1615     paramStruct->groupCountX    = groupCountX;
1616     paramStruct->groupCountY    = groupCountY;
1617     paramStruct->groupCountZ    = groupCountZ;
1618 }
1619 
dispatchIndirect(const Buffer & buffer,VkDeviceSize offset)1620 ANGLE_INLINE void SecondaryCommandBuffer::dispatchIndirect(const Buffer &buffer,
1621                                                            VkDeviceSize offset)
1622 {
1623     DispatchIndirectParams *paramStruct =
1624         initCommand<DispatchIndirectParams>(CommandID::DispatchIndirect);
1625     paramStruct->buffer = buffer.getHandle();
1626     paramStruct->offset = offset;
1627 }
1628 
draw(uint32_t vertexCount,uint32_t firstVertex)1629 ANGLE_INLINE void SecondaryCommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
1630 {
1631     DrawParams *paramStruct  = initCommand<DrawParams>(CommandID::Draw);
1632     paramStruct->vertexCount = vertexCount;
1633     paramStruct->firstVertex = firstVertex;
1634 
1635     mCommandTracker.onDraw();
1636 }
1637 
drawIndexed(uint32_t indexCount)1638 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount)
1639 {
1640     DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed);
1641     paramStruct->indexCount        = indexCount;
1642 
1643     mCommandTracker.onDraw();
1644 }
1645 
drawIndexedBaseVertex(uint32_t indexCount,uint32_t vertexOffset)1646 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedBaseVertex(uint32_t indexCount,
1647                                                                 uint32_t vertexOffset)
1648 {
1649     DrawIndexedBaseVertexParams *paramStruct =
1650         initCommand<DrawIndexedBaseVertexParams>(CommandID::DrawIndexedBaseVertex);
1651     paramStruct->indexCount   = indexCount;
1652     paramStruct->vertexOffset = vertexOffset;
1653 
1654     mCommandTracker.onDraw();
1655 }
1656 
drawIndexedIndirect(const Buffer & buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1657 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedIndirect(const Buffer &buffer,
1658                                                               VkDeviceSize offset,
1659                                                               uint32_t drawCount,
1660                                                               uint32_t stride)
1661 {
1662     DrawIndexedIndirectParams *paramStruct =
1663         initCommand<DrawIndexedIndirectParams>(CommandID::DrawIndexedIndirect);
1664     paramStruct->buffer    = buffer.getHandle();
1665     paramStruct->offset    = offset;
1666     paramStruct->drawCount = drawCount;
1667     paramStruct->stride    = stride;
1668 
1669     mCommandTracker.onDraw();
1670 }
1671 
drawIndexedInstanced(uint32_t indexCount,uint32_t instanceCount)1672 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstanced(uint32_t indexCount,
1673                                                                uint32_t instanceCount)
1674 {
1675     DrawIndexedInstancedParams *paramStruct =
1676         initCommand<DrawIndexedInstancedParams>(CommandID::DrawIndexedInstanced);
1677     paramStruct->indexCount    = indexCount;
1678     paramStruct->instanceCount = instanceCount;
1679 
1680     mCommandTracker.onDraw();
1681 }
1682 
drawIndexedInstancedBaseVertex(uint32_t indexCount,uint32_t instanceCount,uint32_t vertexOffset)1683 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertex(uint32_t indexCount,
1684                                                                          uint32_t instanceCount,
1685                                                                          uint32_t vertexOffset)
1686 {
1687     DrawIndexedInstancedBaseVertexParams *paramStruct =
1688         initCommand<DrawIndexedInstancedBaseVertexParams>(
1689             CommandID::DrawIndexedInstancedBaseVertex);
1690     paramStruct->indexCount    = indexCount;
1691     paramStruct->instanceCount = instanceCount;
1692     paramStruct->vertexOffset  = vertexOffset;
1693 
1694     mCommandTracker.onDraw();
1695 }
1696 
drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,uint32_t instanceCount,uint32_t firstIndex,int32_t vertexOffset,uint32_t firstInstance)1697 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertexBaseInstance(
1698     uint32_t indexCount,
1699     uint32_t instanceCount,
1700     uint32_t firstIndex,
1701     int32_t vertexOffset,
1702     uint32_t firstInstance)
1703 {
1704     DrawIndexedInstancedBaseVertexBaseInstanceParams *paramStruct =
1705         initCommand<DrawIndexedInstancedBaseVertexBaseInstanceParams>(
1706             CommandID::DrawIndexedInstancedBaseVertexBaseInstance);
1707     paramStruct->indexCount    = indexCount;
1708     paramStruct->instanceCount = instanceCount;
1709     paramStruct->firstIndex    = firstIndex;
1710     paramStruct->vertexOffset  = vertexOffset;
1711     paramStruct->firstInstance = firstInstance;
1712 
1713     mCommandTracker.onDraw();
1714 }
1715 
drawIndirect(const Buffer & buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1716 ANGLE_INLINE void SecondaryCommandBuffer::drawIndirect(const Buffer &buffer,
1717                                                        VkDeviceSize offset,
1718                                                        uint32_t drawCount,
1719                                                        uint32_t stride)
1720 {
1721     DrawIndirectParams *paramStruct = initCommand<DrawIndirectParams>(CommandID::DrawIndirect);
1722     paramStruct->buffer             = buffer.getHandle();
1723     paramStruct->offset             = offset;
1724     paramStruct->drawCount          = drawCount;
1725     paramStruct->stride             = stride;
1726 
1727     mCommandTracker.onDraw();
1728 }
1729 
drawInstanced(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex)1730 ANGLE_INLINE void SecondaryCommandBuffer::drawInstanced(uint32_t vertexCount,
1731                                                         uint32_t instanceCount,
1732                                                         uint32_t firstVertex)
1733 {
1734     DrawInstancedParams *paramStruct = initCommand<DrawInstancedParams>(CommandID::DrawInstanced);
1735     paramStruct->vertexCount         = vertexCount;
1736     paramStruct->instanceCount       = instanceCount;
1737     paramStruct->firstVertex         = firstVertex;
1738 
1739     mCommandTracker.onDraw();
1740 }
1741 
drawInstancedBaseInstance(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)1742 ANGLE_INLINE void SecondaryCommandBuffer::drawInstancedBaseInstance(uint32_t vertexCount,
1743                                                                     uint32_t instanceCount,
1744                                                                     uint32_t firstVertex,
1745                                                                     uint32_t firstInstance)
1746 {
1747     DrawInstancedBaseInstanceParams *paramStruct =
1748         initCommand<DrawInstancedBaseInstanceParams>(CommandID::DrawInstancedBaseInstance);
1749     paramStruct->vertexCount   = vertexCount;
1750     paramStruct->instanceCount = instanceCount;
1751     paramStruct->firstVertex   = firstVertex;
1752     paramStruct->firstInstance = firstInstance;
1753 
1754     mCommandTracker.onDraw();
1755 }
1756 
endDebugUtilsLabelEXT()1757 ANGLE_INLINE void SecondaryCommandBuffer::endDebugUtilsLabelEXT()
1758 {
1759     initCommand<EmptyParams>(CommandID::EndDebugUtilsLabel);
1760 }
1761 
endQuery(const QueryPool & queryPool,uint32_t query)1762 ANGLE_INLINE void SecondaryCommandBuffer::endQuery(const QueryPool &queryPool, uint32_t query)
1763 {
1764     EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery);
1765     paramStruct->queryPool      = queryPool.getHandle();
1766     paramStruct->query          = query;
1767 }
1768 
endTransformFeedback(uint32_t firstCounterBuffer,uint32_t counterBufferCount,const VkBuffer * counterBuffers,const VkDeviceSize * counterBufferOffsets)1769 ANGLE_INLINE void SecondaryCommandBuffer::endTransformFeedback(
1770     uint32_t firstCounterBuffer,
1771     uint32_t counterBufferCount,
1772     const VkBuffer *counterBuffers,
1773     const VkDeviceSize *counterBufferOffsets)
1774 {
1775     ASSERT(firstCounterBuffer == 0);
1776     uint8_t *writePtr;
1777     const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(counterBufferCount);
1778     const ArrayParamSize offsetsSize =
1779         calculateArrayParameterSize<VkDeviceSize>(counterBufferCount);
1780     EndTransformFeedbackParams *paramStruct = initCommand<EndTransformFeedbackParams>(
1781         CommandID::EndTransformFeedback, buffersSize.allocateBytes + offsetsSize.allocateBytes,
1782         &writePtr);
1783     paramStruct->bufferCount = counterBufferCount;
1784     writePtr                 = storeArrayParameter(writePtr, counterBuffers, buffersSize);
1785     storeArrayParameter(writePtr, counterBufferOffsets, offsetsSize);
1786 }
1787 
fillBuffer(const Buffer & dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)1788 ANGLE_INLINE void SecondaryCommandBuffer::fillBuffer(const Buffer &dstBuffer,
1789                                                      VkDeviceSize dstOffset,
1790                                                      VkDeviceSize size,
1791                                                      uint32_t data)
1792 {
1793     FillBufferParams *paramStruct = initCommand<FillBufferParams>(CommandID::FillBuffer);
1794     paramStruct->dstBuffer        = dstBuffer.getHandle();
1795     paramStruct->dstOffset        = dstOffset;
1796     paramStruct->size             = size;
1797     paramStruct->data             = data;
1798 }
1799 
imageBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkImageMemoryBarrier & imageMemoryBarrier)1800 ANGLE_INLINE void SecondaryCommandBuffer::imageBarrier(
1801     VkPipelineStageFlags srcStageMask,
1802     VkPipelineStageFlags dstStageMask,
1803     const VkImageMemoryBarrier &imageMemoryBarrier)
1804 {
1805     ASSERT(imageMemoryBarrier.pNext == nullptr);
1806 
1807     uint8_t *writePtr;
1808     const ArrayParamSize imgBarrierSize = calculateArrayParameterSize<VkImageMemoryBarrier>(1);
1809     ImageBarrierParams *paramStruct     = initCommand<ImageBarrierParams>(
1810         CommandID::ImageBarrier, imgBarrierSize.allocateBytes, &writePtr);
1811     paramStruct->srcStageMask = srcStageMask;
1812     paramStruct->dstStageMask = dstStageMask;
1813     storeArrayParameter(writePtr, &imageMemoryBarrier, imgBarrierSize);
1814 }
1815 
imageBarrier2(const VkImageMemoryBarrier2 & imageMemoryBarrier2)1816 ANGLE_INLINE void SecondaryCommandBuffer::imageBarrier2(
1817     const VkImageMemoryBarrier2 &imageMemoryBarrier2)
1818 {
1819     ASSERT(imageMemoryBarrier2.pNext == nullptr);
1820 
1821     uint8_t *writePtr;
1822     const ArrayParamSize imgBarrier2Size = calculateArrayParameterSize<VkImageMemoryBarrier2>(1);
1823     initCommand<ImageBarrier2Params>(CommandID::ImageBarrier2, imgBarrier2Size.allocateBytes,
1824                                      &writePtr);
1825     storeArrayParameter(writePtr, &imageMemoryBarrier2, imgBarrier2Size);
1826 }
1827 
imageWaitEvent(const VkEvent & event,VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkImageMemoryBarrier & imageMemoryBarrier)1828 ANGLE_INLINE void SecondaryCommandBuffer::imageWaitEvent(
1829     const VkEvent &event,
1830     VkPipelineStageFlags srcStageMask,
1831     VkPipelineStageFlags dstStageMask,
1832     const VkImageMemoryBarrier &imageMemoryBarrier)
1833 {
1834     ASSERT(imageMemoryBarrier.pNext == nullptr);
1835 
1836     uint8_t *writePtr;
1837     const ArrayParamSize imgBarrierSize = calculateArrayParameterSize<VkImageMemoryBarrier>(1);
1838 
1839     ImageWaitEventParams *paramStruct = initCommand<ImageWaitEventParams>(
1840         CommandID::ImageWaitEvent, imgBarrierSize.allocateBytes, &writePtr);
1841     paramStruct->event        = event;
1842     paramStruct->srcStageMask = srcStageMask;
1843     paramStruct->dstStageMask = dstStageMask;
1844     storeArrayParameter(writePtr, &imageMemoryBarrier, imgBarrierSize);
1845 }
1846 
insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT & label)1847 ANGLE_INLINE void SecondaryCommandBuffer::insertDebugUtilsLabelEXT(
1848     const VkDebugUtilsLabelEXT &label)
1849 {
1850     commonDebugUtilsLabel(CommandID::InsertDebugUtilsLabel, label);
1851 }
1852 
memoryBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkMemoryBarrier & memoryBarrier)1853 ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask,
1854                                                         VkPipelineStageFlags dstStageMask,
1855                                                         const VkMemoryBarrier &memoryBarrier)
1856 {
1857     ASSERT(memoryBarrier.pNext == nullptr);
1858 
1859     uint8_t *writePtr;
1860     const ArrayParamSize memBarrierSize = calculateArrayParameterSize<VkMemoryBarrier>(1);
1861     MemoryBarrierParams *paramStruct    = initCommand<MemoryBarrierParams>(
1862         CommandID::MemoryBarrier, memBarrierSize.allocateBytes, &writePtr);
1863     paramStruct->srcStageMask = srcStageMask;
1864     paramStruct->dstStageMask = dstStageMask;
1865     storeArrayParameter(writePtr, &memoryBarrier, memBarrierSize);
1866 }
1867 
memoryBarrier2(const VkMemoryBarrier2 & memoryBarrier2)1868 ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier2(const VkMemoryBarrier2 &memoryBarrier2)
1869 {
1870     ASSERT(memoryBarrier2.pNext == nullptr);
1871 
1872     uint8_t *writePtr;
1873     const ArrayParamSize memBarrierSize = calculateArrayParameterSize<VkMemoryBarrier2>(1);
1874     initCommand<MemoryBarrier2Params>(CommandID::MemoryBarrier2, memBarrierSize.allocateBytes,
1875                                       &writePtr);
1876     storeArrayParameter(writePtr, &memoryBarrier2, memBarrierSize);
1877 }
1878 
nextSubpass(VkSubpassContents subpassContents)1879 ANGLE_INLINE void SecondaryCommandBuffer::nextSubpass(VkSubpassContents subpassContents)
1880 {
1881     ASSERT(subpassContents == VK_SUBPASS_CONTENTS_INLINE);
1882     initCommand<EmptyParams>(CommandID::NextSubpass);
1883 }
1884 
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)1885 ANGLE_INLINE void SecondaryCommandBuffer::pipelineBarrier(
1886     VkPipelineStageFlags srcStageMask,
1887     VkPipelineStageFlags dstStageMask,
1888     VkDependencyFlags dependencyFlags,
1889     uint32_t memoryBarrierCount,
1890     const VkMemoryBarrier *memoryBarriers,
1891     uint32_t bufferMemoryBarrierCount,
1892     const VkBufferMemoryBarrier *bufferMemoryBarriers,
1893     uint32_t imageMemoryBarrierCount,
1894     const VkImageMemoryBarrier *imageMemoryBarriers)
1895 {
1896     // Other than for QFOT (where bufferBarrier() is used), ANGLE doesn't use buffer barriers.
1897     // Memory barriers are used instead.
1898     ASSERT(bufferMemoryBarrierCount == 0);
1899     ASSERT(bufferMemoryBarriers == nullptr);
1900 
1901     uint8_t *writePtr;
1902     const ArrayParamSize memBarrierSize =
1903         calculateArrayParameterSize<VkMemoryBarrier>(memoryBarrierCount);
1904     const ArrayParamSize imgBarrierSize =
1905         calculateArrayParameterSize<VkImageMemoryBarrier>(imageMemoryBarrierCount);
1906     PipelineBarrierParams *paramStruct = initCommand<PipelineBarrierParams>(
1907         CommandID::PipelineBarrier, memBarrierSize.allocateBytes + imgBarrierSize.allocateBytes,
1908         &writePtr);
1909     paramStruct->srcStageMask            = srcStageMask;
1910     paramStruct->dstStageMask            = dstStageMask;
1911     paramStruct->dependencyFlags         = dependencyFlags;
1912     paramStruct->memoryBarrierCount      = memoryBarrierCount;
1913     paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount;
1914     // Copy variable sized data
1915     if (memoryBarrierCount > 0)
1916     {
1917         writePtr = storeArrayParameter(writePtr, memoryBarriers, memBarrierSize);
1918     }
1919     if (imageMemoryBarrierCount > 0)
1920     {
1921         storeArrayParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
1922     }
1923 }
1924 
pipelineBarrier2(VkDependencyFlags dependencyFlags,uint32_t memoryBarrierCount,const VkMemoryBarrier2 * memoryBarriers2,uint32_t bufferMemoryBarrierCount,const VkBufferMemoryBarrier2 * bufferMemoryBarriers2,uint32_t imageMemoryBarrierCount,const VkImageMemoryBarrier2 * imageMemoryBarriers2)1925 ANGLE_INLINE void SecondaryCommandBuffer::pipelineBarrier2(
1926     VkDependencyFlags dependencyFlags,
1927     uint32_t memoryBarrierCount,
1928     const VkMemoryBarrier2 *memoryBarriers2,
1929     uint32_t bufferMemoryBarrierCount,
1930     const VkBufferMemoryBarrier2 *bufferMemoryBarriers2,
1931     uint32_t imageMemoryBarrierCount,
1932     const VkImageMemoryBarrier2 *imageMemoryBarriers2)
1933 {
1934     // Other than for QFOT (where bufferBarrier() is used), ANGLE doesn't use buffer barriers.
1935     // Memory barriers are used instead.
1936     ASSERT(bufferMemoryBarrierCount == 0);
1937     ASSERT(bufferMemoryBarriers2 == nullptr);
1938 
1939     uint8_t *writePtr;
1940     const ArrayParamSize memBarrier2Size =
1941         calculateArrayParameterSize<VkMemoryBarrier2>(memoryBarrierCount);
1942     const ArrayParamSize imgBarrier2Size =
1943         calculateArrayParameterSize<VkImageMemoryBarrier2>(imageMemoryBarrierCount);
1944 
1945     PipelineBarrierParams2 *paramStruct = initCommand<PipelineBarrierParams2>(
1946         CommandID::PipelineBarrier2, memBarrier2Size.allocateBytes + imgBarrier2Size.allocateBytes,
1947         &writePtr);
1948 
1949     paramStruct->dependencyFlags         = dependencyFlags;
1950     paramStruct->memoryBarrierCount      = memoryBarrierCount;
1951     paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount;
1952     // Copy variable sized data
1953     if (memoryBarrierCount > 0)
1954     {
1955         writePtr = storeArrayParameter(writePtr, memoryBarriers2, memBarrier2Size);
1956     }
1957     if (imageMemoryBarrierCount > 0)
1958     {
1959         storeArrayParameter(writePtr, imageMemoryBarriers2, imgBarrier2Size);
1960     }
1961 }
1962 
pushConstants(const PipelineLayout & layout,VkShaderStageFlags flag,uint32_t offset,uint32_t size,const void * data)1963 ANGLE_INLINE void SecondaryCommandBuffer::pushConstants(const PipelineLayout &layout,
1964                                                         VkShaderStageFlags flag,
1965                                                         uint32_t offset,
1966                                                         uint32_t size,
1967                                                         const void *data)
1968 {
1969     ASSERT(size == static_cast<size_t>(size));
1970     uint8_t *writePtr;
1971     const ArrayParamSize dataSize    = calculateArrayParameterSize<uint8_t>(size);
1972     PushConstantsParams *paramStruct = initCommand<PushConstantsParams>(
1973         CommandID::PushConstants, dataSize.allocateBytes, &writePtr);
1974     paramStruct->layout = layout.getHandle();
1975     paramStruct->flag   = flag;
1976     paramStruct->offset = offset;
1977     paramStruct->size   = size;
1978     // Copy variable sized data
1979     storeArrayParameter(writePtr, data, dataSize);
1980 }
1981 
resetEvent(VkEvent event,VkPipelineStageFlags stageMask)1982 ANGLE_INLINE void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
1983 {
1984     ResetEventParams *paramStruct = initCommand<ResetEventParams>(CommandID::ResetEvent);
1985     paramStruct->event            = event;
1986     paramStruct->stageMask        = stageMask;
1987 }
1988 
resetQueryPool(const QueryPool & queryPool,uint32_t firstQuery,uint32_t queryCount)1989 ANGLE_INLINE void SecondaryCommandBuffer::resetQueryPool(const QueryPool &queryPool,
1990                                                          uint32_t firstQuery,
1991                                                          uint32_t queryCount)
1992 {
1993     ResetQueryPoolParams *paramStruct =
1994         initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool);
1995     paramStruct->queryPool = queryPool.getHandle();
1996     SetBitField(paramStruct->firstQuery, firstQuery);
1997     SetBitField(paramStruct->queryCount, queryCount);
1998 }
1999 
resolveImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageResolve * regions)2000 ANGLE_INLINE void SecondaryCommandBuffer::resolveImage(const Image &srcImage,
2001                                                        VkImageLayout srcImageLayout,
2002                                                        const Image &dstImage,
2003                                                        VkImageLayout dstImageLayout,
2004                                                        uint32_t regionCount,
2005                                                        const VkImageResolve *regions)
2006 {
2007     // Currently ANGLE uses limited params so verify those assumptions and update if they change.
2008     ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
2009     ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
2010     ASSERT(regionCount == 1);
2011     ResolveImageParams *paramStruct = initCommand<ResolveImageParams>(CommandID::ResolveImage);
2012     paramStruct->srcImage           = srcImage.getHandle();
2013     paramStruct->dstImage           = dstImage.getHandle();
2014     paramStruct->region             = regions[0];
2015 }
2016 
setBlendConstants(const float blendConstants[4])2017 ANGLE_INLINE void SecondaryCommandBuffer::setBlendConstants(const float blendConstants[4])
2018 {
2019     SetBlendConstantsParams *paramStruct =
2020         initCommand<SetBlendConstantsParams>(CommandID::SetBlendConstants);
2021     for (uint32_t channel = 0; channel < 4; ++channel)
2022     {
2023         paramStruct->blendConstants[channel] = blendConstants[channel];
2024     }
2025 }
2026 
setCullMode(VkCullModeFlags cullMode)2027 ANGLE_INLINE void SecondaryCommandBuffer::setCullMode(VkCullModeFlags cullMode)
2028 {
2029     SetCullModeParams *paramStruct = initCommand<SetCullModeParams>(CommandID::SetCullMode);
2030     paramStruct->cullMode          = cullMode;
2031 }
2032 
setDepthBias(float depthBiasConstantFactor,float depthBiasClamp,float depthBiasSlopeFactor)2033 ANGLE_INLINE void SecondaryCommandBuffer::setDepthBias(float depthBiasConstantFactor,
2034                                                        float depthBiasClamp,
2035                                                        float depthBiasSlopeFactor)
2036 {
2037     SetDepthBiasParams *paramStruct      = initCommand<SetDepthBiasParams>(CommandID::SetDepthBias);
2038     paramStruct->depthBiasConstantFactor = depthBiasConstantFactor;
2039     paramStruct->depthBiasClamp          = depthBiasClamp;
2040     paramStruct->depthBiasSlopeFactor    = depthBiasSlopeFactor;
2041 }
2042 
setDepthBiasEnable(VkBool32 depthBiasEnable)2043 ANGLE_INLINE void SecondaryCommandBuffer::setDepthBiasEnable(VkBool32 depthBiasEnable)
2044 {
2045     SetDepthBiasEnableParams *paramStruct =
2046         initCommand<SetDepthBiasEnableParams>(CommandID::SetDepthBiasEnable);
2047     paramStruct->depthBiasEnable = depthBiasEnable;
2048 }
2049 
setDepthCompareOp(VkCompareOp depthCompareOp)2050 ANGLE_INLINE void SecondaryCommandBuffer::setDepthCompareOp(VkCompareOp depthCompareOp)
2051 {
2052     SetDepthCompareOpParams *paramStruct =
2053         initCommand<SetDepthCompareOpParams>(CommandID::SetDepthCompareOp);
2054     paramStruct->depthCompareOp = depthCompareOp;
2055 }
2056 
setDepthTestEnable(VkBool32 depthTestEnable)2057 ANGLE_INLINE void SecondaryCommandBuffer::setDepthTestEnable(VkBool32 depthTestEnable)
2058 {
2059     SetDepthTestEnableParams *paramStruct =
2060         initCommand<SetDepthTestEnableParams>(CommandID::SetDepthTestEnable);
2061     paramStruct->depthTestEnable = depthTestEnable;
2062 }
2063 
setDepthWriteEnable(VkBool32 depthWriteEnable)2064 ANGLE_INLINE void SecondaryCommandBuffer::setDepthWriteEnable(VkBool32 depthWriteEnable)
2065 {
2066     SetDepthWriteEnableParams *paramStruct =
2067         initCommand<SetDepthWriteEnableParams>(CommandID::SetDepthWriteEnable);
2068     paramStruct->depthWriteEnable = depthWriteEnable;
2069 }
2070 
setEvent(VkEvent event,VkPipelineStageFlags stageMask)2071 ANGLE_INLINE void SecondaryCommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
2072 {
2073     SetEventParams *paramStruct = initCommand<SetEventParams>(CommandID::SetEvent);
2074     paramStruct->event          = event;
2075     paramStruct->stageMask      = stageMask;
2076 }
2077 
setFragmentShadingRate(const VkExtent2D * fragmentSize,VkFragmentShadingRateCombinerOpKHR ops[2])2078 ANGLE_INLINE void SecondaryCommandBuffer::setFragmentShadingRate(
2079     const VkExtent2D *fragmentSize,
2080     VkFragmentShadingRateCombinerOpKHR ops[2])
2081 {
2082     ASSERT(fragmentSize != nullptr);
2083 
2084     // Supported parameter values -
2085     // 1. CombinerOp for ops[0] needs to be VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR
2086     //    as there are no current usecases in ANGLE to use primitive fragment shading rates
2087     // 2. The largest fragment size supported is 4x4
2088     ASSERT(ops[0] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR);
2089     ASSERT(fragmentSize->width <= 4);
2090     ASSERT(fragmentSize->height <= 4);
2091 
2092     SetFragmentShadingRateParams *paramStruct =
2093         initCommand<SetFragmentShadingRateParams>(CommandID::SetFragmentShadingRate);
2094     paramStruct->fragmentWidth                    = static_cast<uint16_t>(fragmentSize->width);
2095     paramStruct->fragmentHeight                   = static_cast<uint16_t>(fragmentSize->height);
2096     paramStruct->vkFragmentShadingRateCombinerOp1 = static_cast<uint16_t>(ops[1]);
2097 }
2098 
setFrontFace(VkFrontFace frontFace)2099 ANGLE_INLINE void SecondaryCommandBuffer::setFrontFace(VkFrontFace frontFace)
2100 {
2101     SetFrontFaceParams *paramStruct = initCommand<SetFrontFaceParams>(CommandID::SetFrontFace);
2102     paramStruct->frontFace          = frontFace;
2103 }
2104 
setLineWidth(float lineWidth)2105 ANGLE_INLINE void SecondaryCommandBuffer::setLineWidth(float lineWidth)
2106 {
2107     SetLineWidthParams *paramStruct = initCommand<SetLineWidthParams>(CommandID::SetLineWidth);
2108     paramStruct->lineWidth          = lineWidth;
2109 }
2110 
setLogicOp(VkLogicOp logicOp)2111 ANGLE_INLINE void SecondaryCommandBuffer::setLogicOp(VkLogicOp logicOp)
2112 {
2113     SetLogicOpParams *paramStruct = initCommand<SetLogicOpParams>(CommandID::SetLogicOp);
2114     paramStruct->logicOp          = logicOp;
2115 }
2116 
setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable)2117 ANGLE_INLINE void SecondaryCommandBuffer::setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable)
2118 {
2119     SetPrimitiveRestartEnableParams *paramStruct =
2120         initCommand<SetPrimitiveRestartEnableParams>(CommandID::SetPrimitiveRestartEnable);
2121     paramStruct->primitiveRestartEnable = primitiveRestartEnable;
2122 }
2123 
setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable)2124 ANGLE_INLINE void SecondaryCommandBuffer::setRasterizerDiscardEnable(
2125     VkBool32 rasterizerDiscardEnable)
2126 {
2127     SetRasterizerDiscardEnableParams *paramStruct =
2128         initCommand<SetRasterizerDiscardEnableParams>(CommandID::SetRasterizerDiscardEnable);
2129     paramStruct->rasterizerDiscardEnable = rasterizerDiscardEnable;
2130 }
2131 
setScissor(uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * scissors)2132 ANGLE_INLINE void SecondaryCommandBuffer::setScissor(uint32_t firstScissor,
2133                                                      uint32_t scissorCount,
2134                                                      const VkRect2D *scissors)
2135 {
2136     ASSERT(firstScissor == 0);
2137     ASSERT(scissorCount == 1);
2138     ASSERT(scissors != nullptr);
2139     SetScissorParams *paramStruct = initCommand<SetScissorParams>(CommandID::SetScissor);
2140     paramStruct->scissor          = scissors[0];
2141 }
2142 
setStencilCompareMask(uint32_t compareFrontMask,uint32_t compareBackMask)2143 ANGLE_INLINE void SecondaryCommandBuffer::setStencilCompareMask(uint32_t compareFrontMask,
2144                                                                 uint32_t compareBackMask)
2145 {
2146     SetStencilCompareMaskParams *paramStruct =
2147         initCommand<SetStencilCompareMaskParams>(CommandID::SetStencilCompareMask);
2148     paramStruct->compareFrontMask = static_cast<uint16_t>(compareFrontMask);
2149     paramStruct->compareBackMask  = static_cast<uint16_t>(compareBackMask);
2150 }
2151 
setStencilOp(VkStencilFaceFlags faceMask,VkStencilOp failOp,VkStencilOp passOp,VkStencilOp depthFailOp,VkCompareOp compareOp)2152 ANGLE_INLINE void SecondaryCommandBuffer::setStencilOp(VkStencilFaceFlags faceMask,
2153                                                        VkStencilOp failOp,
2154                                                        VkStencilOp passOp,
2155                                                        VkStencilOp depthFailOp,
2156                                                        VkCompareOp compareOp)
2157 {
2158     SetStencilOpParams *paramStruct = initCommand<SetStencilOpParams>(CommandID::SetStencilOp);
2159     SetBitField(paramStruct->faceMask, faceMask);
2160     SetBitField(paramStruct->failOp, failOp);
2161     SetBitField(paramStruct->passOp, passOp);
2162     SetBitField(paramStruct->depthFailOp, depthFailOp);
2163     SetBitField(paramStruct->compareOp, compareOp);
2164 }
2165 
setStencilReference(uint32_t frontReference,uint32_t backReference)2166 ANGLE_INLINE void SecondaryCommandBuffer::setStencilReference(uint32_t frontReference,
2167                                                               uint32_t backReference)
2168 {
2169     SetStencilReferenceParams *paramStruct =
2170         initCommand<SetStencilReferenceParams>(CommandID::SetStencilReference);
2171     paramStruct->frontReference = static_cast<uint16_t>(frontReference);
2172     paramStruct->backReference  = static_cast<uint16_t>(backReference);
2173 }
2174 
setStencilTestEnable(VkBool32 stencilTestEnable)2175 ANGLE_INLINE void SecondaryCommandBuffer::setStencilTestEnable(VkBool32 stencilTestEnable)
2176 {
2177     SetStencilTestEnableParams *paramStruct =
2178         initCommand<SetStencilTestEnableParams>(CommandID::SetStencilTestEnable);
2179     paramStruct->stencilTestEnable = stencilTestEnable;
2180 }
2181 
setStencilWriteMask(uint32_t writeFrontMask,uint32_t writeBackMask)2182 ANGLE_INLINE void SecondaryCommandBuffer::setStencilWriteMask(uint32_t writeFrontMask,
2183                                                               uint32_t writeBackMask)
2184 {
2185     SetStencilWriteMaskParams *paramStruct =
2186         initCommand<SetStencilWriteMaskParams>(CommandID::SetStencilWriteMask);
2187     paramStruct->writeFrontMask = static_cast<uint16_t>(writeFrontMask);
2188     paramStruct->writeBackMask  = static_cast<uint16_t>(writeBackMask);
2189 }
2190 
setVertexInput(uint32_t vertexBindingDescriptionCount,const VkVertexInputBindingDescription2EXT * vertexBindingDescriptions,uint32_t vertexAttributeDescriptionCount,const VkVertexInputAttributeDescription2EXT * vertexAttributeDescriptions)2191 ANGLE_INLINE void SecondaryCommandBuffer::setVertexInput(
2192     uint32_t vertexBindingDescriptionCount,
2193     const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions,
2194     uint32_t vertexAttributeDescriptionCount,
2195     const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions)
2196 {
2197     uint8_t *writePtr;
2198     const ArrayParamSize vertexBindingDescriptionSize =
2199         calculateArrayParameterSize<VkVertexInputBindingDescription2EXT>(
2200             vertexBindingDescriptionCount);
2201     const ArrayParamSize vertexAttributeDescriptionSize =
2202         calculateArrayParameterSize<VkVertexInputAttributeDescription2EXT>(
2203             vertexAttributeDescriptionCount);
2204 
2205     SetVertexInputParams *paramStruct = initCommand<SetVertexInputParams>(
2206         CommandID::SetVertexInput,
2207         vertexBindingDescriptionSize.allocateBytes + vertexAttributeDescriptionSize.allocateBytes,
2208         &writePtr);
2209 
2210     // Copy params
2211     SetBitField(paramStruct->vertexBindingDescriptionCount, vertexBindingDescriptionCount);
2212     SetBitField(paramStruct->vertexAttributeDescriptionCount, vertexAttributeDescriptionCount);
2213 
2214     if (vertexBindingDescriptionSize.copyBytes)
2215     {
2216         writePtr =
2217             storeArrayParameter(writePtr, vertexBindingDescriptions, vertexBindingDescriptionSize);
2218     }
2219     if (vertexAttributeDescriptionSize.copyBytes)
2220     {
2221         storeArrayParameter(writePtr, vertexAttributeDescriptions, vertexAttributeDescriptionSize);
2222     }
2223 }
2224 
setViewport(uint32_t firstViewport,uint32_t viewportCount,const VkViewport * viewports)2225 ANGLE_INLINE void SecondaryCommandBuffer::setViewport(uint32_t firstViewport,
2226                                                       uint32_t viewportCount,
2227                                                       const VkViewport *viewports)
2228 {
2229     ASSERT(firstViewport == 0);
2230     ASSERT(viewportCount == 1);
2231     ASSERT(viewports != nullptr);
2232     SetViewportParams *paramStruct = initCommand<SetViewportParams>(CommandID::SetViewport);
2233     paramStruct->viewport          = viewports[0];
2234 }
2235 
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)2236 ANGLE_INLINE void SecondaryCommandBuffer::waitEvents(
2237     uint32_t eventCount,
2238     const VkEvent *events,
2239     VkPipelineStageFlags srcStageMask,
2240     VkPipelineStageFlags dstStageMask,
2241     uint32_t memoryBarrierCount,
2242     const VkMemoryBarrier *memoryBarriers,
2243     uint32_t bufferMemoryBarrierCount,
2244     const VkBufferMemoryBarrier *bufferMemoryBarriers,
2245     uint32_t imageMemoryBarrierCount,
2246     const VkImageMemoryBarrier *imageMemoryBarriers)
2247 {
2248     // Other than for QFOT (where bufferBarrier() is used), ANGLE doesn't use buffer barriers.
2249     // Memory barriers are used instead.
2250     ASSERT(bufferMemoryBarrierCount == 0);
2251     ASSERT(bufferMemoryBarriers == nullptr);
2252 
2253     uint8_t *writePtr;
2254     const ArrayParamSize eventSize = calculateArrayParameterSize<VkEvent>(eventCount);
2255     const ArrayParamSize memBarrierSize =
2256         calculateArrayParameterSize<VkMemoryBarrier>(memoryBarrierCount);
2257     const ArrayParamSize imgBarrierSize =
2258         calculateArrayParameterSize<VkImageMemoryBarrier>(imageMemoryBarrierCount);
2259     WaitEventsParams *paramStruct = initCommand<WaitEventsParams>(
2260         CommandID::WaitEvents,
2261         eventSize.allocateBytes + memBarrierSize.allocateBytes + imgBarrierSize.allocateBytes,
2262         &writePtr);
2263     paramStruct->eventCount              = eventCount;
2264     paramStruct->srcStageMask            = srcStageMask;
2265     paramStruct->dstStageMask            = dstStageMask;
2266     paramStruct->memoryBarrierCount      = memoryBarrierCount;
2267     paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount;
2268     // Copy variable sized data
2269     writePtr = storeArrayParameter(writePtr, events, eventSize);
2270     writePtr = storeArrayParameter(writePtr, memoryBarriers, memBarrierSize);
2271     storeArrayParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
2272 }
2273 
writeTimestamp(VkPipelineStageFlagBits pipelineStage,const QueryPool & queryPool,uint32_t query)2274 ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
2275                                                          const QueryPool &queryPool,
2276                                                          uint32_t query)
2277 {
2278     ASSERT(pipelineStage == VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT);
2279 
2280     WriteTimestampParams *paramStruct =
2281         initCommand<WriteTimestampParams>(CommandID::WriteTimestamp);
2282     paramStruct->queryPool = queryPool.getHandle();
2283     paramStruct->query     = query;
2284 }
2285 
writeTimestamp2(VkPipelineStageFlagBits2 pipelineStage,const QueryPool & queryPool,uint32_t query)2286 ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp2(VkPipelineStageFlagBits2 pipelineStage,
2287                                                           const QueryPool &queryPool,
2288                                                           uint32_t query)
2289 {
2290     ASSERT(pipelineStage == VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT);
2291 
2292     WriteTimestampParams *paramStruct =
2293         initCommand<WriteTimestampParams>(CommandID::WriteTimestamp2);
2294     paramStruct->queryPool = queryPool.getHandle();
2295     paramStruct->query     = query;
2296 }
2297 }  // namespace priv
2298 }  // namespace vk
2299 }  // namespace rx
2300 
2301 #endif  // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
2302