Selaa lähdekoodia

Merge support for generalized bindless model (#62)

* Integrated prototype support for multiple unbounded arrays from @jeremyong-az branch Atom/BindlessTest.

I didn't bring every change over though. His changes disabled UnboundedArraysValidator which we need to keep and modify (I'll do this in a subsequent commit). He also added a test azsl file he was testing with, which probably will take a different form when I add some automated tests (again, in an upcoming commit).

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

* Added a new --use-unbounded-spaces command line option. Right now this only affects the validation to allow multiple unbounded arrays through. In my next commit I plan to move things around so that this unbounded spill space concept is tied to this flag rather than tying it to the dx platform. I also added automated tests for the current spill space behavior, which will help me with those upcoming changes.

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

* Update the srg-layouts-multiple-unbounded-arrays.txt emission test to include the root signature dump.

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

* Simplified the original prototype implementation of support for unbounded array spill space. Now it is tied to the --use-unbounded-spaces command line option, instead of the DirectX platform.
All unit tests still pass, included the new ones I added in preparation for this refactoring.

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

* Reverted some unnecessary changes.

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

* Reverted some unnecessary changes.

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

* Further simplified unbounded array spill space. It can always use register 0 since every unbounded array gets a unique register space. There is no need to increment the main register counters every time an unbounded array is encountered.

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

* Removed the --use-unbounded-spaces command line option and made this feature always-on insetead.

While testing I realized the the unbounded arrays validation was overly aggressive. It was applying DirectX restrictions to all platforms, even though DirectX is the only platform where unbounded arrays consume all available registers. After discussing with @jeremyong-az and @moudgils it was determined that using a unique space per unbounded array would not be detrimental to the other platforms, because they don't have any concept of register space anyway, and the spaces are ignored. So rather than support two modes of operation, we just apply unique per-unbounded-array spaces universally. This further simplifies the code by not only removing a command line option, it removes the need most of the unbounded arrays validation and several automated tests.

I also moved a bit of code that modifies the srgInfo out of the UnboundedArraysValidator, it makes more sense to have that in the client code.

Most of the changes to the automated tests should be pretty self-explanator. Some cases deserve a bit of explanation:
- unbounded-arrays-srg-layout.py was removed because this functionality is better-covered by the new srg-layouts-multiple-unbounded-arrays.azsl and verifyPackingUnboundedSpillSpaces().
- UnboundedArrays.azsl was removed because this functionality is better-covered by the new srg-layouts-multiple-unbounded-arrays.azsl and corresponding .txt pattern file.
- AzError/unbounded-arrays4.azsl was removed because there are no more register collision errors.

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

* Removed some unused function parameters.

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

* Revert "Further simplified unbounded array spill space. It can always use register 0 since every unbounded array gets a unique register space. There is no need to increment the main register counters every time an unbounded array is encountered."

This reverts commit 70c3ab8acc37407f0ec82e33b6f9d7cc3546253e.

When I originally made this change, I forgot that since register spaces are ignored on vulkan (and other platforms) we can't always use register 0, that only works on dx12.

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

* Turn off unique spaces per unbound array for non-dx12 backends

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

* The fix for tests to pass is to enable the specific emitter that respects logical space 1000 counting method: namespace dx.
+ minor formatting cosmetics and unsigned that made no sense.
+ it should be noted that there appears to be an odd "hole" in the unbound register counting system that might be a relic of "--use-spaces" absence.

Signed-off-by: Vivien Oddou <[email protected]>

* Update of comment around RequiresUniqueSpaceForUnboundedArrays as per discussion request.

Signed-off-by: Vivien Oddou <[email protected]>

* increase to version 1.8.9
+ update emission check to please latest python split regexp.

Signed-off-by: Vivien Oddou <[email protected]>

Signed-off-by: santorac <[email protected]>
Signed-off-by: rgba16f <[email protected]>
Signed-off-by: Vivien Oddou <[email protected]>
Co-authored-by: santorac <[email protected]>
Co-authored-by: Vivien Oddou <[email protected]>
rgba16f 2 vuotta sitten
vanhempi
commit
c3f7c1e4ca

+ 0 - 1
Platform/Windows/src/DirectX12PlatformEmitter.cpp

@@ -126,5 +126,4 @@ namespace AZ::ShaderCompiler
 
         return Decorate("#define sig ", Join(rootAttrList, ", \" \\\n"), "\"\n\n");
     }
-    
 }

+ 3 - 0
Platform/Windows/src/DirectX12PlatformEmitter.h

@@ -22,6 +22,9 @@ namespace AZ::ShaderCompiler
         [[nodiscard]]
         string GetRootSig(const CodeEmitter& codeEmitter, const RootSigDesc& rootSig, const Options& options, BindingPair::Set signatureQuery) const override final;
 
+        bool RequiresUniqueSpaceForUnboundedArrays() const override {return true;}
+
+
     private:
         DirectX12PlatformEmitter() : PlatformEmitter {} {};
     };

+ 30 - 4
src/AzslcBackend.cpp

@@ -1,4 +1,4 @@
-/*
+/*
  * 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.
  * 
@@ -225,7 +225,7 @@ namespace AZ::ShaderCompiler
         }
     }
 
-    void MultiBindingLocationMaker::SignalRegisterIncrement(BindingType regType, int count /* = 1*/)
+    void MultiBindingLocationMaker::SignalIncrementRegister(BindingType regType, int count)
     {
         m_untainted.m_registerPos[regType] += count;
         m_merged.m_registerPos[regType] += count;
@@ -571,9 +571,35 @@ namespace AZ::ShaderCompiler
         }
 
         auto regType = RootParamTypeToBindingType(paramType);
-        auto srgElementDesc = RootSigDesc::SrgParamDesc{ id, paramType, bindInfo.GetCurrent(regType), count, -1, isUnboundedArray};
+
+        BindingPair binding = bindInfo.GetCurrent(regType);
+        if (isUnboundedArray
+            && GetPlatformEmitter().RequiresUniqueSpaceForUnboundedArrays() /* refer to note¹ hereunder*/ )
+        {
+            //  note¹: On o3de/Atom, the vulkan RHI assumes SRG binding IDs to be 0-7 as there are fixed data structures
+            //         using a MaxSRGs of 8 in the code. Adapting the RHI to remove this assumption would have been costly,
+            //         therefore RequiresUniqueSpaceForUnboundedArrays is now true only for --namespace=dx.
+
+            // Use a unique register space for every unbounded array because in DirectX 12 unbounded arrays consume
+            // all remaining registers for that resource type. By making a unique space for each unbounded array
+            // we support an unlimited number of them.
+            // Note that this does not impact other platforms, where register spaces don't matter (DXC ignores them)
+            // and unbounded arrays do not consume all remaining registers.
+            // Also, on dx12 we don't necessarily need to call SignalIncrementRegister() in this case, and could instead
+            // just use register 0 because the register space is unique, but since other platforms ignore the register
+            // space it's easier to also increment the register on all platforms.
+            
+            binding.m_pair[BindingPair::Set::Untainted].m_logicalSpace = m_unboundedSpillSpace;
+            binding.m_pair[BindingPair::Set::Merged].m_logicalSpace = m_unboundedSpillSpace;
+            ++m_unboundedSpillSpace;
+        }
+
+        bindInfo.SignalIncrementRegister(regType, count);
+
+        auto srgElementDesc = RootSigDesc::SrgParamDesc{ id, paramType, binding, count, -1, isUnboundedArray};
+
         rootSig.m_descriptorMap.emplace(id, srgElementDesc);
-        bindInfo.SignalRegisterIncrement(regType, count);
+
         return srgElementDesc;
     }
 

+ 9 - 1
src/AzslcBackend.h

@@ -11,6 +11,7 @@
 #include "NewLineCounterStream.h"
 
 #include "jsoncpp/dist/json/json.h"
