Commit 64ae9952 by Jamie Madill Committed by Commit Bot

D3D11: Get driver version from DXGI adapter.

This is a simpler and more portable design. Thanks for Austin from MS. BUG=angleproject:1452 Change-Id: I93e8f3fc61107f13c4b2c1cf7fbaf2bb7ccdfafb Reviewed-on: https://chromium-review.googlesource.com/363041Reviewed-by: 's avatarAustin Kinross <aukinros@microsoft.com> Reviewed-by: 's avatarZhenyao Mo <zmo@chromium.org> Commit-Queue: Jamie Madill <jmadill@chromium.org>
parent ee0fac3f
...@@ -358,100 +358,4 @@ egl::Error DisplayD3D::waitNative(EGLint engine, ...@@ -358,100 +358,4 @@ egl::Error DisplayD3D::waitNative(EGLint engine,
return egl::Error(EGL_SUCCESS); return egl::Error(EGL_SUCCESS);
} }
// TODO(jmadill): Do more complete GPU info collection.
egl::Error DisplayD3D::getDriverVersion(const std::string &deviceId, std::string *resultOut)
{
#if defined(ANGLE_ENABLE_WINDOWS_STORE)
// TODO(jmadill): Figure out what to return for Windows Store.
*resultOut = "";
return gl::NoError();
#else
// Display adapter class GUID from
// https://msdn.microsoft.com/en-us/library/windows/hardware/ff553426%28v=vs.85%29.aspx
GUID displayClass = {
0x4d36e968, 0xe325, 0x11ce, {0xbf, 0xc1, 0x08, 0x00, 0x2b, 0xe1, 0x03, 0x18}};
// create device info for the display device
HDEVINFO deviceInfo;
if (!IsWindowsVistaOrGreater())
{
// Collection of information on all adapters is much slower on XP (almost
// 100ms), and not very useful (as it's not going to use the GPU anyway), so
// just collect information on the current device. http://crbug.com/456178
deviceInfo = SetupDiGetClassDevsA(nullptr, deviceId.c_str(), nullptr,
DIGCF_PRESENT | DIGCF_PROFILE | DIGCF_ALLCLASSES);
}
else
{
deviceInfo = SetupDiGetClassDevsA(&displayClass, nullptr, nullptr, DIGCF_PRESENT);
}
if (deviceInfo == INVALID_HANDLE_VALUE)
{
return egl::Error(EGL_BAD_MATCH, "Creating device info failed");
}
bool found = false;
DWORD index = 0;
SP_DEVINFO_DATA deviceInfoData;
deviceInfoData.cbSize = sizeof(deviceInfoData);
while (SetupDiEnumDeviceInfo(deviceInfo, index++, &deviceInfoData))
{
CHAR value[255];
if (SetupDiGetDeviceRegistryPropertyA(deviceInfo, &deviceInfoData, SPDRP_DRIVER, nullptr,
reinterpret_cast<PBYTE>(value), sizeof(value),
nullptr))
{
HKEY key;
std::string driverKey = "System\\CurrentControlSet\\Control\\Class\\";
driverKey += value;
LONG result =
RegOpenKeyExA(HKEY_LOCAL_MACHINE, driverKey.c_str(), 0, KEY_QUERY_VALUE, &key);
if (result == ERROR_SUCCESS)
{
DWORD dwcbData = sizeof(value);
std::string driverVersion;
result = RegQueryValueExA(key, "DriverVersion", nullptr, nullptr,
reinterpret_cast<LPBYTE>(value), &dwcbData);
if (result == ERROR_SUCCESS)
driverVersion = value;
std::string driverDate;
dwcbData = sizeof(value);
result = RegQueryValueExA(key, "DriverDate", nullptr, nullptr,
reinterpret_cast<LPBYTE>(value), &dwcbData);
if (result == ERROR_SUCCESS)
driverDate = value;
std::string driverVendor;
dwcbData = sizeof(value);
result = RegQueryValueExA(key, "ProviderName", nullptr, nullptr,
reinterpret_cast<LPBYTE>(value), &dwcbData);
if (result == ERROR_SUCCESS)
driverVendor = value;
char newDeviceID[MAX_DEVICE_ID_LEN];
CONFIGRET status =
CM_Get_Device_IDA(deviceInfoData.DevInst, newDeviceID, MAX_DEVICE_ID_LEN, 0);
if (status == CR_SUCCESS)
{
std::string id = newDeviceID;
if (id.compare(0, deviceId.size(), deviceId) == 0)
{
*resultOut = driverVersion;
found = true;
}
}
RegCloseKey(key);
}
}
}
return found ? egl::Error(EGL_SUCCESS) : egl::Error(EGL_BAD_MATCH, "No driver version found");
#endif // defined(ANGLE_ENABLE_WINDOWS_STORE)
}
} // namespace rx } // namespace rx
...@@ -70,8 +70,6 @@ class DisplayD3D : public DisplayImpl ...@@ -70,8 +70,6 @@ class DisplayD3D : public DisplayImpl
egl::Surface *drawSurface, egl::Surface *drawSurface,
egl::Surface *readSurface) const override; egl::Surface *readSurface) const override;
egl::Error getDriverVersion(const std::string &deviceId, std::string *resultOut);
private: private:
void generateExtensions(egl::DisplayExtensions *outExtensions) const override; void generateExtensions(egl::DisplayExtensions *outExtensions) const override;
void generateCaps(egl::Caps *outCaps) const override; void generateCaps(egl::Caps *outCaps) const override;
......
...@@ -917,6 +917,18 @@ void Renderer11::populateRenderer11DeviceCaps() ...@@ -917,6 +917,18 @@ void Renderer11::populateRenderer11DeviceCaps()
IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter); IDXGIAdapter2 *dxgiAdapter2 = d3d11::DynamicCastComObject<IDXGIAdapter2>(mDxgiAdapter);
mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr); mRenderer11DeviceCaps.supportsDXGI1_2 = (dxgiAdapter2 != nullptr);
SafeRelease(dxgiAdapter2); SafeRelease(dxgiAdapter2);
LARGE_INTEGER version;
hr = mDxgiAdapter->CheckInterfaceSupport(__uuidof(IDXGIDevice), &version);
if (FAILED(hr))
{
mRenderer11DeviceCaps.driverVersion.reset();
ERR("Error querying driver version from DXGI Adapter.");
}
else
{
mRenderer11DeviceCaps.driverVersion = version;
}
} }
egl::ConfigSet Renderer11::generateConfigs() egl::ConfigSet Renderer11::generateConfigs()
...@@ -4135,22 +4147,7 @@ void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureC ...@@ -4135,22 +4147,7 @@ void Renderer11::generateCaps(gl::Caps *outCaps, gl::TextureCapsMap *outTextureC
WorkaroundsD3D Renderer11::generateWorkarounds() const WorkaroundsD3D Renderer11::generateWorkarounds() const
{ {
auto displayD3D = GetImplAs<DisplayD3D>(mDisplay); return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription);
std::string driverVersion;
std::stringstream deviceStr;
deviceStr << std::uppercase << std::hex;
deviceStr << "PCI\\VEN_" << std::setfill('0') << std::setw(4) << mAdapterDescription.VendorId;
deviceStr << "&DEV_" << std::setfill('0') << std::setw(4) << mAdapterDescription.DeviceId;
deviceStr << "&SUBSYS_" << std::setfill('0') << std::setw(8) << mAdapterDescription.SubSysId;
deviceStr << "&REV_" << std::setfill('0') << std::setw(2) << mAdapterDescription.Revision;
auto err = displayD3D->getDriverVersion(deviceStr.str(), &driverVersion);
if (err.isError())
{
ERR("error getting driver version: ", err.getMessage().c_str());
}
return d3d11::GenerateWorkarounds(mRenderer11DeviceCaps, mAdapterDescription, driverVersion);
} }
gl::Error Renderer11::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd) gl::Error Renderer11::clearTextures(gl::SamplerType samplerType, size_t rangeStart, size_t rangeEnd)
......
...@@ -52,6 +52,7 @@ struct Renderer11DeviceCaps ...@@ -52,6 +52,7 @@ struct Renderer11DeviceCaps
UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM UINT B5G6R5support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G6R5_UNORM
UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM UINT B4G4R4A4support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B4G4R4A4_UNORM
UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM UINT B5G5R5A1support; // Bitfield of D3D11_FORMAT_SUPPORT values for DXGI_FORMAT_B5G5R5A1_UNORM
Optional<LARGE_INTEGER> driverVersion; // Four-part driver version number.
}; };
enum enum
...@@ -541,5 +542,5 @@ class Renderer11 : public RendererD3D ...@@ -541,5 +542,5 @@ class Renderer11 : public RendererD3D
mutable Optional<bool> mSupportsShareHandles; mutable Optional<bool> mSupportsShareHandles;
}; };
} } // namespace rx
#endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_ #endif // LIBANGLE_RENDERER_D3D_D3D11_RENDERER11_H_
...@@ -1507,8 +1507,7 @@ ID3D11BlendState *LazyBlendState::resolve(ID3D11Device *device) ...@@ -1507,8 +1507,7 @@ ID3D11BlendState *LazyBlendState::resolve(ID3D11Device *device)
} }
WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps, WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
const DXGI_ADAPTER_DESC &adapterDesc, const DXGI_ADAPTER_DESC &adapterDesc)
const std::string &driverVersion)
{ {
bool is9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3); bool is9_3 = (deviceCaps.featureLevel <= D3D_FEATURE_LEVEL_9_3);
...@@ -1521,21 +1520,13 @@ WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps, ...@@ -1521,21 +1520,13 @@ WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
// TODO(jmadill): Narrow problematic driver range. // TODO(jmadill): Narrow problematic driver range.
if (adapterDesc.VendorId == VENDOR_ID_NVIDIA) if (adapterDesc.VendorId == VENDOR_ID_NVIDIA)
{ {
if (!driverVersion.empty()) if (deviceCaps.driverVersion.valid())
{ {
// parse the major and minor version numbers WORD part1 = HIWORD(deviceCaps.driverVersion.value().LowPart);
uint32_t x, y, z, w; WORD part2 = LOWORD(deviceCaps.driverVersion.value().LowPart);
std::stringstream parser(driverVersion);
parser >> x;
parser.ignore(1);
parser >> y;
parser.ignore(1);
parser >> z;
parser.ignore(1);
parser >> w;
// Disable the workaround to fix a second driver bug on newer NVIDIA. // Disable the workaround to fix a second driver bug on newer NVIDIA.
workarounds.depthStencilBlitExtraCopy = (z <= 13u && w < 6881); workarounds.depthStencilBlitExtraCopy = (part1 <= 13u && part2 < 6881);
} }
else else
{ {
......
...@@ -347,8 +347,7 @@ void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, c ...@@ -347,8 +347,7 @@ void SetBufferData(ID3D11DeviceContext *context, ID3D11Buffer *constantBuffer, c
} }
WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps, WorkaroundsD3D GenerateWorkarounds(const Renderer11DeviceCaps &deviceCaps,
const DXGI_ADAPTER_DESC &adapterDesc, const DXGI_ADAPTER_DESC &adapterDesc);
const std::string &driverVersion);
enum ReservedConstantBufferSlot enum ReservedConstantBufferSlot
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment