Improve DX compiler library loading

Previously, DX compiler DLLs were loaded using LoadLibrary with no path.
D3D12 compiler DLLs were further sourced from the local user's SDK
directory as a fallback.

For better security, load DX compiler DLLs using full paths, with
SEARCH_DLL_LOAD_DIR | SEARCH_DEFAULT_DIRS for better security. Scenarios
such as Skia and x86 builds where we need dawn_use_built_dxc will
fallback to FXC. No fallbacks to local user SDK directories.

Bug:356665092
Change-Id: Ib4148f9b89da694e3868b4f3c3c329a4b06ce922
Reviewed-on: https://dawn-review.googlesource.com/c/dawn/+/229754
Reviewed-by: Corentin Wallez <cwallez@chromium.org>
Commit-Queue: Rafael Cintron <rafael.cintron@microsoft.com>
Reviewed-by: Antonio Maiorano <amaiorano@google.com>
diff --git a/src/dawn/common/DynamicLib.cpp b/src/dawn/common/DynamicLib.cpp
index d700aa0..d9cdae7 100644
--- a/src/dawn/common/DynamicLib.cpp
+++ b/src/dawn/common/DynamicLib.cpp
@@ -78,7 +78,9 @@
 #if DAWN_PLATFORM_IS(WINUWP)
     mHandle = LoadPackagedLibrary(UTF8ToWStr(filename.c_str()).c_str(), 0);
 #else
