diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp index 6b62e1575f..da42031a7a 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.cpp @@ -551,9 +551,9 @@ void PixelShaderCache::Shutdown() g_ps_disk_cache.Close(); } -bool PixelShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode) +bool PixelShaderCache::SetShader() { - PixelShaderUid uid = GetPixelShaderUid(dstAlphaMode); + PixelShaderUid uid = GetPixelShaderUid(); // Check if the shader is already set if (last_entry) diff --git a/Source/Core/VideoBackends/D3D/PixelShaderCache.h b/Source/Core/VideoBackends/D3D/PixelShaderCache.h index 0e81f3cf33..d3d4106a53 100644 --- a/Source/Core/VideoBackends/D3D/PixelShaderCache.h +++ b/Source/Core/VideoBackends/D3D/PixelShaderCache.h @@ -9,8 +9,6 @@ #include "VideoCommon/PixelShaderGen.h" -enum DSTALPHA_MODE; - namespace DX11 { class PixelShaderCache @@ -19,7 +17,7 @@ public: static void Init(); static void Clear(); static void Shutdown(); - static bool SetShader(DSTALPHA_MODE dstAlphaMode); // TODO: Should be renamed to LoadShader + static bool SetShader(); // TODO: Should be renamed to LoadShader static bool InsertByteCode(const PixelShaderUid& uid, const void* bytecode, unsigned int bytecodelen); diff --git a/Source/Core/VideoBackends/D3D/Render.cpp b/Source/Core/VideoBackends/D3D/Render.cpp index 31eea38d9c..150f51c14c 100644 --- a/Source/Core/VideoBackends/D3D/Render.cpp +++ b/Source/Core/VideoBackends/D3D/Render.cpp @@ -940,8 +940,12 @@ void Renderer::RestoreAPIState() BPFunctions::SetScissor(); } -void Renderer::ApplyState(bool bUseDstAlpha) +void Renderer::ApplyState() { + // TODO: Refactor this logic here. + bool bUseDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && + bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; + gx_state.blend.use_dst_alpha = bUseDstAlpha; D3D::stateman->PushBlendState(gx_state_cache.Get(gx_state.blend)); D3D::stateman->PushDepthState(gx_state_cache.Get(gx_state.zmode)); diff --git a/Source/Core/VideoBackends/D3D/Render.h b/Source/Core/VideoBackends/D3D/Render.h index 0507b76c80..afb3e06b6d 100644 --- a/Source/Core/VideoBackends/D3D/Render.h +++ b/Source/Core/VideoBackends/D3D/Render.h @@ -29,7 +29,7 @@ public: bool IsFullscreen() const override; // TODO: Fix confusing names (see ResetAPIState and RestoreAPIState) - void ApplyState(bool bUseDstAlpha) override; + void ApplyState() override; void RestoreState() override; void ApplyCullDisable(); diff --git a/Source/Core/VideoBackends/D3D/VertexManager.cpp b/Source/Core/VideoBackends/D3D/VertexManager.cpp index 5b78a1101a..9adfb30379 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.cpp +++ b/Source/Core/VideoBackends/D3D/VertexManager.cpp @@ -147,9 +147,9 @@ void VertexManager::Draw(u32 stride) static_cast(g_renderer.get())->RestoreCull(); } -void VertexManager::vFlush(bool useDstAlpha) +void VertexManager::vFlush() { - if (!PixelShaderCache::SetShader(useDstAlpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE)) + if (!PixelShaderCache::SetShader()) { GFX_DEBUGGER_PAUSE_LOG_AT(NEXT_ERROR, true, { printf("Fail to set pixel shader\n"); }); return; @@ -179,7 +179,7 @@ void VertexManager::vFlush(bool useDstAlpha) PrepareDrawBuffers(stride); VertexLoaderManager::GetCurrentVertexFormat()->SetupVertexPointers(); - g_renderer->ApplyState(useDstAlpha); + g_renderer->ApplyState(); Draw(stride); diff --git a/Source/Core/VideoBackends/D3D/VertexManager.h b/Source/Core/VideoBackends/D3D/VertexManager.h index e05a505eb5..6d874c6864 100644 --- a/Source/Core/VideoBackends/D3D/VertexManager.h +++ b/Source/Core/VideoBackends/D3D/VertexManager.h @@ -25,7 +25,7 @@ private: void PrepareDrawBuffers(u32 stride); void Draw(u32 stride); // temp - void vFlush(bool useDstAlpha) override; + void vFlush() override; u32 m_vertexDrawOffset; u32 m_indexDrawOffset; diff --git a/Source/Core/VideoBackends/D3D12/Render.cpp b/Source/Core/VideoBackends/D3D12/Render.cpp index 9016cb8e8d..9fbf8ade33 100644 --- a/Source/Core/VideoBackends/D3D12/Render.cpp +++ b/Source/Core/VideoBackends/D3D12/Render.cpp @@ -920,8 +920,12 @@ void Renderer::RestoreAPIState() static bool s_previous_use_dst_alpha = false; static D3DVertexFormat* s_previous_vertex_format = nullptr; -void Renderer::ApplyState(bool use_dst_alpha) +void Renderer::ApplyState() { + // TODO: Refactor this logic here. + bool use_dst_alpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && + bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; + if (use_dst_alpha != s_previous_use_dst_alpha) { s_previous_use_dst_alpha = use_dst_alpha; diff --git a/Source/Core/VideoBackends/D3D12/Render.h b/Source/Core/VideoBackends/D3D12/Render.h index b4620c0154..356e96e4ee 100644 --- a/Source/Core/VideoBackends/D3D12/Render.h +++ b/Source/Core/VideoBackends/D3D12/Render.h @@ -27,7 +27,7 @@ public: void SetViewport() override; // TODO: Fix confusing names (see ResetAPIState and RestoreAPIState) - void ApplyState(bool use_dst_alpha) override; + void ApplyState() override; void RestoreState() override; void ApplyCullDisable(); diff --git a/Source/Core/VideoBackends/D3D12/ShaderCache.cpp b/Source/Core/VideoBackends/D3D12/ShaderCache.cpp index 3cd1bc03a7..acdf16eafb 100644 --- a/Source/Core/VideoBackends/D3D12/ShaderCache.cpp +++ b/Source/Core/VideoBackends/D3D12/ShaderCache.cpp @@ -132,12 +132,12 @@ void ShaderCache::Shutdown() s_vs_disk_cache.Close(); } -void ShaderCache::LoadAndSetActiveShaders(DSTALPHA_MODE ps_dst_alpha_mode, u32 gs_primitive_type) +void ShaderCache::LoadAndSetActiveShaders(u32 gs_primitive_type) { SetCurrentPrimitiveTopology(gs_primitive_type); GeometryShaderUid gs_uid = GetGeometryShaderUid(gs_primitive_type); - PixelShaderUid ps_uid = GetPixelShaderUid(ps_dst_alpha_mode); + PixelShaderUid ps_uid = GetPixelShaderUid(); VertexShaderUid vs_uid = GetVertexShaderUid(); bool gs_changed = gs_uid != s_last_geometry_shader_uid; @@ -156,7 +156,7 @@ void ShaderCache::LoadAndSetActiveShaders(DSTALPHA_MODE ps_dst_alpha_mode, u32 g if (ps_changed) { - HandlePSUIDChange(ps_uid, ps_dst_alpha_mode); + HandlePSUIDChange(ps_uid); } if (vs_changed) @@ -219,7 +219,7 @@ void ShaderCache::HandleGSUIDChange(GeometryShaderUid gs_uid, u32 gs_primitive_t } } -void ShaderCache::HandlePSUIDChange(PixelShaderUid ps_uid, DSTALPHA_MODE ps_dst_alpha_mode) +void ShaderCache::HandlePSUIDChange(PixelShaderUid ps_uid) { s_last_pixel_shader_uid = ps_uid; diff --git a/Source/Core/VideoBackends/D3D12/ShaderCache.h b/Source/Core/VideoBackends/D3D12/ShaderCache.h index b6308b922b..bfc2fb6ce2 100644 --- a/Source/Core/VideoBackends/D3D12/ShaderCache.h +++ b/Source/Core/VideoBackends/D3D12/ShaderCache.h @@ -19,7 +19,7 @@ public: static void Clear(); static void Shutdown(); - static void LoadAndSetActiveShaders(DSTALPHA_MODE ps_dst_alpha_mode, u32 gs_primitive_type); + static void LoadAndSetActiveShaders(u32 gs_primitive_type); template static D3D12_SHADER_BYTECODE InsertByteCode(const UidType& uid, ShaderCacheType* shader_cache, @@ -43,7 +43,7 @@ private: static void SetCurrentPrimitiveTopology(u32 gs_primitive_type); static void HandleGSUIDChange(GeometryShaderUid gs_uid, u32 gs_primitive_type); - static void HandlePSUIDChange(PixelShaderUid ps_uid, DSTALPHA_MODE ps_dst_alpha_mode); + static void HandlePSUIDChange(PixelShaderUid ps_uid); static void HandleVSUIDChange(VertexShaderUid vs_uid); }; } diff --git a/Source/Core/VideoBackends/D3D12/VertexManager.cpp b/Source/Core/VideoBackends/D3D12/VertexManager.cpp index a803a07e35..88d4731df0 100644 --- a/Source/Core/VideoBackends/D3D12/VertexManager.cpp +++ b/Source/Core/VideoBackends/D3D12/VertexManager.cpp @@ -135,10 +135,9 @@ void VertexManager::Draw(u32 stride) INCSTAT(stats.thisFrame.numDrawCalls); } -void VertexManager::vFlush(bool use_dst_alpha) +void VertexManager::vFlush() { - ShaderCache::LoadAndSetActiveShaders(use_dst_alpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, - m_current_primitive_type); + ShaderCache::LoadAndSetActiveShaders(m_current_primitive_type); if (g_ActiveConfig.backend_info.bSupportsBBox && BoundingBox::active) BBox::Invalidate(); @@ -147,7 +146,7 @@ void VertexManager::vFlush(bool use_dst_alpha) PrepareDrawBuffers(stride); - g_renderer->ApplyState(use_dst_alpha); + g_renderer->ApplyState(); Draw(stride); diff --git a/Source/Core/VideoBackends/D3D12/VertexManager.h b/Source/Core/VideoBackends/D3D12/VertexManager.h index 8fbcf4102e..c180542ccc 100644 --- a/Source/Core/VideoBackends/D3D12/VertexManager.h +++ b/Source/Core/VideoBackends/D3D12/VertexManager.h @@ -29,7 +29,7 @@ protected: private: void PrepareDrawBuffers(u32 stride); void Draw(u32 stride); - void vFlush(bool use_dst_alpha) override; + void vFlush() override; u32 m_vertex_draw_offset; u32 m_index_draw_offset; diff --git a/Source/Core/VideoBackends/Null/ShaderCache.cpp b/Source/Core/VideoBackends/Null/ShaderCache.cpp index a7513f4909..a8decc6f58 100644 --- a/Source/Core/VideoBackends/Null/ShaderCache.cpp +++ b/Source/Core/VideoBackends/Null/ShaderCache.cpp @@ -33,9 +33,9 @@ void ShaderCache::Clear() } template -bool ShaderCache::SetShader(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type) +bool ShaderCache::SetShader(u32 primitive_type) { - Uid uid = GetUid(dst_alpha_mode, primitive_type, APIType::OpenGL); + Uid uid = GetUid(primitive_type, APIType::OpenGL); // Check if the shader is already set if (m_last_entry) diff --git a/Source/Core/VideoBackends/Null/ShaderCache.h b/Source/Core/VideoBackends/Null/ShaderCache.h index 9ed794b8d3..8759820568 100644 --- a/Source/Core/VideoBackends/Null/ShaderCache.h +++ b/Source/Core/VideoBackends/Null/ShaderCache.h @@ -22,10 +22,10 @@ public: virtual ~ShaderCache(); void Clear(); - bool SetShader(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type); + bool SetShader(u32 primitive_type); protected: - virtual Uid GetUid(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type, APIType api_type) = 0; + virtual Uid GetUid(u32 primitive_type, APIType api_type) = 0; virtual ShaderCode GenerateCode(APIType api_type, Uid uid) = 0; private: @@ -40,8 +40,7 @@ public: static std::unique_ptr s_instance; protected: - VertexShaderUid GetUid(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type, - APIType api_type) override + VertexShaderUid GetUid(u32 primitive_type, APIType api_type) override { return GetVertexShaderUid(); } @@ -57,8 +56,7 @@ public: static std::unique_ptr s_instance; protected: - GeometryShaderUid GetUid(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type, - APIType api_type) override + GeometryShaderUid GetUid(u32 primitive_type, APIType api_type) override { return GetGeometryShaderUid(primitive_type); } @@ -74,9 +72,9 @@ public: static std::unique_ptr s_instance; protected: - PixelShaderUid GetUid(DSTALPHA_MODE dst_alpha_mode, u32 primitive_type, APIType api_type) override + PixelShaderUid GetUid(u32 primitive_type, APIType api_type) override { - return GetPixelShaderUid(dst_alpha_mode); + return GetPixelShaderUid(); } ShaderCode GenerateCode(APIType api_type, PixelShaderUid uid) override { diff --git a/Source/Core/VideoBackends/Null/VertexManager.cpp b/Source/Core/VideoBackends/Null/VertexManager.cpp index 2596243f93..86f4c14d48 100644 --- a/Source/Core/VideoBackends/Null/VertexManager.cpp +++ b/Source/Core/VideoBackends/Null/VertexManager.cpp @@ -40,14 +40,11 @@ void VertexManager::ResetBuffer(u32 stride) IndexGenerator::Start(&m_local_i_buffer[0]); } -void VertexManager::vFlush(bool use_dst_alpha) +void VertexManager::vFlush() { - VertexShaderCache::s_instance->SetShader( - use_dst_alpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, m_current_primitive_type); - GeometryShaderCache::s_instance->SetShader( - use_dst_alpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, m_current_primitive_type); - PixelShaderCache::s_instance->SetShader( - use_dst_alpha ? DSTALPHA_DUAL_SOURCE_BLEND : DSTALPHA_NONE, m_current_primitive_type); + VertexShaderCache::s_instance->SetShader(m_current_primitive_type); + GeometryShaderCache::s_instance->SetShader(m_current_primitive_type); + PixelShaderCache::s_instance->SetShader(m_current_primitive_type); } } // namespace diff --git a/Source/Core/VideoBackends/Null/VertexManager.h b/Source/Core/VideoBackends/Null/VertexManager.h index 9e31b30416..3fd5d347d7 100644 --- a/Source/Core/VideoBackends/Null/VertexManager.h +++ b/Source/Core/VideoBackends/Null/VertexManager.h @@ -21,7 +21,7 @@ protected: void ResetBuffer(u32 stride) override; private: - void vFlush(bool use_dst_alpha) override; + void vFlush() override; std::vector m_local_v_buffer; std::vector m_local_i_buffer; }; diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp index 44bf063a8a..9fc17d6d5d 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.cpp @@ -174,10 +174,10 @@ void ProgramShaderCache::UploadConstants() } } -SHADER* ProgramShaderCache::SetShader(DSTALPHA_MODE dstAlphaMode, u32 primitive_type) +SHADER* ProgramShaderCache::SetShader(u32 primitive_type) { SHADERUID uid; - GetShaderId(&uid, dstAlphaMode, primitive_type); + GetShaderId(&uid, primitive_type); // Check if the shader is already set if (last_entry) @@ -388,9 +388,9 @@ GLuint ProgramShaderCache::CompileSingleShader(GLuint type, const std::string& c return result; } -void ProgramShaderCache::GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 primitive_type) +void ProgramShaderCache::GetShaderId(SHADERUID* uid, u32 primitive_type) { - uid->puid = GetPixelShaderUid(dstAlphaMode); + uid->puid = GetPixelShaderUid(); uid->vuid = GetVertexShaderUid(); uid->guid = GetGeometryShaderUid(primitive_type); } diff --git a/Source/Core/VideoBackends/OGL/ProgramShaderCache.h b/Source/Core/VideoBackends/OGL/ProgramShaderCache.h index 7f949031e2..c471db63ed 100644 --- a/Source/Core/VideoBackends/OGL/ProgramShaderCache.h +++ b/Source/Core/VideoBackends/OGL/ProgramShaderCache.h @@ -62,8 +62,8 @@ public: }; static PCacheEntry GetShaderProgram(); - static SHADER* SetShader(DSTALPHA_MODE dstAlphaMode, u32 primitive_type); - static void GetShaderId(SHADERUID* uid, DSTALPHA_MODE dstAlphaMode, u32 primitive_type); + static SHADER* SetShader(u32 primitive_type); + static void GetShaderId(SHADERUID* uid, u32 primitive_type); static bool CompileShader(SHADER& shader, const std::string& vcode, const std::string& pcode, const std::string& gcode = ""); diff --git a/Source/Core/VideoBackends/OGL/VertexManager.cpp b/Source/Core/VideoBackends/OGL/VertexManager.cpp index 6b18517555..522cc342d0 100644 --- a/Source/Core/VideoBackends/OGL/VertexManager.cpp +++ b/Source/Core/VideoBackends/OGL/VertexManager.cpp @@ -136,7 +136,7 @@ void VertexManager::Draw(u32 stride) static_cast(g_renderer.get())->SetGenerationMode(); } -void VertexManager::vFlush(bool useDstAlpha) +void VertexManager::vFlush() { GLVertexFormat* nativeVertexFmt = (GLVertexFormat*)VertexLoaderManager::GetCurrentVertexFormat(); u32 stride = nativeVertexFmt->GetVertexStride(); @@ -149,19 +149,7 @@ void VertexManager::vFlush(bool useDstAlpha) PrepareDrawBuffers(stride); - // Makes sure we can actually do Dual source blending - bool dualSourcePossible = g_ActiveConfig.backend_info.bSupportsDualSourceBlend; - - // If host supports GL_ARB_blend_func_extended, we can do dst alpha in - // the same pass as regular rendering. - if (useDstAlpha && dualSourcePossible) - { - ProgramShaderCache::SetShader(DSTALPHA_DUAL_SOURCE_BLEND, m_current_primitive_type); - } - else - { - ProgramShaderCache::SetShader(DSTALPHA_NONE, m_current_primitive_type); - } + ProgramShaderCache::SetShader(m_current_primitive_type); // upload global constants ProgramShaderCache::UploadConstants(); @@ -171,38 +159,6 @@ void VertexManager::vFlush(bool useDstAlpha) Draw(stride); - // If the GPU does not support dual-source blending, we can approximate the effect by drawing - // the object a second time, with the write mask set to alpha only using a shader that outputs - // the destination/constant alpha value (which would normally be SRC_COLOR.a). - // - // This is also used when logic ops and destination alpha is enabled, since we can't enable - // blending and logic ops concurrently. - bool logic_op_enabled = (bpmem.blendmode.logicopenable && !bpmem.blendmode.blendenable && - GLInterface->GetMode() == GLInterfaceMode::MODE_OPENGL); - if (useDstAlpha && (!dualSourcePossible || logic_op_enabled)) - { - ProgramShaderCache::SetShader(DSTALPHA_ALPHA_PASS, m_current_primitive_type); - - // only update alpha - glColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE); - - glDisable(GL_BLEND); - - if (logic_op_enabled) - glDisable(GL_COLOR_LOGIC_OP); - - Draw(stride); - - // restore color mask - g_renderer->SetColorMask(); - - if (bpmem.blendmode.blendenable || bpmem.blendmode.subtract) - glEnable(GL_BLEND); - - if (logic_op_enabled) - glEnable(GL_COLOR_LOGIC_OP); - } - #if defined(_DEBUG) || defined(DEBUGFAST) if (g_ActiveConfig.iLog & CONF_SAVESHADERS) { diff --git a/Source/Core/VideoBackends/OGL/VertexManager.h b/Source/Core/VideoBackends/OGL/VertexManager.h index 2eecb7d582..af79d7586c 100644 --- a/Source/Core/VideoBackends/OGL/VertexManager.h +++ b/Source/Core/VideoBackends/OGL/VertexManager.h @@ -41,7 +41,7 @@ protected: private: void Draw(u32 stride); - void vFlush(bool useDstAlpha) override; + void vFlush() override; void PrepareDrawBuffers(u32 stride); // Alternative buffers in CPU memory for primatives we are going to discard. diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp index 9e05ca2cae..ca58450971 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.cpp +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.cpp @@ -54,7 +54,7 @@ void SWVertexLoader::ResetBuffer(u32 stride) IndexGenerator::Start(GetIndexBuffer()); } -void SWVertexLoader::vFlush(bool useDstAlpha) +void SWVertexLoader::vFlush() { DebugUtil::OnObjectBegin(); diff --git a/Source/Core/VideoBackends/Software/SWVertexLoader.h b/Source/Core/VideoBackends/Software/SWVertexLoader.h index dcc34f6dee..6ad4a1069a 100644 --- a/Source/Core/VideoBackends/Software/SWVertexLoader.h +++ b/Source/Core/VideoBackends/Software/SWVertexLoader.h @@ -25,7 +25,7 @@ protected: void ResetBuffer(u32 stride) override; u16* GetIndexBuffer() { return &LocalIBuffer[0]; } private: - void vFlush(bool useDstAlpha) override; + void vFlush() override; std::vector LocalVBuffer; std::vector LocalIBuffer; diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.cpp b/Source/Core/VideoBackends/Vulkan/Renderer.cpp index 19f25ad784..d87b8c6519 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.cpp +++ b/Source/Core/VideoBackends/Vulkan/Renderer.cpp @@ -1218,7 +1218,7 @@ void Renderer::ResizeSwapChain() OnSwapChainResized(); } -void Renderer::ApplyState(bool bUseDstAlpha) +void Renderer::ApplyState() { } diff --git a/Source/Core/VideoBackends/Vulkan/Renderer.h b/Source/Core/VideoBackends/Vulkan/Renderer.h index e05792fc08..d07389da71 100644 --- a/Source/Core/VideoBackends/Vulkan/Renderer.h +++ b/Source/Core/VideoBackends/Vulkan/Renderer.h @@ -52,7 +52,7 @@ public: void ReinterpretPixelData(unsigned int convtype) override; - void ApplyState(bool bUseDstAlpha) override; + void ApplyState() override; void ResetAPIState() override; void RestoreAPIState() override; diff --git a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp index d374ec5f1d..69830f11d9 100644 --- a/Source/Core/VideoBackends/Vulkan/StateTracker.cpp +++ b/Source/Core/VideoBackends/Vulkan/StateTracker.cpp @@ -304,10 +304,10 @@ void StateTracker::SetBlendState(const BlendState& state) m_dirty_flags |= DIRTY_FLAG_PIPELINE; } -bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type, DSTALPHA_MODE dstalpha_mode) +bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type) { VertexShaderUid vs_uid = GetVertexShaderUid(); - PixelShaderUid ps_uid = GetPixelShaderUid(dstalpha_mode); + PixelShaderUid ps_uid = GetPixelShaderUid(); bool changed = false; @@ -340,16 +340,6 @@ bool StateTracker::CheckForShaderChanges(u32 gx_primitive_type, DSTALPHA_MODE ds changed = true; } - if (m_dstalpha_mode != dstalpha_mode) - { - // Switching to/from alpha pass requires a pipeline change, since the blend state - // is overridden in the destination alpha pass. - if (m_dstalpha_mode == DSTALPHA_ALPHA_PASS || dstalpha_mode == DSTALPHA_ALPHA_PASS) - changed = true; - - m_dstalpha_mode = dstalpha_mode; - } - if (changed) m_dirty_flags |= DIRTY_FLAG_PIPELINE; @@ -881,22 +871,6 @@ void StateTracker::EndClearRenderPass() EndRenderPass(); } -PipelineInfo StateTracker::GetAlphaPassPipelineConfig(const PipelineInfo& info) const -{ - PipelineInfo temp_info = info; - - // Skip depth writes for this pass. The results will be the same, so no - // point in overwriting depth values with the same value. - temp_info.depth_stencil_state.write_enable = VK_FALSE; - - // Only allow alpha writes, and disable blending. - temp_info.blend_state.blend_enable = VK_FALSE; - temp_info.blend_state.logic_op_enable = VK_FALSE; - temp_info.blend_state.write_mask = VK_COLOR_COMPONENT_A_BIT; - - return temp_info; -} - VkPipeline StateTracker::GetPipelineAndCacheUID(const PipelineInfo& info) { auto result = g_object_cache->GetPipelineWithCacheResult(info); @@ -915,17 +889,7 @@ bool StateTracker::UpdatePipeline() return false; // Grab a new pipeline object, this can fail. - // We have to use a different blend state for the alpha pass of the dstalpha fallback. - if (m_dstalpha_mode == DSTALPHA_ALPHA_PASS) - { - // We need to retain the existing state, since we don't want to break the next draw. - PipelineInfo temp_info = GetAlphaPassPipelineConfig(m_pipeline_state); - m_pipeline_object = GetPipelineAndCacheUID(temp_info); - } - else - { - m_pipeline_object = GetPipelineAndCacheUID(m_pipeline_state); - } + m_pipeline_object = GetPipelineAndCacheUID(m_pipeline_state); m_dirty_flags |= DIRTY_FLAG_PIPELINE_BINDING; return m_pipeline_object != VK_NULL_HANDLE; diff --git a/Source/Core/VideoBackends/Vulkan/StateTracker.h b/Source/Core/VideoBackends/Vulkan/StateTracker.h index 97bcdd2cc0..1f6beddeed 100644 --- a/Source/Core/VideoBackends/Vulkan/StateTracker.h +++ b/Source/Core/VideoBackends/Vulkan/StateTracker.h @@ -58,7 +58,7 @@ public: void SetDepthStencilState(const DepthStencilState& state); void SetBlendState(const BlendState& state); - bool CheckForShaderChanges(u32 gx_primitive_type, DSTALPHA_MODE dstalpha_mode); + bool CheckForShaderChanges(u32 gx_primitive_type); void UpdateVertexShaderConstants(); void UpdateGeometryShaderConstants(); @@ -172,9 +172,6 @@ private: // If not, ends the render pass if it is a clear render pass. bool IsViewportWithinRenderArea() const; - // Gets a pipeline state that can be used to draw the alpha pass with constant alpha enabled. - PipelineInfo GetAlphaPassPipelineConfig(const PipelineInfo& info) const; - // Obtains a Vulkan pipeline object for the specified pipeline configuration. // Also adds this pipeline configuration to the UID cache if it is not present already. VkPipeline GetPipelineAndCacheUID(const PipelineInfo& info); @@ -205,7 +202,6 @@ private: // pipeline state PipelineInfo m_pipeline_state = {}; - DSTALPHA_MODE m_dstalpha_mode = DSTALPHA_NONE; VkPipeline m_pipeline_object = VK_NULL_HANDLE; // shader bindings diff --git a/Source/Core/VideoBackends/Vulkan/VertexManager.cpp b/Source/Core/VideoBackends/Vulkan/VertexManager.cpp index f3116a8cb6..53309b3aec 100644 --- a/Source/Core/VideoBackends/Vulkan/VertexManager.cpp +++ b/Source/Core/VideoBackends/Vulkan/VertexManager.cpp @@ -124,7 +124,7 @@ void VertexManager::ResetBuffer(u32 stride) static_cast(m_index_stream_buffer->GetCurrentOffset() / sizeof(u16)); } -void VertexManager::vFlush(bool use_dst_alpha) +void VertexManager::vFlush() { const VertexFormat* vertex_format = static_cast(VertexLoaderManager::GetCurrentVertexFormat()); @@ -153,13 +153,8 @@ void VertexManager::vFlush(bool use_dst_alpha) break; } - // Can we do single-pass dst alpha? - DSTALPHA_MODE dstalpha_mode = DSTALPHA_NONE; - if (use_dst_alpha && g_vulkan_context->SupportsDualSourceBlend()) - dstalpha_mode = DSTALPHA_DUAL_SOURCE_BLEND; - // Check for any shader stage changes - StateTracker::GetInstance()->CheckForShaderChanges(m_current_primitive_type, dstalpha_mode); + StateTracker::GetInstance()->CheckForShaderChanges(m_current_primitive_type); // Update any changed constants StateTracker::GetInstance()->UpdateVertexShaderConstants(); @@ -202,27 +197,6 @@ void VertexManager::vFlush(bool use_dst_alpha) vkCmdDrawIndexed(g_command_buffer_mgr->GetCurrentCommandBuffer(), index_count, 1, m_current_draw_base_index, m_current_draw_base_vertex, 0); - // If the GPU does not support dual-source blending, we can approximate the effect by drawing - // the object a second time, with the write mask set to alpha only using a shader that outputs - // the destination/constant alpha value (which would normally be SRC_COLOR.a). - // - // This is also used when logic ops and destination alpha is enabled, since we can't enable - // blending and logic ops concurrently (and the logical operation applies to all channels). - bool logic_op_enabled = bpmem.blendmode.logicopenable && !bpmem.blendmode.blendenable; - if (use_dst_alpha && (!g_vulkan_context->SupportsDualSourceBlend() || logic_op_enabled)) - { - StateTracker::GetInstance()->CheckForShaderChanges(m_current_primitive_type, - DSTALPHA_ALPHA_PASS); - if (!StateTracker::GetInstance()->Bind()) - { - WARN_LOG(VIDEO, "Skipped draw of %u indices (alpha pass)", index_count); - return; - } - - vkCmdDrawIndexed(g_command_buffer_mgr->GetCurrentCommandBuffer(), index_count, 1, - m_current_draw_base_index, m_current_draw_base_vertex, 0); - } - StateTracker::GetInstance()->OnDraw(); } diff --git a/Source/Core/VideoBackends/Vulkan/VertexManager.h b/Source/Core/VideoBackends/Vulkan/VertexManager.h index b79e671c6c..8d122179ce 100644 --- a/Source/Core/VideoBackends/Vulkan/VertexManager.h +++ b/Source/Core/VideoBackends/Vulkan/VertexManager.h @@ -31,7 +31,7 @@ protected: void ResetBuffer(u32 stride) override; private: - void vFlush(bool use_dst_alpha) override; + void vFlush() override; std::vector m_cpu_vertex_buffer; std::vector m_cpu_index_buffer; diff --git a/Source/Core/VideoCommon/PixelShaderGen.cpp b/Source/Core/VideoCommon/PixelShaderGen.cpp index 6d10d82202..7a718c8f38 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.cpp +++ b/Source/Core/VideoCommon/PixelShaderGen.cpp @@ -156,13 +156,15 @@ static const char* tevAOutputTable[] = {"prev.a", "c0.a", "c1.a", "c2.a"}; // leak // into this UID; This is really unhelpful if these UIDs ever move from one machine to // another. -PixelShaderUid GetPixelShaderUid(DSTALPHA_MODE dstAlphaMode) +PixelShaderUid GetPixelShaderUid() { PixelShaderUid out; pixel_shader_uid_data* uid_data = out.GetUidData(); memset(uid_data, 0, sizeof(*uid_data)); - uid_data->dstAlphaMode = dstAlphaMode; + uid_data->useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && + bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; + uid_data->genMode_numindstages = bpmem.genMode.numindstages; uid_data->genMode_numtevstages = bpmem.genMode.numtevstages; uid_data->genMode_numtexgens = bpmem.genMode.numtexgens; @@ -327,13 +329,9 @@ PixelShaderUid GetPixelShaderUid(DSTALPHA_MODE dstAlphaMode) uid_data->ztex_op = bpmem.ztex2.op; uid_data->early_ztest = bpmem.UseEarlyDepthTest(); uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel; - - if (dstAlphaMode != DSTALPHA_ALPHA_PASS) - { - uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel; - uid_data->fog_proj = bpmem.fog.c_proj_fsel.proj; - uid_data->fog_RangeBaseEnabled = bpmem.fogRange.Base.Enabled; - } + uid_data->fog_fsel = bpmem.fog.c_proj_fsel.fsel; + uid_data->fog_proj = bpmem.fog.c_proj_fsel.proj; + uid_data->fog_RangeBaseEnabled = bpmem.fogRange.Base.Enabled; return out; } @@ -510,7 +508,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data* const bool use_dual_source = g_ActiveConfig.backend_info.bSupportsDualSourceBlend && (!DriverDetails::HasBug(DriverDetails::BUG_BROKEN_DUAL_SOURCE_BLENDING) || - uid_data->dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND); + uid_data->useDstAlpha); if (ApiType == APIType::OpenGL || ApiType == APIType::Vulkan) { @@ -795,8 +793,7 @@ ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data* out.Write("\tprev.rgb = (prev.rgb - (prev.rgb >> 6)) + abs(dither.y * 3 - dither.x * 2);\n"); } - if (uid_data->dstAlphaMode != DSTALPHA_ALPHA_PASS) - WriteFog(out, uid_data); + WriteFog(out, uid_data); // Write the color and alpha values to the framebuffer WriteColor(out, uid_data, use_dual_source); @@ -1308,7 +1305,7 @@ static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data, b // Colors will be blended against the 8-bit alpha from ocol1 and // the 6-bit alpha from ocol0 will be written to the framebuffer - if (uid_data->dstAlphaMode == DSTALPHA_NONE) + if (!uid_data->useDstAlpha) { out.Write("\tocol0.a = float(prev.a >> 2) / 63.0;\n"); if (use_dual_source) @@ -1322,7 +1319,7 @@ static void WriteColor(ShaderCode& out, const pixel_shader_uid_data* uid_data, b // Use dual-source color blending to perform dst alpha in a single pass if (use_dual_source) { - if (uid_data->dstAlphaMode == DSTALPHA_DUAL_SOURCE_BLEND) + if (uid_data->useDstAlpha) out.Write("\tocol1.a = float(prev.a) / 255.0;\n"); else out.Write("\tocol1.a = float(" I_ALPHA ".a) / 255.0;\n"); diff --git a/Source/Core/VideoCommon/PixelShaderGen.h b/Source/Core/VideoCommon/PixelShaderGen.h index d141fd57f8..2c19d38d87 100644 --- a/Source/Core/VideoCommon/PixelShaderGen.h +++ b/Source/Core/VideoCommon/PixelShaderGen.h @@ -10,14 +10,6 @@ enum class APIType; -// Different ways to achieve rendering with destination alpha -enum DSTALPHA_MODE -{ - DSTALPHA_NONE, // Render normally, without destination alpha - DSTALPHA_ALPHA_PASS, // Render normally first, then render again for alpha - DSTALPHA_DUAL_SOURCE_BLEND // Use dual-source blending -}; - #pragma pack(1) struct pixel_shader_uid_data { @@ -26,7 +18,8 @@ struct pixel_shader_uid_data u32 num_values; // TODO: Shouldn't be a u32 u32 NumValues() const { return num_values; } u32 components : 2; - u32 dstAlphaMode : 2; + u32 pad0 : 1; + u32 useDstAlpha : 1; u32 Pretest : 2; u32 nIndirectStagesUsed : 4; u32 stereo : 1; @@ -170,4 +163,4 @@ struct pixel_shader_uid_data typedef ShaderUid PixelShaderUid; ShaderCode GeneratePixelShaderCode(APIType ApiType, const pixel_shader_uid_data* uid_data); -PixelShaderUid GetPixelShaderUid(DSTALPHA_MODE dstAlphaMode); +PixelShaderUid GetPixelShaderUid(); diff --git a/Source/Core/VideoCommon/RenderBase.h b/Source/Core/VideoCommon/RenderBase.h index f33ce4395a..22d6093420 100644 --- a/Source/Core/VideoCommon/RenderBase.h +++ b/Source/Core/VideoCommon/RenderBase.h @@ -74,7 +74,7 @@ public: virtual void SetViewport() {} virtual void SetFullscreen(bool enable_fullscreen) {} virtual bool IsFullscreen() const { return false; } - virtual void ApplyState(bool bUseDstAlpha) {} + virtual void ApplyState() {} virtual void RestoreState() {} virtual void ResetAPIState() {} virtual void RestoreAPIState() {} diff --git a/Source/Core/VideoCommon/VertexManagerBase.cpp b/Source/Core/VideoCommon/VertexManagerBase.cpp index 4ff4c2c528..f0299f2495 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.cpp +++ b/Source/Core/VideoCommon/VertexManagerBase.cpp @@ -253,12 +253,9 @@ void VertexManagerBase::Flush() GeometryShaderManager::SetConstants(); PixelShaderManager::SetConstants(); - bool useDstAlpha = bpmem.dstalpha.enable && bpmem.blendmode.alphaupdate && - bpmem.zcontrol.pixel_format == PEControl::RGBA6_Z24; - if (PerfQueryBase::ShouldEmulate()) g_perf_query->EnableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); - g_vertex_manager->vFlush(useDstAlpha); + g_vertex_manager->vFlush(); if (PerfQueryBase::ShouldEmulate()) g_perf_query->DisableQuery(bpmem.zcontrol.early_ztest ? PQG_ZCOMP_ZCOMPLOC : PQG_ZCOMP); } diff --git a/Source/Core/VideoCommon/VertexManagerBase.h b/Source/Core/VideoCommon/VertexManagerBase.h index cbc1d63d84..9ebda79a60 100644 --- a/Source/Core/VideoCommon/VertexManagerBase.h +++ b/Source/Core/VideoCommon/VertexManagerBase.h @@ -82,7 +82,7 @@ protected: private: bool m_is_flushed = true; - virtual void vFlush(bool useDstAlpha) = 0; + virtual void vFlush() = 0; virtual void CreateDeviceObjects() {} virtual void DestroyDeviceObjects() {}