private ViewResourceGroupLayout CreateViewResourceGroupLayout(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); ViewResourceGroupLayout result; if (!viewResourceLayouts.TryGetValue(hash, out result)) { result = new ViewResourceGroupLayout { DescriptorSetLayoutBuilder = resourceGroupDescription.DescriptorSetLayout, DescriptorSetLayout = DescriptorSetLayout.New(RenderSystem.GraphicsDevice, resourceGroupDescription.DescriptorSetLayout), ConstantBufferReflection = resourceGroupDescription.ConstantBufferReflection, Entries = new ResourceGroupEntry[RenderSystem.Views.Count], State = effectState, }; for (int index = 0; index < result.Entries.Length; index++) { result.Entries[index].Resources = new ResourceGroup(); } if (resourceGroupDescription.ConstantBufferReflection != null) { result.ConstantBufferSize = resourceGroupDescription.ConstantBufferReflection.Size; result.ConstantBufferHash = resourceGroupDescription.ConstantBufferReflection.Hash; } // Resolve slots result.ConstantBufferOffsets = new int[viewCBufferOffsetSlots.Count]; for (int index = 0; index < viewCBufferOffsetSlots.Count; index++) { ResolveCBufferOffset(result, index, viewCBufferOffsetSlots[index].Variable); } // Resolve logical groups result.LogicalGroups = new LogicalGroup[viewLogicalGroups.Count]; for (int index = 0; index < viewLogicalGroups.Count; index++) { ResolveLogicalGroup(result, index, viewLogicalGroups[index].Variable); } viewResourceLayouts.Add(hash, result); } return(result); }
public override void Prepare(RenderDrawContext context) { foreach (var data in Voxels.VoxelRenderer.renderVoxelVolumeDataList) { var view = data.ReprView; var viewFeature = view.Features[RootRenderFeature.Index]; var viewParameters = new ParameterCollection(); // Find a PerView layout from an effect in normal state ViewResourceGroupLayout firstViewLayout = null; foreach (var viewLayout in viewFeature.Layouts) { // Only process view layouts in normal state if (viewLayout.State != RenderEffectState.Normal) { continue; } var viewLighting = viewLayout.GetLogicalGroup(VoxelizerStorerCasterKey); if (viewLighting.Hash != ObjectId.Empty) { firstViewLayout = viewLayout; break; } } // Nothing found for this view (no effects in normal state) if (firstViewLayout == null) { continue; } var firstViewLighting = firstViewLayout.GetLogicalGroup(VoxelizerStorerCasterKey); // Prepare layout (should be similar for all PerView) { // Generate layout var viewParameterLayout = new ParameterCollectionLayout(); viewParameterLayout.ProcessLogicalGroup(firstViewLayout, ref firstViewLighting); viewParameters.UpdateLayout(viewParameterLayout); } ParameterCollection VSViewParameters = viewParameters; data.Storage.ApplyWriteParameters(VSViewParameters); foreach (var attr in data.Attributes) { attr.ApplyWriteParameters(VSViewParameters); } foreach (var viewLayout in viewFeature.Layouts) { if (viewLayout.State != RenderEffectState.Normal) { continue; } var voxelizerStorer = viewLayout.GetLogicalGroup(VoxelizerStorerCasterKey); if (voxelizerStorer.Hash == ObjectId.Empty) { continue; } if (voxelizerStorer.Hash != firstViewLighting.Hash) { throw new InvalidOperationException("PerView VoxelizerStorer layout differs between different RenderObject in the same RenderView"); } var resourceGroup = viewLayout.Entries[view.Index].Resources; resourceGroup.UpdateLogicalGroup(ref voxelizerStorer, VSViewParameters); } } }