+#include "AzslcRegisters.h"
 
 namespace AZ::ShaderCompiler
 {
@@ -64,6 +65,7 @@ namespace AZ::ShaderCompiler
             BindingPair m_registerBinding;
             int m_registerRange = -1;
             int m_num32BitConstants = -1;
+
             // This flag is added so m_registerRange can take the value
             // of 1 and at the same time We do not forget that m_uid refers
             // to an unbounded array.
@@ -117,7 +119,7 @@ namespace AZ::ShaderCompiler
 
         void SignalUnifyIndices();
         
-        void SignalRegisterIncrement(BindingType regType, int count = 1);
+        void SignalIncrementRegister(BindingType regType, int count);
 
         BindingPair GetCurrent(BindingType regType);
 
@@ -177,6 +179,12 @@ namespace AZ::ShaderCompiler
 
         IntermediateRepresentation*      m_ir;
         TokenStream*                     m_tokens;
+        
+        // On some platforms (DX12), descriptor arrays occupy an individual register slot, and spaces are used
+        // to prevent overlapping ranges. When an unbounded array is encountered, we immediately assign it to
+        // the value of this member variable and increment. This is initialized in the constructor because the
+        // space we spill to must not collide with any other SRG declared in the shader.
+        mutable SpaceIndex m_unboundedSpillSpace = FirstUnboundedSpace;
     };
 
     // independent utility functions

+ 3 - 0
src/AzslcEmitter.h

@@ -233,5 +233,8 @@ namespace AZ::ShaderCompiler
 
         //! This is a readability function for class emission code. Serves for HLSL declarator of classes
         string EmitInheritanceList(const ClassInfo& clInfo);
+
+        //! Given an SRG parameter, determines the space it belongs to based on the platform
+        int ResolveBindingSpace(const RootSigDesc::SrgParamDesc& bindInfo, BindingPair::Set bindSet) const;
     };
 }

+ 13 - 5
src/AzslcMain.cpp

@@ -23,7 +23,7 @@ namespace StdFs = std::filesystem;
 // For large features or milestones. Minor version allows for breaking changes. Existing tests can change.
 #define AZSLC_MINOR "8"   // last change: introduction of class inheritance
 // For small features or bug fixes. They cannot introduce breaking changes. Existing tests shouldn't change.
-#define AZSLC_REVISION "8"  // last change: enhanced grammar compliance with HLSL & robust line directive support & refactor of type qualifiler into typeinfoext
+#define AZSLC_REVISION "9"  // last change: resource unbounded arrays support
 
 
 namespace AZ::ShaderCompiler
@@ -328,12 +328,12 @@ int main(int argc, const char* argv[])
 
     bool uniqueIdx = false;
     cli.add_flag("--unique-idx", uniqueIdx, "Use unique indices for all registers. e.g. b0, t0, u0, s0 becomes b0, t1, u2, s3. Use on platforms that don't differentiate registers by resource type.");
-
+    
     bool cbBody = false;
     cli.add_flag("--cb-body", cbBody, "Emit ConstantBuffer body rather than using <T>.");
 
     bool rootSig = false;
-    cli.add_flag("--root-sig", rootSig, "Emit RootSignature for parameter binding in the shader.");
+    cli.add_flag("--root-sig", rootSig, "Emit RootSignature for parameter binding in the shader. --namespace must also be used to select a specific API.");
 
     int rootConst = 0;
     auto rootConstOpt = cli.add_option("--root-const", rootConst, "Maximum size in bytes of the root constants buffer.");
@@ -357,7 +357,9 @@ int main(int argc, const char* argv[])
     cli.add_flag("--pack-opengl", packOpenGL, "Pack buffers using strict OpenGL packing rules (Vector-strict std140 for uniforms and std430 for storage buffers).");
 
     std::vector<std::string> namespaces;
-    cli.add_option("--namespace", namespaces, "Activate an attribute namespace. May be used multiple times to activate multiple namespaces.");
+    cli.add_option("--namespace", namespaces, 
+        "Activate an attribute namespace. May be used multiple times to activate multiple namespaces. "
+        "Activating a namespace may also activate corresponding API-specific features, like dx for DirectX 12, vk for Vulkan, and mt for Metal.");
 
     bool ia = false;
     cli.add_flag("--ia", ia, "Output a list of vs entries with their Input Assembler layouts *and* a list of CS entries and their numthreads.");
@@ -484,6 +486,11 @@ int main(int argc, const char* argv[])
             throw std::runtime_error("input file could not be opened");
         }
 
+        if (rootSig && namespaces.empty())
+        {
+            throw std::runtime_error("--root-sig requested but no API was selected. Use a --namespace option as well.");
+        }
+
         const string inputFileName = useStdin ? "" : inputFile;
         PreprocessorLineDirectiveFinder lineFinder;
         lineFinder.m_physicalSourceFileName = useStdin ? "stdin" : inputFile;
@@ -552,7 +559,8 @@ int main(int argc, const char* argv[])
             std::for_each(namespaces.begin(), namespaces.end(),
                 [&](const string& space) { ir.AddAttributeNamespaceFilter(space); });
 
-            UnboundedArraysValidator::Options unboundedArraysValidationOptions = { uniqueIdx };
+            UnboundedArraysValidator::Options unboundedArraysValidationOptions;
+            unboundedArraysValidationOptions.m_useUniqueIndicesEnabled = uniqueIdx;
             if (*maxSpacesOpt)
             {
                 unboundedArraysValidationOptions.m_maxSpaces = maxSpaces;

+ 2 - 0
src/AzslcPlatformEmitter.h

@@ -74,5 +74,7 @@ namespace AZ::ShaderCompiler
         //! Aligns the size for the data containing the root constants.
         //! @param size  The size of stride
         virtual uint32_t AlignRootConstants(uint32_t size) const;
+
+        virtual bool RequiresUniqueSpaceForUnboundedArrays() const {return false;}
     };
 }

+ 1 - 1
src/AzslcReflection.cpp

@@ -744,7 +744,7 @@ namespace AZ::ShaderCompiler
                 const auto& samplerInfo = *srgMemberInfo->m_samplerState;
 
                 Json::Value samplerJson(Json::objectValue);
-                samplerJson["Id"] = sId.GetNameLeaf();
+                samplerJson["id"] = sId.GetNameLeaf();
                 samplerJson["isDynamic"] = samplerInfo.m_isDynamic;
                 ReflectBinding(samplerJson, bindInfo);
 

+ 16 - 0
src/AzslcRegisters.h

@@ -0,0 +1,16 @@
+/*
+ * 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
+ *
+ */
+#pragma once
+
+namespace AZ::ShaderCompiler
+{
+    using SpaceIndex = uint32_t; // represents register space0, space1, ...
+
+    // We start at an arbitrarily high number to avoid conflicts with spaces occupied by any user declarations
+    constexpr const SpaceIndex FirstUnboundedSpace = 1000;
+}

+ 6 - 1
src/AzslcSemanticOrchestrator.cpp

@@ -704,11 +704,16 @@ namespace AZ::ShaderCompiler
         assert(typeClass != TypeClass::Alias);
 
         string errorMessage;
-        if (!m_unboundedArraysValidator.CheckFieldCanBeAddedToSrg(isUnboundedArray, srgUid, srgInfo, varUid, varInfo, typeClass, &errorMessage))
+        if (!m_unboundedArraysValidator.CheckFieldCanBeAddedToSrg(isUnboundedArray, srgUid, varUid, varInfo, typeClass, &errorMessage))
         {
             throw AzslcOrchestratorException{ORCHESTRATOR_UNBOUNDED_RESOURCE_ISSUE, ctx->start, errorMessage};
         }
 
+        if (isUnboundedArray)
+        {
+            srgInfo.m_unboundedArrays.push_back(varUid);
+        }
+
         if (typeClass == TypeClass::ConstantBuffer)
         {
             srgInfo.m_CBs.push_back(varUid);

+ 8 - 94
src/AzslcUnboundedArraysValidator.cpp

@@ -19,7 +19,7 @@ namespace AZ::ShaderCompiler
         m_options = options;
     }
 
