Commit 137b1517 by Austin Kinross Committed by Jamie Madill

Improve D3D GetProgramBinary chipset validation

- Check chipset identifying info before trying to compile shaders - Check device feature level when loading a binary - Use chipset VendorID/DeviceID etc instead of LUID so that program binaries remain valid across system reboots Change-Id: I88ba4543bb990956d1d8fb324abf9784d72950cd Reviewed-on: https://chromium-review.googlesource.com/280428Reviewed-by: 's avatarJamie Madill <jmadill@chromium.org> Tested-by: 's avatarJamie Madill <jmadill@chromium.org>
parent 5a6dec50
......@@ -436,6 +436,16 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
{
DeviceIdentifier binaryDeviceIdentifier = { 0 };
stream->readBytes(reinterpret_cast<unsigned char*>(&binaryDeviceIdentifier), sizeof(DeviceIdentifier));
DeviceIdentifier identifier = mRenderer->getAdapterIdentifier();
if (memcmp(&identifier, &binaryDeviceIdentifier, sizeof(DeviceIdentifier)) != 0)
{
infoLog << "Invalid program binary, device configuration has changed.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
int compileFlags = stream->readInt<int>();
if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
{
......@@ -678,16 +688,6 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
stream->skip(geometryShaderSize);
}
GUID binaryIdentifier = {0};
stream->readBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
GUID identifier = mRenderer->getAdapterIdentifier();
if (memcmp(&identifier, &binaryIdentifier, sizeof(GUID)) != 0)
{
infoLog << "Invalid program binary.";
return LinkResult(false, gl::Error(GL_NO_ERROR));
}
initializeUniformStorage();
initAttributesByLayout();
......@@ -696,6 +696,11 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
{
// Output the DeviceIdentifier before we output any shader code
// When we load the binary again later, we can validate the device identifier before trying to compile any HLSL
DeviceIdentifier binaryIdentifier = mRenderer->getAdapterIdentifier();
stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(DeviceIdentifier));
stream->writeInt(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
stream->writeInt(mShaderVersion);
......@@ -849,9 +854,6 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
stream->writeBytes(geometryBlob, geometryShaderSize);
}
GUID binaryIdentifier = mRenderer->getAdapterIdentifier();
stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
return gl::Error(GL_NO_ERROR);
}
......
......@@ -51,6 +51,15 @@ enum ShaderType
SHADER_GEOMETRY
};
struct DeviceIdentifier
{
UINT VendorId;
UINT DeviceId;
UINT SubSysId;
UINT Revision;
UINT FeatureLevel;
};
enum RendererClass
{
RENDERER_D3D11,
......@@ -98,7 +107,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
virtual std::string getShaderModelSuffix() const = 0;
// Direct3D Specific methods
virtual GUID getAdapterIdentifier() const = 0;
virtual DeviceIdentifier getAdapterIdentifier() const = 0;
virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
......
......@@ -2445,14 +2445,17 @@ std::string Renderer11::getRendererDescription() const
return rendererString.str();
}
GUID Renderer11::getAdapterIdentifier() const
{
// Use the adapter LUID as our adapter ID
// This number is local to a machine is only guaranteed to be unique between restarts
static_assert(sizeof(LUID) <= sizeof(GUID), "Size of GUID must be at least as large as LUID.");
GUID adapterId = {0};
memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID));
return adapterId;
DeviceIdentifier Renderer11::getAdapterIdentifier() const
{
// Don't use the AdapterLuid here, since that doesn't persist across reboot.
DeviceIdentifier deviceIdentifier = { 0 };
deviceIdentifier.VendorId = mAdapterDescription.VendorId;
deviceIdentifier.DeviceId = mAdapterDescription.DeviceId;
deviceIdentifier.SubSysId = mAdapterDescription.SubSysId;
deviceIdentifier.Revision = mAdapterDescription.Revision;
deviceIdentifier.FeatureLevel = static_cast<UINT>(mRenderer11DeviceCaps.featureLevel);
return deviceIdentifier;
}
unsigned int Renderer11::getReservedVertexUniformVectors() const
......
......@@ -150,7 +150,7 @@ class Renderer11 : public RendererD3D
VendorID getVendorId() const override;
std::string getRendererDescription() const override;
GUID getAdapterIdentifier() const override;
DeviceIdentifier getAdapterIdentifier() const override;
virtual unsigned int getReservedVertexUniformVectors() const;
virtual unsigned int getReservedFragmentUniformVectors() const;
......
......@@ -2461,9 +2461,16 @@ std::string Renderer9::getRendererDescription() const
return rendererString.str();
}
GUID Renderer9::getAdapterIdentifier() const
DeviceIdentifier Renderer9::getAdapterIdentifier() const
{
return mAdapterIdentifier.DeviceIdentifier;
DeviceIdentifier deviceIdentifier = { 0 };
deviceIdentifier.VendorId = static_cast<UINT>(mAdapterIdentifier.VendorId);
deviceIdentifier.DeviceId = static_cast<UINT>(mAdapterIdentifier.DeviceId);
deviceIdentifier.SubSysId = static_cast<UINT>(mAdapterIdentifier.SubSysId);
deviceIdentifier.Revision = static_cast<UINT>(mAdapterIdentifier.Revision);
deviceIdentifier.FeatureLevel = 0;
return deviceIdentifier;
}
unsigned int Renderer9::getReservedVertexUniformVectors() const
......
......@@ -131,7 +131,7 @@ class Renderer9 : public RendererD3D
VendorID getVendorId() const override;
std::string getRendererDescription() const override;
GUID getAdapterIdentifier() const override;
DeviceIdentifier getAdapterIdentifier() const override;
IDirect3DDevice9 *getDevice() { return mDevice; }
void *getD3DDevice() override;
......
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