Exemplo n.º 1
0
        public static unsafe bool UpdateMaterial(RenderSystem renderSystem, RenderDrawContext context, MaterialInfoBase materialInfo, int materialSlotIndex, RenderEffect renderEffect, ParameterCollection materialParameters)
        {
            var resourceGroupDescription = renderEffect.Reflection.ResourceGroupDescriptions[materialSlotIndex];

            if (resourceGroupDescription.DescriptorSetLayout == null)
            {
                return(false);
            }

            // Check if this material was encountered for the first time this frame and mark it as used
            if (Interlocked.Exchange(ref materialInfo.LastFrameUsed, renderSystem.FrameCounter) == renderSystem.FrameCounter)
            {
                return(true);
            }

            // First time we use the material with a valid effect, let's update layouts
            if (materialInfo.PerMaterialLayout == null || materialInfo.PerMaterialLayout.Hash != renderEffect.Reflection.ResourceGroupDescriptions[materialSlotIndex].Hash)
            {
                materialInfo.PerMaterialLayout = ResourceGroupLayout.New(renderSystem.GraphicsDevice, resourceGroupDescription, renderEffect.Effect.Bytecode);

                var parameterCollectionLayout = materialInfo.ParameterCollectionLayout = new ParameterCollectionLayout();
                parameterCollectionLayout.ProcessResources(resourceGroupDescription.DescriptorSetLayout);
                materialInfo.ResourceCount = parameterCollectionLayout.ResourceCount;

                // Process material cbuffer (if any)
                if (resourceGroupDescription.ConstantBufferReflection != null)
                {
                    materialInfo.ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection;
                    parameterCollectionLayout.ProcessConstantBuffer(resourceGroupDescription.ConstantBufferReflection);
                }
                materialInfo.ParametersChanged = true;
            }

            // If the parameters collection instance changed, we need to update it
            if (materialInfo.ParametersChanged)
            {
                materialInfo.ParameterCollection.UpdateLayout(materialInfo.ParameterCollectionLayout);
                materialInfo.ParameterCollectionCopier = new ParameterCollection.Copier(materialInfo.ParameterCollection, materialParameters);
                materialInfo.ParametersChanged         = false;
            }

            // Copy back to ParameterCollection
            // TODO GRAPHICS REFACTOR directly copy to resource group?
            materialInfo.ParameterCollectionCopier.Copy();

            // Allocate resource groups
            context.ResourceGroupAllocator.PrepareResourceGroup(materialInfo.PerMaterialLayout, BufferPoolAllocationType.UsedMultipleTime, materialInfo.Resources);

            // Set resource bindings in PerMaterial resource set
            for (int resourceSlot = 0; resourceSlot < materialInfo.ResourceCount; ++resourceSlot)
            {
                materialInfo.Resources.DescriptorSet.SetValue(resourceSlot, materialInfo.ParameterCollection.ObjectValues[resourceSlot]);
            }

            // Process PerMaterial cbuffer
            if (materialInfo.ConstantBufferReflection != null)
            {
                var mappedCB = materialInfo.Resources.ConstantBuffer.Data;

                fixed(byte *dataValues = materialInfo.ParameterCollection.DataValues)
                Utilities.CopyMemory(mappedCB, (IntPtr)dataValues, materialInfo.Resources.ConstantBuffer.Size);
            }

            return(true);
        }
Exemplo n.º 2
0
        public static unsafe bool UpdateMaterial(RenderSystem renderSystem, RenderDrawContext context, MaterialInfoBase materialInfo, int materialSlotIndex, RenderEffect renderEffect, ParameterCollection materialParameters)
        {
            // Check if encountered first time this frame
            if (materialInfo.LastFrameUsed == renderSystem.FrameCounter)
                return true;

            // First time we use the material with a valid effect, let's update layouts
            if (materialInfo.PerMaterialLayout == null || materialInfo.PerMaterialLayout.Hash != renderEffect.Reflection.ResourceGroupDescriptions[materialSlotIndex].Hash)
            {
                var resourceGroupDescription = renderEffect.Reflection.ResourceGroupDescriptions[materialSlotIndex];
                if (resourceGroupDescription.DescriptorSetLayout == null)
                    return false;

                materialInfo.PerMaterialLayout = ResourceGroupLayout.New(renderSystem.GraphicsDevice, resourceGroupDescription, renderEffect.Effect.Bytecode);

                var parameterCollectionLayout = materialInfo.ParameterCollectionLayout = new ParameterCollectionLayout();
                parameterCollectionLayout.ProcessResources(resourceGroupDescription.DescriptorSetLayout);
                materialInfo.ResourceCount = parameterCollectionLayout.ResourceCount;

                // Process material cbuffer (if any)
                if (resourceGroupDescription.ConstantBufferReflection != null)
                {
                    materialInfo.ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection;
                    parameterCollectionLayout.ProcessConstantBuffer(resourceGroupDescription.ConstantBufferReflection);
                }
                materialInfo.ParametersChanged = true;
            }

            // If the parameters collection instance changed, we need to update it
            if (materialInfo.ParametersChanged)
            {
                materialInfo.ParameterCollection.UpdateLayout(materialInfo.ParameterCollectionLayout);
                materialInfo.ParameterCollectionCopier = new ParameterCollection.Copier(materialInfo.ParameterCollection, materialParameters);
                materialInfo.ParametersChanged = false;
            }

            // Mark this material as used during this frame
            materialInfo.LastFrameUsed = renderSystem.FrameCounter;

            // Copy back to ParameterCollection
            // TODO GRAPHICS REFACTOR directly copy to resource group?
            materialInfo.ParameterCollectionCopier.Copy();

            // Allocate resource groups
            context.ResourceGroupAllocator.PrepareResourceGroup(materialInfo.PerMaterialLayout, BufferPoolAllocationType.UsedMultipleTime, materialInfo.Resources);

            // Set resource bindings in PerMaterial resource set
            for (int resourceSlot = 0; resourceSlot < materialInfo.ResourceCount; ++resourceSlot)
            {
                materialInfo.Resources.DescriptorSet.SetValue(resourceSlot, materialInfo.ParameterCollection.ObjectValues[resourceSlot]);
            }

            // Process PerMaterial cbuffer
            if (materialInfo.ConstantBufferReflection != null)
            {
                var mappedCB = materialInfo.Resources.ConstantBuffer.Data;
                fixed (byte* dataValues = materialInfo.ParameterCollection.DataValues)
                    Utilities.CopyMemory(mappedCB, (IntPtr)dataValues, materialInfo.Resources.ConstantBuffer.Size);
            }

            return true;
        }