internal Renderer(RenderScene scene, Logger logger = null) { if (scene == null) { throw new ArgumentNullException(nameof(scene)); } this.scene = scene; this.specializationContainer = new SpecializationContainer(logger); this.pushDataContainer = new PushDataContainer( stages: ShaderStages.Vertex | ShaderStages.Fragment, logger); this.logger = logger; }
public Item( int order, bool depthClamp, bool depthBias, IInternalRenderObject renderObject, SpecializationContainer specializationContainer, PushDataContainer pushDataContainer, ShaderProgram vertProg, ShaderProgram fragProg, Device logicalDevice, string debugName = null) { this.order = order; this.renderObject = renderObject; this.specializationContainer = specializationContainer; this.pushDataContainer = pushDataContainer; this.depthClamp = depthClamp; this.depthBias = depthBias; this.debugName = debugName; vertModule = vertProg.CreateModule(logicalDevice); fragModule = fragProg.CreateModule(logicalDevice); }
internal static Pipeline CreatePipeline( Device logicalDevice, RenderPass renderpass, PipelineLayout layout, ShaderModule vertModule, ShaderModule fragModule, SpecializationContainer specializationContainer, bool depthClamp, bool depthBias, ReadOnlySpan <DeviceTexture> targets, IInternalRenderObject renderObject) { if (logicalDevice == null) { throw new ArgumentNullException(nameof(logicalDevice)); } if (renderpass == null) { throw new ArgumentNullException(nameof(renderpass)); } var shaderStages = new [] { new PipelineShaderStageCreateInfo( stage: ShaderStages.Vertex, module: vertModule, name: "main", specializationInfo: specializationContainer?.GetInfo()), new PipelineShaderStageCreateInfo( stage: ShaderStages.Fragment, module: fragModule, name: "main", specializationInfo: specializationContainer?.GetInfo()) }; var depthTest = new PipelineDepthStencilStateCreateInfo { DepthTestEnable = true, DepthWriteEnable = true, DepthCompareOp = CompareOp.LessOrEqual, DepthBoundsTestEnable = false, StencilTestEnable = false }; var rasterizer = new PipelineRasterizationStateCreateInfo( depthClampEnable: depthClamp, rasterizerDiscardEnable: false, polygonMode: PolygonMode.Fill, cullMode: CullModes.Back, frontFace: renderObject.GetFrontFace(), depthBiasEnable: depthBias, depthBiasConstantFactor: .1f, depthBiasSlopeFactor: 1.75f, lineWidth: 1f ); //Gather all the color targets and setup a blend-state for them ResizeArray <PipelineColorBlendAttachmentState> blendAttachments = new ResizeArray <PipelineColorBlendAttachmentState>(); for (int i = 0; i < targets.Length; i++) { if (!targets[i].DepthTexture) { blendAttachments.Add(new PipelineColorBlendAttachmentState( colorWriteMask: ColorComponents.All, blendEnable: false)); } } var blending = new PipelineColorBlendStateCreateInfo( attachments: blendAttachments.ToArray(), logicOpEnable: false ); var multisampleState = new PipelineMultisampleStateCreateInfo( rasterizationSamples: SampleCounts.Count1, sampleShadingEnable: false ); //Pass the viewport and scissor-rect as dynamic so we are not tied to swapchain size //the advantage is this is that we don't need to recreate the pipeline on swapchain //resize var dynamicState = new PipelineDynamicStateCreateInfo( DynamicState.Viewport, DynamicState.Scissor ); return(logicalDevice.CreateGraphicsPipeline(new GraphicsPipelineCreateInfo( layout: layout, renderPass: renderpass, subpass: 0, stages: shaderStages, inputAssemblyState: renderObject.GetInputAssemblyStateInfo(), vertexInputState: renderObject.GetVertexInputState(), rasterizationState: rasterizer, tessellationState: null, //Pass empty viewport and scissor-rect as we set them dynamically viewportState: new PipelineViewportStateCreateInfo(new Viewport(), new Rect2D()), multisampleState: multisampleState, depthStencilState: depthTest, colorBlendState: blending, dynamicState: dynamicState, flags: PipelineCreateFlags.None ))); }