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 \