-    bool UnboundedArraysValidator::CheckUnboundedArrayFieldCanBeAddedToSrg(const IdentifierUID& srgUid, SRGInfo& srgInfo, const IdentifierUID& varUid, const VarInfo& varInfo, TypeClass typeClass,
+    bool UnboundedArraysValidator::CheckUnboundedArrayFieldCanBeAddedToSrg(const IdentifierUID& srgUid, const IdentifierUID& varUid, const VarInfo& varInfo, TypeClass typeClass,
         string* errorMessage)
     {
         if (!CanBeDeclaredAsUnboundedArray(typeClass))
@@ -31,78 +31,31 @@ namespace AZ::ShaderCompiler
             return false;
         }
 
-        srgInfo.m_unboundedArrays.push_back(varUid);
-
-        if (!CheckResourceCanBeAddedToSrgWhenUniqueIndicesIsEnabled(srgUid, varUid, errorMessage))
-        {
-            return false;
-        }
-
-        // Only types that can be declared as unbounded array consume register space.
-        BindingType bindingType = GetBindingType(varInfo.m_typeInfoExt);
-        auto spaceIndex = GetSpaceIndexForSrg(srgUid);
-        ArrayOfUnboundedUids& arrayOfUnboundedUids = m_unboundedUidsPerSpace[spaceIndex];
-        const IdentifierUID& unboundedUid = arrayOfUnboundedUids[bindingType];
-        if (!unboundedUid.IsEmpty())
-        {
-            // An unbounded array was already declared for this resource type. We can not add
-            // another declaration of this type in this register space.
-            if (errorMessage)
-            {
-                *errorMessage = ConcatString("More than one unbounded resource (", unboundedUid.GetName(), " and ", varUid.GetName(), ") in register space");
-            }
-            return false;
-        }
-
-        // Register the unbounded array.
-        arrayOfUnboundedUids[bindingType] = varUid;
         return true;
     }
 
-    bool UnboundedArraysValidator::CheckFieldCanBeAddedToSrg(bool isUnboundedArray, const IdentifierUID& srgUid, SRGInfo& srgInfo, const IdentifierUID& varUid, const VarInfo& varInfo, TypeClass typeClass,
+    bool UnboundedArraysValidator::CheckFieldCanBeAddedToSrg(bool isUnboundedArray, const IdentifierUID& srgUid, const IdentifierUID& varUid, const VarInfo& varInfo, TypeClass typeClass,
         string* errorMessage)
     {
         if (isUnboundedArray)
         {
-            return CheckUnboundedArrayFieldCanBeAddedToSrg(srgUid, srgInfo, varUid, varInfo, typeClass, errorMessage);
-        }
-        auto spaceIndex = GetSpaceIndexForSrg(srgUid);
-
-        if (m_unboundedUidsPerSpace.empty())
-        {
-            // All good. No unbounded array of any kind has been registered so far.
-            return true;
+            return CheckUnboundedArrayFieldCanBeAddedToSrg(srgUid, varUid, varInfo, typeClass, errorMessage);
         }
 
-        if (!CanBeDeclaredAsUnboundedArray(typeClass))
-        {
-            return true;
-        }
-
-        if (!CheckResourceCanBeAddedToSrgWhenUniqueIndicesIsEnabled(srgUid, varUid, errorMessage))
-        {
-            return false;
-        }
-
-        // Only types that can be declared as unbounded array consume register space.
-        const ArrayOfUnboundedUids& arrayOfUnboundedUids = m_unboundedUidsPerSpace[spaceIndex];
-        BindingType bindingType = GetBindingType(varInfo.m_typeInfoExt);
-        const IdentifierUID& unboundedUid = arrayOfUnboundedUids[bindingType];
-        if (!unboundedUid.IsEmpty())
+        auto spaceIndex = GetSpaceIndexForSrg(srgUid);
+        if (spaceIndex >= FirstUnboundedSpace)
         {
-            // An unbounded array was already declared for this resource type. We can not add
-            // another declaration of this type in this register space.
             if (errorMessage)
             {
-                *errorMessage = ConcatString("The unbounded resource [", unboundedUid.GetName(), "], doesn't allow [", varUid.GetName(), "] to be added to the register space");
+                *errorMessage = ConcatString("The number of SRG register spaces overflowed into the spaces reserved for unbounded arrays.");
+                return false;
             }
-            return false;
         }
 
         return true;
     }
 
-    UnboundedArraysValidator::SpaceIndex UnboundedArraysValidator::GetSpaceIndexForSrg(const IdentifierUID& srgUid)
+    SpaceIndex UnboundedArraysValidator::GetSpaceIndexForSrg(const IdentifierUID& srgUid)
     {
         SpaceIndex spaceIndex = 0;
         auto findIt = m_srgToSpaceIndex.find(srgUid);
@@ -118,8 +71,6 @@ namespace AZ::ShaderCompiler
                 spaceIndex = m_maxSpaceIndex;
             }
 
-            // We are using resize() instead of push_back() because if the size doesn't change resize() is no-op.
-            m_unboundedUidsPerSpace.resize(static_cast<size_t>(m_maxSpaceIndex) + 1);
             m_srgToSpaceIndex.emplace(srgUid, spaceIndex);
         }
         else
@@ -129,42 +80,5 @@ namespace AZ::ShaderCompiler
         return spaceIndex;
     }
 
-    bool UnboundedArraysValidator::CheckResourceCanBeAddedToSrgWhenUniqueIndicesIsEnabled(const IdentifierUID& srgUid, const IdentifierUID& varUid, string* errorMessage) const
-    {
-        if (m_options.m_useUniqueIndicesEnabled)
-        {
-            // We allow only one unbounded array per SRG. But if, for a given SRG and unbounded array was already
-            // registered then it is an error to add another variable that consumes register resources.
-            IdentifierUID unboundedArrayUid = GetFirstUnboundedArrayFromSrg(srgUid);
-            if (!unboundedArrayUid.IsEmpty())
-            {
-                if (errorMessage)
-                {
-                    *errorMessage = ConcatString("The unbounded resource [", unboundedArrayUid.GetName(), "], doesn't allow [", varUid.GetName(), "] to be added to the register space");
-                }
-                return false;
-            }
-        }
-        return true;
-    }
-
-    IdentifierUID UnboundedArraysValidator::GetFirstUnboundedArrayFromSrg(const IdentifierUID& srgUid) const
-    {
-        const auto& itor = m_srgToSpaceIndex.find(srgUid);
-        if (itor == m_srgToSpaceIndex.end())
-        {
-            return {};
-        }
-        SpaceIndex spaceIndex = itor->second;
-        const ArrayOfUnboundedUids& arrayOfUnboundedUids = m_unboundedUidsPerSpace[spaceIndex];
-        for (const auto& uid : arrayOfUnboundedUids)
-        {
-            if (!uid.IsEmpty())
-            {
-                return uid;
-            }
-        }
-        return {};
-    }
 
 } // namespace AZ::ShaderCompiler

+ 3 - 31
src/AzslcUnboundedArraysValidator.h

@@ -9,6 +9,7 @@
 
 #include "GenericUtils.h"
 #include "AzslcKindInfo.h"
