/// <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); }
// Internal constructor internal Material(ShaderLayout layout, ShaderProgram program, MaterialInput input, MaterialOutput output) { // Assign objects Layout = layout; Program = program; Layout.IncRefCount(); Program.IncRefCount(); Input = input; Output = output; // Validate vertex inputs if (input.Vertices.Count > 0) { uint vmask = 0; foreach (var vd in input.Vertices) { if ((vmask & vd.LocationMask) != 0) { throw new ArgumentException("Duplicate vertex location in descriptions", nameof(input)); } vmask |= vd.LocationMask; } if (vmask != Layout.VertexLocationMask) { throw new ArgumentException( $"Missing vertex location in material descriptions ({vmask:X8} != {Layout.VertexLocationMask:X8})", nameof(input)); } } // Validate outputs if (output.BlendStates.Count != layout.FragmentOutputs.Count) { throw new ArgumentException("Output count mismatch", nameof(output)); } }