diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2019-01-16 13:31:42 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-16 13:31:42 -0500 |
| commit | 86e11e0e111fab60b9517056ac049bfac6e3bd25 (patch) | |
| tree | f34a8343fb6a949235f1973dc873814f408987ef /source/slang/dxc-support.cpp | |
| parent | c260e6aa3a7dc3e6794442daacde3ae23f029e0b (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.cpp | 121 |
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; } |