+#include "AzslcRegisters.h"
 
 namespace AZ::ShaderCompiler
 {
@@ -33,37 +34,15 @@ namespace AZ::ShaderCompiler
         void SetOptions(const Options& options);
 
         //! Validates, semantically speaking, if a variable/field can be added to a SRG.
-        //! The key concept is that unbounded arrays are only allowed for unpackable shader resources like SRV, UAV, Samplers and CBV.
-        //! And the other key concept is that an unbounded array takes "ownership" of the whole register range starting from the register index
-        //! assigned to them.
-        //! For example:
-        //! ShaderResourceGroup MySrg {
-        //!     Texture2D m_a;    // Owns t0 registers. OK
-        //!     Texture2D m_b[];  // Unbounded Array. Owns t1+ registers. OK.
-        //!     Texture2D m_c;    // BAD because the whole t1+ register range is being assigned to "m_b[]"
-        //! }
-        //! If it returns false, *errorMessage will have the details.
-        //! param isUnboundedArray If true the field is being declared as "m_var[]" instead if "m_var".
-        bool CheckFieldCanBeAddedToSrg(bool isUnboundedArray, const IdentifierUID& srgUid, SRGInfo& srgInfo, const IdentifierUID& varUid, const VarInfo& varInfo, TypeClass typeClass,
+        bool CheckFieldCanBeAddedToSrg(bool isUnboundedArray, const IdentifierUID& srgUid, const IdentifierUID& varUid, const VarInfo& varInfo, TypeClass typeClass,
             string* errorMessage = nullptr);
 
     private:
         //! Helper for CheckFieldCanBeAddedToSrg. Only called if @varUid was declared as an unbounded array.
         //! If it returns false, *errorMessage will have the details.
-        bool CheckUnboundedArrayFieldCanBeAddedToSrg(const IdentifierUID& srgUid, SRGInfo& srgInfo, const IdentifierUID& varUid, const VarInfo& varInfo, TypeClass typeClass,
+        bool CheckUnboundedArrayFieldCanBeAddedToSrg(const IdentifierUID& srgUid, const IdentifierUID& varUid, const VarInfo& varInfo, TypeClass typeClass,
             string* errorMessage = nullptr);
 
-        //! When this function is called, it is guaranteed that varUid refers to a variable
-        //! that can be bound to a resource register.
-        //! For example:
-        //! A variable like "float m_var;" can NOT be bound to a resource register.
-        //! A variable like "Texture2D m_var;" is a resource that can be bound to a "tX" register. 
-        bool CheckResourceCanBeAddedToSrgWhenUniqueIndicesIsEnabled(const IdentifierUID& srgUid, const IdentifierUID& varUid, string* errorMessage = nullptr) const;
-
-        IdentifierUID GetFirstUnboundedArrayFromSrg(const IdentifierUID& srgUid) const;
-
-        using SpaceIndex = uint32_t; // represents register space0, space1, ...
-
         //! Returns the space index that corresponds to the given SRG.
         //! The calculated space index is stored in m_srgToSpaceIndex the first time
         //! this function is called for any given SRG.
@@ -76,13 +55,6 @@ namespace AZ::ShaderCompiler
         unordered_map<IdentifierUID, SpaceIndex> m_srgToSpaceIndex;
         //! Keeps track of max SpaceIndex value in m_srgToSpaceIndex.
         SpaceIndex m_maxSpaceIndex = 0; 
-        using ArrayOfUnboundedUids = array<IdentifierUID, BindingType::EndEnumeratorSentinel_>;
-        //! The index is the SpaceIndex, the content represents a size-fixed array, where each subscript,
-        //! if not empty, means that there's already an unbounded array declared for such resource
-        //! type, therefore we can detect if the user is trying to declare another resource after an unbounded
-        //! array, which is forbidden.
-        //! The size of this array is managed in GetSpaceIndexForSrg().
-        vector<ArrayOfUnboundedUids> m_unboundedUidsPerSpace;
 
     };
 } // namespace AZ::ShaderCompiler

+ 2 - 2
src/AzslcUtils.h

@@ -322,7 +322,7 @@ namespace AZ::ShaderCompiler
         {
             vector<string> asStrs;
             TransformCopy(m_dimensions, asStrs,
-                          [](int d) -> string { return d == Unknown ? "?" : d == Unbounded ? "" : std::to_string(d); });
+                          [](int d) -> string { return d == Unknown ? "<unrecognized-expr>" : d == Unbounded ? "" : std::to_string(d); });
             return asStrs.empty() ? "" : prefix + Join(asStrs.begin(), asStrs.end(), separator) + suffix;
         }
 
@@ -369,7 +369,7 @@ namespace AZ::ShaderCompiler
         //! a[][3] (or a[var][3]) will be a vector of {unknown,3}
         //!  (note: if `var` is a statically foldable const expression, then it has a chance to resolved to its initial value)
         //! empty {} means "not an array"
-        vector<unsigned int> m_dimensions;
+        vector<int> m_dimensions;
     };
 
     //! OutputFormat

+ 5 - 5
src/PadToAttributeMutator.cpp

@@ -192,9 +192,9 @@ namespace AZ::ShaderCompiler
     }
 
     void PadToAttributeMutator::InsertScopePaddings(ClassInfo* classInfo,
-                                                  const IdentifierUID& scopeUid,
-                                                  const MapOfVarInfoUidToPadding& varInfoUidToPadMap,
-                                                  const MiddleEndConfiguration& middleEndconfigration)
+                                                    const IdentifierUID& scopeUid,
+                                                    const MapOfVarInfoUidToPadding& varInfoUidToPadMap,
+                                                    const MiddleEndConfiguration& middleEndconfigration)
     {
         uint32_t nextMemberOffset = 0;
         auto& memberFields = classInfo->GetMemberFields();
@@ -410,7 +410,7 @@ namespace AZ::ShaderCompiler
 
 
     size_t PadToAttributeMutator::InsertPaddingVariables(ClassInfo* classInfo, const IdentifierUID& scopeUid,
-                                                      size_t insertionIndex, uint32_t startingOffset, uint32_t numBytesToAdd)
+                                                         size_t insertionIndex, uint32_t startingOffset, uint32_t numBytesToAdd)
     {
         auto getFloatTypeNameOfSize = +[](uint32_t sizeInBytes) -> const char *
         {
@@ -421,7 +421,7 @@ namespace AZ::ShaderCompiler
             return floatNames[idx];
         };
 
-        auto createVariableInSymbolTable = [&](QualifiedNameView parentName, const string& typeName, UnqualifiedName varName, uint32_t itemsCount = 0) -> IdentifierUID
+        auto createVariableInSymbolTable = [&](QualifiedNameView parentName, const string& typeName, UnqualifiedName varName, int itemsCount = 0) -> IdentifierUID
         {
             QualifiedName dummySymbolFieldName{ JoinPath(parentName, varName) };
 

+ 46 - 0
tests/Advanced/srg-layouts-multiple-unbounded-arrays.azsl

@@ -0,0 +1,46 @@
+ShaderResourceGroupSemantic slot1
+{
+    FrequencyId = 1;
+};
+
+ShaderResourceGroupSemantic slot2
+{
+    FrequencyId = 2;
+};
+
+struct MyStruct
+{
+    float4 m_a;
+    float4 m_b;
+};
+
+
+ShaderResourceGroup SRG1 : slot1
+{
+
+    Texture2D<float4>        m_texSRVa[];      // t0+, space1000
+    Texture2D<float4>        m_texSRVb[];      // t0+, space1001
+    Texture2D<float4>        m_texSRVc;        // t0+, space0
+    Texture2D<float4>        m_texSRVd;        // t1+, space0
+    RWTexture2D<float4>      m_texUAVa[];      // u0+, space1002
+    RWTexture2D<float4>      m_texUAVb[];      // u0+, space1003
+    Sampler                  m_samplera[];     // s0+, space1004
+    Sampler                  m_samplerb[];     // s0+, space1005
+    ConstantBuffer<MyStruct> m_structArraya[]; // b0+, space1006
+    ConstantBuffer<MyStruct> m_structArrayb[]; // b0+, space1007
+};
+
+ShaderResourceGroup SRG2 : slot2
+{
+
+    Texture2D<float4>        m_texSRVa[];      // t0+, space1008
+    Texture2D<float4>        m_texSRVb[];      // t0+, space1009
+    Texture2D<float4>        m_texSRVc;        // t0+, space1
+    Texture2D<float4>        m_texSRVd;        // t1+, space1
+    RWTexture2D<float4>      m_texUAVa[];      // u0+, space1010
+    RWTexture2D<float4>      m_texUAVb[];      // u0+, space1011
+    Sampler                  m_samplera[];     // s0+, space1012
+    Sampler                  m_samplerb[];     // s0+, space1013
+    ConstantBuffer<MyStruct> m_structArraya[]; // b0+, space1014
+    ConstantBuffer<MyStruct> m_structArrayb[]; // b0+, space1015
+};

+ 133 - 1
tests/Advanced/srg-layouts.py

@@ -974,6 +974,135 @@ def verifyPackingRelaxedUniqueIdxUseSpaces(thefile, compilerPath, silent):
         predicates.append(lambda: j["ShaderResourceGroups"][2]["inputsForImageViews"][1]["stride"]  == 12)
 
 
+        if not silent: print (fg.CYAN+ style.BRIGHT+ "input assembler layouts verification..."+ style.RESET_ALL)
+        ok = testfuncs.verifyAllPredicates(predicates, j)
+    return True if ok else False
+    
+def verifyPackingUnboundedSpillSpaces(thefile, compilerPath, silent):
+    j, ok = testfuncs.buildAndGetJson(thefile, compilerPath, silent, ["--srg", "--namespace=dx"])
+
+    if ok:
+        predicates = []
+
+        # Shader Resource Group 0
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][0]["id"]       == "m_texSRVa")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][0]["type"]     == "Texture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][0]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][0]["index"]    == 0)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][0]["space"]    == 1000)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][1]["id"]       == "m_texSRVb")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][1]["type"]     == "Texture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][1]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][1]["index"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][1]["space"]    == 1001)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][2]["id"]       == "m_texSRVc")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][2]["type"]     == "Texture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][2]["count"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][2]["index"]    == 2)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][2]["space"]    == 0)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][3]["id"]       == "m_texSRVd")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][3]["type"]     == "Texture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][3]["count"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][3]["index"]    == 3)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][3]["space"]    == 0)
+
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][4]["id"]       == "m_texUAVa")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][4]["type"]     == "RWTexture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][4]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][4]["index"]    == 0)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][4]["space"]    == 1002)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][5]["id"]       == "m_texUAVb")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][5]["type"]     == "RWTexture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][5]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][5]["index"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][5]["space"]    == 1003)
+
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][0]["id"]       == "m_samplera")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][0]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][0]["index"]    == 0)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][0]["space"]    == 1004)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][1]["id"]       == "m_samplerb")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][1]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][1]["index"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][1]["space"]    == 1005)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][0]["id"]       == "m_structArraya")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][0]["type"]     == "ConstantBuffer<MyStruct>")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][0]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][0]["index"]    == 0)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][0]["space"]    == 1006)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][1]["id"]       == "m_structArrayb")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][1]["type"]     == "ConstantBuffer<MyStruct>")
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][1]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][1]["index"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][1]["space"]    == 1007)
+
+        
+        # Shader Resource Group 1
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][0]["id"]       == "m_texSRVa")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][0]["type"]     == "Texture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][0]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][0]["index"]    == 0)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][0]["space"]    == 1008)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][1]["id"]       == "m_texSRVb")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][1]["type"]     == "Texture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][1]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][1]["index"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][1]["space"]    == 1009)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][2]["id"]       == "m_texSRVc")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][2]["type"]     == "Texture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][2]["count"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][2]["index"]    == 2)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][2]["space"]    == 1)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][3]["id"]       == "m_texSRVd")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][3]["type"]     == "Texture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][3]["count"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][3]["index"]    == 3)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][3]["space"]    == 1)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][4]["id"]       == "m_texUAVa")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][4]["type"]     == "RWTexture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][4]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][4]["index"]    == 0)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][4]["space"]    == 1010)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][5]["id"]       == "m_texUAVb")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][5]["type"]     == "RWTexture2D<float4>")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][5]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][5]["index"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][5]["space"]    == 1011)
+
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][0]["id"]       == "m_samplera")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][0]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][0]["index"]    == 0)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][0]["space"]    == 1012)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][1]["id"]       == "m_samplerb")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][1]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][1]["index"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][1]["space"]    == 1013)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][0]["id"]       == "m_structArraya")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][0]["type"]     == "ConstantBuffer<MyStruct>")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][0]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][0]["index"]    == 0)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][0]["space"]    == 1014)
+        
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][1]["id"]       == "m_structArrayb")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][1]["type"]     == "ConstantBuffer<MyStruct>")
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][1]["count"]    == -1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][1]["index"]    == 1)
+        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][1]["space"]    == 1015)
+
         if not silent: print (fg.CYAN+ style.BRIGHT+ "input assembler layouts verification..."+ style.RESET_ALL)
         ok = testfuncs.verifyAllPredicates(predicates, j)
     return True if ok else False
