summaryrefslogtreecommitdiffstats
path: root/source/slang/dxc-support.cpp
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2019-01-16 13:31:42 -0500
committerGitHub <noreply@github.com>2019-01-16 13:31:42 -0500
commit86e11e0e111fab60b9517056ac049bfac6e3bd25 (patch)
treef34a8343fb6a949235f1973dc873814f408987ef /source/slang/dxc-support.cpp
parentc260e6aa3a7dc3e6794442daacde3ae23f029e0b (diff)
Feature/external compiler reporting (#776)
* Added support for converting SlangResult to string in PlatformUtil. * * Added reportExternalCompilerError * Made external compilers use this * Made DiagnosticSink accept UnownedStringSlice * Made emitXXX compiler functions return SlangError * Use smart pointers to handle life of Com interfaces * * Make SlangResult compatible with HRESULT for some common cases. * Make PlatformUtil::appendResult return SlangResult * Compile check SLANG_RESULT. * Add tests for checking diagnostics from external compilers. * * Make external compiler tests only run on windows for now. * Added 'windows' and 'unix' categories * Added categories based on what backends are available. Will make more tests run on linux and handle case where dxcompiler is not available on appveyor. * * Added spSessionCheckPassThroughSupport * Use to determine whats available for categories for tests * Add support for outputting source filename/s when using pass through.
Diffstat (limited to 'source/slang/dxc-support.cpp')
-rw-r--r--source/slang/dxc-support.cpp121
1 files changed, 47 insertions, 74 deletions
diff --git a/source/slang/dxc-support.cpp b/source/slang/dxc-support.cpp
index b00583f10..7fe22191b 100644
--- a/source/slang/dxc-support.cpp
+++ b/source/slang/dxc-support.cpp
@@ -33,7 +33,19 @@ namespace Slang
EntryPointRequest* entryPoint,
TargetRequest* targetReq);
- int emitDXILForEntryPointUsingDXC(
+ static UnownedStringSlice _getSlice(IDxcBlob* blob)
+ {
+ if (blob)
+ {
+ const char* chars = (const char*)blob->GetBufferPointer();
+ size_t len = blob->GetBufferSize();
+ len -= size_t(len > 0 && chars[len - 1] == 0);
+ return UnownedStringSlice(chars, len);
+ }
+ return UnownedStringSlice();
+ }
+
+ SlangResult emitDXILForEntryPointUsingDXC(
EntryPointRequest* entryPoint,
TargetRequest* targetReq,
List<uint8_t>& outCode)
@@ -49,26 +61,20 @@ namespace Slang
auto dxcCreateInstance = (DxcCreateInstanceProc)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Dxc_DxcCreateInstance, &compileRequest->mSink);
if (!dxcCreateInstance)
{
- return 1;
+ return SLANG_FAIL;
}
- IDxcCompiler* dxcCompiler = nullptr;
- if (FAILED(dxcCreateInstance(
+ ComPtr<IDxcCompiler> dxcCompiler;
+ SLANG_RETURN_ON_FAIL(dxcCreateInstance(
CLSID_DxcCompiler,
__uuidof(dxcCompiler),
- (LPVOID*) &dxcCompiler)))
- {
- return 1;
- }
+ (LPVOID*)dxcCompiler.writeRef()));
- IDxcLibrary* dxcLibrary = nullptr;
- if (FAILED(dxcCreateInstance(
+ ComPtr<IDxcLibrary> dxcLibrary;
+ SLANG_RETURN_ON_FAIL(dxcCreateInstance(
CLSID_DxcLibrary,
__uuidof(dxcLibrary),
- (LPVOID*) &dxcLibrary)))
- {
- return 1;
- }
+ (LPVOID*)dxcLibrary.writeRef()));
// Now let's go ahead and generate HLSL for the entry
// point, since we'll need that to feed into dxc.
@@ -78,15 +84,12 @@ namespace Slang
// Wrap the
// Create blob from the string
- IDxcBlobEncoding* dxcSourceBlob = nullptr;
- if (FAILED(dxcLibrary->CreateBlobWithEncodingFromPinned(
+ ComPtr<IDxcBlobEncoding> dxcSourceBlob;
+ SLANG_RETURN_ON_FAIL(dxcLibrary->CreateBlobWithEncodingFromPinned(
(LPBYTE)hlslCode.Buffer(),
(UINT32)hlslCode.Length(),
0,
- &dxcSourceBlob)))
- {
- return 1;
- }
+ dxcSourceBlob.writeRef()));
WCHAR const* args[16];
UINT32 argCount = 0;
@@ -158,9 +161,11 @@ namespace Slang
args[argCount++] = L"-enable-16bit-types";
}
- IDxcOperationResult* dxcResult = nullptr;
- if (FAILED(dxcCompiler->Compile(dxcSourceBlob,
- L"slang",
+ const String sourcePath = calcTranslationUnitSourcePath(entryPoint->getTranslationUnit());
+
+ ComPtr<IDxcOperationResult> dxcResult;
+ SLANG_RETURN_ON_FAIL(dxcCompiler->Compile(dxcSourceBlob,
+ sourcePath.ToWString().begin(),
profile.GetStage() == Stage::Unknown ? L"" : wideEntryPointName.begin(),
wideProfileName.begin(),
args,
@@ -168,74 +173,44 @@ namespace Slang
nullptr, // `#define`s
0, // `#define` count
nullptr, // `#include` handler
- &dxcResult)))
- {
- return 1;
- }
+ dxcResult.writeRef()));
// Retrieve result.
HRESULT resultCode = S_OK;
- if (FAILED(dxcResult->GetStatus(&resultCode)))
- {
- // This indicates that we failed to retrieve the reuslt...
- return 1;
- }
-
+ SLANG_RETURN_ON_FAIL(dxcResult->GetStatus(&resultCode));
+
// Note: it seems like the dxcompiler interface
// doesn't support querying diagnostic output
// *unless* the compile failed (no way to get
// warnings out!?).
// Verify compile result
- if (FAILED(resultCode))
+ if (SLANG_FAILED(resultCode))
{
// Compilation failed.
+ // Try to read any diagnostic output.
+ ComPtr<IDxcBlobEncoding> dxcErrorBlob;
+ SLANG_RETURN_ON_FAIL(dxcResult->GetErrorBuffer(dxcErrorBlob.writeRef()));
+ // Note: the error blob returned by dxc doesn't always seem
+ // to be nul-terminated, so we should be careful and turn it
+ // into a string for safety.
+ //
- // Try to read any diagnostic output.
- IDxcBlobEncoding* dxcErrorBlob = nullptr;
- if (!FAILED(dxcResult->GetErrorBuffer(&dxcErrorBlob)))
- {
- // Note: the error blob returned by dxc doesn't always seem
- // to be nul-terminated, so we should be careful and turn it
- // into a string for safety.
- //
- // TODO: Alternatively, `diagnoseRaw()` should accept an
- // `UnownedStringSlice` instead of a `const char*`.
- //
- auto errorBegin = (char const*) dxcErrorBlob->GetBufferPointer();
- auto errorEnd = errorBegin + dxcErrorBlob->GetBufferSize();
- String errorString = UnownedStringSlice(errorBegin, errorEnd);
-
- compileRequest->mSink.diagnoseRaw(
- FAILED(resultCode) ? Severity::Error : Severity::Warning,
- errorString.Buffer());
- dxcErrorBlob->Release();
- }
-
- return 1;
+ reportExternalCompileError("dxc", resultCode, _getSlice(dxcErrorBlob), &entryPoint->compileRequest->mSink);
+ return resultCode;
}
// Okay, the compile supposedly succeeded, so we
// just need to grab the buffer with the output DXIL.
- IDxcBlob* dxcResultBlob = nullptr;
- if (FAILED(dxcResult->GetResult(&dxcResultBlob)))
- {
- return 1;
- }
-
+ ComPtr<IDxcBlob> dxcResultBlob;
+ SLANG_RETURN_ON_FAIL(dxcResult->GetResult(dxcResultBlob.writeRef()));
+
outCode.AddRange(
(uint8_t const*)dxcResultBlob->GetBufferPointer(),
(int) dxcResultBlob->GetBufferSize());
- // Clean up after ourselves.
-
- if(dxcResultBlob) dxcResultBlob ->Release();
- if(dxcResult) dxcResult ->Release();
- if(dxcLibrary) dxcLibrary ->Release();
- if(dxcCompiler) dxcCompiler ->Release();
-
- return 0;
+ return SLANG_OK;
}
SlangResult dissassembleDXILUsingDXC(
@@ -270,10 +245,8 @@ namespace Slang
ComPtr<IDxcBlobEncoding> dxcResultBlob;
SLANG_RETURN_ON_FAIL(dxcCompiler->Disassemble(dxcSourceBlob, dxcResultBlob.writeRef()));
- char const* codeBegin = (char const*)dxcResultBlob->GetBufferPointer();
- char const* codeEnd = codeBegin + dxcResultBlob->GetBufferSize() - 1;
- stringOut = String(codeBegin, codeEnd);
-
+ stringOut = _getSlice(dxcResultBlob);
+
return SLANG_OK;
}