| // |
| // 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 "common/vulkan/vk_headers.h" |
| #include "libANGLE/renderer/vulkan/vk_command_buffer_utils.h" |
| #include "libANGLE/renderer/vulkan/vk_wrapper.h" |
| |
| #if ANGLE_ENABLE_VULKAN_SHARED_RING_BUFFER_CMD_ALLOC |
| # include "libANGLE/renderer/vulkan/AllocatorHelperRing.h" |
| #else |
| # include "libANGLE/renderer/vulkan/AllocatorHelperPool.h" |
| #endif |
| |
| namespace rx |
| { |
| class ContextVk; |
| |
| namespace vk |
| { |
| class ErrorContext; |
| class RenderPassDesc; |
| class SecondaryCommandPool; |
| |
| #if ANGLE_ENABLE_VULKAN_SHARED_RING_BUFFER_CMD_ALLOC |
| using SecondaryCommandMemoryAllocator = SharedCommandMemoryAllocator; |
| using SecondaryCommandBlockPool = SharedCommandBlockPool; |
| using SecondaryCommandBlockAllocator = SharedCommandBlockAllocator; |
| #else |
| using SecondaryCommandMemoryAllocator = DedicatedCommandMemoryAllocator; |
| using SecondaryCommandBlockPool = DedicatedCommandBlockPool; |
| using SecondaryCommandBlockAllocator = DedicatedCommandBlockAllocator; |
| #endif |
| |
| namespace priv |
| { |
| |
| // NOTE: Please keep command-related enums, structs, functions and other code dealing with commands |
| // in alphabetical order. |
| // This simplifies searching and updating commands. |
| enum class CommandID : uint16_t |
| { |
| // Invalid cmd used to mark end of sequence of commands |
| Invalid = 0, |
| BeginDebugUtilsLabel, |
| BeginQuery, |
| BeginTransformFeedback, |
| BindComputePipeline, |
| BindDescriptorSets, |
| BindGraphicsPipeline, |
| BindIndexBuffer, |
| BindTransformFeedbackBuffers, |
| BindVertexBuffers, |
| BindVertexBuffers2, |
| BlitImage, |
| BufferBarrier, |
| BufferBarrier2, |
| ClearAttachments, |
| ClearColorImage, |
| ClearDepthStencilImage, |
| CopyBuffer, |
| CopyBufferToImage, |
| CopyImage, |
| CopyImageToBuffer, |
| Dispatch, |
| DispatchIndirect, |
| Draw, |
| DrawIndexed, |
| DrawIndexedBaseVertex, |
| DrawIndexedIndirect, |
| DrawIndexedInstanced, |
| DrawIndexedInstancedBaseVertex, |
| DrawIndexedInstancedBaseVertexBaseInstance, |
| DrawIndirect, |
| DrawInstanced, |
| DrawInstancedBaseInstance, |
| EndDebugUtilsLabel, |
| EndQuery, |
| EndTransformFeedback, |
| FillBuffer, |
| ImageBarrier, |
| ImageBarrier2, |
| ImageWaitEvent, |
| InsertDebugUtilsLabel, |
| MemoryBarrier, |
| MemoryBarrier2, |
| NextSubpass, |
| PipelineBarrier, |
| PipelineBarrier2, |
| PushConstants, |
| ResetEvent, |
| ResetQueryPool, |
| ResolveImage, |
| SetBlendConstants, |
| SetCullMode, |
| SetDepthBias, |
| SetDepthBiasEnable, |
| SetDepthCompareOp, |
| SetDepthTestEnable, |
| SetDepthWriteEnable, |
| SetEvent, |
| SetFragmentShadingRate, |
| SetFrontFace, |
| SetLineWidth, |
| SetLogicOp, |
| SetPrimitiveRestartEnable, |
| SetRasterizerDiscardEnable, |
| SetScissor, |
| SetStencilCompareMask, |
| SetStencilOp, |
| SetStencilReference, |
| SetStencilTestEnable, |
| SetStencilWriteMask, |
| SetVertexInput, |
| SetViewport, |
| WaitEvents, |
| WriteTimestamp, |
| WriteTimestamp2, |
| }; |
| |
| // Header for every cmd in custom cmd buffer |
| struct CommandHeader |
| { |
| CommandID id; |
| uint16_t size; |
| }; |
| static_assert(sizeof(CommandHeader) == 4, "Check CommandHeader size"); |
| |
| #define VERIFY_8_BYTE_ALIGNMENT(StructName) \ |
| static_assert((sizeof(StructName) % 8) == 0, "Check " #StructName " alignment"); |
| |
| ANGLE_ENABLE_STRUCT_PADDING_WARNINGS |
| |
| // Structs to encapsulate parameters for different commands. This makes it easy to know the size of |
| // params & to copy params. Each struct must be prefixed by a CommandHeader (which is 4 bytes) and |
| // must be aligned to 8 bytes. |
| struct BeginQueryParams |
| { |
| CommandHeader header; |
| |
| uint32_t query; |
| VkQueryPool queryPool; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BeginQueryParams) |
| |
| struct BeginTransformFeedbackParams |
| { |
| CommandHeader header; |
| |
| uint32_t bufferCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BeginTransformFeedbackParams) |
| |
| struct BindDescriptorSetParams |
| { |
| CommandHeader header; |
| |
| VkPipelineBindPoint pipelineBindPoint : 8; |
| uint32_t firstSet : 8; |
| uint32_t descriptorSetCount : 8; |
| uint32_t dynamicOffsetCount : 8; |
| |
| VkPipelineLayout layout; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BindDescriptorSetParams) |
| |
| struct BindIndexBufferParams |
| { |
| CommandHeader header; |
| |
| VkIndexType indexType; |
| VkBuffer buffer; |
| VkDeviceSize offset; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BindIndexBufferParams) |
| |
| struct BindPipelineParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| VkPipeline pipeline; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BindPipelineParams) |
| |
| struct BindTransformFeedbackBuffersParams |
| { |
| CommandHeader header; |
| |
| // ANGLE always has firstBinding of 0 so not storing that currently |
| uint32_t bindingCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BindTransformFeedbackBuffersParams) |
| |
| using BindVertexBuffersParams = BindTransformFeedbackBuffersParams; |
| using BindVertexBuffers2Params = BindVertexBuffersParams; |
| |
| struct BlitImageParams |
| { |
| CommandHeader header; |
| |
| VkFilter filter; |
| VkImage srcImage; |
| VkImage dstImage; |
| VkImageBlit region; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BlitImageParams) |
| |
| struct BufferBarrierParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| VkBufferMemoryBarrier bufferMemoryBarrier; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BufferBarrierParams) |
| |
| struct BufferBarrier2Params |
| { |
| CommandHeader header; |
| uint32_t padding; |
| VkBufferMemoryBarrier2 bufferMemoryBarrier2; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(BufferBarrier2Params) |
| |
| struct ClearAttachmentsParams |
| { |
| CommandHeader header; |
| |
| uint32_t attachmentCount; |
| VkClearRect rect; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ClearAttachmentsParams) |
| |
| struct ClearColorImageParams |
| { |
| CommandHeader header; |
| |
| VkImageLayout imageLayout; |
| VkImage image; |
| VkClearColorValue color; |
| VkImageSubresourceRange range; |
| uint32_t padding; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ClearColorImageParams) |
| |
| struct ClearDepthStencilImageParams |
| { |
| CommandHeader header; |
| |
| VkImageLayout imageLayout; |
| VkImage image; |
| VkClearDepthStencilValue depthStencil; |
| VkImageSubresourceRange range; |
| uint32_t padding; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ClearDepthStencilImageParams) |
| |
| struct CopyBufferParams |
| { |
| CommandHeader header; |
| |
| uint32_t regionCount; |
| VkBuffer srcBuffer; |
| VkBuffer destBuffer; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(CopyBufferParams) |
| |
| struct CopyBufferToImageParams |
| { |
| CommandHeader header; |
| |
| VkImageLayout dstImageLayout; |
| VkBuffer srcBuffer; |
| VkImage dstImage; |
| VkBufferImageCopy region; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(CopyBufferToImageParams) |
| |
| struct CopyImageParams |
| { |
| CommandHeader header; |
| |
| VkImageCopy region; |
| VkImageLayout srcImageLayout; |
| VkImageLayout dstImageLayout; |
| VkImage srcImage; |
| VkImage dstImage; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(CopyImageParams) |
| |
| struct CopyImageToBufferParams |
| { |
| CommandHeader header; |
| |
| VkImageLayout srcImageLayout; |
| VkImage srcImage; |
| VkBuffer dstBuffer; |
| VkBufferImageCopy region; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(CopyImageToBufferParams) |
| |
| // This is a common struct used by both begin & insert DebugUtilsLabelEXT() functions |
| struct DebugUtilsLabelParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| float color[4]; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DebugUtilsLabelParams) |
| |
| struct DispatchParams |
| { |
| CommandHeader header; |
| |
| uint32_t groupCountX; |
| uint32_t groupCountY; |
| uint32_t groupCountZ; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DispatchParams) |
| |
| struct DispatchIndirectParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| VkBuffer buffer; |
| VkDeviceSize offset; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DispatchIndirectParams) |
| |
| struct DrawParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| uint32_t vertexCount; |
| uint32_t firstVertex; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawParams) |
| |
| struct DrawIndexedParams |
| { |
| CommandHeader header; |
| |
| uint32_t indexCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawIndexedParams) |
| |
| struct DrawIndexedBaseVertexParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| uint32_t indexCount; |
| uint32_t vertexOffset; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawIndexedBaseVertexParams) |
| |
| struct DrawIndexedIndirectParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| uint32_t drawCount; |
| uint32_t stride; |
| VkBuffer buffer; |
| VkDeviceSize offset; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawIndexedIndirectParams) |
| |
| struct DrawIndexedInstancedParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| uint32_t indexCount; |
| uint32_t instanceCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawIndexedInstancedParams) |
| |
| struct DrawIndexedInstancedBaseVertexParams |
| { |
| CommandHeader header; |
| |
| uint32_t indexCount; |
| uint32_t instanceCount; |
| uint32_t vertexOffset; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawIndexedInstancedBaseVertexParams) |
| |
| struct DrawIndexedInstancedBaseVertexBaseInstanceParams |
| { |
| CommandHeader header; |
| |
| uint32_t indexCount; |
| uint32_t instanceCount; |
| uint32_t firstIndex; |
| int32_t vertexOffset; |
| uint32_t firstInstance; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawIndexedInstancedBaseVertexBaseInstanceParams) |
| |
| struct DrawIndirectParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| uint32_t drawCount; |
| uint32_t stride; |
| VkBuffer buffer; |
| VkDeviceSize offset; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawIndirectParams) |
| |
| struct DrawInstancedParams |
| { |
| CommandHeader header; |
| |
| uint32_t vertexCount; |
| uint32_t instanceCount; |
| uint32_t firstVertex; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawInstancedParams) |
| |
| struct DrawInstancedBaseInstanceParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| uint32_t vertexCount; |
| uint32_t instanceCount; |
| uint32_t firstVertex; |
| uint32_t firstInstance; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(DrawInstancedBaseInstanceParams) |
| |
| // A special struct used with commands that don't have params |
| struct EmptyParams |
| { |
| CommandHeader header; |
| uint32_t padding; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(EmptyParams) |
| |
| struct EndQueryParams |
| { |
| CommandHeader header; |
| |
| uint32_t query; |
| VkQueryPool queryPool; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(EndQueryParams) |
| |
| struct EndTransformFeedbackParams |
| { |
| CommandHeader header; |
| |
| uint32_t bufferCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(EndTransformFeedbackParams) |
| |
| struct FillBufferParams |
| { |
| CommandHeader header; |
| |
| uint32_t data; |
| VkBuffer dstBuffer; |
| VkDeviceSize dstOffset; |
| VkDeviceSize size; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(FillBufferParams) |
| |
| struct ImageBarrierParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ImageBarrierParams) |
| |
| struct ImageBarrier2Params |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ImageBarrier2Params) |
| |
| struct ImageWaitEventParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| VkEvent event; |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ImageWaitEventParams) |
| |
| struct MemoryBarrierParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(MemoryBarrierParams) |
| |
| struct MemoryBarrier2Params |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(MemoryBarrierParams) |
| |
| struct PipelineBarrierParams |
| { |
| CommandHeader header; |
| |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| VkDependencyFlags dependencyFlags; |
| uint32_t memoryBarrierCount; |
| uint32_t imageMemoryBarrierCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(PipelineBarrierParams) |
| |
| struct PipelineBarrierParams2 |
| { |
| CommandHeader header; |
| VkDependencyFlags dependencyFlags; |
| uint32_t memoryBarrierCount; |
| uint32_t imageMemoryBarrierCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(PipelineBarrierParams2) |
| |
| struct PushConstantsParams |
| { |
| CommandHeader header; |
| |
| VkShaderStageFlags flag; |
| VkPipelineLayout layout; |
| uint32_t offset; |
| uint32_t size; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(PushConstantsParams) |
| |
| struct ResetEventParams |
| { |
| CommandHeader header; |
| |
| VkPipelineStageFlags stageMask; |
| VkEvent event; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ResetEventParams) |
| |
| struct ResetQueryPoolParams |
| { |
| CommandHeader header; |
| |
| uint32_t firstQuery : 24; |
| uint32_t queryCount : 8; |
| VkQueryPool queryPool; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ResetQueryPoolParams) |
| |
| struct ResolveImageParams |
| { |
| CommandHeader header; |
| |
| VkImageResolve region; |
| VkImage srcImage; |
| VkImage dstImage; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(ResolveImageParams) |
| |
| struct SetBlendConstantsParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| float blendConstants[4]; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetBlendConstantsParams) |
| |
| struct SetCullModeParams |
| { |
| CommandHeader header; |
| |
| VkCullModeFlags cullMode; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetCullModeParams) |
| |
| struct SetDepthBiasParams |
| { |
| CommandHeader header; |
| |
| float depthBiasConstantFactor; |
| float depthBiasClamp; |
| float depthBiasSlopeFactor; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetDepthBiasParams) |
| |
| struct SetDepthBiasEnableParams |
| { |
| CommandHeader header; |
| |
| VkBool32 depthBiasEnable; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetDepthBiasEnableParams) |
| |
| struct SetDepthCompareOpParams |
| { |
| CommandHeader header; |
| |
| VkCompareOp depthCompareOp; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetDepthCompareOpParams) |
| |
| struct SetDepthTestEnableParams |
| { |
| CommandHeader header; |
| |
| VkBool32 depthTestEnable; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetDepthTestEnableParams) |
| |
| struct SetDepthWriteEnableParams |
| { |
| CommandHeader header; |
| |
| VkBool32 depthWriteEnable; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetDepthWriteEnableParams) |
| |
| struct SetEventParams |
| { |
| CommandHeader header; |
| |
| VkPipelineStageFlags stageMask; |
| VkEvent event; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetEventParams) |
| |
| struct SetFragmentShadingRateParams |
| { |
| CommandHeader header; |
| |
| uint32_t fragmentWidth : 8; |
| uint32_t fragmentHeight : 8; |
| uint32_t vkFragmentShadingRateCombinerOp1 : 16; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetFragmentShadingRateParams) |
| |
| struct SetFrontFaceParams |
| { |
| CommandHeader header; |
| |
| VkFrontFace frontFace; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetFrontFaceParams) |
| |
| struct SetLineWidthParams |
| { |
| CommandHeader header; |
| |
| float lineWidth; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetLineWidthParams) |
| |
| struct SetLogicOpParams |
| { |
| CommandHeader header; |
| |
| VkLogicOp logicOp; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetLogicOpParams) |
| |
| struct SetPrimitiveRestartEnableParams |
| { |
| CommandHeader header; |
| |
| VkBool32 primitiveRestartEnable; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetPrimitiveRestartEnableParams) |
| |
| struct SetRasterizerDiscardEnableParams |
| { |
| CommandHeader header; |
| |
| VkBool32 rasterizerDiscardEnable; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetRasterizerDiscardEnableParams) |
| |
| struct SetScissorParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| VkRect2D scissor; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetScissorParams) |
| |
| struct SetStencilCompareMaskParams |
| { |
| CommandHeader header; |
| |
| uint16_t compareFrontMask; |
| uint16_t compareBackMask; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetStencilCompareMaskParams) |
| |
| struct SetStencilOpParams |
| { |
| CommandHeader header; |
| |
| uint32_t faceMask : 4; |
| uint32_t failOp : 3; |
| uint32_t passOp : 3; |
| uint32_t depthFailOp : 3; |
| uint32_t compareOp : 3; |
| uint32_t padding : 16; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetStencilOpParams) |
| |
| struct SetStencilReferenceParams |
| { |
| CommandHeader header; |
| |
| uint16_t frontReference; |
| uint16_t backReference; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetStencilReferenceParams) |
| |
| struct SetStencilTestEnableParams |
| { |
| CommandHeader header; |
| |
| VkBool32 stencilTestEnable; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetStencilTestEnableParams) |
| |
| struct SetStencilWriteMaskParams |
| { |
| CommandHeader header; |
| |
| uint16_t writeFrontMask; |
| uint16_t writeBackMask; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetStencilWriteMaskParams) |
| |
| struct SetVertexInputParams |
| { |
| CommandHeader header; |
| |
| uint16_t vertexBindingDescriptionCount; |
| uint16_t vertexAttributeDescriptionCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetVertexInputParams) |
| |
| struct SetViewportParams |
| { |
| CommandHeader header; |
| |
| uint32_t padding; |
| VkViewport viewport; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(SetViewportParams) |
| |
| struct WaitEventsParams |
| { |
| CommandHeader header; |
| |
| uint32_t eventCount; |
| VkPipelineStageFlags srcStageMask; |
| VkPipelineStageFlags dstStageMask; |
| uint32_t memoryBarrierCount; |
| uint32_t imageMemoryBarrierCount; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(WaitEventsParams) |
| |
| struct WriteTimestampParams |
| { |
| CommandHeader header; |
| |
| uint32_t query; |
| VkQueryPool queryPool; |
| }; |
| VERIFY_8_BYTE_ALIGNMENT(WriteTimestampParams) |
| |
| #undef VERIFY_8_BYTE_ALIGNMENT |
| |
| ANGLE_DISABLE_STRUCT_PADDING_WARNINGS |
| |
| 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; } |
| |
| static angle::Result InitializeCommandPool(ErrorContext *context, |
| SecondaryCommandPool *pool, |
| uint32_t queueFamilyIndex, |
| ProtectionType protectionType) |
| { |
| return angle::Result::Continue; |
| } |
| static angle::Result InitializeRenderPassInheritanceInfo( |
| ContextVk *contextVk, |
| const Framebuffer &framebuffer, |
| const RenderPassDesc &renderPassDesc, |
| VkCommandBufferInheritanceInfo *inheritanceInfoOut, |
| VkCommandBufferInheritanceRenderingInfo *renderingInfoOut, |
| gl::DrawBuffersArray<VkFormat> *colorFormatStorageOut) |
| { |
| *inheritanceInfoOut = {}; |
| return angle::Result::Continue; |
| } |
| |
| // Add commands |
| void beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label); |
| |
| void beginQuery(const QueryPool &queryPool, uint32_t query, VkQueryControlFlags flags); |
| |
| void beginTransformFeedback(uint32_t firstCounterBuffer, |
| uint32_t bufferCount, |
| const VkBuffer *counterBuffers, |
| const VkDeviceSize *counterBufferOffsets); |
| |
| void bindComputePipeline(const Pipeline &pipeline); |
| |
| void bindDescriptorSets(const PipelineLayout &layout, |
| VkPipelineBindPoint pipelineBindPoint, |
| DescriptorSetIndex 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(uint32_t firstBinding, |
| uint32_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 bindVertexBuffers2(uint32_t firstBinding, |
| uint32_t bindingCount, |
| const VkBuffer *buffers, |
| const VkDeviceSize *offsets, |
| const VkDeviceSize *sizes, |
| const VkDeviceSize *strides); |
| |
| 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 bufferBarrier2(const VkBufferMemoryBarrier2 *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 drawIndexedIndirect(const Buffer &buffer, |
| VkDeviceSize offset, |
| uint32_t drawCount, |
| uint32_t stride); |
| 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 drawIndirect(const Buffer &buffer, |
| VkDeviceSize offset, |
| uint32_t drawCount, |
| uint32_t stride); |
| |
| 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 endDebugUtilsLabelEXT(); |
| |
| void endQuery(const QueryPool &queryPool, uint32_t query); |
| |
| void endTransformFeedback(uint32_t firstCounterBuffer, |
| uint32_t counterBufferCount, |
| const VkBuffer *counterBuffers, |
| const VkDeviceSize *counterBufferOffsets); |
| |
| void fillBuffer(const Buffer &dstBuffer, |
| VkDeviceSize dstOffset, |
| VkDeviceSize size, |
| uint32_t data); |
| |
| void imageBarrier(VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkImageMemoryBarrier &imageMemoryBarrier); |
| |
| void imageBarrier2(const VkImageMemoryBarrier2 &imageMemoryBarrier2); |
| |
| void imageWaitEvent(const VkEvent &event, |
| VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkImageMemoryBarrier &imageMemoryBarrier); |
| void imageWaitEvent2(const VkEvent &event, const VkImageMemoryBarrier2 &imageMemoryBarrier2); |
| |
| void insertDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label); |
| |
| void memoryBarrier(VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkMemoryBarrier &memoryBarrier); |
| |
| void memoryBarrier2(const VkMemoryBarrier2 &memoryBarrier2); |
| |
| void nextSubpass(VkSubpassContents subpassContents); |
| |
| 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 pipelineBarrier2(VkDependencyFlags dependencyFlags, |
| uint32_t memoryBarrierCount, |
| const VkMemoryBarrier2 *memoryBarriers2, |
| uint32_t bufferMemoryBarrierCount, |
| const VkBufferMemoryBarrier2 *bufferMemoryBarriers2, |
| uint32_t imageMemoryBarrierCount, |
| const VkImageMemoryBarrier2 *imageMemoryBarriers2); |
| |
| void pushConstants(const PipelineLayout &layout, |
| VkShaderStageFlags flag, |
| uint32_t offset, |
| uint32_t size, |
| const void *data); |
| |
| void resetEvent(VkEvent event, VkPipelineStageFlags stageMask); |
| |
| void resetQueryPool(const QueryPool &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 setBlendConstants(const float blendConstants[4]); |
| void setCullMode(VkCullModeFlags cullMode); |
| void setDepthBias(float depthBiasConstantFactor, |
| float depthBiasClamp, |
| float depthBiasSlopeFactor); |
| void setDepthBiasEnable(VkBool32 depthBiasEnable); |
| void setDepthCompareOp(VkCompareOp depthCompareOp); |
| void setDepthTestEnable(VkBool32 depthTestEnable); |
| void setDepthWriteEnable(VkBool32 depthWriteEnable); |
| void setEvent(VkEvent event, VkPipelineStageFlags stageMask); |
| void setFragmentShadingRate(const VkExtent2D *fragmentSize, |
| VkFragmentShadingRateCombinerOpKHR ops[2]); |
| void setFrontFace(VkFrontFace frontFace); |
| void setLineWidth(float lineWidth); |
| void setLogicOp(VkLogicOp logicOp); |
| void setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable); |
| void setRasterizerDiscardEnable(VkBool32 rasterizerDiscardEnable); |
| void setScissor(uint32_t firstScissor, uint32_t scissorCount, const VkRect2D *scissors); |
| void setStencilCompareMask(uint32_t compareFrontMask, uint32_t compareBackMask); |
| void setStencilOp(VkStencilFaceFlags faceMask, |
| VkStencilOp failOp, |
| VkStencilOp passOp, |
| VkStencilOp depthFailOp, |
| VkCompareOp compareOp); |
| void setStencilReference(uint32_t frontReference, uint32_t backReference); |
| void setStencilTestEnable(VkBool32 stencilTestEnable); |
| void setStencilWriteMask(uint32_t writeFrontMask, uint32_t writeBackMask); |
| void setVertexInput(uint32_t vertexBindingDescriptionCount, |
| const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions, |
| uint32_t vertexAttributeDescriptionCount, |
| const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions); |
| void setViewport(uint32_t firstViewport, uint32_t viewportCount, const VkViewport *viewports); |
| |
| 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, |
| const QueryPool &queryPool, |
| uint32_t query); |
| |
| void writeTimestamp2(VkPipelineStageFlagBits2 pipelineStage, |
| const QueryPool &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(PrimaryCommandBuffer *primary); |
| |
| // Calculate memory usage of this command buffer for diagnostics. |
| void getMemoryUsageStats(size_t *usedMemoryOut, size_t *allocatedMemoryOut) const; |
| void getMemoryUsageStatsForPoolAlloc(size_t blockSize, |
| 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; |
| |
| // Initialize the SecondaryCommandBuffer by setting the allocator it will use |
| angle::Result initialize(vk::ErrorContext *context, |
| vk::SecondaryCommandPool *pool, |
| bool isRenderPassCommandBuffer, |
| SecondaryCommandMemoryAllocator *allocator) |
| { |
| return mCommandAllocator.initialize(allocator); |
| } |
| |
| void attachAllocator(vk::SecondaryCommandMemoryAllocator *source) |
| { |
| mCommandAllocator.attachAllocator(source); |
| } |
| |
| void detachAllocator(vk::SecondaryCommandMemoryAllocator *destination) |
| { |
| mCommandAllocator.detachAllocator(destination); |
| } |
| |
| angle::Result begin(ErrorContext *context, |
| const VkCommandBufferInheritanceInfo &inheritanceInfo) |
| { |
| return angle::Result::Continue; |
| } |
| angle::Result end(ErrorContext *context) { return angle::Result::Continue; } |
| |
| void open() { mIsOpen = true; } |
| void close() { mIsOpen = false; } |
| |
| void reset() |
| { |
| mCommands.clear(); |
| mCommandAllocator.reset(&mCommandTracker); |
| } |
| |
| // The SecondaryCommandBuffer is valid if it's been initialized |
| bool valid() const { return mCommandAllocator.valid(); } |
| |
| bool empty() const { return mCommandAllocator.empty(); } |
| bool checkEmptyForPoolAlloc() const |
| { |
| return mCommands.size() == 0 || mCommands[0]->id == CommandID::Invalid; |
| } |
| |
| uint32_t getRenderPassWriteCommandCount() const |
| { |
| return mCommandTracker.getRenderPassWriteCommandCount(); |
| } |
| |
| void clearCommands() { mCommands.clear(); } |
| bool hasEmptyCommands() { return mCommands.empty(); } |
| void pushToCommands(uint8_t *command) |
| { |
| mCommands.push_back(reinterpret_cast<priv::CommandHeader *>(command)); |
| } |
| |
| private: |
| void commonDebugUtilsLabel(CommandID cmd, const VkDebugUtilsLabelEXT &label); |
| template <class StructType> |
| ANGLE_INLINE StructType *commonInit(CommandID cmdID, |
| size_t allocationSize, |
| uint8_t *commandMemory) |
| { |
| ASSERT(mIsOpen); |
| ASSERT(allocationSize <= std::numeric_limits<uint16_t>::max()); |
| |
| StructType *command = reinterpret_cast<StructType *>(commandMemory); |
| command->header.id = cmdID; |
| command->header.size = static_cast<uint16_t>(allocationSize); |
| |
| return command; |
| } |
| |
| // Allocate and initialize memory for given commandID & variable param size, setting |
| // variableDataOut 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 **variableDataOut) |
| { |
| constexpr size_t fixedAllocationSize = sizeof(StructType); |
| const size_t allocationSize = fixedAllocationSize + variableSize; |
| |
| // Make sure we have enough room to mark follow-on header "Invalid" |
| const size_t requiredSize = allocationSize + sizeof(CommandHeader); |
| uint8_t *commandMemory = nullptr; |
| |
| mCommandAllocator.onNewVariableSizedCommand(requiredSize, allocationSize, &commandMemory); |
| StructType *command = commonInit<StructType>(cmdID, allocationSize, commandMemory); |
| *variableDataOut = Offset<uint8_t>(commandMemory, fixedAllocationSize); |
| return command; |
| } |
| |
| // 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); |
| |
| // Make sure we have enough room to mark follow-on header "Invalid" |
| const size_t requiredSize = allocationSize + sizeof(CommandHeader); |
| uint8_t *commandMemory = nullptr; |
| mCommandAllocator.onNewCommand(requiredSize, allocationSize, &commandMemory); |
| |
| return commonInit<StructType>(cmdID, allocationSize, commandMemory); |
| } |
| |
| // Return a pointer to the parameter type. Note that every param struct has the header as its |
| // first member, so in fact the parameter type pointer is identical to the header pointer. |
| template <class StructType> |
| const StructType *getParamPtr(const CommandHeader *header) const |
| { |
| return reinterpret_cast<const StructType *>(header); |
| } |
| struct ArrayParamSize |
| { |
| // Given an array of N elements of type T, N*sizeof(T) bytes need to be copied, but due to |
| // alignment requirements, roundUp(size, 8) bytes need to be allocated for the array. |
| size_t copyBytes; |
| size_t allocateBytes; |
| }; |
| template <class T> |
| ANGLE_INLINE ArrayParamSize calculateArrayParameterSize(size_t count) |
| { |
| ArrayParamSize size; |
| size.copyBytes = sizeof(T) * count; |
| size.allocateBytes = roundUpPow2<size_t>(size.copyBytes, 8u); |
| return size; |
| } |
| // Copy size.copyBytes data from paramData to writePointer and return writePointer plus |
| // size.allocateBytes. |
| template <class T> |
| ANGLE_INLINE uint8_t *storeArrayParameter(uint8_t *writePointer, |
| const T *data, |
| const ArrayParamSize &size) |
| { |
| // See |PointerParamSize|. The size should always be calculated with |
| // |calculatePointerParameterSize|, and that satisfies this condition. |
| ASSERT(size.allocateBytes == roundUpPow2<size_t>(size.copyBytes, 8u)); |
| |
| memcpy(writePointer, data, size.copyBytes); |
| return writePointer + size.allocateBytes; |
| } |
| |
| // Flag to indicate that commandBuffer is open for new commands. Initially open. |
| bool mIsOpen; |
| |
| std::vector<CommandHeader *> mCommands; |
| |
| // Allocator used by this class. If non-null then the class is valid. |
| SecondaryCommandBlockPool mCommandAllocator; |
| |
| CommandBufferCommandTracker mCommandTracker; |
| }; |
| |
| ANGLE_INLINE SecondaryCommandBuffer::SecondaryCommandBuffer() : mIsOpen(true) |
| { |
| mCommandAllocator.setCommandBuffer(this); |
| } |
| |
| ANGLE_INLINE SecondaryCommandBuffer::~SecondaryCommandBuffer() |
| { |
| mCommandAllocator.resetCommandBuffer(); |
| } |
| |
| // begin and insert DebugUtilsLabelEXT funcs share this same function body |
| ANGLE_INLINE void SecondaryCommandBuffer::commonDebugUtilsLabel(CommandID cmd, |
| const VkDebugUtilsLabelEXT &label) |
| { |
| uint8_t *writePtr; |
| const ArrayParamSize stringSize = |
| calculateArrayParameterSize<char>(strlen(label.pLabelName) + 1); |
| DebugUtilsLabelParams *paramStruct = |
| initCommand<DebugUtilsLabelParams>(cmd, stringSize.allocateBytes, &writePtr); |
| paramStruct->color[0] = label.color[0]; |
| paramStruct->color[1] = label.color[1]; |
| paramStruct->color[2] = label.color[2]; |
| paramStruct->color[3] = label.color[3]; |
| storeArrayParameter(writePtr, label.pLabelName, stringSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::beginDebugUtilsLabelEXT(const VkDebugUtilsLabelEXT &label) |
| { |
| commonDebugUtilsLabel(CommandID::BeginDebugUtilsLabel, label); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::beginQuery(const QueryPool &queryPool, |
| uint32_t query, |
| VkQueryControlFlags flags) |
| { |
| ASSERT(flags == 0); |
| BeginQueryParams *paramStruct = initCommand<BeginQueryParams>(CommandID::BeginQuery); |
| paramStruct->queryPool = queryPool.getHandle(); |
| paramStruct->query = query; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::beginTransformFeedback( |
| uint32_t firstCounterBuffer, |
| uint32_t bufferCount, |
| const VkBuffer *counterBuffers, |
| const VkDeviceSize *counterBufferOffsets) |
| { |
| ASSERT(firstCounterBuffer == 0); |
| uint8_t *writePtr; |
| const ArrayParamSize bufferSize = calculateArrayParameterSize<VkBuffer>(bufferCount); |
| const ArrayParamSize offsetSize = calculateArrayParameterSize<VkDeviceSize>(bufferCount); |
| BeginTransformFeedbackParams *paramStruct = initCommand<BeginTransformFeedbackParams>( |
| CommandID::BeginTransformFeedback, bufferSize.allocateBytes + offsetSize.allocateBytes, |
| &writePtr); |
| paramStruct->bufferCount = bufferCount; |
| writePtr = storeArrayParameter(writePtr, counterBuffers, bufferSize); |
| storeArrayParameter(writePtr, counterBufferOffsets, offsetSize); |
| } |
| |
| 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, |
| DescriptorSetIndex firstSet, |
| uint32_t descriptorSetCount, |
| const VkDescriptorSet *descriptorSets, |
| uint32_t dynamicOffsetCount, |
| const uint32_t *dynamicOffsets) |
| { |
| const ArrayParamSize descSize = |
| calculateArrayParameterSize<VkDescriptorSet>(descriptorSetCount); |
| const ArrayParamSize offsetSize = calculateArrayParameterSize<uint32_t>(dynamicOffsetCount); |
| uint8_t *writePtr; |
| BindDescriptorSetParams *paramStruct = initCommand<BindDescriptorSetParams>( |
| CommandID::BindDescriptorSets, descSize.allocateBytes + offsetSize.allocateBytes, |
| &writePtr); |
| // Copy params into memory |
| paramStruct->layout = layout.getHandle(); |
| SetBitField(paramStruct->pipelineBindPoint, pipelineBindPoint); |
| SetBitField(paramStruct->firstSet, ToUnderlying(firstSet)); |
| SetBitField(paramStruct->descriptorSetCount, descriptorSetCount); |
| SetBitField(paramStruct->dynamicOffsetCount, dynamicOffsetCount); |
| // Copy variable sized data |
| writePtr = storeArrayParameter(writePtr, descriptorSets, descSize); |
| if (dynamicOffsetCount > 0) |
| { |
| storeArrayParameter(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(uint32_t firstBinding, |
| uint32_t bindingCount, |
| const VkBuffer *buffers, |
| const VkDeviceSize *offsets, |
| const VkDeviceSize *sizes) |
| { |
| ASSERT(firstBinding == 0); |
| uint8_t *writePtr; |
| const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(bindingCount); |
| const ArrayParamSize offsetsSize = calculateArrayParameterSize<VkDeviceSize>(bindingCount); |
| const ArrayParamSize sizesSize = offsetsSize; |
| BindTransformFeedbackBuffersParams *paramStruct = |
| initCommand<BindTransformFeedbackBuffersParams>( |
| CommandID::BindTransformFeedbackBuffers, |
| buffersSize.allocateBytes + offsetsSize.allocateBytes + sizesSize.allocateBytes, |
| &writePtr); |
| // Copy params |
| paramStruct->bindingCount = bindingCount; |
| writePtr = storeArrayParameter(writePtr, buffers, buffersSize); |
| writePtr = storeArrayParameter(writePtr, offsets, offsetsSize); |
| storeArrayParameter(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; |
| const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(bindingCount); |
| const ArrayParamSize offsetsSize = calculateArrayParameterSize<VkDeviceSize>(bindingCount); |
| BindVertexBuffersParams *paramStruct = initCommand<BindVertexBuffersParams>( |
| CommandID::BindVertexBuffers, buffersSize.allocateBytes + offsetsSize.allocateBytes, |
| &writePtr); |
| // Copy params |
| paramStruct->bindingCount = bindingCount; |
| writePtr = storeArrayParameter(writePtr, buffers, buffersSize); |
| storeArrayParameter(writePtr, offsets, offsetsSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bindVertexBuffers2(uint32_t firstBinding, |
| uint32_t bindingCount, |
| const VkBuffer *buffers, |
| const VkDeviceSize *offsets, |
| const VkDeviceSize *sizes, |
| const VkDeviceSize *strides) |
| { |
| ASSERT(firstBinding == 0); |
| ASSERT(sizes == nullptr); |
| uint8_t *writePtr; |
| const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(bindingCount); |
| const ArrayParamSize offsetsSize = calculateArrayParameterSize<VkDeviceSize>(bindingCount); |
| const ArrayParamSize stridesSize = offsetsSize; |
| BindVertexBuffers2Params *paramStruct = initCommand<BindVertexBuffers2Params>( |
| CommandID::BindVertexBuffers2, |
| buffersSize.allocateBytes + offsetsSize.allocateBytes + stridesSize.allocateBytes, |
| &writePtr); |
| // Copy params |
| paramStruct->bindingCount = bindingCount; |
| writePtr = storeArrayParameter(writePtr, buffers, buffersSize); |
| writePtr = storeArrayParameter(writePtr, offsets, offsetsSize); |
| storeArrayParameter(writePtr, strides, stridesSize); |
| } |
| |
| 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) |
| { |
| // Used only during queue family ownership transfers |
| ASSERT(srcStageMask == VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| ASSERT(dstStageMask == VK_PIPELINE_STAGE_ALL_COMMANDS_BIT); |
| |
| BufferBarrierParams *paramStruct = initCommand<BufferBarrierParams>(CommandID::BufferBarrier); |
| paramStruct->bufferMemoryBarrier = *bufferMemoryBarrier; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::bufferBarrier2( |
| const VkBufferMemoryBarrier2 *bufferMemoryBarrier2) |
| { |
| ASSERT(bufferMemoryBarrier2->srcStageMask == VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT); |
| ASSERT(bufferMemoryBarrier2->dstStageMask == VK_PIPELINE_STAGE_2_ALL_COMMANDS_BIT); |
| |
| BufferBarrier2Params *paramStruct = |
| initCommand<BufferBarrier2Params>(CommandID::BufferBarrier2); |
| paramStruct->bufferMemoryBarrier2 = *bufferMemoryBarrier2; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::clearAttachments(uint32_t attachmentCount, |
| const VkClearAttachment *attachments, |
| uint32_t rectCount, |
| const VkClearRect *rects) |
| { |
| ASSERT(rectCount == 1); |
| uint8_t *writePtr; |
| const ArrayParamSize attachmentSize = |
| calculateArrayParameterSize<VkClearAttachment>(attachmentCount); |
| ClearAttachmentsParams *paramStruct = initCommand<ClearAttachmentsParams>( |
| CommandID::ClearAttachments, attachmentSize.allocateBytes, &writePtr); |
| paramStruct->attachmentCount = attachmentCount; |
| paramStruct->rect = rects[0]; |
| // Copy variable sized data |
| storeArrayParameter(writePtr, attachments, attachmentSize); |
| |
| mCommandTracker.onClearAttachments(); |
| } |
| |
| 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; |
| const ArrayParamSize regionSize = calculateArrayParameterSize<VkBufferCopy>(regionCount); |
| CopyBufferParams *paramStruct = |
| initCommand<CopyBufferParams>(CommandID::CopyBuffer, regionSize.allocateBytes, &writePtr); |
| paramStruct->srcBuffer = srcBuffer.getHandle(); |
| paramStruct->destBuffer = destBuffer.getHandle(); |
| paramStruct->regionCount = regionCount; |
| // Copy variable sized data |
| storeArrayParameter(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; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexed(uint32_t indexCount) |
| { |
| DrawIndexedParams *paramStruct = initCommand<DrawIndexedParams>(CommandID::DrawIndexed); |
| paramStruct->indexCount = indexCount; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedBaseVertex(uint32_t indexCount, |
| uint32_t vertexOffset) |
| { |
| DrawIndexedBaseVertexParams *paramStruct = |
| initCommand<DrawIndexedBaseVertexParams>(CommandID::DrawIndexedBaseVertex); |
| paramStruct->indexCount = indexCount; |
| paramStruct->vertexOffset = vertexOffset; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| 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; |
| paramStruct->drawCount = drawCount; |
| paramStruct->stride = stride; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::drawIndexedInstanced(uint32_t indexCount, |
| uint32_t instanceCount) |
| { |
| DrawIndexedInstancedParams *paramStruct = |
| initCommand<DrawIndexedInstancedParams>(CommandID::DrawIndexedInstanced); |
| paramStruct->indexCount = indexCount; |
| paramStruct->instanceCount = instanceCount; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| 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; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| 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; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| 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; |
| paramStruct->drawCount = drawCount; |
| paramStruct->stride = stride; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| 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; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| 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; |
| |
| mCommandTracker.onDraw(); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::endDebugUtilsLabelEXT() |
| { |
| initCommand<EmptyParams>(CommandID::EndDebugUtilsLabel); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::endQuery(const QueryPool &queryPool, uint32_t query) |
| { |
| EndQueryParams *paramStruct = initCommand<EndQueryParams>(CommandID::EndQuery); |
| paramStruct->queryPool = queryPool.getHandle(); |
| paramStruct->query = query; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::endTransformFeedback( |
| uint32_t firstCounterBuffer, |
| uint32_t counterBufferCount, |
| const VkBuffer *counterBuffers, |
| const VkDeviceSize *counterBufferOffsets) |
| { |
| ASSERT(firstCounterBuffer == 0); |
| uint8_t *writePtr; |
| const ArrayParamSize buffersSize = calculateArrayParameterSize<VkBuffer>(counterBufferCount); |
| const ArrayParamSize offsetsSize = |
| calculateArrayParameterSize<VkDeviceSize>(counterBufferCount); |
| EndTransformFeedbackParams *paramStruct = initCommand<EndTransformFeedbackParams>( |
| CommandID::EndTransformFeedback, buffersSize.allocateBytes + offsetsSize.allocateBytes, |
| &writePtr); |
| paramStruct->bufferCount = counterBufferCount; |
| writePtr = storeArrayParameter(writePtr, counterBuffers, buffersSize); |
| storeArrayParameter(writePtr, counterBufferOffsets, offsetsSize); |
| } |
| |
| 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) |
| { |
| ASSERT(imageMemoryBarrier.pNext == nullptr); |
| |
| uint8_t *writePtr; |
| const ArrayParamSize imgBarrierSize = calculateArrayParameterSize<VkImageMemoryBarrier>(1); |
| ImageBarrierParams *paramStruct = initCommand<ImageBarrierParams>( |
| CommandID::ImageBarrier, imgBarrierSize.allocateBytes, &writePtr); |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| storeArrayParameter(writePtr, &imageMemoryBarrier, imgBarrierSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::imageBarrier2( |
| const VkImageMemoryBarrier2 &imageMemoryBarrier2) |
| { |
| ASSERT(imageMemoryBarrier2.pNext == nullptr); |
| |
| uint8_t *writePtr; |
| const ArrayParamSize imgBarrier2Size = calculateArrayParameterSize<VkImageMemoryBarrier2>(1); |
| initCommand<ImageBarrier2Params>(CommandID::ImageBarrier2, imgBarrier2Size.allocateBytes, |
| &writePtr); |
| storeArrayParameter(writePtr, &imageMemoryBarrier2, imgBarrier2Size); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::imageWaitEvent( |
| const VkEvent &event, |
| VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkImageMemoryBarrier &imageMemoryBarrier) |
| { |
| ASSERT(imageMemoryBarrier.pNext == nullptr); |
| |
| uint8_t *writePtr; |
| const ArrayParamSize imgBarrierSize = calculateArrayParameterSize<VkImageMemoryBarrier>(1); |
| |
| ImageWaitEventParams *paramStruct = initCommand<ImageWaitEventParams>( |
| CommandID::ImageWaitEvent, imgBarrierSize.allocateBytes, &writePtr); |
| paramStruct->event = event; |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| storeArrayParameter(writePtr, &imageMemoryBarrier, imgBarrierSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::insertDebugUtilsLabelEXT( |
| const VkDebugUtilsLabelEXT &label) |
| { |
| commonDebugUtilsLabel(CommandID::InsertDebugUtilsLabel, label); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier(VkPipelineStageFlags srcStageMask, |
| VkPipelineStageFlags dstStageMask, |
| const VkMemoryBarrier &memoryBarrier) |
| { |
| ASSERT(memoryBarrier.pNext == nullptr); |
| |
| uint8_t *writePtr; |
| const ArrayParamSize memBarrierSize = calculateArrayParameterSize<VkMemoryBarrier>(1); |
| MemoryBarrierParams *paramStruct = initCommand<MemoryBarrierParams>( |
| CommandID::MemoryBarrier, memBarrierSize.allocateBytes, &writePtr); |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| storeArrayParameter(writePtr, &memoryBarrier, memBarrierSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::memoryBarrier2(const VkMemoryBarrier2 &memoryBarrier2) |
| { |
| ASSERT(memoryBarrier2.pNext == nullptr); |
| |
| uint8_t *writePtr; |
| const ArrayParamSize memBarrierSize = calculateArrayParameterSize<VkMemoryBarrier2>(1); |
| initCommand<MemoryBarrier2Params>(CommandID::MemoryBarrier2, memBarrierSize.allocateBytes, |
| &writePtr); |
| storeArrayParameter(writePtr, &memoryBarrier2, memBarrierSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::nextSubpass(VkSubpassContents subpassContents) |
| { |
| ASSERT(subpassContents == VK_SUBPASS_CONTENTS_INLINE); |
| initCommand<EmptyParams>(CommandID::NextSubpass); |
| } |
| |
| 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) |
| { |
| // Other than for QFOT (where bufferBarrier() is used), ANGLE doesn't use buffer barriers. |
| // Memory barriers are used instead. |
| ASSERT(bufferMemoryBarrierCount == 0); |
| ASSERT(bufferMemoryBarriers == nullptr); |
| |
| uint8_t *writePtr; |
| const ArrayParamSize memBarrierSize = |
| calculateArrayParameterSize<VkMemoryBarrier>(memoryBarrierCount); |
| const ArrayParamSize imgBarrierSize = |
| calculateArrayParameterSize<VkImageMemoryBarrier>(imageMemoryBarrierCount); |
| PipelineBarrierParams *paramStruct = initCommand<PipelineBarrierParams>( |
| CommandID::PipelineBarrier, memBarrierSize.allocateBytes + imgBarrierSize.allocateBytes, |
| &writePtr); |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| paramStruct->dependencyFlags = dependencyFlags; |
| paramStruct->memoryBarrierCount = memoryBarrierCount; |
| paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount; |
| // Copy variable sized data |
| if (memoryBarrierCount > 0) |
| { |
| writePtr = storeArrayParameter(writePtr, memoryBarriers, memBarrierSize); |
| } |
| if (imageMemoryBarrierCount > 0) |
| { |
| storeArrayParameter(writePtr, imageMemoryBarriers, imgBarrierSize); |
| } |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::pipelineBarrier2( |
| VkDependencyFlags dependencyFlags, |
| uint32_t memoryBarrierCount, |
| const VkMemoryBarrier2 *memoryBarriers2, |
| uint32_t bufferMemoryBarrierCount, |
| const VkBufferMemoryBarrier2 *bufferMemoryBarriers2, |
| uint32_t imageMemoryBarrierCount, |
| const VkImageMemoryBarrier2 *imageMemoryBarriers2) |
| { |
| // Other than for QFOT (where bufferBarrier() is used), ANGLE doesn't use buffer barriers. |
| // Memory barriers are used instead. |
| ASSERT(bufferMemoryBarrierCount == 0); |
| ASSERT(bufferMemoryBarriers2 == nullptr); |
| |
| uint8_t *writePtr; |
| const ArrayParamSize memBarrier2Size = |
| calculateArrayParameterSize<VkMemoryBarrier2>(memoryBarrierCount); |
| const ArrayParamSize imgBarrier2Size = |
| calculateArrayParameterSize<VkImageMemoryBarrier2>(imageMemoryBarrierCount); |
| |
| PipelineBarrierParams2 *paramStruct = initCommand<PipelineBarrierParams2>( |
| CommandID::PipelineBarrier2, memBarrier2Size.allocateBytes + imgBarrier2Size.allocateBytes, |
| &writePtr); |
| |
| paramStruct->dependencyFlags = dependencyFlags; |
| paramStruct->memoryBarrierCount = memoryBarrierCount; |
| paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount; |
| // Copy variable sized data |
| if (memoryBarrierCount > 0) |
| { |
| writePtr = storeArrayParameter(writePtr, memoryBarriers2, memBarrier2Size); |
| } |
| if (imageMemoryBarrierCount > 0) |
| { |
| storeArrayParameter(writePtr, imageMemoryBarriers2, imgBarrier2Size); |
| } |
| } |
| |
| 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; |
| const ArrayParamSize dataSize = calculateArrayParameterSize<uint8_t>(size); |
| PushConstantsParams *paramStruct = initCommand<PushConstantsParams>( |
| CommandID::PushConstants, dataSize.allocateBytes, &writePtr); |
| paramStruct->layout = layout.getHandle(); |
| paramStruct->flag = flag; |
| paramStruct->offset = offset; |
| paramStruct->size = size; |
| // Copy variable sized data |
| storeArrayParameter(writePtr, data, dataSize); |
| } |
| |
| 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(const QueryPool &queryPool, |
| uint32_t firstQuery, |
| uint32_t queryCount) |
| { |
| ResetQueryPoolParams *paramStruct = |
| initCommand<ResetQueryPoolParams>(CommandID::ResetQueryPool); |
| paramStruct->queryPool = queryPool.getHandle(); |
| SetBitField(paramStruct->firstQuery, firstQuery); |
| SetBitField(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::setBlendConstants(const float blendConstants[4]) |
| { |
| SetBlendConstantsParams *paramStruct = |
| initCommand<SetBlendConstantsParams>(CommandID::SetBlendConstants); |
| for (uint32_t channel = 0; channel < 4; ++channel) |
| { |
| paramStruct->blendConstants[channel] = blendConstants[channel]; |
| } |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setCullMode(VkCullModeFlags cullMode) |
| { |
| SetCullModeParams *paramStruct = initCommand<SetCullModeParams>(CommandID::SetCullMode); |
| paramStruct->cullMode = cullMode; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setDepthBias(float depthBiasConstantFactor, |
| float depthBiasClamp, |
| float depthBiasSlopeFactor) |
| { |
| SetDepthBiasParams *paramStruct = initCommand<SetDepthBiasParams>(CommandID::SetDepthBias); |
| paramStruct->depthBiasConstantFactor = depthBiasConstantFactor; |
| paramStruct->depthBiasClamp = depthBiasClamp; |
| paramStruct->depthBiasSlopeFactor = depthBiasSlopeFactor; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setDepthBiasEnable(VkBool32 depthBiasEnable) |
| { |
| SetDepthBiasEnableParams *paramStruct = |
| initCommand<SetDepthBiasEnableParams>(CommandID::SetDepthBiasEnable); |
| paramStruct->depthBiasEnable = depthBiasEnable; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setDepthCompareOp(VkCompareOp depthCompareOp) |
| { |
| SetDepthCompareOpParams *paramStruct = |
| initCommand<SetDepthCompareOpParams>(CommandID::SetDepthCompareOp); |
| paramStruct->depthCompareOp = depthCompareOp; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setDepthTestEnable(VkBool32 depthTestEnable) |
| { |
| SetDepthTestEnableParams *paramStruct = |
| initCommand<SetDepthTestEnableParams>(CommandID::SetDepthTestEnable); |
| paramStruct->depthTestEnable = depthTestEnable; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setDepthWriteEnable(VkBool32 depthWriteEnable) |
| { |
| SetDepthWriteEnableParams *paramStruct = |
| initCommand<SetDepthWriteEnableParams>(CommandID::SetDepthWriteEnable); |
| paramStruct->depthWriteEnable = depthWriteEnable; |
| } |
| |
| 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::setFragmentShadingRate( |
| const VkExtent2D *fragmentSize, |
| VkFragmentShadingRateCombinerOpKHR ops[2]) |
| { |
| ASSERT(fragmentSize != nullptr); |
| |
| // Supported parameter values - |
| // 1. CombinerOp for ops[0] needs to be VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR |
| // as there are no current usecases in ANGLE to use primitive fragment shading rates |
| // 2. The largest fragment size supported is 4x4 |
| ASSERT(ops[0] == VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR); |
| ASSERT(fragmentSize->width <= 4); |
| ASSERT(fragmentSize->height <= 4); |
| |
| SetFragmentShadingRateParams *paramStruct = |
| initCommand<SetFragmentShadingRateParams>(CommandID::SetFragmentShadingRate); |
| paramStruct->fragmentWidth = static_cast<uint16_t>(fragmentSize->width); |
| paramStruct->fragmentHeight = static_cast<uint16_t>(fragmentSize->height); |
| paramStruct->vkFragmentShadingRateCombinerOp1 = static_cast<uint16_t>(ops[1]); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setFrontFace(VkFrontFace frontFace) |
| { |
| SetFrontFaceParams *paramStruct = initCommand<SetFrontFaceParams>(CommandID::SetFrontFace); |
| paramStruct->frontFace = frontFace; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setLineWidth(float lineWidth) |
| { |
| SetLineWidthParams *paramStruct = initCommand<SetLineWidthParams>(CommandID::SetLineWidth); |
| paramStruct->lineWidth = lineWidth; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setLogicOp(VkLogicOp logicOp) |
| { |
| SetLogicOpParams *paramStruct = initCommand<SetLogicOpParams>(CommandID::SetLogicOp); |
| paramStruct->logicOp = logicOp; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setPrimitiveRestartEnable(VkBool32 primitiveRestartEnable) |
| { |
| SetPrimitiveRestartEnableParams *paramStruct = |
| initCommand<SetPrimitiveRestartEnableParams>(CommandID::SetPrimitiveRestartEnable); |
| paramStruct->primitiveRestartEnable = primitiveRestartEnable; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setRasterizerDiscardEnable( |
| VkBool32 rasterizerDiscardEnable) |
| { |
| SetRasterizerDiscardEnableParams *paramStruct = |
| initCommand<SetRasterizerDiscardEnableParams>(CommandID::SetRasterizerDiscardEnable); |
| paramStruct->rasterizerDiscardEnable = rasterizerDiscardEnable; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setScissor(uint32_t firstScissor, |
| uint32_t scissorCount, |
| const VkRect2D *scissors) |
| { |
| ASSERT(firstScissor == 0); |
| ASSERT(scissorCount == 1); |
| ASSERT(scissors != nullptr); |
| SetScissorParams *paramStruct = initCommand<SetScissorParams>(CommandID::SetScissor); |
| paramStruct->scissor = scissors[0]; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setStencilCompareMask(uint32_t compareFrontMask, |
| uint32_t compareBackMask) |
| { |
| SetStencilCompareMaskParams *paramStruct = |
| initCommand<SetStencilCompareMaskParams>(CommandID::SetStencilCompareMask); |
| paramStruct->compareFrontMask = static_cast<uint16_t>(compareFrontMask); |
| paramStruct->compareBackMask = static_cast<uint16_t>(compareBackMask); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setStencilOp(VkStencilFaceFlags faceMask, |
| VkStencilOp failOp, |
| VkStencilOp passOp, |
| VkStencilOp depthFailOp, |
| VkCompareOp compareOp) |
| { |
| SetStencilOpParams *paramStruct = initCommand<SetStencilOpParams>(CommandID::SetStencilOp); |
| SetBitField(paramStruct->faceMask, faceMask); |
| SetBitField(paramStruct->failOp, failOp); |
| SetBitField(paramStruct->passOp, passOp); |
| SetBitField(paramStruct->depthFailOp, depthFailOp); |
| SetBitField(paramStruct->compareOp, compareOp); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setStencilReference(uint32_t frontReference, |
| uint32_t backReference) |
| { |
| SetStencilReferenceParams *paramStruct = |
| initCommand<SetStencilReferenceParams>(CommandID::SetStencilReference); |
| paramStruct->frontReference = static_cast<uint16_t>(frontReference); |
| paramStruct->backReference = static_cast<uint16_t>(backReference); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setStencilTestEnable(VkBool32 stencilTestEnable) |
| { |
| SetStencilTestEnableParams *paramStruct = |
| initCommand<SetStencilTestEnableParams>(CommandID::SetStencilTestEnable); |
| paramStruct->stencilTestEnable = stencilTestEnable; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setStencilWriteMask(uint32_t writeFrontMask, |
| uint32_t writeBackMask) |
| { |
| SetStencilWriteMaskParams *paramStruct = |
| initCommand<SetStencilWriteMaskParams>(CommandID::SetStencilWriteMask); |
| paramStruct->writeFrontMask = static_cast<uint16_t>(writeFrontMask); |
| paramStruct->writeBackMask = static_cast<uint16_t>(writeBackMask); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setVertexInput( |
| uint32_t vertexBindingDescriptionCount, |
| const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions, |
| uint32_t vertexAttributeDescriptionCount, |
| const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions) |
| { |
| uint8_t *writePtr; |
| const ArrayParamSize vertexBindingDescriptionSize = |
| calculateArrayParameterSize<VkVertexInputBindingDescription2EXT>( |
| vertexBindingDescriptionCount); |
| const ArrayParamSize vertexAttributeDescriptionSize = |
| calculateArrayParameterSize<VkVertexInputAttributeDescription2EXT>( |
| vertexAttributeDescriptionCount); |
| |
| SetVertexInputParams *paramStruct = initCommand<SetVertexInputParams>( |
| CommandID::SetVertexInput, |
| vertexBindingDescriptionSize.allocateBytes + vertexAttributeDescriptionSize.allocateBytes, |
| &writePtr); |
| |
| // Copy params |
| SetBitField(paramStruct->vertexBindingDescriptionCount, vertexBindingDescriptionCount); |
| SetBitField(paramStruct->vertexAttributeDescriptionCount, vertexAttributeDescriptionCount); |
| |
| if (vertexBindingDescriptionSize.copyBytes) |
| { |
| writePtr = |
| storeArrayParameter(writePtr, vertexBindingDescriptions, vertexBindingDescriptionSize); |
| } |
| if (vertexAttributeDescriptionSize.copyBytes) |
| { |
| storeArrayParameter(writePtr, vertexAttributeDescriptions, vertexAttributeDescriptionSize); |
| } |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::setViewport(uint32_t firstViewport, |
| uint32_t viewportCount, |
| const VkViewport *viewports) |
| { |
| ASSERT(firstViewport == 0); |
| ASSERT(viewportCount == 1); |
| ASSERT(viewports != nullptr); |
| SetViewportParams *paramStruct = initCommand<SetViewportParams>(CommandID::SetViewport); |
| paramStruct->viewport = viewports[0]; |
| } |
| |
| 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) |
| { |
| // Other than for QFOT (where bufferBarrier() is used), ANGLE doesn't use buffer barriers. |
| // Memory barriers are used instead. |
| ASSERT(bufferMemoryBarrierCount == 0); |
| ASSERT(bufferMemoryBarriers == nullptr); |
| |
| uint8_t *writePtr; |
| const ArrayParamSize eventSize = calculateArrayParameterSize<VkEvent>(eventCount); |
| const ArrayParamSize memBarrierSize = |
| calculateArrayParameterSize<VkMemoryBarrier>(memoryBarrierCount); |
| const ArrayParamSize imgBarrierSize = |
| calculateArrayParameterSize<VkImageMemoryBarrier>(imageMemoryBarrierCount); |
| WaitEventsParams *paramStruct = initCommand<WaitEventsParams>( |
| CommandID::WaitEvents, |
| eventSize.allocateBytes + memBarrierSize.allocateBytes + imgBarrierSize.allocateBytes, |
| &writePtr); |
| paramStruct->eventCount = eventCount; |
| paramStruct->srcStageMask = srcStageMask; |
| paramStruct->dstStageMask = dstStageMask; |
| paramStruct->memoryBarrierCount = memoryBarrierCount; |
| paramStruct->imageMemoryBarrierCount = imageMemoryBarrierCount; |
| // Copy variable sized data |
| writePtr = storeArrayParameter(writePtr, events, eventSize); |
| writePtr = storeArrayParameter(writePtr, memoryBarriers, memBarrierSize); |
| storeArrayParameter(writePtr, imageMemoryBarriers, imgBarrierSize); |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp(VkPipelineStageFlagBits pipelineStage, |
| const QueryPool &queryPool, |
| uint32_t query) |
| { |
| ASSERT(pipelineStage == VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT); |
| |
| WriteTimestampParams *paramStruct = |
| initCommand<WriteTimestampParams>(CommandID::WriteTimestamp); |
| paramStruct->queryPool = queryPool.getHandle(); |
| paramStruct->query = query; |
| } |
| |
| ANGLE_INLINE void SecondaryCommandBuffer::writeTimestamp2(VkPipelineStageFlagBits2 pipelineStage, |
| const QueryPool &queryPool, |
| uint32_t query) |
| { |
| ASSERT(pipelineStage == VK_PIPELINE_STAGE_2_BOTTOM_OF_PIPE_BIT); |
| |
| WriteTimestampParams *paramStruct = |
| initCommand<WriteTimestampParams>(CommandID::WriteTimestamp2); |
| paramStruct->queryPool = queryPool.getHandle(); |
| paramStruct->query = query; |
| } |
| } // namespace priv |
| } // namespace vk |
| } // namespace rx |
| |
| #endif // LIBANGLE_RENDERER_VULKAN_SECONDARYCOMMANDBUFFERVK_H_ |