Преглед на файлове

Modify bindless sample to use new bindless mechanism (#551)

* Modify bindless sample to use new mechanism

Signed-off-by: Jeremy Ong <[email protected]>

* Crash fixes + cleanup
- Fix GPU crashes by updating indirect indices every frame as they can change given that they are pointing to views of streaming images.
- Fix another crash related to recreating objects within the level

Signed-off-by: moudgils <[email protected]>

* Add support to directly bind unbounded arrays within the bindless rhi sample

Signed-off-by: moudgils <[email protected]>

* BindlessPrototype sample fixes for Mac

Signed-off-by: rgba16f <[email protected]>

* Fix compile error, #if was testing an old version of the #define name

Signed-off-by: rgba16f <[email protected]>

Signed-off-by: Jeremy Ong <[email protected]>
Signed-off-by: moudgils <[email protected]>
Signed-off-by: rgba16f <[email protected]>
Co-authored-by: Jeremy Ong <[email protected]>
Co-authored-by: moudgils <[email protected]>
rgba16f преди 2 години
родител
ревизия
1a2b90ea14

+ 60 - 0
.clang-format

@@ -0,0 +1,60 @@
+Language: Cpp
+
+AccessModifierOffset: -4
+AlignAfterOpenBracket: AlwaysBreak
+AlignConsecutiveAssignments: false
+AlignConsecutiveDeclarations: false
+AlignEscapedNewlines: Right
+AlignOperands: false
+AlignTrailingComments: false
+AllowAllArgumentsOnNextLine: true
+AllowAllParametersOfDeclarationOnNextLine: true
+AllowShortFunctionsOnASingleLine: None
+AllowShortLambdasOnASingleLine: None
+AlwaysBreakAfterReturnType: None
+AlwaysBreakTemplateDeclarations: true
+BinPackParameters: false
+BreakBeforeBraces: Custom
+BraceWrapping:
+    AfterClass: true
+    AfterControlStatement: true
+    AfterEnum: true
+    AfterFunction: true
+    AfterNamespace: true
+    BeforeLambdaBody: true
+    AfterStruct: true
+    BeforeElse: true
+    SplitEmptyFunction: true
+BreakBeforeTernaryOperators: true
+BreakConstructorInitializers: BeforeComma
+BreakInheritanceList: BeforeComma
+ColumnLimit: 140
+ConstructorInitializerIndentWidth: 4
+ContinuationIndentWidth: 4
+Cpp11BracedListStyle: false
+FixNamespaceComments: true
+IncludeBlocks: Preserve
+IndentCaseBlocks: true
+IndentCaseLabels: false
+IndentPPDirectives: None
+IndentWidth: 4
+KeepEmptyLinesAtTheStartOfBlocks: false
+MaxEmptyLinesToKeep: 1
+NamespaceIndentation: All
+PenaltyReturnTypeOnItsOwnLine: 1000
+PointerAlignment: Left
+SortIncludes: true
+SpaceAfterLogicalNot: false
+SpaceAfterTemplateKeyword: false
+SpaceBeforeAssignmentOperators: true
+SpaceBeforeCpp11BracedList: false
+SpaceBeforeCtorInitializerColon: true
+SpaceBeforeInheritanceColon: true
+SpaceBeforeParens: ControlStatements
+SpaceBeforeRangeBasedForLoopColon: true
+SpaceInEmptyParentheses: false
+SpacesInAngles: false
+SpacesInCStyleCastParentheses: false
+SpacesInParentheses: false
+Standard: c++17
+UseTab: Never

+ 9 - 0
Gem/Code/Source/Platform/Android/BindlessPrototype_Traits_Platform.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#define ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY       1

+ 9 - 0
Gem/Code/Source/Platform/Linux/BindlessPrototype_Traits_Platform.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#define ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY       1

+ 9 - 0
Gem/Code/Source/Platform/Mac/BindlessPrototype_Traits_Platform.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#define ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY       0

+ 9 - 0
Gem/Code/Source/Platform/Windows/BindlessPrototype_Traits_Platform.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#define ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY       1

+ 9 - 0
Gem/Code/Source/Platform/iOS/BindlessPrototype_Traits_Platform.h

@@ -0,0 +1,9 @@
+/*
+ * Copyright (c) Contributors to the Open 3D Engine Project.
+ * For complete copyright and license terms please see the LICENSE at the root of this distribution.
+ *
+ * SPDX-License-Identifier: Apache-2.0 OR MIT
+ *
+ */
+
+#define ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY       0

+ 97 - 44
Gem/Code/Source/RHI/BindlessPrototypeExampleComponent.cpp

@@ -52,6 +52,11 @@ namespace AtomSampleViewer
         // Randomizer, used to generate unique diffuse colors for the materials
         AZ::SimpleLcgRandom g_randomizer;
 
+        static uint32_t RandomValue()
+        {
+            return g_randomizer.GetRandom() % ImageCount;
+        }
+
         template<typename Asset, typename Instance>
         Data::Instance<Instance> CreateResourceImmediate(Data::AssetId assetId)
         {
@@ -91,8 +96,7 @@ namespace AtomSampleViewer
                 AZ::Color color;
                 color.FromU32(colorUint);
 
-                const uint32_t diffuseTextureIndex = g_randomizer.GetRandom() % InternalBP::ImageCount;
-                m_diffuseTextureIndex = diffuseTextureIndex;
+                m_diffuseTextureIndex = RandomValue();
             }
 
             const uint32_t m_materialIndex = 1u;
@@ -109,14 +113,9 @@ namespace AtomSampleViewer
                 color.FromU32(colorUint);
                 m_diffuseColor = color;
 
-                const uint32_t diffuseTextureIndex = g_randomizer.GetRandom() % InternalBP::ImageCount;
-                m_diffuseTextureIndex = diffuseTextureIndex;
-
-                const uint32_t normalTextureIndex = g_randomizer.GetRandom() + 1u % InternalBP::ImageCount;
-                m_normalTextureIndex = normalTextureIndex;
-
-                const uint32_t specularTextureIndex = g_randomizer.GetRandom() + 2u % InternalBP::ImageCount;
-                m_specularTextureIndex = specularTextureIndex;
+                m_diffuseTextureIndex = RandomValue();
+                m_normalTextureIndex = RandomValue();
+                m_specularTextureIndex = RandomValue();
             }
 
             const uint32_t m_materialIndex = 2u;
