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