diff options
| author | Dietrich Geisler <dag368@cornell.edu> | 2020-07-27 12:14:17 -0400 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-07-27 09:14:17 -0700 |
| commit | 348058f96e81d11da2698acf8343a99a199f1f24 (patch) | |
| tree | b795625654f7696b50e98127a9b745bdb8f68fc3 /examples | |
| parent | 87940a649e3b4f757905015de95225d57ec2f27c (diff) | |
Baseline Heterogeneous Example (#1460)
* Baseline Heterogeneous Example
This PR introduces a baseline heterogeneous example, including both a
Slang file and an associated C++ helper file. This refactoring
primarily moves the Slang file "into the driver's seat" while
maintaining that the C++ side still does most of the actual work.
* Fix to prelude path
Diffstat (limited to 'examples')
| -rw-r--r-- | examples/heterogeneous-hello-world/main.cpp | 253 | ||||
| -rw-r--r-- | examples/heterogeneous-hello-world/shader.cpp | 192 | ||||
| -rw-r--r-- | examples/heterogeneous-hello-world/shader.slang | 72 |
3 files changed, 336 insertions, 181 deletions
diff --git a/examples/heterogeneous-hello-world/main.cpp b/examples/heterogeneous-hello-world/main.cpp index 8d5540a32..a590f8c4b 100644 --- a/examples/heterogeneous-hello-world/main.cpp +++ b/examples/heterogeneous-hello-world/main.cpp @@ -35,18 +35,36 @@ #include "gfx/render.h" #include "gfx/d3d11/render-d3d11.h" #include "gfx/window.h" +#include "../../prelude/slang-cpp-types.h"; using namespace gfx; -// We will start with a function that will invoke the Slang compiler -// to generate target-specific code from a shader file, and then -// use that to initialize an API shader program. +// We create global ref pointers to avoid dereferencing values // -// Note that `Renderer` and `ShaderProgram` here are types from -// the graphics API abstraction layer, and *not* part of the -// Slang API. This function is representative of code that a user -// might write to integrate Slang into their renderer/engine. +RefPtr<gfx::ShaderProgram> gShaderProgram; +RefPtr<gfx::ApplicationContext> gAppContext; +RefPtr<gfx::Renderer> gRenderer; + +RefPtr<gfx::BufferResource> gStructuredBuffer; + +RefPtr<gfx::PipelineLayout> gPipelineLayout; +RefPtr<gfx::PipelineState> gPipelineState; +RefPtr<gfx::DescriptorSetLayout> gDescriptorSetLayout; +RefPtr<gfx::DescriptorSet> gDescriptorSet; + +// Boilerplate types to help the slan-generated file // -RefPtr<gfx::ShaderProgram> loadShaderProgram(gfx::Renderer* renderer) +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(); + +gfx::ShaderProgram* loadShaderProgram(gfx::Renderer* renderer) { // First, we need to create a "session" for interacting with the Slang // compiler. This scopes all of our application's interactions @@ -159,54 +177,37 @@ RefPtr<gfx::ShaderProgram> loadShaderProgram(gfx::Renderer* renderer) programDesc.kernels = &kernelDescs[0]; programDesc.kernelCount = 2; - auto shaderProgram = renderer->createProgram(programDesc); + gShaderProgram = renderer->createProgram(programDesc); // Once we've used the output blobs from the Slang compiler to initialize // the API-specific shader program, we can release their memory. // computeShaderBlob->release(); - return shaderProgram; + 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. // -Result computeMain() +gfx::Window* createWindow(int windowWidth, int windowHeight) { - // We will hard-code the size of our rendering window and initial array. - // - int gWindowWidth = 1024; - int gWindowHeight = 768; - float initialArray[4] = { 3.0f, -20.0f, -6.0f, 8.0f }; - - // We will define global variables for the various platform and - // graphics API objects that our application needs: - // - // As a reminder, *none* of these are Slang API objects. All - // of them come from the utility library we are using to simplify - // building an example program. - // - gfx::ApplicationContext* gAppContext; - gfx::Window* gWindow; - RefPtr<gfx::Renderer> gRenderer; - - RefPtr<gfx::BufferResource> gUnorderedAccess; - RefPtr<gfx::BufferResource> gReadBuffer; - - RefPtr<gfx::PipelineLayout> gPipelineLayout; - RefPtr<gfx::PipelineState> gPipelineState; - RefPtr<gfx::DescriptorSet> gDescriptorSet; - // Create a window for our application to render into. // WindowDesc windowDesc; windowDesc.title = "Hello, World!"; - windowDesc.width = gWindowWidth; - windowDesc.height = gWindowHeight; - gWindow = createWindow(windowDesc); + windowDesc.width = windowWidth; + windowDesc.height = windowHeight; + return createWindow(windowDesc); + //return globalWindow; +} +gfx::Renderer* createRenderer( + int windowWidth, + int windowHeight, + gfx::Window* window) +{ // Initialize the rendering layer. // // Note: for now we are hard-coding logic to use the @@ -216,14 +217,18 @@ Result computeMain() // gRenderer = createD3D11Renderer(); Renderer::Desc rendererDesc; - rendererDesc.width = gWindowWidth; - rendererDesc.height = gWindowHeight; + rendererDesc.width = windowWidth; + rendererDesc.height = windowHeight; { - Result res = gRenderer->initialize(rendererDesc, getPlatformWindowHandle(gWindow)); - if(SLANG_FAILED(res)) return res; + Result res = gRenderer->initialize(rendererDesc, getPlatformWindowHandle(window)); + if (SLANG_FAILED(res)) return nullptr; } + return gRenderer; +} - // Create a structured buffer for passing the compute data +gfx::BufferResource* createStructuredBuffer(gfx::Renderer* renderer, float* initialArray) +{ + // Create a structured buffer for storing the data for computation // int structuredBufferSize = 4 * sizeof(float); @@ -233,23 +238,21 @@ Result computeMain() structuredBufferDesc.elementSize = 4; structuredBufferDesc.cpuAccessFlags = Resource::AccessFlag::Read; - gUnorderedAccess = gRenderer->createBufferResource( + gStructuredBuffer = renderer->createBufferResource( Resource::Usage::UnorderedAccess, structuredBufferDesc, initialArray); - if(!gUnorderedAccess) return SLANG_FAIL; - - // Now we will use our `loadShaderProgram` function to load - // the code from `shader.slang` into the graphics API. - // - RefPtr<ShaderProgram> shaderProgram = loadShaderProgram(gRenderer); - if(!shaderProgram) return SLANG_FAIL; + return gStructuredBuffer; +} +gfx::DescriptorSetLayout* buildDescriptorSetLayout(gfx::Renderer* 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*. + // DescriptorSetLayout::SlotRangeDesc slotRanges[] = { DescriptorSetLayout::SlotRangeDesc(DescriptorSlotType::StorageBuffer), @@ -257,78 +260,96 @@ Result computeMain() DescriptorSetLayout::Desc descriptorSetLayoutDesc; descriptorSetLayoutDesc.slotRangeCount = 1; descriptorSetLayoutDesc.slotRanges = &slotRanges[0]; - auto descriptorSetLayout = gRenderer->createDescriptorSetLayout(descriptorSetLayoutDesc); - if(!descriptorSetLayout) return SLANG_FAIL; + gDescriptorSetLayout = renderer->createDescriptorSetLayout(descriptorSetLayoutDesc); + return gDescriptorSetLayout; +} +gfx::PipelineLayout* buildPipeline(gfx::Renderer* renderer, gfx::DescriptorSetLayout* descriptorSetLayout) +{ // Next we will allocate a pipeline layout, which specifies // that we will render with only a single descriptor set bound. // PipelineLayout::DescriptorSetDesc descriptorSets[] = { - PipelineLayout::DescriptorSetDesc( descriptorSetLayout ), + PipelineLayout::DescriptorSetDesc(descriptorSetLayout), }; PipelineLayout::Desc pipelineLayoutDesc; pipelineLayoutDesc.renderTargetCount = 1; pipelineLayoutDesc.descriptorSetCount = 1; pipelineLayoutDesc.descriptorSets = &descriptorSets[0]; - auto pipelineLayout = gRenderer->createPipelineLayout(pipelineLayoutDesc); - if(!pipelineLayout) return SLANG_FAIL; + gPipelineLayout = renderer->createPipelineLayout(pipelineLayoutDesc); - gPipelineLayout = pipelineLayout; + return gPipelineLayout; +} +gfx::DescriptorSet* buildDescriptorSet( + gfx::Renderer* renderer, + gfx::DescriptorSetLayout* descriptorSetLayout, + gfx::BufferResource* structuredBuffer) +{ // Once we have the descriptor set layout, we can allocate // and fill in a descriptor set to hold our parameters. // - auto descriptorSet = gRenderer->createDescriptorSet(descriptorSetLayout); - if(!descriptorSet) return SLANG_FAIL; + gDescriptorSet = renderer->createDescriptorSet(descriptorSetLayout); + if(!gDescriptorSet) return nullptr; // Once we have the bufferResource created, we can fill in // a descriptor set for creating a structured buffer // ResourceView::Desc resourceViewDesc; resourceViewDesc.type = ResourceView::Type::UnorderedAccess; - auto resourceView = gRenderer->createBufferView(gUnorderedAccess, resourceViewDesc); - descriptorSet->setResource(0, 0, resourceView); + auto resourceView = renderer->createBufferView(structuredBuffer, resourceViewDesc); + gDescriptorSet->setResource(0, 0, resourceView); - gDescriptorSet = descriptorSet; + return gDescriptorSet; +} +gfx::PipelineState* buildPipelineState( + gfx::ShaderProgram* shaderProgram, + gfx::Renderer* renderer, + gfx::PipelineLayout* 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 = gPipelineLayout; + desc.pipelineLayout = pipelineLayout; desc.program = shaderProgram; - auto pipelineState = gRenderer->createComputePipelineState(desc); - if(!pipelineState) return SLANG_FAIL; - - gPipelineState = pipelineState; - - // Once we've initialized all the graphics API objects, - // it is time to show our application window and start rendering. - // - //showWindow(gWindow); - - // Now we configure our graphics pipeline state by setting the - // PSO, binding our descriptor set (which references the - // constant buffer that we wrote to above), and setting - // some additional bits of state, before drawing our triangle. - // + gPipelineState = renderer->createComputePipelineState(desc); + return gPipelineState; +} +void printInitialValues(float* initialArray, int length) +{ // Print out the values before the computation printf("Before:\n"); - for (float v : initialArray) + for (int i = 0; i < length; i++) { - printf("%f, ", v); + printf("%f, ", initialArray[i]); } printf("\n"); +} + +void dispatchComputation( + gfx::Renderer* gRenderer, + gfx::PipelineState* gPipelineState, + gfx::PipelineLayout* gPipelineLayout, + gfx::DescriptorSet* gDescriptorSet) +{ gRenderer->setPipelineState(PipelineType::Compute, gPipelineState); gRenderer->setDescriptorSet(PipelineType::Compute, gPipelineLayout, 0, gDescriptorSet); gRenderer->dispatchCompute(4, 1, 1); +} - if(float* outputData = (float*) gRenderer->map(gUnorderedAccess, MapFlavor::HostRead)) +void print_output( + gfx::Renderer* renderer, + gfx::BufferResource* structuredBuffer, + int length) +{ + if (float* outputData = (float*)renderer->map(structuredBuffer, MapFlavor::HostRead)) { // Print out the values the the kernel produced printf("After: \n"); @@ -338,10 +359,74 @@ Result computeMain() } printf("\n"); - gRenderer->unmap(gUnorderedAccess); + renderer->unmap(structuredBuffer); } +} + +// 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::Renderer*)_0, (float*)&_1); +} + +gfx_ShaderProgram_0* loadShaderProgram_0(gfx_Renderer_0* _0) +{ + return (gfx_ShaderProgram_0*)loadShaderProgram((gfx::Renderer*)_0); +} + +gfx_DescriptorSetLayout_0* buildDescriptorSetLayout_0(gfx_Renderer_0* _0) +{ + return (gfx_DescriptorSetLayout_0*)buildDescriptorSetLayout((gfx::Renderer*)_0); +} - return SLANG_OK; +gfx_PipelineLayout_0* buildPipeline_0(gfx_Renderer_0* _0, gfx_DescriptorSetLayout_0* _1) +{ + return (gfx_PipelineLayout_0*)buildPipeline((gfx::Renderer*)_0, (gfx::DescriptorSetLayout*)_1); +} + +gfx_DescriptorSet_0* buildDescriptorSet_0(gfx_Renderer_0* _0, gfx_DescriptorSetLayout_0* _1, gfx_BufferResource_0* _2) +{ + return (gfx_DescriptorSet_0*)buildDescriptorSet( + (gfx::Renderer*)_0, + (gfx::DescriptorSetLayout*)_1, + (gfx::BufferResource*)_2); +} + +gfx_PipelineState_0* buildPipelineState_0(gfx_ShaderProgram_0* _0, gfx_Renderer_0* _1, gfx_PipelineLayout_0* _2) +{ + return (gfx_PipelineState_0*)buildPipelineState( + (gfx::ShaderProgram*)_0, + (gfx::Renderer*)_1, + (gfx::PipelineLayout*)_2); +} + +void printInitialValues_0(FixedArray<float, 4> _0, int32_t _1) +{ + printInitialValues((float*)&_0, _1); +} + +void dispatchComputation_0(gfx_Renderer_0* _0, gfx_PipelineState_0* _1, gfx_PipelineLayout_0* _2, gfx_DescriptorSet_0* _3) +{ + dispatchComputation( + (gfx::Renderer*)_0, + (gfx::PipelineState*)_1, + (gfx::PipelineLayout*)_2, + (gfx::DescriptorSet*)_3); +} + +void print_output_0(gfx_Renderer_0* _0, gfx_BufferResource_0* _1, int32_t _2) +{ + print_output((gfx::Renderer*)_0, (gfx::BufferResource*)_1, _2); } // This "inner" main function is used by the platform abstraction @@ -354,7 +439,7 @@ void innerMain(ApplicationContext* context) // `struct` type, and then walk through the lifecyle // of the application. - if (SLANG_FAILED(computeMain())) + if (!(executeComputation_0())) { return exitApplication(context, 1); } diff --git a/examples/heterogeneous-hello-world/shader.cpp b/examples/heterogeneous-hello-world/shader.cpp index 396b78cb4..e8656bed7 100644 --- a/examples/heterogeneous-hello-world/shader.cpp +++ b/examples/heterogeneous-hello-world/shader.cpp @@ -1,126 +1,130 @@ #include "../../prelude/slang-cpp-prelude.h" -namespace { // anonymous +//namespace { // anonymous #ifdef SLANG_PRELUDE_NAMESPACE using namespace SLANG_PRELUDE_NAMESPACE; #endif -struct KernelContext; +#line 21 "../../examples/heterogeneous-hello-world/shader.slang" +struct gfx_Window_0 +{ +}; -#line 13 "shader.slang" -struct UniformState + +#line 22 +struct gfx_Renderer_0 { +}; -#line 4 - RWStructuredBuffer<float> ioBuffer_0; +#line 23 +struct gfx_BufferResource_0 +{ +}; +struct gfx_ShaderProgram_0 +{ }; -struct KernelContext + +#line 26 +struct gfx_DescriptorSetLayout_0 { - UniformState* uniformState; - uint3 dispatchThreadID; - uint3 groupID; - uint3 groupDispatchThreadID; - uint3 calcGroupThreadID() const - { - uint3 v = { dispatchThreadID.x - groupDispatchThreadID.x, dispatchThreadID.y - groupDispatchThreadID.y, dispatchThreadID.z - groupDispatchThreadID.z }; - return v; - } +}; -#line 8 - void _computeMain() - { +#line 24 +struct gfx_PipelineLayout_0 +{ +}; -#line 10 - uint32_t tid_0 = dispatchThreadID.x; - float i_0 = (uniformState->ioBuffer_0)[tid_0]; - bool _S1 = i_0 < 0.50000000000000000000f; +#line 27 +struct gfx_DescriptorSet_0 +{ +}; -#line 13 - float _S2 = i_0 + i_0; -#line 13 - float _S3 = (F32_sqrt((i_0))); +#line 25 +struct gfx_PipelineState_0 +{ +}; -#line 13 - float o_0 = _S1 ? _S2 : _S3; - (uniformState->ioBuffer_0)[tid_0] = o_0; +#line 34 +gfx_Window_0* createWindow_0(int32_t _0, int32_t _1); -#line 8 - return; - } -}; +#line 35 +gfx_Renderer_0* createRenderer_0(int32_t _0, int32_t _1, gfx_Window_0* _2); -} // anonymous -// [numthreads(4, 1, 1)] -SLANG_PRELUDE_EXPORT -void computeMain_Thread(ComputeThreadVaryingInput* varyingInput, void* params, void* uniformState) -{ - KernelContext context = {}; - context.uniformState = (UniformState*)uniformState; - context.dispatchThreadID = { - varyingInput->groupID.x * 4 + varyingInput->groupThreadID.x, - varyingInput->groupID.y * 1 + varyingInput->groupThreadID.y, - varyingInput->groupID.z * 1 + varyingInput->groupThreadID.z - }; - context._computeMain(); -} -// [numthreads(4, 1, 1)] -SLANG_PRELUDE_EXPORT -void computeMain_Group(ComputeVaryingInput* varyingInput, void* params, void* uniformState) -{ - KernelContext context = {}; - context.uniformState = (UniformState*)uniformState; - const uint3 start = { - varyingInput->startGroupID.x * 4, - varyingInput->startGroupID.y * 1, - varyingInput->startGroupID.z * 1 - }; - context.dispatchThreadID = start; - for (uint32_t x = start.x; x < start.x + 4; ++x) - { - context.dispatchThreadID.x = x; - context._computeMain(); - } -} -// [numthreads(4, 1, 1)] -SLANG_PRELUDE_EXPORT -void computeMain(ComputeVaryingInput* varyingInput, void* params, void* uniformState) + +gfx_BufferResource_0* createStructuredBuffer_0(gfx_Renderer_0* _0, FixedArray<float, 4> _1); + + +#line 33 +gfx_ShaderProgram_0* loadShaderProgram_0(gfx_Renderer_0* _0); + + +#line 40 +gfx_DescriptorSetLayout_0* buildDescriptorSetLayout_0(gfx_Renderer_0* _0); + + +#line 41 +gfx_PipelineLayout_0* buildPipeline_0(gfx_Renderer_0* _0, gfx_DescriptorSetLayout_0* _1); + + +#line 42 +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 printInitialValues_0(FixedArray<float, 4> _0, int32_t _1); + + +#line 51 +void dispatchComputation_0(gfx_Renderer_0* _0, gfx_PipelineState_0* _1, gfx_PipelineLayout_0* _2, gfx_DescriptorSet_0* _3); + + + + +void print_output_0(gfx_Renderer_0* _0, gfx_BufferResource_0* _1, int32_t _2); + + + + +bool executeComputation_0() { - KernelContext context = {}; - context.uniformState = (UniformState*)uniformState; - const uint3 start = { - varyingInput->startGroupID.x * 4, - varyingInput->startGroupID.y * 1, - varyingInput->startGroupID.z * 1 - }; - const uint3 end = { - varyingInput->endGroupID.x * 4, - varyingInput->endGroupID.y * 1, - varyingInput->endGroupID.z * 1 - }; - for (uint32_t z = start.z; z < end.z; ++z) - { - context.dispatchThreadID.z = z; - for (uint32_t y = start.y; y < end.y; ++y) - { - context.dispatchThreadID.y = y; - for (uint32_t x = start.x; x < end.x; ++x) - { - context.dispatchThreadID.x = x; - context._computeMain(); - } - } - } + + + + FixedArray<float, 4> initialArray_0 = { 3.00000000000000000000f, -20.00000000000000000000f, -6.00000000000000000000f, 8.00000000000000000000f }; + + + gfx_Window_0* _S1 = createWindow_0(int(1024), int(768)); + gfx_Renderer_0* _S2 = createRenderer_0(int(1024), int(768), _S1); + gfx_BufferResource_0* _S3 = createStructuredBuffer_0(_S2, initialArray_0); + gfx_ShaderProgram_0* _S4 = loadShaderProgram_0(_S2); + gfx_DescriptorSetLayout_0* _S5 = buildDescriptorSetLayout_0(_S2); + gfx_PipelineLayout_0* _S6 = buildPipeline_0(_S2, _S5); + gfx_DescriptorSet_0* _S7 = buildDescriptorSet_0(_S2, _S5, _S3); + gfx_PipelineState_0* _S8 = buildPipelineState_0(_S4, _S2, _S6); + printInitialValues_0(initialArray_0, int(4)); + dispatchComputation_0(_S2, _S8, _S6, _S7); + print_output_0(_S2, _S3, int(4)); + + + return true; } + +//} // anonymous + diff --git a/examples/heterogeneous-hello-world/shader.slang b/examples/heterogeneous-hello-world/shader.slang index 036f63c85..a9ad66cc7 100644 --- a/examples/heterogeneous-hello-world/shader.slang +++ b/examples/heterogeneous-hello-world/shader.slang @@ -3,10 +3,8 @@ //TEST_INPUT:ubuffer(random(float, 4096, -1.0, 1.0), stride=4):name=ioBuffer RWStructuredBuffer<float> ioBuffer; -// There's some weird duplication going on here. It's not clear how we should introduce UniformState - [numthreads(4, 1, 1)] -public void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) +void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) { uint tid = dispatchThreadID.x; @@ -15,3 +13,71 @@ public void computeMain(uint3 dispatchThreadID : SV_DispatchThreadID) 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); +Ptr<gfx::DescriptorSetLayout> buildDescriptorSetLayout(Ptr<gfx::Renderer> gRenderer); +Ptr<gfx::PipelineLayout> buildPipeline(Ptr<gfx::Renderer> gRenderer, Ptr<gfx::DescriptorSetLayout> descriptorSetLayout); +Ptr<gfx::DescriptorSet> buildDescriptorSet( + Ptr<gfx::Renderer> gRenderer, + Ptr<gfx::DescriptorSetLayout> descriptorSetLayout, + Ptr<gfx::BufferResource> gStructuredBuffer); +Ptr<gfx::PipelineState> buildPipelineState( + Ptr<gfx::ShaderProgram> shaderProgram, + Ptr<gfx::Renderer> gRenderer, + Ptr<gfx::PipelineLayout> gPipelineLayout); +void printInitialValues(float[4] initialArray, int length); +void dispatchComputation( + Ptr<gfx::Renderer> gRenderer, + Ptr<gfx::PipelineState> gPipelineState, + Ptr<gfx::PipelineLayout> gPipelineLayout, + Ptr<gfx::DescriptorSet> gDescriptorSet); +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); + let shaderProgram = loadShaderProgram(renderer); + let descriptorSetLayout = buildDescriptorSetLayout(renderer); + let pipelineLayout = buildPipeline(renderer, descriptorSetLayout); + let descriptorSet = buildDescriptorSet(renderer, descriptorSetLayout, structuredBuffer); + let pipelineState = buildPipelineState(shaderProgram, renderer, pipelineLayout); + printInitialValues(initialArray, 4); + dispatchComputation(renderer, pipelineState, pipelineLayout, descriptorSet); + print_output(renderer, structuredBuffer, 4); + + + return true; +} |
