diff --git a/UnleashedRecomp/gpu/rhi/plume_d3d12.cpp b/UnleashedRecomp/gpu/rhi/plume_d3d12.cpp index 6b9eeea5..395630c2 100644 --- a/UnleashedRecomp/gpu/rhi/plume_d3d12.cpp +++ b/UnleashedRecomp/gpu/rhi/plume_d3d12.cpp @@ -3433,6 +3433,13 @@ namespace plume { capabilities.uma = uma; description.name = deviceName; description.dedicatedVideoMemory = adapterDesc.DedicatedVideoMemory; + description.vendor = RenderDeviceVendor(adapterDesc.VendorId); + + LARGE_INTEGER adapterVersion = {}; + res = adapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &adapterVersion); + if (SUCCEEDED(res)) { + description.driverVersion = adapterVersion.QuadPart; + } if (preferUserChoice) { break; diff --git a/UnleashedRecomp/gpu/rhi/plume_render_interface_types.h b/UnleashedRecomp/gpu/rhi/plume_render_interface_types.h index 36a9c995..b0be1592 100644 --- a/UnleashedRecomp/gpu/rhi/plume_render_interface_types.h +++ b/UnleashedRecomp/gpu/rhi/plume_render_interface_types.h @@ -73,6 +73,13 @@ namespace plume { // Enums. + enum class RenderDeviceVendor { + UNKNOWN = 0x0, + AMD = 0x1002, + NVIDIA = 0x10DE, + INTEL = 0x8086 + }; + enum class RenderFormat { UNKNOWN, R32G32B32A32_TYPELESS, @@ -1770,7 +1777,8 @@ namespace plume { struct RenderDeviceDescription { std::string name = "Unknown"; RenderDeviceType type = RenderDeviceType::UNKNOWN; - uint32_t driverVersion = 0; + RenderDeviceVendor vendor = RenderDeviceVendor::UNKNOWN; + uint64_t driverVersion = 0; uint64_t dedicatedVideoMemory = 0; }; diff --git a/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp b/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp index a95df555..a181eab3 100644 --- a/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp +++ b/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp @@ -3604,6 +3604,7 @@ namespace plume { description.name = deviceName; description.type = toDeviceType(deviceProperties.deviceType); description.driverVersion = deviceProperties.driverVersion; + description.vendor = RenderDeviceVendor(deviceProperties.vendorID); currentDeviceTypeScore = deviceTypeScore; if (preferUserChoice) { diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 0f8d49a0..c5f4e11c 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -1675,7 +1675,26 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver) g_device = g_interface->createDevice(Config::GraphicsDevice); if (g_device != nullptr) { + const RenderDeviceDescription &deviceDescription = g_device->getDescription(); + #ifdef UNLEASHED_RECOMP_D3D12 + if (interfaceFunction == CreateD3D12Interface) + { + if (deviceDescription.vendor == RenderDeviceVendor::AMD) + { + // AMD Drivers before this version have a known issue where MSAA resolve targets will fail to work correctly. + // If no specific graphics API was selected, we silently destroy this one and move to the next option as it'll + // just work incorrectly otherwise and result in visual glitches and 3D rendering not working in general. + constexpr uint64_t MinimumAMDDriverVersion = 0x1F00005DC2005CULL; // 31.0.24002.92 + if ((Config::GraphicsAPI == EGraphicsAPI::Auto) && (deviceDescription.driverVersion < MinimumAMDDriverVersion)) + { + g_device.reset(); + g_interface.reset(); + continue; + } + } + } + g_vulkan = (interfaceFunction == CreateVulkanInterfaceWrapper); #endif break; diff --git a/UnleashedRecomp/user/config.cpp b/UnleashedRecomp/user/config.cpp index 918c7b6d..c506564f 100644 --- a/UnleashedRecomp/user/config.cpp +++ b/UnleashedRecomp/user/config.cpp @@ -302,6 +302,7 @@ CONFIG_DEFINE_ENUM_TEMPLATE(EVoiceLanguage) CONFIG_DEFINE_ENUM_TEMPLATE(EGraphicsAPI) { + { "Auto", EGraphicsAPI::Auto }, #ifdef UNLEASHED_RECOMP_D3D12 { "D3D12", EGraphicsAPI::D3D12 }, #endif diff --git a/UnleashedRecomp/user/config.h b/UnleashedRecomp/user/config.h index b944f691..05fe7229 100644 --- a/UnleashedRecomp/user/config.h +++ b/UnleashedRecomp/user/config.h @@ -62,6 +62,7 @@ enum class EChannelConfiguration : uint32_t enum class EGraphicsAPI : uint32_t { + Auto, #ifdef UNLEASHED_RECOMP_D3D12 D3D12, #endif diff --git a/UnleashedRecomp/user/config_def.h b/UnleashedRecomp/user/config_def.h index 50d9be5f..956614df 100644 --- a/UnleashedRecomp/user/config_def.h +++ b/UnleashedRecomp/user/config_def.h @@ -47,13 +47,7 @@ CONFIG_DEFINE_LOCALISED("Audio", bool, MusicAttenuation, false); CONFIG_DEFINE_LOCALISED("Audio", bool, BattleTheme, true); CONFIG_DEFINE("Video", std::string, GraphicsDevice, ""); - -#ifdef UNLEASHED_RECOMP_D3D12 -CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::D3D12); -#else -CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Vulkan); -#endif - +CONFIG_DEFINE_ENUM("Video", EGraphicsAPI, GraphicsAPI, EGraphicsAPI::Auto); CONFIG_DEFINE("Video", int32_t, WindowX, WINDOWPOS_CENTRED); CONFIG_DEFINE("Video", int32_t, WindowY, WINDOWPOS_CENTRED); CONFIG_DEFINE_LOCALISED("Video", int32_t, WindowSize, -1);