Merge commit 'f2ecefb7ee9b9e6c5daac9f44fe40ebdccbb1c76' into 1.6

This commit is contained in:
Wojtek Figat
2023-06-01 01:06:14 +02:00
121 changed files with 2553 additions and 958 deletions

View File

@@ -114,7 +114,15 @@ GPUDevice* GPUDeviceDX11::Create()
// Create DXGI factory
#if PLATFORM_WINDOWS
IDXGIFactory1* dxgiFactory;
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
IDXGIFactory6* dxgiFactory6;
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory6));
if (hr == S_OK)
dxgiFactory = dxgiFactory6;
else
{
dxgiFactory6 = nullptr;
hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
}
#else
IDXGIFactory2* dxgiFactory;
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
@@ -126,16 +134,17 @@ GPUDevice* GPUDeviceDX11::Create()
}
// Enumerate the DXGIFactory's adapters
int32 selectedAdapterIndex = -1;
Array<GPUAdapterDX> adapters;
IDXGIAdapter* tmpAdapter;
for (uint32 index = 0; dxgiFactory->EnumAdapters(index, &tmpAdapter) != DXGI_ERROR_NOT_FOUND; index++)
IDXGIAdapter* tempAdapter;
for (uint32 index = 0; dxgiFactory->EnumAdapters(index, &tempAdapter) != DXGI_ERROR_NOT_FOUND; index++)
{
GPUAdapterDX adapter;
if (tmpAdapter && TryCreateDevice(tmpAdapter, maxAllowedFeatureLevel, &adapter.MaxFeatureLevel))
if (tempAdapter && TryCreateDevice(tempAdapter, maxAllowedFeatureLevel, &adapter.MaxFeatureLevel))
{
adapter.Index = index;
VALIDATE_DIRECTX_RESULT(tmpAdapter->GetDesc(&adapter.Description));
uint32 outputs = RenderToolsDX::CountAdapterOutputs(tmpAdapter);
VALIDATE_DIRECTX_RESULT(tempAdapter->GetDesc(&adapter.Description));
uint32 outputs = RenderToolsDX::CountAdapterOutputs(tempAdapter);
LOG(Info, "Adapter {1}: '{0}', DirectX {2}", adapter.Description.Description, index, RenderToolsDX::GetFeatureLevelString(adapter.MaxFeatureLevel));
LOG(Info, " Dedicated Video Memory: {0}, Dedicated System Memory: {1}, Shared System Memory: {2}, Output(s): {3}", Utilities::BytesToText(adapter.Description.DedicatedVideoMemory), Utilities::BytesToText(adapter.Description.DedicatedSystemMemory), Utilities::BytesToText(adapter.Description.SharedSystemMemory), outputs);
@@ -143,14 +152,41 @@ GPUDevice* GPUDeviceDX11::Create()
adapters.Add(adapter);
}
}
#if PLATFORM_WINDOWS
// Find the best performing adapter and prefer using it instead of the first device
const auto gpuPreference = DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE;
if (dxgiFactory6 != nullptr && selectedAdapterIndex == -1)
{
if (dxgiFactory6->EnumAdapterByGpuPreference(0, gpuPreference, IID_PPV_ARGS(&tempAdapter)) != DXGI_ERROR_NOT_FOUND)
{
GPUAdapterDX adapter;
if (tempAdapter && TryCreateDevice(tempAdapter, maxAllowedFeatureLevel, &adapter.MaxFeatureLevel))
{
DXGI_ADAPTER_DESC desc;
VALIDATE_DIRECTX_RESULT(tempAdapter->GetDesc(&desc));
for (int i = 0; i < adapters.Count(); i++)
{
if (adapters[i].Description.AdapterLuid.LowPart == desc.AdapterLuid.LowPart &&
adapters[i].Description.AdapterLuid.HighPart == desc.AdapterLuid.HighPart)
{
selectedAdapterIndex = i;
break;
}
}
}
}
}
#endif
// Select the adapter to use
if (adapters.Count() == 0)
if (selectedAdapterIndex < 0)
selectedAdapterIndex = 0;
if (adapters.Count() == 0 || selectedAdapterIndex >= adapters.Count())
{
LOG(Error, "Failed to find valid DirectX adapter!");
return nullptr;
}
GPUAdapterDX selectedAdapter = adapters[0];
GPUAdapterDX selectedAdapter = adapters[selectedAdapterIndex];
uint32 vendorId = 0;
if (CommandLine::Options.NVIDIA)
vendorId = GPU_VENDOR_ID_NVIDIA;
@@ -185,6 +221,15 @@ GPUDevice* GPUDeviceDX11::Create()
Delete(device);
return nullptr;
}
#if PLATFORM_WINDOWS
if (dxgiFactory6 != nullptr)
dxgiFactory6->Release();
else
#endif
{
dxgiFactory->Release();
}
return device;
}

View File

