Skip to content

Commit 78bcb27

Browse files
authored
Graphics API Selection
Originally: To change between DirectX 12 and Vulkan API: you'd need to go to `config.toml` 's GraphicsAPI to either D3D12 or Vulkan. Now, you can choose Graphics APIs directly through the In-Game Video Settings!
1 parent 3c1badf commit 78bcb27

7 files changed

Lines changed: 197 additions & 2 deletions

File tree

UnleashedRecomp/gpu/video.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,10 @@ static std::unique_ptr<RenderDevice> g_device;
299299

300300
static RenderDeviceCapabilities g_capabilities;
301301

302+
// Track the currently active graphics API for display purposes
303+
static EGraphicsAPI g_currentGraphicsAPI = EGraphicsAPI::Auto;
304+
static bool g_currentAPIChosenByAuto = false;
305+
302306
static constexpr size_t NUM_FRAMES = 2;
303307
static constexpr size_t NUM_QUERIES = 2;
304308

@@ -1673,6 +1677,12 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
16731677

16741678
#ifdef UNLEASHED_RECOMP_D3D12
16751679
g_vulkan = DetectWine() || Config::GraphicsAPI == EGraphicsAPI::Vulkan;
1680+
1681+
// Track if the Graphics API was chosen by Auto or manually selected
1682+
g_currentAPIChosenByAuto = (Config::GraphicsAPI == EGraphicsAPI::Auto);
1683+
#else
1684+
// For Vulkan-only builds, check if Auto was selected
1685+
g_currentAPIChosenByAuto = (Config::GraphicsAPI == EGraphicsAPI::Auto);
16761686
#endif
16771687

16781688
// Attempt to create the possible backends using a vector of function pointers. Whichever succeeds first will be the chosen API.
@@ -1765,6 +1775,12 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver, bool graphicsApiRetry)
17651775
}
17661776

17671777
g_vulkan = (interfaceFunction == CreateVulkanInterfaceWrapper);
1778+
1779+
// Track which graphics API is actually being used for display purposes
1780+
g_currentGraphicsAPI = g_vulkan ? EGraphicsAPI::Vulkan : EGraphicsAPI::D3D12;
1781+
#else
1782+
// For Vulkan-only builds
1783+
g_currentGraphicsAPI = EGraphicsAPI::Vulkan;
17681784
#endif
17691785
// Enable triangle strip workaround if we are on AMD, as there is a bug where
17701786
// restart indices cause triangles to be culled incorrectly. Converting them to degenerate triangles fixes it.
@@ -3062,6 +3078,16 @@ void Video::ComputeViewportDimensions()
30623078
AspectRatioPatches::ComputeOffsets();
30633079
}
30643080

3081+
EGraphicsAPI Video::GetCurrentGraphicsAPI()
3082+
{
3083+
return g_currentGraphicsAPI;
3084+
}
3085+
3086+
bool Video::IsCurrentAPIChosenByAuto()
3087+
{
3088+
return g_currentAPIChosenByAuto;
3089+
}
3090+
30653091
static RenderFormat ConvertFormat(uint32_t format)
30663092
{
30673093
switch (format)

UnleashedRecomp/gpu/video.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
//#define PSO_CACHING_CLEANUP
66

77
#include <plume_render_interface.h>
8+
#include <user/config.h>
89

910
#define D3DCLEAR_TARGET 0x1
1011
#define D3DCLEAR_ZBUFFER 0x10
@@ -24,6 +25,8 @@ struct Video
2425
static void StartPipelinePrecompilation();
2526
static void WaitForGPU();
2627
static void ComputeViewportDimensions();
28+
static EGraphicsAPI GetCurrentGraphicsAPI();
29+
static bool IsCurrentAPIChosenByAuto();
2730
};
2831

2932
struct GuestSamplerState

UnleashedRecomp/locale/config_locale.cpp

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -526,6 +526,82 @@ CONFIG_DEFINE_LOCALE(Monitor)
526526
{ ELanguage::Italian, { "Schermo", "Cambia lo schermo su cui visualizzare il gioco." } }
527527
};
528528

