KhronosGroup / Vulkan-Samples

One stop solution for all Vulkan samples
Apache License 2.0
4.14k stars 617 forks source link

FI: Render Graph #436

Open TomAtkinsonArm opened 2 years ago

TomAtkinsonArm commented 2 years ago

What is the Problem?

vkb::CommandBuffer lazily creates resources and is sub-optimal due to its lack of contextual information. This leads to a reliance on the framework caching mechanisms. In some samples this may lead to resource leakage or incorrectly bound resources.

What is the proposed Solution?

For Samples to be more expressive and to align Vulkan Samples to industry standards I propose the creation of a two phase Render Graph. A build phase and an evaluation phase.

The Render Graph would need to own its own concepts of the render pipeline so that its build phase can optimally allocate resources, alias memory for larger post processing samples and reduce the amount of work needed in the evaluation phase.

This would align with Vulkans mentality of building things upfront to have optimal draw calls down the line. It would also significantly reduce the amount of work needed per frame where there hasnt been a need to rebuild the graph. Resources can also be created in parallel upfront. Passes can be reused in multiple samples and greatly simplified.

Some related discussion was carried out in #365

This is not to be used as an API sample. The best cases for this are performance samples and samples which contain techniques where rendering is not the priority but we still require optimal rendering calls for any scene in use.

Examples

API's similar to the Halcyon Renderer may work well in Vulkan Samples.


struct PassInput {};

struct PassOutput {
    ResourceHandle resource;
}

inline PassOutput some_render_pass(RenderGraph& graph, const PassInput &input) {
    auto resource_handle = graph.create_resource(); // create some global resource here

    PassOutput output{};
    output.resource = resource_handle;

    graph.add_pass("Some Render Technique", [=](ResourceTracker& tracker){

        // track read and writes for memory aliasing
        tracker.read(input.input_texture);
        tracker.write(output.resource);

        return [](CommandBuffer& command_bufferf){
            // execute commands here
            command_buffer.draw(3,1,0,0);
        }
    });

    return output;
};

Issues

TomAtkinsonArm commented 2 years ago

AMD Render Pipeline Shader generic Render Graph library will be released soon and can solve all major pain points of this proposal