diff options
| author | jsmall-nvidia <jsmall@nvidia.com> | 2021-05-14 17:50:00 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-05-14 17:50:00 -0400 |
| commit | d4316c88457a32f1169b2d7d82053ccbc05fa7ed (patch) | |
| tree | cbc87350b9ef2f5be31ebc20783e08b895767779 /source/slang | |
| parent | 79d106fac18f5792fcac448a0b037aa834fa6042 (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.cpp | 2 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.cpp | 598 | ||||
| -rwxr-xr-x | source/slang/slang-compiler.h | 5 | ||||
| -rw-r--r-- | source/slang/slang-include-system.cpp | 158 | ||||
| -rw-r--r-- | source/slang/slang-include-system.h | 62 | ||||
| -rw-r--r-- | source/slang/slang-preprocessor.h | 3 |
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 { |