@@ -177,22 +176,15 @@ namespace AtomSampleViewer
 
             m_imguiSidebar.End();
 
-            static const auto recreate = [this]()
-            {
-                ClearObjects();
-                CreateObjects();
-            };
-
             // Recreate the objects when the quantity changed
             if (latticeChanged && enableDynamicUpdates)
             {
-                recreate();
+                Recreate();
             }
-
             // If the dynamic update is toggled
             else if (enableDynamicUpdates != previousEnableDynamicUpdates && enableDynamicUpdates == true)
             {
-                recreate();
+                Recreate();
             }
 
             if (randomizeMaterials)
@@ -202,6 +194,12 @@ namespace AtomSampleViewer
         }
     }
 
+    void BindlessPrototypeExampleComponent::Recreate()
+    {
+        ClearObjects();
+        CreateObjects();
+    }
+
     void BindlessPrototypeExampleComponent::CreateBufferPool()
     {
         m_bufferPool = RHI::Factory::Get().CreateBufferPool();
@@ -335,8 +333,10 @@ namespace AtomSampleViewer
     {
         // FloatBuffer ID
         const char* floatBufferId = "m_floatBuffer";
+#if ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY
         // TextureArray ID
         const char* textureArrayId = "m_textureArray";
+#endif
 
         m_scopeId = RHI::ScopeId("BindlessPrototype");
 
@@ -386,16 +386,22 @@ namespace AtomSampleViewer
         }
 
         // Set up the SRGs
-        {
-            // Set the FloatBufferSrg
-            m_bindlessSrg = std::make_unique<BindlessSrg>(
-                BindlessSrg(m_shader, {m_floatBufferSrgName, m_imageSrgName})
-            );
-        }
+         m_bindlessSrg = std::make_unique<BindlessSrg>(
+            BindlessSrg(m_shader, 
+                        { 
+                            m_samplerSrgName, 
+                            m_floatBufferSrgName, 
+                            m_indirectionBufferSrgName, 
+#if ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY
+                            m_imageSrgName
+#endif
+                         }));
 
         // Create the BufferPool
         CreateBufferPool();
 
+        m_bindlessSrg->CompileSrg(m_samplerSrgName);
+
         // Initialize the float buffer, and set the view
         {
             const uint32_t byteCount = m_bufferFloatCount * static_cast<uint32_t>(sizeof(float));
@@ -452,27 +458,47 @@ namespace AtomSampleViewer
             }
         }
 
