1
0
mirror of https://github.com/doitsujin/dxvk.git synced 2024-12-11 19:24:11 +01:00

[dxgi] Under-report iGPU memory if dGPUs are present

Should help games pick the correct GPU on setups with integrated graphics.
This commit is contained in:
Philip Rebohle 2024-08-19 19:06:52 +02:00 committed by Philip Rebohle
parent 02d8fa593b
commit be45907479

View File

@ -326,38 +326,47 @@ namespace dxvk {
sizeof(pDesc->Description) / sizeof(pDesc->Description[0]) - 1, sizeof(pDesc->Description) / sizeof(pDesc->Description[0]) - 1,
description.c_str(), description.size()); description.c_str(), description.size());
// Get amount of video memory // Get amount of video memory based on the Vulkan heaps
// based on the Vulkan heaps
VkDeviceSize deviceMemory = 0; VkDeviceSize deviceMemory = 0;
VkDeviceSize sharedMemory = 0; VkDeviceSize sharedMemory = 0;
for (uint32_t i = 0; i < memoryProp.memoryHeapCount; i++) { for (uint32_t i = 0; i < memoryProp.memoryHeapCount; i++) {
VkMemoryHeap heap = memoryProp.memoryHeaps[i]; VkMemoryHeap heap = memoryProp.memoryHeaps[i];
if (heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) if (heap.flags & VK_MEMORY_HEAP_DEVICE_LOCAL_BIT) {
deviceMemory += heap.size; // In general we'll have one large device-local heap, and an additional
else // smaller heap on dGPUs in case ReBAR is not supported. Assume that
// the largest available heap is the total amount of available VRAM.
deviceMemory = std::max(heap.size, deviceMemory);
} else {
// This is typically plain sysmem, don't care too much about limits here
sharedMemory += heap.size; sharedMemory += heap.size;
}
} }
// Some games think we are on Intel given a lack of // This can happen on integrated GPUs with one memory heap, over-report
// NVAPI or AGS/atiadlxx support. // here since some games may be allergic to reporting no shared memory.
// Report our device memory as shared memory, if (!sharedMemory)
// and some small amount for the carveout.
if (options->emulateUMA && !m_adapter->isUnifiedMemoryArchitecture()) {
sharedMemory = deviceMemory; sharedMemory = deviceMemory;
deviceMemory = 128 * (1 << 20);
// Some games will default to the GPU with the highest amount of dedicated memory,
// which can be an integrated GPU on some systems. Report available memory as shared
// memory and a small amount as dedicated carve-out if a dedicated GPU is present,
// otherwise report memory normally to not unnecessarily confuse games on Deck.
if ((m_adapter->isLinkedToDGPU() && deviceProp.deviceType == VK_PHYSICAL_DEVICE_TYPE_INTEGRATED_GPU) || options->emulateUMA) {
sharedMemory = std::max(sharedMemory, deviceMemory);
deviceMemory = 512ull << 20;
} }
// Some games are silly and need their memory limited // Some games are silly and need their memory limited
if (options->maxDeviceMemory > 0 if (options->maxDeviceMemory > 0
&& options->maxDeviceMemory < deviceMemory) && options->maxDeviceMemory < deviceMemory)
deviceMemory = options->maxDeviceMemory; deviceMemory = options->maxDeviceMemory;
if (options->maxSharedMemory > 0 if (options->maxSharedMemory > 0
&& options->maxSharedMemory < sharedMemory) && options->maxSharedMemory < sharedMemory)
sharedMemory = options->maxSharedMemory; sharedMemory = options->maxSharedMemory;
if (env::is32BitHostPlatform()) { if (env::is32BitHostPlatform()) {
// The value returned by DXGI is a 32-bit value // The value returned by DXGI is a 32-bit value
// on 32-bit platforms, so we need to clamp it // on 32-bit platforms, so we need to clamp it