// // 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::ImageWaitEvent: return "ImageWaitEvent"; 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 ANGLE_INLINE const T *GetFirstArrayParameter(StructType *param) { // The first array parameter is always right after the struct itself. return Offset(param, sizeof(*param)); } // Given the pointer to one array parameter (and its array count), returns the pointer to the next // array parameter. template ANGLE_INLINE const NextT *GetNextArrayParameter(const PrevT *array, size_t arrayLen) { const size_t arrayAllocateBytes = roundUpPow2(sizeof(*array) * arrayLen, 8u); return Offset(array, arrayAllocateBytes); } } // namespace ANGLE_INLINE const CommandHeader *NextCommand(const CommandHeader *command) { return reinterpret_cast(reinterpret_cast(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(currentCommand); const char *pLabelName = GetFirstArrayParameter(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(currentCommand); vkCmdBeginQuery(cmdBuffer, params->queryPool, params->query, 0); break; } case CommandID::BeginTransformFeedback: { const BeginTransformFeedbackParams *params = getParamPtr(currentCommand); const VkBuffer *counterBuffers = GetFirstArrayParameter(params); const VkDeviceSize *counterBufferOffsets = reinterpret_cast(counterBuffers + params->bufferCount); vkCmdBeginTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount, counterBuffers, counterBufferOffsets); break; } case CommandID::BindComputePipeline: { const BindPipelineParams *params = getParamPtr(currentCommand); vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_COMPUTE, params->pipeline); break; } case CommandID::BindDescriptorSets: { const BindDescriptorSetParams *params = getParamPtr(currentCommand); const VkDescriptorSet *descriptorSets = GetFirstArrayParameter(params); const uint32_t *dynamicOffsets = GetNextArrayParameter(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(currentCommand); vkCmdBindPipeline(cmdBuffer, VK_PIPELINE_BIND_POINT_GRAPHICS, params->pipeline); break; } case CommandID::BindIndexBuffer: { const BindIndexBufferParams *params = getParamPtr(currentCommand); vkCmdBindIndexBuffer(cmdBuffer, params->buffer, params->offset, params->indexType); break; } case CommandID::BindTransformFeedbackBuffers: { const BindTransformFeedbackBuffersParams *params = getParamPtr(currentCommand); const VkBuffer *buffers = GetFirstArrayParameter(params); const VkDeviceSize *offsets = GetNextArrayParameter(buffers, params->bindingCount); const VkDeviceSize *sizes = GetNextArrayParameter(offsets, params->bindingCount); vkCmdBindTransformFeedbackBuffersEXT(cmdBuffer, 0, params->bindingCount, buffers, offsets, sizes); break; } case CommandID::BindVertexBuffers: { const BindVertexBuffersParams *params = getParamPtr(currentCommand); const VkBuffer *buffers = GetFirstArrayParameter(params); const VkDeviceSize *offsets = GetNextArrayParameter(buffers, params->bindingCount); vkCmdBindVertexBuffers(cmdBuffer, 0, params->bindingCount, buffers, offsets); break; } case CommandID::BindVertexBuffers2: { const BindVertexBuffers2Params *params = getParamPtr(currentCommand); const VkBuffer *buffers = GetFirstArrayParameter(params); const VkDeviceSize *offsets = GetNextArrayParameter(buffers, params->bindingCount); const VkDeviceSize *strides = GetNextArrayParameter(offsets, params->bindingCount); vkCmdBindVertexBuffers2EXT(cmdBuffer, 0, params->bindingCount, buffers, offsets, nullptr, strides); break; } case CommandID::BlitImage: { const BlitImageParams *params = getParamPtr(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(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::BufferBarrier2: { const BufferBarrier2Params *params = getParamPtr(currentCommand); const VkDependencyInfo dependencyInfo = { VK_STRUCTURE_TYPE_DEPENDENCY_INFO, nullptr, 0, 0, nullptr, 1, ¶ms->bufferMemoryBarrier2, 0, nullptr}; vkCmdPipelineBarrier2KHR(cmdBuffer, &dependencyInfo); break; } case CommandID::ClearAttachments: { const ClearAttachmentsParams *params = getParamPtr(currentCommand); const VkClearAttachment *attachments = GetFirstArrayParameter(params); vkCmdClearAttachments(cmdBuffer, params->attachmentCount, attachments, 1, ¶ms->rect); break; } case CommandID::ClearColorImage: { const ClearColorImageParams *params = getParamPtr(currentCommand); vkCmdClearColorImage(cmdBuffer, params->image, params->imageLayout, ¶ms->color, 1, ¶ms->range); break; } case CommandID::ClearDepthStencilImage: { const ClearDepthStencilImageParams *params = getParamPtr(currentCommand); vkCmdClearDepthStencilImage(cmdBuffer, params->image, params->imageLayout, ¶ms->depthStencil, 1, ¶ms->range); break; } case CommandID::CopyBuffer: { const CopyBufferParams *params = getParamPtr(currentCommand); const VkBufferCopy *regions = GetFirstArrayParameter(params); vkCmdCopyBuffer(cmdBuffer, params->srcBuffer, params->destBuffer, params->regionCount, regions); break; } case CommandID::CopyBufferToImage: { const CopyBufferToImageParams *params = getParamPtr(currentCommand); vkCmdCopyBufferToImage(cmdBuffer, params->srcBuffer, params->dstImage, params->dstImageLayout, 1, ¶ms->region); break; } case CommandID::CopyImage: { const CopyImageParams *params = getParamPtr(currentCommand); vkCmdCopyImage(cmdBuffer, params->srcImage, params->srcImageLayout, params->dstImage, params->dstImageLayout, 1, ¶ms->region); break; } case CommandID::CopyImageToBuffer: { const CopyImageToBufferParams *params = getParamPtr(currentCommand); vkCmdCopyImageToBuffer(cmdBuffer, params->srcImage, params->srcImageLayout, params->dstBuffer, 1, ¶ms->region); break; } case CommandID::Dispatch: { const DispatchParams *params = getParamPtr(currentCommand); vkCmdDispatch(cmdBuffer, params->groupCountX, params->groupCountY, params->groupCountZ); break; } case CommandID::DispatchIndirect: { const DispatchIndirectParams *params = getParamPtr(currentCommand); vkCmdDispatchIndirect(cmdBuffer, params->buffer, params->offset); break; } case CommandID::Draw: { const DrawParams *params = getParamPtr(currentCommand); vkCmdDraw(cmdBuffer, params->vertexCount, 1, params->firstVertex, 0); break; } case CommandID::DrawIndexed: { const DrawIndexedParams *params = getParamPtr(currentCommand); vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, 0, 0); break; } case CommandID::DrawIndexedBaseVertex: { const DrawIndexedBaseVertexParams *params = getParamPtr(currentCommand); vkCmdDrawIndexed(cmdBuffer, params->indexCount, 1, 0, params->vertexOffset, 0); break; } case CommandID::DrawIndexedIndirect: { const DrawIndexedIndirectParams *params = getParamPtr(currentCommand); vkCmdDrawIndexedIndirect(cmdBuffer, params->buffer, params->offset, params->drawCount, params->stride); break; } case CommandID::DrawIndexedInstanced: { const DrawIndexedInstancedParams *params = getParamPtr(currentCommand); vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, 0, 0); break; } case CommandID::DrawIndexedInstancedBaseVertex: { const DrawIndexedInstancedBaseVertexParams *params = getParamPtr(currentCommand); vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, 0, params->vertexOffset, 0); break; } case CommandID::DrawIndexedInstancedBaseVertexBaseInstance: { const DrawIndexedInstancedBaseVertexBaseInstanceParams *params = getParamPtr( currentCommand); vkCmdDrawIndexed(cmdBuffer, params->indexCount, params->instanceCount, params->firstIndex, params->vertexOffset, params->firstInstance); break; } case CommandID::DrawIndirect: { const DrawIndirectParams *params = getParamPtr(currentCommand); vkCmdDrawIndirect(cmdBuffer, params->buffer, params->offset, params->drawCount, params->stride); break; } case CommandID::DrawInstanced: { const DrawInstancedParams *params = getParamPtr(currentCommand); vkCmdDraw(cmdBuffer, params->vertexCount, params->instanceCount, params->firstVertex, 0); break; } case CommandID::DrawInstancedBaseInstance: { const DrawInstancedBaseInstanceParams *params = getParamPtr(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(currentCommand); vkCmdEndQuery(cmdBuffer, params->queryPool, params->query); break; } case CommandID::EndTransformFeedback: { const EndTransformFeedbackParams *params = getParamPtr(currentCommand); const VkBuffer *counterBuffers = GetFirstArrayParameter(params); const VkDeviceSize *counterBufferOffsets = reinterpret_cast(counterBuffers + params->bufferCount); vkCmdEndTransformFeedbackEXT(cmdBuffer, 0, params->bufferCount, counterBuffers, counterBufferOffsets); break; } case CommandID::FillBuffer: { const FillBufferParams *params = getParamPtr(currentCommand); vkCmdFillBuffer(cmdBuffer, params->dstBuffer, params->dstOffset, params->size, params->data); break; } case CommandID::ImageBarrier: { const ImageBarrierParams *params = getParamPtr(currentCommand); const VkImageMemoryBarrier *imageMemoryBarriers = GetFirstArrayParameter(params); vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0, 0, nullptr, 0, nullptr, 1, imageMemoryBarriers); break; } case CommandID::ImageBarrier2: { const ImageBarrier2Params *params = getParamPtr(currentCommand); const VkImageMemoryBarrier2 *imageMemoryBarriers2 = GetFirstArrayParameter(params); VkDependencyInfo pDependencyInfo = {}; pDependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; pDependencyInfo.dependencyFlags = 0; pDependencyInfo.memoryBarrierCount = 0; pDependencyInfo.pMemoryBarriers = nullptr; pDependencyInfo.bufferMemoryBarrierCount = 0; pDependencyInfo.pBufferMemoryBarriers = nullptr; pDependencyInfo.imageMemoryBarrierCount = 1; pDependencyInfo.pImageMemoryBarriers = imageMemoryBarriers2; vkCmdPipelineBarrier2KHR(cmdBuffer, &pDependencyInfo); break; } case CommandID::ImageWaitEvent: { const ImageWaitEventParams *params = getParamPtr(currentCommand); const VkImageMemoryBarrier *imageMemoryBarriers = GetFirstArrayParameter(params); vkCmdWaitEvents(cmdBuffer, 1, &(params->event), params->srcStageMask, params->dstStageMask, 0, nullptr, 0, nullptr, 1, imageMemoryBarriers); break; } case CommandID::InsertDebugUtilsLabel: { const DebugUtilsLabelParams *params = getParamPtr(currentCommand); const char *pLabelName = GetFirstArrayParameter(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(currentCommand); const VkMemoryBarrier *memoryBarriers = GetFirstArrayParameter(params); vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, 0, 1, memoryBarriers, 0, nullptr, 0, nullptr); break; } case CommandID::MemoryBarrier2: { const MemoryBarrier2Params *params = getParamPtr(currentCommand); const VkMemoryBarrier2 *memoryBarriers2 = GetFirstArrayParameter(params); VkDependencyInfo pDependencyInfo = {}; pDependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; pDependencyInfo.memoryBarrierCount = 1; pDependencyInfo.pMemoryBarriers = memoryBarriers2; pDependencyInfo.bufferMemoryBarrierCount = 0; pDependencyInfo.pBufferMemoryBarriers = nullptr; pDependencyInfo.imageMemoryBarrierCount = 0; pDependencyInfo.pImageMemoryBarriers = nullptr; vkCmdPipelineBarrier2KHR(cmdBuffer, &pDependencyInfo); break; } case CommandID::NextSubpass: { vkCmdNextSubpass(cmdBuffer, VK_SUBPASS_CONTENTS_INLINE); break; } case CommandID::PipelineBarrier: { const PipelineBarrierParams *params = getParamPtr(currentCommand); const VkMemoryBarrier *memoryBarriers = GetFirstArrayParameter(params); const VkImageMemoryBarrier *imageMemoryBarriers = GetNextArrayParameter(memoryBarriers, params->memoryBarrierCount); vkCmdPipelineBarrier(cmdBuffer, params->srcStageMask, params->dstStageMask, params->dependencyFlags, params->memoryBarrierCount, memoryBarriers, 0, nullptr, params->imageMemoryBarrierCount, imageMemoryBarriers); break; } case CommandID::PipelineBarrier2: { const PipelineBarrierParams2 *params = getParamPtr(currentCommand); const VkMemoryBarrier2 *memoryBarriers2 = GetFirstArrayParameter(params); const VkImageMemoryBarrier2 *imageMemoryBarriers2 = GetNextArrayParameter(memoryBarriers2, params->memoryBarrierCount); VkDependencyInfo dependencyInfo = {}; dependencyInfo.sType = VK_STRUCTURE_TYPE_DEPENDENCY_INFO; dependencyInfo.pNext = nullptr; dependencyInfo.dependencyFlags = params->dependencyFlags; dependencyInfo.memoryBarrierCount = params->memoryBarrierCount; dependencyInfo.pMemoryBarriers = memoryBarriers2; dependencyInfo.bufferMemoryBarrierCount = 0; dependencyInfo.pBufferMemoryBarriers = nullptr; dependencyInfo.imageMemoryBarrierCount = params->imageMemoryBarrierCount; dependencyInfo.pImageMemoryBarriers = imageMemoryBarriers2; vkCmdPipelineBarrier2KHR(cmdBuffer, &dependencyInfo); break; } case CommandID::PushConstants: { const PushConstantsParams *params = getParamPtr(currentCommand); const void *data = GetFirstArrayParameter(params); vkCmdPushConstants(cmdBuffer, params->layout, params->flag, params->offset, params->size, data); break; } case CommandID::ResetEvent: { const ResetEventParams *params = getParamPtr(currentCommand); vkCmdResetEvent(cmdBuffer, params->event, params->stageMask); break; } case CommandID::ResetQueryPool: { const ResetQueryPoolParams *params = getParamPtr(currentCommand); vkCmdResetQueryPool(cmdBuffer, params->queryPool, params->firstQuery, params->queryCount); break; } case CommandID::ResolveImage: { const ResolveImageParams *params = getParamPtr(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(currentCommand); vkCmdSetBlendConstants(cmdBuffer, params->blendConstants); break; } case CommandID::SetCullMode: { const SetCullModeParams *params = getParamPtr(currentCommand); vkCmdSetCullModeEXT(cmdBuffer, params->cullMode); break; } case CommandID::SetDepthBias: { const SetDepthBiasParams *params = getParamPtr(currentCommand); vkCmdSetDepthBias(cmdBuffer, params->depthBiasConstantFactor, params->depthBiasClamp, params->depthBiasSlopeFactor); break; } case CommandID::SetDepthBiasEnable: { const SetDepthBiasEnableParams *params = getParamPtr(currentCommand); vkCmdSetDepthBiasEnableEXT(cmdBuffer, params->depthBiasEnable); break; } case CommandID::SetDepthCompareOp: { const SetDepthCompareOpParams *params = getParamPtr(currentCommand); vkCmdSetDepthCompareOpEXT(cmdBuffer, params->depthCompareOp); break; } case CommandID::SetDepthTestEnable: { const SetDepthTestEnableParams *params = getParamPtr(currentCommand); vkCmdSetDepthTestEnableEXT(cmdBuffer, params->depthTestEnable); break; } case CommandID::SetDepthWriteEnable: { const SetDepthWriteEnableParams *params = getParamPtr(currentCommand); vkCmdSetDepthWriteEnableEXT(cmdBuffer, params->depthWriteEnable); break; } case CommandID::SetEvent: { const SetEventParams *params = getParamPtr(currentCommand); vkCmdSetEvent(cmdBuffer, params->event, params->stageMask); break; } case CommandID::SetFragmentShadingRate: { const SetFragmentShadingRateParams *params = getParamPtr(currentCommand); const VkExtent2D fragmentSize = {params->fragmentWidth, params->fragmentHeight}; const VkFragmentShadingRateCombinerOpKHR ops[2] = { VK_FRAGMENT_SHADING_RATE_COMBINER_OP_KEEP_KHR, static_cast( params->vkFragmentShadingRateCombinerOp1)}; vkCmdSetFragmentShadingRateKHR(cmdBuffer, &fragmentSize, ops); break; } case CommandID::SetFrontFace: { const SetFrontFaceParams *params = getParamPtr(currentCommand); vkCmdSetFrontFaceEXT(cmdBuffer, params->frontFace); break; } case CommandID::SetLineWidth: { const SetLineWidthParams *params = getParamPtr(currentCommand); vkCmdSetLineWidth(cmdBuffer, params->lineWidth); break; } case CommandID::SetLogicOp: { const SetLogicOpParams *params = getParamPtr(currentCommand); vkCmdSetLogicOpEXT(cmdBuffer, params->logicOp); break; } case CommandID::SetPrimitiveRestartEnable: { const SetPrimitiveRestartEnableParams *params = getParamPtr(currentCommand); vkCmdSetPrimitiveRestartEnableEXT(cmdBuffer, params->primitiveRestartEnable); break; } case CommandID::SetRasterizerDiscardEnable: { const SetRasterizerDiscardEnableParams *params = getParamPtr(currentCommand); vkCmdSetRasterizerDiscardEnableEXT(cmdBuffer, params->rasterizerDiscardEnable); break; } case CommandID::SetScissor: { const SetScissorParams *params = getParamPtr(currentCommand); vkCmdSetScissor(cmdBuffer, 0, 1, ¶ms->scissor); break; } case CommandID::SetStencilCompareMask: { const SetStencilCompareMaskParams *params = getParamPtr(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(currentCommand); vkCmdSetStencilOpEXT(cmdBuffer, static_cast(params->faceMask), static_cast(params->failOp), static_cast(params->passOp), static_cast(params->depthFailOp), static_cast(params->compareOp)); break; } case CommandID::SetStencilReference: { const SetStencilReferenceParams *params = getParamPtr(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(currentCommand); vkCmdSetStencilTestEnableEXT(cmdBuffer, params->stencilTestEnable); break; } case CommandID::SetStencilWriteMask: { const SetStencilWriteMaskParams *params = getParamPtr(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(currentCommand); const VkVertexInputBindingDescription2EXT *vertexBindingDescriptions = GetFirstArrayParameter(params); const VkVertexInputAttributeDescription2EXT *vertexAttributeDescriptions = GetNextArrayParameter( vertexBindingDescriptions, params->vertexBindingDescriptionCount); vkCmdSetVertexInputEXT( cmdBuffer, params->vertexBindingDescriptionCount, vertexBindingDescriptions, params->vertexAttributeDescriptionCount, vertexAttributeDescriptions); break; } case CommandID::SetViewport: { const SetViewportParams *params = getParamPtr(currentCommand); vkCmdSetViewport(cmdBuffer, 0, 1, ¶ms->viewport); break; } case CommandID::WaitEvents: { const WaitEventsParams *params = getParamPtr(currentCommand); const VkEvent *events = GetFirstArrayParameter(params); const VkMemoryBarrier *memoryBarriers = GetNextArrayParameter(events, params->eventCount); const VkImageMemoryBarrier *imageMemoryBarriers = GetNextArrayParameter(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(currentCommand); vkCmdWriteTimestamp(cmdBuffer, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT, params->queryPool, params->query); break; } case CommandID::WriteTimestamp2: { const WriteTimestampParams *params = getParamPtr(currentCommand); vkCmdWriteTimestamp2KHR(cmdBuffer, VK_PIPELINE_STAGE_2_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(commandEnd) - reinterpret_cast(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