summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Siher <32305650+dsiher@users.noreply.github.com>2022-02-03 19:16:54 -0800
committerGitHub <noreply@github.com>2022-02-03 19:16:54 -0800
commit5eb835f0332868fd56ac14ce7560e0ae9cfafec9 (patch)
tree67ed2ae3b2527e8cfa66f835062490decf3052ad
parent1eda86377847155ed3f0e0b2e40a105af35bd387 (diff)
Fixed naming conflicts in heterogeneous-hello-world (#2114)
* Fixed naming conflicts in heterogeneous-hello-world Added 3 new modifiers (`__unmangled`, `__exportDirectly`, `__externLib`) `__unmangled` causes mangleName() to return the normal name of the decl. `__exportDirectly` changes parent decl name concatenation behavior to use "::" instead of "." (for Name Hint) and emits the name hint when it exists, otherwise it emits the mangled name. `__externLib` stops Slang from emitting the corresponding struct. Also made necessary changes to heterogeneous-hello-world so that this new functionality is shown off. * Undo unintentional formatting changes Co-authored-by: Yong He <yonghe@outlook.com>
-rw-r--r--build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj4
-rw-r--r--examples/heterogeneous-hello-world/main.cpp107
-rw-r--r--examples/heterogeneous-hello-world/shader.slang65
-rw-r--r--prelude/slang-cpp-prelude.h16
-rw-r--r--slang.sln30
-rw-r--r--source/slang/core.meta.slang20
-rw-r--r--source/slang/slang-ast-modifier.h3
-rw-r--r--source/slang/slang-emit-c-like.cpp29
-rw-r--r--source/slang/slang-emit-cpp.cpp31
-rw-r--r--source/slang/slang-ir-inst-defs.h3
-rw-r--r--source/slang/slang-ir-insts.h12
-rw-r--r--source/slang/slang-lower-to-ir.cpp17
-rw-r--r--source/slang/slang-mangle.cpp12
13 files changed, 207 insertions, 142 deletions
diff --git a/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj b/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj
index 70c173112..3e3049f65 100644
--- a/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj
+++ b/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj
@@ -165,7 +165,7 @@
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
@@ -184,7 +184,7 @@
<WarningLevel>Level3</WarningLevel>
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<AdditionalIncludeDirectories>..\..\..;..\..\..\tools;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
- <DebugInformationFormat>EditAndContinue</DebugInformationFormat>
+ <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<Optimization>Disabled</Optimization>
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
</ClCompile>
diff --git a/examples/heterogeneous-hello-world/main.cpp b/examples/heterogeneous-hello-world/main.cpp
index 0d8d2ca73..e711d4486 100644
--- a/examples/heterogeneous-hello-world/main.cpp
+++ b/examples/heterogeneous-hello-world/main.cpp
@@ -27,13 +27,7 @@ ComPtr<gfx::ICommandQueue> gQueue;
// Boilerplate types to help the slang-generated file
//
-struct gfx_Device_0;
-struct gfx_BufferResource_0;
-struct gfx_ShaderProgram_0;
-struct gfx_ResourceView_0;
-struct gfx_TransientResourceHeap_0;
-struct gfx_PipelineState_0;
-bool executeComputation_0();
+bool executeComputation();
// Many Slang API functions return detailed diagnostic information
// (error messages, warnings, etc.) as a "blob" of data, or return
@@ -50,7 +44,7 @@ void diagnoseIfNeeded(slang::IBlob *diagnosticsBlob)
}
}
-gfx::IDevice* createDevice()
+gfx::IDevice *createDevice()
{
ComPtr<gfx::IDevice> device;
IDevice::Desc deviceDesc = {};
@@ -62,7 +56,7 @@ gfx::IDevice* createDevice()
// Loads the shader code defined in `shader.slang` for use by the `gfx` layer.
//
-gfx::IShaderProgram* loadShaderProgram(gfx::IDevice *device, String entryPoint, String moduleName)
+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.
@@ -83,17 +77,17 @@ gfx::IShaderProgram* loadShaderProgram(gfx::IDevice *device, String entryPoint,
// already been loaded previously, that would be used directly.
//
ComPtr<slang::IBlob> diagnosticsBlob;
- slang::IModule *module = slangSession->loadModule(moduleName.getBuffer(), diagnosticsBlob.writeRef());
+ slang::IModule *module = slangSession->loadModule(moduleName, diagnosticsBlob.writeRef());
diagnoseIfNeeded(diagnosticsBlob);
if (!module)
return NULL;
// Look up entry point
//
- char const *computeEntryPointName = entryPoint.getBuffer();
+ // char const *computeEntryPointName = entryPoint.getBuffer();
ComPtr<slang::IEntryPoint> computeEntryPoint;
SLANG_RETURN_NULL_ON_FAIL(
- module->findEntryPointByName(computeEntryPointName, computeEntryPoint.writeRef()));
+ 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`.
@@ -139,9 +133,7 @@ gfx::IShaderProgram* loadShaderProgram(gfx::IDevice *device, String entryPoint,
return gProgram;
}
-gfx::IBufferResource* createStructuredBuffer(
- gfx::IDevice *device,
- float *initialData)
+gfx::IBufferResource* createStructuredBuffer(gfx::IDevice* device, FixedArray<float, 4> initialData)
{
// Create a structured buffer for storing computation data
//
@@ -160,15 +152,15 @@ gfx::IBufferResource* createStructuredBuffer(
bufferDesc.memoryType = MemoryType::DeviceLocal;
SlangResult result = device->createBufferResource(bufferDesc,
- (void *)initialData,
+ (void *)&initialData,
gBufferResource.writeRef());
SLANG_RETURN_NULL_ON_FAIL(result);
return gBufferResource;
}
-gfx::IResourceView* createBufferView(
- gfx::IDevice* device,
- gfx::IBufferResource* buffer)
+gfx::IResourceView *createBufferView(
+ gfx::IDevice *device,
+ gfx::IBufferResource *buffer)
{
// Create a resource view for the structured buffer
//
@@ -179,7 +171,7 @@ gfx::IResourceView* createBufferView(
return gResourceView;
}
-gfx::ITransientResourceHeap* buildTransientHeap(gfx::IDevice *device)
+gfx::ITransientResourceHeap *buildTransientHeap(gfx::IDevice *device)
{
ITransientResourceHeap::Desc transientHeapDesc = {};
transientHeapDesc.constantBufferSize = 4096;
@@ -188,9 +180,9 @@ gfx::ITransientResourceHeap* buildTransientHeap(gfx::IDevice *device)
return gTransientHeap;
}
-gfx::IPipelineState* buildPipelineState(
+gfx::IPipelineState *buildPipelineState(
gfx::IDevice *device,
- gfx::IShaderProgram* shaderProgram)
+ gfx::IShaderProgram *shaderProgram)
{
gfx::ComputePipelineStateDesc pipelineDesc = {};
pipelineDesc.program = shaderProgram;
@@ -199,7 +191,7 @@ gfx::IPipelineState* buildPipelineState(
return gPipelineState;
}
-void printInitialValues(float *initialArray, int length)
+void printInitialValues(FixedArray<float, 4> initialArray, int length)
{
printf("Before:\n");
for (int i = 0; i < length; i++)
@@ -210,10 +202,10 @@ void printInitialValues(float *initialArray, int length)
}
void dispatchComputation(
- gfx::IDevice* device,
- gfx::ITransientResourceHeap* transientHeap,
- gfx::IPipelineState* pipelineState,
- gfx::IResourceView* bufferView,
+ gfx::IDevice *device,
+ gfx::ITransientResourceHeap *transientHeap,
+ gfx::IPipelineState *pipelineState,
+ gfx::IResourceView *bufferView,
unsigned int gridDimsX,
unsigned int gridDimsY,
unsigned int gridDimsZ)
@@ -257,68 +249,15 @@ bool printOutputValues(
return true;
}
-// Boilerplate functions to help the slang-generated file and types
-
-gfx_Device_0* createDevice_0()
-{
- return (gfx_Device_0*)createDevice();
-}
-
-gfx_BufferResource_0* createStructuredBuffer_0(gfx_Device_0* _0, FixedArray<float, 4> _1)
-{
- return (gfx_BufferResource_0*)createStructuredBuffer((gfx::IDevice*)_0, (float*)&_1);
-}
-
-gfx_ShaderProgram_0* loadShaderProgram_0(gfx_Device_0* _0, char* _1, char* _2)
-{
- return (gfx_ShaderProgram_0*)loadShaderProgram((gfx::IDevice*)_0, _1, _2);
-}
-
-gfx_ResourceView_0* createBufferView_0(gfx_Device_0* _0, gfx_BufferResource_0* _1)
-{
- return (gfx_ResourceView_0*)createBufferView((gfx::IDevice*)_0, (gfx::IBufferResource*)_1);
-}
-
-gfx_TransientResourceHeap_0* buildTransientHeap_0(gfx_Device_0* _0)
-{
- return (gfx_TransientResourceHeap_0*)buildTransientHeap((gfx::IDevice*)_0);
-}
-
-gfx_PipelineState_0* buildPipelineState_0(gfx_Device_0* _0, gfx_ShaderProgram_0* _1)
-{
- return (gfx_PipelineState_0*)buildPipelineState((gfx::IDevice*)_0, (gfx::IShaderProgram*)_1);
-}
-
-void printInitialValues_0(FixedArray<float, 4> _0, int32_t _1)
-{
- printInitialValues((float*)&_0, _1);
-}
-
-void dispatchComputation_0(gfx_Device_0* _0, gfx_TransientResourceHeap_0* _1, gfx_PipelineState_0* _2, gfx_ResourceView_0* _3, unsigned int gridDimsX, unsigned int gridDimsY, unsigned int gridDimsZ)
-{
- dispatchComputation(
- (gfx::IDevice*)_0,
- (gfx::ITransientResourceHeap*)_1,
- (gfx::IPipelineState*)_2,
- (gfx::IResourceView*)_3,
- gridDimsX,
- gridDimsY,
- gridDimsZ);
-}
-
-RWStructuredBuffer<float> convertBuffer_0(gfx_BufferResource_0* _0) {
+RWStructuredBuffer<float> convertBuffer(gfx::IBufferResource* _0) {
RWStructuredBuffer<float> result;
result.data = (float*)_0;
return result;
}
-gfx_BufferResource_0* unconvertBuffer_0(RWStructuredBuffer<float> _0) {
- return (gfx_BufferResource_0*)(_0.data);
-}
-
-bool printOutputValues_0(gfx_Device_0* _0, gfx_BufferResource_0* _1, int32_t _2)
+gfx::IBufferResource *unconvertBuffer(RWStructuredBuffer<float> _0)
{
- return printOutputValues((gfx::IDevice*)_0, (gfx::IBufferResource*)_1, _2);
+ return (gfx::IBufferResource *)(_0.data);
}
int main()
@@ -327,7 +266,7 @@ int main()
// `struct` type, and then walk through the lifecyle
// of the application.
- if (!(executeComputation_0()))
+ if (!(executeComputation()))
{
return -1;
}
diff --git a/examples/heterogeneous-hello-world/shader.slang b/examples/heterogeneous-hello-world/shader.slang
index d67fd5582..d87370be1 100644
--- a/examples/heterogeneous-hello-world/shader.slang
+++ b/examples/heterogeneous-hello-world/shader.slang
@@ -1,7 +1,7 @@
// shader.slang
//TEST_INPUT:ubuffer(random(float, 4096, -1.0, 1.0), stride=4):name=ioBuffer
-RWStructuredBuffer<float> convertBuffer(Ptr<gfx::BufferResource> x);
+__unmangled __exportDirectly RWStructuredBuffer<float> convertBuffer(Ptr<gfx::IBufferResource> x);
[shader("compute")]
[numthreads(4, 1, 1)]
@@ -15,44 +15,49 @@ void computeMain(uniform RWStructuredBuffer<float> ioBuffer, uint3 dispatchThrea
ioBuffer[tid] = o;
}
+
+
// Forward declarations of gfx types
//
namespace gfx {
- struct Device{};
- struct BufferResource{};
- struct ResourceView{};
- struct TransientResourceHeap{};
- struct PipelineState{};
- struct ShaderProgram{};
+ __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
//
-Ptr<gfx::Device> createDevice();
-Ptr<gfx::ShaderProgram> loadShaderProgram(Ptr<gfx::Device> device, String entryPoint, String module);
-Ptr<gfx::BufferResource> createStructuredBuffer(
- Ptr<gfx::Device> device,
+__unmangled __exportDirectly Ptr<gfx::IDevice> createDevice();
+__unmangled __exportDirectly Ptr<gfx::IShaderProgram> loadShaderProgram(
+ Ptr<gfx::IDevice> device,
+ String entryPoint,
+ String module);
+__unmangled __exportDirectly Ptr<gfx::IBufferResource> createStructuredBuffer(
+ Ptr<gfx::IDevice> device,
float[4] initialData);
-Ptr<gfx::ResourceView> createBufferView(
- Ptr<gfx::Device> device,
- Ptr<gfx::BufferResource> buffer);
-Ptr<gfx::TransientResourceHeap> buildTransientHeap(
- Ptr<gfx::Device> device);
-Ptr<gfx::PipelineState> buildPipelineState(
- Ptr<gfx::Device> device,
- Ptr<gfx::ShaderProgram> shaderProgram);
-void printInitialValues(float[4] initialArray, int length);
-void dispatchComputation(
- Ptr<gfx::Device> device,
- Ptr<gfx::TransientResourceHeap> transientHeap,
- Ptr<gfx::PipelineState> pipelineState,
- Ptr<gfx::ResourceView> bufferView);
-bool printOutputValues(
- Ptr<gfx::Device> device,
- Ptr<gfx::BufferResource> buffer,
+__unmangled __exportDirectly Ptr<gfx::IResourceView> createBufferView(
+ Ptr<gfx::IDevice> device,
+ Ptr<gfx::IBufferResource> buffer);
+__unmangled __exportDirectly Ptr<gfx::ITransientResourceHeap> buildTransientHeap(
+ Ptr<gfx::IDevice> device);
+__unmangled __exportDirectly Ptr<gfx::IPipelineState> buildPipelineState(
+ Ptr<gfx::IDevice> device,
+ Ptr<gfx::IShaderProgram> shaderProgram);
+__unmangled __exportDirectly void printInitialValues(float[4] initialArray, int length);
+__unmangled __exportDirectly void dispatchComputation(
+ Ptr<gfx::IDevice> device,
+ Ptr<gfx::ITransientResourceHeap> transientHeap,
+ Ptr<gfx::IPipelineState> pipelineState,
+ Ptr<gfx::IResourceView> bufferView);
+__unmangled __exportDirectly bool printOutputValues(
+ Ptr<gfx::IDevice> device,
+ Ptr<gfx::IBufferResource> buffer,
int length);
-public bool executeComputation() {
+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 };
@@ -60,7 +65,7 @@ public bool executeComputation() {
// Declare functions
let device = createDevice();
let structuredBuffer = createStructuredBuffer(device, initialArray);
- let bufferView = createBufferView(device, structuredBuffer);
+ // let bufferView = createBufferView(device, structuredBuffer);
__GPU_FOREACH(device, uint3(4, 1, 1), LAMBDA(uint3 dispatchThreadID)
{ computeMain(convertBuffer(structuredBuffer), dispatchThreadID) ; });
printInitialValues(initialArray, 4);
diff --git a/prelude/slang-cpp-prelude.h b/prelude/slang-cpp-prelude.h
index b1b29284c..612f9ec9f 100644
--- a/prelude/slang-cpp-prelude.h
+++ b/prelude/slang-cpp-prelude.h
@@ -132,18 +132,4 @@ Any compilers not detected by the above logic are now now explicitly zeroed out.
# define SLANG_UNROLL
#endif
-struct gfx_Device_0;
-struct gfx_BufferResource_0;
-struct gfx_ShaderProgram_0;
-struct gfx_ResourceView_0;
-struct gfx_TransientResourceHeap_0;
-struct gfx_PipelineState_0;
-
-gfx_ShaderProgram_0* loadShaderProgram_0(gfx_Device_0* _0, char* _1, char* _2);
-gfx_TransientResourceHeap_0* buildTransientHeap_0(gfx_Device_0* _0);
-gfx_PipelineState_0* buildPipelineState_0(gfx_Device_0* _0, gfx_ShaderProgram_0* _1);
-gfx_ResourceView_0* createBufferView_0(gfx_Device_0* _0, gfx_BufferResource_0* _1);
-void dispatchComputation_0(gfx_Device_0* _0, gfx_TransientResourceHeap_0* _1, gfx_PipelineState_0* _2, gfx_ResourceView_0* _3, uint32_t gridDimsX, uint32_t gridDimsY, uint32_t gridDimsZ);
-gfx_BufferResource_0* unconvertBuffer_0(RWStructuredBuffer<float> _0);
-
-#endif
+#endif \ No newline at end of file
diff --git a/slang.sln b/slang.sln
index b4b30eeee..8b7bf1cf5 100644
--- a/slang.sln
+++ b/slang.sln
@@ -35,6 +35,10 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "gpu-printing", "build\visua
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "hello-world", "build\visual-studio\hello-world\hello-world.vcxproj", "{010BE414-ED5B-CF56-16C0-BD18027062C0}"
EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "heterogeneous-first-gen", "build\visual-studio\heterogeneous-hello-world\heterogeneous-first-gen.vcxproj", "{3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}"
+EndProject
+Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "heterogeneous-hello-world", "build\visual-studio\heterogeneous-hello-world\heterogeneous-hello-world.vcxproj", "{150CAA5A-0177-6A66-AA92-CFCB96DC2D49}"
+EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "model-viewer", "build\visual-studio\model-viewer\model-viewer.vcxproj", "{2F8724C6-1BC3-2730-84D5-3F277030D04A}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ray-tracing", "build\visual-studio\ray-tracing\ray-tracing.vcxproj", "{71AC0F50-5DFD-FA91-8661-E95372118EFB}"
@@ -267,6 +271,30 @@ Global
{010BE414-ED5B-CF56-16C0-BD18027062C0}.Release|Win32.Build.0 = Release|Win32
{010BE414-ED5B-CF56-16C0-BD18027062C0}.Release|x64.ActiveCfg = Release|x64
{010BE414-ED5B-CF56-16C0-BD18027062C0}.Release|x64.Build.0 = Release|x64
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Debug|aarch64.ActiveCfg = Debug aarch64|ARM
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Debug|aarch64.Build.0 = Debug aarch64|ARM
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Debug|Win32.ActiveCfg = Debug|Win32
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Debug|Win32.Build.0 = Debug|Win32
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Debug|x64.ActiveCfg = Debug|x64
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Debug|x64.Build.0 = Debug|x64
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Release|aarch64.ActiveCfg = Release aarch64|ARM
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Release|aarch64.Build.0 = Release aarch64|ARM
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Release|Win32.ActiveCfg = Release|Win32
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Release|Win32.Build.0 = Release|Win32
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Release|x64.ActiveCfg = Release|x64
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B}.Release|x64.Build.0 = Release|x64
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|aarch64.ActiveCfg = Debug aarch64|ARM
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|aarch64.Build.0 = Debug aarch64|ARM
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|Win32.ActiveCfg = Debug|Win32
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|Win32.Build.0 = Debug|Win32
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|x64.ActiveCfg = Debug|x64
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Debug|x64.Build.0 = Debug|x64
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|aarch64.ActiveCfg = Release aarch64|ARM
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|aarch64.Build.0 = Release aarch64|ARM
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|Win32.ActiveCfg = Release|Win32
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|Win32.Build.0 = Release|Win32
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|x64.ActiveCfg = Release|x64
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49}.Release|x64.Build.0 = Release|x64
{2F8724C6-1BC3-2730-84D5-3F277030D04A}.Debug|aarch64.ActiveCfg = Debug aarch64|ARM
{2F8724C6-1BC3-2730-84D5-3F277030D04A}.Debug|aarch64.Build.0 = Debug aarch64|ARM
{2F8724C6-1BC3-2730-84D5-3F277030D04A}.Debug|Win32.ActiveCfg = Debug|Win32
@@ -465,6 +493,8 @@ Global
{37BED5B5-23FA-D81F-8C0C-F1167867813A} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
{57C81DD3-4304-213D-AC16-39349871C957} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
{010BE414-ED5B-CF56-16C0-BD18027062C0} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
+ {3E8C6F8B-AAC3-B722-B3CD-1B461F84DE1B} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
+ {150CAA5A-0177-6A66-AA92-CFCB96DC2D49} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
{2F8724C6-1BC3-2730-84D5-3F277030D04A} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
{71AC0F50-5DFD-FA91-8661-E95372118EFB} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
{17BA8E32-034E-84DA-6C12-DE8E58C5BECC} = {EB5FC2C6-D72D-B6CC-C0C1-26F3AC2E9231}
diff --git a/source/slang/core.meta.slang b/source/slang/core.meta.slang
index ca07b299d..779900fd5 100644
--- a/source/slang/core.meta.slang
+++ b/source/slang/core.meta.slang
@@ -63,6 +63,26 @@ syntax unorm : UNormModifier;
///
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.
+///
+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;
+
/// A type that can be used as an operand for builtins
[sealed]
[builtin]
diff --git a/source/slang/slang-ast-modifier.h b/source/slang/slang-ast-modifier.h
index 2558d7c4b..ae9e0924e 100644
--- a/source/slang/slang-ast-modifier.h
+++ b/source/slang/slang-ast-modifier.h
@@ -28,6 +28,9 @@ 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)};
/// 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-emit-c-like.cpp b/source/slang/slang-emit-c-like.cpp
index e04759773..c0106e9ad 100644
--- a/source/slang/slang-emit-c-like.cpp
+++ b/source/slang/slang-emit-c-like.cpp
@@ -740,6 +740,28 @@ String CLikeSourceEmitter::_generateUniqueName(const UnownedStringSlice& name)
String CLikeSourceEmitter::generateName(IRInst* inst)
{
+ // Handle `__exportDirectly` decoration before all else
+ if (inst->findDecoration<IR__exportDirectly>())
+ {
+ // 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<IRNameHintDecoration>())
+ {
+ return nameHintDecoration->getName();
+ }
+ // Otherwise, we just want the instruction to not be mangled, which is
+ // similarly handled in `getMangledName`.
+ if (auto linkageDecoration = inst->findDecoration<IRLinkageDecoration>())
+ {
+ return linkageDecoration->getMangledName();
+ }
+ }
+
// If the instruction names something
// that should be emitted as a target intrinsic,
// then use that name instead.
@@ -2901,6 +2923,13 @@ 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<IR__externLib>())
+ {
+ return;
+ }
+
m_writer->emit("struct ");
emitPostKeywordTypeAttributes(structType);
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index cb6c210be..e06aa8372 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -2709,26 +2709,43 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
}
}
}
+ // 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<float> _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_Device_0* device, Vector<uint32_t, 3> gridDims, \n");
+ m_writer->emit("_wrapper(gfx::IDevice* device, Vector<uint32_t, 3> gridDims, \n");
m_writer->emit("\tRWStructuredBuffer<float> 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_ShaderProgram_0* shaderProgram = loadShaderProgram_0(device, \"");
+ 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_TransientResourceHeap_0* transientHeap = buildTransientHeap_0(device);");
- m_writer->emit("\n\tgfx_PipelineState_0* pipelineState = ");
- m_writer->emit("buildPipelineState_0(device, shaderProgram);");
- m_writer->emit("\n\tgfx_ResourceView_0* bufferView = createBufferView_0(device, unconvertBuffer_0(buffer));");
- m_writer->emit("\n\tdispatchComputation_0(device, transientHeap, pipelineState, ");
+ 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");
}
diff --git a/source/slang/slang-ir-inst-defs.h b/source/slang/slang-ir-inst-defs.h
index 9fa5a2e9d..0fca118d1 100644
--- a/source/slang/slang-ir-inst-defs.h
+++ b/source/slang/slang-ir-inst-defs.h
@@ -553,6 +553,9 @@ 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)
diff --git a/source/slang/slang-ir-insts.h b/source/slang/slang-ir-insts.h
index 7ef31d71a..9b50047de 100644
--- a/source/slang/slang-ir-insts.h
+++ b/source/slang/slang-ir-insts.h
@@ -269,6 +269,8 @@ 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
{
@@ -2832,6 +2834,16 @@ 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 d4b069dca..b2a71a2e0 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -1034,7 +1034,7 @@ static void addLinkageDecoration(
inst = outerGeneric;
}
- if(isImportedDecl(context, decl))
+ if (isImportedDecl(context, decl))
{
builder->addImportDecoration(inst, mangledName);
}
@@ -1047,6 +1047,14 @@ static void addLinkageDecoration(
builder->addPublicDecoration(inst);
builder->addKeepAliveDecoration(inst);
}
+ if (decl->findModifier<__exportDirectly>())
+ {
+ builder->addExportDirectlyDecoration(inst);
+ }
+ if (decl->findModifier<__externLib>())
+ {
+ builder->addExternLibDecoration(inst);
+ }
}
static void addLinkageDecoration(
@@ -1986,7 +1994,12 @@ static String getNameForNameHint(
StringBuilder sb;
sb.append(parentName);
- sb.append(".");
+ if (decl->hasModifier<__exportDirectly>()) {
+ sb.append("::");
+ }
+ else {
+ sb.append(".");
+ }
sb.append(leafName->text);
return sb.ProduceString();
diff --git a/source/slang/slang-mangle.cpp b/source/slang/slang-mangle.cpp
index b0568994f..acb561531 100644
--- a/source/slang/slang-mangle.cpp
+++ b/source/slang/slang-mangle.cpp
@@ -453,12 +453,20 @@ namespace Slang
// forward to something else? E.g., what if we
// are asked to mangle the name of a `typedef`?
+ auto decl = declRef.getDecl();
+
+ // Handle `__unmangled` modifier by simply emitting
+ // the given name.
+ if (decl->hasModifier<UnmangledModifier>())
+ {
+ emit(context, decl->getName()->text);
+ return;
+ }
+
// We will start with a unique prefix to avoid
// clashes with user-defined symbols:
emitRaw(context, "_S");
- auto decl = declRef.getDecl();
-
// Next we will add a bit of info to register
// the *kind* of declaration we are dealing with.
//