d3d12: Retry root signature serialization with 1.0 if version 1.1 failed
Some drivers do not correctly report what they support, so we need to
try again with version 1.0
Bug: chromium:1512318
Change-Id: Iaf7a38e33cbd95d4442af695eecf79dbb7245469
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/166641
Kokoro: Kokoro <noreply+kokoro@google.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
Commit-Queue: Antonio Maiorano <amaiorano@google.com>
Auto-Submit: Austin Eng <enga@chromium.org>
diff --git a/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp b/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
index 28964bd..c56e294 100644
--- a/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
+++ b/src/dawn/native/d3d12/PipelineLayoutD3D12.cpp
@@ -339,27 +339,36 @@
versionedRootSignatureDescriptor.Desc_1_1.Flags =
D3D12_ROOT_SIGNATURE_FLAG_ALLOW_INPUT_ASSEMBLER_INPUT_LAYOUT;
- ComPtr<ID3DBlob> error;
- HRESULT hr;
- if (device->IsToggleEnabled(Toggle::D3D12UseRootSignatureVersion1_1)) {
- hr = device->GetFunctions()->d3d12SerializeVersionedRootSignature(
- &versionedRootSignatureDescriptor, &mRootSignatureBlob, &error);
- } else {
- hr = SerializeRootParameter1_0(device, versionedRootSignatureDescriptor,
- &mRootSignatureBlob, &error);
- }
- if (DAWN_UNLIKELY(FAILED(hr))) {
+ DAWN_TRY([&]() -> MaybeError {
+ ComPtr<ID3DBlob> error;
+ if (device->IsToggleEnabled(Toggle::D3D12UseRootSignatureVersion1_1) &&
+ DAWN_LIKELY(SUCCEEDED(device->GetFunctions()->d3d12SerializeVersionedRootSignature(
+ &versionedRootSignatureDescriptor, &mRootSignatureBlob, &error)))) {
+ return {};
+ }
+ // If using root signature version 1.1 failed, try again with root signature version 1.0.
+ // Some drivers appear to run an outdated version of the DXIL validator and can't support
+ // 1.1.
+ // Note that retrying again is OK because whether we use version 1.0 or 1.1 doesn't
+ // affect anything else except pipeline layout creation. Nothing else in Dawn cares
+ // what decision we made here.
+ // TODO(crbug.com/1512318): Add some telemetry so we log how often/when this happens.
std::ostringstream messageStream;
if (error) {
- messageStream << static_cast<const char*>(error->GetBufferPointer());
-
- // |error| is observed to always end with a \n, but is not
- // specified to do so, so we add an extra newline just in case.
- messageStream << std::endl;
+ messageStream << static_cast<const char*>(error->GetBufferPointer()) << std::endl;
+ }
+ HRESULT hr = SerializeRootParameter1_0(device, versionedRootSignatureDescriptor,
+ &mRootSignatureBlob, &error);
+ if (DAWN_LIKELY(SUCCEEDED(hr))) {
+ return {};
+ }
+ if (error) {
+ messageStream << static_cast<const char*>(error->GetBufferPointer()) << std::endl;
}
messageStream << "D3D12 serialize root signature";
DAWN_TRY(CheckHRESULT(hr, messageStream.str().c_str()));
- }
+ return {};
+ }());
DAWN_TRY(CheckHRESULT(device->GetD3D12Device()->CreateRootSignature(
0, mRootSignatureBlob->GetBufferPointer(),
mRootSignatureBlob->GetBufferSize(), IID_PPV_ARGS(&mRootSignature)),