| // |
| // Copyright 2019 The ANGLE Project Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| // |
| // SecondaryCommandBuffer: |
| // Lightweight, CPU-Side command buffers used to hold command state until |
| // it has to be submitted to GPU. |
| // |
| |
| #ifndef LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_ |
| #define LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_ |
| |
| #include "volk.h" |
| |
| #include "common/PoolAlloc.h" |
| #include "libANGLE/renderer/vulkan/vk_wrapper.h" |
| |
| namespace rx |
| { |
| |
| namespace vk |
| { |
| |
| namespace priv |
| { |
| |
| enum class CommandID : uint16_t |
| { |
| // Invalid cmd used to mark end of sequence of commands |
| Invalid = 0, |
| BeginQuery, |
| BindComputePipeline, |
| BindDescriptorSets, |
| BindGraphicsPipeline, |
| BindIndexBuffer, |
| BindTransformFeedbackBuffers, |
| BindVertexBuffers, |
| BlitImage, |
| BufferBarrier, |
| ClearAttachments, |
| ClearColorImage, |
| ClearDepthStencilImage, |
| CopyBuffer, |
| CopyBufferToImage, |
| CopyImage, |
| CopyImageToBuffer, |
| Dispatch, |
| DispatchIndirect, |
| Draw, |
| DrawIndexed, |
| DrawIndexedBaseVertex, |
| DrawIndexedInstanced, |
| DrawIndexedInstancedBaseVertex, |
| DrawIndexedInstancedBaseVertexBaseInstance, |
| DrawInstanced, |
| DrawInstancedBaseInstance, |
| DrawIndirect, |
| DrawIndexedIndirect, |
| EndQuery, |
| ExecutionBarrier, |
| FillBuffer, |
| ImageBarrier, |
| MemoryBarrier, |
| PipelineBarrier, |
| PushConstants, |
| ResetEvent, |
| ResetQueryPool, |
| ResolveImage, |
| SetEvent, |
| WaitEvents, |
| WriteTimestamp, |
| }; |
| |
| #define VERIFY_4_BYTE_ALIGNMENT(StructName) \ |
| static_assert((sizeof(StructName) % 4) == 0, "Check StructName alignment"); |
| |
| // Structs to encapsulate parameters for different commands |
| // This makes it easy to know the size of params & to copy params |
| // TODO: Could optimize the size of some of these structs through bit-packing |
| // and customizing sizing based on limited parameter sets used by ANGLE |
| struct BindPipelineParams |
| { |
| VkPipeline pipeline; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(BindPipelineParams) |
| |
| struct BindDescriptorSetParams |
| { |
| VkPipelineLayout layout; |
| VkPipelineBindPoint pipelineBindPoint; |
| uint32_t firstSet; |
| uint32_t descriptorSetCount; |
| uint32_t dynamicOffsetCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(BindDescriptorSetParams) |
| |
| struct BindIndexBufferParams |
| { |
| VkBuffer buffer; |
| VkDeviceSize offset; |
| VkIndexType indexType; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(BindIndexBufferParams) |
| |
| struct BindTransformFeedbackBuffersParams |
| { |
| // ANGLE always has firstBinding of 0 so not storing that currently |
| uint32_t bindingCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(BindTransformFeedbackBuffersParams) |
| |
| struct BindVertexBuffersParams |
| { |
| // ANGLE always has firstBinding of 0 so not storing that currently |
| uint32_t bindingCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(BindVertexBuffersParams) |
| |
| struct BlitImageParams |
| { |
| VkImage srcImage; |
| VkImage dstImage; |
| VkFilter filter; |
| VkImageBlit region; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(BlitImageParams) |
| |
| struct CopyBufferParams |
| { |
| VkBuffer srcBuffer; |
| VkBuffer destBuffer; |
| uint32_t regionCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(CopyBufferParams) |
| |
| struct CopyBufferToImageParams |
| { |
| VkBuffer srcBuffer; |
| VkImage dstImage; |
| VkImageLayout dstImageLayout; |
| VkBufferImageCopy region; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(CopyBufferToImageParams) |
| |
| struct CopyImageParams |
| { |
| VkImage srcImage; |
| VkImageLayout srcImageLayout; |
| VkImage dstImage; |
| VkImageLayout dstImageLayout; |
| VkImageCopy region; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(CopyImageParams) |
| |
| struct CopyImageToBufferParams |
| { |
| VkImage srcImage; |
| VkImageLayout srcImageLayout; |
| VkBuffer dstBuffer; |
| VkBufferImageCopy region; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(CopyImageToBufferParams) |
| |
| struct ClearAttachmentsParams |
| { |
| uint32_t attachmentCount; |
| VkClearRect rect; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(ClearAttachmentsParams) |
| |
| struct ClearColorImageParams |
| { |
| VkImage image; |
| VkImageLayout imageLayout; |
| VkClearColorValue color; |
| VkImageSubresourceRange range; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(ClearColorImageParams) |
| |
| struct ClearDepthStencilImageParams |
| { |
| VkImage image; |
| VkImageLayout imageLayout; |
| VkClearDepthStencilValue depthStencil; |
| VkImageSubresourceRange range; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(ClearDepthStencilImageParams) |
| |
| struct PushConstantsParams |
| { |
| VkPipelineLayout layout; |
| VkShaderStageFlags flag; |
| uint32_t offset; |
| uint32_t size; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(PushConstantsParams) |
| |
| struct DrawParams |
| { |
| uint32_t vertexCount; |
| uint32_t firstVertex; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawParams) |
| |
| struct DrawInstancedParams |
| { |
| uint32_t vertexCount; |
| uint32_t instanceCount; |
| uint32_t firstVertex; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawInstancedParams) |
| |
| struct DrawInstancedBaseInstanceParams |
| { |
| uint32_t vertexCount; |
| uint32_t instanceCount; |
| uint32_t firstVertex; |
| uint32_t firstInstance; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawInstancedBaseInstanceParams) |
| |
| struct DrawIndexedParams |
| { |
| uint32_t indexCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawIndexedParams) |
| |
| struct DrawIndexedBaseVertexParams |
| { |
| uint32_t indexCount; |
| uint32_t vertexOffset; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawIndexedBaseVertexParams) |
| |
| struct DrawIndexedInstancedParams |
| { |
| uint32_t indexCount; |
| uint32_t instanceCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawIndexedInstancedParams) |
| |
| struct DrawIndexedInstancedBaseVertexParams |
| { |
| uint32_t indexCount; |
| uint32_t instanceCount; |
| uint32_t vertexOffset; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawIndexedInstancedBaseVertexParams) |
| |
| struct DrawIndexedInstancedBaseVertexBaseInstanceParams |
| { |
| uint32_t indexCount; |
| uint32_t instanceCount; |
| uint32_t firstIndex; |
| int32_t vertexOffset; |
| uint32_t firstInstance; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawIndexedInstancedBaseVertexBaseInstanceParams) |
| |
| struct DrawIndexedIndirectParams |
| { |
| VkBuffer buffer; |
| VkDeviceSize offset; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawIndexedIndirectParams) |
| |
| struct DispatchParams |
| { |
| uint32_t groupCountX; |
| uint32_t groupCountY; |
| uint32_t groupCountZ; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DispatchParams) |
| |
| struct DrawIndirectParams |
| { |
| VkBuffer buffer; |
| VkDeviceSize offset; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DrawIndirectParams) |
| |
| struct DispatchIndirectParams |
| { |
| VkBuffer buffer; |
| VkDeviceSize offset; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(DispatchIndirectParams) |
| |
| struct FillBufferParams |
| { |
| VkBuffer dstBuffer; |
| VkDeviceSize dstOffset; |
| VkDeviceSize size; |
| uint32_t data; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(FillBufferParams) |
| |
| struct MemoryBarrierParams |
| { |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| VkMemoryBarrier memoryBarrier; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(MemoryBarrierParams) |
| |
| struct PipelineBarrierParams |
| { |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| VkDependencyFlags dependencyFlags; |
| uint32_t memoryBarrierCount; |
| uint32_t bufferMemoryBarrierCount; |
| uint32_t imageMemoryBarrierCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(PipelineBarrierParams) |
| |
| struct ExecutionBarrierParams |
| { |
| VkPipelineStageFlags stageMask; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(ExecutionBarrierParams) |
| |
| struct BufferBarrierParams |
| { |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| VkBufferMemoryBarrier bufferMemoryBarrier; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(BufferBarrierParams) |
| |
| struct ImageBarrierParams |
| { |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| VkImageMemoryBarrier imageMemoryBarrier; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(ImageBarrierParams) |
| |
| struct SetEventParams |
| { |
| VkEvent event; |
| VkPipelineStageFlags stageMask; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(SetEventParams) |
| |
| struct ResetEventParams |
| { |
| VkEvent event; |
| VkPipelineStageFlags stageMask; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(ResetEventParams) |
| |
| struct WaitEventsParams |
| { |
| uint32_t eventCount; |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| uint32_t memoryBarrierCount; |
| uint32_t bufferMemoryBarrierCount; |
| uint32_t imageMemoryBarrierCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(WaitEventsParams) |
| |
| struct ResetQueryPoolParams |
| { |
| VkQueryPool queryPool; |
| uint32_t firstQuery; |
| uint32_t queryCount; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(ResetQueryPoolParams) |
| |
| struct ResolveImageParams |
| { |
| VkImage srcImage; |
| VkImage dstImage; |
| VkImageResolve region; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(ResolveImageParams) |
| |
| struct BeginQueryParams |
| { |
| VkQueryPool queryPool; |
| uint32_t query; |
| VkQueryControlFlags flags; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(BeginQueryParams) |
| |
| struct EndQueryParams |
| { |
| VkQueryPool queryPool; |
| uint32_t query; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(EndQueryParams) |
| |
| struct WriteTimestampParams |
| { |
| VkPipelineStageFlagBits pipelineStage; |
| VkQueryPool queryPool; |
| uint32_t query; |
| }; |
| VERIFY_4_BYTE_ALIGNMENT(WriteTimestampParams) |
| |
| // Header for every cmd in custom cmd buffer |
| struct CommandHeader |
| { |
| CommandID id; |
| uint16_t size; |
| }; |
| |
| static_assert(sizeof(CommandHeader) == 4, "Check CommandHeader size"); |
| |
| template <typename DestT, typename T> |
| ANGLE_INLINE DestT *Offset(T *ptr, size_t bytes) |
| { |
| return reinterpret_cast<DestT *>((reinterpret_cast<uint8_t *>(ptr) + bytes)); |
| } |
| |
| template <typename DestT, typename T> |
| ANGLE_INLINE const DestT *Offset(const T *ptr, size_t bytes) |
| { |
| return reinterpret_cast<const DestT *>((reinterpret_cast<const uint8_t *>(ptr) + bytes)); |
| } |
| |
| class SecondaryCommandBuffer final : angle::NonCopyable |
| { |
| public: |
| SecondaryCommandBuffer(); |
| ~SecondaryCommandBuffer(); |
| |
| static bool SupportsQueries(const VkPhysicalDeviceFeatures &features) { return true; } |
| |
| // SecondaryCommandBuffer replays its commands inline when executed on the primary command |
| // buffer. |
| static constexpr bool ExecutesInline() { return true; } |
| |
| // Add commands |
| void beginQuery(VkQueryPool queryPool, uint32_t query, VkQueryControlFlags flags); |
| |
| void bindComputePipeline(const Pipeline &pipeline); |
| |
| void bindDescriptorSets(const PipelineLayout &layout, |
| VkPipelineBindPoint pipelineBindPoint, |
| uint32_t firstSet, |
| uint32_t descriptorSetCount, |
| const VkDescriptorSet *descriptorSets, |
| uint32_t dynamicOffsetCount, |
| const uint32_t *dynamicOffsets); |
| |
| void bindGraphicsPipeline(const Pipeline &pipeline); |
| |
| void bindIndexBuffer(const Buffer &buffer, VkDeviceSize offset, VkIndexType indexType); |
| |
| void bindTransformFeedbackBuffers(size_t bindingCount, |
| const VkBuffer *buffers, |
| const VkDeviceSize *offsets, |
| const VkDeviceSize *sizes); |
| |
| void bindVertexBuffers(uint32_t firstBinding, |
| uint32_t bindingCount, |
| const VkBuffer *buffers, |
| const VkDeviceSize *offsets); |
| |
| void blitImage(const Image &srcImage, |
| VkImageLayout srcImageLayout, |
| const Image &dstImage, |
| VkImageLayout dstImageLayout, |
| uint32_t regionCount, |
| const VkImageBlit *regions, |
| VkFilter filter); |
| |
| void bufferBarrier(VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkBufferMemoryBarrier *bufferMemoryBarrier); |
| |
| void clearAttachments(uint32_t attachmentCount, |
| const VkClearAttachment *attachments, |
| uint32_t rectCount, |
| const VkClearRect *rects); |
| |
| void clearColorImage(const Image &image, |
| VkImageLayout imageLayout, |
| const VkClearColorValue &color, |
| uint32_t rangeCount, |
| const VkImageSubresourceRange *ranges); |
| |
| void clearDepthStencilImage(const Image &image, |
| VkImageLayout imageLayout, |
| const VkClearDepthStencilValue &depthStencil, |
| uint32_t rangeCount, |
| const VkImageSubresourceRange *ranges); |
| |
| void copyBuffer(const Buffer &srcBuffer, |
| const Buffer &destBuffer, |
| uint32_t regionCount, |
| const VkBufferCopy *regions); |
| |
| void copyBufferToImage(VkBuffer srcBuffer, |
| const Image &dstImage, |
| VkImageLayout dstImageLayout, |
| uint32_t regionCount, |
| const VkBufferImageCopy *regions); |
| |
| void copyImage(const Image &srcImage, |
| VkImageLayout srcImageLayout, |
| const Image &dstImage, |
| VkImageLayout dstImageLayout, |
| uint32_t regionCount, |
| const VkImageCopy *regions); |
| |
| void copyImageToBuffer(const Image &srcImage, |
| VkImageLayout srcImageLayout, |
| VkBuffer dstBuffer, |
| uint32_t regionCount, |
| const VkBufferImageCopy *regions); |
| |
| void dispatch(uint32_t groupCountX, uint32_t groupCountY, uint32_t groupCountZ); |
| |
| void dispatchIndirect(const Buffer &buffer, VkDeviceSize offset); |
| |
| void draw(uint32_t vertexCount, uint32_t firstVertex); |
| |
| void drawIndexed(uint32_t indexCount); |
| void drawIndexedBaseVertex(uint32_t indexCount, uint32_t vertexOffset); |
| |
| void drawIndexedInstanced(uint32_t indexCount, uint32_t instanceCount); |
| void drawIndexedInstancedBaseVertex(uint32_t indexCount, |
| uint32_t instanceCount, |
| uint32_t vertexOffset); |
| void drawIndexedInstancedBaseVertexBaseInstance(uint32_t indexCount, |
| uint32_t instanceCount, |
| uint32_t firstIndex, |
| int32_t vertexOffset, |
| uint32_t firstInstance); |
| |
| void drawInstanced(uint32_t vertexCount, uint32_t instanceCount, uint32_t firstVertex); |
| void drawInstancedBaseInstance(uint32_t vertexCount, |
| uint32_t instanceCount, |
| uint32_t firstVertex, |
| uint32_t firstInstance); |
| |
| void drawIndirect(const Buffer &buffer, |
| VkDeviceSize offset, |
| uint32_t drawCount, |
| uint32_t stride); |
| void drawIndexedIndirect(const Buffer &buffer, |
| VkDeviceSize offset, |
| uint32_t drawCount, |
| uint32_t stride); |
| |
| void endQuery(VkQueryPool queryPool, uint32_t query); |
| |
| void executionBarrier(VkPipelineStageFlags stageMask); |
| |
| void fillBuffer(const Buffer &dstBuffer, |
| VkDeviceSize dstOffset, |
| VkDeviceSize size, |
| uint32_t data); |
| |
| void imageBarrier(VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkImageMemoryBarrier *imageMemoryBarrier); |
| |
| void memoryBarrier(VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkMemoryBarrier *memoryBarrier); |
| |
| void 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); |
| |
| void pushConstants(const PipelineLayout &layout, |
| VkShaderStageFlags flag, |
| uint32_t offset, |
| uint32_t size, |
| const void *data); |
| |
| void resetEvent(VkEvent event, VkPipelineStageFlags stageMask); |
| |
| void resetQueryPool(VkQueryPool queryPool, uint32_t firstQuery, uint32_t queryCount); |
| |
| void resolveImage(const Image &srcImage, |
| VkImageLayout srcImageLayout, |
| const Image &dstImage, |
| VkImageLayout dstImageLayout, |
| uint32_t regionCount, |
| const VkImageResolve *regions); |
| |
| void setEvent(VkEvent event, VkPipelineStageFlags stageMask); |
| |
| void 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); |
| |
| void writeTimestamp(VkPipelineStageFlagBits pipelineStage, |
| VkQueryPool queryPool, |
| uint32_t query); |
| // No-op for compatibility |
| VkResult end() { return VK_SUCCESS; } |
| |
| // Parse the cmds in this cmd buffer into given primary cmd buffer for execution |
| void executeCommands(VkCommandBuffer cmdBuffer); |
| |
| // Calculate memory usage of this command buffer for diagnostics. |
| void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const; |
| |
| // Traverse the list of commands and build a summary for diagnostics. |
| std::string dumpCommands(const char *separator) const; |
| |
| // Pool Alloc uses 16kB pages w/ 16byte header = 16368bytes. To minimize waste |
| // using a 16368/12 = 1364. Also better perf than 1024 due to fewer block allocations |
| static constexpr size_t kBlockSize = 1364; |
| // Make sure block size is 4-byte aligned to avoid Android errors |
| static_assert((kBlockSize % 4) == 0, "Check kBlockSize alignment"); |
| |
| // Initialize the SecondaryCommandBuffer by setting the allocator it will use |
| void initialize(angle::PoolAllocator *allocator) |
| { |
| ASSERT(allocator); |
| mAllocator = allocator; |
| allocateNewBlock(); |
| // Set first command to Invalid to start |
| reinterpret_cast<CommandHeader *>(mCurrentWritePointer)->id = CommandID::Invalid; |
| } |
| |
| void reset() |
| { |
| mCommands.clear(); |
| initialize(mAllocator); |
| } |
| |
| // This will cause the SecondaryCommandBuffer to become invalid by clearing its allocator |
| void releaseHandle() { mAllocator = nullptr; } |
| // The SecondaryCommandBuffer is valid if it's been initialized |
| bool valid() const { return mAllocator != nullptr; } |
| |
| static bool CanKnowIfEmpty() { return true; } |
| bool empty() const { return mCommands.size() == 0 || mCommands[0]->id == CommandID::Invalid; } |
| |
| private: |
| template <class StructType> |
| ANGLE_INLINE StructType *commonInit(CommandID cmdID, size_t allocationSize) |
| { |
| mCurrentBytesRemaining -= allocationSize; |
| |
| CommandHeader *header = reinterpret_cast<CommandHeader *>(mCurrentWritePointer); |
| header->id = cmdID; |
| header->size = static_cast<uint16_t>(allocationSize); |
| ASSERT(allocationSize <= std::numeric_limits<uint16_t>::max()); |
| |
| mCurrentWritePointer += allocationSize; |
| // Set next cmd header to Invalid (0) so cmd sequence will be terminated |
| reinterpret_cast<CommandHeader *>(mCurrentWritePointer)->id = CommandID::Invalid; |
| return Offset<StructType>(header, sizeof(CommandHeader)); |
| } |
| ANGLE_INLINE void allocateNewBlock() |
| { |
| ASSERT(mAllocator); |
| mCurrentWritePointer = mAllocator->fastAllocate(kBlockSize); |
| mCurrentBytesRemaining = kBlockSize; |
| mCommands.push_back(reinterpret_cast<CommandHeader *>(mCurrentWritePointer)); |
| } |
| |
| // Allocate and initialize memory for given commandID & variable param size, setting |
| // variableDataPtr to the byte following fixed cmd data where variable-sized ptr data will |
| // be written and returning a pointer to the start of the command's parameter data |
| template <class StructType> |
| ANGLE_INLINE StructType *initCommand(CommandID cmdID, |
| size_t variableSize, |
| uint8_t **variableDataPtr) |
| { |
| constexpr size_t fixedAllocationSize = sizeof(StructType) + sizeof(CommandHeader); |
| const size_t allocationSize = fixedAllocationSize + variableSize; |
| // Make sure we have enough room to mark follow-on header "Invalid" |
| if (mCurrentBytesRemaining <= (allocationSize + sizeof(CommandHeader))) |
| { |
| allocateNewBlock(); |
| } |
| *variableDataPtr = Offset<uint8_t>(mCurrentWritePointer, fixedAllocationSize); |
| return commonInit<StructType>(cmdID, allocationSize); |
| } |
| |
| // Initialize a command that doesn't have variable-sized ptr data |
| template <class StructType> |
| ANGLE_INLINE StructType *initCommand(CommandID cmdID) |
| { |
| constexpr size_t allocationSize = sizeof(StructType) + sizeof(CommandHeader); |
| // Make sure we have enough room to mark follow-on header "Invalid" |
| if (mCurrentBytesRemaining <= (allocationSize + sizeof(CommandHeader))) |
| { |
| allocateNewBlock(); |
| } |
| return commonInit<StructType>(cmdID, allocationSize); |
| } |
| |
| // Return a ptr to the parameter type |
| template <class StructType> |
| const StructType *getParamPtr(const CommandHeader *header) const |
| { |
| return reinterpret_cast<const StructType *>(reinterpret_cast<const uint8_t *>(header) + |
| sizeof(CommandHeader)); |
| } |
| // Copy sizeInBytes data from paramData to writePointer & return writePointer plus sizeInBytes. |
| template <class PtrType> |
| ANGLE_INLINE uint8_t *storePointerParameter(uint8_t *writePointer, |
| const PtrType *paramData, |
| size_t sizeInBytes) |
| { |
| memcpy(writePointer, paramData, sizeInBytes); |
| return writePointer + sizeInBytes; |
| } |
| |
| std::vector<CommandHeader *> mCommands; |
| |
| // Allocator used by this class. If non-null then the class is valid. |
| angle::PoolAllocator *mAllocator; |
| |
| uint8_t *mCurrentWritePointer; |
| size_t mCurrentBytesRemaining; |
| }; |
| |
| ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer() |
| : mAllocator(nullptr), mCurrentWritePointer(nullptr), mCurrentBytesRemaining(0) |
| {} |
| ANGLE_INLINE SecondaryCommandBuffer::~SecondaryCommandBuffer() {} |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::beginQuery(VkQueryPool queryPool, |
| uint32_t query, |
| VkQueryControlFlags flags) |
| { |
| BeginQueryParams *paramStruct = initCommand<BeginQueryParams>(CommandID::BeginQuery); |
| paramStruct->queryPool = queryPool; |
| paramStruct->query = query; |
| paramStruct->flags = flags; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bindComputePipeline(const Pipeline &pipeline) |
| { |
| BindPipelineParams *paramStruct = |
| initCommand<BindPipelineParams>(CommandID::BindComputePipeline); |
| paramStruct->pipeline = pipeline.getHandle(); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bindDescriptorSets(const PipelineLayout &layout, |
| VkPipelineBindPoint pipelineBindPoint, |
| uint32_t firstSet, |
| uint32_t descriptorSetCount, |
| const VkDescriptorSet *descriptorSets, |
| uint32_t dynamicOffsetCount, |
| const uint32_t *dynamicOffsets) |
| { |
| size_t descSize = descriptorSetCount * sizeof(VkDescriptorSet); |
| size_t offsetSize = dynamicOffsetCount * sizeof(uint32_t); |
| uint8_t *writePtr; |
| BindDescriptorSetParams *paramStruct = initCommand<BindDescriptorSetParams>( |
| CommandID::BindDescriptorSets, descSize + offsetSize, &writePtr); |
| // Copy params into memory |
| paramStruct->layout = layout.getHandle(); |
| paramStruct->pipelineBindPoint = pipelineBindPoint; |
| paramStruct->firstSet = firstSet; |
| paramStruct->descriptorSetCount = descriptorSetCount; |
| paramStruct->dynamicOffsetCount = dynamicOffsetCount; |
| // Copy variable sized data |
| writePtr = storePointerParameter(writePtr, descriptorSets, descSize); |
| storePointerParameter(writePtr, dynamicOffsets, offsetSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bindGraphicsPipeline(const Pipeline &pipeline) |
| { |
| BindPipelineParams *paramStruct = |
| initCommand<BindPipelineParams>(CommandID::BindGraphicsPipeline); |
| paramStruct->pipeline = pipeline.getHandle(); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bindIndexBuffer(const Buffer &buffer, |
| VkDeviceSize offset, |
| VkIndexType indexType) |
| { |
| BindIndexBufferParams *paramStruct = |
| initCommand<BindIndexBufferParams>(CommandID::BindIndexBuffer); |
| paramStruct->buffer = buffer.getHandle(); |
| paramStruct->offset = offset; |
| paramStruct->indexType = indexType; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bindTransformFeedbackBuffers(size_t bindingCount, |
| const VkBuffer *buffers, |
| const VkDeviceSize *offsets, |
| const VkDeviceSize *sizes) |
| { |
| uint8_t *writePtr; |
| size_t buffersSize = bindingCount * sizeof(VkBuffer); |
| size_t offsetsSize = bindingCount * sizeof(VkDeviceSize); |
| size_t sizesSize = offsetsSize; |
| BindTransformFeedbackBuffersParams *paramStruct = |
| initCommand<BindTransformFeedbackBuffersParams>(CommandID::BindTransformFeedbackBuffers, |
| buffersSize + offsetsSize + sizesSize, |
| &writePtr); |
| // Copy params |
| paramStruct->bindingCount = static_cast<uint32_t>(bindingCount); |
| writePtr = storePointerParameter(writePtr, buffers, buffersSize); |
| writePtr = storePointerParameter(writePtr, offsets, offsetsSize); |
| storePointerParameter(writePtr, sizes, sizesSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers(uint32_t firstBinding, |
| uint32_t bindingCount, |
| const VkBuffer *buffers, |
| const VkDeviceSize *offsets) |
| { |
| ASSERT(firstBinding == 0); |
| uint8_t *writePtr; |
| size_t buffersSize = bindingCount * sizeof(VkBuffer); |
| size_t offsetsSize = bindingCount * sizeof(VkDeviceSize); |
| BindVertexBuffersParams *paramStruct = initCommand<BindVertexBuffersParams>( |
| CommandID::BindVertexBuffers, buffersSize + offsetsSize, &writePtr); |
| // Copy params |
| paramStruct->bindingCount = bindingCount; |
| writePtr = storePointerParameter(writePtr, buffers, buffersSize); |
| storePointerParameter(writePtr, offsets, offsetsSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::blitImage(const Image &srcImage, |
| VkImageLayout srcImageLayout, |
| const Image &dstImage, |
| VkImageLayout dstImageLayout, |
| uint32_t regionCount, |
| const VkImageBlit *regions, |
| VkFilter filter) |
| { |
| // Currently ANGLE uses limited params so verify those assumptions and update if they change |
| ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); |
| ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| ASSERT(regionCount == 1); |
| BlitImageParams *paramStruct = initCommand<BlitImageParams>(CommandID::BlitImage); |
| paramStruct->srcImage = srcImage.getHandle(); |
| paramStruct->dstImage = dstImage.getHandle(); |
| paramStruct->filter = filter; |
| paramStruct->region = regions[0]; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bufferBarrier( |
| VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkBufferMemoryBarrier *bufferMemoryBarrier) |
| { |
| BufferBarrierParams *paramStruct = initCommand<BufferBarrierParams>(CommandID::BufferBarrier); |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| paramStruct->bufferMemoryBarrier = *bufferMemoryBarrier; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::clearAttachments(uint32_t attachmentCount, |
| const VkClearAttachment *attachments, |
| uint32_t rectCount, |
| const VkClearRect *rects) |
| { |
| ASSERT(rectCount == 1); |
| uint8_t *writePtr; |
| size_t attachSize = attachmentCount * sizeof(VkClearAttachment); |
| ClearAttachmentsParams *paramStruct = |
| initCommand<ClearAttachmentsParams>(CommandID::ClearAttachments, attachSize, &writePtr); |
| paramStruct->attachmentCount = attachmentCount; |
| paramStruct->rect = rects[0]; |
| // Copy variable sized data |
| storePointerParameter(writePtr, attachments, attachSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::clearColorImage(const Image &image, |
| VkImageLayout imageLayout, |
| const VkClearColorValue &color, |
| uint32_t rangeCount, |
| const VkImageSubresourceRange *ranges) |
| { |
| ASSERT(rangeCount == 1); |
| ClearColorImageParams *paramStruct = |
| initCommand<ClearColorImageParams>(CommandID::ClearColorImage); |
| paramStruct->image = image.getHandle(); |
| paramStruct->imageLayout = imageLayout; |
| paramStruct->color = color; |
| paramStruct->range = ranges[0]; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::clearDepthStencilImage( |
| const Image &image, |
| VkImageLayout imageLayout, |
| const VkClearDepthStencilValue &depthStencil, |
| uint32_t rangeCount, |
| const VkImageSubresourceRange *ranges) |
| { |
| ASSERT(rangeCount == 1); |
| ClearDepthStencilImageParams *paramStruct = |
| initCommand<ClearDepthStencilImageParams>(CommandID::ClearDepthStencilImage); |
| paramStruct->image = image.getHandle(); |
| paramStruct->imageLayout = imageLayout; |
| paramStruct->depthStencil = depthStencil; |
| paramStruct->range = ranges[0]; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::copyBuffer(const Buffer &srcBuffer, |
| const Buffer &destBuffer, |
| uint32_t regionCount, |
| const VkBufferCopy *regions) |
| { |
| uint8_t *writePtr; |
| size_t regionSize = regionCount * sizeof(VkBufferCopy); |
| CopyBufferParams *paramStruct = |
| initCommand<CopyBufferParams>(CommandID::CopyBuffer, regionSize, &writePtr); |
| paramStruct->srcBuffer = srcBuffer.getHandle(); |
| paramStruct->destBuffer = destBuffer.getHandle(); |
| paramStruct->regionCount = regionCount; |
| // Copy variable sized data |
| storePointerParameter(writePtr, regions, regionSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::copyBufferToImage(VkBuffer srcBuffer, |
| const Image &dstImage, |
| VkImageLayout dstImageLayout, |
| uint32_t regionCount, |
| const VkBufferImageCopy *regions) |
| { |
| ASSERT(regionCount == 1); |
| CopyBufferToImageParams *paramStruct = |
| initCommand<CopyBufferToImageParams>(CommandID::CopyBufferToImage); |
| paramStruct->srcBuffer = srcBuffer; |
| paramStruct->dstImage = dstImage.getHandle(); |
| paramStruct->dstImageLayout = dstImageLayout; |
| paramStruct->region = regions[0]; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::copyImage(const Image &srcImage, |
| VkImageLayout srcImageLayout, |
| const Image &dstImage, |
| VkImageLayout dstImageLayout, |
| uint32_t regionCount, |
| const VkImageCopy *regions) |
| { |
| ASSERT(regionCount == 1); |
| CopyImageParams *paramStruct = initCommand<CopyImageParams>(CommandID::CopyImage); |
| paramStruct->srcImage = srcImage.getHandle(); |
| paramStruct->srcImageLayout = srcImageLayout; |
| paramStruct->dstImage = dstImage.getHandle(); |
| paramStruct->dstImageLayout = dstImageLayout; |
| paramStruct->region = regions[0]; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::copyImageToBuffer(const Image &srcImage, |
| VkImageLayout srcImageLayout, |
| VkBuffer dstBuffer, |
| uint32_t regionCount, |
| const VkBufferImageCopy *regions) |
| { |
| ASSERT(regionCount == 1); |
| CopyImageToBufferParams *paramStruct = |
| initCommand<CopyImageToBufferParams>(CommandID::CopyImageToBuffer); |
| paramStruct->srcImage = srcImage.getHandle(); |
| paramStruct->srcImageLayout = srcImageLayout; |
| paramStruct->dstBuffer = dstBuffer; |
| paramStruct->region = regions[0]; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::dispatch(uint32_t groupCountX, |
| uint32_t groupCountY, |
| uint32_t groupCountZ) |
| { |
| DispatchParams *paramStruct = initCommand<DispatchParams>(CommandID::Dispatch); |
| paramStruct->groupCountX = groupCountX; |
| paramStruct->groupCountY = groupCountY; |
| paramStruct->groupCountZ = groupCountZ; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::dispatchIndirect(const Buffer &buffer, |
| VkDeviceSize offset) |
| { |
| DispatchIndirectParams *paramStruct = |
| initCommand<DispatchIndirectParams>(CommandID::DispatchIndirect); |
| paramStruct->buffer = buffer.getHandle(); |
| paramStruct->offset = offset; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::draw(uint32_t vertexCount, uint32_t firstVertex) |
| { |
| DrawParams *paramStruct = initCommand<DrawParams>(CommandID::Draw); |
| paramStruct->vertexCount = vertexCount; |
| paramStruct->firstVertex = firstVertex; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount) |
| { |
| DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed); |
| paramStruct->indexCount = indexCount; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedBaseVertex(uint32_t indexCount, |
| uint32_t vertexOffset) |
| { |
| DrawIndexedBaseVertexParams *paramStruct = |
| initCommand<DrawIndexedBaseVertexParams>(CommandID::DrawIndexedBaseVertex); |
| paramStruct->indexCount = indexCount; |
| paramStruct->vertexOffset = vertexOffset; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstanced(uint32_t indexCount, |
| uint32_t instanceCount) |
| { |
| DrawIndexedInstancedParams *paramStruct = |
| initCommand<DrawIndexedInstancedParams>(CommandID::DrawIndexedInstanced); |
| paramStruct->indexCount = indexCount; |
| paramStruct->instanceCount = instanceCount; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertex(uint32_t indexCount, |
| uint32_t instanceCount, |
| uint32_t vertexOffset) |
| { |
| DrawIndexedInstancedBaseVertexParams *paramStruct = |
| initCommand<DrawIndexedInstancedBaseVertexParams>( |
| CommandID::DrawIndexedInstancedBaseVertex); |
| paramStruct->indexCount = indexCount; |
| paramStruct->instanceCount = instanceCount; |
| paramStruct->vertexOffset = vertexOffset; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstancedBaseVertexBaseInstance( |
| uint32_t indexCount, |
| uint32_t instanceCount, |
| uint32_t firstIndex, |
| int32_t vertexOffset, |
| uint32_t firstInstance) |
| { |
| DrawIndexedInstancedBaseVertexBaseInstanceParams *paramStruct = |
| initCommand<DrawIndexedInstancedBaseVertexBaseInstanceParams>( |
| CommandID::DrawIndexedInstancedBaseVertexBaseInstance); |
| paramStruct->indexCount = indexCount; |
| paramStruct->instanceCount = instanceCount; |
| paramStruct->firstIndex = firstIndex; |
| paramStruct->vertexOffset = vertexOffset; |
| paramStruct->firstInstance = firstInstance; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawInstanced(uint32_t vertexCount, |
| uint32_t instanceCount, |
| uint32_t firstVertex) |
| { |
| DrawInstancedParams *paramStruct = initCommand<DrawInstancedParams>(CommandID::DrawInstanced); |
| paramStruct->vertexCount = vertexCount; |
| paramStruct->instanceCount = instanceCount; |
| paramStruct->firstVertex = firstVertex; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawInstancedBaseInstance(uint32_t vertexCount, |
| uint32_t instanceCount, |
| uint32_t firstVertex, |
| uint32_t firstInstance) |
| { |
| DrawInstancedBaseInstanceParams *paramStruct = |
| initCommand<DrawInstancedBaseInstanceParams>(CommandID::DrawInstancedBaseInstance); |
| paramStruct->vertexCount = vertexCount; |
| paramStruct->instanceCount = instanceCount; |
| paramStruct->firstVertex = firstVertex; |
| paramStruct->firstInstance = firstInstance; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndirect(const Buffer &buffer, |
| VkDeviceSize offset, |
| uint32_t drawCount, |
| uint32_t stride) |
| { |
| DrawIndirectParams *paramStruct = initCommand<DrawIndirectParams>(CommandID::DrawIndirect); |
| paramStruct->buffer = buffer.getHandle(); |
| paramStruct->offset = offset; |
| |
| // OpenGL ES doesn't have a way to specify a drawCount or stride, throw assert if something |
| // changes. |
| ASSERT(drawCount == 1); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedIndirect(const Buffer &buffer, |
| VkDeviceSize offset, |
| uint32_t drawCount, |
| uint32_t stride) |
| { |
| DrawIndexedIndirectParams *paramStruct = |
| initCommand<DrawIndexedIndirectParams>(CommandID::DrawIndexedIndirect); |
| paramStruct->buffer = buffer.getHandle(); |
| paramStruct->offset = offset; |
| ASSERT(drawCount == 1); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::endQuery(VkQueryPool queryPool, uint32_t query) |
| { |
| EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery); |
| paramStruct->queryPool = queryPool; |
| paramStruct->query = query; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::executionBarrier(VkPipelineStageFlags stageMask) |
| { |
| ExecutionBarrierParams *paramStruct = |
| initCommand<ExecutionBarrierParams>(CommandID::ExecutionBarrier); |
| paramStruct->stageMask = stageMask; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::fillBuffer(const Buffer &dstBuffer, |
| VkDeviceSize dstOffset, |
| VkDeviceSize size, |
| uint32_t data) |
| { |
| FillBufferParams *paramStruct = initCommand<FillBufferParams>(CommandID::FillBuffer); |
| paramStruct->dstBuffer = dstBuffer.getHandle(); |
| paramStruct->dstOffset = dstOffset; |
| paramStruct->size = size; |
| paramStruct->data = data; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::imageBarrier( |
| VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkImageMemoryBarrier *imageMemoryBarrier) |
| { |
| ImageBarrierParams *paramStruct = initCommand<ImageBarrierParams>(CommandID::ImageBarrier); |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| paramStruct->imageMemoryBarrier = *imageMemoryBarrier; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkMemoryBarrier *memoryBarrier) |
| { |
| MemoryBarrierParams *paramStruct = initCommand<MemoryBarrierParams>(CommandID::MemoryBarrier); |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| paramStruct->memoryBarrier = *memoryBarrier; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::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) |
| { |
| uint8_t *writePtr; |
| size_t memBarrierSize = memoryBarrierCount * sizeof(VkMemoryBarrier); |
| size_t buffBarrierSize = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier); |
| size_t imgBarrierSize = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier); |
| PipelineBarrierParams *paramStruct = initCommand<PipelineBarrierParams>( |
| CommandID::PipelineBarrier, memBarrierSize + buffBarrierSize + imgBarrierSize, &writePtr); |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| paramStruct->dependencyFlags = dependencyFlags; |
| paramStruct->memoryBarrierCount = memoryBarrierCount; |
| paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount; |
| paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount; |
| // Copy variable sized data |
| writePtr = storePointerParameter(writePtr, memoryBarriers, memBarrierSize); |
| writePtr = storePointerParameter(writePtr, bufferMemoryBarriers, buffBarrierSize); |
| storePointerParameter(writePtr, imageMemoryBarriers, imgBarrierSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::pushConstants(const PipelineLayout &layout, |
| VkShaderStageFlags flag, |
| uint32_t offset, |
| uint32_t size, |
| const void *data) |
| { |
| ASSERT(size == static_cast<size_t>(size)); |
| uint8_t *writePtr; |
| PushConstantsParams *paramStruct = initCommand<PushConstantsParams>( |
| CommandID::PushConstants, static_cast<size_t>(size), &writePtr); |
| paramStruct->layout = layout.getHandle(); |
| paramStruct->flag = flag; |
| paramStruct->offset = offset; |
| paramStruct->size = size; |
| // Copy variable sized data |
| storePointerParameter(writePtr, data, static_cast<size_t>(size)); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::resetEvent(VkEvent event, VkPipelineStageFlags stageMask) |
| { |
| ResetEventParams *paramStruct = initCommand<ResetEventParams>(CommandID::ResetEvent); |
| paramStruct->event = event; |
| paramStruct->stageMask = stageMask; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::resetQueryPool(VkQueryPool queryPool, |
| uint32_t firstQuery, |
| uint32_t queryCount) |
| { |
| ResetQueryPoolParams *paramStruct = |
| initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool); |
| paramStruct->queryPool = queryPool; |
| paramStruct->firstQuery = firstQuery; |
| paramStruct->queryCount = queryCount; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::resolveImage(const Image &srcImage, |
| VkImageLayout srcImageLayout, |
| const Image &dstImage, |
| VkImageLayout dstImageLayout, |
| uint32_t regionCount, |
| const VkImageResolve *regions) |
| { |
| // Currently ANGLE uses limited params so verify those assumptions and update if they change. |
| ASSERT(srcImageLayout == VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL); |
| ASSERT(dstImageLayout == VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL); |
| ASSERT(regionCount == 1); |
| ResolveImageParams *paramStruct = initCommand<ResolveImageParams>(CommandID::ResolveImage); |
| paramStruct->srcImage = srcImage.getHandle(); |
| paramStruct->dstImage = dstImage.getHandle(); |
| paramStruct->region = regions[0]; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setEvent(VkEvent event, VkPipelineStageFlags stageMask) |
| { |
| SetEventParams *paramStruct = initCommand<SetEventParams>(CommandID::SetEvent); |
| paramStruct->event = event; |
| paramStruct->stageMask = stageMask; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::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) |
| { |
| uint8_t *writePtr; |
| size_t eventSize = eventCount * sizeof(VkEvent); |
| size_t memBarrierSize = memoryBarrierCount * sizeof(VkMemoryBarrier); |
| size_t buffBarrierSize = bufferMemoryBarrierCount * sizeof(VkBufferMemoryBarrier); |
| size_t imgBarrierSize = imageMemoryBarrierCount * sizeof(VkImageMemoryBarrier); |
| WaitEventsParams *paramStruct = initCommand<WaitEventsParams>( |
| CommandID::WaitEvents, eventSize + memBarrierSize + buffBarrierSize + imgBarrierSize, |
| &writePtr); |
| paramStruct->eventCount = eventCount; |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| paramStruct->memoryBarrierCount = memoryBarrierCount; |
| paramStruct->bufferMemoryBarrierCount = bufferMemoryBarrierCount; |
| paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount; |
| // Copy variable sized data |
| writePtr = storePointerParameter(writePtr, events, eventSize); |
| writePtr = storePointerParameter(writePtr, memoryBarriers, memBarrierSize); |
| writePtr = storePointerParameter(writePtr, bufferMemoryBarriers, buffBarrierSize); |
| storePointerParameter(writePtr, imageMemoryBarriers, imgBarrierSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, |
| VkQueryPool queryPool, |
| uint32_t query) |
| { |
| WriteTimestampParams *paramStruct = |
| initCommand<WriteTimestampParams>(CommandID::WriteTimestamp); |
| paramStruct->pipelineStage = pipelineStage; |
| paramStruct->queryPool = queryPool; |
| paramStruct->query = query; |
| } |
| } // namespace priv |
| } // namespace vk |
| } // namespace rx |
| |
| #endif // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_ |