Add -Qembed_debug, don't embed debug info by default

- New -Qembed_debug is required to embed PDB in shader container
- -Zi used without -Qembed_debug will not embed debug info anymore,
  and will issue a warning from CompileWithDebug().
- When compiling with Compile() and -Zi, -Qembed_debug is assumed
  for compatibility reasons (lots of breaks without it)
- In dxc and CompileWithDebug() -Fd implies -Qstrip_debug
- Debug name is based on -Fd, unless path ends with '\', meaning you
  want auto-naming and file written under the specified directory
- Debug name always embedded when debug info used, or -Fd used
- -Fd without -Zi just embeds debug name for CompileWithDebug(),
  still error with dxc, since it can't write to your file.
- If not embedding debug info, it doesn't get written to the container,
  only to be stripped out again.
- Fix padding for alignment in DebugName part.
- Default to DebugNameForBinary instead of DebugNameForSource if no
  DebugInfo enabled

- Also fixed missing dependency on table gen options from libclang
This commit is contained in:
Tex Riddell 2019-04-19 19:48:27 -07:00
Родитель 850c8d3676
Коммит 69882a0394
12 изменённых файлов: 329 добавлений и 146 удалений

Просмотреть файл

@ -150,6 +150,7 @@ public:
bool DisplayIncludeProcess = false; // OPT__vi
bool RecompileFromBinary = false; // OPT _Recompile (Recompiling the DXBC binary file not .hlsl file)
bool StripDebug = false; // OPT Qstrip_debug
bool EmbedDebug = false; // OPT Qembed_debug
bool StripRootSignature = false; // OPT_Qstrip_rootsignature
bool StripPrivate = false; // OPT_Qstrip_priv
bool StripReflection = false; // OPT_Qstrip_reflect
@ -167,6 +168,13 @@ public:
bool IsRootSignatureProfile();
bool IsLibraryProfile();
// Helpers to clarify interpretation of flags for behavior in implementation
bool IsDebugInfoEnabled(); // Zi
bool EmbedDebugInfo(); // Qembed_debug
bool EmbedPDBName(); // Zi or Fd
bool DebugFileIsDirectory(); // Fd ends in '\\'
llvm::StringRef GetPDBName(); // Fd name
// SPIRV Change Starts
#ifdef ENABLE_SPIRV_CODEGEN
bool GenSPIRV; // OPT_spirv

Просмотреть файл

@ -330,7 +330,9 @@ def Fc : JoinedOrSeparate<["-", "/"], "Fc">, MetaVarName<"<file>">, HelpText<"Ou
//def Fx : JoinedOrSeparate<["-", "/"], "Fx">, MetaVarName<"<file>">, HelpText<"Output assembly code and hex listing file">;
def Fh : JoinedOrSeparate<["-", "/"], "Fh">, MetaVarName<"<file>">, HelpText<"Output header file containing object code">, Flags<[DriverOption]>, Group<hlslcomp_Group>;
def Fe : JoinedOrSeparate<["-", "/"], "Fe">, MetaVarName<"<file>">, HelpText<"Output warnings and errors to the given file">, Flags<[DriverOption]>, Group<hlslcomp_Group>;
def Fd : JoinedOrSeparate<["-", "/"], "Fd">, MetaVarName<"<file>">, HelpText<"Write debug information to the given file or directory; trail \\ to auto-generate and imply Qstrip_priv">, Flags<[CoreOption, DriverOption]>, Group<hlslcomp_Group>;
def Fd : JoinedOrSeparate<["-", "/"], "Fd">, MetaVarName<"<file>">,
HelpText<"Write debug information to the given file, or automatically named file in directory when ending in '\\'">,
Flags<[CoreOption, DriverOption]>, Group<hlslcomp_Group>;
def Vn : JoinedOrSeparate<["-", "/"], "Vn">, MetaVarName<"<name>">, HelpText<"Use <name> as variable name in header file">, Flags<[DriverOption]>, Group<hlslcomp_Group>;
def Cc : Flag<["-", "/"], "Cc">, HelpText<"Output color coded assembly listings">, Group<hlslcomp_Group>, Flags<[DriverOption]>;
def Ni : Flag<["-", "/"], "Ni">, HelpText<"Output instruction numbers in assembly listings">, Group<hlslcomp_Group>, Flags<[DriverOption]>;
@ -349,6 +351,8 @@ def Qstrip_reflect : Flag<["-", "/"], "Qstrip_reflect">, Flags<[DriverOption]>,
HelpText<"Strip reflection data from shader bytecode (must be used with /Fo <file>)">;
def Qstrip_debug : Flag<["-", "/"], "Qstrip_debug">, Flags<[CoreOption]>, Group<hlslutil_Group>,
HelpText<"Strip debug information from 4_0+ shader bytecode (must be used with /Fo <file>)">;
def Qembed_debug : Flag<["-", "/"], "Qembed_debug">, Flags<[CoreOption]>, Group<hlslutil_Group>,
HelpText<"Embed PDB in shader container (must be used with /Zi)">;
def Qstrip_priv : Flag<["-", "/"], "Qstrip_priv">, Flags<[DriverOption]>, Group<hlslutil_Group>,
HelpText<"Strip private data from shader bytecode (must be used with /Fo <file>)">;

Просмотреть файл

