D3D12: Add HLSL compiler version to key
BUG=dawn:529
Change-Id: I84d8edc6022564cda084a0f0de384a4e15e0e1a1
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/35480
Reviewed-by: Austin Eng <enga@chromium.org>
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Bryan Bernhart <bryan.bernhart@intel.com>
diff --git a/src/dawn_native/d3d12/BackendD3D12.cpp b/src/dawn_native/d3d12/BackendD3D12.cpp
index 946ce7b..8d61208 100644
--- a/src/dawn_native/d3d12/BackendD3D12.cpp
+++ b/src/dawn_native/d3d12/BackendD3D12.cpp
@@ -128,6 +128,16 @@
return mDxcCompiler.Get();
}
+ ResultOrError<IDxcValidator*> Backend::GetOrCreateDxcValidator() {
+ if (mDxcValidator == nullptr) {
+ DAWN_TRY(CheckHRESULT(
+ mFunctions->dxcCreateInstance(CLSID_DxcValidator, IID_PPV_ARGS(&mDxcValidator)),
+ "DXC create validator"));
+ ASSERT(mDxcValidator != nullptr);
+ }
+ return mDxcValidator.Get();
+ }
+
const PlatformFunctions* Backend::GetFunctions() const {
return mFunctions.get();
}
diff --git a/src/dawn_native/d3d12/BackendD3D12.h b/src/dawn_native/d3d12/BackendD3D12.h
index 87c2d13..0490b60 100644
--- a/src/dawn_native/d3d12/BackendD3D12.h
+++ b/src/dawn_native/d3d12/BackendD3D12.h
@@ -32,6 +32,7 @@
ComPtr<IDXGIFactory4> GetFactory() const;
ResultOrError<IDxcLibrary*> GetOrCreateDxcLibrary();
ResultOrError<IDxcCompiler*> GetOrCreateDxcCompiler();
+ ResultOrError<IDxcValidator*> GetOrCreateDxcValidator();
const PlatformFunctions* GetFunctions() const;
std::vector<std::unique_ptr<AdapterBase>> DiscoverDefaultAdapters() override;
@@ -45,6 +46,7 @@
ComPtr<IDXGIFactory4> mFactory;
ComPtr<IDxcLibrary> mDxcLibrary;
ComPtr<IDxcCompiler> mDxcCompiler;
+ ComPtr<IDxcValidator> mDxcValidator;
};
}} // namespace dawn_native::d3d12
diff --git a/src/dawn_native/d3d12/DeviceD3D12.cpp b/src/dawn_native/d3d12/DeviceD3D12.cpp
index 1d15eb5..a03b048 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.cpp
+++ b/src/dawn_native/d3d12/DeviceD3D12.cpp
@@ -218,6 +218,10 @@
return ToBackend(GetAdapter())->GetBackend()->GetOrCreateDxcCompiler();
}
+ ResultOrError<IDxcValidator*> Device::GetOrCreateDxcValidator() const {
+ return ToBackend(GetAdapter())->GetBackend()->GetOrCreateDxcValidator();
+ }
+
const PlatformFunctions* Device::GetFunctions() const {
return ToBackend(GetAdapter())->GetBackend()->GetFunctions();
}
diff --git a/src/dawn_native/d3d12/DeviceD3D12.h b/src/dawn_native/d3d12/DeviceD3D12.h
index 732e187..c35df07 100644
--- a/src/dawn_native/d3d12/DeviceD3D12.h
+++ b/src/dawn_native/d3d12/DeviceD3D12.h
@@ -74,6 +74,7 @@
ComPtr<IDXGIFactory4> GetFactory() const;
ResultOrError<IDxcLibrary*> GetOrCreateDxcLibrary() const;
ResultOrError<IDxcCompiler*> GetOrCreateDxcCompiler() const;
+ ResultOrError<IDxcValidator*> GetOrCreateDxcValidator() const;
ResultOrError<CommandRecordingContext*> GetPendingCommandContext();
diff --git a/src/dawn_native/d3d12/ShaderModuleD3D12.cpp b/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
index 96bb4ba..b117e3f 100644
--- a/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
+++ b/src/dawn_native/d3d12/ShaderModuleD3D12.cpp
@@ -319,9 +319,12 @@
// layout. The pipeline layout is only required if we key from WGSL: two different pipeline
// layouts could be used to produce different shader blobs and the wrong shader blob could
// be loaded since the pipeline layout was missing from the key.
+ // The compiler flags or version used could also produce different HLSL source. HLSL key
+ // needs both to ensure the shader cache key is unique to the HLSL source.
// TODO(dawn:549): Consider keying from WGSL and serialize the pipeline layout it used.
- const PersistentCacheKey& shaderCacheKey =
- CreateHLSLKey(entryPointName, stage, hlslSource, compileFlags);
+ PersistentCacheKey shaderCacheKey;
+ DAWN_TRY_ASSIGN(shaderCacheKey,
+ CreateHLSLKey(entryPointName, stage, hlslSource, compileFlags));
CompiledShader compiledShader = {};
DAWN_TRY_ASSIGN(compiledShader.cachedShader,
@@ -357,10 +360,10 @@
return {};
}
- PersistentCacheKey ShaderModule::CreateHLSLKey(const char* entryPointName,
- SingleShaderStage stage,
- const std::string& hlslSource,
- uint32_t compileFlags) const {
+ ResultOrError<PersistentCacheKey> ShaderModule::CreateHLSLKey(const char* entryPointName,
+ SingleShaderStage stage,
+ const std::string& hlslSource,
+ uint32_t compileFlags) const {
std::stringstream stream;
// Prefix the key with the type to avoid collisions from another type that could have the
@@ -383,7 +386,15 @@
stream << compileFlags;
- // TODO(dawn:549): add the HLSL compiler version for good measure.
+ // Add the HLSL compiler version for good measure.
+ // Prepend the compiler name to ensure the version is always unique.
+ if (GetDevice()->IsToggleEnabled(Toggle::UseDXC)) {
+ uint64_t dxCompilerVersion;
+ DAWN_TRY_ASSIGN(dxCompilerVersion, GetDXCompilerVersion());
+ stream << "DXC" << dxCompilerVersion;
+ } else {
+ stream << "FXC" << GetD3DCompilerVersion();
+ }
// If the source contains multiple entry points, ensure they are cached seperately
// per stage since DX shader code can only be compiled per stage using the same
@@ -394,4 +405,24 @@
return PersistentCacheKey(std::istreambuf_iterator<char>{stream},
std::istreambuf_iterator<char>{});
}
+
+ ResultOrError<uint64_t> ShaderModule::GetDXCompilerVersion() const {
+ ComPtr<IDxcValidator> dxcValidator;
+ DAWN_TRY_ASSIGN(dxcValidator, ToBackend(GetDevice())->GetOrCreateDxcValidator());
+
+ ComPtr<IDxcVersionInfo> versionInfo;
+ DAWN_TRY(CheckHRESULT(dxcValidator.As(&versionInfo),
+ "D3D12 QueryInterface IDxcValidator to IDxcVersionInfo"));
+
+ uint32_t compilerMajor, compilerMinor;
+ DAWN_TRY(CheckHRESULT(versionInfo->GetVersion(&compilerMajor, &compilerMinor),
+ "IDxcVersionInfo::GetVersion"));
+
+ // Pack both into a single version number.
+ return (uint64_t(compilerMajor) << uint64_t(32)) + compilerMinor;
+ }
+
+ uint64_t ShaderModule::GetD3DCompilerVersion() const {
+ return D3D_COMPILER_VERSION;
+ }
}} // namespace dawn_native::d3d12
diff --git a/src/dawn_native/d3d12/ShaderModuleD3D12.h b/src/dawn_native/d3d12/ShaderModuleD3D12.h
index f5a94f0..1f04759 100644
--- a/src/dawn_native/d3d12/ShaderModuleD3D12.h
+++ b/src/dawn_native/d3d12/ShaderModuleD3D12.h
@@ -59,10 +59,13 @@
SingleShaderStage stage,
PipelineLayout* layout) const;
- PersistentCacheKey CreateHLSLKey(const char* entryPointName,
- SingleShaderStage stage,
- const std::string& hlslSource,
- uint32_t compileFlags) const;
+ ResultOrError<PersistentCacheKey> CreateHLSLKey(const char* entryPointName,
+ SingleShaderStage stage,
+ const std::string& hlslSource,
+ uint32_t compileFlags) const;
+
+ ResultOrError<uint64_t> GetDXCompilerVersion() const;
+ uint64_t GetD3DCompilerVersion() const;
#ifdef DAWN_ENABLE_WGSL
std::unique_ptr<tint::ast::Module> mTintModule;