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