Add GPU selection on command line to VK/D3D11/D3D12 tests

This commit is contained in:
baldurk
2018-12-11 15:04:45 +00:00
parent f1d2258c5b
commit b9f5ecaaa8
7 changed files with 311 additions and 16 deletions
+3
View File
@@ -36,6 +36,9 @@
COM_SMARTPTR(ID3DBlob);
COM_SMARTPTR(IDXGISwapChain);
COM_SMARTPTR(IDXGIFactory);
COM_SMARTPTR(IDXGIDevice);
COM_SMARTPTR(IDXGIAdapter);
COM_SMARTPTR(ID3D11Device);
COM_SMARTPTR(ID3D11Device1);
+115 -7
View File
@@ -30,6 +30,8 @@
#include "../renderdoc_app.h"
#include "../win32/win32_window.h"
typedef HRESULT(WINAPI *PFN_CREATE_DXGI_FACTORY)(REFIID, void **);
bool D3D11GraphicsTest::Init(int argc, char **argv)
{
// parse parameters here to override parameters
@@ -39,6 +41,7 @@ bool D3D11GraphicsTest::Init(int argc, char **argv)
// ...
HMODULE d3d11 = LoadLibraryA("d3d11.dll");
HMODULE dxgi = LoadLibraryA("dxgi.dll");
HMODULE d3dcompiler = LoadLibraryA("d3dcompiler_47.dll");
if(!d3dcompiler)
d3dcompiler = LoadLibraryA("d3dcompiler_46.dll");
@@ -49,12 +52,15 @@ bool D3D11GraphicsTest::Init(int argc, char **argv)
if(!d3dcompiler)
d3dcompiler = LoadLibraryA("d3dcompiler_43.dll");
if(!d3d11 || !d3dcompiler)
if(!d3d11 || !dxgi || !d3dcompiler)
{
TEST_ERROR("Couldn't load D3D11");
return false;
}
PFN_CREATE_DXGI_FACTORY createFactory =
(PFN_CREATE_DXGI_FACTORY)GetProcAddress(dxgi, "CreateDXGIFactory");
dyn_D3D11CreateDevice = (PFN_D3D11_CREATE_DEVICE)GetProcAddress(d3d11, "D3D11CreateDevice");
dyn_D3D11CreateDeviceAndSwapChain = (PFN_D3D11_CREATE_DEVICE_AND_SWAP_CHAIN)GetProcAddress(
d3d11, "D3D11CreateDeviceAndSwapChain");
@@ -71,16 +77,91 @@ bool D3D11GraphicsTest::Init(int argc, char **argv)
HRESULT hr = S_OK;
IDXGIFactoryPtr factory = NULL;
hr = createFactory(__uuidof(IDXGIFactory), (void **)&factory);
if(factory.GetInterfacePtr() == NULL || FAILED(hr))
{
TEST_ERROR("CreateDXGIFactory failed: %x", hr);
return false;
}
struct AdapterInfo
{
IDXGIAdapterPtr adapter;
DXGI_ADAPTER_DESC desc;
};
std::vector<AdapterInfo> adapters;
for(UINT i = 0; i < 10; i++)
{
IDXGIAdapterPtr a;
hr = factory->EnumAdapters(i, &a);
if(hr == S_OK && a)
{
DXGI_ADAPTER_DESC desc;
a->GetDesc(&desc);
adapters.push_back({a, desc});
}
else
{
break;
}
}
IDXGIAdapterPtr adapter = NULL;
for(int i = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--warp"))
{
driver = D3D_DRIVER_TYPE_WARP;
break;
}
if(!strcmp(argv[i], "--gpu") && i + 1 < argc)
{
std::string needle = strlower(argv[i + 1]);
if(needle == "warp")
{
driver = D3D_DRIVER_TYPE_WARP;
break;
}
const bool nv = (needle == "nv" || needle == "nvidia");
const bool amd = (needle == "amd");
const bool intel = (needle == "intel");
for(size_t a = 0; a < adapters.size(); a++)
{
std::string haystack = strlower(Wide2UTF8(adapters[a].desc.Description));
if(haystack.find(needle) != std::string::npos || (nv && adapters[a].desc.VendorId == 0x10DE) ||
(amd && adapters[a].desc.VendorId == 0x1002) ||
(intel && adapters[a].desc.VendorId == 0x8086))
{
driver = D3D_DRIVER_TYPE_UNKNOWN;
adapter = adapters[a].adapter;
break;
}
}
break;
}
}
if(headless)
{
hr = dyn_D3D11CreateDevice(NULL, driver, NULL, debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0,
hr = dyn_D3D11CreateDevice(adapter, driver, NULL, debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0,
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(NULL, driver, NULL, debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0,
hr = dyn_D3D11CreateDevice(adapter, driver, NULL, debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0,
features, 1, D3D11_SDK_VERSION, &dev, NULL, &ctx);
}
@@ -88,7 +169,7 @@ bool D3D11GraphicsTest::Init(int argc, char **argv)
if(FAILED(hr) && features[0] != D3D_FEATURE_LEVEL_11_0)
{
driver = D3D_DRIVER_TYPE_REFERENCE;
hr = dyn_D3D11CreateDevice(NULL, driver, NULL, debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0,
hr = dyn_D3D11CreateDevice(adapter, driver, NULL, debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0,
features, 1, D3D11_SDK_VERSION, &dev, NULL, &ctx);
}
@@ -121,7 +202,7 @@ bool D3D11GraphicsTest::Init(int argc, char **argv)
swapDesc.SwapEffect = DXGI_SWAP_EFFECT_DISCARD;
swapDesc.Flags = 0;
hr = dyn_D3D11CreateDeviceAndSwapChain(NULL, driver, NULL,
hr = dyn_D3D11CreateDeviceAndSwapChain(adapter, driver, NULL,
debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0, features, 1,
D3D11_SDK_VERSION, &swapDesc, &swap, &dev, NULL, &ctx);
@@ -129,7 +210,7 @@ bool D3D11GraphicsTest::Init(int argc, char **argv)
if(FAILED(hr))
{
driver = D3D_DRIVER_TYPE_WARP;
hr = dyn_D3D11CreateDeviceAndSwapChain(NULL, driver, NULL,
hr = dyn_D3D11CreateDeviceAndSwapChain(adapter, driver, NULL,
debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0, features, 1,
D3D11_SDK_VERSION, &swapDesc, &swap, &dev, NULL, &ctx);
}
@@ -138,7 +219,7 @@ bool D3D11GraphicsTest::Init(int argc, char **argv)
if(FAILED(hr))
{
driver = D3D_DRIVER_TYPE_REFERENCE;
hr = dyn_D3D11CreateDeviceAndSwapChain(NULL, driver, NULL,
hr = dyn_D3D11CreateDeviceAndSwapChain(adapter, driver, NULL,
debugDevice ? D3D11_CREATE_DEVICE_DEBUG : 0, features, 1,
D3D11_SDK_VERSION, &swapDesc, &swap, &dev, NULL, &ctx);
}
@@ -211,6 +292,33 @@ bool D3D11GraphicsTest::IsSupported()
void D3D11GraphicsTest::PostDeviceCreate()
{
{
IDXGIDevicePtr pDXGIDevice;
HRESULT hr = dev->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
if(FAILED(hr) || !pDXGIDevice)
{
TEST_ERROR("Couldn't get DXGI Device");
}
else
{
IDXGIAdapterPtr pDXGIAdapter;
hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
if(FAILED(hr) || !pDXGIAdapter)
{
TEST_ERROR("Couldn't get DXGI Adapter");
}
else
{
DXGI_ADAPTER_DESC desc = {};
pDXGIAdapter->GetDesc(&desc);
TEST_LOG("Running D3D11 test on %ls", desc.Description);
}
}
}
// if(d3d11_1)
{
dev->QueryInterface(__uuidof(ID3D11Device1), (void **)&dev1);
+1
View File
@@ -35,6 +35,7 @@ COM_SMARTPTR(ID3DBlob);
COM_SMARTPTR(IDXGISwapChain);
COM_SMARTPTR(IDXGISwapChain1);
COM_SMARTPTR(IDXGIFactory4);
COM_SMARTPTR(IDXGIAdapter);
COM_SMARTPTR(ID3D12Debug);
COM_SMARTPTR(ID3D12Debug1);
+91 -8
View File
@@ -52,7 +52,7 @@ bool D3D12GraphicsTest::Init(int argc, char **argv)
if(!d3dcompiler)
d3dcompiler = LoadLibraryA("d3dcompiler_43.dll");
if(!d3d12 || !d3dcompiler)
if(!d3d12 || !dxgi || !d3dcompiler)
{
TEST_ERROR("Couldn't load D3D12");
return false;
@@ -114,20 +114,84 @@ bool D3D12GraphicsTest::Init(int argc, char **argv)
return false;
}
hr = dyn_D3D12CreateDevice(NULL, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device), (void **)&dev);
struct AdapterInfo
{
IDXGIAdapterPtr adapter;
DXGI_ADAPTER_DESC desc;
};
std::vector<AdapterInfo> adapters;
for(UINT i = 0; i < 10; i++)
{
IDXGIAdapterPtr a;
hr = m_Factory->EnumAdapters(i, &a);
if(hr == S_OK && a)
{
DXGI_ADAPTER_DESC desc;
a->GetDesc(&desc);
adapters.push_back({a, desc});
}
else
{
break;
}
}
IDXGIAdapterPtr warp = NULL;
m_Factory->EnumWarpAdapter(__uuidof(IDXGIAdapter), (void **)&warp);
IDXGIAdapterPtr adapter = NULL;
for(int i = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--warp"))
{
adapter = warp;
break;
}
if(!strcmp(argv[i], "--gpu") && i + 1 < argc)
{
std::string needle = strlower(argv[i + 1]);
if(needle == "warp")
{
adapter = warp;
break;
}
const bool nv = (needle == "nv" || needle == "nvidia");
const bool amd = (needle == "amd");
const bool intel = (needle == "intel");
for(size_t a = 0; a < adapters.size(); a++)
{
std::string haystack = strlower(Wide2UTF8(adapters[a].desc.Description));
if(haystack.find(needle) != std::string::npos ||
(nv && adapters[a].desc.VendorId == 0x10DE) ||
(amd && adapters[a].desc.VendorId == 0x1002) ||
(intel && adapters[a].desc.VendorId == 0x8086))
{
adapter = adapters[a].adapter;
break;
}
}
break;
}
}
hr = dyn_D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device),
(void **)&dev);
// if it failed, try again on warp
if(FAILED(hr))
{
IDXGIAdapter *adapter = NULL;
m_Factory->EnumWarpAdapter(__uuidof(IDXGIAdapter), (void **)&adapter);
adapter = warp;
if(adapter)
{
hr = dyn_D3D12CreateDevice(adapter, D3D_FEATURE_LEVEL_11_0, __uuidof(ID3D12Device),
(void **)&dev);
adapter->Release();
}
}
if(FAILED(hr))
@@ -137,6 +201,25 @@ bool D3D12GraphicsTest::Init(int argc, char **argv)
}
}
{
LUID luid = dev->GetAdapterLuid();
IDXGIAdapterPtr pDXGIAdapter;
HRESULT hr = m_Factory->EnumAdapterByLuid(luid, __uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
if(FAILED(hr))
{
TEST_ERROR("Couldn't get DXGI adapter by LUID from D3D device");
}
else
{
DXGI_ADAPTER_DESC desc = {};
pDXGIAdapter->GetDesc(&desc);
TEST_LOG("Running D3D12 test on %ls", desc.Description);
}
}
{
D3D12_COMMAND_QUEUE_DESC desc = {};
desc.Type = D3D12_COMMAND_LIST_TYPE_DIRECT;
+48 -1
View File
@@ -173,7 +173,54 @@ bool VulkanGraphicsTest::Init(int argc, char **argv)
return false;
}
phys = physDevices[0];
std::vector<VkPhysicalDeviceProperties> physProps;
for(VkPhysicalDevice p : physDevices)
{
VkPhysicalDeviceProperties props;
vkGetPhysicalDeviceProperties(p, &props);
physProps.push_back(props);
}
// default to the first discrete card
for(size_t i = 0; i < physDevices.size(); i++)
{
if(physProps[i].deviceType == VK_PHYSICAL_DEVICE_TYPE_DISCRETE_GPU)
{
phys = physDevices[i];
break;
}
}
// if none found, default to first
if(phys == VK_NULL_HANDLE)
phys = physDevices[0];
// allow command line override
for(int i = 0; i < argc; i++)
{
if(!strcmp(argv[i], "--gpu") && i + 1 < argc)
{
std::string needle = strlower(argv[i + 1]);
const bool nv = (needle == "nv" || needle == "nvidia");
const bool amd = (needle == "amd");
const bool intel = (needle == "intel");
for(size_t p = 0; p < physDevices.size(); p++)
{
std::string haystack = strlower(physProps[p].deviceName);
if(haystack.find(needle) != std::string::npos || (nv && physProps[p].vendorID == 0x10DE) ||
(amd && physProps[p].vendorID == 0x1002) || (intel && physProps[p].vendorID == 0x8086))
{
phys = physDevices[p];
break;
}
}
break;
}
}
std::vector<VkQueueFamilyProperties> queueProps;
vkh::getQueueFamilyProperties(queueProps, phys);
+48
View File
@@ -40,3 +40,51 @@ std::string GetCWD()
return cwdstr;
}
std::string Wide2UTF8(const std::wstring &s)
{
int bytes_required = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, NULL, 0, NULL, NULL);
if(bytes_required == 0)
return "";
std::string ret;
ret.resize(bytes_required);
int res = WideCharToMultiByte(CP_UTF8, 0, s.c_str(), -1, &ret[0], bytes_required, NULL, NULL);
if(ret.back() == 0)
ret.pop_back();
if(res == 0)
{
TEST_WARN("Failed to convert wstring '%ls'", s.c_str());
return "";
}
return ret;
}
std::wstring UTF82Wide(const std::string &s)
{
int chars_required = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, NULL, 0);
if(chars_required == 0)
return L"";
std::wstring ret;
ret.resize(chars_required);
int res = MultiByteToWideChar(CP_UTF8, 0, s.c_str(), -1, &ret[0], chars_required);
if(ret.back() == 0)
ret.pop_back();
if(res == 0)
{
TEST_WARN("Failed to convert utf-8 string '%s'", s.c_str());
return L"";
}
return ret;
}
+5
View File
@@ -29,6 +29,11 @@
#define NOMINMAX
#include <windows.h>
#include <string>
std::string Wide2UTF8(const std::wstring &s);
std::wstring UTF82Wide(const std::string &s);
#define DEBUG_BREAK() \
do \
{ \