@@ -1446,6 +1575,9 @@ def doTests(compiler, silent, azdxcpath):
 
     if verifyPackingRelaxedUniqueIdxUseSpaces(os.path.join(workDir, "srg-layouts-spaces.azsl"), compiler, silent) : result += 1
     else: resultFailed += 1
+    
+    if verifyPackingUnboundedSpillSpaces(os.path.join(workDir, "srg-layouts-multiple-unbounded-arrays.azsl"), compiler, silent) : result += 1
+    else: resultFailed += 1
 
     if verifyPackingDirectXMatrices(os.path.join(workDir, "srg-layouts-matrices.azsl"), compiler, silent) : result += 1
     else: resultFailed += 1
@@ -1461,7 +1593,7 @@ def doTests(compiler, silent, azdxcpath):
 
     if verifyPackingMetalInlineConstants(os.path.join(workDir, "inline-constant-layouts.azsl"), compiler, silent) : result += 1
     else: resultFailed += 1
-
+    
 
 if __name__ == "__main__":
     print ("please call from testapp.py")

+ 5 - 21
tests/Advanced/unbounded-arrays-emission-tester.py

@@ -23,9 +23,8 @@ resultFailed = 0
 def doTests(compiler, silent, azdxcpath):
     """
     This test validates:
-        1. Compilation fails if an SRG has multiple unbounded arrays when --unique-idx is used.
-        2. unbounded-arrays-unique-idx-should-pass.azsl with --unique-idx used to fail in v1.7.19, should pass now.
-        2. unbounded-arrays-unique-idx-should-pass-2srgs.azsl with --unique-idx should pass too, because each SRG gets a unique register space.
+        1. unbounded-arrays-unique-idx-should-pass.azsl with --unique-idx used to fail in v1.7.19, should pass now.
+        2. unbounded-arrays-unique-idx-should-pass-2srgs.azsl with --unique-idx should pass too, because each unbounded array is in a unique register space.
     """
     global result
     global resultFailed
@@ -34,30 +33,15 @@ def doTests(compiler, silent, azdxcpath):
     # You can get it once doTests() is called, but not during initialization of the module,
     #  because at that time it will still be set to the working directory of the calling script
     workDir = os.getcwd().replace('\\', '/')
-            
-    # expect to fail with --unique-idx
-    sampleFilePath = os.path.abspath(os.path.join(workDir, "../Semantic/unbounded-arrays1.azsl"))
-    stderr, failed = testfuncs.buildAndGetError(sampleFilePath, compiler, silent, ["--unique-idx"])
-    if failed:
-        result += 1
-        if not silent:
-            stderr = stderr.decode('utf-8')
-            print (fg.CYAN + style.BRIGHT +
-               "unbounded-arrays-emission-tester.py: "+
-               "Good, got expected error when using --unique-idx: " + stderr + style.RESET_ALL)
-    else:
-        resultFailed += 1
-        if not silent:
-            print(style.BRIGHT + fg.RED + "failed unbounded-arrays-emission-tester.py: was expecting error when using --unique-idx." + style.RESET_ALL)
-    
+
     # expect success when using --unique-idx
     sampleFilePath = os.path.abspath(os.path.join(workDir, "../Semantic/unbounded-arrays-unique-idx-should-pass.azsl"))
-    if testhelper.verifyEmissionPatterns(sampleFilePath, compiler, silent, ["--unique-idx",]) : result += 1
+    if testhelper.verifyEmissionPatterns(sampleFilePath, compiler, silent, ["--unique-idx","--namespace=dx"]) : result += 1
     else: resultFailed += 1
     
     # expect success when using --unique-idx
     sampleFilePath = os.path.abspath(os.path.join(workDir, "../Semantic/unbounded-arrays-unique-idx-should-pass-2srgs.azsl"))
-    if testhelper.verifyEmissionPatterns(sampleFilePath, compiler, silent, ["--unique-idx",]) : result += 1
+    if testhelper.verifyEmissionPatterns(sampleFilePath, compiler, silent, ["--unique-idx","--namespace=dx"]) : result += 1
     else: resultFailed += 1
 
     testhelper.printFailedTestList(silent)

+ 0 - 41
tests/Advanced/unbounded-arrays-for-max-spaces.azsl

