| // |
| // 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: |
| // CPU-side storage of commands to delay GPU-side allocation until commands are submitted. |
| // |
| |
| #include "libANGLE/renderer/vulkan/SecondaryCommandBuffer.h" |
| #include "common/debug.h" |
| #include "libANGLE/renderer/vulkan/vk_utils.h" |
| #include "libANGLE/trace.h" |
| |
| namespace rx |
| { |
| namespace vk |
| { |
| namespace priv |
| { |
| namespace |
| { |
| const char *GetCommandString(CommandID id) |
| { |
| switch (id) |
| { |
| case CommandID::Invalid: |
| return "--Invalid--"; |
| case CommandID::BeginDebugUtilsLabel: |
| return "BeginDebugUtilsLabel"; |
| case CommandID::BeginQuery: |
| return "BeginQuery"; |
| case CommandID::BeginTransformFeedback: |
| return "BeginTransformFeedback"; |
| case CommandID::BindComputePipeline: |
| return "BindComputePipeline"; |
| case CommandID::BindDescriptorSets: |
| return "BindDescriptorSets"; |
| case CommandID::BindGraphicsPipeline: |
| return "BindGraphicsPipeline"; |
| case CommandID::BindIndexBuffer: |
| return "BindIndexBuffer"; |
| case CommandID::BindTransformFeedbackBuffers: |
| return "BindTransformFeedbackBuffers"; |
| case CommandID::BindVertexBuffers: |
| return "BindVertexBuffers"; |
| case CommandID::BindVertexBuffers2: |
| return "BindVertexBuffers2"; |
| case CommandID::BlitImage: |
| return "BlitImage"; |
| case CommandID::BufferBarrier: |
| return "BufferBarrier"; |
| case CommandID::ClearAttachments: |
| return "ClearAttachments"; |
| case CommandID::ClearColorImage: |
| return "ClearColorImage"; |
| case CommandID::ClearDepthStencilImage: |
| return "ClearDepthStencilImage"; |
| case CommandID::CopyBuffer: |
| return "CopyBuffer"; |
| case CommandID::CopyBufferToImage: |
| return "CopyBufferToImage"; |
| case CommandID::CopyImage: |
| return "CopyImage"; |
| case CommandID::CopyImageToBuffer: |
| return "CopyImageToBuffer"; |
| case CommandID::Dispatch: |
| return "Dispatch"; |
| case CommandID::DispatchIndirect: |
| return "DispatchIndirect"; |
| case CommandID::Draw: |
| return "Draw"; |
| case CommandID::DrawIndexed: |
| return "DrawIndexed"; |
| case CommandID::DrawIndexedBaseVertex: |
| return "DrawIndexedBaseVertex"; |
| case CommandID::DrawIndexedIndirect: |
| return "DrawIndexedIndirect"; |
| case CommandID::DrawIndexedInstanced: |
| return "DrawIndexedInstanced"; |
| case CommandID::DrawIndexedInstancedBaseVertex: |
| return "DrawIndexedInstancedBaseVertex"; |
| case CommandID::DrawIndexedInstancedBaseVertexBaseInstance: |
| return "DrawIndexedInstancedBaseVertexBaseInstance"; |
| case CommandID::DrawIndirect: |
| return "DrawIndirect"; |
| case CommandID::DrawInstanced: |
| return "DrawInstanced"; |
| case CommandID::DrawInstancedBaseInstance: |
| return "DrawInstancedBaseInstance"; |
| case CommandID::EndDebugUtilsLabel: |
| return "EndDebugUtilsLabel"; |
| case CommandID::EndQuery: |
| return "EndQuery"; |
| case CommandID::EndTransformFeedback: |
| return "EndTransformFeedback"; |
| case CommandID::FillBuffer: |
| return "FillBuffer"; |
| case CommandID::ImageBarrier: |
| return "ImageBarrier"; |
| case CommandID::InsertDebugUtilsLabel: |
| return "InsertDebugUtilsLabel"; |
| case CommandID::MemoryBarrier: |
| return "MemoryBarrier"; |
| case CommandID::NextSubpass: |
| return "NextSubpass"; |
| case CommandID::PipelineBarrier: |
| return "PipelineBarrier"; |
| case CommandID::PushConstants: |
| return "PushConstants"; |
| case CommandID::ResetEvent: |
| return "ResetEvent"; |
| case CommandID::ResetQueryPool: |
| return "ResetQueryPool"; |
| case CommandID::ResolveImage: |
| return "ResolveImage"; |
| case CommandID::SetBlendConstants: |
| return "SetBlendConstants"; |
| case CommandID::SetCullMode: |
| return "SetCullMode"; |
| case CommandID::SetDepthBias: |
| return "SetDepthBias"; |
| case CommandID::SetDepthBiasEnable: |
| return "SetDepthBiasEnable"; |
| case CommandID::SetDepthCompareOp: |
| return "SetDepthCompareOp"; |
| case CommandID::SetDepthTestEnable: |
| return "SetDepthTestEnable"; |
| case CommandID::SetDepthWriteEnable: |
| return "SetDepthWriteEnable"; |
| case CommandID::SetEvent: |
| return "SetEvent"; |
| case CommandID::SetFragmentShadingRate: |
| return "SetFragmentShadingRate"; |
| case CommandID::SetFrontFace: |
| return "SetFrontFace"; |
| case CommandID::SetLineWidth: |
| return "SetLineWidth"; |
| case CommandID::SetLogicOp: |
| return "SetLogicOp"; |
| case CommandID::SetPrimitiveRestartEnable: |
| return "SetPrimitiveRestartEnable"; |
| case CommandID::SetRasterizerDiscardEnable: |
| return "SetRasterizerDiscardEnable"; |
| case CommandID::SetScissor: |
| return "SetScissor"; |
| case CommandID::SetStencilCompareMask: |
| return "SetStencilCompareMask"; |
| case CommandID::SetStencilOp: |
| return "SetStencilOp"; |
| case CommandID::SetStencilReference: |
| return "SetStencilReference"; |
| case CommandID::SetStencilTestEnable: |
| return "SetStencilTestEnable"; |
| case CommandID::SetStencilWriteMask: |
| return "SetStencilWriteMask"; |
| case CommandID::SetVertexInput: |
| return "SetVertexInput"; |
| case CommandID::SetViewport: |
| return "SetViewport"; |
| case CommandID::WaitEvents: |
| return "WaitEvents"; |
| case CommandID::WriteTimestamp: |
| return "WriteTimestamp"; |
| default: |
| // Need this to work around MSVC warning 4715. |
| UNREACHABLE(); |
| return "--unreachable--"; |
| } |
| } |
| |
| // Given the pointer to the parameter struct, returns the pointer to the first array parameter. |
| template <typename T, typename StructType> |
| ANGLE_INLINE const T *GetFirstArrayParameter(StructType *param) |
| { |
| // The first array parameter is always right after the struct itself. |
| return Offset<T>(param, sizeof(*param)); |
| } |
| |
| // Given the pointer to one array parameter (and its array count), returns the pointer to the next |
| // array parameter. |
| template <typename NextT, typename PrevT> |
| ANGLE_INLINE const NextT *GetNextArrayParameter(const PrevT *array, size_t arrayLen) |
| { |
| const size_t arrayAllocateBytes = roundUpPow2<size_t>(sizeof(*array) * arrayLen, 8u); |
| return Offset<NextT>(array, arrayAllocateBytes); |
| } |
| } // namespace |
| |
| ANGLE_INLINE const CommandHeader *NextCommand(const CommandHeader *command) |
| { |
| return reinterpret_cast<const CommandHeader *>(reinterpret_cast<const uint8_t *>(command) + |
| command->size); |
| } |
| |
| // Parse the cmds in this cmd buffer into given primary cmd buffer |
| void SecondaryCommandBuffer::executeCommands(PrimaryCommandBuffer *primary) |
| { |
| VkCommandBuffer cmdBuffer = primary->getHandle(); |
| |
| ANGLE_TRACE_EVENT0("gpu.angle", "SecondaryCommandBuffer::executeCommands"); |
| |
| // Used for ring buffer allocators only. |
| mCommandAllocator.terminateLastCommandBlock(); |
| |
| for (const CommandHeader *command : mCommands) |
| { |
| for (const CommandHeader *currentCommand = command; |
| currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand)) |
| { |
| switch (currentCommand->id) |
| { |
| case CommandID::BeginDebugUtilsLabel: |
| { |
| const DebugUtilsLabelParams *params = |
| getParamPtr<DebugUtilsLabelParams>(currentCommand); |
| const char *pLabelName = GetFirstArrayParameter<char>(params); |
| const VkDebugUtilsLabelEXT label = { |
| VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, |
| nullptr, |
| pLabelName, |
| {params->color[0], params->color[1], params->color[2], params->color[3]}}; |
| ASSERT(vkCmdBeginDebugUtilsLabelEXT); |
| vkCmdBeginDebugUtilsLabelEXT(cmdBuffer, &label); |
| break; |
| } |
| case CommandID::BeginQuery: |
| { |
| const BeginQueryParams *params = getParamPtr<BeginQueryParams>(currentCommand); |
| vkCmdBeginQuery(cmdBuffer, params->queryPool, params->query, 0); |
| break; |
| } |
| case CommandID::BeginTransformFeedback: |
| { |
| const BeginTransformFeedbackParams *params = |
| getParamPtr<BeginTransformFeedbackParams>(currentCommand); |
| const VkBuffer *counterBuffers = GetFirstArrayParameter<VkBuffer>(params); |
| const VkDeviceSize *counterBufferOffsets = |
| reinterpret_cast<const VkDeviceSize *>(counterBuffers + |
| params->bufferCount); |
| vkCmdBeginTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount, |
| counterBuffers, counterBufferOffsets); |
| break; |
| } |
| case CommandID::BindComputePipeline: |
| { |
| const BindPipelineParams *params = |
| getParamPtr<BindPipelineParams>(currentCommand); |
| vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, params->pipeline); |
| break; |
| } |
| case CommandID::BindDescriptorSets: |
| { |
| const BindDescriptorSetParams *params = |
| getParamPtr<BindDescriptorSetParams>(currentCommand); |
| const VkDescriptorSet *descriptorSets = |
| GetFirstArrayParameter<VkDescriptorSet>(params); |
| const uint32_t *dynamicOffsets = |
| GetNextArrayParameter<uint32_t>(descriptorSets, params->descriptorSetCount); |
| vkCmdBindDescriptorSets(cmdBuffer, params->pipelineBindPoint, params->layout, |
| params->firstSet, params->descriptorSetCount, |
| descriptorSets, params->dynamicOffsetCount, |
| dynamicOffsets); |
| break; |
| } |
| case CommandID::BindGraphicsPipeline: |
| { |
| const BindPipelineParams *params = |
| getParamPtr<BindPipelineParams>(currentCommand); |
| vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, params->pipeline); |
| break; |
| } |
| case CommandID::BindIndexBuffer: |
| { |
| const BindIndexBufferParams *params = |
| getParamPtr<BindIndexBufferParams>(currentCommand); |
| vkCmdBindIndexBuffer(cmdBuffer, params->buffer, params->offset, |
| params->indexType); |
| break; |
| } |
| case CommandID::BindTransformFeedbackBuffers: |
| { |
| const BindTransformFeedbackBuffersParams *params = |
| getParamPtr<BindTransformFeedbackBuffersParams>(currentCommand); |
| const VkBuffer *buffers = GetFirstArrayParameter<VkBuffer>(params); |
| const VkDeviceSize *offsets = |
| GetNextArrayParameter<VkDeviceSize>(buffers, params->bindingCount); |
| const VkDeviceSize *sizes = |
| GetNextArrayParameter<VkDeviceSize>(offsets, params->bindingCount); |
| vkCmdBindTransformFeedbackBuffersEXT(cmdBuffer, 0, params->bindingCount, |
| buffers, offsets, sizes); |
| break; |
| } |
| case CommandID::BindVertexBuffers: |
| { |
| const BindVertexBuffersParams *params = |
| getParamPtr<BindVertexBuffersParams>(currentCommand); |
| const VkBuffer *buffers = GetFirstArrayParameter<VkBuffer>(params); |
| const VkDeviceSize *offsets = |
| GetNextArrayParameter<VkDeviceSize>(buffers, params->bindingCount); |
| vkCmdBindVertexBuffers(cmdBuffer, 0, params->bindingCount, buffers, offsets); |
| break; |
| } |
| case CommandID::BindVertexBuffers2: |
| { |
| const BindVertexBuffers2Params *params = |
| getParamPtr<BindVertexBuffers2Params>(currentCommand); |
| const VkBuffer *buffers = GetFirstArrayParameter<VkBuffer>(params); |
| const VkDeviceSize *offsets = |
| GetNextArrayParameter<VkDeviceSize>(buffers, params->bindingCount); |
| const VkDeviceSize *strides = |
| GetNextArrayParameter<VkDeviceSize>(offsets, params->bindingCount); |
| vkCmdBindVertexBuffers2EXT(cmdBuffer, 0, params->bindingCount, buffers, offsets, |
| nullptr, strides); |
| break; |
| } |
| case CommandID::BlitImage: |
| { |
| const BlitImageParams *params = getParamPtr<BlitImageParams>(currentCommand); |
| vkCmdBlitImage(cmdBuffer, params->srcImage, |
| VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, params->dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ¶ms->region, |
| params->filter); |
| break; |
| } |
| case CommandID::BufferBarrier: |
| { |
| const BufferBarrierParams *params = |
| getParamPtr<BufferBarrierParams>(currentCommand); |
| vkCmdPipelineBarrier(cmdBuffer, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, |
| VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, 0, 0, nullptr, 1, |
| ¶ms->bufferMemoryBarrier, 0, nullptr); |
| break; |
| } |
| case CommandID::ClearAttachments: |
| { |
| const ClearAttachmentsParams *params = |
| getParamPtr<ClearAttachmentsParams>(currentCommand); |
| const VkClearAttachment *attachments = |
| GetFirstArrayParameter<VkClearAttachment>(params); |
| vkCmdClearAttachments(cmdBuffer, params->attachmentCount, attachments, 1, |
| ¶ms->rect); |
| break; |
| } |
| case CommandID::ClearColorImage: |
| { |
| const ClearColorImageParams *params = |
| getParamPtr<ClearColorImageParams>(currentCommand); |
| vkCmdClearColorImage(cmdBuffer, params->image, params->imageLayout, |
| ¶ms->color, 1, ¶ms->range); |
| break; |
| } |
| case CommandID::ClearDepthStencilImage: |
| { |
| const ClearDepthStencilImageParams *params = |
| getParamPtr<ClearDepthStencilImageParams>(currentCommand); |
| vkCmdClearDepthStencilImage(cmdBuffer, params->image, params->imageLayout, |
| ¶ms->depthStencil, 1, ¶ms->range); |
| break; |
| } |
| case CommandID::CopyBuffer: |
| { |
| const CopyBufferParams *params = getParamPtr<CopyBufferParams>(currentCommand); |
| const VkBufferCopy *regions = GetFirstArrayParameter<VkBufferCopy>(params); |
| vkCmdCopyBuffer(cmdBuffer, params->srcBuffer, params->destBuffer, |
| params->regionCount, regions); |
| break; |
| } |
| case CommandID::CopyBufferToImage: |
| { |
| const CopyBufferToImageParams *params = |
| getParamPtr<CopyBufferToImageParams>(currentCommand); |
| vkCmdCopyBufferToImage(cmdBuffer, params->srcBuffer, params->dstImage, |
| params->dstImageLayout, 1, ¶ms->region); |
| break; |
| } |
| case CommandID::CopyImage: |
| { |
| const CopyImageParams *params = getParamPtr<CopyImageParams>(currentCommand); |
| vkCmdCopyImage(cmdBuffer, params->srcImage, params->srcImageLayout, |
| params->dstImage, params->dstImageLayout, 1, ¶ms->region); |
| break; |
| } |
| case CommandID::CopyImageToBuffer: |
| { |
| const CopyImageToBufferParams *params = |
| getParamPtr<CopyImageToBufferParams>(currentCommand); |
| vkCmdCopyImageToBuffer(cmdBuffer, params->srcImage, params->srcImageLayout, |
| params->dstBuffer, 1, ¶ms->region); |
| break; |
| } |
| case CommandID::Dispatch: |
| { |
| const DispatchParams *params = getParamPtr<DispatchParams>(currentCommand); |
| vkCmdDispatch(cmdBuffer, params->groupCountX, params->groupCountY, |
| params->groupCountZ); |
| break; |
| } |
| case CommandID::DispatchIndirect: |
| { |
| const DispatchIndirectParams *params = |
| getParamPtr<DispatchIndirectParams>(currentCommand); |
| vkCmdDispatchIndirect(cmdBuffer, params->buffer, params->offset); |
| break; |
| } |
| case CommandID::Draw: |
| { |
| const DrawParams *params = getParamPtr<DrawParams>(currentCommand); |
| vkCmdDraw(cmdBuffer, params->vertexCount, 1, params->firstVertex, 0); |
| break; |
| } |
| case CommandID::DrawIndexed: |
| { |
| const DrawIndexedParams *params = |
| getParamPtr<DrawIndexedParams>(currentCommand); |
| vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, 0, 0); |
| break; |
| } |
| case CommandID::DrawIndexedBaseVertex: |
| { |
| const DrawIndexedBaseVertexParams *params = |
| getParamPtr<DrawIndexedBaseVertexParams>(currentCommand); |
| vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, params->vertexOffset, 0); |
| break; |
| } |
| case CommandID::DrawIndexedIndirect: |
| { |
| const DrawIndexedIndirectParams *params = |
| getParamPtr<DrawIndexedIndirectParams>(currentCommand); |
| vkCmdDrawIndexedIndirect(cmdBuffer, params->buffer, params->offset, |
| params->drawCount, params->stride); |
| break; |
| } |
| case CommandID::DrawIndexedInstanced: |
| { |
| const DrawIndexedInstancedParams *params = |
| getParamPtr<DrawIndexedInstancedParams>(currentCommand); |
| vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, 0, 0); |
| break; |
| } |
| case CommandID::DrawIndexedInstancedBaseVertex: |
| { |
| const DrawIndexedInstancedBaseVertexParams *params = |
| getParamPtr<DrawIndexedInstancedBaseVertexParams>(currentCommand); |
| vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, |
| params->vertexOffset, 0); |
| break; |
| } |
| case CommandID::DrawIndexedInstancedBaseVertexBaseInstance: |
| { |
| const DrawIndexedInstancedBaseVertexBaseInstanceParams *params = |
| getParamPtr<DrawIndexedInstancedBaseVertexBaseInstanceParams>( |
| currentCommand); |
| vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, |
| params->firstIndex, params->vertexOffset, |
| params->firstInstance); |
| break; |
| } |
| case CommandID::DrawIndirect: |
| { |
| const DrawIndirectParams *params = |
| getParamPtr<DrawIndirectParams>(currentCommand); |
| vkCmdDrawIndirect(cmdBuffer, params->buffer, params->offset, params->drawCount, |
| params->stride); |
| break; |
| } |
| case CommandID::DrawInstanced: |
| { |
| const DrawInstancedParams *params = |
| getParamPtr<DrawInstancedParams>(currentCommand); |
| vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount, |
| params->firstVertex, 0); |
| break; |
| } |
| case CommandID::DrawInstancedBaseInstance: |
| { |
| const DrawInstancedBaseInstanceParams *params = |
| getParamPtr<DrawInstancedBaseInstanceParams>(currentCommand); |
| vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount, |
| params->firstVertex, params->firstInstance); |
| break; |
| } |
| case CommandID::EndDebugUtilsLabel: |
| { |
| ASSERT(vkCmdEndDebugUtilsLabelEXT); |
| vkCmdEndDebugUtilsLabelEXT(cmdBuffer); |
| break; |
| } |
| case CommandID::EndQuery: |
| { |
| const EndQueryParams *params = getParamPtr<EndQueryParams>(currentCommand); |
| vkCmdEndQuery(cmdBuffer, params->queryPool, params->query); |
| break; |
| } |
| case CommandID::EndTransformFeedback: |
| { |
| const EndTransformFeedbackParams *params = |
| getParamPtr<EndTransformFeedbackParams>(currentCommand); |
| const VkBuffer *counterBuffers = GetFirstArrayParameter<VkBuffer>(params); |
| const VkDeviceSize *counterBufferOffsets = |
| reinterpret_cast<const VkDeviceSize *>(counterBuffers + |
| params->bufferCount); |
| vkCmdEndTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount, counterBuffers, |
| counterBufferOffsets); |
| break; |
| } |
| case CommandID::FillBuffer: |
| { |
| const FillBufferParams *params = getParamPtr<FillBufferParams>(currentCommand); |
| vkCmdFillBuffer(cmdBuffer, params->dstBuffer, params->dstOffset, params->size, |
| params->data); |
| break; |
| } |
| case CommandID::ImageBarrier: |
| { |
| const ImageBarrierParams *params = |
| getParamPtr<ImageBarrierParams>(currentCommand); |
| const VkImageMemoryBarrier *imageMemoryBarriers = |
| GetFirstArrayParameter<VkImageMemoryBarrier>(params); |
| vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0, |
| 0, nullptr, 0, nullptr, 1, imageMemoryBarriers); |
| break; |
| } |
| case CommandID::InsertDebugUtilsLabel: |
| { |
| const DebugUtilsLabelParams *params = |
| getParamPtr<DebugUtilsLabelParams>(currentCommand); |
| const char *pLabelName = GetFirstArrayParameter<char>(params); |
| const VkDebugUtilsLabelEXT label = { |
| VK_STRUCTURE_TYPE_DEBUG_UTILS_LABEL_EXT, |
| nullptr, |
| pLabelName, |
| {params->color[0], params->color[1], params->color[2], params->color[3]}}; |
| ASSERT(vkCmdInsertDebugUtilsLabelEXT); |
| vkCmdInsertDebugUtilsLabelEXT(cmdBuffer, &label); |
| break; |
| } |
| case CommandID::MemoryBarrier: |
| { |
| const MemoryBarrierParams *params = |
| getParamPtr<MemoryBarrierParams>(currentCommand); |
| const VkMemoryBarrier *memoryBarriers = |
| GetFirstArrayParameter<VkMemoryBarrier>(params); |
| vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0, |
| 1, memoryBarriers, 0, nullptr, 0, nullptr); |
| break; |
| } |
| case CommandID::NextSubpass: |
| { |
| vkCmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); |
| break; |
| } |
| case CommandID::PipelineBarrier: |
| { |
| const PipelineBarrierParams *params = |
| getParamPtr<PipelineBarrierParams>(currentCommand); |
| const VkMemoryBarrier *memoryBarriers = |
| GetFirstArrayParameter<VkMemoryBarrier>(params); |
| const VkImageMemoryBarrier *imageMemoryBarriers = |
| GetNextArrayParameter<VkImageMemoryBarrier>(memoryBarriers, |
| params->memoryBarrierCount); |
| vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, |
| params->dependencyFlags, params->memoryBarrierCount, |
| memoryBarriers, 0, nullptr, |
| params->imageMemoryBarrierCount, imageMemoryBarriers); |
| break; |
| } |
| case CommandID::PushConstants: |
| { |
| const PushConstantsParams *params = |
| getParamPtr<PushConstantsParams>(currentCommand); |
| const void *data = GetFirstArrayParameter<void>(params); |
| vkCmdPushConstants(cmdBuffer, params->layout, params->flag, params->offset, |
| params->size, data); |
| break; |
| } |
| case CommandID::ResetEvent: |
| { |
| const ResetEventParams *params = getParamPtr<ResetEventParams>(currentCommand); |
| vkCmdResetEvent(cmdBuffer, params->event, params->stageMask); |
| break; |
| } |
| case CommandID::ResetQueryPool: |
| { |
| const ResetQueryPoolParams *params = |
| getParamPtr<ResetQueryPoolParams>(currentCommand); |
| vkCmdResetQueryPool(cmdBuffer, params->queryPool, params->firstQuery, |
| params->queryCount); |
| break; |
| } |
| case CommandID::ResolveImage: |
| { |
| const ResolveImageParams *params = |
| getParamPtr<ResolveImageParams>(currentCommand); |
| vkCmdResolveImage(cmdBuffer, params->srcImage, |
| VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, params->dstImage, |
| VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ¶ms->region); |
| break; |
| } |
| case CommandID::SetBlendConstants: |
| { |
| const SetBlendConstantsParams *params = |
| getParamPtr<SetBlendConstantsParams>(currentCommand); |
| vkCmdSetBlendConstants(cmdBuffer, params->blendConstants); |
| break; |
| } |
| case CommandID::SetCullMode: |
| { |
| const SetCullModeParams *params = |
| getParamPtr<SetCullModeParams>(currentCommand); |
| vkCmdSetCullModeEXT(cmdBuffer, params->cullMode); |
| break; |
| } |
| case CommandID::SetDepthBias: |
| { |
| const SetDepthBiasParams *params = |
| getParamPtr<SetDepthBiasParams>(currentCommand); |
| vkCmdSetDepthBias(cmdBuffer, params->depthBiasConstantFactor, |
| params->depthBiasClamp, params->depthBiasSlopeFactor); |
| break; |
| } |
| case CommandID::SetDepthBiasEnable: |
| { |
| const SetDepthBiasEnableParams *params = |
| getParamPtr<SetDepthBiasEnableParams>(currentCommand); |
| vkCmdSetDepthBiasEnableEXT(cmdBuffer, params->depthBiasEnable); |
| break; |
| } |
| case CommandID::SetDepthCompareOp: |
| { |
| const SetDepthCompareOpParams *params = |
| getParamPtr<SetDepthCompareOpParams>(currentCommand); |
| vkCmdSetDepthCompareOpEXT(cmdBuffer, params->depthCompareOp); |
| break; |
| } |
| case CommandID::SetDepthTestEnable: |
| { |
| const SetDepthTestEnableParams *params = |
| getParamPtr<SetDepthTestEnableParams>(currentCommand); |
| vkCmdSetDepthTestEnableEXT(cmdBuffer, params->depthTestEnable); |
| break; |
| } |
| case CommandID::SetDepthWriteEnable: |
| { |
| const SetDepthWriteEnableParams *params = |
| getParamPtr<SetDepthWriteEnableParams>(currentCommand); |
| vkCmdSetDepthWriteEnableEXT(cmdBuffer, params->depthWriteEnable); |
| break; |
| } |
| case CommandID::SetEvent: |
| { |
| const SetEventParams *params = getParamPtr<SetEventParams>(currentCommand); |
| vkCmdSetEvent(cmdBuffer, params->event, params->stageMask); |
| break; |
| } |
| case CommandID::SetFragmentShadingRate: |
| { |
| const SetFragmentShadingRateParams *params = |
| getParamPtr<SetFragmentShadingRateParams>(currentCommand); |
| const VkExtent2D fragmentSize = {params->fragmentWidth, params->fragmentHeight}; |
| const VkFragmentShadingRateCombinerOpKHR ops[2] = { |
| VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, |
| static_cast<VkFragmentShadingRateCombinerOpKHR>( |
| params->vkFragmentShadingRateCombinerOp1)}; |
| vkCmdSetFragmentShadingRateKHR(cmdBuffer, &fragmentSize, ops); |
| break; |
| } |
| case CommandID::SetFrontFace: |
| { |
| const SetFrontFaceParams *params = |
| getParamPtr<SetFrontFaceParams>(currentCommand); |
| vkCmdSetFrontFaceEXT(cmdBuffer, params->frontFace); |
| break; |
| } |
| case CommandID::SetLineWidth: |
| { |
| const SetLineWidthParams *params = |
| getParamPtr<SetLineWidthParams>(currentCommand); |
| vkCmdSetLineWidth(cmdBuffer, params->lineWidth); |
| break; |
| } |
| case CommandID::SetLogicOp: |
| { |
| const SetLogicOpParams *params = getParamPtr<SetLogicOpParams>(currentCommand); |
| vkCmdSetLogicOpEXT(cmdBuffer, params->logicOp); |
| break; |
| } |
| case CommandID::SetPrimitiveRestartEnable: |
| { |
| const SetPrimitiveRestartEnableParams *params = |
| getParamPtr<SetPrimitiveRestartEnableParams>(currentCommand); |
| vkCmdSetPrimitiveRestartEnableEXT(cmdBuffer, params->primitiveRestartEnable); |
| break; |
| } |
| case CommandID::SetRasterizerDiscardEnable: |
| { |
| const SetRasterizerDiscardEnableParams *params = |
| getParamPtr<SetRasterizerDiscardEnableParams>(currentCommand); |
| vkCmdSetRasterizerDiscardEnableEXT(cmdBuffer, params->rasterizerDiscardEnable); |
| break; |
| } |
| case CommandID::SetScissor: |
| { |
| const SetScissorParams *params = getParamPtr<SetScissorParams>(currentCommand); |
| vkCmdSetScissor(cmdBuffer, 0, 1, ¶ms->scissor); |
| break; |
| } |
| case CommandID::SetStencilCompareMask: |
| { |
| const SetStencilCompareMaskParams *params = |
| getParamPtr<SetStencilCompareMaskParams>(currentCommand); |
| vkCmdSetStencilCompareMask(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT, |
| params->compareFrontMask); |
| vkCmdSetStencilCompareMask(cmdBuffer, VK_STENCIL_FACE_BACK_BIT, |
| params->compareBackMask); |
| break; |
| } |
| case CommandID::SetStencilOp: |
| { |
| const SetStencilOpParams *params = |
| getParamPtr<SetStencilOpParams>(currentCommand); |
| vkCmdSetStencilOpEXT(cmdBuffer, |
| static_cast<VkStencilFaceFlags>(params->faceMask), |
| static_cast<VkStencilOp>(params->failOp), |
| static_cast<VkStencilOp>(params->passOp), |
| static_cast<VkStencilOp>(params->depthFailOp), |
| static_cast<VkCompareOp>(params->compareOp)); |
| break; |
| } |
| case CommandID::SetStencilReference: |
| { |
| const SetStencilReferenceParams *params = |
| getParamPtr<SetStencilReferenceParams>(currentCommand); |
| vkCmdSetStencilReference(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT, |
| params->frontReference); |
| vkCmdSetStencilReference(cmdBuffer, VK_STENCIL_FACE_BACK_BIT, |
| params->backReference); |
| break; |
| } |
| case CommandID::SetStencilTestEnable: |
| { |
| const SetStencilTestEnableParams *params = |
| getParamPtr<SetStencilTestEnableParams>(currentCommand); |
| vkCmdSetStencilTestEnableEXT(cmdBuffer, params->stencilTestEnable); |
| break; |
| } |
| case CommandID::SetStencilWriteMask: |
| { |
| const SetStencilWriteMaskParams *params = |
| getParamPtr<SetStencilWriteMaskParams>(currentCommand); |
| vkCmdSetStencilWriteMask(cmdBuffer, VK_STENCIL_FACE_FRONT_BIT, |
| params->writeFrontMask); |
| vkCmdSetStencilWriteMask(cmdBuffer, VK_STENCIL_FACE_BACK_BIT, |
| params->writeBackMask); |
| break; |
| } |
| case CommandID::SetVertexInput: |
| { |
| const SetVertexInputParams *params = |
| getParamPtr<SetVertexInputParams>(currentCommand); |
| const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions = |
| GetFirstArrayParameter<VkVertexInputBindingDescription2EXT>(params); |
| const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions = |
| GetNextArrayParameter<VkVertexInputAttributeDescription2EXT, |
| VkVertexInputBindingDescription2EXT>( |
| vertexBindingDescriptions, params->vertexBindingDescriptionCount); |
| |
| vkCmdSetVertexInputEXT( |
| cmdBuffer, params->vertexBindingDescriptionCount, vertexBindingDescriptions, |
| params->vertexAttributeDescriptionCount, vertexAttributeDescriptions); |
| break; |
| } |
| case CommandID::SetViewport: |
| { |
| const SetViewportParams *params = |
| getParamPtr<SetViewportParams>(currentCommand); |
| vkCmdSetViewport(cmdBuffer, 0, 1, ¶ms->viewport); |
| break; |
| } |
| case CommandID::WaitEvents: |
| { |
| const WaitEventsParams *params = getParamPtr<WaitEventsParams>(currentCommand); |
| const VkEvent *events = GetFirstArrayParameter<VkEvent>(params); |
| const VkMemoryBarrier *memoryBarriers = |
| GetNextArrayParameter<VkMemoryBarrier>(events, params->eventCount); |
| const VkImageMemoryBarrier *imageMemoryBarriers = |
| GetNextArrayParameter<VkImageMemoryBarrier>(memoryBarriers, |
| params->memoryBarrierCount); |
| vkCmdWaitEvents(cmdBuffer, params->eventCount, events, params->srcStageMask, |
| params->dstStageMask, params->memoryBarrierCount, |
| memoryBarriers, 0, nullptr, params->imageMemoryBarrierCount, |
| imageMemoryBarriers); |
| break; |
| } |
| case CommandID::WriteTimestamp: |
| { |
| const WriteTimestampParams *params = |
| getParamPtr<WriteTimestampParams>(currentCommand); |
| vkCmdWriteTimestamp(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, |
| params->queryPool, params->query); |
| break; |
| } |
| default: |
| { |
| UNREACHABLE(); |
| break; |
| } |
| } |
| } |
| } |
| } |
| |
| void SecondaryCommandBuffer::getMemoryUsageStats(size_t *usedMemoryOut, |
| size_t *allocatedMemoryOut) const |
| { |
| mCommandAllocator.getMemoryUsageStats(usedMemoryOut, allocatedMemoryOut); |
| } |
| |
| void SecondaryCommandBuffer::getMemoryUsageStatsForPoolAlloc(size_t blockSize, |
| size_t *usedMemoryOut, |
| size_t *allocatedMemoryOut) const |
| { |
| *allocatedMemoryOut = blockSize * mCommands.size(); |
| |
| *usedMemoryOut = 0; |
| for (const CommandHeader *command : mCommands) |
| { |
| const CommandHeader *commandEnd = command; |
| while (commandEnd->id != CommandID::Invalid) |
| { |
| commandEnd = NextCommand(commandEnd); |
| } |
| |
| *usedMemoryOut += reinterpret_cast<const uint8_t *>(commandEnd) - |
| reinterpret_cast<const uint8_t *>(command) + sizeof(CommandHeader::id); |
| } |
| |
| ASSERT(*usedMemoryOut <= *allocatedMemoryOut); |
| } |
| |
| std::string SecondaryCommandBuffer::dumpCommands(const char *separator) const |
| { |
| std::stringstream result; |
| for (const CommandHeader *command : mCommands) |
| { |
| for (const CommandHeader *currentCommand = command; |
| currentCommand->id != CommandID::Invalid; currentCommand = NextCommand(currentCommand)) |
| { |
| result << GetCommandString(currentCommand->id) << separator; |
| } |
| } |
| return result.str(); |
| } |
| |
| } // namespace priv |
| } // namespace vk |
| } // namespace rx |