Родитель
fd07613a95
Коммит
de09119850
|
@ -141,6 +141,7 @@ public:
|
|||
bool DebugNameForBinary = false; // OPT_Zsb
|
||||
bool DebugNameForSource = false; // OPT_Zss
|
||||
bool DumpBin = false; // OPT_dumpbin
|
||||
bool Link = false; // OPT_link
|
||||
bool WarningAsError = false; // OPT__SLASH_WX
|
||||
bool IEEEStrict = false; // OPT_Gis
|
||||
bool IgnoreLineDirectives = false; // OPT_ignore_line_directives
|
||||
|
|
|
@ -405,6 +405,8 @@ def P : Separate<["-", "/"], "P">, Flags<[CoreOption, DriverOption]>, Group<hlsl
|
|||
|
||||
def dumpbin : Flag<["-", "/"], "dumpbin">, Flags<[DriverOption]>, Group<hlslutil_Group>,
|
||||
HelpText<"Load a binary file rather than compiling">;
|
||||
def link : Flag<["-", "/"], "link">, Flags<[DriverOption]>, Group<hlslutil_Group>,
|
||||
HelpText<"Link list of libraries provided in <inputs> argument separated by ';'">;
|
||||
def Qstrip_reflect : Flag<["-", "/"], "Qstrip_reflect">, Flags<[CoreOption, DriverOption]>, Group<hlslutil_Group>,
|
||||
HelpText<"Strip reflection data from shader bytecode (must be used with /Fo <file>)">;
|
||||
def Qstrip_debug : Flag<["-", "/"], "Qstrip_debug">, Flags<[CoreOption, DriverOption]>, Group<hlslutil_Group>,
|
||||
|
|
|
@ -616,6 +616,7 @@ int ReadDxcOpts(const OptTable *optionTable, unsigned flagsToInclude,
|
|||
opts.DefaultRowMajor = Args.hasFlag(OPT_Zpr, OPT_INVALID, false);
|
||||
opts.DefaultColMajor = Args.hasFlag(OPT_Zpc, OPT_INVALID, false);
|
||||
opts.DumpBin = Args.hasFlag(OPT_dumpbin, OPT_INVALID, false);
|
||||
opts.Link = Args.hasFlag(OPT_link, OPT_INVALID, false);
|
||||
opts.NotUseLegacyCBufLoad = Args.hasFlag(OPT_no_legacy_cbuf_layout, OPT_INVALID, false);
|
||||
opts.NotUseLegacyCBufLoad = Args.hasFlag(OPT_not_use_legacy_cbuf_load_, OPT_INVALID, opts.NotUseLegacyCBufLoad);
|
||||
opts.PackPrefixStable = Args.hasFlag(OPT_pack_prefix_stable, OPT_INVALID, false);
|
||||
|
|
|
@ -158,6 +158,7 @@ public:
|
|||
std::wstring &outputPDBPath, CComPtr<IDxcBlob> &pDebugBlob,
|
||||
IDxcOperationResult **pCompileResult);
|
||||
int DumpBinary();
|
||||
int Link();
|
||||
void Preprocess();
|
||||
void GetCompilerVersionInfo(llvm::raw_string_ostream &OS);
|
||||
};
|
||||
|
@ -831,6 +832,61 @@ int DxcContext::Compile() {
|
|||
return status;
|
||||
}
|
||||
|
||||
int DxcContext::Link() {
|
||||
CComPtr<IDxcLinker> pLinker;
|
||||
IFT(CreateInstance(CLSID_DxcLinker, &pLinker));
|
||||
llvm::StringRef InputFiles = m_Opts.InputFile;
|
||||
llvm::StringRef InputFilesRef(InputFiles);
|
||||
llvm::SmallVector<llvm::StringRef, 2> InputFileList;
|
||||
InputFilesRef.split(InputFileList, ";");
|
||||
|
||||
std::vector<std::wstring> wInputFiles;
|
||||
wInputFiles.reserve(InputFileList.size());
|
||||
std::vector<LPCWSTR> wpInputFiles;
|
||||
wpInputFiles.reserve(InputFileList.size());
|
||||
for (auto &file : InputFileList) {
|
||||
wInputFiles.emplace_back(StringRefUtf16(file.str()));
|
||||
wpInputFiles.emplace_back(wInputFiles.back().c_str());
|
||||
CComPtr<IDxcBlobEncoding> pLib;
|
||||
ReadFileIntoBlob(m_dxcSupport, wInputFiles.back().c_str(), &pLib);
|
||||
IFT(pLinker->RegisterLibrary(wInputFiles.back().c_str(), pLib));
|
||||
}
|
||||
|
||||
CComPtr<IDxcOperationResult> pLinkResult;
|
||||
|
||||
std::vector<std::wstring> argStrings;
|
||||
CopyArgsToWStrings(m_Opts.Args, CoreOption, argStrings);
|
||||
|
||||
std::vector<LPCWSTR> args;
|
||||
args.reserve(argStrings.size());
|
||||
for (const std::wstring &a : argStrings)
|
||||
args.push_back(a.data());
|
||||
|
||||
IFT(pLinker->Link(StringRefUtf16(m_Opts.EntryPoint),
|
||||
StringRefUtf16(m_Opts.TargetProfile), wpInputFiles.data(),
|
||||
wpInputFiles.size(), args.data(), args.size(),
|
||||
&pLinkResult));
|
||||
|
||||
HRESULT status;
|
||||
IFT(pLinkResult->GetStatus(&status));
|
||||
if (SUCCEEDED(status)) {
|
||||
CComPtr<IDxcBlob> pContainer;
|
||||
IFT(pLinkResult->GetResult(&pContainer));
|
||||
if (pContainer.p != nullptr) {
|
||||
ActOnBlob(pContainer.p);
|
||||
}
|
||||
} else {
|
||||
CComPtr<IDxcBlobEncoding> pErrors;
|
||||
IFT(pLinkResult->GetErrorBuffer(&pErrors));
|
||||
if (pErrors != nullptr) {
|
||||
printf("Link failed:\n%s",
|
||||
static_cast<char *>(pErrors->GetBufferPointer()));
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int DxcContext::DumpBinary() {
|
||||
CComPtr<IDxcBlobEncoding> pSource;
|
||||
ReadFileIntoBlob(m_dxcSupport, StringRefUtf16(m_Opts.InputFile), &pSource);
|
||||
|
@ -1238,6 +1294,10 @@ int dxc::main(int argc, const char **argv_) {
|
|||
pStage = "Dumping existing binary";
|
||||
retVal = context.DumpBinary();
|
||||
}
|
||||
else if (dxcOpts.Link) {
|
||||
pStage = "Linking";
|
||||
retVal = context.Link();
|
||||
}
|
||||
else {
|
||||
pStage = "Compilation";
|
||||
retVal = context.Compile();
|
||||
|
|
|
@ -20,6 +20,7 @@ add_clang_executable(dxl
|
|||
)
|
||||
|
||||
target_link_libraries(dxl
|
||||
dxclib
|
||||
dxcompiler
|
||||
)
|
||||
|
||||
|
@ -29,7 +30,9 @@ if (WIN32)
|
|||
include_directories(AFTER ${DIASDK_INCLUDE_DIRS})
|
||||
endif (WIN32)
|
||||
|
||||
add_dependencies(dxl dxcompiler)
|
||||
include_directories(${LLVM_SOURCE_DIR}/tools/clang/tools)
|
||||
|
||||
add_dependencies(dxl dxclib dxcompiler)
|
||||
|
||||
if(UNIX)
|
||||
set(CLANGXX_LINK_OR_COPY create_symlink)
|
||||
|
|
|
@ -9,176 +9,24 @@
|
|||
// //
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "dxc/Support/Global.h"
|
||||
#include "dxc/Support/Unicode.h"
|
||||
#include "dxc/Support/WinIncludes.h"
|
||||
#include "dxclib/dxc.h"
|
||||
#include <vector>
|
||||
|
||||
#include "dxc/dxcapi.h"
|
||||
#include "dxc/Support/dxcapi.use.h"
|
||||
#include "dxc/Support/HLSLOptions.h"
|
||||
#include "dxc/DxilContainer/DxilContainer.h"
|
||||
#ifdef _WIN32
|
||||
int __cdecl wmain(int argc, const wchar_t **argv_)
|
||||
{
|
||||
std::vector<const wchar_t *> args;
|
||||
for (int i=0;i<argc;i++)
|
||||
args.emplace_back(argv_[i]);
|
||||
args.emplace_back(L"-link");
|
||||
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support//MSFileSystem.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include <dia2.h>
|
||||
#include <intsafe.h>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace llvm::opt;
|
||||
using namespace dxc;
|
||||
using namespace hlsl::options;
|
||||
|
||||
static cl::opt<bool> Help("h", cl::desc("Alias for -help"), cl::Hidden);
|
||||
|
||||
static cl::opt<std::string>
|
||||
InputFiles(cl::Positional, cl::desc("<input .lib files seperate with ;>"),
|
||||
cl::init(""));
|
||||
|
||||
static cl::opt<std::string> EntryName("E", cl::desc("Entry function name"),
|
||||
cl::value_desc("entryfunction"),
|
||||
cl::init("main"));
|
||||
|
||||
static cl::opt<std::string> TargetProfile("T", cl::desc("Target profile"),
|
||||
cl::value_desc("profile"),
|
||||
cl::init("ps_6_1"));
|
||||
|
||||
static cl::opt<std::string> OutputFilename("Fo",
|
||||
cl::desc("Override output filename"),
|
||||
cl::value_desc("filename"));
|
||||
|
||||
static cl::opt<bool> ExportShadersOnly("export-shaders-only", cl::desc("Export entry function only"));
|
||||
|
||||
class DxlContext {
|
||||
|
||||
private:
|
||||
DxcDllSupport &m_dxcSupport;
|
||||
template <typename TInterface>
|
||||
HRESULT CreateInstance(REFCLSID clsid, _Outptr_ TInterface **pResult) {
|
||||
return m_dxcSupport.CreateInstance(clsid, pResult);
|
||||
}
|
||||
|
||||
public:
|
||||
DxlContext(DxcDllSupport &dxcSupport) : m_dxcSupport(dxcSupport) {}
|
||||
|
||||
int Link();
|
||||
};
|
||||
|
||||
int DxlContext::Link() {
|
||||
std::string entry = EntryName;
|
||||
std::string profile = TargetProfile;
|
||||
|
||||
CComPtr<IDxcLinker> pLinker;
|
||||
IFT(CreateInstance(CLSID_DxcLinker, &pLinker));
|
||||
|
||||
StringRef InputFilesRef(InputFiles);
|
||||
SmallVector<StringRef, 2> InputFileList;
|
||||
InputFilesRef.split(InputFileList, ";");
|
||||
|
||||
std::vector<std::wstring> wInputFiles;
|
||||
wInputFiles.reserve(InputFileList.size());
|
||||
std::vector<LPCWSTR> wpInputFiles;
|
||||
wpInputFiles.reserve(InputFileList.size());
|
||||
for (auto &file : InputFileList) {
|
||||
wInputFiles.emplace_back(StringRefUtf16(file.str()));
|
||||
wpInputFiles.emplace_back(wInputFiles.back().c_str());
|
||||
CComPtr<IDxcBlobEncoding> pLib;
|
||||
ReadFileIntoBlob(m_dxcSupport, wInputFiles.back().c_str(), &pLib);
|
||||
IFT(pLinker->RegisterLibrary(wInputFiles.back().c_str(), pLib));
|
||||
}
|
||||
|
||||
CComPtr<IDxcOperationResult> pLinkResult;
|
||||
std::vector<LPCWSTR> args;
|
||||
if (ExportShadersOnly) {
|
||||
args.emplace_back(L"-export-shaders-only");
|
||||
}
|
||||
IFT(pLinker->Link(StringRefUtf16(entry), StringRefUtf16(profile),
|
||||
wpInputFiles.data(), wpInputFiles.size(), args.data(), args.size(),
|
||||
&pLinkResult));
|
||||
|
||||
HRESULT status;
|
||||
IFT(pLinkResult->GetStatus(&status));
|
||||
if (SUCCEEDED(status)) {
|
||||
CComPtr<IDxcBlob> pContainer;
|
||||
IFT(pLinkResult->GetResult(&pContainer));
|
||||
if (pContainer.p != nullptr) {
|
||||
// Infer the output filename if needed.
|
||||
if (OutputFilename.empty()) {
|
||||
OutputFilename = EntryName + ".dxbc";
|
||||
}
|
||||
WriteBlobToFile(pContainer, StringRefUtf16(OutputFilename), DXC_CP_UTF8); // TODO: Support DefaultTextCodePage
|
||||
}
|
||||
} else {
|
||||
CComPtr<IDxcBlobEncoding> pErrors;
|
||||
IFT(pLinkResult->GetErrorBuffer(&pErrors));
|
||||
if (pErrors != nullptr) {
|
||||
printf("Link failed:\n%s",
|
||||
static_cast<char *>(pErrors->GetBufferPointer()));
|
||||
}
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
using namespace hlsl::options;
|
||||
|
||||
int __cdecl main(int argc, _In_reads_z_(argc) char **argv) {
|
||||
const char *pStage = "Operation";
|
||||
int retVal = 0;
|
||||
if (llvm::sys::fs::SetupPerThreadFileSystem())
|
||||
return 1;
|
||||
llvm::sys::fs::AutoCleanupPerThreadFileSystem auto_cleanup_fs;
|
||||
if (FAILED(DxcInitThreadMalloc())) return 1;
|
||||
DxcSetThreadMallocToDefault();
|
||||
try {
|
||||
llvm::sys::fs::MSFileSystem *msfPtr;
|
||||
IFT(CreateMSFileSystemForDisk(&msfPtr));
|
||||
std::unique_ptr<::llvm::sys::fs::MSFileSystem> msf(msfPtr);
|
||||
|
||||
::llvm::sys::fs::AutoPerThreadSystem pts(msf.get());
|
||||
IFTLLVM(pts.error_code());
|
||||
|
||||
pStage = "Argument processing";
|
||||
|
||||
// Parse command line options.
|
||||
cl::ParseCommandLineOptions(argc, argv, "dxil linker\n");
|
||||
|
||||
if (InputFiles == "" || Help) {
|
||||
cl::PrintHelpMessage();
|
||||
return 2;
|
||||
}
|
||||
|
||||
DxcDllSupport dxcSupport;
|
||||
|
||||
// Read options and check errors.
|
||||
dxc::EnsureEnabled(dxcSupport);
|
||||
DxlContext context(dxcSupport);
|
||||
|
||||
pStage = "Linking";
|
||||
retVal = context.Link();
|
||||
} catch (const ::hlsl::Exception &hlslException) {
|
||||
try {
|
||||
const char *msg = hlslException.what();
|
||||
Unicode::acp_char printBuffer[128]; // printBuffer is safe to treat as
|
||||
// UTF-8 because we use ASCII only errors
|
||||
// only
|
||||
if (msg == nullptr || *msg == '\0') {
|
||||
sprintf_s(printBuffer, _countof(printBuffer),
|
||||
"Link failed - error code 0x%08x.", hlslException.hr);
|
||||
msg = printBuffer;
|
||||
}
|
||||
printf("%s\n", msg);
|
||||
} catch (...) {
|
||||
printf("%s failed - unable to retrieve error message.\n", pStage);
|
||||
}
|
||||
|
||||
return 1;
|
||||
} catch (std::bad_alloc &) {
|
||||
printf("%s failed - out of memory.\n", pStage);
|
||||
return 1;
|
||||
} catch (...) {
|
||||
printf("%s failed - unknown error.\n", pStage);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return retVal;
|
||||
return dxc::main(args.size(), args.data());
|
||||
#else
|
||||
int main(int argc, const char **argv_) {
|
||||
std::vector<const wchar_t *> args;
|
||||
for (int i=0;i<argc;i++)
|
||||
args.emplace_back(argv_[i]);
|
||||
args.emplace_back("-link");
|
||||
return dxc::main(args.size(), args.data());
|
||||
#endif // _WIN32
|
||||
}
|
Загрузка…
Ссылка в новой задаче