rtengine/src/gfx/gfx_main.c
Kevin Trogant 5d988d15b7 give passes views instead of lists
A view is a collection of lists. This is useful for a shadow mapping
pass that generates more than one shadow map.
Each view would create lists of objects visible in one shadow map.
2024-05-07 08:12:45 +02:00

217 lines
10 KiB
C

#include <stdbool.h>
#include <string.h>
#define RT_DONT_DEFINE_RENDERER_GLOBAL
#include "gfx.h"
#include "renderer_api.h"
#include "runtime/config.h"
#include "runtime/dynamic_libs.h"
/* Attributes are used to bind buffers (or textures) to symbolic values.
* For example, an attribute might be bound to "CELL_GRID", which would be
* replaced with the (at the time of the invoke) grid buffer of the current
* world cell.
*/
rt_renderer_api g_renderer;
#ifndef RT_STATIC_LIB
static rt_dynlib _renderer_lib;
#endif
static bool _renderer_loaded = false;
RT_DLLEXPORT
RT_CVAR_S(rt_Renderer,
"Select the render backend. Available options: [vk, null], Default: vk",
"dx11");
extern rt_cvar rt_RenderViewArenaSize;
extern rt_cvar rt_RenderListPoolSize;
#ifdef RT_STATIC_LIB
extern void RT_RENDERER_API_FN(RegisterCVars)(void);
extern rt_result RT_RENDERER_API_FN(Init)(const rt_renderer_init_info *);
extern void RT_RENDERER_API_FN(Shutdown)(void);
extern unsigned int RT_RENDERER_API_FN(GetMaxFramesInFlight)(void);
extern void RT_RENDERER_API_FN(BeginFrame)(unsigned int);
extern void RT_RENDERER_API_FN(EndFrame)(unsigned int);
extern rt_pipeline_handle RT_RENDERER_API_FN(CompilePipeline)(const rt_pipeline_info *);
extern void RT_RENDERER_API_FN(DestroyPipeline)(rt_pipeline_handle);
extern rt_result RT_RENDERER_API_FN(AllocCommandBuffers)(uint32_t,
const rt_alloc_command_buffer_info *,
rt_command_buffer_handle *);
extern rt_result RT_RENDERER_API_FN(SubmitCommandBuffers)(rt_gpu_queue,
const rt_submit_command_buffers_info *);
extern rt_result RT_RENDERER_API_FN(CreateSemaphores)(uint32_t,
const rt_gpu_semaphore_info *,
rt_gpu_semaphore_handle *);
extern void RT_RENDERER_API_FN(DestroySemaphores)(uint32_t count, rt_gpu_semaphore_handle *);
extern uint64_t RT_RENDERER_API_FN(GetSemaphoreValue)(rt_gpu_semaphore_handle);
extern rt_gpu_semaphore_handle RT_RENDERER_API_FN(GetSwapchainAvailableSemaphore)(void);
extern rt_gpu_semaphore_handle RT_RENDERER_API_FN(GetRenderFinishedSemaphore)(void);
extern rt_result
RT_RENDERER_API_FN(CreateBuffers)(uint32_t, const rt_buffer_info *, rt_buffer_handle *);
extern void RT_RENDERER_API_FN(DestroyBuffers)(uint32_t, rt_buffer_handle *);
extern rt_render_graph_builder RT_RENDERER_API_FN(CreateRenderGraphBuilder)(void);
extern void RT_RENDERER_API_FN(DestroyRenderGraphBuilder)(rt_render_graph_builder *);
extern rt_result RT_RENDERER_API_FN(ExecuteRenderGraph)(rt_render_graph *);
extern void RT_RENDERER_API_FN(SubmitRenderView)(rt_render_graph *render_graph,
uint32_t pass_id,
rt_render_view view);
extern void RT_RENDERER_API_FN(ResetRenderGraph)(rt_render_graph *graph);
extern void RT_RENDERER_API_FN(CmdBeginPass)(rt_command_buffer_handle,
const rt_cmd_begin_pass_info *);
extern void RT_RENDERER_API_FN(CmdEndPass)(rt_command_buffer_handle);
extern void RT_RENDERER_API_FN(CmdTransitionRenderTarget)(rt_command_buffer_handle,
rt_render_target_handle,
rt_render_target_state);
extern void RT_RENDERER_API_FN(CmdFlushRenderTargetWrite)(rt_command_buffer_handle,
rt_render_target_handle);
extern void RT_RENDERER_API_FN(CmdBindPipeline)(rt_command_buffer_handle, rt_pipeline_handle);
extern void RT_RENDERER_API_FN(CmdBindVertexBuffers)(rt_command_buffer_handle,
uint32_t,
uint32_t,
const rt_buffer_handle *,
const uint64_t *);
extern void RT_RENDERER_API_FN(CmdDraw)(rt_command_buffer_handle, uint32_t, uint32_t);
#endif
extern rt_result InitRenderLists(void);
extern void ShutdownRenderLists(void);
extern void ResetRenderLists(void);
extern rt_result InitRenderViews(void);
extern void ShutdownRenderViews(void);
extern void ResetRenderViews(void);
static bool LoadRenderer(void) {
#if !defined(RT_STATIC_LIB)
#define RETRIEVE_SYMBOL(name, type) \
g_renderer.name = (type *)rtGetSymbol(_renderer_lib, "rtRen" #name); \
if (!g_renderer.name) { \
rtReportError("GFX", \
"Unable to retrieve renderer function %s from backend %s", \
#name, \
rt_Renderer.s); \
}
if (strcmp(rt_Renderer.s, "vk") == 0) {
_renderer_lib = rtOpenLib(RT_DLLNAME("rtvk"));
if (!_renderer_lib) {
rtReportError("GFX", "Unable to load renderer backend: %s", RT_DLLNAME("rtvk"));
return false;
}
RETRIEVE_SYMBOL(RegisterCVars, rt_register_renderer_cvars_fn);
RETRIEVE_SYMBOL(Init, rt_init_renderer_fn);
RETRIEVE_SYMBOL(Shutdown, rt_shutdown_renderer_fn);
RETRIEVE_SYMBOL(GetMaxFramesInFlight, rt_get_max_frames_in_flight_fn);
RETRIEVE_SYMBOL(BeginFrame, rt_begin_frame_fn);
RETRIEVE_SYMBOL(EndFrame, rt_end_frame_fn);
RETRIEVE_SYMBOL(CompilePipeline, rt_compile_pipeline_fn);
RETRIEVE_SYMBOL(DestroyPipeline, rt_destroy_pipeline_fn);
RETRIEVE_SYMBOL(AllocCommandBuffers, rt_alloc_command_buffers_fn);
RETRIEVE_SYMBOL(SubmitCommandBuffers, rt_submit_command_buffers_fn);
RETRIEVE_SYMBOL(CreateBuffers, rt_create_buffers_fn);
RETRIEVE_SYMBOL(DestroyBuffers, rt_destroy_buffers_fn);
RETRIEVE_SYMBOL(CreateRenderGrapbuilder, rt_create_render_graph_builder_fn);
RETRIEVE_SYMBOL(DestroyRenderGraphBuilder, rt_destroy_render_graph_builder_fn);
RETRIEVE_SYMBOL(ExecuteRenderGraph, rt_execute_render_graph_fn);
RETRIEVE_SYMBOL(SubmitRenderView, rt_submit_render_view_fn);
RETRIEVE_SYMBOL(ResetRenderGraph, rt_reset_render_graph_fn);
RETRIEVE_SYMBOL(CmdBeginPass, rt_cmd_begin_pass_fn);
RETRIEVE_SYMBOL(CmdEndPass, rt_cmd_end_pass_fn);
RETRIEVE_SYMBOL(CmdTransitionRenderTarget, rt_cmd_transition_render_target_fn);
RETRIEVE_SYMBOL(CmdFlushRenderTargetWrite, rt_cmd_flush_render_target_write_fn);
RETRIEVE_SYMBOL(CmdBindPipeline, rt_cmd_bind_pipeline_fn);
RETRIEVE_SYMBOL(CmdBindVertexBuffers, rt_cmd_bind_vertex_buffers_fn);
RETRIEVE_SYMBOL(CmdDraw, rt_cmd_draw_fn);
} else {
rtReportError("GFX",
"Unsupported renderer backend: (%s) %s",
rt_Renderer.name,
rt_Renderer.s);
return false;
}
#undef RETRIEVE_SYMBOL
#else
g_renderer.RegisterCVars = &rtRenRegisterCVars;
g_renderer.Init = &rtRenInit;
g_renderer.Shutdown = &rtRenShutdown;
g_renderer.GetMaxFramesInFlight = &rtRenGetMaxFramesInFlight;
g_renderer.BeginFrame = &rtRenBeginFrame;
g_renderer.EndFrame = &rtRenEndFrame;
g_renderer.CompilePipeline = &rtRenCompilePipeline;
g_renderer.DestroyPipeline = &rtRenDestroyPipeline;
g_renderer.AllocCommandBuffers = &rtRenAllocCommandBuffers;
g_renderer.SubmitCommandBuffers = &rtRenSubmitCommandBuffers;
g_renderer.CreateBuffers = &rtRenCreateBuffers;
g_renderer.DestroyBuffers = &rtRenDestroyBuffers;
g_renderer.CreateRenderGraphBuilder = &rtRenCreateRenderGraphBuilder;
g_renderer.DestroyRenderGraphBuilder = &rtRenDestroyRenderGraphBuilder;
g_renderer.ExecuteRenderGraph = &rtRenExecuteRenderGraph;
g_renderer.SubmitRenderView = &rtRenSubmitRenderView;
g_renderer.ResetRenderGraph = &rtRenResetRenderGraph;
g_renderer.CmdBeginPass = &rtRenCmdBeginPass;
g_renderer.CmdEndPass = &rtRenCmdEndPass;
g_renderer.CmdTransitionRenderTarget = &rtRenCmdTransitionRenderTarget;
g_renderer.CmdFlushRenderTargetWrite = &rtRenCmdFlushRenderTargetWrite;
g_renderer.CmdBindPipeline = &rtRenCmdBindPipeline;
g_renderer.CmdBindVertexBuffers = &rtRenCmdBindVertexBuffers;
g_renderer.CmdDraw = &rtRenCmdDraw;
#endif
return true;
}
RT_DLLEXPORT void rtRegisterRendererCVars(void) {
if (!_renderer_loaded) {
if (!LoadRenderer())
return;
_renderer_loaded = true;
}
g_renderer.RegisterCVars();
}
RT_DLLEXPORT rt_result rtInitGFX(rt_renderer_init_info *renderer_info) {
rtRegisterCVAR(&rt_Renderer);
rtRegisterCVAR(&rt_RenderViewArenaSize);
rtRegisterCVAR(&rt_RenderListPoolSize);
if (!_renderer_loaded) {
if (!LoadRenderer())
return RT_UNKNOWN_ERROR;
g_renderer.RegisterCVars();
}
rt_result result;
if ((result = g_renderer.Init(renderer_info)) != RT_SUCCESS)
return result;
if ((result = InitRenderLists()) != RT_SUCCESS)
return result;
if ((result = InitRenderViews()) != RT_SUCCESS)
return result;
return result;
}
RT_DLLEXPORT void rtShutdownGFX(void) {
ShutdownRenderViews();
ShutdownRenderLists();
g_renderer.Shutdown();
}
RT_DLLEXPORT void rtBeginGFXFrame(unsigned int frame_id) {
g_renderer.BeginFrame(frame_id);
}
RT_DLLEXPORT void rtEndGFXFrame(unsigned int frame_id) {
g_renderer.EndFrame(frame_id);
ResetRenderLists();
ResetRenderViews();
}