protected override void CreateRenderPath() { Add(new ShadowPass()); clustering = CreateClusteringPass(); Add(clustering); lightCull = new ComputePass(ComputeLight); Add(lightCull); mainPass = new FrameGraphPass { new AttachmentInfo(Graphics.ColorFormat), new AttachmentInfo(Graphics.DepthFormat) { //loadOp = VkAttachmentLoadOp.Load, storeOp = VkAttachmentStoreOp.Store }, new SceneSubpass("cluster_forward") { Set1 = resourceSet1, Set2 = resourceSet2, DisableDepthStencil = false } }; Add(mainPass); }
public ComputePass AddComputePass(Action <ComputePass, RenderContext, CommandBuffer> onDraw) { var renderPass = new ComputePass { OnDraw = onDraw, }; AddRenderPass(renderPass); return(renderPass); }
protected unsafe void ComputeLight(ComputePass renderPass, RenderContext rc, CommandBuffer cmd_buf) { tile_count_x = ((uint)View.ViewRect.extent.width - 1) / TILE_WIDTH + 1; tile_count_y = ((uint)View.ViewRect.extent.height - 1) / TILE_HEIGHT + 1; cmd_buf.ResetQueryPool(QueryPool, 4, 6); //cmd_buf.WriteTimestamp(PipelineStageFlags.TopOfPipe, QueryPool, QUERY_CALC_LIGHT_GRIDS * 2); VkBufferMemoryBarrier *barriers = stackalloc VkBufferMemoryBarrier[2]; barriers[0] = new VkBufferMemoryBarrier(light_pos_ranges.Buffer, VkAccessFlags.HostWrite, VkAccessFlags.ShaderRead); cmd_buf.PipelineBarrier(VkPipelineStageFlags.Host, VkPipelineStageFlags.ComputeShader, VkDependencyFlags.ByRegion, 0, null, 1, barriers, 0, null); // --------------------- calc light grids --------------------- // reads grid_flags, light_pos_ranges // writes light_bounds, grid_light_counts { var pass = clusterLight.Pass[0]; cmd_buf.BindComputePipeline(pass); cmd_buf.BindComputeResourceSet(pass.PipelineLayout, 1, computeSet0); cmd_buf.BindComputeResourceSet(pass.PipelineLayout, 2, computeSet1); cmd_buf.Dispatch((num_lights - 1) / 32 + 1, 1, 1); // cmd_buf.WriteTimestamp(PipelineStageFlags.ComputeShader, QueryPool, QUERY_CALC_LIGHT_GRIDS * 2 + 1); barriers[0] = new VkBufferMemoryBarrier(lightBounds, VkAccessFlags.ShaderRead | VkAccessFlags.ShaderWrite, VkAccessFlags.ShaderRead | VkAccessFlags.ShaderWrite); barriers[1] = barriers[0]; barriers[1].buffer = gridLightCounts; cmd_buf.PipelineBarrier(VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.ComputeShader, VkDependencyFlags.ByRegion, 0, null, 2, barriers, 0, null); } // --------------------- calc grid offsets --------------------- // reads grid_flags, grid_light_counts // writes grid_light_count_total, grid_light_offsets { // cmd_buf.WriteTimestamp(PipelineStageFlags.TopOfPipe, QueryPool, QUERY_CALC_GRID_OFFSETS * 2); var pass = clusterLight.Pass[1]; cmd_buf.BindComputePipeline(pass); cmd_buf.BindComputeResourceSet(pass.PipelineLayout, 1, computeSet0); cmd_buf.BindComputeResourceSet(pass.PipelineLayout, 2, computeSet1); cmd_buf.Dispatch((tile_count_x - 1) / 16 + 1, (tile_count_y - 1) / 16 + 1, TILE_COUNT_Z); // cmd_buf.WriteTimestamp(PipelineStageFlags.ComputeShader, QueryPool, QUERY_CALC_GRID_OFFSETS * 2 + 1); barriers[0].buffer = gridLightCountTotal; barriers[1].buffer = gridLightCountOffsets; cmd_buf.PipelineBarrier(VkPipelineStageFlags.ComputeShader, VkPipelineStageFlags.ComputeShader, VkDependencyFlags.ByRegion, 0, null, 1, barriers, 0, null); } // --------------------- calc light list --------------------- // reads grid_flags, light_bounds, grid_light_counts, grid_light_offsets // writes grid_light_counts_compare, light_list { // cmd_buf.WriteTimestamp(PipelineStageFlags.TopOfPipe, QueryPool, QUERY_CALC_LIGHT_LIST * 2); var pass = clusterLight.Pass[2]; cmd_buf.BindComputePipeline(pass); cmd_buf.BindComputeResourceSet(pass.PipelineLayout, 1, computeSet0); cmd_buf.BindComputeResourceSet(pass.PipelineLayout, 2, computeSet1); cmd_buf.Dispatch((num_lights - 1) / 32 + 1, 1, 1); // cmd_buf.WriteTimestamp(PipelineStageFlags.FragmentShader, QueryPool, QUERY_CALC_LIGHT_LIST * 2 + 1); } }
protected override void CreateRenderPath() { this.Add(new ShadowPass()); geometryPass = new FrameGraphPass(SubmitQueue.EarlyGraphics) { new AttachmentInfo("albedo", SizeHint.Full, VkFormat.R8G8B8A8UNorm, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Sampled), new AttachmentInfo("normal", SizeHint.Full, VkFormat.R8G8B8A8UNorm, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Sampled), new AttachmentInfo(depthTexture.format), new SceneSubpass("gbuffer") { Set1 = clusterSet1 } }; geometryPass.renderPassCreator = OnCreateRenderPass; this.Add(geometryPass); translucentClustering = this.CreateClusteringPass(); this.Add(translucentClustering); if (enableSSAO) { ssaoPass = new FrameGraphPass { new AttachmentInfo("ssao", SizeHint.Full, VkFormat.R8UNorm, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Sampled), new SSAOSubpass() }; this.Add(ssaoPass); ssaoBlur = new FrameGraphPass { new AttachmentInfo("ssao_blur", SizeHint.Full, VkFormat.R8UNorm, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Sampled), new SSAOBlurSubpass() }; this.Add(ssaoBlur); } lightCull = new ComputePass(ComputeLight); this.Add(lightCull); var specializationInfo = new SpecializationInfo(new VkSpecializationMapEntry(0, 0, sizeof(uint))); specializationInfo.Write(0, enableSSAO ? 1 : 0); compositePass = new FrameGraphPass { new AttachmentInfo("color", SizeHint.Full, VkFormat.R8G8B8A8UNorm, VkImageUsageFlags.ColorAttachment | VkImageUsageFlags.Sampled), new AttachmentInfo(depthTexture.format) { storeOp = VkAttachmentStoreOp.Store }, new FullScreenSubpass("shaders/glsl/cluster_deferred.frag", specializationInfo) {