mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-08-28 17:36:36 +00:00
Add a function to enumerate which GPUs are available at replay time
This commit is contained in:
@@ -314,6 +314,8 @@ TEMPLATE_ARRAY_INSTANTIATE(rdcarray, VertexInputAttribute)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResource)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, BoundResourceArray)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, FloatVector)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, GraphicsAPI)
|
||||
TEMPLATE_ARRAY_INSTANTIATE(rdcarray, GPUDevice)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, Attachment)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, BindingElement)
|
||||
TEMPLATE_NAMESPACE_ARRAY_INSTANTIATE(rdcarray, VKPipe, DescriptorBinding)
|
||||
|
||||
@@ -660,3 +660,41 @@ structured data.
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(CaptureFileFormat);
|
||||
|
||||
DOCUMENT("Describes a single GPU at replay time.");
|
||||
struct GPUDevice
|
||||
{
|
||||
DOCUMENT("");
|
||||
GPUDevice() = default;
|
||||
GPUDevice(const GPUDevice &) = default;
|
||||
|
||||
bool operator==(const GPUDevice &o) const
|
||||
{
|
||||
// deliberately don't compare name or APIs - only this triple counts for equality
|
||||
return vendor == o.vendor && deviceID == o.deviceID && driver == o.driver;
|
||||
}
|
||||
bool operator<(const GPUDevice &o) const
|
||||
{
|
||||
if(!(vendor == o.vendor))
|
||||
return vendor < o.vendor;
|
||||
if(!(deviceID == o.deviceID))
|
||||
return deviceID < o.deviceID;
|
||||
if(!(driver == o.driver))
|
||||
return driver < o.driver;
|
||||
return false;
|
||||
}
|
||||
DOCUMENT("The :class:`GPUVendor` of this GPU.");
|
||||
GPUVendor vendor = GPUVendor::Unknown;
|
||||
DOCUMENT("The PCI deviceID of this GPU.");
|
||||
uint32_t deviceID = 0;
|
||||
DOCUMENT("The name of the driver of this GPU, if multiple drivers are available for it.");
|
||||
rdcstr driver;
|
||||
|
||||
DOCUMENT("The human-readable name of this GPU.");
|
||||
rdcstr name;
|
||||
|
||||
DOCUMENT("The list of APIs that this device supports.");
|
||||
rdcarray<GraphicsAPI> apis;
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(GPUDevice);
|
||||
|
||||
@@ -1451,6 +1451,14 @@ and construction of files.
|
||||
)");
|
||||
struct ICaptureAccess
|
||||
{
|
||||
DOCUMENT(R"(Returns the list of available GPUs, that can be used in combination with
|
||||
:class:`ReplayOptions` to force replay on a particular GPU.
|
||||
|
||||
:return: The list of GPUs available.
|
||||
:rtype: ``list`` of :class:`GPUDevice`
|
||||
)");
|
||||
virtual rdcarray<GPUDevice> GetAvailableGPUs() = 0;
|
||||
|
||||
DOCUMENT(R"(Retrieve the total number of available sections.
|
||||
|
||||
:return: The number of sections in the capture
|
||||
|
||||
@@ -1131,6 +1131,118 @@ std::vector<CaptureFileFormat> RenderDoc::GetCaptureFileFormats()
|
||||
return ret;
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> RenderDoc::GetAvailableGPUs()
|
||||
{
|
||||
if(m_AvailableGPUs.empty())
|
||||
{
|
||||
for(GraphicsAPI api : {GraphicsAPI::D3D11, GraphicsAPI::D3D12, GraphicsAPI::Vulkan})
|
||||
{
|
||||
RDCDriver driverType = RDCDriver::Unknown;
|
||||
|
||||
switch(api)
|
||||
{
|
||||
case GraphicsAPI::D3D11: driverType = RDCDriver::D3D11; break;
|
||||
case GraphicsAPI::D3D12: driverType = RDCDriver::D3D12; break;
|
||||
case GraphicsAPI::OpenGL: break;
|
||||
case GraphicsAPI::Vulkan: driverType = RDCDriver::Vulkan; break;
|
||||
}
|
||||
|
||||
if(driverType == RDCDriver::Unknown || !HasReplayDriver(driverType))
|
||||
continue;
|
||||
|
||||
IReplayDriver *driver = NULL;
|
||||
ReplayStatus status = CreateProxyReplayDriver(driverType, &driver);
|
||||
|
||||
if(status == ReplayStatus::Succeeded)
|
||||
{
|
||||
rdcarray<GPUDevice> gpus = driver->GetAvailableGPUs();
|
||||
|
||||
for(const GPUDevice &newgpu : gpus)
|
||||
{
|
||||
bool addnew = true;
|
||||
|
||||
for(GPUDevice &oldgpu : m_AvailableGPUs)
|
||||
{
|
||||
// if we have this GPU listed already, just add its API to the previous list
|
||||
if(oldgpu == newgpu)
|
||||
{
|
||||
oldgpu.apis.push_back(api);
|
||||
addnew = false;
|
||||
}
|
||||
}
|
||||
|
||||
if(addnew)
|
||||
m_AvailableGPUs.push_back(newgpu);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Couldn't create proxy replay driver for %s: %s", ToStr(driverType).c_str(),
|
||||
ToStr(status).c_str());
|
||||
}
|
||||
|
||||
if(driver)
|
||||
driver->Shutdown();
|
||||
}
|
||||
|
||||
// we now have a list of GPUs, however we might have some duplicates if some APIs have
|
||||
// multiple drivers for a single device. To compact this list, for each GPU with no driver
|
||||
// we find all matching multi-drive GPUs and merge it into all matching copies.
|
||||
bool hasDriverNames = false;
|
||||
for(size_t i = 0; i < m_AvailableGPUs.size(); i++)
|
||||
hasDriverNames |= !m_AvailableGPUs[i].driver.empty();
|
||||
|
||||
if(hasDriverNames)
|
||||
{
|
||||
for(size_t i = 0; i < m_AvailableGPUs.size();)
|
||||
{
|
||||
bool applied = false;
|
||||
|
||||
if(!m_AvailableGPUs[i].driver.empty())
|
||||
{
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// scan all subsequent GPUs, if we find a duplicate, merge the APIs
|
||||
for(size_t j = i + 1; j < m_AvailableGPUs.size(); j++)
|
||||
{
|
||||
if(m_AvailableGPUs[i].vendor == m_AvailableGPUs[j].vendor &&
|
||||
m_AvailableGPUs[i].deviceID == m_AvailableGPUs[j].deviceID)
|
||||
{
|
||||
RDCASSERT(!m_AvailableGPUs[j].driver.empty());
|
||||
for(GraphicsAPI a : m_AvailableGPUs[i].apis)
|
||||
{
|
||||
if(m_AvailableGPUs[j].apis.indexOf(a) == -1)
|
||||
m_AvailableGPUs[j].apis.push_back(a);
|
||||
}
|
||||
applied = true;
|
||||
}
|
||||
}
|
||||
|
||||
// we "applied" this GPU to all its driver-based duplicates, so we can remove it now
|
||||
if(applied)
|
||||
{
|
||||
m_AvailableGPUs.erase(i);
|
||||
}
|
||||
else
|
||||
{
|
||||
i++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// sort the APIs list in each GPU, and sort the GPUs
|
||||
std::sort(m_AvailableGPUs.begin(), m_AvailableGPUs.end());
|
||||
for(GPUDevice &dev : m_AvailableGPUs)
|
||||
{
|
||||
std::sort(dev.apis.begin(), dev.apis.end());
|
||||
}
|
||||
}
|
||||
|
||||
return m_AvailableGPUs;
|
||||
}
|
||||
|
||||
bool RenderDoc::HasReplaySupport(RDCDriver driverType)
|
||||
{
|
||||
if(driverType == RDCDriver::Image)
|
||||
|
||||
@@ -496,6 +496,7 @@ public:
|
||||
IDeviceProtocolHandler *GetDeviceProtocol(const rdcstr &protocol);
|
||||
|
||||
std::vector<CaptureFileFormat> GetCaptureFileFormats();
|
||||
rdcarray<GPUDevice> GetAvailableGPUs();
|
||||
|
||||
void SetVulkanLayerCheck(VulkanLayerCheck callback) { m_VulkanCheck = callback; }
|
||||
void SetVulkanLayerInstall(VulkanLayerInstall callback) { m_VulkanInstall = callback; }
|
||||
@@ -635,6 +636,8 @@ private:
|
||||
Threading::CriticalSection m_DriverLock;
|
||||
std::map<RDCDriver, uint64_t> m_ActiveDrivers;
|
||||
|
||||
rdcarray<GPUDevice> m_AvailableGPUs;
|
||||
|
||||
std::map<rdcstr, RENDERDOC_ProgressCallback> m_ProgressCallbacks;
|
||||
|
||||
Threading::CriticalSection m_CaptureLock;
|
||||
|
||||
@@ -196,6 +196,7 @@ public:
|
||||
DriverInformation ret = {};
|
||||
return ret;
|
||||
}
|
||||
rdcarray<GPUDevice> GetAvailableGPUs() { return {}; }
|
||||
const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; }
|
||||
const GLPipe::State *GetGLPipelineState() { return NULL; }
|
||||
const VKPipe::State *GetVulkanPipelineState() { return NULL; }
|
||||
|
||||
@@ -71,6 +71,7 @@ enum RemoteServerPacket
|
||||
eRemoteServer_GetSectionProperties,
|
||||
eRemoteServer_GetSectionContents,
|
||||
eRemoteServer_WriteSection,
|
||||
eRemoteServer_GetAvailableGPUs,
|
||||
eRemoteServer_RemoteServerCount,
|
||||
};
|
||||
|
||||
@@ -367,6 +368,18 @@ static void ActiveRemoteClientThread(ClientThread *threadData,
|
||||
|
||||
tempFiles.push_back(path);
|
||||
}
|
||||
else if(type == eRemoteServer_GetAvailableGPUs)
|
||||
{
|
||||
reader.EndChunk();
|
||||
|
||||
rdcarray<GPUDevice> gpus = RenderDoc::Inst().GetAvailableGPUs();
|
||||
|
||||
{
|
||||
WRITE_DATA_SCOPE();
|
||||
SCOPED_SERIALISE_CHUNK(eRemoteServer_GetAvailableGPUs);
|
||||
SERIALISE_ELEMENT(gpus);
|
||||
}
|
||||
}
|
||||
else if(type == eRemoteServer_ShutdownServer)
|
||||
{
|
||||
reader.EndChunk();
|
||||
@@ -1568,6 +1581,37 @@ rdcstr RemoteServer::DriverName()
|
||||
return driverName;
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> RemoteServer::GetAvailableGPUs()
|
||||
{
|
||||
if(!Connected())
|
||||
return {};
|
||||
|
||||
{
|
||||
WRITE_DATA_SCOPE();
|
||||
SCOPED_SERIALISE_CHUNK(eRemoteServer_GetAvailableGPUs);
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> gpus;
|
||||
|
||||
{
|
||||
READ_DATA_SCOPE();
|
||||
RemoteServerPacket type = ser.ReadChunk<RemoteServerPacket>();
|
||||
|
||||
if(type == eRemoteServer_GetAvailableGPUs)
|
||||
{
|
||||
SERIALISE_ELEMENT(gpus);
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Unexpected response to GetAvailableGPUs");
|
||||
}
|
||||
|
||||
ser.EndChunk();
|
||||
}
|
||||
|
||||
return gpus;
|
||||
}
|
||||
|
||||
int RemoteServer::GetSectionCount()
|
||||
{
|
||||
if(!Connected())
|
||||
|
||||
@@ -77,6 +77,8 @@ public:
|
||||
|
||||
virtual rdcstr DriverName();
|
||||
|
||||
virtual rdcarray<GPUDevice> GetAvailableGPUs();
|
||||
|
||||
virtual int GetSectionCount();
|
||||
|
||||
virtual int FindSectionByName(const char *name);
|
||||
|
||||
@@ -324,6 +324,35 @@ DriverInformation ReplayProxy::GetDriverInfo()
|
||||
PROXY_FUNCTION(GetDriverInfo);
|
||||
}
|
||||
|
||||
template <typename ParamSerialiser, typename ReturnSerialiser>
|
||||
rdcarray<GPUDevice> ReplayProxy::Proxied_GetAvailableGPUs(ParamSerialiser ¶mser,
|
||||
ReturnSerialiser &retser)
|
||||
{
|
||||
const ReplayProxyPacket expectedPacket = eReplayProxy_GetAvailableGPUs;
|
||||
ReplayProxyPacket packet = eReplayProxy_GetAvailableGPUs;
|
||||
rdcarray<GPUDevice> ret = {};
|
||||
|
||||
{
|
||||
BEGIN_PARAMS();
|
||||
END_PARAMS();
|
||||
}
|
||||
|
||||
{
|
||||
REMOTE_EXECUTION();
|
||||
if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored)
|
||||
ret = m_Remote->GetAvailableGPUs();
|
||||
}
|
||||
|
||||
SERIALISE_RETURN(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> ReplayProxy::GetAvailableGPUs()
|
||||
{
|
||||
PROXY_FUNCTION(GetAvailableGPUs);
|
||||
}
|
||||
|
||||
template <typename ParamSerialiser, typename ReturnSerialiser>
|
||||
std::vector<DebugMessage> ReplayProxy::Proxied_GetDebugMessages(ParamSerialiser ¶mser,
|
||||
ReturnSerialiser &retser)
|
||||
@@ -2663,6 +2692,7 @@ bool ReplayProxy::Tick(int type)
|
||||
case eReplayProxy_GetDisassemblyTargets: GetDisassemblyTargets(); break;
|
||||
case eReplayProxy_GetTargetShaderEncodings: GetTargetShaderEncodings(); break;
|
||||
case eReplayProxy_GetDriverInfo: GetDriverInfo(); break;
|
||||
case eReplayProxy_GetAvailableGPUs: GetAvailableGPUs(); break;
|
||||
default: RDCERR("Unexpected command %u", type); return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -99,6 +99,7 @@ enum ReplayProxyPacket
|
||||
eReplayProxy_GetTargetShaderEncodings,
|
||||
|
||||
eReplayProxy_GetDriverInfo,
|
||||
eReplayProxy_GetAvailableGPUs,
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_ENUM(ReplayProxyPacket);
|
||||
@@ -470,6 +471,7 @@ public:
|
||||
|
||||
IMPLEMENT_FUNCTION_PROXIED(APIProperties, GetAPIProperties);
|
||||
IMPLEMENT_FUNCTION_PROXIED(DriverInformation, GetDriverInfo);
|
||||
IMPLEMENT_FUNCTION_PROXIED(rdcarray<GPUDevice>, GetAvailableGPUs);
|
||||
|
||||
IMPLEMENT_FUNCTION_PROXIED(std::vector<DebugMessage>, GetDebugMessages);
|
||||
|
||||
|
||||
@@ -515,6 +515,50 @@ std::vector<DebugMessage> D3D11Replay::GetDebugMessages()
|
||||
return m_pDevice->GetDebugMessages();
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> D3D11Replay::GetAvailableGPUs()
|
||||
{
|
||||
rdcarray<GPUDevice> ret;
|
||||
|
||||
for(UINT i = 0; i < 10; i++)
|
||||
{
|
||||
IDXGIAdapter *adapter = NULL;
|
||||
|
||||
HRESULT hr = m_pFactory->EnumAdapters(i, &adapter);
|
||||
|
||||
if(SUCCEEDED(hr) && adapter)
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
adapter->GetDesc(&desc);
|
||||
|
||||
GPUDevice dev;
|
||||
dev.vendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
dev.deviceID = desc.DeviceId;
|
||||
dev.driver = ""; // D3D doesn't have multiple drivers per API
|
||||
dev.name = StringFormat::Wide2UTF8(desc.Description);
|
||||
dev.apis = {GraphicsAPI::D3D11};
|
||||
|
||||
// don't add duplicate devices even if they get enumerated. Don't add WARP, we'll do that
|
||||
// manually since it's inconsistently enumerated
|
||||
if(ret.indexOf(dev) == -1 && dev.vendor != GPUVendor::Software)
|
||||
ret.push_back(dev);
|
||||
}
|
||||
|
||||
SAFE_RELEASE(adapter);
|
||||
}
|
||||
|
||||
{
|
||||
GPUDevice dev;
|
||||
dev.vendor = GPUVendor::Software;
|
||||
dev.deviceID = 0;
|
||||
dev.driver = ""; // D3D doesn't have multiple drivers per API
|
||||
dev.name = "WARP Rasterizer";
|
||||
dev.apis = {GraphicsAPI::D3D11};
|
||||
ret.push_back(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
APIProperties D3D11Replay::GetAPIProperties()
|
||||
{
|
||||
APIProperties ret = m_pDevice->APIProps;
|
||||
|
||||
@@ -105,6 +105,7 @@ public:
|
||||
void DestroyResources();
|
||||
|
||||
DriverInformation GetDriverInfo() { return m_DriverInfo; }
|
||||
rdcarray<GPUDevice> GetAvailableGPUs();
|
||||
APIProperties GetAPIProperties();
|
||||
|
||||
ResourceDescription &GetResourceDesc(ResourceId id);
|
||||
|
||||
@@ -214,6 +214,52 @@ ReplayStatus D3D12Replay::ReadLogInitialisation(RDCFile *rdc, bool storeStructur
|
||||
return m_pDevice->ReadLogInitialisation(rdc, storeStructuredBuffers);
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> D3D12Replay::GetAvailableGPUs()
|
||||
{
|
||||
rdcarray<GPUDevice> ret;
|
||||
|
||||
for(UINT i = 0; i < 10; i++)
|
||||
{
|
||||
IDXGIAdapter *adapter = NULL;
|
||||
|
||||
HRESULT hr = m_pFactory->EnumAdapters(i, &adapter);
|
||||
|
||||
if(SUCCEEDED(hr) && adapter)
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc;
|
||||
adapter->GetDesc(&desc);
|
||||
|
||||
GPUDevice dev;
|
||||
dev.vendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
dev.deviceID = desc.DeviceId;
|
||||
dev.driver = ""; // D3D doesn't have multiple drivers per API
|
||||
dev.name = StringFormat::Wide2UTF8(desc.Description);
|
||||
dev.apis = {GraphicsAPI::D3D12};
|
||||
|
||||
// don't add duplicate devices even if they get enumerated. Don't add WARP, we'll do that
|
||||
// manually since it's inconsistently enumerated
|
||||
if(ret.indexOf(dev) == -1 && dev.vendor != GPUVendor::Software)
|
||||
ret.push_back(dev);
|
||||
}
|
||||
|
||||
SAFE_RELEASE(adapter);
|
||||
}
|
||||
|
||||
// add WARP as long as we're not 12On7 (where we can't use WARP)
|
||||
if(!m_D3D12On7)
|
||||
{
|
||||
GPUDevice dev;
|
||||
dev.vendor = GPUVendor::Software;
|
||||
dev.deviceID = 0;
|
||||
dev.driver = ""; // D3D doesn't have multiple drivers per API
|
||||
dev.name = "WARP Rasterizer";
|
||||
dev.apis = {GraphicsAPI::D3D12};
|
||||
ret.push_back(dev);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
APIProperties D3D12Replay::GetAPIProperties()
|
||||
{
|
||||
APIProperties ret = m_pDevice->APIProps;
|
||||
|
||||
@@ -65,6 +65,7 @@ public:
|
||||
void CreateResources();
|
||||
void DestroyResources();
|
||||
DriverInformation GetDriverInfo() { return m_DriverInfo; }
|
||||
rdcarray<GPUDevice> GetAvailableGPUs();
|
||||
APIProperties GetAPIProperties();
|
||||
|
||||
ResourceDescription &GetResourceDesc(ResourceId id);
|
||||
|
||||
@@ -167,6 +167,12 @@ ResourceId GLReplay::GetLiveID(ResourceId id)
|
||||
return m_pDriver->GetResourceManager()->GetLiveID(id);
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> GLReplay::GetAvailableGPUs()
|
||||
{
|
||||
// GL doesn't support multiple GPUs, return an empty list
|
||||
return {};
|
||||
}
|
||||
|
||||
APIProperties GLReplay::GetAPIProperties()
|
||||
{
|
||||
APIProperties ret = m_pDriver->APIProps;
|
||||
|
||||
@@ -91,6 +91,7 @@ public:
|
||||
|
||||
void SetDriver(WrappedOpenGL *d) { m_pDriver = d; }
|
||||
DriverInformation GetDriverInfo() { return m_DriverInfo; }
|
||||
rdcarray<GPUDevice> GetAvailableGPUs();
|
||||
APIProperties GetAPIProperties();
|
||||
|
||||
ResourceDescription &GetResourceDesc(ResourceId id);
|
||||
|
||||
@@ -80,6 +80,108 @@ void VulkanReplay::Shutdown()
|
||||
delete m_pDriver;
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> VulkanReplay::GetAvailableGPUs()
|
||||
{
|
||||
rdcarray<GPUDevice> ret;
|
||||
|
||||
// do a manual enumerate to avoid any possible remapping
|
||||
VkInstance instance = m_pDriver->GetInstance();
|
||||
|
||||
uint32_t count = 0;
|
||||
VkResult vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, NULL);
|
||||
|
||||
if(vkr != VK_SUCCESS)
|
||||
return ret;
|
||||
|
||||
VkPhysicalDevice *devices = new VkPhysicalDevice[count];
|
||||
|
||||
vkr = ObjDisp(instance)->EnumeratePhysicalDevices(Unwrap(instance), &count, devices);
|
||||
RDCASSERTEQUAL(vkr, VK_SUCCESS);
|
||||
|
||||
for(uint32_t p = 0; p < count; p++)
|
||||
{
|
||||
VkPhysicalDeviceProperties props = {};
|
||||
ObjDisp(instance)->GetPhysicalDeviceProperties(devices[p], &props);
|
||||
|
||||
VkPhysicalDeviceDriverPropertiesKHR driverProps = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_DRIVER_PROPERTIES_KHR,
|
||||
};
|
||||
|
||||
VkPhysicalDeviceProperties2 physProps2 = {
|
||||
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_PROPERTIES_2, &driverProps,
|
||||
};
|
||||
|
||||
// get driver properties if available
|
||||
if(m_pDriver->GetExtensions(GetRecord(instance)).ext_KHR_get_physical_device_properties2)
|
||||
{
|
||||
uint32_t extCount = 0;
|
||||
ObjDisp(instance)->EnumerateDeviceExtensionProperties(devices[p], NULL, &extCount, NULL);
|
||||
|
||||
VkExtensionProperties *extProps = new VkExtensionProperties[extCount];
|
||||
ObjDisp(instance)->EnumerateDeviceExtensionProperties(devices[p], NULL, &extCount, extProps);
|
||||
|
||||
for(uint32_t e = 0; e < extCount; e++)
|
||||
{
|
||||
if(!strcmp(extProps[e].extensionName, VK_KHR_DRIVER_PROPERTIES_EXTENSION_NAME))
|
||||
{
|
||||
ObjDisp(instance)->GetPhysicalDeviceProperties2(devices[p], &physProps2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY(extProps);
|
||||
}
|
||||
|
||||
GPUDevice dev;
|
||||
dev.vendor = GPUVendorFromPCIVendor(props.vendorID);
|
||||
dev.deviceID = props.deviceID;
|
||||
dev.name = props.deviceName;
|
||||
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;
|
||||
}
|
||||
|
||||
// don't add duplicate devices even if they get enumerated.
|
||||
if(ret.indexOf(dev) == -1)
|
||||
ret.push_back(dev);
|
||||
}
|
||||
|
||||
// loop over devices and remove the driver string unless it's needed to disambiguate from another
|
||||
// identical device.
|
||||
for(size_t i = 0; i < ret.size(); i++)
|
||||
{
|
||||
bool needDriver = false;
|
||||
|
||||
for(size_t j = 0; j < ret.size(); j++)
|
||||
{
|
||||
if(i == j)
|
||||
continue;
|
||||
|
||||
if(ret[i].vendor == ret[j].vendor && ret[i].deviceID == ret[j].deviceID)
|
||||
{
|
||||
RDCASSERT(ret[i].driver != ret[j].driver);
|
||||
needDriver = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!needDriver)
|
||||
ret[i].driver = rdcstr();
|
||||
}
|
||||
|
||||
SAFE_DELETE_ARRAY(devices);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
APIProperties VulkanReplay::GetAPIProperties()
|
||||
{
|
||||
APIProperties ret = m_pDriver->APIProps;
|
||||
|
||||
@@ -231,6 +231,7 @@ public:
|
||||
|
||||
void SetDriver(WrappedVulkan *d) { m_pDriver = d; }
|
||||
DriverInformation GetDriverInfo() { return m_DriverInfo; }
|
||||
rdcarray<GPUDevice> GetAvailableGPUs();
|
||||
APIProperties GetAPIProperties();
|
||||
|
||||
ResourceDescription &GetResourceDesc(ResourceId id);
|
||||
|
||||
@@ -135,6 +135,7 @@ public:
|
||||
return RenderDoc::Inst().GetCaptureFileFormats();
|
||||
}
|
||||
|
||||
rdcarray<GPUDevice> GetAvailableGPUs() { return RenderDoc::Inst().GetAvailableGPUs(); }
|
||||
const SDFile &GetStructuredData()
|
||||
{
|
||||
// decompile to structured data on demand.
|
||||
|
||||
@@ -879,6 +879,18 @@ void DoSerialise(SerialiserType &ser, CounterValue &el)
|
||||
SIZE_CHECK(8);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, GPUDevice &el)
|
||||
{
|
||||
SERIALISE_MEMBER(vendor);
|
||||
SERIALISE_MEMBER(deviceID);
|
||||
SERIALISE_MEMBER(driver);
|
||||
SERIALISE_MEMBER(name);
|
||||
SERIALISE_MEMBER(apis);
|
||||
|
||||
SIZE_CHECK(80);
|
||||
}
|
||||
|
||||
#pragma region Common pipeline state
|
||||
|
||||
template <typename SerialiserType>
|
||||
@@ -2243,6 +2255,7 @@ INSTANTIATE_SERIALISE_TYPE(PixelModification)
|
||||
INSTANTIATE_SERIALISE_TYPE(EventUsage)
|
||||
INSTANTIATE_SERIALISE_TYPE(CounterResult)
|
||||
INSTANTIATE_SERIALISE_TYPE(CounterValue)
|
||||
INSTANTIATE_SERIALISE_TYPE(GPUDevice)
|
||||
INSTANTIATE_SERIALISE_TYPE(D3D11Pipe::Layout)
|
||||
INSTANTIATE_SERIALISE_TYPE(D3D11Pipe::InputAssembly)
|
||||
INSTANTIATE_SERIALISE_TYPE(D3D11Pipe::View)
|
||||
|
||||
@@ -176,6 +176,8 @@ public:
|
||||
virtual bool NeedRemapForFetch(const ResourceFormat &format) = 0;
|
||||
|
||||
virtual DriverInformation GetDriverInfo() = 0;
|
||||
|
||||
virtual rdcarray<GPUDevice> GetAvailableGPUs() = 0;
|
||||
};
|
||||
|
||||
class IReplayDriver : public IRemoteDriver
|
||||
|
||||
Reference in New Issue
Block a user