mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 21:30:53 +00:00
Try creating a device with successive adapters until one succeeds.
On laptops with integrated+discrete adapters, adapter 0 may not support D3D12, so a default create device call will fail. Adapters other than the 0th one need to be specified explicitly.
This commit is contained in:
committed by
Baldur Karlsson
parent
385121d2ca
commit
2f7b260d39
@@ -38,7 +38,7 @@ HMODULE d3d11 = NULL;
|
||||
HMODULE dxgi = NULL;
|
||||
HMODULE d3dcompiler = NULL;
|
||||
IDXGIFactoryPtr factory;
|
||||
IDXGIAdapterPtr adapter;
|
||||
std::vector<IDXGIAdapterPtr> adapters;
|
||||
bool warp = false;
|
||||
|
||||
pD3DCompile dyn_D3DCompile = NULL;
|
||||
@@ -94,7 +94,7 @@ void D3D11GraphicsTest::Prepare(int argc, char **argv)
|
||||
hr = createFactory(__uuidof(IDXGIFactory), (void **)&factory);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
adapter = ChooseD3DAdapter(factory, argc, argv, warp);
|
||||
adapters = FindD3DAdapters(factory, argc, argv, warp);
|
||||
}
|
||||
|
||||
if(!d3d11)
|
||||
@@ -111,23 +111,23 @@ void D3D11GraphicsTest::Prepare(int argc, char **argv)
|
||||
|
||||
if(dyn_D3D11CreateDevice)
|
||||
{
|
||||
ID3D11DevicePtr tempDev;
|
||||
|
||||
D3D_FEATURE_LEVEL features[] = {D3D_FEATURE_LEVEL_11_0};
|
||||
hr = dyn_D3D11CreateDevice(adapter, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, features, 1,
|
||||
D3D11_SDK_VERSION, &tempDev, NULL, NULL);
|
||||
hr = CreateDevice(adapters, NULL, features, 0);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
tempDev->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &opts, sizeof(opts));
|
||||
dev->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS, &opts, sizeof(opts));
|
||||
|
||||
ID3D11Device1Ptr tempDev1;
|
||||
|
||||
tempDev1 = tempDev;
|
||||
tempDev1 = dev;
|
||||
memset(&opts1, 0, sizeof(opts1));
|
||||
if(tempDev1)
|
||||
tempDev1->CheckFeatureSupport(D3D11_FEATURE_D3D11_OPTIONS1, &opts1, sizeof(opts1));
|
||||
}
|
||||
|
||||
// This device was only used to get feature support. Set it back to NULL
|
||||
dev = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -138,41 +138,17 @@ bool D3D11GraphicsTest::Init()
|
||||
return false;
|
||||
|
||||
D3D_FEATURE_LEVEL features[] = {D3D_FEATURE_LEVEL_11_0};
|
||||
D3D_DRIVER_TYPE driver = D3D_DRIVER_TYPE_HARDWARE;
|
||||
|
||||
if(d3d11_1)
|
||||
features[0] = D3D_FEATURE_LEVEL_11_1;
|
||||
|
||||
if(warp)
|
||||
driver = D3D_DRIVER_TYPE_WARP;
|
||||
|
||||
if(adapter)
|
||||
driver = D3D_DRIVER_TYPE_UNKNOWN;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
UINT flags = createFlags | (debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0);
|
||||
|
||||
if(headless)
|
||||
{
|
||||
hr = dyn_D3D11CreateDevice(adapter, driver, NULL, flags, features, 1, D3D11_SDK_VERSION, &dev,
|
||||
NULL, &ctx);
|
||||
|
||||
// if it failed but on a high feature level, try again on warp
|
||||
if(FAILED(hr) && features[0] != D3D_FEATURE_LEVEL_11_0)
|
||||
{
|
||||
driver = D3D_DRIVER_TYPE_WARP;
|
||||
hr = dyn_D3D11CreateDevice(adapter, driver, NULL, flags, features, 1, D3D11_SDK_VERSION, &dev,
|
||||
NULL, &ctx);
|
||||
}
|
||||
|
||||
// if it failed again on a high feature level, try last on ref
|
||||
if(FAILED(hr) && features[0] != D3D_FEATURE_LEVEL_11_0)
|
||||
{
|
||||
driver = D3D_DRIVER_TYPE_REFERENCE;
|
||||
hr = dyn_D3D11CreateDevice(adapter, driver, NULL, flags, features, 1, D3D11_SDK_VERSION, &dev,
|
||||
NULL, &ctx);
|
||||
}
|
||||
hr = CreateDevice(adapters, NULL, features, flags);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -203,24 +179,7 @@ bool D3D11GraphicsTest::Init()
|
||||
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
|
||||
swapDesc.Flags = 0;
|
||||
|
||||
hr = dyn_D3D11CreateDeviceAndSwapChain(adapter, driver, NULL, flags, features, 1,
|
||||
D3D11_SDK_VERSION, &swapDesc, &swap, &dev, NULL, &ctx);
|
||||
|
||||
// if it failed but on a high feature level, try again on warp
|
||||
if(FAILED(hr))
|
||||
{
|
||||
driver = D3D_DRIVER_TYPE_WARP;
|
||||
hr = dyn_D3D11CreateDeviceAndSwapChain(adapter, driver, NULL, flags, features, 1,
|
||||
D3D11_SDK_VERSION, &swapDesc, &swap, &dev, NULL, &ctx);
|
||||
}
|
||||
|
||||
// if it failed again on a high feature level, try last on ref
|
||||
if(FAILED(hr))
|
||||
{
|
||||
driver = D3D_DRIVER_TYPE_REFERENCE;
|
||||
hr = dyn_D3D11CreateDeviceAndSwapChain(adapter, driver, NULL, flags, features, 1,
|
||||
D3D11_SDK_VERSION, &swapDesc, &swap, &dev, NULL, &ctx);
|
||||
}
|
||||
hr = CreateDevice(adapters, &swapDesc, features, flags);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
@@ -257,6 +216,50 @@ GraphicsWindow *D3D11GraphicsTest::MakeWindow(int width, int height, const char
|
||||
return new Win32Window(width, height, title);
|
||||
}
|
||||
|
||||
HRESULT D3D11GraphicsTest::CreateDevice(std::vector<IDXGIAdapterPtr> &adaptersToTry,
|
||||
DXGI_SWAP_CHAIN_DESC *swapDesc, D3D_FEATURE_LEVEL *features,
|
||||
UINT flags)
|
||||
{
|
||||
HRESULT hr = E_FAIL;
|
||||
for(size_t i = 0; i < adaptersToTry.size(); ++i)
|
||||
{
|
||||
if(swapDesc)
|
||||
hr = dyn_D3D11CreateDeviceAndSwapChain(adaptersToTry[i], D3D_DRIVER_TYPE_UNKNOWN, NULL, flags,
|
||||
features, 1, D3D11_SDK_VERSION, swapDesc, &swap, &dev,
|
||||
NULL, &ctx);
|
||||
else
|
||||
hr = dyn_D3D11CreateDevice(adaptersToTry[i], D3D_DRIVER_TYPE_UNKNOWN, NULL, flags, features,
|
||||
1, D3D11_SDK_VERSION, &dev, NULL, &ctx);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
break;
|
||||
}
|
||||
|
||||
// If it failed, try again on warp
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(swapDesc)
|
||||
hr = dyn_D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_WARP, NULL, flags, features, 1,
|
||||
D3D11_SDK_VERSION, swapDesc, &swap, &dev, NULL, &ctx);
|
||||
else
|
||||
hr = dyn_D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, flags, features, 1,
|
||||
D3D11_SDK_VERSION, &dev, NULL, &ctx);
|
||||
}
|
||||
|
||||
// If it failed again, try last on ref
|
||||
if(FAILED(hr))
|
||||
{
|
||||
if(swapDesc)
|
||||
hr = dyn_D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, features,
|
||||
1, D3D11_SDK_VERSION, swapDesc, &swap, &dev, NULL, &ctx);
|
||||
else
|
||||
hr = dyn_D3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, flags, features, 1,
|
||||
D3D11_SDK_VERSION, &dev, NULL, &ctx);
|
||||
}
|
||||
|
||||
return hr;
|
||||
}
|
||||
|
||||
void D3D11GraphicsTest::PostDeviceCreate()
|
||||
{
|
||||
{
|
||||
|
||||
@@ -50,6 +50,8 @@ struct D3D11GraphicsTest : public GraphicsTest
|
||||
void Shutdown();
|
||||
GraphicsWindow *MakeWindow(int width, int height, const char *title);
|
||||
|
||||
HRESULT CreateDevice(std::vector<IDXGIAdapterPtr> &adaptersToTry, DXGI_SWAP_CHAIN_DESC *swapDesc,
|
||||
D3D_FEATURE_LEVEL *features, UINT flags);
|
||||
void PostDeviceCreate();
|
||||
|
||||
enum BufType
|
||||
|
||||
@@ -62,11 +62,13 @@ RD_TEST(D3D12_Sharing, D3D12GraphicsTest)
|
||||
|
||||
IDXGIAdapterPtr pDXGIAdapter;
|
||||
HRESULT hr = EnumAdapterByLuid(dev->GetAdapterLuid(), pDXGIAdapter);
|
||||
std::vector<IDXGIAdapterPtr> adapters;
|
||||
adapters.push_back(pDXGIAdapter);
|
||||
|
||||
if(FAILED(hr))
|
||||
return 2;
|
||||
|
||||
dev2 = CreateDevice(pDXGIAdapter);
|
||||
dev2 = CreateDevice(adapters, D3D_FEATURE_LEVEL_11_0);
|
||||
|
||||
if(!dev2)
|
||||
return 2;
|
||||
|
||||
@@ -39,9 +39,9 @@ HMODULE d3d12 = NULL;
|
||||
HMODULE dxgi = NULL;
|
||||
HMODULE d3dcompiler = NULL;
|
||||
IDXGIFactory1Ptr factory;
|
||||
IDXGIAdapterPtr adapter;
|
||||
std::vector<IDXGIAdapterPtr> adapters;
|
||||
bool d3d12on7 = false;
|
||||
};
|
||||
}; // namespace
|
||||
|
||||
void D3D12GraphicsTest::Prepare(int argc, char **argv)
|
||||
{
|
||||
@@ -90,13 +90,18 @@ void D3D12GraphicsTest::Prepare(int argc, char **argv)
|
||||
{
|
||||
bool warp = false;
|
||||
|
||||
adapter = ChooseD3DAdapter(factory, argc, argv, warp);
|
||||
adapters = FindD3DAdapters(factory, argc, argv, warp);
|
||||
|
||||
if(warp && !d3d12on7)
|
||||
{
|
||||
IDXGIFactory4Ptr factory4 = factory;
|
||||
IDXGIAdapterPtr warpAdapter;
|
||||
if(factory4)
|
||||
factory4->EnumWarpAdapter(__uuidof(IDXGIAdapter), (void **)&adapter);
|
||||
{
|
||||
hr = factory4->EnumWarpAdapter(__uuidof(IDXGIAdapter), (void **)&warpAdapter);
|
||||
if(SUCCEEDED(hr))
|
||||
adapters.push_back(warpAdapter);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -182,7 +187,7 @@ bool D3D12GraphicsTest::Init()
|
||||
}
|
||||
}
|
||||
|
||||
dev = CreateDevice(adapter);
|
||||
dev = CreateDevice(adapters, D3D_FEATURE_LEVEL_11_0);
|
||||
if(!dev)
|
||||
return false;
|
||||
|
||||
@@ -420,17 +425,20 @@ HRESULT D3D12GraphicsTest::EnumAdapterByLuid(LUID luid, IDXGIAdapterPtr &pAdapte
|
||||
return E_FAIL;
|
||||
}
|
||||
|
||||
ID3D12DevicePtr D3D12GraphicsTest::CreateDevice(IDXGIAdapterPtr a)
|
||||
ID3D12DevicePtr D3D12GraphicsTest::CreateDevice(std::vector<IDXGIAdapterPtr> &adaptersToTry,
|
||||
D3D_FEATURE_LEVEL features)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
ID3D12DevicePtr ret;
|
||||
for(size_t i = 0; i < adaptersToTry.size(); ++i)
|
||||
{
|
||||
hr = dyn_D3D12CreateDevice(adaptersToTry[i], features, __uuidof(ID3D12Device), (void **)&ret);
|
||||
|
||||
hr = dyn_D3D12CreateDevice(a, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void **)&ret);
|
||||
|
||||
if(FAILED(hr))
|
||||
TEST_ERROR("D3D12CreateDevice failed: %x", hr);
|
||||
if(SUCCEEDED(hr))
|
||||
return ret;
|
||||
}
|
||||
|
||||
TEST_ERROR("D3D12CreateDevice failed: %x", hr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,8 @@ struct D3D12GraphicsTest : public GraphicsTest
|
||||
GraphicsWindow *MakeWindow(int width, int height, const char *title);
|
||||
|
||||
HRESULT EnumAdapterByLuid(LUID luid, IDXGIAdapterPtr &pAdapter);
|
||||
ID3D12DevicePtr CreateDevice(IDXGIAdapterPtr adapter);
|
||||
ID3D12DevicePtr CreateDevice(std::vector<IDXGIAdapterPtr> &adaptersToTry,
|
||||
D3D_FEATURE_LEVEL features);
|
||||
|
||||
enum BufType
|
||||
{
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
******************************************************************************/
|
||||
|
||||
#include "d3d_helpers.h"
|
||||
#include <vector>
|
||||
#include "../test_common.h"
|
||||
|
||||
std::string D3DFullscreenQuadVertex = R"EOSHADER(
|
||||
@@ -87,7 +86,8 @@ float4 main(v2f IN) : SV_Target0
|
||||
|
||||
)EOSHADER";
|
||||
|
||||
IDXGIAdapterPtr ChooseD3DAdapter(IDXGIFactoryPtr factory, int argc, char **argv, bool &warp)
|
||||
std::vector<IDXGIAdapterPtr> FindD3DAdapters(IDXGIFactoryPtr factory, int argc, char **argv,
|
||||
bool &warp)
|
||||
{
|
||||
struct AdapterInfo
|
||||
{
|
||||
@@ -98,31 +98,30 @@ IDXGIAdapterPtr ChooseD3DAdapter(IDXGIFactoryPtr factory, int argc, char **argv,
|
||||
std::vector<AdapterInfo> adapters;
|
||||
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
for(UINT i = 0; i < 10; i++)
|
||||
{
|
||||
IDXGIAdapterPtr a;
|
||||
hr = factory->EnumAdapters(i, &a);
|
||||
if(hr == S_OK && a)
|
||||
UINT i = 0;
|
||||
while(true)
|
||||
{
|
||||
IDXGIAdapterPtr a;
|
||||
hr = factory->EnumAdapters(i, &a);
|
||||
if(hr != S_OK || !a)
|
||||
break;
|
||||
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
a->GetDesc(&desc);
|
||||
adapters.push_back({a, desc});
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
IDXGIAdapterPtr adapter = NULL;
|
||||
IDXGIAdapterPtr specifiedAdapter = NULL;
|
||||
|
||||
for(int i = 0; i < argc; i++)
|
||||
{
|
||||
if(!strcmp(argv[i], "--warp"))
|
||||
{
|
||||
warp = true;
|
||||
adapter = NULL;
|
||||
specifiedAdapter = NULL;
|
||||
break;
|
||||
}
|
||||
if(!strcmp(argv[i], "--gpu") && i + 1 < argc)
|
||||
@@ -132,7 +131,7 @@ IDXGIAdapterPtr ChooseD3DAdapter(IDXGIFactoryPtr factory, int argc, char **argv,
|
||||
if(needle == "warp")
|
||||
{
|
||||
warp = true;
|
||||
adapter = NULL;
|
||||
specifiedAdapter = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -149,7 +148,7 @@ IDXGIAdapterPtr ChooseD3DAdapter(IDXGIFactoryPtr factory, int argc, char **argv,
|
||||
(amd && adapters[a].desc.VendorId == PCI_VENDOR_AMD) ||
|
||||
(intel && adapters[a].desc.VendorId == PCI_VENDOR_INTEL))
|
||||
{
|
||||
adapter = adapters[a].adapter;
|
||||
specifiedAdapter = adapters[a].adapter;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -158,5 +157,19 @@ IDXGIAdapterPtr ChooseD3DAdapter(IDXGIFactoryPtr factory, int argc, char **argv,
|
||||
}
|
||||
}
|
||||
|
||||
return adapter;
|
||||
// Return the adapters that we want to consider:
|
||||
// With an adapter specified by command line, only return that one
|
||||
// With warp specified, return an empty adapter list - fallback will occur
|
||||
// Otherwise, return all adapters, to be attempted in order
|
||||
if(specifiedAdapter)
|
||||
return {specifiedAdapter};
|
||||
|
||||
if(warp)
|
||||
return {};
|
||||
|
||||
std::vector<IDXGIAdapterPtr> returnedAdapters;
|
||||
for(size_t i = 0; i < adapters.size(); ++i)
|
||||
returnedAdapters.push_back(adapters[i].adapter);
|
||||
|
||||
return returnedAdapters;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
|
||||
#include <comdef.h>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "dx/official/dxgi1_4.h"
|
||||
|
||||
extern std::string D3DFullscreenQuadVertex;
|
||||
@@ -43,7 +44,8 @@ COM_SMARTPTR(IDXGIAdapter);
|
||||
COM_SMARTPTR(IDXGISurface);
|
||||
COM_SMARTPTR(IDXGIResource);
|
||||
|
||||
IDXGIAdapterPtr ChooseD3DAdapter(IDXGIFactoryPtr factory, int argc, char **argv, bool &warp);
|
||||
std::vector<IDXGIAdapterPtr> FindD3DAdapters(IDXGIFactoryPtr factory, int argc, char **argv,
|
||||
bool &warp);
|
||||
|
||||
enum class ResourceType
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user