mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-27 00:46:36 +00:00
Implement forced GPU override on D3D11, D3D12 and Vulkan
This commit is contained in:
@@ -320,6 +320,7 @@ private:
|
||||
|
||||
D3D11InitParams m_InitParams;
|
||||
uint64_t m_SectionVersion;
|
||||
ReplayOptions m_ReplayOptions;
|
||||
|
||||
ResourceId m_BBID;
|
||||
|
||||
@@ -394,10 +395,11 @@ public:
|
||||
ALLOCATE_WITH_WRAPPED_POOL(WrappedID3D11Device, AllocPoolCount);
|
||||
|
||||
WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitParams params);
|
||||
void SetInitParams(const D3D11InitParams ¶ms, uint64_t sectionVersion)
|
||||
void SetInitParams(const D3D11InitParams ¶ms, uint64_t sectionVersion, const ReplayOptions &opts)
|
||||
{
|
||||
m_InitParams = params;
|
||||
m_SectionVersion = sectionVersion;
|
||||
m_ReplayOptions = opts;
|
||||
}
|
||||
uint64_t GetLogVersion() { return m_SectionVersion; }
|
||||
virtual ~WrappedID3D11Device();
|
||||
|
||||
@@ -3788,7 +3788,8 @@ ReplayStatus D3D11_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, I
|
||||
// support because using warp was not deliberate)
|
||||
bool warpFallback = false;
|
||||
|
||||
ChooseBestMatchingAdapter(GraphicsAPI::D3D11, factory, initParams.AdapterDesc, &useWarp, &adapter);
|
||||
ChooseBestMatchingAdapter(GraphicsAPI::D3D11, factory, initParams.AdapterDesc, opts, &useWarp,
|
||||
&adapter);
|
||||
|
||||
if(useWarp)
|
||||
SAFE_RELEASE(adapter);
|
||||
@@ -3921,7 +3922,7 @@ ReplayStatus D3D11_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, I
|
||||
if(SUCCEEDED(hr) && device)
|
||||
{
|
||||
WrappedID3D11Device *wrappedDev = new WrappedID3D11Device(device, initParams);
|
||||
wrappedDev->SetInitParams(initParams, ver);
|
||||
wrappedDev->SetInitParams(initParams, ver, opts);
|
||||
|
||||
RDCLOG("Created device.");
|
||||
D3D11Replay *replay = wrappedDev->GetReplay();
|
||||
|
||||
@@ -394,6 +394,7 @@ private:
|
||||
|
||||
D3D12InitParams m_InitParams;
|
||||
uint64_t m_SectionVersion;
|
||||
ReplayOptions m_ReplayOptions;
|
||||
ID3D12InfoQueue *m_pInfoQueue;
|
||||
|
||||
D3D12ResourceRecord *m_FrameCaptureRecord;
|
||||
@@ -506,10 +507,11 @@ public:
|
||||
}
|
||||
const std::map<ResourceId, DXGI_FORMAT> &GetBackbufferFormats() { return m_BackbufferFormat; }
|
||||
void SetLogFile(const char *logfile);
|
||||
void SetInitParams(const D3D12InitParams ¶ms, uint64_t sectionVersion)
|
||||
void SetInitParams(const D3D12InitParams ¶ms, uint64_t sectionVersion, const ReplayOptions &opts)
|
||||
{
|
||||
m_InitParams = params;
|
||||
m_SectionVersion = sectionVersion;
|
||||
m_ReplayOptions = opts;
|
||||
}
|
||||
uint64_t GetLogVersion() { return m_SectionVersion; }
|
||||
CaptureState GetState() { return m_State; }
|
||||
|
||||
@@ -3754,7 +3754,8 @@ ReplayStatus D3D12_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, I
|
||||
|
||||
IDXGIAdapter *adapter = NULL;
|
||||
|
||||
ChooseBestMatchingAdapter(GraphicsAPI::D3D12, factory, initParams.AdapterDesc, NULL, &adapter);
|
||||
ChooseBestMatchingAdapter(GraphicsAPI::D3D12, factory, initParams.AdapterDesc, opts, NULL,
|
||||
&adapter);
|
||||
|
||||
bool EnableDebugLayer = false;
|
||||
|
||||
@@ -3795,7 +3796,7 @@ ReplayStatus D3D12_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts, I
|
||||
}
|
||||
|
||||
WrappedID3D12Device *wrappedDev = new WrappedID3D12Device(dev, initParams, EnableDebugLayer);
|
||||
wrappedDev->SetInitParams(initParams, ver);
|
||||
wrappedDev->SetInitParams(initParams, ver, opts);
|
||||
|
||||
RDCLOG("Created device.");
|
||||
D3D12Replay *replay = wrappedDev->GetReplay();
|
||||
|
||||
@@ -1736,13 +1736,132 @@ std::string GetDriverVersion(DXGI_ADAPTER_DESC &desc)
|
||||
return device + " " + driverVersion;
|
||||
}
|
||||
|
||||
IDXGIAdapter *EnumBestAdapter(IDXGIFactory *factory, GPUVendor vendor, uint32_t deviceId)
|
||||
{
|
||||
IDXGIAdapter *ret = NULL;
|
||||
DXGI_ADAPTER_DESC retDesc = {};
|
||||
|
||||
for(UINT i = 0; i < 10; i++)
|
||||
{
|
||||
IDXGIAdapter *ad = NULL;
|
||||
HRESULT hr = factory->EnumAdapters(i, &ad);
|
||||
if(hr == S_OK && ad)
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
ad->GetDesc(&desc);
|
||||
|
||||
// if it's a better vendor match than the adapter we have, choose it
|
||||
GPUVendor adVendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
if(adVendor == vendor && GPUVendorFromPCIVendor(retDesc.VendorId) != vendor)
|
||||
{
|
||||
ret = ad;
|
||||
retDesc = desc;
|
||||
continue;
|
||||
}
|
||||
else if(adVendor != vendor)
|
||||
{
|
||||
ad->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
// if they're the same vendor but this is a better device match, choose it
|
||||
if(desc.DeviceId == deviceId && retDesc.DeviceId != deviceId)
|
||||
{
|
||||
ret = ad;
|
||||
retDesc = desc;
|
||||
continue;
|
||||
}
|
||||
|
||||
ad->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void ChooseBestMatchingAdapter(GraphicsAPI api, IDXGIFactory *factory,
|
||||
const DXGI_ADAPTER_DESC &AdapterDesc, bool *useWarp,
|
||||
IDXGIAdapter **adapter)
|
||||
const DXGI_ADAPTER_DESC &AdapterDesc, const ReplayOptions &opts,
|
||||
bool *useWarp, IDXGIAdapter **adapter)
|
||||
{
|
||||
bool retWarp = false;
|
||||
IDXGIAdapter *ret = NULL;
|
||||
DXGI_ADAPTER_DESC retDesc = {};
|
||||
|
||||
bool warpAvailable = false;
|
||||
IDXGIAdapter *warpAdapter = NULL;
|
||||
|
||||
if(api == GraphicsAPI::D3D11)
|
||||
{
|
||||
// D3D11 WARP is always available, we assume.
|
||||
warpAvailable = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// on D3D12 we don't have WARP when we're on 12On7. The easy way to check this is to try and
|
||||
// fetch a IDXGIFactory4, which we want to do anyway to get the warp adapter.
|
||||
IDXGIFactory4 *factory4 = NULL;
|
||||
HRESULT hr = factory->QueryInterface(__uuidof(IDXGIFactory4), (void **)&factory4);
|
||||
if(SUCCEEDED(hr) && factory4)
|
||||
{
|
||||
hr = factory4->EnumWarpAdapter(__uuidof(IDXGIAdapter), (void **)&warpAdapter);
|
||||
|
||||
if(FAILED(hr) || !warpAdapter)
|
||||
{
|
||||
RDCWARN("Couldn't enumerate WARP adapter from IDXGIFactory4");
|
||||
}
|
||||
}
|
||||
|
||||
warpAvailable = warpAdapter != NULL;
|
||||
|
||||
SAFE_RELEASE(factory4);
|
||||
}
|
||||
|
||||
// if we're forcing WARP, try that first
|
||||
if(opts.forceGPUVendor == GPUVendor::Software)
|
||||
{
|
||||
if(warpAvailable)
|
||||
{
|
||||
if(useWarp)
|
||||
*useWarp = true;
|
||||
if(adapter)
|
||||
*adapter = warpAdapter;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCWARN("WARP is not available to replay on. Falling back to default adapter selection.");
|
||||
}
|
||||
}
|
||||
else if(opts.forceGPUVendor != GPUVendor::Unknown)
|
||||
{
|
||||
// otherwise we're trying to force a device, see if we can get it
|
||||
ret = EnumBestAdapter(factory, opts.forceGPUVendor, opts.forceGPUDeviceID);
|
||||
|
||||
if(ret == NULL)
|
||||
{
|
||||
RDCLOG(
|
||||
"Couldn't find specified adapter to replay on, falling back to default adapter "
|
||||
"selection");
|
||||
}
|
||||
else
|
||||
{
|
||||
DXGI_ADAPTER_DESC retDesc = {};
|
||||
ret->GetDesc(&retDesc);
|
||||
RDCLOG("Forcing use of %s / %ls adapter for replay",
|
||||
ToStr(GPUVendorFromPCIVendor(retDesc.VendorId)).c_str(), retDesc.Description);
|
||||
|
||||
if(useWarp)
|
||||
*useWarp = false;
|
||||
if(adapter)
|
||||
*adapter = ret;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// default selection algorithm
|
||||
|
||||
GPUVendor vendor = GPUVendorFromPCIVendor(AdapterDesc.VendorId);
|
||||
|
||||
@@ -1750,43 +1869,23 @@ void ChooseBestMatchingAdapter(GraphicsAPI api, IDXGIFactory *factory,
|
||||
if(!wcscmp(AdapterDesc.Description, L"Software Adapter"))
|
||||
vendor = GPUVendor::Software;
|
||||
|
||||
// if the vendor is software we should try to use WARP
|
||||
// if we're forcing WARP, try that first we should try to use WARP
|
||||
if(vendor == GPUVendor::Software)
|
||||
{
|
||||
retWarp = true;
|
||||
|
||||
// D3D11 WARP is always available, we assume.
|
||||
if(api == GraphicsAPI::D3D11)
|
||||
if(warpAvailable)
|
||||
{
|
||||
ret = NULL;
|
||||
ret = warpAdapter;
|
||||
warpAdapter = NULL;
|
||||
retWarp = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// on D3D12 we don't have WARP when we're on 12On7. The easy way to check this is to try and
|
||||
// fetch a IDXGIFactory4, which we want to do anyway to get the warp adapter.
|
||||
IDXGIFactory4 *factory4 = NULL;
|
||||
HRESULT hr = factory->QueryInterface(__uuidof(IDXGIFactory4), (void **)&factory4);
|
||||
if(SUCCEEDED(hr) && factory4)
|
||||
{
|
||||
hr = factory4->EnumWarpAdapter(__uuidof(IDXGIAdapter), (void **)&ret);
|
||||
RDCWARN(
|
||||
"WARP would be the selected adapter, but is not available. Falling back to default "
|
||||
"adapter selection.");
|
||||
|
||||
if(FAILED(hr) || !ret)
|
||||
{
|
||||
RDCWARN("Couldn't enumerate WARP adapter from IDXGIFactory4");
|
||||
retWarp = false;
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if WARP isn't available, fall back
|
||||
RDCWARN(
|
||||
"WARP is the best matching adapter, but is not available. Falling back to default "
|
||||
"adapter selection.");
|
||||
|
||||
retWarp = false;
|
||||
ret = NULL;
|
||||
}
|
||||
retWarp = false;
|
||||
ret = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1795,51 +1894,24 @@ void ChooseBestMatchingAdapter(GraphicsAPI api, IDXGIFactory *factory,
|
||||
// matching adapter
|
||||
if(retWarp == false && ret == NULL && AdapterDesc.Description[0])
|
||||
{
|
||||
for(UINT i = 0; i < 10; i++)
|
||||
{
|
||||
IDXGIAdapter *ad = NULL;
|
||||
HRESULT hr = factory->EnumAdapters(i, &ad);
|
||||
if(hr == S_OK && ad)
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
ad->GetDesc(&desc);
|
||||
|
||||
// if it's a better vendor match than the adapter we have, choose it
|
||||
if(desc.VendorId == AdapterDesc.VendorId && retDesc.VendorId != AdapterDesc.VendorId)
|
||||
{
|
||||
ret = ad;
|
||||
retDesc = desc;
|
||||
continue;
|
||||
}
|
||||
else if(desc.VendorId != AdapterDesc.VendorId)
|
||||
{
|
||||
ad->Release();
|
||||
continue;
|
||||
}
|
||||
|
||||
// if they're the same vendor but this is a better device match, choose it
|
||||
if(desc.DeviceId == AdapterDesc.DeviceId && retDesc.DeviceId != AdapterDesc.DeviceId)
|
||||
{
|
||||
ret = ad;
|
||||
retDesc = desc;
|
||||
continue;
|
||||
}
|
||||
|
||||
ad->Release();
|
||||
}
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
ret =
|
||||
EnumBestAdapter(factory, GPUVendorFromPCIVendor(AdapterDesc.VendorId), AdapterDesc.DeviceId);
|
||||
|
||||
if(ret == NULL)
|
||||
{
|
||||
RDCLOG("Couldn't find similar adapter to replay on, using default adapter");
|
||||
}
|
||||
else
|
||||
{
|
||||
DXGI_ADAPTER_DESC retDesc = {};
|
||||
ret->GetDesc(&retDesc);
|
||||
RDCLOG("Selected %s / %ls adapter for replay",
|
||||
ToStr(GPUVendorFromPCIVendor(retDesc.VendorId)).c_str(), retDesc.Description);
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_RELEASE(warpAdapter);
|
||||
|
||||
if(useWarp)
|
||||
*useWarp = retWarp;
|
||||
if(adapter)
|
||||
|
||||
@@ -70,8 +70,8 @@ void WarnUnknownGUID(const char *name, REFIID riid);
|
||||
|
||||
std::string GetDriverVersion(DXGI_ADAPTER_DESC &desc);
|
||||
void ChooseBestMatchingAdapter(GraphicsAPI api, IDXGIFactory *factory,
|
||||
const DXGI_ADAPTER_DESC &AdapterDesc, bool *useWarp,
|
||||
IDXGIAdapter **adapter);
|
||||
const DXGI_ADAPTER_DESC &AdapterDesc, const ReplayOptions &opts,
|
||||
bool *useWarp, IDXGIAdapter **adapter);
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(DXGI_SAMPLE_DESC);
|
||||
DECLARE_REFLECTION_STRUCT(DXGI_ADAPTER_DESC);
|
||||
|
||||
@@ -710,10 +710,12 @@ WrappedOpenGL::WrappedOpenGL(GLPlatform &platform)
|
||||
m_CurCtxDataTLS = Threading::AllocateTLSSlot();
|
||||
}
|
||||
|
||||
void WrappedOpenGL::Initialise(GLInitParams ¶ms, uint64_t sectionVersion)
|
||||
void WrappedOpenGL::Initialise(GLInitParams ¶ms, uint64_t sectionVersion,
|
||||
const ReplayOptions &opts)
|
||||
{
|
||||
m_SectionVersion = sectionVersion;
|
||||
m_GlobalInitParams = params;
|
||||
m_ReplayOptions = opts;
|
||||
}
|
||||
|
||||
void WrappedOpenGL::MarkReferencedWhileCapturing(GLResourceRecord *record, FrameRefType refType)
|
||||
|
||||
@@ -130,6 +130,7 @@ private:
|
||||
|
||||
uint64_t m_SectionVersion;
|
||||
GLInitParams m_GlobalInitParams;
|
||||
ReplayOptions m_ReplayOptions;
|
||||
|
||||
WriteSerialiser m_ScratchSerialiser;
|
||||
std::set<std::string> m_StringDB;
|
||||
@@ -569,7 +570,7 @@ public:
|
||||
|
||||
bool IsUnsafeDraw(uint32_t eventId) { return m_UnsafeDraws.find(eventId) != m_UnsafeDraws.end(); }
|
||||
// replay interface
|
||||
void Initialise(GLInitParams ¶ms, uint64_t sectionVersion);
|
||||
void Initialise(GLInitParams ¶ms, uint64_t sectionVersion, const ReplayOptions &opts);
|
||||
void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
|
||||
ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers);
|
||||
|
||||
|
||||
@@ -3465,7 +3465,7 @@ ReplayStatus CreateReplayDevice(RDCDriver rdcdriver, RDCFile *rdc, const ReplayO
|
||||
replay->SetProxy(rdc == NULL);
|
||||
replay->SetReplayData(data);
|
||||
|
||||
gldriver->Initialise(initParams, ver);
|
||||
gldriver->Initialise(initParams, ver, opts);
|
||||
|
||||
*driver = (IReplayDriver *)replay;
|
||||
return ReplayStatus::Succeeded;
|
||||
|
||||
@@ -720,6 +720,21 @@ StencilOperation MakeStencilOp(VkStencilOp op)
|
||||
return StencilOperation::Keep;
|
||||
}
|
||||
|
||||
rdcstr HumanDriverName(VkDriverIdKHR driverId)
|
||||
{
|
||||
switch(driverId)
|
||||
{
|
||||
case VK_DRIVER_ID_AMD_PROPRIETARY_KHR: return "AMD Propriertary";
|
||||
case VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR: return "AMD Open-source";
|
||||
case VK_DRIVER_ID_MESA_RADV_KHR: return "AMD RADV";
|
||||
case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR: return "Intel Propriertary";
|
||||
case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR: return "Intel Open-source";
|
||||
default: break;
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
BASIC_TYPE_SERIALISE_STRINGIFY(VkPackedVersion, (uint32_t &)el, SDBasic::UnsignedInteger, 4);
|
||||
|
||||
INSTANTIATE_SERIALISE_TYPE(VkPackedVersion);
|
||||
|
||||
@@ -99,6 +99,7 @@ LogicOperation MakeLogicOp(VkLogicOp op);
|
||||
BlendMultiplier MakeBlendMultiplier(VkBlendFactor blend);
|
||||
BlendOperation MakeBlendOp(VkBlendOp op);
|
||||
StencilOperation MakeStencilOp(VkStencilOp op);
|
||||
rdcstr HumanDriverName(VkDriverIdKHR driverId);
|
||||
|
||||
// set conservative access bits for this image layout
|
||||
VkAccessFlags MakeAccessMask(VkImageLayout layout);
|
||||
|
||||
@@ -272,6 +272,7 @@ private:
|
||||
std::vector<TempMem *> m_ThreadTempMem;
|
||||
|
||||
VulkanReplay m_Replay;
|
||||
ReplayOptions m_ReplayOptions;
|
||||
|
||||
VkInitParams m_InitParams;
|
||||
uint64_t m_SectionVersion;
|
||||
@@ -932,7 +933,7 @@ public:
|
||||
uint32_t GetQueueFamilyIndex() { return m_QueueFamilyIdx; }
|
||||
bool ReleaseResource(WrappedVkRes *res);
|
||||
|
||||
ReplayStatus Initialise(VkInitParams ¶ms, uint64_t sectionVersion);
|
||||
ReplayStatus Initialise(VkInitParams ¶ms, uint64_t sectionVersion, const ReplayOptions &opts);
|
||||
uint64_t GetLogVersion() { return m_SectionVersion; }
|
||||
void SetStructuredExport(uint64_t sectionVersion)
|
||||
{
|
||||
|
||||
@@ -139,15 +139,7 @@ rdcarray<GPUDevice> VulkanReplay::GetAvailableGPUs()
|
||||
dev.apis = {GraphicsAPI::Vulkan};
|
||||
|
||||
// only set the driver name when it's useful to disambiguate
|
||||
switch(driverProps.driverID)
|
||||
{
|
||||
default: dev.driver = "";
|
||||
case VK_DRIVER_ID_AMD_PROPRIETARY_KHR: dev.driver = "AMD Propriertary"; break;
|
||||
case VK_DRIVER_ID_AMD_OPEN_SOURCE_KHR: dev.driver = "AMD Open-source"; break;
|
||||
case VK_DRIVER_ID_MESA_RADV_KHR: dev.driver = "AMD RADV"; break;
|
||||
case VK_DRIVER_ID_INTEL_PROPRIETARY_WINDOWS_KHR: dev.driver = "Intel Propriertary"; break;
|
||||
case VK_DRIVER_ID_INTEL_OPEN_SOURCE_MESA_KHR: dev.driver = "Intel Open-source"; break;
|
||||
}
|
||||
dev.driver = HumanDriverName(driverProps.driverID);
|
||||
|
||||
// don't add duplicate devices even if they get enumerated.
|
||||
if(ret.indexOf(dev) == -1)
|
||||
@@ -4204,7 +4196,7 @@ ReplayStatus Vulkan_CreateReplayDevice(RDCFile *rdc, const ReplayOptions &opts,
|
||||
SAFE_DELETE(rgp);
|
||||
|
||||
WrappedVulkan *vk = new WrappedVulkan();
|
||||
ReplayStatus status = vk->Initialise(initParams, ver);
|
||||
ReplayStatus status = vk->Initialise(initParams, ver, opts);
|
||||
|
||||
if(status != ReplayStatus::Succeeded)
|
||||
{
|
||||
|
||||
@@ -170,10 +170,12 @@ static void StripUnwantedExtensions(std::vector<std::string> &Extensions)
|
||||
}
|
||||
}
|
||||
|
||||
ReplayStatus WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVersion)
|
||||
ReplayStatus WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVersion,
|
||||
const ReplayOptions &opts)
|
||||
{
|
||||
m_InitParams = params;
|
||||
m_SectionVersion = sectionVersion;
|
||||
m_ReplayOptions = opts;
|
||||
|
||||
StripUnwantedLayers(params.Layers);
|
||||
StripUnwantedExtensions(params.Extensions);
|
||||
@@ -988,12 +990,20 @@ bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(SerialiserType &ser, Vk
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR,
|
||||
};
|
||||
|
||||
rdcarray<VkPhysicalDeviceProperties> compPhysPropsArray;
|
||||
rdcarray<VkPhysicalDeviceDriverPropertiesKHR> compDriverPropsArray;
|
||||
|
||||
compPhysPropsArray.resize(m_ReplayPhysicalDevices.size());
|
||||
compDriverPropsArray.resize(m_ReplayPhysicalDevices.size());
|
||||
|
||||
// first cache all the physical device data to compare against
|
||||
for(uint32_t i = 0; i < (uint32_t)m_ReplayPhysicalDevices.size(); i++)
|
||||
{
|
||||
VkPhysicalDeviceProperties compPhysProps = {};
|
||||
VkPhysicalDeviceDriverPropertiesKHR compDriverProps = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR,
|
||||
};
|
||||
VkPhysicalDeviceProperties &compPhysProps = compPhysPropsArray[i];
|
||||
RDCEraseEl(compPhysProps);
|
||||
VkPhysicalDeviceDriverPropertiesKHR &compDriverProps = compDriverPropsArray[i];
|
||||
RDCEraseEl(compDriverProps);
|
||||
compDriverProps.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR;
|
||||
|
||||
pd = m_ReplayPhysicalDevices[i];
|
||||
|
||||
@@ -1043,84 +1053,167 @@ bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(SerialiserType &ser, Vk
|
||||
compDriverProps.conformanceVersion.subminor, compDriverProps.conformanceVersion.patch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// the first is the best at the start
|
||||
if(i == 0)
|
||||
// if we're forcing use of a GPU, try to find that one
|
||||
bool forced = false;
|
||||
if(m_ReplayOptions.forceGPUVendor != GPUVendor::Unknown)
|
||||
{
|
||||
for(uint32_t i = 0; i < (uint32_t)m_ReplayPhysicalDevices.size(); i++)
|
||||
{
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
const VkPhysicalDeviceProperties &compPhysProps = compPhysPropsArray[i];
|
||||
const VkPhysicalDeviceDriverPropertiesKHR &compDriverProps = compDriverPropsArray[i];
|
||||
|
||||
// an exact vendorID match is a better match than not
|
||||
if(compPhysProps.vendorID == physProps.vendorID && bestPhysProps.vendorID != physProps.vendorID)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
else if(compPhysProps.vendorID != physProps.vendorID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
VkDriverInfo bestInfo(bestPhysProps);
|
||||
VkDriverInfo compInfo(compPhysProps);
|
||||
|
||||
// ditto deviceID
|
||||
if(compPhysProps.deviceID == physProps.deviceID && bestPhysProps.deviceID != physProps.deviceID)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
else if(compPhysProps.deviceID != physProps.deviceID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// an exact vendorID match is a better match than not
|
||||
if(compInfo.Vendor() == m_ReplayOptions.forceGPUVendor &&
|
||||
bestInfo.Vendor() != m_ReplayOptions.forceGPUVendor)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
forced = true;
|
||||
continue;
|
||||
}
|
||||
else if(compInfo.Vendor() != m_ReplayOptions.forceGPUVendor)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// driver matching. Only do this if both capture and replay gave us valid driver info to
|
||||
// compare
|
||||
if(compDriverProps.driverID && driverProps.driverID)
|
||||
// ditto deviceID
|
||||
if(compPhysProps.deviceID == m_ReplayOptions.forceGPUDeviceID &&
|
||||
bestPhysProps.deviceID != m_ReplayOptions.forceGPUDeviceID)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
forced = true;
|
||||
continue;
|
||||
}
|
||||
else if(compPhysProps.deviceID != m_ReplayOptions.forceGPUDeviceID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// driver matching. Only do this if we have a driver name to look at
|
||||
if(compDriverProps.driverID && !m_ReplayOptions.forceGPUDriverName.empty())
|
||||
{
|
||||
rdcstr compHumanDriverName = HumanDriverName(compDriverProps.driverID);
|
||||
rdcstr bestHumanDriverName = HumanDriverName(bestDriverProps.driverID);
|
||||
|
||||
// check for a better driverID match
|
||||
if(compHumanDriverName == m_ReplayOptions.forceGPUDriverName &&
|
||||
bestHumanDriverName != m_ReplayOptions.forceGPUDriverName)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
forced = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(forced)
|
||||
{
|
||||
RDCLOG("Forcing use of physical device");
|
||||
}
|
||||
else
|
||||
{
|
||||
bestIdx = 0;
|
||||
RDCEraseEl(bestPhysProps);
|
||||
RDCEraseEl(bestDriverProps);
|
||||
|
||||
for(uint32_t i = 0; i < (uint32_t)m_ReplayPhysicalDevices.size(); i++)
|
||||
{
|
||||
// check for a better driverID match
|
||||
if(compDriverProps.driverID == driverProps.driverID &&
|
||||
bestDriverProps.driverID != driverProps.driverID)
|
||||
const VkPhysicalDeviceProperties &compPhysProps = compPhysPropsArray[i];
|
||||
const VkPhysicalDeviceDriverPropertiesKHR &compDriverProps = compDriverPropsArray[i];
|
||||
|
||||
pd = m_ReplayPhysicalDevices[i];
|
||||
|
||||
// the first is the best at the start
|
||||
if(i == 0)
|
||||
{
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
|
||||
// an exact vendorID match is a better match than not
|
||||
if(compPhysProps.vendorID == physProps.vendorID &&
|
||||
bestPhysProps.vendorID != physProps.vendorID)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
else if(compDriverProps.driverID != driverProps.driverID)
|
||||
else if(compPhysProps.vendorID != physProps.vendorID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// if we have an exact driver version match, prefer that
|
||||
if(compPhysProps.driverVersion == physProps.driverVersion &&
|
||||
bestPhysProps.driverVersion != physProps.driverVersion)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
else if(compPhysProps.driverVersion != physProps.driverVersion)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
// ditto deviceID
|
||||
if(compPhysProps.deviceID == physProps.deviceID &&
|
||||
bestPhysProps.deviceID != physProps.deviceID)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
else if(compPhysProps.deviceID != physProps.deviceID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we have multiple identical devices, which isn't uncommon, favour the one
|
||||
// that hasn't been assigned
|
||||
if(m_ReplayPhysicalDevicesUsed[bestIdx] && !m_ReplayPhysicalDevicesUsed[i])
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
continue;
|
||||
}
|
||||
// driver matching. Only do this if both capture and replay gave us valid driver info to
|
||||
// compare
|
||||
if(compDriverProps.driverID && driverProps.driverID)
|
||||
{
|
||||
// check for a better driverID match
|
||||
if(compDriverProps.driverID == driverProps.driverID &&
|
||||
bestDriverProps.driverID != driverProps.driverID)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
else if(compDriverProps.driverID != driverProps.driverID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// this device isn't any better, ignore it
|
||||
// if we have an exact driver version match, prefer that
|
||||
if(compPhysProps.driverVersion == physProps.driverVersion &&
|
||||
bestPhysProps.driverVersion != physProps.driverVersion)
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
bestDriverProps = compDriverProps;
|
||||
continue;
|
||||
}
|
||||
else if(compPhysProps.driverVersion != physProps.driverVersion)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// if we have multiple identical devices, which isn't uncommon, favour the one
|
||||
// that hasn't been assigned
|
||||
if(m_ReplayPhysicalDevicesUsed[bestIdx] && !m_ReplayPhysicalDevicesUsed[i])
|
||||
{
|
||||
bestIdx = i;
|
||||
bestPhysProps = compPhysProps;
|
||||
continue;
|
||||
}
|
||||
|
||||
// this device isn't any better, ignore it
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
@@ -1139,7 +1232,8 @@ bool WrappedVulkan::Serialise_vkEnumeratePhysicalDevices(SerialiserType &ser, Vk
|
||||
driverProps.conformanceVersion.patch);
|
||||
}
|
||||
|
||||
RDCLOG("Mapping during replay to best-match physical device %u", bestIdx);
|
||||
RDCLOG("Mapping during replay to %s physical device %u", forced ? "forced" : "best-match",
|
||||
bestIdx);
|
||||
}
|
||||
|
||||
pd = m_ReplayPhysicalDevices[bestIdx];
|
||||
|
||||
Reference in New Issue
Block a user