Implement forced GPU override on D3D11, D3D12 and Vulkan

This commit is contained in:
baldurk
2019-08-27 18:51:56 +01:00
parent 20be9f3d52
commit b0933dcf33
14 changed files with 342 additions and 158 deletions
+3 -1
View File
@@ -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 &params, uint64_t sectionVersion)
void SetInitParams(const D3D11InitParams &params, uint64_t sectionVersion, const ReplayOptions &opts)
{
m_InitParams = params;
m_SectionVersion = sectionVersion;
m_ReplayOptions = opts;
}
uint64_t GetLogVersion() { return m_SectionVersion; }
virtual ~WrappedID3D11Device();
+3 -2
View File
@@ -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();
+3 -1
View File
@@ -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 &params, uint64_t sectionVersion)
void SetInitParams(const D3D12InitParams &params, 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; }
+3 -2
View File
@@ -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();
+142 -70
View File
@@ -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)
+2 -2
View File
@@ -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);
+3 -1
View File
@@ -710,10 +710,12 @@ WrappedOpenGL::WrappedOpenGL(GLPlatform &platform)
m_CurCtxDataTLS = Threading::AllocateTLSSlot();
}
void WrappedOpenGL::Initialise(GLInitParams &params, uint64_t sectionVersion)
void WrappedOpenGL::Initialise(GLInitParams &params, uint64_t sectionVersion,
const ReplayOptions &opts)
{
m_SectionVersion = sectionVersion;
m_GlobalInitParams = params;
m_ReplayOptions = opts;
}
void WrappedOpenGL::MarkReferencedWhileCapturing(GLResourceRecord *record, FrameRefType refType)
+2 -1
View File
@@ -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 &params, uint64_t sectionVersion);
void Initialise(GLInitParams &params, uint64_t sectionVersion, const ReplayOptions &opts);
void ReplayLog(uint32_t startEventID, uint32_t endEventID, ReplayLogType replayType);
ReplayStatus ReadLogInitialisation(RDCFile *rdc, bool storeStructuredBuffers);
+1 -1
View File
@@ -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;
+15
View File
@@ -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);
+1
View File
@@ -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);
+2 -1
View File
@@ -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 &params, uint64_t sectionVersion);
ReplayStatus Initialise(VkInitParams &params, uint64_t sectionVersion, const ReplayOptions &opts);
uint64_t GetLogVersion() { return m_SectionVersion; }
void SetStructuredExport(uint64_t sectionVersion)
{
+2 -10
View File
@@ -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 &params, uint64_t sectionVersion)
ReplayStatus WrappedVulkan::Initialise(VkInitParams &params, 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];