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