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); }
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; }