public void BindResources(CommandList commandList, DescriptorSet[] descriptorSets) { for (int setIndex = 0; setIndex < descriptorSetBindings.Length; setIndex++) { var bindingOperations = descriptorSetBindings[setIndex]; if (bindingOperations == null) continue; var descriptorSet = descriptorSets[setIndex]; var bindingOperation = Interop.Pin(ref bindingOperations[0]); for (int index = 0; index < bindingOperations.Length; index++, bindingOperation = Interop.IncrementPinned(bindingOperation)) { var value = descriptorSet.HeapObjects[descriptorSet.DescriptorStartOffset + bindingOperation.EntryIndex]; switch (bindingOperation.Class) { case EffectParameterClass.ConstantBuffer: { //commandList.SetConstantBuffer(bindingOperation.Stage, bindingOperation.SlotStart, (Buffer)value.Value); commandList.SetConstantBuffer(bindingOperation.Stage, bindingOperation.SlotStart, (Buffer)value.Value); break; } case EffectParameterClass.Sampler: { commandList.SetSamplerState(bindingOperation.Stage, bindingOperation.SlotStart, bindingOperation.ImmutableSampler ?? (SamplerState)value.Value); break; } case EffectParameterClass.ShaderResourceView: { commandList.SetShaderResourceView(bindingOperation.Stage, bindingOperation.SlotStart, (GraphicsResource)value.Value); break; } case EffectParameterClass.UnorderedAccessView: { commandList.SetUnorderedAccessView(bindingOperation.Stage, bindingOperation.SlotStart, (GraphicsResource)value.Value); break; } default: throw new ArgumentOutOfRangeException(); } } } }
public void PrepareResourceGroup(ResourceGroupLayout resourceGroupLayout, BufferPoolAllocationType constantBufferAllocationType, ResourceGroup resourceGroup) { if (resourceGroup == null) { throw new InvalidOperationException(); } resourceGroup.DescriptorSet = DescriptorSet.New(graphicsDevice, currentDescriptorPool, resourceGroupLayout.DescriptorSetLayout); if (!resourceGroup.DescriptorSet.IsValid) { SetupNextDescriptorPool(); resourceGroup.DescriptorSet = DescriptorSet.New(graphicsDevice, currentDescriptorPool, resourceGroupLayout.DescriptorSetLayout); } if (resourceGroupLayout.ConstantBufferSize > 0) { if (currentBufferPool == null || !currentBufferPool.CanAllocate(resourceGroupLayout.ConstantBufferSize)) { SetupNextBufferPool(); } currentBufferPool.Allocate(graphicsDevice, resourceGroupLayout.ConstantBufferSize, constantBufferAllocationType, ref resourceGroup.ConstantBuffer); } }
/// <inheritdoc/> public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex) { var commandList = context.CommandList; foreach (var renderFeature in RenderFeatures) { renderFeature.Draw(context, renderView, renderViewStage, startIndex, endIndex); } var descriptorSets = new DescriptorSet[EffectDescriptorSetSlotCount]; MeshDraw currentDrawData = null; for (int index = startIndex; index < endIndex; index++) { var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode; var renderNode = GetRenderNode(renderNodeReference); var renderMesh = (RenderMesh)renderNode.RenderObject; var drawData = renderMesh.ActiveMeshDraw; // Get effect // TODO: Use real effect slot var renderEffect = renderNode.RenderEffect; if (renderEffect.Effect == null) continue; // Bind VB if (currentDrawData != drawData) { for (int i = 0; i < drawData.VertexBuffers.Length; i++) { var vertexBuffer = drawData.VertexBuffers[i]; commandList.SetVertexBuffer(i, vertexBuffer.Buffer, vertexBuffer.Offset, vertexBuffer.Stride); } if (drawData.IndexBuffer != null) commandList.SetIndexBuffer(drawData.IndexBuffer.Buffer, drawData.IndexBuffer.Offset, drawData.IndexBuffer.Is32Bit); currentDrawData = drawData; } var resourceGroupOffset = ComputeResourceGroupOffset(renderNodeReference); // Update cbuffer renderEffect.Reflection.BufferUploader.Apply(context.CommandList, ResourceGroupPool, resourceGroupOffset); // Bind descriptor sets for (int i = 0; i < descriptorSets.Length; ++i) { var resourceGroup = ResourceGroupPool[resourceGroupOffset++]; if (resourceGroup != null) descriptorSets[i] = resourceGroup.DescriptorSet; } commandList.SetPipelineState(renderEffect.PipelineState); commandList.SetDescriptorSets(0, descriptorSets); // Draw if (drawData.IndexBuffer == null) { commandList.Draw(drawData.DrawCount, drawData.StartLocation); } else { commandList.DrawIndexed(drawData.DrawCount, drawData.StartLocation); } } }
public void SetDescriptorSets(int index, DescriptorSet[] descriptorSets) { for (int i = 0; i < descriptorSets.Length; ++i) { currentDescriptorSets[index++] = descriptorSets[i]; } }
public void SetDescriptorSets(int index, DescriptorSet[] descriptorSets) { RestartWithNewHeap: NativeCommandList.SetDescriptorHeaps(2, descriptorHeaps); var descriptorTableIndex = 0; for (int i = 0; i < descriptorSets.Length; ++i) { // Find what is already mapped var descriptorSet = descriptorSets[i]; var srvBindCount = boundPipelineState.SrvBindCounts[i]; var samplerBindCount = boundPipelineState.SamplerBindCounts[i]; if (srvBindCount > 0 && (IntPtr)descriptorSet.SrvStart.Ptr != IntPtr.Zero) { GpuDescriptorHandle gpuSrvStart; // Check if we need to copy them to shader visible descriptor heap if (!srvMapping.TryGetValue(descriptorSet.SrvStart.Ptr, out gpuSrvStart)) { var srvCount = descriptorSet.Description.SrvCount; // Make sure heap is big enough if (srvHeapOffset + srvCount > GraphicsDevice.SrvHeapSize) { ResetSrvHeap(true); goto RestartWithNewHeap; } // Copy NativeDevice.CopyDescriptorsSimple(srvCount, srvHeap.CPUDescriptorHandleForHeapStart + srvHeapOffset * GraphicsDevice.SrvHandleIncrementSize, descriptorSet.SrvStart, DescriptorHeapType.ConstantBufferViewShaderResourceViewUnorderedAccessView); // Store mapping srvMapping.Add(descriptorSet.SrvStart.Ptr, gpuSrvStart = srvHeap.GPUDescriptorHandleForHeapStart + srvHeapOffset * GraphicsDevice.SrvHandleIncrementSize); // Bump srvHeapOffset += srvCount; } // Bind resource tables (note: once per using stage, until we solve how to choose shader registers effect-wide at compile time) for (int j = 0; j < srvBindCount; ++j) NativeCommandList.SetGraphicsRootDescriptorTable(descriptorTableIndex++, gpuSrvStart); } if (samplerBindCount > 0 && (IntPtr)descriptorSet.SamplerStart.Ptr != IntPtr.Zero) { GpuDescriptorHandle gpuSamplerStart; // Check if we need to copy them to shader visible descriptor heap if (!samplerMapping.TryGetValue(descriptorSet.SamplerStart.Ptr, out gpuSamplerStart)) { var samplerCount = descriptorSet.Description.SamplerCount; // Make sure heap is big enough if (samplerHeapOffset + samplerCount > GraphicsDevice.SamplerHeapSize) { ResetSamplerHeap(true); goto RestartWithNewHeap; } // Copy NativeDevice.CopyDescriptorsSimple(samplerCount, samplerHeap.CPUDescriptorHandleForHeapStart + samplerHeapOffset * GraphicsDevice.SamplerHandleIncrementSize, descriptorSet.SamplerStart, DescriptorHeapType.Sampler); // Store mapping samplerMapping.Add(descriptorSet.SamplerStart.Ptr, gpuSamplerStart = samplerHeap.GPUDescriptorHandleForHeapStart + samplerHeapOffset * GraphicsDevice.SamplerHandleIncrementSize); // Bump samplerHeapOffset += samplerCount; } // Bind resource tables (note: once per using stage, until we solve how to choose shader registers effect-wide at compile time) for (int j = 0; j < samplerBindCount; ++j) NativeCommandList.SetGraphicsRootDescriptorTable(descriptorTableIndex++, gpuSamplerStart); } } }
public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex) { var commandList = context.CommandList; var descriptorSets = new DescriptorSet[EffectDescriptorSetSlotCount]; for (int index = startIndex; index < endIndex; index++) { var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode; var renderNode = GetRenderNode(renderNodeReference); // Get effect // TODO: Use real effect slot var renderEffect = renderNode.RenderEffect; if (renderEffect.Effect == null) continue; commandList.SetPipelineState(renderEffect.PipelineState); var resourceGroupOffset = ComputeResourceGroupOffset(renderNodeReference); renderEffect.Reflection.BufferUploader.Apply(context.CommandList, ResourceGroupPool, resourceGroupOffset); // Bind descriptor sets for (int i = 0; i < descriptorSets.Length; ++i) { var resourceGroup = ResourceGroupPool[resourceGroupOffset++]; if (resourceGroup != null) descriptorSets[i] = resourceGroup.DescriptorSet; } commandList.SetDescriptorSets(0, descriptorSets); commandList.DrawQuad(); } }
/// <inheritdoc/> public override void Draw(RenderDrawContext context, RenderView renderView, RenderViewStage renderViewStage, int startIndex, int endIndex) { var commandList = context.CommandList; // TODO: PerView data Matrix viewInverse; Matrix.Invert(ref renderView.View, out viewInverse); var descriptorSets = new DescriptorSet[EffectDescriptorSetSlotCount]; for (var index = startIndex; index < endIndex; index++) { var renderNodeReference = renderViewStage.SortedRenderNodes[index].RenderNode; var renderNode = GetRenderNode(renderNodeReference); var renderParticleEmitter = (RenderParticleEmitter)renderNode.RenderObject; if (renderParticleEmitter.ParticleEmitter.VertexBuilder.ResourceContext == null) continue; // Generate vertices // TODO: Just just unmap/barrier here renderParticleEmitter.ParticleEmitter.BuildVertexBuffer(context.CommandList, ref viewInverse); // Get effect var renderEffect = renderNode.RenderEffect; if (renderEffect.Effect == null) continue; // TODO GRAPHICS REFACTOR: Extract data var particleSystemComponent = renderParticleEmitter.RenderParticleSystem.ParticleSystemComponent; var particleSystem = particleSystemComponent.ParticleSystem; var vertexBuilder = renderParticleEmitter.ParticleEmitter.VertexBuilder; // Bind VB var vertexBuffer = vertexBuilder.ResourceContext.VertexBuffer; var indexBuffer = vertexBuilder.ResourceContext.IndexBuffer; commandList.SetVertexBuffer(0, vertexBuffer.Buffer, vertexBuffer.Offset, vertexBuffer.Stride); commandList.SetIndexBuffer(indexBuffer.Buffer, indexBuffer.Offset, indexBuffer.Is32Bit); var resourceGroupOffset = ComputeResourceGroupOffset(renderNodeReference); // Update cbuffer renderEffect.Reflection.BufferUploader.Apply(context.CommandList, ResourceGroupPool, resourceGroupOffset); // Bind descriptor sets for (int i = 0; i < descriptorSets.Length; ++i) { var resourceGroup = ResourceGroupPool[resourceGroupOffset++]; if (resourceGroup != null) descriptorSets[i] = resourceGroup.DescriptorSet; } commandList.SetPipelineState(renderEffect.PipelineState); commandList.SetDescriptorSets(0, descriptorSets); commandList.DrawIndexed(vertexBuilder.LivingQuads * vertexBuilder.IndicesPerQuad, vertexBuilder.ResourceContext.IndexBufferPosition); } }