• 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/PoolAlloc.h"
15 #include "common/vulkan/vk_headers.h"
16 #include "libANGLE/renderer/vulkan/vk_command_buffer_utils.h"
17 #include "libANGLE/renderer/vulkan/vk_wrapper.h"
18 
19 namespace rx
20 {
21 class ContextVk;
22 
23 namespace vk
24 {
25 class Context;
26 class RenderPassDesc;
27 
28 namespace priv
29 {
30 
31 // NOTE: Please keep command-related enums, stucts, functions
32 //  and other code dealing with commands in alphabetical order
33 //  This simplifies searching and updating commands.
34 enum class CommandID : uint16_t
35 {
36     // Invalid cmd used to mark end of sequence of commands
37     Invalid = 0,
38     BeginDebugUtilsLabel,
39     BeginQuery,
40     BeginTransformFeedback,
41     BindComputePipeline,
42     BindDescriptorSets,
43     BindGraphicsPipeline,
44     BindIndexBuffer,
45     BindTransformFeedbackBuffers,
46     BindVertexBuffers,
47     BlitImage,
48     BufferBarrier,
49     ClearAttachments,
50     ClearColorImage,
51     ClearDepthStencilImage,
52     CopyBuffer,
53     CopyBufferToImage,
54     CopyImage,
55     CopyImageToBuffer,
56     Dispatch,
57     DispatchIndirect,
58     Draw,
59     DrawIndexed,
60     DrawIndexedBaseVertex,
61     DrawIndexedIndirect,
62     DrawIndexedInstanced,
63     DrawIndexedInstancedBaseVertex,
64     DrawIndexedInstancedBaseVertexBaseInstance,
65     DrawIndirect,
66     DrawInstanced,
67     DrawInstancedBaseInstance,
68     EndDebugUtilsLabel,
69     EndQuery,
70     EndTransformFeedback,
71     FillBuffer,
72     ImageBarrier,
73     InsertDebugUtilsLabel,
74     MemoryBarrier,
75     NextSubpass,
76     PipelineBarrier,
77     PushConstants,
78     ResetEvent,
79     ResetQueryPool,
80     ResolveImage,
81     SetEvent,
82     SetScissor,
83     SetViewport,
84     WaitEvents,
85     WriteTimestamp,
86 };
87 
88 #define VERIFY_4_BYTE_ALIGNMENT(StructName) \
89     static_assert((sizeof(StructName) % 4) == 0, "Check StructName alignment");
90 
91 // Structs to encapsulate parameters for different commands
92 // This makes it easy to know the size of params & to copy params
93 // TODO: Could optimize the size of some of these structs through bit-packing
94 //  and customizing sizing based on limited parameter sets used by ANGLE
95 struct BeginQueryParams
96 {
97     VkQueryPool queryPool;
98     uint32_t query;
99     VkQueryControlFlags flags;
100 };
101 VERIFY_4_BYTE_ALIGNMENT(BeginQueryParams)
102 
103 struct BeginTransformFeedbackParams
104 {
105     uint32_t bufferCount;
106 };
107 VERIFY_4_BYTE_ALIGNMENT(BeginTransformFeedbackParams)
108 
109 struct BindDescriptorSetParams
110 {
111     VkPipelineLayout layout;
112     VkPipelineBindPoint pipelineBindPoint;
113     uint32_t firstSet;
114     uint32_t descriptorSetCount;
115     uint32_t dynamicOffsetCount;
116 };
117 VERIFY_4_BYTE_ALIGNMENT(BindDescriptorSetParams)
118 
119 struct BindIndexBufferParams
120 {
121     VkBuffer buffer;
122     VkDeviceSize offset;
123     VkIndexType indexType;
124 };
125 VERIFY_4_BYTE_ALIGNMENT(BindIndexBufferParams)
126 
127 struct BindPipelineParams
128 {
129     VkPipeline pipeline;
130 };
131 VERIFY_4_BYTE_ALIGNMENT(BindPipelineParams)
132 
133 struct BindTransformFeedbackBuffersParams
134 {
135     // ANGLE always has firstBinding of 0 so not storing that currently
136     uint32_t bindingCount;
137 };
138 VERIFY_4_BYTE_ALIGNMENT(BindTransformFeedbackBuffersParams)
139 
140 using BindVertexBuffersParams = BindTransformFeedbackBuffersParams;
141 
142 struct BlitImageParams
143 {
144     VkImage srcImage;
145     VkImage dstImage;
146     VkFilter filter;
147     VkImageBlit region;
148 };
149 VERIFY_4_BYTE_ALIGNMENT(BlitImageParams)
150 
151 struct BufferBarrierParams
152 {
153     VkPipelineStageFlags srcStageMask;
154     VkPipelineStageFlags dstStageMask;
155     VkBufferMemoryBarrier bufferMemoryBarrier;
156 };
157 VERIFY_4_BYTE_ALIGNMENT(BufferBarrierParams)
158 
159 struct ClearAttachmentsParams
160 {
161     uint32_t attachmentCount;
162     VkClearRect rect;
163 };
164 VERIFY_4_BYTE_ALIGNMENT(ClearAttachmentsParams)
165 
166 struct ClearColorImageParams
167 {
168     VkImage image;
169     VkImageLayout imageLayout;
170     VkClearColorValue color;
171     VkImageSubresourceRange range;
172 };
173 VERIFY_4_BYTE_ALIGNMENT(ClearColorImageParams)
174 
175 struct ClearDepthStencilImageParams
176 {
177     VkImage image;
178     VkImageLayout imageLayout;
179     VkClearDepthStencilValue depthStencil;
180     VkImageSubresourceRange range;
181 };
182 VERIFY_4_BYTE_ALIGNMENT(ClearDepthStencilImageParams)
183 
184 struct CopyBufferParams
185 {
186     VkBuffer srcBuffer;
187     VkBuffer destBuffer;
188     uint32_t regionCount;
189 };
190 VERIFY_4_BYTE_ALIGNMENT(CopyBufferParams)
191 
192 struct CopyBufferToImageParams
193 {
194     VkBuffer srcBuffer;
195     VkImage dstImage;
196     VkImageLayout dstImageLayout;
197     VkBufferImageCopy region;
198 };
199 VERIFY_4_BYTE_ALIGNMENT(CopyBufferToImageParams)
200 
201 struct CopyImageParams
202 {
203     VkImage srcImage;
204     VkImageLayout srcImageLayout;
205     VkImage dstImage;
206     VkImageLayout dstImageLayout;
207     VkImageCopy region;
208 };
209 VERIFY_4_BYTE_ALIGNMENT(CopyImageParams)
210 
211 struct CopyImageToBufferParams
212 {
213     VkImage srcImage;
214     VkImageLayout srcImageLayout;
215     VkBuffer dstBuffer;
216     VkBufferImageCopy region;
217 };
218 VERIFY_4_BYTE_ALIGNMENT(CopyImageToBufferParams)
219 
220 // This is a common struct used by both begin & insert DebugUtilsLabelEXT() functions
221 struct DebugUtilsLabelParams
222 {
223     float color[4];
224 };
225 VERIFY_4_BYTE_ALIGNMENT(DebugUtilsLabelParams)
226 
227 struct DispatchParams
228 {
229     uint32_t groupCountX;
230     uint32_t groupCountY;
231     uint32_t groupCountZ;
232 };
233 VERIFY_4_BYTE_ALIGNMENT(DispatchParams)
234 
235 struct DispatchIndirectParams
236 {
237     VkBuffer buffer;
238     VkDeviceSize offset;
239 };
240 VERIFY_4_BYTE_ALIGNMENT(DispatchIndirectParams)
241 
242 struct DrawParams
243 {
244     uint32_t vertexCount;
245     uint32_t firstVertex;
246 };
247 VERIFY_4_BYTE_ALIGNMENT(DrawParams)
248 
249 struct DrawIndexedParams
250 {
251     uint32_t indexCount;
252 };
253 VERIFY_4_BYTE_ALIGNMENT(DrawIndexedParams)
254 
255 struct DrawIndexedBaseVertexParams
256 {
257     uint32_t indexCount;
258     uint32_t vertexOffset;
259 };
260 VERIFY_4_BYTE_ALIGNMENT(DrawIndexedBaseVertexParams)
261 
262 struct DrawIndexedIndirectParams
263 {
264     VkBuffer buffer;
265     VkDeviceSize offset;
266     uint32_t drawCount;
267     uint32_t stride;
268 };
269 VERIFY_4_BYTE_ALIGNMENT(DrawIndexedIndirectParams)
270 
271 struct DrawIndexedInstancedParams
272 {
273     uint32_t indexCount;
274     uint32_t instanceCount;
275 };
276 VERIFY_4_BYTE_ALIGNMENT(DrawIndexedInstancedParams)
277 
278 struct DrawIndexedInstancedBaseVertexParams
279 {
280     uint32_t indexCount;
281     uint32_t instanceCount;
282     uint32_t vertexOffset;
283 };
284 VERIFY_4_BYTE_ALIGNMENT(DrawIndexedInstancedBaseVertexParams)
285 
286 struct DrawIndexedInstancedBaseVertexBaseInstanceParams
287 {
288     uint32_t indexCount;
289     uint32_t instanceCount;
290     uint32_t firstIndex;
291     int32_t vertexOffset;
292     uint32_t firstInstance;
293 };
294 VERIFY_4_BYTE_ALIGNMENT(DrawIndexedInstancedBaseVertexBaseInstanceParams)
295 
296 struct DrawIndirectParams
297 {
298     VkBuffer buffer;
299     VkDeviceSize offset;
300     uint32_t drawCount;
301     uint32_t stride;
302 };
303 VERIFY_4_BYTE_ALIGNMENT(DrawIndirectParams)
304 
305 struct DrawInstancedParams
306 {
307     uint32_t vertexCount;
308     uint32_t instanceCount;
309     uint32_t firstVertex;
310 };
311 VERIFY_4_BYTE_ALIGNMENT(DrawInstancedParams)
312 
313 struct DrawInstancedBaseInstanceParams
314 {
315     uint32_t vertexCount;
316     uint32_t instanceCount;
317     uint32_t firstVertex;
318     uint32_t firstInstance;
319 };
320 VERIFY_4_BYTE_ALIGNMENT(DrawInstancedBaseInstanceParams)
321 
322 // A special struct used with commands that don't have params
323 struct EmptyParams
324 {};
325 
326 struct EndQueryParams
327 {
328     VkQueryPool queryPool;
329     uint32_t query;
330 };
331 VERIFY_4_BYTE_ALIGNMENT(EndQueryParams)
332 
333 struct EndTransformFeedbackParams
334 {
335     uint32_t bufferCount;
336 };
337 VERIFY_4_BYTE_ALIGNMENT(EndTransformFeedbackParams)
338 
339 struct FillBufferParams
340 {
341     VkBuffer dstBuffer;
342     VkDeviceSize dstOffset;
343     VkDeviceSize size;
344     uint32_t data;
345 };
346 VERIFY_4_BYTE_ALIGNMENT(FillBufferParams)
347 
348 struct ImageBarrierParams
349 {
350     VkPipelineStageFlags srcStageMask;
351     VkPipelineStageFlags dstStageMask;
352     VkImageMemoryBarrier imageMemoryBarrier;
353 };
354 VERIFY_4_BYTE_ALIGNMENT(ImageBarrierParams)
355 
356 struct MemoryBarrierParams
357 {
358     VkPipelineStageFlags srcStageMask;
359     VkPipelineStageFlags dstStageMask;
360     VkMemoryBarrier memoryBarrier;
361 };
362 VERIFY_4_BYTE_ALIGNMENT(MemoryBarrierParams)
363 
364 struct NextSubpassParams
365 {
366     VkSubpassContents subpassContents;
367 };
368 VERIFY_4_BYTE_ALIGNMENT(NextSubpassParams)
369 
370 struct PipelineBarrierParams
371 {
372     VkPipelineStageFlags srcStageMask;
373     VkPipelineStageFlags dstStageMask;
374     VkDependencyFlags dependencyFlags;
375     uint32_t memoryBarrierCount;
376     uint32_t bufferMemoryBarrierCount;
377     uint32_t imageMemoryBarrierCount;
378 };
379 VERIFY_4_BYTE_ALIGNMENT(PipelineBarrierParams)
380 
381 struct PushConstantsParams
382 {
383     VkPipelineLayout layout;
384     VkShaderStageFlags flag;
385     uint32_t offset;
386     uint32_t size;
387 };
388 VERIFY_4_BYTE_ALIGNMENT(PushConstantsParams)
389 
390 struct ResetEventParams
391 {
392     VkEvent event;
393     VkPipelineStageFlags stageMask;
394 };
395 VERIFY_4_BYTE_ALIGNMENT(ResetEventParams)
396 
397 struct ResetQueryPoolParams
398 {
399     VkQueryPool queryPool;
400     uint32_t firstQuery;
401     uint32_t queryCount;
402 };
403 VERIFY_4_BYTE_ALIGNMENT(ResetQueryPoolParams)
404 
405 struct ResolveImageParams
406 {
407     VkImage srcImage;
408     VkImage dstImage;
409     VkImageResolve region;
410 };
411 VERIFY_4_BYTE_ALIGNMENT(ResolveImageParams)
412 
413 struct SetEventParams
414 {
415     VkEvent event;
416     VkPipelineStageFlags stageMask;
417 };
418 VERIFY_4_BYTE_ALIGNMENT(SetEventParams)
419 
420 struct SetScissorParams
421 {
422     VkRect2D scissor;
423 };
424 VERIFY_4_BYTE_ALIGNMENT(SetScissorParams)
425 
426 struct SetViewportParams
427 {
428     VkViewport viewport;
429 };
430 VERIFY_4_BYTE_ALIGNMENT(SetViewportParams)
431 
432 struct WaitEventsParams
433 {
434     uint32_t eventCount;
435     VkPipelineStageFlags srcStageMask;
436     VkPipelineStageFlags dstStageMask;
437     uint32_t memoryBarrierCount;
438     uint32_t bufferMemoryBarrierCount;
439     uint32_t imageMemoryBarrierCount;
440 };
441 VERIFY_4_BYTE_ALIGNMENT(WaitEventsParams)
442 
443 struct WriteTimestampParams
444 {
445     VkPipelineStageFlagBits pipelineStage;
446     VkQueryPool queryPool;
447     uint32_t query;
448 };
449 VERIFY_4_BYTE_ALIGNMENT(WriteTimestampParams)
450 
451 // Header for every cmd in custom cmd buffer
452 struct CommandHeader
453 {
454     CommandID id;
455     uint16_t size;
456 };
457 static_assert(sizeof(CommandHeader) == 4, "Check CommandHeader size");
458 
459 template <typename DestT, typename T>
Offset(T * ptr,size_t bytes)460 ANGLE_INLINE DestT *Offset(T *ptr, size_t bytes)
461 {
462     return reinterpret_cast<DestT *>((reinterpret_cast<uint8_t *>(ptr) + bytes));
463 }
464 
465 template <typename DestT, typename T>
Offset(const T * ptr,size_t bytes)466 ANGLE_INLINE const DestT *Offset(const T *ptr, size_t bytes)
467 {
468     return reinterpret_cast<const DestT *>((reinterpret_cast<const uint8_t *>(ptr) + bytes));
469 }
470 
471 class SecondaryCommandBuffer final : angle::NonCopyable
472 {
473   public:
474     SecondaryCommandBuffer();
475     ~SecondaryCommandBuffer();
476 
SupportsQueries(const VkPhysicalDeviceFeatures & features)477     static bool SupportsQueries(const VkPhysicalDeviceFeatures &features) { return true; }
478 
479     // SecondaryCommandBuffer replays its commands inline when executed on the primary command
480     // buffer.
ExecutesInline()481     static constexpr bool ExecutesInline() { return true; }
482 
InitializeCommandPool(Context * context,CommandPool * pool,uint32_t queueFamilyIndex,bool hasProtectedContent)483     static angle::Result InitializeCommandPool(Context *context,
484                                                CommandPool *pool,
485                                                uint32_t queueFamilyIndex,
486                                                bool hasProtectedContent)
487     {
488         return angle::Result::Continue;
489     }
InitializeRenderPassInheritanceInfo(ContextVk * contextVk,const Framebuffer & framebuffer,const RenderPassDesc & renderPassDesc,VkCommandBufferInheritanceInfo * inheritanceInfoOut)490     static angle::Result InitializeRenderPassInheritanceInfo(
491         ContextVk *contextVk,
492         const Framebuffer &framebuffer,
493         const RenderPassDesc &renderPassDesc,
494         VkCommandBufferInheritanceInfo *inheritanceInfoOut)
495     {
496         return angle::Result::Continue;
497     }
498 
499     // Add commands
500     void beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label);
501 
502     void beginQuery(const QueryPool &queryPool, uint32_t query, VkQueryControlFlags flags);
503 
504     void beginTransformFeedback(uint32_t firstCounterBuffer,
505                                 uint32_t bufferCount,
506                                 const VkBuffer *counterBuffers,
507                                 const VkDeviceSize *counterBufferOffsets);
508 
509     void bindComputePipeline(const Pipeline &pipeline);
510 
511     void bindDescriptorSets(const PipelineLayout &layout,
512                             VkPipelineBindPoint pipelineBindPoint,
513                             DescriptorSetIndex firstSet,
514                             uint32_t descriptorSetCount,
515                             const VkDescriptorSet *descriptorSets,
516                             uint32_t dynamicOffsetCount,
517                             const uint32_t *dynamicOffsets);
518 
519     void bindGraphicsPipeline(const Pipeline &pipeline);
520 
521     void bindIndexBuffer(const Buffer &buffer, VkDeviceSize offset, VkIndexType indexType);
522 
523     void bindTransformFeedbackBuffers(uint32_t firstBinding,
524                                       uint32_t bindingCount,
525                                       const VkBuffer *buffers,
526                                       const VkDeviceSize *offsets,
527                                       const VkDeviceSize *sizes);
528 
529     void bindVertexBuffers(uint32_t firstBinding,
530                            uint32_t bindingCount,
531                            const VkBuffer *buffers,
532                            const VkDeviceSize *offsets);
533 
534     void blitImage(const Image &srcImage,
535                    VkImageLayout srcImageLayout,
536                    const Image &dstImage,
537                    VkImageLayout dstImageLayout,
538                    uint32_t regionCount,
539                    const VkImageBlit *regions,
540                    VkFilter filter);
541 
542     void bufferBarrier(VkPipelineStageFlags srcStageMask,
543                        VkPipelineStageFlags dstStageMask,
544                        const VkBufferMemoryBarrier *bufferMemoryBarrier);
545 
546     void clearAttachments(uint32_t attachmentCount,
547                           const VkClearAttachment *attachments,
548                           uint32_t rectCount,
549                           const VkClearRect *rects);
550 
551     void clearColorImage(const Image &image,
552                          VkImageLayout imageLayout,
553                          const VkClearColorValue &color,
554                          uint32_t rangeCount,
555                          const VkImageSubresourceRange *ranges);
556 
557     void clearDepthStencilImage(const Image &image,
558                                 VkImageLayout imageLayout,
559                                 const VkClearDepthStencilValue &depthStencil,
560                                 uint32_t rangeCount,
561                                 const VkImageSubresourceRange *ranges);
562 
563     void copyBuffer(const Buffer &srcBuffer,
564                     const Buffer &destBuffer,
565                     uint32_t regionCount,
566                     const VkBufferCopy *regions);
567 
568     void copyBufferToImage(VkBuffer srcBuffer,
569                            const Image &dstImage,
570                            VkImageLayout dstImageLayout,
571                            uint32_t regionCount,
572                            const VkBufferImageCopy *regions);
573 
574     void copyImage(const Image &srcImage,
575                    VkImageLayout srcImageLayout,
576                    const Image &dstImage,
577                    VkImageLayout dstImageLayout,
578                    uint32_t regionCount,
579                    const VkImageCopy *regions);
580 
581     void copyImageToBuffer(const Image &srcImage,
582                            VkImageLayout srcImageLayout,
583                            VkBuffer dstBuffer,
584                            uint32_t regionCount,
585                            const VkBufferImageCopy *regions);
586 
587     void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
588 
589     void dispatchIndirect(const Buffer &buffer, VkDeviceSize offset);
590 
591     void draw(uint32_t vertexCount, uint32_t firstVertex);
592 
593     void drawIndexed(uint32_t indexCount);
594     void drawIndexedBaseVertex(uint32_t indexCount, uint32_t vertexOffset);
595     void drawIndexedIndirect(const Buffer &buffer,
596                              VkDeviceSize offset,
597                              uint32_t drawCount,
598                              uint32_t stride);
599     void drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount);
600     void drawIndexedInstancedBaseVertex(uint32_t indexCount,
601                                         uint32_t instanceCount,
602                                         uint32_t vertexOffset);
603     void drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,
604                                                     uint32_t instanceCount,
605                                                     uint32_t firstIndex,
606                                                     int32_t vertexOffset,
607                                                     uint32_t firstInstance);
608 
609     void drawIndirect(const Buffer &buffer,
610                       VkDeviceSize offset,
611                       uint32_t drawCount,
612                       uint32_t stride);
613 
614     void drawInstanced(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex);
615     void drawInstancedBaseInstance(uint32_t vertexCount,
616                                    uint32_t instanceCount,
617                                    uint32_t firstVertex,
618                                    uint32_t firstInstance);
619 
620     void endDebugUtilsLabelEXT();
621 
622     void endQuery(const QueryPool &queryPool, uint32_t query);
623 
624     void endTransformFeedback(uint32_t firstCounterBuffer,
625                               uint32_t counterBufferCount,
626                               const VkBuffer *counterBuffers,
627                               const VkDeviceSize *counterBufferOffsets);
628 
629     void fillBuffer(const Buffer &dstBuffer,
630                     VkDeviceSize dstOffset,
631                     VkDeviceSize size,
632                     uint32_t data);
633 
634     void imageBarrier(VkPipelineStageFlags srcStageMask,
635                       VkPipelineStageFlags dstStageMask,
636                       const VkImageMemoryBarrier &imageMemoryBarrier);
637 
638     void insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label);
639 
640     void memoryBarrier(VkPipelineStageFlags srcStageMask,
641                        VkPipelineStageFlags dstStageMask,
642                        const VkMemoryBarrier *memoryBarrier);
643 
644     void nextSubpass(VkSubpassContents subpassContents);
645 
646     void pipelineBarrier(VkPipelineStageFlags srcStageMask,
647                          VkPipelineStageFlags dstStageMask,
648                          VkDependencyFlags dependencyFlags,
649                          uint32_t memoryBarrierCount,
650                          const VkMemoryBarrier *memoryBarriers,
651                          uint32_t bufferMemoryBarrierCount,
652                          const VkBufferMemoryBarrier *bufferMemoryBarriers,
653                          uint32_t imageMemoryBarrierCount,
654                          const VkImageMemoryBarrier *imageMemoryBarriers);
655 
656     void pushConstants(const PipelineLayout &layout,
657                        VkShaderStageFlags flag,
658                        uint32_t offset,
659                        uint32_t size,
660                        const void *data);
661 
662     void resetEvent(VkEvent event, VkPipelineStageFlags stageMask);
663 
664     void resetQueryPool(const QueryPool &queryPool, uint32_t firstQuery, uint32_t queryCount);
665 
666     void resolveImage(const Image &srcImage,
667                       VkImageLayout srcImageLayout,
668                       const Image &dstImage,
669                       VkImageLayout dstImageLayout,
670                       uint32_t regionCount,
671                       const VkImageResolve *regions);
672 
673     void setEvent(VkEvent event, VkPipelineStageFlags stageMask);
674 
675     void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *scissors);
676 
677     void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *viewports);
678 
679     void waitEvents(uint32_t eventCount,
680                     const VkEvent *events,
681                     VkPipelineStageFlags srcStageMask,
682                     VkPipelineStageFlags dstStageMask,
683                     uint32_t memoryBarrierCount,
684                     const VkMemoryBarrier *memoryBarriers,
685                     uint32_t bufferMemoryBarrierCount,
686                     const VkBufferMemoryBarrier *bufferMemoryBarriers,
687                     uint32_t imageMemoryBarrierCount,
688                     const VkImageMemoryBarrier *imageMemoryBarriers);
689 
690     void writeTimestamp(VkPipelineStageFlagBits pipelineStage,
691                         const QueryPool &queryPool,
692                         uint32_t query);
693 
694     // No-op for compatibility
end()695     VkResult end() { return VK_SUCCESS; }
696 
697     // Parse the cmds in this cmd buffer into given primary cmd buffer for execution
698     void executeCommands(PrimaryCommandBuffer *primary);
699 
700     // Calculate memory usage of this command buffer for diagnostics.
701     void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const;
702 
703     // Traverse the list of commands and build a summary for diagnostics.
704     std::string dumpCommands(const char *separator) const;
705 
706     // Pool Alloc uses 16kB pages w/ 16byte header = 16368bytes. To minimize waste
707     //  using a 16368/12 = 1364. Also better perf than 1024 due to fewer block allocations
708     static constexpr size_t kBlockSize = 1364;
709     // Make sure block size is 4-byte aligned to avoid Android errors
710     static_assert((kBlockSize % 4) == 0, "Check kBlockSize alignment");
711 
712     // Initialize the SecondaryCommandBuffer by setting the allocator it will use
initialize(vk::Context * context,vk::CommandPool * pool,bool isRenderPassCommandBuffer,angle::PoolAllocator * allocator)713     angle::Result initialize(vk::Context *context,
714                              vk::CommandPool *pool,
715                              bool isRenderPassCommandBuffer,
716                              angle::PoolAllocator *allocator)
717     {
718         ASSERT(allocator);
719         ASSERT(mCommands.empty());
720         mAllocator = allocator;
721         allocateNewBlock();
722         // Set first command to Invalid to start
723         reinterpret_cast<CommandHeader *>(mCurrentWritePointer)->id = CommandID::Invalid;
724 
725         return angle::Result::Continue;
726     }
727 
begin(Context * context,const VkCommandBufferInheritanceInfo & inheritanceInfo)728     angle::Result begin(Context *context, const VkCommandBufferInheritanceInfo &inheritanceInfo)
729     {
730         return angle::Result::Continue;
731     }
end(Context * context)732     angle::Result end(Context *context) { return angle::Result::Continue; }
733 
open()734     void open() { mIsOpen = true; }
close()735     void close() { mIsOpen = false; }
736 
reset()737     void reset()
738     {
739         mCommands.clear();
740         mCurrentWritePointer   = nullptr;
741         mCurrentBytesRemaining = 0;
742         mCommandTracker.reset();
743     }
744 
745     // This will cause the SecondaryCommandBuffer to become invalid by clearing its allocator
releaseHandle()746     void releaseHandle() { mAllocator = nullptr; }
747     // The SecondaryCommandBuffer is valid if it's been initialized
valid()748     bool valid() const { return mAllocator != nullptr; }
749 
empty()750     bool empty() const { return mCommands.size() == 0 || mCommands[0]->id == CommandID::Invalid; }
getRenderPassWriteCommandCount()751     uint32_t getRenderPassWriteCommandCount() const
752     {
753         return mCommandTracker.getRenderPassWriteCommandCount();
754     }
755 
756   private:
757     void commonDebugUtilsLabel(CommandID cmd, const VkDebugUtilsLabelEXT &label);
758     template <class StructType>
commonInit(CommandID cmdID,size_t allocationSize)759     ANGLE_INLINE StructType *commonInit(CommandID cmdID, size_t allocationSize)
760     {
761         ASSERT(mIsOpen);
762         mCurrentBytesRemaining -= allocationSize;
763 
764         CommandHeader *header = reinterpret_cast<CommandHeader *>(mCurrentWritePointer);
765         header->id            = cmdID;
766         header->size          = static_cast<uint16_t>(allocationSize);
767         ASSERT(allocationSize <= std::numeric_limits<uint16_t>::max());
768 
769         mCurrentWritePointer += allocationSize;
770         // Set next cmd header to Invalid (0) so cmd sequence will be terminated
771         reinterpret_cast<CommandHeader *>(mCurrentWritePointer)->id = CommandID::Invalid;
772         return Offset<StructType>(header, sizeof(CommandHeader));
773     }
774     ANGLE_INLINE void allocateNewBlock(size_t blockSize = kBlockSize)
775     {
776         ASSERT(mAllocator);
777         mCurrentWritePointer   = mAllocator->fastAllocate(blockSize);
778         mCurrentBytesRemaining = blockSize;
779         mCommands.push_back(reinterpret_cast<CommandHeader *>(mCurrentWritePointer));
780     }
781 
782     // Allocate and initialize memory for given commandID & variable param size, setting
783     // variableDataPtr to the byte following fixed cmd data where variable-sized ptr data will
784     // be written and returning a pointer to the start of the command's parameter data
785     template <class StructType>
initCommand(CommandID cmdID,size_t variableSize,uint8_t ** variableDataPtr)786     ANGLE_INLINE StructType *initCommand(CommandID cmdID,
787                                          size_t variableSize,
788                                          uint8_t **variableDataPtr)
789     {
790         constexpr size_t fixedAllocationSize = sizeof(StructType) + sizeof(CommandHeader);
791         const size_t allocationSize          = fixedAllocationSize + variableSize;
792         // Make sure we have enough room to mark follow-on header "Invalid"
793         const size_t requiredSize = allocationSize + sizeof(CommandHeader);
794         if (mCurrentBytesRemaining < requiredSize)
795         {
796             // variable size command can potentially exceed default cmd allocation blockSize
797             if (requiredSize <= kBlockSize)
798                 allocateNewBlock();
799             else
800             {
801                 // Make sure allocation is 4-byte aligned
802                 const size_t alignedSize = roundUpPow2<size_t>(requiredSize, 4);
803                 ASSERT((alignedSize % 4) == 0);
804                 allocateNewBlock(alignedSize);
805             }
806         }
807         *variableDataPtr = Offset<uint8_t>(mCurrentWritePointer, fixedAllocationSize);
808         return commonInit<StructType>(cmdID, allocationSize);
809     }
810 
811     // Initialize a command that doesn't have variable-sized ptr data
812     template <class StructType>
initCommand(CommandID cmdID)813     ANGLE_INLINE StructType *initCommand(CommandID cmdID)
814     {
815         constexpr size_t paramSize =
816             std::is_same<StructType, EmptyParams>::value ? 0 : sizeof(StructType);
817         constexpr size_t allocationSize = paramSize + sizeof(CommandHeader);
818         // Make sure we have enough room to mark follow-on header "Invalid"
819         if (mCurrentBytesRemaining < (allocationSize + sizeof(CommandHeader)))
820         {
821             ASSERT((allocationSize + sizeof(CommandHeader)) < kBlockSize);
822             allocateNewBlock();
823         }
824         return commonInit<StructType>(cmdID, allocationSize);
825     }
826 
827     // Return a ptr to the parameter type
828     template <class StructType>
getParamPtr(const CommandHeader * header)829     const StructType *getParamPtr(const CommandHeader *header) const
830     {
831         return reinterpret_cast<const StructType *>(reinterpret_cast<const uint8_t *>(header) +
832                                                     sizeof(CommandHeader));
833     }
834     // Copy sizeInBytes data from paramData to writePointer & return writePointer plus sizeInBytes.
835     template <class PtrType>
storePointerParameter(uint8_t * writePointer,const PtrType * paramData,size_t sizeInBytes)836     ANGLE_INLINE uint8_t *storePointerParameter(uint8_t *writePointer,
837                                                 const PtrType *paramData,
838                                                 size_t sizeInBytes)
839     {
840         memcpy(writePointer, paramData, sizeInBytes);
841         return writePointer + sizeInBytes;
842     }
843 
844     // Flag to indicate that commandBuffer is open for new commands. Initially open.
845     bool mIsOpen;
846 
847     std::vector<CommandHeader *> mCommands;
848 
849     // Allocator used by this class. If non-null then the class is valid.
850     angle::PoolAllocator *mAllocator;
851 
852     uint8_t *mCurrentWritePointer;
853     size_t mCurrentBytesRemaining;
854 
855     CommandBufferCommandTracker mCommandTracker;
856 };
857 
SecondaryCommandBuffer()858 ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer()
859     : mIsOpen(true), mAllocator(nullptr), mCurrentWritePointer(nullptr), mCurrentBytesRemaining(0)
860 {}
861 
~SecondaryCommandBuffer()862 ANGLE_INLINE SecondaryCommandBuffer::~SecondaryCommandBuffer() {}
863 
864 // begin and insert DebugUtilsLabelEXT funcs share this same function body
commonDebugUtilsLabel(CommandID cmd,const VkDebugUtilsLabelEXT & label)865 ANGLE_INLINE void SecondaryCommandBuffer::commonDebugUtilsLabel(CommandID cmd,
866                                                                 const VkDebugUtilsLabelEXT &label)
867 {
868     uint8_t *writePtr;
869     const size_t stringSize        = strlen(label.pLabelName) + 1;
870     const size_t alignedStringSize = roundUpPow2<size_t>(stringSize, 4);
871     DebugUtilsLabelParams *paramStruct =
872         initCommand<DebugUtilsLabelParams>(cmd, alignedStringSize, &writePtr);
873     paramStruct->color[0] = label.color[0];
874     paramStruct->color[1] = label.color[1];
875     paramStruct->color[2] = label.color[2];
876     paramStruct->color[3] = label.color[3];
877     storePointerParameter(writePtr, label.pLabelName, stringSize);
878 }
879 
beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT & label)880 ANGLE_INLINE void SecondaryCommandBuffer::beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label)
881 {
882     commonDebugUtilsLabel(CommandID::BeginDebugUtilsLabel, label);
883 }
884 
beginQuery(const QueryPool & queryPool,uint32_t query,VkQueryControlFlags flags)885 ANGLE_INLINE void SecondaryCommandBuffer::beginQuery(const QueryPool &queryPool,
886                                                      uint32_t query,
887                                                      VkQueryControlFlags flags)
888 {
889     BeginQueryParams *paramStruct = initCommand<BeginQueryParams>(CommandID::BeginQuery);
890     paramStruct->queryPool        = queryPool.getHandle();
891     paramStruct->query            = query;
892     paramStruct->flags            = flags;
893 }
894 
beginTransformFeedback(uint32_t firstCounterBuffer,uint32_t bufferCount,const VkBuffer * counterBuffers,const VkDeviceSize * counterBufferOffsets)895 ANGLE_INLINE void SecondaryCommandBuffer::beginTransformFeedback(
896     uint32_t firstCounterBuffer,
897     uint32_t bufferCount,
898     const VkBuffer *counterBuffers,
899     const VkDeviceSize *counterBufferOffsets)
900 {
901     ASSERT(firstCounterBuffer == 0);
902     ASSERT(counterBufferOffsets == nullptr);
903     uint8_t *writePtr;
904     size_t bufferSize                         = bufferCount * sizeof(VkBuffer);
905     BeginTransformFeedbackParams *paramStruct = initCommand<BeginTransformFeedbackParams>(
906         CommandID::BeginTransformFeedback, bufferSize, &writePtr);
907     paramStruct->bufferCount = bufferCount;
908     storePointerParameter(writePtr, counterBuffers, bufferSize);
909 }
910 
bindComputePipeline(const Pipeline & pipeline)911 ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pipeline)
912 {
913     BindPipelineParams *paramStruct =
914         initCommand<BindPipelineParams>(CommandID::BindComputePipeline);
915     paramStruct->pipeline = pipeline.getHandle();
916 }
917 
bindDescriptorSets(const PipelineLayout & layout,VkPipelineBindPoint pipelineBindPoint,DescriptorSetIndex firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * descriptorSets,uint32_t dynamicOffsetCount,const uint32_t * dynamicOffsets)918 ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
919                                                              VkPipelineBindPoint pipelineBindPoint,
920                                                              DescriptorSetIndex firstSet,
921                                                              uint32_t descriptorSetCount,
922                                                              const VkDescriptorSet *descriptorSets,
923                                                              uint32_t dynamicOffsetCount,
924                                                              const uint32_t *dynamicOffsets)
925 {
926     size_t descSize   = descriptorSetCount * sizeof(VkDescriptorSet);
927     size_t offsetSize = dynamicOffsetCount * sizeof(uint32_t);
928     uint8_t *writePtr;
929     BindDescriptorSetParams *paramStruct = initCommand<BindDescriptorSetParams>(
930         CommandID::BindDescriptorSets, descSize + offsetSize, &writePtr);
931     // Copy params into memory
932     paramStruct->layout             = layout.getHandle();
933     paramStruct->pipelineBindPoint  = pipelineBindPoint;
934     paramStruct->firstSet           = ToUnderlying(firstSet);
935     paramStruct->descriptorSetCount = descriptorSetCount;
936     paramStruct->dynamicOffsetCount = dynamicOffsetCount;
937     // Copy variable sized data
938     writePtr = storePointerParameter(writePtr, descriptorSets, descSize);
939     storePointerParameter(writePtr, dynamicOffsets, offsetSize);
940 }
941 
bindGraphicsPipeline(const Pipeline & pipeline)942 ANGLE_INLINE void SecondaryCommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
943 {
944     BindPipelineParams *paramStruct =
945         initCommand<BindPipelineParams>(CommandID::BindGraphicsPipeline);
946     paramStruct->pipeline = pipeline.getHandle();
947 }
948 
bindIndexBuffer(const Buffer & buffer,VkDeviceSize offset,VkIndexType indexType)949 ANGLE_INLINE void SecondaryCommandBuffer::bindIndexBuffer(const Buffer &buffer,
950                                                           VkDeviceSize offset,
951                                                           VkIndexType indexType)
952 {
953     BindIndexBufferParams *paramStruct =
954         initCommand<BindIndexBufferParams>(CommandID::BindIndexBuffer);
955     paramStruct->buffer    = buffer.getHandle();
956     paramStruct->offset    = offset;
957     paramStruct->indexType = indexType;
958 }
959 
bindTransformFeedbackBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets,const VkDeviceSize * sizes)960 ANGLE_INLINE void SecondaryCommandBuffer::bindTransformFeedbackBuffers(uint32_t firstBinding,
961                                                                        uint32_t bindingCount,
962                                                                        const VkBuffer *buffers,
963                                                                        const VkDeviceSize *offsets,
964                                                                        const VkDeviceSize *sizes)
965 {
966     ASSERT(firstBinding == 0);
967     uint8_t *writePtr;
968     size_t buffersSize = bindingCount * sizeof(VkBuffer);
969     size_t offsetsSize = bindingCount * sizeof(VkDeviceSize);
970     size_t sizesSize   = offsetsSize;
971     BindTransformFeedbackBuffersParams *paramStruct =
972         initCommand<BindTransformFeedbackBuffersParams>(CommandID::BindTransformFeedbackBuffers,
973                                                         buffersSize + offsetsSize + sizesSize,
974                                                         &writePtr);
975     // Copy params
976     paramStruct->bindingCount = bindingCount;
977     writePtr                  = storePointerParameter(writePtr, buffers, buffersSize);
978     writePtr                  = storePointerParameter(writePtr, offsets, offsetsSize);
979     storePointerParameter(writePtr, sizes, sizesSize);
980 }
981 
bindVertexBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets)982 ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers(uint32_t firstBinding,
983                                                             uint32_t bindingCount,
984                                                             const VkBuffer *buffers,
985                                                             const VkDeviceSize *offsets)
986 {
987     ASSERT(firstBinding == 0);
988     uint8_t *writePtr;
989     size_t buffersSize                   = bindingCount * sizeof(VkBuffer);
990     size_t offsetsSize                   = bindingCount * sizeof(VkDeviceSize);
991     BindVertexBuffersParams *paramStruct = initCommand<BindVertexBuffersParams>(
992         CommandID::BindVertexBuffers, buffersSize + offsetsSize, &writePtr);
993     // Copy params
994     paramStruct->bindingCount = bindingCount;
995     writePtr                  = storePointerParameter(writePtr, buffers, buffersSize);
996     storePointerParameter(writePtr, offsets, offsetsSize);
997 }
998 
blitImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * regions,VkFilter filter)999 ANGLE_INLINE void SecondaryCommandBuffer::blitImage(const Image &srcImage,
1000                                                     VkImageLayout srcImageLayout,
1001                                                     const Image &dstImage,
1002                                                     VkImageLayout dstImageLayout,
1003                                                     uint32_t regionCount,
1004                                                     const VkImageBlit *regions,
1005                                                     VkFilter filter)
1006 {
1007     // Currently ANGLE uses limited params so verify those assumptions and update if they change
1008     ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1009     ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1010     ASSERT(regionCount == 1);
1011     BlitImageParams *paramStruct = initCommand<BlitImageParams>(CommandID::BlitImage);
1012     paramStruct->srcImage        = srcImage.getHandle();
1013     paramStruct->dstImage        = dstImage.getHandle();
1014     paramStruct->filter          = filter;
1015     paramStruct->region          = regions[0];
1016 }
1017 
bufferBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkBufferMemoryBarrier * bufferMemoryBarrier)1018 ANGLE_INLINE void SecondaryCommandBuffer::bufferBarrier(
1019     VkPipelineStageFlags srcStageMask,
1020     VkPipelineStageFlags dstStageMask,
1021     const VkBufferMemoryBarrier *bufferMemoryBarrier)
1022 {
1023     BufferBarrierParams *paramStruct = initCommand<BufferBarrierParams>(CommandID::BufferBarrier);
1024     paramStruct->srcStageMask        = srcStageMask;
1025     paramStruct->dstStageMask        = dstStageMask;
1026     paramStruct->bufferMemoryBarrier = *bufferMemoryBarrier;
1027 }
1028 
clearAttachments(uint32_t attachmentCount,const VkClearAttachment * attachments,uint32_t rectCount,const VkClearRect * rects)1029 ANGLE_INLINE void SecondaryCommandBuffer::clearAttachments(uint32_t attachmentCount,
1030                                                            const VkClearAttachment *attachments,
1031                                                            uint32_t rectCount,
1032                                                            const VkClearRect *rects)
1033 {
1034     ASSERT(rectCount == 1);
1035     uint8_t *writePtr;
1036     size_t attachSize = attachmentCount * sizeof(VkClearAttachment);
1037     ClearAttachmentsParams *paramStruct =
1038         initCommand<ClearAttachmentsParams>(CommandID::ClearAttachments, attachSize, &writePtr);
1039     paramStruct->attachmentCount = attachmentCount;
1040     paramStruct->rect            = rects[0];
1041     // Copy variable sized data
1042     storePointerParameter(writePtr, attachments, attachSize);
1043 
1044     mCommandTracker.onClearAttachments();
1045 }
1046 
clearColorImage(const Image & image,VkImageLayout imageLayout,const VkClearColorValue & color,uint32_t rangeCount,const VkImageSubresourceRange * ranges)1047 ANGLE_INLINE void SecondaryCommandBuffer::clearColorImage(const Image &image,
1048                                                           VkImageLayout imageLayout,
1049                                                           const VkClearColorValue &color,
1050                                                           uint32_t rangeCount,
1051                                                           const VkImageSubresourceRange *ranges)
1052 {
1053     ASSERT(rangeCount == 1);
1054     ClearColorImageParams *paramStruct =
1055         initCommand<ClearColorImageParams>(CommandID::ClearColorImage);
1056     paramStruct->image       = image.getHandle();
1057     paramStruct->imageLayout = imageLayout;
1058     paramStruct->color       = color;
1059     paramStruct->range       = ranges[0];
1060 }
1061 
clearDepthStencilImage(const Image & image,VkImageLayout imageLayout,const VkClearDepthStencilValue & depthStencil,uint32_t rangeCount,const VkImageSubresourceRange * ranges)1062 ANGLE_INLINE void SecondaryCommandBuffer::clearDepthStencilImage(
1063     const Image &image,
1064     VkImageLayout imageLayout,
1065     const VkClearDepthStencilValue &depthStencil,
1066     uint32_t rangeCount,
1067     const VkImageSubresourceRange *ranges)
1068 {
1069     ASSERT(rangeCount == 1);
1070     ClearDepthStencilImageParams *paramStruct =
1071         initCommand<ClearDepthStencilImageParams>(CommandID::ClearDepthStencilImage);
1072     paramStruct->image        = image.getHandle();
1073     paramStruct->imageLayout  = imageLayout;
1074     paramStruct->depthStencil = depthStencil;
1075     paramStruct->range        = ranges[0];
1076 }
1077 
copyBuffer(const Buffer & srcBuffer,const Buffer & destBuffer,uint32_t regionCount,const VkBufferCopy * regions)1078 ANGLE_INLINE void SecondaryCommandBuffer::copyBuffer(const Buffer &srcBuffer,
1079                                                      const Buffer &destBuffer,
1080                                                      uint32_t regionCount,
1081                                                      const VkBufferCopy *regions)
1082 {
1083     uint8_t *writePtr;
1084     size_t regionSize = regionCount * sizeof(VkBufferCopy);
1085     CopyBufferParams *paramStruct =
1086         initCommand<CopyBufferParams>(CommandID::CopyBuffer, regionSize, &writePtr);
1087     paramStruct->srcBuffer   = srcBuffer.getHandle();
1088     paramStruct->destBuffer  = destBuffer.getHandle();
1089     paramStruct->regionCount = regionCount;
1090     // Copy variable sized data
1091     storePointerParameter(writePtr, regions, regionSize);
1092 }
1093 
copyBufferToImage(VkBuffer srcBuffer,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * regions)1094 ANGLE_INLINE void SecondaryCommandBuffer::copyBufferToImage(VkBuffer srcBuffer,
1095                                                             const Image &dstImage,
1096                                                             VkImageLayout dstImageLayout,
1097                                                             uint32_t regionCount,
1098                                                             const VkBufferImageCopy *regions)
1099 {
1100     ASSERT(regionCount == 1);
1101     CopyBufferToImageParams *paramStruct =
1102         initCommand<CopyBufferToImageParams>(CommandID::CopyBufferToImage);
1103     paramStruct->srcBuffer      = srcBuffer;
1104     paramStruct->dstImage       = dstImage.getHandle();
1105     paramStruct->dstImageLayout = dstImageLayout;
1106     paramStruct->region         = regions[0];
1107 }
1108 
copyImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * regions)1109 ANGLE_INLINE void SecondaryCommandBuffer::copyImage(const Image &srcImage,
1110                                                     VkImageLayout srcImageLayout,
1111                                                     const Image &dstImage,
1112                                                     VkImageLayout dstImageLayout,
1113                                                     uint32_t regionCount,
1114                                                     const VkImageCopy *regions)
1115 {
1116     ASSERT(regionCount == 1);
1117     CopyImageParams *paramStruct = initCommand<CopyImageParams>(CommandID::CopyImage);
1118     paramStruct->srcImage        = srcImage.getHandle();
1119     paramStruct->srcImageLayout  = srcImageLayout;
1120     paramStruct->dstImage        = dstImage.getHandle();
1121     paramStruct->dstImageLayout  = dstImageLayout;
1122     paramStruct->region          = regions[0];
1123 }
1124 
copyImageToBuffer(const Image & srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * regions)1125 ANGLE_INLINE void SecondaryCommandBuffer::copyImageToBuffer(const Image &srcImage,
1126                                                             VkImageLayout srcImageLayout,
1127                                                             VkBuffer dstBuffer,
1128                                                             uint32_t regionCount,
1129                                                             const VkBufferImageCopy *regions)
1130 {
1131     ASSERT(regionCount == 1);
1132     CopyImageToBufferParams *paramStruct =
1133         initCommand<CopyImageToBufferParams>(CommandID::CopyImageToBuffer);
1134     paramStruct->srcImage       = srcImage.getHandle();
1135     paramStruct->srcImageLayout = srcImageLayout;
1136     paramStruct->dstBuffer      = dstBuffer;
1137     paramStruct->region         = regions[0];
1138 }
1139 
dispatch(uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)1140 ANGLE_INLINE void SecondaryCommandBuffer::dispatch(uint32_t groupCountX,
1141                                                    uint32_t groupCountY,
1142                                                    uint32_t groupCountZ)
1143 {
1144     DispatchParams *paramStruct = initCommand<DispatchParams>(CommandID::Dispatch);
1145     paramStruct->groupCountX    = groupCountX;
1146     paramStruct->groupCountY    = groupCountY;
1147     paramStruct->groupCountZ    = groupCountZ;
1148 }
1149 
dispatchIndirect(const Buffer & buffer,VkDeviceSize offset)1150 ANGLE_INLINE void SecondaryCommandBuffer::dispatchIndirect(const Buffer &buffer,
1151                                                            VkDeviceSize offset)
1152 {
1153     DispatchIndirectParams *paramStruct =
1154         initCommand<DispatchIndirectParams>(CommandID::DispatchIndirect);
1155     paramStruct->buffer = buffer.getHandle();
1156     paramStruct->offset = offset;
1157 }
1158 
draw(uint32_t vertexCount,uint32_t firstVertex)1159 ANGLE_INLINE void SecondaryCommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
1160 {
1161     DrawParams *paramStruct  = initCommand<DrawParams>(CommandID::Draw);
1162     paramStruct->vertexCount = vertexCount;
1163     paramStruct->firstVertex = firstVertex;
1164 
1165     mCommandTracker.onDraw();
1166 }
1167 
drawIndexed(uint32_t indexCount)1168 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount)
1169 {
1170     DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed);
1171     paramStruct->indexCount        = indexCount;
1172 
1173     mCommandTracker.onDraw();
1174 }
1175 
drawIndexedBaseVertex(uint32_t indexCount,uint32_t vertexOffset)1176 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedBaseVertex(uint32_t indexCount,
1177                                                                 uint32_t vertexOffset)
1178 {
1179     DrawIndexedBaseVertexParams *paramStruct =
1180         initCommand<DrawIndexedBaseVertexParams>(CommandID::DrawIndexedBaseVertex);
1181     paramStruct->indexCount   = indexCount;
1182     paramStruct->vertexOffset = vertexOffset;
1183 
1184     mCommandTracker.onDraw();
1185 }
1186 
drawIndexedIndirect(const Buffer & buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1187 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedIndirect(const Buffer &buffer,
1188                                                               VkDeviceSize offset,
1189                                                               uint32_t drawCount,
1190                                                               uint32_t stride)
1191 {
1192     DrawIndexedIndirectParams *paramStruct =
1193         initCommand<DrawIndexedIndirectParams>(CommandID::DrawIndexedIndirect);
1194     paramStruct->buffer    = buffer.getHandle();
1195     paramStruct->offset    = offset;
1196     paramStruct->drawCount = drawCount;
1197     paramStruct->stride    = stride;
1198 
1199     mCommandTracker.onDraw();
1200 }
1201 
drawIndexedInstanced(uint32_t indexCount,uint32_t instanceCount)1202 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstanced(uint32_t indexCount,
1203                                                                uint32_t instanceCount)
1204 {
1205     DrawIndexedInstancedParams *paramStruct =
1206         initCommand<DrawIndexedInstancedParams>(CommandID::DrawIndexedInstanced);
1207     paramStruct->indexCount    = indexCount;
1208     paramStruct->instanceCount = instanceCount;
1209 
1210     mCommandTracker.onDraw();
1211 }
1212 
drawIndexedInstancedBaseVertex(uint32_t indexCount,uint32_t instanceCount,uint32_t vertexOffset)1213 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertex(uint32_t indexCount,
1214                                                                          uint32_t instanceCount,
1215                                                                          uint32_t vertexOffset)
1216 {
1217     DrawIndexedInstancedBaseVertexParams *paramStruct =
1218         initCommand<DrawIndexedInstancedBaseVertexParams>(
1219             CommandID::DrawIndexedInstancedBaseVertex);
1220     paramStruct->indexCount    = indexCount;
1221     paramStruct->instanceCount = instanceCount;
1222     paramStruct->vertexOffset  = vertexOffset;
1223 
1224     mCommandTracker.onDraw();
1225 }
1226 
drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,uint32_t instanceCount,uint32_t firstIndex,int32_t vertexOffset,uint32_t firstInstance)1227 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertexBaseInstance(
1228     uint32_t indexCount,
1229     uint32_t instanceCount,
1230     uint32_t firstIndex,
1231     int32_t vertexOffset,
1232     uint32_t firstInstance)
1233 {
1234     DrawIndexedInstancedBaseVertexBaseInstanceParams *paramStruct =
1235         initCommand<DrawIndexedInstancedBaseVertexBaseInstanceParams>(
1236             CommandID::DrawIndexedInstancedBaseVertexBaseInstance);
1237     paramStruct->indexCount    = indexCount;
1238     paramStruct->instanceCount = instanceCount;
1239     paramStruct->firstIndex    = firstIndex;
1240     paramStruct->vertexOffset  = vertexOffset;
1241     paramStruct->firstInstance = firstInstance;
1242 
1243     mCommandTracker.onDraw();
1244 }
1245 
drawIndirect(const Buffer & buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1246 ANGLE_INLINE void SecondaryCommandBuffer::drawIndirect(const Buffer &buffer,
1247                                                        VkDeviceSize offset,
1248                                                        uint32_t drawCount,
1249                                                        uint32_t stride)
1250 {
1251     DrawIndirectParams *paramStruct = initCommand<DrawIndirectParams>(CommandID::DrawIndirect);
1252     paramStruct->buffer             = buffer.getHandle();
1253     paramStruct->offset             = offset;
1254     paramStruct->drawCount          = drawCount;
1255     paramStruct->stride             = stride;
1256 
1257     mCommandTracker.onDraw();
1258 }
1259 
drawInstanced(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex)1260 ANGLE_INLINE void SecondaryCommandBuffer::drawInstanced(uint32_t vertexCount,
1261                                                         uint32_t instanceCount,
1262                                                         uint32_t firstVertex)
1263 {
1264     DrawInstancedParams *paramStruct = initCommand<DrawInstancedParams>(CommandID::DrawInstanced);
1265     paramStruct->vertexCount         = vertexCount;
1266     paramStruct->instanceCount       = instanceCount;
1267     paramStruct->firstVertex         = firstVertex;
1268 
1269     mCommandTracker.onDraw();
1270 }
1271 
drawInstancedBaseInstance(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)1272 ANGLE_INLINE void SecondaryCommandBuffer::drawInstancedBaseInstance(uint32_t vertexCount,
1273                                                                     uint32_t instanceCount,
1274                                                                     uint32_t firstVertex,
1275                                                                     uint32_t firstInstance)
1276 {
1277     DrawInstancedBaseInstanceParams *paramStruct =
1278         initCommand<DrawInstancedBaseInstanceParams>(CommandID::DrawInstancedBaseInstance);
1279     paramStruct->vertexCount   = vertexCount;
1280     paramStruct->instanceCount = instanceCount;
1281     paramStruct->firstVertex   = firstVertex;
1282     paramStruct->firstInstance = firstInstance;
1283 
1284     mCommandTracker.onDraw();
1285 }
1286 
endDebugUtilsLabelEXT()1287 ANGLE_INLINE void SecondaryCommandBuffer::endDebugUtilsLabelEXT()
1288 {
1289     initCommand<EmptyParams>(CommandID::EndDebugUtilsLabel);
1290 }
1291 
endQuery(const QueryPool & queryPool,uint32_t query)1292 ANGLE_INLINE void SecondaryCommandBuffer::endQuery(const QueryPool &queryPool, uint32_t query)
1293 {
1294     EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery);
1295     paramStruct->queryPool      = queryPool.getHandle();
1296     paramStruct->query          = query;
1297 }
1298 
endTransformFeedback(uint32_t firstCounterBuffer,uint32_t counterBufferCount,const VkBuffer * counterBuffers,const VkDeviceSize * counterBufferOffsets)1299 ANGLE_INLINE void SecondaryCommandBuffer::endTransformFeedback(
1300     uint32_t firstCounterBuffer,
1301     uint32_t counterBufferCount,
1302     const VkBuffer *counterBuffers,
1303     const VkDeviceSize *counterBufferOffsets)
1304 {
1305     ASSERT(firstCounterBuffer == 0);
1306     ASSERT(counterBufferOffsets == nullptr);
1307     uint8_t *writePtr;
1308     size_t bufferSize                       = counterBufferCount * sizeof(VkBuffer);
1309     EndTransformFeedbackParams *paramStruct = initCommand<EndTransformFeedbackParams>(
1310         CommandID::EndTransformFeedback, bufferSize, &writePtr);
1311     paramStruct->bufferCount = counterBufferCount;
1312     storePointerParameter(writePtr, counterBuffers, bufferSize);
1313 }
1314 
fillBuffer(const Buffer & dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)1315 ANGLE_INLINE void SecondaryCommandBuffer::fillBuffer(const Buffer &dstBuffer,
1316                                                      VkDeviceSize dstOffset,
1317                                                      VkDeviceSize size,
1318                                                      uint32_t data)
1319 {
1320     FillBufferParams *paramStruct = initCommand<FillBufferParams>(CommandID::FillBuffer);
1321     paramStruct->dstBuffer        = dstBuffer.getHandle();
1322     paramStruct->dstOffset        = dstOffset;
1323     paramStruct->size             = size;
1324     paramStruct->data             = data;
1325 }
1326 
imageBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkImageMemoryBarrier & imageMemoryBarrier)1327 ANGLE_INLINE void SecondaryCommandBuffer::imageBarrier(
1328     VkPipelineStageFlags srcStageMask,
1329     VkPipelineStageFlags dstStageMask,
1330     const VkImageMemoryBarrier &imageMemoryBarrier)
1331 {
1332     ImageBarrierParams *paramStruct = initCommand<ImageBarrierParams>(CommandID::ImageBarrier);
1333     ASSERT(imageMemoryBarrier.pNext == nullptr);
1334     paramStruct->srcStageMask       = srcStageMask;
1335     paramStruct->dstStageMask       = dstStageMask;
1336     paramStruct->imageMemoryBarrier = imageMemoryBarrier;
1337 }
1338 
insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT & label)1339 ANGLE_INLINE void SecondaryCommandBuffer::insertDebugUtilsLabelEXT(
1340     const VkDebugUtilsLabelEXT &label)
1341 {
1342     commonDebugUtilsLabel(CommandID::InsertDebugUtilsLabel, label);
1343 }
1344 
memoryBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkMemoryBarrier * memoryBarrier)1345 ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask,
1346                                                         VkPipelineStageFlags dstStageMask,
1347                                                         const VkMemoryBarrier *memoryBarrier)
1348 {
1349     MemoryBarrierParams *paramStruct = initCommand<MemoryBarrierParams>(CommandID::MemoryBarrier);
1350     paramStruct->srcStageMask        = srcStageMask;
1351     paramStruct->dstStageMask        = dstStageMask;
1352     paramStruct->memoryBarrier       = *memoryBarrier;
1353 }
1354 
nextSubpass(VkSubpassContents subpassContents)1355 ANGLE_INLINE void SecondaryCommandBuffer::nextSubpass(VkSubpassContents subpassContents)
1356 {
1357     NextSubpassParams *paramStruct = initCommand<NextSubpassParams>(CommandID::NextSubpass);
1358     paramStruct->subpassContents   = subpassContents;
1359 }
1360 
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)1361 ANGLE_INLINE void SecondaryCommandBuffer::pipelineBarrier(
1362     VkPipelineStageFlags srcStageMask,
1363     VkPipelineStageFlags dstStageMask,
1364     VkDependencyFlags dependencyFlags,
1365     uint32_t memoryBarrierCount,
1366     const VkMemoryBarrier *memoryBarriers,
1367     uint32_t bufferMemoryBarrierCount,
1368     const VkBufferMemoryBarrier *bufferMemoryBarriers,
1369     uint32_t imageMemoryBarrierCount,
1370     const VkImageMemoryBarrier *imageMemoryBarriers)
1371 {
1372     uint8_t *writePtr;
1373     size_t memBarrierSize              = memoryBarrierCount * sizeof(VkMemoryBarrier);
1374     size_t buffBarrierSize             = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
1375     size_t imgBarrierSize              = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
1376     PipelineBarrierParams *paramStruct = initCommand<PipelineBarrierParams>(
1377         CommandID::PipelineBarrier, memBarrierSize + buffBarrierSize + imgBarrierSize, &writePtr);
1378     paramStruct->srcStageMask             = srcStageMask;
1379     paramStruct->dstStageMask             = dstStageMask;
1380     paramStruct->dependencyFlags          = dependencyFlags;
1381     paramStruct->memoryBarrierCount       = memoryBarrierCount;
1382     paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount;
1383     paramStruct->imageMemoryBarrierCount  = imageMemoryBarrierCount;
1384     // Copy variable sized data
1385     writePtr = storePointerParameter(writePtr, memoryBarriers, memBarrierSize);
1386     writePtr = storePointerParameter(writePtr, bufferMemoryBarriers, buffBarrierSize);
1387     storePointerParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
1388 }
1389 
pushConstants(const PipelineLayout & layout,VkShaderStageFlags flag,uint32_t offset,uint32_t size,const void * data)1390 ANGLE_INLINE void SecondaryCommandBuffer::pushConstants(const PipelineLayout &layout,
1391                                                         VkShaderStageFlags flag,
1392                                                         uint32_t offset,
1393                                                         uint32_t size,
1394                                                         const void *data)
1395 {
1396     ASSERT(size == static_cast<size_t>(size));
1397     uint8_t *writePtr;
1398     PushConstantsParams *paramStruct = initCommand<PushConstantsParams>(
1399         CommandID::PushConstants, static_cast<size_t>(size), &writePtr);
1400     paramStruct->layout = layout.getHandle();
1401     paramStruct->flag   = flag;
1402     paramStruct->offset = offset;
1403     paramStruct->size   = size;
1404     // Copy variable sized data
1405     storePointerParameter(writePtr, data, static_cast<size_t>(size));
1406 }
1407 
resetEvent(VkEvent event,VkPipelineStageFlags stageMask)1408 ANGLE_INLINE void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
1409 {
1410     ResetEventParams *paramStruct = initCommand<ResetEventParams>(CommandID::ResetEvent);
1411     paramStruct->event            = event;
1412     paramStruct->stageMask        = stageMask;
1413 }
1414 
resetQueryPool(const QueryPool & queryPool,uint32_t firstQuery,uint32_t queryCount)1415 ANGLE_INLINE void SecondaryCommandBuffer::resetQueryPool(const QueryPool &queryPool,
1416                                                          uint32_t firstQuery,
1417                                                          uint32_t queryCount)
1418 {
1419     ResetQueryPoolParams *paramStruct =
1420         initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool);
1421     paramStruct->queryPool  = queryPool.getHandle();
1422     paramStruct->firstQuery = firstQuery;
1423     paramStruct->queryCount = queryCount;
1424 }
1425 
resolveImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageResolve * regions)1426 ANGLE_INLINE void SecondaryCommandBuffer::resolveImage(const Image &srcImage,
1427                                                        VkImageLayout srcImageLayout,
1428                                                        const Image &dstImage,
1429                                                        VkImageLayout dstImageLayout,
1430                                                        uint32_t regionCount,
1431                                                        const VkImageResolve *regions)
1432 {
1433     // Currently ANGLE uses limited params so verify those assumptions and update if they change.
1434     ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1435     ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1436     ASSERT(regionCount == 1);
1437     ResolveImageParams *paramStruct = initCommand<ResolveImageParams>(CommandID::ResolveImage);
1438     paramStruct->srcImage           = srcImage.getHandle();
1439     paramStruct->dstImage           = dstImage.getHandle();
1440     paramStruct->region             = regions[0];
1441 }
1442 
setEvent(VkEvent event,VkPipelineStageFlags stageMask)1443 ANGLE_INLINE void SecondaryCommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
1444 {
1445     SetEventParams *paramStruct = initCommand<SetEventParams>(CommandID::SetEvent);
1446     paramStruct->event          = event;
1447     paramStruct->stageMask      = stageMask;
1448 }
1449 
setScissor(uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * scissors)1450 ANGLE_INLINE void SecondaryCommandBuffer::setScissor(uint32_t firstScissor,
1451                                                      uint32_t scissorCount,
1452                                                      const VkRect2D *scissors)
1453 {
1454     ASSERT(firstScissor == 0);
1455     ASSERT(scissorCount == 1);
1456     ASSERT(scissors != nullptr);
1457     SetScissorParams *paramStruct = initCommand<SetScissorParams>(CommandID::SetScissor);
1458     paramStruct->scissor          = scissors[0];
1459 }
1460 
setViewport(uint32_t firstViewport,uint32_t viewportCount,const VkViewport * viewports)1461 ANGLE_INLINE void SecondaryCommandBuffer::setViewport(uint32_t firstViewport,
1462                                                       uint32_t viewportCount,
1463                                                       const VkViewport *viewports)
1464 {
1465     ASSERT(firstViewport == 0);
1466     ASSERT(viewportCount == 1);
1467     ASSERT(viewports != nullptr);
1468     SetViewportParams *paramStruct = initCommand<SetViewportParams>(CommandID::SetViewport);
1469     paramStruct->viewport          = viewports[0];
1470 }
1471 
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)1472 ANGLE_INLINE void SecondaryCommandBuffer::waitEvents(
1473     uint32_t eventCount,
1474     const VkEvent *events,
1475     VkPipelineStageFlags srcStageMask,
1476     VkPipelineStageFlags dstStageMask,
1477     uint32_t memoryBarrierCount,
1478     const VkMemoryBarrier *memoryBarriers,
1479     uint32_t bufferMemoryBarrierCount,
1480     const VkBufferMemoryBarrier *bufferMemoryBarriers,
1481     uint32_t imageMemoryBarrierCount,
1482     const VkImageMemoryBarrier *imageMemoryBarriers)
1483 {
1484     uint8_t *writePtr;
1485     size_t eventSize              = eventCount * sizeof(VkEvent);
1486     size_t memBarrierSize         = memoryBarrierCount * sizeof(VkMemoryBarrier);
1487     size_t buffBarrierSize        = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
1488     size_t imgBarrierSize         = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
1489     WaitEventsParams *paramStruct = initCommand<WaitEventsParams>(
1490         CommandID::WaitEvents, eventSize + memBarrierSize + buffBarrierSize + imgBarrierSize,
1491         &writePtr);
1492     paramStruct->eventCount               = eventCount;
1493     paramStruct->srcStageMask             = srcStageMask;
1494     paramStruct->dstStageMask             = dstStageMask;
1495     paramStruct->memoryBarrierCount       = memoryBarrierCount;
1496     paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount;
1497     paramStruct->imageMemoryBarrierCount  = imageMemoryBarrierCount;
1498     // Copy variable sized data
1499     writePtr = storePointerParameter(writePtr, events, eventSize);
1500     writePtr = storePointerParameter(writePtr, memoryBarriers, memBarrierSize);
1501     writePtr = storePointerParameter(writePtr, bufferMemoryBarriers, buffBarrierSize);
1502     storePointerParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
1503 }
1504 
writeTimestamp(VkPipelineStageFlagBits pipelineStage,const QueryPool & queryPool,uint32_t query)1505 ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
1506                                                          const QueryPool &queryPool,
1507                                                          uint32_t query)
1508 {
1509     WriteTimestampParams *paramStruct =
1510         initCommand<WriteTimestampParams>(CommandID::WriteTimestamp);
1511     paramStruct->pipelineStage = pipelineStage;
1512     paramStruct->queryPool     = queryPool.getHandle();
1513     paramStruct->query         = query;
1514 }
1515 }  // namespace priv
1516 }  // namespace vk
1517 }  // namespace rx
1518 
1519 #endif  // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
1520