feat(vk): Basic command list submit workflow
This commit is contained in:
		
							parent
							
								
									823b9ef9af
								
							
						
					
					
						commit
						33e596c9d6
					
				@ -11,7 +11,7 @@
 | 
				
			|||||||
typedef struct rt_physical_resource_manager_i rt_physical_resource_manager_i;
 | 
					typedef struct rt_physical_resource_manager_i rt_physical_resource_manager_i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef rt_physical_resource_manager_i rt_render_device_get_physical_resource_manager_fn(void *o);
 | 
					typedef rt_physical_resource_manager_i rt_render_device_get_physical_resource_manager_fn(void *o);
 | 
				
			||||||
typedef rt_result rt_render_device_submit_command_list_fn(void *o, rt_render_command_list *list);
 | 
					typedef rt_result rt_render_device_submit_command_list_fn(void *o, const rt_render_command_list *list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Interface for the render device.
 | 
					/* Interface for the render device.
 | 
				
			||||||
 * The device is responsible for executing command lists. */
 | 
					 * The device is responsible for executing command lists. */
 | 
				
			||||||
 | 
				
			|||||||
@ -49,7 +49,7 @@ void CommandListsOnBeginFrame(void) {
 | 
				
			|||||||
#define COMMAND_LIST_MAX_LENGTH (COMMAND_LIST_CAPACITY / AVERAGE_COMMAND_DATA_SIZE)
 | 
					#define COMMAND_LIST_MAX_LENGTH (COMMAND_LIST_CAPACITY / AVERAGE_COMMAND_DATA_SIZE)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get a new render command list. */
 | 
					/* Get a new render command list. */
 | 
				
			||||||
RT_DLLEXPORT rt_begin_render_command_list_result rtBeginRenderCommandList(void) {
 | 
					RT_DLLEXPORT rt_begin_render_command_list_result rtBeginRenderCommandList(rt_render_queue queue) {
 | 
				
			||||||
    size_t mem_required = COMMAND_LIST_MAX_LENGTH * sizeof(rt_render_command_header) + COMMAND_LIST_CAPACITY;
 | 
					    size_t mem_required = COMMAND_LIST_MAX_LENGTH * sizeof(rt_render_command_header) + COMMAND_LIST_CAPACITY;
 | 
				
			||||||
    rtLockMutex(_mutex);
 | 
					    rtLockMutex(_mutex);
 | 
				
			||||||
    void *mem = rtArenaPush(_current_arena, mem_required);
 | 
					    void *mem = rtArenaPush(_current_arena, mem_required);
 | 
				
			||||||
@ -60,6 +60,7 @@ RT_DLLEXPORT rt_begin_render_command_list_result rtBeginRenderCommandList(void)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
    rt_render_command_list list = {
 | 
					    rt_render_command_list list = {
 | 
				
			||||||
        .headers = mem,
 | 
					        .headers = mem,
 | 
				
			||||||
 | 
					        .target_queue = queue,
 | 
				
			||||||
        .data = (void *)((rt_render_command_header *)mem + COMMAND_LIST_MAX_LENGTH),
 | 
					        .data = (void *)((rt_render_command_header *)mem + COMMAND_LIST_MAX_LENGTH),
 | 
				
			||||||
        .length = 0u,
 | 
					        .length = 0u,
 | 
				
			||||||
        .data_capacity =  COMMAND_LIST_CAPACITY,
 | 
					        .data_capacity =  COMMAND_LIST_CAPACITY,
 | 
				
			||||||
@ -72,7 +73,7 @@ RT_DLLEXPORT rt_begin_render_command_list_result rtBeginRenderCommandList(void)
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Lowlevel function that writes the data to the queue. */
 | 
					/* Lowlevel function that writes the data to the queue. */
 | 
				
			||||||
RT_DLLEXPORT rt_result rtEncodeRenderCommand(rt_render_command_list *list, rt_render_command_type type, rt_render_queue queue, const void *data) {
 | 
					RT_DLLEXPORT rt_result rtEncodeRenderCommand(rt_render_command_list *list, rt_render_command_type type, const void *data) {
 | 
				
			||||||
    size_t data_size = 0u;
 | 
					    size_t data_size = 0u;
 | 
				
			||||||
    switch (type) {
 | 
					    switch (type) {
 | 
				
			||||||
    case RT_RENDER_COMMAND_DRAW_INDIRECT:
 | 
					    case RT_RENDER_COMMAND_DRAW_INDIRECT:
 | 
				
			||||||
@ -87,9 +88,7 @@ RT_DLLEXPORT rt_result rtEncodeRenderCommand(rt_render_command_list *list, rt_re
 | 
				
			|||||||
        rtReportError("RENDERER", "Reached maximum lenght or capacity of command list.");
 | 
					        rtReportError("RENDERER", "Reached maximum lenght or capacity of command list.");
 | 
				
			||||||
        return RT_OUT_OF_MEMORY;
 | 
					        return RT_OUT_OF_MEMORY;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					 | 
				
			||||||
    list->headers[list->length].type = type;
 | 
					    list->headers[list->length].type = type;
 | 
				
			||||||
    list->headers[list->length].target_queue = queue;
 | 
					 | 
				
			||||||
    ++list->length;
 | 
					    ++list->length;
 | 
				
			||||||
    char *dest = (char *)list->data + list->data_end;
 | 
					    char *dest = (char *)list->data + list->data_end;
 | 
				
			||||||
    memcpy(dest, data, data_size);
 | 
					    memcpy(dest, data, data_size);
 | 
				
			||||||
@ -97,7 +96,7 @@ RT_DLLEXPORT rt_result rtEncodeRenderCommand(rt_render_command_list *list, rt_re
 | 
				
			|||||||
    return RT_SUCCESS;
 | 
					    return RT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Submit a finished command list to the graphics device. The list will not be usable after this function is done. */
 | 
					/* Submit a finished command list to the graphics device. */
 | 
				
			||||||
RT_DLLEXPORT rt_result rtSubmitCommandList(rt_render_command_list *list) {
 | 
					RT_DLLEXPORT rt_result rtSubmitCommandList(const rt_render_command_list *list) {
 | 
				
			||||||
    return g_device_i.SubmitCommandList(g_device_i.o, list);
 | 
					    return g_device_i.SubmitCommandList(g_device_i.o, list);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -8,6 +8,9 @@
 | 
				
			|||||||
/* Types of render commands */
 | 
					/* Types of render commands */
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
    RT_RENDER_COMMAND_DRAW_INDIRECT,
 | 
					    RT_RENDER_COMMAND_DRAW_INDIRECT,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    RT_RENDER_COMMAND_COUNT,
 | 
				
			||||||
} rt_render_command_type;
 | 
					} rt_render_command_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef enum {
 | 
					typedef enum {
 | 
				
			||||||
@ -27,15 +30,21 @@ typedef struct {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
    uint32_t type;
 | 
					    uint32_t type;
 | 
				
			||||||
    uint32_t target_queue;
 | 
					 | 
				
			||||||
} rt_render_command_header;
 | 
					} rt_render_command_header;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct {
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    /* One header per command */
 | 
				
			||||||
    rt_render_command_header *headers;
 | 
					    rt_render_command_header *headers;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Contains the command data */
 | 
				
			||||||
    void *data;
 | 
					    void *data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Number of encoded commands */
 | 
					    /* Number of encoded commands */
 | 
				
			||||||
    uint32_t length;
 | 
					    uint32_t length;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Tne device queue to which this list should be submitted*/
 | 
				
			||||||
 | 
					    uint32_t target_queue;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Information used while encoding.
 | 
					    /* Information used while encoding.
 | 
				
			||||||
     * In the future, it would be possible to move this to another struct that is discarded after
 | 
					     * In the future, it would be possible to move this to another struct that is discarded after
 | 
				
			||||||
     * encoding is finished.
 | 
					     * encoding is finished.
 | 
				
			||||||
@ -57,20 +66,20 @@ typedef struct {
 | 
				
			|||||||
} rt_begin_render_command_list_result;
 | 
					} rt_begin_render_command_list_result;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Get a new render command list. */
 | 
					/* Get a new render command list. */
 | 
				
			||||||
RT_DLLEXPORT rt_begin_render_command_list_result rtBeginRenderCommandList(void);
 | 
					RT_DLLEXPORT rt_begin_render_command_list_result rtBeginRenderCommandList(rt_render_queue queue);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Lowlevel function that writes the data to the queue. */
 | 
					/* Lowlevel function that writes the data to the queue. */
 | 
				
			||||||
RT_DLLEXPORT rt_result rtEncodeRenderCommand(rt_render_command_list *list, rt_render_command_type type, rt_render_queue queue, const void *data);
 | 
					RT_DLLEXPORT rt_result rtEncodeRenderCommand(rt_render_command_list *list, rt_render_command_type type, const void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Helper functions for specific commands */
 | 
					/* Helper functions for specific commands */
 | 
				
			||||||
RT_INLINE rt_result rtEncodeDrawIndirect(rt_render_command_list *list, const rt_draw_indirect_data *draw_indirect_data) {
 | 
					RT_INLINE rt_result rtEncodeDrawIndirect(rt_render_command_list *list, const rt_draw_indirect_data *draw_indirect_data) {
 | 
				
			||||||
    return rtEncodeRenderCommand(list, RT_RENDER_COMMAND_DRAW_INDIRECT, RT_RENDER_QUEUE_GRAPHICS, draw_indirect_data);
 | 
					    return rtEncodeRenderCommand(list, RT_RENDER_COMMAND_DRAW_INDIRECT, draw_indirect_data);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* *** Submission *** */
 | 
					/* *** Submission *** */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Submit a finished command list to the graphics device. The list will not be usable after this function is done. */
 | 
					/* Submit a finished command list to the graphics device. */
 | 
				
			||||||
RT_DLLEXPORT rt_result rtSubmitCommandList(rt_render_command_list *list);
 | 
					RT_DLLEXPORT rt_result rtSubmitCommandList(const rt_render_command_list *list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										196
									
								
								src/renderer/vk/command_buffers.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								src/renderer/vk/command_buffers.c
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,196 @@
 | 
				
			|||||||
 | 
					#include "command_buffers.h"
 | 
				
			||||||
 | 
					#include "device.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* We need one command pool per frame per thread. */
 | 
				
			||||||
 | 
					#include <stdlib.h>
 | 
				
			||||||
 | 
					#include <volk/volk.h>
 | 
				
			||||||
 | 
					#include <runtime/runtime.h>
 | 
				
			||||||
 | 
					#include <runtime/atomics.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rt_vk_command_pool_set {
 | 
				
			||||||
 | 
					    VkCommandPool graphics;
 | 
				
			||||||
 | 
					    VkCommandPool compute;
 | 
				
			||||||
 | 
					    VkCommandPool transfer;
 | 
				
			||||||
 | 
					} ;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    long indices[3];
 | 
				
			||||||
 | 
					} rt_thread_pool_indices;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static RT_THREAD_LOCAL rt_thread_pool_indices t_pool_indices;
 | 
				
			||||||
 | 
					static RT_THREAD_LOCAL bool t_are_indices_initialized[3] = {false, false, false};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rt_vk_command_pool_array rtReserveCommandPoolArray(long max_threads) {
 | 
				
			||||||
 | 
					    rt_vk_command_pool_array array;
 | 
				
			||||||
 | 
					    array.next_unused = 0;
 | 
				
			||||||
 | 
					    array.capacity = 0;
 | 
				
			||||||
 | 
					    array.pools = calloc(max_threads, sizeof(rt_vk_command_pool_set));
 | 
				
			||||||
 | 
					    if (!array.pools)
 | 
				
			||||||
 | 
					        return array;
 | 
				
			||||||
 | 
					    array.capacity = max_threads;
 | 
				
			||||||
 | 
					    return array;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void rtReleaseCommandPoolArray(rt_vk_command_pool_array *array) {
 | 
				
			||||||
 | 
					    free(array->pools);
 | 
				
			||||||
 | 
					    array->pools = NULL;
 | 
				
			||||||
 | 
					    array->capacity = 0;
 | 
				
			||||||
 | 
					    array->next_unused = 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static rt_vk_command_pool_set *GetThreadsPoolSet(rt_vk_device *dev, uint32_t frame_id) {
 | 
				
			||||||
 | 
					    uint32_t slot = frame_id % dev->max_frames_in_flight;
 | 
				
			||||||
 | 
					    if (!t_are_indices_initialized[slot]) {
 | 
				
			||||||
 | 
					        /* Alloc the set */
 | 
				
			||||||
 | 
					        rt_vk_command_pool_set *set = NULL;
 | 
				
			||||||
 | 
					        long index = rtAtomic32Inc(&dev->frames[slot].command_pools.next_unused) - 1; /* Inc returns the new value */
 | 
				
			||||||
 | 
					        if (index >= dev->frames[slot].command_pools.capacity) {
 | 
				
			||||||
 | 
					            rtReportError("VK", "Ran out of space for per-thread command buffers. Try to increase r_VkMaxThreads");
 | 
				
			||||||
 | 
					            return NULL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        set = &dev->frames[slot].command_pools.pools[index];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        /* Create the pools */
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            VkCommandPoolCreateInfo pool_info = {
 | 
				
			||||||
 | 
					                .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
 | 
				
			||||||
 | 
					                .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
 | 
				
			||||||
 | 
					                .queueFamilyIndex = dev->graphics_family,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            if (vkCreateCommandPool(dev->device, &pool_info, dev->alloc_cb, &set->graphics) != VK_SUCCESS) {
 | 
				
			||||||
 | 
					                rtReportError("VK", "vkCreateCommandPool failed.");
 | 
				
			||||||
 | 
					                return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#ifdef RT_DEBUG
 | 
				
			||||||
 | 
					            uint32_t thread_id = rtGetCurrentThreadId();
 | 
				
			||||||
 | 
					            char name[128];
 | 
				
			||||||
 | 
					            rtSPrint(name, 128, "Graphics Command Pool (FrameSlot %u, Thread %u)", slot, thread_id);
 | 
				
			||||||
 | 
					            VkDebugUtilsObjectNameInfoEXT name_info = {
 | 
				
			||||||
 | 
					                .sType        = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
 | 
				
			||||||
 | 
					                .objectHandle = (uint64_t)set->graphics,
 | 
				
			||||||
 | 
					                .objectType   = VK_OBJECT_TYPE_COMMAND_POOL,
 | 
				
			||||||
 | 
					                .pObjectName  = name,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            vkSetDebugUtilsObjectNameEXT(dev->device, &name_info);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (dev->compute_family != dev->graphics_family) {
 | 
				
			||||||
 | 
					            VkCommandPoolCreateInfo pool_info = {
 | 
				
			||||||
 | 
					                .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
 | 
				
			||||||
 | 
					                .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
 | 
				
			||||||
 | 
					                .queueFamilyIndex = dev->compute_family,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            if (vkCreateCommandPool(dev->device, &pool_info, dev->alloc_cb, &set->compute) != VK_SUCCESS) {
 | 
				
			||||||
 | 
					                rtReportError("VK", "vkCreateCommandPool failed.");
 | 
				
			||||||
 | 
					                return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#ifdef RT_DEBUG
 | 
				
			||||||
 | 
					            uint32_t thread_id = rtGetCurrentThreadId();
 | 
				
			||||||
 | 
					            char name[128];
 | 
				
			||||||
 | 
					            rtSPrint(name, 128, "Compute Command Pool (FrameSlot %u, Thread %u)", slot, thread_id);
 | 
				
			||||||
 | 
					            VkDebugUtilsObjectNameInfoEXT name_info = {
 | 
				
			||||||
 | 
					                .sType        = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
 | 
				
			||||||
 | 
					                .objectHandle = (uint64_t)set->compute,
 | 
				
			||||||
 | 
					                .objectType   = VK_OBJECT_TYPE_COMMAND_POOL,
 | 
				
			||||||
 | 
					                .pObjectName  = name,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            vkSetDebugUtilsObjectNameEXT(dev->device, &name_info);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            set->compute = set->graphics;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        if (dev->transfer_family != dev->graphics_family && dev->transfer_family != dev->compute_family) {
 | 
				
			||||||
 | 
					            VkCommandPoolCreateInfo pool_info = {
 | 
				
			||||||
 | 
					                .sType = VK_STRUCTURE_TYPE_COMMAND_POOL_CREATE_INFO,
 | 
				
			||||||
 | 
					                .flags = VK_COMMAND_POOL_CREATE_TRANSIENT_BIT,
 | 
				
			||||||
 | 
					                .queueFamilyIndex = dev->transfer_family,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            if (vkCreateCommandPool(dev->device, &pool_info, dev->alloc_cb, &set->transfer) != VK_SUCCESS) {
 | 
				
			||||||
 | 
					                rtReportError("VK", "vkCreateCommandPool failed.");
 | 
				
			||||||
 | 
					                return NULL;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					#ifdef RT_DEBUG
 | 
				
			||||||
 | 
					            uint32_t thread_id = rtGetCurrentThreadId();
 | 
				
			||||||
 | 
					            char name[128];
 | 
				
			||||||
 | 
					            rtSPrint(name, 128, "Transfer Command Pool (FrameSlot %u, Thread %u)", slot, thread_id);
 | 
				
			||||||
 | 
					            VkDebugUtilsObjectNameInfoEXT name_info = {
 | 
				
			||||||
 | 
					                .sType        = VK_STRUCTURE_TYPE_DEBUG_UTILS_OBJECT_NAME_INFO_EXT,
 | 
				
			||||||
 | 
					                .objectHandle = (uint64_t)set->transfer,
 | 
				
			||||||
 | 
					                .objectType   = VK_OBJECT_TYPE_COMMAND_POOL,
 | 
				
			||||||
 | 
					                .pObjectName  = name,
 | 
				
			||||||
 | 
					            };
 | 
				
			||||||
 | 
					            vkSetDebugUtilsObjectNameEXT(dev->device, &name_info);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else if (dev->transfer_family == dev->graphics_family) {
 | 
				
			||||||
 | 
					            set->transfer = set->graphics;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            RT_ASSERT(dev->transfer_family == dev->compute_family, "");
 | 
				
			||||||
 | 
					            set->transfer = set->compute;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        t_pool_indices.indices[slot] = index;
 | 
				
			||||||
 | 
					        t_are_indices_initialized[slot] = true;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    long index = t_pool_indices.indices[slot];
 | 
				
			||||||
 | 
					#ifdef RT_DEBUG
 | 
				
			||||||
 | 
					    if (index >= dev->frames[slot].command_pools.next_unused)
 | 
				
			||||||
 | 
					        return NULL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					    return &dev->frames[slot].command_pools.pools[index];
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VkCommandPool rtGetGraphicsCommandPool(rt_vk_device *dev) {
 | 
				
			||||||
 | 
					    rt_vk_command_pool_set *set = GetThreadsPoolSet(dev, dev->current_frame_id);
 | 
				
			||||||
 | 
					    return RT_VERIFY(set)->graphics;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VkCommandPool rtGetComputeCommandPool(rt_vk_device *dev) {
 | 
				
			||||||
 | 
					    rt_vk_command_pool_set *set = GetThreadsPoolSet(dev, dev->current_frame_id);
 | 
				
			||||||
 | 
					    return RT_VERIFY(set)->compute;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VkCommandPool rtGetTransferCommandPool(rt_vk_device *dev) {
 | 
				
			||||||
 | 
					    rt_vk_command_pool_set *set = GetThreadsPoolSet(dev, dev->current_frame_id);
 | 
				
			||||||
 | 
					    return RT_VERIFY(set)->transfer;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VkCommandBuffer rtAllocateGraphicsCommandBuffer(rt_vk_device *dev) {
 | 
				
			||||||
 | 
					    VkCommandPool pool = rtGetGraphicsCommandPool(dev);
 | 
				
			||||||
 | 
					    VkCommandBufferAllocateInfo alloc_info = {
 | 
				
			||||||
 | 
					        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
 | 
				
			||||||
 | 
					        .commandPool =  pool,
 | 
				
			||||||
 | 
					        .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
 | 
				
			||||||
 | 
					        .commandBufferCount = 1,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    VkCommandBuffer cmdbuf = VK_NULL_HANDLE;
 | 
				
			||||||
 | 
					    vkAllocateCommandBuffers(dev->device, &alloc_info, &cmdbuf);
 | 
				
			||||||
 | 
					    return cmdbuf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VkCommandBuffer rtAllocateComputeCommandBuffer(rt_vk_device *dev) {
 | 
				
			||||||
 | 
					    VkCommandPool pool = rtGetComputeCommandPool(dev);
 | 
				
			||||||
 | 
					    VkCommandBufferAllocateInfo alloc_info = {
 | 
				
			||||||
 | 
					        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
 | 
				
			||||||
 | 
					        .commandPool =  pool,
 | 
				
			||||||
 | 
					        .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
 | 
				
			||||||
 | 
					        .commandBufferCount = 1,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    VkCommandBuffer cmdbuf = VK_NULL_HANDLE;
 | 
				
			||||||
 | 
					    vkAllocateCommandBuffers(dev->device, &alloc_info, &cmdbuf);
 | 
				
			||||||
 | 
					    return cmdbuf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VkCommandBuffer rtAllocateTransferCommandBuffer(rt_vk_device *dev) {
 | 
				
			||||||
 | 
					    VkCommandPool pool = rtGetTransferCommandPool(dev);
 | 
				
			||||||
 | 
					    VkCommandBufferAllocateInfo alloc_info = {
 | 
				
			||||||
 | 
					        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_ALLOCATE_INFO,
 | 
				
			||||||
 | 
					        .commandPool =  pool,
 | 
				
			||||||
 | 
					        .level = VK_COMMAND_BUFFER_LEVEL_PRIMARY,
 | 
				
			||||||
 | 
					        .commandBufferCount = 1,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    VkCommandBuffer cmdbuf = VK_NULL_HANDLE;
 | 
				
			||||||
 | 
					    vkAllocateCommandBuffers(dev->device, &alloc_info, &cmdbuf);
 | 
				
			||||||
 | 
					    return cmdbuf;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								src/renderer/vk/command_buffers.h
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								src/renderer/vk/command_buffers.h
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					#ifndef RT_VK_COMMAND_LISTS_H
 | 
				
			||||||
 | 
					#define RT_VK_COMMAND_LISTS_H
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include <volk/volk.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					struct rt_vk_device;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef struct rt_vk_command_pool_set rt_vk_command_pool_set;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* Contains an array of command pools. Threads safe an index into the array
 | 
				
			||||||
 | 
					 * to access their own command pool set. */
 | 
				
			||||||
 | 
					typedef struct {
 | 
				
			||||||
 | 
					    rt_vk_command_pool_set *pools;
 | 
				
			||||||
 | 
					    long capacity;
 | 
				
			||||||
 | 
					    long next_unused;
 | 
				
			||||||
 | 
					} rt_vk_command_pool_array;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rt_vk_command_pool_array rtReserveCommandPoolArray(long max_threads);
 | 
				
			||||||
 | 
					void rtReleaseCommandPoolArray(rt_vk_command_pool_array *array);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VkCommandPool rtGetGraphicsCommandPool(struct rt_vk_device *dev);
 | 
				
			||||||
 | 
					VkCommandPool rtGetComputeCommandPool(struct rt_vk_device *dev);
 | 
				
			||||||
 | 
					VkCommandPool rtGetTransferCommandPool(struct rt_vk_device *dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					VkCommandBuffer rtAllocateGraphicsCommandBuffer(struct rt_vk_device *dev);
 | 
				
			||||||
 | 
					VkCommandBuffer rtAllocateComputeCommandBuffer(struct rt_vk_device *dev);
 | 
				
			||||||
 | 
					VkCommandBuffer rtAllocateTransferCommandBuffer(struct rt_vk_device *dev);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
@ -19,6 +19,7 @@ RT_CVAR_I(r_VkEnableAPIAllocTracking,
 | 
				
			|||||||
RT_CVAR_S(r_VkPhysDeviceName, "Name of the selected physical device. Default: \"\"", "");
 | 
					RT_CVAR_S(r_VkPhysDeviceName, "Name of the selected physical device. Default: \"\"", "");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
RT_CVAR_I(r_VkMaxFramesInFlight, "Maximum number of frames in flight. [2/3] Default: 2", 2);
 | 
					RT_CVAR_I(r_VkMaxFramesInFlight, "Maximum number of frames in flight. [2/3] Default: 2", 2);
 | 
				
			||||||
 | 
					RT_CVAR_UI(r_VkMaxThreads, "Maximum number of threads used. (Default: 128)", 128);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static VkAllocationCallbacks _tracking_alloc_cbs;
 | 
					static VkAllocationCallbacks _tracking_alloc_cbs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -564,6 +565,8 @@ static rt_result CreatePerFrameObjects(rt_vk_device *dev) {
 | 
				
			|||||||
        name_info.objectHandle = (uint64_t)dev->frames[i].swapchain_transitioned;
 | 
					        name_info.objectHandle = (uint64_t)dev->frames[i].swapchain_transitioned;
 | 
				
			||||||
        vkSetDebugUtilsObjectNameEXT(dev->device, &name_info);
 | 
					        vkSetDebugUtilsObjectNameEXT(dev->device, &name_info);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        dev->frames[i].command_pools = rtReserveCommandPoolArray(r_VkMaxThreads.ui);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return RT_SUCCESS;
 | 
					    return RT_SUCCESS;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -627,6 +630,10 @@ rt_create_vk_device_result rtCreateVkDevice(const rt_renderer_window_info *info)
 | 
				
			|||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    dev.bindless_registry = bindless_registry_result.bindless_registry;
 | 
					    dev.bindless_registry = bindless_registry_result.bindless_registry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dev.created_pools = calloc(128 * 9, sizeof(VkCommandPool));
 | 
				
			||||||
 | 
					    dev.created_pool_count = 0;
 | 
				
			||||||
 | 
					    dev.max_created_pools = 128 * 9;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    rt_time_delta initTime = rtTimeBetween(initBegin, rtTimeNow());
 | 
					    rt_time_delta initTime = rtTimeBetween(initBegin, rtTimeNow());
 | 
				
			||||||
    rtLog("VK", "Init complete. Took %lf seconds.", initTime);
 | 
					    rtLog("VK", "Init complete. Took %lf seconds.", initTime);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -637,6 +644,7 @@ out:
 | 
				
			|||||||
void rtDestroyVkDevice(rt_vk_device *dev) {
 | 
					void rtDestroyVkDevice(rt_vk_device *dev) {
 | 
				
			||||||
    rtLog("VK", "Shutdown");
 | 
					    rtLog("VK", "Shutdown");
 | 
				
			||||||
    vkDeviceWaitIdle(dev->device);
 | 
					    vkDeviceWaitIdle(dev->device);
 | 
				
			||||||
 | 
					    free(dev->created_pools);
 | 
				
			||||||
    rtDestroyVkBindlessRegistry(&dev->bindless_registry);
 | 
					    rtDestroyVkBindlessRegistry(&dev->bindless_registry);
 | 
				
			||||||
    rtDestroyVkPhysicalResourceManager(&dev->phys_res_mgr);
 | 
					    rtDestroyVkPhysicalResourceManager(&dev->phys_res_mgr);
 | 
				
			||||||
    DestroySwapchain(dev);
 | 
					    DestroySwapchain(dev);
 | 
				
			||||||
@ -662,25 +670,98 @@ rt_physical_resource_manager_i rtVkDevGetPhysicalResourceManager(void *o) {
 | 
				
			|||||||
    return iface;
 | 
					    return iface;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
rt_result rtVkDevSubmitCommandList(void *o, rt_render_command_list *list) {
 | 
					 | 
				
			||||||
    /* Dummy implementation */
 | 
					 | 
				
			||||||
    RT_UNUSED(o);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    size_t data_off = 0;
 | 
					/* Commands */
 | 
				
			||||||
    for (uint32_t i = 0; i < list->length; ++i) {
 | 
					static rt_result DrawIndirectImpl(rt_vk_device *dev, VkCommandBuffer cmdbuf, const void *_data) {
 | 
				
			||||||
        if (list->headers[i].type != RT_RENDER_COMMAND_DRAW_INDIRECT)
 | 
					    const rt_draw_indirect_data *data = _data;
 | 
				
			||||||
            break;
 | 
					    const rt_vk_physical_resource *buffer_resource = rtGetVkPhysicalResource(&dev->phys_res_mgr, data->buffer);
 | 
				
			||||||
        rtLog("VK", "DrawIndirect %u", i);
 | 
					    if (!buffer_resource) {
 | 
				
			||||||
        rtLog("VK", "Target queue: %u", list->headers[i].target_queue);
 | 
					        rtLog("VK", "Invalid buffer in draw indirect data");
 | 
				
			||||||
 | 
					        return RT_INVALID_VALUE;
 | 
				
			||||||
        RT_VERIFY(data_off < list->data_end);
 | 
					 | 
				
			||||||
        rt_draw_indirect_data *data = (rt_draw_indirect_data *)((char *)list->data + data_off);
 | 
					 | 
				
			||||||
        rtLog("VK", "buffer %u draw_count %u offset %u stride %u",
 | 
					 | 
				
			||||||
            data->buffer.value,
 | 
					 | 
				
			||||||
            data->draw_count,
 | 
					 | 
				
			||||||
            data->offset,
 | 
					 | 
				
			||||||
            data->stride);
 | 
					 | 
				
			||||||
        data_off += sizeof(rt_draw_indirect_data);
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    RT_ASSERT(buffer_resource->type == RT_RENDER_RESOURCE_TYPE_BUFFER,
 | 
				
			||||||
 | 
					        "Buffer handle in draw indirect data does not reference a buffer object");
 | 
				
			||||||
 | 
					    vkCmdDrawIndirect(cmdbuf, buffer_resource->buffer, data->offset, data->draw_count, data->stride);
 | 
				
			||||||
    return RT_SUCCESS;
 | 
					    return RT_SUCCESS;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					typedef rt_result rt_vk_render_command_impl_fn(rt_vk_device *dev, VkCommandBuffer cmdbuf, const void *data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static size_t _command_data_sizes[RT_RENDER_COMMAND_COUNT] = {
 | 
				
			||||||
 | 
					    sizeof(rt_draw_indirect_data),
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static rt_vk_render_command_impl_fn *_command_impls[RT_RENDER_COMMAND_COUNT] = {
 | 
				
			||||||
 | 
					    DrawIndirectImpl,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rt_result rtVkDevSubmitCommandList(void *o, const rt_render_command_list *list) {
 | 
				
			||||||
 | 
					    rt_vk_device *dev = o;
 | 
				
			||||||
 | 
					    size_t data_off = 0;
 | 
				
			||||||
 | 
					    rt_result res = RT_SUCCESS;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Prepare command buffer */
 | 
				
			||||||
 | 
					    VkQueue queue = VK_NULL_HANDLE;
 | 
				
			||||||
 | 
					    VkCommandBuffer cmdbuf = VK_NULL_HANDLE;
 | 
				
			||||||
 | 
					    if (list->target_queue == RT_RENDER_QUEUE_GRAPHICS) {
 | 
				
			||||||
 | 
					        cmdbuf = rtAllocateComputeCommandBuffer(dev);
 | 
				
			||||||
 | 
					        queue = dev->graphics_queue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (list->target_queue == RT_RENDER_QUEUE_COMPUTE) {
 | 
				
			||||||
 | 
					        cmdbuf = rtAllocateComputeCommandBuffer(dev);
 | 
				
			||||||
 | 
					        queue = dev->compute_queue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else if (list->target_queue == RT_RENDER_QUEUE_TRANSFER) {
 | 
				
			||||||
 | 
					        cmdbuf = rtAllocateTransferCommandBuffer(dev);
 | 
				
			||||||
 | 
					        queue = dev->transfer_queue;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        RT_ASSERT("VK", "Invalid target queue");
 | 
				
			||||||
 | 
					        return RT_INVALID_VALUE;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    VkCommandBufferBeginInfo begin_info = {.sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_BEGIN_INFO,
 | 
				
			||||||
 | 
					    .flags = VK_COMMAND_BUFFER_USAGE_ONE_TIME_SUBMIT_BIT};
 | 
				
			||||||
 | 
					    if (vkBeginCommandBuffer(cmdbuf, &begin_info) != VK_SUCCESS) {
 | 
				
			||||||
 | 
					        rtLog("VK", "vkBeginCommandBuffer failed");
 | 
				
			||||||
 | 
					        return RT_UNKNOWN_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Iterate over all commands and decode them */
 | 
				
			||||||
 | 
					    for (uint32_t i = 0; i < list->length; ++i) {
 | 
				
			||||||
 | 
					        rt_render_command_header header = list->headers[i];
 | 
				
			||||||
 | 
					        RT_ASSERT(header.type < RT_RENDER_COMMAND_COUNT,
 | 
				
			||||||
 | 
					            "Invalid render command type.");
 | 
				
			||||||
 | 
					        const void *data = (const char *)list->data + data_off;
 | 
				
			||||||
 | 
					        res = _command_impls[header.type](dev, cmdbuf, data);
 | 
				
			||||||
 | 
					        if (res != RT_SUCCESS)
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
 | 
					        data_off += _command_data_sizes[header.type];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (res != RT_SUCCESS) {
 | 
				
			||||||
 | 
					        return res;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* End the command buffers and create submit info */
 | 
				
			||||||
 | 
					    vkEndCommandBuffer(cmdbuf);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Submit it! */
 | 
				
			||||||
 | 
					    VkCommandBufferSubmitInfo cmdbuf_info = {
 | 
				
			||||||
 | 
					        .sType = VK_STRUCTURE_TYPE_COMMAND_BUFFER_SUBMIT_INFO,
 | 
				
			||||||
 | 
					        .commandBuffer = cmdbuf
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    VkSubmitInfo2 submit_info = {
 | 
				
			||||||
 | 
					        .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO_2,
 | 
				
			||||||
 | 
					        .commandBufferInfoCount = 1,
 | 
				
			||||||
 | 
					        .pCommandBufferInfos = &cmdbuf_info,
 | 
				
			||||||
 | 
					        .waitSemaphoreInfoCount = 0,
 | 
				
			||||||
 | 
					        .pWaitSemaphoreInfos = NULL,
 | 
				
			||||||
 | 
					        .signalSemaphoreInfoCount = 0,
 | 
				
			||||||
 | 
					        .pSignalSemaphoreInfos = NULL,
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    if (vkQueueSubmit2(queue, 1, &submit_info, VK_NULL_HANDLE) != VK_SUCCESS) {
 | 
				
			||||||
 | 
					        rtLog("VK"," vkQueueSubmit2 failed");
 | 
				
			||||||
 | 
					        res = RT_UNKNOWN_ERROR;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return res;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -8,6 +8,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "physical_resource_manager.h"
 | 
					#include "physical_resource_manager.h"
 | 
				
			||||||
#include "bindless_registry.h"
 | 
					#include "bindless_registry.h"
 | 
				
			||||||
 | 
					#include "command_buffers.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _WIN32
 | 
					#ifdef _WIN32
 | 
				
			||||||
struct HINSTANCE__;
 | 
					struct HINSTANCE__;
 | 
				
			||||||
@ -31,6 +32,8 @@ typedef struct {
 | 
				
			|||||||
    VkSemaphore render_finished;
 | 
					    VkSemaphore render_finished;
 | 
				
			||||||
    VkSemaphore image_available;
 | 
					    VkSemaphore image_available;
 | 
				
			||||||
    VkSemaphore swapchain_transitioned;
 | 
					    VkSemaphore swapchain_transitioned;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    rt_vk_command_pool_array command_pools;
 | 
				
			||||||
} rt_vk_frame_data;
 | 
					} rt_vk_frame_data;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef struct rt_vk_device {
 | 
					typedef struct rt_vk_device {
 | 
				
			||||||
@ -76,6 +79,11 @@ typedef struct rt_vk_device {
 | 
				
			|||||||
    rt_vk_physical_resource_manager phys_res_mgr;
 | 
					    rt_vk_physical_resource_manager phys_res_mgr;
 | 
				
			||||||
    rt_vk_bindless_registry bindless_registry;
 | 
					    rt_vk_bindless_registry bindless_registry;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* *** Save created command pools in a list to clean them up at exit */
 | 
				
			||||||
 | 
					    VkCommandPool *created_pools;
 | 
				
			||||||
 | 
					    long created_pool_count;
 | 
				
			||||||
 | 
					    long max_created_pools;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* *** Debug utils *** */
 | 
					    /* *** Debug utils *** */
 | 
				
			||||||
#ifdef RT_DEBUG
 | 
					#ifdef RT_DEBUG
 | 
				
			||||||
    VkDebugUtilsMessengerEXT messenger;
 | 
					    VkDebugUtilsMessengerEXT messenger;
 | 
				
			||||||
@ -93,6 +101,6 @@ void rtDestroyVkDevice(rt_vk_device *dev);
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* rt_render_device_i functions */
 | 
					/* rt_render_device_i functions */
 | 
				
			||||||
rt_physical_resource_manager_i rtVkDevGetPhysicalResourceManager(void *o);
 | 
					rt_physical_resource_manager_i rtVkDevGetPhysicalResourceManager(void *o);
 | 
				
			||||||
rt_result rtVkDevSubmitCommandList(void *o, rt_render_command_list *list);
 | 
					rt_result rtVkDevSubmitCommandList(void *o, const rt_render_command_list *list);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -7,6 +7,7 @@
 | 
				
			|||||||
extern rt_cvar r_VkEnableAPIAllocTracking;
 | 
					extern rt_cvar r_VkEnableAPIAllocTracking;
 | 
				
			||||||
extern rt_cvar r_VkPhysDeviceName;
 | 
					extern rt_cvar r_VkPhysDeviceName;
 | 
				
			||||||
extern rt_cvar r_VkMaxFramesInFlight;
 | 
					extern rt_cvar r_VkMaxFramesInFlight;
 | 
				
			||||||
 | 
					extern rt_cvar r_VkMaxThreads;
 | 
				
			||||||
extern rt_cvar r_VkPreferMailboxMode;
 | 
					extern rt_cvar r_VkPreferMailboxMode;
 | 
				
			||||||
extern rt_cvar r_VkPreferRelaxedMode;
 | 
					extern rt_cvar r_VkPreferRelaxedMode;
 | 
				
			||||||
extern rt_cvar r_VkEnableVSync;
 | 
					extern rt_cvar r_VkEnableVSync;
 | 
				
			||||||
@ -21,6 +22,7 @@ void VkRegisterCVARs(void) {
 | 
				
			|||||||
    rtRegisterCVAR(&r_VkEnableAPIAllocTracking);
 | 
					    rtRegisterCVAR(&r_VkEnableAPIAllocTracking);
 | 
				
			||||||
    rtRegisterCVAR(&r_VkPhysDeviceName);
 | 
					    rtRegisterCVAR(&r_VkPhysDeviceName);
 | 
				
			||||||
    rtRegisterCVAR(&r_VkMaxFramesInFlight);
 | 
					    rtRegisterCVAR(&r_VkMaxFramesInFlight);
 | 
				
			||||||
 | 
					    rtRegisterCVAR(&r_VkMaxThreads);
 | 
				
			||||||
    rtRegisterCVAR(&r_VkPreferMailboxMode);
 | 
					    rtRegisterCVAR(&r_VkPreferMailboxMode);
 | 
				
			||||||
    rtRegisterCVAR(&r_VkPreferRelaxedMode);
 | 
					    rtRegisterCVAR(&r_VkPreferRelaxedMode);
 | 
				
			||||||
    rtRegisterCVAR(&r_VkEnableVSync);
 | 
					    rtRegisterCVAR(&r_VkEnableVSync);
 | 
				
			||||||
 | 
				
			|||||||
@ -14,10 +14,12 @@ if get_option('build_vk')
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  vk_renderer_lib = library('rtvk',
 | 
					  vk_renderer_lib = library('rtvk',
 | 
				
			||||||
    'bindless_registry.h',
 | 
					    'bindless_registry.h',
 | 
				
			||||||
 | 
					    'command_buffers.h',
 | 
				
			||||||
    'device.h',
 | 
					    'device.h',
 | 
				
			||||||
    'physical_resource_manager.h',
 | 
					    'physical_resource_manager.h',
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    'bindless_registry.c',
 | 
					    'bindless_registry.c',
 | 
				
			||||||
 | 
					    'command_buffers.c',
 | 
				
			||||||
    'device.c',
 | 
					    'device.c',
 | 
				
			||||||
    'init.c',
 | 
					    'init.c',
 | 
				
			||||||
    'physical_resource_manager.c',
 | 
					    'physical_resource_manager.c',
 | 
				
			||||||
 | 
				
			|||||||
@ -147,6 +147,17 @@ void rtVkPhysicalResourceManagerDestroy(void *o, rt_render_resource_handle handl
 | 
				
			|||||||
    rtUnlockWrite(&phys_res_mgr->lock);
 | 
					    rtUnlockWrite(&phys_res_mgr->lock);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rt_vk_physical_resource *rtGetVkPhysicalResource(rt_vk_physical_resource_manager *phys_res_mgr, rt_render_resource_handle handle) {
 | 
				
			||||||
 | 
					    rt_vk_physical_resource *resource = NULL;
 | 
				
			||||||
 | 
					    rtLockRead(&phys_res_mgr->lock);
 | 
				
			||||||
 | 
					    uint32_t slot = rtHashtableLookup(&phys_res_mgr->resource_lut, handle.value, UINT32_MAX);
 | 
				
			||||||
 | 
					    if (slot != UINT32_MAX) {
 | 
				
			||||||
 | 
					        resource = &phys_res_mgr->resources[slot];
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    rtUnlockRead(&phys_res_mgr->lock);
 | 
				
			||||||
 | 
					    return resource;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* Call this with a held write lock! */
 | 
					/* Call this with a held write lock! */
 | 
				
			||||||
static uint32_t AllocStorageSlot(rt_vk_physical_resource_manager *phys_res_mgr, rt_render_resource_handle h) {
 | 
					static uint32_t AllocStorageSlot(rt_vk_physical_resource_manager *phys_res_mgr, rt_render_resource_handle h) {
 | 
				
			||||||
    if (phys_res_mgr->free_slot_count > 0u) {
 | 
					    if (phys_res_mgr->free_slot_count > 0u) {
 | 
				
			||||||
 | 
				
			|||||||
@ -52,6 +52,8 @@ rt_create_vk_physical_resource_manager_result rtCreateVkPhysicalResourceManager(
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void rtDestroyVkPhysicalResourceManager(rt_vk_physical_resource_manager *phys_res_mgr);
 | 
					void rtDestroyVkPhysicalResourceManager(rt_vk_physical_resource_manager *phys_res_mgr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					rt_vk_physical_resource *rtGetVkPhysicalResource(rt_vk_physical_resource_manager *phys_res_mgr, rt_render_resource_handle handle);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* rt_physical_resource_manager_i functions */
 | 
					/* rt_physical_resource_manager_i functions */
 | 
				
			||||||
bool rtVkPhysicalResourceManagerIsPresent(void *o, rt_render_resource_handle handle);
 | 
					bool rtVkPhysicalResourceManagerIsPresent(void *o, rt_render_resource_handle handle);
 | 
				
			||||||
void rtVkPhysicalResourceManagerDestroy(void *o, rt_render_resource_handle handle);
 | 
					void rtVkPhysicalResourceManagerDestroy(void *o, rt_render_resource_handle handle);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user