diff options
| author | cheneym2 <acheney@nvidia.com> | 2024-08-05 15:37:46 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-08-05 15:37:46 -0400 |
| commit | d72f9f6f72a7a74d7466a1e301e1853fea5daa25 (patch) | |
| tree | 4ae77e2dd622779b64d063d1f50fc7af8c13a94a /source/compiler-core | |
| parent | d63f5e20f1edf7c51ca5c456baceb9eb9a84c95b (diff) | |
Initial support for precompiled DXIL in slang-modules (#4755)
* Add embedded precompiled binary IR ops
Add IR operations to embed precompiled DXIL or SPIR-V blobs
into IR. Adds a BlobLit literal that is mostly identical to
StringLit except for its inability to be displayed, e.g.
in dumped IR. In the future, the blob might be dumped as
hexadecimal, but for now it is summarized as "<binary blob>".
* EmbeddedDXIL and SPIR-V options
The options, '-embed-dxil' and '-embed-spirv' in slangc, will
cause a target dxil or spirv to be compiled and stored in the
translation unit IR when written to a slang-module. Subsequent
changes actually implement the options.
* Per-translation unit DXIL precompilation
When -embed-dxil is specified, perform a precompilation to DXIL of
each TU, linked only with stdlib. Embed the resulting DXIL for
the TU in a IR op. Being part of IR, the precompiled DXIL can be
serialized to disk in a slang-module.
Upon loading slang-modules, the new IR op will be searched for and
the precompiled DXIL blob is saved with the loaded Module. During
linking, if all the Modules have precompiled blobs they will be
sent to the downstream compile commands as libraries instead of
source, skipping the downstream compilation, using DXC only for
linking.
Fixes Issue #4580
* Remove placeholder embedded SPIRV support
Code was added only to sketch out how other precompiled bins
will be supported.
* Remove the rest of the SPIRV placeholder support
* Fix warnings, test error on non-windows
* Remove lib_6_6 hack, add dxil_lib capability
* Allocate blob value from irmodule memarena
* Add null check after memarena allocation
* Restore the request->e2erequest code path for generatewholeprogram
* Update capability handling, move EmbedDXIL enum to end to preserve abi
* Remove lib_6_6 hack
* Move ICompileRequest functions to end
Diffstat (limited to 'source/compiler-core')
| -rw-r--r-- | source/compiler-core/slang-dxc-compiler.cpp | 112 |
1 files changed, 65 insertions, 47 deletions
diff --git a/source/compiler-core/slang-dxc-compiler.cpp b/source/compiler-core/slang-dxc-compiler.cpp index aa005d47f..0ecfd0b30 100644 --- a/source/compiler-core/slang-dxc-compiler.cpp +++ b/source/compiler-core/slang-dxc-compiler.cpp @@ -381,18 +381,24 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& inOptions, IArt CompileOptions options = getCompatibleVersion(&inOptions); - // This compiler can only deal with a single artifact - if (options.sourceArtifacts.count != 1) + // This compiler can only deal at most, a single source code artifact + // Should be okay to link together multiple libraries without any source artifacts (assuming that means source code) + if (options.sourceArtifacts.count > 1) { return SLANG_FAIL; } - IArtifact* sourceArtifact = options.sourceArtifacts[0]; + bool hasSource = options.sourceArtifacts.count > 0; - if (options.sourceLanguage != SLANG_SOURCE_LANGUAGE_HLSL || options.targetType != SLANG_DXIL) + IArtifact* sourceArtifact = hasSource ? options.sourceArtifacts[0] : nullptr; + + if (hasSource) { - SLANG_ASSERT(!"Can only compile HLSL to DXIL"); - return SLANG_FAIL; + if (options.sourceLanguage != SLANG_SOURCE_LANGUAGE_HLSL || options.targetType != SLANG_DXIL) + { + SLANG_ASSERT(!"Can only compile HLSL to DXIL"); + return SLANG_FAIL; + } } // Find all of the libraries @@ -416,16 +422,19 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& inOptions, IArt ComPtr<IDxcLibrary> dxcLibrary; SLANG_RETURN_ON_FAIL(m_createInstance(CLSID_DxcLibrary, __uuidof(dxcLibrary), (LPVOID*)dxcLibrary.writeRef())); + ComPtr<IDxcBlobEncoding> dxcSourceBlob = nullptr; ComPtr<ISlangBlob> sourceBlob; - SLANG_RETURN_ON_FAIL(sourceArtifact->loadBlob(ArtifactKeep::Yes, sourceBlob.writeRef())); + if (hasSource) + { + SLANG_RETURN_ON_FAIL(sourceArtifact->loadBlob(ArtifactKeep::Yes, sourceBlob.writeRef())); - // Create blob from the string - ComPtr<IDxcBlobEncoding> dxcSourceBlob; - SLANG_RETURN_ON_FAIL(dxcLibrary->CreateBlobWithEncodingFromPinned( - (LPBYTE)sourceBlob->getBufferPointer(), - (UINT32)sourceBlob->getBufferSize(), - 0, - dxcSourceBlob.writeRef())); + // Create blob from the string + SLANG_RETURN_ON_FAIL(dxcLibrary->CreateBlobWithEncodingFromPinned( + (LPBYTE)sourceBlob->getBufferPointer(), + (UINT32)sourceBlob->getBufferSize(), + 0, + dxcSourceBlob.writeRef())); + } List<const WCHAR*> args; @@ -508,7 +517,7 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& inOptions, IArt String profileName = asString(options.profileName); // If we are going to link we have to compile in the lib profile style - if (libraries.getCount()) + if (libraries.getCount() && hasSource) { if (!profileName.startsWith("lib")) { @@ -561,28 +570,33 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& inOptions, IArt } #endif - String sourcePath = ArtifactUtil::findPath(sourceArtifact); - OSString wideSourcePath = sourcePath.toWString(); + String sourcePath; + ComPtr<IDxcBlob> dxcResultBlob = nullptr; + auto diagnostics = ArtifactDiagnostics::create(); + ComPtr<IDxcOperationResult> dxcOperationResult = nullptr; + if (hasSource) + { + sourcePath = ArtifactUtil::findPath(sourceArtifact); + OSString wideSourcePath = sourcePath.toWString(); - DxcIncludeHandler includeHandler(&searchDirectories, options.fileSystemExt, options.sourceManager); + DxcIncludeHandler includeHandler(&searchDirectories, options.fileSystemExt, options.sourceManager); - ComPtr<IDxcOperationResult> dxcOperationResult; - SLANG_RETURN_ON_FAIL(dxcCompiler->Compile(dxcSourceBlob, - wideSourcePath.begin(), - wideEntryPointName.begin(), - wideProfileName.begin(), - args.getBuffer(), - UINT32(args.getCount()), - nullptr, // `#define`s - 0, // `#define` count - &includeHandler, // `#include` handler - dxcOperationResult.writeRef())); + SLANG_RETURN_ON_FAIL(dxcCompiler->Compile(dxcSourceBlob, + wideSourcePath.begin(), + wideEntryPointName.begin(), + wideProfileName.begin(), + args.getBuffer(), + UINT32(args.getCount()), + nullptr, // `#define`s + 0, // `#define` count + &includeHandler, // `#include` handler + dxcOperationResult.writeRef())); - auto diagnostics = ArtifactDiagnostics::create(); - - ComPtr<IDxcBlob> dxcResultBlob; + SLANG_RETURN_ON_FAIL(_handleOperationResult(dxcOperationResult, diagnostics, dxcResultBlob)); - SLANG_RETURN_ON_FAIL(_handleOperationResult(dxcOperationResult, diagnostics, dxcResultBlob)); + ComPtr<IDxcBlobEncoding> dxcResultBlob2 = nullptr; + dxcCompiler->Disassemble(dxcResultBlob, dxcResultBlob2.writeRef()); + } // If we have libraries then we need to link... if (libraries.getCount()) @@ -604,26 +618,30 @@ SlangResult DXCDownstreamCompiler::compile(const CompileOptions& inOptions, IArt libraryNames.add(String(_addName(library, pool)).toWString()); } - // Add the compiled blob name - String name; - if (options.modulePath.count) - { - name = Path::getFileNameWithoutExt(asString(options.modulePath)); - } - else if (sourcePath.getLength()) + if (hasSource) { - name = Path::getFileNameWithoutExt(sourcePath); - } + // Add the compiled blob name + String name; + if (options.modulePath.count) + { + name = Path::getFileNameWithoutExt(asString(options.modulePath)); + } + else if (sourcePath.getLength()) + { + name = Path::getFileNameWithoutExt(sourcePath); + } - // Add the blob with name - { - auto blob = (ISlangBlob*)dxcResultBlob.get(); - libraryBlobs.add(ComPtr<ISlangBlob>(blob)); - libraryNames.add(String(_addName(name.getUnownedSlice(), pool)).toWString()); + // Add the blob with name + { + auto blob = (ISlangBlob*)dxcResultBlob.get(); + libraryBlobs.add(ComPtr<ISlangBlob>(blob)); + libraryNames.add(String(_addName(name.getUnownedSlice(), pool)).toWString()); + } } const Index librariesCount = libraryNames.getCount(); SLANG_ASSERT(libraryBlobs.getCount() == librariesCount); + SLANG_ASSERT(libraryNames.getCount() == librariesCount); List<const wchar_t*> linkLibraryNames; |
