diff --git a/GPU/Software/BinManager.cpp b/GPU/Software/BinManager.cpp index ac50f4c5a3..7906cbe79f 100644 --- a/GPU/Software/BinManager.cpp +++ b/GPU/Software/BinManager.cpp @@ -172,9 +172,7 @@ void BinManager::UpdateState() { creatingState_ = true; stateIndex_ = (uint16_t)states_.Push(RasterizerState()); // When new funcs are compiled, we need to flush if WX exclusive. - ComputeRasterizerState(&states_[stateIndex_], [&]() { - Flush("compile"); - }); + ComputeRasterizerState(&states_[stateIndex_], this); states_[stateIndex_].samplerID.cached.clut = cluts_[clutIndex_].readable; creatingState_ = false; diff --git a/GPU/Software/DrawPixel.cpp b/GPU/Software/DrawPixel.cpp index 2f4ea23b17..341ba80f7b 100644 --- a/GPU/Software/DrawPixel.cpp +++ b/GPU/Software/DrawPixel.cpp @@ -20,6 +20,7 @@ #include "Common/Data/Convert/ColorConv.h" #include "Core/Config.h" #include "GPU/GPUState.h" +#include "GPU/Software/BinManager.h" #include "GPU/Software/DrawPixel.h" #include "GPU/Software/FuncId.h" #include "GPU/Software/Rasterizer.h" @@ -707,8 +708,8 @@ void SOFTRAST_CALL DrawSinglePixel(int x, int y, int z, int fog, Vec4IntArg colo SetPixelColor(fbFormat, pixelID.cached.framebufStride, x, y, new_color, old_color, targetWriteMask); } -SingleFunc GetSingleFunc(const PixelFuncID &id, std::function flushForCompile) { - SingleFunc jitted = jitCache->GetSingle(id, flushForCompile); +SingleFunc GetSingleFunc(const PixelFuncID &id, BinManager *binner) { + SingleFunc jitted = jitCache->GetSingle(id, binner); if (jitted) { return jitted; } @@ -786,7 +787,7 @@ void PixelJitCache::Flush() { compileQueue_.clear(); } -SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id, std::function flushForCompile) { +SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id, BinManager *binner) { if (!g_Config.bSoftwareRenderingJit) return nullptr; @@ -798,14 +799,14 @@ SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id, std::function return it; } - if (!flushForCompile) { + if (!binner) { // Can't compile, let's try to do it later when there's an opportunity. compileQueue_.insert(id); return nullptr; } guard.unlock(); - flushForCompile(); + binner->Flush("compile"); guard.lock(); for (const auto &queued : compileQueue_) { diff --git a/GPU/Software/DrawPixel.h b/GPU/Software/DrawPixel.h index e9d2715da4..1e100c81be 100644 --- a/GPU/Software/DrawPixel.h +++ b/GPU/Software/DrawPixel.h @@ -19,7 +19,6 @@ #include "ppsspp_config.h" -#include #include #include #include @@ -29,6 +28,8 @@ #include "GPU/Software/FuncId.h" #include "GPU/Software/RasterizerRegCache.h" +class BinManager; + namespace Rasterizer { // Our std::unordered_map argument will ignore the alignment attribute, but that doesn't matter. @@ -39,7 +40,7 @@ namespace Rasterizer { #endif typedef void (SOFTRAST_CALL *SingleFunc)(int x, int y, int z, int fog, Vec4IntArg color_in, const PixelFuncID &pixelID); -SingleFunc GetSingleFunc(const PixelFuncID &id, std::function flushForCompile); +SingleFunc GetSingleFunc(const PixelFuncID &id, BinManager *binner); void Init(); void FlushJit(); @@ -64,7 +65,7 @@ public: PixelJitCache(); // Returns a pointer to the code to run. - SingleFunc GetSingle(const PixelFuncID &id, std::function flushForCompile); + SingleFunc GetSingle(const PixelFuncID &id, BinManager *binner); SingleFunc GenericSingle(const PixelFuncID &id); void Clear() override; void Flush(); diff --git a/GPU/Software/Rasterizer.cpp b/GPU/Software/Rasterizer.cpp index 176e2a8199..4b9ed61d27 100644 --- a/GPU/Software/Rasterizer.cpp +++ b/GPU/Software/Rasterizer.cpp @@ -93,15 +93,15 @@ static inline Vec4 Interpolate(const float &c0, const float &c1, const fl return Interpolate(c0, c1, c2, w0.Cast(), w1.Cast(), w2.Cast(), wsum_recip); } -void ComputeRasterizerState(RasterizerState *state, std::function flushForCompile) { +void ComputeRasterizerState(RasterizerState *state, BinManager *binner) { ComputePixelFuncID(&state->pixelID); - state->drawPixel = Rasterizer::GetSingleFunc(state->pixelID, flushForCompile); + state->drawPixel = Rasterizer::GetSingleFunc(state->pixelID, binner); state->enableTextures = gstate.isTextureMapEnabled() && !state->pixelID.clearMode; if (state->enableTextures) { ComputeSamplerID(&state->samplerID); - state->linear = Sampler::GetLinearFunc(state->samplerID, flushForCompile); - state->nearest = Sampler::GetNearestFunc(state->samplerID, flushForCompile); + state->linear = Sampler::GetLinearFunc(state->samplerID, binner); + state->nearest = Sampler::GetNearestFunc(state->samplerID, binner); // Since the definitions are the same, just force this setting using the func pointer. if (g_Config.iTexFiltering == TEX_FILTER_FORCE_LINEAR) { @@ -1697,10 +1697,14 @@ bool GetCurrentTexture(GPUDebugBuffer &buffer, int level) ComputeSamplerID(&id); id.cached.clut = clut; - Sampler::FetchFunc sampler = Sampler::GetFetchFunc(id, [] { - if (gpuDebug) - gpuDebug->DispatchFlush(); - }); + // Slight annoyance, we may have to force a compile. + Sampler::FetchFunc sampler = Sampler::GetFetchFunc(id, nullptr); + if (!sampler) { + Sampler::FlushJit(); + sampler = Sampler::GetFetchFunc(id, nullptr); + if (!sampler) + return false; + } u8 *texptr = Memory::GetPointerWrite(texaddr); u32 *row = (u32 *)buffer.GetData(); diff --git a/GPU/Software/Rasterizer.h b/GPU/Software/Rasterizer.h index aad5b648ef..d4e4ebe17c 100644 --- a/GPU/Software/Rasterizer.h +++ b/GPU/Software/Rasterizer.h @@ -30,6 +30,7 @@ struct GPUDebugBuffer; struct BinCoords; +class BinManager; namespace Rasterizer { @@ -100,7 +101,7 @@ struct RasterizerState { } }; -void ComputeRasterizerState(RasterizerState *state, std::function flushForCompile); +void ComputeRasterizerState(RasterizerState *state, BinManager *binner); void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0); void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0, const VertexData &v1, bool forceFlat); void CalculateRasterStateFlags(RasterizerState *state, const VertexData &v0, const VertexData &v1, const VertexData &v2); diff --git a/GPU/Software/Sampler.cpp b/GPU/Software/Sampler.cpp index 66022fa53b..97a47933cc 100644 --- a/GPU/Software/Sampler.cpp +++ b/GPU/Software/Sampler.cpp @@ -25,6 +25,7 @@ #include "Core/Reporting.h" #include "GPU/Common/TextureDecoder.h" #include "GPU/GPUState.h" +#include "GPU/Software/BinManager.h" #include "GPU/Software/Rasterizer.h" #include "GPU/Software/RasterizerRegCache.h" #include "GPU/Software/Sampler.h" @@ -67,9 +68,9 @@ bool DescribeCodePtr(const u8 *ptr, std::string &name) { return true; } -NearestFunc GetNearestFunc(SamplerID id, std::function flushForCompile) { +NearestFunc GetNearestFunc(SamplerID id, BinManager *binner) { id.linear = false; - NearestFunc jitted = jitCache->GetNearest(id, flushForCompile); + NearestFunc jitted = jitCache->GetNearest(id, binner); if (jitted) { return jitted; } @@ -77,9 +78,9 @@ NearestFunc GetNearestFunc(SamplerID id, std::function flushForCompile) return &SampleNearest; } -LinearFunc GetLinearFunc(SamplerID id, std::function flushForCompile) { +LinearFunc GetLinearFunc(SamplerID id, BinManager *binner) { id.linear = true; - LinearFunc jitted = jitCache->GetLinear(id, flushForCompile); + LinearFunc jitted = jitCache->GetLinear(id, binner); if (jitted) { return jitted; } @@ -87,9 +88,9 @@ LinearFunc GetLinearFunc(SamplerID id, std::function flushForCompile) { return &SampleLinear; } -FetchFunc GetFetchFunc(SamplerID id, std::function flushForCompile) { +FetchFunc GetFetchFunc(SamplerID id, BinManager *binner) { id.fetch = true; - FetchFunc jitted = jitCache->GetFetch(id, flushForCompile); + FetchFunc jitted = jitCache->GetFetch(id, binner); if (jitted) { return jitted; } @@ -153,7 +154,7 @@ void SamplerJitCache::Flush() { compileQueue_.clear(); } -NearestFunc SamplerJitCache::GetByID(const SamplerID &id, std::function flushForCompile) { +NearestFunc SamplerJitCache::GetByID(const SamplerID &id, BinManager *binner) { if (!g_Config.bSoftwareRenderingJit) return nullptr; @@ -164,14 +165,14 @@ NearestFunc SamplerJitCache::GetByID(const SamplerID &id, std::function if (it != nullptr) return it; - if (!flushForCompile) { + if (!binner) { // Can't compile, let's try to do it later when there's an opportunity. compileQueue_.insert(id); return nullptr; } guard.unlock(); - flushForCompile(); + binner->Flush("compile"); guard.lock(); for (const auto &queued : compileQueue_) { @@ -189,16 +190,16 @@ NearestFunc SamplerJitCache::GetByID(const SamplerID &id, std::function return cache_.Get(key); } -NearestFunc SamplerJitCache::GetNearest(const SamplerID &id, std::function flushForCompile) { - return (NearestFunc)GetByID(id, flushForCompile); +NearestFunc SamplerJitCache::GetNearest(const SamplerID &id, BinManager *binner) { + return (NearestFunc)GetByID(id, binner); } -LinearFunc SamplerJitCache::GetLinear(const SamplerID &id, std::function flushForCompile) { - return (LinearFunc)GetByID(id, flushForCompile); +LinearFunc SamplerJitCache::GetLinear(const SamplerID &id, BinManager *binner) { + return (LinearFunc)GetByID(id, binner); } -FetchFunc SamplerJitCache::GetFetch(const SamplerID &id, std::function flushForCompile) { - return (FetchFunc)GetByID(id, flushForCompile); +FetchFunc SamplerJitCache::GetFetch(const SamplerID &id, BinManager *binner) { + return (FetchFunc)GetByID(id, binner); } void SamplerJitCache::Compile(const SamplerID &id) { diff --git a/GPU/Software/Sampler.h b/GPU/Software/Sampler.h index 0d14ae12d2..0f8f413453 100644 --- a/GPU/Software/Sampler.h +++ b/GPU/Software/Sampler.h @@ -19,7 +19,6 @@ #include "ppsspp_config.h" -#include #include #include #include "Common/Data/Collections/Hashmaps.h" @@ -27,6 +26,8 @@ #include "GPU/Software/FuncId.h" #include "GPU/Software/RasterizerRegCache.h" +class BinManager; + namespace Sampler { // Our std::unordered_map argument will ignore the alignment attribute, but that doesn't matter. @@ -37,13 +38,13 @@ namespace Sampler { #endif typedef Rasterizer::Vec4IntResult(SOFTRAST_CALL *FetchFunc)(int u, int v, const u8 *tptr, int bufw, int level, const SamplerID &samplerID); -FetchFunc GetFetchFunc(SamplerID id, std::function flushForCompile); +FetchFunc GetFetchFunc(SamplerID id, BinManager *binner); typedef Rasterizer::Vec4IntResult (SOFTRAST_CALL *NearestFunc)(float s, float t, Rasterizer::Vec4IntArg prim_color, const u8 *const *tptr, const uint16_t *bufw, int level, int levelFrac, const SamplerID &samplerID); -NearestFunc GetNearestFunc(SamplerID id, std::function flushForCompile); +NearestFunc GetNearestFunc(SamplerID id, BinManager *binner); typedef Rasterizer::Vec4IntResult (SOFTRAST_CALL *LinearFunc)(float s, float t, Rasterizer::Vec4IntArg prim_color, const u8 *const *tptr, const uint16_t *bufw, int level, int levelFrac, const SamplerID &samplerID); -LinearFunc GetLinearFunc(SamplerID id, std::function flushForCompile); +LinearFunc GetLinearFunc(SamplerID id, BinManager *binner); void Init(); void FlushJit(); @@ -56,9 +57,9 @@ public: SamplerJitCache(); // Returns a pointer to the code to run. - NearestFunc GetNearest(const SamplerID &id, std::function flushForCompile); - LinearFunc GetLinear(const SamplerID &id, std::function flushForCompile); - FetchFunc GetFetch(const SamplerID &id, std::function flushForCompile); + NearestFunc GetNearest(const SamplerID &id, BinManager *binner); + LinearFunc GetLinear(const SamplerID &id, BinManager *binner); + FetchFunc GetFetch(const SamplerID &id, BinManager *binner); void Clear() override; void Flush(); @@ -66,7 +67,7 @@ public: private: void Compile(const SamplerID &id); - NearestFunc GetByID(const SamplerID &id, std::function flushForCompile); + NearestFunc GetByID(const SamplerID &id, BinManager *binner); FetchFunc CompileFetch(const SamplerID &id); NearestFunc CompileNearest(const SamplerID &id); LinearFunc CompileLinear(const SamplerID &id); diff --git a/unittest/TestSoftwareGPUJit.cpp b/unittest/TestSoftwareGPUJit.cpp index d0d08ba3a2..5d7c6946d4 100644 --- a/unittest/TestSoftwareGPUJit.cpp +++ b/unittest/TestSoftwareGPUJit.cpp @@ -18,6 +18,7 @@ #include "Common/Data/Random/Rng.h" #include "Common/StringUtils.h" #include "Core/Config.h" +#include "GPU/Software/BinManager.h" #include "GPU/Software/DrawPixel.h" #include "GPU/Software/Sampler.h" #include "GPU/Software/SoftGpu.h" @@ -25,21 +26,22 @@ static bool TestSamplerJit() { using namespace Sampler; SamplerJitCache *cache = new SamplerJitCache(); + BinManager binner; auto GetLinear = [&](SamplerID &id) { id.linear = true; id.fetch = false; - return cache->GetLinear(id, [] {}); + return cache->GetLinear(id, &binner); }; auto GetNearest = [&](SamplerID &id) { id.linear = false; id.fetch = false; - return cache->GetNearest(id, [] {}); + return cache->GetNearest(id, &binner); }; auto GetFetch = [&](SamplerID &id) { id.linear = false; id.fetch = true; - return cache->GetFetch(id, [] {}); + return cache->GetFetch(id, &binner); }; GMRng rng; @@ -111,6 +113,7 @@ static bool TestSamplerJit() { static bool TestPixelJit() { using namespace Rasterizer; PixelJitCache *cache = new PixelJitCache(); + BinManager binner; GMRng rng; int successes = 0; @@ -134,7 +137,7 @@ static bool TestPixelJit() { continue; i++; - SingleFunc func = cache->GetSingle(id, [] {}); + SingleFunc func = cache->GetSingle(id, &binner); SingleFunc genericFunc = cache->GenericSingle(id); if (func != genericFunc) { successes++;