Render_Pass_Handle :: #type, distinct u32; Pass_Buffer_Info :: struct { shader_type: Shader_Type; slot: u32; buffer: Buffer_Handle; } Render_Graph :: struct { temp_sampler: Sampler_Handle; render_passes: PArray(Render_Pass, Render_Pass_Handle); } new_render_graph :: () -> *Render_Graph { graph := New(Render_Graph); return graph; } execute_render_graph :: (graph: *Render_Graph) { for graph.render_passes { execute_render_pass(it); } } push_material_pass_properties :: (render_pass: Render_Pass, mat_pass: Material_Pass_Old) { for mat_pass.properties { if it.parameter.type == { case .BUFFER; push_cmd_set_constant_buffer(renderer, it.parameter.slot, it.buffer, it.parameter.shader); case .SAMPLER; push_cmd_set_sampler(renderer, it.parameter.slot, it.sampler); case .TEXTURE; { is_texture_input := false; input_index := 0; if it.parameter.mapping == { case .SHADER_ATTACHMENT0; is_texture_input = true; input_index = 0; case .SHADER_ATTACHMENT1; is_texture_input = true; input_index = 1; case .SHADER_ATTACHMENT2; is_texture_input = true; input_index = 2; case .SHADER_ATTACHMENT3; is_texture_input = true; input_index = 3; } if is_texture_input { input := render_pass.inputs[input_index]; owning_pass := parray_get(*engine.renderer.render_graph.render_passes, engine.input.pass_handle); if engine.input.rt_index == DEPTH_STENCIL_SLOT { push_cmd_set_texture(renderer, it.parameter.slot, owning_pass.depth_stencil); } else { push_cmd_set_texture(renderer, it.parameter.slot, owning_pass.render_targets[engine.input.rt_index]); } } else { if it.texture > 0 { push_cmd_set_texture(renderer, it.parameter.slot, it.texture); } } } } } } setup_pass_inputs :: (render_pass: Render_Pass) { for input: render_pass.inputs { owning_pass := parray_get(*engine.renderer.render_graph.render_passes, input.pass_handle); if input.rt_index == DEPTH_STENCIL_SLOT { push_cmd_set_texture(engine.renderer, xx it_index, owning_pass.depth_stencil); } else { push_cmd_set_texture(engine.renderer, xx it_index, owning_pass.render_targets[input.rt_index]); } } } set_render_pass_clear_color :: (rp: Render_Pass_Handle, input_index: s32, color: Color) { pass := parray_get(*engine.renderer.render_graph.render_passes, rp); pass.clear_colors[input_index] = color; } execute_render_pass :: (render_pass: Render_Pass) { // @Incomplete: Add command buffer as parameter if render_pass.render_targets.count == 0 { if render_pass.has_depth_stencil { push_cmd_set_render_targets(engine.renderer, depth_stencil_enabled=render_pass.has_depth_stencil, depth_stencil_buffer=render_pass.depth_stencil); push_cmd_clear_depth_stencil(engine.renderer, render_pass.depth_stencil, 1.0); width := ifx render_pass.width == SWAPCHAIN_SIZE then engine.renderer.render_target_width else render_pass.width; height := ifx render_pass.height == SWAPCHAIN_SIZE then engine.renderer.render_target_height else render_pass.height; push_cmd_set_viewport(engine.renderer, width, height); } else { assert(render_pass.uses_backbuffer); push_cmd_set_backbuffer(engine.renderer); color: Vector4; color.x = 0.0; color.y = 0.0; color.z = 0.0; color.w = 1.0; push_cmd_clear_backbuffer(engine.renderer, color); push_cmd_set_viewport(engine.renderer, xx engine.renderer.render_target_width, xx engine.renderer.render_target_height); } } else { width := render_pass.width; height := render_pass.height; if render_pass.width == SWAPCHAIN_SIZE { width = engine.renderer.render_target_width; } if render_pass.height == SWAPCHAIN_SIZE { height = engine.renderer.render_target_height; } push_cmd_set_render_targets(engine.renderer, ..render_pass.render_targets, render_pass.has_depth_stencil, render_pass.depth_stencil); push_cmd_set_viewport(engine.renderer, width, height); for render_pass.render_targets { push_cmd_clear_render_target(engine.renderer, it, render_pass.clear_colors[it_index]); } if render_pass.has_depth_stencil { push_cmd_clear_depth_stencil(engine.renderer, render_pass.depth_stencil, 1.0); } } // @NOCHECKIN Setup inputs! setup_pass_inputs(render_pass); render_pass.callback(render_pass); } #load "render_pass.jai";