@@ -1,41 +0,0 @@
-// This file requires a separate register space per SRG and (--max-spaces >= 4) to pass.
-
-ShaderResourceGroupSemantic slot1
-{
-    FrequencyId = 1;
-};
-
-ShaderResourceGroupSemantic slot2
-{
-    FrequencyId = 2;
-};
-
-ShaderResourceGroupSemantic slot3
-{
-    FrequencyId = 3;
-};
-
-ShaderResourceGroupSemantic slot4
-{
-    FrequencyId = 4;
-};
-
-ShaderResourceGroup SRG1 : slot1
-{
-    Texture2D<float4>        m_texSRVa[];        // Takes t0+, space0
-};
-
-ShaderResourceGroup SRG2 : slot2
-{
-    Texture2D<float4>        m_texSRVa[];        // Takes t0+, space1, but --max-spaces==1 should fail
-};
-
-ShaderResourceGroup SRG3 : slot3
-{
-    Texture2D<float4>        m_texSRVa[];        // Takes t0+, space2, but --max-spaces==2 should fail
-};
-
-ShaderResourceGroup SRG4 : slot4
-{
-    Texture2D<float4>        m_texSRVa[];        // Takes t0+, space3, but --max-spaces==3 should fail
-};

+ 0 - 67
tests/Advanced/unbounded-arrays-max-spaces.py

@@ -1,67 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-"""
-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
-
-"""
-import sys
-import os
-
-import platform
-sys.path.append("..")
-from clr import *
-import os.path
-from os.path import join, normpath, basename
-import testhelper
-import testfuncs
-
-result = 0  # to define for sub-tests
-resultFailed = 0
-def doTests(compiler, silent, azdxcpath):
-    """
-    This test does a thorough validation of separate register spaces per SRG when a limited amount
-    of spaces is defined with the command line argument --max-spaces.
-    """
-    global result
-    global resultFailed
-
-    # Working directory should have been set to this script's directory by the calling parent
-    # You can get it once doTests() is called, but not during initialization of the module,
-    #  because at that time it will still be set to the working directory of the calling script
-    workDir = os.getcwd().replace('\\', '/')
-
-    # validate --max-spaces.
-    sampleFilePath = os.path.abspath(os.path.join(workDir, "unbounded-arrays-for-max-spaces.azsl"))
-    maxMaxSpaces = 4
-    numExpectedFailures = 0
-    for maxSpaces in range(maxMaxSpaces):
-        maxSpaces += 1
-        stderr, failed = testfuncs.buildAndGetError(sampleFilePath, compiler, True, ["--max-spaces", "%d" % maxSpaces])
-        if failed:
-            stderr = stderr.decode('utf-8')
-            srgA = "SRG%d" % maxSpaces
-            srgB = "SRG%d" % (maxSpaces + 1)
-            gotExpectedFailure = (srgA in stderr) and (srgB in stderr)
-            if not gotExpectedFailure and not silent:
-                print(style.BRIGHT + fg.RED + "failed unbounded-arrays-emission-tester.py: for unbounded-arrays-for-max-spaces.azsl at maxSpaces={}: {}".format(maxSpaces, stderr) + style.RESET_ALL)
-            numExpectedFailures += gotExpectedFailure
-    if numExpectedFailures == maxMaxSpaces - 1:
-        result += 1
-        if not silent:
-            print (fg.CYAN + style.BRIGHT +
-               "unbounded-arrays-max-spaces.py: "+
-               "Good, got expected failure count of: {}".format(numExpectedFailures) + style.RESET_ALL)
-    else:
-        resultFailed += 1
-        if not silent:
-            print (style.BRIGHT + fg.RED  +
-               "unbounded-arrays-max-spaces.py: "+
-               "Error: Got unexpected failure count of: {}".format(numExpectedFailures) + style.RESET_ALL)
-
-    testhelper.printFailedTestList(silent)
-    
-if __name__ == "__main__":
-    print ("please call from testapp.py")

+ 0 - 95
tests/Advanced/unbounded-arrays-srg-layout.py

@@ -1,95 +0,0 @@
-#!/usr/bin/python
-# -*- coding: utf-8 -*-
-"""
-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
-"""
-import sys
-import os
-sys.path.append("..")
-sys.path.append("../..")
-from clr import *
-import testfuncs
-
-# This test validates SRG Layout emission when using unbounded arrays.
-# In particular, valid unbounded arrays should be emitted with
-#  "count" = -1
-# in the json srg layout.
-
-def verify(thefile, compilerPath, silent):
-    j, ok = testfuncs.buildAndGetJson(thefile, compilerPath, silent, ["--srg"])
-
-    if ok:
-        predicates = []
-        #SRG1
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSRGConstants"][0]["constantByteOffset"] == 0)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSRGConstants"][0]["constantByteSize"]   == 4)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSRGConstants"][1]["constantByteOffset"] == 4)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSRGConstants"][1]["constantByteSize"]   == 8)
-
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][0]["index"] ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][0]["count"] ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][1]["index"] ==  2)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForBufferViews"][1]["count"] == -1)
-
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][0]["index"]  ==  0)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][0]["count"]  ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][1]["index"]  ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][1]["count"]  == -1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][2]["index"]  ==  0)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][2]["count"]  ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][3]["index"]  ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForImageViews"][3]["count"]  == -1)
-
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][0]["index"]    ==  0)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][0]["count"]    ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][1]["index"]    ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][0]["inputsForSamplers"][1]["count"]    == -1)
-
-        #SRG2
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSRGConstants"][0]["constantByteOffset"] == 0)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSRGConstants"][0]["constantByteSize"]   == 4)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSRGConstants"][1]["constantByteOffset"] == 4)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSRGConstants"][1]["constantByteSize"]   == 8)
-
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][0]["index"] ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][0]["count"] ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][1]["index"] ==  2)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForBufferViews"][1]["count"] == -1)
-
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][0]["index"]  ==  0)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][0]["count"]  ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][1]["index"]  ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][1]["count"]  == -1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][2]["index"]  ==  0)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][2]["count"]  ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][3]["index"]  ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForImageViews"][3]["count"]  == -1)
-
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][0]["index"]    ==  0)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][0]["count"]    ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][1]["index"]    ==  1)
-        predicates.append(lambda: j["ShaderResourceGroups"][1]["inputsForSamplers"][1]["count"]    == -1)
-
-        if not silent: print (fg.CYAN+ style.BRIGHT+ "reflected binding info verification..."+ style.RESET_ALL)
-        ok = testfuncs.verifyAllPredicates(predicates, j)
-    return True if ok else False
-
-result = 0  # to define for sub-tests
-resultFailed = 0
-def doTests(compiler, silent, azdxcpath):
-    global result
-    global resultFailed
-
-    # Working directory should have been set to this script's directory by the calling parent
-    # You can get it once doTests() is called, but not during initialization of the module,
-    #  because at that time it will still be set to the working directory of the calling script
-    workDir = os.getcwd()
-
-    if verify(os.path.join(workDir, "../Emission/UnboundedArrays.azsl"), compiler, silent) : result += 1
-    else: resultFailed += 1
-
-if __name__ == "__main__":
-    print ("please call from testapp.py")

+ 0 - 71
tests/Emission/UnboundedArrays.azsl

