private FrameResourceGroupLayout CreateFrameResourceGroupLayout(ResourceGroupDescription resourceGroupDescription, RenderEffectState effectState)
        {
            if (resourceGroupDescription.DescriptorSetLayout == null)
            {
                return(null);
            }

            // We combine both hash for DescriptorSet and cbuffer itself (if it exists)
            var hash            = resourceGroupDescription.Hash;
            var effectStateHash = new ObjectId(0, 0, 0, (uint)effectState);

            ObjectId.Combine(ref effectStateHash, ref hash, out hash);

            FrameResourceGroupLayout result;

            if (!frameResourceLayouts.TryGetValue(hash, out result))
            {
                result = new FrameResourceGroupLayout
                {
                    DescriptorSetLayoutBuilder = resourceGroupDescription.DescriptorSetLayout,
                    DescriptorSetLayout        = DescriptorSetLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription.DescriptorSetLayout),
                    ConstantBufferReflection   = resourceGroupDescription.ConstantBufferReflection,
                    State = effectState,
                };

                result.Entry.Resources = new ResourceGroup();

                if (resourceGroupDescription.ConstantBufferReflection != null)
                {
                    result.ConstantBufferSize = resourceGroupDescription.ConstantBufferReflection.Size;
                    result.ConstantBufferHash = resourceGroupDescription.ConstantBufferReflection.Hash;
                }

                // Resolve slots
                result.ConstantBufferOffsets = new int[frameCBufferOffsetSlots.Count];
                for (int index = 0; index < frameCBufferOffsetSlots.Count; index++)
                {
                    ResolveCBufferOffset(result, index, frameCBufferOffsetSlots[index].Variable);
                }

                frameResourceLayouts.Add(hash, result);
            }

            return(result);
        }
        private FrameResourceGroupLayout CreateFrameResourceGroupLayout(ResourceGroupDescription resourceGroupDescription, RenderEffectState effectState)
        {
            if (resourceGroupDescription.DescriptorSetLayout == null)
                return null;

            // We combine both hash for DescriptorSet and cbuffer itself (if it exists)
            var hash = resourceGroupDescription.Hash;
            var effectStateHash = new ObjectId(0, 0, 0, (uint)effectState);
            ObjectId.Combine(ref effectStateHash, ref hash, out hash);

            FrameResourceGroupLayout result;
            if (!frameResourceLayouts.TryGetValue(hash, out result))
            {
                result = new FrameResourceGroupLayout
                {
                    DescriptorSetLayoutBuilder = resourceGroupDescription.DescriptorSetLayout,
                    DescriptorSetLayout = DescriptorSetLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription.DescriptorSetLayout),
                    ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection,
                    State = effectState,
                };

                result.Entry.Resources = new ResourceGroup();

                if (resourceGroupDescription.ConstantBufferReflection != null)
                {
                    result.ConstantBufferSize = resourceGroupDescription.ConstantBufferReflection.Size;
                    result.ConstantBufferHash = resourceGroupDescription.ConstantBufferReflection.Hash;
                }

                // Resolve slots
                result.ConstantBufferOffsets = new int[frameCBufferOffsetSlots.Count];
                for (int index = 0; index < frameCBufferOffsetSlots.Count; index++)
                {
                    ResolveCBufferOffset(result, index, frameCBufferOffsetSlots[index].Variable);
                }

                frameResourceLayouts.Add(hash, result);
            }

            return result;
        }