{"id":13699652,"url":"https://github.com/acdemiralp/fg","last_synced_at":"2025-05-04T16:35:33.872Z","repository":{"id":44687062,"uuid":"118976540","full_name":"acdemiralp/fg","owner":"acdemiralp","description":"Rendering abstraction which describes a frame as a directed acyclic graph of render tasks and resources.","archived":false,"fork":false,"pushed_at":"2019-04-17T20:45:49.000Z","size":1081,"stargazers_count":534,"open_issues_count":1,"forks_count":58,"subscribers_count":47,"default_branch":"develop","last_synced_at":"2024-08-03T20:05:11.076Z","etag":null,"topics":["abstraction","cpp17","frame","graph","rendering"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/acdemiralp.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":"license.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2018-01-25T22:46:00.000Z","updated_at":"2024-08-01T05:00:22.000Z","dependencies_parsed_at":"2022-08-03T18:15:28.318Z","dependency_job_id":null,"html_url":"https://github.com/acdemiralp/fg","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acdemiralp%2Ffg","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acdemiralp%2Ffg/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acdemiralp%2Ffg/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/acdemiralp%2Ffg/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/acdemiralp","download_url":"https://codeload.github.com/acdemiralp/fg/tar.gz/refs/heads/develop","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224398825,"owners_count":17304661,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["abstraction","cpp17","frame","graph","rendering"],"created_at":"2024-08-02T20:00:40.581Z","updated_at":"2024-11-13T05:31:58.495Z","avatar_url":"https://github.com/acdemiralp.png","language":"C++","funding_links":[],"categories":["C++","**Code**","Graphics"],"sub_categories":[],"readme":"**What is a framegraph?** \n\nA rendering abstraction which describes a frame as a directed acyclic graph of render tasks and resources.\nBased on the [Game Developers Conference (GDC) presentation by Yuriy O’Donnell](https://www.gdcvault.com/play/1024612/FrameGraph-Extensible-Rendering-Architecture-in).\n\n**What is a render task?** \n\nA compute or graphics task to be performed as part of a rendering pipeline.\n\n**What is a resource?** \n\nData created, read or written by a render task. Alternates between two states; virtual and real.\nWhile virtual, the resource is not instantiated but contains the necessary information to do so. \nWhile real, the resource is instantiated and ready for use.\nA **transient** resource is owned, realized and virtualized by the framegraph.\nA **retained** resource is always real and is imported into the framegraph.\n\n**Usage**\n\nFirst, create descriptions for your rendering resources (e.g. buffers, textures) and declare them as framegraph resources.\n```cxx\nstruct buffer_description\n{\n  std::size_t size;\n};\nstruct texture_description\n{\n  std::size_t                levels;\n  GLenum                     format;\n  std::array\u003cstd::size_t, 3\u003e size  ;\n};\n\nusing buffer_resource     = fg::resource\u003cbuffer_description , gl::buffer    \u003e;\nusing texture_1d_resource = fg::resource\u003ctexture_description, gl::texture_1d\u003e;\nusing texture_2d_resource = fg::resource\u003ctexture_description, gl::texture_2d\u003e;\nusing texture_3d_resource = fg::resource\u003ctexture_description, gl::texture_3d\u003e;\n```\n\nThen, specialize `fg::realize\u003cdescription_type, actual_type\u003e` for each declared resource. This function takes in a resource description and returns an actual resource.\n```cxx\nnamespace fg\n{\ntemplate\u003c\u003e\nstd::unique_ptr\u003cgl::buffer\u003e     realize(const buffer_description\u0026  description)\n{\n  auto actual = std::make_unique\u003cgl::buffer\u003e(); \n  actual-\u003eset_size(static_cast\u003cGLsizeiptr\u003e(description.size));\n  return actual;\n}\ntemplate\u003c\u003e\nstd::unique_ptr\u003cgl::texture_2d\u003e realize(const texture_description\u0026 description)\n{\n  auto actual = std::make_unique\u003cgl::texture_2d\u003e();\n  actual-\u003eset_storage(\n    description.levels , \n    description.format , \n    description.size[0], \n    description.size[1]);\n  return actual;\n}\n}\n```\n\nYou are now ready to create a framegraph and add your render tasks / retained resources to it.\n```cxx\nfg::framegraph framegraph;\n\ngl::texture_2d backbuffer;\nauto retained_resource = framegraph.add_retained_resource(\n  \"Backbuffer\", \n  texture_description(), \n  \u0026backbuffer);\n\nstruct render_task_data\n{\n  texture_2d_resource* input1;\n  texture_2d_resource* input2;\n  texture_2d_resource* input3;\n  texture_2d_resource* output;\n};\nauto render_task = framegraph.add_render_task\u003crender_task_data\u003e(\n  \"Render Task\",\n  [\u0026] (render_task_data\u0026 data, fg::render_task_builder\u0026 builder)\n  {\n    data.input1 = builder.create\u003ctexture_2d_resource\u003e(\"Texture 1\", texture_description());\n    data.input2 = builder.create\u003ctexture_2d_resource\u003e(\"Texture 2\", texture_description());\n    data.input3 = builder.create\u003ctexture_2d_resource\u003e(\"Texture 3\", texture_description());\n    data.output = builder.write \u003ctexture_2d_resource\u003e(retained_resource);\n  },\n  [=] (const render_task_data\u0026 data)\n  {\n    auto actual1 = data.input1-\u003eactual();\n    auto actual2 = data.input2-\u003eactual();\n    auto actual3 = data.input3-\u003eactual();\n    auto actual4 = data.output-\u003eactual();\n    // Perform actual rendering. You may load resources from CPU by capturing them.\n  });\n\nauto\u0026 data = render_task-\u003edata();\n```\n\nOnce all render tasks and resources are added, call `framegraph.compile()`. Then, `framegraph.execute()` in each update. It is also possible to export to GraphViz for debugging / visualization via `framegraph.export_graphviz(filename)`:\n\n![alt text](https://github.com/acdemiralp/fg/blob/develop/docs/images/example.png \"Example 1\")\n\n![alt text](https://github.com/acdemiralp/fg/blob/develop/docs/images/example2.png \"Example 2\")\n\n**Next Steps** \n- Asynchronous render tasks (+ resource / aliasing barriers).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facdemiralp%2Ffg","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Facdemiralp%2Ffg","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Facdemiralp%2Ffg/lists"}