// Copyright 2017 The Dawn Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "dawn_native/d3d12/ShaderModuleD3D12.h"

#include "common/Assert.h"
#include "common/BitSetIterator.h"
#include "common/Log.h"
#include "common/WindowsUtils.h"
#include "dawn_native/Pipeline.h"
#include "dawn_native/TintUtils.h"
#include "dawn_native/d3d12/BindGroupLayoutD3D12.h"
#include "dawn_native/d3d12/D3D12Error.h"
#include "dawn_native/d3d12/DeviceD3D12.h"
#include "dawn_native/d3d12/PipelineLayoutD3D12.h"
#include "dawn_native/d3d12/PlatformFunctions.h"
#include "dawn_native/d3d12/UtilsD3D12.h"

#include <d3dcompiler.h>

#include <tint/tint.h>
#include <map>
#include <sstream>
#include <unordered_map>

namespace dawn_native { namespace d3d12 {

    namespace {
        ResultOrError<uint64_t> GetDXCompilerVersion(ComPtr<IDxcValidator> dxcValidator) {
            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 GetD3DCompilerVersion() {
            return D3D_COMPILER_VERSION;
        }

        struct CompareBindingPoint {
            constexpr bool operator()(const tint::transform::BindingPoint& lhs,
                                      const tint::transform::BindingPoint& rhs) const {
                if (lhs.group != rhs.group) {
                    return lhs.group < rhs.group;
                } else {
                    return lhs.binding < rhs.binding;
                }
            }
        };

        void Serialize(std::stringstream& output, const tint::ast::Access& access) {
            output << access;
        }

        void Serialize(std::stringstream& output,
                       const tint::transform::BindingPoint& binding_point) {
            output << "(BindingPoint";
            output << " group=" << binding_point.group;
            output << " binding=" << binding_point.binding;
            output << ")";
        }

        template <typename T>
        void Serialize(std::stringstream& output,
                       const std::unordered_map<tint::transform::BindingPoint, T>& map) {
            output << "(map";

            std::map<tint::transform::BindingPoint, T, CompareBindingPoint> sorted(map.begin(),
                                                                                   map.end());
            for (auto& entry : sorted) {
                output << " ";
                Serialize(output, entry.first);
                output << "=";
                Serialize(output, entry.second);
            }
            output << ")";
        }

        // 32 bit float has 7 decimal digits of precision so setting n to 8 should be enough
        std::string FloatToStringWithPrecision(float v, std::streamsize n = 8) {
            std::ostringstream out;
            out.precision(n);
            out << std::fixed << v;
            return out.str();
        }

        std::string GetHLSLValueString(EntryPointMetadata::OverridableConstant::Type dawnType,
                                       const OverridableConstantScalar* entry,
                                       double value = 0) {
            switch (dawnType) {
                case EntryPointMetadata::OverridableConstant::Type::Boolean:
                    return std::to_string(entry ? entry->b : static_cast<int32_t>(value));
                case EntryPointMetadata::OverridableConstant::Type::Float32:
                    return FloatToStringWithPrecision(entry ? entry->f32
                                                            : static_cast<float>(value));
                case EntryPointMetadata::OverridableConstant::Type::Int32:
                    return std::to_string(entry ? entry->i32 : static_cast<int32_t>(value));
                case EntryPointMetadata::OverridableConstant::Type::Uint32:
                    return std::to_string(entry ? entry->u32 : static_cast<uint32_t>(value));
                default:
                    UNREACHABLE();
            }
        }

        constexpr char kSpecConstantPrefix[] = "WGSL_SPEC_CONSTANT_";

        void GetOverridableConstantsDefines(
            std::vector<std::pair<std::string, std::string>>* defineStrings,
            const PipelineConstantEntries* pipelineConstantEntries,
            const EntryPointMetadata::OverridableConstantsMap* shaderEntryPointConstants) {
            std::unordered_set<std::string> overriddenConstants;

            // Set pipeline overridden values
            for (const auto& pipelineConstant : *pipelineConstantEntries) {
                const std::string& name = pipelineConstant.first;
                double value = pipelineConstant.second;

                overriddenConstants.insert(name);

                // This is already validated so `name` must exist
                const auto& moduleConstant = shaderEntryPointConstants->at(name);

                defineStrings->emplace_back(
                    kSpecConstantPrefix + std::to_string(static_cast<int32_t>(moduleConstant.id)),
                    GetHLSLValueString(moduleConstant.type, nullptr, value));
            }

            // Set shader initialized default values
            for (const auto& iter : *shaderEntryPointConstants) {
                const std::string& name = iter.first;
                if (overriddenConstants.count(name) != 0) {
                    // This constant already has overridden value
                    continue;
                }

                const auto& moduleConstant = shaderEntryPointConstants->at(name);

                // Uninitialized default values are okay since they ar only defined to pass
                // compilation but not used
                defineStrings->emplace_back(
                    kSpecConstantPrefix + std::to_string(static_cast<int32_t>(moduleConstant.id)),
                    GetHLSLValueString(moduleConstant.type, &moduleConstant.defaultValue));
            }
        }

        // The inputs to a shader compilation. These have been intentionally isolated from the
        // device to help ensure that the pipeline cache key contains all inputs for compilation.
        struct ShaderCompilationRequest {
            enum Compiler { FXC, DXC };

            // Common inputs
            Compiler compiler;
            const tint::Program* program;
            const char* entryPointName;
            SingleShaderStage stage;
            uint32_t compileFlags;
            bool disableSymbolRenaming;
            tint::transform::BindingRemapper::BindingPoints bindingPoints;
            tint::transform::BindingRemapper::AccessControls accessControls;
            bool isRobustnessEnabled;
            bool usesNumWorkgroups;
            uint32_t numWorkgroupsRegisterSpace;
            uint32_t numWorkgroupsShaderRegister;
            std::vector<std::pair<std::string, std::string>> defineStrings;

            // FXC/DXC common inputs
            bool disableWorkgroupInit;

            // FXC inputs
            uint64_t fxcVersion;

            // DXC inputs
            uint64_t dxcVersion;
            const D3D12DeviceInfo* deviceInfo;
            bool hasShaderFloat16Feature;

            static ResultOrError<ShaderCompilationRequest> Create(
                const char* entryPointName,
                SingleShaderStage stage,
                const PipelineLayout* layout,
                uint32_t compileFlags,
                const Device* device,
                const tint::Program* program,
                const EntryPointMetadata& entryPoint,
                const ProgrammableStage& programmableStage) {
                Compiler compiler;
                uint64_t dxcVersion = 0;
                if (device->IsToggleEnabled(Toggle::UseDXC)) {
                    compiler = Compiler::DXC;
                    DAWN_TRY_ASSIGN(dxcVersion, GetDXCompilerVersion(device->GetDxcValidator()));
                } else {
                    compiler = Compiler::FXC;
                }

                using tint::transform::BindingPoint;
                using tint::transform::BindingRemapper;

                BindingRemapper::BindingPoints bindingPoints;
                BindingRemapper::AccessControls accessControls;

                // d3d12::BindGroupLayout packs the bindings per HLSL register-space. We modify the
                // Tint AST to make the "bindings" decoration match the offset chosen by
                // d3d12::BindGroupLayout so that Tint produces HLSL with the correct registers
                // assigned to each interface variable.
                const BindingInfoArray& moduleBindingInfo = entryPoint.bindings;
                for (BindGroupIndex group : IterateBitSet(layout->GetBindGroupLayoutsMask())) {
                    const BindGroupLayout* bgl = ToBackend(layout->GetBindGroupLayout(group));
                    const auto& groupBindingInfo = moduleBindingInfo[group];
                    for (const auto& it : groupBindingInfo) {
                        BindingNumber binding = it.first;
                        auto const& bindingInfo = it.second;
                        BindingIndex bindingIndex = bgl->GetBindingIndex(binding);
                        BindingPoint srcBindingPoint{static_cast<uint32_t>(group),
                                                     static_cast<uint32_t>(binding)};
                        BindingPoint dstBindingPoint{static_cast<uint32_t>(group),
                                                     bgl->GetShaderRegister(bindingIndex)};
                        if (srcBindingPoint != dstBindingPoint) {
                            bindingPoints.emplace(srcBindingPoint, dstBindingPoint);
                        }

                        // Declaring a read-only storage buffer in HLSL but specifying a storage
                        // buffer in the BGL produces the wrong output. Force read-only storage
                        // buffer bindings to be treated as UAV instead of SRV. Internal storage
                        // buffer is a storage buffer used in the internal pipeline.
                        const bool forceStorageBufferAsUAV =
                            (bindingInfo.buffer.type == wgpu::BufferBindingType::ReadOnlyStorage &&
                             (bgl->GetBindingInfo(bindingIndex).buffer.type ==
                                  wgpu::BufferBindingType::Storage ||
                              bgl->GetBindingInfo(bindingIndex).buffer.type ==
                                  kInternalStorageBufferBinding));
                        if (forceStorageBufferAsUAV) {
                            accessControls.emplace(srcBindingPoint, tint::ast::Access::kReadWrite);
                        }
                    }
                }

                ShaderCompilationRequest request;
                request.compiler = compiler;
                request.program = program;
                request.entryPointName = entryPointName;
                request.stage = stage;
                request.compileFlags = compileFlags;
                request.disableSymbolRenaming =
                    device->IsToggleEnabled(Toggle::DisableSymbolRenaming);
                request.bindingPoints = std::move(bindingPoints);
                request.accessControls = std::move(accessControls);
                request.isRobustnessEnabled = device->IsRobustnessEnabled();
                request.disableWorkgroupInit =
                    device->IsToggleEnabled(Toggle::DisableWorkgroupInit);
                request.usesNumWorkgroups = entryPoint.usesNumWorkgroups;
                request.numWorkgroupsShaderRegister = layout->GetNumWorkgroupsShaderRegister();
                request.numWorkgroupsRegisterSpace = layout->GetNumWorkgroupsRegisterSpace();
                request.fxcVersion = compiler == Compiler::FXC ? GetD3DCompilerVersion() : 0;
                request.dxcVersion = compiler == Compiler::DXC ? dxcVersion : 0;
                request.deviceInfo = &device->GetDeviceInfo();
                request.hasShaderFloat16Feature = device->IsFeatureEnabled(Feature::ShaderFloat16);

                GetOverridableConstantsDefines(
                    &request.defineStrings, &programmableStage.constants,
                    &programmableStage.module->GetEntryPoint(programmableStage.entryPoint)
                         .overridableConstants);

                return std::move(request);
            }

            ResultOrError<PersistentCacheKey> CreateCacheKey() const {
                // Generate the WGSL from the Tint program so it's normalized.
                // TODO(tint:1180): Consider using a binary serialization of the tint AST for a more
                // compact representation.
                auto result = tint::writer::wgsl::Generate(program, tint::writer::wgsl::Options{});
                if (!result.success) {
                    std::ostringstream errorStream;
                    errorStream << "Tint WGSL failure:" << std::endl;
                    errorStream << "Generator: " << result.error << std::endl;
                    return DAWN_INTERNAL_ERROR(errorStream.str().c_str());
                }

                std::stringstream stream;

                // Prefix the key with the type to avoid collisions from another type that could
                // have the same key.
                stream << static_cast<uint32_t>(PersistentKeyType::Shader);
                stream << "\n";

                stream << result.wgsl.length();
                stream << "\n";

                stream << result.wgsl;
                stream << "\n";

                stream << "(ShaderCompilationRequest";
                stream << " compiler=" << compiler;
                stream << " entryPointName=" << entryPointName;
                stream << " stage=" << uint32_t(stage);
                stream << " compileFlags=" << compileFlags;
                stream << " disableSymbolRenaming=" << disableSymbolRenaming;

                stream << " bindingPoints=";
                Serialize(stream, bindingPoints);

                stream << " accessControls=";
                Serialize(stream, accessControls);

                stream << " useNumWorkgroups=" << usesNumWorkgroups;
                stream << " numWorkgroupsRegisterSpace=" << numWorkgroupsRegisterSpace;
                stream << " numWorkgroupsShaderRegister=" << numWorkgroupsShaderRegister;

                stream << " shaderModel=" << deviceInfo->shaderModel;
                stream << " disableWorkgroupInit=" << disableWorkgroupInit;
                stream << " isRobustnessEnabled=" << isRobustnessEnabled;
                stream << " fxcVersion=" << fxcVersion;
                stream << " dxcVersion=" << dxcVersion;
                stream << " hasShaderFloat16Feature=" << hasShaderFloat16Feature;

                stream << " defines={";
                for (const auto& it : defineStrings) {
                    stream << " <" << it.first << "," << it.second << ">";
                }
                stream << " }";

                stream << ")";
                stream << "\n";

                return PersistentCacheKey(std::istreambuf_iterator<char>{stream},
                                          std::istreambuf_iterator<char>{});
            }
        };

        std::vector<const wchar_t*> GetDXCArguments(uint32_t compileFlags, bool enable16BitTypes) {
            std::vector<const wchar_t*> arguments;
            if (compileFlags & D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY) {
                arguments.push_back(L"/Gec");
            }
            if (compileFlags & D3DCOMPILE_IEEE_STRICTNESS) {
                arguments.push_back(L"/Gis");
            }
            if (compileFlags & D3DCOMPILE_OPTIMIZATION_LEVEL2) {
                switch (compileFlags & D3DCOMPILE_OPTIMIZATION_LEVEL2) {
                    case D3DCOMPILE_OPTIMIZATION_LEVEL0:
                        arguments.push_back(L"/O0");
                        break;
                    case D3DCOMPILE_OPTIMIZATION_LEVEL2:
                        arguments.push_back(L"/O2");
                        break;
                    case D3DCOMPILE_OPTIMIZATION_LEVEL3:
                        arguments.push_back(L"/O3");
                        break;
                }
            }
            if (compileFlags & D3DCOMPILE_DEBUG) {
                arguments.push_back(L"/Zi");
            }
            if (compileFlags & D3DCOMPILE_PACK_MATRIX_ROW_MAJOR) {
                arguments.push_back(L"/Zpr");
            }
            if (compileFlags & D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR) {
                arguments.push_back(L"/Zpc");
            }
            if (compileFlags & D3DCOMPILE_AVOID_FLOW_CONTROL) {
                arguments.push_back(L"/Gfa");
            }
            if (compileFlags & D3DCOMPILE_PREFER_FLOW_CONTROL) {
                arguments.push_back(L"/Gfp");
            }
            if (compileFlags & D3DCOMPILE_RESOURCES_MAY_ALIAS) {
                arguments.push_back(L"/res_may_alias");
            }

            if (enable16BitTypes) {
                // enable-16bit-types are only allowed in -HV 2018 (default)
                arguments.push_back(L"/enable-16bit-types");
            }

            arguments.push_back(L"-HV");
            arguments.push_back(L"2018");

            return arguments;
        }

        ResultOrError<ComPtr<IDxcBlob>> CompileShaderDXC(IDxcLibrary* dxcLibrary,
                                                         IDxcCompiler* dxcCompiler,
                                                         const ShaderCompilationRequest& request,
                                                         const std::string& hlslSource) {
            ComPtr<IDxcBlobEncoding> sourceBlob;
            DAWN_TRY(
                CheckHRESULT(dxcLibrary->CreateBlobWithEncodingOnHeapCopy(
                                 hlslSource.c_str(), hlslSource.length(), CP_UTF8, &sourceBlob),
                             "DXC create blob"));

            std::wstring entryPointW;
            DAWN_TRY_ASSIGN(entryPointW, ConvertStringToWstring(request.entryPointName));

            std::vector<const wchar_t*> arguments =
                GetDXCArguments(request.compileFlags, request.hasShaderFloat16Feature);

            // Build defines for overridable constants
            std::vector<std::pair<std::wstring, std::wstring>> defineStrings;
            defineStrings.reserve(request.defineStrings.size());
            for (const auto& it : request.defineStrings) {
                defineStrings.emplace_back(UTF8ToWStr(it.first.c_str()),
                                           UTF8ToWStr(it.second.c_str()));
            }

            std::vector<DxcDefine> dxcDefines;
            dxcDefines.reserve(defineStrings.size());
            for (const auto& d : defineStrings) {
                dxcDefines.push_back({d.first.c_str(), d.second.c_str()});
            }

            ComPtr<IDxcOperationResult> result;
            DAWN_TRY(CheckHRESULT(
                dxcCompiler->Compile(sourceBlob.Get(), nullptr, entryPointW.c_str(),
                                     request.deviceInfo->shaderProfiles[request.stage].c_str(),
                                     arguments.data(), arguments.size(), dxcDefines.data(),
                                     dxcDefines.size(), nullptr, &result),
                "DXC compile"));

            HRESULT hr;
            DAWN_TRY(CheckHRESULT(result->GetStatus(&hr), "DXC get status"));

            if (FAILED(hr)) {
                ComPtr<IDxcBlobEncoding> errors;
                DAWN_TRY(CheckHRESULT(result->GetErrorBuffer(&errors), "DXC get error buffer"));

                return DAWN_FORMAT_VALIDATION_ERROR("DXC compile failed with: %s",
                                                    static_cast<char*>(errors->GetBufferPointer()));
            }

            ComPtr<IDxcBlob> compiledShader;
            DAWN_TRY(CheckHRESULT(result->GetResult(&compiledShader), "DXC get result"));
            return std::move(compiledShader);
        }

        std::string CompileFlagsToStringFXC(uint32_t compileFlags) {
            struct Flag {
                uint32_t value;
                const char* name;
            };
            constexpr Flag flags[] = {
            // Populated from d3dcompiler.h
#define F(f) Flag{f, #f}
                F(D3DCOMPILE_DEBUG),
                F(D3DCOMPILE_SKIP_VALIDATION),
                F(D3DCOMPILE_SKIP_OPTIMIZATION),
                F(D3DCOMPILE_PACK_MATRIX_ROW_MAJOR),
                F(D3DCOMPILE_PACK_MATRIX_COLUMN_MAJOR),
                F(D3DCOMPILE_PARTIAL_PRECISION),
                F(D3DCOMPILE_FORCE_VS_SOFTWARE_NO_OPT),
                F(D3DCOMPILE_FORCE_PS_SOFTWARE_NO_OPT),
                F(D3DCOMPILE_NO_PRESHADER),
                F(D3DCOMPILE_AVOID_FLOW_CONTROL),
                F(D3DCOMPILE_PREFER_FLOW_CONTROL),
                F(D3DCOMPILE_ENABLE_STRICTNESS),
                F(D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY),
                F(D3DCOMPILE_IEEE_STRICTNESS),
                F(D3DCOMPILE_RESERVED16),
                F(D3DCOMPILE_RESERVED17),
                F(D3DCOMPILE_WARNINGS_ARE_ERRORS),
                F(D3DCOMPILE_RESOURCES_MAY_ALIAS),
                F(D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES),
                F(D3DCOMPILE_ALL_RESOURCES_BOUND),
                F(D3DCOMPILE_DEBUG_NAME_FOR_SOURCE),
                F(D3DCOMPILE_DEBUG_NAME_FOR_BINARY),
#undef F
            };

            std::string result;
            for (const Flag& f : flags) {
                if ((compileFlags & f.value) != 0) {
                    result += f.name + std::string("\n");
                }
            }

            // Optimization level must be handled separately as two bits are used, and the values
            // don't map neatly to 0-3.
            if ((compileFlags & D3DCOMPILE_OPTIMIZATION_LEVEL2) != 0) {
                result += "D3DCOMPILE_OPTIMIZATION_LEVEL2";
            } else if ((compileFlags & D3DCOMPILE_OPTIMIZATION_LEVEL0) != 0) {
                result += "D3DCOMPILE_OPTIMIZATION_LEVEL0";
            } else if ((compileFlags & D3DCOMPILE_OPTIMIZATION_LEVEL3) != 0) {
                result += "D3DCOMPILE_OPTIMIZATION_LEVEL3";
            } else {
                result += "D3DCOMPILE_OPTIMIZATION_LEVEL1";
            }
            result += std::string("\n");

            return result;
        }

        ResultOrError<ComPtr<ID3DBlob>> CompileShaderFXC(const PlatformFunctions* functions,
                                                         const ShaderCompilationRequest& request,
                                                         const std::string& hlslSource) {
            const char* targetProfile = nullptr;
            switch (request.stage) {
                case SingleShaderStage::Vertex:
                    targetProfile = "vs_5_1";
                    break;
                case SingleShaderStage::Fragment:
                    targetProfile = "ps_5_1";
                    break;
                case SingleShaderStage::Compute:
                    targetProfile = "cs_5_1";
                    break;
            }

            ComPtr<ID3DBlob> compiledShader;
            ComPtr<ID3DBlob> errors;

            // Build defines for overridable constants
            const D3D_SHADER_MACRO* pDefines = nullptr;
            std::vector<D3D_SHADER_MACRO> fxcDefines;
            if (request.defineStrings.size() > 0) {
                fxcDefines.reserve(request.defineStrings.size() + 1);
                for (const auto& d : request.defineStrings) {
                    fxcDefines.push_back({d.first.c_str(), d.second.c_str()});
                }
                // d3dCompile D3D_SHADER_MACRO* pDefines is a nullptr terminated array
                fxcDefines.push_back({nullptr, nullptr});
                pDefines = fxcDefines.data();
            }

            DAWN_INVALID_IF(FAILED(functions->d3dCompile(
                                hlslSource.c_str(), hlslSource.length(), nullptr, pDefines, nullptr,
                                request.entryPointName, targetProfile, request.compileFlags, 0,
                                &compiledShader, &errors)),
                            "D3D compile failed with: %s",
                            static_cast<char*>(errors->GetBufferPointer()));

            return std::move(compiledShader);
        }

        ResultOrError<std::string> TranslateToHLSL(const ShaderCompilationRequest& request,
                                                   std::string* remappedEntryPointName) {
            std::ostringstream errorStream;
            errorStream << "Tint HLSL failure:" << std::endl;

            tint::transform::Manager transformManager;
            tint::transform::DataMap transformInputs;

            if (request.isRobustnessEnabled) {
                transformManager.Add<tint::transform::Robustness>();
            }
            transformManager.Add<tint::transform::BindingRemapper>();

            transformManager.Add<tint::transform::SingleEntryPoint>();
            transformInputs.Add<tint::transform::SingleEntryPoint::Config>(request.entryPointName);

            transformManager.Add<tint::transform::Renamer>();

            if (request.disableSymbolRenaming) {
                // We still need to rename HLSL reserved keywords
                transformInputs.Add<tint::transform::Renamer::Config>(
                    tint::transform::Renamer::Target::kHlslKeywords);
            }

            // D3D12 registers like `t3` and `c3` have the same bindingOffset number in
            // the remapping but should not be considered a collision because they have
            // different types.
            const bool mayCollide = true;
            transformInputs.Add<tint::transform::BindingRemapper::Remappings>(
                std::move(request.bindingPoints), std::move(request.accessControls), mayCollide);

            tint::Program transformedProgram;
            tint::transform::DataMap transformOutputs;
            DAWN_TRY_ASSIGN(transformedProgram,
                            RunTransforms(&transformManager, request.program, transformInputs,
                                          &transformOutputs, nullptr));

            if (auto* data = transformOutputs.Get<tint::transform::Renamer::Data>()) {
                auto it = data->remappings.find(request.entryPointName);
                if (it != data->remappings.end()) {
                    *remappedEntryPointName = it->second;
                } else {
                    DAWN_INVALID_IF(!request.disableSymbolRenaming,
                                    "Could not find remapped name for entry point.");

                    *remappedEntryPointName = request.entryPointName;
                }
            } else {
                return DAWN_FORMAT_VALIDATION_ERROR("Transform output missing renamer data.");
            }

            tint::writer::hlsl::Options options;
            options.disable_workgroup_init = request.disableWorkgroupInit;
            if (request.usesNumWorkgroups) {
                options.root_constant_binding_point.group = request.numWorkgroupsRegisterSpace;
                options.root_constant_binding_point.binding = request.numWorkgroupsShaderRegister;
            }
            auto result = tint::writer::hlsl::Generate(&transformedProgram, options);
            DAWN_INVALID_IF(!result.success, "An error occured while generating HLSL: %s",
                            result.error);

            return std::move(result.hlsl);
        }

        template <typename F>
        MaybeError CompileShader(const PlatformFunctions* functions,
                                 IDxcLibrary* dxcLibrary,
                                 IDxcCompiler* dxcCompiler,
                                 ShaderCompilationRequest&& request,
                                 bool dumpShaders,
                                 F&& DumpShadersEmitLog,
                                 CompiledShader* compiledShader) {
            // Compile the source shader to HLSL.
            std::string hlslSource;
            std::string remappedEntryPoint;
            DAWN_TRY_ASSIGN(hlslSource, TranslateToHLSL(request, &remappedEntryPoint));
            if (dumpShaders) {
                std::ostringstream dumpedMsg;
                dumpedMsg << "/* Dumped generated HLSL */" << std::endl << hlslSource;
                DumpShadersEmitLog(WGPULoggingType_Info, dumpedMsg.str().c_str());
            }
            request.entryPointName = remappedEntryPoint.c_str();
            switch (request.compiler) {
                case ShaderCompilationRequest::Compiler::DXC:
                    DAWN_TRY_ASSIGN(compiledShader->compiledDXCShader,
                                    CompileShaderDXC(dxcLibrary, dxcCompiler, request, hlslSource));
                    break;
                case ShaderCompilationRequest::Compiler::FXC:
                    DAWN_TRY_ASSIGN(compiledShader->compiledFXCShader,
                                    CompileShaderFXC(functions, request, hlslSource));
                    break;
            }

            if (dumpShaders && request.compiler == ShaderCompilationRequest::Compiler::FXC) {
                std::ostringstream dumpedMsg;
                dumpedMsg << "/* FXC compile flags */ " << std::endl
                          << CompileFlagsToStringFXC(request.compileFlags) << std::endl;

                dumpedMsg << "/* Dumped disassembled DXBC */" << std::endl;

                ComPtr<ID3DBlob> disassembly;
                if (FAILED(functions->d3dDisassemble(
                        compiledShader->compiledFXCShader->GetBufferPointer(),
                        compiledShader->compiledFXCShader->GetBufferSize(), 0, nullptr,
                        &disassembly))) {
                    dumpedMsg << "D3D disassemble failed" << std::endl;
                } else {
                    dumpedMsg << reinterpret_cast<const char*>(disassembly->GetBufferPointer());
                }
                DumpShadersEmitLog(WGPULoggingType_Info, dumpedMsg.str().c_str());
            }

            return {};
        }

    }  // anonymous namespace

