From 255fd5873f65a6b01d5385c277d55612dc3cc587 Mon Sep 17 00:00:00 2001 From: Yong He Date: Mon, 28 Mar 2022 22:14:33 -0700 Subject: Allow slangc to generate exe from .slang file. (#2170) --- .gitignore | 5 + .../heterogeneous-first-gen.vcxproj | 168 --------- .../heterogeneous-hello-world.vcxproj | 324 ----------------- .../heterogeneous-hello-world.vcxproj.filters | 21 -- .../run-generators/run-generators.vcxproj | 17 + .../run-generators/run-generators.vcxproj.filters | 3 + build/visual-studio/slang-rt/slang-rt.vcxproj | 396 +++++++++++++++++++++ .../slang-rt/slang-rt.vcxproj.filters | 326 +++++++++++++++++ build/visual-studio/slang/slang.vcxproj | 1 + build/visual-studio/slang/slang.vcxproj.filters | 3 + examples/cpu-hello-world/main.cpp | 2 +- examples/heterogeneous-hello-world/main.cpp | 273 -------------- examples/heterogeneous-hello-world/main.slang | 10 + examples/heterogeneous-hello-world/shader.slang | 76 ---- prelude/slang-cpp-host-prelude.h | 16 + premake5.lua | 47 +-- slang.h | 9 +- slang.sln | 14 + source/compiler-core/slang-downstream-compiler.h | 5 +- source/compiler-core/slang-gcc-compiler-util.cpp | 10 +- .../slang-visual-studio-compiler-util.cpp | 16 +- source/core/slang-common.h | 19 + source/core/slang-smart-pointer.h | 5 +- source/core/slang-string.h | 14 +- source/core/slang-token-reader.cpp | 3 - source/core/slang-token-reader.h | 2 + source/core/slang-type-convert-util.cpp | 1 + source/core/slang-type-text-util.cpp | 7 +- source/slang/core.meta.slang | 18 +- source/slang/slang-ast-modifier.h | 4 +- source/slang/slang-compiler.cpp | 91 +++-- source/slang/slang-compiler.h | 13 +- source/slang/slang-emit-c-like.cpp | 37 +- source/slang/slang-emit-cpp.cpp | 183 +++------- source/slang/slang-emit.cpp | 11 +- source/slang/slang-ir-inst-defs.h | 6 +- source/slang/slang-ir-insts.h | 30 +- source/slang/slang-lower-to-ir.cpp | 15 +- source/slang/slang-mangle.cpp | 4 +- source/slang/slang-options.cpp | 10 +- source/slang/slang-parameter-binding.cpp | 6 +- source/slang/slang-type-layout.cpp | 12 +- source/slang/slang.cpp | 12 +- tools/gfx/cpu/render-cpu.cpp | 2 +- tools/render-test/render-test-main.cpp | 2 +- tools/slang-embed/slang-embed.cpp | 10 +- tools/slang-test/slang-test-main.cpp | 13 +- 47 files changed, 1080 insertions(+), 1192 deletions(-) delete mode 100644 build/visual-studio/heterogeneous-hello-world/heterogeneous-first-gen.vcxproj delete mode 100644 build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj delete mode 100644 build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj.filters create mode 100644 build/visual-studio/slang-rt/slang-rt.vcxproj create mode 100644 build/visual-studio/slang-rt/slang-rt.vcxproj.filters delete mode 100644 examples/heterogeneous-hello-world/main.cpp create mode 100644 examples/heterogeneous-hello-world/main.slang delete mode 100644 examples/heterogeneous-hello-world/shader.slang create mode 100644 prelude/slang-cpp-host-prelude.h diff --git a/.gitignore b/.gitignore index bf49ea7d7..f2c9be351 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,8 @@ prelude/*.h.cpp /examples/heterogeneous-hello-world/shader.cpp /multiple-definitions.hlsl /external/slang-llvm/ + +build/**/*.tlog +build/**/*.lastbuildstate +build/**/*.recipe +build/**/*.log diff --git a/build/visual-studio/heterogeneous-hello-world/heterogeneous-first-gen.vcxproj b/build/visual-studio/heterogeneous-hello-world/heterogeneous-first-gen.vcxproj deleted file mode 100644 index a2181ad08..000000000 --- a/build/visual-studio/heterogeneous-hello-world/heterogeneous-first-gen.vcxproj +++ /dev/null @@ -1,168 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Debug - ARM - - - Debug aarch64 - Win32 - - - Debug aarch64 - x64 - - - Debug aarch64 - ARM - - - Release - Win32 - - - Release - x64 - - - Release - ARM - - - Release aarch64 - Win32 - - - Release aarch64 - x64 - - - Release aarch64 - ARM - - - - {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B} - true - Win32Proj - heterogeneous-first-gen - - - - Utility - v142 - - - Utility - v142 - - - Utility - v142 - - - Utility - v142 - - - Utility - v142 - - - Utility - v142 - - - - - - - - - - - - - - - - - - - - - - - - - ..\..\..\bin\windows-x86\debug\ - obj\x86\Debug\ - - - ..\..\..\bin\windows-x64\debug\ - obj\x64\Debug\ - - - ..\..\..\bin\windows-aarch64\debug\ - obj\aarch64\Debug\ - - - ..\..\..\bin\windows-x86\release\ - obj\x86\Release\ - - - ..\..\..\bin\windows-x64\release\ - obj\x64\Release\ - - - ..\..\..\bin\windows-aarch64\release\ - obj\aarch64\Release\ - - - - "../../../bin/windows-x86/debug/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - - - - - "../../../bin/windows-x64/debug/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - - - - - "../../../bin/windows-aarch64/debug/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - - - - - "../../../bin/windows-x86/release/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - - - - - "../../../bin/windows-x64/release/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - - - - - "../../../bin/windows-aarch64/release/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - - - - - {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7} - - - - - - \ No newline at end of file diff --git a/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj b/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj deleted file mode 100644 index 3e3049f65..000000000 --- a/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj +++ /dev/null @@ -1,324 +0,0 @@ - - - - - Debug - Win32 - - - Debug - x64 - - - Debug - ARM - - - Debug aarch64 - Win32 - - - Debug aarch64 - x64 - - - Debug aarch64 - ARM - - - Release - Win32 - - - Release - x64 - - - Release - ARM - - - Release aarch64 - Win32 - - - Release aarch64 - x64 - - - Release aarch64 - ARM - - - - {150CAA5A-0177-6A66-AA92-CFCB96DC2D49} - true - Win32Proj - heterogeneous-hello-world - - - - Application - true - Unicode - v142 - - - Application - true - Unicode - v142 - - - Application - true - Unicode - v142 - true - - - Application - false - Unicode - v142 - - - Application - false - Unicode - v142 - - - Application - false - Unicode - v142 - true - - - - - - - - - - - - - - - - - - - - - - - - - true - ..\..\..\bin\windows-x86\debug\ - ..\..\..\intermediate\windows-x86\debug\heterogeneous-hello-world\ - heterogeneous-hello-world - .exe - - - true - ..\..\..\bin\windows-x64\debug\ - ..\..\..\intermediate\windows-x64\debug\heterogeneous-hello-world\ - heterogeneous-hello-world - .exe - - - true - ..\..\..\bin\windows-aarch64\debug\ - ..\..\..\intermediate\windows-aarch64\debug\heterogeneous-hello-world\ - heterogeneous-hello-world - .exe - - - false - ..\..\..\bin\windows-x86\release\ - ..\..\..\intermediate\windows-x86\release\heterogeneous-hello-world\ - heterogeneous-hello-world - .exe - - - false - ..\..\..\bin\windows-x64\release\ - ..\..\..\intermediate\windows-x64\release\heterogeneous-hello-world\ - heterogeneous-hello-world - .exe - - - false - ..\..\..\bin\windows-aarch64\release\ - ..\..\..\intermediate\windows-aarch64\release\heterogeneous-hello-world\ - heterogeneous-hello-world - .exe - - - - NotUsing - Level3 - _DEBUG;%(PreprocessorDefinitions) - ..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories) - ProgramDatabase - Disabled - MultiThreadedDebug - - - Console - true - - - "../../../bin/windows-x86/debug/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - Generating shader.cpp in ../../../examples/heterogeneous-hello-world/ - - - - - NotUsing - Level3 - _DEBUG;%(PreprocessorDefinitions) - ..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories) - ProgramDatabase - Disabled - MultiThreadedDebug - - - Console - true - - - "../../../bin/windows-x64/debug/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - Generating shader.cpp in ../../../examples/heterogeneous-hello-world/ - - - - - NotUsing - Level3 - _DEBUG;%(PreprocessorDefinitions) - ..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories) - ProgramDatabase - Disabled - MultiThreadedDebug - - - Console - true - - - "../../../bin/windows-aarch64/debug/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - Generating shader.cpp in ../../../examples/heterogeneous-hello-world/ - - - - - NotUsing - Level3 - NDEBUG;%(PreprocessorDefinitions) - ..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories) - Full - true - true - false - true - MultiThreaded - - - Console - true - true - - - "../../../bin/windows-x86/release/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - Generating shader.cpp in ../../../examples/heterogeneous-hello-world/ - - - - - NotUsing - Level3 - NDEBUG;%(PreprocessorDefinitions) - ..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories) - Full - true - true - false - true - MultiThreaded - - - Console - true - true - - - "../../../bin/windows-x64/release/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - Generating shader.cpp in ../../../examples/heterogeneous-hello-world/ - - - - - NotUsing - Level3 - NDEBUG;%(PreprocessorDefinitions) - ..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories) - Full - true - true - false - true - MultiThreaded - - - Console - true - true - - - "../../../bin/windows-aarch64/release/slangc" "../../../examples/heterogeneous-hello-world/shader.slang" -o "../../../examples/heterogeneous-hello-world/shader.cpp" -heterogeneous -target cpp -target hlsl - Generating shader.cpp in ../../../examples/heterogeneous-hello-world/ - - - - - - - - - - - - {37BED5B5-23FA-D81F-8C0C-F1167867813A} - - - {DB00DA62-0533-4AFD-B59F-A67D5B3A0808} - - - {222F7498-B40C-4F3F-A704-DDEB91A4484A} - - - {F5ADB74E-02A7-44FB-AA3B-FC02F8AC7A4B} - - - {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7} - - - {3565FE5E-4FA3-11EB-AE93-0242AC130002} - - - {F9BE7957-8399-899E-0C49-E714FDDD4B65} - - - {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B} - - - - - - \ No newline at end of file diff --git a/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj.filters b/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj.filters deleted file mode 100644 index 3b195e092..000000000 --- a/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj.filters +++ /dev/null @@ -1,21 +0,0 @@ - - - - - {E9C7FDCE-D52A-8D73-7EB0-C5296AF258F6} - - - - - Source Files - - - Source Files - - - - - Source Files - - - \ No newline at end of file diff --git a/build/visual-studio/run-generators/run-generators.vcxproj b/build/visual-studio/run-generators/run-generators.vcxproj index 6e10e3ca1..c8a99e931 100644 --- a/build/visual-studio/run-generators/run-generators.vcxproj +++ b/build/visual-studio/run-generators/run-generators.vcxproj @@ -258,6 +258,23 @@ + + Document + "../../../bin/windows-x86/debug/slang-embed" %(Identity) + "../../../bin/windows-x64/debug/slang-embed" %(Identity) + "$(SolutionDir)/bin/windows-x64/debug/slang-embed" %(Identity) + "../../../bin/windows-x86/release/slang-embed" %(Identity) + "../../../bin/windows-x64/release/slang-embed" %(Identity) + "$(SolutionDir)/bin/windows-x64/release/slang-embed" %(Identity) + ../../../prelude/slang-cpp-host-prelude.h.cpp + slang-embed %(Identity) + ../../../bin/windows-x86/debug/slang-embed.exe + ../../../bin/windows-x64/debug/slang-embed.exe + ../../../bin/windows-x64/debug/slang-embed.exe + ../../../bin/windows-x86/release/slang-embed.exe + ../../../bin/windows-x64/release/slang-embed.exe + ../../../bin/windows-x64/release/slang-embed.exe + Document "../../../bin/windows-x86/debug/slang-embed" %(Identity) diff --git a/build/visual-studio/run-generators/run-generators.vcxproj.filters b/build/visual-studio/run-generators/run-generators.vcxproj.filters index 775c3672c..609af9779 100644 --- a/build/visual-studio/run-generators/run-generators.vcxproj.filters +++ b/build/visual-studio/run-generators/run-generators.vcxproj.filters @@ -25,6 +25,9 @@ + + Header Files + Header Files diff --git a/build/visual-studio/slang-rt/slang-rt.vcxproj b/build/visual-studio/slang-rt/slang-rt.vcxproj new file mode 100644 index 000000000..c0fab7f97 --- /dev/null +++ b/build/visual-studio/slang-rt/slang-rt.vcxproj @@ -0,0 +1,396 @@ + + + + + Debug + Win32 + + + Debug + x64 + + + Debug + ARM + + + Debug aarch64 + Win32 + + + Debug aarch64 + x64 + + + Debug aarch64 + ARM + + + Release + Win32 + + + Release + x64 + + + Release + ARM + + + Release aarch64 + Win32 + + + Release aarch64 + x64 + + + Release aarch64 + ARM + + + + {DFC79D72-91DE-434C-871B-B3943B488BEB} + true + Win32Proj + slang-rt + + + + DynamicLibrary + true + Unicode + v142 + + + DynamicLibrary + true + Unicode + v142 + + + DynamicLibrary + true + Unicode + v142 + true + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + + + DynamicLibrary + false + Unicode + v142 + true + + + + + + + + + + + + + + + + + + + + + + + + + true + ..\..\..\bin\windows-x86\debug\ + ..\..\..\intermediate\windows-x86\debug\slang-rt\ + slang-rt + .dll + + + true + ..\..\..\bin\windows-x64\debug\ + ..\..\..\intermediate\windows-x64\debug\slang-rt\ + slang-rt + .dll + + + true + ..\..\..\bin\windows-aarch64\debug\ + ..\..\..\intermediate\windows-aarch64\debug\slang-rt\ + slang-rt + .dll + + + false + ..\..\..\bin\windows-x86\release\ + ..\..\..\intermediate\windows-x86\release\slang-rt\ + slang-rt + .dll + + + false + ..\..\..\bin\windows-x64\release\ + ..\..\..\intermediate\windows-x64\release\slang-rt\ + slang-rt + .dll + + + false + ..\..\..\bin\windows-aarch64\release\ + ..\..\..\intermediate\windows-aarch64\release\slang-rt\ + slang-rt + .dll + + + + NotUsing + Level4 + true + _DEBUG;SLANG_RT_DYNAMIC;SLANG_RT_DYNAMIC_EXPORT;%(PreprocessorDefinitions) + ProgramDatabase + Disabled + MultiThreadedDebug + + + Windows + true + ..\..\..\bin\windows-x86\debug\slang-rt.lib + true + + + + + NotUsing + Level4 + true + _DEBUG;SLANG_RT_DYNAMIC;SLANG_RT_DYNAMIC_EXPORT;%(PreprocessorDefinitions) + ProgramDatabase + Disabled + MultiThreadedDebug + + + Windows + true + ..\..\..\bin\windows-x64\debug\slang-rt.lib + true + + + + + NotUsing + Level4 + true + _DEBUG;SLANG_RT_DYNAMIC;SLANG_RT_DYNAMIC_EXPORT;%(PreprocessorDefinitions) + ProgramDatabase + Disabled + MultiThreadedDebug + + + Windows + true + ..\..\..\bin\windows-aarch64\debug\slang-rt.lib + true + + + + + NotUsing + Level4 + true + NDEBUG;SLANG_RT_DYNAMIC;SLANG_RT_DYNAMIC_EXPORT;%(PreprocessorDefinitions) + Full + true + true + false + true + MultiThreaded + + + Windows + true + true + ..\..\..\bin\windows-x86\release\slang-rt.lib + true + + + + + NotUsing + Level4 + true + NDEBUG;SLANG_RT_DYNAMIC;SLANG_RT_DYNAMIC_EXPORT;%(PreprocessorDefinitions) + Full + true + true + false + true + MultiThreaded + + + Windows + true + true + ..\..\..\bin\windows-x64\release\slang-rt.lib + true + + + + + NotUsing + Level4 + true + NDEBUG;SLANG_RT_DYNAMIC;SLANG_RT_DYNAMIC_EXPORT;%(PreprocessorDefinitions) + Full + true + true + false + true + MultiThreaded + + + Windows + true + true + ..\..\..\bin\windows-aarch64\release\slang-rt.lib + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {E76ACB11-4A12-4F0A-BE1E-CE0B8836EB7F} + + + {E1EC8075-823E-46E5-BC38-C124CCCDF878} + + + + + + \ No newline at end of file diff --git a/build/visual-studio/slang-rt/slang-rt.vcxproj.filters b/build/visual-studio/slang-rt/slang-rt.vcxproj.filters new file mode 100644 index 000000000..51b0313f6 --- /dev/null +++ b/build/visual-studio/slang-rt/slang-rt.vcxproj.filters @@ -0,0 +1,326 @@ + + + + + {21EB8090-0D4E-1035-B6D3-48EBA215DCB7} + + + {E9C7FDCE-D52A-8D73-7EB0-C5296AF258F6} + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + + + Source Files + + + \ No newline at end of file diff --git a/build/visual-studio/slang/slang.vcxproj b/build/visual-studio/slang/slang.vcxproj index 61ddc40f4..a54c4da89 100644 --- a/build/visual-studio/slang/slang.vcxproj +++ b/build/visual-studio/slang/slang.vcxproj @@ -432,6 +432,7 @@ IF EXIST ..\..\..\external\slang-binaries\bin\windows-aarch64\slang-glslang.dll\ + diff --git a/build/visual-studio/slang/slang.vcxproj.filters b/build/visual-studio/slang/slang.vcxproj.filters index ba0e4fe52..3b88a758a 100644 --- a/build/visual-studio/slang/slang.vcxproj.filters +++ b/build/visual-studio/slang/slang.vcxproj.filters @@ -389,6 +389,9 @@ + + Header Files + Header Files diff --git a/examples/cpu-hello-world/main.cpp b/examples/cpu-hello-world/main.cpp index cf8c57285..460b4698b 100644 --- a/examples/cpu-hello-world/main.cpp +++ b/examples/cpu-hello-world/main.cpp @@ -83,7 +83,7 @@ static SlangResult _innerMain(int argc, char** argv) // We would like to request a CPU code that can be executed directly on the host - // which is the 'SLANG_HOST_CALLABLE' target. // If we wanted a just a shared library/dll, we could have used SLANG_SHARED_LIBRARY. - int targetIndex = spAddCodeGenTarget(slangRequest, SLANG_HOST_CALLABLE); + int targetIndex = spAddCodeGenTarget(slangRequest, SLANG_SHADER_HOST_CALLABLE); // Set the target flag to indicate that we want to compile all the entrypoints in the // slang shader file into a library. diff --git a/examples/heterogeneous-hello-world/main.cpp b/examples/heterogeneous-hello-world/main.cpp deleted file mode 100644 index e711d4486..000000000 --- a/examples/heterogeneous-hello-world/main.cpp +++ /dev/null @@ -1,273 +0,0 @@ -// main.cpp - -// This example uses the Slang gfx layer to target different APIs and execute -// both CPU and GPU code from a single Slang file (?) -// -#include -#include -using Slang::ComPtr; - -#include "slang-gfx.h" -#include "gfx-util/shader-cursor.h" -#include "source/core/slang-basic.h" -#include "../../prelude/slang-cpp-types.h" - -using namespace gfx; -using namespace Slang; - -// Creating global ref pointers to avoid dereferencing values -// -ComPtr gDevice; -ComPtr gProgram; -ComPtr gBufferResource; -ComPtr gResourceView; -ComPtr gTransientHeap; -ComPtr gPipelineState; -ComPtr gQueue; - -// Boilerplate types to help the slang-generated file -// -bool executeComputation(); - -// Many Slang API functions return detailed diagnostic information -// (error messages, warnings, etc.) as a "blob" of data, or return -// a null blob pointer instead if there were no issues. -// -// For convenience, we define a subroutine that will dump the information -// in a diagnostic blob if one is produced, and skip it otherwise. -// -void diagnoseIfNeeded(slang::IBlob *diagnosticsBlob) -{ - if (diagnosticsBlob != nullptr) - { - printf("%s", (const char *)diagnosticsBlob->getBufferPointer()); - } -} - -gfx::IDevice *createDevice() -{ - ComPtr device; - IDevice::Desc deviceDesc = {}; - // Changing device type would happen here. For example: - //deviceDesc.deviceType = DeviceType::CUDA; - SLANG_RETURN_NULL_ON_FAIL(gfxCreateDevice(&deviceDesc, gDevice.writeRef())); - return gDevice; -} - -// Loads the shader code defined in `shader.slang` for use by the `gfx` layer. -// -gfx::IShaderProgram *loadShaderProgram(gfx::IDevice *device, char* entryPoint, char* moduleName) -{ - // We need to obtain a compilation session (`slang::ISession`) that will provide - // a scope to all the compilation and loading of code we do. - // - ComPtr slangSession; - SLANG_RETURN_NULL_ON_FAIL(device->getSlangSession(slangSession.writeRef())); - - // We can now start loading code into the slang session. - // - // The simplest way to load code is by calling `loadModule` with the name of a Slang - // module. A call to `loadModule("MyStuff")` will behave more or less as if you - // wrote: - // - // import MyStuff; - // - // In a Slang shader file. The compiler will use its search paths to try to locate - // `MyModule.slang`, then compile and load that file. If a matching module had - // already been loaded previously, that would be used directly. - // - ComPtr diagnosticsBlob; - slang::IModule *module = slangSession->loadModule(moduleName, diagnosticsBlob.writeRef()); - diagnoseIfNeeded(diagnosticsBlob); - if (!module) - return NULL; - - // Look up entry point - // - // char const *computeEntryPointName = entryPoint.getBuffer(); - ComPtr computeEntryPoint; - SLANG_RETURN_NULL_ON_FAIL( - module->findEntryPointByName(entryPoint, computeEntryPoint.writeRef())); - - // At this point we have a few different Slang API objects that represent - // pieces of our code: `module`, `vertexEntryPoint`, and `fragmentEntryPoint`. - // - // A single Slang module could contain many different entry points (e.g., - // four vertex entry points, three fragment entry points, and two compute - // shaders), and before we try to generate output code for our target API - // we need to identify which entry points we plan to use together. - // - // Modules and entry points are both examples of *component types* in the - // Slang API. The API also provides a way to build a *composite* out of - // other pieces, and that is what we are going to do with our module - // and entry points. - // - Slang::List componentTypes; - componentTypes.add(module); - componentTypes.add(computeEntryPoint); - - // Actually creating the composite component type is a single operation - // on the Slang session, but the operation could potentially fail if - // something about the composite was invalid (e.g., you are trying to - // combine multiple copies of the same module), so we need to deal - // with the possibility of diagnostic output. - // - ComPtr composedProgram; - SlangResult result = slangSession->createCompositeComponentType( - componentTypes.getBuffer(), - componentTypes.getCount(), - composedProgram.writeRef(), - diagnosticsBlob.writeRef()); - diagnoseIfNeeded(diagnosticsBlob); - SLANG_RETURN_NULL_ON_FAIL(result); - - // At this point, `composedProgram` represents the shader program - // we want to run, and the compute shader there have been checked. - // We can create a `gfx::IShaderProgram` object from `composedProgram` - // so it may be used by the graphics layer. - gfx::IShaderProgram::Desc programDesc = {}; - programDesc.slangProgram = composedProgram.get(); - - gProgram = device->createProgram(programDesc); - - return gProgram; -} - -gfx::IBufferResource* createStructuredBuffer(gfx::IDevice* device, FixedArray initialData) -{ - // Create a structured buffer for storing computation data - // - const int numberCount = 4; - int structuredBufferSize = numberCount * sizeof(float); - - IBufferResource::Desc bufferDesc = {}; - bufferDesc.sizeInBytes = numberCount * sizeof(float); - bufferDesc.format = gfx::Format::Unknown; - bufferDesc.elementSize = sizeof(float); - bufferDesc.allowedStates = ResourceStateSet(ResourceState::ShaderResource, - ResourceState::UnorderedAccess, - ResourceState::CopyDestination, - ResourceState::CopySource); - bufferDesc.defaultState = ResourceState::UnorderedAccess; - bufferDesc.memoryType = MemoryType::DeviceLocal; - - SlangResult result = device->createBufferResource(bufferDesc, - (void *)&initialData, - gBufferResource.writeRef()); - SLANG_RETURN_NULL_ON_FAIL(result); - return gBufferResource; -} - -gfx::IResourceView *createBufferView( - gfx::IDevice *device, - gfx::IBufferResource *buffer) -{ - // Create a resource view for the structured buffer - // - gfx::IResourceView::Desc viewDesc = {}; - viewDesc.type = gfx::IResourceView::Type::UnorderedAccess; - viewDesc.format = gfx::Format::Unknown; - SLANG_RETURN_NULL_ON_FAIL(device->createBufferView(buffer, viewDesc, gResourceView.writeRef())); - return gResourceView; -} - -gfx::ITransientResourceHeap *buildTransientHeap(gfx::IDevice *device) -{ - ITransientResourceHeap::Desc transientHeapDesc = {}; - transientHeapDesc.constantBufferSize = 4096; - SLANG_RETURN_NULL_ON_FAIL( - device->createTransientResourceHeap(transientHeapDesc, gTransientHeap.writeRef())); - return gTransientHeap; -} - -gfx::IPipelineState *buildPipelineState( - gfx::IDevice *device, - gfx::IShaderProgram *shaderProgram) -{ - gfx::ComputePipelineStateDesc pipelineDesc = {}; - pipelineDesc.program = shaderProgram; - SLANG_RETURN_NULL_ON_FAIL( - device->createComputePipelineState(pipelineDesc, gPipelineState.writeRef())); - return gPipelineState; -} - -void printInitialValues(FixedArray initialArray, int length) -{ - printf("Before:\n"); - for (int i = 0; i < length; i++) - { - printf("%f, ", initialArray[i]); - } - printf("\n"); -} - -void dispatchComputation( - gfx::IDevice *device, - gfx::ITransientResourceHeap *transientHeap, - gfx::IPipelineState *pipelineState, - gfx::IResourceView *bufferView, - unsigned int gridDimsX, - unsigned int gridDimsY, - unsigned int gridDimsZ) -{ - ICommandQueue::Desc queueDesc = {ICommandQueue::QueueType::Graphics}; - gQueue = device->createCommandQueue(queueDesc); - - auto commandBuffer = transientHeap->createCommandBuffer(); - auto encoder = commandBuffer->encodeComputeCommands(); - - // First, obtain a root shader object from command encoder to start parameter binding. - auto rootObject = encoder->bindPipeline(pipelineState); - - gfx::ShaderCursor entryPointCursor( - rootObject->getEntryPoint(0)); // get a cursor the the first entry-point. - // Bind buffer view to the entry point. - entryPointCursor.getPath("ioBuffer").setResource(bufferView); - - encoder->dispatchCompute(gridDimsX, gridDimsY, gridDimsZ); - encoder->endEncoding(); - commandBuffer->close(); - gQueue->executeCommandBuffer(commandBuffer); - gQueue->waitOnHost(); -} - -bool printOutputValues( - gfx::IDevice *device, - gfx::IBufferResource *buffer, - int length) -{ - ComPtr resultBlob; - SLANG_RETURN_FALSE_ON_FAIL(device->readBufferResource( - buffer, 0, length * sizeof(float), resultBlob.writeRef())); - auto result = reinterpret_cast(resultBlob->getBufferPointer()); - printf("After: \n"); - for (int i = 0; i < length; i++) - { - printf("%f, ", result[i]); - } - printf("\n"); - return true; -} - -RWStructuredBuffer convertBuffer(gfx::IBufferResource* _0) { - RWStructuredBuffer result; - result.data = (float*)_0; - return result; -} - -gfx::IBufferResource *unconvertBuffer(RWStructuredBuffer _0) -{ - return (gfx::IBufferResource *)(_0.data); -} - -int main() -{ - // We construct an instance of our example application - // `struct` type, and then walk through the lifecyle - // of the application. - - if (!(executeComputation())) - { - return -1; - } -} diff --git a/examples/heterogeneous-hello-world/main.slang b/examples/heterogeneous-hello-world/main.slang new file mode 100644 index 000000000..08b4b7f39 --- /dev/null +++ b/examples/heterogeneous-hello-world/main.slang @@ -0,0 +1,10 @@ +// main.slang + +__target_intrinsic(cpp, "printf(\"%s\", ($0).getBuffer())") +public void writeln(String text); + +public __extern_cpp int main() +{ + writeln("hello world"); + return 0; +} \ No newline at end of file diff --git a/examples/heterogeneous-hello-world/shader.slang b/examples/heterogeneous-hello-world/shader.slang deleted file mode 100644 index d87370be1..000000000 --- a/examples/heterogeneous-hello-world/shader.slang +++ /dev/null @@ -1,76 +0,0 @@ -// shader.slang - -//TEST_INPUT:ubuffer(random(float, 4096, -1.0, 1.0), stride=4):name=ioBuffer -__unmangled __exportDirectly RWStructuredBuffer convertBuffer(Ptr x); - -[shader("compute")] -[numthreads(4, 1, 1)] -void computeMain(uniform RWStructuredBuffer ioBuffer, uint3 dispatchThreadID : SV_DispatchThreadID) -{ - uint tid = dispatchThreadID.x; - - float i = ioBuffer[tid]; - float o = i < 0.5 ? (i + i) : sqrt(i); - - ioBuffer[tid] = o; -} - - - -// Forward declarations of gfx types -// -namespace gfx { - __externLib __exportDirectly struct IDevice{}; - __externLib __exportDirectly struct IBufferResource{}; - __exportDirectly struct ITransientResourceHeap{}; - __exportDirectly struct IPipelineState{}; - __exportDirectly struct IShaderProgram{}; - __exportDirectly struct IResourceView{}; -} - -// Forward declarations of cpp functions -// -__unmangled __exportDirectly Ptr createDevice(); -__unmangled __exportDirectly Ptr loadShaderProgram( - Ptr device, - String entryPoint, - String module); -__unmangled __exportDirectly Ptr createStructuredBuffer( - Ptr device, - float[4] initialData); -__unmangled __exportDirectly Ptr createBufferView( - Ptr device, - Ptr buffer); -__unmangled __exportDirectly Ptr buildTransientHeap( - Ptr device); -__unmangled __exportDirectly Ptr buildPipelineState( - Ptr device, - Ptr shaderProgram); -__unmangled __exportDirectly void printInitialValues(float[4] initialArray, int length); -__unmangled __exportDirectly void dispatchComputation( - Ptr device, - Ptr transientHeap, - Ptr pipelineState, - Ptr bufferView); -__unmangled __exportDirectly bool printOutputValues( - Ptr device, - Ptr buffer, - int length); - -public __unmangled __exportDirectly bool executeComputation() { - // We will hard-code the size of our initial array. - // - float initialArray[4] = { 3.0f, -20.0f, -6.0f, 8.0f }; - - // Declare functions - let device = createDevice(); - let structuredBuffer = createStructuredBuffer(device, initialArray); - // let bufferView = createBufferView(device, structuredBuffer); - __GPU_FOREACH(device, uint3(4, 1, 1), LAMBDA(uint3 dispatchThreadID) - { computeMain(convertBuffer(structuredBuffer), dispatchThreadID) ; }); - printInitialValues(initialArray, 4); - printOutputValues(device, structuredBuffer, 4); - - - return true; -} diff --git a/prelude/slang-cpp-host-prelude.h b/prelude/slang-cpp-host-prelude.h new file mode 100644 index 000000000..90087d158 --- /dev/null +++ b/prelude/slang-cpp-host-prelude.h @@ -0,0 +1,16 @@ +#ifndef SLANG_CPP_HOST_PRELUDE_H +#define SLANG_CPP_HOST_PRELUDE_H + +#include +#include +#include + +#include "../source/core/slang-string.h" +#include "../source/core/slang-smart-pointer.h" +#include "../slang-com-ptr.h" +#include "../slang-gfx.h" + +using namespace Slang; +using namespace gfx; + +#endif diff --git a/premake5.lua b/premake5.lua index d5a9d102a..d4b1715a2 100644 --- a/premake5.lua +++ b/premake5.lua @@ -680,30 +680,17 @@ newoption { example "cpu-hello-world" kind "ConsoleApp" - if enableExperimental then - project "heterogeneous-first-gen" - kind "Utility" + project "heterogeneous-hello-world" + kind "ConsoleApp" links "slangc" location("build/" .. slangUtil.getBuildLocationName(targetInfo) .. "/heterogeneous-hello-world") prebuildcommands { - "\"%{wks.location:lower()}/bin/" .. targetName .. "/%{cfg.buildcfg:lower()}/slangc\" \"%{wks.location:lower()}/examples/heterogeneous-hello-world/shader.slang\" -o \"%{wks.location:lower()}/examples/heterogeneous-hello-world/shader.cpp\" -heterogeneous -target cpp -target hlsl" - } - - example "heterogeneous-hello-world" - kind "ConsoleApp" - -- Additionally add slangc for compiling shader.cpp - links { "example-base", "slang", "gfx", "gfx-util", "slangc", "platform", "core", "heterogeneous-first-gen" } - -- Generate shader.cpp from shader.slang - prebuildmessage "Generating shader.cpp in %{wks.location:lower()}/examples/heterogeneous-hello-world/" - prebuildcommands { - "\"%{wks.location:lower()}/bin/" .. targetName .. "/%{cfg.buildcfg:lower()}/slangc\" \"%{wks.location:lower()}/examples/heterogeneous-hello-world/shader.slang\" -o \"%{wks.location:lower()}/examples/heterogeneous-hello-world/shader.cpp\" -heterogeneous -target cpp -target hlsl" - } - files { - "examples/heterogeneous-hello-world/shader.cpp" + "\"%{cfg.targetdir}/slangc\" \"%{wks.location:lower()}/examples/heterogeneous-hello-world/main.slang\" -o \"%{cfg.targetdir}/heterogeneous-hello-world.exe\"" } + files {"examples/heterogeneous-hello-world/*.slang"} + end - -- Most of the other projects have more interesting configuration going -- on, so let's walk through them in order of increasing complexity. -- @@ -754,6 +741,21 @@ newoption { addSourceDir "source/compiler-core/unix" end +standardProject("slang-rt", "source/slang-rt") + uuid "DFC79D72-91DE-434C-871B-B3943B488BEB" + kind "SharedLib" + pic "On" + warnings "Extra" + links {"miniz", "lz4"} + flags { "FatalWarnings" } + defines { "SLANG_RT_DYNAMIC", "SLANG_RT_DYNAMIC_EXPORT" } + addSourceDir "source/core" + if targetInfo.isWindows then + addSourceDir "source/core/windows" + else + addSourceDir "source/core/unix" + end + -- -- The cpp extractor is a tool that scans C++ header files to extract -- reflection like information, and generate files to handle @@ -1213,7 +1215,8 @@ newoption { files { "prelude/slang-cuda-prelude.h.cpp", "prelude/slang-hlsl-prelude.h.cpp", - "prelude/slang-cpp-prelude.h.cpp" + "prelude/slang-cpp-prelude.h.cpp", + "prelude/slang-cpp-host-prelude.h.cpp" } end @@ -1318,7 +1321,8 @@ newoption { files { "prelude/slang-cuda-prelude.h.cpp", "prelude/slang-hlsl-prelude.h.cpp", - "prelude/slang-cpp-prelude.h.cpp" + "prelude/slang-cpp-prelude.h.cpp", + "prelude/slang-cpp-host-prelude.h.cpp" } -- @@ -1396,7 +1400,8 @@ newoption { files { "prelude/slang-cuda-prelude.h.cpp", "prelude/slang-hlsl-prelude.h.cpp", - "prelude/slang-cpp-prelude.h.cpp" + "prelude/slang-cpp-prelude.h.cpp", + "prelude/slang-cpp-host-prelude.h.cpp" } -- Add the slang source diff --git a/slang.h b/slang.h index 1d4c517b5..0de215a33 100644 --- a/slang.h +++ b/slang.h @@ -551,13 +551,14 @@ extern "C" SLANG_DXIL, SLANG_DXIL_ASM, SLANG_C_SOURCE, ///< The C language - SLANG_CPP_SOURCE, ///< The C++ language - SLANG_EXECUTABLE, ///< Executable (for hosting CPU/OS) - SLANG_SHARED_LIBRARY, ///< A shared library/Dll (for hosting CPU/OS) - SLANG_HOST_CALLABLE, ///< A CPU target that makes the compiled code available to be run immediately + SLANG_CPP_SOURCE, ///< C++ code for shader kernels. + SLANG_HOST_EXECUTABLE, ///< Standalone binary executable (for hosting CPU/OS) + SLANG_SHADER_SHARED_LIBRARY, ///< A shared library/Dll for shader kernels (for hosting CPU/OS) + SLANG_SHADER_HOST_CALLABLE, ///< A CPU target that makes the compiled shader code available to be run immediately SLANG_CUDA_SOURCE, ///< Cuda source SLANG_PTX, ///< PTX SLANG_OBJECT_CODE, ///< Object code that can be used for later linking + SLANG_HOST_CPP_SOURCE, ///< C++ code for host library or executable. SLANG_TARGET_COUNT_OF, }; diff --git a/slang.sln b/slang.sln index b4b30eeee..f9584f25d 100644 --- a/slang.sln +++ b/slang.sln @@ -65,6 +65,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang", "build\visual-studi {E145B2B8-CD13-A6BE-B6A7-16E5A2148223} = {E145B2B8-CD13-A6BE-B6A7-16E5A2148223} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slang-rt", "build\visual-studio\slang-rt\slang-rt.vcxproj", "{DFC79D72-91DE-434C-871B-B3943B488BEB}" +EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "slangc", "build\visual-studio\slangc\slangc.vcxproj", "{D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test-tool", "test-tool", "{57B5AA5E-C340-1823-CC51-9B17385C7423}" @@ -387,6 +389,18 @@ Global {DB00DA62-0533-4AFD-B59F-A67D5B3A0808}.Release|Win32.Build.0 = Release|Win32 {DB00DA62-0533-4AFD-B59F-A67D5B3A0808}.Release|x64.ActiveCfg = Release|x64 {DB00DA62-0533-4AFD-B59F-A67D5B3A0808}.Release|x64.Build.0 = Release|x64 + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Debug|aarch64.ActiveCfg = Debug aarch64|ARM + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Debug|aarch64.Build.0 = Debug aarch64|ARM + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Debug|Win32.ActiveCfg = Debug|Win32 + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Debug|Win32.Build.0 = Debug|Win32 + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Debug|x64.ActiveCfg = Debug|x64 + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Debug|x64.Build.0 = Debug|x64 + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Release|aarch64.ActiveCfg = Release aarch64|ARM + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Release|aarch64.Build.0 = Release aarch64|ARM + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Release|Win32.ActiveCfg = Release|Win32 + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Release|Win32.Build.0 = Release|Win32 + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Release|x64.ActiveCfg = Release|x64 + {DFC79D72-91DE-434C-871B-B3943B488BEB}.Release|x64.Build.0 = Release|x64 {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|aarch64.ActiveCfg = Debug aarch64|ARM {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|aarch64.Build.0 = Debug aarch64|ARM {D56CBCEB-1EB5-4CA8-AEC4-48EA35ED61C7}.Debug|Win32.ActiveCfg = Debug|Win32 diff --git a/source/compiler-core/slang-downstream-compiler.h b/source/compiler-core/slang-downstream-compiler.h index dc9e29185..e40ffc13a 100644 --- a/source/compiler-core/slang-downstream-compiler.h +++ b/source/compiler-core/slang-downstream-compiler.h @@ -274,7 +274,7 @@ public: OptimizationLevel optimizationLevel = OptimizationLevel::Default; DebugInfoType debugInfoType = DebugInfoType::Standard; - SlangCompileTarget targetType = SLANG_EXECUTABLE; + SlangCompileTarget targetType = SLANG_HOST_EXECUTABLE; SlangSourceLanguage sourceLanguage = SLANG_SOURCE_LANGUAGE_CPP; FloatingPointMode floatingPointMode = FloatingPointMode::Default; PipelineType pipelineType = PipelineType::Unknown; @@ -302,6 +302,9 @@ public: List includePaths; List libraryPaths; + /// Libraries to link against. + List libraries; + List requiredCapabilityVersions; /// For compilers/compiles that require an entry point name, else can be empty diff --git a/source/compiler-core/slang-gcc-compiler-util.cpp b/source/compiler-core/slang-gcc-compiler-util.cpp index b5c359247..8d1b87b68 100644 --- a/source/compiler-core/slang-gcc-compiler-util.cpp +++ b/source/compiler-core/slang-gcc-compiler-util.cpp @@ -415,12 +415,12 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse switch (options.targetType) { - case SLANG_SHARED_LIBRARY: + case SLANG_SHADER_SHARED_LIBRARY: { outPath << SharedLibrary::calcPlatformPath(options.modulePath.getUnownedSlice()); return SLANG_OK; } - case SLANG_EXECUTABLE: + case SLANG_HOST_EXECUTABLE: { outPath << options.modulePath; outPath << Process::getExecutableSuffix(); @@ -547,7 +547,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse switch (options.targetType) { - case SLANG_SHARED_LIBRARY: + case SLANG_SHADER_SHARED_LIBRARY: { // Shared library cmdLine.addArg("-shared"); @@ -559,7 +559,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse } break; } - case SLANG_EXECUTABLE: + case SLANG_HOST_EXECUTABLE: { break; } @@ -601,7 +601,7 @@ static SlangResult _parseGCCFamilyLine(const UnownedStringSlice& line, LineParse //cmdLine.addArg(linkOptions); } - if (options.targetType == SLANG_SHARED_LIBRARY) + if (options.targetType == SLANG_SHADER_SHARED_LIBRARY) { if (!PlatformUtil::isFamily(PlatformFamily::Apple, platformKind)) { diff --git a/source/compiler-core/slang-visual-studio-compiler-util.cpp b/source/compiler-core/slang-visual-studio-compiler-util.cpp index 9bdfd406a..2ba69c1ce 100644 --- a/source/compiler-core/slang-visual-studio-compiler-util.cpp +++ b/source/compiler-core/slang-visual-studio-compiler-util.cpp @@ -23,12 +23,12 @@ namespace Slang switch (options.targetType) { - case SLANG_SHARED_LIBRARY: + case SLANG_SHADER_SHARED_LIBRARY: { outPath << options.modulePath << ".dll"; return SLANG_OK; } - case SLANG_EXECUTABLE: + case SLANG_HOST_EXECUTABLE: { outPath << options.modulePath << ".exe"; return SLANG_OK; @@ -60,7 +60,7 @@ namespace Slang { outPaths.add(options.modulePath + ".ilk"); - if (options.targetType == SLANG_SHARED_LIBRARY) + if (options.targetType == SLANG_SHADER_SHARED_LIBRARY) { outPaths.add(options.modulePath + ".exp"); outPaths.add(options.modulePath + ".lib"); @@ -191,7 +191,7 @@ namespace Slang switch (options.targetType) { - case SLANG_SHARED_LIBRARY: + case SLANG_SHADER_SHARED_LIBRARY: { // Create dynamic link library if (options.debugInfoType == DebugInfoType::None) @@ -206,7 +206,7 @@ namespace Slang cmdLine.addPrefixPathArg("/Fe", options.modulePath, ".dll"); break; } - case SLANG_EXECUTABLE: + case SLANG_HOST_EXECUTABLE: { cmdLine.addPrefixPathArg("/Fe", options.modulePath, ".exe"); break; @@ -256,6 +256,12 @@ namespace Slang cmdLine.addPrefixPathArg("/LIBPATH:", libPath); } + // Link libraries. + for (const auto& lib : options.libraries) + { + cmdLine.addPrefixPathArg("", lib, ".lib"); + } + return SLANG_OK; } diff --git a/source/core/slang-common.h b/source/core/slang-common.h index f17660e0d..694162f1d 100644 --- a/source/core/slang-common.h +++ b/source/core/slang-common.h @@ -94,3 +94,22 @@ template void slang_use_obj(T&) {} #define SLANG_UNREFERENCED_PARAMETER(P) slang_use_obj(P) #define SLANG_UNREFERENCED_VARIABLE(P) slang_use_obj(P) #endif + +#if defined(SLANG_RT_DYNAMIC) +#if defined(_MSC_VER) +# ifdef SLANG_RT_DYNAMIC_EXPORT +# define SLANG_RT_API SLANG_DLL_EXPORT +# else +# define SLANG_RT_API __declspec(dllimport) +# endif +#else +// TODO: need to consider compiler capabilities +//# ifdef SLANG_RT_DYNAMIC_EXPORT +# define SLANG_RT_API SLANG_DLL_EXPORT +//# endif +#endif +#endif + +#ifndef SLANG_RT_API +#define SLANG_RT_API +#endif diff --git a/source/core/slang-smart-pointer.h b/source/core/slang-smart-pointer.h index 2e5821ffd..a6aa35906 100644 --- a/source/core/slang-smart-pointer.h +++ b/source/core/slang-smart-pointer.h @@ -10,7 +10,7 @@ namespace Slang { // Base class for all reference-counted objects - class RefObject + class SLANG_RT_API RefObject { private: UInt referenceCount; @@ -86,8 +86,7 @@ namespace Slang SLANG_FORCE_INLINE const T* as(const RefObject* obj) { return dynamicCast(obj); } // "Smart" pointer to a reference-counted object - template - struct RefPtr + template struct SLANG_RT_API RefPtr { RefPtr() : pointer(nullptr) diff --git a/source/core/slang-string.h b/source/core/slang-string.h index cb13ec415..6dc3275eb 100644 --- a/source/core/slang-string.h +++ b/source/core/slang-string.h @@ -62,7 +62,7 @@ namespace Slang return (((unsigned char)ch) & 0xC0) == 0x80; } - struct UnownedStringSlice + struct SLANG_RT_API UnownedStringSlice { public: typedef UnownedStringSlice ThisType; @@ -190,7 +190,7 @@ namespace Slang // A `StringRepresentation` provides the backing storage for // all reference-counted string-related types. - class StringRepresentation : public RefObject + class SLANG_RT_API StringRepresentation : public RefObject { public: Index length; @@ -286,7 +286,7 @@ namespace Slang - struct UnownedTerminatedStringSlice : public UnownedStringSlice + struct SLANG_RT_API UnownedTerminatedStringSlice : public UnownedStringSlice { public: UnownedTerminatedStringSlice(char const* b) @@ -294,7 +294,7 @@ namespace Slang {} }; - struct StringSlice + struct SLANG_RT_API StringSlice { public: StringSlice(); @@ -333,7 +333,7 @@ namespace Slang }; /// String as expected by underlying platform APIs - class OSString + class SLANG_RT_API OSString { public: /// Default @@ -394,7 +394,7 @@ namespace Slang @brief Represents a UTF-8 encoded string. */ - class String + class SLANG_RT_API String { friend struct StringSlice; friend class StringBuilder; @@ -837,7 +837,7 @@ namespace Slang } }; - class StringBuilder : public String + class SLANG_RT_API StringBuilder : public String { private: enum { InitialSize = 1024 }; diff --git a/source/core/slang-token-reader.cpp b/source/core/slang-token-reader.cpp index 3be010751..7ffbc12fa 100644 --- a/source/core/slang-token-reader.cpp +++ b/source/core/slang-token-reader.cpp @@ -681,9 +681,6 @@ namespace Misc { { switch (data[i]) { - case ' ': - sb << "\\s"; - break; case '\n': sb << "\\n"; break; diff --git a/source/core/slang-token-reader.h b/source/core/slang-token-reader.h index 26539732c..bf5ca4cdc 100644 --- a/source/core/slang-token-reader.h +++ b/source/core/slang-token-reader.h @@ -295,6 +295,8 @@ namespace Misc { return result; } + String EscapeStringLiteral(String str); + String UnescapeStringLiteral(String str); } // namespace Misc } // namespace Slang diff --git a/source/core/slang-type-convert-util.cpp b/source/core/slang-type-convert-util.cpp index fbf385319..6e6598357 100644 --- a/source/core/slang-type-convert-util.cpp +++ b/source/core/slang-type-convert-util.cpp @@ -17,6 +17,7 @@ namespace Slang case SLANG_HLSL: return SLANG_SOURCE_LANGUAGE_HLSL; case SLANG_C_SOURCE: return SLANG_SOURCE_LANGUAGE_C; case SLANG_CPP_SOURCE: return SLANG_SOURCE_LANGUAGE_CPP; + case SLANG_HOST_CPP_SOURCE: return SLANG_SOURCE_LANGUAGE_CPP; case SLANG_CUDA_SOURCE: return SLANG_SOURCE_LANGUAGE_CUDA; default: break; } diff --git a/source/core/slang-type-text-util.cpp b/source/core/slang-type-text-util.cpp index 5be097d15..13bf439ce 100644 --- a/source/core/slang-type-text-util.cpp +++ b/source/core/slang-type-text-util.cpp @@ -68,11 +68,12 @@ static const CompileTargetInfo s_compileTargetInfos[] = { SLANG_SPIRV_ASM, "spv.asm", "spirv-asm,spirv-assembly" }, { SLANG_C_SOURCE, "c", "c" }, { SLANG_CPP_SOURCE, "cpp,c++,cxx", "cpp,c++,cxx" }, - { SLANG_EXECUTABLE, "exe", "exe,executable" }, - { SLANG_SHARED_LIBRARY, "dll,so", "sharedlib,sharedlibrary,dll" }, + { SLANG_HOST_CPP_SOURCE, "cpp,c++,cxx", "cpp,c++,cxx"}, + { SLANG_HOST_EXECUTABLE,"exe", "exe,executable" }, + { SLANG_SHADER_SHARED_LIBRARY, "dll,so", "sharedlib,sharedlibrary,dll" }, { SLANG_CUDA_SOURCE, "cu", "cuda,cu" }, { SLANG_PTX, "ptx", "ptx" }, - { SLANG_HOST_CALLABLE, "", "host-callable,callable" }, + { SLANG_SHADER_HOST_CALLABLE, "", "host-callable,callable" }, { SLANG_OBJECT_CODE, "obj,o", "object-code" }, }; diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang index 779900fd5..c8e05d769 100644 --- a/source/slang/core.meta.slang +++ b/source/slang/core.meta.slang @@ -66,22 +66,10 @@ syntax snorm : SNormModifier; /// Modifier to indicate that a function name should not be mangled /// by the Slang compiler. /// -/// The `__unmangled` modifier should only be valid on functions -/// and is mainly useful for the experimental heterogeneous -/// features of Slang. +/// The `__extern_cpp` modifier makes a symbol to have unmangled +/// name in source/output C++ code. /// -syntax __unmangled : UnmangledModifier; - -/// Modifier to indicate that a function name should be exported -/// directly. Used in tandem with `__unmangled` in heterogeneous -/// features of Slang. -/// -syntax __exportDirectly : __exportDirectly; - -/// Modifier to indicate that a struct is defined externally and -/// should therefore not be exported by Slang. -/// -syntax __externLib : __externLib; +syntax __extern_cpp : ExternCppModifier; /// A type that can be used as an operand for builtins [sealed] diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h index ae9e0924e..35a8ea317 100644 --- a/source/slang/slang-ast-modifier.h +++ b/source/slang/slang-ast-modifier.h @@ -28,9 +28,7 @@ class PostfixModifier : public Modifier { SLANG_AST_CLASS(PostfixModifier)}; class ExportedModifier : public Modifier { SLANG_AST_CLASS(ExportedModifier)}; class ConstExprModifier : public Modifier { SLANG_AST_CLASS(ConstExprModifier)}; class GloballyCoherentModifier : public Modifier { SLANG_AST_CLASS(GloballyCoherentModifier)}; -class UnmangledModifier : public Modifier { SLANG_AST_CLASS(UnmangledModifier)}; -class __exportDirectly : public Modifier { SLANG_AST_CLASS(__exportDirectly)}; -class __externLib : public Modifier { SLANG_AST_CLASS(__externLib)}; +class ExternCppModifier : public Modifier { SLANG_AST_CLASS(ExternCppModifier)}; /// A modifier that indicates an `InheritanceDecl` should be ignored during name lookup (and related checks). class IgnoreForLookupModifier : public Modifier { SLANG_AST_CLASS(IgnoreForLookupModifier) }; diff --git a/source/slang/slang-compiler.cpp b/source/slang/slang-compiler.cpp index 39d558c01..14912d719 100644 --- a/source/slang/slang-compiler.cpp +++ b/source/slang/slang-compiler.cpp @@ -55,7 +55,19 @@ namespace Slang // !!!!!!!!!!!!!!!!!!!!!! free functions for DiagnosicSink !!!!!!!!!!!!!!!!!!!!!!!!!!!!! - void printDiagnosticArg(StringBuilder& sb, CodeGenTarget val) +bool isHeterogeneousTarget(CodeGenTarget target) +{ + switch (target) + { + case CodeGenTarget::HostCPPSource: + case CodeGenTarget::HostExecutable: + return true; + default: + return false; + } +} + +void printDiagnosticArg(StringBuilder& sb, CodeGenTarget val) { switch (val) { @@ -527,6 +539,7 @@ namespace Slang case CodeGenTarget::HLSL: case CodeGenTarget::CUDASource: case CodeGenTarget::CPPSource: + case CodeGenTarget::HostCPPSource: case CodeGenTarget::CSource: { return PassThroughMode::None; @@ -555,9 +568,9 @@ namespace Slang { return PassThroughMode::Glslang; } - case CodeGenTarget::HostCallable: - case CodeGenTarget::SharedLibrary: - case CodeGenTarget::Executable: + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::ShaderSharedLibrary: + case CodeGenTarget::HostExecutable: { // We need some C/C++ compiler return PassThroughMode::GenericCCpp; @@ -973,12 +986,11 @@ namespace Slang { switch (target) { - case CodeGenTarget::HostCallable: - case CodeGenTarget::SharedLibrary: - case CodeGenTarget::Executable: - { + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::ShaderSharedLibrary: return CodeGenTarget::CPPSource; - } + case CodeGenTarget::HostExecutable: + return CodeGenTarget::HostCPPSource; case CodeGenTarget::PTX: return CodeGenTarget::CUDASource; case CodeGenTarget::DXBytecode: return CodeGenTarget::HLSL; case CodeGenTarget::DXIL: return CodeGenTarget::HLSL; @@ -988,6 +1000,17 @@ namespace Slang return CodeGenTarget::Unknown; } + static bool _isCPUHostTarget(CodeGenTarget target) + { + switch (target) + { + case CodeGenTarget::HostCPPSource: + case CodeGenTarget::HostExecutable: + return true; + default: + return false; + } + } SlangResult emitWithDownstreamForEntryPoints( ComponentType* program, @@ -1027,7 +1050,7 @@ namespace Slang return SLANG_FAIL; } } - + SLANG_ASSERT(compilerType != PassThroughMode::None); // Get the required downstream compiler @@ -1259,9 +1282,18 @@ namespace Slang } // If we aren't using LLVM 'host callable', we want downstream compile to produce a shared library - if (compilerType != PassThroughMode::LLVM && target == CodeGenTarget::HostCallable) + if (compilerType != PassThroughMode::LLVM && target == CodeGenTarget::ShaderHostCallable) { - target = CodeGenTarget::SharedLibrary; + target = CodeGenTarget::ShaderSharedLibrary; + } + + if (!isPassThroughEnabled(endToEndReq)) + { + if (_isCPUHostTarget(target)) + { + options.libraryPaths.add(Path::getParentDirectory(Path::getExecutablePath())); + options.libraries.add("slang-rt"); + } } options.targetType = (SlangCompileTarget)target; @@ -1527,9 +1559,9 @@ namespace Slang case CodeGenTarget::DXIL: case CodeGenTarget::DXBytecode: case CodeGenTarget::PTX: - case CodeGenTarget::HostCallable: - case CodeGenTarget::SharedLibrary: - case CodeGenTarget::Executable: + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::ShaderSharedLibrary: + case CodeGenTarget::HostExecutable: { RefPtr downstreamResult; @@ -1583,9 +1615,9 @@ namespace Slang case CodeGenTarget::DXIL: case CodeGenTarget::DXBytecode: case CodeGenTarget::PTX: - case CodeGenTarget::HostCallable: - case CodeGenTarget::SharedLibrary: - case CodeGenTarget::Executable: + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::ShaderSharedLibrary: + case CodeGenTarget::HostExecutable: { RefPtr downstreamResult; @@ -1606,6 +1638,7 @@ namespace Slang case CodeGenTarget::HLSL: case CodeGenTarget::CUDASource: case CodeGenTarget::CPPSource: + case CodeGenTarget::HostCPPSource: case CodeGenTarget::CSource: { RefPtr extensionTracker = _newExtensionTracker(target); @@ -1796,7 +1829,7 @@ namespace Slang ComPtr blob; if (SLANG_FAILED(result.getBlob(blob))) { - if (targetReq->getTarget() == CodeGenTarget::HostCallable) + if (targetReq->getTarget() == CodeGenTarget::ShaderHostCallable) { // Some HostCallable are not directly representable as a 'binary'. // So here, we just ignore if that appears the case, and don't output an unexpected error. @@ -1840,9 +1873,9 @@ namespace Slang case CodeGenTarget::PTX: // For now we just dump PTX out as hex - case CodeGenTarget::HostCallable: - case CodeGenTarget::SharedLibrary: - case CodeGenTarget::Executable: + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::ShaderSharedLibrary: + case CodeGenTarget::HostExecutable: HexDumpUtil::dumpWithMarkers((const uint8_t*)blobData, blobSize, 24, writer); break; @@ -2453,11 +2486,12 @@ namespace Slang case CodeGenTarget::CSource: return ".c"; case CodeGenTarget::CUDASource: return ".cu"; case CodeGenTarget::CPPSource: return ".cpp"; + case CodeGenTarget::HostCPPSource: return ".cpp"; // What these should be called is target specific, but just use these exts to make clear for now // for now - case CodeGenTarget::Executable: return ".exe"; - case CodeGenTarget::HostCallable: - case CodeGenTarget::SharedLibrary: return ".shared-lib"; + case CodeGenTarget::HostExecutable: return ".exe"; + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::ShaderSharedLibrary: return ".shared-lib"; default: break; } return nullptr; @@ -2475,6 +2509,7 @@ namespace Slang switch (target) { case CodeGenTarget::CPPSource: + case CodeGenTarget::HostCPPSource: case CodeGenTarget::CUDASource: case CodeGenTarget::CSource: case CodeGenTarget::DXILAssembly: @@ -2513,9 +2548,9 @@ namespace Slang break; } - case CodeGenTarget::HostCallable: - case CodeGenTarget::SharedLibrary: - case CodeGenTarget::Executable: + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::ShaderSharedLibrary: + case CodeGenTarget::HostExecutable: { dumpIntermediateBinary(compileRequest, data, size, _getTargetExtension(target)); break; diff --git a/source/slang/slang-compiler.h b/source/slang/slang-compiler.h index 5f14fb4f6..7f8257777 100755 --- a/source/slang/slang-compiler.h +++ b/source/slang/slang-compiler.h @@ -71,15 +71,18 @@ namespace Slang DXILAssembly = SLANG_DXIL_ASM, CSource = SLANG_C_SOURCE, CPPSource = SLANG_CPP_SOURCE, - Executable = SLANG_EXECUTABLE, - SharedLibrary = SLANG_SHARED_LIBRARY, - HostCallable = SLANG_HOST_CALLABLE, + HostCPPSource = SLANG_HOST_CPP_SOURCE, + HostExecutable = SLANG_HOST_EXECUTABLE, + ShaderSharedLibrary = SLANG_SHADER_SHARED_LIBRARY, + ShaderHostCallable = SLANG_SHADER_HOST_CALLABLE, CUDASource = SLANG_CUDA_SOURCE, PTX = SLANG_PTX, ObjectCode = SLANG_OBJECT_CODE, CountOf = SLANG_TARGET_COUNT_OF, }; + bool isHeterogeneousTarget(CodeGenTarget target); + void printDiagnosticArg(StringBuilder& sb, CodeGenTarget val); enum class ContainerFormat : SlangContainerFormat @@ -1457,6 +1460,7 @@ namespace Slang { lineDirectiveMode = mode; } + void setDumpIntermediates(bool value) { dumpIntermediates = value; @@ -1658,9 +1662,6 @@ namespace Slang bool m_obfuscateCode = false; - // Determine whether to output heterogeneity-related code - bool m_heterogeneous = false; - /// Holds any args that are destined for downstream compilers/tools etc DownstreamArgs m_downstreamArgs; diff --git a/source/slang/slang-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp index d3dd0e5b8..eb178a366 100644 --- a/source/slang/slang-emit-c-like.cpp +++ b/source/slang/slang-emit-c-like.cpp @@ -78,6 +78,7 @@ struct CLikeSourceEmitter::ComputeEmitActionsContext return SourceLanguage::C; } case CodeGenTarget::CPPSource: + case CodeGenTarget::HostCPPSource: { return SourceLanguage::CPP; } @@ -741,28 +742,6 @@ String CLikeSourceEmitter::_generateUniqueName(const UnownedStringSlice& name) String CLikeSourceEmitter::generateName(IRInst* inst) { - // Handle `__exportDirectly` decoration before all else - if (inst->findDecoration()) - { - // If instruction has a NameHint, we naively emit it as a namespace - // This is automatically handled in `getNameforNameHint` when the - // `__exportDirectly` decoration is found, so we can just return it. - // TODO: This is a very hacky solution. - // - // Another option would be to have two separate decorations, one that - // handles this namespace, and a separate decoration for unmangled names. - if (auto nameHintDecoration = inst->findDecoration()) - { - return nameHintDecoration->getName(); - } - // Otherwise, we just want the instruction to not be mangled, which is - // similarly handled in `getMangledName`. - if (auto linkageDecoration = inst->findDecoration()) - { - return linkageDecoration->getMangledName(); - } - } - // If the instruction names something // that should be emitted as a target intrinsic, // then use that name instead. @@ -802,6 +781,13 @@ String CLikeSourceEmitter::generateName(IRInst* inst) return generateEntryPointNameImpl(entryPointDecor); } + // If the instruction has a linkage decoration, just use that. + if (auto externCppDecoration = inst->findDecoration()) + { + // Just use the linkages mangled name directly. + return externCppDecoration->getName(); + } + // If we have a name hint on the instruction, then we will try to use that // to provide the basis for the actual name in the output code. if(auto nameHintDecoration = inst->findDecoration()) @@ -2915,13 +2901,6 @@ void CLikeSourceEmitter::emitStruct(IRStructType* structType) return; } - // If the selected `struct` type is externally defined - // then we also don't want to emit anything. - if (auto externLibDecoration = structType->findDecoration()) - { - return; - } - m_writer->emit("struct "); emitPostKeywordTypeAttributes(structType); diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp index e06aa8372..e7b7af991 100644 --- a/source/slang/slang-emit-cpp.cpp +++ b/source/slang/slang-emit-cpp.cpp @@ -2,7 +2,7 @@ #include "slang-emit-cpp.h" #include "../core/slang-writer.h" - +#include "../core/slang-token-reader.h" #include "slang-emit-source-writer.h" #include "slang-mangled-lexer.h" @@ -167,6 +167,31 @@ static UnownedStringSlice _getCTypeVecPostFix(IROp op) } } +static bool _isCppTarget(CodeGenTarget target) +{ + switch (target) + { + case CodeGenTarget::CPPSource: + case CodeGenTarget::HostCPPSource: + return true; + default: + return false; + } +} + +static bool _isCppOrCudaTarget(CodeGenTarget target) +{ + switch (target) + { + case CodeGenTarget::CPPSource: + case CodeGenTarget::HostCPPSource: + case CodeGenTarget::CUDASource: + return true; + default: + return false; + } +} + /* !!!!!!!!!!!!!!!!!!!!!!!! CPPEmitHandler !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */ /* static */ UnownedStringSlice CPPSourceEmitter::getBuiltinTypeName(IROp op) @@ -198,7 +223,7 @@ static UnownedStringSlice _getCTypeVecPostFix(IROp op) void CPPSourceEmitter::emitTypeDefinition(IRType* inType) { - if (m_target == CodeGenTarget::CPPSource) + if (_isCppTarget(m_target)) { // All types are templates in C++ return; @@ -432,7 +457,7 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S auto vecCount = int(getIntVal(vecType->getElementCount())); auto elemType = vecType->getElementType(); - if (target == CodeGenTarget::CPPSource || target == CodeGenTarget::CUDASource) + if (_isCppOrCudaTarget(target)) { out << "Vector<" << _getTypeName(elemType) << ", " << vecCount << ">"; } @@ -458,7 +483,7 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S const auto rowCount = int(getIntVal(matType->getRowCount())); const auto colCount = int(getIntVal(matType->getColumnCount())); - if (target == CodeGenTarget::CPPSource || target == CodeGenTarget::CUDASource) + if (_isCppOrCudaTarget(target)) { out << "Matrix<" << _getTypeName(elementType) << ", " << rowCount << ", " << colCount << ">"; } @@ -542,6 +567,11 @@ SlangResult CPPSourceEmitter::calcTypeName(IRType* type, CodeGenTarget target, S out << "TypeInfo*"; return SLANG_OK; } + case kIROp_StringType: + { + out << "String"; + return SLANG_OK; + } default: { if (isNominalOp(type->getOp())) @@ -2326,6 +2356,14 @@ bool CPPSourceEmitter::tryEmitInstExprImpl(IRInst* inst, const EmitOpInfo& inOut m_writer->emit("))"); return true; } + case kIROp_StringLit: + { + m_writer->emit("String("); + m_writer->emit(Slang::Misc::EscapeStringLiteral(as(inst)->getStringSlice())); + m_writer->emit(")"); + return true; + } + } } @@ -2361,10 +2399,9 @@ void CPPSourceEmitter::emitPreprocessorDirectivesImpl() if (m_target == CodeGenTarget::CPPSource) { - // Put all into an anonymous namespace - // This includes any generated types, and generated intrinsics - if (!m_compileRequest->getLinkage()->m_heterogeneous) - m_writer->emit("namespace { // anonymous \n\n"); + // When generating kernel code in C++, put all into an anonymous namespace + // This includes any generated types, and generated intrinsics. + m_writer->emit("namespace { // anonymous \n\n"); m_writer->emit("#ifdef SLANG_PRELUDE_NAMESPACE\n"); m_writer->emit("using namespace SLANG_PRELUDE_NAMESPACE;\n"); m_writer->emit("#endif\n\n"); @@ -2629,130 +2666,7 @@ void CPPSourceEmitter::_emitForwardDeclarations(const List& actions) void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink) { - // If we are emitting a heterogeneous program - // Emit the binary blob of each non-CPP target - ComponentType* program = m_compileRequest->getProgram(); - auto linkage = m_compileRequest->getLinkage(); - if (linkage->m_heterogeneous) - { - for (auto inst : module->getGlobalInsts()) - { - auto func = as(inst); - if (!func) - continue; - if (auto entryPointDecoration = func->findDecoration()) - { - String entryPointName = entryPointDecoration->getName()->getStringSlice(); - String moduleName = entryPointDecoration->getModuleName()->getStringSlice(); - for (int index = 0; index < program->getEntryPointCount(); index++) - { - auto entryPoint = program->getEntryPoint(index); - if (entryPointName == entryPoint->getName()->text) - { - for (auto targetRequest : linkage->targets) - { - // Emit for all non-CPU targets - switch (targetRequest->getTarget()) - { - case(CodeGenTarget::CPPSource): - case(CodeGenTarget::CSource): - case(CodeGenTarget::HostCallable): - case(CodeGenTarget::CUDASource): - - break; - - default: - - auto targetProgram = program->getTargetProgram(targetRequest); - CompileResult result = - targetProgram->getOrCreateEntryPointResult(index, sink); - - Slang::ComPtr blob; - if (SLANG_FAILED(result.getBlob(blob))) - { - sink->diagnoseRaw(Severity::Error, - "Slang heterogeneous error: No blob to emit\n"); - m_writer->emit("size_t __"); - m_writer->emit(entryPointName); - m_writer->emit("Size = 0;\n"); - m_writer->emit("unsigned char __"); - m_writer->emit(entryPointName); - m_writer->emit("[1];\n"); - } - - else - { - // auto ptr = (const unsigned char*)blob->getBufferPointer(); - - // m_writer->emit("size_t __"); - // m_writer->emit(entryPointName); - // m_writer->emit("Size = "); - // m_writer->emitInt64(blob->getBufferSize()); - // m_writer->emit(";\n"); - - // m_writer->emit("unsigned char __"); - // m_writer->emit(entryPointName); - // m_writer->emit("[] = {"); - // every 20 bytes, emit a newline - // size_t j = 0; - // for (size_t i = 0; i < blob->getBufferSize(); i++) { - // m_writer->emitUInt64(ptr[i]); - // m_writer->emit(", "); - // if (j == 20) - // { - // m_writer->emit("\n"); - // j = 0; - // } - // j++; - // } - // m_writer->emit("};\n"); - } - } - } - // Hardcode in (for now) an include for slang-gfx.h so that we can make use - // of the gfx namespace - // - // TODO: Aside from making sure this approach is viable, it would also be - // much better to allow this to be done by the programmer in the Slang file. - m_writer->emit("#include \"slang-gfx.h\"\n\n"); - - // Emit boilerplate that requires gfx. - // This is required by the wrapper, so that will be the next place to look - // as far as removing boilerplate goes. - m_writer->emit("gfx::IShaderProgram* loadShaderProgram(gfx::IDevice* _0, char* _1, char* _2);\n"); - m_writer->emit("gfx::ITransientResourceHeap* buildTransientHeap(gfx::IDevice* _0);\n"); - m_writer->emit("gfx::IPipelineState* buildPipelineState(gfx::IDevice* _0, gfx::IShaderProgram* _1);\n"); - m_writer->emit("void dispatchComputation(gfx::IDevice* _0, gfx::ITransientResourceHeap* _1, gfx::IPipelineState* _2, gfx::IResourceView* _3, uint32_t gridDimsX, uint32_t gridDimsY, uint32_t gridDimsZ);\n"); - m_writer->emit("gfx::IResourceView* createBufferView(gfx::IDevice* _0, gfx::IBufferResource* _1);\n"); - m_writer->emit("gfx::IBufferResource* unconvertBuffer(RWStructuredBuffer _0);\n\n"); - - // Emit a wrapper function for calling the shader blob - m_writer->emit("void "); - m_writer->emit(entryPointName); - m_writer->emit("_wrapper(gfx::IDevice* device, Vector gridDims, \n"); - m_writer->emit("\tRWStructuredBuffer buffer)\n{"); - /* m_writer->emit("\n\tgfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(device, __"); - m_writer->emit(entryPointName); - m_writer->emit(", __"); - m_writer->emit(entryPointName); - m_writer->emit("Size);");*/ - m_writer->emit("\n\tgfx::IShaderProgram* shaderProgram = loadShaderProgram(device, \""); - m_writer->emit(entryPointName); - m_writer->emit("\", \""); - m_writer->emit(moduleName); - m_writer->emit("\");"); - m_writer->emit("\n\tgfx::ITransientResourceHeap* transientHeap = buildTransientHeap(device);"); - m_writer->emit("\n\tgfx::IPipelineState* pipelineState = "); - m_writer->emit("buildPipelineState(device, shaderProgram);"); - m_writer->emit("\n\tgfx::IResourceView* bufferView = createBufferView(device, unconvertBuffer(buffer));"); - m_writer->emit("\n\tdispatchComputation(device, transientHeap, pipelineState, "); - m_writer->emit("bufferView, gridDims.x, gridDims.y, gridDims.z);"); - m_writer->emit("\n}\n"); - } - } - } - } - } + SLANG_UNUSED(sink); // Setup all built in types used in the module m_typeSet.addAllBuiltinTypes(module); @@ -2790,9 +2704,8 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink) if (m_target == CodeGenTarget::CPPSource) { - // Need to close the anonymous namespace when outputting for C++ - if (!linkage->m_heterogeneous) - m_writer->emit("} // anonymous\n\n"); + // Need to close the anonymous namespace when outputting for C++ kernel. + m_writer->emit("} // anonymous\n\n"); } // Finally we need to output dll entry points diff --git a/source/slang/slang-emit.cpp b/source/slang/slang-emit.cpp index a0ac30857..23f06e8e9 100644 --- a/source/slang/slang-emit.cpp +++ b/source/slang/slang-emit.cpp @@ -59,6 +59,8 @@ #include +Slang::String get_slang_cpp_host_prelude(); + namespace Slang { EntryPointLayout* findEntryPointLayout( @@ -257,6 +259,8 @@ Result linkAndOptimizeIR( CollectEntryPointUniformParamsOptions passOptions; switch( target ) { + case CodeGenTarget::HostCPPSource: + break; case CodeGenTarget::CUDASource: collectOptiXEntryPointUniformParams(irModule); #if 0 @@ -286,7 +290,7 @@ Result linkAndOptimizeIR( #endif validateIRModuleIfEnabled(compileRequest, irModule); break; - + case CodeGenTarget::HostCPPSource: case CodeGenTarget::CPPSource: case CodeGenTarget::CUDASource: break; @@ -873,6 +877,11 @@ SlangResult emitEntryPointsSourceFromIR( sourceEmitter->emitPreludeDirectives(); + if (isHeterogeneousTarget(target)) + { + sourceWriter.emit(get_slang_cpp_host_prelude()); + } + else { // If there is a prelude emit it const auto& prelude = compileRequest->getSession()->getPreludeForLanguage(sourceLanguage); diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h index a3486ee68..bcc42ad9e 100644 --- a/source/slang/slang-ir-inst-defs.h +++ b/source/slang/slang-ir-inst-defs.h @@ -558,9 +558,6 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) INST(InstanceDecoration, instance, 1, 0) INST(NumThreadsDecoration, numThreads, 3, 0) - INST(__exportDirectly, __exportDirectly, 0, 0) - INST(__externLib, __externLib, 0, 0) - // Added to IRParam parameters to an entry point /* GeometryInputPrimitiveTypeDecoration */ INST(PointInputPrimitiveTypeDecoration, pointPrimitiveType, 0, 0) @@ -604,6 +601,9 @@ INST(HighLevelDeclDecoration, highLevelDecl, 1, 0) INST(ExportDecoration, export, 1, 0) INST_RANGE(LinkageDecoration, ImportDecoration, ExportDecoration) + /// An extern_cpp decoration marks the inst to emit its name without mangling for C++ interop. + INST(ExternCppDecoration, externCpp, 1, 0) + /* Decorations for RTTI objects */ INST(RTTITypeSizeDecoration, RTTI_typeSize, 1, 0) INST(AnyValueSizeDecoration, AnyValueSize, 1, 0) diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h index 09a3bdbb3..102c48495 100644 --- a/source/slang/slang-ir-insts.h +++ b/source/slang/slang-ir-insts.h @@ -269,8 +269,6 @@ IR_SIMPLE_DECORATION(PublicDecoration) IR_SIMPLE_DECORATION(KeepAliveDecoration) IR_SIMPLE_DECORATION(RequiresNVAPIDecoration) IR_SIMPLE_DECORATION(NoInlineDecoration) -IR_SIMPLE_DECORATION(__exportDirectly) -IR_SIMPLE_DECORATION(__externLib) struct IRNVAPIMagicDecoration : IRDecoration { @@ -419,6 +417,19 @@ struct IRExportDecoration : IRLinkageDecoration IR_LEAF_ISA(ExportDecoration) }; +struct IRExternCppDecoration : IRDecoration +{ + enum + { + kOp = kIROp_ExternCppDecoration + }; + IR_LEAF_ISA(ExternCppDecoration) + + IRStringLit* getNameOperand() { return cast(getOperand(0)); } + + UnownedStringSlice getName() { return getNameOperand()->getStringSlice(); } +}; + struct IRFormatDecoration : IRDecoration { enum { kOp = kIROp_FormatDecoration }; @@ -2795,6 +2806,11 @@ public: addDecoration(value, kIROp_ExportDecoration, getStringValue(mangledName)); } + void addExternCppDecoration(IRInst* value, UnownedStringSlice const& mangledName) + { + addDecoration(value, kIROp_ExternCppDecoration, getStringValue(mangledName)); + } + void addEntryPointDecoration(IRInst* value, Profile profile, UnownedStringSlice const& name, UnownedStringSlice const& moduleName) { IRInst* operands[] = { getIntValue(getIntType(), profile.raw), getStringValue(name), getStringValue(moduleName) }; @@ -2866,16 +2882,6 @@ public: { addDecoration(inst, kIROp_SequentialIDDecoration, getIntValue(getUIntType(), id)); } - - void addExportDirectlyDecoration(IRInst* value) - { - addDecoration(value, kIROp___exportDirectly); - } - - void addExternLibDecoration(IRInst* value) - { - addDecoration(value, kIROp___externLib); - } }; void addHoistableInst( diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp index 9ec8c1c71..779034979 100644 --- a/source/slang/slang-lower-to-ir.cpp +++ b/source/slang/slang-lower-to-ir.cpp @@ -1047,13 +1047,9 @@ static void addLinkageDecoration( builder->addPublicDecoration(inst); builder->addKeepAliveDecoration(inst); } - if (decl->findModifier<__exportDirectly>()) + if (decl->findModifier()) { - builder->addExportDirectlyDecoration(inst); - } - if (decl->findModifier<__externLib>()) - { - builder->addExternLibDecoration(inst); + builder->addExternCppDecoration(inst, mangledName); } } @@ -1994,12 +1990,7 @@ static String getNameForNameHint( StringBuilder sb; sb.append(parentName); - if (decl->hasModifier<__exportDirectly>()) { - sb.append("::"); - } - else { - sb.append("."); - } + sb.append("."); sb.append(leafName->text); return sb.ProduceString(); diff --git a/source/slang/slang-mangle.cpp b/source/slang/slang-mangle.cpp index acb561531..e6c0a8e7f 100644 --- a/source/slang/slang-mangle.cpp +++ b/source/slang/slang-mangle.cpp @@ -455,9 +455,9 @@ namespace Slang auto decl = declRef.getDecl(); - // Handle `__unmangled` modifier by simply emitting + // Handle `__extern_cpp` modifier by simply emitting // the given name. - if (decl->hasModifier()) + if (decl->hasModifier()) { emit(context, decl->getName()->text); return; diff --git a/source/slang/slang-options.cpp b/source/slang/slang-options.cpp index b40dedc99..2d5e1aeea 100644 --- a/source/slang/slang-options.cpp +++ b/source/slang/slang-options.cpp @@ -1161,10 +1161,6 @@ struct OptionsParser rawEntryPoints.add(rawEntryPoint); } - else if (argValue == "-heterogeneous") - { - requestImpl->getLinkage()->m_heterogeneous = true; - } else if (argValue == "-lang") { CommandLineArg name; @@ -1995,9 +1991,9 @@ struct OptionsParser case CodeGenTarget::CPPSource: case CodeGenTarget::PTX: case CodeGenTarget::CUDASource: - case CodeGenTarget::HostCallable: - case CodeGenTarget::Executable: - case CodeGenTarget::SharedLibrary: + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::HostExecutable: + case CodeGenTarget::ShaderSharedLibrary: rawOutput.isWholeProgram = true; break; default: diff --git a/source/slang/slang-parameter-binding.cpp b/source/slang/slang-parameter-binding.cpp index 7fbc59dc7..7bff7118e 100644 --- a/source/slang/slang-parameter-binding.cpp +++ b/source/slang/slang-parameter-binding.cpp @@ -3033,9 +3033,9 @@ static bool _isCPUTarget(CodeGenTarget target) { case CodeGenTarget::CPPSource: case CodeGenTarget::CSource: - case CodeGenTarget::Executable: - case CodeGenTarget::SharedLibrary: - case CodeGenTarget::HostCallable: + case CodeGenTarget::HostExecutable: + case CodeGenTarget::ShaderSharedLibrary: + case CodeGenTarget::ShaderHostCallable: { return true; } diff --git a/source/slang/slang-type-layout.cpp b/source/slang/slang-type-layout.cpp index b48e70eae..cd81c6173 100644 --- a/source/slang/slang-type-layout.cpp +++ b/source/slang/slang-type-layout.cpp @@ -1403,9 +1403,9 @@ LayoutRulesFamilyImpl* getDefaultLayoutRulesFamilyForTarget(TargetRequest* targe case CodeGenTarget::SPIRVAssembly: return &kGLSLLayoutRulesFamilyImpl; - case CodeGenTarget::HostCallable: - case CodeGenTarget::Executable: - case CodeGenTarget::SharedLibrary: + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::HostExecutable: + case CodeGenTarget::ShaderSharedLibrary: case CodeGenTarget::CPPSource: case CodeGenTarget::CSource: { @@ -1610,9 +1610,9 @@ bool isCPUTarget(TargetRequest* targetReq) case CodeGenTarget::CPPSource: case CodeGenTarget::CSource: - case CodeGenTarget::HostCallable: - case CodeGenTarget::Executable: - case CodeGenTarget::SharedLibrary: + case CodeGenTarget::ShaderHostCallable: + case CodeGenTarget::HostExecutable: + case CodeGenTarget::ShaderSharedLibrary: return true; } } diff --git a/source/slang/slang.cpp b/source/slang/slang.cpp index e0b11604c..e83ab2da3 100644 --- a/source/slang/slang.cpp +++ b/source/slang/slang.cpp @@ -215,8 +215,8 @@ void Session::_initCodeGenTransitionMap() // We *don't* add a default for host callable, as we will determine what is suitable depending on what // is available. We prefer LLVM if that's available. If it's not we can use generic C/C++ compiler - map.addTransition(source, CodeGenTarget::SharedLibrary, PassThroughMode::GenericCCpp); - map.addTransition(source, CodeGenTarget::Executable, PassThroughMode::GenericCCpp); + map.addTransition(source, CodeGenTarget::ShaderSharedLibrary, PassThroughMode::GenericCCpp); + map.addTransition(source, CodeGenTarget::HostExecutable, PassThroughMode::GenericCCpp); map.addTransition(source, CodeGenTarget::ObjectCode, PassThroughMode::GenericCCpp); } } @@ -666,7 +666,7 @@ SlangPassThrough Session::getDownstreamCompilerForTransition(SlangCompileTarget } // Special case host-callable - if (target == CodeGenTarget::HostCallable) + if (target == CodeGenTarget::ShaderHostCallable) { if (source == CodeGenTarget::CSource || source == CodeGenTarget::CPPSource) { @@ -1326,9 +1326,9 @@ CapabilitySet TargetRequest::getTargetCaps() break; case CodeGenTarget::CPPSource: - case CodeGenTarget::Executable: - case CodeGenTarget::SharedLibrary: - case CodeGenTarget::HostCallable: + case CodeGenTarget::HostExecutable: + case CodeGenTarget::ShaderSharedLibrary: + case CodeGenTarget::ShaderHostCallable: atoms.add(CapabilityAtom::CPP); break; diff --git a/tools/gfx/cpu/render-cpu.cpp b/tools/gfx/cpu/render-cpu.cpp index d17cf6ea8..7e1de796a 100644 --- a/tools/gfx/cpu/render-cpu.cpp +++ b/tools/gfx/cpu/render-cpu.cpp @@ -1143,7 +1143,7 @@ public: { SLANG_RETURN_ON_FAIL(slangContext.initialize( desc.slang, - SLANG_HOST_CALLABLE, + SLANG_SHADER_HOST_CALLABLE, "sm_5_1", makeArray(slang::PreprocessorMacroDesc{ "__CPU__", "1" }).getView())); diff --git a/tools/render-test/render-test-main.cpp b/tools/render-test/render-test-main.cpp index 81e8cd38a..aa0a60829 100644 --- a/tools/render-test/render-test-main.cpp +++ b/tools/render-test/render-test-main.cpp @@ -1204,7 +1204,7 @@ static SlangResult _innerMain(Slang::StdWriters* stdWriters, SlangSession* sessi slangPassThrough = SLANG_PASS_THROUGH_GLSLANG; break; case DeviceType::CPU: - input.target = SLANG_HOST_CALLABLE; + input.target = SLANG_SHADER_HOST_CALLABLE; input.profile = ""; nativeLanguage = SLANG_SOURCE_LANGUAGE_CPP; slangPassThrough = SLANG_PASS_THROUGH_GENERIC_C_CPP; diff --git a/tools/slang-embed/slang-embed.cpp b/tools/slang-embed/slang-embed.cpp index 4a81c1b95..7fb865eee 100644 --- a/tools/slang-embed/slang-embed.cpp +++ b/tools/slang-embed/slang-embed.cpp @@ -18,7 +18,7 @@ #include "../../source/core/slang-string.h" #include "../../source/core/slang-string-util.h" #include "../../source/core/slang-io.h" - +#include "../../source/core/slang-dictionary.h" // Utility to free pointers on scope exit struct ScopedMemory @@ -59,6 +59,7 @@ struct App { char const* appName = "slang-embed"; char const* inputPath = nullptr; + Slang::HashSet includedFiles; void parseOptions(int argc, char** argv) { @@ -89,6 +90,13 @@ struct App { using namespace Slang; + String canonicalPath; + if (SLANG_SUCCEEDED(Slang::Path::getCanonical(inputPath, canonicalPath))) + { + if (!includedFiles.Add(canonicalPath)) + return; + } + // We open the input file in text mode because we are currently // embedding textual source files. If/when this utility gets // used for binary files another mode could be called for. diff --git a/tools/slang-test/slang-test-main.cpp b/tools/slang-test/slang-test-main.cpp index 05be9e0de..d5f4408ed 100644 --- a/tools/slang-test/slang-test-main.cpp +++ b/tools/slang-test/slang-test-main.cpp @@ -759,6 +759,7 @@ static PassThroughFlags _getPassThroughFlagsForTarget(SlangCompileTarget target) case SLANG_GLSL: case SLANG_C_SOURCE: case SLANG_CPP_SOURCE: + case SLANG_HOST_CPP_SOURCE: case SLANG_CUDA_SOURCE: { return 0; @@ -779,9 +780,9 @@ static PassThroughFlags _getPassThroughFlagsForTarget(SlangCompileTarget target) return PassThroughFlag::Dxc; } - case SLANG_HOST_CALLABLE: - case SLANG_EXECUTABLE: - case SLANG_SHARED_LIBRARY: + case SLANG_SHADER_HOST_CALLABLE: + case SLANG_HOST_EXECUTABLE: + case SLANG_SHADER_SHARED_LIBRARY: { return PassThroughFlag::Generic_C_CPP; } @@ -891,7 +892,7 @@ static SlangResult _extractRenderTestRequirements(const CommandLine& cmdLine, Te passThru = SLANG_PASS_THROUGH_GLSLANG; break; case RenderApiType::CPU: - target = SLANG_HOST_CALLABLE; + target = SLANG_SHADER_HOST_CALLABLE; nativeLanguage = SLANG_SOURCE_LANGUAGE_CPP; passThru = SLANG_PASS_THROUGH_GENERIC_C_CPP; break; @@ -1364,7 +1365,7 @@ TestResult runSimpleTest(TestContext* context, TestInput& input) } // If it's executable we run it and use it's output - if (target == SLANG_EXECUTABLE) + if (target == SLANG_HOST_EXECUTABLE) { ExecuteResult runExeRes; if (SLANG_FAILED(_executeBinary(exeRes.standardOutput.getUnownedSlice(), runExeRes))) @@ -1797,7 +1798,7 @@ static TestResult runCPPCompilerSharedLibrary(TestContext* context, TestInput& i options.sourceLanguage = (ext == "c") ? SLANG_SOURCE_LANGUAGE_C : SLANG_SOURCE_LANGUAGE_CPP; // Build a shared library - options.targetType = SLANG_SHARED_LIBRARY; + options.targetType = SLANG_SHADER_SHARED_LIBRARY; // Compile this source options.sourceFiles.add(filePath); -- cgit v1.2.3