From 91c9343e877ff51d7a65a62e789d9d39a4dc4e5e Mon Sep 17 00:00:00 2001 From: "Unknown W. Brackets" Date: Fri, 31 Dec 2021 11:42:37 -0800 Subject: [PATCH] samplerjit: Refactor and reuse constant pool. It's just here to be rip accessible, the fixed values can be output just once. --- GPU/Software/Sampler.cpp | 14 ++++ GPU/Software/Sampler.h | 2 + GPU/Software/SamplerX86.cpp | 125 +++++++++++++++++++++--------------- 3 files changed, 90 insertions(+), 51 deletions(-) diff --git a/GPU/Software/Sampler.cpp b/GPU/Software/Sampler.cpp index 11485aba51..64983244f8 100644 --- a/GPU/Software/Sampler.cpp +++ b/GPU/Software/Sampler.cpp @@ -119,6 +119,20 @@ void SamplerJitCache::Clear() { ClearCodeSpace(0); cache_.clear(); addresses_.clear(); + + const10All16_ = nullptr; + const10Low_ = nullptr; + const10All8_ = nullptr; + + constWidth256f_ = nullptr; + constHeight256f_ = nullptr; + constWidthMinus1i_ = nullptr; + constHeightMinus1i_ = nullptr; + + constOnes32_ = nullptr; + constOnes16_ = nullptr; + constUNext_ = nullptr; + constVNext_ = nullptr; } void SamplerJitCache::Describe(const std::string &message) { diff --git a/GPU/Software/Sampler.h b/GPU/Software/Sampler.h index 126d345e4e..94ed480944 100644 --- a/GPU/Software/Sampler.h +++ b/GPU/Software/Sampler.h @@ -82,6 +82,8 @@ private: Rasterizer::RegCache::Reg GetZeroVec(); Rasterizer::RegCache::Reg GetGState(); + void WriteConstantPool(const SamplerID &id); + bool Jit_ReadTextureFormat(const SamplerID &id); bool Jit_GetTexData(const SamplerID &id, int bitsPerTexel); bool Jit_GetTexDataSwizzled(const SamplerID &id, int bitsPerTexel); diff --git a/GPU/Software/SamplerX86.cpp b/GPU/Software/SamplerX86.cpp index 3470daff4e..dc5e587a8b 100644 --- a/GPU/Software/SamplerX86.cpp +++ b/GPU/Software/SamplerX86.cpp @@ -152,6 +152,9 @@ LinearFunc SamplerJitCache::CompileLinear(const SamplerID &id) { lockReg(XMM9, RegCache::VEC_ARG_COLOR); #endif + // Let's drop some helpful constants here. + WriteConstantPool(id); + // We'll first write the nearest sampler, which we will CALL. // This may differ slightly based on the "linear" flag. const u8 *nearest = AlignCode16(); @@ -182,57 +185,6 @@ LinearFunc SamplerJitCache::CompileLinear(const SamplerID &id) { unlockOptReg(RegCache::VEC_ARG_COLOR); regCache_.Reset(true); - // Let's drop some helpful constants here. - const10All16_ = AlignCode16(); - Write16(0x10); Write16(0x10); Write16(0x10); Write16(0x10); - Write16(0x10); Write16(0x10); Write16(0x10); Write16(0x10); - - const10Low_ = AlignCode16(); - Write16(0x10); Write16(0x10); Write16(0x10); Write16(0x10); - Write16(0); Write16(0); Write16(0); Write16(0); - - const10All8_ = AlignCode16(); - for (int i = 0; i < 16; ++i) - Write8(0x10); - - if (!id.hasAnyMips) { - constWidth256f_ = AlignCode16(); - float w256f = (1 << id.width0Shift) * 256; - Write32(*(uint32_t *)&w256f); Write32(*(uint32_t *)&w256f); - Write32(*(uint32_t *)&w256f); Write32(*(uint32_t *)&w256f); - - constHeight256f_ = AlignCode16(); - float h256f = (1 << id.height0Shift) * 256; - Write32(*(uint32_t *)&h256f); Write32(*(uint32_t *)&h256f); - Write32(*(uint32_t *)&h256f); Write32(*(uint32_t *)&h256f); - - constWidthMinus1i_ = AlignCode16(); - Write32((1 << id.width0Shift) - 1); Write32((1 << id.width0Shift) - 1); - Write32((1 << id.width0Shift) - 1); Write32((1 << id.width0Shift) - 1); - - constHeightMinus1i_ = AlignCode16(); - Write32((1 << id.height0Shift) - 1); Write32((1 << id.height0Shift) - 1); - Write32((1 << id.height0Shift) - 1); Write32((1 << id.height0Shift) - 1); - } else { - constWidth256f_ = nullptr; - constHeight256f_ = nullptr; - constWidthMinus1i_ = nullptr; - constHeightMinus1i_ = nullptr; - } - - constOnes32_ = AlignCode16(); - Write32(1); Write32(1); Write32(1); Write32(1); - - constOnes16_ = AlignCode16(); - Write16(1); Write16(1); Write16(1); Write16(1); - Write16(1); Write16(1); Write16(1); Write16(1); - - constUNext_ = AlignCode16(); - Write32(0); Write32(1); Write32(0); Write32(1); - - constVNext_ = AlignCode16(); - Write32(0); Write32(0); Write32(1); Write32(1); - // Now the actual linear func, which is exposed externally. const u8 *start = AlignCode16(); Describe("Init"); @@ -579,6 +531,77 @@ LinearFunc SamplerJitCache::CompileLinear(const SamplerID &id) { return (LinearFunc)start; } +void SamplerJitCache::WriteConstantPool(const SamplerID &id) { + // We reuse constants in any pool, because our code space is small. + if (const10All16_ == nullptr) { + const10All16_ = AlignCode16(); + for (int i = 0; i < 8; ++i) + Write16(0x10); + } + + if (const10Low_ == nullptr) { + const10Low_ = AlignCode16(); + for (int i = 0; i < 4; ++i) + Write16(0x10); + for (int i = 0; i < 4; ++i) + Write16(0); + } + + if (const10All8_ == nullptr) { + const10All8_ = AlignCode16(); + for (int i = 0; i < 16; ++i) + Write8(0x10); + } + + if (constOnes32_ == nullptr) { + constOnes32_ = AlignCode16(); + for (int i = 0; i < 4; ++i) + Write32(1); + } + + if (constOnes16_ == nullptr) { + constOnes16_ = AlignCode16(); + for (int i = 0; i < 8; ++i) + Write16(1); + } + + if (constUNext_ == nullptr) { + constUNext_ = AlignCode16(); + Write32(0); Write32(1); Write32(0); Write32(1); + } + + if (constVNext_ == nullptr) { + constVNext_ = AlignCode16(); + Write32(0); Write32(0); Write32(1); Write32(1); + } + + // These are unique to the sampler ID. + if (!id.hasAnyMips) { + constWidth256f_ = AlignCode16(); + float w256f = (1 << id.width0Shift) * 256; + Write32(*(uint32_t *)&w256f); Write32(*(uint32_t *)&w256f); + Write32(*(uint32_t *)&w256f); Write32(*(uint32_t *)&w256f); + + constHeight256f_ = AlignCode16(); + float h256f = (1 << id.height0Shift) * 256; + Write32(*(uint32_t *)&h256f); Write32(*(uint32_t *)&h256f); + Write32(*(uint32_t *)&h256f); Write32(*(uint32_t *)&h256f); + + constWidthMinus1i_ = AlignCode16(); + Write32((1 << id.width0Shift) - 1); Write32((1 << id.width0Shift) - 1); + Write32((1 << id.width0Shift) - 1); Write32((1 << id.width0Shift) - 1); + + constHeightMinus1i_ = AlignCode16(); + Write32((1 << id.height0Shift) - 1); Write32((1 << id.height0Shift) - 1); + Write32((1 << id.height0Shift) - 1); Write32((1 << id.height0Shift) - 1); + } else { + constWidth256f_ = nullptr; + constHeight256f_ = nullptr; + constWidthMinus1i_ = nullptr; + constHeightMinus1i_ = nullptr; + } +} + RegCache::Reg SamplerJitCache::GetZeroVec() { if (!regCache_.Has(RegCache::VEC_ZERO)) { X64Reg r = regCache_.Alloc(RegCache::VEC_ZERO);