rtengine/src/runtime/gfx_main.c
2024-01-16 16:10:56 +01:00

96 lines
3.4 KiB
C

#include <string.h>
#define RT_DONT_DEFINE_RENDERER_GLOBAL
#include "config.h"
#include "dynamic_libs.h"
#include "gfx.h"
#include "renderer_api.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;
static rt_dynlib _renderer_lib;
static bool _renderer_loaded = false;
RT_CVAR_S(rt_Renderer, "Select the render backend. Available options: [vk], Default: vk", "vk");
#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 rt_pipeline_handle RT_RENDERER_API_FN(CompilePipeline)(const rt_pipeline_info *);
extern void RT_RENDERER_API_FN(DestroyPipeline)(rt_pipeline_handle handle);
#endif
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(CompilePipeline, rt_compile_pipeline_fn);
RETRIEVE_SYMBOL(DestroyPipeline, rt_destroy_pipeline_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.CompilePipeline = &rtRenCompilePipeline;
g_renderer.DestroyPipeline = &rtRenDestroyPipeline;
#endif
return true;
}
RT_DLLEXPORT void rtRegisterRendererCVars(void) {
if (!_renderer_loaded) {
if (!LoadRenderer())
return;
_renderer_loaded = true;
}
g_renderer.RegisterCVars();
}
RT_DLLEXPORT bool rtInitGFX(rt_renderer_init_info *renderer_info) {
if (!_renderer_loaded) {
if (!LoadRenderer())
return false;
g_renderer.RegisterCVars();
}
if (g_renderer.Init(renderer_info) != RT_SUCCESS)
return false;
return true;
}
RT_DLLEXPORT void rtShutdownGFX(void) {
g_renderer.Shutdown();
}