-        // Set the images
+        //Load appropriate textures used by the unbounded texture array
+        AZStd::vector<const RHI::ImageView*> imageViews;
+        for (uint32_t textureIdx = 0u; textureIdx < InternalBP::ImageCount; textureIdx++)
         {
-            Data::Instance<AZ::RPI::ShaderResourceGroup> imageSrg = m_bindlessSrg->GetSrg(m_imageSrgName);
-            AZ::RHI::ShaderInputImageUnboundedArrayIndex imageIndex = imageSrg->FindShaderInputImageUnboundedArrayIndex(AZ::Name(textureArrayId));
-
-            AZStd::vector<const RHI::ImageView*> imageViews;
-            for (uint32_t textureIdx = 0u; textureIdx < InternalBP::ImageCount; textureIdx++)
-            {
-                AZ::Data::Instance<AZ::RPI::StreamingImage> image = LoadStreamingImage(InternalBP::Images[textureIdx], InternalBP::SampleName);
-                m_images.push_back(image);
-                imageViews.push_back(image->GetImageView());
-            }
-
-            [[maybe_unused]] bool result = imageSrg->SetImageViewUnboundedArray(imageIndex, imageViews);
-            AZ_Assert(result, "Failed to set image view unbounded array into shader resource group.");
-
-            // Compile the image SRG
-            imageSrg->Compile();
+            AZ::Data::Instance<AZ::RPI::StreamingImage> image = LoadStreamingImage(InternalBP::Images[textureIdx], InternalBP::SampleName);
+            m_images.push_back(image);
+            m_imageViews.push_back(image->GetImageView());
         }
 
-        // Create and allocate the materials in the FloatBuffer
+        // Set the indirect buffer for the images
+        {
+            m_indirectionBuffer = RHI::Factory::Get().CreateBuffer();
+            m_indirectionBuffer->SetName(Name("IndirectionBuffer"));
+            RHI::BufferInitRequest bufferRequest;
+            bufferRequest.m_descriptor.m_bindFlags = RHI::BufferBindFlags::ShaderRead;
+            bufferRequest.m_descriptor.m_byteCount = sizeof(uint32_t) * InternalBP::ImageCount;
+            bufferRequest.m_buffer = m_indirectionBuffer.get();
+            [[maybe_unused]] RHI::ResultCode resultCode = m_bufferPool->InitBuffer(bufferRequest);
+            AZ_Assert(resultCode == RHI::ResultCode::Success, "Failed to create Indirection Buffer");
+
+            RHI::BufferViewDescriptor viewDesc =
+                RHI::BufferViewDescriptor::CreateRaw(0, aznumeric_cast<uint32_t>(bufferRequest.m_descriptor.m_byteCount));
+            m_indirectionBufferView = m_indirectionBuffer->GetBufferView(viewDesc);
+        }
+        
+#if ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY
+       // Set the images
+       {
+           Data::Instance<AZ::RPI::ShaderResourceGroup> imageSrg = m_bindlessSrg->GetSrg(m_imageSrgName);
+           AZ::RHI::ShaderInputImageUnboundedArrayIndex imageIndex =
+               imageSrg->FindShaderInputImageUnboundedArrayIndex(AZ::Name(textureArrayId));
+
+           [[maybe_unused]] bool result = imageSrg->SetImageViewUnboundedArray(imageIndex, m_imageViews);
+           AZ_Assert(result, "Failed to set image view unbounded array into shader resource group.");
+
+           // Compile the image SRG
+           imageSrg->Compile();
+       }
+#endif
+        
+        // Create and allocate the materials in the FloatBufferimageSrg
         {
             m_materialHandleArray.resize(m_materialCount);
             CreateMaterials();
@@ -564,9 +590,13 @@ namespace AtomSampleViewer
                     const SubMeshInstance& subMesh = m_subMeshInstanceArray[instanceIdx];
 
                     const RHI::ShaderResourceGroup* shaderResourceGroups[] = {
+                        m_bindlessSrg->GetSrg(m_samplerSrgName)->GetRHIShaderResourceGroup(),
                         subMesh.m_perSubMeshSrg->GetRHIShaderResourceGroup(),
-                        m_bindlessSrg->GetSrg(m_imageSrgName)->GetRHIShaderResourceGroup(),
                         m_bindlessSrg->GetSrg(m_floatBufferSrgName)->GetRHIShaderResourceGroup(),
+#if ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY
+                        m_bindlessSrg->GetSrg(m_imageSrgName)->GetRHIShaderResourceGroup(),
+#endif
+                        m_bindlessSrg->GetSrg(m_indirectionBufferSrgName)->GetRHIShaderResourceGroup(),
                     };
                     RHI::DrawItem drawItem;
                     drawItem.m_arguments = subMesh.m_mesh->m_drawArguments;
@@ -675,6 +705,29 @@ namespace AtomSampleViewer
                                               static_cast<void *>(&m_lightDir),
                                               static_cast<uint32_t>(sizeof(Vector3)));
 
