feat(renderer): Virtual resource registry first version
Some checks failed
Ubuntu Cross to Win64 / Cross Compile with ming64 (1.4.0, ubuntu-latest) (push) Failing after 1m37s
Some checks failed
Ubuntu Cross to Win64 / Cross Compile with ming64 (1.4.0, ubuntu-latest) (push) Failing after 1m37s
This commit is contained in:
parent
3a7bca385c
commit
e25dde131a
@ -1,9 +1,12 @@
|
||||
#include "renderer.h"
|
||||
#include "backend_api.h"
|
||||
#include "runtime/runtime.h"
|
||||
|
||||
#include <SDL2/SDL_syswm.h>
|
||||
#include <runtime/config.h>
|
||||
|
||||
RT_CVAR_S(rt_Renderer, "The used renderer. Available options: vk, dx11. (Default: vk)", "vk");
|
||||
extern rt_cvar r_MaxRenderResources;
|
||||
|
||||
RT_DLLEXPORT void rtRegisterRenderCVARs(void) {
|
||||
rtRegisterCVAR(&rt_Renderer);
|
||||
@ -13,10 +16,23 @@ RT_DLLEXPORT void rtRegisterRenderBackendCVARs(void) {
|
||||
g_render_backend.RegisterCVARs();
|
||||
}
|
||||
|
||||
rt_render_device_i g_device_i;
|
||||
|
||||
extern rt_result InitVirtualResourceRegistry(void);
|
||||
extern void ShutdownVirtualResourceRegistry(void);
|
||||
|
||||
RT_DLLEXPORT rt_result rtInitRenderer(const rt_renderer_window_info *info) {
|
||||
rt_render_backend_init_result backend_res = g_render_backend.Init(info);
|
||||
return backend_res.result;
|
||||
if (backend_res.result != RT_SUCCESS)
|
||||
return backend_res.result;
|
||||
g_device_i = backend_res.device;
|
||||
|
||||
rt_result res;
|
||||
if ((res = InitVirtualResourceRegistry()) != RT_SUCCESS) {
|
||||
g_render_backend.Shutdown();
|
||||
return res;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
RT_DLLEXPORT void rtShutdownRenderer(void) {
|
||||
|
@ -19,11 +19,14 @@ renderer_lib = library('renderer',
|
||||
'backend_api.h',
|
||||
'renderer.h',
|
||||
'render_mesh.h',
|
||||
'render_resource.h',
|
||||
'virtual_resource_registry.h',
|
||||
|
||||
'init.c',
|
||||
'load_stub.c',
|
||||
'meshlet_pools.c',
|
||||
'render_mesh.c',
|
||||
'virtual_resource_registry.c',
|
||||
dependencies: [m_dep, thread_dep],
|
||||
link_with: renderer_link_libs,
|
||||
include_directories: engine_incdir,
|
||||
|
97
src/renderer/render_resource.h
Normal file
97
src/renderer/render_resource.h
Normal file
@ -0,0 +1,97 @@
|
||||
#ifndef RT_RENDERER_RENDER_RESOURCE_H
|
||||
#define RT_RENDERER_RENDER_RESOURCE_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <runtime/runtime.h>
|
||||
#include <runtime/resources.h>
|
||||
|
||||
typedef enum {
|
||||
RT_RENDER_RESOURCE_TYPE_INVALID,
|
||||
RT_RENDER_RESOURCE_TYPE_BUFFER,
|
||||
RT_RENDER_RESOURCE_TYPE_TEXTURE2D,
|
||||
/* Max is 2**6 = 64 */
|
||||
} rt_render_resource_type;
|
||||
|
||||
/* Handle to a render resource.
|
||||
* The layout is:
|
||||
* | type : 6 | version : 6 | index : 20 |
|
||||
* MSB LSB
|
||||
*/
|
||||
typedef struct {
|
||||
uint32_t value;
|
||||
} rt_render_resource_handle;
|
||||
|
||||
#define RT_RENDER_RESOURCE_MAX_VERSION 0x3f
|
||||
|
||||
/* Extract the type part of a render resource handle */
|
||||
static RT_INLINE rt_render_resource_type rtGetRenderResourceHandleType(rt_render_resource_handle h) {
|
||||
return (rt_render_resource_type)((h.value >> 26) & 0x3f);
|
||||
}
|
||||
|
||||
/* Extract the version part of a render resource handle */
|
||||
static RT_INLINE uint32_t rtGetRenderResourceHandleVersion(rt_render_resource_handle h) {
|
||||
return (h.value >> 20) & 0x3f;
|
||||
}
|
||||
|
||||
/* Extract the index part of a render resource handle */
|
||||
static RT_INLINE uint32_t rtGetRenderResourceHandleIndex(rt_render_resource_handle h) {
|
||||
return h.value & 0xfffff;
|
||||
}
|
||||
|
||||
/* Create a render resource handle. This only does the required bit-shifting, it does not actually register any resource for the handle. */
|
||||
static RT_INLINE rt_render_resource_handle rtMakeRenderResourceHandle(rt_render_resource_type type, uint32_t version, uint32_t index) {
|
||||
rt_render_resource_handle h;
|
||||
h.value = ((type & 0x3f) << 26u) | ((version & 0x3f) << 20u) | (index & 0xfffff);
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Resource description structs */
|
||||
|
||||
typedef enum {
|
||||
RT_RENDER_BUFFER_USAGE_NONE = 0,
|
||||
RT_RENDER_BUFFER_USAGE_VERTEX_BUFFER = 0x01,
|
||||
RT_RENDER_BUFFER_USAGE_INDEX_BUFFER = 0x02,
|
||||
RT_RENDER_BUFFER_USAGE_STORAGE_BUFFER = 0x04,
|
||||
|
||||
/* The buffer will be used as a source to populate other resources
|
||||
* with data */
|
||||
RT_RENDER_BUFFER_USAGE_UPLOAD_BUFFER = 0x10,
|
||||
} rt_render_buffer_usage_flags;
|
||||
|
||||
typedef enum {
|
||||
/* The buffer can reside in memory that can only be accessed by the GPU */
|
||||
RT_RENDER_BUFFER_ACCESS_GPU_ONLY = 0x01,
|
||||
|
||||
/* The buffer needs to be in CPU accessible memory */
|
||||
RT_RENDER_BUFFER_ACCESS_CPU_AND_GPU = 0x02,
|
||||
|
||||
/* The buffer is short-lived (will be destroyed at the end of the frame) */
|
||||
RT_RENDER_BUFFER_ACCESS_TRANSIENT = 0x04,
|
||||
} rt_render_buffer_access_flags;
|
||||
|
||||
/* Describes a gpu buffer */
|
||||
typedef struct {
|
||||
/* The required size in bytes */
|
||||
size_t size;
|
||||
|
||||
/* Bitmask describing the usage of the buffer */
|
||||
rt_render_buffer_usage_flags usage;
|
||||
|
||||
/* Bitmask describing the access the buffer needs to support */
|
||||
rt_render_buffer_access_flags access;
|
||||
|
||||
/* ResourceID of the resource that will be used to populate this buffer. */
|
||||
rt_resource_id source_resource;
|
||||
} rt_render_buffer_desc;
|
||||
|
||||
/* Describes a gpu texture */
|
||||
typedef struct {
|
||||
/* Width in pixels */
|
||||
uint32_t width;
|
||||
|
||||
/* Height in pixels */
|
||||
uint32_t height;
|
||||
} rt_render_texture2d_desc;
|
||||
|
||||
#endif
|
||||
|
@ -42,7 +42,6 @@ RT_DLLEXPORT rt_result rtLoadRenderBackend(void);
|
||||
|
||||
RT_DLLEXPORT void rtRegisterRenderBackendCVARs(void);
|
||||
|
||||
|
||||
RT_DLLEXPORT rt_result rtInitRenderer(const rt_renderer_window_info *window);
|
||||
|
||||
RT_DLLEXPORT void rtShutdownRenderer(void);
|
||||
|
138
src/renderer/virtual_resource_registry.c
Normal file
138
src/renderer/virtual_resource_registry.c
Normal file
@ -0,0 +1,138 @@
|
||||
#include <runtime/config.h>
|
||||
#include <runtime/threading.h>
|
||||
#include <runtime/runtime.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "virtual_resource_registry.h"
|
||||
#include "render_resource.h"
|
||||
|
||||
RT_CVAR_SZ(r_MaxRenderResources, "Maximum number of render resources that can exist simultaneously. (Default: 16384)", 16384);
|
||||
|
||||
typedef struct {
|
||||
rt_render_resource_handle *handles;
|
||||
struct {
|
||||
union {
|
||||
/* For management */
|
||||
uint32_t next_free;
|
||||
|
||||
rt_render_buffer_desc buffer;
|
||||
rt_render_texture2d_desc texture2d;
|
||||
};
|
||||
} *descs;
|
||||
uint32_t first_free;
|
||||
rt_rwlock lock;
|
||||
} rt_description_table;
|
||||
|
||||
static rt_description_table _description_tab;
|
||||
|
||||
rt_result InitVirtualResourceRegistry(void) {
|
||||
_description_tab.handles = calloc(r_MaxRenderResources.sz, sizeof(rt_render_resource_handle));
|
||||
if (!_description_tab.handles)
|
||||
return RT_OUT_OF_MEMORY;
|
||||
_description_tab.descs = calloc(r_MaxRenderResources.sz, sizeof(*_description_tab.descs));
|
||||
if (!_description_tab.descs) {
|
||||
free(_description_tab.handles);
|
||||
return RT_OUT_OF_MEMORY;
|
||||
}
|
||||
rt_create_rwlock_result lock_res = rtCreateRWLock();
|
||||
if (!lock_res.ok) {
|
||||
free(_description_tab.handles);
|
||||
free(_description_tab.descs);
|
||||
return RT_UNKNOWN_ERROR;
|
||||
}
|
||||
_description_tab.lock = lock_res.lock;
|
||||
_description_tab.first_free = 0;
|
||||
for (uint32_t i = 0; i < r_MaxRenderResources.sz; ++i) {
|
||||
_description_tab.descs[i].next_free = i + 1;
|
||||
}
|
||||
return RT_SUCCESS;
|
||||
}
|
||||
|
||||
void ShutdownVirtualResourceRegistry(void) {
|
||||
free(_description_tab.handles);
|
||||
free(_description_tab.descs);
|
||||
rtDestroyRWLock(&_description_tab.lock);
|
||||
}
|
||||
|
||||
/* Returns true if the handle refers to an existing resource. */
|
||||
bool rtIsRenderResourceKnown(rt_render_resource_handle h) {
|
||||
uint32_t idx = rtGetRenderResourceHandleIndex(h);
|
||||
if (idx >= r_MaxRenderResources.sz)
|
||||
return false;
|
||||
rtLockRead(&_description_tab.lock);
|
||||
bool is_known = _description_tab.handles[idx].value == h.value;
|
||||
rtUnlockRead(&_description_tab.lock);
|
||||
return is_known;
|
||||
}
|
||||
|
||||
static const void *GetResourceDescription(rt_render_resource_handle h) {
|
||||
rt_render_resource_type type = rtGetRenderResourceHandleType(h);
|
||||
uint32_t idx = rtGetRenderResourceHandleIndex(h);
|
||||
if (idx >= r_MaxRenderResources.sz)
|
||||
return false;
|
||||
const void *desc = NULL;
|
||||
rtLockRead(&_description_tab.lock);
|
||||
if (_description_tab.handles[idx].value == h.value) {
|
||||
switch (type) {
|
||||
case RT_RENDER_RESOURCE_TYPE_BUFFER:
|
||||
desc = &_description_tab.descs[idx].buffer;
|
||||
break;
|
||||
case RT_RENDER_RESOURCE_TYPE_TEXTURE2D:
|
||||
desc = &_description_tab.descs[idx].texture2d;
|
||||
break;
|
||||
default:
|
||||
desc = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
rtUnlockRead(&_description_tab.lock);
|
||||
return desc;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the resource description or NULL, if the handle does not refer to a valid buffer */
|
||||
const rt_render_buffer_desc *rtGetRenderBufferDescription(rt_render_resource_handle h) {
|
||||
return GetResourceDescription(h);
|
||||
}
|
||||
|
||||
/* Returns a pointer to the resource description or NULL, if the handle does not refer to a valid texture2d */
|
||||
const rt_render_texture2d_desc *rtGetRenderTexture2DDescription(rt_render_resource_handle h) {
|
||||
return GetResourceDescription(h);
|
||||
}
|
||||
|
||||
static rt_render_resource_handle AllocSlot(rt_render_resource_type type, const void *desc) {
|
||||
rt_render_resource_handle h = rtMakeRenderResourceHandle(RT_RENDER_RESOURCE_TYPE_INVALID, 0, 0);
|
||||
rtLockWrite(&_description_tab.lock);
|
||||
uint32_t slot = _description_tab.first_free;
|
||||
if (slot < r_MaxRenderResources.sz) {
|
||||
_description_tab.first_free = _description_tab.descs[slot].next_free;
|
||||
uint32_t current_version = rtGetRenderResourceHandleVersion(_description_tab.handles[slot]);
|
||||
uint32_t next_version = (current_version + 1) & RT_RENDER_RESOURCE_MAX_VERSION;
|
||||
h = rtMakeRenderResourceHandle(type, next_version, slot);
|
||||
_description_tab.handles[slot] = h;
|
||||
switch (type) {
|
||||
case RT_RENDER_RESOURCE_TYPE_BUFFER:
|
||||
memcpy(&_description_tab.descs[slot].buffer, desc, sizeof(rt_render_buffer_desc));
|
||||
break;
|
||||
case RT_RENDER_RESOURCE_TYPE_TEXTURE2D:
|
||||
memcpy(&_description_tab.descs[slot].texture2d, desc, sizeof(rt_render_texture2d_desc));
|
||||
break;
|
||||
default:
|
||||
rtReportError("RENDERER", "Tried to create a resource with invalid type %u", type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
rtUnlockWrite(&_description_tab.lock);
|
||||
return h;
|
||||
}
|
||||
|
||||
/* Stores the render buffer description and returns a handle to the new resource. */
|
||||
rt_render_resource_handle rtCreateRenderBuffer(const rt_render_buffer_desc *desc) {
|
||||
return AllocSlot(RT_RENDER_RESOURCE_TYPE_BUFFER, desc);
|
||||
}
|
||||
|
||||
/* Stores the texture2d description and returns a handle to the new resource. */
|
||||
rt_render_resource_handle rtCreateRenderTexture2D(const rt_render_texture2d_desc *desc) {
|
||||
return AllocSlot(RT_RENDER_RESOURCE_TYPE_TEXTURE2D, desc);
|
||||
}
|
33
src/renderer/virtual_resource_registry.h
Normal file
33
src/renderer/virtual_resource_registry.h
Normal file
@ -0,0 +1,33 @@
|
||||
#ifndef RT_RENDERER_VIRTUAL_RESOURCE_REGISTRY_H
|
||||
#define RT_RENDERER_VIRTUAL_RESOURCE_REGISTRY_H
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <runtime/runtime.h>
|
||||
#include "render_resource.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/* Returns true if the handle refers to an existing resource. */
|
||||
bool rtIsRenderResourceKnown(rt_render_resource_handle h);
|
||||
|
||||
/* Returns a pointer to the resource description or NULL, if the handle does not refer to a valid buffer */
|
||||
const rt_render_buffer_desc *rtGetRenderBufferDescription(rt_render_resource_handle h);
|
||||
|
||||
/* Returns a pointer to the resource description or NULL, if the handle does not refer to a valid texture2d */
|
||||
const rt_render_texture2d_desc *rtGetRenderTexture2DDescription(rt_render_resource_handle h);
|
||||
|
||||
/* Stores the render buffer description and returns a handle to the new resource. */
|
||||
rt_render_resource_handle rtCreateRenderBuffer(const rt_render_buffer_desc *desc);
|
||||
|
||||
/* Stores the texture2d description and returns a handle to the new resource. */
|
||||
rt_render_resource_handle rtCreateRenderTexture2D(const rt_render_texture2d_desc *desc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user