From e24c431855d2e10d66ef195c9965f8e68336554f Mon Sep 17 00:00:00 2001 From: Sergey Lipskiy Date: Sat, 22 Apr 2023 21:26:50 +0700 Subject: [PATCH] Attempt to compile shaders asynchronously, #2701 --- src/Combiner.cpp | 53 ++++++++++++++++++++++++++++++++++++++++++++++++ src/Combiner.h | 9 ++++++++ src/Config.cpp | 1 + src/Config.h | 1 + src/gDP.cpp | 1 + 5 files changed, 65 insertions(+) diff --git a/src/Combiner.cpp b/src/Combiner.cpp index 7cadc5efc..1d2027054 100644 --- a/src/Combiner.cpp +++ b/src/Combiner.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include "Combiner.h" @@ -108,6 +109,13 @@ void CombinerInfo::init() setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0)); gDP.otherMode.cycleType = G_CYC_FILL; setCombine(EncodeCombineMode(0, 0, 0, SHADE, 0, 0, 0, SHADE, 0, 0, 0, SHADE, 0, 0, 0, SHADE)); + + gDP.otherMode.cycleType = G_CYC_1CYCLE; + setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL0)); + m_defaultKeys[0] = m_pCurrent->getKey(); + gDP.otherMode.cycleType = G_CYC_2CYCLE; + setCombine(EncodeCombineMode(0, 0, 0, TEXEL0, 0, 0, 0, TEXEL1, 0, 0, 0, TEXEL0, 0, 0, 0, TEXEL1)); + m_defaultKeys[1] = m_pCurrent->getKey(); } m_shadowmapProgram.reset(gfxContext.createDepthFogShader()); @@ -299,6 +307,20 @@ void CombinerInfo::setCombine(u64 _mux ) if (iter != m_combiners.end()) { m_pCurrent = iter->second; } else { + if (gDP.otherMode.cycleType <= G_CYC_2CYCLE && + config.generalEmulation.enableAsyncShadersCompilation != 0 && + config.video.threadedVideo != 0) + { + iter = m_combiners.find(m_defaultKeys[gDP.otherMode.cycleType]); + if (iter != m_combiners.end()) { + m_pCurrent = iter->second; + if (m_unknownCombiners.insert(key).second) + m_combinersToCompile.push_back(key); + m_bChanged = true; + return; + } + } + m_pCurrent = Combiner_Compile(key); m_pCurrent->update(true); m_combiners[m_pCurrent->getKey()] = m_pCurrent; @@ -306,6 +328,37 @@ void CombinerInfo::setCombine(u64 _mux ) m_bChanged = true; } +void CombinerInfo::compileUnknownShaders() +{ +#if 1 + if (m_combinersToCompile.empty()) + return; + + std::thread task([this] { + std::unique_lock lock(m_compileCombinersMutex); + + for (auto& key : m_combinersToCompile) + { + m_pCurrent = Combiner_Compile(key); + m_pCurrent->update(true); + m_combiners[m_pCurrent->getKey()] = m_pCurrent; + } + m_combinersToCompile.clear(); + }); + task.detach(); +#else + if (m_combinersToCompile.empty()) + return; + for (auto& key : m_combinersToCompile) + { + m_pCurrent = Combiner_Compile(key); + m_pCurrent->update(true); + m_combiners[m_pCurrent->getKey()] = m_pCurrent; + } + m_combinersToCompile.clear(); +#endif +} + void CombinerInfo::updateParameters() { m_pCurrent->update(false); diff --git a/src/Combiner.h b/src/Combiner.h index a33cf276a..5e13785d4 100644 --- a/src/Combiner.h +++ b/src/Combiner.h @@ -3,6 +3,8 @@ #include #include +#include +#include #include "GLideN64.h" #include "GraphicsDrawer.h" @@ -128,6 +130,8 @@ class CombinerInfo void setCombine(u64 _mux); void updateParameters(); + void compileUnknownShaders(); + void setDepthFogCombiner(); graphics::ShaderProgram * getTexrectUpscaleCopyProgram(); graphics::ShaderProgram * getTexrectColorAndDepthUpscaleCopyProgram(); @@ -163,6 +167,11 @@ class CombinerInfo graphics::CombinerProgram * m_pCurrent; graphics::Combiners m_combiners; + std::mutex m_compileCombinersMutex; + std::set m_unknownCombiners; + std::vector m_combinersToCompile; + std::array m_defaultKeys; + std::unique_ptr m_shadowmapProgram; std::unique_ptr m_texrectUpscaleCopyProgram; std::unique_ptr m_texrectColorAndDepthUpscaleCopyProgram; diff --git a/src/Config.cpp b/src/Config.cpp index c4e971625..09e4c99ec 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -51,6 +51,7 @@ void Config::resetToDefaults() generalEmulation.enableClipping = 1; generalEmulation.enableCustomSettings = 1; generalEmulation.enableShadersStorage = 1; + generalEmulation.enableAsyncShadersCompilation = 1; generalEmulation.enableLegacyBlending = 0; generalEmulation.enableHybridFilter = 1; generalEmulation.enableInaccurateTextureCoordinates = 0; diff --git a/src/Config.h b/src/Config.h index ae3e7400a..a7994296c 100644 --- a/src/Config.h +++ b/src/Config.h @@ -65,6 +65,7 @@ struct Config u32 enableClipping; u32 enableCustomSettings; u32 enableShadersStorage; + u32 enableAsyncShadersCompilation; u32 enableLegacyBlending; u32 enableHybridFilter; u32 enableInaccurateTextureCoordinates; diff --git a/src/gDP.cpp b/src/gDP.cpp index 6615b6000..d2d6a055f 100644 --- a/src/gDP.cpp +++ b/src/gDP.cpp @@ -983,6 +983,7 @@ void gDPFullSync() CheckInterrupts(); + CombinerInfo::get().compileUnknownShaders(); DebugMsg( DEBUG_NORMAL, "gDPFullSync();\n" ); }