Пример #1
0
        public RenderInfo GetPipelineAndResources(GraphicsDevice graphicsDevice, ResourceFactory resourceFactory, ResourceLayout vpLayout, Framebuffer framebuffer)
        {
            // TODO Cache this by device, factory
            var key = new Tuple <GraphicsDevice, ResourceFactory>(graphicsDevice, resourceFactory);

            if (RenderInfoCache.TryGetValue(key, out var ri))
            {
                return(ri);
            }

            ri = new RenderInfo();

            var resourceLayoutElementDescriptionList = new List <ResourceLayoutElementDescription> {
            };
            var bindableResourceList = new List <BindableResource>();

            GraphicsPipelineDescription pd = new GraphicsPipelineDescription();

            pd.PrimitiveTopology = PrimitiveTopology;

            var nDrawables = (uint)Elements.Count;

            var alignment = graphicsDevice.UniformBufferMinOffsetAlignment;

            var modelViewMatrixObjSizeInBytes = 64u;

            if (alignment > 64u)
            {
                modelViewMatrixObjSizeInBytes = alignment;
            }

            ri.UniformStrides.Add(modelViewMatrixObjSizeInBytes);

            ri.ModelViewBuffer =
                resourceFactory.CreateBuffer(new BufferDescription(modelViewMatrixObjSizeInBytes * nDrawables, BufferUsage.UniformBuffer | BufferUsage.Dynamic));

            resourceLayoutElementDescriptionList.Add(
                new ResourceLayoutElementDescription("Model", ResourceKind.UniformBuffer, ShaderStages.Vertex, ResourceLayoutElementOptions.DynamicBinding));

            //bindableResourceList.Add(ri.ModelViewBuffer);
            bindableResourceList.Add(new DeviceBufferRange(ri.ModelViewBuffer, 0, modelViewMatrixObjSizeInBytes));

            // Process Attached Textures
            foreach (var tex2d in PipelineState.TextureList)
            {
                var deviceTexture =
                    tex2d.ProcessedTexture.CreateDeviceTexture(graphicsDevice, resourceFactory,
                                                               TextureUsage.Sampled);
                var textureView =
                    resourceFactory.CreateTextureView(deviceTexture);

                resourceLayoutElementDescriptionList.Add(
                    new ResourceLayoutElementDescription(tex2d.TextureName, ResourceKind.TextureReadOnly,
                                                         ShaderStages.Fragment)
                    );
                resourceLayoutElementDescriptionList.Add(
                    new ResourceLayoutElementDescription(tex2d.SamplerName, ResourceKind.Sampler,
                                                         ShaderStages.Fragment)
                    );

                bindableResourceList.Add(textureView);
                bindableResourceList.Add(graphicsDevice.Aniso4xSampler);
            }

            foreach (var uniform in PipelineState.UniformList)
            {
                uniform.ConfigureDeviceBuffers(graphicsDevice, resourceFactory);

                resourceLayoutElementDescriptionList.Add(uniform.ResourceLayoutElementDescription);

                bindableResourceList.Add(uniform.DeviceBufferRange);

                if (uniform.ResourceLayoutElementDescription.Options == ResourceLayoutElementOptions.DynamicBinding)
                {
                    ri.UniformStrides.Add(uniform.DeviceBufferRange.SizeInBytes);
                }
            }

            ri.ResourceLayout = resourceFactory.CreateResourceLayout(
                new ResourceLayoutDescription(resourceLayoutElementDescriptionList.ToArray()));

            ri.ResourceSet = resourceFactory.CreateResourceSet(
                new ResourceSetDescription(
                    ri.ResourceLayout,
                    bindableResourceList.ToArray()
                    )
                );

            pd.BlendState        = PipelineState.BlendStateDescription;
            pd.DepthStencilState = PipelineState.DepthStencilState;
            pd.RasterizerState   = PipelineState.RasterizerStateDescription;

            // TODO - cache based on the shader description and reuse shader objects
            if (null != PipelineState.VertexShaderDescription && null != PipelineState.FragmentShaderDescription)
            {
                Shader[] shaders = resourceFactory.CreateFromSpirv(
                    PipelineState.VertexShaderDescription.Value,
                    PipelineState.FragmentShaderDescription.Value,
                    GetOptions(graphicsDevice, framebuffer)
                    );

                Shader vs = shaders[0];
                Shader fs = shaders[1];

                pd.ShaderSet = new ShaderSetDescription(
                    vertexLayouts: new VertexLayoutDescription[] { VertexLayout },
                    shaders: new Shader[] { vs, fs });
            }

            pd.ResourceLayouts = new[] { vpLayout, ri.ResourceLayout };

            pd.Outputs = framebuffer.OutputDescription;

            ri.Pipeline = resourceFactory.CreateGraphicsPipeline(pd);

            RenderInfoCache.Add(key, ri);

            return(ri);
        }
