• 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 <vulkan/vulkan.h>
15 
16 #include "common/PoolAlloc.h"
17 #include "libANGLE/renderer/vulkan/vk_wrapper.h"
18 
19 namespace rx
20 {
21 
22 namespace vk
23 {
24 
25 namespace priv
26 {
27 
28 enum class CommandID : uint16_t
29 {
30     // Invalid cmd used to mark end of sequence of commands
31     Invalid = 0,
32     BeginQuery,
33     BindComputePipeline,
34     BindDescriptorSets,
35     BindGraphicsPipeline,
36     BindIndexBuffer,
37     BindVertexBuffers,
38     BlitImage,
39     ClearAttachments,
40     ClearColorImage,
41     ClearDepthStencilImage,
42     CopyBuffer,
43     CopyBufferToImage,
44     CopyImage,
45     CopyImageToBuffer,
46     Dispatch,
47     DispatchIndirect,
48     Draw,
49     DrawIndexed,
50     DrawIndexedInstanced,
51     DrawInstanced,
52     EndQuery,
53     ExecutionBarrier,
54     FillBuffer,
55     ImageBarrier,
56     MemoryBarrier,
57     PipelineBarrier,
58     PushConstants,
59     ResetEvent,
60     ResetQueryPool,
61     ResolveImage,
62     SetEvent,
63     WaitEvents,
64     WriteTimestamp,
65 };
66 
67 #define VERIFY_4_BYTE_ALIGNMENT(StructName) \
68     static_assert((sizeof(StructName) % 4) == 0, "Check StructName alignment");
69 
70 // Structs to encapsulate parameters for different commands
71 // This makes it easy to know the size of params & to copy params
72 // TODO: Could optimize the size of some of these structs through bit-packing
73 //  and customizing sizing based on limited parameter sets used by ANGLE
74 struct BindPipelineParams
75 {
76     VkPipeline pipeline;
77 };
78 VERIFY_4_BYTE_ALIGNMENT(BindPipelineParams)
79 
80 struct BindDescriptorSetParams
81 {
82     VkPipelineLayout layout;
83     VkPipelineBindPoint pipelineBindPoint;
84     uint32_t firstSet;
85     uint32_t descriptorSetCount;
86     uint32_t dynamicOffsetCount;
87 };
88 VERIFY_4_BYTE_ALIGNMENT(BindDescriptorSetParams)
89 
90 struct BindIndexBufferParams
91 {
92     VkBuffer buffer;
93     VkDeviceSize offset;
94     VkIndexType indexType;
95 };
96 VERIFY_4_BYTE_ALIGNMENT(BindIndexBufferParams)
97 
98 struct BindVertexBuffersParams
99 {
100     // ANGLE always has firstBinding of 0 so not storing that currently
101     uint32_t bindingCount;
102 };
103 VERIFY_4_BYTE_ALIGNMENT(BindVertexBuffersParams)
104 
105 struct BlitImageParams
106 {
107     VkImage srcImage;
108     VkImage dstImage;
109     VkFilter filter;
110     VkImageBlit region;
111 };
112 VERIFY_4_BYTE_ALIGNMENT(BlitImageParams)
113 
114 struct CopyBufferParams
115 {
116     VkBuffer srcBuffer;
117     VkBuffer destBuffer;
118     uint32_t regionCount;
119 };
120 VERIFY_4_BYTE_ALIGNMENT(CopyBufferParams)
121 
122 struct CopyBufferToImageParams
123 {
124     VkBuffer srcBuffer;
125     VkImage dstImage;
126     VkImageLayout dstImageLayout;
127     VkBufferImageCopy region;
128 };
129 VERIFY_4_BYTE_ALIGNMENT(CopyBufferToImageParams)
130 
131 struct CopyImageParams
132 {
133     VkImage srcImage;
134     VkImageLayout srcImageLayout;
135     VkImage dstImage;
136     VkImageLayout dstImageLayout;
137     VkImageCopy region;
138 };
139 VERIFY_4_BYTE_ALIGNMENT(CopyImageParams)
140 
141 struct CopyImageToBufferParams
142 {
143     VkImage srcImage;
144     VkImageLayout srcImageLayout;
145     VkBuffer dstBuffer;
146     VkBufferImageCopy region;
147 };
148 VERIFY_4_BYTE_ALIGNMENT(CopyImageToBufferParams)
149 
150 struct ClearAttachmentsParams
151 {
152     uint32_t attachmentCount;
153     VkClearRect rect;
154 };
155 VERIFY_4_BYTE_ALIGNMENT(ClearAttachmentsParams)
156 
157 struct ClearColorImageParams
158 {
159     VkImage image;
160     VkImageLayout imageLayout;
161     VkClearColorValue color;
162     VkImageSubresourceRange range;
163 };
164 VERIFY_4_BYTE_ALIGNMENT(ClearColorImageParams)
165 
166 struct ClearDepthStencilImageParams
167 {
168     VkImage image;
169     VkImageLayout imageLayout;
170     VkClearDepthStencilValue depthStencil;
171     VkImageSubresourceRange range;
172 };
173 VERIFY_4_BYTE_ALIGNMENT(ClearDepthStencilImageParams)
174 
175 struct PushConstantsParams
176 {
177     VkPipelineLayout layout;
178     VkShaderStageFlags flag;
179     uint32_t offset;
180     uint32_t size;
181 };
182 VERIFY_4_BYTE_ALIGNMENT(PushConstantsParams)
183 
184 struct DrawParams
185 {
186     uint32_t vertexCount;
187     uint32_t firstVertex;
188 };
189 VERIFY_4_BYTE_ALIGNMENT(DrawParams)
190 
191 struct DrawInstancedParams
192 {
193     uint32_t vertexCount;
194     uint32_t instanceCount;
195     uint32_t firstVertex;
196 };
197 VERIFY_4_BYTE_ALIGNMENT(DrawInstancedParams)
198 
199 struct DrawIndexedParams
200 {
201     uint32_t indexCount;
202 };
203 VERIFY_4_BYTE_ALIGNMENT(DrawIndexedParams)
204 
205 struct DrawIndexedInstancedParams
206 {
207     uint32_t indexCount;
208     uint32_t instanceCount;
209 };
210 VERIFY_4_BYTE_ALIGNMENT(DrawIndexedInstancedParams)
211 
212 struct DispatchParams
213 {
214     uint32_t groupCountX;
215     uint32_t groupCountY;
216     uint32_t groupCountZ;
217 };
218 VERIFY_4_BYTE_ALIGNMENT(DispatchParams)
219 
220 struct DispatchIndirectParams
221 {
222     VkBuffer buffer;
223     VkDeviceSize offset;
224 };
225 VERIFY_4_BYTE_ALIGNMENT(DispatchIndirectParams)
226 
227 struct FillBufferParams
228 {
229     VkBuffer dstBuffer;
230     VkDeviceSize dstOffset;
231     VkDeviceSize size;
232     uint32_t data;
233 };
234 VERIFY_4_BYTE_ALIGNMENT(FillBufferParams)
235 
236 struct MemoryBarrierParams
237 {
238     VkPipelineStageFlags srcStageMask;
239     VkPipelineStageFlags dstStageMask;
240     VkMemoryBarrier memoryBarrier;
241 };
242 VERIFY_4_BYTE_ALIGNMENT(MemoryBarrierParams)
243 
244 struct PipelineBarrierParams
245 {
246     VkPipelineStageFlags srcStageMask;
247     VkPipelineStageFlags dstStageMask;
248     VkDependencyFlags dependencyFlags;
249     uint32_t memoryBarrierCount;
250     uint32_t bufferMemoryBarrierCount;
251     uint32_t imageMemoryBarrierCount;
252 };
253 VERIFY_4_BYTE_ALIGNMENT(PipelineBarrierParams)
254 
255 struct ExecutionBarrierParams
256 {
257     VkPipelineStageFlags stageMask;
258 };
259 VERIFY_4_BYTE_ALIGNMENT(ExecutionBarrierParams)
260 
261 struct ImageBarrierParams
262 {
263     VkPipelineStageFlags srcStageMask;
264     VkPipelineStageFlags dstStageMask;
265     VkImageMemoryBarrier imageMemoryBarrier;
266 };
267 VERIFY_4_BYTE_ALIGNMENT(ImageBarrierParams)
268 
269 struct SetEventParams
270 {
271     VkEvent event;
272     VkPipelineStageFlags stageMask;
273 };
274 VERIFY_4_BYTE_ALIGNMENT(SetEventParams)
275 
276 struct ResetEventParams
277 {
278     VkEvent event;
279     VkPipelineStageFlags stageMask;
280 };
281 VERIFY_4_BYTE_ALIGNMENT(ResetEventParams)
282 
283 struct WaitEventsParams
284 {
285     uint32_t eventCount;
286     VkPipelineStageFlags srcStageMask;
287     VkPipelineStageFlags dstStageMask;
288     uint32_t memoryBarrierCount;
289     uint32_t bufferMemoryBarrierCount;
290     uint32_t imageMemoryBarrierCount;
291 };
292 VERIFY_4_BYTE_ALIGNMENT(WaitEventsParams)
293 
294 struct ResetQueryPoolParams
295 {
296     VkQueryPool queryPool;
297     uint32_t firstQuery;
298     uint32_t queryCount;
299 };
300 VERIFY_4_BYTE_ALIGNMENT(ResetQueryPoolParams)
301 
302 struct ResolveImageParams
303 {
304     VkImage srcImage;
305     VkImage dstImage;
306     VkImageResolve region;
307 };
308 VERIFY_4_BYTE_ALIGNMENT(ResolveImageParams)
309 
310 struct BeginQueryParams
311 {
312     VkQueryPool queryPool;
313     uint32_t query;
314     VkQueryControlFlags flags;
315 };
316 VERIFY_4_BYTE_ALIGNMENT(BeginQueryParams)
317 
318 struct EndQueryParams
319 {
320     VkQueryPool queryPool;
321     uint32_t query;
322 };
323 VERIFY_4_BYTE_ALIGNMENT(EndQueryParams)
324 
325 struct WriteTimestampParams
326 {
327     VkPipelineStageFlagBits pipelineStage;
328     VkQueryPool queryPool;
329     uint32_t query;
330 };
331 VERIFY_4_BYTE_ALIGNMENT(WriteTimestampParams)
332 
333 // Header for every cmd in custom cmd buffer
334 struct CommandHeader
335 {
336     CommandID id;
337     uint16_t size;
338 };
339 
340 static_assert(sizeof(CommandHeader) == 4, "Check CommandHeader size");
341 
342 template <typename DestT, typename T>
Offset(T * ptr,size_t bytes)343 ANGLE_INLINE DestT *Offset(T *ptr, size_t bytes)
344 {
345     return reinterpret_cast<DestT *>((reinterpret_cast<uint8_t *>(ptr) + bytes));
346 }
347 
348 template <typename DestT, typename T>
Offset(const T * ptr,size_t bytes)349 ANGLE_INLINE const DestT *Offset(const T *ptr, size_t bytes)
350 {
351     return reinterpret_cast<const DestT *>((reinterpret_cast<const uint8_t *>(ptr) + bytes));
352 }
353 
354 class SecondaryCommandBuffer final : angle::NonCopyable
355 {
356   public:
357     SecondaryCommandBuffer();
358     ~SecondaryCommandBuffer();
359 
SupportsQueries(const VkPhysicalDeviceFeatures & features)360     static bool SupportsQueries(const VkPhysicalDeviceFeatures &features) { return true; }
361 
362     // SecondaryCommandBuffer replays its commands inline when executed on the primary command
363     // buffer.
ExecutesInline()364     static constexpr bool ExecutesInline() { return true; }
365 
366     // Add commands
367     void beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags);
368 
369     void bindComputePipeline(const Pipeline &pipeline);
370 
371     void bindDescriptorSets(const PipelineLayout &layout,
372                             VkPipelineBindPoint pipelineBindPoint,
373                             uint32_t firstSet,
374                             uint32_t descriptorSetCount,
375                             const VkDescriptorSet *descriptorSets,
376                             uint32_t dynamicOffsetCount,
377                             const uint32_t *dynamicOffsets);
378 
379     void bindGraphicsPipeline(const Pipeline &pipeline);
380 
381     void bindIndexBuffer(const Buffer &buffer, VkDeviceSize offset, VkIndexType indexType);
382 
383     void bindVertexBuffers(uint32_t firstBinding,
384                            uint32_t bindingCount,
385                            const VkBuffer *buffers,
386                            const VkDeviceSize *offsets);
387 
388     void blitImage(const Image &srcImage,
389                    VkImageLayout srcImageLayout,
390                    const Image &dstImage,
391                    VkImageLayout dstImageLayout,
392                    uint32_t regionCount,
393                    const VkImageBlit *regions,
394                    VkFilter filter);
395 
396     void clearAttachments(uint32_t attachmentCount,
397                           const VkClearAttachment *attachments,
398                           uint32_t rectCount,
399                           const VkClearRect *rects);
400 
401     void clearColorImage(const Image &image,
402                          VkImageLayout imageLayout,
403                          const VkClearColorValue &color,
404                          uint32_t rangeCount,
405                          const VkImageSubresourceRange *ranges);
406 
407     void clearDepthStencilImage(const Image &image,
408                                 VkImageLayout imageLayout,
409                                 const VkClearDepthStencilValue &depthStencil,
410                                 uint32_t rangeCount,
411                                 const VkImageSubresourceRange *ranges);
412 
413     void copyBuffer(const Buffer &srcBuffer,
414                     const Buffer &destBuffer,
415                     uint32_t regionCount,
416                     const VkBufferCopy *regions);
417 
418     void copyBufferToImage(VkBuffer srcBuffer,
419                            const Image &dstImage,
420                            VkImageLayout dstImageLayout,
421                            uint32_t regionCount,
422                            const VkBufferImageCopy *regions);
423 
424     void copyImage(const Image &srcImage,
425                    VkImageLayout srcImageLayout,
426                    const Image &dstImage,
427                    VkImageLayout dstImageLayout,
428                    uint32_t regionCount,
429                    const VkImageCopy *regions);
430 
431     void copyImageToBuffer(const Image &srcImage,
432                            VkImageLayout srcImageLayout,
433                            VkBuffer dstBuffer,
434                            uint32_t regionCount,
435                            const VkBufferImageCopy *regions);
436 
437     void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ);
438 
439     void dispatchIndirect(const Buffer &buffer, VkDeviceSize offset);
440 
441     void draw(uint32_t vertexCount, uint32_t firstVertex);
442 
443     void drawIndexed(uint32_t indexCount);
444 
445     void drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount);
446 
447     void drawInstanced(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex);
448 
449     void endQuery(VkQueryPool queryPool, uint32_t query);
450 
451     void executionBarrier(VkPipelineStageFlags stageMask);
452 
453     void fillBuffer(const Buffer &dstBuffer,
454                     VkDeviceSize dstOffset,
455                     VkDeviceSize size,
456                     uint32_t data);
457 
458     void imageBarrier(VkPipelineStageFlags srcStageMask,
459                       VkPipelineStageFlags dstStageMask,
460                       const VkImageMemoryBarrier *imageMemoryBarrier);
461 
462     void memoryBarrier(VkPipelineStageFlags srcStageMask,
463                        VkPipelineStageFlags dstStageMask,
464                        const VkMemoryBarrier *memoryBarrier);
465 
466     void pipelineBarrier(VkPipelineStageFlags srcStageMask,
467                          VkPipelineStageFlags dstStageMask,
468                          VkDependencyFlags dependencyFlags,
469                          uint32_t memoryBarrierCount,
470                          const VkMemoryBarrier *memoryBarriers,
471                          uint32_t bufferMemoryBarrierCount,
472                          const VkBufferMemoryBarrier *bufferMemoryBarriers,
473                          uint32_t imageMemoryBarrierCount,
474                          const VkImageMemoryBarrier *imageMemoryBarriers);
475 
476     void pushConstants(const PipelineLayout &layout,
477                        VkShaderStageFlags flag,
478                        uint32_t offset,
479                        uint32_t size,
480                        const void *data);
481 
482     void resetEvent(VkEvent event, VkPipelineStageFlags stageMask);
483 
484     void resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount);
485 
486     void resolveImage(const Image &srcImage,
487                       VkImageLayout srcImageLayout,
488                       const Image &dstImage,
489                       VkImageLayout dstImageLayout,
490                       uint32_t regionCount,
491                       const VkImageResolve *regions);
492 
493     void setEvent(VkEvent event, VkPipelineStageFlags stageMask);
494 
495     void waitEvents(uint32_t eventCount,
496                     const VkEvent *events,
497                     VkPipelineStageFlags srcStageMask,
498                     VkPipelineStageFlags dstStageMask,
499                     uint32_t memoryBarrierCount,
500                     const VkMemoryBarrier *memoryBarriers,
501                     uint32_t bufferMemoryBarrierCount,
502                     const VkBufferMemoryBarrier *bufferMemoryBarriers,
503                     uint32_t imageMemoryBarrierCount,
504                     const VkImageMemoryBarrier *imageMemoryBarriers);
505 
506     void writeTimestamp(VkPipelineStageFlagBits pipelineStage,
507                         VkQueryPool queryPool,
508                         uint32_t query);
509     // No-op for compatibility
end()510     VkResult end() { return VK_SUCCESS; }
511 
512     // Parse the cmds in this cmd buffer into given primary cmd buffer for execution
513     void executeCommands(VkCommandBuffer cmdBuffer);
514 
515     // Traverse the list of commands and build a summary for diagnostics.
516     std::string dumpCommands(const char *separator) const;
517 
518     // Pool Alloc uses 16kB pages w/ 16byte header = 16368bytes. To minimize waste
519     //  using a 16368/12 = 1364. Also better perf than 1024 due to fewer block allocations
520     static constexpr size_t kBlockSize = 1364;
521     // Make sure block size is 4-byte aligned to avoid Android errors
522     static_assert((kBlockSize % 4) == 0, "Check kBlockSize alignment");
523 
524     // Initialize the SecondaryCommandBuffer by setting the allocator it will use
initialize(angle::PoolAllocator * allocator)525     void initialize(angle::PoolAllocator *allocator)
526     {
527         ASSERT(allocator);
528         mAllocator = allocator;
529         allocateNewBlock();
530         // Set first command to Invalid to start
531         reinterpret_cast<CommandHeader *>(mCurrentWritePointer)->id = CommandID::Invalid;
532     }
533 
534     // This will cause the SecondaryCommandBuffer to become invalid by clearing its allocator
releaseHandle()535     void releaseHandle() { mAllocator = nullptr; }
536     // The SecondaryCommandBuffer is valid if it's been initialized
valid()537     bool valid() const { return mAllocator != nullptr; }
538 
CanKnowIfEmpty()539     static bool CanKnowIfEmpty() { return true; }
empty()540     bool empty() const { return mCommands.size() == 0 || mCommands[0]->id == CommandID::Invalid; }
541 
542   private:
543     template <class StructType>
commonInit(CommandID cmdID,size_t allocationSize)544     ANGLE_INLINE StructType *commonInit(CommandID cmdID, size_t allocationSize)
545     {
546         mCurrentBytesRemaining -= allocationSize;
547 
548         CommandHeader *header = reinterpret_cast<CommandHeader *>(mCurrentWritePointer);
549         header->id            = cmdID;
550         header->size          = static_cast<uint16_t>(allocationSize);
551         ASSERT(allocationSize <= std::numeric_limits<uint16_t>::max());
552 
553         mCurrentWritePointer += allocationSize;
554         // Set next cmd header to Invalid (0) so cmd sequence will be terminated
555         reinterpret_cast<CommandHeader *>(mCurrentWritePointer)->id = CommandID::Invalid;
556         return Offset<StructType>(header, sizeof(CommandHeader));
557     }
allocateNewBlock()558     ANGLE_INLINE void allocateNewBlock()
559     {
560         ASSERT(mAllocator);
561         mCurrentWritePointer   = mAllocator->fastAllocate(kBlockSize);
562         mCurrentBytesRemaining = kBlockSize;
563         mCommands.push_back(reinterpret_cast<CommandHeader *>(mCurrentWritePointer));
564     }
565 
566     // Allocate and initialize memory for given commandID & variable param size, setting
567     // variableDataPtr to the byte following fixed cmd data where variable-sized ptr data will
568     // be written and returning a pointer to the start of the command's parameter data
569     template <class StructType>
initCommand(CommandID cmdID,size_t variableSize,uint8_t ** variableDataPtr)570     ANGLE_INLINE StructType *initCommand(CommandID cmdID,
571                                          size_t variableSize,
572                                          uint8_t **variableDataPtr)
573     {
574         constexpr size_t fixedAllocationSize = sizeof(StructType) + sizeof(CommandHeader);
575         const size_t allocationSize          = fixedAllocationSize + variableSize;
576         // Make sure we have enough room to mark follow-on header "Invalid"
577         if (mCurrentBytesRemaining <= (allocationSize + sizeof(CommandHeader)))
578         {
579             allocateNewBlock();
580         }
581         *variableDataPtr = Offset<uint8_t>(mCurrentWritePointer, fixedAllocationSize);
582         return commonInit<StructType>(cmdID, allocationSize);
583     }
584 
585     // Initialize a command that doesn't have variable-sized ptr data
586     template <class StructType>
initCommand(CommandID cmdID)587     ANGLE_INLINE StructType *initCommand(CommandID cmdID)
588     {
589         constexpr size_t allocationSize = sizeof(StructType) + sizeof(CommandHeader);
590         // Make sure we have enough room to mark follow-on header "Invalid"
591         if (mCurrentBytesRemaining <= (allocationSize + sizeof(CommandHeader)))
592         {
593             allocateNewBlock();
594         }
595         return commonInit<StructType>(cmdID, allocationSize);
596     }
597 
598     // Return a ptr to the parameter type
599     template <class StructType>
getParamPtr(const CommandHeader * header)600     const StructType *getParamPtr(const CommandHeader *header) const
601     {
602         return reinterpret_cast<const StructType *>(reinterpret_cast<const uint8_t *>(header) +
603                                                     sizeof(CommandHeader));
604     }
605     // Copy sizeInBytes data from paramData to writePointer & return writePointer plus sizeInBytes.
606     template <class PtrType>
storePointerParameter(uint8_t * writePointer,const PtrType * paramData,size_t sizeInBytes)607     ANGLE_INLINE uint8_t *storePointerParameter(uint8_t *writePointer,
608                                                 const PtrType *paramData,
609                                                 size_t sizeInBytes)
610     {
611         memcpy(writePointer, paramData, sizeInBytes);
612         return writePointer + sizeInBytes;
613     }
614 
615     std::vector<CommandHeader *> mCommands;
616 
617     // Allocator used by this class. If non-null then the class is valid.
618     angle::PoolAllocator *mAllocator;
619 
620     uint8_t *mCurrentWritePointer;
621     size_t mCurrentBytesRemaining;
622 };
623 
SecondaryCommandBuffer()624 ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer()
625     : mAllocator(nullptr), mCurrentWritePointer(nullptr), mCurrentBytesRemaining(0)
626 {}
~SecondaryCommandBuffer()627 ANGLE_INLINE SecondaryCommandBuffer::~SecondaryCommandBuffer() {}
628 
beginQuery(VkQueryPool queryPool,uint32_t query,VkQueryControlFlags flags)629 ANGLE_INLINE void SecondaryCommandBuffer::beginQuery(VkQueryPool queryPool,
630                                                      uint32_t query,
631                                                      VkQueryControlFlags flags)
632 {
633     BeginQueryParams *paramStruct = initCommand<BeginQueryParams>(CommandID::BeginQuery);
634     paramStruct->queryPool        = queryPool;
635     paramStruct->query            = query;
636     paramStruct->flags            = flags;
637 }
638 
bindComputePipeline(const Pipeline & pipeline)639 ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pipeline)
640 {
641     BindPipelineParams *paramStruct =
642         initCommand<BindPipelineParams>(CommandID::BindComputePipeline);
643     paramStruct->pipeline = pipeline.getHandle();
644 }
645 
bindDescriptorSets(const PipelineLayout & layout,VkPipelineBindPoint pipelineBindPoint,uint32_t firstSet,uint32_t descriptorSetCount,const VkDescriptorSet * descriptorSets,uint32_t dynamicOffsetCount,const uint32_t * dynamicOffsets)646 ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout,
647                                                              VkPipelineBindPoint pipelineBindPoint,
648                                                              uint32_t firstSet,
649                                                              uint32_t descriptorSetCount,
650                                                              const VkDescriptorSet *descriptorSets,
651                                                              uint32_t dynamicOffsetCount,
652                                                              const uint32_t *dynamicOffsets)
653 {
654     size_t descSize   = descriptorSetCount * sizeof(VkDescriptorSet);
655     size_t offsetSize = dynamicOffsetCount * sizeof(uint32_t);
656     uint8_t *writePtr;
657     BindDescriptorSetParams *paramStruct = initCommand<BindDescriptorSetParams>(
658         CommandID::BindDescriptorSets, descSize + offsetSize, &writePtr);
659     // Copy params into memory
660     paramStruct->layout             = layout.getHandle();
661     paramStruct->pipelineBindPoint  = pipelineBindPoint;
662     paramStruct->firstSet           = firstSet;
663     paramStruct->descriptorSetCount = descriptorSetCount;
664     paramStruct->dynamicOffsetCount = dynamicOffsetCount;
665     // Copy variable sized data
666     writePtr = storePointerParameter(writePtr, descriptorSets, descSize);
667     storePointerParameter(writePtr, dynamicOffsets, offsetSize);
668 }
669 
bindGraphicsPipeline(const Pipeline & pipeline)670 ANGLE_INLINE void SecondaryCommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline)
671 {
672     BindPipelineParams *paramStruct =
673         initCommand<BindPipelineParams>(CommandID::BindGraphicsPipeline);
674     paramStruct->pipeline = pipeline.getHandle();
675 }
676 
bindIndexBuffer(const Buffer & buffer,VkDeviceSize offset,VkIndexType indexType)677 ANGLE_INLINE void SecondaryCommandBuffer::bindIndexBuffer(const Buffer &buffer,
678                                                           VkDeviceSize offset,
679                                                           VkIndexType indexType)
680 {
681     BindIndexBufferParams *paramStruct =
682         initCommand<BindIndexBufferParams>(CommandID::BindIndexBuffer);
683     paramStruct->buffer    = buffer.getHandle();
684     paramStruct->offset    = offset;
685     paramStruct->indexType = indexType;
686 }
687 
bindVertexBuffers(uint32_t firstBinding,uint32_t bindingCount,const VkBuffer * buffers,const VkDeviceSize * offsets)688 ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers(uint32_t firstBinding,
689                                                             uint32_t bindingCount,
690                                                             const VkBuffer *buffers,
691                                                             const VkDeviceSize *offsets)
692 {
693     ASSERT(firstBinding == 0);
694     uint8_t *writePtr;
695     size_t buffersSize                   = bindingCount * sizeof(VkBuffer);
696     size_t offsetsSize                   = bindingCount * sizeof(VkDeviceSize);
697     BindVertexBuffersParams *paramStruct = initCommand<BindVertexBuffersParams>(
698         CommandID::BindVertexBuffers, buffersSize + offsetsSize, &writePtr);
699     // Copy params
700     paramStruct->bindingCount = bindingCount;
701     writePtr                  = storePointerParameter(writePtr, buffers, buffersSize);
702     storePointerParameter(writePtr, offsets, offsetsSize);
703 }
704 
blitImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageBlit * regions,VkFilter filter)705 ANGLE_INLINE void SecondaryCommandBuffer::blitImage(const Image &srcImage,
706                                                     VkImageLayout srcImageLayout,
707                                                     const Image &dstImage,
708                                                     VkImageLayout dstImageLayout,
709                                                     uint32_t regionCount,
710                                                     const VkImageBlit *regions,
711                                                     VkFilter filter)
712 {
713     // Currently ANGLE uses limited params so verify those assumptions and update if they change
714     ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
715     ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
716     ASSERT(regionCount == 1);
717     BlitImageParams *paramStruct = initCommand<BlitImageParams>(CommandID::BlitImage);
718     paramStruct->srcImage        = srcImage.getHandle();
719     paramStruct->dstImage        = dstImage.getHandle();
720     paramStruct->filter          = filter;
721     paramStruct->region          = regions[0];
722 }
723 
clearAttachments(uint32_t attachmentCount,const VkClearAttachment * attachments,uint32_t rectCount,const VkClearRect * rects)724 ANGLE_INLINE void SecondaryCommandBuffer::clearAttachments(uint32_t attachmentCount,
725                                                            const VkClearAttachment *attachments,
726                                                            uint32_t rectCount,
727                                                            const VkClearRect *rects)
728 {
729     ASSERT(rectCount == 1);
730     uint8_t *writePtr;
731     size_t attachSize = attachmentCount * sizeof(VkClearAttachment);
732     ClearAttachmentsParams *paramStruct =
733         initCommand<ClearAttachmentsParams>(CommandID::ClearAttachments, attachSize, &writePtr);
734     paramStruct->attachmentCount = attachmentCount;
735     paramStruct->rect            = rects[0];
736     // Copy variable sized data
737     storePointerParameter(writePtr, attachments, attachSize);
738 }
739 
clearColorImage(const Image & image,VkImageLayout imageLayout,const VkClearColorValue & color,uint32_t rangeCount,const VkImageSubresourceRange * ranges)740 ANGLE_INLINE void SecondaryCommandBuffer::clearColorImage(const Image &image,
741                                                           VkImageLayout imageLayout,
742                                                           const VkClearColorValue &color,
743                                                           uint32_t rangeCount,
744                                                           const VkImageSubresourceRange *ranges)
745 {
746     ASSERT(rangeCount == 1);
747     ClearColorImageParams *paramStruct =
748         initCommand<ClearColorImageParams>(CommandID::ClearColorImage);
749     paramStruct->image       = image.getHandle();
750     paramStruct->imageLayout = imageLayout;
751     paramStruct->color       = color;
752     paramStruct->range       = ranges[0];
753 }
754 
clearDepthStencilImage(const Image & image,VkImageLayout imageLayout,const VkClearDepthStencilValue & depthStencil,uint32_t rangeCount,const VkImageSubresourceRange * ranges)755 ANGLE_INLINE void SecondaryCommandBuffer::clearDepthStencilImage(
756     const Image &image,
757     VkImageLayout imageLayout,
758     const VkClearDepthStencilValue &depthStencil,
759     uint32_t rangeCount,
760     const VkImageSubresourceRange *ranges)
761 {
762     ASSERT(rangeCount == 1);
763     ClearDepthStencilImageParams *paramStruct =
764         initCommand<ClearDepthStencilImageParams>(CommandID::ClearDepthStencilImage);
765     paramStruct->image        = image.getHandle();
766     paramStruct->imageLayout  = imageLayout;
767     paramStruct->depthStencil = depthStencil;
768     paramStruct->range        = ranges[0];
769 }
770 
copyBuffer(const Buffer & srcBuffer,const Buffer & destBuffer,uint32_t regionCount,const VkBufferCopy * regions)771 ANGLE_INLINE void SecondaryCommandBuffer::copyBuffer(const Buffer &srcBuffer,
772                                                      const Buffer &destBuffer,
773                                                      uint32_t regionCount,
774                                                      const VkBufferCopy *regions)
775 {
776     uint8_t *writePtr;
777     size_t regionSize = regionCount * sizeof(VkBufferCopy);
778     CopyBufferParams *paramStruct =
779         initCommand<CopyBufferParams>(CommandID::CopyBuffer, regionSize, &writePtr);
780     paramStruct->srcBuffer   = srcBuffer.getHandle();
781     paramStruct->destBuffer  = destBuffer.getHandle();
782     paramStruct->regionCount = regionCount;
783     // Copy variable sized data
784     storePointerParameter(writePtr, regions, regionSize);
785 }
786 
copyBufferToImage(VkBuffer srcBuffer,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkBufferImageCopy * regions)787 ANGLE_INLINE void SecondaryCommandBuffer::copyBufferToImage(VkBuffer srcBuffer,
788                                                             const Image &dstImage,
789                                                             VkImageLayout dstImageLayout,
790                                                             uint32_t regionCount,
791                                                             const VkBufferImageCopy *regions)
792 {
793     ASSERT(regionCount == 1);
794     CopyBufferToImageParams *paramStruct =
795         initCommand<CopyBufferToImageParams>(CommandID::CopyBufferToImage);
796     paramStruct->srcBuffer      = srcBuffer;
797     paramStruct->dstImage       = dstImage.getHandle();
798     paramStruct->dstImageLayout = dstImageLayout;
799     paramStruct->region         = regions[0];
800 }
801 
copyImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageCopy * regions)802 ANGLE_INLINE void SecondaryCommandBuffer::copyImage(const Image &srcImage,
803                                                     VkImageLayout srcImageLayout,
804                                                     const Image &dstImage,
805                                                     VkImageLayout dstImageLayout,
806                                                     uint32_t regionCount,
807                                                     const VkImageCopy *regions)
808 {
809     ASSERT(regionCount == 1);
810     CopyImageParams *paramStruct = initCommand<CopyImageParams>(CommandID::CopyImage);
811     paramStruct->srcImage        = srcImage.getHandle();
812     paramStruct->srcImageLayout  = srcImageLayout;
813     paramStruct->dstImage        = dstImage.getHandle();
814     paramStruct->dstImageLayout  = dstImageLayout;
815     paramStruct->region          = regions[0];
816 }
817 
copyImageToBuffer(const Image & srcImage,VkImageLayout srcImageLayout,VkBuffer dstBuffer,uint32_t regionCount,const VkBufferImageCopy * regions)818 ANGLE_INLINE void SecondaryCommandBuffer::copyImageToBuffer(const Image &srcImage,
819                                                             VkImageLayout srcImageLayout,
820                                                             VkBuffer dstBuffer,
821                                                             uint32_t regionCount,
822                                                             const VkBufferImageCopy *regions)
823 {
824     ASSERT(regionCount == 1);
825     CopyImageToBufferParams *paramStruct =
826         initCommand<CopyImageToBufferParams>(CommandID::CopyImageToBuffer);
827     paramStruct->srcImage       = srcImage.getHandle();
828     paramStruct->srcImageLayout = srcImageLayout;
829     paramStruct->dstBuffer      = dstBuffer;
830     paramStruct->region         = regions[0];
831 }
832 
dispatch(uint32_t groupCountX,uint32_t groupCountY,uint32_t groupCountZ)833 ANGLE_INLINE void SecondaryCommandBuffer::dispatch(uint32_t groupCountX,
834                                                    uint32_t groupCountY,
835                                                    uint32_t groupCountZ)
836 {
837     DispatchParams *paramStruct = initCommand<DispatchParams>(CommandID::Dispatch);
838     paramStruct->groupCountX    = groupCountX;
839     paramStruct->groupCountY    = groupCountY;
840     paramStruct->groupCountZ    = groupCountZ;
841 }
842 
dispatchIndirect(const Buffer & buffer,VkDeviceSize offset)843 ANGLE_INLINE void SecondaryCommandBuffer::dispatchIndirect(const Buffer &buffer,
844                                                            VkDeviceSize offset)
845 {
846     DispatchIndirectParams *paramStruct =
847         initCommand<DispatchIndirectParams>(CommandID::DispatchIndirect);
848     paramStruct->buffer = buffer.getHandle();
849     paramStruct->offset = offset;
850 }
851 
draw(uint32_t vertexCount,uint32_t firstVertex)852 ANGLE_INLINE void SecondaryCommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex)
853 {
854     DrawParams *paramStruct  = initCommand<DrawParams>(CommandID::Draw);
855     paramStruct->vertexCount = vertexCount;
856     paramStruct->firstVertex = firstVertex;
857 }
858 
drawIndexed(uint32_t indexCount)859 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount)
860 {
861     DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed);
862     paramStruct->indexCount        = indexCount;
863 }
864 
drawIndexedInstanced(uint32_t indexCount,uint32_t instanceCount)865 ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstanced(uint32_t indexCount,
866                                                                uint32_t instanceCount)
867 {
868     DrawIndexedInstancedParams *paramStruct =
869         initCommand<DrawIndexedInstancedParams>(CommandID::DrawIndexedInstanced);
870     paramStruct->indexCount    = indexCount;
871     paramStruct->instanceCount = instanceCount;
872 }
873 
drawInstanced(uint32_t vertexCount,uint32_t instanceCount,uint32_t firstVertex)874 ANGLE_INLINE void SecondaryCommandBuffer::drawInstanced(uint32_t vertexCount,
875                                                         uint32_t instanceCount,
876                                                         uint32_t firstVertex)
877 {
878     DrawInstancedParams *paramStruct = initCommand<DrawInstancedParams>(CommandID::DrawInstanced);
879     paramStruct->vertexCount         = vertexCount;
880     paramStruct->instanceCount       = instanceCount;
881     paramStruct->firstVertex         = firstVertex;
882 }
883 
endQuery(VkQueryPool queryPool,uint32_t query)884 ANGLE_INLINE void SecondaryCommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query)
885 {
886     EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery);
887     paramStruct->queryPool      = queryPool;
888     paramStruct->query          = query;
889 }
890 
executionBarrier(VkPipelineStageFlags stageMask)891 ANGLE_INLINE void SecondaryCommandBuffer::executionBarrier(VkPipelineStageFlags stageMask)
892 {
893     ExecutionBarrierParams *paramStruct =
894         initCommand<ExecutionBarrierParams>(CommandID::ExecutionBarrier);
895     paramStruct->stageMask = stageMask;
896 }
897 
fillBuffer(const Buffer & dstBuffer,VkDeviceSize dstOffset,VkDeviceSize size,uint32_t data)898 ANGLE_INLINE void SecondaryCommandBuffer::fillBuffer(const Buffer &dstBuffer,
899                                                      VkDeviceSize dstOffset,
900                                                      VkDeviceSize size,
901                                                      uint32_t data)
902 {
903     FillBufferParams *paramStruct = initCommand<FillBufferParams>(CommandID::FillBuffer);
904     paramStruct->dstBuffer        = dstBuffer.getHandle();
905     paramStruct->dstOffset        = dstOffset;
906     paramStruct->size             = size;
907     paramStruct->data             = data;
908 }
909 
imageBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkImageMemoryBarrier * imageMemoryBarrier)910 ANGLE_INLINE void SecondaryCommandBuffer::imageBarrier(
911     VkPipelineStageFlags srcStageMask,
912     VkPipelineStageFlags dstStageMask,
913     const VkImageMemoryBarrier *imageMemoryBarrier)
914 {
915     ImageBarrierParams *paramStruct = initCommand<ImageBarrierParams>(CommandID::ImageBarrier);
916     paramStruct->srcStageMask       = srcStageMask;
917     paramStruct->dstStageMask       = dstStageMask;
918     paramStruct->imageMemoryBarrier = *imageMemoryBarrier;
919 }
920 
memoryBarrier(VkPipelineStageFlags srcStageMask,VkPipelineStageFlags dstStageMask,const VkMemoryBarrier * memoryBarrier)921 ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask,
922                                                         VkPipelineStageFlags dstStageMask,
923                                                         const VkMemoryBarrier *memoryBarrier)
924 {
925     MemoryBarrierParams *paramStruct = initCommand<MemoryBarrierParams>(CommandID::MemoryBarrier);
926     paramStruct->srcStageMask        = srcStageMask;
927     paramStruct->dstStageMask        = dstStageMask;
928     paramStruct->memoryBarrier       = *memoryBarrier;
929 }
930 
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)931 ANGLE_INLINE void SecondaryCommandBuffer::pipelineBarrier(
932     VkPipelineStageFlags srcStageMask,
933     VkPipelineStageFlags dstStageMask,
934     VkDependencyFlags dependencyFlags,
935     uint32_t memoryBarrierCount,
936     const VkMemoryBarrier *memoryBarriers,
937     uint32_t bufferMemoryBarrierCount,
938     const VkBufferMemoryBarrier *bufferMemoryBarriers,
939     uint32_t imageMemoryBarrierCount,
940     const VkImageMemoryBarrier *imageMemoryBarriers)
941 {
942     uint8_t *writePtr;
943     size_t memBarrierSize              = memoryBarrierCount * sizeof(VkMemoryBarrier);
944     size_t buffBarrierSize             = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
945     size_t imgBarrierSize              = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
946     PipelineBarrierParams *paramStruct = initCommand<PipelineBarrierParams>(
947         CommandID::PipelineBarrier, memBarrierSize + buffBarrierSize + imgBarrierSize, &writePtr);
948     paramStruct->srcStageMask             = srcStageMask;
949     paramStruct->dstStageMask             = dstStageMask;
950     paramStruct->dependencyFlags          = dependencyFlags;
951     paramStruct->memoryBarrierCount       = memoryBarrierCount;
952     paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount;
953     paramStruct->imageMemoryBarrierCount  = imageMemoryBarrierCount;
954     // Copy variable sized data
955     writePtr = storePointerParameter(writePtr, memoryBarriers, memBarrierSize);
956     writePtr = storePointerParameter(writePtr, bufferMemoryBarriers, buffBarrierSize);
957     storePointerParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
958 }
959 
pushConstants(const PipelineLayout & layout,VkShaderStageFlags flag,uint32_t offset,uint32_t size,const void * data)960 ANGLE_INLINE void SecondaryCommandBuffer::pushConstants(const PipelineLayout &layout,
961                                                         VkShaderStageFlags flag,
962                                                         uint32_t offset,
963                                                         uint32_t size,
964                                                         const void *data)
965 {
966     ASSERT(size == static_cast<size_t>(size));
967     uint8_t *writePtr;
968     PushConstantsParams *paramStruct = initCommand<PushConstantsParams>(
969         CommandID::PushConstants, static_cast<size_t>(size), &writePtr);
970     paramStruct->layout = layout.getHandle();
971     paramStruct->flag   = flag;
972     paramStruct->offset = offset;
973     paramStruct->size   = size;
974     // Copy variable sized data
975     storePointerParameter(writePtr, data, static_cast<size_t>(size));
976 }
977 
resetEvent(VkEvent event,VkPipelineStageFlags stageMask)978 ANGLE_INLINE void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask)
979 {
980     ResetEventParams *paramStruct = initCommand<ResetEventParams>(CommandID::ResetEvent);
981     paramStruct->event            = event;
982     paramStruct->stageMask        = stageMask;
983 }
984 
resetQueryPool(VkQueryPool queryPool,uint32_t firstQuery,uint32_t queryCount)985 ANGLE_INLINE void SecondaryCommandBuffer::resetQueryPool(VkQueryPool queryPool,
986                                                          uint32_t firstQuery,
987                                                          uint32_t queryCount)
988 {
989     ResetQueryPoolParams *paramStruct =
990         initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool);
991     paramStruct->queryPool  = queryPool;
992     paramStruct->firstQuery = firstQuery;
993     paramStruct->queryCount = queryCount;
994 }
995 
resolveImage(const Image & srcImage,VkImageLayout srcImageLayout,const Image & dstImage,VkImageLayout dstImageLayout,uint32_t regionCount,const VkImageResolve * regions)996 ANGLE_INLINE void SecondaryCommandBuffer::resolveImage(const Image &srcImage,
997                                                        VkImageLayout srcImageLayout,
998                                                        const Image &dstImage,
999                                                        VkImageLayout dstImageLayout,
1000                                                        uint32_t regionCount,
1001                                                        const VkImageResolve *regions)
1002 {
1003     // Currently ANGLE uses limited params so verify those assumptions and update if they change.
1004     ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL);
1005     ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL);
1006     ASSERT(regionCount == 1);
1007     ResolveImageParams *paramStruct = initCommand<ResolveImageParams>(CommandID::ResolveImage);
1008     paramStruct->srcImage           = srcImage.getHandle();
1009     paramStruct->dstImage           = dstImage.getHandle();
1010     paramStruct->region             = regions[0];
1011 }
1012 
setEvent(VkEvent event,VkPipelineStageFlags stageMask)1013 ANGLE_INLINE void SecondaryCommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask)
1014 {
1015     SetEventParams *paramStruct = initCommand<SetEventParams>(CommandID::SetEvent);
1016     paramStruct->event          = event;
1017     paramStruct->stageMask      = stageMask;
1018 }
1019 
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)1020 ANGLE_INLINE void SecondaryCommandBuffer::waitEvents(
1021     uint32_t eventCount,
1022     const VkEvent *events,
1023     VkPipelineStageFlags srcStageMask,
1024     VkPipelineStageFlags dstStageMask,
1025     uint32_t memoryBarrierCount,
1026     const VkMemoryBarrier *memoryBarriers,
1027     uint32_t bufferMemoryBarrierCount,
1028     const VkBufferMemoryBarrier *bufferMemoryBarriers,
1029     uint32_t imageMemoryBarrierCount,
1030     const VkImageMemoryBarrier *imageMemoryBarriers)
1031 {
1032     uint8_t *writePtr;
1033     size_t eventSize              = eventCount * sizeof(VkEvent);
1034     size_t memBarrierSize         = memoryBarrierCount * sizeof(VkMemoryBarrier);
1035     size_t buffBarrierSize        = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier);
1036     size_t imgBarrierSize         = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier);
1037     WaitEventsParams *paramStruct = initCommand<WaitEventsParams>(
1038         CommandID::WaitEvents, eventSize + memBarrierSize + buffBarrierSize + imgBarrierSize,
1039         &writePtr);
1040     paramStruct->eventCount               = eventCount;
1041     paramStruct->srcStageMask             = srcStageMask;
1042     paramStruct->dstStageMask             = dstStageMask;
1043     paramStruct->memoryBarrierCount       = memoryBarrierCount;
1044     paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount;
1045     paramStruct->imageMemoryBarrierCount  = imageMemoryBarrierCount;
1046     // Copy variable sized data
1047     writePtr = storePointerParameter(writePtr, events, eventSize);
1048     writePtr = storePointerParameter(writePtr, memoryBarriers, memBarrierSize);
1049     writePtr = storePointerParameter(writePtr, bufferMemoryBarriers, buffBarrierSize);
1050     storePointerParameter(writePtr, imageMemoryBarriers, imgBarrierSize);
1051 }
1052 
writeTimestamp(VkPipelineStageFlagBits pipelineStage,VkQueryPool queryPool,uint32_t query)1053 ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage,
1054                                                          VkQueryPool queryPool,
1055                                                          uint32_t query)
1056 {
1057     WriteTimestampParams *paramStruct =
1058         initCommand<WriteTimestampParams>(CommandID::WriteTimestamp);
1059     paramStruct->pipelineStage = pipelineStage;
1060     paramStruct->queryPool     = queryPool;
1061     paramStruct->query         = query;
1062 }
1063 }  // namespace priv
1064 }  // namespace vk
1065 }  // namespace rx
1066 
1067 #endif  // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_
1068