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);
 | 
			
		||||
    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