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