Skip to content

render plan api plan

Matthew Egeler edited this page Dec 16, 2019 · 18 revisions

Implementation details:

  • A graffiks render pass can usually be a vulkan subpass
  • A graffiks render pass should sometimes be a full vulkan "render pass", such as if the pass has asked for an input that requires multiple pixel inputs from the previous pass for a given fragment in the new pass (this is a subpass limitation). This is required for things like blurring or ambient occlusion
  • Multiple graffiks render passes could actually become a single subpass if a set of render passes do not depend on eachother. This could potentially reduce overhead, but needs to be tested.

Notes:

  • Right now, our functions are "[set/def]shaderset_attr*" and are provided to the shaderset as a whole, basically assuming that the first shader are receiving the attributes. I feel like "[set/def]_shader_attr" that specifies a specific shader index within the set makes more sense.
  • Instead of accepting gfks_mesh objects, we could accept gfks_vertex_buffer objects. This would allow the user of the engine to manage vertex buffers, and prevent us from creating a separate vertex buffer for each mesh. Instead of accepting a mesh array, we could simply accept a single gfks_vertex_buffer. How different mesh topologies (such as VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST) play into this is TBD. We may want to support different meshes with different topo settings.
  • Regardless of dependency settings, the engine needs to put render passes into a linear order. Instead of constructing a dependency graph for this, we could simply require the user of the engine order them for us as well as define dependencies for multithreading/subpass dependency purposes. This would be faster, because we no longer need to spend cpu time determining the order -- and generally the user of the engine knows the static order, and compiles right into that order.
 // Create render plan objects                                                                                                                 
 gfks_render_plan *deferred_render_plan = gfks_create_render_plan(context);                                                                    
                                                                                                                                               
 gfks_render_pass *geometry_pass        = gfks_create_render_pass(context);                                                                    
 gfks_render_pass *diffuse_pass         = gfks_create_render_pass(context);                                                                    
 gfks_render_pass *specular_pass        = gfks_create_render_pass(context);                                                                    
 gfks_render_pass *composite_pass       = gfks_create_render_pass(context);                                                                    
                                                                                                                                               
 // Add passes to our plan (order does not matter)                                                                                             
 deferred_render_plan->add_render_pass(deferred_render_plan, geometry_pass);                                                                   
 deferred_render_plan->add_render_pass(deferred_render_plan, diffuse_pass);                                                                    
 deferred_render_plan->add_render_pass(deferred_render_plan, specular_pass);                                                                   
 deferred_render_plan->add_render_pass(deferred_render_plan, composite_pass);                                                                  
                                                                                                                                               
 // Define dependencies                                                                                                                        
 diffuse_pass->depends_on(diffuse_pass, geometry_pass);                                                                                        
 specular_pass->depends_on(specular_pass, geometry_pass);                                                                                      
 composite_pass->depends_on(composite_pass, diffuse_pass);                                                                                     
 composite_pass->depends_on(composite_pass, specular_pass);                                                                                    
                                                                                                                                               
 // Set up render pass info                                                                                                                    
 //                                                                                                                                            
 // def_shaderset_attr_* defines the existance of an input for a specified chain of shaders -                                                  
 // the 2nd arg is always the shaderset index within the pass info we want to feed this input to                                               
 // the 3nd arg is always an input index for the shader. The data type within the shader depends on the call.                                  
 uint32_t shaderset_index = diffuse_pass->add_shaderset(shaders);                                                                              
 diffuse_pass->def_shaderset_attr_vertex_location(diffuse_pass, shaderset_index, 0);                                                                    
 diffuse_pass->def_shaderset_attr_vertex_color(diffuse_pass, shaderset_index, 1);                                                        
 diffuse_pass->def_shaderset_attr_global_transformation_matrix(diffuse_pass, shaderset_index, 2);                                              
 diffuse_pass->def_shaderset_attr_mesh_transformation_matrix(diffuse_pass, shaderset_index, 3);                                                
 diffuse_pass->def_shaderset_attr_previous_pass(diffuse_pass, shaderset_index, 4, geometry_pass); // should error here if we don't have the dep
 // etc etc for other passes                                                                                                                   
                                                                                                                                               
 // Define the surface(s) that we want to be presented to                                                                                      
 deferred_render_plan->add_presentation_surface(deferred_render_plan, surface);                                                                
                                                                                                                                               
 // All done planning - finalize the plan!                                                                                                     
 deferred_render_plan->finalize_plan();                                                                                                        
 
 // Define meshes to draw
 diffuse_pass->set_draw_meshes_for_shader_set(diffuse_pass, shaderset_index, mesh_array);
 
 // Or, if we wanted to draw some arbitrary vertices not backed by a buffer
 diffuse_pass->set_arbitrary_vertex_count(diffuse_pass, 3);
                                                                                                                                           
 // Give our passes some input data                                                                                                            
 //                                                                                                                                            
 // set_shaderset_attr_* sets the value of a specified attr, and can be called any number of times                                             
 // 2nd arg is always the input index for the shader (we already have a unique ID, no need to make another)                                    
 diffuse_pass->set_shaderset_attr_vertex_color(diffuse_pass, 1, mesh_index, color_array);                                                
 diffuse_pass->set_shaderset_attr_global_transformation_matrix(diffuse_pass, 2, matrix);                                                       
 diffuse_pass->set_shaderset_attr_mesh_transformation_matrix(diffuse_pass, 3, mesh_index, matrix);
 diffuse_pass->apply_settings(diffuse_pass);                                         
 // etc etc for other passes                                                                                                                   
                                                                                                                                               
 // Draw loop                                                                                                                                  
 while (drawing frames) {                                                                                                                      
   deferred_render_plan.execute()                                                                                                              
 }                                                                                                                                             

Clone this wiki locally