+        Data::Instance<AZ::RPI::ShaderResourceGroup> indirectionBufferSrg = m_bindlessSrg->GetSrg(m_indirectionBufferSrgName);
+
+        RHI::BufferMapRequest mapRequest{ *m_indirectionBuffer, 0, sizeof(uint32_t) * InternalBP::ImageCount };
+        RHI::BufferMapResponse mapResponse;
+        m_bufferPool->MapBuffer(mapRequest, mapResponse);
+
+        AZStd::vector<const RHI::ImageView*> views;
+        for(AZ::Data::Instance<AZ::RPI::StreamingImage> image : m_images)
+        {
+            views.push_back(image->GetImageView());
+        }
+        
+        bool readOnlyTexture = true;
+        uint32_t arrayIndex = 0;
+        auto indirectionBufferIndex = indirectionBufferSrg->FindShaderInputBufferIndex(AZ::Name{ "m_indirectionBuffer" });
+        indirectionBufferSrg->SetBindlessViews(
+            indirectionBufferIndex, m_indirectionBufferView.get(),
+            views, static_cast<uint32_t*>(mapResponse.m_data),
+            readOnlyTexture, arrayIndex);
+
+        m_bufferPool->UnmapBuffer(*m_indirectionBuffer);
+        indirectionBufferSrg->Compile();
+
         BasicRHIComponent::OnFramePrepare(frameGraphBuilder);
     }
 

+ 18 - 1
Gem/Code/Source/RHI/BindlessPrototypeExampleComponent.h

@@ -22,6 +22,8 @@
 
 #include <Utils/ImGuiSidebar.h>
 
