summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Siher <32305650+dsiher@users.noreply.github.com>2021-09-14 12:59:55 -0400
committerGitHub <noreply@github.com>2021-09-14 09:59:55 -0700
commit502aa3812a82cf0d091cff0c67804e4ee448ac78 (patch)
tree8ac8def3a30a6531cee7f6b0380d8929811fade5
parentd9d42879c4b6c0202732897ec60a355ccc91f243 (diff)
Bring heterogeneous-hello-world back up to date. (#1935)
* Bring heterogeneous-hello-world back up to date. * Reintroduced heterogeneous-hello-world into the premake * No longer uses compiled bytecode for entry point, instead a loadModule call is hardocoded with the slang file name. * Entry point is, similarly, hardcoded for now. * Added a bypass to slang-legalize-types for an unneeded GPUForeach check * Run premake and change to relative path * Removed experimental and added README Co-authored-by: Yong He <yonghe@outlook.com>
-rw-r--r--build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj21
-rw-r--r--examples/experimental/heterogeneous-hello-world/main.cpp380
-rw-r--r--examples/experimental/heterogeneous-hello-world/shader.cpp197
-rw-r--r--examples/experimental/heterogeneous-hello-world/shader.slang65
-rw-r--r--examples/heterogeneous-hello-world/README.md (renamed from examples/experimental/heterogeneous-hello-world/README.md)0
-rw-r--r--examples/heterogeneous-hello-world/main.cpp335
-rw-r--r--examples/heterogeneous-hello-world/shader.cpp215
-rw-r--r--examples/heterogeneous-hello-world/shader.slang71
-rw-r--r--prelude/slang-cpp-prelude.h21
-rw-r--r--premake5.lua3
-rw-r--r--slang.sln11
-rw-r--r--source/slang/slang-ast-stmt.h2
-rw-r--r--source/slang/slang-check-stmt.cpp2
-rw-r--r--source/slang/slang-emit-cpp.cpp20
-rw-r--r--source/slang/slang-ir-legalize-types.cpp3
-rw-r--r--source/slang/slang-lower-to-ir.cpp4
-rw-r--r--source/slang/slang-parser.cpp2
17 files changed, 673 insertions, 679 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 78bdb1f3e..7ac8673be 100644
--- a/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj
+++ b/build/visual-studio/heterogeneous-hello-world/heterogeneous-hello-world.vcxproj
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
@@ -29,25 +29,25 @@
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<CharacterSet>Unicode</CharacterSet>
- <PlatformToolset>v140</PlatformToolset>
+ <PlatformToolset>v142</PlatformToolset>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
@@ -169,21 +169,24 @@
<None Include="..\..\..\examples\heterogeneous-hello-world\shader.slang" />
</ItemGroup>
<ItemGroup>
+ <ProjectReference Include="..\example-base\example-base.vcxproj">
+ <Project>{37BED5B5-23FA-D81F-8C0C-F1167867813A}</Project>
+ </ProjectReference>
<ProjectReference Include="..\slang\slang.vcxproj">
<Project>{DB00DA62-0533-4AFD-B59F-A67D5B3A0808}</Project>
</ProjectReference>
- <ProjectReference Include="..\core\core.vcxproj">
- <Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project>
- </ProjectReference>
<ProjectReference Include="..\gfx\gfx.vcxproj">
<Project>{222F7498-B40C-4F3F-A704-DDEB91A4484A}</Project>
</ProjectReference>
<ProjectReference Include="..\gfx-util\gfx-util.vcxproj">
<Project>{F5ADB74E-02A7-44FB-AA3B-FC02F8AC7A4B}</Project>
</ProjectReference>
- <ProjectReference Include="..\graphics-app-framework\graphics-app-framework.vcxproj">
+ <ProjectReference Include="..\platform\platform.vcxproj">
<Project>{3565FE5E-4FA3-11EB-AE93-0242AC130002}</Project>
</ProjectReference>
+ <ProjectReference Include="..\core\core.vcxproj">
+ <Project>{F9BE7957-8399-899E-0C49-E714FDDD4B65}</Project>
+ </ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
diff --git a/examples/experimental/heterogeneous-hello-world/main.cpp b/examples/experimental/heterogeneous-hello-world/main.cpp
deleted file mode 100644
index 372fcd615..000000000
--- a/examples/experimental/heterogeneous-hello-world/main.cpp
+++ /dev/null
@@ -1,380 +0,0 @@
-// This example is out of date and currently disabled from build.
-// The `gfx` layer has been refactored with a new command list based
-// model. The example must be updated to use the new `gfx` interface
-// before it can be included in build.
-
-#if 0
-// main.cpp
-
-// This file implements an extremely simple example of loading and
-// executing a Slang shader program. This is primarily an example
-// of how to use Slang as a "drop-in" replacement for an existing
-// HLSL compiler like the `D3DCompile` API. More advanced usage
-// of advanced Slang language and API features is left to the
-// next example.
-//
-// The comments in the file will attempt to explain concepts as
-// they are introduced.
-//
-// Of course, in order to use the Slang API, we need to include
-// its header. We have set up the build options for this project
-// so that it is as simple as:
-//
-#include <slang.h>
-//
-// Other build setups are possible, and Slang doesn't assume that
-// its include directory must be added to your global include
-// path.
-
-// For the purposes of keeping the demo code as simple as possible,
-// while still retaining some level of portability, our examples
-// make use of a small platform and graphics API abstraction layer,
-// which is included in the Slang source distribution under the
-// `tools/` directory.
-//
-// Applications can of course use Slang without ever touching this
-// abstraction layer, so we will not focus on it when explaining
-// examples, except in places where best practices for interacting
-// with Slang may depend on an application/engine making certain
-// design choices in their abstraction layer.
-//
-#include "slang-com-ptr.h"
-#include "slang-gfx.h"
-#include "tools/graphics-app-framework/window.h"
-#include "../../prelude/slang-cpp-types.h"
-#include "source/core/slang-basic.h"
-
-using namespace gfx;
-
-// We create global ref pointers to avoid dereferencing values
-//
-ComPtr<gfx::IShaderProgram> gShaderProgram;
-Slang::ComPtr<gfx::IRenderer> gRenderer;
-
-ComPtr<gfx::IBufferResource> gStructuredBuffer;
-
-ComPtr<gfx::IPipelineLayout> gPipelineLayout;
-ComPtr<gfx::IPipelineState> gPipelineState;
-ComPtr<gfx::IDescriptorSetLayout> gDescriptorSetLayout;
-ComPtr<gfx::IDescriptorSet> gDescriptorSet;
-
-// Boilerplate types to help the slan-generated file
-//
-struct gfx_Window_0;
-struct gfx_Renderer_0;
-struct gfx_BufferResource_0;
-struct gfx_ShaderProgram_0;
-struct gfx_DescriptorSetLayout_0;
-struct gfx_PipelineLayout_0;
-struct gfx_DescriptorSet_0;
-struct gfx_PipelineState_0;
-
-bool executeComputation_0();
-extern unsigned char __computeMain[];
-extern size_t __computeMainSize;
-
-gfx::IShaderProgram* loadShaderProgram(gfx::IRenderer* renderer, unsigned char computeCode[], size_t computeCodeSize)
-{
- // We extract the begin/end pointers to the output code buffers directly
- //
- char unsigned const* computeCodeEnd = computeCode + computeCodeSize;
-
- // Now we use the operations of the example graphics API abstraction
- // layer to load shader code into the underlying API.
- //
- // Reminder: this section does not involve the Slang API at all.
- //
-
- gfx::IShaderProgram::KernelDesc kernelDescs[] =
- {
- { gfx::StageType::Compute, computeCode, computeCodeEnd },
- };
-
- gfx::IShaderProgram::Desc programDesc = {};
- programDesc.pipelineType = gfx::PipelineType::Compute;
- programDesc.kernels = &kernelDescs[0];
- programDesc.kernelCount = 1;
-
- gShaderProgram = renderer->createProgram(programDesc);
-
- return gShaderProgram;
-}
-
-// Now that we've covered the function that actually loads and
-// compiles our Slang shade code, we can go through the rest
-// of the application code without as much commentary.
-//
-gfx::Window* createWindow(int windowWidth, int windowHeight)
-{
- // Create a window for our application to render into.
- //
- WindowDesc windowDesc;
- windowDesc.title = "Hello, World!";
- windowDesc.width = windowWidth;
- windowDesc.height = windowHeight;
- return createWindow(windowDesc);
- //return globalWindow;
-}
-
-gfx::IRenderer* createRenderer(
- int windowWidth,
- int windowHeight,
- gfx::Window* window)
-{
- // Initialize the rendering layer.
- //
- // Note: for now we are hard-coding logic to use the
- // Direct3D11 back-end for the graphics API abstraction.
- // A future version of this example may support multiple
- // platforms/APIs.
- //
- IRenderer::Desc rendererDesc = {};
- rendererDesc.rendererType = gfx::RendererType::DirectX11;
- Result res = gfxCreateRenderer(&rendererDesc, gRenderer.writeRef());
-
- if (SLANG_FAILED(res)) return nullptr;
- return gRenderer;
-}
-
-gfx::IBufferResource* createStructuredBuffer(gfx::IRenderer* renderer, float* initialArray)
-{
- // Create a structured buffer for storing the data for computation
- //
- int structuredBufferSize = 4 * sizeof(float);
-
- IBufferResource::Desc structuredBufferDesc;
- structuredBufferDesc.init(structuredBufferSize);
- structuredBufferDesc.setDefaults(IResource::Usage::UnorderedAccess);
- structuredBufferDesc.elementSize = 4;
- structuredBufferDesc.cpuAccessFlags = IResource::AccessFlag::Read;
-
- gStructuredBuffer = renderer->createBufferResource(
- IResource::Usage::UnorderedAccess,
- structuredBufferDesc,
- initialArray);
- return gStructuredBuffer;
-}
-
-gfx::IDescriptorSetLayout* buildDescriptorSetLayout(gfx::IRenderer* renderer)
-{
- // Our example graphics API usess a "modern" D3D12/Vulkan style
- // of resource binding, so now we will dive into describing and
- // allocating "descriptor sets."
- //
- // First, we need to construct a descriptor set *layout*.
- //
- IDescriptorSetLayout::SlotRangeDesc slotRanges[] =
- {
- IDescriptorSetLayout::SlotRangeDesc(DescriptorSlotType::StorageBuffer),
- };
- IDescriptorSetLayout::Desc descriptorSetLayoutDesc;
- descriptorSetLayoutDesc.slotRangeCount = 1;
- descriptorSetLayoutDesc.slotRanges = &slotRanges[0];
- gDescriptorSetLayout = renderer->createDescriptorSetLayout(descriptorSetLayoutDesc);
- return gDescriptorSetLayout;
-}
-
-gfx::IPipelineLayout* buildPipeline(gfx::IRenderer* renderer, gfx::IDescriptorSetLayout* descriptorSetLayout)
-{
- // Next we will allocate a pipeline layout, which specifies
- // that we will render with only a single descriptor set bound.
- //
-
- IPipelineLayout::DescriptorSetDesc descriptorSets[] =
- {
- IPipelineLayout::DescriptorSetDesc(descriptorSetLayout),
- };
- IPipelineLayout::Desc pipelineLayoutDesc;
- pipelineLayoutDesc.renderTargetCount = 1;
- pipelineLayoutDesc.descriptorSetCount = 1;
- pipelineLayoutDesc.descriptorSets = &descriptorSets[0];
- gPipelineLayout = renderer->createPipelineLayout(pipelineLayoutDesc);
-
- return gPipelineLayout;
-}
-
-gfx::IDescriptorSet* buildDescriptorSet(
- gfx::IRenderer* renderer,
- gfx::IDescriptorSetLayout* descriptorSetLayout,
- gfx::IBufferResource* structuredBuffer)
-{
- // Once we have the descriptor set layout, we can allocate
- // and fill in a descriptor set to hold our parameters.
- //
- gDescriptorSet = renderer->createDescriptorSet(descriptorSetLayout, gfx::IDescriptorSet::Flag::Transient);
- if(!gDescriptorSet) return nullptr;
-
- // Once we have the bufferResource created, we can fill in
- // a descriptor set for creating a structured buffer
- //
- IResourceView::Desc resourceViewDesc;
- resourceViewDesc.type = IResourceView::Type::UnorderedAccess;
- auto resourceView = renderer->createBufferView(structuredBuffer, resourceViewDesc);
- gDescriptorSet->setResource(0, 0, resourceView);
-
- return gDescriptorSet;
-}
-
-gfx::IPipelineState* buildPipelineState(
- gfx::IShaderProgram* shaderProgram,
- gfx::IRenderer* renderer,
- gfx::IPipelineLayout* pipelineLayout)
-{
- // Following the D3D12/Vulkan style of API, we need a pipeline state object
- // (PSO) to encapsulate the configuration of the overall graphics pipeline.
- //
- ComputePipelineStateDesc desc;
- desc.pipelineLayout = pipelineLayout;
- desc.program = shaderProgram;
- gPipelineState = renderer->createComputePipelineState(desc);
- return gPipelineState;
-}
-
-void printInitialValues(float* initialArray, int length)
-{
- // Print out the values before the computation
- printf("Before:\n");
- for (int i = 0; i < length; i++)
- {
- printf("%f, ", initialArray[i]);
- }
- printf("\n");
-}
-
-void dispatchComputation(
- gfx::ICommandQueue* gQueue,
- gfx::IPipelineState* gPipelineState,
- gfx::IPipelineLayout* gPipelineLayout,
- gfx::IDescriptorSet* gDescriptorSet,
- unsigned int gridDimsX,
- unsigned int gridDimsY,
- unsigned int gridDimsZ)
-{
- auto cmdBuf = gQueue->createCommandBuffer();
- auto encoder = cmdBuf->encodeComputeCommands();
- encoder->setPipelineState(gPipelineState);
- encoder->setDescriptorSet(PipelineType::Compute, gPipelineLayout, 0, gDescriptorSet);
- encoder->dispatchCompute(gridDimsX, gridDimsY, gridDimsZ);
- encoder->endEncoding();
- gQueue->executeCommandBuffer(cmdBuf);
-}
-
-void print_output(
- gfx::IRenderer* renderer,
- gfx::IBufferResource* structuredBuffer,
- int length)
-{
- ComPtr<ISlangBlob> blob;
- renderer->readBufferResource(structuredBuffer, 0, length * sizeof(float), blob.writeRef());
- if (float* outputData = (float*)blob->getBufferPointer())
- {
- // Print out the values the the kernel produced
- printf("After: \n");
- for (int i = 0; i < 4; i++)
- {
- printf("%f, ", outputData[i]);
- }
- printf("\n");
- }
-}
-
-// Boilerplate functions to help the slang-generated file and types
-gfx_Window_0* createWindow_0(int32_t _0, int32_t _1)
-{
- return (gfx_Window_0*)createWindow(_0, _1);
-}
-
-gfx_Renderer_0* createRenderer_0(int32_t _0, int32_t _1, gfx_Window_0* _2)
-{
- return (gfx_Renderer_0*)createRenderer(_0, _1, (gfx::Window*)_2);
-}
-
-gfx_BufferResource_0* createStructuredBuffer_0(gfx_Renderer_0* _0, FixedArray<float, 4> _1)
-{
- return (gfx_BufferResource_0*)createStructuredBuffer((gfx::IRenderer*)_0, (float*)&_1);
-}
-
-gfx_ShaderProgram_0* loadShaderProgram_0(gfx_Renderer_0* _0, unsigned char _1[], size_t _2)
-{
- return (gfx_ShaderProgram_0*)loadShaderProgram((gfx::IRenderer*)_0, _1, _2);
-}
-
-gfx_DescriptorSetLayout_0* buildDescriptorSetLayout_0(gfx_Renderer_0* _0)
-{
- return (gfx_DescriptorSetLayout_0*)buildDescriptorSetLayout((gfx::IRenderer*)_0);
-}
-
-gfx_PipelineLayout_0* buildPipeline_0(gfx_Renderer_0* _0, gfx_DescriptorSetLayout_0* _1)
-{
- return (gfx_PipelineLayout_0*)buildPipeline((gfx::IRenderer*)_0, (gfx::IDescriptorSetLayout*)_1);
-}
-
-gfx_DescriptorSet_0* buildDescriptorSet_0(gfx_Renderer_0* _0, gfx_DescriptorSetLayout_0* _1, gfx_BufferResource_0* _2)
-{
- return (gfx_DescriptorSet_0*)buildDescriptorSet(
- (gfx::IRenderer*)_0,
- (gfx::IDescriptorSetLayout*)_1,
- (gfx::IBufferResource*)_2);
-}
-
-gfx_PipelineState_0* buildPipelineState_0(gfx_ShaderProgram_0* _0, gfx_Renderer_0* _1, gfx_PipelineLayout_0* _2)
-{
- return (gfx_PipelineState_0*)buildPipelineState(
- (gfx::IShaderProgram*)_0, (gfx::IRenderer*)_1,
- (gfx::IPipelineLayout*)_2);
-}
-
-void printInitialValues_0(FixedArray<float, 4> _0, int32_t _1)
-{
- printInitialValues((float*)&_0, _1);
-}
-
-void dispatchComputation_0(gfx_CommandQueue_0* _0, gfx_PipelineState_0* _1, gfx_PipelineLayout_0* _2, gfx_DescriptorSet_0* _3, unsigned int gridDimsX, unsigned int gridDimsY, unsigned int gridDimsZ)
-{
- dispatchComputation(
- (gfx::ICommandQueue*)_0,
- (gfx::IPipelineState*)_1,
- (gfx::IPipelineLayout*)_2,
- (gfx::IDescriptorSet*)_3,
- gridDimsX,
- gridDimsY,
- gridDimsZ);
-}
-
-RWStructuredBuffer<float> convertBuffer_0(gfx_BufferResource_0* _0) {
- RWStructuredBuffer<float> result;
- result.data = (float*)_0;
- return result;
-}
-
-gfx_BufferResource_0* unconvertBuffer_0(RWStructuredBuffer<float> _0) {
- return (gfx_BufferResource_0*)(_0.data);
-}
-
-void print_output_0(gfx_CommandQueue_0* _0, gfx_BufferResource_0* _1, int32_t _2)
-{
- print_output((gfx::ICommandQueue*)_0, (gfx::IBufferResource*)_1, _2);
-}
-
-// This "inner" main function is used by the platform abstraction
-// layer to deal with differences in how an entry point needs
-// to be defined for different platforms.
-//
-void innerMain(ApplicationContext* context)
-{
- // We construct an instance of our example application
- // `struct` type, and then walk through the lifecyle
- // of the application.
-
- if (!(executeComputation_0()))
- {
- return exitApplication(context, 1);
- }
-}
-
-// This macro instantiates an appropriate main function to
-// invoke the `innerMain` above.
-//
-GFX_CONSOLE_MAIN(innerMain)
-
-#endif
diff --git a/examples/experimental/heterogeneous-hello-world/shader.cpp b/examples/experimental/heterogeneous-hello-world/shader.cpp
deleted file mode 100644
index 5a8dd7815..000000000
--- a/examples/experimental/heterogeneous-hello-world/shader.cpp
+++ /dev/null
@@ -1,197 +0,0 @@
-#if 0
-#include "../../prelude/slang-cpp-prelude.h"
-
-
-#ifdef SLANG_PRELUDE_NAMESPACE
-using namespace SLANG_PRELUDE_NAMESPACE;
-#endif
-
-Vector<uint32_t, 3> operator*(Vector<uint32_t, 3> a, Vector<uint32_t, 3> b)
-{
- Vector<uint32_t, 3> r;
- r.x = a.x * b.x;
- r.y = a.y * b.y;
- r.z = a.z * b.z;
- return r;
-}
-
-Vector<uint32_t, 3> operator+(Vector<uint32_t, 3> a, Vector<uint32_t, 3> b)
-{
- Vector<uint32_t, 3> r;
- r.x = a.x + b.x;
- r.y = a.y + b.y;
- r.z = a.z + b.z;
- return r;
-}
-
-Vector<uint32_t, 3> make_VecU3(uint32_t a, uint32_t b, uint32_t c)
-{
- return Vector<uint32_t, 3>{ a, b, c};
-}
-
-size_t __computeMainSize = 668;
-unsigned char __computeMain[] = {68, 88, 66, 67, 87, 111, 81, 164, 2, 29, 72, 42, 151, 28, 13, 217, 55, 37, 7, 95, 1, 0, 0, 0, 156, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 8, 1, 0, 0, 24, 1, 0, 0, 40, 1, 0, 0, 32, 2, 0, 0, 82, 68, 69, 70, 204, 0, 0, 0, 1, 0, 0, 0, 88, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 83, 67, 0, 9, 16, 0, 164, 0, 0, 0, 60, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 1, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 101, 110, 116, 114, 121, 80, 111, 105, 110, 116, 80, 97, 114, 97, 109, 115, 95, 105, 111, 66, 117, 102, 102, 101, 114, 95, 48, 0, 60, 0, 0, 0, 1, 0, 0, 0, 112, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 2, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 36, 69, 108, 101, 109, 101, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83, 76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48, 46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 240, 0, 0, 0, 64, 0, 5, 0, 60, 0, 0, 0, 106, 8, 0, 1, 158, 0, 0, 4, 0, 224, 17, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 2, 18, 0, 2, 0, 104, 0, 0, 2, 1, 0, 0, 0, 155, 0, 0, 4, 4, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 6, 224, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0, 0, 0, 63, 0, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 75, 0, 0, 5, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 0, 0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 224, 17, 0, 0, 0, 0, 0, 10, 0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 62, 0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0};
-void computeMain_wrapper(gfx_Renderer_0* renderer, Vector<uint32_t, 3> gridDims,
- RWStructuredBuffer<float> buffer)
-{
- gfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(renderer, __computeMain, __computeMainSize);
- gfx_DescriptorSetLayout_0* setLayout = buildDescriptorSetLayout_0(renderer);
- gfx_PipelineLayout_0* pipelineLayout = buildPipeline_0(renderer, setLayout);
- gfx_DescriptorSet_0* descriptorSet = buildDescriptorSet_0(renderer, setLayout, unconvertBuffer_0(buffer));
- gfx_PipelineState_0* pipelineState = buildPipelineState_0(shaderProgram, renderer, pipelineLayout);
- dispatchComputation_0(renderer, pipelineState, pipelineLayout, descriptorSet, gridDims.x, gridDims.y, gridDims.z);
-}
-
-#line 7 "../../examples/heterogeneous-hello-world/shader.slang"
-struct EntryPointParams_0
-{
- RWStructuredBuffer<float> ioBuffer_0;
-};
-
-struct KernelContext_0
-{
-};
-
-
-#line 21
-struct gfx_Window_0
-{
-};
-
-
-#line 22
-struct gfx_Renderer_0
-{
-};
-
-
-#line 23
-struct gfx_BufferResource_0
-{
-};
-
-
-#line 7
-void _computeMain(void* _S1, void* entryPointParams_0, void* _S2)
-{
- ComputeThreadVaryingInput* _S3 = ((ComputeThreadVaryingInput*)(_S1));
- KernelContext_0 kernelContext_0;
-
-#line 9
- uint32_t tid_0 = (*(&_S3->groupID) * make_VecU3(4U, 1U, 1U) + *(&_S3->groupThreadID)).x;
-
- float* _S4 = &(*(&((EntryPointParams_0*)(entryPointParams_0))->ioBuffer_0))[tid_0];
-
-#line 11
- float i_0 = *_S4;
- bool _S5 = i_0 < 0.50000000000000000000f;
-
-#line 12
- float _S6 = i_0 + i_0;
-
-#line 12
- float _S7 = (F32_sqrt((i_0)));
-
-#line 12
- float o_0 = _S5 ? _S6 : _S7;
-
- float* _S8 = &(*(&((EntryPointParams_0*)(entryPointParams_0))->ioBuffer_0))[tid_0];
-
-#line 14
- *_S8 = o_0;
-
-#line 7
- return;
-}
-
-
-#line 34
-gfx_Window_0* createWindow_0(int32_t _0, int32_t _1);
-
-
-#line 35
-gfx_Renderer_0* createRenderer_0(int32_t _0, int32_t _1, gfx_Window_0* _2);
-
-
-
-gfx_BufferResource_0* createStructuredBuffer_0(gfx_Renderer_0* _0, FixedArray<float, 4> _1);
-
-
-#line 4
-RWStructuredBuffer<float> convertBuffer_0(gfx_BufferResource_0* _0);
-
-
-#line 40
-void printInitialValues_0(FixedArray<float, 4> _0, int32_t _1);
-
-
-#line 41
-void print_output_0(gfx_Renderer_0* _0, gfx_BufferResource_0* _1, int32_t _2);
-
-
-
-
-bool executeComputation_0()
-{
-
-
-
- FixedArray<float, 4> initialArray_0 = { 3.00000000000000000000f, -20.00000000000000000000f, -6.00000000000000000000f, 8.00000000000000000000f };
-
-
- gfx_Window_0* _S9 = createWindow_0(int(1024), int(768));
- gfx_Renderer_0* _S10 = createRenderer_0(int(1024), int(768), _S9);
- gfx_CommandQueue_0* _
- gfx_BufferResource_0* _S11 = createStructuredBuffer_0(_S10, initialArray_0);
- Vector<uint32_t, 3> _S12 = make_VecU3(uint32_t(int(4)), uint32_t(int(1)), uint32_t(int(1)));
- RWStructuredBuffer<float> _S13 = convertBuffer_0(_S11);
-
-#line 57
- computeMain_wrapper(_S10, _S12, _S13);
-
- printInitialValues_0(initialArray_0, int(4));
- print_output_0(_S10, _S11, int(4));
-
-
- return true;
-}
-
-// [numthreads(4, 1, 1)]
-SLANG_PRELUDE_EXPORT
-void computeMain_Thread(ComputeThreadVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
-{
- _computeMain(varyingInput, entryPointParams, globalParams);
-}
-// [numthreads(4, 1, 1)]
-SLANG_PRELUDE_EXPORT
-void computeMain_Group(ComputeVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
-{
- ComputeThreadVaryingInput threadInput = {};
- threadInput.groupID = varyingInput->startGroupID;
- for (uint32_t x = 0; x < 4; ++x)
- {
- threadInput.groupThreadID.x = x;
- _computeMain(&threadInput, entryPointParams, globalParams);
- }
-}
-// [numthreads(4, 1, 1)]
-SLANG_PRELUDE_EXPORT
-void computeMain(ComputeVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
-{
- ComputeVaryingInput vi = *varyingInput;
- ComputeVaryingInput groupVaryingInput = {};
- for (uint32_t z = vi.startGroupID.z; z < vi.endGroupID.z; ++z)
- {
- groupVaryingInput.startGroupID.z = z;
- for (uint32_t y = vi.startGroupID.y; y < vi.endGroupID.y; ++y)
- {
- groupVaryingInput.startGroupID.y = y;
- for (uint32_t x = vi.startGroupID.x; x < vi.endGroupID.x; ++x)
- {
- groupVaryingInput.startGroupID.x = x;
- computeMain_Group(&groupVaryingInput, entryPointParams, globalParams);
- }
- }
- }
-}
-#endif
diff --git a/examples/experimental/heterogeneous-hello-world/shader.slang b/examples/experimental/heterogeneous-hello-world/shader.slang
deleted file mode 100644
index 47c883b39..000000000
--- a/examples/experimental/heterogeneous-hello-world/shader.slang
+++ /dev/null
@@ -1,65 +0,0 @@
-// shader.slang
-
-//TEST_INPUT:ubuffer(random(float, 4096, -1.0, 1.0), stride=4):name=ioBuffer
-RWStructuredBuffer<float> convertBuffer(Ptr<gfx::BufferResource> x);
-
-[shader("compute")]
-[numthreads(4, 1, 1)]
-void computeMain(uniform RWStructuredBuffer<float> 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 {
- struct ApplicationContext{};
- struct Window{};
- struct Renderer{};
- struct BufferResource{};
- struct PipelineLayout{};
- struct PipelineState{};
- struct DescriptorSetLayout{};
- struct DescriptorSet{};
- struct ShaderProgram{};
-}
-
-// Forward declarations of cpp functions
-//
-Ptr<gfx::ShaderProgram> loadShaderProgram(Ptr<gfx::Renderer> renderer);
-Ptr<gfx::Window> createWindow(int gWindowWidth, int gWindowHeight);
-Ptr<gfx::Renderer> createRenderer(
- int gWindowWidth,
- int gWindowHeight,
- Ptr<gfx::Window> gWindow);
-Ptr<gfx::BufferResource> createStructuredBuffer(Ptr<gfx::Renderer> gRenderer, float[4] initialArray);
-void printInitialValues(float[4] initialArray, int length);
-void print_output(
- Ptr<gfx::Renderer> gRenderer,
- Ptr<gfx::BufferResource> gStructuredBuffer,
- int length);
-
-public bool executeComputation() {
- // We will hard-code the size of our rendering window and initial array.
- //
- int windowWidth = 1024;
- int windowHeight = 768;
- float initialArray[4] = { 3.0f, -20.0f, -6.0f, 8.0f };
-
- // Declare functions
- let window = createWindow(windowWidth, windowHeight);
- let renderer = createRenderer(windowWidth, windowHeight, window);
- let structuredBuffer = createStructuredBuffer(renderer, initialArray);
- __GPU_FOREACH(renderer, uint3(4, 1, 1), LAMBDA(uint3 dispatchThreadID)
- { computeMain(convertBuffer(structuredBuffer), dispatchThreadID) ; });
- printInitialValues(initialArray, 4);
- print_output(renderer, structuredBuffer, 4);
-
-
- return true;
-}
diff --git a/examples/experimental/heterogeneous-hello-world/README.md b/examples/heterogeneous-hello-world/README.md
index 709652922..709652922 100644
--- a/examples/experimental/heterogeneous-hello-world/README.md
+++ b/examples/heterogeneous-hello-world/README.md
diff --git a/examples/heterogeneous-hello-world/main.cpp b/examples/heterogeneous-hello-world/main.cpp
new file mode 100644
index 000000000..9e0bb8b0f
--- /dev/null
+++ b/examples/heterogeneous-hello-world/main.cpp
@@ -0,0 +1,335 @@
+// 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 <slang.h>
+#include <slang-com-ptr.h>
+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<gfx::IDevice> gDevice;
+ComPtr<gfx::IShaderProgram> gProgram;
+ComPtr<gfx::IBufferResource> gBufferResource;
+ComPtr<gfx::IResourceView> gResourceView;
+ComPtr<gfx::ITransientResourceHeap> gTransientHeap;
+ComPtr<gfx::IPipelineState> gPipelineState;
+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();
+
+// 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<gfx::IDevice> 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)
+{
+ // 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<slang::ISession> 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<slang::IBlob> diagnosticsBlob;
+ slang::IModule *module = slangSession->loadModule("shader", diagnosticsBlob.writeRef());
+ diagnoseIfNeeded(diagnosticsBlob);
+ if (!module)
+ return NULL;
+
+ // Look up entry point (hardcoded for now)
+ //
+ char const *computeEntryPointName = "computeMain";
+ ComPtr<slang::IEntryPoint> computeEntryPoint;
+ SLANG_RETURN_NULL_ON_FAIL(
+ module->findEntryPointByName(computeEntryPointName, 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<slang::IComponentType *> 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<slang::IComponentType> 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.pipelineType = gfx::PipelineType::Compute;
+ programDesc.slangProgram = composedProgram.get();
+
+ gProgram = device->createProgram(programDesc);
+
+ return gProgram;
+}
+
+gfx::IBufferResource* createStructuredBuffer(
+ gfx::IDevice *device,
+ float *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.cpuAccessFlags = AccessFlag::Write | AccessFlag::Read;
+
+ 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(float *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->wait();
+}
+
+bool printOutputValues(
+ gfx::IDevice *device,
+ gfx::IBufferResource *buffer,
+ int length)
+{
+ ComPtr<ISlangBlob> resultBlob;
+ SLANG_RETURN_FALSE_ON_FAIL(device->readBufferResource(
+ buffer, 0, length * sizeof(float), resultBlob.writeRef()));
+ auto result = reinterpret_cast<const float *>(resultBlob->getBufferPointer());
+ printf("After: \n");
+ for (int i = 0; i < length; i++)
+ {
+ printf("%f, ", result[i]);
+ }
+ printf("\n");
+ 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)
+{
+ return (gfx_ShaderProgram_0*)loadShaderProgram((gfx::IDevice*)_0);
+}
+
+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> 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)
+{
+ return printOutputValues((gfx::IDevice*)_0, (gfx::IBufferResource*)_1, _2);
+}
+
+int main()
+{
+ // We construct an instance of our example application
+ // `struct` type, and then walk through the lifecyle
+ // of the application.
+
+ if (!(executeComputation_0()))
+ {
+ return -1;
+ }
+}
diff --git a/examples/heterogeneous-hello-world/shader.cpp b/examples/heterogeneous-hello-world/shader.cpp
new file mode 100644
index 000000000..0c0c24ebc
--- /dev/null
+++ b/examples/heterogeneous-hello-world/shader.cpp
@@ -0,0 +1,215 @@
+#include "../../prelude/slang-cpp-prelude.h"
+
+
+#ifdef SLANG_PRELUDE_NAMESPACE
+using namespace SLANG_PRELUDE_NAMESPACE;
+#endif
+
+Vector<uint32_t, 3> operator+(Vector<uint32_t, 3> a, Vector<uint32_t, 3> b)
+{
+ Vector<uint32_t, 3> r;
+ r.x = a.x + b.x;
+ r.y = a.y + b.y;
+ r.z = a.z + b.z;
+ return r;
+}
+
+Vector<uint32_t, 3> operator*(Vector<uint32_t, 3> a, Vector<uint32_t, 3> b)
+{
+ Vector<uint32_t, 3> r;
+ r.x = a.x * b.x;
+ r.y = a.y * b.y;
+ r.z = a.z * b.z;
+ return r;
+}
+
+Vector<uint32_t, 3> make_VecU3(uint32_t a, uint32_t b, uint32_t c)
+{
+ return Vector<uint32_t, 3>{ a, b, c};
+}
+
+size_t __computeMainSize = 668;
+unsigned char __computeMain[] = {68, 88, 66, 67, 87, 111, 81, 164, 2, 29, 72, 42, 151, 28, 13, 217, 55, 37, 7, 95, 1,
+0, 0, 0, 156, 2, 0, 0, 5, 0, 0, 0, 52, 0, 0, 0, 8, 1, 0, 0, 24,
+1, 0, 0, 40, 1, 0, 0, 32, 2, 0, 0, 82, 68, 69, 70, 204, 0, 0, 0, 1,
+0, 0, 0, 88, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 0, 4, 83, 67, 0,
+9, 16, 0, 164, 0, 0, 0, 60, 0, 0, 0, 6, 0, 0, 0, 6, 0, 0, 0, 1,
+0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 101,
+110, 116, 114, 121, 80, 111, 105, 110, 116, 80, 97, 114, 97, 109, 115, 95, 105, 111, 66, 117,
+102, 102, 101, 114, 95, 48, 0, 60, 0, 0, 0, 1, 0, 0, 0, 112, 0, 0, 0, 4,
+0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 136, 0, 0, 0, 0, 0, 0, 0, 4,
+0, 0, 0, 2, 0, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 36, 69, 108, 101, 109,
+101, 110, 116, 0, 171, 171, 171, 0, 0, 3, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 77, 105, 99, 114, 111, 115, 111, 102, 116, 32, 40, 82, 41, 32, 72, 76, 83,
+76, 32, 83, 104, 97, 100, 101, 114, 32, 67, 111, 109, 112, 105, 108, 101, 114, 32, 49, 48,
+46, 49, 0, 73, 83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 79,
+83, 71, 78, 8, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 83, 72, 69, 88, 240,
+0, 0, 0, 64, 0, 5, 0, 60, 0, 0, 0, 106, 8, 0, 1, 158, 0, 0, 4, 0,
+224, 17, 0, 0, 0, 0, 0, 4, 0, 0, 0, 95, 0, 0, 2, 18, 0, 2, 0, 104,
+0, 0, 2, 1, 0, 0, 0, 155, 0, 0, 4, 4, 0, 0, 0, 1, 0, 0, 0, 1,
+0, 0, 0, 167, 0, 0, 8, 18, 0, 16, 0, 0, 0, 0, 0, 10, 0, 2, 0, 1,
+64, 0, 0, 0, 0, 0, 0, 6, 224, 17, 0, 0, 0, 0, 0, 49, 0, 0, 7, 34,
+0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 1, 64, 0, 0, 0,
+0, 0, 63, 0, 0, 0, 7, 66, 0, 16, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0,
+0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 75, 0, 0, 5, 18, 0, 16, 0, 0,
+0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 55, 0, 0, 9, 18, 0, 16, 0, 0,
+0, 0, 0, 26, 0, 16, 0, 0, 0, 0, 0, 42, 0, 16, 0, 0, 0, 0, 0, 10,
+0, 16, 0, 0, 0, 0, 0, 168, 0, 0, 8, 18, 224, 17, 0, 0, 0, 0, 0, 10,
+0, 2, 0, 1, 64, 0, 0, 0, 0, 0, 0, 10, 0, 16, 0, 0, 0, 0, 0, 62,
+0, 0, 1, 83, 84, 65, 84, 116, 0, 0, 0, 7, 0, 0, 0, 1, 0, 0, 0, 0,
+0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+0, 0, 0, 0, 0, 0, 0, };
+void computeMain_wrapper(gfx_Device_0* device, Vector<uint32_t, 3> gridDims,
+ RWStructuredBuffer<float> buffer)
+{
+ gfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(device);
+ gfx_TransientResourceHeap_0* transientHeap = buildTransientHeap_0(device);
+ gfx_PipelineState_0* pipelineState = buildPipelineState_0(device, shaderProgram);
+ gfx_ResourceView_0* bufferView = createBufferView_0(device, unconvertBuffer_0(buffer));
+ dispatchComputation_0(device, transientHeap, pipelineState, bufferView, gridDims.x, gridDims.y, gridDims.z);
+}
+
+#line 8 "../../../examples/heterogeneous-hello-world/shader.slang"
+struct EntryPointParams_0
+{
+ RWStructuredBuffer<float> ioBuffer_0;
+};
+
+
+#line 21
+struct gfx_Device_0
+{
+};
+
+
+#line 22
+struct gfx_BufferResource_0
+{
+};
+
+
+#line 23
+struct gfx_ResourceView_0
+{
+};
+
+
+#line 8
+void _computeMain(void* _S1, void* entryPointParams_0, void* _S2)
+{
+
+#line 8
+ ComputeThreadVaryingInput* _S3 = (slang_bit_cast<ComputeThreadVaryingInput*>(_S1));
+
+ uint32_t tid_0 = (*(&_S3->groupID) * make_VecU3(4U, 1U, 1U) + *(&_S3->groupThreadID)).x;
+
+ float* _S4 = &(*(&(slang_bit_cast<EntryPointParams_0*>(entryPointParams_0))->ioBuffer_0))[tid_0];
+
+#line 12
+ float i_0 = *_S4;
+ bool _S5 = i_0 < 0.50000000000000000000f;
+
+#line 13
+ float _S6 = i_0 + i_0;
+
+#line 13
+ float _S7 = (F32_sqrt((i_0)));
+
+#line 13
+ float o_0 = _S5 ? _S6 : _S7;
+
+ float* _S8 = &(*(&(slang_bit_cast<EntryPointParams_0*>(entryPointParams_0))->ioBuffer_0))[tid_0];
+
+#line 15
+ *_S8 = o_0;
+ return;
+}
+
+
+#line 31
+gfx_Device_0* createDevice_0();
+
+gfx_BufferResource_0* createStructuredBuffer_0(gfx_Device_0* _0, FixedArray<float, 4> _1);
+
+
+gfx_ResourceView_0* createBufferView_0(gfx_Device_0* _0, gfx_BufferResource_0* _1);
+
+
+#line 4
+RWStructuredBuffer<float> convertBuffer_0(gfx_BufferResource_0* _0);
+
+
+#line 44
+void printInitialValues_0(FixedArray<float, 4> _0, int32_t _1);
+
+
+#line 50
+bool printOutputValues_0(gfx_Device_0* _0, gfx_BufferResource_0* _1, int32_t _2);
+
+
+
+
+bool executeComputation_0()
+{
+
+ FixedArray<float, 4> initialArray_0 = { 3.00000000000000000000f, -20.00000000000000000000f, -6.00000000000000000000f, 8.00000000000000000000f };
+
+
+ gfx_Device_0* _S9 = createDevice_0();
+ gfx_BufferResource_0* _S10 = createStructuredBuffer_0(_S9, initialArray_0);
+ gfx_ResourceView_0* _S11 = createBufferView_0(_S9, _S10);
+ Vector<uint32_t, 3> _S12 = make_VecU3(uint32_t(int(4)), uint32_t(int(1)), uint32_t(int(1)));
+ RWStructuredBuffer<float> _S13 = convertBuffer_0(_S10);
+
+#line 64
+ computeMain_wrapper(_S9, _S12, _S13);
+
+ printInitialValues_0(initialArray_0, int(4));
+ bool _S14 = printOutputValues_0(_S9, _S10, int(4));
+
+
+ return true;
+}
+
+// [numthreads(4, 1, 1)]
+SLANG_PRELUDE_EXPORT
+void computeMain_Thread(ComputeThreadVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
+{
+ _computeMain(varyingInput, entryPointParams, globalParams);
+}
+// [numthreads(4, 1, 1)]
+SLANG_PRELUDE_EXPORT
+void computeMain_Group(ComputeVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
+{
+ ComputeThreadVaryingInput threadInput = {};
+ threadInput.groupID = varyingInput->startGroupID;
+ for (uint32_t x = 0; x < 4; ++x)
+ {
+ threadInput.groupThreadID.x = x;
+ _computeMain(&threadInput, entryPointParams, globalParams);
+ }
+}
+// [numthreads(4, 1, 1)]
+SLANG_PRELUDE_EXPORT
+void computeMain(ComputeVaryingInput* varyingInput, void* entryPointParams, void* globalParams)
+{
+ ComputeVaryingInput vi = *varyingInput;
+ ComputeVaryingInput groupVaryingInput = {};
+ for (uint32_t z = vi.startGroupID.z; z < vi.endGroupID.z; ++z)
+ {
+ groupVaryingInput.startGroupID.z = z;
+ for (uint32_t y = vi.startGroupID.y; y < vi.endGroupID.y; ++y)
+ {
+ groupVaryingInput.startGroupID.y = y;
+ for (uint32_t x = vi.startGroupID.x; x < vi.endGroupID.x; ++x)
+ {
+ groupVaryingInput.startGroupID.x = x;
+ computeMain_Group(&groupVaryingInput, entryPointParams, globalParams);
+ }
+ }
+ }
+}
diff --git a/examples/heterogeneous-hello-world/shader.slang b/examples/heterogeneous-hello-world/shader.slang
new file mode 100644
index 000000000..b66640e3d
--- /dev/null
+++ b/examples/heterogeneous-hello-world/shader.slang
@@ -0,0 +1,71 @@
+// shader.slang
+
+//TEST_INPUT:ubuffer(random(float, 4096, -1.0, 1.0), stride=4):name=ioBuffer
+RWStructuredBuffer<float> convertBuffer(Ptr<gfx::BufferResource> x);
+
+[shader("compute")]
+[numthreads(4, 1, 1)]
+void computeMain(uniform RWStructuredBuffer<float> 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 {
+ struct Device{};
+ struct BufferResource{};
+ struct ResourceView{};
+ struct TransientResourceHeap{};
+ struct PipelineState{};
+ struct ShaderProgram{};
+}
+
+// Forward declarations of cpp functions
+//
+Ptr<gfx::Device> createDevice();
+Ptr<gfx::ShaderProgram> loadShaderProgram(Ptr<gfx::Device> device);
+Ptr<gfx::BufferResource> createStructuredBuffer(
+ Ptr<gfx::Device> 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,
+ int length);
+
+public 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-prelude.h b/prelude/slang-cpp-prelude.h
index 76ff16590..5981c8734 100644
--- a/prelude/slang-cpp-prelude.h
+++ b/prelude/slang-cpp-prelude.h
@@ -132,21 +132,18 @@ Any compilers not detected by the above logic are now now explicitly zeroed out.
# define SLANG_UNROLL
#endif
-struct gfx_Renderer_0;
+struct gfx_Device_0;
struct gfx_BufferResource_0;
struct gfx_ShaderProgram_0;
-struct gfx_DescriptorSetLayout_0;
-struct gfx_PipelineLayout_0;
-struct gfx_DescriptorSet_0;
-struct gfx_BufferResource_0;
+struct gfx_ResourceView_0;
+struct gfx_TransientResourceHeap_0;
struct gfx_PipelineState_0;
-struct gfx_CommandQueue_0;
-gfx_ShaderProgram_0* loadShaderProgram_0(gfx_Renderer_0* _0, unsigned char _1[], size_t _2);
-gfx_DescriptorSetLayout_0* buildDescriptorSetLayout_0(gfx_Renderer_0* _0);
-gfx_PipelineLayout_0* buildPipeline_0(gfx_Renderer_0* _0, gfx_DescriptorSetLayout_0* _1);
-gfx_DescriptorSet_0* buildDescriptorSet_0(gfx_Renderer_0* _0, gfx_DescriptorSetLayout_0* _1, gfx_BufferResource_0* _2);
-gfx_PipelineState_0* buildPipelineState_0(gfx_ShaderProgram_0* _0, gfx_Renderer_0* _1, gfx_PipelineLayout_0* _2);
-void dispatchComputation_0(gfx_Renderer_0* _0, gfx_PipelineState_0* _1, gfx_PipelineLayout_0* _2, gfx_DescriptorSet_0* _3, uint32_t _4, uint32_t _5, uint32_t _6);
+
+gfx_ShaderProgram_0* loadShaderProgram_0(gfx_Device_0* _0);
+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
diff --git a/premake5.lua b/premake5.lua
index 71af44d4a..38cb78a9a 100644
--- a/premake5.lua
+++ b/premake5.lua
@@ -668,6 +668,9 @@ example "shader-object"
example "cpu-hello-world"
kind "ConsoleApp"
+example "heterogeneous-hello-world"
+ kind "ConsoleApp"
+
-- Most of the other projects have more interesting configuration going
-- on, so let's walk through them in order of increasing complexity.
--
diff --git a/slang.sln b/slang.sln
index c0e80b982..a33155535 100644
--- a/slang.sln
+++ b/slang.sln
@@ -31,6 +31,8 @@ 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-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}"
@@ -181,6 +183,14 @@ 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
+ {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|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|Win32.ActiveCfg = Debug|Win32
{2F8724C6-1BC3-2730-84D5-3F277030D04A}.Debug|Win32.Build.0 = Debug|Win32
{2F8724C6-1BC3-2730-84D5-3F277030D04A}.Debug|x64.ActiveCfg = Debug|x64
@@ -301,6 +311,7 @@ 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}
+ {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/slang-ast-stmt.h b/source/slang/slang-ast-stmt.h
index 20f9e270e..2edc844c6 100644
--- a/source/slang/slang-ast-stmt.h
+++ b/source/slang/slang-ast-stmt.h
@@ -125,7 +125,7 @@ class GpuForeachStmt : public ScopeStmt
{
SLANG_AST_CLASS(GpuForeachStmt)
- Expr* renderer = nullptr;
+ Expr* device = nullptr;
Expr* gridDims = nullptr;
VarDecl* dispatchThreadID = nullptr;
Expr* kernelCall = nullptr;
diff --git a/source/slang/slang-check-stmt.cpp b/source/slang/slang-check-stmt.cpp
index 9a5aee15c..6f8ed9ff5 100644
--- a/source/slang/slang-check-stmt.cpp
+++ b/source/slang/slang-check-stmt.cpp
@@ -290,7 +290,7 @@ namespace Slang
void SemanticsStmtVisitor::visitGpuForeachStmt(GpuForeachStmt*stmt)
{
- stmt->renderer = CheckExpr(stmt->renderer);
+ stmt->device = CheckExpr(stmt->device);
stmt->gridDims = CheckExpr(stmt->gridDims);
ensureDeclBase(stmt->dispatchThreadID, DeclCheckState::Checked);
WithOuterStmt subContext(this, stmt);
diff --git a/source/slang/slang-emit-cpp.cpp b/source/slang/slang-emit-cpp.cpp
index 60b86b827..f71406261 100644
--- a/source/slang/slang-emit-cpp.cpp
+++ b/source/slang/slang-emit-cpp.cpp
@@ -2710,22 +2710,20 @@ void CPPSourceEmitter::emitModuleImpl(IRModule* module, DiagnosticSink* sink)
// Emit a wrapper function for calling the shader blob
m_writer->emit("void ");
m_writer->emit(entryPointName);
- m_writer->emit("_wrapper(gfx_Renderer_0* renderer, Vector<uint32_t, 3> gridDims, \n");
+ m_writer->emit("_wrapper(gfx_Device_0* device, Vector<uint32_t, 3> gridDims, \n");
m_writer->emit("\tRWStructuredBuffer<float> buffer)\n{");
- m_writer->emit("\n\tgfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(renderer, __");
+ /* 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_DescriptorSetLayout_0* setLayout = buildDescriptorSetLayout_0(renderer);");
- m_writer->emit("\n\tgfx_PipelineLayout_0* pipelineLayout = buildPipeline_0(renderer, setLayout);");
- m_writer->emit("\n\tgfx_DescriptorSet_0* descriptorSet = ");
- m_writer->emit("buildDescriptorSet_0(renderer, setLayout, unconvertBuffer_0(buffer));");
+ m_writer->emit("Size);");*/
+ m_writer->emit("\n\tgfx_ShaderProgram_0* shaderProgram = loadShaderProgram_0(device);");
+ m_writer->emit("\n\tgfx_TransientResourceHeap_0* transientHeap = buildTransientHeap_0(device);");
m_writer->emit("\n\tgfx_PipelineState_0* pipelineState = ");
- m_writer->emit("buildPipelineState_0(shaderProgram, renderer, pipelineLayout);");
-
- m_writer->emit("\n\tdispatchComputation_0(renderer, pipelineState, pipelineLayout, ");
- m_writer->emit("descriptorSet, gridDims.x, gridDims.y, gridDims.z);");
+ 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("bufferView, gridDims.x, gridDims.y, gridDims.z);");
m_writer->emit("\n}\n");
}
}
diff --git a/source/slang/slang-ir-legalize-types.cpp b/source/slang/slang-ir-legalize-types.cpp
index d88166f83..416df6c77 100644
--- a/source/slang/slang-ir-legalize-types.cpp
+++ b/source/slang/slang-ir-legalize-types.cpp
@@ -1668,6 +1668,9 @@ static LegalVal legalizeInst(
return legalizeConstruct(context, type);
case kIROp_undefined:
return LegalVal();
+ case kIROp_GpuForeach:
+ // This case should only happen when compiling for a target that does not support GpuForeach
+ return LegalVal();
default:
// TODO: produce a user-visible diagnostic here
SLANG_UNEXPECTED("non-simple operand(s)!");
diff --git a/source/slang/slang-lower-to-ir.cpp b/source/slang/slang-lower-to-ir.cpp
index c1738887d..cde9fcc70 100644
--- a/source/slang/slang-lower-to-ir.cpp
+++ b/source/slang/slang-lower-to-ir.cpp
@@ -4345,13 +4345,13 @@ struct StmtLoweringVisitor : StmtVisitor<StmtLoweringVisitor>
auto builder = getBuilder();
startBlockIfNeeded(stmt);
- auto renderer = getSimpleVal(context, lowerRValueExpr(context, stmt->renderer));
+ auto device = getSimpleVal(context, lowerRValueExpr(context, stmt->device));
auto gridDims = getSimpleVal(context, lowerRValueExpr(context, stmt->gridDims));
List<IRInst*> irArgs;
if (auto callExpr = as<InvokeExpr>(stmt->kernelCall))
{
- irArgs.add(renderer);
+ irArgs.add(device);
irArgs.add(gridDims);
auto fref = getSimpleVal(context, lowerRValueExpr(context, callExpr->functionExpr));
irArgs.add(fref);
diff --git a/source/slang/slang-parser.cpp b/source/slang/slang-parser.cpp
index 7bb933b39..d9bbaaace 100644
--- a/source/slang/slang-parser.cpp
+++ b/source/slang/slang-parser.cpp
@@ -3745,7 +3745,7 @@ namespace Slang
parser->FillPosition(stmt);
parser->ReadToken("__GPU_FOREACH");
parser->ReadToken(TokenType::LParent);
- stmt->renderer = parser->ParseArgExpr();
+ stmt->device = parser->ParseArgExpr();
parser->ReadToken(TokenType::Comma);
stmt->gridDims = parser->ParseArgExpr();