Minor refactor with pipelines in QueueRunner (makes more information available for easier debugging)

This commit is contained in:
Henrik Rydgård 2022-09-03 22:04:01 +02:00
parent 6b1e4806cf
commit d3309dd8e9
5 changed files with 43 additions and 37 deletions

View file

@ -1144,8 +1144,8 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
VKRFramebuffer *fb = step.render.framebuffer; VKRFramebuffer *fb = step.render.framebuffer;
VkPipeline lastGraphicsPipeline = VK_NULL_HANDLE; VKRGraphicsPipeline *lastGraphicsPipeline = nullptr;
VkPipeline lastComputePipeline = VK_NULL_HANDLE; VKRComputePipeline *lastComputePipeline = nullptr;
auto &commands = step.commands; auto &commands = step.commands;
@ -1168,40 +1168,43 @@ void VulkanQueueRunner::PerformRenderPass(const VKRStep &step, VkCommandBuffer c
case VKRRenderCommand::BIND_PIPELINE: case VKRRenderCommand::BIND_PIPELINE:
{ {
VkPipeline pipeline = c.pipeline.pipeline; VkPipeline pipeline = c.pipeline.pipeline;
if (pipeline != lastGraphicsPipeline) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
pipelineLayout = c.pipeline.pipelineLayout; pipelineLayout = c.pipeline.pipelineLayout;
lastGraphicsPipeline = pipeline;
// Reset dynamic state so it gets refreshed with the new pipeline. // Reset dynamic state so it gets refreshed with the new pipeline.
lastStencilWriteMask = -1; lastStencilWriteMask = -1;
lastStencilCompareMask = -1; lastStencilCompareMask = -1;
lastStencilReference = -1; lastStencilReference = -1;
}
break; break;
} }
case VKRRenderCommand::BIND_GRAPHICS_PIPELINE: case VKRRenderCommand::BIND_GRAPHICS_PIPELINE:
{ {
VkPipeline pipeline = c.graphics_pipeline.pipeline->BlockUntilReady(); VKRGraphicsPipeline *graphicsPipeline = c.graphics_pipeline.pipeline;
if (pipeline != lastGraphicsPipeline && pipeline != VK_NULL_HANDLE) { if (graphicsPipeline != lastGraphicsPipeline) {
VkPipeline pipeline = graphicsPipeline->pipeline->BlockUntilReady();
if (pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_GRAPHICS, pipeline);
pipelineLayout = c.pipeline.pipelineLayout; pipelineLayout = c.pipeline.pipelineLayout;
lastGraphicsPipeline = pipeline; lastGraphicsPipeline = graphicsPipeline;
// Reset dynamic state so it gets refreshed with the new pipeline. // Reset dynamic state so it gets refreshed with the new pipeline.
lastStencilWriteMask = -1; lastStencilWriteMask = -1;
lastStencilCompareMask = -1; lastStencilCompareMask = -1;
lastStencilReference = -1; lastStencilReference = -1;
} }
}
break; break;
} }
case VKRRenderCommand::BIND_COMPUTE_PIPELINE: case VKRRenderCommand::BIND_COMPUTE_PIPELINE:
{ {
VkPipeline pipeline = c.graphics_pipeline.pipeline->BlockUntilReady(); VKRComputePipeline *computePipeline = c.compute_pipeline.pipeline;
if (pipeline != lastComputePipeline && pipeline != VK_NULL_HANDLE) { if (computePipeline != lastComputePipeline) {
VkPipeline pipeline = computePipeline->pipeline->BlockUntilReady();
if (pipeline != VK_NULL_HANDLE) {
vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline); vkCmdBindPipeline(cmd, VK_PIPELINE_BIND_POINT_COMPUTE, pipeline);
pipelineLayout = c.pipeline.pipelineLayout; pipelineLayout = c.pipeline.pipelineLayout;
lastComputePipeline = pipeline; lastComputePipeline = computePipeline;
}
} }
break; break;
} }

View file

@ -55,11 +55,11 @@ struct VkRenderData {
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
} pipeline; } pipeline;
struct { struct {
Promise<VkPipeline> *pipeline; VKRGraphicsPipeline *pipeline;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
} graphics_pipeline; } graphics_pipeline;
struct { struct {
Promise<VkPipeline> *pipeline; VKRComputePipeline *pipeline;
VkPipelineLayout pipelineLayout; VkPipelineLayout pipelineLayout;
} compute_pipeline; } compute_pipeline;
struct { struct {

View file

@ -80,8 +80,11 @@ bool VKRGraphicsPipeline::Create(VulkanContext *vulkan) {
pipeline->Post(vkpipeline); pipeline->Post(vkpipeline);
} }
// Having the desc stick around can be useful for debugging.
#ifndef _DEBUG
delete desc; delete desc;
desc = nullptr; desc = nullptr;
#endif
return success; return success;
} }

