mirror of
https://github.com/baldurk/renderdoc.git
synced 2026-05-29 21:30:53 +00:00
Add way to query for driver version info without replaying.
* This lets us print what driver is available without opening a capture, useful for autotest logging. * We also print the driver version & vendor on capture as well as replay for all APIs. Previously we were only printing this reliably on replay for GL/Vulkan but it's useful everywhere for post-mortem debugging.
This commit is contained in:
@@ -1203,6 +1203,18 @@ worked around by re-sorting bindings.
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(APIProperties);
|
||||
|
||||
DOCUMENT("Gives information about the driver for this API.");
|
||||
struct DriverInformation
|
||||
{
|
||||
DOCUMENT("The :class:`GPUVendor` that provides this driver");
|
||||
GPUVendor vendor;
|
||||
|
||||
DOCUMENT("The version string for the driver");
|
||||
char version[128];
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(DriverInformation);
|
||||
|
||||
DOCUMENT("A 128-bit Uuid.");
|
||||
struct Uuid
|
||||
{
|
||||
|
||||
@@ -2214,6 +2214,13 @@ This will be in the form "0123456789abcdef0123456789abcdef01234567"
|
||||
)");
|
||||
extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetCommitHash();
|
||||
|
||||
DOCUMENT(R"(Retrieves the driver information (if available) for a given graphics API.
|
||||
|
||||
:return: The driver information.
|
||||
:rtype: ``DriverInformation``
|
||||
)");
|
||||
extern "C" RENDERDOC_API DriverInformation RENDERDOC_CC RENDERDOC_GetDriverInformation(GraphicsAPI api);
|
||||
|
||||
DOCUMENT("Internal function for retrieving a config setting.");
|
||||
extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetConfigSetting(const char *name);
|
||||
|
||||
|
||||
@@ -1059,6 +1059,41 @@ map<RDCDriver, string> RenderDoc::GetRemoteDrivers()
|
||||
return ret;
|
||||
}
|
||||
|
||||
DriverInformation RenderDoc::GetDriverInformation(GraphicsAPI api)
|
||||
{
|
||||
DriverInformation ret = {GPUVendor::Unknown, ""};
|
||||
|
||||
RDCDriver driverType = RDCDriver::Unknown;
|
||||
switch(api)
|
||||
{
|
||||
case GraphicsAPI::D3D11: driverType = RDCDriver::D3D11; break;
|
||||
case GraphicsAPI::D3D12: driverType = RDCDriver::D3D12; break;
|
||||
case GraphicsAPI::OpenGL: driverType = RDCDriver::OpenGL; break;
|
||||
case GraphicsAPI::Vulkan: driverType = RDCDriver::Vulkan; break;
|
||||
}
|
||||
|
||||
if(driverType == RDCDriver::Unknown || !HasReplayDriver(driverType))
|
||||
return ret;
|
||||
|
||||
IReplayDriver *driver = NULL;
|
||||
ReplayStatus status = CreateProxyReplayDriver(driverType, &driver);
|
||||
|
||||
if(status == ReplayStatus::Succeeded)
|
||||
{
|
||||
ret = driver->GetDriverInfo();
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCERR("Couldn't create proxy replay driver for %s: %s", ToStr(driverType).c_str(),
|
||||
ToStr(status).c_str());
|
||||
}
|
||||
|
||||
if(driver)
|
||||
driver->Shutdown();
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void RenderDoc::EnableVendorExtensions(VendorExtensions ext)
|
||||
{
|
||||
m_VendorExts[(int)ext] = true;
|
||||
|
||||
@@ -398,6 +398,8 @@ public:
|
||||
void BecomeRemoteServer(const char *listenhost, uint16_t port, RENDERDOC_KillCallback killReplay,
|
||||
RENDERDOC_PreviewWindowCallback previewWindow);
|
||||
|
||||
DriverInformation GetDriverInformation(GraphicsAPI api);
|
||||
|
||||
// can't be disabled, only enabled then latched
|
||||
|
||||
bool IsVendorExtensionEnabled(VendorExtensions ext) { return m_VendorExts[(int)ext]; }
|
||||
|
||||
@@ -170,6 +170,7 @@ public:
|
||||
return ret;
|
||||
}
|
||||
void SavePipelineState() {}
|
||||
DriverInformation GetDriverInfo() { return {GPUVendor::Unknown, ""}; }
|
||||
const D3D12Pipe::State *GetD3D12PipelineState() { return NULL; }
|
||||
const GLPipe::State *GetGLPipelineState() { return NULL; }
|
||||
const VKPipe::State *GetVulkanPipelineState() { return NULL; }
|
||||
|
||||
@@ -90,6 +90,8 @@ std::string DoStringise(const ReplayProxyPacket &el)
|
||||
STRINGISE_ENUM_NAMED(eReplayProxy_DisassembleShader, "DisassembleShader");
|
||||
STRINGISE_ENUM_NAMED(eReplayProxy_GetDisassemblyTargets, "GetDisassemblyTargets");
|
||||
STRINGISE_ENUM_NAMED(eReplayProxy_GetTargetShaderEncodings, "GetTargetShaderEncodings");
|
||||
|
||||
STRINGISE_ENUM_NAMED(eReplayProxy_GetDriverInfo, "GetDriverInfo");
|
||||
}
|
||||
END_ENUM_STRINGISE();
|
||||
}
|
||||
@@ -293,6 +295,35 @@ APIProperties ReplayProxy::GetAPIProperties()
|
||||
PROXY_FUNCTION(GetAPIProperties);
|
||||
}
|
||||
|
||||
template <typename ParamSerialiser, typename ReturnSerialiser>
|
||||
DriverInformation ReplayProxy::Proxied_GetDriverInfo(ParamSerialiser ¶mser,
|
||||
ReturnSerialiser &retser)
|
||||
{
|
||||
const ReplayProxyPacket expectedPacket = eReplayProxy_GetDriverInfo;
|
||||
ReplayProxyPacket packet = eReplayProxy_GetDriverInfo;
|
||||
DriverInformation ret = {};
|
||||
|
||||
{
|
||||
BEGIN_PARAMS();
|
||||
END_PARAMS();
|
||||
}
|
||||
|
||||
{
|
||||
REMOTE_EXECUTION();
|
||||
if(paramser.IsReading() && !paramser.IsErrored() && !m_IsErrored)
|
||||
ret = m_Remote->GetDriverInfo();
|
||||
}
|
||||
|
||||
SERIALISE_RETURN(ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
DriverInformation ReplayProxy::GetDriverInfo()
|
||||
{
|
||||
PROXY_FUNCTION(GetDriverInfo);
|
||||
}
|
||||
|
||||
template <typename ParamSerialiser, typename ReturnSerialiser>
|
||||
std::vector<DebugMessage> ReplayProxy::Proxied_GetDebugMessages(ParamSerialiser ¶mser,
|
||||
ReturnSerialiser &retser)
|
||||
@@ -2598,6 +2629,7 @@ bool ReplayProxy::Tick(int type)
|
||||
case eReplayProxy_DisassembleShader: DisassembleShader(ResourceId(), NULL, ""); break;
|
||||
case eReplayProxy_GetDisassemblyTargets: GetDisassemblyTargets(); break;
|
||||
case eReplayProxy_GetTargetShaderEncodings: GetTargetShaderEncodings(); break;
|
||||
case eReplayProxy_GetDriverInfo: GetDriverInfo(); break;
|
||||
default: RDCERR("Unexpected command %u", type); return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -97,6 +97,8 @@ enum ReplayProxyPacket
|
||||
eReplayProxy_DisassembleShader,
|
||||
eReplayProxy_GetDisassemblyTargets,
|
||||
eReplayProxy_GetTargetShaderEncodings,
|
||||
|
||||
eReplayProxy_GetDriverInfo,
|
||||
};
|
||||
|
||||
DECLARE_REFLECTION_ENUM(ReplayProxyPacket);
|
||||
@@ -447,6 +449,7 @@ public:
|
||||
IMPLEMENT_FUNCTION_PROXIED(TextureDescription, GetTexture, ResourceId id);
|
||||
|
||||
IMPLEMENT_FUNCTION_PROXIED(APIProperties, GetAPIProperties);
|
||||
IMPLEMENT_FUNCTION_PROXIED(DriverInformation, GetDriverInfo);
|
||||
|
||||
IMPLEMENT_FUNCTION_PROXIED(std::vector<DebugMessage>, GetDebugMessages);
|
||||
|
||||
|
||||
@@ -146,6 +146,36 @@ WrappedID3D11Device::WrappedID3D11Device(ID3D11Device *realDevice, D3D11InitPara
|
||||
m_DeviceRecord->SubResources = NULL;
|
||||
|
||||
RenderDoc::Inst().AddDeviceFrameCapturer((ID3D11Device *)this, this);
|
||||
|
||||
{
|
||||
IDXGIDevice *pDXGIDevice = NULL;
|
||||
HRESULT hr = m_pDevice->QueryInterface(__uuidof(IDXGIDevice), (void **)&pDXGIDevice);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't get DXGI device from D3D device");
|
||||
}
|
||||
else
|
||||
{
|
||||
IDXGIAdapter *pDXGIAdapter = NULL;
|
||||
hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
|
||||
|
||||
if(SUCCEEDED(hr))
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc = {};
|
||||
pDXGIAdapter->GetDesc(&desc);
|
||||
|
||||
GPUVendor vendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
std::string descString = GetDriverVersion(desc);
|
||||
|
||||
RDCLOG("New D3D11 device created: %s / %s", ToStr(vendor).c_str(), descString.c_str());
|
||||
|
||||
SAFE_RELEASE(pDXGIAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_RELEASE(pDXGIDevice);
|
||||
}
|
||||
}
|
||||
|
||||
ID3D11DeviceContext *context = NULL;
|
||||
|
||||
@@ -54,6 +54,8 @@ D3D11Replay::D3D11Replay()
|
||||
m_WARP = false;
|
||||
|
||||
m_HighlightCache.driver = this;
|
||||
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
}
|
||||
|
||||
D3D11Replay::~D3D11Replay()
|
||||
@@ -95,14 +97,6 @@ void D3D11Replay::CreateResources()
|
||||
IDXGIAdapter *pDXGIAdapter;
|
||||
hr = pDXGIDevice->GetParent(__uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
|
||||
|
||||
DXGI_ADAPTER_DESC desc = {};
|
||||
pDXGIAdapter->GetDesc(&desc);
|
||||
|
||||
m_Vendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
|
||||
if(m_WARP)
|
||||
m_Vendor = GPUVendor::Software;
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't get DXGI adapter from DXGI device");
|
||||
@@ -110,6 +104,22 @@ void D3D11Replay::CreateResources()
|
||||
}
|
||||
else
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc = {};
|
||||
pDXGIAdapter->GetDesc(&desc);
|
||||
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
|
||||
m_DriverInfo.vendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
|
||||
std::string descString = GetDriverVersion(desc);
|
||||
descString.resize(RDCMIN(descString.size(), ARRAY_COUNT(m_DriverInfo.version) - 1));
|
||||
memcpy(m_DriverInfo.version, descString.c_str(), descString.size());
|
||||
|
||||
RDCLOG("Running replay on %s / %s", ToStr(m_DriverInfo.vendor).c_str(), m_DriverInfo.version);
|
||||
|
||||
if(m_WARP)
|
||||
m_DriverInfo.vendor = GPUVendor::Software;
|
||||
|
||||
hr = pDXGIAdapter->GetParent(__uuidof(IDXGIFactory), (void **)&m_pFactory);
|
||||
|
||||
SAFE_RELEASE(pDXGIDevice);
|
||||
@@ -162,24 +172,24 @@ void D3D11Replay::CreateResources()
|
||||
NVCounters *countersNV = NULL;
|
||||
IntelCounters *countersIntel = NULL;
|
||||
|
||||
if(m_Vendor == GPUVendor::AMD)
|
||||
if(m_DriverInfo.vendor == GPUVendor::AMD)
|
||||
{
|
||||
RDCLOG("AMD GPU detected - trying to initialise AMD counters");
|
||||
countersAMD = new AMDCounters();
|
||||
}
|
||||
else if(m_Vendor == GPUVendor::nVidia)
|
||||
else if(m_DriverInfo.vendor == GPUVendor::nVidia)
|
||||
{
|
||||
RDCLOG("nVidia GPU detected - trying to initialise nVidia counters");
|
||||
countersNV = new NVCounters();
|
||||
}
|
||||
else if(m_Vendor == GPUVendor::Intel)
|
||||
else if(m_DriverInfo.vendor == GPUVendor::Intel)
|
||||
{
|
||||
RDCLOG("Intel GPU detected - trying to initialize Intel counters");
|
||||
countersIntel = new IntelCounters();
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCLOG("%s GPU detected - no counters available", ToStr(m_Vendor).c_str());
|
||||
RDCLOG("%s GPU detected - no counters available", ToStr(m_DriverInfo.vendor).c_str());
|
||||
}
|
||||
|
||||
ID3D11Device *d3dDevice = m_pDevice->GetReal();
|
||||
@@ -507,7 +517,7 @@ APIProperties D3D11Replay::GetAPIProperties()
|
||||
|
||||
ret.pipelineType = GraphicsAPI::D3D11;
|
||||
ret.localRenderer = GraphicsAPI::D3D11;
|
||||
ret.vendor = m_Vendor;
|
||||
ret.vendor = m_DriverInfo.vendor;
|
||||
ret.degraded = m_WARP;
|
||||
ret.shadersMutable = false;
|
||||
|
||||
|
||||
@@ -104,6 +104,7 @@ public:
|
||||
void CreateResources();
|
||||
void DestroyResources();
|
||||
|
||||
DriverInformation GetDriverInfo() { return m_DriverInfo; }
|
||||
APIProperties GetAPIProperties();
|
||||
|
||||
ResourceDescription &GetResourceDesc(ResourceId id);
|
||||
@@ -240,8 +241,6 @@ private:
|
||||
bool m_WARP;
|
||||
bool m_Proxy;
|
||||
|
||||
GPUVendor m_Vendor = GPUVendor::Unknown;
|
||||
|
||||
D3D11DebugManager *GetDebugManager();
|
||||
// shared by BuildCustomShader and BuildTargetShader
|
||||
void BuildShader(ShaderEncoding sourceEncoding, bytebuf source, std::string entry,
|
||||
@@ -303,6 +302,8 @@ private:
|
||||
|
||||
IDXGIFactory *m_pFactory = NULL;
|
||||
|
||||
DriverInformation m_DriverInfo;
|
||||
|
||||
AMDCounters *m_pAMDCounters = NULL;
|
||||
NVCounters *m_pNVCounters = NULL;
|
||||
IntelCounters *m_pIntelCounters = NULL;
|
||||
|
||||
@@ -221,6 +221,49 @@ WrappedID3D12Device::WrappedID3D12Device(ID3D12Device *realDevice, D3D12InitPara
|
||||
m_FrameCaptureRecord = NULL;
|
||||
|
||||
ResourceIDGen::SetReplayResourceIDs();
|
||||
|
||||
// create temporary factory to print the driver version info
|
||||
if(m_pDevice)
|
||||
{
|
||||
typedef HRESULT(WINAPI * PFN_CREATE_DXGI_FACTORY)(REFIID, void **);
|
||||
|
||||
PFN_CREATE_DXGI_FACTORY createFunc = (PFN_CREATE_DXGI_FACTORY)GetProcAddress(
|
||||
GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
|
||||
|
||||
IDXGIFactory4 *tmpFactory = NULL;
|
||||
HRESULT hr = createFunc(__uuidof(IDXGIFactory4), (void **)&tmpFactory);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't create DXGI factory! HRESULT: %s", ToStr(hr).c_str());
|
||||
}
|
||||
|
||||
if(tmpFactory)
|
||||
{
|
||||
IDXGIAdapter *pDXGIAdapter = NULL;
|
||||
hr = tmpFactory->EnumAdapterByLuid(m_pDevice->GetAdapterLuid(), __uuidof(IDXGIAdapter),
|
||||
(void **)&pDXGIAdapter);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't get DXGI adapter by LUID from D3D12 device");
|
||||
}
|
||||
else
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc = {};
|
||||
pDXGIAdapter->GetDesc(&desc);
|
||||
|
||||
GPUVendor vendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
std::string descString = GetDriverVersion(desc);
|
||||
|
||||
RDCLOG("New D3D12 device created: %s / %s", ToStr(vendor).c_str(), descString.c_str());
|
||||
|
||||
SAFE_RELEASE(pDXGIAdapter);
|
||||
}
|
||||
}
|
||||
|
||||
SAFE_RELEASE(tmpFactory);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -85,6 +85,8 @@ D3D12Replay::D3D12Replay()
|
||||
m_Proxy = false;
|
||||
|
||||
m_HighlightCache.driver = this;
|
||||
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
}
|
||||
|
||||
void D3D12Replay::Shutdown()
|
||||
@@ -98,46 +100,57 @@ void D3D12Replay::Shutdown()
|
||||
m_pDevice->Release();
|
||||
}
|
||||
|
||||
void D3D12Replay::Initialise()
|
||||
{
|
||||
typedef HRESULT(WINAPI * PFN_CREATE_DXGI_FACTORY)(REFIID, void **);
|
||||
|
||||
PFN_CREATE_DXGI_FACTORY createFunc =
|
||||
(PFN_CREATE_DXGI_FACTORY)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
|
||||
|
||||
HRESULT hr = createFunc(__uuidof(IDXGIFactory4), (void **)&m_pFactory);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't create DXGI factory! HRESULT: %s", ToStr(hr).c_str());
|
||||
}
|
||||
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
|
||||
if(m_pFactory)
|
||||
{
|
||||
RefCountDXGIObject::HandleWrap(__uuidof(IDXGIFactory4), (void **)&m_pFactory);
|
||||
|
||||
LUID luid = m_pDevice->GetAdapterLuid();
|
||||
|
||||
IDXGIAdapter *pDXGIAdapter;
|
||||
hr = m_pFactory->EnumAdapterByLuid(luid, __uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't get DXGI adapter by LUID from D3D device");
|
||||
}
|
||||
else
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc = {};
|
||||
pDXGIAdapter->GetDesc(&desc);
|
||||
|
||||
m_DriverInfo.vendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
|
||||
std::string descString = GetDriverVersion(desc);
|
||||
descString.resize(RDCMIN(descString.size(), ARRAY_COUNT(m_DriverInfo.version) - 1));
|
||||
memcpy(m_DriverInfo.version, descString.c_str(), descString.size());
|
||||
|
||||
RDCLOG("Running replay on %s / %s", ToStr(m_DriverInfo.vendor).c_str(), m_DriverInfo.version);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void D3D12Replay::CreateResources()
|
||||
{
|
||||
m_DebugManager = new D3D12DebugManager(m_pDevice);
|
||||
|
||||
if(RenderDoc::Inst().IsReplayApp())
|
||||
{
|
||||
typedef HRESULT(WINAPI * PFN_CREATE_DXGI_FACTORY)(REFIID, void **);
|
||||
|
||||
PFN_CREATE_DXGI_FACTORY createFunc =
|
||||
(PFN_CREATE_DXGI_FACTORY)GetProcAddress(GetModuleHandleA("dxgi.dll"), "CreateDXGIFactory1");
|
||||
|
||||
HRESULT hr = createFunc(__uuidof(IDXGIFactory4), (void **)&m_pFactory);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't create DXGI factory! HRESULT: %s", ToStr(hr).c_str());
|
||||
}
|
||||
|
||||
if(m_pFactory)
|
||||
{
|
||||
RefCountDXGIObject::HandleWrap(__uuidof(IDXGIFactory4), (void **)&m_pFactory);
|
||||
|
||||
LUID luid = m_pDevice->GetAdapterLuid();
|
||||
|
||||
IDXGIAdapter *pDXGIAdapter;
|
||||
hr = m_pFactory->EnumAdapterByLuid(luid, __uuidof(IDXGIAdapter), (void **)&pDXGIAdapter);
|
||||
|
||||
if(FAILED(hr))
|
||||
{
|
||||
RDCERR("Couldn't get DXGI adapter by LUID from D3D device");
|
||||
}
|
||||
else
|
||||
{
|
||||
DXGI_ADAPTER_DESC desc = {};
|
||||
pDXGIAdapter->GetDesc(&desc);
|
||||
|
||||
m_Vendor = GPUVendorFromPCIVendor(desc.VendorId);
|
||||
}
|
||||
}
|
||||
|
||||
CreateSOBuffers();
|
||||
|
||||
m_General.Init(m_pDevice, m_DebugManager);
|
||||
@@ -149,14 +162,14 @@ void D3D12Replay::CreateResources()
|
||||
|
||||
AMDCounters *counters = NULL;
|
||||
|
||||
if(m_Vendor == GPUVendor::AMD)
|
||||
if(m_DriverInfo.vendor == GPUVendor::AMD)
|
||||
{
|
||||
RDCLOG("AMD GPU detected - trying to initialise AMD counters");
|
||||
counters = new AMDCounters(m_pDevice->IsDebugLayerEnabled());
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCLOG("%s GPU detected - no counters available", ToStr(m_Vendor).c_str());
|
||||
RDCLOG("%s GPU detected - no counters available", ToStr(m_DriverInfo.vendor).c_str());
|
||||
}
|
||||
|
||||
ID3D12Device *d3dDevice = m_pDevice->GetReal();
|
||||
@@ -211,7 +224,7 @@ APIProperties D3D12Replay::GetAPIProperties()
|
||||
|
||||
ret.pipelineType = GraphicsAPI::D3D12;
|
||||
ret.localRenderer = GraphicsAPI::D3D12;
|
||||
ret.vendor = m_Vendor;
|
||||
ret.vendor = m_DriverInfo.vendor;
|
||||
ret.degraded = false;
|
||||
ret.shadersMutable = false;
|
||||
ret.rgpCapture = m_RGP != NULL && m_RGP->DriverSupportsInterop();
|
||||
@@ -3658,6 +3671,8 @@ ReplayStatus D3D12_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
|
||||
replay->SetProxy(rdc == NULL);
|
||||
replay->SetRGP(rgp);
|
||||
|
||||
replay->Initialise();
|
||||
|
||||
*driver = (IReplayDriver *)replay;
|
||||
return ReplayStatus::Succeeded;
|
||||
}
|
||||
|
||||
@@ -57,11 +57,13 @@ public:
|
||||
void SetRGP(AMDRGPControl *rgp) { m_RGP = rgp; }
|
||||
void SetProxy(bool proxy) { m_Proxy = proxy; }
|
||||
bool IsRemoteProxy() { return m_Proxy; }
|
||||
void Initialise();
|
||||
void Shutdown();
|
||||
|
||||
void SetDevice(WrappedID3D12Device *d) { m_pDevice = d; }
|
||||
void CreateResources();
|
||||
void DestroyResources();
|
||||
DriverInformation GetDriverInfo() { return m_DriverInfo; }
|
||||
APIProperties GetAPIProperties();
|
||||
|
||||
ResourceDescription &GetResourceDesc(ResourceId id);
|
||||
@@ -276,8 +278,6 @@ private:
|
||||
|
||||
bool m_Proxy;
|
||||
|
||||
GPUVendor m_Vendor = GPUVendor::Unknown;
|
||||
|
||||
vector<ID3D12Resource *> m_ProxyResources;
|
||||
|
||||
struct OutputWindow
|
||||
@@ -411,6 +411,8 @@ private:
|
||||
AMDCounters *m_pAMDCounters = NULL;
|
||||
AMDRGPControl *m_RGP = NULL;
|
||||
|
||||
DriverInformation m_DriverInfo;
|
||||
|
||||
D3D12AMDDrawCallback *m_pAMDDrawCallback = NULL;
|
||||
|
||||
void FillTimersAMD(uint32_t *eventStartID, uint32_t *sampleIndex, vector<uint32_t> *eventIDs);
|
||||
|
||||
@@ -26,6 +26,11 @@
|
||||
#include "common/common.h"
|
||||
#include "common/threading.h"
|
||||
#include "serialise/serialiser.h"
|
||||
#include "strings/string_utils.h"
|
||||
|
||||
// for GetDriverVersion()
|
||||
#include <devpkey.h>
|
||||
#include <setupapi.h>
|
||||
|
||||
UINT GetFormatBPP(DXGI_FORMAT f)
|
||||
{
|
||||
@@ -1367,6 +1372,91 @@ void WarnUnknownGUID(const char *name, REFIID riid)
|
||||
}
|
||||
}
|
||||
|
||||
static std::string GetDeviceProperty(HDEVINFO devs, PSP_DEVINFO_DATA data, const DEVPROPKEY *key)
|
||||
{
|
||||
DEVPROPTYPE type = {};
|
||||
DWORD bufSize = 0;
|
||||
|
||||
// this ALWAYS fails, we need to check if the er ror was just an insufficient buffer.
|
||||
SetupDiGetDevicePropertyW(devs, data, key, &type, NULL, 0, &bufSize, 0);
|
||||
|
||||
if(GetLastError() != ERROR_INSUFFICIENT_BUFFER)
|
||||
return "";
|
||||
|
||||
RDCASSERTEQUAL((uint32_t)type, DEVPROP_TYPE_STRING);
|
||||
|
||||
std::wstring string;
|
||||
string.resize(bufSize);
|
||||
BOOL success =
|
||||
SetupDiGetDevicePropertyW(devs, data, key, &type, (PBYTE)string.data(), bufSize, &bufSize, 0);
|
||||
|
||||
if(!success)
|
||||
return "";
|
||||
|
||||
return StringFormat::Wide2UTF8(string);
|
||||
}
|
||||
|
||||
std::string GetDriverVersion(DXGI_ADAPTER_DESC &desc)
|
||||
{
|
||||
std::string device = StringFormat::Wide2UTF8(desc.Description);
|
||||
|
||||
// fixed GUID for graphics drivers, from
|
||||
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx
|
||||
GUID display_class = {0x4d36e968, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
|
||||
|
||||
HDEVINFO devs = SetupDiGetClassDevs(&display_class, NULL, NULL, DIGCF_PRESENT);
|
||||
|
||||
if(devs == NULL)
|
||||
{
|
||||
RDCERR("Couldn't enumerate graphics adapters: %d", GetLastError());
|
||||
return device;
|
||||
}
|
||||
|
||||
std::string pci_match = StringFormat::Fmt("pci\\ven_%04x&dev_%04x", desc.VendorId, desc.DeviceId);
|
||||
|
||||
std::string driverVersion = "";
|
||||
|
||||
DWORD idx = 0;
|
||||
SP_DEVINFO_DATA data = {};
|
||||
data.cbSize = sizeof(data);
|
||||
while(SetupDiEnumDeviceInfo(devs, idx, &data))
|
||||
{
|
||||
std::string version = GetDeviceProperty(devs, &data, &DEVPKEY_Device_DriverVersion);
|
||||
|
||||
if(version.empty())
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(devs);
|
||||
return device;
|
||||
}
|
||||
|
||||
// if we got a version, and didn't have one yet, set it
|
||||
if(version.empty())
|
||||
driverVersion = version;
|
||||
|
||||
std::string pciid = GetDeviceProperty(devs, &data, &DEVPKEY_Device_MatchingDeviceId);
|
||||
|
||||
if(version.empty())
|
||||
{
|
||||
SetupDiDestroyDeviceInfoList(devs);
|
||||
return device;
|
||||
}
|
||||
|
||||
pciid = strlower(pciid);
|
||||
|
||||
// if the PCI id matches, take it
|
||||
if(pciid == pci_match)
|
||||
driverVersion = version;
|
||||
|
||||
// move to the next device
|
||||
RDCEraseEl(data);
|
||||
data.cbSize = sizeof(data);
|
||||
idx++;
|
||||
}
|
||||
|
||||
SetupDiDestroyDeviceInfoList(devs);
|
||||
return device + " " + driverVersion;
|
||||
}
|
||||
|
||||
Topology MakePrimitiveTopology(D3D_PRIMITIVE_TOPOLOGY Topo)
|
||||
{
|
||||
switch(Topo)
|
||||
|
||||
@@ -63,6 +63,8 @@ D3D_PRIMITIVE_TOPOLOGY MakeD3DPrimitiveTopology(Topology Topo);
|
||||
|
||||
void WarnUnknownGUID(const char *name, REFIID riid);
|
||||
|
||||
std::string GetDriverVersion(DXGI_ADAPTER_DESC &desc);
|
||||
|
||||
DECLARE_REFLECTION_STRUCT(DXGI_SAMPLE_DESC);
|
||||
DECLARE_REFLECTION_STRUCT(IID);
|
||||
DECLARE_REFLECTION_ENUM(DXGI_FORMAT);
|
||||
|
||||
@@ -672,8 +672,11 @@ void GLReplay::InitDebugData()
|
||||
|
||||
// try to identify the GPU we're running on.
|
||||
{
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
|
||||
const char *vendor = (const char *)drv.glGetString(eGL_VENDOR);
|
||||
const char *renderer = (const char *)drv.glGetString(eGL_RENDERER);
|
||||
const char *version = (const char *)drv.glGetString(eGL_VERSION);
|
||||
|
||||
// we're just doing substring searches, so combine both for ease.
|
||||
std::string combined = (vendor ? vendor : "");
|
||||
@@ -718,24 +721,34 @@ void GLReplay::InitDebugData()
|
||||
{
|
||||
if(combined.find(p.search) != std::string::npos)
|
||||
{
|
||||
if(m_Vendor == GPUVendor::Unknown)
|
||||
if(m_DriverInfo.vendor == GPUVendor::Unknown)
|
||||
{
|
||||
m_Vendor = p.vendor;
|
||||
m_DriverInfo.vendor = p.vendor;
|
||||
}
|
||||
else
|
||||
{
|
||||
// either we already found this with another pattern, or we've identified two patterns and
|
||||
// it's ambiguous. Keep the first one we found, arbitrarily, but print a warning.
|
||||
if(m_Vendor != p.vendor)
|
||||
if(m_DriverInfo.vendor != p.vendor)
|
||||
{
|
||||
RDCWARN("Already identified '%s' as %s, but now identified as %s", combined.c_str(),
|
||||
ToStr(m_Vendor).c_str(), ToStr(p.vendor).c_str());
|
||||
ToStr(m_DriverInfo.vendor).c_str(), ToStr(p.vendor).c_str());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
RDCDEBUG("Identified GPU vendor '%s'", ToStr(m_Vendor).c_str());
|
||||
RDCDEBUG("Identified GPU vendor '%s'", ToStr(m_DriverInfo.vendor).c_str());
|
||||
|
||||
std::string versionString = version;
|
||||
|
||||
versionString += " / ";
|
||||
versionString += renderer;
|
||||
versionString += " / ";
|
||||
versionString += vendor;
|
||||
|
||||
versionString.resize(RDCMIN(versionString.size(), ARRAY_COUNT(m_DriverInfo.version) - 1));
|
||||
memcpy(m_DriverInfo.version, versionString.c_str(), versionString.size());
|
||||
}
|
||||
|
||||
// these below need to be made on the replay context, as they are context-specific (not shared)
|
||||
|
||||
@@ -1162,6 +1162,10 @@ void WrappedOpenGL::ActivateContext(GLWindowingData winData)
|
||||
{
|
||||
ctxdata.built = true;
|
||||
|
||||
if(IsCaptureMode(m_State))
|
||||
RDCLOG("Activating new GL context: %s / %s / %s", GL.glGetString(eGL_VENDOR),
|
||||
GL.glGetString(eGL_RENDERER), GL.glGetString(eGL_VERSION));
|
||||
|
||||
const vector<string> &globalExts = IsGLES ? m_GLESExtensions : m_GLExtensions;
|
||||
|
||||
if(HasExt[KHR_debug] && GL.glDebugMessageCallback &&
|
||||
|
||||
@@ -54,6 +54,7 @@ GLReplay::GLReplay()
|
||||
m_OutputWindowID = 1;
|
||||
|
||||
RDCEraseEl(m_GetTexturePrevData);
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
}
|
||||
|
||||
void GLReplay::Shutdown()
|
||||
@@ -151,7 +152,7 @@ APIProperties GLReplay::GetAPIProperties()
|
||||
ret.pipelineType = GraphicsAPI::OpenGL;
|
||||
ret.localRenderer = GraphicsAPI::OpenGL;
|
||||
ret.degraded = m_Degraded;
|
||||
ret.vendor = m_Vendor;
|
||||
ret.vendor = m_DriverInfo.vendor;
|
||||
ret.shadersMutable = true;
|
||||
|
||||
return ret;
|
||||
@@ -259,14 +260,14 @@ void GLReplay::SetReplayData(GLWindowingData data)
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_Vendor == GPUVendor::AMD)
|
||||
if(m_DriverInfo.vendor == GPUVendor::AMD)
|
||||
{
|
||||
RDCLOG("AMD GPU detected - trying to initialise AMD counters");
|
||||
counters = new AMDCounters();
|
||||
}
|
||||
else
|
||||
{
|
||||
RDCLOG("%s GPU detected - no counters available", ToStr(m_Vendor).c_str());
|
||||
RDCLOG("%s GPU detected - no counters available", ToStr(m_DriverInfo.vendor).c_str());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -92,6 +92,7 @@ public:
|
||||
void Shutdown();
|
||||
|
||||
void SetDriver(WrappedOpenGL *d) { m_pDriver = d; }
|
||||
DriverInformation GetDriverInfo() { return m_DriverInfo; }
|
||||
APIProperties GetAPIProperties();
|
||||
|
||||
ResourceDescription &GetResourceDesc(ResourceId id);
|
||||
@@ -372,8 +373,6 @@ private:
|
||||
|
||||
bool m_Degraded;
|
||||
|
||||
GPUVendor m_Vendor = GPUVendor::Unknown;
|
||||
|
||||
HighlightCache m_HighlightCache;
|
||||
|
||||
// eventId -> data
|
||||
@@ -426,6 +425,8 @@ private:
|
||||
|
||||
GLPipe::State m_CurPipelineState;
|
||||
|
||||
DriverInformation m_DriverInfo;
|
||||
|
||||
// AMD counter instance
|
||||
AMDCounters *m_pAMDCounters = NULL;
|
||||
|
||||
|
||||
@@ -55,6 +55,8 @@ VulkanReplay::VulkanReplay()
|
||||
m_BindDepth = false;
|
||||
|
||||
m_DebugWidth = m_DebugHeight = 1;
|
||||
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
}
|
||||
|
||||
VulkanDebugManager *VulkanReplay::GetDebugManager()
|
||||
@@ -807,6 +809,54 @@ void VulkanReplay::FileChanged()
|
||||
{
|
||||
}
|
||||
|
||||
void VulkanReplay::GetInitialDriverVersion()
|
||||
{
|
||||
RDCEraseEl(m_DriverInfo);
|
||||
|
||||
VkInstance inst = m_pDriver->GetInstance();
|
||||
|
||||
uint32_t count;
|
||||
VkResult vkr = ObjDisp(inst)->EnumeratePhysicalDevices(Unwrap(inst), &count, NULL);
|
||||
|
||||
if(vkr != VK_SUCCESS)
|
||||
{
|
||||
RDCERR("Couldn't enumerate physical devices");
|
||||
return;
|
||||
}
|
||||
|
||||
if(count == 0)
|
||||
{
|
||||
RDCERR("No physical devices available");
|
||||
}
|
||||
|
||||
count = 1;
|
||||
VkPhysicalDevice firstDevice = VK_NULL_HANDLE;
|
||||
|
||||
vkr = ObjDisp(inst)->EnumeratePhysicalDevices(Unwrap(inst), &count, &firstDevice);
|
||||
|
||||
// incomplete is expected if multiple GPUs are present, and we're just grabbing the first
|
||||
if(vkr != VK_SUCCESS && vkr != VK_INCOMPLETE)
|
||||
{
|
||||
RDCERR("Couldn't fetch first physical device");
|
||||
return;
|
||||
}
|
||||
|
||||
VkPhysicalDeviceProperties props;
|
||||
ObjDisp(inst)->GetPhysicalDeviceProperties(firstDevice, &props);
|
||||
|
||||
SetDriverInformation(props);
|
||||
}
|
||||
|
||||
void VulkanReplay::SetDriverInformation(const VkPhysicalDeviceProperties &props)
|
||||
{
|
||||
VkDriverInfo info(props);
|
||||
m_DriverInfo.vendor = info.Vendor();
|
||||
std::string versionString =
|
||||
StringFormat::Fmt("%s %u.%u.%u", props.deviceName, info.Major(), info.Minor(), info.Patch());
|
||||
versionString.resize(RDCMIN(versionString.size(), ARRAY_COUNT(m_DriverInfo.version) - 1));
|
||||
memcpy(m_DriverInfo.version, versionString.c_str(), versionString.size());
|
||||
}
|
||||
|
||||
void VulkanReplay::SavePipelineState()
|
||||
{
|
||||
const VulkanRenderState &state = m_pDriver->m_RenderState;
|
||||
@@ -3515,6 +3565,8 @@ ReplayStatus Vulkan_CreateReplayDevice(RDCFile *rdc, IReplayDriver **driver)
|
||||
|
||||
*driver = (IReplayDriver *)replay;
|
||||
|
||||
replay->GetInitialDriverVersion();
|
||||
|
||||
return ReplayStatus::Succeeded;
|
||||
}
|
||||
|
||||
|
||||
@@ -196,6 +196,7 @@ public:
|
||||
void DestroyResources();
|
||||
|
||||
void SetDriver(WrappedVulkan *d) { m_pDriver = d; }
|
||||
DriverInformation GetDriverInfo() { return m_DriverInfo; }
|
||||
APIProperties GetAPIProperties();
|
||||
|
||||
ResourceDescription &GetResourceDesc(ResourceId id);
|
||||
@@ -338,6 +339,8 @@ public:
|
||||
static bool CheckVulkanLayer(VulkanLayerFlags &flags, std::vector<std::string> &myJSONs,
|
||||
std::vector<std::string> &otherJSONs);
|
||||
static void InstallVulkanLayer(bool systemLevel);
|
||||
void GetInitialDriverVersion();
|
||||
void SetDriverInformation(const VkPhysicalDeviceProperties &props);
|
||||
|
||||
AMDCounters *GetAMDCounters() { return m_pAMDCounters; }
|
||||
private:
|
||||
@@ -606,6 +609,8 @@ private:
|
||||
|
||||
VKPipe::State m_VulkanPipelineState;
|
||||
|
||||
DriverInformation m_DriverInfo;
|
||||
|
||||
void FillTimersAMD(uint32_t *eventStartID, uint32_t *sampleIndex, vector<uint32_t> *eventIDs);
|
||||
|
||||
vector<CounterResult> FetchCountersAMD(const vector<GPUCounter> &counters);
|
||||
|
||||
@@ -309,8 +309,11 @@ ReplayStatus WrappedVulkan::Initialise(VkInitParams ¶ms, uint64_t sectionVer
|
||||
GetResourceManager()->AddLiveResource(params.InstanceID, m_Instance);
|
||||
|
||||
// we'll add the chunk later when we re-process it.
|
||||
AddResource(params.InstanceID, ResourceType::Device, "Instance");
|
||||
GetReplay()->GetResourceDesc(params.InstanceID).initialisationChunks.clear();
|
||||
if(params.InstanceID != ResourceId())
|
||||
{
|
||||
AddResource(params.InstanceID, ResourceType::Device, "Instance");
|
||||
GetReplay()->GetResourceDesc(params.InstanceID).initialisationChunks.clear();
|
||||
}
|
||||
|
||||
InitInstanceExtensionTables(m_Instance, &m_EnabledExtensions);
|
||||
|
||||
@@ -919,6 +922,16 @@ VkResult WrappedVulkan::vkEnumeratePhysicalDevices(VkInstance instance,
|
||||
|
||||
ObjDisp(devices[i])->GetPhysicalDeviceMemoryProperties(Unwrap(devices[i]), record->memProps);
|
||||
|
||||
VkPhysicalDeviceProperties physProps;
|
||||
|
||||
ObjDisp(devices[i])->GetPhysicalDeviceProperties(Unwrap(devices[i]), &physProps);
|
||||
|
||||
VkDriverInfo capturedVersion(physProps);
|
||||
|
||||
RDCLOG("physical device %u: %s (ver %u.%u patch 0x%x) - %04x:%04x", i, physProps.deviceName,
|
||||
capturedVersion.Major(), capturedVersion.Minor(), capturedVersion.Patch(),
|
||||
physProps.vendorID, physProps.deviceID);
|
||||
|
||||
m_PhysicalDevices[i] = devices[i];
|
||||
|
||||
// we remap memory indices to discourage coherent maps as much as possible
|
||||
@@ -1835,6 +1848,8 @@ bool WrappedVulkan::Serialise_vkCreateDevice(SerialiserType &ser, VkPhysicalDevi
|
||||
ObjDisp(physicalDevice)
|
||||
->GetPhysicalDeviceFeatures(Unwrap(physicalDevice), &m_PhysicalDeviceData.features);
|
||||
|
||||
m_Replay.SetDriverInformation(m_PhysicalDeviceData.props);
|
||||
|
||||
// MoltenVK reports 0x3fffffff for this limit so just ignore that value if it comes up
|
||||
RDCASSERT(m_PhysicalDeviceData.props.limits.maxBoundDescriptorSets <
|
||||
ARRAY_COUNT(BakedCmdBufferInfo::pushDescriptorID[0]) ||
|
||||
|
||||
@@ -180,6 +180,11 @@ extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetCommitHash()
|
||||
return GitVersionHash;
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API DriverInformation RENDERDOC_CC RENDERDOC_GetDriverInformation(GraphicsAPI api)
|
||||
{
|
||||
return RenderDoc::Inst().GetDriverInformation(api);
|
||||
}
|
||||
|
||||
extern "C" RENDERDOC_API const char *RENDERDOC_CC RENDERDOC_GetConfigSetting(const char *name)
|
||||
{
|
||||
return RenderDoc::Inst().GetConfigSetting(name).c_str();
|
||||
|
||||
@@ -479,6 +479,15 @@ void DoSerialise(SerialiserType &ser, APIProperties &el)
|
||||
SIZE_CHECK(20);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, DriverInformation &el)
|
||||
{
|
||||
SERIALISE_MEMBER(vendor);
|
||||
SERIALISE_MEMBER(version);
|
||||
|
||||
SIZE_CHECK(132);
|
||||
}
|
||||
|
||||
template <typename SerialiserType>
|
||||
void DoSerialise(SerialiserType &ser, DebugMessage &el)
|
||||
{
|
||||
@@ -2170,6 +2179,7 @@ INSTANTIATE_SERIALISE_TYPE(ResourceDescription)
|
||||
INSTANTIATE_SERIALISE_TYPE(TextureDescription)
|
||||
INSTANTIATE_SERIALISE_TYPE(BufferDescription)
|
||||
INSTANTIATE_SERIALISE_TYPE(APIProperties)
|
||||
INSTANTIATE_SERIALISE_TYPE(DriverInformation)
|
||||
INSTANTIATE_SERIALISE_TYPE(DebugMessage)
|
||||
INSTANTIATE_SERIALISE_TYPE(APIEvent)
|
||||
INSTANTIATE_SERIALISE_TYPE(DrawcallDescription)
|
||||
|
||||
@@ -170,6 +170,8 @@ public:
|
||||
virtual void FileChanged() = 0;
|
||||
|
||||
virtual bool NeedRemapForFetch(const ResourceFormat &format) = 0;
|
||||
|
||||
virtual DriverInformation GetDriverInfo() = 0;
|
||||
};
|
||||
|
||||
class IReplayDriver : public IRemoteDriver
|
||||
|
||||
Reference in New Issue
Block a user