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