#ifndef RENDER_GRAPH_H #define RENDER_GRAPH_H #include #include #include "gpu.h" typedef struct UIContextStruct UIContext; typedef struct HexContextStruct HexContext; typedef uint32_t RGResource; #define RG_RESOURCE_SWAPCHAIN UINT32_MAX typedef struct RGResourceUsageStruct { RGResource resource[MAX_FRAMES_IN_FLIGHT]; VkPipelineStageFlags stage; VkAccessFlags access; VkImageLayout layout; } RGResourceUsage; typedef enum { RG_NODE_INPUT = 0, RG_NODE_COMPUTE = 1, RG_NODE_RENDER = 2, RG_NODE_DISPLAY = 3, } RGNodeType; typedef void (*RGRecordFn)( VkCommandBuffer, void* userdata, RenderContext*, UIContext*, HexContext*, uint32_t image_index, uint32_t frame, double time); typedef struct RGBarrierStruct { VkImageMemoryBarrier barrier; VkPipelineStageFlags src_stage; VkPipelineStageFlags dst_stage; RGResource resource[MAX_FRAMES_IN_FLIGHT]; } RGBarrier; #define RG_MAX_NODES 64 #define RG_MAX_RESOURCES_PER_NODE 16 typedef struct RGNodeStruct { RGNodeType type; RGResourceUsage reads[RG_MAX_RESOURCES_PER_NODE]; uint32_t read_count; RGResourceUsage writes[RG_MAX_RESOURCES_PER_NODE]; uint32_t write_count; RGBarrier pre_barriers[RG_MAX_RESOURCES_PER_NODE]; uint32_t pre_barrier_count; RGRecordFn record; void* userdata; bool active; } RGNode; typedef struct RenderGraphStruct { RGNode nodes[RG_MAX_NODES]; uint32_t node_count; uint32_t topo_order[RG_MAX_NODES]; uint32_t topo_count; bool compiled; } RenderGraph; // Returns stable node handle (index). Copies reads/writes arrays internally. uint32_t render_graph_add_node( RenderGraph*, RGNodeType, RGResourceUsage* reads, uint32_t read_count, RGResourceUsage* writes, uint32_t write_count, RGRecordFn, void* userdata); // Permanent-node helpers — call once at startup from run_app. // Each registers the appropriate node with the correct callback and resource declarations. uint32_t render_graph_add_ui_compute_node(RenderGraph*); uint32_t render_graph_add_ui_composite_node(RenderGraph*); uint32_t render_graph_add_display_node(RenderGraph*); // Convenience: registers a camera's hex-draw RENDER node with correct resource declarations. struct CameraStruct; uint32_t render_graph_add_camera_node(RenderGraph*, struct CameraStruct*); void render_graph_remove_node(RenderGraph*, uint32_t handle); // Derives topo order and image barriers from declared resource usages. void render_graph_compile(RenderGraph*, UIContext* ui); // Records all nodes into their respective command buffers in topo order. // COMPUTE nodes → compute_cmd. RENDER/DISPLAY nodes → graphics_cmd. // Caller handles queue submit and semaphore chain. VkResult render_graph_execute( RenderGraph*, VkCommandBuffer graphics_cmd, VkCommandBuffer compute_cmd, RenderContext*, UIContext*, HexContext*, uint32_t image_index, double time); void render_graph_invalidate(RenderGraph*); #endif