• 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     uint8_t *writePtr;
903     size_t bufferSize                         = bufferCount * sizeof(VkBuffer);
904     size_t offsetSize                         = bufferCount * sizeof(VkDeviceSize);
905     BeginTransformFeedbackParams *paramStruct = initCommand<BeginTransformFeedbackParams>(
906         CommandID::BeginTransformFeedback, bufferSize + offsetSize, &writePtr);
907     paramStruct->bufferCount = bufferCount;
908     writePtr                 = storePointerParameter(writePtr, counterBuffers, bufferSize);
909     storePointerParameter(writePtr, counterBufferOffsets, offsetSize);
910 }
911 
bindComputePipeline(const Pipeline & pipeline)912 ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pipeline)
913 {
914     BindPipelineParams *paramStruct =
915         initCommand<BindPipelineParams>(CommandID::BindComputePipeline);
916     paramStruct->pipeline = pipeline.getHandle();
917 }
918 
bindDescriptorSets(const PipelineLayout & layout,VkPipelineBindPoint pipelineBindPoint,DescriptorSetIndex firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * descriptorSets,uint32_t dynamicOffsetCount,const uint32_t * dynamicOffsets)919 ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
920                                                              VkPipelineBindPoint pipelineBindPoint,
921                                                              DescriptorSetIndex firstSet,
922                                                              uint32_t descriptorSetCount,
923                                                              const VkDescriptorSet *descriptorSets,
924                                                              uint32_t dynamicOffsetCount,
925                                                              const uint32_t *dynamicOffsets)
926 {
927     size_t descSize   = descriptorSetCount * sizeof(VkDescriptorSet);
928     size_t offsetSize = dynamicOffsetCount * sizeof(uint32_t);
929     uint8_t *writePtr;
930     BindDescriptorSetParams *paramStruct = initCommand<BindDescriptorSetParams>(
931         CommandID::BindDescriptorSets, descSize + offsetSize, &writePtr);
932     // Copy params into memory
933     paramStruct->layout             = layout.getHandle();
934     paramStruct->pipelineBindPoint  = pipelineBindPoint;
935     paramStruct->firstSet           = ToUnderlying(firstSet);
936     paramStruct->descriptorSetCount = descriptorSetCount;
937     paramStruct->dynamicOffsetCount = dynamicOffsetCount;
938     // Copy variable sized data
939     writePtr = storePointerParameter(writePtr, descriptorSets, descSize);
940     storePointerParameter(writePtr, dynamicOffsets, offsetSize);
941 }
942 
bindGraphicsPipeline(const Pipeline & pipeline)943 ANGLE_INLINE void SecondaryCommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
944 {
945     BindPipelineParams *paramStruct =
946         initCommand<BindPipelineParams>(CommandID::BindGraphicsPipeline);
947     paramStruct->pipeline = pipeline.getHandle();
948 }
949 
bindIndexBuffer(const Buffer & buffer,VkDeviceSize offset,VkIndexType indexType)950 ANGLE_INLINE void SecondaryCommandBuffer::bindIndexBuffer(const Buffer &buffer,
951                                                           VkDeviceSize offset,
952                                                           VkIndexType indexType)
953 {
954     BindIndexBufferParams *paramStruct =
955         initCommand<BindIndexBufferParams>(CommandID::BindIndexBuffer);
956     paramStruct->buffer    = buffer.getHandle();
957     paramStruct->offset    = offset;
958     paramStruct->indexType = indexType;
959 }
960 
bindTransformFeedbackBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets,const VkDeviceSize * sizes)961 ANGLE_INLINE void SecondaryCommandBuffer::bindTransformFeedbackBuffers(uint32_t firstBinding,
962                                                                        uint32_t bindingCount,
963                                                                        const VkBuffer *buffers,
964                                                                        const VkDeviceSize *offsets,
965                                                                        const VkDeviceSize *sizes)
966 {
967     ASSERT(firstBinding == 0);
968     uint8_t *writePtr;
969     size_t buffersSize = bindingCount * sizeof(VkBuffer);
970     size_t offsetsSize = bindingCount * sizeof(VkDeviceSize);
971     size_t sizesSize   = offsetsSize;
972     BindTransformFeedbackBuffersParams *paramStruct =
973         initCommand<BindTransformFeedbackBuffersParams>(CommandID::BindTransformFeedbackBuffers,
974                                                         buffersSize + offsetsSize + sizesSize,
975                                                         &writePtr);
976     // Copy params
977     paramStruct->bindingCount = bindingCount;
978     writePtr                  = storePointerParameter(writePtr, buffers, buffersSize);
979     writePtr                  = storePointerParameter(writePtr, offsets, offsetsSize);
980     storePointerParameter(writePtr, sizes, sizesSize);
981 }
982 
bindVertexBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets)983 ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers(uint32_t firstBinding,
984                                                             uint32_t bindingCount,
985                                                             const VkBuffer *buffers,
986                                                             const VkDeviceSize *offsets)
987 {
988     ASSERT(firstBinding == 0);
989     uint8_t *writePtr;
990     size_t buffersSize                   = bindingCount * sizeof(VkBuffer);
991     size_t offsetsSize                   = bindingCount * sizeof(VkDeviceSize);
992     BindVertexBuffersParams *paramStruct = initCommand<BindVertexBuffersParams>(
993         CommandID::BindVertexBuffers, buffersSize + offsetsSize, &writePtr);
994     // Copy params
995     paramStruct->bindingCount = bindingCount;
996     writePtr                  = storePointerParameter(writePtr, buffers, buffersSize);
997     storePointerParameter(writePtr, offsets, offsetsSize);
998 }
999 
blitImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * regions,VkFilter filter)1000 ANGLE_INLINE void SecondaryCommandBuffer::blitImage(const Image &srcImage,
1001                                                     VkImageLayout srcImageLayout,
1002                                                     const Image &dstImage,
1003                                                     VkImageLayout dstImageLayout,
1004                                                     uint32_t regionCount,
1005                                                     const VkImageBlit *regions,
1006                                                     VkFilter filter)
1007 {
1008     // Currently ANGLE uses limited params so verify those assumptions and update if they change
1009     ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1010     ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1011     ASSERT(regionCount == 1);
1012     BlitImageParams *paramStruct = initCommand<BlitImageParams>(CommandID::BlitImage);
1013     paramStruct->srcImage        = srcImage.getHandle();
1014     paramStruct->dstImage        = dstImage.getHandle();
1015     paramStruct->filter          = filter;
1016     paramStruct->region          = regions[0];
1017 }
1018 
bufferBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkBufferMemoryBarrier * bufferMemoryBarrier)1019 ANGLE_INLINE void SecondaryCommandBuffer::bufferBarrier(
1020     VkPipelineStageFlags srcStageMask,
1021     VkPipelineStageFlags dstStageMask,
1022     const VkBufferMemoryBarrier *bufferMemoryBarrier)
1023 {
1024     BufferBarrierParams *paramStruct = initCommand<BufferBarrierParams>(CommandID::BufferBarrier);
1025     paramStruct->srcStageMask        = srcStageMask;
1026     paramStruct->dstStageMask        = dstStageMask;
1027     paramStruct->bufferMemoryBarrier = *bufferMemoryBarrier;
1028 }
1029 
clearAttachments(uint32_t attachmentCount,const VkClearAttachment * attachments,uint32_t rectCount,const VkClearRect * rects)1030 ANGLE_INLINE void SecondaryCommandBuffer::clearAttachments(uint32_t attachmentCount,
1031                                                            const VkClearAttachment *attachments,
1032                                                            uint32_t rectCount,
1033                                                            const VkClearRect *rects)
1034 {
1035     ASSERT(rectCount == 1);
1036     uint8_t *writePtr;
1037     size_t attachSize = attachmentCount * sizeof(VkClearAttachment);
1038     ClearAttachmentsParams *paramStruct =
1039         initCommand<ClearAttachmentsParams>(CommandID::ClearAttachments, attachSize, &writePtr);
1040     paramStruct->attachmentCount = attachmentCount;
1041     paramStruct->rect            = rects[0];
1042     // Copy variable sized data
1043     storePointerParameter(writePtr, attachments, attachSize);
1044 
1045     mCommandTracker.onClearAttachments();
1046 }
1047 
clearColorImage(const Image & image,VkImageLayout imageLayout,const VkClearColorValue & color,uint32_t rangeCount,const VkImageSubresourceRange * ranges)1048 ANGLE_INLINE void SecondaryCommandBuffer::clearColorImage(const Image &image,
1049                                                           VkImageLayout imageLayout,
1050                                                           const VkClearColorValue &color,
1051                                                           uint32_t rangeCount,
1052                                                           const VkImageSubresourceRange *ranges)
1053 {
1054     ASSERT(rangeCount == 1);
1055     ClearColorImageParams *paramStruct =
1056         initCommand<ClearColorImageParams>(CommandID::ClearColorImage);
1057     paramStruct->image       = image.getHandle();
1058     paramStruct->imageLayout = imageLayout;
1059     paramStruct->color       = color;
1060     paramStruct->range       = ranges[0];
1061 }
1062 
clearDepthStencilImage(const Image & image,VkImageLayout imageLayout,const VkClearDepthStencilValue & depthStencil,uint32_t rangeCount,const VkImageSubresourceRange * ranges)1063 ANGLE_INLINE void SecondaryCommandBuffer::clearDepthStencilImage(
1064     const Image &image,
1065     VkImageLayout imageLayout,
1066     const VkClearDepthStencilValue &depthStencil,
1067     uint32_t rangeCount,
1068     const VkImageSubresourceRange *ranges)
1069 {
1070     ASSERT(rangeCount == 1);
1071     ClearDepthStencilImageParams *paramStruct =
1072         initCommand<ClearDepthStencilImageParams>(CommandID::ClearDepthStencilImage);
1073     paramStruct->image        = image.getHandle();
1074     paramStruct->imageLayout  = imageLayout;
1075     paramStruct->depthStencil = depthStencil;
1076     paramStruct->range        = ranges[0];
1077 }
1078 
copyBuffer(const Buffer & srcBuffer,const Buffer & destBuffer,uint32_t regionCount,const VkBufferCopy * regions)1079 ANGLE_INLINE void SecondaryCommandBuffer::copyBuffer(const Buffer &srcBuffer,
1080                                                      const Buffer &destBuffer,
1081                                                      uint32_t regionCount,
1082                                                      const VkBufferCopy *regions)
1083 {
1084     uint8_t *writePtr;
1085     size_t regionSize = regionCount * sizeof(VkBufferCopy);
1086     CopyBufferParams *paramStruct =
1087         initCommand<CopyBufferParams>(CommandID::CopyBuffer, regionSize, &writePtr);
1088     paramStruct->srcBuffer   = srcBuffer.getHandle();
1089     paramStruct->destBuffer  = destBuffer.getHandle();
1090     paramStruct->regionCount = regionCount;
1091     // Copy variable sized data
1092     storePointerParameter(writePtr, regions, regionSize);
1093 }
1094 
copyBufferToImage(VkBuffer srcBuffer,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * regions)1095 ANGLE_INLINE void SecondaryCommandBuffer::copyBufferToImage(VkBuffer srcBuffer,
1096                                                             const Image &dstImage,
1097                                                             VkImageLayout dstImageLayout,
1098                                                             uint32_t regionCount,
1099                                                             const VkBufferImageCopy *regions)
1100 {
1101     ASSERT(regionCount == 1);
1102     CopyBufferToImageParams *paramStruct =
1103         initCommand<CopyBufferToImageParams>(CommandID::CopyBufferToImage);
1104     paramStruct->srcBuffer      = srcBuffer;
1105     paramStruct->dstImage       = dstImage.getHandle();
1106     paramStruct->dstImageLayout = dstImageLayout;
1107     paramStruct->region         = regions[0];
1108 }
1109 
copyImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * regions)1110 ANGLE_INLINE void SecondaryCommandBuffer::copyImage(const Image &srcImage,
1111                                                     VkImageLayout srcImageLayout,
1112                                                     const Image &dstImage,
1113                                                     VkImageLayout dstImageLayout,
1114                                                     uint32_t regionCount,
1115                                                     const VkImageCopy *regions)
1116 {
1117     ASSERT(regionCount == 1);
1118     CopyImageParams *paramStruct = initCommand<CopyImageParams>(CommandID::CopyImage);
1119     paramStruct->srcImage        = srcImage.getHandle();
1120     paramStruct->srcImageLayout  = srcImageLayout;
1121     paramStruct->dstImage        = dstImage.getHandle();
1122     paramStruct->dstImageLayout  = dstImageLayout;
1123     paramStruct->region          = regions[0];
1124 }
1125 
copyImageToBuffer(const Image & srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * regions)1126 ANGLE_INLINE void SecondaryCommandBuffer::copyImageToBuffer(const Image &srcImage,
1127                                                             VkImageLayout srcImageLayout,
1128                                                             VkBuffer dstBuffer,
1129                                                             uint32_t regionCount,
1130                                                             const VkBufferImageCopy *regions)
1131 {
1132     ASSERT(regionCount == 1);
1133     CopyImageToBufferParams *paramStruct =
1134         initCommand<CopyImageToBufferParams>(CommandID::CopyImageToBuffer);
1135     paramStruct->srcImage       = srcImage.getHandle();
1136     paramStruct->srcImageLayout = srcImageLayout;
1137     paramStruct->dstBuffer      = dstBuffer;
1138     paramStruct->region         = regions[0];
1139 }
1140 
dispatch(uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)1141 ANGLE_INLINE void SecondaryCommandBuffer::dispatch(uint32_t groupCountX,
1142                                                    uint32_t groupCountY,
1143                                                    uint32_t groupCountZ)
1144 {
1145     DispatchParams *paramStruct = initCommand<DispatchParams>(CommandID::Dispatch);
1146     paramStruct->groupCountX    = groupCountX;
1147     paramStruct->groupCountY    = groupCountY;
1148     paramStruct->groupCountZ    = groupCountZ;
1149 }
1150 
dispatchIndirect(const Buffer & buffer,VkDeviceSize offset)1151 ANGLE_INLINE void SecondaryCommandBuffer::dispatchIndirect(const Buffer &buffer,
1152                                                            VkDeviceSize offset)
1153 {
1154     DispatchIndirectParams *paramStruct =
1155         initCommand<DispatchIndirectParams>(CommandID::DispatchIndirect);
1156     paramStruct->buffer = buffer.getHandle();
1157     paramStruct->offset = offset;
1158 }
1159 
draw(uint32_t vertexCount,uint32_t firstVertex)1160 ANGLE_INLINE void SecondaryCommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
1161 {
1162     DrawParams *paramStruct  = initCommand<DrawParams>(CommandID::Draw);
1163     paramStruct->vertexCount = vertexCount;
1164     paramStruct->firstVertex = firstVertex;
1165 
1166     mCommandTracker.onDraw();
1167 }
1168 
drawIndexed(uint32_t indexCount)1169 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount)
1170 {
1171     DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed);
1172     paramStruct->indexCount        = indexCount;
1173 
1174     mCommandTracker.onDraw();
1175 }
1176 
drawIndexedBaseVertex(uint32_t indexCount,uint32_t vertexOffset)1177 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedBaseVertex(uint32_t indexCount,
1178                                                                 uint32_t vertexOffset)
1179 {
1180     DrawIndexedBaseVertexParams *paramStruct =
1181         initCommand<DrawIndexedBaseVertexParams>(CommandID::DrawIndexedBaseVertex);
1182     paramStruct->indexCount   = indexCount;
1183     paramStruct->vertexOffset = vertexOffset;
1184 
1185     mCommandTracker.onDraw();
1186 }
1187 
drawIndexedIndirect(const Buffer & buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1188 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedIndirect(const Buffer &buffer,
1189                                                               VkDeviceSize offset,
1190                                                               uint32_t drawCount,
1191                                                               uint32_t stride)
1192 {
1193     DrawIndexedIndirectParams *paramStruct =
1194         initCommand<DrawIndexedIndirectParams>(CommandID::DrawIndexedIndirect);
1195     paramStruct->buffer    = buffer.getHandle();
1196     paramStruct->offset    = offset;
1197     paramStruct->drawCount = drawCount;
1198     paramStruct->stride    = stride;
1199 
1200     mCommandTracker.onDraw();
1201 }
1202 
drawIndexedInstanced(uint32_t indexCount,uint32_t instanceCount)1203 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstanced(uint32_t indexCount,
1204                                                                uint32_t instanceCount)
1205 {
1206     DrawIndexedInstancedParams *paramStruct =
1207         initCommand<DrawIndexedInstancedParams>(CommandID::DrawIndexedInstanced);
1208     paramStruct->indexCount    = indexCount;
1209     paramStruct->instanceCount = instanceCount;
1210 
1211     mCommandTracker.onDraw();
1212 }
1213 
drawIndexedInstancedBaseVertex(uint32_t indexCount,uint32_t instanceCount,uint32_t vertexOffset)1214 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertex(uint32_t indexCount,
1215                                                                          uint32_t instanceCount,
1216                                                                          uint32_t vertexOffset)
1217 {
1218     DrawIndexedInstancedBaseVertexParams *paramStruct =
1219         initCommand<DrawIndexedInstancedBaseVertexParams>(
1220             CommandID::DrawIndexedInstancedBaseVertex);
1221     paramStruct->indexCount    = indexCount;
1222     paramStruct->instanceCount = instanceCount;
1223     paramStruct->vertexOffset  = vertexOffset;
1224 
1225     mCommandTracker.onDraw();
1226 }
1227 
drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount,uint32_t instanceCount,uint32_t firstIndex,int32_t vertexOffset,uint32_t firstInstance)1228 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertexBaseInstance(
1229     uint32_t indexCount,
1230     uint32_t instanceCount,
1231     uint32_t firstIndex,
1232     int32_t vertexOffset,
1233     uint32_t firstInstance)
1234 {
1235     DrawIndexedInstancedBaseVertexBaseInstanceParams *paramStruct =
1236         initCommand<DrawIndexedInstancedBaseVertexBaseInstanceParams>(
1237             CommandID::DrawIndexedInstancedBaseVertexBaseInstance);
1238     paramStruct->indexCount    = indexCount;
1239     paramStruct->instanceCount = instanceCount;
1240     paramStruct->firstIndex    = firstIndex;
1241     paramStruct->vertexOffset  = vertexOffset;
1242     paramStruct->firstInstance = firstInstance;
1243 
1244     mCommandTracker.onDraw();
1245 }
1246 
drawIndirect(const Buffer & buffer,VkDeviceSize offset,uint32_t drawCount,uint32_t stride)1247 ANGLE_INLINE void SecondaryCommandBuffer::drawIndirect(const Buffer &buffer,
1248                                                        VkDeviceSize offset,
1249                                                        uint32_t drawCount,
1250                                                        uint32_t stride)
1251 {
1252     DrawIndirectParams *paramStruct = initCommand<DrawIndirectParams>(CommandID::DrawIndirect);
1253     paramStruct->buffer             = buffer.getHandle();
1254     paramStruct->offset             = offset;
1255     paramStruct->drawCount          = drawCount;
1256     paramStruct->stride             = stride;
1257 
1258     mCommandTracker.onDraw();
1259 }
1260 
drawInstanced(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex)1261 ANGLE_INLINE void SecondaryCommandBuffer::drawInstanced(uint32_t vertexCount,
1262                                                         uint32_t instanceCount,
1263                                                         uint32_t firstVertex)
1264 {
1265     DrawInstancedParams *paramStruct = initCommand<DrawInstancedParams>(CommandID::DrawInstanced);
1266     paramStruct->vertexCount         = vertexCount;
1267     paramStruct->instanceCount       = instanceCount;
1268     paramStruct->firstVertex         = firstVertex;
1269 
1270     mCommandTracker.onDraw();
1271 }
1272 
drawInstancedBaseInstance(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex,uint32_t firstInstance)1273 ANGLE_INLINE void SecondaryCommandBuffer::drawInstancedBaseInstance(uint32_t vertexCount,
1274                                                                     uint32_t instanceCount,
1275                                                                     uint32_t firstVertex,
1276                                                                     uint32_t firstInstance)
1277 {
1278     DrawInstancedBaseInstanceParams *paramStruct =
1279         initCommand<DrawInstancedBaseInstanceParams>(CommandID::DrawInstancedBaseInstance);
1280     paramStruct->vertexCount   = vertexCount;
1281     paramStruct->instanceCount = instanceCount;
1282     paramStruct->firstVertex   = firstVertex;
1283     paramStruct->firstInstance = firstInstance;
1284 
1285     mCommandTracker.onDraw();
1286 }
1287 
endDebugUtilsLabelEXT()1288 ANGLE_INLINE void SecondaryCommandBuffer::endDebugUtilsLabelEXT()
1289 {
1290     initCommand<EmptyParams>(CommandID::EndDebugUtilsLabel);
1291 }
1292 
endQuery(const QueryPool & queryPool,uint32_t query)1293 ANGLE_INLINE void SecondaryCommandBuffer::endQuery(const QueryPool &queryPool, uint32_t query)
1294 {
1295     EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery);
1296     paramStruct->queryPool      = queryPool.getHandle();
1297     paramStruct->query          = query;
1298 }
1299 
endTransformFeedback(uint32_t firstCounterBuffer,uint32_t counterBufferCount,const VkBuffer * counterBuffers,const VkDeviceSize * counterBufferOffsets)1300 ANGLE_INLINE void SecondaryCommandBuffer::endTransformFeedback(
1301     uint32_t firstCounterBuffer,
1302     uint32_t counterBufferCount,
1303     const VkBuffer *counterBuffers,
1304     const VkDeviceSize *counterBufferOffsets)
1305 {
1306     ASSERT(firstCounterBuffer == 0);
1307     uint8_t *writePtr;
1308     size_t bufferSize                       = counterBufferCount * sizeof(VkBuffer);
1309     size_t offsetSize                       = counterBufferCount * sizeof(VkDeviceSize);
1310     EndTransformFeedbackParams *paramStruct = initCommand<EndTransformFeedbackParams>(
1311         CommandID::EndTransformFeedback, bufferSize + offsetSize, &writePtr);
1312     paramStruct->bufferCount = counterBufferCount;
1313     writePtr                 = storePointerParameter(writePtr, counterBuffers, bufferSize);
1314     storePointerParameter(writePtr, counterBufferOffsets, offsetSize);
1315 }
1316 
fillBuffer(const Buffer & dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)1317 ANGLE_INLINE void SecondaryCommandBuffer::fillBuffer(const Buffer &dstBuffer,
1318                                                      VkDeviceSize dstOffset,
1319                                                      VkDeviceSize size,
1320                                                      uint32_t data)
1321 {
1322     FillBufferParams *paramStruct = initCommand<FillBufferParams>(CommandID::FillBuffer);
1323     paramStruct->dstBuffer        = dstBuffer.getHandle();
1324     paramStruct->dstOffset        = dstOffset;
1325     paramStruct->size             = size;
1326     paramStruct->data             = data;
1327 }
1328 
imageBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkImageMemoryBarrier & imageMemoryBarrier)1329 ANGLE_INLINE void SecondaryCommandBuffer::imageBarrier(
1330     VkPipelineStageFlags srcStageMask,
1331     VkPipelineStageFlags dstStageMask,
1332     const VkImageMemoryBarrier &imageMemoryBarrier)
1333 {
1334     ImageBarrierParams *paramStruct = initCommand<ImageBarrierParams>(CommandID::ImageBarrier);
1335     ASSERT(imageMemoryBarrier.pNext == nullptr);
1336     paramStruct->srcStageMask       = srcStageMask;
1337     paramStruct->dstStageMask       = dstStageMask;
1338     paramStruct->imageMemoryBarrier = imageMemoryBarrier;
1339 }
1340 
insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT & label)1341 ANGLE_INLINE void SecondaryCommandBuffer::insertDebugUtilsLabelEXT(
1342     const VkDebugUtilsLabelEXT &label)
1343 {
1344     commonDebugUtilsLabel(CommandID::InsertDebugUtilsLabel, label);
1345 }
1346 
memoryBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkMemoryBarrier * memoryBarrier)1347 ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask,
1348                                                         VkPipelineStageFlags dstStageMask,
1349                                                         const VkMemoryBarrier *memoryBarrier)
1350 {
1351     MemoryBarrierParams *paramStruct = initCommand<MemoryBarrierParams>(CommandID::MemoryBarrier);
1352     paramStruct->srcStageMask        = srcStageMask;
1353     paramStruct->dstStageMask        = dstStageMask;
1354     paramStruct->memoryBarrier       = *memoryBarrier;
1355 }
1356 
nextSubpass(VkSubpassContents subpassContents)1357 ANGLE_INLINE void SecondaryCommandBuffer::nextSubpass(VkSubpassContents subpassContents)
1358 {
1359     NextSubpassParams *paramStruct = initCommand<NextSubpassParams>(CommandID::NextSubpass);
1360     paramStruct->subpassContents   = subpassContents;
1361 }
1362 
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)1363 ANGLE_INLINE void SecondaryCommandBuffer::pipelineBarrier(
1364     VkPipelineStageFlags srcStageMask,
1365     VkPipelineStageFlags dstStageMask,
1366     VkDependencyFlags dependencyFlags,
1367     uint32_t memoryBarrierCount,
1368     const VkMemoryBarrier *memoryBarriers,
1369     uint32_t bufferMemoryBarrierCount,
1370     const VkBufferMemoryBarrier *bufferMemoryBarriers,
1371     uint32_t imageMemoryBarrierCount,
1372     const VkImageMemoryBarrier *imageMemoryBarriers)
1373 {
1374     uint8_t *writePtr;
1375     size_t memBarrierSize              = memoryBarrierCount * sizeof(VkMemoryBarrier);
1376     size_t buffBarrierSize             = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
1377     size_t imgBarrierSize              = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
1378     PipelineBarrierParams *paramStruct = initCommand<PipelineBarrierParams>(
1379         CommandID::PipelineBarrier, memBarrierSize + buffBarrierSize + imgBarrierSize, &writePtr);
1380     paramStruct->srcStageMask             = srcStageMask;
1381     paramStruct->dstStageMask             = dstStageMask;
1382     paramStruct->dependencyFlags          = dependencyFlags;
1383     paramStruct->memoryBarrierCount       = memoryBarrierCount;
1384     paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount;
1385     paramStruct->imageMemoryBarrierCount  = imageMemoryBarrierCount;
1386     // Copy variable sized data
1387     writePtr = storePointerParameter(writePtr, memoryBarriers, memBarrierSize);
1388     writePtr = storePointerParameter(writePtr, bufferMemoryBarriers, buffBarrierSize);
1389     storePointerParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
1390 }
1391 
pushConstants(const PipelineLayout & layout,VkShaderStageFlags flag,uint32_t offset,uint32_t size,const void * data)1392 ANGLE_INLINE void SecondaryCommandBuffer::pushConstants(const PipelineLayout &layout,
1393                                                         VkShaderStageFlags flag,
1394                                                         uint32_t offset,
1395                                                         uint32_t size,
1396                                                         const void *data)
1397 {
1398     ASSERT(size == static_cast<size_t>(size));
1399     uint8_t *writePtr;
1400     PushConstantsParams *paramStruct = initCommand<PushConstantsParams>(
1401         CommandID::PushConstants, static_cast<size_t>(size), &writePtr);
1402     paramStruct->layout = layout.getHandle();
1403     paramStruct->flag   = flag;
1404     paramStruct->offset = offset;
1405     paramStruct->size   = size;
1406     // Copy variable sized data
1407     storePointerParameter(writePtr, data, static_cast<size_t>(size));
1408 }
1409 
resetEvent(VkEvent event,VkPipelineStageFlags stageMask)1410 ANGLE_INLINE void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
1411 {
1412     ResetEventParams *paramStruct = initCommand<ResetEventParams>(CommandID::ResetEvent);
1413     paramStruct->event            = event;
1414     paramStruct->stageMask        = stageMask;
1415 }
1416 
resetQueryPool(const QueryPool & queryPool,uint32_t firstQuery,uint32_t queryCount)1417 ANGLE_INLINE void SecondaryCommandBuffer::resetQueryPool(const QueryPool &queryPool,
1418                                                          uint32_t firstQuery,
1419                                                          uint32_t queryCount)
1420 {
1421     ResetQueryPoolParams *paramStruct =
1422         initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool);
1423     paramStruct->queryPool  = queryPool.getHandle();
1424     paramStruct->firstQuery = firstQuery;
1425     paramStruct->queryCount = queryCount;
1426 }
1427 
resolveImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageResolve * regions)1428 ANGLE_INLINE void SecondaryCommandBuffer::resolveImage(const Image &srcImage,
1429                                                        VkImageLayout srcImageLayout,
1430                                                        const Image &dstImage,
1431                                                        VkImageLayout dstImageLayout,
1432                                                        uint32_t regionCount,
1433                                                        const VkImageResolve *regions)
1434 {
1435     // Currently ANGLE uses limited params so verify those assumptions and update if they change.
1436     ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1437     ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1438     ASSERT(regionCount == 1);
1439     ResolveImageParams *paramStruct = initCommand<ResolveImageParams>(CommandID::ResolveImage);
1440     paramStruct->srcImage           = srcImage.getHandle();
1441     paramStruct->dstImage           = dstImage.getHandle();
1442     paramStruct->region             = regions[0];
1443 }
1444 
setEvent(VkEvent event,VkPipelineStageFlags stageMask)1445 ANGLE_INLINE void SecondaryCommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
1446 {
1447     SetEventParams *paramStruct = initCommand<SetEventParams>(CommandID::SetEvent);
1448     paramStruct->event          = event;
1449     paramStruct->stageMask      = stageMask;
1450 }
1451 
setScissor(uint32_t firstScissor,uint32_t scissorCount,const VkRect2D * scissors)1452 ANGLE_INLINE void SecondaryCommandBuffer::setScissor(uint32_t firstScissor,
1453                                                      uint32_t scissorCount,
1454                                                      const VkRect2D *scissors)
1455 {
1456     ASSERT(firstScissor == 0);
1457     ASSERT(scissorCount == 1);
1458     ASSERT(scissors != nullptr);
1459     SetScissorParams *paramStruct = initCommand<SetScissorParams>(CommandID::SetScissor);
1460     paramStruct->scissor          = scissors[0];
1461 }
1462 
setViewport(uint32_t firstViewport,uint32_t viewportCount,const VkViewport * viewports)1463 ANGLE_INLINE void SecondaryCommandBuffer::setViewport(uint32_t firstViewport,
1464                                                       uint32_t viewportCount,
1465                                                       const VkViewport *viewports)
1466 {
1467     ASSERT(firstViewport == 0);
1468     ASSERT(viewportCount == 1);
1469     ASSERT(viewports != nullptr);
1470     SetViewportParams *paramStruct = initCommand<SetViewportParams>(CommandID::SetViewport);
1471     paramStruct->viewport          = viewports[0];
1472 }
1473 
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)1474 ANGLE_INLINE void SecondaryCommandBuffer::waitEvents(
1475     uint32_t eventCount,
1476     const VkEvent *events,
1477     VkPipelineStageFlags srcStageMask,
1478     VkPipelineStageFlags dstStageMask,
1479     uint32_t memoryBarrierCount,
1480     const VkMemoryBarrier *memoryBarriers,
1481     uint32_t bufferMemoryBarrierCount,
1482     const VkBufferMemoryBarrier *bufferMemoryBarriers,
1483     uint32_t imageMemoryBarrierCount,
1484     const VkImageMemoryBarrier *imageMemoryBarriers)
1485 {
1486     uint8_t *writePtr;
1487     size_t eventSize              = eventCount * sizeof(VkEvent);
1488     size_t memBarrierSize         = memoryBarrierCount * sizeof(VkMemoryBarrier);
1489     size_t buffBarrierSize        = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
1490     size_t imgBarrierSize         = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
1491     WaitEventsParams *paramStruct = initCommand<WaitEventsParams>(
1492         CommandID::WaitEvents, eventSize + memBarrierSize + buffBarrierSize + imgBarrierSize,
1493         &writePtr);
1494     paramStruct->eventCount               = eventCount;
1495     paramStruct->srcStageMask             = srcStageMask;
1496     paramStruct->dstStageMask             = dstStageMask;
1497     paramStruct->memoryBarrierCount       = memoryBarrierCount;
1498     paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount;
1499     paramStruct->imageMemoryBarrierCount  = imageMemoryBarrierCount;
1500     // Copy variable sized data
1501     writePtr = storePointerParameter(writePtr, events, eventSize);
1502     writePtr = storePointerParameter(writePtr, memoryBarriers, memBarrierSize);
1503     writePtr = storePointerParameter(writePtr, bufferMemoryBarriers, buffBarrierSize);
1504     storePointerParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
1505 }
1506 
writeTimestamp(VkPipelineStageFlagBits pipelineStage,const QueryPool & queryPool,uint32_t query)1507 ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
1508                                                          const QueryPool &queryPool,
1509                                                          uint32_t query)
1510 {
1511     WriteTimestampParams *paramStruct =
1512         initCommand<WriteTimestampParams>(CommandID::WriteTimestamp);
1513     paramStruct->pipelineStage = pipelineStage;
1514     paramStruct->queryPool     = queryPool.getHandle();
1515     paramStruct->query         = query;
1516 }
1517 }  // namespace priv
1518 }  // namespace vk
1519 }  // namespace rx
1520 
1521 #endif  // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
1522