@@ -1,71 +0,0 @@
-// This sample makes sure unbounded arrays are supported across all register classes t,u,s,b.
-
-ShaderResourceGroupSemantic slot1
-{
-    FrequencyId = 1;
-};
-
-ShaderResourceGroupSemantic slot2
-{
-    FrequencyId = 2;
-};
-
-struct MyStruct
-{
-    float4 m_a;
-    float4 m_b;
-};
-
-ShaderResourceGroup SRG1 : slot1
-{
-    int m_index; // Triggers usage of b0.
-    uint2 m_rwTexCoord;
-
-    Texture2D<float4>        m_texSRVa;        // Takes t0, space0
-    Texture2D<float4>        m_texSRVb[];      // Takes t1+, space0
-    RWTexture2D<float4>      m_texUAVa;        // Takes u0, space0
-    RWTexture2D<float4>      m_texUAVb[];      // Takes u1+, space0
-    Sampler                  m_samplera;       // Takes s0, space0
-    Sampler                  m_samplerb[];     // Takes s1+, space0
-    ConstantBuffer<MyStruct> m_structArraya;   // Takes b1, space0
-    ConstantBuffer<MyStruct> m_structArrayb[]; // Takes b2+, space0 
-};
-
-// SRG2 will take space1 because each SRG gets a unique register space.
-// Otherwise this shader wouldn't compile because all unbounded arrays in SRG1
-// would take over all available registers in space0. 
-ShaderResourceGroup SRG2 : slot2
-{
-    int m_index; // Triggers usage of b0.
-    uint2 m_rwTexCoord;
-
-    Texture2D<float4>        m_texSRVa;        // Takes t0, space1
-    Texture2D<float4>        m_texSRVb[];      // Takes t1+, space1
-    RWTexture2D<float4>      m_texUAVa;        // Takes u0, space1
-    RWTexture2D<float4>      m_texUAVb[];      // Takes u1+, space1
-    Sampler                  m_samplera;       // Takes s0, space1
-    Sampler                  m_samplerb[];     // Takes s1+, space1
-    ConstantBuffer<MyStruct> m_structArraya;   // Takes b1, space1
-    ConstantBuffer<MyStruct> m_structArrayb[]; // Takes b2+, space1 
-}
-
-float4 MainPS(float2 uv : TEXCOORD0) : SV_Target0
-{
-    float4 diffuse = float4(0, 0, 0, 1);
-
-    diffuse += SRG1::m_texSRVa.Sample(SRG1::m_samplera, uv);
-    diffuse += SRG1::m_texSRVb[SRG1::m_index].Sample(SRG1::m_samplerb[SRG1::m_index], uv);
-    diffuse += SRG1::m_texUAVa[SRG1::m_rwTexCoord];
-    diffuse += SRG1::m_texUAVb[SRG1::m_index][SRG1::m_rwTexCoord];
-    diffuse += SRG1::m_structArraya.m_a;
-    diffuse += SRG1::m_structArrayb[SRG1::m_index].m_b;
-
-    diffuse += SRG2::m_texSRVa.Sample(SRG2::m_samplera, uv);
-    diffuse += SRG2::m_texSRVb[SRG2::m_index].Sample(SRG2::m_samplerb[SRG2::m_index], uv);
-    diffuse += SRG2::m_texUAVa[SRG2::m_rwTexCoord];
-    diffuse += SRG2::m_texUAVb[SRG2::m_index][SRG2::m_rwTexCoord];
-    diffuse += SRG2::m_structArraya.m_a;
-    diffuse += SRG2::m_structArrayb[SRG2::m_index].m_b;
-    
-    return diffuse;
-}

+ 0 - 34
tests/Emission/UnboundedArrays.txt

@@ -1,34 +0,0 @@
-# list lines expected to have tokens matching the patterns in the strings. each space is a separation.
-
-"Texture2D < float4 > SRG1_m_texSRVa : register ( t0  , space0 ) ;"
-"Texture2D < float4 > SRG1_m_texSRVb [] : register ( t1  , space0 ) ;"
-"RWTexture2D < float4 > SRG1_m_texUAVa : register ( u0  , space0 ) ;"
-"RWTexture2D < float4 > SRG1_m_texUAVb [] : register ( u1  , space0 ) ;"
-"SamplerState SRG1_m_samplera : register ( s0  , space0 ) ;"
-"SamplerState SRG1_m_samplerb [] : register ( s1  , space0 ) ;"
-"ConstantBuffer < :: SRG1_SRGConstantsStruct > SRG1_SRGConstantBuffer : register ( b0  , space0 ) ;"
-"ConstantBuffer < :: MyStruct > SRG1_m_structArraya : register ( b1  , space0 ) ;"
-"ConstantBuffer < :: MyStruct > SRG1_m_structArrayb [] : register ( b2  , space0 ) ;"
-"Texture2D < float4 > SRG2_m_texSRVa : register ( t0  , space1 ) ;"
-"Texture2D < float4 > SRG2_m_texSRVb [] : register ( t1  , space1 ) ;"
-"RWTexture2D < float4 > SRG2_m_texUAVa : register ( u0  , space1 ) ;"
-"RWTexture2D < float4 > SRG2_m_texUAVb [] : register ( u1  , space1 ) ;"
-"SamplerState SRG2_m_samplera : register ( s0  , space1 ) ;"
-"SamplerState SRG2_m_samplerb [] : register ( s1  , space1 ) ;"
-"ConstantBuffer < :: SRG2_SRGConstantsStruct > SRG2_SRGConstantBuffer : register ( b0  , space1 ) ;"
-"ConstantBuffer < :: MyStruct > SRG2_m_structArraya : register ( b1  , space1 ) ;"
-"ConstantBuffer < :: MyStruct > SRG2_m_structArrayb [] : register ( b2  , space1 ) ;"
-"float4 MainPS ( float2 uv : TEXCOORD0 ) : SV_Target0"
-"float4 diffuse = float4 ( 0 , 0 , 0 , 1 ) ;"
-"diffuse += :: SRG1_m_texSRVa . Sample ( :: SRG1_m_samplera , uv ) ;"
-"diffuse += :: SRG1_m_texSRVb [ :: SRG1_SRGConstantBuffer . SRG1_m_index ] . Sample ( :: SRG1_m_samplerb [ :: SRG1_SRGConstantBuffer . SRG1_m_index ] , uv ) ;"
-"diffuse += :: SRG1_m_texUAVa [ :: SRG1_SRGConstantBuffer . SRG1_m_rwTexCoord ] ;"
-"diffuse += :: SRG1_m_texUAVb [ :: SRG1_SRGConstantBuffer . SRG1_m_index ] [ :: SRG1_SRGConstantBuffer . SRG1_m_rwTexCoord ] ;"
-"diffuse += :: SRG1_m_structArraya . m_a ;"
-"diffuse += :: SRG1_m_structArrayb [ :: SRG1_SRGConstantBuffer . SRG1_m_index ] . m_b ;"
-"diffuse += :: SRG2_m_texSRVa . Sample ( :: SRG2_m_samplera , uv ) ;"
-"diffuse += :: SRG2_m_texSRVb [ :: SRG2_SRGConstantBuffer . SRG2_m_index ] . Sample ( :: SRG2_m_samplerb [ :: SRG2_SRGConstantBuffer . SRG2_m_index ] , uv ) ;"
-"diffuse += :: SRG2_m_texUAVa [ :: SRG2_SRGConstantBuffer . SRG2_m_rwTexCoord ] ;"
-"diffuse += :: SRG2_m_texUAVb [ :: SRG2_SRGConstantBuffer . SRG2_m_index ] [ :: SRG2_SRGConstantBuffer . SRG2_m_rwTexCoord ] ;"
-"diffuse += :: SRG2_m_structArraya . m_a ;"
-"diffuse += :: SRG2_m_structArrayb [ :: SRG2_SRGConstantBuffer . SRG2_m_index ] . m_b ;"

+ 46 - 0
tests/Emission/srg-layouts-multiple-unbounded-arrays.azsl