-    mHandle = LoadLibraryA(filename.c_str());
+    // Use SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS to avoid DLL search path attacks.
+    mHandle = LoadLibraryExA(filename.c_str(), nullptr,
+                             LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR | LOAD_LIBRARY_SEARCH_DEFAULT_DIRS);
 #endif
     if (mHandle == nullptr && error != nullptr) {
         *error = "Windows Error: " + std::to_string(GetLastError());
diff --git a/src/dawn/native/d3d/D3DCompilationRequest.h b/src/dawn/native/d3d/D3DCompilationRequest.h
index 65d07f9..73ceead 100644
--- a/src/dawn/native/d3d/D3DCompilationRequest.h
+++ b/src/dawn/native/d3d/D3DCompilationRequest.h
@@ -65,7 +65,6 @@
     X(uint32_t, shaderModel)                                                                     \
     X(uint32_t, compileFlags)                                                                    \
     X(Compiler, compiler)                                                                        \
-    X(uint64_t, compilerVersion)                                                                 \
     X(std::wstring_view, dxcShaderProfile)                                                       \
     X(std::string_view, fxcShaderProfile)                                                        \
     X(pD3DCompile, d3dCompile)                                                                   \
@@ -86,7 +85,6 @@
     X(bool, hasShaderF16Feature)                    \
     X(uint32_t, compileFlags)                       \
     X(Compiler, compiler)                           \
-    X(uint64_t, compilerVersion)                    \
     X(std::wstring_view, dxcShaderProfile)          \
     X(std::string_view, fxcShaderProfile)           \
     X(pD3DCompile, d3dCompile)                      \
diff --git a/src/dawn/native/d3d/PlatformFunctions.cpp b/src/dawn/native/d3d/PlatformFunctions.cpp
index 5efe68e..d7a67b8 100644
--- a/src/dawn/native/d3d/PlatformFunctions.cpp
+++ b/src/dawn/native/d3d/PlatformFunctions.cpp
@@ -32,6 +32,8 @@
 
 #include <vector>
 
+#include "dawn/common/SystemUtils.h"
+
 namespace dawn::native::d3d {
 
 namespace {
@@ -96,7 +98,9 @@
     d3dDisassemble = &D3DDisassemble;
 #else
     std::string error;
-    if (!mFXCompilerLib.Open("d3dcompiler_47.dll", &error) ||
+    const auto modulePath = GetModuleDirectory();
+    const std::string& pathToPrepend = modulePath.value_or("");
+    if (!mFXCompilerLib.Open(pathToPrepend + "d3dcompiler_47.dll", &error) ||
         !mFXCompilerLib.GetProc(&d3dCompile, "D3DCompile", &error) ||
         !mFXCompilerLib.GetProc(&d3dDisassemble, "D3DDisassemble", &error)) {
         return DAWN_INTERNAL_ERROR(error.c_str());
diff --git a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
index 575c1a4..4835a5d 100644
--- a/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
+++ b/src/dawn/native/d3d11/ShaderModuleD3D11.cpp
@@ -101,7 +101,6 @@
     // D3D11 only supports FXC.
     req.bytecode.compiler = d3d::Compiler::FXC;
     req.bytecode.d3dCompile = device->GetFunctions()->d3dCompile;
-    req.bytecode.compilerVersion = D3D_COMPILER_VERSION;
     DAWN_ASSERT(device->GetDeviceInfo().shaderModel == 50);
     switch (stage) {
         case SingleShaderStage::Vertex:
diff --git a/src/dawn/native/d3d12/BackendD3D12.cpp b/src/dawn/native/d3d12/BackendD3D12.cpp
index a94fb13..6e475aa 100644
--- a/src/dawn/native/d3d12/BackendD3D12.cpp
+++ b/src/dawn/native/d3d12/BackendD3D12.cpp
@@ -40,14 +40,6 @@
 
 namespace dawn::native::d3d12 {
 
-namespace {
-
-uint64_t MakeDXCVersion(uint64_t majorVersion, uint64_t minorVersion) {
-    return (majorVersion << 32) + minorVersion;
-}
-
-}  // anonymous namespace
-
 Backend::Backend(InstanceBase* instance) : Base(instance, wgpu::BackendType::D3D12) {}
 
 MaybeError Backend::Initialize() {
@@ -60,49 +52,10 @@
         DAWN_TRY(Base::Initialize(std::move(functions)));
     }
 
-    // Check if DXC is available and cache DXC version information
-    if (!GetFunctions()->IsDXCBinaryAvailable()) {
-        // DXC version information is not available if DXC binaries are not available.
-        mDxcVersionInfo = DxcUnavailable{"DXC binary is not available"};
-    } else {
-        // Check the DXC version information and validate them being not lower than pre-defined
-        // minimum version.
-        AcquireDxcVersionInformation();
-
-        // Check that DXC version information is acquired successfully.
-        if (std::holds_alternative<DxcVersionInfo>(mDxcVersionInfo)) {
-            const DxcVersionInfo& dxcVersionInfo = std::get<DxcVersionInfo>(mDxcVersionInfo);
-
-            // The required minimum version for DXC compiler and validator.
-            // Notes about requirement consideration:
-            //   * DXC version 1.4 has some known issues when compiling Tint generated HLSL program,
-            //   please
-            //     refer to crbug.com/tint/1719
-            //   * Windows SDK 20348 provides DXC compiler and validator version 1.6
-            // Here the minimum version requirement for DXC compiler and validator are both set
-            // to 1.6.
-            constexpr uint64_t minimumCompilerMajorVersion = 1;
-            constexpr uint64_t minimumCompilerMinorVersion = 6;
-            constexpr uint64_t minimumValidatorMajorVersion = 1;
-            constexpr uint64_t minimumValidatorMinorVersion = 6;
-
-            // Check that DXC compiler and validator version are not lower than minimum.
-            if (dxcVersionInfo.DxcCompilerVersion <
-                    MakeDXCVersion(minimumCompilerMajorVersion, minimumCompilerMinorVersion) ||
-                dxcVersionInfo.DxcValidatorVersion <
-                    MakeDXCVersion(minimumValidatorMajorVersion, minimumValidatorMinorVersion)) {
-                // If DXC version is lower than required minimum, set mDxcVersionInfo to
-                // DxcUnavailable to indicate that DXC is not available.
-                std::ostringstream ss;
-                ss << "DXC version too low: dxil.dll required version 1.6, actual version "
-                   << (dxcVersionInfo.DxcValidatorVersion >> 32) << "."
-                   << (dxcVersionInfo.DxcValidatorVersion & ((uint64_t(1) << 32) - 1))
-                   << ", dxcompiler.dll required version 1.6, actual version "
-                   << (dxcVersionInfo.DxcCompilerVersion >> 32) << "."
-                   << (dxcVersionInfo.DxcCompilerVersion & ((uint64_t(1) << 32) - 1));
-                mDxcVersionInfo = DxcUnavailable{ss.str()};
-            }
-        }
+    // Check if DXC is available and initialize its validator and compiler interfaces.
+    if (GetFunctions()->IsDXCBinaryAvailable()) {
+        DAWN_TRY(EnsureDxcValidator());
+        DAWN_TRY(EnsureDxcCompiler());
     }
 
     // Enable the debug layer (requires the Graphics Tools "optional feature").
@@ -182,83 +135,9 @@
     return mDxcValidator;
 }
 
-void Backend::AcquireDxcVersionInformation() {
-    DAWN_ASSERT(std::holds_alternative<DxcUnavailable>(mDxcVersionInfo));
-
-    auto tryAcquireDxcVersionInfo = [this]() -> ResultOrError<DxcVersionInfo> {
-        DAWN_TRY(EnsureDxcValidator());
-        DAWN_TRY(EnsureDxcCompiler());
-
-        ComPtr<IDxcVersionInfo> compilerVersionInfo;
-
-        DAWN_TRY(CheckHRESULT(mDxcCompiler.As(&compilerVersionInfo),
-                              "D3D12 QueryInterface IDxcCompiler3 to IDxcVersionInfo"));
-        uint32_t compilerMajor, compilerMinor;
-        DAWN_TRY(CheckHRESULT(compilerVersionInfo->GetVersion(&compilerMajor, &compilerMinor),
-                              "IDxcVersionInfo::GetVersion"));
-
-        ComPtr<IDxcVersionInfo> validatorVersionInfo;
-
-        DAWN_TRY(CheckHRESULT(mDxcValidator.As(&validatorVersionInfo),
-                              "D3D12 QueryInterface IDxcValidator to IDxcVersionInfo"));
-        uint32_t validatorMajor, validatorMinor;
-        DAWN_TRY(CheckHRESULT(validatorVersionInfo->GetVersion(&validatorMajor, &validatorMinor),
-                              "IDxcVersionInfo::GetVersion"));
-
-        // Pack major and minor version number into a single version number.
-        uint64_t compilerVersion = MakeDXCVersion(compilerMajor, compilerMinor);
-        uint64_t validatorVersion = MakeDXCVersion(validatorMajor, validatorMinor);
-        return DxcVersionInfo{compilerVersion, validatorVersion};
-    };
-
-    auto dxcVersionInfoOrError = tryAcquireDxcVersionInfo();
-
-    if (dxcVersionInfoOrError.IsSuccess()) {
-        // Cache the DXC version information.
-        mDxcVersionInfo = dxcVersionInfoOrError.AcquireSuccess();
-    } else {
-        // Error occurs when acquiring DXC version information, set the cache to unavailable and
-        // record the error message.
-        std::string errorMessage = dxcVersionInfoOrError.AcquireError()->GetFormattedMessage();
-        dawn::ErrorLog() << errorMessage;
-        mDxcVersionInfo = DxcUnavailable{errorMessage};
-    }
-}
-
-// Return both DXC compiler and DXC validator version, assert that DXC version information is
-// acquired successfully.
-DxcVersionInfo Backend::GetDxcVersion() const {
-    DAWN_ASSERT(std::holds_alternative<DxcVersionInfo>(mDxcVersionInfo));
-    return DxcVersionInfo(std::get<DxcVersionInfo>(mDxcVersionInfo));
-}
-
-// Return true if and only if DXC binary is available, and the DXC version is validated to
-// be no older than a pre-defined minimum version.
+// Return true if and only if DXC binary is available.
 bool Backend::IsDXCAvailable() const {
-    // mDxcVersionInfo hold DxcVersionInfo instead of DxcUnavailable if and only if DXC binaries and
-    // version are validated in `Initialize`.
-    return std::holds_alternative<DxcVersionInfo>(mDxcVersionInfo);
-}
-
-// Return true if and only if IsDXCAvailable() return true, and the DXC compiler and validator
-// version are validated to be no older than the minimum version given in parameter.
-bool Backend::IsDXCAvailableAndVersionAtLeast(uint64_t minimumCompilerMajorVersion,
-                                              uint64_t minimumCompilerMinorVersion,
-                                              uint64_t minimumValidatorMajorVersion,
-                                              uint64_t minimumValidatorMinorVersion) const {
-    // mDxcVersionInfo hold DxcVersionInfo instead of DxcUnavailable if and only if DXC binaries and
-    // version are validated in `Initialize`.
-    if (std::holds_alternative<DxcVersionInfo>(mDxcVersionInfo)) {
-        const DxcVersionInfo& dxcVersionInfo = std::get<DxcVersionInfo>(mDxcVersionInfo);
-        // Check that DXC compiler and validator version are not lower than given requirements.
-        if (dxcVersionInfo.DxcCompilerVersion >=
-                MakeDXCVersion(minimumCompilerMajorVersion, minimumCompilerMinorVersion) &&
-            dxcVersionInfo.DxcValidatorVersion >=
-                MakeDXCVersion(minimumValidatorMajorVersion, minimumValidatorMinorVersion)) {
-            return true;
-        }
-    }
-    return false;
+    return GetFunctions()->IsDXCBinaryAvailable();
 }
 
 ResultOrError<Ref<PhysicalDeviceBase>> Backend::CreatePhysicalDeviceFromIDXGIAdapter(
diff --git a/src/dawn/native/d3d12/BackendD3D12.h b/src/dawn/native/d3d12/BackendD3D12.h
index 57dd2e5..467e735 100644
--- a/src/dawn/native/d3d12/BackendD3D12.h
+++ b/src/dawn/native/d3d12/BackendD3D12.h
@@ -41,14 +41,6 @@
 
 class PlatformFunctions;
 
-// DxcVersionInfo holds both DXC compiler (dxcompiler.dll) version and DXC validator (dxil.dll)
-// version, which are not necessarily identical. Both are in uint64_t type, as the result of
-// MakeDXCVersion.
-struct DxcVersionInfo {
-    uint64_t DxcCompilerVersion;
-    uint64_t DxcValidatorVersion;
-};
-
 // If DXC version information is not available due to no DXC binary or error occurs when acquiring
 // version, DxcUnavailable indicates the version information being unavailable and holds the
 // detailed error information.
@@ -72,17 +64,6 @@
     // version are validated to be no older than a specific minimum version, currently 1.6.
     bool IsDXCAvailable() const;
 
-    // Return true if and only if mIsDXCAvailable is true, and the DXC compiler and validator
-    // version are validated to be no older than the minimum version given in parameter.
-    bool IsDXCAvailableAndVersionAtLeast(uint64_t minimumCompilerMajorVersion,
-                                         uint64_t minimumCompilerMinorVersion,
-                                         uint64_t minimumValidatorMajorVersion,
-                                         uint64_t minimumValidatorMinorVersion) const;
-
-    // Return the DXC version information cached in mDxcVersionInformation, assert that the version
-    // information is valid. Must be called after ensuring `IsDXCAvailable()` return true.
-    DxcVersionInfo GetDxcVersion() const;
-
     const PlatformFunctions* GetFunctions() const;
 
   protected:
@@ -90,24 +71,10 @@
         ComPtr<IDXGIAdapter> dxgiAdapter) override;
 
   private:
-    // Acquiring DXC version information and store the result in mDxcVersionInfo. This function
-    // should be called only once, during startup in `Initialize`.
-    void AcquireDxcVersionInformation();
-
     ComPtr<IDxcLibrary> mDxcLibrary;
     ComPtr<IDxcCompiler3> mDxcCompiler;
     ComPtr<IDxcValidator> mDxcValidator;
 
-    // DXC binaries and DXC version information are checked when start up in `Initialize`. There are
-    // two possible states:
-    //   1. The DXC binary is not available, or error occurs when checking the version information
-    //      and therefore no DXC version information available, or the DXC version is lower than
-    //      requested minimum and therefore DXC is not available, represented by DxcUnavailable
-    //      in which a error message is held;
-    //   3. The DXC version information is acquired successfully and validated not lower than
-    //      requested minimum, stored in DxcVersionInfo.
-    std::variant<DxcUnavailable, DxcVersionInfo> mDxcVersionInfo;
-
     using Base = d3d::Backend;
 };
 
diff --git a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
index 55dd073..1e78e94 100644
--- a/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
+++ b/src/dawn/native/d3d12/PhysicalDeviceD3D12.cpp
@@ -176,8 +176,8 @@
     // ShaderF16 features require DXC version being 1.4 or higher, shader model supporting 6.2 or
     // higher, and native supporting F16 shader ops.
     bool shaderF16Enabled = false;
-    if (GetBackend()->IsDXCAvailableAndVersionAtLeast(1, 4, 1, 4) &&
-        mDeviceInfo.highestSupportedShaderModel >= 62 && mDeviceInfo.supportsNative16BitShaderOps) {
+    if (GetBackend()->IsDXCAvailable() && mDeviceInfo.highestSupportedShaderModel >= 62 &&
+        mDeviceInfo.supportsNative16BitShaderOps) {
         EnableFeature(Feature::ShaderF16);
         shaderF16Enabled = true;
     }
@@ -561,25 +561,22 @@
 
 void PhysicalDevice::SetupBackendAdapterToggles(dawn::platform::Platform* platform,
                                                 TogglesState* adapterToggles) const {
-    // Check for use_dxc toggle
 #ifdef DAWN_USE_BUILT_DXC
-    // Default to using DXC. If shader model < 6.0, though, we must use FXC.
+    DAWN_CHECK(GetBackend()->IsDXCAvailable());
     if (GetDeviceInfo().highestSupportedShaderModel < 60) {
+        // If shader model < 6.0, though, we must use FXC.
         adapterToggles->ForceSet(Toggle::UseDXC, false);
     }
-
-    bool useDxc = platform->IsFeatureEnabled(dawn::platform::Features::kWebGPUUseDXC);
+    const bool useDxc = platform->IsFeatureEnabled(dawn::platform::Features::kWebGPUUseDXC);
     adapterToggles->Default(Toggle::UseDXC, useDxc);
 #else
-    // Default to using FXC
-    if (!GetBackend()->IsDXCAvailable()) {
-        adapterToggles->ForceSet(Toggle::UseDXC, false);
-    }
+    DAWN_CHECK(!GetBackend()->IsDXCAvailable());
+    adapterToggles->ForceSet(Toggle::UseDXC, false);
     adapterToggles->Default(Toggle::UseDXC, false);
 #endif
 
-    uint32_t deviceId = GetDeviceId();
-    uint32_t vendorId = GetVendorId();
+    const uint32_t deviceId = GetDeviceId();
+    const uint32_t vendorId = GetVendorId();
 
     // On Intel Gen12 D3D driver < 32.0.101.5762, using shader model 6.6 will cause unexpected
     // result when adding/subtracting I32/U32 vector/scalar with vector/scalar in constant
@@ -682,16 +679,14 @@
     // Native support of packed 4x8 integer dot product required shader model 6.4 or higher, and
     // DXC 1.4 or higher.
     if (!(GetAppliedShaderModelUnderToggles(*deviceToggles) >= 64) ||
-        !deviceToggles->IsEnabled(Toggle::UseDXC) ||
-        !GetBackend()->IsDXCAvailableAndVersionAtLeast(1, 4, 1, 4)) {
+        !deviceToggles->IsEnabled(Toggle::UseDXC) || !GetBackend()->IsDXCAvailable()) {
         deviceToggles->ForceSet(Toggle::PolyFillPacked4x8DotProduct, true);
     }
 
     // Native support of pack/unpack 4x8 intrinsics required shader model 6.6 or higher, and
     // DXC 1.4 or higher.
     if (!(GetAppliedShaderModelUnderToggles(*deviceToggles) >= 66) ||
-        !deviceToggles->IsEnabled(Toggle::UseDXC) ||
-        !GetBackend()->IsDXCAvailableAndVersionAtLeast(1, 6, 1, 6)) {
+        !deviceToggles->IsEnabled(Toggle::UseDXC) || !GetBackend()->IsDXCAvailable()) {
         deviceToggles->ForceSet(Toggle::D3D12PolyFillPackUnpack4x8, true);
     }
 
diff --git a/src/dawn/native/d3d12/PlatformFunctionsD3D12.cpp b/src/dawn/native/d3d12/PlatformFunctionsD3D12.cpp
index c84c8e4..e49af12 100644
--- a/src/dawn/native/d3d12/PlatformFunctionsD3D12.cpp
+++ b/src/dawn/native/d3d12/PlatformFunctionsD3D12.cpp
@@ -32,92 +32,23 @@
 #include <string>
 #include <utility>
 
+#include "dawn/common/SystemUtils.h"
+
 namespace dawn::native::d3d12 {
 
-namespace {
-
-// Extract Version from "10.0.{Version}.0" if possible, otherwise return 0.
-uint32_t GetWindowsSDKVersionFromDirectoryName(const char* directoryName) {
-    constexpr char kPrefix[] = "10.0.";
-    constexpr char kPostfix[] = ".0";
-
-    constexpr uint32_t kPrefixLen = sizeof(kPrefix) - 1;
-    constexpr uint32_t kPostfixLen = sizeof(kPostfix) - 1;
-    const uint32_t directoryNameLen = strlen(directoryName);
-
-    if (directoryNameLen < kPrefixLen + kPostfixLen + 1) {
-        return 0;
-    }
-
-    // Check if directoryName starts with "10.0.".
-    if (strncmp(directoryName, kPrefix, kPrefixLen) != 0) {
-        return 0;
-    }
-
-    // Check if directoryName ends with ".0".
-    if (strncmp(directoryName + (directoryNameLen - kPostfixLen), kPostfix, kPostfixLen) != 0) {
-        return 0;
-    }
-
-    // Extract Version from "10.0.{Version}.0" and convert Version into an integer.
-    return atoi(directoryName + kPrefixLen);
-}
-
-class ScopedFileHandle final {
-  public:
-    explicit ScopedFileHandle(HANDLE handle) : mHandle(handle) {}
-    ~ScopedFileHandle() {
-        if (mHandle != INVALID_HANDLE_VALUE) {
-            DAWN_ASSERT(FindClose(mHandle));
-        }
-    }
-    HANDLE GetHandle() const { return mHandle; }
-
-  private:
-    HANDLE mHandle;
-};
-
-std::string GetWindowsSDKBasePath() {
-    const char* kDefaultWindowsSDKPath = "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\*";
-    WIN32_FIND_DATAA fileData;
-    ScopedFileHandle handle(FindFirstFileA(kDefaultWindowsSDKPath, &fileData));
-    if (handle.GetHandle() == INVALID_HANDLE_VALUE) {
-        return "";
-    }
-
-    uint32_t highestWindowsSDKVersion = 0;
-    do {
-        if (!(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) {
-            continue;
-        }
-
-        highestWindowsSDKVersion = std::max(
-            highestWindowsSDKVersion, GetWindowsSDKVersionFromDirectoryName(fileData.cFileName));
-    } while (FindNextFileA(handle.GetHandle(), &fileData));
-
-    if (highestWindowsSDKVersion == 0) {
-        return "";
-    }
-
-    // Currently we only support using DXC on x64.
-    std::ostringstream ostream;
-    ostream << "C:\\Program Files (x86)\\Windows Kits\\10\\bin\\10.0." << highestWindowsSDKVersion
-            << ".0\\x64\\";
-
-    return ostream.str();
-}
-
-}  // anonymous namespace
-
 PlatformFunctions::PlatformFunctions() = default;
 PlatformFunctions::~PlatformFunctions() = default;
 
 MaybeError PlatformFunctions::LoadFunctions() {
     DAWN_TRY(Base::LoadFunctions());
-    LoadDXCLibraries();
+
+    const auto modulePath = GetModuleDirectory();
+    const std::string& pathToPrepend = modulePath.value_or("");
+
+    LoadDXCLibraries(pathToPrepend);
     DAWN_TRY(LoadD3D12());
     DAWN_TRY(LoadD3D11());
-    LoadPIXRuntime();
+    LoadPIXRuntime(pathToPrepend);
     return {};
 }
 
@@ -166,13 +97,13 @@
     return mPIXEventRuntimeLib.Valid();
 }
 
-void PlatformFunctions::LoadPIXRuntime() {
+void PlatformFunctions::LoadPIXRuntime(const std::string& pathToPrepend) {
     // TODO(dawn:766):
     // In UWP PIX should be statically linked WinPixEventRuntime_UAP.lib
     // So maybe we should put WinPixEventRuntime as a third party package
     // Currently PIX is not going to be loaded in UWP since the following
     // mPIXEventRuntimeLib.Open will fail.
-    if (!mPIXEventRuntimeLib.Open("WinPixEventRuntime.dll") ||
+    if (!mPIXEventRuntimeLib.Open(pathToPrepend + "WinPixEventRuntime.dll") ||
         !mPIXEventRuntimeLib.GetProc(&pixBeginEventOnCommandList, "PIXBeginEventOnCommandList") ||
         !mPIXEventRuntimeLib.GetProc(&pixEndEventOnCommandList, "PIXEndEventOnCommandList") ||
         !mPIXEventRuntimeLib.GetProc(&pixSetMarkerOnCommandList, "PIXSetMarkerOnCommandList")) {
@@ -180,66 +111,27 @@
     }
 }
 
-void PlatformFunctions::LoadDXCLibraries() {
+void PlatformFunctions::LoadDXCLibraries(const std::string& pathToPrepend) {
     // TODO(dawn:766)
     // Statically linked with dxcompiler.lib in UWP
     // currently linked with dxcompiler.lib making CoreApp unable to activate
     // LoadDXIL and LoadDXCompiler will fail in UWP, but LoadFunctions() can still be
     // successfully executed.
 
-    const std::string& windowsSDKBasePath = GetWindowsSDKBasePath();
-
-    LoadDXIL(windowsSDKBasePath);
-    LoadDXCompiler(windowsSDKBasePath);
-}
-
-void PlatformFunctions::LoadDXIL(const std::string& baseWindowsSDKPath) {
-    constexpr char kDxilDLLName[] = "dxil.dll";
-    const std::array kDxilDLLPaths{
-#ifdef DAWN_USE_BUILT_DXC
-        std::string{kDxilDLLName},
-#else
-        std::string{kDxilDLLName},
-        baseWindowsSDKPath + kDxilDLLName,
-#endif
-    };
-
-    for (const std::string& dxilDLLPath : kDxilDLLPaths) {
-        if (mDXILLib.Open(dxilDLLPath, nullptr)) {
-            return;
-        }
-    }
-    DAWN_ASSERT(!mDXILLib.Valid());
-}
-
-void PlatformFunctions::LoadDXCompiler(const std::string& baseWindowsSDKPath) {
+    DynamicLib dxilLib;
     // DXIL must be loaded before DXC, otherwise shader signing is unavailable
-    if (!mDXILLib.Valid()) {
+    if (!dxilLib.Open(pathToPrepend + "dxil.dll")) {
         return;
     }
 
-    constexpr char kDxCompilerDLLName[] = "dxcompiler.dll";
-    const std::array kDxCompilerDLLPaths{
-#ifdef DAWN_USE_BUILT_DXC
-        std::string{kDxCompilerDLLName},
-#else
-        std::string{kDxCompilerDLLName}, baseWindowsSDKPath + kDxCompilerDLLName
-#endif
-    };
-
     DynamicLib dxCompilerLib;
-    for (const std::string& dllName : kDxCompilerDLLPaths) {
-        if (dxCompilerLib.Open(dllName, nullptr)) {
-            break;
-        }
+    if (!dxCompilerLib.Open(pathToPrepend + "dxcompiler.dll") ||
+        !dxCompilerLib.GetProc(&dxcCreateInstance, "DxcCreateInstance", nullptr)) {
+        return;
     }
 
-    if (dxCompilerLib.Valid() &&
-        dxCompilerLib.GetProc(&dxcCreateInstance, "DxcCreateInstance", nullptr)) {
-        mDXCompilerLib = std::move(dxCompilerLib);
-    } else {
-        mDXILLib.Close();
-    }
+    mDXCompilerLib = std::move(dxCompilerLib);
+    mDXILLib = std::move(dxilLib);
 }
 
 // Use Backend::IsDXCAvailable if possible, which also check the DXC is no older than a given
diff --git a/src/dawn/native/d3d12/PlatformFunctionsD3D12.h b/src/dawn/native/d3d12/PlatformFunctionsD3D12.h
index b242dee..0de055b 100644
--- a/src/dawn/native/d3d12/PlatformFunctionsD3D12.h
+++ b/src/dawn/native/d3d12/PlatformFunctionsD3D12.h
@@ -87,10 +87,8 @@
 
     MaybeError LoadD3D12();
     MaybeError LoadD3D11();
-    void LoadPIXRuntime();
-    void LoadDXCLibraries();
-    void LoadDXIL(const std::string& baseWindowsSDKPath);
-    void LoadDXCompiler(const std::string& baseWindowsSDKPath);
+    void LoadPIXRuntime(const std::string& pathToPrepend);
+    void LoadDXCLibraries(const std::string& pathToPrepend);
 
     DynamicLib mD3D12Lib;
     DynamicLib mD3D11Lib;
diff --git a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
index 67dac1b..8ae0b73 100644
--- a/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
+++ b/src/dawn/native/d3d12/ShaderModuleD3D12.cpp
@@ -148,19 +148,14 @@
         // If UseDXC toggle are not forced to be disable, DXC should have been validated to be
         // available.
         DAWN_ASSERT(ToBackend(device->GetPhysicalDevice())->GetBackend()->IsDXCAvailable());
-        // We can get the DXC version information since IsDXCAvailable() is true.
-        d3d12::DxcVersionInfo dxcVersionInfo =
-            ToBackend(device->GetPhysicalDevice())->GetBackend()->GetDxcVersion();
 
         req.bytecode.compiler = d3d::Compiler::DXC;
         req.bytecode.dxcLibrary = device->GetDxcLibrary().Get();
         req.bytecode.dxcCompiler = device->GetDxcCompiler().Get();
-        req.bytecode.compilerVersion = dxcVersionInfo.DxcCompilerVersion;
         req.bytecode.dxcShaderProfile = device->GetDxcShaderProfiles()[stage];
     } else {
         req.bytecode.compiler = d3d::Compiler::FXC;
         req.bytecode.d3dCompile = device->GetFunctions()->d3dCompile;
-        req.bytecode.compilerVersion = D3D_COMPILER_VERSION;
         switch (stage) {
             case SingleShaderStage::Vertex:
                 req.bytecode.fxcShaderProfile = "vs_5_1";