Load framegraphs from resource files
This commit is contained in:
		
							parent
							
								
									bdd3db98bb
								
							
						
					
					
						commit
						cc49a017f9
					
				
							
								
								
									
										64
									
								
								assets/test.framegraph
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								assets/test.framegraph
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,64 @@
 | 
				
			|||||||
 | 
					render_targets {
 | 
				
			||||||
 | 
					    color0 {
 | 
				
			||||||
 | 
					        format R8G8B8A8_SRGB;
 | 
				
			||||||
 | 
					        width 1024;
 | 
				
			||||||
 | 
					        height 768;
 | 
				
			||||||
 | 
					        sample_count 4;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    swapchain_out {
 | 
				
			||||||
 | 
					        format SWAPCHAIN;
 | 
				
			||||||
 | 
					        width SWAPCHAIN;
 | 
				
			||||||
 | 
					        height SWAPCHAIN;
 | 
				
			||||||
 | 
					        sample_count 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    depth0 {
 | 
				
			||||||
 | 
					        format DEPTH24_STENCIL8;
 | 
				
			||||||
 | 
					        width 512;
 | 
				
			||||||
 | 
					        height 384;
 | 
				
			||||||
 | 
					        sample_count 4;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					passes {
 | 
				
			||||||
 | 
					    pass0 {
 | 
				
			||||||
 | 
					        writes {
 | 
				
			||||||
 | 
					            color0 {
 | 
				
			||||||
 | 
					                clear_value {
 | 
				
			||||||
 | 
					                    r 1.0;
 | 
				
			||||||
 | 
					                    g 1.0;
 | 
				
			||||||
 | 
					                    b 1.0;
 | 
				
			||||||
 | 
					                    a 1.0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                clear YES;
 | 
				
			||||||
 | 
					                discard NO;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            depth0 {
 | 
				
			||||||
 | 
					                clear_value {
 | 
				
			||||||
 | 
					                    d 0.0;
 | 
				
			||||||
 | 
					                    s 0;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                clear YES;
 | 
				
			||||||
 | 
					                discard YES;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    pass1 {
 | 
				
			||||||
 | 
					        reads {
 | 
				
			||||||
 | 
					            color0 {
 | 
				
			||||||
 | 
					                mode SAMPLED;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        writes {
 | 
				
			||||||
 | 
					            swapchain_out {
 | 
				
			||||||
 | 
					                clear NO;
 | 
				
			||||||
 | 
					                discard NO;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -28,6 +28,8 @@ elif compiler.get_argument_syntax() == 'msvc'
 | 
				
			|||||||
  if buildtype == 'debug'
 | 
					  if buildtype == 'debug'
 | 
				
			||||||
    add_project_arguments(['/RTCsu'], language : ['c', 'cpp'])
 | 
					    add_project_arguments(['/RTCsu'], language : ['c', 'cpp'])
 | 
				
			||||||
  endif
 | 
					  endif
 | 
				
			||||||
 | 
					  # Allow nameless struct/unions (standard in C11)
 | 
				
			||||||
 | 
					  add_project_arguments(['/wd4201'], language : 'cpp')
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if get_option('default_library') == 'static'
 | 
					if get_option('default_library') == 'static'
 | 
				
			||||||
@ -98,6 +100,7 @@ if get_option('build_asset_compiler')
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    'src/runtime/asset_compiler.c',
 | 
					    'src/runtime/asset_compiler.c',
 | 
				
			||||||
    'src/runtime/description_parser.c',
 | 
					    'src/runtime/description_parser.c',
 | 
				
			||||||
 | 
					    'src/runtime/framegraph_processor.c',
 | 
				
			||||||
    'src/runtime/pipeline_processor.c',
 | 
					    'src/runtime/pipeline_processor.c',
 | 
				
			||||||
    'src/runtime/shader_compiler.c',
 | 
					    'src/runtime/shader_compiler.c',
 | 
				
			||||||
  ]
 | 
					  ]
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,6 @@
 | 
				
			|||||||
#include "runtime/gfx.h"
 | 
					#include "runtime/gfx.h"
 | 
				
			||||||
 | 
					#include "runtime/resources.h"
 | 
				
			||||||
 | 
					#include "runtime/mem_arena.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static rt_framegraph *_framegraph;
 | 
					static rt_framegraph *_framegraph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -6,6 +8,7 @@ static rt_framegraph *_framegraph;
 | 
				
			|||||||
void Init(void) {
 | 
					void Init(void) {
 | 
				
			||||||
    rtLog("GAME", "Init");
 | 
					    rtLog("GAME", "Init");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    #if 0
 | 
				
			||||||
    rt_render_target_id rt_ids[4] = {rtCalculateRenderTargetID("rt0", sizeof("rt0")),
 | 
					    rt_render_target_id rt_ids[4] = {rtCalculateRenderTargetID("rt0", sizeof("rt0")),
 | 
				
			||||||
                                     rtCalculateRenderTargetID("rt1", sizeof("rt1")),
 | 
					                                     rtCalculateRenderTargetID("rt1", sizeof("rt1")),
 | 
				
			||||||
                                     rtCalculateRenderTargetID("rt2", sizeof("rt2")),
 | 
					                                     rtCalculateRenderTargetID("rt2", sizeof("rt2")),
 | 
				
			||||||
@ -54,8 +57,16 @@ void Init(void) {
 | 
				
			|||||||
    };
 | 
					    };
 | 
				
			||||||
    rtSetRelptr(&info.render_passes, passes);
 | 
					    rtSetRelptr(&info.render_passes, passes);
 | 
				
			||||||
    rtSetRelptr(&info.render_targets, rts);
 | 
					    rtSetRelptr(&info.render_targets, rts);
 | 
				
			||||||
 | 
					    #endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    _framegraph = rtCreateFramegraph(&info);
 | 
					    rt_resource_id id  = rtGetResourceID("assets/test.framegraph");
 | 
				
			||||||
 | 
					    rt_temp_arena temp = rtGetTemporaryArena(NULL, 0);
 | 
				
			||||||
 | 
					    rt_resource *resource =
 | 
				
			||||||
 | 
					        rtArenaPush(temp.arena, rtGetResourceSize(id));
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    rtGetResource(id, resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    _framegraph = rtCreateFramegraph(resource->data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Called after exiting the main-loop and before the runtime starts its shutdown */
 | 
					/* Called after exiting the main-loop and before the runtime starts its shutdown */
 | 
				
			||||||
 | 
				
			|||||||
@ -2,10 +2,26 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
VkFormat rtPixelFormatToVkFormat(rt_pixel_format format) {
 | 
					VkFormat rtPixelFormatToVkFormat(rt_pixel_format format) {
 | 
				
			||||||
    switch (format) {
 | 
					    switch (format) {
 | 
				
			||||||
 | 
					    case RT_PIXEL_FORMAT_R8G8B8A8_UNORM:
 | 
				
			||||||
 | 
					        return VK_FORMAT_R8G8B8A8_UNORM;
 | 
				
			||||||
 | 
					    case RT_PIXEL_FORMAT_B8G8R8A8_UNORM:
 | 
				
			||||||
 | 
					        return VK_FORMAT_B8G8R8A8_UNORM;
 | 
				
			||||||
    case RT_PIXEL_FORMAT_R8G8B8A8_SRGB:
 | 
					    case RT_PIXEL_FORMAT_R8G8B8A8_SRGB:
 | 
				
			||||||
        return VK_FORMAT_R8G8B8A8_SRGB;
 | 
					        return VK_FORMAT_R8G8B8A8_SRGB;
 | 
				
			||||||
 | 
					    case RT_PIXEL_FORMAT_B8G8R8A8_SRGB:
 | 
				
			||||||
 | 
					        return VK_FORMAT_B8G8R8A8_SRGB;
 | 
				
			||||||
 | 
					    case RT_PIXEL_FORMAT_R8G8B8_UNORM:
 | 
				
			||||||
 | 
					        return VK_FORMAT_R8G8B8_UNORM;
 | 
				
			||||||
 | 
					    case RT_PIXEL_FORMAT_B8G8R8_UNORM:
 | 
				
			||||||
 | 
					        return VK_FORMAT_B8G8R8_UNORM;
 | 
				
			||||||
 | 
					    case RT_PIXEL_FORMAT_R8G8B8_SRGB:
 | 
				
			||||||
 | 
					        return VK_FORMAT_R8G8B8_SRGB;
 | 
				
			||||||
 | 
					    case RT_PIXEL_FORMAT_B8G8R8_SRGB:
 | 
				
			||||||
 | 
					        return VK_FORMAT_B8G8R8_SRGB;
 | 
				
			||||||
    case RT_PIXEL_FORMAT_DEPTH24_STENCIL8:
 | 
					    case RT_PIXEL_FORMAT_DEPTH24_STENCIL8:
 | 
				
			||||||
        return VK_FORMAT_D24_UNORM_S8_UINT;
 | 
					        return VK_FORMAT_D24_UNORM_S8_UINT;
 | 
				
			||||||
 | 
					    case RT_PIXEL_FORMAT_DEPTH32:
 | 
				
			||||||
 | 
					        return VK_FORMAT_D32_SFLOAT;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        return VK_FORMAT_UNDEFINED;
 | 
					        return VK_FORMAT_UNDEFINED;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -20,6 +36,8 @@ VkSampleCountFlagBits rtSampleCountToFlags(unsigned int count) {
 | 
				
			|||||||
    while (count > 1) {
 | 
					    while (count > 1) {
 | 
				
			||||||
        if ((counts & count) == 0)
 | 
					        if ((counts & count) == 0)
 | 
				
			||||||
            count >>= 1;
 | 
					            count >>= 1;
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return (VkSampleCountFlagBits)count;
 | 
					    return (VkSampleCountFlagBits)count;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -175,7 +175,7 @@ rt_render_target_handle RT_RENDERER_API_FN(CreateRenderTarget)(const rt_render_t
 | 
				
			|||||||
            slot->render_target.format = g_swapchain.format;
 | 
					            slot->render_target.format = g_swapchain.format;
 | 
				
			||||||
            slot->render_target.match_swapchain |= RT_RENDER_TARGET_MATCH_SWAPCHAIN_FORMAT;
 | 
					            slot->render_target.match_swapchain |= RT_RENDER_TARGET_MATCH_SWAPCHAIN_FORMAT;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (info->format == RT_PIXEL_FORMAT_DEPTH24_STENCIL8) {
 | 
					        if (info->format == RT_PIXEL_FORMAT_DEPTH24_STENCIL8 || info->format == RT_PIXEL_FORMAT_DEPTH32) {
 | 
				
			||||||
            slot->render_target.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
 | 
					            slot->render_target.usage = VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT |
 | 
				
			||||||
                                        VK_IMAGE_USAGE_SAMPLED_BIT |
 | 
					                                        VK_IMAGE_USAGE_SAMPLED_BIT |
 | 
				
			||||||
                                        VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
 | 
					                                        VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
 | 
				
			||||||
 | 
				
			|||||||
@ -65,9 +65,11 @@ static rt_asset_db _asset_db;
 | 
				
			|||||||
static rt_processing_queue _processing_queue;
 | 
					static rt_processing_queue _processing_queue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern RT_ASSET_PROCESSOR_FN(PipelineProcessor);
 | 
					extern RT_ASSET_PROCESSOR_FN(PipelineProcessor);
 | 
				
			||||||
 | 
					extern RT_ASSET_PROCESSOR_FN(FramegraphProcessor);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static rt_asset_processor _processors[] = {
 | 
					static rt_asset_processor _processors[] = {
 | 
				
			||||||
    {.file_ext = ".pipeline", .proc = PipelineProcessor}
 | 
					    {.file_ext = ".pipeline", .proc = PipelineProcessor},
 | 
				
			||||||
 | 
					    {.file_ext = ".framegraph", .proc = FramegraphProcessor},
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void ProcessorThreadEntry(void *);
 | 
					static void ProcessorThreadEntry(void *);
 | 
				
			||||||
 | 
				
			|||||||
@ -17,10 +17,34 @@
 | 
				
			|||||||
extern "C" {
 | 
					extern "C" {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef union {
 | 
				
			||||||
 | 
					    float v[4];
 | 
				
			||||||
 | 
					    struct {
 | 
				
			||||||
 | 
					        float r;
 | 
				
			||||||
 | 
					        float g;
 | 
				
			||||||
 | 
					        float b;
 | 
				
			||||||
 | 
					        float a;
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					} rt_color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* NOTE(kevin): When you add a value here, you need to handle them in
 | 
				
			||||||
 | 
					 * framegraph_processor.c : ParseFramegraph 
 | 
				
			||||||
 | 
					 * and in the render target and texture functions of all renderers. */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
    RT_PIXEL_FORMAT_INVALID,
 | 
					    RT_PIXEL_FORMAT_INVALID,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RT_PIXEL_FORMAT_R8G8B8A8_UNORM,
 | 
				
			||||||
 | 
					    RT_PIXEL_FORMAT_B8G8R8A8_UNORM,
 | 
				
			||||||
    RT_PIXEL_FORMAT_R8G8B8A8_SRGB,
 | 
					    RT_PIXEL_FORMAT_R8G8B8A8_SRGB,
 | 
				
			||||||
 | 
					    RT_PIXEL_FORMAT_B8G8R8A8_SRGB,
 | 
				
			||||||
 | 
					    RT_PIXEL_FORMAT_R8G8B8_UNORM,
 | 
				
			||||||
 | 
					    RT_PIXEL_FORMAT_B8G8R8_UNORM,
 | 
				
			||||||
 | 
					    RT_PIXEL_FORMAT_R8G8B8_SRGB,
 | 
				
			||||||
 | 
					    RT_PIXEL_FORMAT_B8G8R8_SRGB,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RT_PIXEL_FORMAT_DEPTH24_STENCIL8,
 | 
					    RT_PIXEL_FORMAT_DEPTH24_STENCIL8,
 | 
				
			||||||
 | 
					    RT_PIXEL_FORMAT_DEPTH32,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Special value indicating whichever format the swapchain uses */
 | 
					    /* Special value indicating whichever format the swapchain uses */
 | 
				
			||||||
    RT_PIXEL_FORMAT_SWAPCHAIN,
 | 
					    RT_PIXEL_FORMAT_SWAPCHAIN,
 | 
				
			||||||
@ -28,6 +52,21 @@ typedef enum {
 | 
				
			|||||||
    RT_PIXEL_FORMAT_count,
 | 
					    RT_PIXEL_FORMAT_count,
 | 
				
			||||||
} rt_pixel_format;
 | 
					} rt_pixel_format;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* In renderer_api.h -> Not necessary for almost all gfx usage */
 | 
				
			||||||
 | 
					typedef struct rt_renderer_init_info_s rt_renderer_init_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_DLLEXPORT void rtRegisterRendererCVars(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_DLLEXPORT rt_result rtInitGFX(rt_renderer_init_info *renderer_info);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_DLLEXPORT void rtShutdownGFX(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* *********************************************************************
 | 
				
			||||||
 | 
					 * Framegraph API 
 | 
				
			||||||
 | 
					 * 
 | 
				
			||||||
 | 
					 * The framegraph is used to organize and schedule the work for a frame.
 | 
				
			||||||
 | 
					 * *********************************************************************/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Special value for the .width and .height fields of rt_render_target_info
 | 
					/* Special value for the .width and .height fields of rt_render_target_info
 | 
				
			||||||
 * to indicate that these should be set to the width or height of the swapchain, respectively. */
 | 
					 * to indicate that these should be set to the width or height of the swapchain, respectively. */
 | 
				
			||||||
#define RT_RENDER_TARGET_SIZE_SWAPCHAIN 0
 | 
					#define RT_RENDER_TARGET_SIZE_SWAPCHAIN 0
 | 
				
			||||||
@ -44,8 +83,8 @@ typedef struct {
 | 
				
			|||||||
} rt_render_target_info;
 | 
					} rt_render_target_info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
    RT_RENDER_TARGET_READ_INPUT_ATTACHMENT,
 | 
					 | 
				
			||||||
    RT_RENDER_TARGET_READ_SAMPLED,
 | 
					    RT_RENDER_TARGET_READ_SAMPLED,
 | 
				
			||||||
 | 
					    RT_RENDER_TARGET_READ_INPUT_ATTACHMENT,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RT_RENDER_TARGET_READ_count,
 | 
					    RT_RENDER_TARGET_READ_count,
 | 
				
			||||||
} rt_render_target_read_mode;
 | 
					} rt_render_target_read_mode;
 | 
				
			||||||
@ -66,7 +105,7 @@ typedef enum {
 | 
				
			|||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    rt_render_target_id render_target;
 | 
					    rt_render_target_id render_target;
 | 
				
			||||||
    union {
 | 
					    union {
 | 
				
			||||||
        float color[4];
 | 
					        rt_color color;
 | 
				
			||||||
        struct {
 | 
					        struct {
 | 
				
			||||||
            float depth;
 | 
					            float depth;
 | 
				
			||||||
            int32_t stencil;
 | 
					            int32_t stencil;
 | 
				
			||||||
@ -102,20 +141,6 @@ typedef struct {
 | 
				
			|||||||
    rt_render_pass_finalize_fn *Finalize;
 | 
					    rt_render_pass_finalize_fn *Finalize;
 | 
				
			||||||
} rt_render_pass_bind_fns;
 | 
					} rt_render_pass_bind_fns;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* In renderer_api.h -> Not necessary for almost all gfx usage */
 | 
					 | 
				
			||||||
typedef struct rt_renderer_init_info_s rt_renderer_init_info;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RT_DLLEXPORT void rtRegisterRendererCVars(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RT_DLLEXPORT rt_result rtInitGFX(rt_renderer_init_info *renderer_info);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
RT_DLLEXPORT void rtShutdownGFX(void);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Framegraph API 
 | 
					 | 
				
			||||||
 * 
 | 
					 | 
				
			||||||
 * The framegraph is used to organize and schedule the work for a frame.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct rt_framegraph_s rt_framegraph;
 | 
					typedef struct rt_framegraph_s rt_framegraph;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -310,6 +310,7 @@ static bool ValidateInfo(const rt_framegraph_info *info) {
 | 
				
			|||||||
            rtReportError(
 | 
					            rtReportError(
 | 
				
			||||||
                "GFX",
 | 
					                "GFX",
 | 
				
			||||||
                "Framegraph pass %u reads too many rendertargets: %u (maximum allowed is %u)",
 | 
					                "Framegraph pass %u reads too many rendertargets: %u (maximum allowed is %u)",
 | 
				
			||||||
 | 
					                i,
 | 
				
			||||||
                passes[i].read_render_target_count,
 | 
					                passes[i].read_render_target_count,
 | 
				
			||||||
                RT_RENDERPASS_MAX_READS);
 | 
					                RT_RENDERPASS_MAX_READS);
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
@ -317,6 +318,7 @@ static bool ValidateInfo(const rt_framegraph_info *info) {
 | 
				
			|||||||
            rtReportError(
 | 
					            rtReportError(
 | 
				
			||||||
                "GFX",
 | 
					                "GFX",
 | 
				
			||||||
                "Framegraph pass %u writes too many rendertargets: %u (maximum allowed is %u)",
 | 
					                "Framegraph pass %u writes too many rendertargets: %u (maximum allowed is %u)",
 | 
				
			||||||
 | 
					                i,
 | 
				
			||||||
                passes[i].write_render_target_count,
 | 
					                passes[i].write_render_target_count,
 | 
				
			||||||
                RT_RENDERPASS_MAX_WRITES);
 | 
					                RT_RENDERPASS_MAX_WRITES);
 | 
				
			||||||
            return false;
 | 
					            return false;
 | 
				
			||||||
 | 
				
			|||||||
@ -98,6 +98,16 @@ static size_t GetResourceDataSize(const rt_resource *resource) {
 | 
				
			|||||||
        const rt_shader_info *info = resource->data;
 | 
					        const rt_shader_info *info = resource->data;
 | 
				
			||||||
        return sizeof(rt_shader_info) + (info) ? info->bytecode_length : 0;
 | 
					        return sizeof(rt_shader_info) + (info) ? info->bytecode_length : 0;
 | 
				
			||||||
    } break;
 | 
					    } break;
 | 
				
			||||||
 | 
					    case RT_RESOURCE_FRAMEGRAPH: {
 | 
				
			||||||
 | 
					        const rt_framegraph_info *info = resource->data;
 | 
				
			||||||
 | 
					        size_t size = sizeof(*info) + sizeof(rt_render_target_info) * info->render_target_count +
 | 
				
			||||||
 | 
					                      sizeof(rt_render_pass_info) * info->render_pass_count;
 | 
				
			||||||
 | 
					        const rt_render_pass_info *passes = rtResolveConstRelptr(&info->render_passes);
 | 
				
			||||||
 | 
					        for (uint32_t i = 0; i < info->render_pass_count; ++i) {
 | 
				
			||||||
 | 
					            size += passes[i].read_render_target_count * sizeof(rt_render_target_read) +
 | 
				
			||||||
 | 
					                    passes[i].write_render_target_count * sizeof(rt_render_target_write);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        rtLog("RESMGR", "Tried to get size of an invalid resource type %u", resource->type);
 | 
					        rtLog("RESMGR", "Tried to get size of an invalid resource type %u", resource->type);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -117,8 +127,38 @@ static void CopyResourceData(const rt_resource *resource, void *dest) {
 | 
				
			|||||||
        memcpy(dest_info + 1, rtResolveConstRelptr(&info->bytecode), info->bytecode_length);
 | 
					        memcpy(dest_info + 1, rtResolveConstRelptr(&info->bytecode), info->bytecode_length);
 | 
				
			||||||
        rtSetRelptr(&dest_info->bytecode, (void *)(dest_info + 1));
 | 
					        rtSetRelptr(&dest_info->bytecode, (void *)(dest_info + 1));
 | 
				
			||||||
    } break;
 | 
					    } break;
 | 
				
			||||||
 | 
					    case RT_RESOURCE_FRAMEGRAPH: {
 | 
				
			||||||
 | 
					        const rt_framegraph_info *info = resource->data;
 | 
				
			||||||
 | 
					        rt_framegraph_info *dest_info  = dest;
 | 
				
			||||||
 | 
					        memcpy(dest_info, info, sizeof(*info));
 | 
				
			||||||
 | 
					        memcpy(dest_info + 1,
 | 
				
			||||||
 | 
					               rtResolveConstRelptr(&info->render_targets),
 | 
				
			||||||
 | 
					               info->render_target_count * sizeof(rt_render_target_info));
 | 
				
			||||||
 | 
					        rtSetRelptr(&dest_info->render_targets, (void *)(dest_info + 1));
 | 
				
			||||||
 | 
					        char *passes_begin =
 | 
				
			||||||
 | 
					            (char *)(dest_info + 1) + info->render_target_count * sizeof(rt_render_target_info);
 | 
				
			||||||
 | 
					        memcpy(passes_begin,
 | 
				
			||||||
 | 
					               rtResolveConstRelptr(&info->render_passes),
 | 
				
			||||||
 | 
					               info->render_pass_count * sizeof(rt_render_pass_info));
 | 
				
			||||||
 | 
					        char *read_write_dest = passes_begin + info->render_pass_count * sizeof(rt_render_pass_info);
 | 
				
			||||||
 | 
					        rt_render_pass_info *passes_dest = (rt_render_pass_info *)passes_begin;
 | 
				
			||||||
 | 
					        const rt_render_pass_info *passes =
 | 
				
			||||||
 | 
					            (const rt_render_pass_info *)rtResolveConstRelptr(&info->render_passes);
 | 
				
			||||||
 | 
					        for (uint32_t i = 0; i < info->render_pass_count; ++i) {
 | 
				
			||||||
 | 
					            rtSetRelptr(&passes_dest[i].read_render_targets, read_write_dest);
 | 
				
			||||||
 | 
					            memcpy(read_write_dest,
 | 
				
			||||||
 | 
					                   rtResolveConstRelptr(&passes[i].read_render_targets),
 | 
				
			||||||
 | 
					                   sizeof(rt_render_target_read) * passes[i].read_render_target_count);
 | 
				
			||||||
 | 
					            read_write_dest += sizeof(rt_render_target_read) * passes[i].read_render_target_count;
 | 
				
			||||||
 | 
					            rtSetRelptr(&passes_dest[i].write_render_targets, read_write_dest);
 | 
				
			||||||
 | 
					            memcpy(read_write_dest,
 | 
				
			||||||
 | 
					                   rtResolveConstRelptr(&passes[i].write_render_targets),
 | 
				
			||||||
 | 
					                   sizeof(rt_render_target_write) * passes[i].write_render_target_count);
 | 
				
			||||||
 | 
					            read_write_dest += sizeof(rt_render_target_write) * passes[i].write_render_target_count;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } break;
 | 
				
			||||||
    default:
 | 
					    default:
 | 
				
			||||||
        rtLog("RESMGR", "Tried to get copy a resource of invalid type %u", resource->type);
 | 
					        rtLog("RESMGR", "Tried to copy a resource of invalid type %u", resource->type);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -749,6 +789,15 @@ RT_DLLEXPORT void rtPrefetchResources(const rt_resource_id *ids, uint32_t count)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_DLLEXPORT rt_resource_id rtGetResourceID(const char *name) {
 | 
				
			||||||
 | 
					    size_t name_len   = strlen(name);
 | 
				
			||||||
 | 
					    rt_resource_id id = (rt_resource_id)rtHashBytes(name, name_len);
 | 
				
			||||||
 | 
					    if (id == RT_INVALID_RESOURCE_ID || id == RT_TOMBSTONE_ID)
 | 
				
			||||||
 | 
					        id = ~id;
 | 
				
			||||||
 | 
					    return id;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RT_DLLEXPORT rt_result rtCreateResources(uint32_t count,
 | 
					RT_DLLEXPORT rt_result rtCreateResources(uint32_t count,
 | 
				
			||||||
                                         const char **names,
 | 
					                                         const char **names,
 | 
				
			||||||
                                         const rt_resource *resources,
 | 
					                                         const rt_resource *resources,
 | 
				
			||||||
@ -764,11 +813,7 @@ RT_DLLEXPORT rt_result rtCreateResources(uint32_t count,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    rtLockWrite(&_namespace.lock);
 | 
					    rtLockWrite(&_namespace.lock);
 | 
				
			||||||
    for (uint32_t i = 0; i < count; ++i) {
 | 
					    for (uint32_t i = 0; i < count; ++i) {
 | 
				
			||||||
        size_t name_len   = strlen(names[i]);
 | 
					        rt_resource_id id = rtGetResourceID(names[i]);
 | 
				
			||||||
        rt_resource_id id = (rt_resource_id)rtHashBytes(names[i], name_len);
 | 
					 | 
				
			||||||
        if (id == RT_INVALID_RESOURCE_ID || id == RT_TOMBSTONE_ID)
 | 
					 | 
				
			||||||
            id = ~id;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        bool inserted = false;
 | 
					        bool inserted = false;
 | 
				
			||||||
        for (size_t j = 0; j < ns_size; ++j) {
 | 
					        for (size_t j = 0; j < ns_size; ++j) {
 | 
				
			||||||
            size_t at = (id + j) % ns_size;
 | 
					            size_t at = (id + j) % ns_size;
 | 
				
			||||||
 | 
				
			|||||||
@ -35,6 +35,8 @@ typedef enum {
 | 
				
			|||||||
    /* A pipeline state object */
 | 
					    /* A pipeline state object */
 | 
				
			||||||
    RT_RESOURCE_PIPELINE,
 | 
					    RT_RESOURCE_PIPELINE,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RT_RESOURCE_FRAMEGRAPH,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    RT_RESOURCE_TYPE_count,
 | 
					    RT_RESOURCE_TYPE_count,
 | 
				
			||||||
} rt_resource_type;
 | 
					} rt_resource_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -74,6 +76,10 @@ RT_DLLEXPORT void rtPrefetchResources(const rt_resource_id *ids, uint32_t count)
 | 
				
			|||||||
/* Returns the size of a resource in bytes, or 0 if the resource id is invalid. */
 | 
					/* Returns the size of a resource in bytes, or 0 if the resource id is invalid. */
 | 
				
			||||||
RT_DLLEXPORT size_t rtGetResourceSize(rt_resource_id id);
 | 
					RT_DLLEXPORT size_t rtGetResourceSize(rt_resource_id id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Returns the resource id that maps to a given name.
 | 
				
			||||||
 | 
					 * Does not check if a resource with that id does exist. */
 | 
				
			||||||
 | 
					RT_DLLEXPORT rt_resource_id rtGetResourceID(const char *name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Logs information about a resource. Useful for debugging */
 | 
					/* Logs information about a resource. Useful for debugging */
 | 
				
			||||||
RT_DLLEXPORT void rDebugLogResource(rt_resource_id id, const rt_resource *resource);
 | 
					RT_DLLEXPORT void rDebugLogResource(rt_resource_id id, const rt_resource *resource);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,26 @@ RT_DLLEXPORT void rtLockWrite(rt_rwlock *lock);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
RT_DLLEXPORT void rtUnlockWrite(rt_rwlock *lock);
 | 
					RT_DLLEXPORT void rtUnlockWrite(rt_rwlock *lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Semaphore */
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    volatile int counter;
 | 
				
			||||||
 | 
					    int max;
 | 
				
			||||||
 | 
					    rt_condition_var *cond;
 | 
				
			||||||
 | 
					} rt_semaphore;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    bool ok;
 | 
				
			||||||
 | 
					    rt_semaphore semaphore;
 | 
				
			||||||
 | 
					} rt_create_semaphore_result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_DLLEXPORT rt_create_semaphore_result rtCreateSemaphore(int initial_value, int max_value);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_DLLEXPORT void rtDestroySemaphore(rt_semaphore *sem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_DLLEXPORT void rtSignalSemaphore(rt_semaphore *sem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					RT_DLLEXPORT void rtWaitOnSemaphore(rt_semaphore *sem);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Threads */
 | 
					/* Threads */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct rt_thread_s rt_thread;
 | 
					typedef struct rt_thread_s rt_thread;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,5 @@
 | 
				
			|||||||
#include "threading.h"
 | 
					#include "threading.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <assert.h>
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Based on: https://eli.thegreenplace.net/2019/implementing-reader-writer-locks/ */
 | 
					/* Based on: https://eli.thegreenplace.net/2019/implementing-reader-writer-locks/ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RT_DLLEXPORT rt_create_rwlock_result rtCreateRWLock(void) {
 | 
					RT_DLLEXPORT rt_create_rwlock_result rtCreateRWLock(void) {
 | 
				
			||||||
@ -26,7 +24,7 @@ RT_DLLEXPORT void rtLockRead(rt_rwlock *lock) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
RT_DLLEXPORT void rtUnlockRead(rt_rwlock *lock) {
 | 
					RT_DLLEXPORT void rtUnlockRead(rt_rwlock *lock) {
 | 
				
			||||||
    rtLockConditionVar(lock->cond);
 | 
					    rtLockConditionVar(lock->cond);
 | 
				
			||||||
    assert(lock->reader_count > 0);
 | 
					    RT_ASSERT(lock->reader_count > 0, "Tried to unlock a read-write lock that is not held.");
 | 
				
			||||||
    --lock->reader_count;
 | 
					    --lock->reader_count;
 | 
				
			||||||
    bool signal = lock->reader_count == 0;
 | 
					    bool signal = lock->reader_count == 0;
 | 
				
			||||||
    rtUnlockConditionVar(lock->cond, signal);
 | 
					    rtUnlockConditionVar(lock->cond, signal);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user