public void CreateDeviceResources(GraphicsDevice gd, OutputDescription outputDescription, ColorSpaceHandling colorSpaceHandling) { _gd = gd; _colorSpaceHandling = colorSpaceHandling; ResourceFactory factory = gd.ResourceFactory; _vertexBuffer = factory.CreateBuffer(new BufferDescription(10000, BufferUsage.VertexBuffer | BufferUsage.Dynamic)); _vertexBuffer.Name = "ImGui.NET Vertex Buffer"; _indexBuffer = factory.CreateBuffer(new BufferDescription(2000, BufferUsage.IndexBuffer | BufferUsage.Dynamic)); _indexBuffer.Name = "ImGui.NET Index Buffer"; RecreateFontDeviceTexture(gd); _projMatrixBuffer = factory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic)); _projMatrixBuffer.Name = "ImGui.NET Projection Buffer"; byte[] vertexShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-vertex", ShaderStages.Vertex, _colorSpaceHandling); byte[] fragmentShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-frag", ShaderStages.Fragment, _colorSpaceHandling); _vertexShader = factory.CreateShader(new ShaderDescription(ShaderStages.Vertex, vertexShaderBytes, "VS")); _fragmentShader = factory.CreateShader(new ShaderDescription(ShaderStages.Fragment, fragmentShaderBytes, "FS")); VertexLayoutDescription[] vertexLayouts = new VertexLayoutDescription[] { new VertexLayoutDescription( new VertexElementDescription("in_position", VertexElementSemantic.Position, VertexElementFormat.Float2), new VertexElementDescription("in_texCoord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2), new VertexElementDescription("in_color", VertexElementSemantic.Color, VertexElementFormat.Byte4_Norm)) }; _layout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("ProjectionMatrixBuffer", ResourceKind.UniformBuffer, ShaderStages.Vertex), new ResourceLayoutElementDescription("MainSampler", ResourceKind.Sampler, ShaderStages.Fragment))); _textureLayout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("MainTexture", ResourceKind.TextureReadOnly, ShaderStages.Fragment))); GraphicsPipelineDescription pd = new GraphicsPipelineDescription( BlendStateDescription.SingleAlphaBlend, new DepthStencilStateDescription(false, false, ComparisonKind.Always), new RasterizerStateDescription(FaceCullMode.None, PolygonFillMode.Solid, FrontFace.Clockwise, true, true), PrimitiveTopology.TriangleList, new ShaderSetDescription( vertexLayouts, new[] { _vertexShader, _fragmentShader }, new[] { new SpecializationConstant(0, gd.IsClipSpaceYInverted), new SpecializationConstant(1, _colorSpaceHandling == ColorSpaceHandling.Legacy), }), new ResourceLayout[] { _layout, _textureLayout }, outputDescription, ResourceBindingModel.Default); _pipeline = factory.CreateGraphicsPipeline(ref pd); _mainResourceSet = factory.CreateResourceSet(new ResourceSetDescription(_layout, _projMatrixBuffer, gd.PointSampler)); _fontTextureResourceSet = factory.CreateResourceSet(new ResourceSetDescription(_textureLayout, _fontTextureView)); }
public void CreateDeviceResources(GraphicsDevice gd, CommandList cl, OutputDescription outputDescription) { _gd = gd; ResourceFactory factory = gd.ResourceFactory; _vertexBuffer = factory.CreateVertexBuffer(new BufferDescription(10000, true)); _indexBuffer = factory.CreateIndexBuffer(new IndexBufferDescription(2000, IndexFormat.UInt16, true)); RecreateFontDeviceTexture(gd, cl); _projMatrixBuffer = factory.CreateUniformBuffer(new BufferDescription(64)); byte[] vertexShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-vertex", ShaderStages.Vertex); byte[] fragmentShaderBytes = LoadEmbeddedShaderCode(gd.ResourceFactory, "imgui-frag", ShaderStages.Fragment); _vertexShader = factory.CreateShader(new ShaderDescription(ShaderStages.Vertex, vertexShaderBytes)); _fragmentShader = factory.CreateShader(new ShaderDescription(ShaderStages.Fragment, fragmentShaderBytes)); VertexLayoutDescription[] vertexLayouts = new VertexLayoutDescription[] { new VertexLayoutDescription( new VertexElementDescription("in_position", VertexElementSemantic.Position, VertexElementFormat.Float2), new VertexElementDescription("in_texCoord", VertexElementSemantic.TextureCoordinate, VertexElementFormat.Float2), new VertexElementDescription("in_color", VertexElementSemantic.Color, VertexElementFormat.Byte4)) }; ShaderStageDescription[] shaderStages = new ShaderStageDescription[] { new ShaderStageDescription(ShaderStages.Vertex, _vertexShader, "VS"), new ShaderStageDescription(ShaderStages.Fragment, _fragmentShader, "FS") }; _layout = factory.CreateResourceLayout(new ResourceLayoutDescription( new ResourceLayoutElementDescription("ProjectionMatrixBuffer", ResourceKind.Uniform, ShaderStages.Vertex), new ResourceLayoutElementDescription("FontTexture", ResourceKind.Texture, ShaderStages.Fragment), new ResourceLayoutElementDescription("FontSampler", ResourceKind.Sampler, ShaderStages.Fragment))); PipelineDescription pd = new PipelineDescription( BlendStateDescription.SingleAlphaBlend, new DepthStencilStateDescription(false, false, DepthComparisonKind.Always), new RasterizerStateDescription(FaceCullMode.None, TriangleFillMode.Solid, FrontFace.Clockwise, false, true), PrimitiveTopology.TriangleList, new ShaderSetDescription(vertexLayouts, shaderStages), new ResourceLayout[] { _layout }, outputDescription); _pipeline = factory.CreatePipeline(ref pd); _resourceSet = factory.CreateResourceSet(new ResourceSetDescription(_layout, _projMatrixBuffer, _fontTextureView, gd.PointSampler)); }
/// <summary> /// Constructs a new ComputePipelineDescription. /// </summary> /// <param name="shaderStage">The compute <see cref="Shader"/> to be used in the Pipeline. This must be a Shader with /// <see cref="ShaderStages.Compute"/>.</param> /// <param name="resourceLayout">The resource layout available to the Pipeline.</param> /// <param name="threadGroupSizeX">The X dimension of the thread group size.</param> /// <param name="threadGroupSizeY">The Y dimension of the thread group size.</param> /// <param name="threadGroupSizeZ">The Z dimension of the thread group size.</param> public ComputePipelineDescription( Shader shaderStage, ResourceLayout resourceLayout, uint threadGroupSizeX, uint threadGroupSizeY, uint threadGroupSizeZ) { ComputeShader = shaderStage; ResourceLayouts = new[] { resourceLayout }; ThreadGroupSizeX = threadGroupSizeX; ThreadGroupSizeY = threadGroupSizeY; ThreadGroupSizeZ = threadGroupSizeZ; }
/// <summary> /// Constructs a new ComputePipelineDescription. /// </summary> /// <param name="shaderStage">The compute <see cref="Shader"/> to be used in the Pipeline. This must be a Shader with /// <see cref="ShaderStages.Compute"/>.</param> /// <param name="resourceLayout">The resource layout available to the Pipeline.</param> /// <param name="threadGroupSizeX">The X dimension of the thread group size.</param> /// <param name="threadGroupSizeY">The Y dimension of the thread group size.</param> /// <param name="threadGroupSizeZ">The Z dimension of the thread group size.</param> /// <param name="specializations">An array of <see cref="SpecializationConstant"/> used to override specialization /// constants in the created <see cref="Pipeline"/>. Each element in this array describes a single ID-value pair, which /// will be matched with the constants specified in the <see cref="Shader"/>.</param> public ComputePipelineDescription( Shader shaderStage, ResourceLayout resourceLayout, uint threadGroupSizeX, uint threadGroupSizeY, uint threadGroupSizeZ, SpecializationConstant[] specializations) { ComputeShader = shaderStage; ResourceLayouts = new[] { resourceLayout }; ThreadGroupSizeX = threadGroupSizeX; ThreadGroupSizeY = threadGroupSizeY; ThreadGroupSizeZ = threadGroupSizeZ; Specializations = specializations; }
/// <summary> /// Constructs a new <see cref="GraphicsPipelineDescription"/>. /// </summary> /// <param name="blendState">A description of the blend state, which controls how color values are blended into each /// color target.</param> /// <param name="depthStencilStateDescription">A description of the depth stencil state, which controls depth tests, /// writing, and comparisons.</param> /// <param name="rasterizerState">A description of the rasterizer state, which controls culling, clipping, scissor, and /// polygon-fill behavior.</param> /// <param name="primitiveTopology">The <see cref="PrimitiveTopology"/> to use, which controls how a series of input /// vertices is interpreted by the <see cref="Pipeline"/>.</param> /// <param name="shaderSet">A description of the shader set to be used.</param> /// <param name="resourceLayout">A <see cref="ResourceLayout"/>, which controls the layout of shader resoruces in the /// <see cref="Pipeline"/>.</param> /// <param name="outputs">A description of the output attachments used by the <see cref="Pipeline"/>.</param> public GraphicsPipelineDescription( BlendStateDescription blendState, DepthStencilStateDescription depthStencilStateDescription, RasterizerStateDescription rasterizerState, PrimitiveTopology primitiveTopology, ShaderSetDescription shaderSet, ResourceLayout resourceLayout, OutputDescription outputs) { BlendState = blendState; DepthStencilState = depthStencilStateDescription; RasterizerState = rasterizerState; PrimitiveTopology = primitiveTopology; ShaderSet = shaderSet; ResourceLayouts = new[] { resourceLayout }; Outputs = outputs; }
/// <summary> /// Sets the active <see cref="ResourceSet"/> for the given index. This ResourceSet is only active for the compute /// Pipeline. /// </summary> /// <param name="slot">The resource slot.</param> /// <param name="rs">The new <see cref="ResourceSet"/>.</param> public void SetComputeResourceSet(uint slot, ResourceSet rs) { #if VALIDATE_USAGE if (_computePipeline == null) { throw new VeldridException($"A compute Pipeline must be active before {nameof(SetComputeResourceSet)} can be called."); } int layoutsCount = _computePipeline.ResourceLayouts.Length; if (layoutsCount <= slot) { throw new VeldridException( $"Failed to bind ResourceSet to slot {slot}. The active compute Pipeline only contains {layoutsCount} ResourceLayouts."); } ResourceLayout layout = _computePipeline.ResourceLayouts[slot]; int pipelineLength = layout.ResourceKinds.Length; int setLength = rs.Layout.ResourceKinds.Length; if (pipelineLength != setLength) { throw new VeldridException($"Failed to bind ResourceSet to slot {slot}. The number of resources in the ResourceSet ({setLength}) does not match the number expected by the active Pipeline ({pipelineLength})."); } for (int i = 0; i < pipelineLength; i++) { ResourceKind pipelineKind = layout.ResourceKinds[i]; ResourceKind setKind = rs.Layout.ResourceKinds[i]; if (pipelineKind != setKind) { throw new VeldridException( $"Failed to bind ResourceSet to slot {slot}. Resource element {i} was of the incorrect type. The bound Pipeline expects {pipelineKind}, but the ResourceSet contained {setKind}."); } } #endif SetComputeResourceSetCore(slot, rs); }
/// <summary> /// Constructs a new ResourceSetDescription. /// </summary> /// <param name="layout">The <see cref="ResourceLayout"/> describing the number and kind of resources used.</param> /// <param name="boundResources">An array of <see cref="BindableResource"/> objects. /// The number and type of resources must match those specified in the <see cref="ResourceLayout"/>.</param> public ResourceSetDescription(ResourceLayout layout, params BindableResource[] boundResources) { Layout = layout; BoundResources = boundResources; }
/// <summary> /// Constructs a new ComputePipelineDescription. /// </summary> /// <param name="shaderStage">The compute <see cref="Shader"/> to be used in the Pipeline. This must be a Shader with /// <see cref="ShaderStages.Compute"/>.</param> /// <param name="resourceLayout">The resource layout available to the Pipeline.</param> public ComputePipelineDescription(Shader shaderStage, ResourceLayout resourceLayout) { ComputeShader = shaderStage; ResourceLayouts = new[] { resourceLayout }; }