@ -12,6 +12,7 @@
#include "llvm/Option/OptTable.h"
#include "llvm/Option/Option.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/Path.h"
#include "dxc/Support/Global.h"
#include "dxc/Support/WinIncludes.h"
#include "dxc/Support/HLSLOptions.h"
@ -144,6 +145,28 @@ bool DxcOpts::IsLibraryProfile() {
return TargetProfile.startswith("lib_");
}
bool DxcOpts::IsDebugInfoEnabled() {
return DebugInfo;
}
bool DxcOpts::EmbedDebugInfo() {
return EmbedDebug;
}
bool DxcOpts::EmbedPDBName() {
return IsDebugInfoEnabled() || !DebugFile.empty();
}
bool DxcOpts::DebugFileIsDirectory() {
return !DebugFile.empty() && llvm::sys::path::is_separator(DebugFile[DebugFile.size() - 1]);
}
llvm::StringRef DxcOpts::GetPDBName() {
if (!DebugFileIsDirectory())
return DebugFile;
return llvm::StringRef();
}
MainArgs::MainArgs(int argc, const wchar_t **argv, int skipArgCount) {
if (argc > skipArgCount) {
Utf8StringVector.reserve(argc - skipArgCount);
@ -411,10 +434,10 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
opts.OutputObject = Args.getLastArgValue(OPT_Fo);
opts.OutputHeader = Args.getLastArgValue(OPT_Fh);
opts.OutputWarningsFile = Args.getLastArgValue(OPT_Fe);
opts.UseColor = Args.hasFlag(OPT_Cc, OPT_INVALID);
opts.UseInstructionNumbers = Args.hasFlag(OPT_Ni, OPT_INVALID);
opts.UseInstructionByteOffsets = Args.hasFlag(OPT_No, OPT_INVALID);
opts.UseHexLiterals = Args.hasFlag(OPT_Lx, OPT_INVALID);
opts.UseColor = Args.hasFlag(OPT_Cc, OPT_INVALID, false);
opts.UseInstructionNumbers = Args.hasFlag(OPT_Ni, OPT_INVALID, false);
opts.UseInstructionByteOffsets = Args.hasFlag(OPT_No, OPT_INVALID, false);
opts.UseHexLiterals = Args.hasFlag(OPT_Lx, OPT_INVALID, false);
opts.Preprocess = Args.getLastArgValue(OPT_P);
opts.AstDump = Args.hasFlag(OPT_ast_dump, OPT_INVALID, false);
opts.CodeGenHighLevel = Args.hasFlag(OPT_fcgl, OPT_INVALID, false);
@ -533,6 +556,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
opts.PreferFlowControl = Args.hasFlag(OPT_Gfp, OPT_INVALID, false);
opts.RecompileFromBinary = Args.hasFlag(OPT_recompile, OPT_INVALID, false);
opts.StripDebug = Args.hasFlag(OPT_Qstrip_debug, OPT_INVALID, false);
opts.EmbedDebug = Args.hasFlag(OPT_Qembed_debug, OPT_INVALID, false);
opts.StripRootSignature = Args.hasFlag(OPT_Qstrip_rootsignature, OPT_INVALID, false);
opts.StripPrivate = Args.hasFlag(OPT_Qstrip_priv, OPT_INVALID, false);
opts.StripReflection = Args.hasFlag(OPT_Qstrip_reflect, OPT_INVALID, false);
@ -609,8 +633,16 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
return 1;
}
if (opts.EmbedDebug && !opts.DebugInfo) {
errors << "Must enable debug info with /Zi for /Qembed_debug";
return 1;
}
if (!opts.DebugNameForBinary && !opts.DebugNameForSource) {
if (opts.DebugInfo)
opts.DebugNameForSource = true;
else
opts.DebugNameForBinary = true;
}
else if (opts.DebugNameForBinary && opts.DebugNameForSource) {
errors << "Cannot specify both /Zss and /Zsb";

Просмотреть файл

@ -1565,10 +1565,6 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
// If we have debug information present, serialize it to a debug part, then use the stripped version as the canonical program version.
CComPtr<AbstractMemoryStream> pProgramStream = pInputProgramStream;
const uint32_t DebugInfoNameHashLen = 32; // 32 chars of MD5
const uint32_t DebugInfoNameSuffix = 4; // '.lld'
const uint32_t DebugInfoNameNullAndPad = 4; // '\0\0\0\0'
CComPtr<AbstractMemoryStream> pHashStream;
if (HasDebugInfo(*pModule->GetModule())) {
uint32_t debugInUInt32, debugPaddingBytes;
GetPaddedProgramPartSize(pInputProgramStream, debugInUInt32, debugPaddingBytes);
@ -1586,48 +1582,24 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
IFT(CreateMemoryStream(DxcGetThreadMallocNoRef(), &pProgramStream));
raw_stream_ostream outStream(pProgramStream.p);
WriteBitcodeToFile(pModule->GetModule(), outStream, true);
} else {
// If no debug info, clear DebugNameDependOnSource
// (it's default, and this scenario can happen)
Flags &= ~SerializeDxilFlags::DebugNameDependOnSource;
}
// Serialize debug name if requested.
CComPtr<AbstractMemoryStream> pHashStream;
std::string DebugNameStr; // Used if constructing name based on hash
if (Flags & SerializeDxilFlags::IncludeDebugNamePart) {
if (DebugName.empty()) {
// 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<AbstractMemoryStream>(pModuleBitcode)
: CComPtr<AbstractMemoryStream>(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) + NameLen + DebugInfoNameNullAndPad;
writer.AddPart(DFCC_ShaderDebugName, DebugInfoContentLen,
[DebugInfoNameSuffix, DebugInfoNameHashLen, UseDebugName, DebugName, pHashStream]
(AbstractMemoryStream *pStream)
{
DxilShaderDebugName NameContent;
NameContent.Flags = 0;
if (UseDebugName) {
NameContent.NameLength = DebugName.size();
IFT(WriteStreamValue(pStream, NameContent));
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<uint8_t> Data((uint8_t *)pHashStream->GetPtr(), pHashStream->GetPtrSize());
llvm::MD5 md5;
llvm::MD5::MD5Result md5Result;
@ -1635,15 +1607,32 @@ void hlsl::SerializeDxilContainerForModule(DxilModule *pModule,
md5.update(Data);
md5.final(md5Result);
md5.stringifyResult(md5Result, Hash);
DebugNameStr += Hash;
DebugNameStr += ".lld";
DebugName = DebugNameStr;
}
// Calculate the size of the blob part.
const uint32_t DebugInfoContentLen = PSVALIGN4(
sizeof(DxilShaderDebugName) + DebugName.size() + 1); // 1 for null
writer.AddPart(DFCC_ShaderDebugName, DebugInfoContentLen,
[DebugName]
(AbstractMemoryStream *pStream)
{
DxilShaderDebugName NameContent;
NameContent.Flags = 0;
NameContent.NameLength = DebugName.size();
IFT(WriteStreamValue(pStream, NameContent));
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));
}
IFT(pStream->Write(DebugName.begin(), DebugName.size(), &cbWritten));
const char Pad[] = { '\0','\0','\0','\0' };
// Always writes at least one null to align size
unsigned padLen = (4 - ((sizeof(DxilShaderDebugName) + cbWritten) & 0x3));
IFT(pStream->Write(Pad, padLen, &cbWritten));
});
}
}
// Compute padded bitcode size.
uint32_t programInUInt32, programPaddingBytes;

Просмотреть файл

@ -150,7 +150,10 @@ public:
}
int Compile();
void Recompile(IDxcBlob *pSource, IDxcLibrary *pLibrary, IDxcCompiler *pCompiler, std::vector<LPCWSTR> &args, IDxcOperationResult **pCompileResult);
void Recompile(IDxcBlob *pSource, IDxcLibrary *pLibrary,
IDxcCompiler *pCompiler, std::vector<LPCWSTR> &args,
std::wstring &outputPDBPath, CComPtr<IDxcBlob> &pDebugBlob,
IDxcOperationResult **pCompileResult);
int DumpBinary();
void Preprocess();
void GetCompilerVersionInfo(llvm::raw_string_ostream &OS);
@ -223,13 +226,12 @@ int DxcContext::ActOnBlob(IDxcBlob *pBlob, IDxcBlob *pDebugBlob, LPCWSTR pDebugB
"found in the shader, please use the "
"/Zi switch to generate debug "
"information compiling this shader.");
if (pDebugBlob != nullptr) {
IFTBOOLMSG(pDebugBlobName && *pDebugBlobName, E_INVALIDARG,
"/Fd was specified but no debug name was produced");
WriteBlobToFile(pDebugBlob, pDebugBlobName);
}
else {
} else {
// Note: This is for load from binary case
WritePartToFile(pBlob, hlsl::DFCC_ShaderDebugInfoDXIL, m_Opts.DebugFile);
}
}
@ -542,7 +544,11 @@ public:
}
};
void DxcContext::Recompile(IDxcBlob *pSource, IDxcLibrary *pLibrary, IDxcCompiler *pCompiler, std::vector<LPCWSTR> &args, IDxcOperationResult **ppCompileResult) {
void DxcContext::Recompile(IDxcBlob *pSource, IDxcLibrary *pLibrary,
IDxcCompiler *pCompiler, std::vector<LPCWSTR> &args,
std::wstring &outputPDBPath,
CComPtr<IDxcBlob> &pDebugBlob,
IDxcOperationResult **ppCompileResult) {
// Recompile currently only supported on Windows
#ifdef _WIN32
CComPtr<IDxcBlob> pTargetBlob;
@ -689,11 +695,28 @@ void DxcContext::Recompile(IDxcBlob *pSource, IDxcLibrary *pLibrary, IDxcCompile
}
CComPtr<IDxcOperationResult> pResult;
if (!m_Opts.DebugFile.empty()) {
CComPtr<IDxcCompiler2> pCompiler2;
CComHeapPtr<WCHAR> pDebugName;
Unicode::UTF8ToUTF16String(m_Opts.DebugFile.str().c_str(), &outputPDBPath);
IFT(pCompiler->QueryInterface(&pCompiler2));
IFT(pCompiler2->CompileWithDebug(
pCompileSource, pMainFileName, StringRefUtf16(EntryPoint),
StringRefUtf16(TargetProfile), ConcatArgs.data(), ConcatArgs.size(),
ConcatDefines.data(), ConcatDefines.size(), pIncludeHandler, &pResult,
&pDebugName, &pDebugBlob));
if (pDebugName.m_pData && m_Opts.DebugFileIsDirectory()) {
outputPDBPath += pDebugName.m_pData;
}
} else {
IFT(pCompiler->Compile(pCompileSource, pMainFileName,
StringRefUtf16(EntryPoint),
StringRefUtf16(TargetProfile), ConcatArgs.data(),
ConcatArgs.size(), ConcatDefines.data(),
ConcatDefines.size(), pIncludeHandler, &pResult));
}
*ppCompileResult = pResult.Detach();
#else
assert(false && "Recompile is currently only supported on Windows.");
@ -705,7 +728,7 @@ int DxcContext::Compile() {
CComPtr<IDxcCompiler> pCompiler;
CComPtr<IDxcOperationResult> pCompileResult;
CComPtr<IDxcBlob> pDebugBlob;
std::wstring debugName;
std::wstring outputPDBPath;
{
CComPtr<IDxcBlobEncoding> pSource;
@ -727,9 +750,9 @@ int DxcContext::Compile() {
IFTARG(pSource->GetBufferSize() >= 4);
if (m_Opts.RecompileFromBinary) {
Recompile(pSource, pLibrary, pCompiler, args, &pCompileResult);
}
else {
Recompile(pSource, pLibrary, pCompiler, args, outputPDBPath, pDebugBlob,
&pCompileResult);
} else {
CComPtr<IDxcIncludeHandler> pIncludeHandler;
IFT(pLibrary->CreateIncludeHandler(&pIncludeHandler));
@ -744,10 +767,10 @@ int DxcContext::Compile() {
}
}
if (!m_Opts.DebugFile.empty() && m_Opts.DebugFile.endswith(llvm::StringRef("\\"))) {
args.push_back(L"/Qstrip_debug"); // implied
if (!m_Opts.DebugFile.empty()) {
CComPtr<IDxcCompiler2> pCompiler2;
CComHeapPtr<WCHAR> pDebugName;
Unicode::UTF8ToUTF16String(m_Opts.DebugFile.str().c_str(), &outputPDBPath);
IFT(pCompiler.QueryInterface(&pCompiler2));
IFT(pCompiler2->CompileWithDebug(
pSource, StringRefUtf16(m_Opts.InputFile),
@ -755,9 +778,8 @@ int DxcContext::Compile() {
args.data(), args.size(), m_Opts.Defines.data(),
m_Opts.Defines.size(), pIncludeHandler, &pCompileResult,
&pDebugName, &pDebugBlob));
if (pDebugName.m_pData) {
Unicode::UTF8ToUTF16String(m_Opts.DebugFile.str().c_str(), &debugName);
debugName += pDebugName.m_pData;
if (pDebugName.m_pData && m_Opts.DebugFileIsDirectory()) {
outputPDBPath += pDebugName.m_pData;
}
} else {
IFT(pCompiler->Compile(pSource, StringRefUtf16(m_Opts.InputFile),
@ -767,6 +789,13 @@ int DxcContext::Compile() {
m_Opts.Defines.size(), pIncludeHandler, &pCompileResult));
}
}
// When compiling we don't embed debug info if options don't ask for it.
// If user specified /Qstrip_debug, remove from m_Opts now so we don't
// try to modify the container to strip debug info that isn't there.
if (!m_Opts.EmbedDebugInfo()) {
m_Opts.StripDebug = false;
}
}
if (!m_Opts.OutputWarningsFile.empty()) {
@ -786,7 +815,7 @@ int DxcContext::Compile() {
pCompiler.Release();
pCompileResult.Release();
if (pProgram.p != nullptr) {
ActOnBlob(pProgram.p, pDebugBlob, debugName.c_str());
ActOnBlob(pProgram.p, pDebugBlob, outputPDBPath.c_str());
}
}
return status;

Просмотреть файл

@ -32,6 +32,17 @@ using namespace hlsl;
// This declaration is used for the locally-linked validator.
HRESULT CreateDxcValidator(_In_ REFIID riid, _Out_ LPVOID *ppv);
static bool HasDebugInfo(const Module &M) {
for (Module::const_named_metadata_iterator NMI = M.named_metadata_begin(),
NME = M.named_metadata_end();
NMI != NME; ++NMI) {
if (NMI->getName().startswith("llvm.dbg.")) {
return true;
}
}
return false;
}
class DxcAssembler : public IDxcAssembler {
private:
DXC_MICROCOM_TM_REF_FIELDS()
@ -130,9 +141,12 @@ HRESULT STDMETHODCALLTYPE DxcAssembler::AssembleToContainer(
outStream.flush();
CComPtr<IDxcBlob> pResultBlob;
static constexpr hlsl::SerializeDxilFlags flags = static_cast<hlsl::SerializeDxilFlags>(
static_cast<uint32_t>(SerializeDxilFlags::IncludeDebugNamePart) |
static_cast<uint32_t>(SerializeDxilFlags::IncludeDebugInfoPart));
hlsl::SerializeDxilFlags flags = hlsl::SerializeDxilFlags::None;
if (HasDebugInfo(*M)) {
flags |= SerializeDxilFlags::IncludeDebugInfoPart;
flags |= SerializeDxilFlags::IncludeDebugNamePart;
flags |= SerializeDxilFlags::DebugNameDependOnSource;
}
dxcutil::AssembleToContainer(std::move(M), pResultBlob,
TM.p, flags,
pOutputStream);

Просмотреть файл

@ -573,12 +573,14 @@ public:
outStream.flush();
SerializeDxilFlags SerializeFlags = SerializeDxilFlags::None;
if (opts.DebugInfo) {
SerializeFlags = SerializeDxilFlags::IncludeDebugNamePart;
// Unless we want to strip it right away, include it in the container.
if (!opts.StripDebug || ppDebugBlob == nullptr) {
SerializeFlags |= SerializeDxilFlags::IncludeDebugInfoPart;
if (opts.EmbedPDBName()) {
SerializeFlags |= SerializeDxilFlags::IncludeDebugNamePart;
}
// If -Qembed_debug specified, or if there is no output pointer
// for the debug blob (such as when called by Compile()),
// embed the debug info.
if (opts.EmbedDebugInfo() || (opts.DebugInfo && !ppDebugBlob)) {
SerializeFlags |= SerializeDxilFlags::IncludeDebugInfoPart;
}
if (opts.DebugNameForSource) {
SerializeFlags |= SerializeDxilFlags::DebugNameDependOnSource;
@ -592,7 +594,7 @@ public:
if (needsValidation) {
valHR = dxcutil::ValidateAndAssembleToContainer(
action.takeModule(), pOutputBlob, m_pMalloc, SerializeFlags,
pOutputStream, opts.DebugInfo, opts.DebugFile, compiler.getDiagnostics());
pOutputStream, opts.IsDebugInfoEnabled(), opts.GetPDBName(), compiler.getDiagnostics());
} else {
dxcutil::AssembleToContainer(action.takeModule(),
pOutputBlob, m_pMalloc,
@ -635,7 +637,7 @@ public:
HRESULT status;
DXVERIFY_NOMSG(SUCCEEDED((*ppResult)->GetStatus(&status)));
if (SUCCEEDED(status)) {
if (opts.DebugInfo && ppDebugBlob) {
if (opts.IsDebugInfoEnabled() && ppDebugBlob) {
DXVERIFY_NOMSG(SUCCEEDED(pOutputStream.QueryInterface(ppDebugBlob)));
}
if (ppDebugBlobName) {
@ -851,7 +853,7 @@ public:
compiler.getFrontendOpts().Inputs.push_back(FrontendInputFile(pMainFile, IK_HLSL));
// Setup debug information.
if (Opts.DebugInfo) {
if (Opts.IsDebugInfoEnabled()) {
CodeGenOptions &CGOpts = compiler.getCodeGenOpts();
CGOpts.setDebugInfo(CodeGenOptions::FullDebugInfo);
CGOpts.DebugColumnInfo = 1;

Просмотреть файл

@ -184,6 +184,8 @@ if(ENABLE_SHARED)
endif()
endif() # HLSL Change
add_dependencies(libclang TablegenHLSLOptions) # HLSL Change
# HLSL Change Starts
# add_clang_library(${LIBCLANG_STATIC_TARGET_NAME} STATIC ${SOURCES})
# target_link_libraries(${LIBCLANG_STATIC_TARGET_NAME} ${LIBS})

Просмотреть файл

@ -830,7 +830,7 @@ public:
VERIFY_SUCCEEDED(CreateCompiler(&pCompiler));
CreateBlobFromText(hlsl, &pSource);
LPCWSTR args[] = { L"/Zi" };
LPCWSTR args[] = { L"/Zi", L"/Qembed_debug" };
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main",
L"ps_6_0", args, _countof(args), nullptr, 0, nullptr, &pResult));
VERIFY_SUCCEEDED(pResult->GetResult(&pProgram));
@ -1255,7 +1255,7 @@ TEST_F(CompilerTest, CompileWhenDebugWorksThenStripDebug) {
" return local;\r\n"
"}",
&pSource);
LPCWSTR args[] = {L"/Zi"};
LPCWSTR args[] = {L"/Zi", L"/Qembed_debug"};
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main",
L"ps_6_0", args, _countof(args), nullptr,
@ -1352,7 +1352,7 @@ TEST_F(CompilerTest, CompileThenAddCustomDebugName) {
"}",
&pSource);
LPCWSTR args[] = { L"/Zi", L"/Zss" };
LPCWSTR args[] = { L"/Zi", L"/Qembed_debug", L"/Zss" };
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"source.hlsl", L"main",
L"ps_6_0", args, _countof(args), nullptr, 0,
@ -2266,8 +2266,11 @@ static void CompileTestAndLoadDia(dxc::DxcDllSupport &dllSupport, IDiaDataSource
CComPtr<IDxcLibrary> pLib;
CComPtr<IDxcContainerReflection> pReflection;
UINT32 index;
std::vector<LPCWSTR> args;
args.push_back(L"/Zi");
args.push_back(L"/Qembed_debug");
VerifyCompileOK(dllSupport, EmptyCompute, L"cs_6_0", L"/Zi", &pContainer);
VerifyCompileOK(dllSupport, EmptyCompute, L"cs_6_0", args, &pContainer);
VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcLibrary, &pLib));
VERIFY_SUCCEEDED(dllSupport.CreateInstance(CLSID_DxcContainerReflection, &pReflection));
VERIFY_SUCCEEDED(pReflection->Load(pContainer));

Просмотреть файл

@ -522,9 +522,9 @@ bool DxilContainerTest::InitSupport() {
TEST_F(DxilContainerTest, CompileWhenDebugSourceThenSourceMatters) {
char program1[] = "float4 main() : SV_Target { return 0; }";
char program2[] = " float4 main() : SV_Target { return 0; } ";
LPCWSTR Zi[] = { L"/Zi" };
LPCWSTR ZiZss[] = { L"/Zi", L"/Zss" };
LPCWSTR ZiZsb[] = { L"/Zi", L"/Zsb" };
LPCWSTR Zi[] = { L"/Zi", L"/Qembed_debug" };
LPCWSTR ZiZss[] = { L"/Zi", L"/Qembed_debug", L"/Zss" };
LPCWSTR ZiZsb[] = { L"/Zi", L"/Qembed_debug", L"/Zsb" };
// No debug info, no debug name...
std::string noName = CompileToDebugName(program1, L"main", L"ps_6_0", nullptr, 0);
@ -1497,11 +1497,12 @@ TEST_F(DxilContainerTest, DxilContainerUnitTest) {
CComPtr<IDxcOperationResult> pResult;
std::vector<LPCWSTR> arguments;
arguments.emplace_back(L"/Zi");
arguments.emplace_back(L"/Qembed_debug");
VERIFY_SUCCEEDED(CreateCompiler(&pCompiler));
CreateBlobFromText("float4 main() : SV_Target { return 0; }", &pSource);
// Test DxilContainer with ShaderDebugInfoDXIL
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"main", L"ps_6_0", arguments.data(), 1, nullptr, 0, nullptr, &pResult));
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"main", L"ps_6_0", arguments.data(), arguments.size(), nullptr, 0, nullptr, &pResult));
VERIFY_SUCCEEDED(pResult->GetResult(&pProgram));
const hlsl::DxilContainerHeader *pHeader = static_cast<const hlsl::DxilContainerHeader *> (pProgram->GetBufferPointer());

Просмотреть файл

@ -71,8 +71,8 @@ public:
m_dllSupport.CreateInstance(CLSID_DxcLinker, pResultLinker));
}
void CompileLib(LPCWSTR filename, IDxcBlob **pResultBlob, LPCWSTR *pArguments,
UINT32 argCount) {
void CompileLib(LPCWSTR filename, IDxcBlob **pResultBlob,
llvm::ArrayRef<LPCWSTR> pArguments = {}) {
std::wstring fullPath = hlsl_test::GetPathToHlslDataFile(filename);
CComPtr<IDxcBlobEncoding> pSource;
CComPtr<IDxcLibrary> pLibrary;
@ -89,15 +89,12 @@ public:
VERIFY_SUCCEEDED(
m_dllSupport.CreateInstance(CLSID_DxcCompiler, &pCompiler));
VERIFY_SUCCEEDED(pCompiler->Compile(pSource, L"hlsl.hlsl", L"", shWide,
pArguments, argCount, nullptr, 0,
const_cast<LPCWSTR*>(pArguments.data()), pArguments.size(),
nullptr, 0,
nullptr, &pResult));
VERIFY_SUCCEEDED(pResult->GetResult(pResultBlob));
}
void CompileLib(LPCWSTR filename, IDxcBlob **pResourceBlob) {
CompileLib(filename, pResourceBlob, nullptr, 0);
}
void RegisterDxcModule(LPCWSTR pLibName, IDxcBlob *pBlob,
IDxcLinker *pLinker) {
VERIFY_SUCCEEDED(pLinker->RegisterLibrary(pLibName, pBlob));
@ -170,10 +167,10 @@ TEST_F(LinkerTest, RunLinkAllProfiles) {
CreateLinker(&pLinker);
LPCWSTR libName = L"entry";
LPCWSTR option[] = { L"-Zi" };
LPCWSTR option[] = { L"-Zi", L"-Qembed_debug" };
CComPtr<IDxcBlob> pEntryLib;
CompileLib(L"..\\CodeGenHLSL\\lib_entries2.hlsl", &pEntryLib, option, 1);
CompileLib(L"..\\CodeGenHLSL\\lib_entries2.hlsl", &pEntryLib, option);
RegisterDxcModule(libName, pEntryLib, pLinker);
Link(L"vs_main", L"vs_6_0", pLinker, {libName}, {},{});
@ -379,15 +376,15 @@ TEST_F(LinkerTest, RunLinkResRet) {
}
TEST_F(LinkerTest, RunLinkToLib) {
LPCWSTR option[] = {L"-Zi"};
LPCWSTR option[] = {L"-Zi", L"-Qembed_debug"};
CComPtr<IDxcBlob> pEntryLib;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_mat_entry2.hlsl",
&pEntryLib, option, 1);
&pEntryLib, option);
CComPtr<IDxcBlob> pLib;
CompileLib(
L"..\\CodeGenHLSL\\linker\\lib_mat_cast2.hlsl",
&pLib, option, 1);
&pLib, option);
CComPtr<IDxcLinker> pLinker;
CreateLinker(&pLinker);
@ -398,7 +395,7 @@ TEST_F(LinkerTest, RunLinkToLib) {
LPCWSTR libName2 = L"test";
RegisterDxcModule(libName2, pLib, pLinker);
Link(L"", L"lib_6_3", pLinker, {libName, libName2}, {"!llvm.dbg.cu"}, {});
Link(L"", L"lib_6_3", pLinker, {libName, libName2}, {"!llvm.dbg.cu"}, {}, option);
}
TEST_F(LinkerTest, RunLinkToLibExport) {
@ -444,14 +441,14 @@ TEST_F(LinkerTest, RunLinkFailSelectRes) {
}
TEST_F(LinkerTest, RunLinkToLibWithUnresolvedFunctions) {
LPCWSTR option[] = { L"-Zi" };
LPCWSTR option[] = { L"-Zi", L"-Qembed_debug" };
CComPtr<IDxcBlob> pLib1;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func1.hlsl",
&pLib1, option, 1);
&pLib1, option);
CComPtr<IDxcBlob> pLib2;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func2.hlsl",
&pLib2, option, 1);
&pLib2, option);
CComPtr<IDxcLinker> pLinker;
CreateLinker(&pLinker);
@ -474,14 +471,14 @@ TEST_F(LinkerTest, RunLinkToLibWithUnresolvedFunctions) {
}
TEST_F(LinkerTest, RunLinkToLibWithUnresolvedFunctionsExports) {
LPCWSTR option[] = { L"-Zi" };
LPCWSTR option[] = { L"-Zi", L"-Qembed_debug" };
CComPtr<IDxcBlob> pLib1;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func1.hlsl",
&pLib1, option, 1);
&pLib1, option);
CComPtr<IDxcBlob> pLib2;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func2.hlsl",
&pLib2, option, 1);
&pLib2, option);
CComPtr<IDxcLinker> pLinker;
CreateLinker(&pLinker);
@ -509,14 +506,14 @@ TEST_F(LinkerTest, RunLinkToLibWithUnresolvedFunctionsExports) {
}
TEST_F(LinkerTest, RunLinkToLibWithExportNamesSwapped) {
LPCWSTR option[] = { L"-Zi" };
LPCWSTR option[] = { L"-Zi", L"-Qembed_debug" };
CComPtr<IDxcBlob> pLib1;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func1.hlsl",
&pLib1, option, 1);
&pLib1, option);
CComPtr<IDxcBlob> pLib2;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func2.hlsl",
&pLib2, option, 1);
&pLib2, option);
CComPtr<IDxcLinker> pLinker;
CreateLinker(&pLinker);
@ -541,14 +538,14 @@ TEST_F(LinkerTest, RunLinkToLibWithExportNamesSwapped) {
}
TEST_F(LinkerTest, RunLinkToLibWithExportCollision) {
LPCWSTR option[] = { L"-Zi" };
LPCWSTR option[] = { L"-Zi", L"-Qembed_debug" };
CComPtr<IDxcBlob> pLib1;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func1.hlsl",
&pLib1, option, 1);
&pLib1, option);
CComPtr<IDxcBlob> pLib2;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func2.hlsl",
&pLib2, option, 1);
&pLib2, option);
CComPtr<IDxcLinker> pLinker;
CreateLinker(&pLinker);
@ -566,14 +563,14 @@ TEST_F(LinkerTest, RunLinkToLibWithExportCollision) {
}
TEST_F(LinkerTest, RunLinkToLibWithUnusedExport) {
LPCWSTR option[] = { L"-Zi" };
LPCWSTR option[] = { L"-Zi", L"-Qembed_debug" };
CComPtr<IDxcBlob> pLib1;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func1.hlsl",
&pLib1, option, 1);
&pLib1, option);
CComPtr<IDxcBlob> pLib2;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func2.hlsl",
&pLib2, option, 1);
&pLib2, option);
CComPtr<IDxcLinker> pLinker;
CreateLinker(&pLinker);
@ -591,14 +588,14 @@ TEST_F(LinkerTest, RunLinkToLibWithUnusedExport) {
}
TEST_F(LinkerTest, RunLinkToLibWithNoExports) {
LPCWSTR option[] = { L"-Zi" };
LPCWSTR option[] = { L"-Zi", L"-Qembed_debug" };
CComPtr<IDxcBlob> pLib1;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func1.hlsl",
&pLib1, option, 1);
&pLib1, option);
CComPtr<IDxcBlob> pLib2;
CompileLib(L"..\\CodeGenHLSL\\linker\\lib_unresolved_func2.hlsl",
&pLib2, option, 1);
&pLib2, option);
CComPtr<IDxcLinker> pLinker;
CreateLinker(&pLinker);
@ -616,14 +613,14 @@ TEST_F(LinkerTest, RunLinkToLibWithNoExports) {
}
TEST_F(LinkerTest, RunLinkWithPotentialIntrinsicNameCollisions) {
LPCWSTR option[] = { L"-Zi" };
LPCWSTR option[] = { L"-Zi", L"-Qembed_debug" };
CComPtr<IDxcBlob> pLib1;
CompileLib(L"..\\CodeGenHLSL\\linker\\createHandle_multi.hlsl",
&pLib1, option, 1);
&pLib1, option);
CComPtr<IDxcBlob> pLib2;
CompileLib(L"..\\CodeGenHLSL\\linker\\createHandle_multi2.hlsl",
&pLib2, option, 1);
&pLib2, option);
CComPtr<IDxcLinker> pLinker;
CreateLinker(&pLinker);

