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