+#include <BindlessPrototype_Traits_Platform.h>
+
 namespace AZ
 {
     namespace RHI
@@ -180,6 +182,9 @@ namespace AtomSampleViewer
         // Create the BufferPol
         void CreateBufferPool();
 
+        //Recreate objects
+        void Recreate();
+        
         // ImGui sidebar
         ImGuiSidebar m_imguiSidebar;
 
@@ -216,6 +221,8 @@ namespace AtomSampleViewer
         // Image array holding all of the StreamImages
         AZStd::vector<AZ::Data::Instance<AZ::RPI::StreamingImage>> m_images;
 
+        AZStd::vector<const AZ::RHI::ImageView*> m_imageViews;
+
         // Light direction handle
         FloatBufferHandle m_lightDirectionHandle;
 
@@ -238,6 +245,12 @@ namespace AtomSampleViewer
         // BufferPool used to allocate buffers in this example
         AZ::RHI::Ptr<AZ::RHI::BufferPool> m_bufferPool = nullptr;
 
+        // Indirection buffer holding uint indices of texture resources
+        AZ::RHI::Ptr<AZ::RHI::Buffer> m_indirectionBuffer = nullptr;
+
+        // View associated with the indirection buffer
+        AZ::RHI::Ptr<AZ::RHI::BufferView> m_indirectionBufferView = nullptr;
+        
         // Pool size in bytes, 1MB
         static constexpr uint32_t m_poolSizeInBytes = 1u << 20u;
 
@@ -246,8 +259,12 @@ namespace AtomSampleViewer
         static constexpr uint32_t m_modelLod = 0u;
 
         AZ::RHI::ScopeId m_scopeId;
-        static constexpr const char* m_imageSrgName = "ImageSrg";
+        static constexpr const char* m_samplerSrgName = "SamplerSrg";
         static constexpr const char* m_floatBufferSrgName = "FloatBufferSrg";
+        static constexpr const char* m_indirectionBufferSrgName = "IndirectionBufferSrg";
+#if ATOMSAMPLEVIEWER_TRAIT_BINDLESS_PROTOTYPE_SUPPORTS_DIRECT_BOUND_UNBOUNDED_ARRAY
+        static constexpr const char* m_imageSrgName = "ImageSrg";
+#endif
 
         // Material count
         static constexpr uint32_t m_materialCount = 1024u;

+ 1 - 0
Scripts/MaterialScreenshotTests.bv.lua

@@ -44,6 +44,7 @@ function GenerateMaterialScreenshot(imageComparisonThresholdLevel, materialName,
         options.showGroundPlane = false
     end
 
+    Print("Generating material screenshot for " .. materialName)
     Print("MODEL: " .. options.model)
 
     materialName = string.lower(materialName)

+ 17 - 9
Shaders/RHI/BindlessPrototype.azsl

@@ -7,10 +7,11 @@
  */
 
 // GlobalSrg::m_floatBuffer
-// PerSceneSrg::m_textureArray
 // PerSceneSrg::m_sampler
 #include "BindlessPrototypeSrg.azsli"
 
+#include <Atom/Features/Bindless.azsli>
+
 struct BindlessMaterial0
 {
     uint4 materialIndex;
@@ -44,7 +45,7 @@ struct PerObject
 
 ShaderResourceGroupSemantic PerSubMesh
 {
-    FrequencyId = 1;
+    FrequencyId = 4;
 };
 
 // [TODO ATOM-2769] When the inline feature is complete, use InlineConstant instead of sending the data
@@ -131,21 +132,28 @@ PixelOutput MainPS(VertexOutput psInput)
         BindlessMaterial1 bindlessMaterial1; 
         ReadFromFloatBuffer(bindlessMaterial1.m_diffuseColor, HandleSrg::m_materialHandle, offset);
         ReadFromFloatBuffer(bindlessMaterial1.m_diffuseTextureIndex, HandleSrg::m_materialHandle, offset);
-
-        Texture2D texture = ImageSrg::m_textureArray[bindlessMaterial1.m_diffuseTextureIndex % 8]; // % 8 for wrap-around texture index as specified in ImageSrg.m_textureArray
-        OUT.m_color = texture.Sample(ImageSrg::m_sampler, psInput.m_uv);
+        
+#ifdef UB_DIRECTBINDING_NOTSUPPPORTED 
+        Texture2D texture = Bindless::GetTexture2D(
+            IndirectionBufferSrg::m_indirectionBuffer.Load(bindlessMaterial1.m_diffuseTextureIndex * 4));
+#else   
+        // % 8 for wrap-around texture index as specified in ImageSrg.m_textureArray
+        Texture2D texture = ImageSrg::m_textureArray[bindlessMaterial1.m_diffuseTextureIndex % 8]; 
+#endif
+        OUT.m_color = texture.Sample(SamplerSrg::m_sampler, psInput.m_uv);
     }
     else if(materialIndex.x == 2) // Shaded material
     {
-        float4 color;
+        float4 color; 
         BindlessMaterial2 bindlessMaterial2; 
         ReadFromFloatBuffer(bindlessMaterial2.m_diffuseColor, HandleSrg::m_materialHandle, offset);
         ReadFromFloatBuffer(bindlessMaterial2.m_diffuseTextureIndex, HandleSrg::m_materialHandle, offset);
         ReadFromFloatBuffer(bindlessMaterial2.m_normalTextureIndex, HandleSrg::m_materialHandle, offset);
         ReadFromFloatBuffer(bindlessMaterial2.m_specularTextureIndex, HandleSrg::m_materialHandle, offset);
 
-        Texture2D texture = ImageSrg::m_textureArray[bindlessMaterial2.m_diffuseTextureIndex % 8]; // % 8 for wrap-around texture index as specified in ImageSrg.m_textureArray
-        color = texture.Sample(ImageSrg::m_sampler, psInput.m_uv);
+        Texture2D texture = Bindless::GetTexture2D(
+            IndirectionBufferSrg::m_indirectionBuffer.Load(bindlessMaterial2.m_diffuseTextureIndex * 4));
+        color = texture.Sample(SamplerSrg::m_sampler, psInput.m_uv);
 
         float3 lightDir;
         uint lightOffset = 0;
@@ -161,4 +169,4 @@ PixelOutput MainPS(VertexOutput psInput)
     }
 
     return OUT;
-}
+}

