diff --git a/UnleashedRecomp/gpu/rhi/plume_render_interface_types.h b/UnleashedRecomp/gpu/rhi/plume_render_interface_types.h index 89974ced..124daeff 100644 --- a/UnleashedRecomp/gpu/rhi/plume_render_interface_types.h +++ b/UnleashedRecomp/gpu/rhi/plume_render_interface_types.h @@ -475,6 +475,14 @@ namespace plume { typedef uint32_t RenderSampleCounts; + enum class RenderDeviceType { + UNKNOWN, + INTEGRATED, + DISCRETE, + VIRTUAL, + CPU + }; + // Global functions. constexpr uint32_t RenderFormatSize(RenderFormat format) { @@ -1754,6 +1762,7 @@ namespace plume { struct RenderDeviceDescription { std::string name = "Unknown"; + RenderDeviceType type = RenderDeviceType::UNKNOWN; uint32_t driverVersion = 0; uint64_t dedicatedVideoMemory = 0; }; diff --git a/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp b/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp index 8d7c2ca7..192c7ed5 100644 --- a/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp +++ b/UnleashedRecomp/gpu/rhi/plume_vulkan.cpp @@ -705,6 +705,21 @@ namespace plume { } } + static RenderDeviceType toDeviceType(VkPhysicalDeviceType type) { + switch (type) { + case VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU: + return RenderDeviceType::INTEGRATED; + case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU: + return RenderDeviceType::DISCRETE; + case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU: + return RenderDeviceType::VIRTUAL; + case VK_PHYSICAL_DEVICE_TYPE_CPU: + return RenderDeviceType::CPU; + default: + return RenderDeviceType::UNKNOWN; + } + } + static void setObjectName(VkDevice device, VkDebugReportObjectTypeEXT objectType, uint64_t object, const std::string &name) { # ifdef VULKAN_OBJECT_NAMES_ENABLED VkDebugMarkerObjectNameInfoEXT nameInfo = {}; @@ -3496,6 +3511,7 @@ namespace plume { if (preferOption) { physicalDevice = physicalDevices[i]; description.name = std::string(deviceProperties.deviceName); + description.type = toDeviceType(deviceProperties.deviceType); description.driverVersion = deviceProperties.driverVersion; currentDeviceTypeScore = deviceTypeScore; } diff --git a/UnleashedRecomp/gpu/video.cpp b/UnleashedRecomp/gpu/video.cpp index 3c640a61..cf29ea5c 100644 --- a/UnleashedRecomp/gpu/video.cpp +++ b/UnleashedRecomp/gpu/video.cpp @@ -1480,6 +1480,29 @@ static void BeginCommandList() commandList->setGraphicsDescriptorSet(g_samplerDescriptorSet.get(), 3); } +template +static void ApplyLowEndDefault(ConfigDef &configDef, T newDefault, bool &changed) +{ + if (configDef.IsDefaultValue() && !configDef.IsLoadedFromConfig) + { + configDef = newDefault; + changed = true; + } +} + +static void ApplyLowEndDefaults() +{ + bool changed = false; + + ApplyLowEndDefault(Config::AntiAliasing, EAntiAliasing::MSAA2x, changed); + ApplyLowEndDefault(Config::ShadowResolution, EShadowResolution::Original, changed); + ApplyLowEndDefault(Config::TransparencyAntiAliasing, false, changed); + + if (changed) { + Config::Save(); + } +} + bool Video::CreateHostDevice(const char *sdlVideoDriver) { for (uint32_t i = 0; i < 16; i++) @@ -1529,6 +1552,16 @@ bool Video::CreateHostDevice(const char *sdlVideoDriver) LoadEmbeddedResources(); + constexpr uint64_t LowEndMemoryLimit = 2048ULL * 1024ULL * 1024ULL; + RenderDeviceDescription deviceDescription = g_device->getDescription(); + bool lowEndType = deviceDescription.type != RenderDeviceType::UNKNOWN && deviceDescription.type != RenderDeviceType::DISCRETE; + bool lowEndMemory = deviceDescription.dedicatedVideoMemory < LowEndMemoryLimit; + if (lowEndType || lowEndMemory) + { + // Switch to low end defaults if a non-discrete GPU was detected or a low amount of VRAM was detected. + ApplyLowEndDefaults(); + } + g_capabilities = g_device->getCapabilities(); g_queue = g_device->createCommandQueue(RenderCommandListType::DIRECT);