From d09546e1ec906c5027c25ba0ba3a49e5affb6643 Mon Sep 17 00:00:00 2001 From: Jamie Madill Date: Fri, 22 Feb 2019 10:24:44 -0500 Subject: [PATCH] D3D: Fall back to old compiler DLL. This is a workaround for Windows 7 users sometimes not having the UCRT required for the new versions of the MS HLSL compiler. It requires a specific version of the Windows SDK with the old compiler DLL. Bug: chromium:920704 Change-Id: Id9adb3b9d569272cbd69a8b4fc99dc160d837dbc Reviewed-on: https://chromium-review.googlesource.com/c/1403254 Reviewed-by: Jamie Madill Reviewed-by: Bruce Dawson Commit-Queue: Jamie Madill --- BUILD.gn | 13 ++++++- scripts/file_exists.py | 22 ++++++++++++ src/libANGLE/renderer/d3d/HLSLCompiler.cpp | 40 ++++++++++++++++++---- 3 files changed, 67 insertions(+), 8 deletions(-) create mode 100644 scripts/file_exists.py diff --git a/BUILD.gn b/BUILD.gn index 4559f4fa9..050737910 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -153,12 +153,23 @@ config("build_id_config") { # Windows ARM64 is available since 10.0.16299 so no need to copy # d3dcompiler_47.dll because this file is available as inbox. if (is_win && target_cpu != "arm64") { + # We also ship an older DLL for compatiblity with Windows 7 machines without + # the UCRT. This DLL isn't available in the standard SDK distribution. + _old_compiler = "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_old.dll" + _has_old_compiler = + exec_script("scripts/file_exists.py", [ _old_compiler ], "value") + copy("copy_compiler_dll") { sources = [ "$windows_sdk_path/Redist/D3D/$target_cpu/d3dcompiler_47.dll", ] + + if (_has_old_compiler) { + sources += [ _old_compiler ] + } + outputs = [ - "$root_out_dir/d3dcompiler_47.dll", + "$root_out_dir/{{source_file_part}}", ] } } diff --git a/scripts/file_exists.py b/scripts/file_exists.py new file mode 100644 index 000000000..d492be6bf --- /dev/null +++ b/scripts/file_exists.py @@ -0,0 +1,22 @@ +#!/usr/bin/python2 +# Copyright 2019 The ANGLE Project Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. +# +# Simple helper for use in 'gn' files to check if a file exists. + +import os, shutil, sys + +def main(): + if len(sys.argv) != 2: + print "Usage: %s " % sys.argv[0] + sys.exit(1) + + if os.path.exists(sys.argv[1]): + print "true" + else: + print "false" + sys.exit(0) + +if __name__ == '__main__': + main() diff --git a/src/libANGLE/renderer/d3d/HLSLCompiler.cpp b/src/libANGLE/renderer/d3d/HLSLCompiler.cpp index 371471e6b..323929568 100644 --- a/src/libANGLE/renderer/d3d/HLSLCompiler.cpp +++ b/src/libANGLE/renderer/d3d/HLSLCompiler.cpp @@ -16,9 +16,9 @@ #include "libANGLE/renderer/d3d/ContextD3D.h" #include "third_party/trace_event/trace_event.h" -#if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED namespace { +#if ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED # ifdef CREATE_COMPILER_FLAG_INFO # undef CREATE_COMPILER_FLAG_INFO # endif @@ -81,9 +81,19 @@ bool IsCompilerFlagSet(UINT mask, UINT flag) return isFlagSet; } } -} // anonymous namespace #endif // ANGLE_APPEND_ASSEMBLY_TO_SHADER_DEBUG_INFO == ANGLE_ENABLED +constexpr char kOldCompilerLibrary[] = "d3dcompiler_old.dll"; + +enum D3DCompilerLoadLibraryResult +{ + D3DCompilerDefaultLibrarySuccess, + D3DCompilerOldLibrarySuccess, + D3DCompilerFailure, + D3DCompilerEnumBoundary, +}; +} // anonymous namespace + namespace rx { @@ -132,15 +142,31 @@ angle::Result HLSLCompiler::ensureInitialized(d3d::Context *context) // built with. mD3DCompilerModule = LoadLibraryA(D3DCOMPILER_DLL_A); - if (!mD3DCompilerModule) + if (mD3DCompilerModule) { - DWORD lastError = GetLastError(); - ERR() << "LoadLibrary(" << D3DCOMPILER_DLL_A << ") failed. GetLastError=" << lastError; - ANGLE_TRY_HR(context, E_OUTOFMEMORY, "LoadLibrary failed to load D3D Compiler DLL."); + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult", + D3DCompilerDefaultLibrarySuccess, D3DCompilerEnumBoundary); + } + else + { + WARN() << "Failed to load HLSL compiler library. Trying old DLL."; + mD3DCompilerModule = LoadLibraryA(kOldCompilerLibrary); + if (mD3DCompilerModule) + { + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult", + D3DCompilerOldLibrarySuccess, D3DCompilerEnumBoundary); + } } } - ASSERT(mD3DCompilerModule); + if (!mD3DCompilerModule) + { + DWORD lastError = GetLastError(); + ERR() << "LoadLibrary(" << D3DCOMPILER_DLL_A << ") failed. GetLastError=" << lastError; + ANGLE_HISTOGRAM_ENUMERATION("GPU.ANGLE.D3DCompilerLoadLibraryResult", D3DCompilerFailure, + D3DCompilerEnumBoundary); + ANGLE_TRY_HR(context, E_OUTOFMEMORY, "LoadLibrary failed to load D3D Compiler DLL."); + } mD3DCompileFunc = reinterpret_cast(GetProcAddress(mD3DCompilerModule, "D3DCompile"));