From 4e7099bf479c927ad0c610f89757767398fd7e05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Tue, 15 Aug 2017 10:38:20 +0200 Subject: [PATCH] Vulkan: Fix some more state dirtying issues. --- GPU/D3D11/FramebufferManagerD3D11.cpp | 4 +--- GPU/D3D11/StateMappingD3D11.cpp | 1 + GPU/Vulkan/DrawEngineVulkan.cpp | 6 +++++- GPU/Vulkan/FramebufferVulkan.cpp | 1 + GPU/Vulkan/GPU_Vulkan.cpp | 6 +++++- GPU/Vulkan/ShaderManagerVulkan.cpp | 1 + GPU/Vulkan/StateMappingVulkan.cpp | 23 ++++++++++++----------- 7 files changed, 26 insertions(+), 16 deletions(-) diff --git a/GPU/D3D11/FramebufferManagerD3D11.cpp b/GPU/D3D11/FramebufferManagerD3D11.cpp index e3516f2221..f5d55de6f1 100644 --- a/GPU/D3D11/FramebufferManagerD3D11.cpp +++ b/GPU/D3D11/FramebufferManagerD3D11.cpp @@ -509,12 +509,10 @@ void FramebufferManagerD3D11::ReformatFramebufferFrom(VirtualFramebuffer *vfb, G context_->RSSetViewports(1, &vp); context_->IASetPrimitiveTopology(D3D11_PRIMITIVE_TOPOLOGY_TRIANGLESTRIP); context_->Draw(4, 0); - - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_RASTER_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_VIEWPORTSCISSOR_STATE); } RebindFramebuffer(); - gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VERTEXSHADER_STATE); + gstate_c.Dirty(DIRTY_BLEND_STATE | DIRTY_DEPTHSTENCIL_STATE | DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_VERTEXSHADER_STATE); } static void CopyPixelDepthOnly(u32 *dstp, const u32 *srcp, size_t c) { diff --git a/GPU/D3D11/StateMappingD3D11.cpp b/GPU/D3D11/StateMappingD3D11.cpp index 7b05b5aec8..de8d00b804 100644 --- a/GPU/D3D11/StateMappingD3D11.cpp +++ b/GPU/D3D11/StateMappingD3D11.cpp @@ -417,6 +417,7 @@ void DrawEngineD3D11::ApplyDrawState(int prim) { vp.Height = vpAndScissor.viewportH; vp.MinDepth = depthMin; vp.MaxDepth = depthMax; + if (vpAndScissor.dirtyProj) { gstate_c.Dirty(DIRTY_PROJMATRIX); } diff --git a/GPU/Vulkan/DrawEngineVulkan.cpp b/GPU/Vulkan/DrawEngineVulkan.cpp index 28cc856c9f..42998136c6 100644 --- a/GPU/Vulkan/DrawEngineVulkan.cpp +++ b/GPU/Vulkan/DrawEngineVulkan.cpp @@ -257,6 +257,9 @@ void DrawEngineVulkan::DeviceRestore(VulkanContext *vulkan) { } void DrawEngineVulkan::BeginFrame() { + lastCmd_ = VK_NULL_HANDLE; + lastPipeline_ = nullptr; + FrameData *frame = &frame_[curFrame_ & 1]; vkResetDescriptorPool(vulkan_->GetDevice(), frame->descPool, 0); frame->descSets.clear(); @@ -572,7 +575,8 @@ void DrawEngineVulkan::DoFlush() { if (cmd != lastCmd_) { lastPipeline_ = nullptr; lastCmd_ = cmd; - gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE); + // Since we have a new cmdbuf, dirty our dynamic state so it gets re-set. + gstate_c.Dirty(DIRTY_VIEWPORTSCISSOR_STATE|DIRTY_DEPTHSTENCIL_STATE); } VkRenderPass rp = (VkRenderPass)draw_->GetNativeObject(Draw::NativeObject::CURRENT_RENDERPASS); diff --git a/GPU/Vulkan/FramebufferVulkan.cpp b/GPU/Vulkan/FramebufferVulkan.cpp index f819cdc326..b93cbd07de 100644 --- a/GPU/Vulkan/FramebufferVulkan.cpp +++ b/GPU/Vulkan/FramebufferVulkan.cpp @@ -377,6 +377,7 @@ void FramebufferManagerVulkan::Bind2DShader() { void FramebufferManagerVulkan::BindPostShader(const PostShaderUniforms &uniforms) { Bind2DShader(); + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); } void FramebufferManagerVulkan::RebindFramebuffer() { diff --git a/GPU/Vulkan/GPU_Vulkan.cpp b/GPU/Vulkan/GPU_Vulkan.cpp index cbcebe6e06..ad23ad4ff2 100644 --- a/GPU/Vulkan/GPU_Vulkan.cpp +++ b/GPU/Vulkan/GPU_Vulkan.cpp @@ -526,11 +526,13 @@ void GPU_Vulkan::Execute_VertexType(u32 op, u32 diff) { if (diff & (GE_VTYPE_TC_MASK | GE_VTYPE_THROUGH_MASK)) { gstate_c.Dirty(DIRTY_UVSCALEOFFSET); if (diff & GE_VTYPE_THROUGH_MASK) - gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE); + gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE); } } void GPU_Vulkan::Execute_VertexTypeSkinning(u32 op, u32 diff) { + if (diff) + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE); // Don't flush when weight count changes, unless morph is enabled. if ((diff & ~GE_VTYPE_WEIGHTCOUNT_MASK) || (op & GE_VTYPE_MORPHCOUNT_MASK) != 0) { // Restore and flush @@ -546,6 +548,8 @@ void GPU_Vulkan::Execute_VertexTypeSkinning(u32 op, u32 diff) { gstate_c.deferredVertTypeDirty = 0; } } + if (diff & GE_VTYPE_THROUGH_MASK) + gstate_c.Dirty(DIRTY_RASTER_STATE | DIRTY_VIEWPORTSCISSOR_STATE | DIRTY_FRAGMENTSHADER_STATE); } void GPU_Vulkan::Execute_Bezier(u32 op, u32 diff) { diff --git a/GPU/Vulkan/ShaderManagerVulkan.cpp b/GPU/Vulkan/ShaderManagerVulkan.cpp index c97593f3dc..70d20cf3f3 100644 --- a/GPU/Vulkan/ShaderManagerVulkan.cpp +++ b/GPU/Vulkan/ShaderManagerVulkan.cpp @@ -216,6 +216,7 @@ void ShaderManagerVulkan::DirtyShader() { void ShaderManagerVulkan::DirtyLastShader() { // disables vertex arrays lastVShader_ = nullptr; lastFShader_ = nullptr; + gstate_c.Dirty(DIRTY_VERTEXSHADER_STATE | DIRTY_FRAGMENTSHADER_STATE); } uint64_t ShaderManagerVulkan::UpdateUniforms() { diff --git a/GPU/Vulkan/StateMappingVulkan.cpp b/GPU/Vulkan/StateMappingVulkan.cpp index b55476253c..821c4b1466 100644 --- a/GPU/Vulkan/StateMappingVulkan.cpp +++ b/GPU/Vulkan/StateMappingVulkan.cpp @@ -332,6 +332,15 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag fbManager.GetTargetBufferWidth(), fbManager.GetTargetBufferHeight(), vpAndScissor); + float depthMin = vpAndScissor.depthRangeMin; + float depthMax = vpAndScissor.depthRangeMax; + + if (depthMin < 0.0f) depthMin = 0.0f; + if (depthMax > 1.0f) depthMax = 1.0f; + if (vpAndScissor.dirtyDepth) { + gstate_c.Dirty(DIRTY_DEPTHRANGE); + } + VkViewport &vp = dynState.viewport; vp.x = vpAndScissor.viewportX; vp.y = vpAndScissor.viewportY; @@ -339,6 +348,7 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag vp.height = vpAndScissor.viewportH; vp.minDepth = vpAndScissor.depthRangeMin; vp.maxDepth = vpAndScissor.depthRangeMax; + if (vpAndScissor.dirtyProj) { gstate_c.Dirty(DIRTY_PROJMATRIX); } @@ -347,23 +357,14 @@ void DrawEngineVulkan::ConvertStateToVulkanKey(FramebufferManagerVulkan &fbManag if (vpAndScissor.scissorEnable) { scissor.offset.x = vpAndScissor.scissorX; scissor.offset.y = vpAndScissor.scissorY; - scissor.extent.width = vpAndScissor.scissorW; - scissor.extent.height = vpAndScissor.scissorH; + scissor.extent.width = std::max(0, vpAndScissor.scissorW); + scissor.extent.height = std::max(0, vpAndScissor.scissorH); } else { scissor.offset.x = 0; scissor.offset.y = 0; scissor.extent.width = framebufferManager_->GetRenderWidth(); scissor.extent.height = framebufferManager_->GetRenderHeight(); } - - float depthMin = vpAndScissor.depthRangeMin; - float depthMax = vpAndScissor.depthRangeMax; - - if (depthMin < 0.0f) depthMin = 0.0f; - if (depthMax > 1.0f) depthMax = 1.0f; - if (vpAndScissor.dirtyDepth) { - gstate_c.Dirty(DIRTY_DEPTHRANGE); - } } key.topology = primToVulkan[prim];