View file

@ -141,20 +141,19 @@ struct VKRComputePipelineDesc {
VkComputePipelineCreateInfo pipe{ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO }; VkComputePipelineCreateInfo pipe{ VK_STRUCTURE_TYPE_COMPUTE_PIPELINE_CREATE_INFO };
}; };
// Wrapped pipeline, which will later allow for background compilation while emulating the rest of the frame. // Wrapped pipeline.
struct VKRGraphicsPipeline { struct VKRGraphicsPipeline {
VKRGraphicsPipeline() { VKRGraphicsPipeline() {
pipeline = Promise<VkPipeline>::CreateEmpty(); pipeline = Promise<VkPipeline>::CreateEmpty();
} }
~VKRGraphicsPipeline() {
delete desc;
}
VKRGraphicsPipelineDesc *desc = nullptr; // While non-zero, is pending and pipeline isn't valid. VKRGraphicsPipelineDesc *desc = nullptr;
Promise<VkPipeline> *pipeline; Promise<VkPipeline> *pipeline;
bool Create(VulkanContext *vulkan); bool Create(VulkanContext *vulkan);
bool Pending() const {
return pipeline == VK_NULL_HANDLE && desc != nullptr;
}
}; };
struct VKRComputePipeline { struct VKRComputePipeline {
@ -263,7 +262,7 @@ public:
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != nullptr); _dbg_assert_(pipeline != nullptr);
VkRenderData data{ VKRRenderCommand::BIND_GRAPHICS_PIPELINE }; VkRenderData data{ VKRRenderCommand::BIND_GRAPHICS_PIPELINE };
data.graphics_pipeline.pipeline = pipeline->pipeline; data.graphics_pipeline.pipeline = pipeline;
data.graphics_pipeline.pipelineLayout = pipelineLayout; data.graphics_pipeline.pipelineLayout = pipelineLayout;
curPipelineFlags_ |= flags; curPipelineFlags_ |= flags;
curRenderStep_->commands.push_back(data); curRenderStep_->commands.push_back(data);
@ -273,7 +272,7 @@ public:
_dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER); _dbg_assert_(curRenderStep_ && curRenderStep_->stepType == VKRStepType::RENDER);
_dbg_assert_(pipeline != nullptr); _dbg_assert_(pipeline != nullptr);
VkRenderData data{ VKRRenderCommand::BIND_COMPUTE_PIPELINE }; VkRenderData data{ VKRRenderCommand::BIND_COMPUTE_PIPELINE };
data.compute_pipeline.pipeline = pipeline->pipeline; data.compute_pipeline.pipeline = pipeline;
data.compute_pipeline.pipelineLayout = pipelineLayout; data.compute_pipeline.pipelineLayout = pipelineLayout;
curPipelineFlags_ |= flags; curPipelineFlags_ |= flags;
curRenderStep_->commands.push_back(data); curRenderStep_->commands.push_back(data);

View file

@ -808,7 +808,8 @@ void FramebufferManagerCommon::CopyToColorFromOverlappingFramebuffers(VirtualFra
} }
if (dst != currentRenderVfb_ && tookActions) { if (dst != currentRenderVfb_ && tookActions) {
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "After FakeReinterpret"); // Will probably just change the name of the current renderpass, since one was started by the reinterpret itself.
draw_->BindFramebufferAsRenderTarget(currentRenderVfb_->fbo, { Draw::RPAction::KEEP, Draw::RPAction::KEEP, Draw::RPAction::KEEP }, "After Reinterpret");
} }
shaderManager_->DirtyLastShader(); shaderManager_->DirtyLastShader();
@ -2791,7 +2792,7 @@ void FramebufferManagerCommon::BlitFramebuffer(VirtualFramebuffer *dst, int dstX
draw_->InvalidateCachedState(); draw_->InvalidateCachedState();
gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_BLEND_STATE | DIRTY_RASTER_STATE); gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE);
} }
// The input is raw pixel coordinates, scale not taken into account. // The input is raw pixel coordinates, scale not taken into account.