mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-07-07 07:42:57 +12:00
Add optional texture hashing
This commit is contained in:
parent
6182d4cfe9
commit
a0aa11dac0
10 changed files with 106 additions and 54 deletions
|
@ -90,6 +90,7 @@ void EmulatorConfig::load() {
|
|||
|
||||
forceShadergenForLights = toml::find_or<toml::boolean>(gpu, "ForceShadergenForLighting", true);
|
||||
lightShadergenThreshold = toml::find_or<toml::integer>(gpu, "ShadergenLightThreshold", 1);
|
||||
hashTextures = toml::find_or<toml::boolean>(gpu, "HashTextures", hashTexturesDefault);
|
||||
enableRenderdoc = toml::find_or<toml::boolean>(gpu, "EnableRenderdoc", false);
|
||||
}
|
||||
}
|
||||
|
@ -101,7 +102,7 @@ void EmulatorConfig::load() {
|
|||
|
||||
auto dspCoreName = toml::find_or<std::string>(audio, "DSPEmulation", "HLE");
|
||||
dspType = Audio::DSPCore::typeFromString(dspCoreName);
|
||||
|
||||
|
||||
audioEnabled = toml::find_or<toml::boolean>(audio, "EnableAudio", audioEnabledDefault);
|
||||
aacEnabled = toml::find_or<toml::boolean>(audio, "EnableAACAudio", true);
|
||||
printDSPFirmware = toml::find_or<toml::boolean>(audio, "PrintDSPFirmware", false);
|
||||
|
@ -180,7 +181,7 @@ void EmulatorConfig::save() {
|
|||
data["Window"]["WindowPosY"] = windowSettings.y;
|
||||
data["Window"]["WindowWidth"] = windowSettings.width;
|
||||
data["Window"]["WindowHeight"] = windowSettings.height;
|
||||
|
||||
|
||||
data["GPU"]["EnableShaderJIT"] = shaderJitEnabled;
|
||||
data["GPU"]["Renderer"] = std::string(Renderer::typeToString(rendererType));
|
||||
data["GPU"]["EnableVSync"] = vsyncEnabled;
|
||||
|
@ -190,6 +191,7 @@ void EmulatorConfig::save() {
|
|||
data["GPU"]["ShadergenLightThreshold"] = lightShadergenThreshold;
|
||||
data["GPU"]["AccelerateShaders"] = accelerateShaders;
|
||||
data["GPU"]["EnableRenderdoc"] = enableRenderdoc;
|
||||
data["GPU"]["HashTextures"] = hashTextures;
|
||||
|
||||
data["Audio"]["DSPEmulation"] = std::string(Audio::DSPCore::typeToString(dspType));
|
||||
data["Audio"]["EnableAudio"] = audioEnabled;
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "PICA/float_types.hpp"
|
||||
#include "PICA/gpu.hpp"
|
||||
#include "PICA/pica_frag_uniforms.hpp"
|
||||
#include "PICA/pica_hash.hpp"
|
||||
#include "PICA/pica_simd.hpp"
|
||||
#include "PICA/regs.hpp"
|
||||
#include "PICA/shader_decompiler.hpp"
|
||||
|
@ -359,17 +360,29 @@ void RendererGL::bindTexturesToSlots() {
|
|||
const u32 width = getBits<16, 11>(dim);
|
||||
const u32 addr = (regs[ioBase + 4] & 0x0FFFFFFF) << 3;
|
||||
u32 format = regs[ioBase + (i == 0 ? 13 : 5)] & 0xF;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
|
||||
if (addr != 0) [[likely]] {
|
||||
Texture targetTex(addr, static_cast<PICA::TextureFmt>(format), width, height, config);
|
||||
|
||||
if (hashTextures) {
|
||||
const u8* startPointer = gpu.getPointerPhys<u8>(targetTex.location);
|
||||
const usize sizeInBytes = targetTex.sizeInBytes();
|
||||
|
||||
if (startPointer == nullptr || (sizeInBytes > 0 && gpu.getPointerPhys<u8>(targetTex.location + sizeInBytes - 1) == nullptr))
|
||||
[[unlikely]] {
|
||||
Helpers::warn("Out-of-bounds texture fetch");
|
||||
} else {
|
||||
targetTex.hash = PICAHash::computeHash((const char*)startPointer, sizeInBytes);
|
||||
}
|
||||
}
|
||||
|
||||
OpenGL::Texture tex = getTexture(targetTex);
|
||||
tex.bind();
|
||||
} else {
|
||||
// Mapping a texture from NULL. PICA seems to read the last sampled colour, but for now we will display a black texture instead since it is far easier.
|
||||
// Games that do this don't really care what it does, they just expect the PICA to not crash, since it doesn't have a PU/MMU and can do all sorts of
|
||||
// Weird invalid memory accesses without crashing
|
||||
// Mapping a texture from NULL. PICA seems to read the last sampled colour, but for now we will display a black texture instead since it
|
||||
// is far easier. Games that do this don't really care what it does, they just expect the PICA to not crash, since it doesn't have a
|
||||
// PU/MMU and can do all sorts of Weird invalid memory accesses without crashing
|
||||
blankTexture.bind();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
#undef NO
|
||||
|
||||
#include "PICA/gpu.hpp"
|
||||
#include "PICA/pica_hash.hpp"
|
||||
#include "SDL_metal.h"
|
||||
|
||||
using namespace PICA;
|
||||
|
@ -729,6 +730,19 @@ void RendererMTL::bindTexturesToSlots() {
|
|||
|
||||
if (addr != 0) [[likely]] {
|
||||
Metal::Texture targetTex(device, addr, static_cast<PICA::TextureFmt>(format), width, height, config);
|
||||
|
||||
if (hashTextures) {
|
||||
const u8* startPointer = gpu.getPointerPhys<u8>(targetTex.location);
|
||||
const usize sizeInBytes = targetTex.sizeInBytes();
|
||||
|
||||
if (startPointer == nullptr || (sizeInBytes > 0 && gpu.getPointerPhys<u8>(targetTex.location + sizeInBytes - 1) == nullptr))
|
||||
[[unlikely]] {
|
||||
Helpers::warn("Out-of-bounds texture fetch");
|
||||
} else {
|
||||
targetTex.hash = PICAHash::computeHash((const char*)startPointer, sizeInBytes);
|
||||
}
|
||||
}
|
||||
|
||||
auto tex = getTexture(targetTex);
|
||||
commandEncoder.setFragmentTexture(tex.texture, i);
|
||||
commandEncoder.setFragmentSamplerState(tex.sampler ? tex.sampler : nearestSampler, i);
|
||||
|
|
|
@ -32,18 +32,14 @@ Emulator::Emulator()
|
|||
dspService.setDSPCore(dsp.get());
|
||||
|
||||
audioDevice.init(dsp->getSamples());
|
||||
setAudioEnabled(config.audioEnabled);
|
||||
|
||||
if (Renderdoc::isSupported() && config.enableRenderdoc) {
|
||||
loadRenderdoc();
|
||||
}
|
||||
|
||||
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
|
||||
if (config.discordRpcEnabled) {
|
||||
discordRpc.init();
|
||||
updateDiscord();
|
||||
}
|
||||
#endif
|
||||
|
||||
reloadSettings();
|
||||
reset(ReloadOption::NoReload);
|
||||
}
|
||||
|
||||
|
@ -461,6 +457,8 @@ void Emulator::reloadSettings() {
|
|||
loadRenderdoc();
|
||||
}
|
||||
|
||||
gpu.getRenderer()->setHashTextures(config.hashTextures);
|
||||
|
||||
#ifdef PANDA3DS_ENABLE_DISCORD_RPC
|
||||
// Reload RPC setting if we're compiling with RPC support
|
||||
|
||||
|
|
|
@ -176,6 +176,9 @@ static void configInit() {
|
|||
{"panda3ds_use_ubershader", EmulatorConfig::ubershaderDefault ? "Use ubershaders (No stutter, maybe slower); enabled|disabled"
|
||||
: "Use ubershaders (No stutter, maybe slower); disabled|enabled"},
|
||||
{"panda3ds_use_vsync", "Enable VSync; enabled|disabled"},
|
||||
{"panda3ds_hash_textures", EmulatorConfig::hashTexturesDefault ? "Hash textures (Better graphics, maybe slower); enabled|disabled"
|
||||
: "Hash textures (Better graphics, maybe slower); disabled|enabled"},
|
||||
|
||||
{"panda3ds_system_language", "System language; En|Fr|Es|De|It|Pt|Nl|Ru|Ja|Zh|Ko|Tw"},
|
||||
{"panda3ds_dsp_emulation", "DSP emulation; HLE|LLE|Null"},
|
||||
{"panda3ds_use_audio", EmulatorConfig::audioEnabledDefault ? "Enable audio; enabled|disabled" : "Enable audio; disabled|enabled"},
|
||||
|
@ -216,6 +219,7 @@ static void configUpdate() {
|
|||
config.accurateShaderMul = fetchVariableBool("panda3ds_accurate_shader_mul", false);
|
||||
config.useUbershaders = fetchVariableBool("panda3ds_use_ubershader", EmulatorConfig::ubershaderDefault);
|
||||
config.accelerateShaders = fetchVariableBool("panda3ds_accelerate_shaders", EmulatorConfig::accelerateShadersDefault);
|
||||
config.hashTextures = fetchVariableBool("panda3ds_hash_textures", EmulatorConfig::hashTexturesDefault);
|
||||
|
||||
config.forceShadergenForLights = fetchVariableBool("panda3ds_ubershader_lighting_override", true);
|
||||
config.lightShadergenThreshold = fetchVariableRange("panda3ds_ubershader_lighting_override_threshold", 1, 8);
|
||||
|
|
|
@ -231,6 +231,11 @@ ConfigWindow::ConfigWindow(ConfigCallback configCallback, MainWindowCallback win
|
|||
connectCheckbox(accelerateShaders, config.accelerateShaders);
|
||||
gpuLayout->addRow(accelerateShaders);
|
||||
|
||||
QCheckBox* hashTextures = new QCheckBox(tr("Hash textures"));
|
||||
hashTextures->setToolTip(tr("Enable this to reduce texture mismatches at the cost of slightly lower performance"));
|
||||
connectCheckbox(hashTextures, config.hashTextures);
|
||||
gpuLayout->addRow(hashTextures);
|
||||
|
||||
QCheckBox* forceShadergenForLights = new QCheckBox(tr("Force shadergen when rendering lights"));
|
||||
connectCheckbox(forceShadergenForLights, config.forceShadergenForLights);
|
||||
gpuLayout->addRow(forceShadergenForLights);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue