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