    // static
    ResultOrError<Ref<ShaderModule>> ShaderModule::Create(Device* device,
                                                          const ShaderModuleDescriptor* descriptor,
                                                          ShaderModuleParseResult* parseResult) {
        Ref<ShaderModule> module = AcquireRef(new ShaderModule(device, descriptor));
        DAWN_TRY(module->Initialize(parseResult));
        return module;
    }

    ShaderModule::ShaderModule(Device* device, const ShaderModuleDescriptor* descriptor)
        : ShaderModuleBase(device, descriptor) {
    }

    MaybeError ShaderModule::Initialize(ShaderModuleParseResult* parseResult) {
        ScopedTintICEHandler scopedICEHandler(GetDevice());
        return InitializeBase(parseResult);
    }

    ResultOrError<CompiledShader> ShaderModule::Compile(const ProgrammableStage& programmableStage,
                                                        SingleShaderStage stage,
                                                        PipelineLayout* layout,
                                                        uint32_t compileFlags) {
        ASSERT(!IsError());
        ScopedTintICEHandler scopedICEHandler(GetDevice());

        Device* device = ToBackend(GetDevice());

        CompiledShader compiledShader = {};

        tint::transform::Manager transformManager;
        tint::transform::DataMap transformInputs;

        const tint::Program* program;
        tint::Program programAsValue;
        if (stage == SingleShaderStage::Vertex) {
            transformManager.Add<tint::transform::FirstIndexOffset>();
            transformInputs.Add<tint::transform::FirstIndexOffset::BindingPoint>(
                layout->GetFirstIndexOffsetShaderRegister(),
                layout->GetFirstIndexOffsetRegisterSpace());

            tint::transform::DataMap transformOutputs;
            DAWN_TRY_ASSIGN(programAsValue,
                            RunTransforms(&transformManager, GetTintProgram(), transformInputs,
                                          &transformOutputs, nullptr));

            if (auto* data = transformOutputs.Get<tint::transform::FirstIndexOffset::Data>()) {
                // TODO(dawn:549): Consider adding this information to the pipeline cache once we
                // can store more than the shader blob in it.
                compiledShader.firstOffsetInfo.usesVertexIndex = data->has_vertex_index;
                if (compiledShader.firstOffsetInfo.usesVertexIndex) {
                    compiledShader.firstOffsetInfo.vertexIndexOffset = data->first_vertex_offset;
                }
                compiledShader.firstOffsetInfo.usesInstanceIndex = data->has_instance_index;
                if (compiledShader.firstOffsetInfo.usesInstanceIndex) {
                    compiledShader.firstOffsetInfo.instanceIndexOffset =
                        data->first_instance_offset;
                }
            }

            program = &programAsValue;
        } else {
            program = GetTintProgram();
        }

        ShaderCompilationRequest request;
        DAWN_TRY_ASSIGN(
            request, ShaderCompilationRequest::Create(
                         programmableStage.entryPoint.c_str(), stage, layout, compileFlags, device,
                         program, GetEntryPoint(programmableStage.entryPoint), programmableStage));

        PersistentCacheKey shaderCacheKey;
        DAWN_TRY_ASSIGN(shaderCacheKey, request.CreateCacheKey());

        DAWN_TRY_ASSIGN(
            compiledShader.cachedShader,
            device->GetPersistentCache()->GetOrCreate(
                shaderCacheKey, [&](auto doCache) -> MaybeError {
                    DAWN_TRY(CompileShader(
                        device->GetFunctions(),
                        device->IsToggleEnabled(Toggle::UseDXC) ? device->GetDxcLibrary().Get()
                                                                : nullptr,
                        device->IsToggleEnabled(Toggle::UseDXC) ? device->GetDxcCompiler().Get()
                                                                : nullptr,
                        std::move(request), device->IsToggleEnabled(Toggle::DumpShaders),
                        [&](WGPULoggingType loggingType, const char* message) {
                            GetDevice()->EmitLog(loggingType, message);
                        },
                        &compiledShader));
                    const D3D12_SHADER_BYTECODE shader = compiledShader.GetD3D12ShaderBytecode();
                    doCache(shader.pShaderBytecode, shader.BytecodeLength);
                    return {};
                }));

        return std::move(compiledShader);
    }

    D3D12_SHADER_BYTECODE CompiledShader::GetD3D12ShaderBytecode() const {
        if (cachedShader.buffer != nullptr) {
            return {cachedShader.buffer.get(), cachedShader.bufferSize};
        } else if (compiledFXCShader != nullptr) {
            return {compiledFXCShader->GetBufferPointer(), compiledFXCShader->GetBufferSize()};
        } else if (compiledDXCShader != nullptr) {
            return {compiledDXCShader->GetBufferPointer(), compiledDXCShader->GetBufferSize()};
        }
        UNREACHABLE();
        return {};
    }
}}  // namespace dawn_native::d3d12