@@ -0,0 +1,46 @@
+ShaderResourceGroupSemantic slot1
+{
+    FrequencyId = 1;
+};
+
+ShaderResourceGroupSemantic slot2
+{
+    FrequencyId = 2;
+};
+
+struct MyStruct
+{
+    float4 m_a;
+    float4 m_b;
+};
+
+
+ShaderResourceGroup SRG1 : slot1
+{
+
+    Texture2D<float4>        m_texSRVa[];      // t0+, space1000
+    Texture2D<float4>        m_texSRVb[];      // t0+, space1001
+    Texture2D<float4>        m_texSRVc;        // t0+, space0
+    Texture2D<float4>        m_texSRVd;        // t1+, space0
+    RWTexture2D<float4>      m_texUAVa[];      // u0+, space1002
+    RWTexture2D<float4>      m_texUAVb[];      // u0+, space1003
+    Sampler                  m_samplera[];     // s0+, space1004
+    Sampler                  m_samplerb[];     // s0+, space1005
+    ConstantBuffer<MyStruct> m_structArraya[]; // b0+, space1006
+    ConstantBuffer<MyStruct> m_structArrayb[]; // b0+, space1007
+};
+
+ShaderResourceGroup SRG2 : slot2
+{
+
+    Texture2D<float4>        m_texSRVa[];      // t0+, space1008
+    Texture2D<float4>        m_texSRVb[];      // t0+, space1009
+    Texture2D<float4>        m_texSRVc;        // t0+, space1
+    Texture2D<float4>        m_texSRVd;        // t1+, space1
+    RWTexture2D<float4>      m_texUAVa[];      // u0+, space1010
+    RWTexture2D<float4>      m_texUAVb[];      // u0+, space1011
+    Sampler                  m_samplera[];     // s0+, space1012
+    Sampler                  m_samplerb[];     // s0+, space1013
+    ConstantBuffer<MyStruct> m_structArraya[]; // b0+, space1014
+    ConstantBuffer<MyStruct> m_structArrayb[]; // b0+, space1015
+};

+ 44 - 0
tests/Emission/srg-layouts-multiple-unbounded-arrays.txt

@@ -0,0 +1,44 @@
+/*
+    Cmdargs: ['--root-sig', '--namespace=dx']
+*/
+"Texture2D < float4 > SRG1_m_texSRVa [] : register ( t0 , space1000 ) "
+"Texture2D < float4 > SRG1_m_texSRVb [] : register ( t1 , space1001 ) "
+"Texture2D < float4 > SRG1_m_texSRVc : register ( t2 , space0 ) "
+"Texture2D < float4 > SRG1_m_texSRVd : register ( t3 , space0 ) "
+"RWTexture2D < float4 > SRG1_m_texUAVa [] : register ( u0 , space1002 ) "
+"RWTexture2D < float4 > SRG1_m_texUAVb [] : register ( u1 , space1003 ) "
+"SamplerState SRG1_m_samplera [] : register ( s0 , space1004 ) "
+"SamplerState SRG1_m_samplerb [] : register ( s1 , space1005 ) "
+"ConstantBuffer < :: MyStruct > SRG1_m_structArraya [] : register ( b0 , space1006 ) "
+"ConstantBuffer < :: MyStruct > SRG1_m_structArrayb [] : register ( b1 , space1007 ) "
+"Texture2D < float4 > SRG2_m_texSRVa [] : register ( t0 , space1008 ) "
+"Texture2D < float4 > SRG2_m_texSRVb [] : register ( t1 , space1009 ) "
+"Texture2D < float4 > SRG2_m_texSRVc : register ( t2 , space1 ) "
+"Texture2D < float4 > SRG2_m_texSRVd : register ( t3 , space1 ) "
+"RWTexture2D < float4 > SRG2_m_texUAVa [] : register ( u0 , space1010 ) "
+"RWTexture2D < float4 > SRG2_m_texUAVb [] : register ( u1 , space1011 ) "
+"SamplerState SRG2_m_samplera [] : register ( s0 , space1012 ) "
+"SamplerState SRG2_m_samplerb [] : register ( s1 , space1013 ) "
+"ConstantBuffer < :: MyStruct > SRG2_m_structArraya [] : register ( b0 , space1014 ) "
+"ConstantBuffer < :: MyStruct > SRG2_m_structArrayb [] : register ( b1 , space1015 ) "
+
+"SRV     ( t0 , space = 1000 , numDescriptors = 1 ) "
+"SRV     ( t1 , space = 1001 , numDescriptors = 1 ) "
+"SRV     ( t2 , space = 0 ,    numDescriptors = 1 ) "
+"SRV     ( t3 , space = 0 ,    numDescriptors = 1 ) "
+"UAV     ( u0 , space = 1002 , numDescriptors = 1 ) "
+"UAV     ( u1 , space = 1003 , numDescriptors = 1 ) "
+"CBV     ( b0 , space = 1006 , numDescriptors = 1 ) "
+"CBV     ( b1 , space = 1007 , numDescriptors = 1 ) "
+"Sampler ( s0 , space = 1004 , numDescriptors = 1 ) "
+"Sampler ( s1 , space = 1005 , numDescriptors = 1 ) "
+"SRV     ( t0 , space = 1008 , numDescriptors = 1 ) "
+"SRV     ( t1 , space = 1009 , numDescriptors = 1 ) "
+"SRV     ( t2 , space = 1 ,    numDescriptors = 1 ) "
+"SRV     ( t3 , space = 1 ,    numDescriptors = 1 ) "
+"UAV     ( u0 , space = 1010 , numDescriptors = 1 ) "
+"UAV     ( u1 , space = 1011 , numDescriptors = 1 ) "
+"CBV     ( b0 , space = 1014 , numDescriptors = 1 ) "
+"CBV     ( b1 , space = 1015 , numDescriptors = 1 ) "
+"Sampler ( s0 , space = 1012 , numDescriptors = 1 ) "
+"Sampler ( s1 , space = 1013 , numDescriptors = 1 ) "

+ 0 - 27
tests/Semantic/AsError/unbounded-arrays4.azsl

@@ -1,27 +0,0 @@
-// Makes sure unbounded arrays are supported across all register classes t,u,s,b,
-// This one fails because resources can not be added after unbounded arrays.
-
-
-ShaderResourceGroupSemantic slot1
-{
-    FrequencyId = 1;
-};
-
-struct MyStruct
-{
-    float3 m_a;
-    float3 m_b;
-};
-
-ShaderResourceGroup SRG1 : slot1
-{
-    Texture2D<float4>        m_texSRVa[];      // Takes t0+
-    Texture2D<float4>        m_texSRVb;        // #EC 48. Error. t0+ already taken.  
-    RWTexture2D<float4>      m_texUAVa[];      // Takes u0+
-    RWTexture2D<float4>      m_texUAVb;        // #EC 48. Error. u0+ already taken. 
-    Sampler                  m_samplera[];     // Takes s0+
-    Sampler                  m_samplerb;       // #EC 48. Error. s0+ already taken. 
-    ConstantBuffer<MyStruct> m_structArraya[]; // Takes b0+
-    ConstantBuffer<MyStruct> m_structArrayb;   // #EC 48. Error. b0+ already taken.
-};
-

+ 2 - 2
tests/Semantic/unbounded-arrays-unique-idx-should-pass-2srgs.txt

@@ -1,9 +1,9 @@
 # list lines expected to have tokens matching the patterns in the strings. each space is a separation.
 
-"ByteAddressBuffer SRG1_m_meshBuffers [] : register ( t8 , space0 ) ;"
+"ByteAddressBuffer SRG1_m_meshBuffers [] : register ( t8 , space1000 ) ;"
 "ConstantBuffer < :: SRG1_SRGConstantsStruct > SRG1_SRGConstantBuffer : register ( b6 , space0 ) ;"
 "ConstantBuffer < :: MyStruct > SRG1_m_data : register ( b7 , space0 ) ;"
 
-"ByteAddressBuffer SRG2_m_meshBuffers [] : register ( t8 , space1 ) ;"
+"ByteAddressBuffer SRG2_m_meshBuffers [] : register ( t8 , space1001 ) ;"
 "ConstantBuffer < :: SRG2_SRGConstantsStruct > SRG2_SRGConstantBuffer : register ( b6 , space1 ) ;"
 "ConstantBuffer < :: MyStruct > SRG2_m_data : register ( b7 , space1 ) ;"

+ 1 - 1
tests/Semantic/unbounded-arrays-unique-idx-should-pass.txt

@@ -1,5 +1,5 @@
 # list lines expected to have tokens matching the patterns in the strings. each space is a separation.
 
-"ByteAddressBuffer SRG1_m_meshBuffers [] : register ( t8 , space0 ) ;"
+"ByteAddressBuffer SRG1_m_meshBuffers [] : register ( t8 , space1000 ) ;"
 "ConstantBuffer < :: SRG1_SRGConstantsStruct > SRG1_SRGConstantBuffer : register ( b6 , space0 ) ;"
 "ConstantBuffer < :: MyStruct > SRG1_m_data : register ( b7 , space0 ) ;"