+ 4 - 2
Shaders/RHI/BindlessPrototype.shader

@@ -7,6 +7,9 @@
 
     "DrawList" : "forward",
 
+    "AddBuildArguments"
+        : { "dxc" : ["-fspv-target-env=vulkan1.2"] },
+
     "ProgramSettings":
     {
       "EntryPoints":
@@ -20,6 +23,5 @@
           "type": "Fragment"
         }
       ]
-    },
-    "DisabledRHIBackends": ["metal"]
+    }
 }

+ 23 - 5
Shaders/RHI/BindlessPrototypeSrg.azsli

@@ -17,12 +17,22 @@ struct FloatBuffer
 // Listed on update frequency
 ShaderResourceGroupSemantic FrequencyPerScene 
 {
-    FrequencyId = 6;
+    FrequencyId = 0;
 };
 
 ShaderResourceGroupSemantic FloatBufferSemanticId
 {
-    FrequencyId = 7;
+    FrequencyId = 1;
+};
+
+ShaderResourceGroupSemantic IndirectionBufferSemanticId
+{
+    FrequencyId = 2;
+};
+
+ShaderResourceGroupSemantic NonBindlessTextureSemanticId
+{
+    FrequencyId = 3;
 };
 
 ShaderResourceGroup FloatBufferSrg : FloatBufferSemanticId
@@ -30,7 +40,12 @@ ShaderResourceGroup FloatBufferSrg : FloatBufferSemanticId
     StructuredBuffer<FloatBuffer> m_floatBuffer;
 };
 
-ShaderResourceGroup ImageSrg : FrequencyPerScene
+ShaderResourceGroup IndirectionBufferSrg : IndirectionBufferSemanticId
+{
+    ByteAddressBuffer m_indirectionBuffer;
+}; 
+
+ShaderResourceGroup SamplerSrg : FrequencyPerScene
 {
     Sampler m_sampler
     {
@@ -39,10 +54,13 @@ ShaderResourceGroup ImageSrg : FrequencyPerScene
         AddressV = Wrap;
         AddressW = Wrap;
     };
+};
 
+ShaderResourceGroup ImageSrg : NonBindlessTextureSemanticId
+{
     // Array of textures
-    Texture2D m_textureArray[];
-}
+    Texture2D m_textureArray[UNBOUNDED_SIZE];
+};
 
 // Helper functions to read data from the FloatBuffer. The FloatBuffer is accessed with an offset and an index.
 // The offset holds the initial offset within the FloatBuffer, and the index is a sub-index, which increments with each property that is being read.