Пример #2
0
        public RenderInfo GetPipelineAndResources(GraphicsDevice graphicsDevice, ResourceFactory resourceFactory, ResourceLayout vpLayout)
        {
            // TODO Cache this by device, factory
            var key = new Tuple <GraphicsDevice, ResourceFactory>(graphicsDevice, resourceFactory);

            if (RenderInfoCache.TryGetValue(key, out var ri))
            {
                return(ri);
            }

            ri = new RenderInfo();

            var resourceLayoutElementDescriptionList = new List <ResourceLayoutElementDescription> {
            };
            var bindableResourceList = new List <BindableResource>();

            GraphicsPipelineDescription pd = new GraphicsPipelineDescription();

            pd.PrimitiveTopology = PrimitiveTopology;

//
// TODO - CASE 1 - implement this when Veldrid supports dynamic uniform buffers.
//
//            var nDrawables = (uint)Elements.Count;
//            ri.ModelBuffer =
//                resourceFactory.CreateBuffer(new BufferDescription(64*nDrawables, BufferUsage.UniformBuffer | BufferUsage.Dynamic));
//
//            var modelMatrixBuffer = new Matrix4x4[nDrawables];
//            for(var i=0; i<nDrawables; ++i)
//            {
//                modelMatrixBuffer[i] = Elements[i].ModelMatrix;
//            }

            // TODO - this shouldn't be allocated here!
            var modelMatrixBuffer = Matrix4x4.Identity;

            ri.ModelViewBuffer =
                resourceFactory.CreateBuffer(new BufferDescription(64, BufferUsage.UniformBuffer | BufferUsage.Dynamic));

            graphicsDevice.UpdateBuffer(ri.ModelViewBuffer, 0, modelMatrixBuffer);
            // TODO - this shouldn't be allocated here!

            resourceLayoutElementDescriptionList.Add(
                new ResourceLayoutElementDescription("Model", ResourceKind.UniformBuffer, ShaderStages.Vertex));

            bindableResourceList.Add(ri.ModelViewBuffer);

            // Process Attached Textures
            foreach (var tex2d in PipelineState.TextureList)
            {
                var deviceTexture =
                    tex2d.ProcessedTexture.CreateDeviceTexture(graphicsDevice, resourceFactory,
                                                               TextureUsage.Sampled);
                var textureView =
                    resourceFactory.CreateTextureView(deviceTexture);

                resourceLayoutElementDescriptionList.Add(
                    new ResourceLayoutElementDescription(tex2d.TextureName, ResourceKind.TextureReadOnly,
                                                         ShaderStages.Fragment)
                    );
                resourceLayoutElementDescriptionList.Add(
                    new ResourceLayoutElementDescription(tex2d.SamplerName, ResourceKind.Sampler,
                                                         ShaderStages.Fragment)
                    );

                bindableResourceList.Add(textureView);
                bindableResourceList.Add(graphicsDevice.Aniso4xSampler);
            }

            ri.ResourceLayout = resourceFactory.CreateResourceLayout(
                new ResourceLayoutDescription(resourceLayoutElementDescriptionList.ToArray()));

            ri.ResourceSet = resourceFactory.CreateResourceSet(
                new ResourceSetDescription(
                    ri.ResourceLayout,
                    bindableResourceList.ToArray()
                    )
                );

            pd.BlendState        = PipelineState.BlendStateDescription;
            pd.DepthStencilState = PipelineState.DepthStencilState;
            pd.RasterizerState   = PipelineState.RasterizerStateDescription;

            if (null != PipelineState.VertexShaderDescription && null != PipelineState.FragmentShaderDescription)
            {
                var vertexShaderProg   = resourceFactory.CreateShader(PipelineState.VertexShaderDescription.Value);
                var fragmentShaderProg = resourceFactory.CreateShader(PipelineState.FragmentShaderDescription.Value);

                pd.ShaderSet = new ShaderSetDescription(
                    vertexLayouts: new VertexLayoutDescription[] { VertexLayout },
                    shaders: new Shader[] { vertexShaderProg, fragmentShaderProg });
            }

            pd.ResourceLayouts = new[] { vpLayout, ri.ResourceLayout };

            pd.Outputs = graphicsDevice.SwapchainFramebuffer.OutputDescription;

            ri.Pipeline = resourceFactory.CreateGraphicsPipeline(pd);

            RenderInfoCache.Add(key, ri);

            return(ri);
        }