Просмотреть файл

@ -29,16 +29,34 @@ if %errorlevel% neq 0 (
exit /b 1
)
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fd smoke.hlsl.d 1>nul
rem /Fd implies /Qstrip_debug
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fd smoke.hlsl.d /Fo smoke.hlsl.Fd.dxo 1>nul
if %errorlevel% neq 0 (
echo Failed - %CD%\dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fd %CD%\smoke.hlsl.d
echo Failed - %CD%\dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Fd %CD%\smoke.hlsl.d
call :cleanup 2>nul
exit /b 1
)
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fd %CD%\ /Fo smoke.hlsl.strip 1>nul
dxc.exe -dumpbin smoke.hlsl.Fd.dxo | findstr "shader debug name: smoke.hlsl.d" 1>nul
if %errorlevel% neq 0 (
echo Failed - %CD%\dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fd %CD%\
echo Failed to find shader debug name.
call :cleanup 2>nul
exit /b 1
)
dxc.exe -dumpbin smoke.hlsl.Fd.dxo | findstr "DICompileUnit" 1>nul
if %errorlevel% equ 0 (
echo Found DICompileUnit after implied strip.
call :cleanup 2>nul
exit /b 1
)
rem del .lld file if exists
dir %CD%\*.lld 1>nul
if %errorlevel% equ 0 (
del %CD%\*.lld
)
rem /Fd implies /Qstrip_debug ; path with \ produces auto hash-named .lld file
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fd .\ /Fo smoke.hlsl.strip 1>nul
if %errorlevel% neq 0 (
echo Failed - %CD%\dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Fd %CD%\
call :cleanup 2>nul
exit /b 1
)
@ -49,8 +67,8 @@ if %errorlevel% neq 0 (
call :cleanup 2>nul
exit /b 1
)
rem /Fd with trailing backslash implies /Qstrip_debug
dxc.exe -dumpbin smoke.hlsl.strip | findstr "shader debug name" 1>nul
rem auto debug name is hex digest + .lld
dxc.exe -dumpbin smoke.hlsl.strip | findstr -r -c:"shader debug name: [0-9a-f]*.lld" 1>nul
if %errorlevel% neq 0 (
echo Failed to find shader debug name.
call :cleanup 2>nul
@ -63,6 +81,79 @@ if %errorlevel% equ 0 (
exit /b 1
)
rem Embed debug info
rem first delete .lld file if exists
dir %CD%\*.lld 1>nul
if %errorlevel% equ 0 (
del %CD%\*.lld
)
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Qembed_debug /Fo smoke.hlsl.embedpdb 1>nul
if %errorlevel% neq 0 (
echo Failed - %CD%\dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Qembed_debug
call :cleanup 2>nul
exit /b 1
)
rem .lld file should NOT be produced
dir %CD%\*.lld 1>nul
if %errorlevel% equ 0 (
echo Found unexpected .lld file at %CD%
call :cleanup 2>nul
exit /b 1
)
rem should have auto debug name, which is hex digest + .lld
dxc.exe -dumpbin smoke.hlsl.embedpdb | findstr -r -c:"shader debug name: [0-9a-f]*.lld" 1>nul
if %errorlevel% neq 0 (
echo Failed to find shader debug name.
call :cleanup 2>nul
exit /b 1
)
dxc.exe -dumpbin smoke.hlsl.embedpdb | findstr "DICompileUnit" 1>nul
if %errorlevel% neq 0 (
echo Did not find DICompileUnit when /Zi /Qembed_debug is used to embed debug info.
call :cleanup 2>nul
exit /b 1
)
rem Drop embedded debug info after compile and warn.
rem first delete .lld file if exists
dir %CD%\*.lld 1>nul
if %errorlevel% equ 0 (
del %CD%\*.lld
)
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fo smoke.hlsl.noembedpdb /Fe smoke.err.noembedpdb 1>nul
if %errorlevel% neq 0 (
echo Failed - %CD%\dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi
call :cleanup 2>nul
exit /b 1
)
rem Search for warning:
findstr -c:"warning: Debug info (PDB) will not be embedded in shader binary without -Qembed_debug" smoke.err.noembedpdb
if %errorlevel% neq 0 (
echo Did not find warning about not embedding debug info without -Qembed_debug.
call :cleanup 2>nul
exit /b 1
)
rem .lld file should NOT be produced
dir %CD%\*.lld 1>nul
if %errorlevel% equ 0 (
echo Found unexpected .lld file at %CD%
call :cleanup 2>nul
exit /b 1
)
rem should have auto debug name, which is hex digest + .lld
dxc.exe -dumpbin smoke.hlsl.noembedpdb | findstr -r -c:"shader debug name: [0-9a-f]*.lld" 1>nul
if %errorlevel% neq 0 (
echo Failed to find shader debug name.
call :cleanup 2>nul
exit /b 1
)
dxc.exe -dumpbin smoke.hlsl.noembedpdb | findstr "DICompileUnit" 1>nul
if %errorlevel% equ 0 (
echo Found DICompileUnit when /Zi is used without /Qembed_debug, which should not embed debug info.
call :cleanup 2>nul
exit /b 1
)
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Fe smoke.hlsl.e 1>nul
if %errorlevel% neq 0 (
echo Failed - %CD%\dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Fe %CD%\smoke.hlsl.e
@ -185,14 +276,14 @@ if %errorlevel% equ 0 (
exit /b 1
)
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fo smoke.cso 1> nul
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Qembed_debug /Fo smoke.cso 1> nul
if %errorlevel% neq 0 (
echo Failed to compile to binary object from %CD%\smoke.hlsl
call :cleanup 2>nul
exit /b 1
)
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Fo smoke.cso /Cc /Ni /No /Lx 1> nul
dxc.exe /T ps_6_0 "%testfiles%\smoke.hlsl" /Zi /Qembed_debug /Fo smoke.cso /Cc /Ni /No /Lx 1> nul
if %errorlevel% neq 0 (
echo Failed to compile to binary object from "%testfiles%\smoke.hlsl" with disassembly options
call :cleanup 2>nul
@ -220,7 +311,7 @@ if %errorlevel% neq 0 (
exit /b 1
)
dxc.exe "%testfiles%\smoke.hlsl" /D "semantic = SV_Position" /T vs_6_0 /Zi /DDX12 /Fo smoke.cso 1> nul
dxc.exe "%testfiles%\smoke.hlsl" /D "semantic = SV_Position" /T vs_6_0 /Zi /Qembed_debug /DDX12 /Fo smoke.cso 1> nul
if %errorlevel% neq 0 (
echo Failed to compile "%testfiles%\smoke.hlsl" with command line defines
call :cleanup 2>nul
@ -340,7 +431,7 @@ if %errorlevel% equ 0 (
exit /b 1
)
dxc.exe "%testfiles%\TextVS.hlsl" /Tvs_6_0 /Zi /Fo TextVS.cso 1>nul
dxc.exe "%testfiles%\TextVS.hlsl" /Tvs_6_0 /Zi /Qembed_debug /Fo TextVS.cso 1>nul
if %errorlevel% neq 0 (
echo failed to compile "%testfiles%\TextVS.hlsl"
call :cleanup 2>nul
@ -639,7 +730,12 @@ call :cleanup
exit /b 0
:cleanup
del %CD%\*.lld
exit /b 0
rem del .lld file if exists
dir %CD%\*.lld 1>nul
if %errorlevel% equ 0 (
del %CD%\*.lld
)
del %CD%\NonUniform.cso
del %CD%\NonUniformNoRootSig.cso
del %CD%\NonUniformRootSig.cso
@ -660,9 +756,13 @@ del %CD%\smoke.cso.plain.bc
del %CD%\smoke.hl.txt
del %CD%\smoke.hlsl.c
del %CD%\smoke.hlsl.d
del %CD%\smoke.hlsl.Fd.dxo
del %CD%\smoke.hlsl.e
del %CD%\smoke.hlsl.h
del %CD%\smoke.hlsl.strip
del %CD%\smoke.hlsl.embedpdb
del %CD%\smoke.hlsl.noembedpdb
del %CD%\smoke.err.noembedpdb
del %CD%\smoke.ll
del %CD%\smoke.opt.ll
del %CD%\smoke.opt.prn.txt
@ -679,6 +779,8 @@ del %CD%\test-global-rs.hlsl
del %CD%\test-local-rs.hlsl
del %CD%\test-global-rs.cso
del %CD%\test-local-rs.cso
del %CD%\smoke.no.warning.txt
del %CD%\smoke.warning.txt
exit /b 0