diff --git a/include/dxc/DxilContainer/DxilContainerAssembler.h b/include/dxc/DxilContainer/DxilContainerAssembler.h index 787c207e9..3236618e0 100644 --- a/include/dxc/DxilContainer/DxilContainerAssembler.h +++ b/include/dxc/DxilContainer/DxilContainerAssembler.h @@ -13,6 +13,7 @@ #include #include "dxc/DxilContainer/DxilContainer.h" +#include "llvm/ADT/StringRef.h" namespace hlsl { @@ -48,6 +49,7 @@ DxilContainerWriter *NewDxilContainerWriter(); void SerializeDxilContainerForModule(hlsl::DxilModule *pModule, AbstractMemoryStream *pModuleBitcode, AbstractMemoryStream *pStream, + llvm::StringRef DebugName, SerializeDxilFlags Flags); void SerializeDxilContainerForRootSignature(hlsl::RootSignatureHandle *pRootSigHandle, AbstractMemoryStream *pStream); diff --git a/include/dxc/Support/HLSLOptions.td b/include/dxc/Support/HLSLOptions.td index 760230480..af332e689 100644 --- a/include/dxc/Support/HLSLOptions.td +++ b/include/dxc/Support/HLSLOptions.td @@ -330,7 +330,7 @@ def Fc : JoinedOrSeparate<["-", "/"], "Fc">, MetaVarName<"">, HelpText<"Ou //def Fx : JoinedOrSeparate<["-", "/"], "Fx">, MetaVarName<"">, HelpText<"Output assembly code and hex listing file">; def Fh : JoinedOrSeparate<["-", "/"], "Fh">, MetaVarName<"">, HelpText<"Output header file containing object code">, Flags<[DriverOption]>, Group; def Fe : JoinedOrSeparate<["-", "/"], "Fe">, MetaVarName<"">, HelpText<"Output warnings and errors to the given file">, Flags<[DriverOption]>, Group; -def Fd : JoinedOrSeparate<["-", "/"], "Fd">, MetaVarName<"">, HelpText<"Write debug information to the given file or directory; trail \\ to auto-generate and imply Qstrip_priv">, Flags<[DriverOption]>, Group; +def Fd : JoinedOrSeparate<["-", "/"], "Fd">, MetaVarName<"">, HelpText<"Write debug information to the given file or directory; trail \\ to auto-generate and imply Qstrip_priv">, Flags<[CoreOption, DriverOption]>, Group; def Vn : JoinedOrSeparate<["-", "/"], "Vn">, MetaVarName<"">, HelpText<"Use as variable name in header file">, Flags<[DriverOption]>, Group; def Cc : Flag<["-", "/"], "Cc">, HelpText<"Output color coded assembly listings">, Group, Flags<[DriverOption]>; def Ni : Flag<["-", "/"], "Ni">, HelpText<"Output instruction numbers in assembly listings">, Group, Flags<[DriverOption]>; diff --git a/lib/DxilContainer/DxilContainerAssembler.cpp b/lib/DxilContainer/DxilContainerAssembler.cpp index 4230c98ff..4daa56125 100644 --- a/lib/DxilContainer/DxilContainerAssembler.cpp +++ b/lib/DxilContainer/DxilContainerAssembler.cpp @@ -1464,6 +1464,7 @@ public: void hlsl::SerializeDxilContainerForModule(DxilModule *pModule, AbstractMemoryStream *pModuleBitcode, AbstractMemoryStream *pFinalStream, + llvm::StringRef DebugName, SerializeDxilFlags Flags) { // TODO: add a flag to update the module and remove information that is not part // of DXIL proper and is used only to assemble the container. @@ -1590,30 +1591,53 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule, // If the debug name should be specific to the sources, base the name on the debug // bitcode, which will include the source references, line numbers, etc. Otherwise, // do it exclusively on the target shader bitcode. + pHashStream = (int)(Flags & SerializeDxilFlags::DebugNameDependOnSource) ? CComPtr(pModuleBitcode) : CComPtr(pProgramStream); + + // Use user specified debug name if a) it's given and b) it's not a path + bool UseDebugName = DebugName.size() && !DebugName.endswith(llvm::StringRef("\\")); + + // Calculate the length of the name + const uint32_t NameLen = UseDebugName ? + DebugName.size() : + DebugInfoNameHashLen + DebugInfoNameSuffix; + + // Calculate the size of the blob part. const uint32_t DebugInfoContentLen = - sizeof(DxilShaderDebugName) + DebugInfoNameHashLen + - DebugInfoNameSuffix + DebugInfoNameNullAndPad; + sizeof(DxilShaderDebugName) + NameLen + DebugInfoNameNullAndPad; + writer.AddPart(DFCC_ShaderDebugName, DebugInfoContentLen, [&](AbstractMemoryStream *pStream) { DxilShaderDebugName NameContent; NameContent.Flags = 0; - NameContent.NameLength = DebugInfoNameHashLen + DebugInfoNameSuffix; - IFT(WriteStreamValue(pStream, NameContent)); - ArrayRef Data((uint8_t *)pHashStream->GetPtr(), pHashStream->GetPtrSize()); - llvm::MD5 md5; - llvm::MD5::MD5Result md5Result; - SmallString<32> Hash; - md5.update(Data); - md5.final(md5Result); - md5.stringifyResult(md5Result, Hash); + if (UseDebugName) { + NameContent.NameLength = DebugName.size(); + IFT(WriteStreamValue(pStream, NameContent)); - ULONG cbWritten; - IFT(pStream->Write(Hash.data(), Hash.size(), &cbWritten)); - const char SuffixAndPad[] = ".lld\0\0\0"; - IFT(pStream->Write(SuffixAndPad, _countof(SuffixAndPad), &cbWritten)); + ULONG cbWritten; + IFT(pStream->Write(DebugName.begin(), DebugName.size(), &cbWritten)); + const char Pad[] = { '\0','\0','\0','\0' }; + IFT(pStream->Write(Pad, _countof(Pad), &cbWritten)); + } + else { + NameContent.NameLength = DebugInfoNameHashLen + DebugInfoNameSuffix; + IFT(WriteStreamValue(pStream, NameContent)); + + ArrayRef Data((uint8_t *)pHashStream->GetPtr(), pHashStream->GetPtrSize()); + llvm::MD5 md5; + llvm::MD5::MD5Result md5Result; + SmallString<32> Hash; + md5.update(Data); + md5.final(md5Result); + md5.stringifyResult(md5Result, Hash); + + ULONG cbWritten; + IFT(pStream->Write(Hash.data(), Hash.size(), &cbWritten)); + const char SuffixAndPad[] = { '.','l','l','d','\0','\0','\0','\0' }; + IFT(pStream->Write(SuffixAndPad, _countof(SuffixAndPad), &cbWritten)); + } }); } } diff --git a/tools/clang/tools/dxcompiler/dxclinker.cpp b/tools/clang/tools/dxcompiler/dxclinker.cpp index 74a04e9b3..1dfb5c08d 100644 --- a/tools/clang/tools/dxcompiler/dxclinker.cpp +++ b/tools/clang/tools/dxcompiler/dxclinker.cpp @@ -256,7 +256,7 @@ HRESULT STDMETHODCALLTYPE DxcLinker::Link( valHR = dxcutil::ValidateAndAssembleToContainer( std::move(pM), pOutputBlob, pMalloc, SerializeFlags, pOutputStream, - /*bDebugInfo*/ false, Diag); + /*bDebugInfo*/ false, llvm::StringRef(), Diag); } else { dxcutil::AssembleToContainer(std::move(pM), pOutputBlob, m_pMalloc, SerializeFlags, pOutputStream); diff --git a/tools/clang/tools/dxcompiler/dxcompilerobj.cpp b/tools/clang/tools/dxcompiler/dxcompilerobj.cpp index 708fd8baa..7b897de3c 100644 --- a/tools/clang/tools/dxcompiler/dxcompilerobj.cpp +++ b/tools/clang/tools/dxcompiler/dxcompilerobj.cpp @@ -592,7 +592,7 @@ public: if (needsValidation) { valHR = dxcutil::ValidateAndAssembleToContainer( action.takeModule(), pOutputBlob, m_pMalloc, SerializeFlags, - pOutputStream, opts.DebugInfo, compiler.getDiagnostics()); + pOutputStream, opts.DebugInfo, opts.DebugFile, compiler.getDiagnostics()); } else { dxcutil::AssembleToContainer(action.takeModule(), pOutputBlob, m_pMalloc, diff --git a/tools/clang/tools/dxcompiler/dxcutil.cpp b/tools/clang/tools/dxcompiler/dxcutil.cpp index 0139903f0..52e655551 100644 --- a/tools/clang/tools/dxcompiler/dxcutil.cpp +++ b/tools/clang/tools/dxcompiler/dxcutil.cpp @@ -78,16 +78,20 @@ public: CComPtr pContainerStream; IFT(CreateMemoryStream(pMalloc, &pContainerStream)); SerializeDxilContainerForModule(&m_llvmModule->GetOrCreateDxilModule(), - pModuleBitcode, pContainerStream, Flags); + pModuleBitcode, pContainerStream, m_debugName, Flags); pDxilContainerBlob.Release(); IFT(pContainerStream.QueryInterface(&pDxilContainerBlob)); } + void SetDebugName(llvm::StringRef DebugName) { + m_debugName = DebugName; + } llvm::Module *get() { return m_llvmModule.get(); } llvm::Module *getWithDebugInfo() { return m_llvmModuleWithDebugInfo.get(); } private: + std::string m_debugName; std::unique_ptr m_llvmModule; std::unique_ptr m_llvmModuleWithDebugInfo; }; @@ -152,7 +156,7 @@ void ReadOptsAndValidate(hlsl::options::MainArgs &mainArgs, HRESULT ValidateAndAssembleToContainer( std::unique_ptr pM, CComPtr &pOutputBlob, IMalloc *pMalloc, SerializeDxilFlags SerializeFlags, - CComPtr &pOutputStream, bool bDebugInfo, + CComPtr &pOutputStream, bool bDebugInfo, llvm::StringRef DebugName, clang::DiagnosticsEngine &Diag) { HRESULT valHR = S_OK; @@ -176,6 +180,9 @@ HRESULT ValidateAndAssembleToContainer( // module. if (bDebugInfo) { llvmModule.CloneForDebugInfo(); + if (DebugName.size()) { + llvmModule.SetDebugName(DebugName); + } } } diff --git a/tools/clang/tools/dxcompiler/dxcutil.h b/tools/clang/tools/dxcompiler/dxcutil.h index db6f0302d..5d7f27523 100644 --- a/tools/clang/tools/dxcompiler/dxcutil.h +++ b/tools/clang/tools/dxcompiler/dxcutil.h @@ -41,7 +41,7 @@ namespace dxcutil { HRESULT ValidateAndAssembleToContainer( std::unique_ptr pM, CComPtr &pOutputContainerBlob, IMalloc *pMalloc, hlsl::SerializeDxilFlags SerializeFlags, - CComPtr &pModuleBitcode, bool bDebugInfo, + CComPtr &pModuleBitcode, bool bDebugInfo, llvm::StringRef DebugName, clang::DiagnosticsEngine &Diag); void GetValidatorVersion(unsigned *pMajor, unsigned *pMinor); void AssembleToContainer(std::unique_ptr pM, diff --git a/tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp b/tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp index eddd1f72f..0dc04d0b6 100644 --- a/tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp +++ b/tools/clang/tools/dxrfallbackcompiler/dxcutil.cpp @@ -81,7 +81,7 @@ public: CComPtr pContainerStream; IFT(CreateMemoryStream(pMalloc, &pContainerStream)); SerializeDxilContainerForModule(&m_llvmModule->GetOrCreateDxilModule(), - pModuleBitcode, pContainerStream, Flags); + pModuleBitcode, pContainerStream, llvm::StringRef(), Flags); pDxilContainerBlob.Release(); IFT(pContainerStream.QueryInterface(&pDxilContainerBlob));