permet escollir driver de gpu o no escollir-ne cap

This commit is contained in:
2026-03-28 01:14:41 +01:00
parent 02c1bf647e
commit 348a76090b
8 changed files with 90 additions and 1 deletions

View File

@@ -578,6 +578,7 @@ void Screen::initShaders() {
if (!shader_backend_) {
shader_backend_ = std::make_unique<Rendering::SDL3GPUShader>();
shader_backend_->setPreferredDriver(Options::video.gpu_preferred_driver);
}
shader_backend_->init(window_, tex, "", "");
gpu_driver_ = shader_backend_->getDriverName();

View File

@@ -74,6 +74,7 @@ class Screen {
auto getBorderSurface() -> std::shared_ptr<Surface>;
[[nodiscard]] auto getText() const -> std::shared_ptr<Text> { return text_; }
[[nodiscard]] auto getGameSurfaceDstRect() const -> SDL_FRect { return game_surface_dstrect_; }
[[nodiscard]] auto getGPUDriver() const -> const std::string& { return gpu_driver_; }
private:
// Estructuras

View File

@@ -269,13 +269,23 @@ namespace Rendering {
// ----------------------------------------------------------------
// 1. Create GPU device (solo si no existe ya)
// ----------------------------------------------------------------
if (preferred_driver_ == "none") {
SDL_Log("SDL3GPUShader: GPU disabled by config, using SDL_Renderer fallback");
driver_name_ = "none";
return false;
}
if (device_ == nullptr) {
#ifdef __APPLE__
const SDL_GPUShaderFormat PREFERRED = SDL_GPU_SHADERFORMAT_MSL | SDL_GPU_SHADERFORMAT_METALLIB;
#else
const SDL_GPUShaderFormat PREFERRED = SDL_GPU_SHADERFORMAT_SPIRV;
#endif
device_ = SDL_CreateGPUDevice(PREFERRED, false, nullptr);
const char* preferred = preferred_driver_.empty() ? nullptr : preferred_driver_.c_str();
device_ = SDL_CreateGPUDevice(PREFERRED, false, preferred);
if (device_ == nullptr && preferred != nullptr) {
SDL_Log("SDL3GPUShader: driver '%s' not available, falling back to auto", preferred);
device_ = SDL_CreateGPUDevice(PREFERRED, false, nullptr);
}
if (device_ == nullptr) {
SDL_Log("SDL3GPUShader: SDL_CreateGPUDevice failed: %s", SDL_GetError());
return false;

View File

@@ -58,6 +58,9 @@ namespace Rendering {
[[nodiscard]] auto isHardwareAccelerated() const -> bool override { return is_initialized_; }
[[nodiscard]] auto getDriverName() const -> std::string override { return driver_name_; }
// Establece el driver GPU preferido (vacío = auto). Debe llamarse antes de init().
void setPreferredDriver(const std::string& driver) override { preferred_driver_ = driver; }
// Sube píxeles ARGB8888 desde CPU; llamado antes de render()
void uploadPixels(const Uint32* pixels, int width, int height) override;
@@ -121,6 +124,7 @@ namespace Rendering {
int oversample_ = 1; // SS on/off (1 = off, >1 = on)
int downscale_algo_ = 1; // 0 = bilinear legacy, 1 = Lanczos2, 2 = Lanczos3
std::string driver_name_;
std::string preferred_driver_; // Driver preferido; vacío = auto (SDL elige)
bool is_initialized_ = false;
bool vsync_ = true;
bool integer_scale_ = false;

View File

@@ -116,6 +116,12 @@ namespace Rendering {
* @return Cadena vacía si no disponible
*/
[[nodiscard]] virtual auto getDriverName() const -> std::string { return {}; }
/**
* @brief Establece el driver GPU preferido antes de init().
* Vacío = selección automática de SDL. Implementado en SDL3GPUShader.
*/
virtual void setPreferredDriver(const std::string& /*driver*/) {}
};
} // namespace Rendering

View File

@@ -404,6 +404,14 @@ namespace Options {
}
}
if (vid.contains("gpu_preferred_driver")) {
try {
video.gpu_preferred_driver = vid["gpu_preferred_driver"].get_value<std::string>();
} catch (...) {
video.gpu_preferred_driver = "";
}
}
loadPaletteFromYaml(vid);
}
@@ -662,6 +670,7 @@ namespace Options {
file << " keep_aspect: " << (video.keep_aspect ? "true" : "false") << "\n";
file << " linear_upscale: " << (video.linear_upscale ? "true" : "false") << "\n";
file << " downscale_algo: " << video.downscale_algo << " # 0=bilinear, 1=Lanczos2, 2=Lanczos3\n";
file << " gpu_preferred_driver: \"" << video.gpu_preferred_driver << "\" # GPU driver (empty = auto)\n";
file << " palette: " << video.palette << "\n";
file << " border:\n";
file << " enabled: " << (video.border.enabled ? "true" : "false") << "\n";

View File

@@ -89,6 +89,7 @@ namespace Options {
Border border{}; // Borde de la pantalla
std::string palette{Defaults::Video::PALETTE_NAME}; // Paleta de colores a usar en el juego
std::string info; // Información sobre el modo de vídeo
std::string gpu_preferred_driver; // Driver GPU preferido; vacío = auto. Aplica en el próximo arranque.
};
// Estructura para las opciones de musica

View File

@@ -72,6 +72,7 @@ static void printHelp() {
SDL_Log(" UPSCALE [NEAREST|LINEAR] SS upscale filter (toggle if no arg)");
SDL_Log(" DOWNSCALE [BILINEAR|LANCZOS2|LANCZOS3] SS downscale algorithm");
SDL_Log(" VSYNC [ON|OFF] Vertical sync");
SDL_Log(" DRIVER [LIST|AUTO|NONE|<name>] GPU driver (restart to apply)");
SDL_Log(" PALETTE [NEXT|PREV] Color palette (F5/F6)");
#ifdef _DEBUG
SDL_Log(" DEBUG Toggle debug overlay (F12)");
@@ -215,6 +216,62 @@ static const std::vector<ConsoleCommand> COMMANDS = {
Options::video.vertical_sync,
Screen::get()->toggleVSync())},
// DRIVER [LIST|AUTO|<nombre>] — Driver GPU (aplica en el próximo arranque)
{.keyword = "DRIVER", .execute = [](const std::vector<std::string>& args) -> std::string {
// Sin argumentos: muestra el driver activo (permitido en kiosk)
if (args.empty()) {
const auto& driver = Screen::get()->getGPUDriver();
return "GPU: " + (driver.empty() ? std::string("sdl") : driver);
}
// LIST: lista drivers disponibles marcando el activo con * (permitido en kiosk)
if (args[0] == "LIST") {
const int COUNT = SDL_GetNumGPUDrivers();
if (COUNT <= 0) { return "No GPU drivers found"; }
const std::string& active = Screen::get()->getGPUDriver();
std::string result = "Drivers:";
for (int i = 0; i < COUNT; ++i) {
const char* name = SDL_GetGPUDriver(i);
if (name != nullptr) {
result += ' ';
result += name;
if (active == name) { result += '*'; }
}
}
SDL_Log("SDL GPU drivers: %s", result.c_str());
return result;
}
// Cambiar driver: bloqueado en kiosk salvo PLEASE
const bool HAS_PLEASE = std::ranges::find(args, std::string("PLEASE")) != args.end();
if (Options::kiosk.enabled && !HAS_PLEASE) {
return "Not allowed in kiosk mode";
}
if (args[0] == "AUTO") {
Options::video.gpu_preferred_driver.clear();
Options::saveToFile();
return "Driver: auto (restart)";
}
if (args[0] == "NONE") {
Options::video.gpu_preferred_driver = "none";
Options::saveToFile();
return "Driver: none (SDL fallback, restart)";
}
std::string driver_lower = args[0];
std::ranges::transform(driver_lower, driver_lower.begin(), ::tolower);
// Validar que el nombre existe en la lista de drivers SDL
const int COUNT = SDL_GetNumGPUDrivers();
bool found = false;
for (int i = 0; i < COUNT && !found; ++i) {
const char* name = SDL_GetGPUDriver(i);
if (name != nullptr && driver_lower == name) { found = true; }
}
if (!found) {
return "Unknown driver: " + driver_lower + ". Use DRIVER LIST or NONE";
}
Options::video.gpu_preferred_driver = driver_lower;
Options::saveToFile();
return "Driver: " + driver_lower + " (restart)";
}},
// PALETTE NEXT/PREV — Paleta de colores (F5/F6)
{.keyword = "PALETTE", .execute = [](const std::vector<std::string>& args) -> std::string {
if (args.empty()) { return "Usage: PALETTE [NEXT|PREV]"; }