Esempio n. 1
0
        internal static VkPipeline CreatePipeline(PipelineDescription desc, Renderer renderer, uint subpass,
                                                  out BuildStates buildState)
        {
            // Validate
            var rlayout = (renderer.MSAA != MSAA.X1) ? renderer.MSAALayout ! : renderer.Layout;

            if (!desc.IsComplete)
            {
                throw new InvalidOperationException("Cannot create a pipeline from an incomplete description");
            }
            if (desc.Shader !.IsDisposed)
            {
                throw new ObjectDisposedException("desc.Shader", "Cannot build a pipeline with a disposed shader");
            }
            var cacnt = rlayout.Subpasses[subpass].ColorCount;

            if (desc.AllColorBlends !.Length != 1 && (cacnt != desc.AllColorBlends.Length))
            {
                throw new InvalidOperationException("Invalid color blend count for pipeline");
            }
            var hasds = rlayout.Subpasses[subpass].DepthOffset.HasValue;

            if (!hasds && (desc.DepthStencil !.Value.DepthMode != DepthMode.None))
            {
                throw new InvalidOperationException(
                          "Cannot perform depth/stencil operations on non-depth/stencil subpass");
            }
            if (desc.Shader !.CheckCompatiblity(desc, renderer, subpass) is string shaderErr)
            {
                throw new InvalidOperationException($"Invalid shader for pipeline - {shaderErr}");
            }

            // Describe the color blends
            var cblends = (desc.AllColorBlends.Length != 1)
                                ? desc.AllColorBlends !
                                : Enumerable.Repeat((ColorBlendState)desc.SharedColorBlend !, (int)cacnt).ToArray();

            // Vertex info
            CalculateVertexInfo(desc.VertexDescriptions !, out var vertexAttrs, out var vertexBinds);

            // Create the build states
            buildState = new(
                cblends,
                desc.BlendConstants,
                (DepthStencilState)desc.DepthStencil !,
                (VertexInput)desc.VertexInput !,
                vertexBinds,
                vertexAttrs,
                (RasterizerState)desc.Rasterizer !
                );

            // Create the initial pipeline
            return(CreatePipeline(buildState, renderer, subpass, desc.Shader !.Layout, desc.Shader.Program));
        }
Esempio n. 2
0
        /// <summary>
        /// Create a new pipeline with the given description, for use in the given renderer and subpass.
        /// </summary>
        /// <param name="description">The description of the pipeline states to build into the pipeline.</param>
        /// <param name="renderer">The renderer to use the pipeline in.</param>
        /// <param name="subpass">The subpass index within the renderer to use the pipeline in.</param>
        public Pipeline(PipelineDescription description, Renderer renderer, uint subpass)
            : base(ResourceType.Pipeline)
        {
            // Create the pipeline handle
            Handle = CreatePipeline(description, renderer, subpass, out var cache);
            if (renderer.MSAALayout is not null)
            {
                BuildCache = cache;                 // Only save cache if we might rebuild from MSAA change
            }

            // Assign fields
            Layout = description.Shader !.Layout;
            Layout.IncRefCount();
            ShaderProgram = description.Shader.Program;
            ShaderProgram.IncRefCount();
            Renderer = renderer;
            Subpass  = subpass;

            // Assign values
            VertexBindingCount = (uint)cache.VertexBindings.Length;

            // Register to the renderer
            renderer.AddPipeline(this);
        }