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) ...@@ -436,6 +436,16 @@ bool ProgramD3D::validateSamplers(gl::InfoLog *infoLog, const gl::Caps &caps)
LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) 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>(); int compileFlags = stream->readInt<int>();
if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL) if (compileFlags != ANGLE_COMPILE_OPTIMIZATION_LEVEL)
{ {
...@@ -678,16 +688,6 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -678,16 +688,6 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
stream->skip(geometryShaderSize); 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(); initializeUniformStorage();
initAttributesByLayout(); initAttributesByLayout();
...@@ -696,6 +696,11 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream) ...@@ -696,6 +696,11 @@ LinkResult ProgramD3D::load(gl::InfoLog &infoLog, gl::BinaryInputStream *stream)
gl::Error ProgramD3D::save(gl::BinaryOutputStream *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(ANGLE_COMPILE_OPTIMIZATION_LEVEL);
stream->writeInt(mShaderVersion); stream->writeInt(mShaderVersion);
...@@ -849,9 +854,6 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream) ...@@ -849,9 +854,6 @@ gl::Error ProgramD3D::save(gl::BinaryOutputStream *stream)
stream->writeBytes(geometryBlob, geometryShaderSize); stream->writeBytes(geometryBlob, geometryShaderSize);
} }
GUID binaryIdentifier = mRenderer->getAdapterIdentifier();
stream->writeBytes(reinterpret_cast<unsigned char*>(&binaryIdentifier), sizeof(GUID));
return gl::Error(GL_NO_ERROR); return gl::Error(GL_NO_ERROR);
} }
......
...@@ -51,6 +51,15 @@ enum ShaderType ...@@ -51,6 +51,15 @@ enum ShaderType
SHADER_GEOMETRY SHADER_GEOMETRY
}; };
struct DeviceIdentifier
{
UINT VendorId;
UINT DeviceId;
UINT SubSysId;
UINT Revision;
UINT FeatureLevel;
};
enum RendererClass enum RendererClass
{ {
RENDERER_D3D11, RENDERER_D3D11,
...@@ -98,7 +107,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D ...@@ -98,7 +107,7 @@ class RendererD3D : public Renderer, public BufferFactoryD3D
virtual std::string getShaderModelSuffix() const = 0; virtual std::string getShaderModelSuffix() const = 0;
// Direct3D Specific methods // 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; virtual SwapChainD3D *createSwapChain(NativeWindow nativeWindow, HANDLE shareHandle, GLenum backBufferFormat, GLenum depthBufferFormat) = 0;
......
...@@ -2445,14 +2445,17 @@ std::string Renderer11::getRendererDescription() const ...@@ -2445,14 +2445,17 @@ std::string Renderer11::getRendererDescription() const
return rendererString.str(); return rendererString.str();
} }
GUID Renderer11::getAdapterIdentifier() const DeviceIdentifier Renderer11::getAdapterIdentifier() const
{ {
// Use the adapter LUID as our adapter ID // Don't use the AdapterLuid here, since that doesn't persist across reboot.
// This number is local to a machine is only guaranteed to be unique between restarts DeviceIdentifier deviceIdentifier = { 0 };
static_assert(sizeof(LUID) <= sizeof(GUID), "Size of GUID must be at least as large as LUID."); deviceIdentifier.VendorId = mAdapterDescription.VendorId;
GUID adapterId = {0}; deviceIdentifier.DeviceId = mAdapterDescription.DeviceId;
memcpy(&adapterId, &mAdapterDescription.AdapterLuid, sizeof(LUID)); deviceIdentifier.SubSysId = mAdapterDescription.SubSysId;
return adapterId; deviceIdentifier.Revision = mAdapterDescription.Revision;
deviceIdentifier.FeatureLevel = static_cast<UINT>(mRenderer11DeviceCaps.featureLevel);
return deviceIdentifier;
} }
unsigned int Renderer11::getReservedVertexUniformVectors() const unsigned int Renderer11::getReservedVertexUniformVectors() const
......
...@@ -150,7 +150,7 @@ class Renderer11 : public RendererD3D ...@@ -150,7 +150,7 @@ class Renderer11 : public RendererD3D
VendorID getVendorId() const override; VendorID getVendorId() const override;
std::string getRendererDescription() const override; std::string getRendererDescription() const override;
GUID getAdapterIdentifier() const override; DeviceIdentifier getAdapterIdentifier() const override;
virtual unsigned int getReservedVertexUniformVectors() const; virtual unsigned int getReservedVertexUniformVectors() const;
virtual unsigned int getReservedFragmentUniformVectors() const; virtual unsigned int getReservedFragmentUniformVectors() const;
......
...@@ -2461,9 +2461,16 @@ std::string Renderer9::getRendererDescription() const ...@@ -2461,9 +2461,16 @@ std::string Renderer9::getRendererDescription() const
return rendererString.str(); 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 unsigned int Renderer9::getReservedVertexUniformVectors() const
......
...@@ -131,7 +131,7 @@ class Renderer9 : public RendererD3D ...@@ -131,7 +131,7 @@ class Renderer9 : public RendererD3D
VendorID getVendorId() const override; VendorID getVendorId() const override;
std::string getRendererDescription() const override; std::string getRendererDescription() const override;
GUID getAdapterIdentifier() const override; DeviceIdentifier getAdapterIdentifier() const override;
IDirect3DDevice9 *getDevice() { return mDevice; } IDirect3DDevice9 *getDevice() { return mDevice; }
void *getD3DDevice() override; 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