mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-12 09:09:47 +12:00
Add shaderMode option and remove useUbershader option
This commit is contained in:
parent
91ebff1b5f
commit
1b779cafa1
8 changed files with 68 additions and 19 deletions
|
@ -13,17 +13,9 @@ struct EmulatorConfig {
|
||||||
static constexpr bool shaderJitDefault = false;
|
static constexpr bool shaderJitDefault = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// For now, use specialized shaders by default on MacOS as M1 drivers are buggy when using the ubershader, and on Android since mobile GPUs are
|
|
||||||
// horrible. On other platforms we default to ubershader + shadergen fallback for lights
|
|
||||||
#if defined(__ANDROID__) || defined(__APPLE__)
|
|
||||||
static constexpr bool ubershaderDefault = false;
|
|
||||||
#else
|
|
||||||
static constexpr bool ubershaderDefault = true;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bool shaderJitEnabled = shaderJitDefault;
|
bool shaderJitEnabled = shaderJitDefault;
|
||||||
bool discordRpcEnabled = false;
|
bool discordRpcEnabled = false;
|
||||||
bool useUbershaders = ubershaderDefault;
|
ShaderMode shaderMode = defaultShaderMode;
|
||||||
bool accurateShaderMul = false;
|
bool accurateShaderMul = false;
|
||||||
|
|
||||||
// Toggles whether to force shadergen when there's more than N lights active and we're using the ubershader, for better performance
|
// Toggles whether to force shadergen when there's more than N lights active and we're using the ubershader, for better performance
|
||||||
|
|
|
@ -21,6 +21,20 @@ enum class RendererType : s8 {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct EmulatorConfig;
|
struct EmulatorConfig;
|
||||||
|
enum class ShaderMode {
|
||||||
|
Specialized = 1,
|
||||||
|
Ubershader = 2,
|
||||||
|
Hybrid = 3,
|
||||||
|
};
|
||||||
|
|
||||||
|
// For now, use specialized shaders by default on MacOS as M1 drivers are buggy when using the ubershader, and on Android since mobile GPUs are
|
||||||
|
// horrible. On other platforms we default to ubershader + shadergen fallback for lights
|
||||||
|
#if defined(__ANDROID__) || defined(__APPLE__)
|
||||||
|
static constexpr ShaderMode defaultShaderMode = ShaderMode::Specialized;
|
||||||
|
#else
|
||||||
|
static constexpr ShaderMode defaultShaderMode = ShaderMode::Ubershader;
|
||||||
|
#endif
|
||||||
|
|
||||||
class GPU;
|
class GPU;
|
||||||
struct SDL_Window;
|
struct SDL_Window;
|
||||||
|
|
||||||
|
@ -56,6 +70,8 @@ class Renderer {
|
||||||
static constexpr u32 vertexBufferSize = 0x10000;
|
static constexpr u32 vertexBufferSize = 0x10000;
|
||||||
static std::optional<RendererType> typeFromString(std::string inString);
|
static std::optional<RendererType> typeFromString(std::string inString);
|
||||||
static const char* typeToString(RendererType rendererType);
|
static const char* typeToString(RendererType rendererType);
|
||||||
|
static std::optional<ShaderMode> shaderModeFromString(std::string inString);
|
||||||
|
static const char* shaderModeToString(ShaderMode shaderMode);
|
||||||
|
|
||||||
virtual void reset() = 0;
|
virtual void reset() = 0;
|
||||||
virtual void display() = 0; // Display the 3DS screen contents to the window
|
virtual void display() = 0; // Display the 3DS screen contents to the window
|
||||||
|
@ -77,7 +93,7 @@ class Renderer {
|
||||||
virtual std::string getUbershader() { return ""; }
|
virtual std::string getUbershader() { return ""; }
|
||||||
virtual void setUbershader(const std::string& shader) {}
|
virtual void setUbershader(const std::string& shader) {}
|
||||||
|
|
||||||
virtual void setUbershaderSetting(bool value) {}
|
virtual void setShaderMode(ShaderMode shaderMode) {}
|
||||||
|
|
||||||
// Functions for initializing the graphics context for the Qt frontend, where we don't have the convenience of SDL_Window
|
// Functions for initializing the graphics context for the Qt frontend, where we don't have the convenience of SDL_Window
|
||||||
#ifdef PANDA3DS_FRONTEND_QT
|
#ifdef PANDA3DS_FRONTEND_QT
|
||||||
|
|
|
@ -30,7 +30,7 @@ class RendererGL final : public Renderer {
|
||||||
|
|
||||||
OpenGL::VertexArray vao;
|
OpenGL::VertexArray vao;
|
||||||
OpenGL::VertexBuffer vbo;
|
OpenGL::VertexBuffer vbo;
|
||||||
bool enableUbershader = true;
|
ShaderMode shaderMode = defaultShaderMode;
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
struct {
|
struct {
|
||||||
|
@ -110,8 +110,8 @@ class RendererGL final : public Renderer {
|
||||||
virtual bool supportsShaderReload() override { return true; }
|
virtual bool supportsShaderReload() override { return true; }
|
||||||
virtual std::string getUbershader() override;
|
virtual std::string getUbershader() override;
|
||||||
virtual void setUbershader(const std::string& shader) override;
|
virtual void setUbershader(const std::string& shader) override;
|
||||||
|
|
||||||
virtual void setUbershaderSetting(bool value) override { enableUbershader = value; }
|
virtual void setShaderMode(ShaderMode value) override { shaderMode = value; }
|
||||||
|
|
||||||
std::optional<ColourBuffer> getColourBuffer(u32 addr, PICA::ColorFmt format, u32 width, u32 height, bool createIfnotFound = true);
|
std::optional<ColourBuffer> getColourBuffer(u32 addr, PICA::ColorFmt format, u32 width, u32 height, bool createIfnotFound = true);
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
|
#include "renderer.hpp"
|
||||||
#include "toml.hpp"
|
#include "toml.hpp"
|
||||||
|
|
||||||
// Largely based on https://github.com/nba-emu/NanoBoyAdvance/blob/master/src/platform/core/src/config.cpp
|
// Largely based on https://github.com/nba-emu/NanoBoyAdvance/blob/master/src/platform/core/src/config.cpp
|
||||||
|
@ -60,9 +61,18 @@ void EmulatorConfig::load() {
|
||||||
rendererType = RendererType::OpenGL;
|
rendererType = RendererType::OpenGL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto shaderModeName = toml::find_or<std::string>(gpu, "ShaderMode", Renderer::shaderModeToString(defaultShaderMode));
|
||||||
|
auto configShaderMode = Renderer::shaderModeFromString(shaderModeName);
|
||||||
|
|
||||||
|
if (configShaderMode.has_value()) {
|
||||||
|
shaderMode = configShaderMode.value();
|
||||||
|
} else {
|
||||||
|
Helpers::warn("Invalid shader mode specified: %s\n", shaderModeName.c_str());
|
||||||
|
shaderMode = defaultShaderMode;
|
||||||
|
}
|
||||||
|
|
||||||
shaderJitEnabled = toml::find_or<toml::boolean>(gpu, "EnableShaderJIT", shaderJitDefault);
|
shaderJitEnabled = toml::find_or<toml::boolean>(gpu, "EnableShaderJIT", shaderJitDefault);
|
||||||
vsyncEnabled = toml::find_or<toml::boolean>(gpu, "EnableVSync", true);
|
vsyncEnabled = toml::find_or<toml::boolean>(gpu, "EnableVSync", true);
|
||||||
useUbershaders = toml::find_or<toml::boolean>(gpu, "UseUbershaders", ubershaderDefault);
|
|
||||||
accurateShaderMul = toml::find_or<toml::boolean>(gpu, "AccurateShaderMultiplication", false);
|
accurateShaderMul = toml::find_or<toml::boolean>(gpu, "AccurateShaderMultiplication", false);
|
||||||
|
|
||||||
forceShadergenForLights = toml::find_or<toml::boolean>(gpu, "ForceShadergenForLighting", true);
|
forceShadergenForLights = toml::find_or<toml::boolean>(gpu, "ForceShadergenForLighting", true);
|
||||||
|
@ -132,7 +142,7 @@ void EmulatorConfig::save() {
|
||||||
data["GPU"]["Renderer"] = std::string(Renderer::typeToString(rendererType));
|
data["GPU"]["Renderer"] = std::string(Renderer::typeToString(rendererType));
|
||||||
data["GPU"]["EnableVSync"] = vsyncEnabled;
|
data["GPU"]["EnableVSync"] = vsyncEnabled;
|
||||||
data["GPU"]["AccurateShaderMultiplication"] = accurateShaderMul;
|
data["GPU"]["AccurateShaderMultiplication"] = accurateShaderMul;
|
||||||
data["GPU"]["UseUbershaders"] = useUbershaders;
|
data["GPU"]["ShaderMode"] = std::string(Renderer::shaderModeToString(shaderMode));
|
||||||
data["GPU"]["ForceShadergenForLighting"] = forceShadergenForLights;
|
data["GPU"]["ForceShadergenForLighting"] = forceShadergenForLights;
|
||||||
data["GPU"]["ShadergenLightThreshold"] = lightShadergenThreshold;
|
data["GPU"]["ShadergenLightThreshold"] = lightShadergenThreshold;
|
||||||
|
|
||||||
|
|
|
@ -117,7 +117,7 @@ void GPU::reset() {
|
||||||
externalRegs[Framebuffer1Config] = static_cast<u32>(PICA::ColorFmt::RGB8);
|
externalRegs[Framebuffer1Config] = static_cast<u32>(PICA::ColorFmt::RGB8);
|
||||||
externalRegs[Framebuffer1Select] = 0;
|
externalRegs[Framebuffer1Select] = 0;
|
||||||
|
|
||||||
renderer->setUbershaderSetting(config.useUbershaders);
|
renderer->setShaderMode(config.shaderMode);
|
||||||
renderer->reset();
|
renderer->reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -414,8 +414,10 @@ void RendererGL::drawVertices(PICA::PrimType primType, std::span<const Vertex> v
|
||||||
OpenGL::Triangle,
|
OpenGL::Triangle,
|
||||||
};
|
};
|
||||||
|
|
||||||
bool usingUbershader = enableUbershader;
|
bool usingUbershader = false;
|
||||||
if (usingUbershader) {
|
if (shaderMode == ShaderMode::Ubershader) {
|
||||||
|
usingUbershader = true;
|
||||||
|
|
||||||
const bool lightsEnabled = (regs[InternalRegs::LightingEnable] & 1) != 0;
|
const bool lightsEnabled = (regs[InternalRegs::LightingEnable] & 1) != 0;
|
||||||
const uint lightCount = (regs[InternalRegs::LightNumber] & 0x7) + 1;
|
const uint lightCount = (regs[InternalRegs::LightNumber] & 0x7) + 1;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
#include <emulator.hpp>
|
#include <emulator.hpp>
|
||||||
#include <renderer_gl/renderer_gl.hpp>
|
#include <renderer_gl/renderer_gl.hpp>
|
||||||
|
#include "renderer.hpp"
|
||||||
|
|
||||||
static retro_environment_t envCallbacks;
|
static retro_environment_t envCallbacks;
|
||||||
static retro_video_refresh_t videoCallbacks;
|
static retro_video_refresh_t videoCallbacks;
|
||||||
|
@ -179,9 +180,10 @@ static void configUpdate() {
|
||||||
config.sdCardInserted = FetchVariableBool("panda3ds_use_virtual_sd", true);
|
config.sdCardInserted = FetchVariableBool("panda3ds_use_virtual_sd", true);
|
||||||
config.sdWriteProtected = FetchVariableBool("panda3ds_write_protect_virtual_sd", false);
|
config.sdWriteProtected = FetchVariableBool("panda3ds_write_protect_virtual_sd", false);
|
||||||
config.accurateShaderMul = FetchVariableBool("panda3ds_accurate_shader_mul", false);
|
config.accurateShaderMul = FetchVariableBool("panda3ds_accurate_shader_mul", false);
|
||||||
config.useUbershaders = FetchVariableBool("panda3ds_use_ubershader", true);
|
|
||||||
config.forceShadergenForLights = FetchVariableBool("panda3ds_ubershader_lighting_override", true);
|
config.forceShadergenForLights = FetchVariableBool("panda3ds_ubershader_lighting_override", true);
|
||||||
config.lightShadergenThreshold = std::clamp(std::stoi(FetchVariable("panda3ds_ubershader_lighting_override_threshold", "1")), 1, 8);
|
config.lightShadergenThreshold = std::clamp(std::stoi(FetchVariable("panda3ds_ubershader_lighting_override_threshold", "1")), 1, 8);
|
||||||
|
// TODO: be able to use hybrid mode
|
||||||
|
config.shaderMode = FetchVariableBool("panda3ds_use_ubershader", defaultShaderMode == ShaderMode::Ubershader) ? ShaderMode::Ubershader : ShaderMode::Specialized;
|
||||||
config.discordRpcEnabled = false;
|
config.discordRpcEnabled = false;
|
||||||
|
|
||||||
config.save();
|
config.save();
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <optional>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
|
||||||
Renderer::Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
Renderer::Renderer(GPU& gpu, const std::array<u32, regNum>& internalRegs, const std::array<u32, extRegNum>& externalRegs)
|
||||||
|
@ -36,4 +37,30 @@ const char* Renderer::typeToString(RendererType rendererType) {
|
||||||
case RendererType::Software: return "software";
|
case RendererType::Software: return "software";
|
||||||
default: return "Invalid";
|
default: return "Invalid";
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<ShaderMode> Renderer::shaderModeFromString(std::string inString) {
|
||||||
|
// Transform to lower-case to make the setting case-insensitive
|
||||||
|
std::transform(inString.begin(), inString.end(), inString.begin(), [](unsigned char c) { return std::tolower(c); });
|
||||||
|
|
||||||
|
static const std::unordered_map<std::string, ShaderMode> map = {
|
||||||
|
{"specialized", ShaderMode::Specialized}, {"special", ShaderMode::Specialized},
|
||||||
|
{"ubershader", ShaderMode::Ubershader}, {"uber", ShaderMode::Ubershader},
|
||||||
|
{"hybrid", ShaderMode::Hybrid}, {"threaded", ShaderMode::Hybrid}, {"i hate opengl context creation", ShaderMode::Hybrid},
|
||||||
|
};
|
||||||
|
|
||||||
|
if (auto search = map.find(inString); search != map.end()) {
|
||||||
|
return search->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* Renderer::shaderModeToString(ShaderMode shaderMode) {
|
||||||
|
switch (shaderMode) {
|
||||||
|
case ShaderMode::Specialized: return "specialized";
|
||||||
|
case ShaderMode::Ubershader: return "ubershader";
|
||||||
|
case ShaderMode::Hybrid: return "hybrid";
|
||||||
|
default: return "Invalid";
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Add table
Reference in a new issue