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