summaryrefslogtreecommitdiffstats
path: root/source/slang
diff options
context:
space:
mode:
authorjsmall-nvidia <jsmall@nvidia.com>2021-05-14 17:50:00 -0400
committerGitHub <noreply@github.com>2021-05-14 17:50:00 -0400
commitd4316c88457a32f1169b2d7d82053ccbc05fa7ed (patch)
treecbc87350b9ef2f5be31ebc20783e08b895767779 /source/slang
parent79d106fac18f5792fcac448a0b037aa834fa6042 (diff)
FXC as DownstreamCompiler (#1844)
* #include an absolute path didn't work - because paths were taken to always be relative. * WIP Fxc as downstream compiler. * First pass FXC downstream compiler working. * GCC compile fix. * Fix FXC parsing issue. * Special case filesystem access. * Use StringUtil getSlice. * Fix isses with not emitting source for FXC. * Small fixes for DXBC handling.
Diffstat (limited to 'source/slang')
-rw-r--r--source/slang/slang-check.cpp2
-rwxr-xr-xsource/slang/slang-compiler.cpp598
-rwxr-xr-xsource/slang/slang-compiler.h5
-rw-r--r--source/slang/slang-include-system.cpp158
-rw-r--r--source/slang/slang-include-system.h62
-rw-r--r--source/slang/slang-preprocessor.h3
6 files changed, 206 insertions, 622 deletions
diff --git a/source/slang/slang-check.cpp b/source/slang/slang-check.cpp
index 600578297..a5701aa90 100644
--- a/source/slang/slang-check.cpp
+++ b/source/slang/slang-check.cpp
@@ -70,8 +70,6 @@ namespace Slang
{
case FuncType::Glslang_Compile_1_0: return { "glslang_compile", PassThroughMode::Glslang} ;
case FuncType::Glslang_Compile_1_1: return { "glslang_compile_1_1", PassThroughMode::Glslang} ;
- case FuncType::Fxc_D3DCompile: return { "D3DCompile", PassThroughMode::Fxc};
- case FuncType::Fxc_D3DDisassemble: return { "D3DDisassemble", PassThroughMode::Fxc };
case FuncType::Dxc_DxcCreateInstance: return { "DxcCreateInstance", PassThroughMode::Dxc };
default: return { nullptr, PassThroughMode::None };
}
diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp
index 736250219..22e5bb61e 100755
--- a/source/slang/slang-compiler.cpp
+++ b/source/slang/slang-compiler.cpp
@@ -35,18 +35,12 @@
#undef WIN32_LEAN_AND_MEAN
#undef NOMINMAX
#include <d3dcompiler.h>
- #ifndef SLANG_ENABLE_DXBC_SUPPORT
- #define SLANG_ENABLE_DXBC_SUPPORT 1
- #endif
#ifndef SLANG_ENABLE_DXIL_SUPPORT
#define SLANG_ENABLE_DXIL_SUPPORT 1
#endif
#endif
//
-// Otherwise, don't enable DXBC/DXIL by default:
-#ifndef SLANG_ENABLE_DXBC_SUPPORT
- #define SLANG_ENABLE_DXBC_SUPPORT 0
-#endif
+// Otherwise, don't enable DXIL by default:
#ifndef SLANG_ENABLE_DXIL_SUPPORT
#define SLANG_ENABLE_DXIL_SUPPORT 0
#endif
@@ -415,9 +409,6 @@ namespace Slang
#if !SLANG_ENABLE_DXIL_SUPPORT
case PassThroughMode::Dxc: return SLANG_E_NOT_IMPLEMENTED;
#endif
-#if !SLANG_ENABLE_DXBC_SUPPORT
- case PassThroughMode::Fxc: return SLANG_E_NOT_IMPLEMENTED;
-#endif
#if !SLANG_ENABLE_GLSLANG_SUPPORT
case PassThroughMode::Glslang: return SLANG_E_NOT_IMPLEMENTED;
#endif
@@ -522,7 +513,8 @@ namespace Slang
bool isPassThroughEnabled(
EndToEndCompileRequest* endToEndReq)
- { // If there isn't an end-to-end compile going on,
+ {
+ // If there isn't an end-to-end compile going on,
// there can be no pass-through.
//
if (!endToEndReq) return false;
@@ -556,23 +548,11 @@ namespace Slang
return nullptr;
}
- static void _appendEscapedPath(const UnownedStringSlice& path, StringBuilder& outBuilder)
- {
- for (auto c : path)
- {
- // TODO(JS): Probably want more sophisticated handling...
- if (c == '\\')
- {
- outBuilder.appendChar(c);
- }
- outBuilder.appendChar(c);
- }
- }
-
static void _appendCodeWithPath(const UnownedStringSlice& filePath, const UnownedStringSlice& fileContent, StringBuilder& outCodeBuilder)
{
outCodeBuilder << "#line 1 \"";
- _appendEscapedPath(filePath, outCodeBuilder);
+ auto handler = StringEscapeUtil::getHandler(StringEscapeUtil::Style::Cpp);
+ handler->appendEscaped(filePath, outCodeBuilder);
outCodeBuilder << "\"\n";
outCodeBuilder << fileContent << "\n";
}
@@ -883,276 +863,6 @@ namespace Slang
return *entryPointIndices.begin();
}
-#if SLANG_ENABLE_DXBC_SUPPORT
-
- static UnownedStringSlice _getSlice(ID3DBlob* 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();
- }
-
- struct FxcIncludeHandler : ID3DInclude
- {
-
- STDMETHOD(Open)(D3D_INCLUDE_TYPE includeType, LPCSTR fileName, LPCVOID parentData, LPCVOID* outData, UINT* outSize) override
- {
- SLANG_UNUSED(includeType);
- // NOTE! The pParentData means the *text* of any previous include.
- // In order to work out what *path* that came from, we need to seach which source file it came from, and
- // use it's path
-
- // Assume the root pathInfo initially
- PathInfo includedFromPathInfo = m_rootPathInfo;
-
- // Lets try and find the parent source if there is any
- if (parentData)
- {
- SourceFile* foundSourceFile = m_system.getSourceManager()->findSourceFileByContentRecursively((const char*)parentData);
- if (foundSourceFile)
- {
- includedFromPathInfo = foundSourceFile->getPathInfo();
- }
- }
-
- String path(fileName);
- PathInfo pathInfo;
- ComPtr<ISlangBlob> blob;
-
- SLANG_RETURN_ON_FAIL(m_system.findAndLoadFile(path, includedFromPathInfo.foundPath, pathInfo, blob));
-
- // Return the data
- *outData = blob->getBufferPointer();
- *outSize = (UINT) blob->getBufferSize();
-
- return S_OK;
- }
-
- STDMETHOD(Close)(LPCVOID pData) override
- {
- SLANG_UNUSED(pData);
- return S_OK;
- }
- FxcIncludeHandler(SearchDirectoryList* searchDirectories, ISlangFileSystemExt* fileSystemExt, SourceManager* sourceManager):
- m_system(searchDirectories, fileSystemExt, sourceManager)
- {
- }
-
- PathInfo m_rootPathInfo;
- IncludeSystem m_system;
- };
-
- SlangResult emitDXBytecodeForEntryPoint(
- ComponentType* program,
- BackEndCompileRequest* compileRequest,
- Int entryPointIndex,
- TargetRequest* targetReq,
- EndToEndCompileRequest* endToEndReq,
- List<uint8_t>& byteCodeOut)
- {
- byteCodeOut.clear();
-
- auto session = compileRequest->getSession();
- auto sink = compileRequest->getSink();
-
- auto compileFunc = (pD3DCompile)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Fxc_D3DCompile, sink);
- if (!compileFunc)
- {
- return SLANG_FAIL;
- }
-
- SourceResult source;
- SLANG_RETURN_ON_FAIL(emitEntryPointSource(compileRequest, entryPointIndex, targetReq, CodeGenTarget::HLSL, endToEndReq, source));
-
- const auto& hlslCode = source.source;
- maybeDumpIntermediate(compileRequest, hlslCode.getBuffer(), CodeGenTarget::HLSL);
-
- auto entryPoint = program->getEntryPoint(entryPointIndex);
- auto profile = getEffectiveProfile(entryPoint, targetReq);
-
- auto linkage = compileRequest->getLinkage();
-
- // If we have been invoked in a pass-through mode, then we need to make sure
- // that the downstream compiler sees whatever options were passed to Slang
- // via the command line or API.
- //
- // TODO: more pieces of information should be added here as needed.
- //
- List<D3D_SHADER_MACRO> dxMacrosStorage;
- D3D_SHADER_MACRO const* dxMacros = nullptr;
-
- FxcIncludeHandler fxcIncludeHandlerStorage(&linkage->searchDirectories, linkage->getFileSystemExt(), sink->getSourceManager());
- FxcIncludeHandler* fxcIncludeHandler = &fxcIncludeHandlerStorage;
-
- if(auto translationUnit = findPassThroughTranslationUnit(endToEndReq, entryPointIndex))
- {
- for( auto& define : translationUnit->compileRequest->preprocessorDefinitions )
- {
- D3D_SHADER_MACRO dxMacro;
- dxMacro.Name = define.Key.getBuffer();
- dxMacro.Definition = define.Value.getBuffer();
- dxMacrosStorage.add(dxMacro);
- }
- for( auto& define : translationUnit->preprocessorDefinitions )
- {
- D3D_SHADER_MACRO dxMacro;
- dxMacro.Name = define.Key.getBuffer();
- dxMacro.Definition = define.Value.getBuffer();
- dxMacrosStorage.add(dxMacro);
- }
- D3D_SHADER_MACRO nullTerminator = { 0, 0 };
- dxMacrosStorage.add(nullTerminator);
-
- dxMacros = dxMacrosStorage.getBuffer();
-
- fxcIncludeHandler = &fxcIncludeHandlerStorage;
- fxcIncludeHandlerStorage.m_rootPathInfo = translationUnit->m_sourceFiles[0]->getPathInfo();
- }
-
- DWORD flags = 0;
-
- switch( targetReq->getFloatingPointMode() )
- {
- default:
- break;
-
- case FloatingPointMode::Precise:
- flags |= D3DCOMPILE_IEEE_STRICTNESS;
- break;
- }
-
- // Some of the `D3DCOMPILE_*` constants aren't available in all
- // versions of `d3dcompiler.h`, so we define them here just in case
- #ifndef D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES
- #define D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES (1 << 20)
- #endif
-
- #ifndef D3DCOMPILE_ALL_RESOURCES_BOUND
- #define D3DCOMPILE_ALL_RESOURCES_BOUND (1 << 21)
- #endif
-
- flags |= D3DCOMPILE_ENABLE_STRICTNESS;
- flags |= D3DCOMPILE_ENABLE_UNBOUNDED_DESCRIPTOR_TABLES;
-
- switch( linkage->optimizationLevel )
- {
- default:
- break;
-
- case OptimizationLevel::None: flags |= D3DCOMPILE_OPTIMIZATION_LEVEL0; break;
- case OptimizationLevel::Default: flags |= D3DCOMPILE_OPTIMIZATION_LEVEL1; break;
- case OptimizationLevel::High: flags |= D3DCOMPILE_OPTIMIZATION_LEVEL2; break;
- case OptimizationLevel::Maximal: flags |= D3DCOMPILE_OPTIMIZATION_LEVEL3; break;
- }
-
- switch( linkage->debugInfoLevel )
- {
- case DebugInfoLevel::None:
- break;
-
- default:
- flags |= D3DCOMPILE_DEBUG;
- break;
- }
-
- const String sourcePath = calcSourcePathForEntryPoint(endToEndReq, entryPointIndex);
-
- ComPtr<ID3DBlob> codeBlob;
- ComPtr<ID3DBlob> diagnosticsBlob;
- HRESULT hr = compileFunc(
- hlslCode.begin(),
- hlslCode.getLength(),
- sourcePath.getBuffer(),
- dxMacros,
- fxcIncludeHandler,
- getText(entryPoint->getName()).begin(),
- GetHLSLProfileName(profile).getBuffer(),
- flags,
- 0, // unused: effect flags
- codeBlob.writeRef(),
- diagnosticsBlob.writeRef());
-
- if (codeBlob && SLANG_SUCCEEDED(hr))
- {
- byteCodeOut.addRange((uint8_t const*)codeBlob->GetBufferPointer(), (int)codeBlob->GetBufferSize());
- }
-
- if (FAILED(hr))
- {
- reportExternalCompileError("fxc", hr, _getSlice(diagnosticsBlob), sink);
- }
-
- return hr;
- }
-
- SlangResult dissassembleDXBC(
- BackEndCompileRequest* compileRequest,
- void const* data,
- size_t size,
- String& assemOut)
- {
- assemOut = String();
-
- auto session = compileRequest->getSession();
- auto sink = compileRequest->getSink();
-
- auto disassembleFunc = (pD3DDisassemble)session->getSharedLibraryFunc(Session::SharedLibraryFuncType::Fxc_D3DDisassemble, sink);
- if (!disassembleFunc)
- {
- return SLANG_E_NOT_FOUND;
- }
-
- if (!data || !size)
- {
- return SLANG_FAIL;
- }
-
- ComPtr<ID3DBlob> codeBlob;
- SlangResult res = disassembleFunc(data, size, 0, nullptr, codeBlob.writeRef());
-
- if (codeBlob)
- {
- assemOut = _getSlice(codeBlob);
- }
- if (FAILED(res))
- {
- // TODO(tfoley): need to figure out what to diagnose here...
- reportExternalCompileError("fxc", res, UnownedStringSlice(), sink);
- }
-
- return res;
- }
-
- SlangResult emitDXBytecodeAssemblyForEntryPoint(
- ComponentType* program,
- BackEndCompileRequest* compileRequest,
- Int entryPointIndex,
- TargetRequest* targetReq,
- EndToEndCompileRequest* endToEndReq,
- String& assemOut)
- {
-
- List<uint8_t> dxbc;
- SLANG_RETURN_ON_FAIL(emitDXBytecodeForEntryPoint(
- program,
- compileRequest,
- entryPointIndex,
- targetReq,
- endToEndReq,
- dxbc));
- if (!dxbc.getCount())
- {
- return SLANG_FAIL;
- }
- return dissassembleDXBC(compileRequest, dxbc.getBuffer(), dxbc.getCount(), assemOut);
- }
-#endif
-
#if SLANG_ENABLE_DXIL_SUPPORT
// Implementations in `dxc-support.cpp`
@@ -1262,10 +972,42 @@ SlangResult dissassembleDXILUsingDXC(
return SLANG_OK;
}
+ // True if the downstream compiler will need to emit source to make compilation work
+ // That it may be desirable to not emit source if it is available as is on the file system
+ // and the downstream compiler accesses files through the file system.
+ static bool _isEmittedSourceRequired(DownstreamCompiler* compiler, TranslationUnitRequest* translationUnit)
+ {
+ // We only bother if it's a file based compiler.
+ if (compiler->isFileBased())
+ {
+ // It can only have *one* source file as otherwise we have to combine to make a new source file anyway
+ const auto& sourceFiles = translationUnit->getSourceFiles();
+
+ // The *assumption* here is that if it's file based that assuming it can find the file with the same contents
+ // it can compile directly without having to save off as a file
+ if (sourceFiles.getCount() == 1)
+ {
+ const SourceFile* sourceFile = sourceFiles[0];
+ // We need the path to be found and set
+ //
+ // NOTE! That the downstream compiler can determine if the path and contents match such that it can be used
+ // without writing file
+ const PathInfo& pathInfo = sourceFile->getPathInfo();
+ if ((pathInfo.type == PathInfo::Type::FoundPath || pathInfo.type == PathInfo::Type::Normal) && pathInfo.foundPath.getLength())
+ {
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
SlangResult emitWithDownstreamForEntryPoints(
+ ComponentType* program,
BackEndCompileRequest* slangRequest,
const List<Int>& entryPointIndices,
TargetRequest* targetReq,
+ CodeGenTarget target,
EndToEndCompileRequest* endToEndReq,
RefPtr<DownstreamCompileResult>& outResult)
{
@@ -1275,8 +1017,6 @@ SlangResult dissassembleDXILUsingDXC(
auto session = slangRequest->getSession();
- const String originalSourcePath = calcSourcePathForEntryPoints(endToEndReq, entryPointIndices);
-
CodeGenTarget sourceTarget = CodeGenTarget::None;
SourceLanguage sourceLanguage = SourceLanguage::Unknown;
@@ -1285,7 +1025,6 @@ SlangResult dissassembleDXILUsingDXC(
// If we are not in pass through, lookup the default compiler for the emitted source type
if (downstreamCompiler == PassThroughMode::None)
{
- auto target = targetReq->getTarget();
switch (target)
{
case CodeGenTarget::PTX:
@@ -1302,26 +1041,34 @@ SlangResult dissassembleDXILUsingDXC(
sourceLanguage = SourceLanguage::CPP;
break;
}
+ case CodeGenTarget::DXBytecode:
+ {
+ sourceTarget = CodeGenTarget::HLSL;
+ sourceLanguage = SourceLanguage::HLSL;
+ downstreamCompiler = PassThroughMode::Fxc;
+ break;
+ }
default: break;
}
- downstreamCompiler = PassThroughMode(session->getDefaultDownstreamCompiler(SlangSourceLanguage(sourceLanguage)));
+ // Try looking up based on the language if one isn't set
+ if (downstreamCompiler == PassThroughMode::None)
+ {
+ downstreamCompiler = PassThroughMode(session->getDefaultDownstreamCompiler(SlangSourceLanguage(sourceLanguage)));
+ }
}
+
+ // We should have a downstream compiler set at this point
+ SLANG_ASSERT(downstreamCompiler != PassThroughMode::None);
+
// Get the required downstream compiler
DownstreamCompiler* compiler = session->getOrLoadDownstreamCompiler(downstreamCompiler, sink);
if (!compiler)
{
auto compilerName = TypeTextUtil::getPassThroughAsHumanText((SlangPassThrough)downstreamCompiler);
- if (downstreamCompiler != PassThroughMode::None)
- {
- sink->diagnose(SourceLoc(), Diagnostics::passThroughCompilerNotFound, compilerName);
- }
- else
- {
- sink->diagnose(SourceLoc(), Diagnostics::cppCompilerNotFound, compilerName);
- }
+ sink->diagnose(SourceLoc(), Diagnostics::passThroughCompilerNotFound, compilerName);
return SLANG_FAIL;
}
@@ -1383,27 +1130,40 @@ SlangResult dissassembleDXILUsingDXC(
// We are just passing thru, so it's whatever it originally was
sourceLanguage = translationUnit->sourceLanguage;
- sourceTarget = CodeGenTarget(DownstreamCompiler::getCompileTarget(SlangSourceLanguage(sourceLanguage)));
- // Special case if we have a single file, so that we pass the path, and the contents
- const auto& sourceFiles = translationUnit->getSourceFiles();
- if (sourceFiles.getCount() == 1)
+ // TODO(JS): This seems like a bit of a hack
+ // That if a pass-through is being performed and the source language is Slang
+ // no downstream compiler knows how to deal with that, so probably means 'HLSL'
+ if (sourceLanguage == SourceLanguage::Slang)
{
- const SourceFile* sourceFile = sourceFiles[0];
- const PathInfo& pathInfo = sourceFile->getPathInfo();
- if (pathInfo.type == PathInfo::Type::FoundPath || pathInfo.type == PathInfo::Type::Normal)
- {
- options.sourceContentsPath = pathInfo.foundPath;
- }
- options.sourceContents = sourceFile->getContent();
+ sourceLanguage = SourceLanguage::HLSL;
}
- else
+
+ sourceTarget = CodeGenTarget(DownstreamCompiler::getCompileTarget(SlangSourceLanguage(sourceLanguage)));
+
+ // If emitted source is required, emit and set the path
+ if (_isEmittedSourceRequired(compiler, translationUnit))
{
+ // If it's not file based we can set an appropriate path name, and it doesn't matter if it doesn't
+ // exist on the file system
+ const String originalSourcePath = calcSourcePathForEntryPoints(endToEndReq, entryPointIndices);
+ options.sourceContentsPath = originalSourcePath;
+
SourceResult source;
SLANG_RETURN_ON_FAIL(emitEntryPointsSource(slangRequest, entryPointIndices, targetReq, sourceTarget, endToEndReq, source));
-
options.sourceContents = source.source;
}
+ else
+ {
+ // Special case if we have a single file, so that we pass the path, and the contents
+ const auto& sourceFiles = translationUnit->getSourceFiles();
+ SLANG_ASSERT(sourceFiles.getCount() == 1);
+
+ const SourceFile* sourceFile = sourceFiles[0];
+
+ options.sourceContentsPath = sourceFile->getPathInfo().foundPath;
+ options.sourceContents = sourceFile->getContent();
+ }
}
else
{
@@ -1435,36 +1195,44 @@ SlangResult dissassembleDXILUsingDXC(
maybeDumpIntermediate(slangRequest, options.sourceContents.getBuffer(), sourceTarget);
}
+ // Set the file sytem and source manager, as *may* be used by downstream compiler
+ options.fileSystemExt = slangRequest->getFileSystemExt();
+ options.sourceManager = slangRequest->getSourceManager();
+
// Set the source type
options.sourceLanguage = SlangSourceLanguage(sourceLanguage);
-
+
// Disable exceptions and security checks
options.flags &= ~(CompileOptions::Flag::EnableExceptionHandling | CompileOptions::Flag::EnableSecurityChecks);
- // Set what kind of target we should build
- switch (targetReq->getTarget())
+ if (downstreamCompiler == PassThroughMode::Fxc)
{
- case CodeGenTarget::HostCallable:
- case CodeGenTarget::SharedLibrary:
- {
- options.targetType = DownstreamCompiler::TargetType::SharedLibrary;
- break;
- }
- case CodeGenTarget::Executable:
- {
- options.targetType = DownstreamCompiler::TargetType::Executable;
- break;
- }
- case CodeGenTarget::PTX:
+ if (entryPointIndices.getCount() != 1)
{
- // TODO(JS): Not clear what to do here.
- // For example should 'Kernel' be distinct from 'Executable'. For now just use executable.
- options.targetType = DownstreamCompiler::TargetType::Executable;
- break;
+ // We only support a single entry point on this target
+ SLANG_ASSERT(!"Can only compile with a single entry point on this target");
+ return SLANG_FAIL;
}
- default: break;
+
+ const Index entryPointIndex = entryPointIndices[0];
+
+ auto entryPoint = program->getEntryPoint(entryPointIndex);
+ auto profile = getEffectiveProfile(entryPoint, targetReq);
+
+ // Set the profile
+ options.profileName = GetHLSLProfileName(profile);
+
+ options.entryPointName = getText(entryPoint->getName());
}
+ // For host callable we want downstream compile to produce a shared library
+ if (target == CodeGenTarget::HostCallable)
+ {
+ target = CodeGenTarget::SharedLibrary;
+ }
+
+ options.targetType = (SlangCompileTarget)target;
+
// Need to configure for the compilation
{
@@ -1543,8 +1311,7 @@ SlangResult dissassembleDXILUsingDXC(
options.pipelineType = DownstreamCompiler::PipelineType::RayTracing;
break;
}
- }
-
+ }
}
// Add all the search paths (as calculated earlier - they will only be set if this is a pass through else will be empty)
@@ -1569,6 +1336,7 @@ SlangResult dissassembleDXILUsingDXC(
const auto& diagnostics = downstreamCompileResult->getDiagnostics();
+ if (diagnostics.diagnostics.getCount())
{
StringBuilder compilerText;
compiler->getDesc().appendAsText(compilerText);
@@ -1631,6 +1399,52 @@ SlangResult dissassembleDXILUsingDXC(
return SLANG_OK;
}
+ SlangResult dissassembleWithDownstream(
+ BackEndCompileRequest* slangRequest,
+ CodeGenTarget target,
+ const void* data,
+ size_t dataSizeInBytes,
+ ISlangBlob** outBlob)
+ {
+ auto session = slangRequest->getSession();
+ auto sink = slangRequest->getSink();
+
+ // Get the downstream compiler that can be used for this target
+
+ // TODO(JS):
+ // This could perhaps be performed in some other manner if there was more than one way to produce
+ // disassembly from a binary.
+ auto downstreamCompiler = getDownstreamCompilerRequiredForTarget(target);
+
+ // Get the required downstream compiler
+ DownstreamCompiler* compiler = session->getOrLoadDownstreamCompiler(downstreamCompiler, sink);
+
+ if (!compiler)
+ {
+ auto compilerName = TypeTextUtil::getPassThroughAsHumanText((SlangPassThrough)downstreamCompiler);
+ sink->diagnose(SourceLoc(), Diagnostics::passThroughCompilerNotFound, compilerName);
+ return SLANG_FAIL;
+ }
+
+ ComPtr<ISlangBlob> dissassemblyBlob;
+ SLANG_RETURN_ON_FAIL(compiler->dissassemble(SlangCompileTarget(target), data, dataSizeInBytes, dissassemblyBlob.writeRef()));
+
+ *outBlob = dissassemblyBlob.detach();
+ return SLANG_OK;
+ }
+
+ SlangResult dissassembleWithDownstream(
+ BackEndCompileRequest* slangRequest,
+ CodeGenTarget target,
+ DownstreamCompileResult* downstreamResult,
+ ISlangBlob** outBlob)
+ {
+
+ ComPtr<ISlangBlob> codeBlob;
+ SLANG_RETURN_ON_FAIL(downstreamResult->getBinary(codeBlob));
+ return dissassembleWithDownstream(slangRequest, target, codeBlob->getBufferPointer(), codeBlob->getBufferSize(), outBlob);
+ }
+
SlangResult emitSPIRVForEntryPointsDirectly(
BackEndCompileRequest* compileRequest,
const List<Int>& entryPointIndices,
@@ -1757,6 +1571,32 @@ SlangResult dissassembleDXILUsingDXC(
switch (target)
{
+ case CodeGenTarget::DXBytecodeAssembly:
+ {
+ RefPtr<DownstreamCompileResult> downstreamResult;
+ const CodeGenTarget intermediateTarget = CodeGenTarget::DXBytecode;
+
+ if (SLANG_SUCCEEDED(emitWithDownstreamForEntryPoints(
+ program,
+ compileRequest,
+ entryPointIndices,
+ targetReq,
+ intermediateTarget,
+ endToEndReq,
+ downstreamResult)))
+ {
+ maybeDumpIntermediate(compileRequest, downstreamResult, target);
+
+ ComPtr<ISlangBlob> disassemblyBlob;
+ if (SLANG_SUCCEEDED(dissassembleWithDownstream(compileRequest, intermediateTarget, downstreamResult, disassemblyBlob.writeRef())))
+ {
+ // Return the disassembly blob
+ result = CompileResult(disassemblyBlob);
+ }
+ }
+ }
+ break;
+ case CodeGenTarget::DXBytecode:
case CodeGenTarget::PTX:
case CodeGenTarget::HostCallable:
case CodeGenTarget::SharedLibrary:
@@ -1765,14 +1605,15 @@ SlangResult dissassembleDXILUsingDXC(
RefPtr<DownstreamCompileResult> downstreamResult;
if (SLANG_SUCCEEDED(emitWithDownstreamForEntryPoints(
+ program,
compileRequest,
entryPointIndices,
targetReq,
+ target,
endToEndReq,
downstreamResult)))
{
maybeDumpIntermediate(compileRequest, downstreamResult, target);
-
result = CompileResult(downstreamResult);
}
}
@@ -1796,47 +1637,6 @@ SlangResult dissassembleDXILUsingDXC(
}
break;
-#if SLANG_ENABLE_DXBC_SUPPORT
- case CodeGenTarget::DXBytecode:
- {
- // Assert only one entry point case -- move out of this function
- List<uint8_t> code;
- auto entryPointIndex = assertSingleEntryPoint(entryPointIndices);
- if (SLANG_SUCCEEDED(emitDXBytecodeForEntryPoint(
- program,
- compileRequest,
- entryPointIndex,
- targetReq,
- endToEndReq,
- code)))
- {
- maybeDumpIntermediate(compileRequest, code.getBuffer(), code.getCount(), target);
-
- result = CompileResult(ListBlob::moveCreate(code));
- }
- }
- break;
-
- case CodeGenTarget::DXBytecodeAssembly:
- {
- // Assert only one entry point case
- String code;
- auto entryPointIndex = assertSingleEntryPoint(entryPointIndices);
- if (SLANG_SUCCEEDED(emitDXBytecodeAssemblyForEntryPoint(
- program,
- compileRequest,
- entryPointIndex,
- targetReq,
- endToEndReq,
- code)))
- {
- maybeDumpIntermediate(compileRequest, code.getBuffer(), target);
- result = CompileResult(code);
- }
- }
- break;
-#endif
-
#if SLANG_ENABLE_DXIL_SUPPORT
case CodeGenTarget::DXIL:
{
@@ -2098,16 +1898,24 @@ SlangResult dissassembleDXILUsingDXC(
switch (targetReq->getTarget())
{
- #if SLANG_ENABLE_DXBC_SUPPORT
- case CodeGenTarget::DXBytecode:
+ case CodeGenTarget::DXBytecodeAssembly:
{
- String assembly;
- dissassembleDXBC(backEndReq, blobData, blobSize, assembly);
- writeOutputToConsole(writer, assembly);
+ const UnownedStringSlice disassembly = StringUtil::getSlice(blob);
+ writeOutputToConsole(writer, disassembly);
}
break;
- #endif
+ case CodeGenTarget::DXBytecode:
+ {
+ ComPtr<ISlangBlob> disassemblyBlob;
+ if (SLANG_SUCCEEDED(dissassembleWithDownstream(backEndReq, targetReq->getTarget(), blobData, blobSize, disassemblyBlob.writeRef())))
+ {
+ const UnownedStringSlice disassembly = StringUtil::getSlice(disassemblyBlob);
+ writeOutputToConsole(writer, disassembly);
+ }
+ }
+ break;
+
#if SLANG_ENABLE_DXIL_SUPPORT
case CodeGenTarget::DXIL:
{
@@ -2675,7 +2483,6 @@ SlangResult dissassembleDXILUsingDXC(
}
break;
- #if SLANG_ENABLE_DXBC_SUPPORT
case CodeGenTarget::DXBytecodeAssembly:
dumpIntermediateText(compileRequest, data, size, ".dxbc.asm");
break;
@@ -2683,12 +2490,13 @@ SlangResult dissassembleDXILUsingDXC(
case CodeGenTarget::DXBytecode:
dumpIntermediateBinary(compileRequest, data, size, ".dxbc");
{
- String dxbcAssembly;
- dissassembleDXBC(compileRequest, data, size, dxbcAssembly);
- dumpIntermediateText(compileRequest, dxbcAssembly.begin(), dxbcAssembly.getLength(), ".dxbc.asm");
+ ComPtr<ISlangBlob> disassemblyBlob;
+ if (SLANG_SUCCEEDED(dissassembleWithDownstream(compileRequest, target, data, size, disassemblyBlob.writeRef())))
+ {
+ dumpIntermediateText(compileRequest, disassemblyBlob->getBufferPointer(), disassemblyBlob->getBufferSize(), ".dxbc.asm");
+ }
}
break;
- #endif
#if SLANG_ENABLE_DXIL_SUPPORT
case CodeGenTarget::DXILAssembly:
diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h
index e57c1683a..52f3b9465 100755
--- a/source/slang/slang-compiler.h
+++ b/source/slang/slang-compiler.h
@@ -8,6 +8,7 @@
#include "../compiler-core/slang-downstream-compiler.h"
#include "../compiler-core/slang-name.h"
+#include "../compiler-core/slang-include-system.h"
#include "../core/slang-std-writers.h"
@@ -21,7 +22,6 @@
#include "slang-syntax.h"
-#include "slang-include-system.h"
#include "slang-serialize-ir-types.h"
@@ -76,6 +76,7 @@ namespace Slang
HostCallable = SLANG_HOST_CALLABLE,
CUDASource = SLANG_CUDA_SOURCE,
PTX = SLANG_PTX,
+ ObjectCode = SLANG_OBJECT_CODE,
CountOf = SLANG_TARGET_COUNT_OF,
};
@@ -2229,8 +2230,6 @@ namespace Slang
{
Glslang_Compile_1_0,
Glslang_Compile_1_1,
- Fxc_D3DCompile,
- Fxc_D3DDisassemble,
Dxc_DxcCreateInstance,
CountOf,
};
diff --git a/source/slang/slang-include-system.cpp b/source/slang/slang-include-system.cpp
deleted file mode 100644
index 891d376f6..000000000
--- a/source/slang/slang-include-system.cpp
+++ /dev/null
@@ -1,158 +0,0 @@
-// slang-include-system.cpp
-#include "slang-include-system.h"
-
-#include "../core/slang-io.h"
-#include "../core/slang-string-util.h"
-
-namespace Slang
-{
-
-SlangResult IncludeSystem::findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& outPathInfo)
-{
- String combinedPath;
-
- if (fromPath.getLength() == 0 || Path::isAbsolute(path))
- {
- // If the path is absolute or the fromPath is empty, the combined path is just the path
- combinedPath = path;
- }
- else
- {
- // Get relative path
- ComPtr<ISlangBlob> combinedPathBlob;
- SLANG_RETURN_ON_FAIL(m_fileSystemExt->calcCombinedPath(fromPathType, fromPath.begin(), path.begin(), combinedPathBlob.writeRef()));
- combinedPath = StringUtil::getString(combinedPathBlob);
- if (combinedPath.getLength() <= 0)
- {
- return SLANG_FAIL;
- }
- }
-
- // This checks the path exists
- SlangPathType pathType;
- SLANG_RETURN_ON_FAIL(m_fileSystemExt->getPathType(combinedPath.begin(), &pathType));
- if (pathType != SLANG_PATH_TYPE_FILE)
- {
- return SLANG_E_NOT_FOUND;
- }
-
- // Get the uniqueIdentity
- ComPtr<ISlangBlob> uniqueIdentityBlob;
- SLANG_RETURN_ON_FAIL(m_fileSystemExt->getFileUniqueIdentity(combinedPath.begin(), uniqueIdentityBlob.writeRef()));
-
- // If the rel path exists -> a uniqueIdentity MUST exists too
- String uniqueIdentity(StringUtil::getString(uniqueIdentityBlob));
- if (uniqueIdentity.getLength() <= 0)
- {
- // Unique identity can't be empty
- return SLANG_FAIL;
- }
-
- outPathInfo = PathInfo::makeNormal(combinedPath, uniqueIdentity);
- return SLANG_OK;
-}
-
-String IncludeSystem::simplifyPath(const String& path)
-{
- ComPtr<ISlangBlob> simplifiedPath;
- if (SLANG_FAILED(m_fileSystemExt->getSimplifiedPath(path.getBuffer(), simplifiedPath.writeRef())))
- {
- return path;
- }
- return StringUtil::getString(simplifiedPath);
-}
-
-SlangResult IncludeSystem::findFile(String const& pathToInclude, String const& pathIncludedFrom, PathInfo& outPathInfo)
-{
- outPathInfo.type = PathInfo::Type::Unknown;
-
- // If it's absolute we only have to try and find if it's there - no need to look at search paths
- if (Path::isAbsolute(pathToInclude))
- {
- // We pass in "" as the from path, so ensure no from path is taken into account
- // and to allow easy identification that this is in effect absolute
- return findFile(SLANG_PATH_TYPE_DIRECTORY, UnownedStringSlice::fromLiteral(""), pathToInclude, outPathInfo);
- }
-
- // Try just relative to current path
- {
- SlangResult res = findFile(SLANG_PATH_TYPE_FILE, pathIncludedFrom, pathToInclude, outPathInfo);
- // It either succeeded or wasn't found, anything else is a failure passed back
- if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
- {
- return res;
- }
- }
-
- // Search all the searchDirectories
- for (auto sd = m_searchDirectories; sd; sd = sd->parent)
- {
- for (auto& dir : sd->searchDirectories)
- {
- SlangResult res = findFile(SLANG_PATH_TYPE_DIRECTORY, dir.path, pathToInclude, outPathInfo);
- if (SLANG_SUCCEEDED(res) || res != SLANG_E_NOT_FOUND)
- {
- return res;
- }
- }
- }
-
- return SLANG_E_NOT_FOUND;
-}
-
-SlangResult IncludeSystem::loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>& outBlob)
-{
- if (m_sourceManager)
- {
- // See if this an already loaded source file
- SourceFile* sourceFile = m_sourceManager->findSourceFileRecursively(pathInfo.uniqueIdentity);
-
- // If not create a new one, and add to the list of known source files
- if (!sourceFile)
- {
- ComPtr<ISlangBlob> foundSourceBlob;
- if (SLANG_FAILED(m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), foundSourceBlob.writeRef())))
- {
- return SLANG_E_CANNOT_OPEN;
- }
-
- sourceFile = m_sourceManager->createSourceFileWithBlob(pathInfo, foundSourceBlob);
- m_sourceManager->addSourceFile(pathInfo.uniqueIdentity, sourceFile);
-
- outBlob = foundSourceBlob;
- return SLANG_OK;
- }
- else
- {
- if (sourceFile->getContentBlob())
- {
- outBlob = sourceFile->getContentBlob();
- return SLANG_OK;
- }
-
- ComPtr<ISlangBlob> foundSourceBlob;
- if (SLANG_FAILED(m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), foundSourceBlob.writeRef())))
- {
- return SLANG_E_CANNOT_OPEN;
- }
-
- sourceFile->setContents(foundSourceBlob);
- outBlob = foundSourceBlob;
- return SLANG_OK;
- }
- }
- else
- {
- // If we don't have the source manager, just load
- return m_fileSystemExt->loadFile(pathInfo.foundPath.getBuffer(), outBlob.writeRef());
- }
-}
-
-SlangResult IncludeSystem::findAndLoadFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo, ComPtr<ISlangBlob>& outBlob)
-{
- SLANG_RETURN_ON_FAIL(findFile(pathToInclude, pathIncludedFrom, outPathInfo));
- SLANG_RETURN_ON_FAIL(loadFile(outPathInfo, outBlob));
- return SLANG_OK;
-}
-
-} // namespace Slang
diff --git a/source/slang/slang-include-system.h b/source/slang/slang-include-system.h
deleted file mode 100644
index 70f6dd81e..000000000
--- a/source/slang/slang-include-system.h
+++ /dev/null
@@ -1,62 +0,0 @@
-#ifndef SLANG_INCLUDE_SYSTEM_H
-#define SLANG_INCLUDE_SYSTEM_H
-// slang-include-system.h
-
-#include "../compiler-core/slang-source-loc.h"
-
-namespace Slang
-{
-
-// A directory to be searched when looking for files (e.g., `#include`)
-struct SearchDirectory
-{
- SearchDirectory() = default;
- SearchDirectory(SearchDirectory const& other) = default;
- SearchDirectory(String const& path)
- : path(path)
- {}
-
- String path;
-};
-
-/// A list of directories to search for files (e.g., `#include`)
-struct SearchDirectoryList
-{
- // A parent list that should also be searched
- SearchDirectoryList* parent = nullptr;
-
- // Directories to be searched
- List<SearchDirectory> searchDirectories;
-};
-
-/* A helper class that builds basic include handling on top of searchDirectories/fileSystemExt and optionally a sourceManager */
-struct IncludeSystem
-{
- IncludeSystem(SearchDirectoryList* searchDirectories, ISlangFileSystemExt* fileSystemExt, SourceManager* sourceManager = nullptr) :
- m_searchDirectories(searchDirectories),
- m_fileSystemExt(fileSystemExt),
- m_sourceManager(sourceManager)
- {
- }
-
- SlangResult findFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo);
- SlangResult findFile(SlangPathType fromPathType, const String& fromPath, const String& path, PathInfo& outPathInfo);
- String simplifyPath(const String& path);
- SlangResult loadFile(const PathInfo& pathInfo, ComPtr<ISlangBlob>& outBlob);
-
- SlangResult findAndLoadFile(const String& pathToInclude, const String& pathIncludedFrom, PathInfo& outPathInfo, ComPtr<ISlangBlob>& outBlob);
-
- SearchDirectoryList* getSearchDirectoryList() const { return m_searchDirectories; }
- ISlangFileSystemExt* getFileSystem() const { return m_fileSystemExt; }
- SourceManager* getSourceManager() const { return m_sourceManager; }
-
-protected:
-
- SearchDirectoryList* m_searchDirectories;
- ISlangFileSystemExt* m_fileSystemExt;
- SourceManager* m_sourceManager; ///< If not set, will not look up the content in the source manager
-};
-
-}
-
-#endif // SLANG_INCLUDE_HANDLER_H
diff --git a/source/slang/slang-preprocessor.h b/source/slang/slang-preprocessor.h
index 9de82b9f2..9f3940d29 100644
--- a/source/slang/slang-preprocessor.h
+++ b/source/slang/slang-preprocessor.h
@@ -5,8 +5,7 @@
#include "../core/slang-basic.h"
#include "../compiler-core/slang-lexer.h"
-
-#include "slang-include-system.h"
+#include "../compiler-core/slang-include-system.h"
namespace Slang {