diff --git a/CMakeLists.txt b/CMakeLists.txt index 9206a69bd9..b3b33d1f22 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1393,6 +1393,7 @@ list(APPEND CoreExtra Core/MIPS/x86/RegCacheFPU.cpp Core/MIPS/x86/RegCacheFPU.h GPU/Common/VertexDecoderX86.cpp + GPU/Software/DrawPixelX86.cpp GPU/Software/SamplerX86.cpp ) diff --git a/GPU/GPU.vcxproj b/GPU/GPU.vcxproj index 3360496097..9ef8aa4f24 100644 --- a/GPU/GPU.vcxproj +++ b/GPU/GPU.vcxproj @@ -631,6 +631,7 @@ + diff --git a/GPU/GPU.vcxproj.filters b/GPU/GPU.vcxproj.filters index c8aaf5354c..0f3248dc0b 100644 --- a/GPU/GPU.vcxproj.filters +++ b/GPU/GPU.vcxproj.filters @@ -542,5 +542,8 @@ Software + + Software + \ No newline at end of file diff --git a/GPU/Software/DrawPixel.cpp b/GPU/Software/DrawPixel.cpp index 00beb3e7f3..f7f6389bc2 100644 --- a/GPU/Software/DrawPixel.cpp +++ b/GPU/Software/DrawPixel.cpp @@ -15,6 +15,7 @@ // Official git repository and contact information can be found at // https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. +#include #include "Common/Data/Convert/ColorConv.h" #include "GPU/GPUState.h" #include "GPU/Software/DrawPixel.h" @@ -26,14 +27,25 @@ using namespace Math3D; namespace Rasterizer { +std::mutex jitCacheLock; +PixelJitCache *jitCache = nullptr; + void Init() { + jitCache = new PixelJitCache(); } void Shutdown() { + delete jitCache; + jitCache = nullptr; } bool DescribeCodePtr(const u8 *ptr, std::string &name) { - return false; + if (!jitCache->IsInSpace(ptr)) { + return false; + } + + name = jitCache->DescribeCodePtr(ptr); + return true; } static inline u8 GetPixelStencil(GEBufferFormat fmt, int x, int y) { @@ -462,6 +474,11 @@ inline void DrawSinglePixel(int x, int y, int z, int fog, const Vec4 &color } SingleFunc GetSingleFunc(const PixelFuncID &id) { + SingleFunc jitted = jitCache->GetSingle(id); + if (jitted) { + return jitted; + } + if (id.clearMode) { switch (id.fbFormat) { case GE_FORMAT_565: @@ -488,4 +505,67 @@ SingleFunc GetSingleFunc(const PixelFuncID &id) { return nullptr; } +PixelJitCache::PixelJitCache() +#if PPSSPP_ARCH(ARM64) + : fp(this) +#endif +{ + AllocCodeSpace(1024 * 256 * 4); + + // Add some random code to "help" MSVC's buggy disassembler :( +#if defined(_WIN32) && (PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64)) && !PPSSPP_PLATFORM(UWP) + using namespace Gen; + for (int i = 0; i < 100; i++) { + MOV(32, R(EAX), R(EBX)); + RET(); + } +#elif PPSSPP_ARCH(ARM) + BKPT(0); + BKPT(0); +#endif +} + +void PixelJitCache::Clear() { + ClearCodeSpace(0); + cache_.clear(); + addresses_.clear(); +} + +std::string PixelJitCache::DescribeCodePtr(const u8 *ptr) { + ptrdiff_t dist = 0x7FFFFFFF; + PixelFuncID found{}; + for (const auto &it : addresses_) { + ptrdiff_t it_dist = ptr - it.second; + if (it_dist >= 0 && it_dist < dist) { + found = it.first; + dist = it_dist; + } + } + + return DescribePixelFuncID(found); +} + +SingleFunc PixelJitCache::GetSingle(const PixelFuncID &id) { + std::lock_guard guard(jitCacheLock); + + auto it = cache_.find(id); + if (it != cache_.end()) { + return it->second; + } + + // TODO: What should be the min size? Can we even hit this? + if (GetSpaceLeft() < 65536) { + Clear(); + } + +#if PPSSPP_ARCH(AMD64) && !PPSSPP_PLATFORM(UWP) + addresses_[id] = GetCodePointer(); + SingleFunc func = CompileSingle(id); + cache_[id] = func; + return func; +#else + return nullptr; +#endif +} + }; diff --git a/GPU/Software/DrawPixel.h b/GPU/Software/DrawPixel.h index 26d50da2ce..ba36d8e005 100644 --- a/GPU/Software/DrawPixel.h +++ b/GPU/Software/DrawPixel.h @@ -45,4 +45,35 @@ void Shutdown(); bool DescribeCodePtr(const u8 *ptr, std::string &name); +#if PPSSPP_ARCH(ARM) +class PixelJitCache : public ArmGen::ARMXCodeBlock { +#elif PPSSPP_ARCH(ARM64) +class PixelJitCache : public Arm64Gen::ARM64CodeBlock { +#elif PPSSPP_ARCH(X86) || PPSSPP_ARCH(AMD64) +class PixelJitCache : public Gen::XCodeBlock { +#elif PPSSPP_ARCH(MIPS) +class PixelJitCache : public MIPSGen::MIPSCodeBlock { +#else +class PixelJitCache : public FakeGen::FakeXCodeBlock { +#endif +public: + PixelJitCache(); + + // Returns a pointer to the code to run. + SingleFunc GetSingle(const PixelFuncID &id); + void Clear(); + + std::string DescribeCodePtr(const u8 *ptr); + +private: + SingleFunc CompileSingle(const PixelFuncID &id); + +#if PPSSPP_ARCH(ARM64) + Arm64Gen::ARM64FloatEmitter fp; +#endif + + std::unordered_map cache_; + std::unordered_map addresses_; +}; + }; diff --git a/GPU/Software/DrawPixelX86.cpp b/GPU/Software/DrawPixelX86.cpp new file mode 100644 index 0000000000..e1449b4dfb --- /dev/null +++ b/GPU/Software/DrawPixelX86.cpp @@ -0,0 +1,38 @@ +// Copyright (c) 2017- PPSSPP Project. + +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, version 2.0 or later versions. + +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License 2.0 for more details. + +// A copy of the GPL 2.0 should have been included with the program. +// If not, see http://www.gnu.org/licenses/ + +// Official git repository and contact information can be found at +// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/. + +#include "ppsspp_config.h" +#if PPSSPP_ARCH(AMD64) + +#include +#include "Common/x64Emitter.h" +#include "Common/CPUDetect.h" +#include "GPU/GPUState.h" +#include "GPU/Software/DrawPixel.h" +#include "GPU/ge_constants.h" + +using namespace Gen; + +namespace Rasterizer { + +SingleFunc PixelJitCache::CompileSingle(const PixelFuncID &id) { + return nullptr; +} + +}; + +#endif diff --git a/android/jni/Android.mk b/android/jni/Android.mk index 8896f6fda3..a3039ecd41 100644 --- a/android/jni/Android.mk +++ b/android/jni/Android.mk @@ -30,6 +30,7 @@ ARCH_FILES := \ $(SRC)/Core/MIPS/x86/RegCache.cpp \ $(SRC)/Core/MIPS/x86/RegCacheFPU.cpp \ $(SRC)/GPU/Common/VertexDecoderX86.cpp \ + $(SRC)/GPU/Software/DrawPixelX86.cpp \ $(SRC)/GPU/Software/SamplerX86.cpp endif @@ -52,6 +53,7 @@ ARCH_FILES := \ $(SRC)/Core/MIPS/x86/RegCache.cpp \ $(SRC)/Core/MIPS/x86/RegCacheFPU.cpp \ $(SRC)/GPU/Common/VertexDecoderX86.cpp \ + $(SRC)/GPU/Software/DrawPixelX86.cpp \ $(SRC)/GPU/Software/SamplerX86.cpp endif diff --git a/libretro/Makefile.common b/libretro/Makefile.common index 580cf1b47d..fd8048c7ee 100644 --- a/libretro/Makefile.common +++ b/libretro/Makefile.common @@ -679,7 +679,7 @@ ifeq ($(WITH_DYNAREC),1) CPUFLAGS += -m32 endif endif - SOURCES_CXX += $(GPUDIR)/Software/SamplerX86.cpp + SOURCES_CXX += $(GPUDIR)/Software/DrawPixelX86.cpp $(GPUDIR)/Software/SamplerX86.cpp SOURCES_CXX += $(COMMONDIR)/x64Emitter.cpp \ $(COMMONDIR)/x64Analyzer.cpp \ $(COMMONDIR)/ABI.cpp \