@@ -89,7 +89,15 @@ GPUDevice* GPUDeviceDX12::Create()
// Create DXGI factory (CreateDXGIFactory2 is supported on Windows 8.1 or newer)
IDXGIFactory4* dxgiFactory;
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
IDXGIFactory6* dxgiFactory6;
HRESULT hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory6));
if (hr == S_OK)
dxgiFactory = dxgiFactory6;
else
{
dxgiFactory6 = nullptr;
hr = CreateDXGIFactory1(IID_PPV_ARGS(&dxgiFactory));
}
if (hr != S_OK)
{
LOG(Error, "Cannot create DXGI adapter. Error code: {0:x}.", hr);
@@ -97,6 +105,7 @@ GPUDevice* GPUDeviceDX12::Create()
}
// Enumerate the DXGIFactory's adapters
int32 selectedAdapterIndex = -1;
Array<GPUAdapterDX> adapters;
IDXGIAdapter* tempAdapter;
for (uint32 index = 0; dxgiFactory->EnumAdapters(index, &tempAdapter) != DXGI_ERROR_NOT_FOUND; index++)
@@ -118,13 +127,39 @@ GPUDevice* GPUDeviceDX12::Create()
}
}
// Find the best performing adapter and prefer using it instead of the first device
const auto gpuPreference = DXGI_GPU_PREFERENCE_HIGH_PERFORMANCE;
if (dxgiFactory6 != nullptr && selectedAdapterIndex == -1)
{
if (dxgiFactory6->EnumAdapterByGpuPreference(0, gpuPreference, IID_PPV_ARGS(&tempAdapter)) != DXGI_ERROR_NOT_FOUND)
{
GPUAdapterDX adapter;
if (tempAdapter && CheckDX12Support(tempAdapter))
{
DXGI_ADAPTER_DESC desc;
VALIDATE_DIRECTX_RESULT(tempAdapter->GetDesc(&desc));
for (int i = 0; i < adapters.Count(); i++)
{
if (adapters[i].Description.AdapterLuid.LowPart == desc.AdapterLuid.LowPart &&
adapters[i].Description.AdapterLuid.HighPart == desc.AdapterLuid.HighPart)
{
selectedAdapterIndex = i;
break;
}
}
}
}
}
// Select the adapter to use
if (adapters.Count() == 0)
if (selectedAdapterIndex < 0)
selectedAdapterIndex = 0;
if (adapters.Count() == 0 || selectedAdapterIndex >= adapters.Count())
{
LOG(Error, "Failed to find valid DirectX adapter!");
return nullptr;
}
GPUAdapterDX selectedAdapter = adapters[0];
GPUAdapterDX selectedAdapter = adapters[selectedAdapterIndex];
uint32 vendorId = 0;
if (CommandLine::Options.NVIDIA)
vendorId = GPU_VENDOR_ID_NVIDIA;
@@ -167,6 +202,15 @@ GPUDevice* GPUDeviceDX12::Create()
return nullptr;
}
#if !(PLATFORM_XBOX_SCARLETT || PLATFORM_XBOX_ONE)
if (dxgiFactory6 != nullptr)
dxgiFactory6->Release();
else
#endif
{
dxgiFactory->Release();
}
return device;
}

View File

@@ -40,9 +40,11 @@ typedef IGraphicsUnknown IDXGISwapChain3;
#include <d3d11_1.h>
#include <dxgi1_3.h>
#include <dxgi1_5.h>
#include <dxgi1_6.h>
#endif
#if GRAPHICS_API_DIRECTX12
#include <dxgi1_5.h>
#include <dxgi1_6.h>
#endif
#pragma comment(lib, "DXGI.lib")

View File

@@ -1155,6 +1155,7 @@ GPUDevice* GPUDeviceVulkan::Create()
#endif
// Enumerate all GPU devices and pick one
int32 selectedAdapterIndex = -1;
uint32 gpuCount = 0;
VALIDATE_VULKAN_RESULT(vkEnumeratePhysicalDevices(Instance, &gpuCount, nullptr));
if (gpuCount <= 0)
@@ -1187,6 +1188,9 @@ GPUDevice* GPUDeviceVulkan::Create()
break;
case VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU:
type = TEXT("Discrete GPU");
// Select the first discrete GPU device
if (selectedAdapterIndex == -1)
selectedAdapterIndex = gpuIndex;
break;
case VK_PHYSICAL_DEVICE_TYPE_VIRTUAL_GPU:
type = TEXT("Virtual GPU");
@@ -1203,12 +1207,13 @@ GPUDevice* GPUDeviceVulkan::Create()
}
// Select the adapter to use
if (adapters.Count() == 0)
if (selectedAdapterIndex < 0)
selectedAdapterIndex = 0;
if (adapters.Count() == 0 || selectedAdapterIndex >= adapters.Count())
{
LOG(Error, "Failed to find valid Vulkan adapter!");
return nullptr;
}
int32 selectedAdapter = 0;
uint32 vendorId = 0;
if (CommandLine::Options.NVIDIA)
vendorId = GPU_VENDOR_ID_NVIDIA;
@@ -1222,15 +1227,15 @@ GPUDevice* GPUDeviceVulkan::Create()
{
if (adapters[i].GetVendorId() == vendorId)
{
selectedAdapter = i;
selectedAdapterIndex = i;
break;
}
}
}
ASSERT(selectedAdapter != -1 && adapters[selectedAdapter].IsValid());
ASSERT(adapters[selectedAdapterIndex].IsValid());
// Create device
auto device = New<GPUDeviceVulkan>(ShaderProfile::Vulkan_SM5, New<GPUAdapterVulkan>(adapters[selectedAdapter]));
auto device = New<GPUDeviceVulkan>(ShaderProfile::Vulkan_SM5, New<GPUAdapterVulkan>(adapters[selectedAdapterIndex]));
if (device->Init())
{
LOG(Warning, "Graphics Device init failed");