529+
// Japanese Notes: This localization should include furigana.
530+
CONFIG_DEFINE_LOCALE(GraphicsAPI)
531+
{
532+
{ ELanguage::English, { "Graphics API", "Change the graphics API used for rendering. \n\nWARNING: Changing graphics api requires game restart" } },
533+
{ ELanguage::Japanese, { "グラフィックAPI", "レンダリングに[使用:しよう]するグラフィックAPIを[変更:へんこう]します。\n\n[警告:けいこく]: グラフィックAPIの[変更:へんこう]にはゲームの[再起動:さいきどう]が[必要:ひつよう]です" } },
534+
{ ELanguage::German, { "Grafik-API", "Ändere die Grafik-API für das Rendering. \n\nWARNUNG: Das Ändern der Grafik-API erfordert einen Neustart des Spiels" } },
535+
{ ELanguage::French, { "API graphique", "Modifie l'API graphique utilisée pour le rendu. \n\nATTENTION : Changer l'API graphique nécessite un redémarrage du jeu" } },
536+
{ ELanguage::Spanish, { "API de gráficos", "Cambia la API de gráficos utilizada para el renderizado. \n\nADVERTENCIA: Cambiar la API de gráficos requiere reiniciar el juego" } },
537+
{ ELanguage::Italian, { "API grafica", "Modifica l'API grafica utilizzata per il rendering. \n\nATTENZIONE: Cambiare l'API grafica richiede il riavvio del gioco" } }
538+
};
539+
540+
// Japanese Notes: This localization should include furigana in its description.
541+
CONFIG_DEFINE_ENUM_LOCALE(EGraphicsAPI)
542+
{
543+
{
544+
ELanguage::English,
545+
{
546+
{ EGraphicsAPI::Auto, { "AUTO", "Automatically selects the best available graphics API for your system." } },
547+
#ifdef UNLEASHED_RECOMP_D3D12
548+
{ EGraphicsAPI::D3D12, { "DX12", "use Microsoft's DirectX 12 API for graphics rendering." } },
549+
#endif
550+
{ EGraphicsAPI::Vulkan, { "VULKAN", "use Khronos Group's Vulkan API for graphics rendering." } }
551+
}
552+
},
553+
{
554+
ELanguage::Japanese,
555+
{
556+
{ EGraphicsAPI::Auto, { "自動", "[自動:じどう]: [最適:さいてき]なグラフィックAPIを\u200B[自動的:じどうてき]に\u200B[選択:せんたく]します" } },
557+
#ifdef UNLEASHED_RECOMP_D3D12
558+
{ EGraphicsAPI::D3D12, { "DX12", "Microsoft の DirectX 12 API を\u200B[使用:しよう]してレンダリングします" } },
559+
#endif
560+
{ EGraphicsAPI::Vulkan, { "VULKAN", "Khronos Group の Vulkan API を\u200B[使用:しよう]してレンダリングします" } }
561+
}
562+
},
563+
{
564+
ELanguage::German,
565+
{
566+
{ EGraphicsAPI::Auto, { "AUTO", "Wählt automatisch die beste verfügbare Grafik-API aus." } },
567+
#ifdef UNLEASHED_RECOMP_D3D12
568+
{ EGraphicsAPI::D3D12, { "DX12", "Verwendet Microsofts DirectX 12 API für das Rendering." } },
569+
#endif
570+
{ EGraphicsAPI::Vulkan, { "VULKAN", "Verwendet die Khronos Group's Vulkan API für das Rendering." } }
571+
}
572+
},
573+
{
574+
ELanguage::French,
575+
{
576+
{ EGraphicsAPI::Auto, { "AUTO", "sélectionne automatiquement la meilleure API graphique disponible." } },
577+
#ifdef UNLEASHED_RECOMP_D3D12
578+
{ EGraphicsAPI::D3D12, { "DX12", "utilise l'API DirectX 12 de Microsoft pour le rendu." } },
579+
#endif
580+
{ EGraphicsAPI::Vulkan, { "VULKAN", "utilise l'API Vulkan du Khronos Group pour le rendu." } }
581+
}
582+
},
583+
{
584+
ELanguage::Spanish,
585+
{
586+
{ EGraphicsAPI::Auto, { "AUTO", "selecciona automáticamente la mejor API de gráficos disponible." } },
587+
#ifdef UNLEASHED_RECOMP_D3D12
588+
{ EGraphicsAPI::D3D12, { "DX12", "utiliza la API DirectX 12 de Microsoft para el renderizado." } },
589+
#endif
590+
{ EGraphicsAPI::Vulkan, { "VULKAN", "utiliza la API Vulkan del Khronos Group para el renderizado." } }
591+
}
592+
},
593+
{
594+
ELanguage::Italian,
595+
{
596+
{ EGraphicsAPI::Auto, { "AUTO", "seleziona automaticamente la migliore API grafica disponibile." } },
597+
#ifdef UNLEASHED_RECOMP_D3D12
598+
{ EGraphicsAPI::D3D12, { "DX12", "utilizza l'API DirectX 12 di Microsoft per il rendering." } },
599+
#endif
600+
{ EGraphicsAPI::Vulkan, { "VULKAN", "utilizza l'API Vulkan del Khronos Group per il rendering." } }
601+
}
602+
}
603+
};
604+
529605
// Japanese Notes: This localization should include furigana.
530606
CONFIG_DEFINE_LOCALE(AspectRatio)
531607
{

UnleashedRecomp/ui/options_menu.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1271,6 +1271,7 @@ static void DrawConfigOptions()
12711271
DrawConfigOption(rowCount++, yOffset, &Config::AspectRatio, true);
12721272
DrawConfigOption(rowCount++, yOffset, &Config::ResolutionScale, true, nullptr, 0.25f, 1.0f, 2.0f);
12731273
DrawConfigOption(rowCount++, yOffset, &Config::Fullscreen, true);
1274+
DrawConfigOption(rowCount++, yOffset, &Config::GraphicsAPI, true);
12741275
DrawConfigOption(rowCount++, yOffset, &Config::VSync, true);
12751276
DrawConfigOption(rowCount++, yOffset, &Config::FPS, true, nullptr, FPS_MIN, 120, FPS_MAX);
12761277
DrawConfigOption(rowCount++, yOffset, &Config::Brightness, true);

UnleashedRecomp/user/config.cpp

Lines changed: 77 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#include <os/logger.h>
33
#include <ui/game_window.h>
44
#include <user/paths.h>
5+
#include <gpu/video.h>
56

67
std::vector<IConfigDef*> g_configDefinitions;
78

@@ -407,6 +408,12 @@ CONFIG_DEFINE_ENUM_TEMPLATE(EUIAlignmentMode)
407408
extern CONFIG_ENUM_LOCALE(type) g_##type##_locale; \
408409
ConfigDef<type> Config::name{section, #name, &g_##name##_locale, defaultValue, &g_##type##_template, &g_##type##_locale};
409410

411+
#undef CONFIG_DEFINE_ENUM_LOCALISED_HIDDEN
412+
#define CONFIG_DEFINE_ENUM_LOCALISED_HIDDEN(section, type, name, defaultValue) \
413+
extern CONFIG_LOCALE g_##name##_locale; \
414+
extern CONFIG_ENUM_LOCALE(type) g_##type##_locale; \
415+
ConfigDef<type, true> Config::name{section, #name, &g_##name##_locale, defaultValue, &g_##type##_template, &g_##type##_locale};
416+
410417
#include "config_def.h"
411418

412419
// CONFIG_DEFINE
@@ -594,6 +601,58 @@ std::string ConfigDef<T, isHidden>::GetValueLocalised(ELanguage language) const
594601
return ToString(false);
595602
}
596603

604+
template<typename T, bool isHidden>
605+
bool ConfigDef<T, isHidden>::ShouldShowCurrentAPI() const
606+
{
607+
if constexpr (std::is_same_v<T, EGraphicsAPI>)
608+
{
609+
return Value == EGraphicsAPI::Auto &&
610+
Config::GraphicsAPI.Value == EGraphicsAPI::Auto &&
611+
Video::IsCurrentAPIChosenByAuto();
612+
}
613+
return false;
614+
}
615+
616+
template<typename T, bool isHidden>
617+
std::string ConfigDef<T, isHidden>::GetCurrentAPIName(const ELanguage* languages, CONFIG_ENUM_LOCALE(T)* locale) const
618+
{
619+
if constexpr (std::is_same_v<T, EGraphicsAPI>)
620+
{
621+
EGraphicsAPI currentAPI = Video::GetCurrentGraphicsAPI();
622+
if (currentAPI == EGraphicsAPI::Auto) return "";
623+
624+
for (auto langToFind : {languages[0], languages[1]})
625+
{
626+
auto langFindResult = locale->find(langToFind);
627+
if (langFindResult != locale->end())
628+
{
629+
auto apiFindResult = langFindResult->second.find(currentAPI);
630+
if (apiFindResult != langFindResult->second.end())
631+
{
632+
return std::get<0>(apiFindResult->second);
633+
}
634+
}
635+
if (langToFind == ELanguage::English) break;
636+
}
637+
}
638+
return "";
639+
}
640+
641+
template<typename T, bool isHidden>
642+
std::string ConfigDef<T, isHidden>::GetCurrentAPIText(ELanguage language, const std::string& apiName) const
643+
{
644+
switch (language)
645+
{
646+
case ELanguage::English: return " Currently using: " + apiName;
647+
case ELanguage::Japanese: return " [現在:げんざい][使用中:しようちゅう]: " + apiName;
648+
case ELanguage::German: return " Derzeit verwendet: " + apiName;
649+
case ELanguage::French: return " Actuellement utilisé : " + apiName;
650+
case ELanguage::Spanish: return " Actualmente usando: " + apiName;
651+
case ELanguage::Italian: return " Attualmente in uso: " + apiName;
652+
default: return " Currently using: " + apiName;
653+
}
654+
}
655+
597656
template<typename T, bool isHidden>
598657
std::string ConfigDef<T, isHidden>::GetValueDescription(ELanguage language) const
599658
{
@@ -620,7 +679,24 @@ std::string ConfigDef<T, isHidden>::GetValueDescription(ELanguage language) cons
620679
{
621680
auto valueFindResult = languageFindResult->second.find(Value);
622681
if (valueFindResult != languageFindResult->second.end())
623-
return std::get<1>(valueFindResult->second);
682+
{
683+
std::string description = std::get<1>(valueFindResult->second);
684+
685+
// Special case for EGraphicsAPI::Auto - append current API info
686+
if constexpr (std::is_same_v<T, EGraphicsAPI>)
687+
{
688+
if (ShouldShowCurrentAPI())
689+
{
690+
std::string currentAPIText = GetCurrentAPIName(languages, locale);
691+
if (!currentAPIText.empty())
692+
{
693+
description += GetCurrentAPIText(language, currentAPIText);
694+
}
695+
}
696+
}
697+
698+
return description;
699+
}
624700
}
625701

626702
if (languageToFind == ELanguage::English)

UnleashedRecomp/user/config.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,13 @@ class ConfigDef final : public IConfigDef
200200
void GetLocaleStrings(std::vector<std::string_view>& localeStrings) const override;
201201
void SnapToNearestAccessibleValue(bool searchUp) override;
202202

203+
private:
204+
// Graphics API dynamic text
205+
bool ShouldShowCurrentAPI() const;
206+
std::string GetCurrentAPIName(const ELanguage* languages, CONFIG_ENUM_LOCALE(T)* locale) const;
207+
std::string GetCurrentAPIText(ELanguage language, const std::string& apiName) const;
208+
209+
public:
203210
operator T() const
204211
{
205212
return Value;
@@ -219,6 +226,7 @@ class ConfigDef final : public IConfigDef
219226
#define CONFIG_DEFINE_LOCALISED(section, type, name, defaultValue) CONFIG_DECLARE(type, name)
220227
#define CONFIG_DEFINE_ENUM(section, type, name, defaultValue) CONFIG_DECLARE(type, name)
221228
#define CONFIG_DEFINE_ENUM_LOCALISED(section, type, name, defaultValue) CONFIG_DECLARE(type, name)
229+
#define CONFIG_DEFINE_ENUM_LOCALISED_HIDDEN(section, type, name, defaultValue) CONFIG_DECLARE_HIDDEN(type, name)
222230

223231
class Config
224232
{

UnleashedRecomp/user/config_def.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,12 @@ CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false);
4747
CONFIG_DEFINE_LOCALISED("Audio", bool, BattleTheme, true);
4848

4949
CONFIG_DEFINE("Video", std::string, GraphicsDevice, "");
50-
CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Auto);
50+
#ifdef UNLEASHED_RECOMP_D3D12
51+
CONFIG_DEFINE_ENUM_LOCALISED("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Auto);
52+
#else
53+
// Hide Graphics API setting for Vulkan-only builds
54+
CONFIG_DEFINE_ENUM_LOCALISED_HIDDEN("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Vulkan);
55+
#endif
5156
CONFIG_DEFINE("Video", int32_t, WindowX, WINDOWPOS_CENTRED);
5257
CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED);
5358
CONFIG_DEFINE_LOCALISED("Video", int32_t, WindowSize, -1);

0 commit comments

Comments
 (0)