rename the engine to recreational.tech

This commit is contained in:
Kevin Trogant 2024-01-16 16:10:56 +01:00
parent 448d448430
commit abb367dffc
69 changed files with 1759 additions and 1756 deletions

3
.gitignore vendored
View File

@ -5,3 +5,6 @@
# assetc directories # assetc directories
/actemp/* /actemp/*
/data/* /data/*
/.cache/*
/.vs/*

View File

@ -22,16 +22,16 @@ elif compiler.get_argument_syntax() == 'msvc'
endif endif
if get_option('default_library') == 'static' if get_option('default_library') == 'static'
add_project_arguments(['-DVY_STATIC_LIB'], language : 'c') add_project_arguments(['-DRT_STATIC_LIB'], language : 'c')
endif endif
if get_option('error_report_debugbreak') if get_option('error_report_debugbreak')
add_project_arguments(['-DVY_ERROR_REPORT_DEBUGBREAK'], language : 'c') add_project_arguments(['-DRT_ERROR_REPORT_DEBUGBREAK'], language : 'c')
endif endif
# Debug specific flags # Debug specific flags
if buildtype == 'debug' or buildtype == 'debugoptimized' if buildtype == 'debug' or buildtype == 'debugoptimized'
add_project_arguments([ '-DVY_DEBUG'], language : 'c') add_project_arguments([ '-DRT_DEBUG'], language : 'c')
endif endif
# Gather dependencies # Gather dependencies
@ -42,12 +42,12 @@ vk_dep = dependency('vulkan', required : false)
windowing_dep = [] windowing_dep = []
if get_option('use_xlib') if get_option('use_xlib')
windowing_dep = dependency('x11', required : true) windowing_dep = dependency('x11', required : true)
add_project_arguments(['-DVY_USE_XLIB'], language : 'c') add_project_arguments(['-DRT_USE_XLIB'], language : 'c')
endif endif
incdir = include_directories(['contrib', 'src']) incdir = include_directories(['contrib', 'src'])
runtime_lib = library('vyrt', runtime_lib = library('rt',
# Project Sources # Project Sources
'src/runtime/aio.h', 'src/runtime/aio.h',
'src/runtime/app.h', 'src/runtime/app.h',
@ -107,7 +107,7 @@ if vk_dep.found()
endif endif
vk_inc_dep = vk_dep.partial_dependency(compile_args : true, includes : true) vk_inc_dep = vk_dep.partial_dependency(compile_args : true, includes : true)
vk_renderer_lib = library('vyvk', vk_renderer_lib = library('rtvk',
# Project Sources # Project Sources
'src/renderer/vk/gpu.h', 'src/renderer/vk/gpu.h',
'src/renderer/vk/swapchain.h', 'src/renderer/vk/swapchain.h',
@ -177,7 +177,7 @@ executable('assetc',
link_args : ['-L'+shaderc_libdir, '-lshaderc_combined'], link_args : ['-L'+shaderc_libdir, '-lshaderc_combined'],
win_subsystem : 'console') win_subsystem : 'console')
# Game
executable('voyage', executable('voyage',
'src/game/voyage.c', 'src/game/voyage.c',
include_directories : incdir, include_directories : incdir,

View File

@ -6,13 +6,13 @@
#include <Windows.h> #include <Windows.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
return vyWin32Entry(hInstance, hPrevInstance, pCmdLine, nCmdShow); return rtWin32Entry(hInstance, hPrevInstance, pCmdLine, nCmdShow);
} }
#elif defined(__linux__) #elif defined(__linux__)
int main(int argc, char **argv) { int main(int argc, char **argv) {
return vyXlibEntry(argc, argv); return rtXlibEntry(argc, argv);
} }
#endif #endif

View File

@ -1,22 +1,22 @@
#ifndef VY_VK_FRAMEBUFFER_H #ifndef RT_VK_FRAMEBUFFER_H
#define VY_VK_FRAMEBUFFER_H #define RT_VK_FRAMEBUFFER_H
#include <volk/volk.h> #include <volk/volk.h>
typedef struct { typedef struct {
VkFramebuffer framebuffer; VkFramebuffer framebuffer;
uint32_t pass_idx; uint32_t pass_idx;
} vy_framebuffer; } rt_framebuffer;
typedef struct { typedef struct {
uint32_t index; uint32_t index;
} vy_framebuffer_handle; } rt_framebuffer_handle;
/* Reserve a slot, but don't actually create the framebuffer yet. /* Reserve a slot, but don't actually create the framebuffer yet.
* We can use this if we are unsure if the framebuffer will really be needed. * We can use this if we are unsure if the framebuffer will really be needed.
*/ */
vy_framebuffer_handle vy_reserve_framebuffer(void); rt_framebuffer_handle rt_reserve_framebuffer(void);
vy_framebuffer *vy_get_framebuffer(vy_framebuffer_handle handle); rt_framebuffer *rt_get_framebuffer(rt_framebuffer_handle handle);
#endif #endif

View File

@ -1,12 +1,12 @@
#ifndef VY_VK_GPU_H #ifndef RT_VK_GPU_H
#define VY_VK_GPU_H #define RT_VK_GPU_H
#include <volk/volk.h> #include <volk/volk.h>
#ifdef _WIN32 #ifdef _WIN32
struct HINSTANCE__; struct HINSTANCE__;
struct HWND__; struct HWND__;
#elif defined(VY_USE_XLIB) #elif defined(RT_USE_XLIB)
struct _XDisplay; struct _XDisplay;
#endif #endif
@ -14,11 +14,11 @@ typedef struct {
#ifdef _WIN32 #ifdef _WIN32
struct HINSTANCE__ *hInstance; struct HINSTANCE__ *hInstance;
struct HWND__ *hWnd; struct HWND__ *hWnd;
#elif defined(VY_USE_XLIB) #elif defined(RT_USE_XLIB)
struct _XDisplay *display; struct _XDisplay *display;
unsigned long window; unsigned long window;
#endif #endif
} vy_native_window; } rt_native_window;
typedef struct { typedef struct {
VkInstance instance; VkInstance instance;
@ -34,14 +34,14 @@ typedef struct {
uint32_t compute_family; uint32_t compute_family;
uint32_t present_family; uint32_t present_family;
vy_native_window native_window; rt_native_window native_window;
VkPhysicalDeviceDescriptorIndexingProperties descriptor_indexing_props; VkPhysicalDeviceDescriptorIndexingProperties descriptor_indexing_props;
VkPhysicalDeviceProperties phys_device_props; VkPhysicalDeviceProperties phys_device_props;
} vy_vk_gpu; } rt_vk_gpu;
#ifndef VY_VK_DONT_DEFINE_GPU_GLOBAL #ifndef RT_VK_DONT_DEFINE_GPU_GLOBAL
extern vy_vk_gpu g_gpu; extern rt_vk_gpu g_gpu;
#endif #endif
#endif #endif

View File

@ -2,7 +2,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define VY_VK_DONT_DEFINE_GPU_GLOBAL #define RT_VK_DONT_DEFINE_GPU_GLOBAL
#include "gpu.h" #include "gpu.h"
#include "swapchain.h" #include "swapchain.h"
@ -10,13 +10,13 @@
#include "runtime/renderer_api.h" #include "runtime/renderer_api.h"
#include "runtime/runtime.h" #include "runtime/runtime.h"
VY_CVAR_I(r_VkEnableAPIAllocTracking, RT_CVAR_I(r_VkEnableAPIAllocTracking,
"Enable tracking of allocations done by the vulkan api. [0/1] Default: 0", "Enable tracking of allocations done by the vulkan api. [0/1] Default: 0",
0); 0);
VY_CVAR_S(r_VkPhysDeviceName, "Name of the selected physical device. Default: \"\"", ""); RT_CVAR_S(r_VkPhysDeviceName, "Name of the selected physical device. Default: \"\"", "");
vy_vk_gpu g_gpu; rt_vk_gpu g_gpu;
static VkAllocationCallbacks _tracking_alloc_cbs; static VkAllocationCallbacks _tracking_alloc_cbs;
@ -39,7 +39,7 @@ static const char *AllocationScopeToString(VkSystemAllocationScope scope) {
static void * static void *
TrackAllocation(void *userData, size_t size, size_t alignment, VkSystemAllocationScope scope) { TrackAllocation(void *userData, size_t size, size_t alignment, VkSystemAllocationScope scope) {
vyLog("vk", rtLog("vk",
"Allocation. Size: %zu, Alignment: %zu, Scope: %s", "Allocation. Size: %zu, Alignment: %zu, Scope: %s",
size, size,
alignment, alignment,
@ -56,7 +56,7 @@ static void *TrackReallocation(void *userData,
size_t size, size_t size,
size_t alignment, size_t alignment,
VkSystemAllocationScope scope) { VkSystemAllocationScope scope) {
vyLog("vk", rtLog("vk",
"Reallocation. Size: %zu, Alignment: %zu, Scope: %s", "Reallocation. Size: %zu, Alignment: %zu, Scope: %s",
size, size,
alignment, alignment,
@ -77,20 +77,20 @@ DebugUtilsMessengerCb(VkDebugUtilsMessageSeverityFlagBitsEXT severity,
return VK_FALSE; return VK_FALSE;
} }
extern vy_cvar r_VkPreferredSwapchainImages; extern rt_cvar r_VkPreferredSwapchainImages;
extern vy_cvar r_VkPreferMailboxMode; extern rt_cvar r_VkPreferMailboxMode;
void VY_RENDERER_API_FN(RegisterCVars)(void) { void RT_RENDERER_API_FN(RegisterCVars)(void) {
vyRegisterCVAR(&r_VkEnableAPIAllocTracking); rtRegisterCVAR(&r_VkEnableAPIAllocTracking);
vyRegisterCVAR(&r_VkPhysDeviceName); rtRegisterCVAR(&r_VkPhysDeviceName);
vyRegisterCVAR(&r_VkPreferredSwapchainImages); rtRegisterCVAR(&r_VkPreferredSwapchainImages);
vyRegisterCVAR(&r_VkPreferMailboxMode); rtRegisterCVAR(&r_VkPreferMailboxMode);
} }
static vy_result CreateInstance(void) { static rt_result CreateInstance(void) {
VkResult result = volkInitialize(); VkResult result = volkInitialize();
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
vyReportError("vk", "Initialization failed: volkInitialize()"); rtReportError("vk", "Initialization failed: volkInitialize()");
return 1; return 1;
} }
@ -106,18 +106,18 @@ static vy_result CreateInstance(void) {
VK_KHR_SURFACE_EXTENSION_NAME, VK_KHR_SURFACE_EXTENSION_NAME,
#ifdef _WIN32 #ifdef _WIN32
"VK_KHR_win32_surface", "VK_KHR_win32_surface",
#elif defined(VY_USE_XLIB) #elif defined(RT_USE_XLIB)
"VK_KHR_xlib_surface", "VK_KHR_xlib_surface",
#endif #endif
#ifdef VY_DEBUG #ifdef RT_DEBUG
VK_EXT_DEBUG_UTILS_EXTENSION_NAME, VK_EXT_DEBUG_UTILS_EXTENSION_NAME,
#endif #endif
}; };
const char *layers[1]; const char *layers[1];
unsigned int layer_count = 0; unsigned int layer_count = 0;
#ifdef VY_DEBUG #ifdef RT_DEBUG
/* Search for layers we want to enable */ /* Search for layers we want to enable */
uint32_t available_layer_count = 0; uint32_t available_layer_count = 0;
result = vkEnumerateInstanceLayerProperties(&available_layer_count, NULL); result = vkEnumerateInstanceLayerProperties(&available_layer_count, NULL);
@ -134,10 +134,10 @@ static vy_result CreateInstance(void) {
} }
free(props); free(props);
} else { } else {
vyLog("vk", "Failed to allocate storage for instance layer properties."); rtLog("vk", "Failed to allocate storage for instance layer properties.");
} }
} else { } else {
vyLog("vk", "vkEnumerateInstanceLayerProperties failed."); rtLog("vk", "vkEnumerateInstanceLayerProperties failed.");
} }
#endif #endif
@ -145,18 +145,18 @@ static vy_result CreateInstance(void) {
.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO,
.pApplicationInfo = &app_info, .pApplicationInfo = &app_info,
.ppEnabledExtensionNames = extensions, .ppEnabledExtensionNames = extensions,
.enabledExtensionCount = VY_ARRAY_COUNT(extensions), .enabledExtensionCount = RT_ARRAY_COUNT(extensions),
.ppEnabledLayerNames = layers, .ppEnabledLayerNames = layers,
.enabledLayerCount = layer_count, .enabledLayerCount = layer_count,
}; };
result = vkCreateInstance(&instance_info, g_gpu.alloc_cb, &g_gpu.instance); result = vkCreateInstance(&instance_info, g_gpu.alloc_cb, &g_gpu.instance);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
vyReportError("vk", "Failed to create the vulkan instance."); rtReportError("vk", "Failed to create the vulkan instance.");
return 1; return 1;
} }
volkLoadInstance(g_gpu.instance); volkLoadInstance(g_gpu.instance);
#ifdef VY_DEBUG #ifdef RT_DEBUG
/* Create the debug utils messenger */ /* Create the debug utils messenger */
VkDebugUtilsMessengerCreateInfoEXT messenger_info = { VkDebugUtilsMessengerCreateInfoEXT messenger_info = {
.sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT, .sType = VK_STRUCTURE_TYPE_DEBUG_UTILS_MESSENGER_CREATE_INFO_EXT,
@ -171,10 +171,10 @@ static vy_result CreateInstance(void) {
g_gpu.alloc_cb, g_gpu.alloc_cb,
&g_gpu.messenger); &g_gpu.messenger);
#endif #endif
return VY_SUCCESS; return RT_SUCCESS;
} }
static vy_result CreateSurface(const vy_renderer_init_info *info) { static rt_result CreateSurface(const rt_renderer_init_info *info) {
#ifdef _WIN32 #ifdef _WIN32
g_gpu.native_window.hInstance = info->hInstance; g_gpu.native_window.hInstance = info->hInstance;
g_gpu.native_window.hWnd = info->hWnd; g_gpu.native_window.hWnd = info->hWnd;
@ -185,10 +185,10 @@ static vy_result CreateSurface(const vy_renderer_init_info *info) {
}; };
if (vkCreateWin32SurfaceKHR(g_gpu.instance, &surface_info, g_gpu.alloc_cb, &g_gpu.surface) == if (vkCreateWin32SurfaceKHR(g_gpu.instance, &surface_info, g_gpu.alloc_cb, &g_gpu.surface) ==
VK_SUCCESS) VK_SUCCESS)
return VY_SUCCESS; return RT_SUCCESS;
else else
return 100; return 100;
#elif defined(VY_USE_XLIB_KHR) #elif defined(RT_USE_XLIB_KHR)
g_gpu.native_window.display = info->display; g_gpu.native_window.display = info->display;
g_gpu.native_window.window = info->window; g_gpu.native_window.window = info->window;
VkXlibSurfaceCreateInfoKHR surface_info = { VkXlibSurfaceCreateInfoKHR surface_info = {
@ -198,7 +198,7 @@ static vy_result CreateSurface(const vy_renderer_init_info *info) {
}; };
if (vkCreateXlibSurfaceKHR(g_gpu.instance, &surface_info, &g_gpu.alloc_cb, &g_gpu.surface) == if (vkCreateXlibSurfaceKHR(g_gpu.instance, &surface_info, &g_gpu.alloc_cb, &g_gpu.surface) ==
VK_SUCCESS) VK_SUCCESS)
return VY_SUCCESS; return RT_SUCCESS;
else else
return 100; return 100;
#endif #endif
@ -208,10 +208,10 @@ typedef struct {
uint32_t graphics; uint32_t graphics;
uint32_t compute; uint32_t compute;
uint32_t present; uint32_t present;
} vy_queue_indices; } rt_queue_indices;
static vy_queue_indices RetrieveQueueIndices(VkPhysicalDevice phys_dev, VkSurfaceKHR surface) { static rt_queue_indices RetrieveQueueIndices(VkPhysicalDevice phys_dev, VkSurfaceKHR surface) {
vy_queue_indices indices = {.graphics = UINT32_MAX, rt_queue_indices indices = {.graphics = UINT32_MAX,
.compute = UINT32_MAX, .compute = UINT32_MAX,
.present = UINT32_MAX}; .present = UINT32_MAX};
@ -254,7 +254,7 @@ static bool CheckDeviceExtensionSupported(VkPhysicalDevice phys_dev) {
vkEnumerateDeviceExtensionProperties(phys_dev, NULL, &extension_count, supported_extensions); vkEnumerateDeviceExtensionProperties(phys_dev, NULL, &extension_count, supported_extensions);
bool supported = true; bool supported = true;
for (uint32_t i = 0; i < VY_ARRAY_COUNT(required_extensions); ++i) { for (uint32_t i = 0; i < RT_ARRAY_COUNT(required_extensions); ++i) {
bool found = false; bool found = false;
for (uint32_t j = 0; j < extension_count; ++j) { for (uint32_t j = 0; j < extension_count; ++j) {
if (strncmp(supported_extensions[j].extensionName, if (strncmp(supported_extensions[j].extensionName,
@ -275,18 +275,18 @@ out:
return supported; return supported;
} }
static vy_result ChoosePhysicalDevice(void) { static rt_result ChoosePhysicalDevice(void) {
g_gpu.phys_device = VK_NULL_HANDLE; g_gpu.phys_device = VK_NULL_HANDLE;
uint32_t phys_device_count = 0; uint32_t phys_device_count = 0;
VkResult result = vkEnumeratePhysicalDevices(g_gpu.instance, &phys_device_count, NULL); VkResult result = vkEnumeratePhysicalDevices(g_gpu.instance, &phys_device_count, NULL);
if (result != VK_SUCCESS) { if (result != VK_SUCCESS) {
vyReportError("vk", "Failed to enumerate the physical devices."); rtReportError("vk", "Failed to enumerate the physical devices.");
return 2; return 2;
} }
VkPhysicalDevice *phys_devices = calloc(phys_device_count, sizeof(VkPhysicalDevice)); VkPhysicalDevice *phys_devices = calloc(phys_device_count, sizeof(VkPhysicalDevice));
if (!phys_devices) { if (!phys_devices) {
vyReportError("vk", "Failed to enumerate the physical devices: Out of memory."); rtReportError("vk", "Failed to enumerate the physical devices: Out of memory.");
return 2; return 2;
} }
vkEnumeratePhysicalDevices(g_gpu.instance, &phys_device_count, phys_devices); vkEnumeratePhysicalDevices(g_gpu.instance, &phys_device_count, phys_devices);
@ -307,7 +307,7 @@ static vy_result ChoosePhysicalDevice(void) {
if (!CheckDeviceExtensionSupported(phys_devices[i])) if (!CheckDeviceExtensionSupported(phys_devices[i]))
continue; continue;
vy_queue_indices indices = RetrieveQueueIndices(phys_devices[i], g_gpu.surface); rt_queue_indices indices = RetrieveQueueIndices(phys_devices[i], g_gpu.surface);
if (indices.compute == UINT32_MAX || indices.present == UINT32_MAX || if (indices.compute == UINT32_MAX || indices.present == UINT32_MAX ||
indices.graphics == UINT32_MAX) indices.graphics == UINT32_MAX)
continue; continue;
@ -354,18 +354,18 @@ static vy_result ChoosePhysicalDevice(void) {
free(phys_devices); free(phys_devices);
if (g_gpu.phys_device == VK_NULL_HANDLE) { if (g_gpu.phys_device == VK_NULL_HANDLE) {
vyReportError("vk", "Failed to find a suitable physical device."); rtReportError("vk", "Failed to find a suitable physical device.");
return 3; return 3;
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
static vy_result CreateDevice(void) { static rt_result CreateDevice(void) {
const char *extensions[] = { const char *extensions[] = {
VK_KHR_SWAPCHAIN_EXTENSION_NAME, VK_KHR_SWAPCHAIN_EXTENSION_NAME,
}; };
vy_queue_indices queue_indices = RetrieveQueueIndices(g_gpu.phys_device, g_gpu.surface); rt_queue_indices queue_indices = RetrieveQueueIndices(g_gpu.phys_device, g_gpu.surface);
g_gpu.compute_family = queue_indices.compute; g_gpu.compute_family = queue_indices.compute;
g_gpu.graphics_family = queue_indices.graphics; g_gpu.graphics_family = queue_indices.graphics;
@ -402,14 +402,14 @@ static vy_result CreateDevice(void) {
VkDeviceCreateInfo device_info = { VkDeviceCreateInfo device_info = {
.sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO, .sType = VK_STRUCTURE_TYPE_DEVICE_CREATE_INFO,
.enabledExtensionCount = VY_ARRAY_COUNT(extensions), .enabledExtensionCount = RT_ARRAY_COUNT(extensions),
.ppEnabledExtensionNames = extensions, .ppEnabledExtensionNames = extensions,
.pQueueCreateInfos = queue_info, .pQueueCreateInfos = queue_info,
.queueCreateInfoCount = distinct_queue_count, .queueCreateInfoCount = distinct_queue_count,
}; };
if (vkCreateDevice(g_gpu.phys_device, &device_info, g_gpu.alloc_cb, &g_gpu.device) != if (vkCreateDevice(g_gpu.phys_device, &device_info, g_gpu.alloc_cb, &g_gpu.device) !=
VK_SUCCESS) { VK_SUCCESS) {
vyReportError("vk", "Device creation failed."); rtReportError("vk", "Device creation failed.");
return 10; return 10;
} }
@ -417,14 +417,14 @@ static vy_result CreateDevice(void) {
vkGetDeviceQueue(g_gpu.device, queue_indices.compute, 0, &g_gpu.compute_queue); vkGetDeviceQueue(g_gpu.device, queue_indices.compute, 0, &g_gpu.compute_queue);
vkGetDeviceQueue(g_gpu.device, queue_indices.present, 0, &g_gpu.present_queue); vkGetDeviceQueue(g_gpu.device, queue_indices.present, 0, &g_gpu.present_queue);
return VY_SUCCESS; return RT_SUCCESS;
} }
extern vy_result InitPipelineManagement(void); extern rt_result InitPipelineManagement(void);
extern void ShutdownPipelineManagement(void); extern void ShutdownPipelineManagement(void);
vy_result VY_RENDERER_API_FN(Init)(const vy_renderer_init_info *info) { rt_result RT_RENDERER_API_FN(Init)(const rt_renderer_init_info *info) {
vyLog("vk", "Init"); rtLog("vk", "Init");
_tracking_alloc_cbs.pUserData = NULL; _tracking_alloc_cbs.pUserData = NULL;
_tracking_alloc_cbs.pfnAllocation = TrackAllocation; _tracking_alloc_cbs.pfnAllocation = TrackAllocation;
@ -438,31 +438,31 @@ vy_result VY_RENDERER_API_FN(Init)(const vy_renderer_init_info *info) {
} }
int res = CreateInstance(); int res = CreateInstance();
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
res = CreateSurface(info); res = CreateSurface(info);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
res = ChoosePhysicalDevice(); res = ChoosePhysicalDevice();
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
res = CreateDevice(); res = CreateDevice();
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
res = InitPipelineManagement(); res = InitPipelineManagement();
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
res = vyCreateSwapchain(); res = rtCreateSwapchain();
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
return VY_SUCCESS; return RT_SUCCESS;
} }
void VY_RENDERER_API_FN(Shutdown)(void) { void RT_RENDERER_API_FN(Shutdown)(void) {
vyLog("vk", "Shutdown"); rtLog("vk", "Shutdown");
vkDeviceWaitIdle(g_gpu.device); vkDeviceWaitIdle(g_gpu.device);
vyDestroySwapchain(); rtDestroySwapchain();
ShutdownPipelineManagement(); ShutdownPipelineManagement();
vkDestroyDevice(g_gpu.device, g_gpu.alloc_cb); vkDestroyDevice(g_gpu.device, g_gpu.alloc_cb);
vkDestroySurfaceKHR(g_gpu.instance, g_gpu.surface, g_gpu.alloc_cb); vkDestroySurfaceKHR(g_gpu.instance, g_gpu.surface, g_gpu.alloc_cb);

View File

@ -9,38 +9,38 @@
#include <volk/volk.h> #include <volk/volk.h>
#include <stdlib.h> #include <stdlib.h>
VY_CVAR_I(r_VkMaxPipelineCount, "Maximum number of pipeline objects. Default: 1024", 1024); RT_CVAR_I(r_VkMaxPipelineCount, "Maximum number of pipeline objects. Default: 1024", 1024);
typedef struct vy_pipeline_s { typedef struct rt_pipeline_s {
uint32_t version; uint32_t version;
vy_pipeline pipeline; rt_pipeline pipeline;
struct vy_pipeline_s *next_free; struct rt_pipeline_s *next_free;
} vy_pipeline_slot; } rt_pipeline_slot;
static vy_pipeline_slot *_pipelines; static rt_pipeline_slot *_pipelines;
static vy_pipeline_slot *_first_free; static rt_pipeline_slot *_first_free;
static vy_rwlock _lock; static rt_rwlock _lock;
vy_result InitPipelineManagement(void) { rt_result InitPipelineManagement(void) {
vy_create_rwlock_result lock_res = vyCreateRWLock(); rt_create_rwlock_result lock_res = rtCreateRWLock();
if (!lock_res.ok) if (!lock_res.ok)
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
_lock = lock_res.lock; _lock = lock_res.lock;
_pipelines = calloc(r_VkMaxPipelineCount.i, sizeof(vy_pipeline_slot)); _pipelines = calloc(r_VkMaxPipelineCount.i, sizeof(rt_pipeline_slot));
if (!_pipelines) { if (!_pipelines) {
vyDestroyRWLock(&_lock); rtDestroyRWLock(&_lock);
return VY_OUT_OF_MEMORY; return RT_OUT_OF_MEMORY;
} }
/* Keep [0] unused to preserve 0 as the invalid handle */ /* Keep [0] unused to preserve 0 as the invalid handle */
_first_free = &_pipelines[1]; _first_free = &_pipelines[1];
for (int i = 1; i < r_VkMaxPipelineCount.i - 1; ++i) { for (int i = 1; i < r_VkMaxPipelineCount.i - 1; ++i) {
_pipelines[i].next_free = &_pipelines[i + 1]; _pipelines[i].next_free = &_pipelines[i + 1];
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
static void DestroyPipeline(vy_pipeline_slot *slot) { static void DestroyPipeline(rt_pipeline_slot *slot) {
if (slot->pipeline.pipeline) { if (slot->pipeline.pipeline) {
vkDestroyPipeline(g_gpu.device, slot->pipeline.pipeline, g_gpu.alloc_cb); vkDestroyPipeline(g_gpu.device, slot->pipeline.pipeline, g_gpu.alloc_cb);
} }
@ -53,22 +53,22 @@ void ShutdownPipelineManagement(void) {
DestroyPipeline(&_pipelines[i]); DestroyPipeline(&_pipelines[i]);
} }
free(_pipelines); free(_pipelines);
vyDestroyRWLock(&_lock); rtDestroyRWLock(&_lock);
_first_free = NULL; _first_free = NULL;
} }
vy_pipeline_handle VY_RENDERER_API_FN(CompilePipeline)(const vy_pipeline_info *info) { rt_pipeline_handle RT_RENDERER_API_FN(CompilePipeline)(const rt_pipeline_info *info) {
vy_pipeline_handle handle = VY_INVALID_HANDLE; rt_pipeline_handle handle = RT_INVALID_HANDLE;
vyLockWrite(&_lock); rtLockWrite(&_lock);
if (!_first_free) { if (!_first_free) {
vyLog("VK", "No free pipeline slots!"); rtLog("VK", "No free pipeline slots!");
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
return handle; return handle;
} }
vy_pipeline_slot *slot = _first_free; rt_pipeline_slot *slot = _first_free;
_first_free = slot->next_free; _first_free = slot->next_free;
slot->version = (slot->version + 1) & VY_GFX_HANDLE_MAX_VERSION; slot->version = (slot->version + 1) & RT_GFX_HANDLE_MAX_VERSION;
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
/* No other thread that calls compile gets the same slot. /* No other thread that calls compile gets the same slot.
* Another thread accessing the slot via GetPipeline would get a version mismatch. * Another thread accessing the slot via GetPipeline would get a version mismatch.
@ -78,26 +78,26 @@ vy_pipeline_handle VY_RENDERER_API_FN(CompilePipeline)(const vy_pipeline_info *i
return handle; return handle;
} }
void VY_RENDERER_API_FN(DestroyPipeline)(vy_pipeline_handle handle) { void RT_RENDERER_API_FN(DestroyPipeline)(rt_pipeline_handle handle) {
if (handle.index >= (uint32_t)r_VkMaxPipelineCount.i) if (handle.index >= (uint32_t)r_VkMaxPipelineCount.i)
return; return;
vyLockWrite(&_lock); rtLockWrite(&_lock);
if (_pipelines[handle.index].version == handle.version) if (_pipelines[handle.index].version == handle.version)
DestroyPipeline(&_pipelines[handle.index]); DestroyPipeline(&_pipelines[handle.index]);
else else
vyLog("VK", "Tried to destroy a pipeline using an outdated handle."); rtLog("VK", "Tried to destroy a pipeline using an outdated handle.");
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
} }
const vy_pipeline *vyGetPipeline(vy_pipeline_handle handle) { const rt_pipeline *rtGetPipeline(rt_pipeline_handle handle) {
if (handle.index >= (uint32_t)r_VkMaxPipelineCount.i) if (handle.index >= (uint32_t)r_VkMaxPipelineCount.i)
return NULL; return NULL;
vyLockRead(&_lock); rtLockRead(&_lock);
vy_pipeline *res = NULL; rt_pipeline *res = NULL;
if (_pipelines[handle.index].version == handle.version) if (_pipelines[handle.index].version == handle.version)
res = &_pipelines[handle.index].pipeline; res = &_pipelines[handle.index].pipeline;
else else
vyLog("VK", "Tried to access a pipeline using an outdated handle."); rtLog("VK", "Tried to access a pipeline using an outdated handle.");
vyUnlockRead(&_lock); rtUnlockRead(&_lock);
return res; return res;
} }

View File

@ -1,5 +1,5 @@
#ifndef VY_VK_PIPELINES_H #ifndef RT_VK_PIPELINES_H
#define VY_VK_PIPELINES_H #define RT_VK_PIPELINES_H
#include <volk/volk.h> #include <volk/volk.h>
@ -7,9 +7,9 @@
typedef struct { typedef struct {
VkPipeline pipeline; VkPipeline pipeline;
} vy_pipeline; } rt_pipeline;
/* A pipeline is immutable after creation. */ /* A pipeline is immutable after creation. */
const vy_pipeline *vyGetPipeline(vy_pipeline_handle handle); const rt_pipeline *rtGetPipeline(rt_pipeline_handle handle);
#endif #endif

View File

@ -1,4 +1,4 @@
#define VY_VK_DONT_DEFINE_SWAPCHAIN_GLOBAL #define RT_VK_DONT_DEFINE_SWAPCHAIN_GLOBAL
#include "swapchain.h" #include "swapchain.h"
#include "gpu.h" #include "gpu.h"
@ -9,24 +9,24 @@
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
#elif defined(VY_USE_XLIB) #elif defined(RT_USE_XLIB)
#include <X11/Xlib.h> #include <X11/Xlib.h>
#endif #endif
VY_CVAR_I(r_VkPreferredSwapchainImages, RT_CVAR_I(r_VkPreferredSwapchainImages,
"Preferred number of swapchain iamges. [2/3] Default: 2", "Preferred number of swapchain iamges. [2/3] Default: 2",
2); 2);
VY_CVAR_I(r_VkPreferMailboxMode, "Prefer mailbox present mode over fifo mode. [0/1] Default: 0", 1); RT_CVAR_I(r_VkPreferMailboxMode, "Prefer mailbox present mode over fifo mode. [0/1] Default: 0", 1);
typedef struct { typedef struct {
VkPresentModeKHR present_mode; VkPresentModeKHR present_mode;
VkSurfaceFormatKHR surface_format; VkSurfaceFormatKHR surface_format;
VkExtent2D extent; VkExtent2D extent;
VkSurfaceTransformFlagsKHR pre_transform; VkSurfaceTransformFlagsKHR pre_transform;
} vy_device_swapchain_parameters; } rt_device_swapchain_parameters;
static vy_device_swapchain_parameters DetermineSwapchainParameters(void) { static rt_device_swapchain_parameters DetermineSwapchainParameters(void) {
vy_device_swapchain_parameters params; rt_device_swapchain_parameters params;
/* determine presentation mode. FIFO should always be available */ /* determine presentation mode. FIFO should always be available */
params.present_mode = VK_PRESENT_MODE_FIFO_KHR; params.present_mode = VK_PRESENT_MODE_FIFO_KHR;
@ -76,10 +76,10 @@ static vy_device_swapchain_parameters DetermineSwapchainParameters(void) {
return params; return params;
} }
vy_swapchain g_swapchain; rt_swapchain g_swapchain;
vy_result vyCreateSwapchain(void) { rt_result rtCreateSwapchain(void) {
vy_device_swapchain_parameters device_params = DetermineSwapchainParameters(); rt_device_swapchain_parameters device_params = DetermineSwapchainParameters();
uint32_t image_count = r_VkPreferredSwapchainImages.i; uint32_t image_count = r_VkPreferredSwapchainImages.i;
if (image_count < 2) if (image_count < 2)
@ -117,7 +117,7 @@ vy_result vyCreateSwapchain(void) {
&swapchain_info, &swapchain_info,
g_gpu.alloc_cb, g_gpu.alloc_cb,
&g_swapchain.swapchain) != VK_SUCCESS) { &g_swapchain.swapchain) != VK_SUCCESS) {
vyReportError("vk", "Failed to create the swapchain"); rtReportError("vk", "Failed to create the swapchain");
return 50; return 50;
} }
g_swapchain.format = device_params.surface_format.format; g_swapchain.format = device_params.surface_format.format;
@ -125,8 +125,8 @@ vy_result vyCreateSwapchain(void) {
/* Retrieve images */ /* Retrieve images */
g_swapchain.image_count = 0; g_swapchain.image_count = 0;
vkGetSwapchainImagesKHR(g_gpu.device, g_swapchain.swapchain, &g_swapchain.image_count, NULL); vkGetSwapchainImagesKHR(g_gpu.device, g_swapchain.swapchain, &g_swapchain.image_count, NULL);
if (g_swapchain.image_count > VY_VK_MAX_SWAPCHAIN_IMAGES) { if (g_swapchain.image_count > RT_VK_MAX_SWAPCHAIN_IMAGES) {
vyReportError("vk", "Unsupported number of swapchain images: %u", g_swapchain.image_count); rtReportError("vk", "Unsupported number of swapchain images: %u", g_swapchain.image_count);
return 51; return 51;
} }
vkGetSwapchainImagesKHR(g_gpu.device, vkGetSwapchainImagesKHR(g_gpu.device,
@ -161,21 +161,21 @@ vy_result vyCreateSwapchain(void) {
&view_info, &view_info,
g_gpu.alloc_cb, g_gpu.alloc_cb,
&g_swapchain.image_views[i]) != VK_SUCCESS) { &g_swapchain.image_views[i]) != VK_SUCCESS) {
vyReportError("vk", "Failed to create an image view for the swapchain."); rtReportError("vk", "Failed to create an image view for the swapchain.");
return 52; return 52;
} }
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
vy_result vyRecreateSwapchain(void) { rt_result rtRecreateSwapchain(void) {
/* TODO(Kevin): Old swapchain in swapchain create info */ /* TODO(Kevin): Old swapchain in swapchain create info */
vyDestroySwapchain(); rtDestroySwapchain();
return vyCreateSwapchain(); return rtCreateSwapchain();
} }
void vyDestroySwapchain(void) { void rtDestroySwapchain(void) {
for (uint32_t i = 0; i < g_swapchain.image_count; ++i) { for (uint32_t i = 0; i < g_swapchain.image_count; ++i) {
vkDestroyImageView(g_gpu.device, g_swapchain.image_views[i], g_gpu.alloc_cb); vkDestroyImageView(g_gpu.device, g_swapchain.image_views[i], g_gpu.alloc_cb);
} }

View File

@ -1,28 +1,28 @@
#ifndef VY_VK_SWAPCHAIN_H #ifndef RT_VK_SWAPCHAIN_H
#define VY_VK_SWAPCHAIN_H #define RT_VK_SWAPCHAIN_H
#include <volk/volk.h> #include <volk/volk.h>
#include "runtime/runtime.h" #include "runtime/runtime.h"
#define VY_VK_MAX_SWAPCHAIN_IMAGES 3 #define RT_VK_MAX_SWAPCHAIN_IMAGES 3
typedef struct { typedef struct {
VkSwapchainKHR swapchain; VkSwapchainKHR swapchain;
VkImage images[VY_VK_MAX_SWAPCHAIN_IMAGES]; VkImage images[RT_VK_MAX_SWAPCHAIN_IMAGES];
VkImageView image_views[VY_VK_MAX_SWAPCHAIN_IMAGES]; VkImageView image_views[RT_VK_MAX_SWAPCHAIN_IMAGES];
uint32_t image_count; uint32_t image_count;
VkFormat format; VkFormat format;
} vy_swapchain; } rt_swapchain;
#ifndef VY_VK_DONT_DEFINE_SWAPCHAIN_GLOBAL #ifndef RT_VK_DONT_DEFINE_SWAPCHAIN_GLOBAL
extern vy_swapchain g_swapchain; extern rt_swapchain g_swapchain;
#endif #endif
vy_result vyCreateSwapchain(void); rt_result rtCreateSwapchain(void);
vy_result vyRecreateSwapchain(void); rt_result rtRecreateSwapchain(void);
void vyDestroySwapchain(void); void rtDestroySwapchain(void);
#endif #endif

View File

@ -21,33 +21,33 @@ typedef struct {
HANDLE file_handle; HANDLE file_handle;
OVERLAPPED overlapped; OVERLAPPED overlapped;
#endif #endif
volatile vy_aio_state state; volatile rt_aio_state state;
} vy_aio; } rt_aio;
typedef struct { typedef struct {
vy_mutex *guard; rt_mutex *guard;
vy_aio *storage; rt_aio *storage;
uint32_t capacity; uint32_t capacity;
uint32_t head; uint32_t head;
uint32_t tail; uint32_t tail;
} vy_aio_ringbuffer; } rt_aio_ringbuffer;
typedef struct { typedef struct {
vy_aio *a; rt_aio *a;
vy_aio *b; rt_aio *b;
uint32_t a_count; uint32_t a_count;
} vy_ringbuffer_space; } rt_ringbuffer_space;
static vy_aio_ringbuffer _ringbuffer; static rt_aio_ringbuffer _ringbuffer;
static vy_ringbuffer_space ReserveRingbufferSpace(uint32_t count) { static rt_ringbuffer_space ReserveRingbufferSpace(uint32_t count) {
if (!vyLockMutex(_ringbuffer.guard)) { if (!rtLockMutex(_ringbuffer.guard)) {
vy_ringbuffer_space failed = {NULL, NULL, 0}; rt_ringbuffer_space failed = {NULL, NULL, 0};
return failed; return failed;
} }
vy_ringbuffer_space result = {NULL, NULL, 0}; rt_ringbuffer_space result = {NULL, NULL, 0};
if (_ringbuffer.head >= _ringbuffer.tail) { if (_ringbuffer.head >= _ringbuffer.tail) {
if (_ringbuffer.head + count <= _ringbuffer.capacity) { if (_ringbuffer.head + count <= _ringbuffer.capacity) {
@ -66,7 +66,7 @@ static vy_ringbuffer_space ReserveRingbufferSpace(uint32_t count) {
_ringbuffer.head = b_count; _ringbuffer.head = b_count;
} else { } else {
/* Not enough space, we would overwrite the tail */ /* Not enough space, we would overwrite the tail */
vyLog("aio", "Ringbuffer is full."); rtLog("aio", "Ringbuffer is full.");
} }
} }
} else { } else {
@ -78,78 +78,78 @@ static vy_ringbuffer_space ReserveRingbufferSpace(uint32_t count) {
_ringbuffer.head = (_ringbuffer.head + count) % _ringbuffer.capacity; _ringbuffer.head = (_ringbuffer.head + count) % _ringbuffer.capacity;
} else { } else {
/* Not enough space, we would overwrite the tail */ /* Not enough space, we would overwrite the tail */
vyLog("aio", "Ringbuffer is full."); rtLog("aio", "Ringbuffer is full.");
} }
} }
vyUnlockMutex(_ringbuffer.guard); rtUnlockMutex(_ringbuffer.guard);
return result; return result;
} }
#ifdef _WIN32 #ifdef _WIN32
static void static void
win32CompletionRoutine(DWORD error_code, DWORD num_bytes_transfered, LPOVERLAPPED overlapped) { win32CompletionRoutine(DWORD error_code, DWORD num_bytes_transfered, LPOVERLAPPED overlapped) {
vy_aio *op = (vy_aio *)overlapped->hEvent; rt_aio *op = (rt_aio *)overlapped->hEvent;
assert(op->state == VY_AIO_STATE_PENDING); assert(op->state == RT_AIO_STATE_PENDING);
if (error_code != ERROR_SUCCESS) { if (error_code != ERROR_SUCCESS) {
op->state = VY_AIO_STATE_FAILED; op->state = RT_AIO_STATE_FAILED;
vyLog("aio", "Async io failed: %u", error_code); rtLog("aio", "Async io failed: %u", error_code);
} else { } else {
op->state = VY_AIO_STATE_FINISHED; op->state = RT_AIO_STATE_FINISHED;
} }
CloseHandle(op->file_handle); CloseHandle(op->file_handle);
} }
#endif #endif
VY_CVAR_I(rt_MaxConcurrentAsyncIO, RT_CVAR_I(rt_MaxConcurrentAsyncIO,
"Maximum number of concurrent async. I/O operations. Default: 1024", "Maximum number of concurrent async. I/O operations. Default: 1024",
1024); 1024);
vy_result InitAIO(void) { rt_result InitAIO(void) {
unsigned int max_concurrent_operations = rt_MaxConcurrentAsyncIO.i; unsigned int max_concurrent_operations = rt_MaxConcurrentAsyncIO.i;
_ringbuffer.guard = vyCreateMutex(); _ringbuffer.guard = rtCreateMutex();
if (!_ringbuffer.guard) { if (!_ringbuffer.guard) {
return VY_AIO_OUT_OF_MEMORY; return RT_AIO_OUT_OF_MEMORY;
} }
if (max_concurrent_operations == 0) if (max_concurrent_operations == 0)
max_concurrent_operations = 1024; max_concurrent_operations = 1024;
_ringbuffer.storage = calloc(max_concurrent_operations, sizeof(vy_aio)); _ringbuffer.storage = calloc(max_concurrent_operations, sizeof(rt_aio));
if (!_ringbuffer.storage) if (!_ringbuffer.storage)
return VY_AIO_OUT_OF_MEMORY; return RT_AIO_OUT_OF_MEMORY;
_ringbuffer.head = 0; _ringbuffer.head = 0;
_ringbuffer.tail = 0; _ringbuffer.tail = 0;
_ringbuffer.capacity = max_concurrent_operations; _ringbuffer.capacity = max_concurrent_operations;
return VY_SUCCESS; return RT_SUCCESS;
} }
void ShutdownAIO(void) { void ShutdownAIO(void) {
vyDestroyMutex(_ringbuffer.guard); rtDestroyMutex(_ringbuffer.guard);
free(_ringbuffer.storage); free(_ringbuffer.storage);
_ringbuffer.capacity = 0; _ringbuffer.capacity = 0;
} }
VY_DLLEXPORT vy_result vySubmitLoadBatch(const vy_load_batch *batch, vy_aio_handle *handles) { RT_DLLEXPORT rt_result rtSubmitLoadBatch(const rt_load_batch *batch, rt_aio_handle *handles) {
if (batch->num_loads > VY_LOAD_BATCH_MAX_SIZE) { if (batch->num_loads > RT_LOAD_BATCH_MAX_SIZE) {
return VY_AIO_LOAD_TOO_LARGE; return RT_AIO_LOAD_TOO_LARGE;
} }
vy_ringbuffer_space rbspace = ReserveRingbufferSpace(batch->num_loads); rt_ringbuffer_space rbspace = ReserveRingbufferSpace(batch->num_loads);
if (!rbspace.a) { if (!rbspace.a) {
vyReportError("aio", "Too many pending file operations"); rtReportError("aio", "Too many pending file operations");
return VY_AIO_TOO_MANY_OPERATIONS; return RT_AIO_TOO_MANY_OPERATIONS;
} }
for (unsigned int i = 0; i < batch->num_loads; ++i) { for (unsigned int i = 0; i < batch->num_loads; ++i) {
vy_aio *op = (i < rbspace.a_count) ? &rbspace.a[i] : &rbspace.b[i - rbspace.a_count]; rt_aio *op = (i < rbspace.a_count) ? &rbspace.a[i] : &rbspace.b[i - rbspace.a_count];
op->state = VY_AIO_STATE_PENDING; op->state = RT_AIO_STATE_PENDING;
const char *file_path = vyGetFilePath(batch->loads[i].file); const char *file_path = rtGetFilePath(batch->loads[i].file);
if (!file_path) { if (!file_path) {
vyReportError("aio", "Failed to resolve file path for a batched load"); rtReportError("aio", "Failed to resolve file path for a batched load");
op->state = VY_AIO_STATE_INVALID; op->state = RT_AIO_STATE_INVALID;
handles[i] = VY_AIO_INVALID_HANDLE; handles[i] = RT_AIO_INVALID_HANDLE;
continue; continue;
} }
#ifdef _WIN32 #ifdef _WIN32
@ -168,10 +168,10 @@ VY_DLLEXPORT vy_result vySubmitLoadBatch(const vy_load_batch *batch, vy_aio_hand
file_path, file_path,
-1, -1,
wpath, wpath,
VY_ARRAY_COUNT(wpath)) == 0) { RT_ARRAY_COUNT(wpath)) == 0) {
vyReportError("aio", "MultiByteToWideChar failed with error code: %u", GetLastError()); rtReportError("aio", "MultiByteToWideChar failed with error code: %u", GetLastError());
op->state = VY_AIO_STATE_FINISHED; op->state = RT_AIO_STATE_FINISHED;
handles[i] = VY_AIO_INVALID_HANDLE; handles[i] = RT_AIO_INVALID_HANDLE;
continue; continue;
} }
@ -183,12 +183,12 @@ VY_DLLEXPORT vy_result vySubmitLoadBatch(const vy_load_batch *batch, vy_aio_hand
FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
NULL); NULL);
if (file_handle == INVALID_HANDLE_VALUE) { if (file_handle == INVALID_HANDLE_VALUE) {
vyReportError("aio", rtReportError("aio",
"CreateFileW failed for file: %s with error code: %u", "CreateFileW failed for file: %s with error code: %u",
file_path, file_path,
GetLastError()); GetLastError());
op->state = VY_AIO_STATE_INVALID; op->state = RT_AIO_STATE_INVALID;
handles[i] = VY_AIO_INVALID_HANDLE; handles[i] = RT_AIO_INVALID_HANDLE;
continue; continue;
} }
op->file_handle = file_handle; op->file_handle = file_handle;
@ -199,9 +199,9 @@ VY_DLLEXPORT vy_result vySubmitLoadBatch(const vy_load_batch *batch, vy_aio_hand
win32CompletionRoutine); win32CompletionRoutine);
DWORD err = GetLastError(); DWORD err = GetLastError();
if (!result || err != ERROR_SUCCESS) { if (!result || err != ERROR_SUCCESS) {
vyReportError("aio", "ReadFileEx failed with error code: %u", err); rtReportError("aio", "ReadFileEx failed with error code: %u", err);
op->state = VY_AIO_STATE_FINISHED; op->state = RT_AIO_STATE_FINISHED;
handles[i] = VY_AIO_INVALID_HANDLE; handles[i] = RT_AIO_INVALID_HANDLE;
CloseHandle(file_handle); CloseHandle(file_handle);
op->file_handle = NULL; op->file_handle = NULL;
} }
@ -212,69 +212,69 @@ VY_DLLEXPORT vy_result vySubmitLoadBatch(const vy_load_batch *batch, vy_aio_hand
#endif #endif
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
VY_DLLEXPORT volatile vy_aio_state vyGetAIOState(vy_aio_handle handle) { RT_DLLEXPORT volatile rt_aio_state rtGetAIOState(rt_aio_handle handle) {
if (handle == VY_AIO_INVALID_HANDLE || handle > _ringbuffer.capacity) if (handle == RT_AIO_INVALID_HANDLE || handle > _ringbuffer.capacity)
return VY_AIO_STATE_INVALID; return RT_AIO_STATE_INVALID;
#ifdef _WIN32 #ifdef _WIN32
/* Give the compation function an opportunity to run */ /* Give the compation function an opportunity to run */
SleepEx(0, TRUE); SleepEx(0, TRUE);
#endif #endif
vyLockMutex(_ringbuffer.guard); rtLockMutex(_ringbuffer.guard);
vy_aio_state state = _ringbuffer.storage[handle - 1].state; rt_aio_state state = _ringbuffer.storage[handle - 1].state;
vyUnlockMutex(_ringbuffer.guard); rtUnlockMutex(_ringbuffer.guard);
return state; return state;
} }
VY_DLLEXPORT void vyReleaseAIO(vy_aio_handle handle) { RT_DLLEXPORT void rtReleaseAIO(rt_aio_handle handle) {
if (handle == VY_AIO_INVALID_HANDLE || handle > _ringbuffer.capacity) { if (handle == RT_AIO_INVALID_HANDLE || handle > _ringbuffer.capacity) {
return; return;
} }
vyLockMutex(_ringbuffer.guard); rtLockMutex(_ringbuffer.guard);
_ringbuffer.storage[handle - 1].state = VY_AIO_STATE_INVALID; _ringbuffer.storage[handle - 1].state = RT_AIO_STATE_INVALID;
if (handle - 1 == _ringbuffer.tail) { if (handle - 1 == _ringbuffer.tail) {
/* Advance the tail such that it points to the last used slot. (Or to head, if the /* Advance the tail such that it points to the last used slot. (Or to head, if the
* ringbuffer is now empty) */ * ringbuffer is now empty) */
uint32_t i = _ringbuffer.tail; uint32_t i = _ringbuffer.tail;
while ((_ringbuffer.storage[i].state == VY_AIO_STATE_INVALID) && i != _ringbuffer.head) { while ((_ringbuffer.storage[i].state == RT_AIO_STATE_INVALID) && i != _ringbuffer.head) {
i = (i + 1) % _ringbuffer.capacity; i = (i + 1) % _ringbuffer.capacity;
} }
_ringbuffer.tail = i; _ringbuffer.tail = i;
} }
vyUnlockMutex(_ringbuffer.guard); rtUnlockMutex(_ringbuffer.guard);
} }
VY_DLLEXPORT vy_aio_state vyWaitForAIOCompletion(vy_aio_handle handle) { RT_DLLEXPORT rt_aio_state rtWaitForAIOCompletion(rt_aio_handle handle) {
if (handle == VY_AIO_INVALID_HANDLE || handle > _ringbuffer.capacity) if (handle == RT_AIO_INVALID_HANDLE || handle > _ringbuffer.capacity)
return VY_AIO_STATE_INVALID; return RT_AIO_STATE_INVALID;
vy_aio_state state; rt_aio_state state;
do { do {
state = vyGetAIOState(handle); state = rtGetAIOState(handle);
/* NOTE(Kevin): This is where we could temporarily run a job. */ /* NOTE(Kevin): This is where we could temporarily run a job. */
#ifdef _WIN32 #ifdef _WIN32
YieldProcessor(); YieldProcessor();
#elif defined(__linux__) #elif defined(__linux__)
sched_yield(); sched_yield();
#endif #endif
} while (state == VY_AIO_STATE_PENDING); } while (state == RT_AIO_STATE_PENDING);
return state; return state;
} }
VY_DLLEXPORT vy_result vySubmitSingleLoad(vy_file_load load, vy_aio_handle *handle) { RT_DLLEXPORT rt_result rtSubmitSingleLoad(rt_file_load load, rt_aio_handle *handle) {
vy_load_batch batch; rt_load_batch batch;
batch.loads[0] = load; batch.loads[0] = load;
batch.num_loads = 1; batch.num_loads = 1;
return vySubmitLoadBatch(&batch, handle); return rtSubmitLoadBatch(&batch, handle);
} }
VY_DLLEXPORT vy_aio_state vySubmitSingleLoadSync(vy_file_load load) { RT_DLLEXPORT rt_aio_state rtSubmitSingleLoadSync(rt_file_load load) {
vy_aio_handle handle; rt_aio_handle handle;
if (vySubmitSingleLoad(load, &handle) != VY_SUCCESS) if (rtSubmitSingleLoad(load, &handle) != RT_SUCCESS)
return VY_AIO_STATE_FAILED; return RT_AIO_STATE_FAILED;
vy_aio_state state = vyWaitForAIOCompletion(handle); rt_aio_state state = rtWaitForAIOCompletion(handle);
vyReleaseAIO(handle); rtReleaseAIO(handle);
return state; return state;
} }

View File

@ -1,5 +1,5 @@
#ifndef VY_AIO_H #ifndef RT_AIO_H
#define VY_AIO_H #define RT_AIO_H
#include <stdint.h> #include <stdint.h>
@ -13,57 +13,57 @@ typedef struct {
* Must be valid until the load is finished. * Must be valid until the load is finished.
*/ */
void *dest; void *dest;
vy_file_id file; /**< Unique identifier for the file */ rt_file_id file; /**< Unique identifier for the file */
} vy_file_load; } rt_file_load;
#define VY_LOAD_BATCH_MAX_SIZE 64 #define RT_LOAD_BATCH_MAX_SIZE 64
/** A batch of loads that will be started together. /** A batch of loads that will be started together.
* *
* The aio system will hand these to the OS. * The aio system will hand these to the OS.
*/ */
typedef struct { typedef struct {
vy_file_load loads[VY_LOAD_BATCH_MAX_SIZE]; rt_file_load loads[RT_LOAD_BATCH_MAX_SIZE];
/** Must be smaller or equal to @c VY_LOAD_BATCH_MAX_SIZE */ /** Must be smaller or equal to @c RT_LOAD_BATCH_MAX_SIZE */
unsigned int num_loads; unsigned int num_loads;
} vy_load_batch; } rt_load_batch;
#define VY_AIO_INVALID_HANDLE 0 #define RT_AIO_INVALID_HANDLE 0
/** Handle for an async io operation. Can be used to query the state and result. */ /** Handle for an async io operation. Can be used to query the state and result. */
typedef uint32_t vy_aio_handle; typedef uint32_t rt_aio_handle;
enum { enum {
VY_AIO_LOAD_TOO_LARGE = (VY_SUCCESS + 1), RT_AIO_LOAD_TOO_LARGE = (RT_SUCCESS + 1),
VY_AIO_TOO_MANY_OPERATIONS, RT_AIO_TOO_MANY_OPERATIONS,
VY_AIO_OUT_OF_MEMORY, RT_AIO_OUT_OF_MEMORY,
}; };
typedef enum { typedef enum {
VY_AIO_STATE_INVALID, RT_AIO_STATE_INVALID,
VY_AIO_STATE_PENDING, RT_AIO_STATE_PENDING,
VY_AIO_STATE_FINISHED, RT_AIO_STATE_FINISHED,
VY_AIO_STATE_FAILED, RT_AIO_STATE_FAILED,
} vy_aio_state; } rt_aio_state;
VY_DLLEXPORT vy_result vySubmitLoadBatch(const vy_load_batch *batch, vy_aio_handle *handles); RT_DLLEXPORT rt_result rtSubmitLoadBatch(const rt_load_batch *batch, rt_aio_handle *handles);
VY_DLLEXPORT volatile vy_aio_state vyGetAIOState(vy_aio_handle handle); RT_DLLEXPORT volatile rt_aio_state rtGetAIOState(rt_aio_handle handle);
/* Blocks until the given operation is no longer pending. /* Blocks until the given operation is no longer pending.
* Returns the state that caused the wait to end. The handle is still valid after this function returned. */ * Returns the state that caused the wait to end. The handle is still valid after this function returned. */
VY_DLLEXPORT vy_aio_state vyWaitForAIOCompletion(vy_aio_handle handle); RT_DLLEXPORT rt_aio_state rtWaitForAIOCompletion(rt_aio_handle handle);
/* Releases the internal storage for the operation. /* Releases the internal storage for the operation.
* The system is allowed to re-use the same handle value for new operations after this was called. * The system is allowed to re-use the same handle value for new operations after this was called.
*/ */
VY_DLLEXPORT void vyReleaseAIO(vy_aio_handle handle); RT_DLLEXPORT void rtReleaseAIO(rt_aio_handle handle);
VY_DLLEXPORT vy_result vySubmitSingleLoad(vy_file_load load, vy_aio_handle *handle); RT_DLLEXPORT rt_result rtSubmitSingleLoad(rt_file_load load, rt_aio_handle *handle);
/* Convenience wrapper for a single synchronous file load. /* Convenience wrapper for a single synchronous file load.
* Returns the state that caused the wait for completion to return. */ * Returns the state that caused the wait for completion to return. */
VY_DLLEXPORT vy_aio_state vySubmitSingleLoadSync(vy_file_load load); RT_DLLEXPORT rt_aio_state rtSubmitSingleLoadSync(rt_file_load load);
#endif #endif

View File

@ -5,9 +5,9 @@
#include "gfx.h" #include "gfx.h"
#include "renderer_api.h" #include "renderer_api.h"
VY_CVAR_I(rt_Fullscreen, "Show window in fullscreen mode. [0/1] Default: 0", 0); RT_CVAR_I(rt_Fullscreen, "Show window in fullscreen mode. [0/1] Default: 0", 0);
VY_CVAR_I(rt_WindowWidth, "Window width. Default: 1024", 1024); RT_CVAR_I(rt_WindowWidth, "Window width. Default: 1024", 1024);
VY_CVAR_I(rt_WindowHeight, "Window height. Default: 768", 768); RT_CVAR_I(rt_WindowHeight, "Window height. Default: 768", 768);
#ifdef _WIN32 #ifdef _WIN32
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
@ -23,22 +23,22 @@ static LRESULT CALLBACK win32WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM
} }
} }
VY_DLLEXPORT int RT_DLLEXPORT int
vyWin32Entry(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) { rtWin32Entry(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int nCmdShow) {
if (vyInitRuntime() != VY_SUCCESS) if (rtInitRuntime() != RT_SUCCESS)
return 1; return 1;
vyRegisterRendererCVars(); rtRegisterRendererCVars();
WNDCLASSEXW wndclass = { WNDCLASSEXW wndclass = {
.cbSize = sizeof(wndclass), .cbSize = sizeof(wndclass),
.hInstance = hInstance, .hInstance = hInstance,
.lpszClassName = L"vyWndClass", .lpszClassName = L"rtWndClass",
.style = CS_OWNDC, .style = CS_OWNDC,
.lpfnWndProc = win32WndProc, .lpfnWndProc = win32WndProc,
}; };
if (!RegisterClassExW(&wndclass)) { if (!RegisterClassExW(&wndclass)) {
vyReportError("CORE", "RegisterClassEx failed: %u", GetLastError()); rtReportError("CORE", "RegisterClassEx failed: %u", GetLastError());
return 1; return 1;
} }
@ -48,7 +48,7 @@ vyWin32Entry(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int n
int w = GetSystemMetrics(SM_CXSCREEN); int w = GetSystemMetrics(SM_CXSCREEN);
int h = GetSystemMetrics(SM_CYSCREEN); int h = GetSystemMetrics(SM_CYSCREEN);
wnd = CreateWindowExW(WS_EX_APPWINDOW, wnd = CreateWindowExW(WS_EX_APPWINDOW,
L"vyWndClass", L"rtWndClass",
L"Voyage", L"Voyage",
WS_POPUP, WS_POPUP,
0, 0,
@ -65,7 +65,7 @@ vyWin32Entry(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int n
int w = rt_WindowWidth.i; int w = rt_WindowWidth.i;
int h = rt_WindowHeight.i; int h = rt_WindowHeight.i;
wnd = CreateWindowExW(WS_EX_APPWINDOW, wnd = CreateWindowExW(WS_EX_APPWINDOW,
L"vyWndClass", L"rtWndClass",
L"Voyage", L"Voyage",
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU, WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
CW_USEDEFAULT, CW_USEDEFAULT,
@ -80,13 +80,13 @@ vyWin32Entry(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int n
} }
if (!wnd) { if (!wnd) {
vyReportError("CORE", "Failed to create the game window: %u", GetLastError()); rtReportError("CORE", "Failed to create the game window: %u", GetLastError());
return 1; return 1;
} }
vy_renderer_init_info renderer_info = {.hWnd = wnd, .hInstance = hInstance}; rt_renderer_init_info renderer_info = {.hWnd = wnd, .hInstance = hInstance};
if (!vyInitGFX(&renderer_info)) { if (!rtInitGFX(&renderer_info)) {
vyReportError("GFX", "Init failed."); rtReportError("GFX", "Init failed.");
return 1; return 1;
} }
@ -104,17 +104,17 @@ vyWin32Entry(HINSTANCE hInstance, HINSTANCE hPrevInstance, PWSTR pCmdLine, int n
} }
} }
vyShutdownGFX(); rtShutdownGFX();
DestroyWindow(wnd); DestroyWindow(wnd);
UnregisterClassW(L"vyWndClass", hInstance); UnregisterClassW(L"rtWndClass", hInstance);
vyShutdownRuntime(); rtShutdownRuntime();
return 0; return 0;
} }
#elif defined(VY_USE_XLIB) #elif defined(RT_USE_XLIB)
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <assert.h> #include <assert.h>
@ -123,7 +123,7 @@ static void xlibSetFullscreen(Display *dpy, int screen, Window window, bool enab
Atom wm_state = XInternAtom(dpy, "_NET_W_STATE", False); Atom wm_state = XInternAtom(dpy, "_NET_W_STATE", False);
Atom wm_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False); Atom wm_fullscreen = XInternAtom(dpy, "_NET_WM_STATE_FULLSCREEN", False);
if (wm_state == None || wm_fullscreen == None) { if (wm_state == None || wm_fullscreen == None) {
vyLog("CORE", "Window manager does not support fullscreen mode."); rtLog("CORE", "Window manager does not support fullscreen mode.");
return; return;
} }
@ -146,7 +146,7 @@ static void xlibSetFullscreen(Display *dpy, int screen, Window window, bool enab
long ev_mask = SubstructureRedirectMask; long ev_mask = SubstructureRedirectMask;
if (!XSendEvent(dpy, root_window, False, ev_mask, &ev)) { if (!XSendEvent(dpy, root_window, False, ev_mask, &ev)) {
vyReportError("CORE", "Failed to send x11 fullscreen event."); rtReportError("CORE", "Failed to send x11 fullscreen event.");
} }
#undef _NET_WM_STATE_ADD #undef _NET_WM_STATE_ADD
@ -154,16 +154,16 @@ static void xlibSetFullscreen(Display *dpy, int screen, Window window, bool enab
#undef EVENT_SOURCE_APPLICATION #undef EVENT_SOURCE_APPLICATION
} }
VY_DLLEXPORT int vyXlibEntry(int argc, char **argv) { RT_DLLEXPORT int rtXlibEntry(int argc, char **argv) {
if (vyInitRuntime() != VY_SUCCESS) if (rtInitRuntime() != RT_SUCCESS)
return 1; return 1;
vyRegisterRendererCVars(); rtRegisterRendererCVars();
Display *dpy = XOpenDisplay(NULL); Display *dpy = XOpenDisplay(NULL);
if (!dpy) { if (!dpy) {
vyReportError("CORE", "Failed to open default display"); rtReportError("CORE", "Failed to open default display");
return 1; return 1;
} }
int screen = DefaultScreen(dpy); int screen = DefaultScreen(dpy);
@ -185,7 +185,7 @@ VY_DLLEXPORT int vyXlibEntry(int argc, char **argv) {
Atom wm_close = XInternAtom(dpy, "WM_DELETE_WINDOW", False); Atom wm_close = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
if (!wm_close) { if (!wm_close) {
vyReportError("CORE", "Failed to find WM_DELETE_WINDOW atom."); rtReportError("CORE", "Failed to find WM_DELETE_WINDOW atom.");
XDestroyWindow(dpy, window); XDestroyWindow(dpy, window);
XCloseDisplay(dpy); XCloseDisplay(dpy);
return 1; return 1;
@ -195,9 +195,9 @@ VY_DLLEXPORT int vyXlibEntry(int argc, char **argv) {
if (rt_Fullscreen.i) if (rt_Fullscreen.i)
xlibSetFullscreen(dpy, screen, window, true); xlibSetFullscreen(dpy, screen, window, true);
vy_renderer_init_info renderer_info = {.display = dpy, .window = window}; rt_renderer_init_info renderer_info = {.display = dpy, .window = window};
if (!vyInitGFX(&renderer_info)) { if (!rtInitGFX(&renderer_info)) {
vyReportError("GFX", "Init failed."); rtReportError("GFX", "Init failed.");
return 1; return 1;
} }
@ -218,7 +218,7 @@ VY_DLLEXPORT int vyXlibEntry(int argc, char **argv) {
break; break;
case ClientMessage: case ClientMessage:
if (event.xclient.data.l[0] == (long)wm_close) { if (event.xclient.data.l[0] == (long)wm_close) {
vyLog("CORE", "Received WM_DELETE_WINDOW"); rtLog("CORE", "Received WM_DELETE_WINDOW");
keep_running = false; keep_running = false;
} }
break; break;
@ -226,10 +226,10 @@ VY_DLLEXPORT int vyXlibEntry(int argc, char **argv) {
} }
} }
vyShutdownGFX(); rtShutdownGFX();
XDestroyWindow(dpy, window); XDestroyWindow(dpy, window);
XCloseDisplay(dpy); XCloseDisplay(dpy);
vyShutdownRuntime(); rtShutdownRuntime();
return 0; return 0;
} }

View File

@ -1,5 +1,5 @@
#ifndef VY_APP_H #ifndef RT_APP_H
#define VY_APP_H #define RT_APP_H
/* Platform specific application entry point */ /* Platform specific application entry point */
@ -10,14 +10,14 @@
/* Forward declared here, to avoid including windows.h */ /* Forward declared here, to avoid including windows.h */
struct HINSTANCE__; struct HINSTANCE__;
VY_DLLEXPORT int vyWin32Entry(struct HINSTANCE__ *hInstance, RT_DLLEXPORT int rtWin32Entry(struct HINSTANCE__ *hInstance,
struct HINSTANCE__ *hPrevInstance, struct HINSTANCE__ *hPrevInstance,
wchar_t *pCmdLine, wchar_t *pCmdLine,
int nCmdShow); int nCmdShow);
#elif defined(VY_USE_XLIB) #elif defined(RT_USE_XLIB)
VY_DLLEXPORT int vyXlibEntry(int argc, char **argv); RT_DLLEXPORT int rtXlibEntry(int argc, char **argv);
#endif #endif

View File

@ -9,10 +9,10 @@
#include <assert.h> #include <assert.h>
#include <stdlib.h> #include <stdlib.h>
VY_CVAR_I(rt_AssetCacheSize, "Number of asset cache entries. Default: 1024.", 1024); RT_CVAR_I(rt_AssetCacheSize, "Number of asset cache entries. Default: 1024.", 1024);
/* asset_loading.c */ /* asset_loading.c */
extern vy_result DecompressAsset(void *compressed_buffer, extern rt_result DecompressAsset(void *compressed_buffer,
size_t compressed_buffer_size, size_t compressed_buffer_size,
void **p_decompressed, void **p_decompressed,
size_t *p_decompressed_size); size_t *p_decompressed_size);
@ -21,63 +21,63 @@ typedef enum {
CACHE_ENTRY_STATE_FREE, CACHE_ENTRY_STATE_FREE,
CACHE_ENTRY_STATE_LOADING, CACHE_ENTRY_STATE_LOADING,
CACHE_ENTRY_STATE_LOADED, CACHE_ENTRY_STATE_LOADED,
} vy_asset_cache_entry_state; } rt_asset_cache_entry_state;
typedef struct vy_asset_cache_entry_s { typedef struct rt_asset_cache_entry_s {
vy_asset_cache_entry_state state; rt_asset_cache_entry_state state;
vy_aio_handle load; rt_aio_handle load;
void *buffer; void *buffer;
size_t size; size_t size;
int refcount; int refcount;
/* Reclaim list */ /* Reclaim list */
struct vy_asset_cache_entry_s *prev_reclaim; struct rt_asset_cache_entry_s *prev_reclaim;
struct vy_asset_cache_entry_s *next_reclaim; struct rt_asset_cache_entry_s *next_reclaim;
} vy_asset_cache_entry; } rt_asset_cache_entry;
static vy_uid *_uids; static rt_uid *_uids;
static vy_asset_cache_entry *_entries; static rt_asset_cache_entry *_entries;
static vy_asset_cache_entry *_first_reclaim; static rt_asset_cache_entry *_first_reclaim;
static vy_asset_cache_entry *_last_reclaim; static rt_asset_cache_entry *_last_reclaim;
/* Locked as writer when modifiying entries, as reader when searching */ /* Locked as writer when modifiying entries, as reader when searching */
static vy_rwlock _lock; static rt_rwlock _lock;
vy_result InitAssetCache(void) { rt_result InitAssetCache(void) {
_entries = calloc((size_t)rt_AssetCacheSize.i, sizeof(vy_asset_cache_entry)); _entries = calloc((size_t)rt_AssetCacheSize.i, sizeof(rt_asset_cache_entry));
if (!_entries) { if (!_entries) {
return VY_BUFFER_ALLOC_FAILED; return RT_BUFFER_ALLOC_FAILED;
} }
_uids = calloc((size_t)rt_AssetCacheSize.i, sizeof(vy_uid)); _uids = calloc((size_t)rt_AssetCacheSize.i, sizeof(rt_uid));
if (!_uids) { if (!_uids) {
free(_entries); free(_entries);
return VY_BUFFER_ALLOC_FAILED; return RT_BUFFER_ALLOC_FAILED;
} }
vy_create_rwlock_result lock_res = vyCreateRWLock(); rt_create_rwlock_result lock_res = rtCreateRWLock();
if (!lock_res.ok) { if (!lock_res.ok) {
free(_entries); free(_entries);
free(_uids); free(_uids);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
_lock = lock_res.lock; _lock = lock_res.lock;
return VY_SUCCESS; return RT_SUCCESS;
} }
void ShutdownAssetCache(void) { void ShutdownAssetCache(void) {
free(_entries); free(_entries);
free(_uids); free(_uids);
vyDestroyRWLock(&_lock); rtDestroyRWLock(&_lock);
_first_reclaim = NULL; _first_reclaim = NULL;
_last_reclaim = NULL; _last_reclaim = NULL;
} }
static void ReleaseEntry(vy_asset_cache_entry *entry) { static void ReleaseEntry(rt_asset_cache_entry *entry) {
if (entry->load != VY_AIO_INVALID_HANDLE) { if (entry->load != RT_AIO_INVALID_HANDLE) {
vyWaitForAIOCompletion(entry->load); rtWaitForAIOCompletion(entry->load);
vyReleaseAIO(entry->load); rtReleaseAIO(entry->load);
entry->load = VY_AIO_INVALID_HANDLE; entry->load = RT_AIO_INVALID_HANDLE;
} }
vyReleaseBuffer(entry->buffer, entry->size); rtReleaseBuffer(entry->buffer, entry->size);
entry->buffer = NULL; entry->buffer = NULL;
entry->size = 0; entry->size = 0;
entry->next_reclaim = NULL; entry->next_reclaim = NULL;
@ -85,28 +85,28 @@ static void ReleaseEntry(vy_asset_cache_entry *entry) {
} }
static void GarbageCollect(void) { static void GarbageCollect(void) {
vyLockWrite(&_lock); rtLockWrite(&_lock);
vy_asset_cache_entry *entry = _first_reclaim; rt_asset_cache_entry *entry = _first_reclaim;
while (entry) { while (entry) {
assert(entry->refcount == 0); assert(entry->refcount == 0);
vy_asset_cache_entry *next = entry->next_reclaim; rt_asset_cache_entry *next = entry->next_reclaim;
if (entry->state == CACHE_ENTRY_STATE_LOADED) { if (entry->state == CACHE_ENTRY_STATE_LOADED) {
ReleaseEntry(entry); ReleaseEntry(entry);
_first_reclaim = next; _first_reclaim = next;
} }
entry = next; entry = next;
} }
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
} }
static vy_asset_cache_entry *GetEntry(vy_uid uid) { static rt_asset_cache_entry *GetEntry(rt_uid uid) {
/* Hash lookup */ /* Hash lookup */
unsigned int mod = (unsigned int)rt_AssetCacheSize.i - 1; unsigned int mod = (unsigned int)rt_AssetCacheSize.i - 1;
for (unsigned int i = 0; i < (unsigned int)rt_AssetCacheSize.i; ++i) { for (unsigned int i = 0; i < (unsigned int)rt_AssetCacheSize.i; ++i) {
unsigned int slot = (uid + i) & mod; unsigned int slot = (uid + i) & mod;
if (_uids[slot] == uid) { if (_uids[slot] == uid) {
return &_entries[slot]; return &_entries[slot];
} else if (_uids[slot] == VY_INVALID_UID) { } else if (_uids[slot] == RT_INVALID_UID) {
break; break;
} }
} }
@ -114,8 +114,8 @@ static vy_asset_cache_entry *GetEntry(vy_uid uid) {
} }
static bool IsAssetLoaded(vy_uid uid) { static bool IsAssetLoaded(rt_uid uid) {
const vy_asset_cache_entry *entry = GetEntry(uid); const rt_asset_cache_entry *entry = GetEntry(uid);
if (entry) if (entry)
return entry->state == CACHE_ENTRY_STATE_LOADED || return entry->state == CACHE_ENTRY_STATE_LOADED ||
entry->state == CACHE_ENTRY_STATE_LOADING; entry->state == CACHE_ENTRY_STATE_LOADING;
@ -123,7 +123,7 @@ static bool IsAssetLoaded(vy_uid uid) {
return false; return false;
} }
static int InsertEntry(vy_uid uid) { static int InsertEntry(rt_uid uid) {
unsigned int mod = (unsigned int)rt_AssetCacheSize.i - 1; unsigned int mod = (unsigned int)rt_AssetCacheSize.i - 1;
for (unsigned int i = 0; i < (unsigned int)rt_AssetCacheSize.i; ++i) { for (unsigned int i = 0; i < (unsigned int)rt_AssetCacheSize.i; ++i) {
unsigned int slot = (uid + i) & mod; unsigned int slot = (uid + i) & mod;
@ -133,58 +133,58 @@ static int InsertEntry(vy_uid uid) {
} }
return -1; return -1;
} }
static vy_result InsertAndLoadAssets(const vy_uid *uids, size_t count) { static rt_result InsertAndLoadAssets(const rt_uid *uids, size_t count) {
vy_load_batch batch = {.num_loads = 0}; rt_load_batch batch = {.num_loads = 0};
vy_result res = VY_SUCCESS; rt_result res = RT_SUCCESS;
count = (count < VY_LOAD_BATCH_MAX_SIZE) ? count : VY_LOAD_BATCH_MAX_SIZE; count = (count < RT_LOAD_BATCH_MAX_SIZE) ? count : RT_LOAD_BATCH_MAX_SIZE;
vy_asset_cache_entry *load_entries[VY_LOAD_BATCH_MAX_SIZE]; rt_asset_cache_entry *load_entries[RT_LOAD_BATCH_MAX_SIZE];
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
vyLockRead(&_lock); rtLockRead(&_lock);
bool needs_load = !IsAssetLoaded(uids[i]); bool needs_load = !IsAssetLoaded(uids[i]);
vyUnlockRead(&_lock); rtUnlockRead(&_lock);
if (!needs_load) if (!needs_load)
continue; continue;
vyLockWrite(&_lock); rtLockWrite(&_lock);
/* It's possible that another thread loaded the asset in the meantime */ /* It's possible that another thread loaded the asset in the meantime */
if (!IsAssetLoaded(uids[i])) { if (!IsAssetLoaded(uids[i])) {
const vy_uid_data *data = vyGetUIDData(uids[i]); const rt_uid_data *data = rtGetUIDData(uids[i]);
if (!data) { if (!data) {
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
vyLog("ASSET_CACHE", "Failed to get uid data for uid %u", uids[i]); rtLog("ASSET_CACHE", "Failed to get uid data for uid %u", uids[i]);
res = VY_UNKNOWN_ASSET; res = RT_UNKNOWN_ASSET;
continue; continue;
} }
void *compressed_data = vyAllocBuffer(data->size); void *compressed_data = rtAllocBuffer(data->size);
if (!compressed_data) { if (!compressed_data) {
/* Try again after garbage collection */ /* Try again after garbage collection */
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
GarbageCollect(); GarbageCollect();
compressed_data = vyAllocBuffer(data->size); compressed_data = rtAllocBuffer(data->size);
if (!compressed_data) { if (!compressed_data) {
vyLog("ASSET_CACHE", rtLog("ASSET_CACHE",
"Failed to allocate intermediate buffer for uid %u", "Failed to allocate intermediate buffer for uid %u",
uids[i]); uids[i]);
res = VY_BUFFER_ALLOC_FAILED; res = RT_BUFFER_ALLOC_FAILED;
continue; continue;
} }
vyLockWrite(&_lock); rtLockWrite(&_lock);
} }
int slot = InsertEntry(uids[i]); int slot = InsertEntry(uids[i]);
if (slot == -1) { if (slot == -1) {
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
vyLog("ASSET_CACHE", "Failed to insert new entry for uid %u", uids[i]); rtLog("ASSET_CACHE", "Failed to insert new entry for uid %u", uids[i]);
res = VY_ASSET_CACHE_FULL; res = RT_ASSET_CACHE_FULL;
break; break;
} }
vy_asset_cache_entry *entry = &_entries[slot]; rt_asset_cache_entry *entry = &_entries[slot];
load_entries[batch.num_loads] = entry; load_entries[batch.num_loads] = entry;
/* We set the refcount to 0, but don't insert the entry /* We set the refcount to 0, but don't insert the entry
@ -197,7 +197,7 @@ static vy_result InsertAndLoadAssets(const vy_uid *uids, size_t count) {
entry->size = data->size; entry->size = data->size;
entry->next_reclaim = NULL; entry->next_reclaim = NULL;
entry->prev_reclaim = NULL; entry->prev_reclaim = NULL;
entry->load = VY_AIO_INVALID_HANDLE; entry->load = RT_AIO_INVALID_HANDLE;
batch.loads[batch.num_loads].file = data->pkg_file; batch.loads[batch.num_loads].file = data->pkg_file;
batch.loads[batch.num_loads].num_bytes = data->size; batch.loads[batch.num_loads].num_bytes = data->size;
@ -206,45 +206,45 @@ static vy_result InsertAndLoadAssets(const vy_uid *uids, size_t count) {
++batch.num_loads; ++batch.num_loads;
} }
} }
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
/* Dispatch the load */ /* Dispatch the load */
vy_aio_handle handles[VY_LOAD_BATCH_MAX_SIZE]; rt_aio_handle handles[RT_LOAD_BATCH_MAX_SIZE];
if ((res = vySubmitLoadBatch(&batch, handles)) != VY_SUCCESS) { if ((res = rtSubmitLoadBatch(&batch, handles)) != RT_SUCCESS) {
vyLog("ASSET_CACHE", "Failed to submit %u asset loads.", batch.num_loads); rtLog("ASSET_CACHE", "Failed to submit %u asset loads.", batch.num_loads);
return res; return res;
} }
/* Set the aio handles of the inserted entries */ /* Set the aio handles of the inserted entries */
vyLockWrite(&_lock); rtLockWrite(&_lock);
for (unsigned int i = 0; i < batch.num_loads; ++i) { for (unsigned int i = 0; i < batch.num_loads; ++i) {
load_entries[batch.num_loads]->load = handles[i]; load_entries[batch.num_loads]->load = handles[i];
} }
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
return res; return res;
} }
static bool DecompressEntry(vy_uid uid, vy_asset_cache_entry *entry) { static bool DecompressEntry(rt_uid uid, rt_asset_cache_entry *entry) {
vyReleaseAIO(entry->load); rtReleaseAIO(entry->load);
entry->load = VY_AIO_INVALID_HANDLE; entry->load = RT_AIO_INVALID_HANDLE;
void *decompressed_buffer; void *decompressed_buffer;
size_t decompressed_size; size_t decompressed_size;
vy_result dec_res = rt_result dec_res =
DecompressAsset(entry->buffer, entry->size, &decompressed_buffer, &decompressed_size); DecompressAsset(entry->buffer, entry->size, &decompressed_buffer, &decompressed_size);
if (dec_res == VY_SUCCESS) { if (dec_res == RT_SUCCESS) {
vyReleaseBuffer(entry->buffer, entry->size); rtReleaseBuffer(entry->buffer, entry->size);
entry->buffer = decompressed_buffer; entry->buffer = decompressed_buffer;
entry->size = decompressed_size; entry->size = decompressed_size;
entry->state = CACHE_ENTRY_STATE_LOADED; entry->state = CACHE_ENTRY_STATE_LOADED;
return true; return true;
} else if (dec_res == VY_BUFFER_ALLOC_FAILED) { } else if (dec_res == RT_BUFFER_ALLOC_FAILED) {
GarbageCollect(); GarbageCollect();
/* Try again */ /* Try again */
if (DecompressAsset(entry->buffer, entry->size, &decompressed_buffer, &decompressed_size) == if (DecompressAsset(entry->buffer, entry->size, &decompressed_buffer, &decompressed_size) ==
VY_SUCCESS) { RT_SUCCESS) {
vyReleaseBuffer(entry->buffer, entry->size); rtReleaseBuffer(entry->buffer, entry->size);
entry->buffer = decompressed_buffer; entry->buffer = decompressed_buffer;
entry->size = decompressed_size; entry->size = decompressed_size;
entry->state = CACHE_ENTRY_STATE_LOADED; entry->state = CACHE_ENTRY_STATE_LOADED;
@ -252,74 +252,74 @@ static bool DecompressEntry(vy_uid uid, vy_asset_cache_entry *entry) {
} }
/* Don't do anything yet. We might be able to to do this later, once some /* Don't do anything yet. We might be able to to do this later, once some
* buffers become free. */ * buffers become free. */
vyLog("ASSET_CACHE", "Failed to decompress asset %u", uid); rtLog("ASSET_CACHE", "Failed to decompress asset %u", uid);
return false; return false;
} else { } else {
vyLog("ASSET_CACHE", "Failed to decompress asset %u", uid); rtLog("ASSET_CACHE", "Failed to decompress asset %u", uid);
ReleaseEntry(entry); ReleaseEntry(entry);
ptrdiff_t idx = entry - _entries; ptrdiff_t idx = entry - _entries;
_uids[idx] = VY_INVALID_UID; _uids[idx] = RT_INVALID_UID;
return false; return false;
} }
} }
static void CheckCompletedLoads(const vy_uid *uids, size_t count) { static void CheckCompletedLoads(const rt_uid *uids, size_t count) {
for (size_t i = 0; i < count; ++i) { for (size_t i = 0; i < count; ++i) {
vyLockRead(&_lock); rtLockRead(&_lock);
volatile vy_asset_cache_entry *entry = (volatile vy_asset_cache_entry *)GetEntry(uids[i]); volatile rt_asset_cache_entry *entry = (volatile rt_asset_cache_entry *)GetEntry(uids[i]);
if (!entry) { if (!entry) {
vyUnlockRead(&_lock); rtUnlockRead(&_lock);
vyLog("ASSET_CACHE", "Passed unknown uid %u to CheckCompletedLoads()", uids[i]); rtLog("ASSET_CACHE", "Passed unknown uid %u to CheckCompletedLoads()", uids[i]);
continue; continue;
} }
if (entry->state != CACHE_ENTRY_STATE_LOADING) { if (entry->state != CACHE_ENTRY_STATE_LOADING) {
vyUnlockRead(&_lock); rtUnlockRead(&_lock);
continue; continue;
} }
bool load_finished = vyGetAIOState(entry->load) == VY_AIO_STATE_FINISHED; bool load_finished = rtGetAIOState(entry->load) == RT_AIO_STATE_FINISHED;
vyUnlockRead(&_lock); rtUnlockRead(&_lock);
if (load_finished) { if (load_finished) {
vyLockWrite(&_lock); rtLockWrite(&_lock);
/* Ensure that no-one else handled this */ /* Ensure that no-one else handled this */
if (entry->state == CACHE_ENTRY_STATE_LOADING) { if (entry->state == CACHE_ENTRY_STATE_LOADING) {
DecompressEntry(uids[i], (vy_asset_cache_entry *)entry); DecompressEntry(uids[i], (rt_asset_cache_entry *)entry);
} }
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
} }
} }
} }
VY_DLLEXPORT vy_get_asset_result vyGetAsset(vy_uid uid) { RT_DLLEXPORT rt_get_asset_result rtGetAsset(rt_uid uid) {
vy_get_asset_result result = { rt_get_asset_result result = {
.result = VY_SUCCESS, .result = RT_SUCCESS,
}; };
vyLockRead(&_lock); rtLockRead(&_lock);
bool needs_load = !IsAssetLoaded(uid); bool needs_load = !IsAssetLoaded(uid);
vyUnlockRead(&_lock); rtUnlockRead(&_lock);
if (needs_load) { if (needs_load) {
vy_uid load_uids[VY_LOAD_BATCH_MAX_SIZE]; rt_uid load_uids[RT_LOAD_BATCH_MAX_SIZE];
size_t load_count = 1; size_t load_count = 1;
load_uids[0] = uid; load_uids[0] = uid;
vy_asset_dependency_list deps = vyGetAssetDependencies(uid); rt_asset_dependency_list deps = rtGetAssetDependencies(uid);
for (size_t i = 0; i < deps.count && i < VY_LOAD_BATCH_MAX_SIZE - 1; ++i) { for (size_t i = 0; i < deps.count && i < RT_LOAD_BATCH_MAX_SIZE - 1; ++i) {
load_uids[i + 1] = deps.dependencies[i]; load_uids[i + 1] = deps.dependencies[i];
++load_count; ++load_count;
} }
result.result = InsertAndLoadAssets(load_uids, load_count); result.result = InsertAndLoadAssets(load_uids, load_count);
if (result.result == VY_SUCCESS) { if (result.result == RT_SUCCESS) {
CheckCompletedLoads(load_uids, load_count); CheckCompletedLoads(load_uids, load_count);
} }
} }
vyLockWrite(&_lock); rtLockWrite(&_lock);
vy_asset_cache_entry *entry = GetEntry(uid); rt_asset_cache_entry *entry = GetEntry(uid);
if (entry) { if (entry) {
if (entry->state == CACHE_ENTRY_STATE_LOADED) { if (entry->state == CACHE_ENTRY_STATE_LOADED) {
++entry->refcount; ++entry->refcount;
@ -327,19 +327,19 @@ VY_DLLEXPORT vy_get_asset_result vyGetAsset(vy_uid uid) {
result.size = entry->size; result.size = entry->size;
} else if (entry->state == CACHE_ENTRY_STATE_LOADING) { } else if (entry->state == CACHE_ENTRY_STATE_LOADING) {
if (entry->state == CACHE_ENTRY_STATE_LOADING) { if (entry->state == CACHE_ENTRY_STATE_LOADING) {
assert(entry->load != VY_AIO_INVALID_HANDLE); assert(entry->load != RT_AIO_INVALID_HANDLE);
++entry->refcount; ++entry->refcount;
if (vyWaitForAIOCompletion(entry->load) == VY_AIO_STATE_FINISHED) { if (rtWaitForAIOCompletion(entry->load) == RT_AIO_STATE_FINISHED) {
if (DecompressEntry(uid, entry)) { if (DecompressEntry(uid, entry)) {
result.data = entry->buffer; result.data = entry->buffer;
result.size = entry->size; result.size = entry->size;
} else { } else {
result.result = VY_LOAD_FAILED; result.result = RT_LOAD_FAILED;
} }
} else { } else {
ReleaseEntry(entry); ReleaseEntry(entry);
vyLog("ASSET_CACHE", "Failed to load asset %u", uid); rtLog("ASSET_CACHE", "Failed to load asset %u", uid);
result.result = VY_LOAD_FAILED; result.result = RT_LOAD_FAILED;
} }
} }
} }
@ -354,14 +354,14 @@ VY_DLLEXPORT vy_get_asset_result vyGetAsset(vy_uid uid) {
if (entry->prev_reclaim) if (entry->prev_reclaim)
entry->prev_reclaim->next_reclaim = entry->next_reclaim; entry->prev_reclaim->next_reclaim = entry->next_reclaim;
} }
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
return result; return result;
} }
VY_DLLEXPORT void vyReleaseAsset(vy_uid uid) { RT_DLLEXPORT void rtReleaseAsset(rt_uid uid) {
vyLockWrite(&_lock); rtLockWrite(&_lock);
vy_asset_cache_entry *entry = GetEntry(uid); rt_asset_cache_entry *entry = GetEntry(uid);
if (entry && entry->refcount > 0) { if (entry && entry->refcount > 0) {
--entry->refcount; --entry->refcount;
if (entry->refcount == 0) { if (entry->refcount == 0) {
@ -375,5 +375,5 @@ VY_DLLEXPORT void vyReleaseAsset(vy_uid uid) {
_last_reclaim = entry; _last_reclaim = entry;
} }
} }
vyUnlockWrite(&_lock); rtUnlockWrite(&_lock);
} }

View File

@ -1,4 +1,4 @@
#define VY_DEFINE_DEPENDENCY_FILE_STRUCTURES #define RT_DEFINE_DEPENDENCY_FILE_STRUCTURES
#include "asset_dependencies.h" #include "asset_dependencies.h"
#include "aio.h" #include "aio.h"
@ -12,87 +12,87 @@
typedef struct { typedef struct {
uint32_t begin; uint32_t begin;
uint32_t count; uint32_t count;
} vy_dep_list; } rt_dep_list;
typedef struct { typedef struct {
vy_uid *uids; rt_uid *uids;
vy_dep_list *lists; rt_dep_list *lists;
uint32_t capacity; uint32_t capacity;
} vy_dep_map; } rt_dep_map;
static vy_dep_map _map; static rt_dep_map _map;
static vy_uid *_list_mem; static rt_uid *_list_mem;
vy_result LoadAssetDependencies(void) { rt_result LoadAssetDependencies(void) {
vy_dependency_file_header header; rt_dependency_file_header header;
vy_file_id fid = vyAddFile("data/deps.bin"); rt_file_id fid = rtAddFile("data/deps.bin");
if (vySubmitSingleLoadSync((vy_file_load){.dest = &header, if (rtSubmitSingleLoadSync((rt_file_load){.dest = &header,
.num_bytes = sizeof(header), .num_bytes = sizeof(header),
.offset = 0, .offset = 0,
.file = fid}) != VY_AIO_STATE_FINISHED) { .file = fid}) != RT_AIO_STATE_FINISHED) {
vyReportError("core", "Failed to load deps.bin"); rtReportError("core", "Failed to load deps.bin");
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
void *buffer = vyAllocBuffer(header.data_size); void *buffer = rtAllocBuffer(header.data_size);
if (vySubmitSingleLoadSync((vy_file_load){.dest = buffer, if (rtSubmitSingleLoadSync((rt_file_load){.dest = buffer,
.num_bytes = header.data_size, .num_bytes = header.data_size,
.offset = sizeof(header), .offset = sizeof(header),
.file = fid}) != VY_AIO_STATE_FINISHED) { .file = fid}) != RT_AIO_STATE_FINISHED) {
vyReportError("core", "Failed to load deps.bin"); rtReportError("core", "Failed to load deps.bin");
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
/* We know the exact number of list entries */ /* We know the exact number of list entries */
uint64_t total_list_entries = uint64_t total_list_entries =
(header.data_size - header.num_lists * sizeof(vy_dependency_file_list_header)) / (header.data_size - header.num_lists * sizeof(rt_dependency_file_list_header)) /
sizeof(vy_uid); sizeof(rt_uid);
_list_mem = malloc(total_list_entries * sizeof(vy_uid)); _list_mem = malloc(total_list_entries * sizeof(rt_uid));
if (!_list_mem) { if (!_list_mem) {
vyReleaseBuffer(buffer, header.data_size); rtReleaseBuffer(buffer, header.data_size);
vyReportError("core", "Failed to allocate dependency list storage."); rtReportError("core", "Failed to allocate dependency list storage.");
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
_map.capacity = vyNextPowerOfTwo32(header.num_lists); _map.capacity = rtNextPowerOfTwo32(header.num_lists);
_map.uids = calloc(_map.capacity, sizeof(vy_uid)); _map.uids = calloc(_map.capacity, sizeof(rt_uid));
if (!_map.uids) { if (!_map.uids) {
free(_list_mem); free(_list_mem);
vyReleaseBuffer(buffer, header.data_size); rtReleaseBuffer(buffer, header.data_size);
vyReportError("core", "Failed to allocate dependency list storage."); rtReportError("core", "Failed to allocate dependency list storage.");
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
_map.lists = calloc(_map.capacity, sizeof(vy_dep_list)); _map.lists = calloc(_map.capacity, sizeof(rt_dep_list));
if (!_map.uids) { if (!_map.uids) {
free(_list_mem); free(_list_mem);
free(_map.uids); free(_map.uids);
vyReleaseBuffer(buffer, header.data_size); rtReleaseBuffer(buffer, header.data_size);
vyReportError("core", "Failed to allocate dependency list storage."); rtReportError("core", "Failed to allocate dependency list storage.");
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
uint32_t storage_at = 0; uint32_t storage_at = 0;
vy_dependency_file_list_header *list = buffer; rt_dependency_file_list_header *list = buffer;
for (uint32_t i = 0; i < header.num_lists; ++i) { for (uint32_t i = 0; i < header.num_lists; ++i) {
const vy_uid *entries = (vy_uid *)(list + 1); const rt_uid *entries = (rt_uid *)(list + 1);
/* Validate the checksum */ /* Validate the checksum */
XXH64_hash_t file_hash = XXH64_hashFromCanonical(&list->checksum); XXH64_hash_t file_hash = XXH64_hashFromCanonical(&list->checksum);
XXH64_hash_t calc_hash = XXH3_64bits(entries, sizeof(vy_uid) * list->num_entries); XXH64_hash_t calc_hash = XXH3_64bits(entries, sizeof(rt_uid) * list->num_entries);
if (file_hash != calc_hash) { if (file_hash != calc_hash) {
vyReportError("core", "Checksum mismatch in list %u", i); rtReportError("core", "Checksum mismatch in list %u", i);
vyReleaseBuffer(buffer, header.data_size); rtReleaseBuffer(buffer, header.data_size);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
/* Store the list */ /* Store the list */
memcpy(_list_mem + storage_at, entries, sizeof(vy_uid) * list->num_entries); memcpy(_list_mem + storage_at, entries, sizeof(rt_uid) * list->num_entries);
bool inserted = false; bool inserted = false;
for (uint32_t j = 0; j < _map.capacity; ++j) { for (uint32_t j = 0; j < _map.capacity; ++j) {
uint32_t slot = (list->uid + j) % _map.capacity; uint32_t slot = (list->uid + j) % _map.capacity;
if (_map.uids[slot] == VY_INVALID_UID) { if (_map.uids[slot] == RT_INVALID_UID) {
_map.uids[slot] = list->uid; _map.uids[slot] = list->uid;
_map.lists[slot].begin = storage_at; _map.lists[slot].begin = storage_at;
_map.lists[slot].count = list->num_entries; _map.lists[slot].count = list->num_entries;
@ -104,12 +104,12 @@ vy_result LoadAssetDependencies(void) {
assert(inserted); assert(inserted);
assert(storage_at <= total_list_entries); assert(storage_at <= total_list_entries);
list = (vy_dependency_file_list_header *)(entries + list->num_entries); list = (rt_dependency_file_list_header *)(entries + list->num_entries);
} }
vyReleaseBuffer(buffer, header.data_size); rtReleaseBuffer(buffer, header.data_size);
return VY_SUCCESS; return RT_SUCCESS;
} }
void ReleaseAssetDependencies(void) { void ReleaseAssetDependencies(void) {
@ -118,8 +118,8 @@ void ReleaseAssetDependencies(void) {
free(_map.lists); free(_map.lists);
} }
VY_DLLEXPORT vy_asset_dependency_list vyGetAssetDependencies(vy_uid asset) { RT_DLLEXPORT rt_asset_dependency_list rtGetAssetDependencies(rt_uid asset) {
vy_asset_dependency_list result = { rt_asset_dependency_list result = {
.dependencies = NULL, .dependencies = NULL,
.count = 0, .count = 0,
}; };
@ -129,7 +129,7 @@ VY_DLLEXPORT vy_asset_dependency_list vyGetAssetDependencies(vy_uid asset) {
result.dependencies = &_list_mem[_map.lists[slot].begin]; result.dependencies = &_list_mem[_map.lists[slot].begin];
result.count = _map.lists[slot].count; result.count = _map.lists[slot].count;
break; break;
} else if (_map.uids[slot] == VY_INVALID_UID) { } else if (_map.uids[slot] == RT_INVALID_UID) {
break; break;
} }
} }

View File

@ -1,9 +1,9 @@
#ifndef VY_ASSET_DEPENDENCIES_H #ifndef RT_ASSET_DEPENDENCIES_H
#define VY_ASSET_DEPENDENCIES_H #define RT_ASSET_DEPENDENCIES_H
#include "assets.h" #include "assets.h"
#ifdef VY_DEFINE_DEPENDENCY_FILE_STRUCTURES #ifdef RT_DEFINE_DEPENDENCY_FILE_STRUCTURES
#include "xxhash/xxhash.h" #include "xxhash/xxhash.h"
@ -11,23 +11,23 @@
typedef struct { typedef struct {
uint64_t data_size; uint64_t data_size;
uint32_t num_lists; uint32_t num_lists;
} vy_dependency_file_header; } rt_dependency_file_header;
typedef struct { typedef struct {
vy_uid uid; rt_uid uid;
uint32_t num_entries; uint32_t num_entries;
XXH64_canonical_t checksum; XXH64_canonical_t checksum;
} vy_dependency_file_list_header; } rt_dependency_file_list_header;
#pragma pack(pop) #pragma pack(pop)
#endif #endif
typedef struct { typedef struct {
const vy_uid *dependencies; const rt_uid *dependencies;
uint32_t count; uint32_t count;
} vy_asset_dependency_list; } rt_asset_dependency_list;
VY_DLLEXPORT vy_asset_dependency_list vyGetAssetDependencies(vy_uid asset); RT_DLLEXPORT rt_asset_dependency_list rtGetAssetDependencies(rt_uid asset);
#endif #endif

View File

@ -3,70 +3,70 @@
#include "aio.h" #include "aio.h"
#include "buffer_manager.h" #include "buffer_manager.h"
#define VY_DEFINE_PACKAGE_FILE_STRUCTURES #define RT_DEFINE_PACKAGE_FILE_STRUCTURES
#include "packages.h" #include "packages.h"
#include "lz4/lz4.h" #include "lz4/lz4.h"
vy_result DecompressAsset(void *compressed_buffer, rt_result DecompressAsset(void *compressed_buffer,
size_t compressed_buffer_size, size_t compressed_buffer_size,
void **p_decompressed, void **p_decompressed,
size_t *p_decompressed_size) { size_t *p_decompressed_size) {
const vy_package_asset_header *header = compressed_buffer; const rt_package_asset_header *header = compressed_buffer;
size_t compressed_size = (compressed_buffer_size) - sizeof(*header); size_t compressed_size = (compressed_buffer_size) - sizeof(*header);
XXH64_hash_t calculated_hash = XXH3_64bits((header + 1), compressed_size); XXH64_hash_t calculated_hash = XXH3_64bits((header + 1), compressed_size);
XXH64_hash_t file_hash = XXH64_hashFromCanonical(&header->checksum); XXH64_hash_t file_hash = XXH64_hashFromCanonical(&header->checksum);
if (calculated_hash != file_hash) { if (calculated_hash != file_hash) {
vyLog("core", "Checksum mismatch for asset"); rtLog("core", "Checksum mismatch for asset");
return VY_LOAD_FAILED; return RT_LOAD_FAILED;
} }
size_t size = (size_t)header->decompressed_size; size_t size = (size_t)header->decompressed_size;
void *decompressed_buffer = vyAllocBuffer(size); void *decompressed_buffer = rtAllocBuffer(size);
if (!decompressed_buffer) { if (!decompressed_buffer) {
return VY_BUFFER_ALLOC_FAILED; return RT_BUFFER_ALLOC_FAILED;
} }
if (LZ4_decompress_safe((const char *)(header + 1), if (LZ4_decompress_safe((const char *)(header + 1),
(char *)decompressed_buffer, (char *)decompressed_buffer,
(int)compressed_size, (int)compressed_size,
(int)size) < 0) { (int)size) < 0) {
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
*p_decompressed = decompressed_buffer; *p_decompressed = decompressed_buffer;
*p_decompressed_size = size; *p_decompressed_size = size;
return VY_SUCCESS; return RT_SUCCESS;
} }
VY_DLLEXPORT vy_result vyLoadAssetDirect(vy_uid uid, void **p_buffer, size_t *p_size) { RT_DLLEXPORT rt_result rtLoadAssetDirect(rt_uid uid, void **p_buffer, size_t *p_size) {
const vy_uid_data *data = vyGetUIDData(uid); const rt_uid_data *data = rtGetUIDData(uid);
if (!data) if (!data)
return VY_UNKNOWN_ASSET; return RT_UNKNOWN_ASSET;
void *compressed_buffer = vyAllocBuffer(data->size); void *compressed_buffer = rtAllocBuffer(data->size);
if (!compressed_buffer) { if (!compressed_buffer) {
return VY_BUFFER_ALLOC_FAILED; return RT_BUFFER_ALLOC_FAILED;
} }
if (vySubmitSingleLoadSync((vy_file_load) { if (rtSubmitSingleLoadSync((rt_file_load) {
.file = data->pkg_file, .file = data->pkg_file,
.offset = data->offset, .offset = data->offset,
.num_bytes = data->size, .num_bytes = data->size,
.dest = compressed_buffer, .dest = compressed_buffer,
}) != VY_AIO_STATE_FINISHED) { }) != RT_AIO_STATE_FINISHED) {
vyReleaseBuffer(compressed_buffer, data->size); rtReleaseBuffer(compressed_buffer, data->size);
return VY_LOAD_FAILED; return RT_LOAD_FAILED;
} }
void *decompressed_buffer; void *decompressed_buffer;
size_t decompressed_size; size_t decompressed_size;
vy_result res = DecompressAsset(compressed_buffer, data->size, &decompressed_buffer, &decompressed_size); rt_result res = DecompressAsset(compressed_buffer, data->size, &decompressed_buffer, &decompressed_size);
vyReleaseBuffer(compressed_buffer, data->size); rtReleaseBuffer(compressed_buffer, data->size);
*p_buffer = decompressed_buffer; *p_buffer = decompressed_buffer;
*p_size = decompressed_size; *p_size = decompressed_size;

View File

@ -1,40 +1,40 @@
#ifndef VY_ASSETS_H #ifndef RT_ASSETS_H
#define VY_ASSETS_H #define RT_ASSETS_H
#include <stdint.h> #include <stdint.h>
#include "runtime.h" #include "runtime.h"
/* Unique identifier for an asset. */ /* Unique identifier for an asset. */
typedef uint32_t vy_uid; typedef uint32_t rt_uid;
#define VY_INVALID_UID 0 #define RT_INVALID_UID 0
/* Used to identify renderer backend dependent assets. */ /* Used to identify renderer backend dependent assets. */
enum { enum {
VY_INVALID_RENDERER_BACKEND_CODE = 0, RT_INVALID_RENDERER_BACKEND_CODE = 0,
VY_RENDERER_BACKEND_CODE_VK = 1, RT_RENDERER_BACKEND_CODE_VK = 1,
VY_RENDERER_BACKEND_CODE_ONE_PAST_LAST, RT_RENDERER_BACKEND_CODE_ONE_PAST_LAST,
}; };
typedef uint8_t vy_renderer_backend_code; typedef uint8_t rt_renderer_backend_code;
enum { enum {
VY_UNKNOWN_ASSET = VY_CUSTOM_ERROR_START, RT_UNKNOWN_ASSET = RT_CUSTOM_ERROR_START,
VY_BUFFER_ALLOC_FAILED, RT_BUFFER_ALLOC_FAILED,
VY_LOAD_FAILED, RT_LOAD_FAILED,
VY_ASSET_CACHE_FULL, RT_ASSET_CACHE_FULL,
}; };
/* Load an asset without using the cache */ /* Load an asset without using the cache */
VY_DLLEXPORT vy_result vyLoadAssetDirect(vy_uid uid, void **buffer, size_t *size); RT_DLLEXPORT rt_result rtLoadAssetDirect(rt_uid uid, void **buffer, size_t *size);
typedef struct { typedef struct {
void *data; void *data;
size_t size; size_t size;
vy_result result; rt_result result;
} vy_get_asset_result; } rt_get_asset_result;
VY_DLLEXPORT vy_get_asset_result vyGetAsset(vy_uid uid); RT_DLLEXPORT rt_get_asset_result rtGetAsset(rt_uid uid);
#endif #endif

View File

@ -8,13 +8,13 @@
#include <stdint.h> #include <stdint.h>
#include <stdlib.h> #include <stdlib.h>
typedef struct vy_buffer_region_s { typedef struct rt_buffer_region_s {
void *memory; void *memory;
int16_t *refcounts; // One per block int16_t *refcounts; // One per block
uint32_t *bitmap; uint32_t *bitmap;
size_t block_count; size_t block_count;
vy_mutex *guard; rt_mutex *guard;
} vy_buffer_region; } rt_buffer_region;
/* Count leading zeroes. /* Count leading zeroes.
* Note that the return value of __builtin_clz(0) is undefined. */ * Note that the return value of __builtin_clz(0) is undefined. */
@ -49,17 +49,17 @@ static inline bool IsLZCNTSupported(void) {
#endif #endif
/* NOTE(Kevin): Keep these sorted! */ /* NOTE(Kevin): Keep these sorted! */
static size_t _block_sizes[] = {VY_KB(512), VY_MB(1), VY_MB(4), VY_MB(8)}; static size_t _block_sizes[] = {RT_KB(512), RT_MB(1), RT_MB(4), RT_MB(8)};
#define NUM_BLOCK_SIZES (sizeof(_block_sizes) / sizeof(_block_sizes[0])) #define NUM_BLOCK_SIZES (sizeof(_block_sizes) / sizeof(_block_sizes[0]))
static vy_buffer_region _regions[NUM_BLOCK_SIZES]; static rt_buffer_region _regions[NUM_BLOCK_SIZES];
VY_CVAR_SZ(rt_BufferManagerMemory, RT_CVAR_SZ(rt_BufferManagerMemory,
"Total number of bytes allocated for the buffer manager. Default: 1GB", "Total number of bytes allocated for the buffer manager. Default: 1GB",
VY_GB(1)); RT_GB(1));
vy_result InitBufferManager(void) { rt_result InitBufferManager(void) {
if ((rt_BufferManagerMemory.sz % NUM_BLOCK_SIZES) != 0) if ((rt_BufferManagerMemory.sz % NUM_BLOCK_SIZES) != 0)
vyLog("BUFFERMGR", rtLog("BUFFERMGR",
"Configured memory amount is not dividable by number of block " "Configured memory amount is not dividable by number of block "
"sizes: %u MB/%u", "sizes: %u MB/%u",
rt_BufferManagerMemory.sz / (1024 * 1024), rt_BufferManagerMemory.sz / (1024 * 1024),
@ -68,7 +68,7 @@ vy_result InitBufferManager(void) {
size_t mem_per_size = rt_BufferManagerMemory.sz / NUM_BLOCK_SIZES; size_t mem_per_size = rt_BufferManagerMemory.sz / NUM_BLOCK_SIZES;
for (unsigned int i = 0; i < NUM_BLOCK_SIZES; ++i) { for (unsigned int i = 0; i < NUM_BLOCK_SIZES; ++i) {
if ((mem_per_size % _block_sizes[i]) != 0) if ((mem_per_size % _block_sizes[i]) != 0)
vyLog("BUFFERMGR", rtLog("BUFFERMGR",
"Memory per block size is not dividable by block size: %u " "Memory per block size is not dividable by block size: %u "
"MB/%u KB", "MB/%u KB",
mem_per_size / (1024 * 1024), mem_per_size / (1024 * 1024),
@ -76,46 +76,46 @@ vy_result InitBufferManager(void) {
size_t block_count = mem_per_size / _block_sizes[i]; size_t block_count = mem_per_size / _block_sizes[i];
_regions[i].block_count = block_count; _regions[i].block_count = block_count;
_regions[i].guard = vyCreateMutex(); _regions[i].guard = rtCreateMutex();
if (!_regions[i].guard) { if (!_regions[i].guard) {
vyReportError("BUFFERMGR", "Failed to create guard mutex %u", i); rtReportError("BUFFERMGR", "Failed to create guard mutex %u", i);
return VY_BUFFER_MGR_MUTEX_CREATION_FAILED; return RT_BUFFER_MGR_MUTEX_CREATION_FAILED;
} }
_regions[i].memory = malloc(mem_per_size); _regions[i].memory = malloc(mem_per_size);
if (!_regions[i].memory) { if (!_regions[i].memory) {
vyDestroyMutex(_regions[i].guard); rtDestroyMutex(_regions[i].guard);
vyReportError("BUFFERMGR", "Failed to allocate memory.", i); rtReportError("BUFFERMGR", "Failed to allocate memory.", i);
return VY_BUFFER_MGR_OUT_OF_MEMORY; return RT_BUFFER_MGR_OUT_OF_MEMORY;
} }
_regions[i].bitmap = calloc((block_count + 31) / 32, sizeof(uint32_t)); _regions[i].bitmap = calloc((block_count + 31) / 32, sizeof(uint32_t));
if (!_regions[i].bitmap) { if (!_regions[i].bitmap) {
vyDestroyMutex(_regions[i].guard); rtDestroyMutex(_regions[i].guard);
free(_regions[i].memory); free(_regions[i].memory);
vyReportError("BUFFERMGR", "Failed to allocate memory.", i); rtReportError("BUFFERMGR", "Failed to allocate memory.", i);
return VY_BUFFER_MGR_OUT_OF_MEMORY; return RT_BUFFER_MGR_OUT_OF_MEMORY;
} }
_regions[i].refcounts = calloc(block_count, sizeof(uint16_t)); _regions[i].refcounts = calloc(block_count, sizeof(uint16_t));
if (!_regions[i].refcounts) { if (!_regions[i].refcounts) {
vyDestroyMutex(_regions[i].guard); rtDestroyMutex(_regions[i].guard);
free(_regions[i].memory); free(_regions[i].memory);
free(_regions[i].bitmap); free(_regions[i].bitmap);
vyReportError("BUFFERMGR", "Failed to allocate memory.", i); rtReportError("BUFFERMGR", "Failed to allocate memory.", i);
return VY_BUFFER_MGR_OUT_OF_MEMORY; return RT_BUFFER_MGR_OUT_OF_MEMORY;
} }
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
void ShutdownBufferManager(void) { void ShutdownBufferManager(void) {
for (unsigned int i = 0; i < NUM_BLOCK_SIZES; ++i) { for (unsigned int i = 0; i < NUM_BLOCK_SIZES; ++i) {
vyDestroyMutex(_regions[i].guard); rtDestroyMutex(_regions[i].guard);
free(_regions[i].memory); free(_regions[i].memory);
free(_regions[i].bitmap); free(_regions[i].bitmap);
free(_regions[i].refcounts); free(_regions[i].refcounts);
} }
} }
VY_DLLEXPORT void *vyAllocBuffer(size_t size) { RT_DLLEXPORT void *rtAllocBuffer(size_t size) {
assert(IsLZCNTSupported()); assert(IsLZCNTSupported());
// Determine the best block size to use // Determine the best block size to use
@ -131,8 +131,8 @@ VY_DLLEXPORT void *vyAllocBuffer(size_t size) {
void *result = NULL; void *result = NULL;
vy_buffer_region *region = &_regions[best_fit]; rt_buffer_region *region = &_regions[best_fit];
vyLockMutex(region->guard); rtLockMutex(region->guard);
size_t dword_count = (region->block_count + 31) / 32; size_t dword_count = (region->block_count + 31) / 32;
if (required_blocks < 32) { if (required_blocks < 32) {
@ -207,11 +207,11 @@ VY_DLLEXPORT void *vyAllocBuffer(size_t size) {
} }
} }
vyUnlockMutex(region->guard); rtUnlockMutex(region->guard);
return result; return result;
} }
VY_DLLEXPORT void vyReleaseBuffer(const void *begin, size_t size) { RT_DLLEXPORT void rtReleaseBuffer(const void *begin, size_t size) {
if (!begin) if (!begin)
return; return;
uintptr_t begin_addr = (uintptr_t)begin; uintptr_t begin_addr = (uintptr_t)begin;
@ -223,7 +223,7 @@ VY_DLLEXPORT void vyReleaseBuffer(const void *begin, size_t size) {
size_t block_count = (size + _block_sizes[i] - 1) / _block_sizes[i]; size_t block_count = (size + _block_sizes[i] - 1) / _block_sizes[i];
size_t first_block = (begin_addr - region_addr) / _block_sizes[i]; size_t first_block = (begin_addr - region_addr) / _block_sizes[i];
vyLockMutex(_regions[i].guard); rtLockMutex(_regions[i].guard);
for (size_t j = 0; j < block_count; ++j) { for (size_t j = 0; j < block_count; ++j) {
size_t dword = (first_block + j) / 32; size_t dword = (first_block + j) / 32;
size_t bit = (first_block + j) % 32; size_t bit = (first_block + j) % 32;
@ -231,14 +231,14 @@ VY_DLLEXPORT void vyReleaseBuffer(const void *begin, size_t size) {
if (--_regions[i].refcounts[first_block + j] == 0) if (--_regions[i].refcounts[first_block + j] == 0)
_regions[i].bitmap[dword] &= ~(1u << bit); _regions[i].bitmap[dword] &= ~(1u << bit);
} }
vyUnlockMutex(_regions[i].guard); rtUnlockMutex(_regions[i].guard);
return; return;
} }
} }
vyLog("BUFFERMGR", "Tried to release an invalid buffer"); rtLog("BUFFERMGR", "Tried to release an invalid buffer");
} }
VY_DLLEXPORT void vyIncreaseBufferRefCount(const void *begin, size_t size) { RT_DLLEXPORT void rtIncreaseBufferRefCount(const void *begin, size_t size) {
uintptr_t begin_addr = (uintptr_t)begin; uintptr_t begin_addr = (uintptr_t)begin;
for (unsigned int i = 0; i < NUM_BLOCK_SIZES; ++i) { for (unsigned int i = 0; i < NUM_BLOCK_SIZES; ++i) {
uintptr_t region_addr = (uintptr_t)_regions[i].memory; uintptr_t region_addr = (uintptr_t)_regions[i].memory;
@ -248,13 +248,13 @@ VY_DLLEXPORT void vyIncreaseBufferRefCount(const void *begin, size_t size) {
size_t block_count = (size + _block_sizes[i] - 1) / _block_sizes[i]; size_t block_count = (size + _block_sizes[i] - 1) / _block_sizes[i];
size_t first_block = (begin_addr - region_addr) / _block_sizes[i]; size_t first_block = (begin_addr - region_addr) / _block_sizes[i];
vyLockMutex(_regions[i].guard); rtLockMutex(_regions[i].guard);
for (size_t j = 0; j < block_count; ++j) { for (size_t j = 0; j < block_count; ++j) {
++_regions[i].refcounts[first_block + j]; ++_regions[i].refcounts[first_block + j];
} }
vyUnlockMutex(_regions[i].guard); rtUnlockMutex(_regions[i].guard);
return; return;
} }
} }
vyLog("BUFFERMGR", "Tried to increase the refcount of an invalid buffer"); rtLog("BUFFERMGR", "Tried to increase the refcount of an invalid buffer");
} }

View File

@ -1,17 +1,17 @@
#ifndef VY_BUFFER_MANAGER_H #ifndef RT_BUFFER_MANAGER_H
#define VY_BUFFER_MANAGER_H #define RT_BUFFER_MANAGER_H
#include "runtime.h" #include "runtime.h"
enum { enum {
VY_BUFFER_MGR_OUT_OF_MEMORY = VY_CUSTOM_ERROR_START, RT_BUFFER_MGR_OUT_OF_MEMORY = RT_CUSTOM_ERROR_START,
VY_BUFFER_MGR_MUTEX_CREATION_FAILED, RT_BUFFER_MGR_MUTEX_CREATION_FAILED,
}; };
VY_DLLEXPORT void *vyAllocBuffer(size_t size); RT_DLLEXPORT void *rtAllocBuffer(size_t size);
VY_DLLEXPORT void vyReleaseBuffer(const void *begin, size_t size); RT_DLLEXPORT void rtReleaseBuffer(const void *begin, size_t size);
VY_DLLEXPORT void vyIncreaseBufferRefCount(const void *begin, size_t size); RT_DLLEXPORT void rtIncreaseBufferRefCount(const void *begin, size_t size);
#endif #endif

View File

@ -5,35 +5,35 @@
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#define VY_MAX_CVARS 1024 #define RT_MAX_CVARS 1024
static vy_cvar *_vars[VY_MAX_CVARS]; static rt_cvar *_vars[RT_MAX_CVARS];
static unsigned int _next = 0; static unsigned int _next = 0;
static vy_mutex *_mutex = NULL; static rt_mutex *_mutex = NULL;
void vyRegisterCVAR(vy_cvar *cvar) { void rtRegisterCVAR(rt_cvar *cvar) {
if (!_mutex) if (!_mutex)
_mutex = vyCreateMutex(); _mutex = rtCreateMutex();
vyLockMutex(_mutex); rtLockMutex(_mutex);
if (_next < VY_MAX_CVARS) { if (_next < RT_MAX_CVARS) {
_vars[_next++] = cvar; _vars[_next++] = cvar;
} else { } else {
vyReportError("cvar", "Ran out of space for CVars"); rtReportError("cvar", "Ran out of space for CVars");
} }
vyUnlockMutex(_mutex); rtUnlockMutex(_mutex);
} }
vy_cvar *vyGetCVAR(const char *name) { rt_cvar *rtGetCVAR(const char *name) {
if (!_mutex) if (!_mutex)
_mutex = vyCreateMutex(); _mutex = rtCreateMutex();
vy_cvar *var = NULL; rt_cvar *var = NULL;
vyLockMutex(_mutex); rtLockMutex(_mutex);
for (unsigned int i = 0; i < _next; ++i) { for (unsigned int i = 0; i < _next; ++i) {
if (strcmp(name, _vars[i]->name) == 0) { if (strcmp(name, _vars[i]->name) == 0) {
var = _vars[i]; var = _vars[i];
break; break;
} }
} }
vyUnlockMutex(_mutex); rtUnlockMutex(_mutex);
return var; return var;
} }

View File

@ -1,14 +1,14 @@
#ifndef VY_CONFIG_H #ifndef RT_CONFIG_H
#define VY_CONFIG_H #define RT_CONFIG_H
#include "runtime.h" #include "runtime.h"
typedef enum { typedef enum {
VY_CVAR_TYPE_INT, RT_CVAR_TYPE_INT,
VY_CVAR_TYPE_FLOAT, RT_CVAR_TYPE_FLOAT,
VY_CVAR_TYPE_STRING, RT_CVAR_TYPE_STRING,
VY_CVAR_TYPE_SIZE, RT_CVAR_TYPE_SIZE,
} vy_cvar_type; } rt_cvar_type;
typedef struct { typedef struct {
const char *name; const char *name;
@ -19,21 +19,21 @@ typedef struct {
const char *s; const char *s;
size_t sz; size_t sz;
}; };
vy_cvar_type type; rt_cvar_type type;
} vy_cvar; } rt_cvar;
/* n variable name, d description string, v default value*/ /* n variable name, d description string, v default value*/
#define VY_CVAR_I(n, d, v) \ #define RT_CVAR_I(n, d, v) \
vy_cvar n = {.name = #n, .description = d, .i = (v), .type = VY_CVAR_TYPE_INT} rt_cvar n = {.name = #n, .description = d, .i = (v), .type = RT_CVAR_TYPE_INT}
#define VY_CVAR_F(n, d, v) \ #define RT_CVAR_F(n, d, v) \
vy_cvar n = {.name = #n, .description = d, .f = (v), .type = VY_CVAR_TYPE_FLOAT} rt_cvar n = {.name = #n, .description = d, .f = (v), .type = RT_CVAR_TYPE_FLOAT}
#define VY_CVAR_S(n, d, v) \ #define RT_CVAR_S(n, d, v) \
vy_cvar n = {.name = #n, .description = d, .s = (v), .type = VY_CVAR_TYPE_STRING} rt_cvar n = {.name = #n, .description = d, .s = (v), .type = RT_CVAR_TYPE_STRING}
#define VY_CVAR_SZ(n, d, v) \ #define RT_CVAR_SZ(n, d, v) \
vy_cvar n = {.name = #n, .description = d, .sz = (v), .type = VY_CVAR_TYPE_SIZE} rt_cvar n = {.name = #n, .description = d, .sz = (v), .type = RT_CVAR_TYPE_SIZE}
VY_DLLEXPORT void vyRegisterCVAR(vy_cvar *cvar); RT_DLLEXPORT void rtRegisterCVAR(rt_cvar *cvar);
VY_DLLEXPORT vy_cvar *vyGetCVAR(const char *name); RT_DLLEXPORT rt_cvar *rtGetCVAR(const char *name);
#endif #endif

View File

@ -4,41 +4,41 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
VY_DLLEXPORT vy_dynlib vyOpenCallerLib(void) { RT_DLLEXPORT rt_dynlib rtOpenCallerLib(void) {
return (vy_dynlib)GetModuleHandleW(NULL); return (rt_dynlib)GetModuleHandleW(NULL);
} }
VY_DLLEXPORT vy_dynlib vyOpenLib(const char *libname) { RT_DLLEXPORT rt_dynlib rtOpenLib(const char *libname) {
wchar_t libname_w[MAX_PATH]; wchar_t libname_w[MAX_PATH];
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, libname, -1, libname_w, MAX_PATH); MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, libname, -1, libname_w, MAX_PATH);
HMODULE mod = LoadLibraryW(libname_w); HMODULE mod = LoadLibraryW(libname_w);
return (vy_dynlib)mod; return (rt_dynlib)mod;
} }
VY_DLLEXPORT void *vyGetSymbol(vy_dynlib lib, const char *symbol) { RT_DLLEXPORT void *rtGetSymbol(rt_dynlib lib, const char *symbol) {
return (void *)GetProcAddress((HMODULE)lib, symbol); return (void *)GetProcAddress((HMODULE)lib, symbol);
} }
VY_DLLEXPORT void vyCloseLib(vy_dynlib lib) { RT_DLLEXPORT void rtCloseLib(rt_dynlib lib) {
FreeLibrary((HMODULE)lib); FreeLibrary((HMODULE)lib);
} }
#elif defined(__linux__) #elif defined(__linux__)
#include <dlfcn.h> #include <dlfcn.h>
VY_DLLEXPORT vy_dynlib vyOpenCallerLib(void) { RT_DLLEXPORT rt_dynlib rtOpenCallerLib(void) {
return dlopen(NULL, RTLD_NOW | RTLD_LOCAL); return dlopen(NULL, RTLD_NOW | RTLD_LOCAL);
} }
VY_DLLEXPORT vy_dynlib vyOpenLib(const char *libname) { RT_DLLEXPORT rt_dynlib rtOpenLib(const char *libname) {
return dlopen(libname, RTLD_NOW | RTLD_LOCAL); return dlopen(libname, RTLD_NOW | RTLD_LOCAL);
} }
VY_DLLEXPORT void *vyGetSymbol(vy_dynlib lib, const char *symbol) { RT_DLLEXPORT void *rtGetSymbol(rt_dynlib lib, const char *symbol) {
return dlsym(lib, symbol); return dlsym(lib, symbol);
} }
VY_DLLEXPORT void vyCloseLib(vy_dynlib lib) { RT_DLLEXPORT void rtCloseLib(rt_dynlib lib) {
dlclose(lib); dlclose(lib);
} }

View File

@ -1,26 +1,26 @@
#ifndef VY_DYNAMIC_LIBS_H #ifndef RT_DYNAMIC_LIBS_H
#define VY_DYNAMIC_LIBS_H #define RT_DYNAMIC_LIBS_H
#include "runtime.h" #include "runtime.h"
#ifdef _WIN32 #ifdef _WIN32
#define VY_DLLNAME(s) \ #define RT_DLLNAME(s) \
(".\\"s \ (".\\"s \
".dll") ".dll")
#elif defined(__linux__) #elif defined(__linux__)
#define VY_DLLNAME(s) \ #define RT_DLLNAME(s) \
("./lib"s \ ("./lib"s \
".so") ".so")
#endif #endif
typedef void *vy_dynlib; typedef void *rt_dynlib;
VY_DLLEXPORT vy_dynlib vyOpenLib(const char *libname); RT_DLLEXPORT rt_dynlib rtOpenLib(const char *libname);
VY_DLLEXPORT vy_dynlib vyOpenCallerLib(void); RT_DLLEXPORT rt_dynlib rtOpenCallerLib(void);
VY_DLLEXPORT void *vyGetSymbol(vy_dynlib lib, const char *symbol); RT_DLLEXPORT void *rtGetSymbol(rt_dynlib lib, const char *symbol);
VY_DLLEXPORT void vyCloseLib(vy_dynlib lib); RT_DLLEXPORT void rtCloseLib(rt_dynlib lib);
#endif #endif

View File

@ -22,14 +22,14 @@
static bool DisplayErrorBox(const char *text) { static bool DisplayErrorBox(const char *text) {
#ifdef _WIN32 #ifdef _WIN32
WCHAR msg[256]; WCHAR msg[256];
vyUTF8ToWStr(text, msg, VY_ARRAY_COUNT(msg)); rtUTF8ToWStr(text, msg, RT_ARRAY_COUNT(msg));
#ifdef VY_ERROR_REPORT_DEBUGBREAK #ifdef RT_ERROR_REPORT_DEBUGBREAK
return MessageBoxW(NULL, msg, L"Error", MB_OKCANCEL | MB_ICONERROR) == IDCANCEL; return MessageBoxW(NULL, msg, L"Error", MB_OKCANCEL | MB_ICONERROR) == IDCANCEL;
#else #else
MessageBoxW(NULL, msg, L"Error", MB_ICONERROR); MessageBoxW(NULL, msg, L"Error", MB_ICONERROR);
return false; return false;
#endif /* VY_ERROR_REPORT_DEBUGBREAK */ #endif /* RT_ERROR_REPORT_DEBUGBREAK */
#else #else
return false; return false;
#endif #endif
@ -38,21 +38,21 @@ static bool DisplayErrorBox(const char *text) {
static void LogOut(const char *text) { static void LogOut(const char *text) {
#ifdef _WIN32 #ifdef _WIN32
WCHAR msg[256]; WCHAR msg[256];
vyUTF8ToWStr(text, msg, VY_ARRAY_COUNT(msg)); rtUTF8ToWStr(text, msg, RT_ARRAY_COUNT(msg));
OutputDebugStringW(msg); OutputDebugStringW(msg);
#endif #endif
fprintf(stderr, "%s", text); fprintf(stderr, "%s", text);
} }
VY_DLLEXPORT void vyReportError(const char *subsystem, const char *fmt, ...) { RT_DLLEXPORT void rtReportError(const char *subsystem, const char *fmt, ...) {
char buf[256]; char buf[256];
int at = snprintf(buf, VY_ARRAY_COUNT(buf) - 1, "[%s] ", subsystem); int at = snprintf(buf, RT_ARRAY_COUNT(buf) - 1, "[%s] ", subsystem);
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
at += vsnprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, fmt, ap); at += vsnprintf(&buf[at], RT_ARRAY_COUNT(buf) - at - 1, fmt, ap);
va_end(ap); va_end(ap);
at += snprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, "\n"); at += snprintf(&buf[at], RT_ARRAY_COUNT(buf) - at - 1, "\n");
LogOut(buf); LogOut(buf);
if (DisplayErrorBox(buf)) { if (DisplayErrorBox(buf)) {
@ -60,15 +60,15 @@ VY_DLLEXPORT void vyReportError(const char *subsystem, const char *fmt, ...) {
} }
} }
VY_DLLEXPORT void vyLog(const char *subsystem, const char *fmt, ...) { RT_DLLEXPORT void rtLog(const char *subsystem, const char *fmt, ...) {
char buf[256]; char buf[256];
int at = snprintf(buf, VY_ARRAY_COUNT(buf) - 1, "[%s] ", subsystem); int at = snprintf(buf, RT_ARRAY_COUNT(buf) - 1, "[%s] ", subsystem);
va_list ap; va_list ap;
va_start(ap, fmt); va_start(ap, fmt);
at += vsnprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, fmt, ap); at += vsnprintf(&buf[at], RT_ARRAY_COUNT(buf) - at - 1, fmt, ap);
va_end(ap); va_end(ap);
at += snprintf(&buf[at], VY_ARRAY_COUNT(buf) - at - 1, "\n"); at += snprintf(&buf[at], RT_ARRAY_COUNT(buf) - at - 1, "\n");
LogOut(buf); LogOut(buf);
} }

View File

@ -6,22 +6,22 @@
#define NAME_CAP(cap) ((cap)*128) #define NAME_CAP(cap) ((cap)*128)
typedef struct { typedef struct {
vy_file_id *ids; rt_file_id *ids;
unsigned int *name_offsets; unsigned int *name_offsets;
char *names; char *names;
unsigned int capacity; unsigned int capacity;
unsigned int name_head; unsigned int name_head;
vy_mutex *mutex; rt_mutex *mutex;
} vy_file_tab; } rt_file_tab;
static vy_file_tab _file_tab; static rt_file_tab _file_tab;
VY_CVAR_I(rt_FileTabCapacity, "Maximum number of filetab entries. Default: 1024", 1024); RT_CVAR_I(rt_FileTabCapacity, "Maximum number of filetab entries. Default: 1024", 1024);
vy_result InitFileTab(void) { rt_result InitFileTab(void) {
unsigned int max_files = (unsigned int)rt_FileTabCapacity.i; unsigned int max_files = (unsigned int)rt_FileTabCapacity.i;
_file_tab.ids = calloc(max_files, sizeof(vy_file_id)); _file_tab.ids = calloc(max_files, sizeof(rt_file_id));
if (!_file_tab.ids) if (!_file_tab.ids)
return 1; return 1;
_file_tab.name_offsets = calloc(max_files, sizeof(unsigned int)); _file_tab.name_offsets = calloc(max_files, sizeof(unsigned int));
@ -33,38 +33,38 @@ vy_result InitFileTab(void) {
_file_tab.capacity = max_files; _file_tab.capacity = max_files;
_file_tab.name_head = 0; _file_tab.name_head = 0;
_file_tab.mutex = vyCreateMutex(); _file_tab.mutex = rtCreateMutex();
return VY_SUCCESS; return RT_SUCCESS;
} }
void ShutdownFileTab(void) { void ShutdownFileTab(void) {
free(_file_tab.ids); free(_file_tab.ids);
free(_file_tab.names); free(_file_tab.names);
free(_file_tab.name_offsets); free(_file_tab.name_offsets);
vyDestroyMutex(_file_tab.mutex); rtDestroyMutex(_file_tab.mutex);
} }
VY_DLLEXPORT vy_file_id vyGetFileId(const char *path) { RT_DLLEXPORT rt_file_id rtGetFileId(const char *path) {
vy_text_span span; rt_text_span span;
span.start = path; span.start = path;
span.length = (unsigned int)strlen(path); span.length = (unsigned int)strlen(path);
return vyGetFileIdFromSpan(span); return rtGetFileIdFromSpan(span);
} }
VY_DLLEXPORT vy_file_id vyGetFileIdFromSpan(vy_text_span path) { RT_DLLEXPORT rt_file_id rtGetFileIdFromSpan(rt_text_span path) {
/* Randomly choosen, aka finger smash keyboard */ /* Randomly choosen, aka finger smash keyboard */
XXH64_hash_t seed = 15340978; XXH64_hash_t seed = 15340978;
vy_file_id fid = (vy_file_id)XXH3_64bits_withSeed(path.start, path.length, seed); rt_file_id fid = (rt_file_id)XXH3_64bits_withSeed(path.start, path.length, seed);
if (fid == 0) if (fid == 0)
fid = ~fid; fid = ~fid;
return fid; return fid;
} }
VY_DLLEXPORT vy_file_id vyAddFileFromSpan(vy_text_span path) { RT_DLLEXPORT rt_file_id rtAddFileFromSpan(rt_text_span path) {
vy_file_id fid = vyGetFileIdFromSpan(path); rt_file_id fid = rtGetFileIdFromSpan(path);
if (!vyLockMutex(_file_tab.mutex)) { if (!rtLockMutex(_file_tab.mutex)) {
vyReportError("fio", "Failed to lock the guard mutex."); rtReportError("fio", "Failed to lock the guard mutex.");
return 0; return 0;
} }
@ -97,24 +97,24 @@ VY_DLLEXPORT vy_file_id vyAddFileFromSpan(vy_text_span path) {
if (i == _file_tab.capacity) if (i == _file_tab.capacity)
fid = 0; fid = 0;
vyUnlockMutex(_file_tab.mutex); rtUnlockMutex(_file_tab.mutex);
return fid; return fid;
} }
VY_DLLEXPORT vy_file_id vyAddFile(const char *path) { RT_DLLEXPORT rt_file_id rtAddFile(const char *path) {
vy_text_span span; rt_text_span span;
span.start = path; span.start = path;
span.length = (unsigned int)strlen(path); span.length = (unsigned int)strlen(path);
return vyAddFileFromSpan(span); return rtAddFileFromSpan(span);
} }
VY_DLLEXPORT const char *vyGetFilePath(vy_file_id fid) { RT_DLLEXPORT const char *rtGetFilePath(rt_file_id fid) {
/* Hash Lookup */ /* Hash Lookup */
if (fid == 0) if (fid == 0)
return NULL; return NULL;
if (!vyLockMutex(_file_tab.mutex)) { if (!rtLockMutex(_file_tab.mutex)) {
vyReportError("fio", "Failed to lock the guard mutex."); rtReportError("fio", "Failed to lock the guard mutex.");
return 0; return 0;
} }
const char *result = NULL; const char *result = NULL;
@ -130,6 +130,6 @@ VY_DLLEXPORT const char *vyGetFilePath(vy_file_id fid) {
} }
++i; ++i;
} }
vyUnlockMutex(_file_tab.mutex); rtUnlockMutex(_file_tab.mutex);
return result; return result;
} }

View File

@ -1,22 +1,22 @@
#ifndef VY_FILE_TAB_H #ifndef RT_FILE_TAB_H
#define VY_FILE_TAB_H #define RT_FILE_TAB_H
#include "runtime.h" #include "runtime.h"
#include <stdint.h> #include <stdint.h>
/* used to identify a file (XXH3 hash of the path) */ /* used to identify a file (XXH3 hash of the path) */
typedef uint64_t vy_file_id; typedef uint64_t rt_file_id;
#define VY_INVALID_FILE_ID 0 #define RT_INVALID_FILE_ID 0
VY_DLLEXPORT vy_file_id vyGetFileId(const char *path); RT_DLLEXPORT rt_file_id rtGetFileId(const char *path);
VY_DLLEXPORT vy_file_id vyGetFileIdFromSpan(vy_text_span path); RT_DLLEXPORT rt_file_id rtGetFileIdFromSpan(rt_text_span path);
VY_DLLEXPORT vy_file_id vyAddFile(const char *path); RT_DLLEXPORT rt_file_id rtAddFile(const char *path);
VY_DLLEXPORT vy_file_id vyAddFileFromSpan(vy_text_span path); RT_DLLEXPORT rt_file_id rtAddFileFromSpan(rt_text_span path);
VY_DLLEXPORT const char *vyGetFilePath(vy_file_id fid); RT_DLLEXPORT const char *rtGetFilePath(rt_file_id fid);
#endif #endif

View File

@ -1,5 +1,5 @@
#ifndef VY_GFX_H #ifndef RT_GFX_H
#define VY_GFX_H #define RT_GFX_H
/* graphics system. this is the interface of the rendering code. /* graphics system. this is the interface of the rendering code.
* *
@ -15,22 +15,22 @@
#include "runtime.h" #include "runtime.h"
/* In renderer_api.h -> Not necessary for almost all gfx usage */ /* In renderer_api.h -> Not necessary for almost all gfx usage */
typedef struct vy_renderer_init_info_s vy_renderer_init_info; typedef struct rt_renderer_init_info_s rt_renderer_init_info;
VY_DLLEXPORT void vyRegisterRendererCVars(void); RT_DLLEXPORT void rtRegisterRendererCVars(void);
VY_DLLEXPORT bool vyInitGFX(vy_renderer_init_info *renderer_info); RT_DLLEXPORT bool rtInitGFX(rt_renderer_init_info *renderer_info);
VY_DLLEXPORT void vyShutdownGFX(void); RT_DLLEXPORT void rtShutdownGFX(void);
/* Handles backend objects */ /* Handles backend objects */
#define VY_GFX_HANDLE_MAX_VERSION 255 #define RT_GFX_HANDLE_MAX_VERSION 255
typedef struct { typedef struct {
uint32_t version : 8; uint32_t version : 8;
uint32_t index : 24; uint32_t index : 24;
} vy_pipeline_handle; } rt_pipeline_handle;
/* Attributes are used to bind buffers (or textures) to symbolic values. /* Attributes are used to bind buffers (or textures) to symbolic values.
* For example, an attribute might be bound to "CELL_GRID", which would be * For example, an attribute might be bound to "CELL_GRID", which would be
@ -39,15 +39,15 @@ typedef struct {
*/ */
typedef enum { typedef enum {
VY_ATTRIBUTE_VALUE_UNDEFINED, RT_ATTRIBUTE_VALUE_UNDEFINED,
VY_ATTRIBUTE_VALUE_MATERIAL_ALBEDO, RT_ATTRIBUTE_VALUE_MATERIAL_ALBEDO,
VY_ATTRIBUTE_VALUE_MATERIAL_NORMAL, RT_ATTRIBUTE_VALUE_MATERIAL_NORMAL,
} vy_attribute_value; } rt_attribute_value;
typedef struct { typedef struct {
uint32_t index; uint32_t index;
vy_attribute_value value; rt_attribute_value value;
} vy_attribute_binding; } rt_attribute_binding;
#endif #endif

View File

@ -1,6 +1,6 @@
#include <string.h> #include <string.h>
#define VY_DONT_DEFINE_RENDERER_GLOBAL #define RT_DONT_DEFINE_RENDERER_GLOBAL
#include "config.h" #include "config.h"
#include "dynamic_libs.h" #include "dynamic_libs.h"
@ -13,45 +13,45 @@
* world cell. * world cell.
*/ */
vy_renderer_api g_renderer; rt_renderer_api g_renderer;
static vy_dynlib _renderer_lib; static rt_dynlib _renderer_lib;
static bool _renderer_loaded = false; static bool _renderer_loaded = false;
VY_CVAR_S(rt_Renderer, "Select the render backend. Available options: [vk], Default: vk", "vk"); RT_CVAR_S(rt_Renderer, "Select the render backend. Available options: [vk], Default: vk", "vk");
#ifdef VY_STATIC_LIB #ifdef RT_STATIC_LIB
extern void VY_RENDERER_API_FN(RegisterCVars)(void); extern void RT_RENDERER_API_FN(RegisterCVars)(void);
extern vy_result VY_RENDERER_API_FN(Init)(const vy_renderer_init_info *); extern rt_result RT_RENDERER_API_FN(Init)(const rt_renderer_init_info *);
extern void VY_RENDERER_API_FN(Shutdown)(void); extern void RT_RENDERER_API_FN(Shutdown)(void);
extern vy_pipeline_handle VY_RENDERER_API_FN(CompilePipeline)(const vy_pipeline_info *); extern rt_pipeline_handle RT_RENDERER_API_FN(CompilePipeline)(const rt_pipeline_info *);
extern void VY_RENDERER_API_FN(DestroyPipeline)(vy_pipeline_handle handle); extern void RT_RENDERER_API_FN(DestroyPipeline)(rt_pipeline_handle handle);
#endif #endif
static bool LoadRenderer(void) { static bool LoadRenderer(void) {
#if !defined(VY_STATIC_LIB) #if !defined(RT_STATIC_LIB)
#define RETRIEVE_SYMBOL(name, type) \ #define RETRIEVE_SYMBOL(name, type) \
g_renderer.name = (type *)vyGetSymbol(_renderer_lib, "vyRen" #name); \ g_renderer.name = (type *)rtGetSymbol(_renderer_lib, "rtRen" #name); \
if (!g_renderer.name) { \ if (!g_renderer.name) { \
vyReportError("GFX", \ rtReportError("GFX", \
"Unable to retrieve renderer function %s from backend %s", \ "Unable to retrieve renderer function %s from backend %s", \
#name, \ #name, \
rt_Renderer.s); \ rt_Renderer.s); \
} }
if (strcmp(rt_Renderer.s, "vk") == 0) { if (strcmp(rt_Renderer.s, "vk") == 0) {
_renderer_lib = vyOpenLib(VY_DLLNAME("vyvk")); _renderer_lib = rtOpenLib(RT_DLLNAME("rtvk"));
if (!_renderer_lib) { if (!_renderer_lib) {
vyReportError("GFX", "Unable to load renderer backend: %s", VY_DLLNAME("vyvk")); rtReportError("GFX", "Unable to load renderer backend: %s", RT_DLLNAME("rtvk"));
return false; return false;
} }
RETRIEVE_SYMBOL(RegisterCVars, vy_register_renderer_cvars_fn); RETRIEVE_SYMBOL(RegisterCVars, rt_register_renderer_cvars_fn);
RETRIEVE_SYMBOL(Init, vy_init_renderer_fn); RETRIEVE_SYMBOL(Init, rt_init_renderer_fn);
RETRIEVE_SYMBOL(Shutdown, vy_shutdown_renderer_fn); RETRIEVE_SYMBOL(Shutdown, rt_shutdown_renderer_fn);
RETRIEVE_SYMBOL(CompilePipeline, vy_compile_pipeline_fn); RETRIEVE_SYMBOL(CompilePipeline, rt_compile_pipeline_fn);
RETRIEVE_SYMBOL(DestroyPipeline, vy_destroy_pipeline_fn); RETRIEVE_SYMBOL(DestroyPipeline, rt_destroy_pipeline_fn);
} else { } else {
vyReportError("GFX", rtReportError("GFX",
"Unsupported renderer backend: (%s) %s", "Unsupported renderer backend: (%s) %s",
rt_Renderer.name, rt_Renderer.name,
rt_Renderer.s); rt_Renderer.s);
@ -59,16 +59,16 @@ static bool LoadRenderer(void) {
} }
#undef RETRIEVE_SYMBOL #undef RETRIEVE_SYMBOL
#else #else
g_renderer.RegisterCVars = &vyRenRegisterCVars; g_renderer.RegisterCVars = &rtRenRegisterCVars;
g_renderer.Init = &vyRenInit; g_renderer.Init = &rtRenInit;
g_renderer.Shutdown = &vyRenShutdown; g_renderer.Shutdown = &rtRenShutdown;
g_renderer.CompilePipeline = &vyRenCompilePipeline; g_renderer.CompilePipeline = &rtRenCompilePipeline;
g_renderer.DestroyPipeline = &vyRenDestroyPipeline; g_renderer.DestroyPipeline = &rtRenDestroyPipeline;
#endif #endif
return true; return true;
} }
VY_DLLEXPORT void vyRegisterRendererCVars(void) { RT_DLLEXPORT void rtRegisterRendererCVars(void) {
if (!_renderer_loaded) { if (!_renderer_loaded) {
if (!LoadRenderer()) if (!LoadRenderer())
return; return;
@ -77,19 +77,19 @@ VY_DLLEXPORT void vyRegisterRendererCVars(void) {
g_renderer.RegisterCVars(); g_renderer.RegisterCVars();
} }
VY_DLLEXPORT bool vyInitGFX(vy_renderer_init_info *renderer_info) { RT_DLLEXPORT bool rtInitGFX(rt_renderer_init_info *renderer_info) {
if (!_renderer_loaded) { if (!_renderer_loaded) {
if (!LoadRenderer()) if (!LoadRenderer())
return false; return false;
g_renderer.RegisterCVars(); g_renderer.RegisterCVars();
} }
if (g_renderer.Init(renderer_info) != VY_SUCCESS) if (g_renderer.Init(renderer_info) != RT_SUCCESS)
return false; return false;
return true; return true;
} }
VY_DLLEXPORT void vyShutdownGFX(void) { RT_DLLEXPORT void rtShutdownGFX(void) {
g_renderer.Shutdown(); g_renderer.Shutdown();
} }

View File

@ -1,11 +1,11 @@
#ifndef VY_HANDLES_H #ifndef RT_HANDLES_H
#define VY_HANDLES_H #define RT_HANDLES_H
/* All handle types should contain a uint32_t index */ /* All handle types should contain a uint32_t index */
#define VY_INVALID_HANDLE \ #define RT_INVALID_HANDLE \
{ .index = 0 } { .index = 0 }
#define VY_IS_HANDLE_VALID(handle) ((handle).index != 0) #define RT_IS_HANDLE_VALID(handle) ((handle).index != 0)
#endif #endif

View File

@ -5,85 +5,85 @@
#include "buffer_manager.h" #include "buffer_manager.h"
#include "uidtab.h" #include "uidtab.h"
extern vy_cvar rt_Renderer; extern rt_cvar rt_Renderer;
extern vy_cvar rt_Fullscreen; extern rt_cvar rt_Fullscreen;
extern vy_cvar rt_WindowWidth; extern rt_cvar rt_WindowWidth;
extern vy_cvar rt_WindowHeight; extern rt_cvar rt_WindowHeight;
extern vy_cvar rt_BufferManagerMemory; extern rt_cvar rt_BufferManagerMemory;
extern vy_cvar rt_FileTabCapacity; extern rt_cvar rt_FileTabCapacity;
extern vy_cvar rt_MaxConcurrentAsyncIO; extern rt_cvar rt_MaxConcurrentAsyncIO;
extern vy_cvar rt_AssetCacheSize; extern rt_cvar rt_AssetCacheSize;
void RegisterRuntimeCVars(void) { void RegisterRuntimeCVars(void) {
vyRegisterCVAR(&rt_Renderer); rtRegisterCVAR(&rt_Renderer);
vyRegisterCVAR(&rt_Fullscreen); rtRegisterCVAR(&rt_Fullscreen);
vyRegisterCVAR(&rt_WindowWidth); rtRegisterCVAR(&rt_WindowWidth);
vyRegisterCVAR(&rt_WindowHeight); rtRegisterCVAR(&rt_WindowHeight);
vyRegisterCVAR(&rt_BufferManagerMemory); rtRegisterCVAR(&rt_BufferManagerMemory);
vyRegisterCVAR(&rt_FileTabCapacity); rtRegisterCVAR(&rt_FileTabCapacity);
vyRegisterCVAR(&rt_MaxConcurrentAsyncIO); rtRegisterCVAR(&rt_MaxConcurrentAsyncIO);
vyRegisterCVAR(&rt_AssetCacheSize); rtRegisterCVAR(&rt_AssetCacheSize);
} }
extern void SetMainThreadId(void); extern void SetMainThreadId(void);
extern vy_result InitBufferManager(void); extern rt_result InitBufferManager(void);
extern void ShutdownBufferManager(void); extern void ShutdownBufferManager(void);
extern vy_result InitFileTab(void); extern rt_result InitFileTab(void);
extern void ShutdownFileTab(void); extern void ShutdownFileTab(void);
extern vy_result InitAIO(void); extern rt_result InitAIO(void);
extern void ShutdownAIO(void); extern void ShutdownAIO(void);
extern vy_result InitAssetCache(void); extern rt_result InitAssetCache(void);
extern void ShutdownAssetCache(void); extern void ShutdownAssetCache(void);
extern vy_result LoadUIDTable(void); extern rt_result LoadUIDTable(void);
extern void ReleaseUIDTable(void); extern void ReleaseUIDTable(void);
extern vy_result LoadAssetDependencies(void); extern rt_result LoadAssetDependencies(void);
extern void ReleaseAssetDependencies(void); extern void ReleaseAssetDependencies(void);
extern vy_result LoadPackageNames(void); extern rt_result LoadPackageNames(void);
VY_DLLEXPORT vy_result vyInitRuntime(void) { RT_DLLEXPORT rt_result rtInitRuntime(void) {
SetMainThreadId(); SetMainThreadId();
RegisterRuntimeCVars(); RegisterRuntimeCVars();
vy_result res; rt_result res;
if ((res = InitBufferManager()) != VY_SUCCESS) { if ((res = InitBufferManager()) != RT_SUCCESS) {
vyReportError("BUFFERMGR", "Init failed."); rtReportError("BUFFERMGR", "Init failed.");
return res; return res;
} }
if ((res = InitFileTab()) != VY_SUCCESS) { if ((res = InitFileTab()) != RT_SUCCESS) {
vyReportError("FTAB", "Init failed."); rtReportError("FTAB", "Init failed.");
return res; return res;
} }
if ((res = InitAIO()) != VY_SUCCESS) { if ((res = InitAIO()) != RT_SUCCESS) {
vyReportError("AIO", "Init failed."); rtReportError("AIO", "Init failed.");
return res; return res;
} }
if ((res = InitAssetCache()) != VY_SUCCESS) { if ((res = InitAssetCache()) != RT_SUCCESS) {
vyReportError("ASSETCACHE", "Init failed."); rtReportError("ASSETCACHE", "Init failed.");
return res; return res;
} }
if ((res = LoadUIDTable()) != VY_SUCCESS) { if ((res = LoadUIDTable()) != RT_SUCCESS) {
vyLog("CORE", "LoadUIDTable returned result: %u", res); rtLog("CORE", "LoadUIDTable returned result: %u", res);
} }
if ((res = LoadAssetDependencies()) != VY_SUCCESS) { if ((res = LoadAssetDependencies()) != RT_SUCCESS) {
vyReportError("ASSETDEP", "Init failed."); rtReportError("ASSETDEP", "Init failed.");
return res; return res;
} }
if ((res = LoadPackageNames()) != VY_SUCCESS) { if ((res = LoadPackageNames()) != RT_SUCCESS) {
vyLog("CORE", "LoadPackageNames returned result: %u", res); rtLog("CORE", "LoadPackageNames returned result: %u", res);
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
VY_DLLEXPORT void vyShutdownRuntime(void) { RT_DLLEXPORT void rtShutdownRuntime(void) {
ReleaseAssetDependencies(); ReleaseAssetDependencies();
ReleaseUIDTable(); ReleaseUIDTable();
ShutdownAssetCache(); ShutdownAssetCache();

View File

@ -8,27 +8,27 @@
typedef struct { typedef struct {
uint32_t base_iteration; uint32_t base_iteration;
uint32_t iteration_count; uint32_t iteration_count;
vy_job_fn *fn; rt_job_fn *fn;
void *param; void *param;
} vy_job_chunk; } rt_job_chunk;
typedef struct { typedef struct {
/* Queue */ /* Queue */
struct { struct {
vy_job_chunk *chunks; rt_job_chunk *chunks;
unsigned int head; unsigned int head;
unsigned int tail; unsigned int tail;
vy_condition_var *lock; rt_condition_var *lock;
} job_queue; } job_queue;
/* Thread data */ /* Thread data */
vy_thread *thread; rt_thread *thread;
} vy_worker_data; } rt_worker_data;
static volatile bool _keep_running = true; static volatile bool _keep_running = true;
static vy_worker_data _worker_data[MAX_WORKERS]; static rt_worker_data _worker_data[MAX_WORKERS];
static void ExecOneJobIfAvailable(vy_worker_data *wd) { static void ExecOneJobIfAvailable(rt_worker_data *wd) {
if (wd->job_queue.head == wd->job_queue.tail) { if (wd->job_queue.head == wd->job_queue.tail) {
/* No job available. /* No job available.
* TODO: Pick one job queue at random and check if we can steal? * TODO: Pick one job queue at random and check if we can steal?
@ -36,7 +36,7 @@ static void ExecOneJobIfAvailable(vy_worker_data *wd) {
return; return;
} }
vy_job_chunk chunk = wd->job_queue.chunks[wd->job_queue.head]; rt_job_chunk chunk = wd->job_queue.chunks[wd->job_queue.head];
wd->job_queue.head = (wd->job_queue.head + 1) % JOB_QUEUE_SIZE; wd->job_queue.head = (wd->job_queue.head + 1) % JOB_QUEUE_SIZE;
for (uint32_t i = 0; i < chunk.iteration_count; ++i) { for (uint32_t i = 0; i < chunk.iteration_count; ++i) {
chunk.fn(chunk.param, chunk.base_iteration + i); chunk.fn(chunk.param, chunk.base_iteration + i);
@ -44,22 +44,22 @@ static void ExecOneJobIfAvailable(vy_worker_data *wd) {
} }
static void WorkerEntry(void *param) { static void WorkerEntry(void *param) {
vy_worker_data *wd = param; rt_worker_data *wd = param;
while (_keep_running) { while (_keep_running) {
vyLockConditionVar(wd->job_queue.lock); rtLockConditionVar(wd->job_queue.lock);
while (wd->job_queue.head == wd->job_queue.tail && _keep_running) { while (wd->job_queue.head == wd->job_queue.tail && _keep_running) {
vyWaitOnConditionVar(wd->job_queue.lock); rtWaitOnConditionVar(wd->job_queue.lock);
} }
ExecOneJobIfAvailable(wd); ExecOneJobIfAvailable(wd);
vyUnlockConditionVar(wd->job_queue.lock, false); rtUnlockConditionVar(wd->job_queue.lock, false);
} }
} }
void vyInitJobSystem(unsigned int worker_count) { void rtInitJobSystem(unsigned int worker_count) {
if (worker_count > MAX_WORKERS) if (worker_count > MAX_WORKERS)
worker_count = MAX_WORKERS; worker_count = MAX_WORKERS;
for (unsigned int i = 0; i < worker_count; ++i) { for (unsigned int i = 0; i < worker_count; ++i) {
_worker_data[i].thread = vySpawnThread(WorkerEntry, &_worker_data[i], "JobWorker"); _worker_data[i].thread = rtSpawnThread(WorkerEntry, &_worker_data[i], "JobWorker");
} }
} }

View File

@ -1,5 +1,5 @@
#ifndef VY_JOBS_H #ifndef RT_JOBS_H
#define VY_JOBS_H #define RT_JOBS_H
/* Work stealing job scheduler */ /* Work stealing job scheduler */
@ -7,14 +7,14 @@
#include <stdint.h> #include <stdint.h>
typedef void vy_job_fn(void *param, uint32_t iteration); typedef void rt_job_fn(void *param, uint32_t iteration);
typedef struct { typedef struct {
uint32_t iterations; uint32_t iterations;
vy_job_fn *fn; rt_job_fn *fn;
void *param; void *param;
} vy_job_decl; } rt_job_decl;
VY_DLLEXPORT void vyDispatchJob(const vy_job_decl *decl); RT_DLLEXPORT void rtDispatchJob(const rt_job_decl *decl);
#endif #endif

View File

@ -1,20 +1,20 @@
#include <stdio.h> #include <stdio.h>
#include "file_tab.h" #include "file_tab.h"
vy_result LoadPackageNames(void) { rt_result LoadPackageNames(void) {
FILE *f = fopen("data/packages.txt", "r"); FILE *f = fopen("data/packages.txt", "r");
if (!f) { if (!f) {
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
while (!feof(f)) { while (!feof(f)) {
char line[256]; char line[256];
fscanf(f, "%255s\n", line); fscanf(f, "%255s\n", line);
line[255] = '\0'; line[255] = '\0';
vyAddFile(line); rtAddFile(line);
} }
fclose(f); fclose(f);
return VY_SUCCESS; return RT_SUCCESS;
} }

View File

@ -1,7 +1,7 @@
#ifndef VY_PACKAGES_H #ifndef RT_PACKAGES_H
#define VY_PACKAGES_H #define RT_PACKAGES_H
#ifdef VY_DEFINE_PACKAGE_FILE_STRUCTURES #ifdef RT_DEFINE_PACKAGE_FILE_STRUCTURES
#include <stdint.h> #include <stdint.h>
#include "xxhash/xxhash.h" #include "xxhash/xxhash.h"
@ -10,7 +10,7 @@
typedef struct { typedef struct {
XXH64_canonical_t checksum; XXH64_canonical_t checksum;
uint32_t decompressed_size; uint32_t decompressed_size;
} vy_package_asset_header; } rt_package_asset_header;
#pragma pack(pop) #pragma pack(pop)
#endif #endif

View File

@ -1,5 +1,5 @@
#ifndef VY_GFX_BACKEND_H #ifndef RT_GFX_BACKEND_H
#define VY_GFX_BACKEND_H #define RT_GFX_BACKEND_H
/* Backend functions and types. */ /* Backend functions and types. */
@ -12,52 +12,52 @@
#ifdef _WIN32 #ifdef _WIN32
struct HINSTANCE__; struct HINSTANCE__;
struct HWND__; struct HWND__;
#elif defined(VY_USE_XLIB) #elif defined(RT_USE_XLIB)
struct _XDisplay; struct _XDisplay;
#endif #endif
struct vy_renderer_init_info_s { struct rt_renderer_init_info_s {
#ifdef _WIN32 #ifdef _WIN32
struct HINSTANCE__ *hInstance; struct HINSTANCE__ *hInstance;
struct HWND__ *hWnd; struct HWND__ *hWnd;
#elif defined(VY_USE_XLIB) #elif defined(RT_USE_XLIB)
struct _XDisplay *display; struct _XDisplay *display;
unsigned long window; unsigned long window;
#endif #endif
}; };
typedef struct { typedef struct {
vy_uid vertex_shader; rt_uid vertex_shader;
vy_uid fragment_shader; rt_uid fragment_shader;
vy_uid compute_shader; rt_uid compute_shader;
vy_relptr texture_bindings; rt_relptr texture_bindings;
vy_relptr uniform_bindings; rt_relptr uniform_bindings;
vy_relptr storage_bindings; rt_relptr storage_bindings;
uint16_t texture_binding_count; uint16_t texture_binding_count;
uint16_t uniform_binding_count; uint16_t uniform_binding_count;
uint16_t storage_binding_count; uint16_t storage_binding_count;
} vy_pipeline_info; } rt_pipeline_info;
typedef void vy_register_renderer_cvars_fn(void); typedef void rt_register_renderer_cvars_fn(void);
typedef vy_result vy_init_renderer_fn(const vy_renderer_init_info *info); typedef rt_result rt_init_renderer_fn(const rt_renderer_init_info *info);
typedef void vy_shutdown_renderer_fn(void); typedef void rt_shutdown_renderer_fn(void);
typedef vy_pipeline_handle vy_compile_pipeline_fn(const vy_pipeline_info *info); typedef rt_pipeline_handle rt_compile_pipeline_fn(const rt_pipeline_info *info);
typedef void vy_destroy_pipeline_fn(vy_pipeline_handle handle); typedef void rt_destroy_pipeline_fn(rt_pipeline_handle handle);
typedef struct { typedef struct {
vy_register_renderer_cvars_fn *RegisterCVars; rt_register_renderer_cvars_fn *RegisterCVars;
vy_init_renderer_fn *Init; rt_init_renderer_fn *Init;
vy_shutdown_renderer_fn *Shutdown; rt_shutdown_renderer_fn *Shutdown;
vy_compile_pipeline_fn *CompilePipeline; rt_compile_pipeline_fn *CompilePipeline;
vy_destroy_pipeline_fn *DestroyPipeline; rt_destroy_pipeline_fn *DestroyPipeline;
} vy_renderer_api; } rt_renderer_api;
#define VY_RENDERER_API_FN(name) VY_DLLEXPORT vyRen##name #define RT_RENDERER_API_FN(name) RT_DLLEXPORT rtRen##name
#ifndef VY_DONT_DEFINE_RENDERER_GLOBAL #ifndef RT_DONT_DEFINE_RENDERER_GLOBAL
extern vy_renderer_api g_renderer; extern rt_renderer_api g_renderer;
#endif #endif
#endif #endif

View File

@ -1,47 +1,47 @@
#ifndef VY_VOYAGE_H #ifndef RT_VOYAGE_H
#define VY_VOYAGE_H #define RT_VOYAGE_H
/* basic types and macros */ /* basic types and macros */
#include <stddef.h> #include <stddef.h>
#include <stdint.h> #include <stdint.h>
#if defined(_MSC_VER) && !defined(VY_STATIC_LIB) #if defined(_MSC_VER) && !defined(RT_STATIC_LIB)
#define VY_DLLEXPORT __declspec(dllexport) #define RT_DLLEXPORT __declspec(dllexport)
#else #else
#define VY_DLLEXPORT #define RT_DLLEXPORT
#endif #endif
#if defined(_MSC_VER) #if defined(_MSC_VER)
#define VY_INLINE __forceinline #define RT_INLINE __forceinline
#elif defined(__GNUC__) || defined(__clang__) #elif defined(__GNUC__) || defined(__clang__)
#define VY_INLINE inline __attribute__((always_inline)) #define RT_INLINE inline __attribute__((always_inline))
#endif #endif
#define VY_UNUSED(x) ((void)sizeof((x))) #define RT_UNUSED(x) ((void)sizeof((x)))
#define VY_ARRAY_COUNT(x) (sizeof((x)) / sizeof((x)[0])) #define RT_ARRAY_COUNT(x) (sizeof((x)) / sizeof((x)[0]))
#define VY_KB(n) ((n)*1024U) #define RT_KB(n) ((n)*1024U)
#define VY_MB(n) ((n)*1024U * 1024U) #define RT_MB(n) ((n)*1024U * 1024U)
#define VY_GB(n) ((n)*1024U * 1024U * 1024U) #define RT_GB(n) ((n)*1024U * 1024U * 1024U)
typedef unsigned int vy_result; typedef unsigned int rt_result;
/* Default result codes */ /* Default result codes */
enum { enum {
VY_SUCCESS = 0, RT_SUCCESS = 0,
VY_OUT_OF_MEMORY = 1, RT_OUT_OF_MEMORY = 1,
VY_CUSTOM_ERROR_START, RT_CUSTOM_ERROR_START,
VY_UNKNOWN_ERROR = (vy_result)-1, RT_UNKNOWN_ERROR = (rt_result)-1,
}; };
typedef struct { typedef struct {
const char *start; const char *start;
unsigned int length; unsigned int length;
} vy_text_span; } rt_text_span;
/* Returns results like strcmp(): /* Returns results like strcmp():
* - If the first differing character is smaller in span than in cmp: < 0 * - If the first differing character is smaller in span than in cmp: < 0
@ -50,33 +50,33 @@ typedef struct {
* - If span.length is smaller than strlen(cmp): -1 * - If span.length is smaller than strlen(cmp): -1
* - If span.length is greater than strlen(cmp): 1 * - If span.length is greater than strlen(cmp): 1
*/ */
VY_DLLEXPORT int vyCompareSpanToString(vy_text_span span, const char *cmp); RT_DLLEXPORT int rtCompareSpanToString(rt_text_span span, const char *cmp);
VY_DLLEXPORT void vyReportError(const char *subsystem, const char *fmt, ...); RT_DLLEXPORT void rtReportError(const char *subsystem, const char *fmt, ...);
VY_DLLEXPORT void vyLog(const char *subsystem, const char *fmt, ...); RT_DLLEXPORT void rtLog(const char *subsystem, const char *fmt, ...);
enum { enum {
VY_INVALID_UNICODE = VY_CUSTOM_ERROR_START, RT_INVALID_UNICODE = RT_CUSTOM_ERROR_START,
VY_INSUFFICIENT_BUFFER, RT_INSUFFICIENT_BUFFER,
}; };
/* Returns VY_SUCCESS if the string was successfully converted, /* Returns RT_SUCCESS if the string was successfully converted,
* VY_INVALID_UNICODE if invalid unicode characters were encountered or * RT_INVALID_UNICODE if invalid unicode characters were encountered or
* VY_INSUFFICIENT_BUFFER if the provided output buffer is too small */ * RT_INSUFFICIENT_BUFFER if the provided output buffer is too small */
VY_DLLEXPORT vy_result vyUTF8ToWStr(const char *utf8, wchar_t *wstr, size_t len); RT_DLLEXPORT rt_result rtUTF8ToWStr(const char *utf8, wchar_t *wstr, size_t len);
/* Returns VY_SUCCESS if the string was successfully converted, /* Returns RT_SUCCESS if the string was successfully converted,
* VY_INVALID_UNICODE if invalid unicode characters were encountered or * RT_INVALID_UNICODE if invalid unicode characters were encountered or
* VY_INSUFFICIENT_BUFFER if the provided output buffer is too small */ * RT_INSUFFICIENT_BUFFER if the provided output buffer is too small */
VY_DLLEXPORT vy_result vyWStrToUTF8(const wchar_t *wstr, char *utf8, size_t len); RT_DLLEXPORT rt_result rtWStrToUTF8(const wchar_t *wstr, char *utf8, size_t len);
/* Relative pointer */ /* Relative pointer */
typedef struct { typedef struct {
int32_t off; int32_t off;
} vy_relptr; } rt_relptr;
static VY_INLINE void *vyResolveRelptr(vy_relptr *ptr) { static RT_INLINE void *rtResolveRelptr(rt_relptr *ptr) {
if (ptr->off != 0) { if (ptr->off != 0) {
char *p = (char *)ptr; char *p = (char *)ptr;
return (void *)(p + (ptrdiff_t)ptr->off); return (void *)(p + (ptrdiff_t)ptr->off);
@ -85,7 +85,7 @@ static VY_INLINE void *vyResolveRelptr(vy_relptr *ptr) {
} }
} }
static VY_INLINE void vySetRelptr(vy_relptr *ptr, void *target) { static RT_INLINE void rtSetRelptr(rt_relptr *ptr, void *target) {
if (target) { if (target) {
char *p = (char *)ptr, *t = (char *)target; char *p = (char *)ptr, *t = (char *)target;
ptrdiff_t d = t - p; ptrdiff_t d = t - p;
@ -98,7 +98,7 @@ static VY_INLINE void vySetRelptr(vy_relptr *ptr, void *target) {
/* Bitfiddling functions */ /* Bitfiddling functions */
/* Portable solution, On x64 using clzl is probably faster. */ /* Portable solution, On x64 using clzl is probably faster. */
static VY_INLINE uint32_t vyNextPowerOfTwo32(uint32_t v) { static RT_INLINE uint32_t rtNextPowerOfTwo32(uint32_t v) {
v--; v--;
v |= v >> 1; v |= v >> 1;
v |= v >> 2; v |= v >> 2;
@ -112,8 +112,8 @@ static VY_INLINE uint32_t vyNextPowerOfTwo32(uint32_t v) {
/* Runtime init. Initializes basic systems. /* Runtime init. Initializes basic systems.
* You need to call this, even if you build a CLI only app. */ * You need to call this, even if you build a CLI only app. */
VY_DLLEXPORT vy_result vyInitRuntime(void); RT_DLLEXPORT rt_result rtInitRuntime(void);
VY_DLLEXPORT void vyShutdownRuntime(void); RT_DLLEXPORT void rtShutdownRuntime(void);
#endif #endif

View File

@ -7,7 +7,7 @@
#include <Windows.h> #include <Windows.h>
#endif #endif
VY_DLLEXPORT int vyCompareSpanToString(vy_text_span span, const char *cmp) { RT_DLLEXPORT int rtCompareSpanToString(rt_text_span span, const char *cmp) {
size_t cmp_len = strlen(cmp); size_t cmp_len = strlen(cmp);
if (cmp_len != (size_t)span.length) if (cmp_len != (size_t)span.length)
return (span.length < cmp_len) ? -1 : 1; return (span.length < cmp_len) ? -1 : 1;
@ -18,40 +18,40 @@ VY_DLLEXPORT int vyCompareSpanToString(vy_text_span span, const char *cmp) {
return 0; return 0;
} }
VY_DLLEXPORT vy_result vyUTF8ToWStr(const char *utf8, wchar_t *wstr, size_t len) { RT_DLLEXPORT rt_result rtUTF8ToWStr(const char *utf8, wchar_t *wstr, size_t len) {
#ifdef _WIN32 #ifdef _WIN32
int res = MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, utf8, -1, wstr, (int)len); int res = MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, utf8, -1, wstr, (int)len);
if (res > 0) { if (res > 0) {
return VY_SUCCESS; return RT_SUCCESS;
} else { } else {
DWORD err = GetLastError(); DWORD err = GetLastError();
if (err == ERROR_INSUFFICIENT_BUFFER) if (err == ERROR_INSUFFICIENT_BUFFER)
return VY_INSUFFICIENT_BUFFER; return RT_INSUFFICIENT_BUFFER;
else if (err == ERROR_NO_UNICODE_TRANSLATION) else if (err == ERROR_NO_UNICODE_TRANSLATION)
return VY_INVALID_UNICODE; return RT_INVALID_UNICODE;
else { else {
vyReportError("CORE", "Unexpected error in vyUTF8ToWStr(): %u", err); rtReportError("CORE", "Unexpected error in rtUTF8ToWStr(): %u", err);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
} }
#endif #endif
} }
VY_DLLEXPORT vy_result vyWStrToUTF8(const wchar_t *wstr, char *utf8, size_t len) { RT_DLLEXPORT rt_result rtWStrToUTF8(const wchar_t *wstr, char *utf8, size_t len) {
#ifdef _WIN32 #ifdef _WIN32
int res = WideCharToMultiByte(CP_UTF8, WC_COMPOSITECHECK, wstr, -1, utf8, (int)len, NULL, NULL); int res = WideCharToMultiByte(CP_UTF8, WC_COMPOSITECHECK, wstr, -1, utf8, (int)len, NULL, NULL);
if (res > 0) { if (res > 0) {
return VY_SUCCESS; return RT_SUCCESS;
} else { } else {
DWORD err = GetLastError(); DWORD err = GetLastError();
if (err == ERROR_INSUFFICIENT_BUFFER) if (err == ERROR_INSUFFICIENT_BUFFER)
return VY_INSUFFICIENT_BUFFER; return RT_INSUFFICIENT_BUFFER;
else if (err == ERROR_NO_UNICODE_TRANSLATION) else if (err == ERROR_NO_UNICODE_TRANSLATION)
return VY_INVALID_UNICODE; return RT_INVALID_UNICODE;
else { else {
vyReportError("CORE", "Unexpected error in vyWStrToUTF8(): %u", err); rtReportError("CORE", "Unexpected error in rtWStrToUTF8(): %u", err);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
} }
#endif #endif

View File

@ -1,5 +1,5 @@
#ifndef VY_THREADING_H #ifndef RT_THREADING_H
#define VY_THREADING_H #define RT_THREADING_H
/* platform independent threading */ /* platform independent threading */
@ -9,70 +9,70 @@
/* Mutexes */ /* Mutexes */
typedef struct vy_mutex_s vy_mutex; typedef struct rt_mutex_s rt_mutex;
VY_DLLEXPORT vy_mutex *vyCreateMutex(void); RT_DLLEXPORT rt_mutex *rtCreateMutex(void);
VY_DLLEXPORT void vyDestroyMutex(vy_mutex *mutex); RT_DLLEXPORT void rtDestroyMutex(rt_mutex *mutex);
VY_DLLEXPORT bool vyLockMutex(vy_mutex *mutex); RT_DLLEXPORT bool rtLockMutex(rt_mutex *mutex);
VY_DLLEXPORT bool vyUnlockMutex(vy_mutex *mutex); RT_DLLEXPORT bool rtUnlockMutex(rt_mutex *mutex);
/* Condition variables */ /* Condition variables */
typedef struct vy_condition_var_s vy_condition_var; typedef struct rt_condition_var_s rt_condition_var;
VY_DLLEXPORT vy_condition_var *vyCreateConditionVar(void); RT_DLLEXPORT rt_condition_var *rtCreateConditionVar(void);
VY_DLLEXPORT void vyDestroyConditionVar(vy_condition_var *var); RT_DLLEXPORT void rtDestroyConditionVar(rt_condition_var *var);
VY_DLLEXPORT void vyLockConditionVar(vy_condition_var *var); RT_DLLEXPORT void rtLockConditionVar(rt_condition_var *var);
VY_DLLEXPORT void vyUnlockConditionVar(vy_condition_var *var, bool signal); RT_DLLEXPORT void rtUnlockConditionVar(rt_condition_var *var, bool signal);
/* The condition variable must be locked by the thread! */ /* The condition variable must be locked by the thread! */
VY_DLLEXPORT void vyWaitOnConditionVar(vy_condition_var *var); RT_DLLEXPORT void rtWaitOnConditionVar(rt_condition_var *var);
/* Read-Write Lock */ /* Read-Write Lock */
typedef struct { typedef struct {
volatile int reader_count; volatile int reader_count;
vy_condition_var *cond; rt_condition_var *cond;
} vy_rwlock; } rt_rwlock;
typedef struct { typedef struct {
bool ok; bool ok;
vy_rwlock lock; rt_rwlock lock;
} vy_create_rwlock_result; } rt_create_rwlock_result;
VY_DLLEXPORT vy_create_rwlock_result vyCreateRWLock(void); RT_DLLEXPORT rt_create_rwlock_result rtCreateRWLock(void);
VY_DLLEXPORT void vyDestroyRWLock(vy_rwlock *lock); RT_DLLEXPORT void rtDestroyRWLock(rt_rwlock *lock);
VY_DLLEXPORT void vyLockRead(vy_rwlock *lock); RT_DLLEXPORT void rtLockRead(rt_rwlock *lock);
VY_DLLEXPORT void vyUnlockRead(vy_rwlock *lock); RT_DLLEXPORT void rtUnlockRead(rt_rwlock *lock);
VY_DLLEXPORT void vyLockWrite(vy_rwlock *lock); RT_DLLEXPORT void rtLockWrite(rt_rwlock *lock);
VY_DLLEXPORT void vyUnlockWrite(vy_rwlock *lock); RT_DLLEXPORT void rtUnlockWrite(rt_rwlock *lock);
/* Threads */ /* Threads */
typedef struct vy_thread_s vy_thread; typedef struct rt_thread_s rt_thread;
typedef void vy_thread_entry_fn(void *param); typedef void rt_thread_entry_fn(void *param);
VY_DLLEXPORT vy_thread *vySpawnThread(vy_thread_entry_fn *entry, void *param, const char *name); RT_DLLEXPORT rt_thread *rtSpawnThread(rt_thread_entry_fn *entry, void *param, const char *name);
VY_DLLEXPORT void vyJoinThread(vy_thread *thread); RT_DLLEXPORT void rtJoinThread(rt_thread *thread);
VY_DLLEXPORT unsigned int vyGetCPUCoreCount(void); RT_DLLEXPORT unsigned int rtGetCPUCoreCount(void);
typedef uint32_t vy_thread_id; typedef uint32_t rt_thread_id;
VY_DLLEXPORT vy_thread_id vyGetCurrentThreadId(void); RT_DLLEXPORT rt_thread_id rtGetCurrentThreadId(void);
VY_DLLEXPORT bool vyIsMainThread(void); RT_DLLEXPORT bool rtIsMainThread(void);
#endif #endif

View File

@ -4,46 +4,46 @@
#ifdef __linux__ #ifdef __linux__
#include <pthread.h> #include <pthread.h>
struct vy_condition_var_s { struct rt_condition_var_s {
pthread_mutex_t mutex; pthread_mutex_t mutex;
pthread_cond_t cond; pthread_cond_t cond;
ptrdiff_t next_reusable; ptrdiff_t next_reusable;
}; };
#define MAX_CONDS 1024 #define MAX_CONDS 1024
vy_condition_var _conds[MAX_CONDS]; rt_condition_var _conds[MAX_CONDS];
static ptrdiff_t _first_reusable = MAX_CONDS; static ptrdiff_t _first_reusable = MAX_CONDS;
static ptrdiff_t _next = 0; static ptrdiff_t _next = 0;
static pthread_mutex_t _guard = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _guard = PTHREAD_MUTEX_INITIALIZER;
VY_DLLEXPORT vy_condition_var *vyCreateConditionVar(void) { RT_DLLEXPORT rt_condition_var *rtCreateConditionVar(void) {
pthread_mutex_lock(&_guard); pthread_mutex_lock(&_guard);
if (_first_reusable < MAX_CONDS) { if (_first_reusable < MAX_CONDS) {
vy_condition_var *cond = &_conds[_first_reusable]; rt_condition_var *cond = &_conds[_first_reusable];
_first_reusable = cond->next_reusable; _first_reusable = cond->next_reusable;
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return cond; return cond;
} else if (_next < MAX_CONDS) { } else if (_next < MAX_CONDS) {
vy_condition_var *cond = &_conds[_next]; rt_condition_var *cond = &_conds[_next];
if (pthread_mutex_init(&cond->mutex, NULL) != 0) { if (pthread_mutex_init(&cond->mutex, NULL) != 0) {
vyLog("core", "Condition variable creation failed"); rtLog("core", "Condition variable creation failed");
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return NULL; return NULL;
} }
if (pthread_cond_init(&cond->cond, NULL) != 0) { if (pthread_cond_init(&cond->cond, NULL) != 0) {
vyLog("core", "Condition variable creation failed"); rtLog("core", "Condition variable creation failed");
} }
cond->next_reusable = MAX_CONDS; cond->next_reusable = MAX_CONDS;
++_next; ++_next;
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return cond; return cond;
} }
vyReportError("core", "Ran out of condition variable objects"); rtReportError("core", "Ran out of condition variable objects");
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return NULL; return NULL;
} }
VY_DLLEXPORT void vyDestroyConditionVar(vy_condition_var *var) { RT_DLLEXPORT void rtDestroyConditionVar(rt_condition_var *var) {
ptrdiff_t index = var - &_conds[0]; ptrdiff_t index = var - &_conds[0];
pthread_mutex_lock(&_guard); pthread_mutex_lock(&_guard);
var->next_reusable = _first_reusable; var->next_reusable = _first_reusable;
@ -51,17 +51,17 @@ VY_DLLEXPORT void vyDestroyConditionVar(vy_condition_var *var) {
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
} }
VY_DLLEXPORT void vyLockConditionVar(vy_condition_var *var) { RT_DLLEXPORT void rtLockConditionVar(rt_condition_var *var) {
pthread_mutex_lock(&var->mutex); pthread_mutex_lock(&var->mutex);
} }
VY_DLLEXPORT void vyUnlockConditionVar(vy_condition_var *var, bool signal) { RT_DLLEXPORT void rtUnlockConditionVar(rt_condition_var *var, bool signal) {
if (signal) if (signal)
pthread_cond_signal(&var->cond); pthread_cond_signal(&var->cond);
pthread_mutex_unlock(&var->mutex); pthread_mutex_unlock(&var->mutex);
} }
VY_DLLEXPORT void vyWaitOnConditionVar(vy_condition_var *var) { RT_DLLEXPORT void rtWaitOnConditionVar(rt_condition_var *var) {
pthread_cond_wait(&var->cond, &var->mutex); pthread_cond_wait(&var->cond, &var->mutex);
} }
@ -69,47 +69,47 @@ VY_DLLEXPORT void vyWaitOnConditionVar(vy_condition_var *var) {
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
struct vy_condition_var_s { struct rt_condition_var_s {
CRITICAL_SECTION critical_section; CRITICAL_SECTION critical_section;
CONDITION_VARIABLE cond; CONDITION_VARIABLE cond;
ptrdiff_t next_reusable; ptrdiff_t next_reusable;
}; };
#define MAX_CONDS 1024 #define MAX_CONDS 1024
vy_condition_var _conds[MAX_CONDS]; rt_condition_var _conds[MAX_CONDS];
static ptrdiff_t _first_reusable = MAX_CONDS; static ptrdiff_t _first_reusable = MAX_CONDS;
static ptrdiff_t _next = 0; static ptrdiff_t _next = 0;
static HANDLE _guard; static HANDLE _guard;
static INIT_ONCE _guard_init = INIT_ONCE_STATIC_INIT; static INIT_ONCE _guard_init = INIT_ONCE_STATIC_INIT;
static BOOL CALLBACK InitGuardFn(PINIT_ONCE initOnce, PVOID parameter, PVOID *context) { static BOOL CALLBACK InitGuardFn(PINIT_ONCE initOnce, PVOID parameter, PVOID *context) {
VY_UNUSED(initOnce); RT_UNUSED(initOnce);
VY_UNUSED(parameter); RT_UNUSED(parameter);
VY_UNUSED(context); RT_UNUSED(context);
_guard = CreateMutexW(NULL, FALSE, NULL); _guard = CreateMutexW(NULL, FALSE, NULL);
return _guard != NULL; return _guard != NULL;
} }
VY_DLLEXPORT vy_condition_var *vyCreateConditionVar(void) { RT_DLLEXPORT rt_condition_var *rtCreateConditionVar(void) {
if (!InitOnceExecuteOnce(&_guard_init, InitGuardFn, NULL, NULL)) { if (!InitOnceExecuteOnce(&_guard_init, InitGuardFn, NULL, NULL)) {
vyReportError("core", "Failed to initialize the guard mutex."); rtReportError("core", "Failed to initialize the guard mutex.");
return NULL; return NULL;
} }
if (WaitForSingleObjectEx(_guard, INFINITE, TRUE) != WAIT_OBJECT_0) { if (WaitForSingleObjectEx(_guard, INFINITE, TRUE) != WAIT_OBJECT_0) {
vyLog("core", "Failed to lock the guard variable: %u", GetLastError()); rtLog("core", "Failed to lock the guard variable: %u", GetLastError());
return NULL; return NULL;
} }
if (_first_reusable < MAX_CONDS) { if (_first_reusable < MAX_CONDS) {
vy_condition_var *cond = &_conds[_first_reusable]; rt_condition_var *cond = &_conds[_first_reusable];
_first_reusable = cond->next_reusable; _first_reusable = cond->next_reusable;
ReleaseMutex(_guard); ReleaseMutex(_guard);
return cond; return cond;
} else if (_next < MAX_CONDS) { } else if (_next < MAX_CONDS) {
vy_condition_var *cond = &_conds[_next]; rt_condition_var *cond = &_conds[_next];
if (!InitializeCriticalSectionAndSpinCount(&cond->critical_section, 4000)) { if (!InitializeCriticalSectionAndSpinCount(&cond->critical_section, 4000)) {
vyLog("core", "Condition variable creation failed"); rtLog("core", "Condition variable creation failed");
ReleaseMutex(_guard); ReleaseMutex(_guard);
return NULL; return NULL;
} }
@ -119,15 +119,15 @@ VY_DLLEXPORT vy_condition_var *vyCreateConditionVar(void) {
ReleaseMutex(_guard); ReleaseMutex(_guard);
return cond; return cond;
} }
vyReportError("core", "Ran out of condition variable objects"); rtReportError("core", "Ran out of condition variable objects");
ReleaseMutex(_guard); ReleaseMutex(_guard);
return NULL; return NULL;
} }
VY_DLLEXPORT void vyDestroyConditionVar(vy_condition_var *var) { RT_DLLEXPORT void rtDestroyConditionVar(rt_condition_var *var) {
ptrdiff_t index = var - &_conds[0]; ptrdiff_t index = var - &_conds[0];
if (WaitForSingleObjectEx(_guard, INFINITE, TRUE) != WAIT_OBJECT_0) { if (WaitForSingleObjectEx(_guard, INFINITE, TRUE) != WAIT_OBJECT_0) {
vyLog("core", "Failed to lock the guard variable: %u", GetLastError()); rtLog("core", "Failed to lock the guard variable: %u", GetLastError());
return; return;
} }
var->next_reusable = _first_reusable; var->next_reusable = _first_reusable;
@ -135,17 +135,17 @@ VY_DLLEXPORT void vyDestroyConditionVar(vy_condition_var *var) {
ReleaseMutex(_guard); ReleaseMutex(_guard);
} }
VY_DLLEXPORT void vyLockConditionVar(vy_condition_var *var) { RT_DLLEXPORT void rtLockConditionVar(rt_condition_var *var) {
EnterCriticalSection(&var->critical_section); EnterCriticalSection(&var->critical_section);
} }
VY_DLLEXPORT void vyUnlockConditionVar(vy_condition_var *var, bool signal) { RT_DLLEXPORT void rtUnlockConditionVar(rt_condition_var *var, bool signal) {
LeaveCriticalSection(&var->critical_section); LeaveCriticalSection(&var->critical_section);
if (signal) if (signal)
WakeAllConditionVariable(&var->cond); WakeAllConditionVariable(&var->cond);
} }
VY_DLLEXPORT void vyWaitOnConditionVar(vy_condition_var *var) { RT_DLLEXPORT void rtWaitOnConditionVar(rt_condition_var *var) {
SleepConditionVariableCS(&var->cond, &var->critical_section, INFINITE); SleepConditionVariableCS(&var->cond, &var->critical_section, INFINITE);
} }

View File

@ -5,48 +5,48 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
struct vy_mutex_s { struct rt_mutex_s {
HANDLE handle; HANDLE handle;
ptrdiff_t next_reusable; ptrdiff_t next_reusable;
DWORD owner; DWORD owner;
}; };
#define MAX_MUTEX 1024 #define MAX_MUTEX 1024
static vy_mutex _mutex[MAX_MUTEX]; static rt_mutex _mutex[MAX_MUTEX];
static ptrdiff_t _first_reusable = MAX_MUTEX; static ptrdiff_t _first_reusable = MAX_MUTEX;
static ptrdiff_t _next = 0; static ptrdiff_t _next = 0;
static HANDLE _guard; static HANDLE _guard;
static INIT_ONCE _guard_init = INIT_ONCE_STATIC_INIT; static INIT_ONCE _guard_init = INIT_ONCE_STATIC_INIT;
static BOOL CALLBACK InitGuardFn(PINIT_ONCE initOnce, PVOID parameter, PVOID *context) { static BOOL CALLBACK InitGuardFn(PINIT_ONCE initOnce, PVOID parameter, PVOID *context) {
VY_UNUSED(initOnce); RT_UNUSED(initOnce);
VY_UNUSED(parameter); RT_UNUSED(parameter);
VY_UNUSED(context); RT_UNUSED(context);
_guard = CreateMutexW(NULL, FALSE, NULL); _guard = CreateMutexW(NULL, FALSE, NULL);
return _guard != NULL; return _guard != NULL;
} }
VY_DLLEXPORT vy_mutex *vyCreateMutex(void) { RT_DLLEXPORT rt_mutex *rtCreateMutex(void) {
if (!InitOnceExecuteOnce(&_guard_init, InitGuardFn, NULL, NULL)) { if (!InitOnceExecuteOnce(&_guard_init, InitGuardFn, NULL, NULL)) {
vyReportError("core", "Failed to initialize the guard mutex."); rtReportError("core", "Failed to initialize the guard mutex.");
return NULL; return NULL;
} }
if (WaitForSingleObjectEx(_guard, INFINITE, TRUE) != WAIT_OBJECT_0) { if (WaitForSingleObjectEx(_guard, INFINITE, TRUE) != WAIT_OBJECT_0) {
vyLog("core", "Failed to lock the guard variable: %u", GetLastError()); rtLog("core", "Failed to lock the guard variable: %u", GetLastError());
return NULL; return NULL;
} }
if (_first_reusable < MAX_MUTEX) { if (_first_reusable < MAX_MUTEX) {
vy_mutex *mtx = &_mutex[_first_reusable]; rt_mutex *mtx = &_mutex[_first_reusable];
_first_reusable = mtx->next_reusable; _first_reusable = mtx->next_reusable;
mtx->owner = 0; mtx->owner = 0;
return mtx; return mtx;
} else if (_next < MAX_MUTEX) { } else if (_next < MAX_MUTEX) {
vy_mutex *mtx = &_mutex[_next]; rt_mutex *mtx = &_mutex[_next];
mtx->handle = CreateMutexW(NULL, FALSE, NULL); mtx->handle = CreateMutexW(NULL, FALSE, NULL);
if (!mtx->handle) { if (!mtx->handle) {
vyLog("core", "Mutex creation failed: %u", GetLastError()); rtLog("core", "Mutex creation failed: %u", GetLastError());
return NULL; return NULL;
} }
mtx->next_reusable = MAX_MUTEX; mtx->next_reusable = MAX_MUTEX;
@ -54,17 +54,17 @@ VY_DLLEXPORT vy_mutex *vyCreateMutex(void) {
++_next; ++_next;
return mtx; return mtx;
} }
vyReportError("core", "Ran out of mutex objects"); rtReportError("core", "Ran out of mutex objects");
return NULL; return NULL;
} }
VY_DLLEXPORT void vyDestroyMutex(vy_mutex *mutex) { RT_DLLEXPORT void rtDestroyMutex(rt_mutex *mutex) {
ptrdiff_t index = mutex - &_mutex[0]; ptrdiff_t index = mutex - &_mutex[0];
mutex->next_reusable = _first_reusable; mutex->next_reusable = _first_reusable;
_first_reusable = index; _first_reusable = index;
} }
VY_DLLEXPORT bool vyLockMutex(vy_mutex *mutex) { RT_DLLEXPORT bool rtLockMutex(rt_mutex *mutex) {
DWORD caller = GetCurrentThreadId(); DWORD caller = GetCurrentThreadId();
DWORD result; DWORD result;
do { do {
@ -72,7 +72,7 @@ VY_DLLEXPORT bool vyLockMutex(vy_mutex *mutex) {
if (result == WAIT_OBJECT_0) { if (result == WAIT_OBJECT_0) {
mutex->owner = caller; mutex->owner = caller;
} else if (result != WAIT_IO_COMPLETION) { } else if (result != WAIT_IO_COMPLETION) {
vyLog("core", rtLog("core",
"WaitForSingleObjectEx returned %x (GetLastError(): %u)", "WaitForSingleObjectEx returned %x (GetLastError(): %u)",
result, result,
(result == WAIT_FAILED) ? GetLastError() : 0); (result == WAIT_FAILED) ? GetLastError() : 0);
@ -81,10 +81,10 @@ VY_DLLEXPORT bool vyLockMutex(vy_mutex *mutex) {
return result == WAIT_OBJECT_0; return result == WAIT_OBJECT_0;
} }
VY_DLLEXPORT bool vyUnlockMutex(vy_mutex *mutex) { RT_DLLEXPORT bool rtUnlockMutex(rt_mutex *mutex) {
DWORD caller = GetCurrentThreadId(); DWORD caller = GetCurrentThreadId();
if (caller != mutex->owner) { if (caller != mutex->owner) {
vyReportError("core", "Tried to unlock a mutex held by another thread."); rtReportError("core", "Tried to unlock a mutex held by another thread.");
return false; return false;
} }
mutex->owner = 0; mutex->owner = 0;
@ -97,28 +97,28 @@ VY_DLLEXPORT bool vyUnlockMutex(vy_mutex *mutex) {
#elif defined(__linux__) #elif defined(__linux__)
#include <pthread.h> #include <pthread.h>
struct vy_mutex_s { struct rt_mutex_s {
pthread_mutex_t handle; pthread_mutex_t handle;
ptrdiff_t next_reusable; ptrdiff_t next_reusable;
}; };
#define MAX_MUTEX 1024 #define MAX_MUTEX 1024
static vy_mutex _mutex[MAX_MUTEX]; static rt_mutex _mutex[MAX_MUTEX];
static ptrdiff_t _first_reusable = MAX_MUTEX; static ptrdiff_t _first_reusable = MAX_MUTEX;
static ptrdiff_t _next = 0; static ptrdiff_t _next = 0;
static pthread_mutex_t _guard = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _guard = PTHREAD_MUTEX_INITIALIZER;
VY_DLLEXPORT vy_mutex *vyCreateMutex(void) { RT_DLLEXPORT rt_mutex *rtCreateMutex(void) {
pthread_mutex_lock(&_guard); pthread_mutex_lock(&_guard);
if (_first_reusable < MAX_MUTEX) { if (_first_reusable < MAX_MUTEX) {
vy_mutex *mtx = &_mutex[_first_reusable]; rt_mutex *mtx = &_mutex[_first_reusable];
_first_reusable = mtx->next_reusable; _first_reusable = mtx->next_reusable;
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return mtx; return mtx;
} else if (_next < MAX_MUTEX) { } else if (_next < MAX_MUTEX) {
vy_mutex *mtx = &_mutex[_next]; rt_mutex *mtx = &_mutex[_next];
if (pthread_mutex_init(&mtx->handle, NULL) != 0) { if (pthread_mutex_init(&mtx->handle, NULL) != 0) {
vyLog("core", "Mutex creation failed"); rtLog("core", "Mutex creation failed");
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return NULL; return NULL;
} }
@ -127,12 +127,12 @@ VY_DLLEXPORT vy_mutex *vyCreateMutex(void) {
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return mtx; return mtx;
} }
vyReportError("core", "Ran out of mutex objects"); rtReportError("core", "Ran out of mutex objects");
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return NULL; return NULL;
} }
VY_DLLEXPORT void vyDestroyMutex(vy_mutex *mutex) { RT_DLLEXPORT void rtDestroyMutex(rt_mutex *mutex) {
ptrdiff_t index = mutex - &_mutex[0]; ptrdiff_t index = mutex - &_mutex[0];
pthread_mutex_lock(&_guard); pthread_mutex_lock(&_guard);
mutex->next_reusable = _first_reusable; mutex->next_reusable = _first_reusable;
@ -140,11 +140,11 @@ VY_DLLEXPORT void vyDestroyMutex(vy_mutex *mutex) {
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
} }
VY_DLLEXPORT bool vyLockMutex(vy_mutex *mutex) { RT_DLLEXPORT bool rtLockMutex(rt_mutex *mutex) {
return pthread_mutex_lock(&mutex->handle) == 0; return pthread_mutex_lock(&mutex->handle) == 0;
} }
VY_DLLEXPORT bool vyUnlockMutex(vy_mutex *mutex) { RT_DLLEXPORT bool rtUnlockMutex(rt_mutex *mutex) {
return pthread_mutex_unlock(&mutex->handle) == 0; return pthread_mutex_unlock(&mutex->handle) == 0;
} }

View File

@ -4,40 +4,40 @@
/* Based on: https://eli.thegreenplace.net/2019/implementing-reader-writer-locks/ */ /* Based on: https://eli.thegreenplace.net/2019/implementing-reader-writer-locks/ */
VY_DLLEXPORT vy_create_rwlock_result vyCreateRWLock(void) { RT_DLLEXPORT rt_create_rwlock_result rtCreateRWLock(void) {
vy_create_rwlock_result res; rt_create_rwlock_result res;
res.lock.reader_count = 0; res.lock.reader_count = 0;
res.lock.cond = vyCreateConditionVar(); res.lock.cond = rtCreateConditionVar();
res.ok = res.lock.cond != NULL; res.ok = res.lock.cond != NULL;
return res; return res;
} }
VY_DLLEXPORT void vyDestroyRWLock(vy_rwlock *lock) { RT_DLLEXPORT void rtDestroyRWLock(rt_rwlock *lock) {
vyDestroyConditionVar(lock->cond); rtDestroyConditionVar(lock->cond);
lock->cond = NULL; lock->cond = NULL;
lock->reader_count = 0; lock->reader_count = 0;
} }
VY_DLLEXPORT void vyLockRead(vy_rwlock *lock) { RT_DLLEXPORT void rtLockRead(rt_rwlock *lock) {
vyLockConditionVar(lock->cond); rtLockConditionVar(lock->cond);
++lock->reader_count; ++lock->reader_count;
vyUnlockConditionVar(lock->cond, false); rtUnlockConditionVar(lock->cond, false);
} }
VY_DLLEXPORT void vyUnlockRead(vy_rwlock *lock) { RT_DLLEXPORT void rtUnlockRead(rt_rwlock *lock) {
vyLockConditionVar(lock->cond); rtLockConditionVar(lock->cond);
assert(lock->reader_count > 0); assert(lock->reader_count > 0);
--lock->reader_count; --lock->reader_count;
bool signal = lock->reader_count == 0; bool signal = lock->reader_count == 0;
vyUnlockConditionVar(lock->cond, signal); rtUnlockConditionVar(lock->cond, signal);
} }
VY_DLLEXPORT void vyLockWrite(vy_rwlock *lock) { RT_DLLEXPORT void rtLockWrite(rt_rwlock *lock) {
vyLockConditionVar(lock->cond); rtLockConditionVar(lock->cond);
while (lock->reader_count > 0) while (lock->reader_count > 0)
vyWaitOnConditionVar(lock->cond); rtWaitOnConditionVar(lock->cond);
} }
VY_DLLEXPORT void vyUnlockWrite(vy_rwlock *lock) { RT_DLLEXPORT void rtUnlockWrite(rt_rwlock *lock) {
vyUnlockConditionVar(lock->cond, true); rtUnlockConditionVar(lock->cond, true);
} }

View File

@ -6,59 +6,59 @@
#define WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN
#include <Windows.h> #include <Windows.h>
struct vy_thread_s { struct rt_thread_s {
HANDLE handle; HANDLE handle;
ptrdiff_t next_reusable; ptrdiff_t next_reusable;
vy_thread_entry_fn *entry; rt_thread_entry_fn *entry;
void *param; void *param;
bool needs_join; bool needs_join;
}; };
#define MAX_THREADS 256 #define MAX_THREADS 256
static vy_thread _threads[MAX_THREADS]; static rt_thread _threads[MAX_THREADS];
static ptrdiff_t _first_reusable = MAX_THREADS; static ptrdiff_t _first_reusable = MAX_THREADS;
static ptrdiff_t _next = 0; static ptrdiff_t _next = 0;
static HANDLE _guard; static HANDLE _guard;
static INIT_ONCE _guard_init = INIT_ONCE_STATIC_INIT; static INIT_ONCE _guard_init = INIT_ONCE_STATIC_INIT;
static vy_thread_id _main_thread_id; static rt_thread_id _main_thread_id;
/* Called by the runtime during setup */ /* Called by the runtime during setup */
extern void SetMainThreadId(void) { extern void SetMainThreadId(void) {
_main_thread_id = (vy_thread_id)GetCurrentThreadId(); _main_thread_id = (rt_thread_id)GetCurrentThreadId();
} }
static BOOL CALLBACK InitGuardFn(PINIT_ONCE initOnce, PVOID parameter, PVOID *context) { static BOOL CALLBACK InitGuardFn(PINIT_ONCE initOnce, PVOID parameter, PVOID *context) {
VY_UNUSED(initOnce); RT_UNUSED(initOnce);
VY_UNUSED(parameter); RT_UNUSED(parameter);
VY_UNUSED(context); RT_UNUSED(context);
_guard = CreateMutexW(NULL, FALSE, NULL); _guard = CreateMutexW(NULL, FALSE, NULL);
return _guard != NULL; return _guard != NULL;
} }
static DWORD WINAPI win32ThreadWrapper(LPVOID arg) { static DWORD WINAPI win32ThreadWrapper(LPVOID arg) {
vy_thread *user_thread = arg; rt_thread *user_thread = arg;
user_thread->needs_join = false; user_thread->needs_join = false;
user_thread->entry(user_thread->param); user_thread->entry(user_thread->param);
user_thread->needs_join = true; user_thread->needs_join = true;
return 0; return 0;
} }
VY_DLLEXPORT vy_thread *vySpawnThread(vy_thread_entry_fn *entry, void *param, const char *name) { RT_DLLEXPORT rt_thread *rtSpawnThread(rt_thread_entry_fn *entry, void *param, const char *name) {
if (!InitOnceExecuteOnce(&_guard_init, InitGuardFn, NULL, NULL)) { if (!InitOnceExecuteOnce(&_guard_init, InitGuardFn, NULL, NULL)) {
vyReportError("core", "Failed to initialize the guard mutex."); rtReportError("core", "Failed to initialize the guard mutex.");
return NULL; return NULL;
} }
vy_thread *thrd = NULL; rt_thread *thrd = NULL;
if (WaitForSingleObject(_guard, INFINITE) != WAIT_OBJECT_0) { if (WaitForSingleObject(_guard, INFINITE) != WAIT_OBJECT_0) {
vyLog("core", "Failed to lock the guard variable: %u", GetLastError()); rtLog("core", "Failed to lock the guard variable: %u", GetLastError());
return NULL; return NULL;
} }
if (_first_reusable < MAX_THREADS) { if (_first_reusable < MAX_THREADS) {
@ -79,29 +79,29 @@ VY_DLLEXPORT vy_thread *vySpawnThread(vy_thread_entry_fn *entry, void *param, co
thrd->param = param; thrd->param = param;
thrd->handle = CreateThread(NULL, 0, win32ThreadWrapper, (LPVOID)thrd, 0, NULL); thrd->handle = CreateThread(NULL, 0, win32ThreadWrapper, (LPVOID)thrd, 0, NULL);
if (thrd->handle == NULL) { if (thrd->handle == NULL) {
vyLog("core", "Thread creation failed"); rtLog("core", "Thread creation failed");
thrd = NULL; thrd = NULL;
} }
WCHAR wname[64]; WCHAR wname[64];
if (thrd && name && vyUTF8ToWStr(name, wname, sizeof(wname)) == VY_SUCCESS) if (thrd && name && rtUTF8ToWStr(name, wname, sizeof(wname)) == RT_SUCCESS)
SetThreadDescription(thrd->handle, wname); SetThreadDescription(thrd->handle, wname);
} else { } else {
vyReportError("core", "Ran out of thread objects"); rtReportError("core", "Ran out of thread objects");
} }
ReleaseMutex(_guard); ReleaseMutex(_guard);
return thrd; return thrd;
} }
VY_DLLEXPORT void vyJoinThread(vy_thread *thread) { RT_DLLEXPORT void rtJoinThread(rt_thread *thread) {
WaitForSingleObject(thread->handle, INFINITE); WaitForSingleObject(thread->handle, INFINITE);
CloseHandle(thread->handle); CloseHandle(thread->handle);
thread->needs_join = false; thread->needs_join = false;
ptrdiff_t index = thread - &_threads[0]; ptrdiff_t index = thread - &_threads[0];
if (WaitForSingleObject(_guard, INFINITE) != WAIT_OBJECT_0) { if (WaitForSingleObject(_guard, INFINITE) != WAIT_OBJECT_0) {
vyLog("core", "Failed to lock the guard variable: %u", GetLastError()); rtLog("core", "Failed to lock the guard variable: %u", GetLastError());
return; return;
} }
thread->next_reusable = _first_reusable; thread->next_reusable = _first_reusable;
@ -109,18 +109,18 @@ VY_DLLEXPORT void vyJoinThread(vy_thread *thread) {
ReleaseMutex(_guard); ReleaseMutex(_guard);
} }
VY_DLLEXPORT unsigned int vyGetCPUCoreCount(void) { RT_DLLEXPORT unsigned int rtGetCPUCoreCount(void) {
SYSTEM_INFO info; SYSTEM_INFO info;
GetSystemInfo(&info); GetSystemInfo(&info);
return (unsigned int)info.dwNumberOfProcessors; return (unsigned int)info.dwNumberOfProcessors;
} }
VY_DLLEXPORT vy_thread_id vyGetCurrentThreadId(void) { RT_DLLEXPORT rt_thread_id rtGetCurrentThreadId(void) {
return (vy_thread_id)GetCurrentThreadId(); return (rt_thread_id)GetCurrentThreadId();
} }
VY_DLLEXPORT bool vyIsMainThread(void) { RT_DLLEXPORT bool rtIsMainThread(void) {
return vyGetCurrentThreadId() == _main_thread_id; return rtGetCurrentThreadId() == _main_thread_id;
} }
#elif defined(__linux__) #elif defined(__linux__)
@ -129,33 +129,33 @@ VY_DLLEXPORT bool vyIsMainThread(void) {
#include <pthread.h> #include <pthread.h>
#include <unistd.h> #include <unistd.h>
struct vy_thread_s { struct rt_thread_s {
pthread_t handle; pthread_t handle;
ptrdiff_t next_reusable; ptrdiff_t next_reusable;
vy_thread_entry_fn *entry; rt_thread_entry_fn *entry;
void *param; void *param;
bool needs_join; bool needs_join;
}; };
#define MAX_THREADS 256 #define MAX_THREADS 256
static vy_thread _threads[MAX_THREADS]; static rt_thread _threads[MAX_THREADS];
static ptrdiff_t _first_reusable = MAX_THREADS; static ptrdiff_t _first_reusable = MAX_THREADS;
static ptrdiff_t _next = 0; static ptrdiff_t _next = 0;
static pthread_mutex_t _guard = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t _guard = PTHREAD_MUTEX_INITIALIZER;
static void *linuxThreadWrapper(void *arg) { static void *linuxThreadWrapper(void *arg) {
vy_thread *user_thread = arg; rt_thread *user_thread = arg;
user_thread->needs_join = false; user_thread->needs_join = false;
user_thread->entry(user_thread->param); user_thread->entry(user_thread->param);
user_thread->needs_join = true; user_thread->needs_join = true;
return NULL; return NULL;
} }
VY_DLLEXPORT vy_thread *vySpawnThread(vy_thread_entry_fn *entry, void *param, const char *name) { RT_DLLEXPORT rt_thread *rtSpawnThread(rt_thread_entry_fn *entry, void *param, const char *name) {
vy_thread *thrd = NULL; rt_thread *thrd = NULL;
pthread_mutex_lock(&_guard); pthread_mutex_lock(&_guard);
if (_first_reusable < MAX_THREADS) { if (_first_reusable < MAX_THREADS) {
thrd = &_threads[_first_reusable]; thrd = &_threads[_first_reusable];
@ -173,19 +173,19 @@ VY_DLLEXPORT vy_thread *vySpawnThread(vy_thread_entry_fn *entry, void *param, co
thrd->entry = entry; thrd->entry = entry;
thrd->param = param; thrd->param = param;
if (pthread_create(&thrd->handle, NULL, linuxThreadWrapper, thrd) != 0) { if (pthread_create(&thrd->handle, NULL, linuxThreadWrapper, thrd) != 0) {
vyLog("core", "Thread creation failed"); rtLog("core", "Thread creation failed");
thrd = NULL; thrd = NULL;
} }
if (thrd && name) if (thrd && name)
pthread_setname_np(thrd->handle, name); pthread_setname_np(thrd->handle, name);
} else { } else {
vyReportError("core", "Ran out of thread objects"); rtReportError("core", "Ran out of thread objects");
} }
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
return thrd; return thrd;
} }
VY_DLLEXPORT void vyJoinThread(vy_thread *thread) { RT_DLLEXPORT void rtJoinThread(rt_thread *thread) {
pthread_join(thread->handle, NULL); pthread_join(thread->handle, NULL);
thread->needs_join = false; thread->needs_join = false;
ptrdiff_t index = thread - &_threads[0]; ptrdiff_t index = thread - &_threads[0];
@ -195,17 +195,17 @@ VY_DLLEXPORT void vyJoinThread(vy_thread *thread) {
pthread_mutex_unlock(&_guard); pthread_mutex_unlock(&_guard);
} }
VY_DLLEXPORT unsigned int vyGetCPUCoreCount(void) { RT_DLLEXPORT unsigned int rtGetCPUCoreCount(void) {
int n = (int)sysconf(_SC_NPROCESSORS_ONLN); int n = (int)sysconf(_SC_NPROCESSORS_ONLN);
return (n > 0) ? (unsigned int)n : (unsigned int)sysconf(_SC_NPROCESSORS_CONF); return (n > 0) ? (unsigned int)n : (unsigned int)sysconf(_SC_NPROCESSORS_CONF);
} }
VY_DLLEXPORT vy_thread_id vyGetCurrentThreadId(void) { RT_DLLEXPORT rt_thread_id rtGetCurrentThreadId(void) {
return (vy_thread_id)GetCurrentThreadId(); return (rt_thread_id)GetCurrentThreadId();
} }
VY_DLLEXPORT bool vyIsMainThread(void) { RT_DLLEXPORT bool rtIsMainThread(void) {
return vyGetCurrentThreadId() == _main_thread_id; return rtGetCurrentThreadId() == _main_thread_id;
} }

View File

@ -1,4 +1,4 @@
#define VY_DEFINE_UIDTAB_FILE_STRUCTURES #define RT_DEFINE_UIDTAB_FILE_STRUCTURES
#include "uidtab.h" #include "uidtab.h"
#include "aio.h" #include "aio.h"
@ -10,25 +10,25 @@
#include <stdbool.h> #include <stdbool.h>
typedef struct { typedef struct {
vy_uid *uids; rt_uid *uids;
vy_uid_data *data; rt_uid_data *data;
uint32_t slots; uint32_t slots;
} vy_uidtab; } rt_uidtab;
static vy_uidtab _tab; static rt_uidtab _tab;
vy_result LoadUIDTable(void) { rt_result LoadUIDTable(void) {
/* We use stdio here, because we cannot load any asset in parallel to this. /* We use stdio here, because we cannot load any asset in parallel to this.
* This is because the uidtab is what tells us which assets exist. * This is because the uidtab is what tells us which assets exist.
*/ */
FILE *f = fopen("data/uidtab.bin", "rb"); FILE *f = fopen("data/uidtab.bin", "rb");
if (!f) if (!f)
return VY_LOAD_FAILED; return RT_LOAD_FAILED;
vy_uidtab_header header; rt_uidtab_header header;
if (fread(&header, sizeof(header), 1, f) != 1) { if (fread(&header, sizeof(header), 1, f) != 1) {
fclose(f); fclose(f);
return VY_LOAD_FAILED; return RT_LOAD_FAILED;
} }
/* TODO(Kevin): For some reason, the checksum calculation causes /* TODO(Kevin): For some reason, the checksum calculation causes
@ -36,29 +36,29 @@ vy_result LoadUIDTable(void) {
XXH3_state_t *checksum = XXH3_createState(); XXH3_state_t *checksum = XXH3_createState();
if (!checksum) { if (!checksum) {
fclose(f); fclose(f);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
*/ */
_tab.slots = vyNextPowerOfTwo32(header.num_entries * 2); _tab.slots = rtNextPowerOfTwo32(header.num_entries * 2);
void *mem = malloc((sizeof(vy_uid) + sizeof(vy_uid_data)) * _tab.slots); void *mem = malloc((sizeof(rt_uid) + sizeof(rt_uid_data)) * _tab.slots);
if (!mem) { if (!mem) {
fclose(f); fclose(f);
_tab.slots = 0; _tab.slots = 0;
return VY_OUT_OF_MEMORY; return RT_OUT_OF_MEMORY;
} }
_tab.uids = mem; _tab.uids = mem;
_tab.data = (vy_uid_data *)(_tab.uids + _tab.slots); _tab.data = (rt_uid_data *)(_tab.uids + _tab.slots);
memset(mem, 0, (sizeof(vy_uid) + sizeof(vy_uid_data)) * _tab.slots); memset(mem, 0, (sizeof(rt_uid) + sizeof(rt_uid_data)) * _tab.slots);
uint32_t mod = _tab.slots - 1; uint32_t mod = _tab.slots - 1;
for (uint32_t i = 0; i < header.num_entries; ++i) { for (uint32_t i = 0; i < header.num_entries; ++i) {
vy_uidtab_entry entry; rt_uidtab_entry entry;
if (fread(&entry, sizeof(entry), 1, f) != 1) { if (fread(&entry, sizeof(entry), 1, f) != 1) {
free(mem); free(mem);
_tab.slots = 0; _tab.slots = 0;
fclose(f); fclose(f);
return VY_LOAD_FAILED; return RT_LOAD_FAILED;
} }
//XXH3_64bits_update(checksum, &entry, sizeof(entry)); //XXH3_64bits_update(checksum, &entry, sizeof(entry));
@ -66,7 +66,7 @@ vy_result LoadUIDTable(void) {
bool inserted = false; bool inserted = false;
for (uint32_t j = 0; j < _tab.slots; ++j) { for (uint32_t j = 0; j < _tab.slots; ++j) {
uint32_t at = (entry.uid + j) & mod; uint32_t at = (entry.uid + j) & mod;
if (_tab.uids[at] == VY_INVALID_UID) { if (_tab.uids[at] == RT_INVALID_UID) {
_tab.uids[at] = entry.uid; _tab.uids[at] = entry.uid;
_tab.data[at].pkg_file = entry.file; _tab.data[at].pkg_file = entry.file;
_tab.data[at].size = entry.size; _tab.data[at].size = entry.size;
@ -77,12 +77,12 @@ vy_result LoadUIDTable(void) {
} }
} }
if (!inserted) { if (!inserted) {
vyReportError("core", rtReportError("core",
"Failed to insert an entry into the uid table. This should not happen."); "Failed to insert an entry into the uid table. This should not happen.");
fclose(f); fclose(f);
free(mem); free(mem);
_tab.slots = 0; _tab.slots = 0;
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
} }
@ -94,12 +94,12 @@ vy_result LoadUIDTable(void) {
XXH3_freeState(checksum); XXH3_freeState(checksum);
if (checksum_hash != file_hash) { if (checksum_hash != file_hash) {
vyLog("core", rtLog("core",
"WARNING: uidtab.bin checksum does not match calculated checksum of loaded entries."); "WARNING: uidtab.bin checksum does not match calculated checksum of loaded entries.");
} }
*/ */
return VY_SUCCESS; return RT_SUCCESS;
} }
void ReleaseUIDTable(void) { void ReleaseUIDTable(void) {
@ -107,13 +107,13 @@ void ReleaseUIDTable(void) {
_tab.slots = 0; _tab.slots = 0;
} }
VY_DLLEXPORT const vy_uid_data *vyGetUIDData(vy_uid uid) { RT_DLLEXPORT const rt_uid_data *rtGetUIDData(rt_uid uid) {
uint32_t mod = _tab.slots - 1; uint32_t mod = _tab.slots - 1;
for (uint32_t j = 0; j < _tab.slots; ++j) { for (uint32_t j = 0; j < _tab.slots; ++j) {
uint32_t at = (uid + j) & mod; uint32_t at = (uid + j) & mod;
if (_tab.uids[at] == uid) { if (_tab.uids[at] == uid) {
return &_tab.data[at]; return &_tab.data[at];
} else if (_tab.uids[at] == VY_INVALID_UID) { } else if (_tab.uids[at] == RT_INVALID_UID) {
break; break;
} }
} }

View File

@ -1,36 +1,36 @@
#ifndef VY_UIDTAB_H #ifndef RT_UIDTAB_H
#define VY_UIDTAB_H #define RT_UIDTAB_H
#include "runtime.h" #include "runtime.h"
#include "file_tab.h" #include "file_tab.h"
#include "assets.h" #include "assets.h"
#include "xxhash/xxhash.h" #include "xxhash/xxhash.h"
#ifdef VY_DEFINE_UIDTAB_FILE_STRUCTURES #ifdef RT_DEFINE_UIDTAB_FILE_STRUCTURES
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct { typedef struct {
XXH64_canonical_t checksum; XXH64_canonical_t checksum;
uint32_t num_entries; uint32_t num_entries;
} vy_uidtab_header; } rt_uidtab_header;
#pragma pack(pop) #pragma pack(pop)
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct { typedef struct {
vy_file_id file; rt_file_id file;
uint64_t offset; uint64_t offset;
uint64_t size; uint64_t size;
vy_uid uid; rt_uid uid;
} vy_uidtab_entry; } rt_uidtab_entry;
#pragma pack(pop) #pragma pack(pop)
#endif #endif
/* Data associated with an uid */ /* Data associated with an uid */
typedef struct { typedef struct {
vy_file_id pkg_file; rt_file_id pkg_file;
uint64_t offset; uint64_t offset;
uint64_t size; uint64_t size;
} vy_uid_data; } rt_uid_data;
VY_DLLEXPORT const vy_uid_data *vyGetUIDData(vy_uid uid); RT_DLLEXPORT const rt_uid_data *rtGetUIDData(rt_uid uid);
#endif #endif

View File

@ -3,38 +3,38 @@
#include "runtime/runtime.h" #include "runtime/runtime.h"
/* Check basic relative pointer behaviour */ /* Check basic relative pointer behaviour */
static vy_result RelPtrTest(void) { static rt_result RelPtrTest(void) {
char buf[sizeof(vy_relptr) + sizeof(unsigned int)]; char buf[sizeof(rt_relptr) + sizeof(unsigned int)];
vy_relptr *ptr = (vy_relptr *)buf; rt_relptr *ptr = (rt_relptr *)buf;
unsigned int *target = (unsigned int *)&buf[sizeof(vy_relptr)]; unsigned int *target = (unsigned int *)&buf[sizeof(rt_relptr)];
*target = 42; *target = 42;
vySetRelptr(ptr, target); rtSetRelptr(ptr, target);
void *resolved = vyResolveRelptr(ptr); void *resolved = rtResolveRelptr(ptr);
if ((uintptr_t)resolved != (uintptr_t)target) if ((uintptr_t)resolved != (uintptr_t)target)
return 1; return 1;
if (*(unsigned int *)resolved != *target) if (*(unsigned int *)resolved != *target)
return 2; return 2;
return VY_SUCCESS; return RT_SUCCESS;
} }
static vy_result NegRelPtrTest(void) { static rt_result NegRelPtrTest(void) {
char buf[sizeof(unsigned int) + sizeof(vy_relptr)]; char buf[sizeof(unsigned int) + sizeof(rt_relptr)];
unsigned int *target = (unsigned int *)buf; unsigned int *target = (unsigned int *)buf;
vy_relptr *ptr = (vy_relptr *)&buf[sizeof(unsigned int)]; rt_relptr *ptr = (rt_relptr *)&buf[sizeof(unsigned int)];
*target = 42; *target = 42;
vySetRelptr(ptr, target); rtSetRelptr(ptr, target);
void *resolved = vyResolveRelptr(ptr); void *resolved = rtResolveRelptr(ptr);
if ((uintptr_t)resolved != (uintptr_t)target) if ((uintptr_t)resolved != (uintptr_t)target)
return 1; return 1;
if (*(unsigned int *)resolved != *target) if (*(unsigned int *)resolved != *target)
return 2; return 2;
return VY_SUCCESS; return RT_SUCCESS;
} }
/* Scaffolding /* Scaffolding
@ -42,25 +42,25 @@ static vy_result NegRelPtrTest(void) {
* Run all the test cases, output if they passed or failed. * Run all the test cases, output if they passed or failed.
*/ */
typedef vy_result vy_test_fnc(void); typedef rt_result rt_test_fnc(void);
typedef struct { typedef struct {
const char *name; const char *name;
vy_test_fnc *fnc; rt_test_fnc *fnc;
} vy_test_case; } rt_test_case;
#define TEST_CASE(fn) { .name = #fn, .fnc = fn, } #define TEST_CASE(fn) { .name = #fn, .fnc = fn, }
static vy_test_case _test_cases[] = {TEST_CASE(RelPtrTest), TEST_CASE(NegRelPtrTest)}; static rt_test_case _test_cases[] = {TEST_CASE(RelPtrTest), TEST_CASE(NegRelPtrTest)};
int main() { int main() {
int out = 0; int out = 0;
for (size_t i = 0; i < VY_ARRAY_COUNT(_test_cases); ++i) { for (size_t i = 0; i < RT_ARRAY_COUNT(_test_cases); ++i) {
printf("[%s] ... ", _test_cases[i].name); printf("[%s] ... ", _test_cases[i].name);
vy_result res = _test_cases[i].fnc(); rt_result res = _test_cases[i].fnc();
if (res == VY_SUCCESS) { if (res == RT_SUCCESS) {
printf("OK\n"); printf("OK\n");
} }
else { else {

View File

@ -4,7 +4,7 @@
#include "packages.h" #include "packages.h"
#include "dependency_tracking.h" #include "dependency_tracking.h"
#define VY_ASSETC_DONT_DEFINE_OPTIONS_GLOBAL #define RT_ASSETC_DONT_DEFINE_OPTIONS_GLOBAL
#include "options.h" #include "options.h"
#include "runtime/aio.h" #include "runtime/aio.h"
@ -15,24 +15,24 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
extern vy_result vyProcessPipelineFile(vy_file_id file, extern rt_result rtProcessPipelineFile(rt_file_id file,
void *buffer, void *buffer,
size_t size, size_t size,
uint32_t flags, uint32_t flags,
vy_processor_output *output); rt_processor_output *output);
extern vy_result vyProcessShaderFile(vy_file_id file, extern rt_result rtProcessShaderFile(rt_file_id file,
void *buffer, void *buffer,
size_t size, size_t size,
uint32_t flags, uint32_t flags,
vy_processor_output *output); rt_processor_output *output);
extern void vyDiscoverAssets(void); extern void rtDiscoverAssets(void);
vy_assetc_options g_assetc_options = { rt_assetc_options g_assetc_options = {
.root_directory = ".", .root_directory = ".",
.optimization = VY_ASSET_OPTIMIZATION_NONE, .optimization = RT_ASSET_OPTIMIZATION_NONE,
.renderer_backend = VY_RENDERER_BACKEND_CODE_VK, .renderer_backend = RT_RENDERER_BACKEND_CODE_VK,
}; };
static bool ParseCommandLineArgs(int argc, char **argv) { static bool ParseCommandLineArgs(int argc, char **argv) {
@ -44,9 +44,9 @@ static bool ParseCommandLineArgs(int argc, char **argv) {
if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--renderer") == 0) { if (strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--renderer") == 0) {
if (strcmp(val, "vk") == 0) { if (strcmp(val, "vk") == 0) {
g_assetc_options.renderer_backend = VY_RENDERER_BACKEND_CODE_VK; g_assetc_options.renderer_backend = RT_RENDERER_BACKEND_CODE_VK;
} else { } else {
vyReportError("ASSETC", rtReportError("ASSETC",
"Invalid render backend %s. Valid options are: vk", "Invalid render backend %s. Valid options are: vk",
val); val);
return false; return false;
@ -54,13 +54,13 @@ static bool ParseCommandLineArgs(int argc, char **argv) {
matched = true; matched = true;
} else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--optimization") == 0) { } else if (strcmp(argv[i], "-o") == 0 || strcmp(argv[i], "--optimization") == 0) {
if (strcmp(val, "none") == 0) { if (strcmp(val, "none") == 0) {
g_assetc_options.optimization = VY_ASSET_OPTIMIZATION_NONE; g_assetc_options.optimization = RT_ASSET_OPTIMIZATION_NONE;
} else if (strcmp(val, "space") == 0) { } else if (strcmp(val, "space") == 0) {
g_assetc_options.optimization = VY_ASSET_OPTIMIZATION_SPACE; g_assetc_options.optimization = RT_ASSET_OPTIMIZATION_SPACE;
} else if (strcmp(val, "performance") == 0) { } else if (strcmp(val, "performance") == 0) {
g_assetc_options.optimization = VY_ASSET_OPTIMIZATION_PERFORMANCE; g_assetc_options.optimization = RT_ASSET_OPTIMIZATION_PERFORMANCE;
} else { } else {
vyReportError("ASSETC", rtReportError("ASSETC",
"Invalid optimization level %s. Valid options are: none, space, " "Invalid optimization level %s. Valid options are: none, space, "
"performance", "performance",
val); val);
@ -68,7 +68,7 @@ static bool ParseCommandLineArgs(int argc, char **argv) {
} }
matched = true; matched = true;
} else if (argv[i][0] == '-') { } else if (argv[i][0] == '-') {
vyReportError("ASSETC", "Invalid command line argument %s", argv[i]); rtReportError("ASSETC", "Invalid command line argument %s", argv[i]);
return false; return false;
} }
@ -83,7 +83,7 @@ static bool ParseCommandLineArgs(int argc, char **argv) {
g_assetc_options.root_directory = argv[i]; g_assetc_options.root_directory = argv[i];
} else { } else {
/* Maybe have secondary directories later? */ /* Maybe have secondary directories later? */
vyReportError("ASSETC", rtReportError("ASSETC",
"More than one root directory passed as command line " "More than one root directory passed as command line "
"argument."); "argument.");
return false; return false;
@ -93,57 +93,57 @@ static bool ParseCommandLineArgs(int argc, char **argv) {
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
vyInitRuntime(); rtInitRuntime();
/* Init assetc */ /* Init assetc */
if (!ParseCommandLineArgs(argc, argv)) { if (!ParseCommandLineArgs(argc, argv)) {
return 1; return 1;
} }
vyInitPackages(); rtInitPackages();
if (vyLoadAssetMeta() != VY_SUCCESS) { if (rtLoadAssetMeta() != RT_SUCCESS) {
return 1; return 1;
} }
if (vyInitDependencyTracking() != VY_SUCCESS) { if (rtInitDependencyTracking() != RT_SUCCESS) {
return 1; return 1;
} }
if (vyAddAssetProcessor(".pipeline", vyProcessPipelineFile) != VY_SUCCESS) if (rtAddAssetProcessor(".pipeline", rtProcessPipelineFile) != RT_SUCCESS)
return 1; return 1;
if (vyAddAssetProcessor(".glsl", vyProcessShaderFile) != VY_SUCCESS) if (rtAddAssetProcessor(".glsl", rtProcessShaderFile) != RT_SUCCESS)
return 1; return 1;
if (vyStartProcessing() != VY_SUCCESS) { if (rtStartProcessing() != RT_SUCCESS) {
return 1; return 1;
} }
/* Create necessary directories */ /* Create necessary directories */
vySetWorkingDirectory(g_assetc_options.root_directory); rtSetWorkingDirectory(g_assetc_options.root_directory);
vyCreateDirectory("assets"); rtCreateDirectory("assets");
vyCreateDirectory("actemp"); rtCreateDirectory("actemp");
vyCreateDirectory("data"); rtCreateDirectory("data");
/* "Mainloop" */ /* "Mainloop" */
vyDiscoverAssets(); rtDiscoverAssets();
vyWaitUntilProcessingIsFinished(); rtWaitUntilProcessingIsFinished();
vyStopProcessing(); rtStopProcessing();
/* Write result */ /* Write result */
vySaveAssetMeta(); rtSaveAssetMeta();
if (vySavePackages() != VY_SUCCESS) { if (rtSavePackages() != RT_SUCCESS) {
return 1; return 1;
} }
if (vyWriteUIDTab() != VY_SUCCESS) { if (rtWriteUIDTab() != RT_SUCCESS) {
return 1; return 1;
} }
if (vySaveAssetDependencies() != VY_SUCCESS) { if (rtSaveAssetDependencies() != RT_SUCCESS) {
return 1; return 1;
} }
vyShutdownRuntime(); rtShutdownRuntime();
return 0; return 0;
} }

View File

@ -12,113 +12,113 @@
#define MAP_SIZE 2048 #define MAP_SIZE 2048
typedef struct { typedef struct {
vy_file_id fids[MAP_SIZE]; rt_file_id fids[MAP_SIZE];
vy_uid uids[MAP_SIZE]; rt_uid uids[MAP_SIZE];
vy_assetmeta meta[MAP_SIZE]; rt_assetmeta meta[MAP_SIZE];
unsigned int used_slots; unsigned int used_slots;
} vy_uid_map; } rt_uid_map;
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct { typedef struct {
XXH64_canonical_t checksum; XXH64_canonical_t checksum;
uint32_t num_entries; uint32_t num_entries;
uint32_t _reserved; uint32_t _reserved;
} vy_assetmeta_header; } rt_assetmeta_header;
#pragma pack(pop) #pragma pack(pop)
#pragma pack(push, 1) #pragma pack(push, 1)
typedef struct { typedef struct {
vy_uid uid; rt_uid uid;
vy_file_id source_file; rt_file_id source_file;
vy_assetmeta meta; rt_assetmeta meta;
} vy_assetmeta_entry; } rt_assetmeta_entry;
#pragma pack(pop) #pragma pack(pop)
static vy_uid_map _map; static rt_uid_map _map;
static vy_mutex *_guard; static rt_mutex *_guard;
vy_result vyLoadAssetMeta(void) { rt_result rtLoadAssetMeta(void) {
_guard = vyCreateMutex(); _guard = rtCreateMutex();
/* Load the meta file */ /* Load the meta file */
size_t fsz = vyGetFileSize("actemp/meta.bin"); size_t fsz = rtGetFileSize("actemp/meta.bin");
if (fsz == 0) { if (fsz == 0) {
vyLog("ASSETC", "Metadata file 'meta.bin' not found. All assets will be processed."); rtLog("ASSETC", "Metadata file 'meta.bin' not found. All assets will be processed.");
return VY_SUCCESS; return RT_SUCCESS;
} }
void *buffer = vyAllocBuffer(fsz); void *buffer = rtAllocBuffer(fsz);
if (!buffer) { if (!buffer) {
vyReportError("ASSETC", "Failed to allocate buffer for holding asset metadata."); rtReportError("ASSETC", "Failed to allocate buffer for holding asset metadata.");
return 1; return 1;
} }
vy_load_batch load; rt_load_batch load;
load.loads[0].dest = buffer; load.loads[0].dest = buffer;
load.loads[0].file = vyAddFile("actemp/meta.bin"); load.loads[0].file = rtAddFile("actemp/meta.bin");
load.loads[0].num_bytes = fsz; load.loads[0].num_bytes = fsz;
load.loads[0].offset = 0; load.loads[0].offset = 0;
load.num_loads = 1; load.num_loads = 1;
vy_aio_handle handle; rt_aio_handle handle;
if (vySubmitLoadBatch(&load, &handle) != VY_SUCCESS) { if (rtSubmitLoadBatch(&load, &handle) != RT_SUCCESS) {
vyReportError("ASSETC", "Failed to submit load of 'meta.bin'."); rtReportError("ASSETC", "Failed to submit load of 'meta.bin'.");
vyReleaseBuffer(buffer, fsz); rtReleaseBuffer(buffer, fsz);
return 1; return 1;
} }
if (vyWaitForAIOCompletion(handle) != VY_AIO_STATE_FINISHED) { if (rtWaitForAIOCompletion(handle) != RT_AIO_STATE_FINISHED) {
vyReportError("ASSETC", "Failed to load 'meta.bin'."); rtReportError("ASSETC", "Failed to load 'meta.bin'.");
vyReleaseBuffer(buffer, fsz); rtReleaseBuffer(buffer, fsz);
vyReleaseAIO(handle); rtReleaseAIO(handle);
return 1; return 1;
} }
vyReleaseAIO(handle); rtReleaseAIO(handle);
const vy_assetmeta_header *header = buffer; const rt_assetmeta_header *header = buffer;
const vy_assetmeta_entry *entries = (vy_assetmeta_entry *)(header + 1); const rt_assetmeta_entry *entries = (rt_assetmeta_entry *)(header + 1);
if ((sizeof(vy_assetmeta_entry) * header->num_entries + sizeof(*header)) > fsz) { if ((sizeof(rt_assetmeta_entry) * header->num_entries + sizeof(*header)) > fsz) {
vyReportError("ASSETC", "Header of 'meta.bin' is corrupted: Mismatched num_entries and filesize."); rtReportError("ASSETC", "Header of 'meta.bin' is corrupted: Mismatched num_entries and filesize.");
vyReleaseBuffer(buffer, fsz); rtReleaseBuffer(buffer, fsz);
return 1; return 1;
} }
XXH64_hash_t hash = XXH3_64bits(entries, sizeof(vy_assetmeta_entry) * header->num_entries); XXH64_hash_t hash = XXH3_64bits(entries, sizeof(rt_assetmeta_entry) * header->num_entries);
XXH64_hash_t header_hash = XXH64_hashFromCanonical(&header->checksum); XXH64_hash_t header_hash = XXH64_hashFromCanonical(&header->checksum);
if (hash != header_hash) { if (hash != header_hash) {
vyReportError("ASSETC", rtReportError("ASSETC",
"Metadata file 'meta.bin' is corrupted: Wrong checksum."); "Metadata file 'meta.bin' is corrupted: Wrong checksum.");
vyReleaseBuffer(buffer, fsz); rtReleaseBuffer(buffer, fsz);
return 1; return 1;
} }
for (uint32_t i = 0; i < header->num_entries; ++i) { for (uint32_t i = 0; i < header->num_entries; ++i) {
/* Load here to avoid unaligned pointer */ /* Load here to avoid unaligned pointer */
vy_assetmeta meta = entries[i].meta; rt_assetmeta meta = entries[i].meta;
vyAddUIDMapping(entries[i].source_file, entries[i].uid, &meta); rtAddUIDMapping(entries[i].source_file, entries[i].uid, &meta);
} }
vyReleaseBuffer(buffer, fsz); rtReleaseBuffer(buffer, fsz);
return 0; return 0;
} }
vy_result vySaveAssetMeta(void) { rt_result rtSaveAssetMeta(void) {
vy_assetmeta_header header = {0}; rt_assetmeta_header header = {0};
/* Count number of entries */ /* Count number of entries */
for (size_t i = 0; i < MAP_SIZE; ++i) { for (size_t i = 0; i < MAP_SIZE; ++i) {
if (_map.fids[i] != VY_INVALID_FILE_ID) if (_map.fids[i] != RT_INVALID_FILE_ID)
header.num_entries += 1; header.num_entries += 1;
} }
vy_assetmeta_entry *entries = vyAllocBuffer(sizeof(vy_assetmeta_entry) * header.num_entries); rt_assetmeta_entry *entries = rtAllocBuffer(sizeof(rt_assetmeta_entry) * header.num_entries);
if (!entries) if (!entries)
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
/* Store entries */ /* Store entries */
size_t j = 0; size_t j = 0;
for (size_t i = 0; i < MAP_SIZE; ++i) { for (size_t i = 0; i < MAP_SIZE; ++i) {
if (_map.fids[i] != VY_INVALID_FILE_ID) { if (_map.fids[i] != RT_INVALID_FILE_ID) {
entries[j].source_file = _map.fids[i]; entries[j].source_file = _map.fids[i];
entries[j].uid = _map.uids[i]; entries[j].uid = _map.uids[i];
entries[j].meta = _map.meta[i]; entries[j].meta = _map.meta[i];
@ -126,52 +126,52 @@ vy_result vySaveAssetMeta(void) {
} }
} }
XXH64_hash_t hash = XXH3_64bits(entries, sizeof(vy_assetmeta_entry) * header.num_entries); XXH64_hash_t hash = XXH3_64bits(entries, sizeof(rt_assetmeta_entry) * header.num_entries);
XXH64_canonicalFromHash(&header.checksum, hash); XXH64_canonicalFromHash(&header.checksum, hash);
header._reserved = 0; header._reserved = 0;
FILE *f = fopen("actemp/meta.bin", "wb"); FILE *f = fopen("actemp/meta.bin", "wb");
if (!f) { if (!f) {
vyReportError("ASSETC", "Failed to open 'meta.bin'"); rtReportError("ASSETC", "Failed to open 'meta.bin'");
vyReleaseBuffer(entries, sizeof(vy_assetmeta_entry) * header.num_entries); rtReleaseBuffer(entries, sizeof(rt_assetmeta_entry) * header.num_entries);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
if (fwrite(&header, sizeof(header), 1, f) != 1) { if (fwrite(&header, sizeof(header), 1, f) != 1) {
vyReportError("ASSETC", "Failed to write 'meta.bin'"); rtReportError("ASSETC", "Failed to write 'meta.bin'");
vyReleaseBuffer(entries, sizeof(vy_assetmeta_entry) * header.num_entries); rtReleaseBuffer(entries, sizeof(rt_assetmeta_entry) * header.num_entries);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
if (fwrite(entries, sizeof(vy_assetmeta_entry), header.num_entries, f) != header.num_entries) { if (fwrite(entries, sizeof(rt_assetmeta_entry), header.num_entries, f) != header.num_entries) {
vyReportError("ASSETC", "Failed to write 'meta.bin'"); rtReportError("ASSETC", "Failed to write 'meta.bin'");
vyReleaseBuffer(entries, sizeof(vy_assetmeta_entry) * header.num_entries); rtReleaseBuffer(entries, sizeof(rt_assetmeta_entry) * header.num_entries);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
fclose(f); fclose(f);
return VY_SUCCESS; return RT_SUCCESS;
} }
vy_uid vyLookupUID(vy_file_id fid) { rt_uid rtLookupUID(rt_file_id fid) {
vyLockMutex(_guard); rtLockMutex(_guard);
unsigned int i = 0; unsigned int i = 0;
vy_uid result = VY_INVALID_UID; rt_uid result = RT_INVALID_UID;
while (i < MAP_SIZE) { while (i < MAP_SIZE) {
unsigned int slot = (fid + i) % MAP_SIZE; unsigned int slot = (fid + i) % MAP_SIZE;
if (_map.fids[slot] == fid) { if (_map.fids[slot] == fid) {
result = _map.uids[slot]; result = _map.uids[slot];
break; break;
} else if (_map.fids[slot] == VY_INVALID_FILE_ID) { } else if (_map.fids[slot] == RT_INVALID_FILE_ID) {
break; break;
} }
++i; ++i;
} }
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return result; return result;
} }
bool vyGetAssetMeta(vy_file_id source_file, vy_assetmeta *meta) { bool rtGetAssetMeta(rt_file_id source_file, rt_assetmeta *meta) {
vyLockMutex(_guard); rtLockMutex(_guard);
unsigned int i = 0; unsigned int i = 0;
bool result = false; bool result = false;
while (i < MAP_SIZE) { while (i < MAP_SIZE) {
@ -180,25 +180,25 @@ bool vyGetAssetMeta(vy_file_id source_file, vy_assetmeta *meta) {
*meta = _map.meta[slot]; *meta = _map.meta[slot];
result = true; result = true;
break; break;
} else if (_map.fids[slot] == VY_INVALID_FILE_ID) { } else if (_map.fids[slot] == RT_INVALID_FILE_ID) {
break; break;
} }
++i; ++i;
} }
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return result; return result;
} }
void vyAddUIDMapping(vy_file_id fid, vy_uid uid, const vy_assetmeta *meta) { void rtAddUIDMapping(rt_file_id fid, rt_uid uid, const rt_assetmeta *meta) {
vyLockMutex(_guard); rtLockMutex(_guard);
float fill_rate = (float)_map.used_slots / MAP_SIZE; float fill_rate = (float)_map.used_slots / MAP_SIZE;
if (fill_rate >= .5f) { if (fill_rate >= .5f) {
vyLog("ASSETC", "UID map is above 50% filled."); rtLog("ASSETC", "UID map is above 50% filled.");
} }
unsigned int i = 0; unsigned int i = 0;
while (i < MAP_SIZE) { while (i < MAP_SIZE) {
unsigned int slot = (fid + i) % MAP_SIZE; unsigned int slot = (fid + i) % MAP_SIZE;
if (_map.fids[slot] == VY_INVALID_FILE_ID) { if (_map.fids[slot] == RT_INVALID_FILE_ID) {
_map.fids[slot] = fid; _map.fids[slot] = fid;
_map.uids[slot] = uid; _map.uids[slot] = uid;
if (meta) { if (meta) {
@ -216,7 +216,7 @@ void vyAddUIDMapping(vy_file_id fid, vy_uid uid, const vy_assetmeta *meta) {
++i; ++i;
} }
if (i == MAP_SIZE) { if (i == MAP_SIZE) {
vyReportError("ASSETC", "Failed to insert entry into UID map."); rtReportError("ASSETC", "Failed to insert entry into UID map.");
} }
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
} }

View File

@ -1,5 +1,5 @@
#ifndef VY_ASSETC_ASSETMETA_H #ifndef RT_ASSETC_ASSETMETA_H
#define VY_ASSETC_ASSETMETA_H #define RT_ASSETC_ASSETMETA_H
#include "runtime/file_tab.h" #include "runtime/file_tab.h"
#include "runtime/assets.h" #include "runtime/assets.h"
@ -11,18 +11,18 @@ typedef struct {
uint64_t last_changed; uint64_t last_changed;
uint64_t compiled_ts; uint64_t compiled_ts;
uint32_t processing_flags; uint32_t processing_flags;
} vy_assetmeta; } rt_assetmeta;
vy_result vyLoadAssetMeta(void); rt_result rtLoadAssetMeta(void);
vy_result vySaveAssetMeta(void); rt_result rtSaveAssetMeta(void);
/* The UID map associates processed files with generated asset uids. */ /* The UID map associates processed files with generated asset uids. */
void vyAddUIDMapping(vy_file_id fid, vy_uid uid, const vy_assetmeta *meta); void rtAddUIDMapping(rt_file_id fid, rt_uid uid, const rt_assetmeta *meta);
/* Returns true if the asset is found. false otherwise */ /* Returns true if the asset is found. false otherwise */
bool vyGetAssetMeta(vy_file_id source_file, vy_assetmeta *meta); bool rtGetAssetMeta(rt_file_id source_file, rt_assetmeta *meta);
vy_uid vyLookupUID(vy_file_id fid); rt_uid rtLookupUID(rt_file_id fid);
#endif #endif

View File

@ -10,15 +10,15 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
vy_result vyParseAssetSettings(const char *text, rt_result rtParseAssetSettings(const char *text,
size_t length, size_t length,
const char *file_path, const char *file_path,
vy_asset_settings *settings) { rt_asset_settings *settings) {
unsigned int root_list; unsigned int root_list;
vy_parse_state state; rt_parse_state state;
vy_result res = vyParseDescription(text, length, file_path, &root_list, &state); rt_result res = rtParseDescription(text, length, file_path, &root_list, &state);
if (res != VY_SUCCESS) { if (res != RT_SUCCESS) {
vyReportError("ASSETC", "Failed to parse asset settings: %s", file_path); rtReportError("ASSETC", "Failed to parse asset settings: %s", file_path);
return res; return res;
} }
@ -27,66 +27,66 @@ vy_result vyParseAssetSettings(const char *text,
settings->processing_flags = 0; settings->processing_flags = 0;
settings->reprocess_on_dependency_change = false; settings->reprocess_on_dependency_change = false;
const vy_parsed_stmt *package_stmt = vyFindStatement(&state, root_list, "package"); const rt_parsed_stmt *package_stmt = rtFindStatement(&state, root_list, "package");
if (package_stmt) { if (package_stmt) {
if (package_stmt->form != VY_STMT_FORM_VALUE) { if (package_stmt->form != RT_STMT_FORM_VALUE) {
vyReportError("ASSETC", rtReportError("ASSETC",
"Expected a package name as the value of 'package' in %s.", "Expected a package name as the value of 'package' in %s.",
file_path); file_path);
res = VY_UNKNOWN_ERROR; res = RT_UNKNOWN_ERROR;
goto out; goto out;
} }
settings->package = vyAddPackageFile(package_stmt->value); settings->package = rtAddPackageFile(package_stmt->value);
} }
const vy_parsed_stmt *flags_stmt = vyFindStatement(&state, root_list, "processing_flags"); const rt_parsed_stmt *flags_stmt = rtFindStatement(&state, root_list, "processing_flags");
if (flags_stmt) { if (flags_stmt) {
if (flags_stmt->form != VY_STMT_FORM_VALUE) { if (flags_stmt->form != RT_STMT_FORM_VALUE) {
vyReportError("ASSETC", rtReportError("ASSETC",
"Expected a hexadecimal number as the value of 'processing_flags' in %s.", "Expected a hexadecimal number as the value of 'processing_flags' in %s.",
file_path); file_path);
res = VY_UNKNOWN_ERROR; res = RT_UNKNOWN_ERROR;
goto out; goto out;
} }
sscanf(flags_stmt->value.start, "%x", &settings->processing_flags); sscanf(flags_stmt->value.start, "%x", &settings->processing_flags);
} }
const vy_parsed_stmt *reprocess_stmt = const rt_parsed_stmt *reprocess_stmt =
vyFindStatement(&state, root_list, "reprocess_on_dependency_change"); rtFindStatement(&state, root_list, "reprocess_on_dependency_change");
if (reprocess_stmt) { if (reprocess_stmt) {
if (reprocess_stmt->form != VY_STMT_FORM_VALUE) { if (reprocess_stmt->form != RT_STMT_FORM_VALUE) {
vyReportError("ASSETC", rtReportError("ASSETC",
"Expected either 'true' or 'false' as the value of 'reprocess_on_dependency_change' in %s.", "Expected either 'true' or 'false' as the value of 'reprocess_on_dependency_change' in %s.",
file_path); file_path);
res = VY_UNKNOWN_ERROR; res = RT_UNKNOWN_ERROR;
goto out; goto out;
} }
if (vyCompareSpanToString(reprocess_stmt->value, "true") == 0) if (rtCompareSpanToString(reprocess_stmt->value, "true") == 0)
settings->reprocess_on_dependency_change = true; settings->reprocess_on_dependency_change = true;
else if (vyCompareSpanToString(reprocess_stmt->value, "false") == 0) else if (rtCompareSpanToString(reprocess_stmt->value, "false") == 0)
settings->reprocess_on_dependency_change = false; settings->reprocess_on_dependency_change = false;
else { else {
vyReportError("ASSETC", rtReportError("ASSETC",
"Expected either 'true' or 'false' as the value of " "Expected either 'true' or 'false' as the value of "
"'reprocess_on_dependency_change' in %s.", "'reprocess_on_dependency_change' in %s.",
file_path); file_path);
res = VY_UNKNOWN_ERROR; res = RT_UNKNOWN_ERROR;
goto out; goto out;
} }
} }
out: out:
vyReleaseParseState(&state); rtReleaseParseState(&state);
return res; return res;
} }
vy_result vyLoadAssetSettings(const char *asset_path, vy_asset_settings *settings) { rt_result rtLoadAssetSettings(const char *asset_path, rt_asset_settings *settings) {
size_t path_len = strlen(asset_path); size_t path_len = strlen(asset_path);
char *as_path = malloc(path_len + 3); char *as_path = malloc(path_len + 3);
if (!as_path) { if (!as_path) {
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
memcpy(as_path, asset_path, path_len); memcpy(as_path, asset_path, path_len);
@ -98,47 +98,47 @@ vy_result vyLoadAssetSettings(const char *asset_path, vy_asset_settings *setting
} }
strcpy(&as_path[path_len - ext_len], ".as"); strcpy(&as_path[path_len - ext_len], ".as");
size_t as_size = vyGetFileSize(as_path); size_t as_size = rtGetFileSize(as_path);
if (as_size == 0) { if (as_size == 0) {
vyReportError("ASSETC", "Failed to retrieve size of setting file %s", as_path); rtReportError("ASSETC", "Failed to retrieve size of setting file %s", as_path);
free(as_path); free(as_path);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
void *as_buffer = vyAllocBuffer(as_size); void *as_buffer = rtAllocBuffer(as_size);
vy_load_batch as_load; rt_load_batch as_load;
as_load.loads[0].file = vyAddFile(as_path); as_load.loads[0].file = rtAddFile(as_path);
as_load.loads[0].num_bytes = as_size; as_load.loads[0].num_bytes = as_size;
as_load.loads[0].dest = as_buffer; as_load.loads[0].dest = as_buffer;
if (!as_load.loads[0].dest) { if (!as_load.loads[0].dest) {
vyReportError("ASSETC", "Failed to allocate buffer for setting file %s", as_path); rtReportError("ASSETC", "Failed to allocate buffer for setting file %s", as_path);
free(as_path); free(as_path);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
as_load.loads[0].offset = 0; as_load.loads[0].offset = 0;
as_load.num_loads = 1; as_load.num_loads = 1;
vy_aio_handle as_handle; rt_aio_handle as_handle;
if (vySubmitLoadBatch(&as_load, &as_handle) != VY_SUCCESS) { if (rtSubmitLoadBatch(&as_load, &as_handle) != RT_SUCCESS) {
vyReportError("ASSETC", "Failed to submit load of setting file %s", as_path); rtReportError("ASSETC", "Failed to submit load of setting file %s", as_path);
free(as_path); free(as_path);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
if (vyWaitForAIOCompletion(as_handle) != VY_AIO_STATE_FINISHED) { if (rtWaitForAIOCompletion(as_handle) != RT_AIO_STATE_FINISHED) {
vyReportError("ASSETC", "Failed to load setting file %s", as_path); rtReportError("ASSETC", "Failed to load setting file %s", as_path);
free(as_path); free(as_path);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
vyReleaseAIO(as_handle); rtReleaseAIO(as_handle);
if (vyParseAssetSettings(as_buffer, as_size, as_path, settings) != VY_SUCCESS) { if (rtParseAssetSettings(as_buffer, as_size, as_path, settings) != RT_SUCCESS) {
free(as_path); free(as_path);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
free(as_path); free(as_path);
return VY_SUCCESS; return RT_SUCCESS;
} }

View File

@ -1,5 +1,5 @@
#ifndef VY_ASSETC_ASSETSETTINGS_H #ifndef RT_ASSETC_ASSETSETTINGS_H
#define VY_ASSETC_ASSETSETTINGS_H #define RT_ASSETC_ASSETSETTINGS_H
#include "runtime/runtime.h" #include "runtime/runtime.h"
#include <stdbool.h> #include <stdbool.h>
@ -8,14 +8,14 @@ typedef struct {
unsigned int package; unsigned int package;
uint32_t processing_flags; uint32_t processing_flags;
bool reprocess_on_dependency_change; bool reprocess_on_dependency_change;
} vy_asset_settings; } rt_asset_settings;
vy_result vyParseAssetSettings(const char *text, rt_result rtParseAssetSettings(const char *text,
size_t length, size_t length,
const char *file_path, const char *file_path,
vy_asset_settings *settings); rt_asset_settings *settings);
vy_result vyLoadAssetSettings(const char *asset_path, vy_asset_settings *settings); rt_result rtLoadAssetSettings(const char *asset_path, rt_asset_settings *settings);
#endif #endif

View File

@ -1,13 +1,13 @@
#ifndef VY_ASSETC_COMPILED_H #ifndef RT_ASSETC_COMPILED_H
#define VY_ASSETC_COMPILED_H #define RT_ASSETC_COMPILED_H
#include "runtime/runtime.h" #include "runtime/runtime.h"
#include "runtime/assets.h" #include "runtime/assets.h"
vy_uid vyGetUID(const char *name); rt_uid rtGetUID(const char *name);
void vyStoreOutput(vy_uid uid, const void *data, size_t size); void rtStoreOutput(rt_uid uid, const void *data, size_t size);
vy_result vyWriteCompiledFiles(void); rt_result rtWriteCompiledFiles(void);
#endif #endif

View File

@ -1,6 +1,6 @@
#include "dependency_tracking.h" #include "dependency_tracking.h"
#define VY_DEFINE_DEPENDENCY_FILE_STRUCTURES #define RT_DEFINE_DEPENDENCY_FILE_STRUCTURES
#include "runtime/assets.h" #include "runtime/assets.h"
#include "runtime/threading.h" #include "runtime/threading.h"
#include "runtime/asset_dependencies.h" #include "runtime/asset_dependencies.h"
@ -24,11 +24,11 @@
/* 64 byte cache line - 8 (next index + count) / 4 (u32) = 14 */ /* 64 byte cache line - 8 (next index + count) / 4 (u32) = 14 */
#define BUCKET_ENTRY_COUNT 14 #define BUCKET_ENTRY_COUNT 14
typedef struct vy_dep_list_bucket_s { typedef struct rt_dep_list_bucket_s {
uint32_t next; uint32_t next;
uint32_t count; uint32_t count;
vy_uid entries[BUCKET_ENTRY_COUNT]; rt_uid entries[BUCKET_ENTRY_COUNT];
} vy_dep_list_bucket; } rt_dep_list_bucket;
typedef union { typedef union {
/* Indices of the first buckets */ /* Indices of the first buckets */
@ -37,47 +37,47 @@ typedef union {
uint32_t dependents; uint32_t dependents;
}; };
uint32_t lists[2]; uint32_t lists[2];
} vy_dep_list; } rt_dep_list;
static vy_mutex *_guard; static rt_mutex *_guard;
static vy_dep_list_bucket *_buckets; static rt_dep_list_bucket *_buckets;
static uint32_t _bucket_count; static uint32_t _bucket_count;
static uint32_t _bucket_capacity; static uint32_t _bucket_capacity;
#define MAP_SIZE 2048 #define MAP_SIZE 2048
static vy_uid _uids[MAP_SIZE]; static rt_uid _uids[MAP_SIZE];
static vy_dep_list _lists[MAP_SIZE]; static rt_dep_list _lists[MAP_SIZE];
vy_result vyInitDependencyTracking(void) { rt_result rtInitDependencyTracking(void) {
_guard = vyCreateMutex(); _guard = rtCreateMutex();
if (!_guard) if (!_guard)
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
_buckets = malloc(sizeof(vy_dep_list_bucket) * 256); _buckets = malloc(sizeof(rt_dep_list_bucket) * 256);
if (!_buckets) if (!_buckets)
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
_bucket_capacity = 256; _bucket_capacity = 256;
_bucket_count = 1; _bucket_count = 1;
return VY_SUCCESS; return RT_SUCCESS;
} }
static uint32_t AllocNewBucket(void) { static uint32_t AllocNewBucket(void) {
if (_bucket_count == _bucket_capacity) { if (_bucket_count == _bucket_capacity) {
void *t = realloc(_buckets, (size_t)_bucket_capacity * 2 * sizeof(vy_dep_list_bucket)); void *t = realloc(_buckets, (size_t)_bucket_capacity * 2 * sizeof(rt_dep_list_bucket));
if (!t) if (!t)
return 0; return 0;
_buckets = t; _buckets = t;
_bucket_capacity *= 2; _bucket_capacity *= 2;
} }
memset(&_buckets[_bucket_count], 0, sizeof(vy_dep_list_bucket)); memset(&_buckets[_bucket_count], 0, sizeof(rt_dep_list_bucket));
return _bucket_count++; return _bucket_count++;
} }
static vy_result InsertIntoList(vy_uid list_asset, vy_uid uid, int list_index) { static rt_result InsertIntoList(rt_uid list_asset, rt_uid uid, int list_index) {
vyLockMutex(_guard); rtLockMutex(_guard);
bool inserted = false; bool inserted = false;
for (uint32_t i = 0; i < MAP_SIZE; i++) { for (uint32_t i = 0; i < MAP_SIZE; i++) {
uint32_t at = (list_asset + i) % MAP_SIZE; uint32_t at = (list_asset + i) % MAP_SIZE;
@ -88,13 +88,13 @@ static vy_result InsertIntoList(vy_uid list_asset, vy_uid uid, int list_index) {
if (_lists[at].lists[list_index] == 0) { if (_lists[at].lists[list_index] == 0) {
_lists[at].lists[list_index] = AllocNewBucket(); _lists[at].lists[list_index] = AllocNewBucket();
if (!_lists[at].lists[list_index]) { if (!_lists[at].lists[list_index]) {
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
} }
/* Advance to the end of the list */ /* Advance to the end of the list */
vy_dep_list_bucket *bucket = &_buckets[_lists[at].lists[list_index]]; rt_dep_list_bucket *bucket = &_buckets[_lists[at].lists[list_index]];
while (bucket->next != END_OF_LIST) { while (bucket->next != END_OF_LIST) {
bucket = &_buckets[bucket->next]; bucket = &_buckets[bucket->next];
} }
@ -103,8 +103,8 @@ static vy_result InsertIntoList(vy_uid list_asset, vy_uid uid, int list_index) {
if (bucket->count == BUCKET_ENTRY_COUNT) { if (bucket->count == BUCKET_ENTRY_COUNT) {
bucket->next = AllocNewBucket(); bucket->next = AllocNewBucket();
if (!bucket->next) { if (!bucket->next) {
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
bucket = &_buckets[bucket->next]; bucket = &_buckets[bucket->next];
} }
@ -116,64 +116,64 @@ static vy_result InsertIntoList(vy_uid list_asset, vy_uid uid, int list_index) {
break; break;
} }
} }
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
assert(inserted); assert(inserted);
return VY_SUCCESS; return RT_SUCCESS;
} }
vy_result vyAddAssetDependency(vy_uid dependent, vy_uid dependency) { rt_result rtAddAssetDependency(rt_uid dependent, rt_uid dependency) {
vy_result res = InsertIntoList(dependent, dependency, 0); rt_result res = InsertIntoList(dependent, dependency, 0);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
res = InsertIntoList(dependency, dependent, 1); res = InsertIntoList(dependency, dependent, 1);
return res; return res;
} }
vy_result vySaveAssetDependencies(void) { rt_result rtSaveAssetDependencies(void) {
assert(vyIsMainThread()); assert(rtIsMainThread());
vy_dependency_file_header header = {.num_lists = 0, .data_size = 0}; rt_dependency_file_header header = {.num_lists = 0, .data_size = 0};
for (size_t i = 0; i < MAP_SIZE; ++i) { for (size_t i = 0; i < MAP_SIZE; ++i) {
if (_uids[i] != VY_INVALID_UID) { if (_uids[i] != RT_INVALID_UID) {
if (!_lists[i].dependencies) if (!_lists[i].dependencies)
continue; continue;
header.num_lists += 1; header.num_lists += 1;
/* Determine the list size */ /* Determine the list size */
vy_dep_list_bucket *bucket = &_buckets[_lists[i].dependencies]; rt_dep_list_bucket *bucket = &_buckets[_lists[i].dependencies];
uint32_t total_list_size = bucket->count; uint32_t total_list_size = bucket->count;
while (bucket->next != END_OF_LIST) { while (bucket->next != END_OF_LIST) {
bucket = &_buckets[bucket->next]; bucket = &_buckets[bucket->next];
total_list_size += bucket->count; total_list_size += bucket->count;
} }
header.data_size += total_list_size * sizeof(vy_uid) + sizeof(vy_dependency_file_list_header); header.data_size += total_list_size * sizeof(rt_uid) + sizeof(rt_dependency_file_list_header);
} }
} }
FILE *f = fopen("data/deps.bin", "wb"); FILE *f = fopen("data/deps.bin", "wb");
if (!f) { if (!f) {
vyReportError("ASSETC", "Failed to open 'deps.bin' for writing."); rtReportError("ASSETC", "Failed to open 'deps.bin' for writing.");
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
if (fwrite(&header, sizeof(header), 1, f) != 1) { if (fwrite(&header, sizeof(header), 1, f) != 1) {
vyReportError("ASSETC", "Failed to write to 'deps.bin'."); rtReportError("ASSETC", "Failed to write to 'deps.bin'.");
fclose(f); fclose(f);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
void *buffer = NULL; void *buffer = NULL;
size_t buffer_size = 0; size_t buffer_size = 0;
for (size_t i = 0; i < MAP_SIZE; ++i) { for (size_t i = 0; i < MAP_SIZE; ++i) {
if (_uids[i] != VY_INVALID_UID) { if (_uids[i] != RT_INVALID_UID) {
if (!_lists[i].dependencies) if (!_lists[i].dependencies)
continue; continue;
/* Determine the list size */ /* Determine the list size */
vy_dep_list_bucket *bucket = &_buckets[_lists[i].dependencies]; rt_dep_list_bucket *bucket = &_buckets[_lists[i].dependencies];
uint32_t total_list_size = bucket->count; uint32_t total_list_size = bucket->count;
while (bucket->next != END_OF_LIST) { while (bucket->next != END_OF_LIST) {
bucket = &_buckets[bucket->next]; bucket = &_buckets[bucket->next];
@ -182,21 +182,21 @@ vy_result vySaveAssetDependencies(void) {
/* Allocate */ /* Allocate */
size_t required_size = size_t required_size =
total_list_size * sizeof(vy_uid) + sizeof(vy_dependency_file_list_header); total_list_size * sizeof(rt_uid) + sizeof(rt_dependency_file_list_header);
if (required_size > buffer_size) { if (required_size > buffer_size) {
void *t = realloc(buffer, required_size); void *t = realloc(buffer, required_size);
if (!t) { if (!t) {
free(buffer); free(buffer);
fclose(f); fclose(f);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
buffer = t; buffer = t;
buffer_size = required_size; buffer_size = required_size;
} }
/* Fill header */ /* Fill header */
vy_dependency_file_list_header *list_header = buffer; rt_dependency_file_list_header *list_header = buffer;
vy_uid *list = (vy_uid *)(list_header + 1); rt_uid *list = (rt_uid *)(list_header + 1);
list_header->uid = _uids[i]; list_header->uid = _uids[i];
list_header->num_entries = total_list_size; list_header->num_entries = total_list_size;
@ -204,19 +204,19 @@ vy_result vySaveAssetDependencies(void) {
uint32_t at = 0; uint32_t at = 0;
bucket = &_buckets[_lists[i].dependencies]; bucket = &_buckets[_lists[i].dependencies];
do { do {
memcpy(&list[at], bucket->entries, sizeof(vy_uid) * bucket->count); memcpy(&list[at], bucket->entries, sizeof(rt_uid) * bucket->count);
at += bucket->count; at += bucket->count;
bucket = &_buckets[bucket->next]; bucket = &_buckets[bucket->next];
} while (bucket != &_buckets[END_OF_LIST]); } while (bucket != &_buckets[END_OF_LIST]);
XXH64_hash_t hash = XXH3_64bits(list, sizeof(vy_uid) * total_list_size); XXH64_hash_t hash = XXH3_64bits(list, sizeof(rt_uid) * total_list_size);
XXH64_canonicalFromHash(&list_header->checksum, hash); XXH64_canonicalFromHash(&list_header->checksum, hash);
if (fwrite(buffer, required_size, 1, f) != 1) { if (fwrite(buffer, required_size, 1, f) != 1) {
vyReportError("ASSETC", "Failed to write to 'deps.bin'."); rtReportError("ASSETC", "Failed to write to 'deps.bin'.");
fclose(f); fclose(f);
free(buffer); free(buffer);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
} }
} }
@ -224,5 +224,5 @@ vy_result vySaveAssetDependencies(void) {
fclose(f); fclose(f);
free(buffer); free(buffer);
return VY_SUCCESS; return RT_SUCCESS;
} }

View File

@ -1,14 +1,14 @@
#ifndef VY_ASSETC_DEPENDENCY_TRACKING_H #ifndef RT_ASSETC_DEPENDENCY_TRACKING_H
#define VY_ASSETC_DEPENDENCY_TRACKING_H #define RT_ASSETC_DEPENDENCY_TRACKING_H
#include "runtime/runtime.h" #include "runtime/runtime.h"
#include "runtime/assets.h" #include "runtime/assets.h"
vy_result vyInitDependencyTracking(void); rt_result rtInitDependencyTracking(void);
vy_result vyAddAssetDependency(vy_uid dependent, vy_uid dependency); rt_result rtAddAssetDependency(rt_uid dependent, rt_uid dependency);
vy_result vySaveAssetDependencies(void); rt_result rtSaveAssetDependencies(void);
#endif #endif

View File

@ -17,7 +17,7 @@ static bool IsWhitespace(char c) {
return c == ' ' || c == '\t' || c == '\n' || c == '\r'; return c == ' ' || c == '\t' || c == '\n' || c == '\r';
} }
static void SkipWhitespace(vy_parse_state *state) { static void SkipWhitespace(rt_parse_state *state) {
while (state->at < state->length && IsWhitespace(state->text[state->at])) { while (state->at < state->length && IsWhitespace(state->text[state->at])) {
if (state->text[state->at] == '\n') if (state->text[state->at] == '\n')
++state->line; ++state->line;
@ -25,8 +25,8 @@ static void SkipWhitespace(vy_parse_state *state) {
} }
} }
static bool ParseAttribute(vy_parse_state *state, vy_text_span *_name) { static bool ParseAttribute(rt_parse_state *state, rt_text_span *_name) {
vy_text_span name; rt_text_span name;
name.start = &state->text[state->at]; name.start = &state->text[state->at];
name.length = 0; name.length = 0;
while (state->at < state->length && !IsWhitespace(state->text[state->at])) { while (state->at < state->length && !IsWhitespace(state->text[state->at])) {
@ -34,7 +34,7 @@ static bool ParseAttribute(vy_parse_state *state, vy_text_span *_name) {
++state->at; ++state->at;
++name.length; ++name.length;
} else { } else {
vyReportError("GFX", rtReportError("GFX",
"%s:%d Unexpected character %c", "%s:%d Unexpected character %c",
state->file, state->file,
state->line, state->line,
@ -46,8 +46,8 @@ static bool ParseAttribute(vy_parse_state *state, vy_text_span *_name) {
return true; return true;
} }
static bool ParseValue(vy_parse_state *state, vy_text_span *_value) { static bool ParseValue(rt_parse_state *state, rt_text_span *_value) {
vy_text_span value; rt_text_span value;
value.start = &state->text[state->at]; value.start = &state->text[state->at];
value.length = 0; value.length = 0;
while (state->at < state->length && !IsWhitespace(state->text[state->at]) && while (state->at < state->length && !IsWhitespace(state->text[state->at]) &&
@ -56,7 +56,7 @@ static bool ParseValue(vy_parse_state *state, vy_text_span *_value) {
++state->at; ++state->at;
++value.length; ++value.length;
} else { } else {
vyReportError("GFX", rtReportError("GFX",
"%s:%d Unexpected character %c", "%s:%d Unexpected character %c",
state->file, state->file,
state->line, state->line,
@ -73,18 +73,18 @@ static bool ParseValue(vy_parse_state *state, vy_text_span *_value) {
#define BLOCK_END "END" #define BLOCK_END "END"
#define BLOCK_END_LENGTH 3 #define BLOCK_END_LENGTH 3
VY_INLINE static bool IsBlockBegin(vy_parse_state *state) { RT_INLINE static bool IsBlockBegin(rt_parse_state *state) {
return (state->length - state->at >= BLOCK_BEGIN_LENGTH) && return (state->length - state->at >= BLOCK_BEGIN_LENGTH) &&
(memcmp(&state->text[state->at], BLOCK_BEGIN, BLOCK_BEGIN_LENGTH) == 0); (memcmp(&state->text[state->at], BLOCK_BEGIN, BLOCK_BEGIN_LENGTH) == 0);
} }
VY_INLINE static bool IsBlockEnd(vy_parse_state *state) { RT_INLINE static bool IsBlockEnd(rt_parse_state *state) {
return (state->length - state->at >= BLOCK_END_LENGTH) && return (state->length - state->at >= BLOCK_END_LENGTH) &&
(memcmp(&state->text[state->at], BLOCK_END, BLOCK_END_LENGTH) == 0); (memcmp(&state->text[state->at], BLOCK_END, BLOCK_END_LENGTH) == 0);
} }
static bool ParseBlock(vy_parse_state *state, vy_text_span *p_value) { static bool ParseBlock(rt_parse_state *state, rt_text_span *p_value) {
vy_text_span value; rt_text_span value;
value.start = &state->text[state->at]; value.start = &state->text[state->at];
value.length = 0; value.length = 0;
while (state->at < state->length) { while (state->at < state->length) {
@ -99,10 +99,10 @@ static bool ParseBlock(vy_parse_state *state, vy_text_span *p_value) {
return false; return false;
} }
static bool ParseStmtList(vy_parse_state *state, unsigned int *list_index); static bool ParseStmtList(rt_parse_state *state, unsigned int *list_index);
static bool ParseStmt(vy_parse_state *state, unsigned int *stmt_index) { static bool ParseStmt(rt_parse_state *state, unsigned int *stmt_index) {
vy_parsed_stmt stmt; rt_parsed_stmt stmt;
stmt.next = UINT_MAX; /* end of list */ stmt.next = UINT_MAX; /* end of list */
SkipWhitespace(state); SkipWhitespace(state);
@ -111,7 +111,7 @@ static bool ParseStmt(vy_parse_state *state, unsigned int *stmt_index) {
SkipWhitespace(state); SkipWhitespace(state);
if (state->at == state->length) { if (state->at == state->length) {
vyReportError("GFX", "%s:%d Expected either a value or '{'", state->file, state->line); rtReportError("GFX", "%s:%d Expected either a value or '{'", state->file, state->line);
return false; return false;
} }
@ -119,7 +119,7 @@ static bool ParseStmt(vy_parse_state *state, unsigned int *stmt_index) {
/* Consume '{' */ /* Consume '{' */
++state->at; ++state->at;
stmt.form = VY_STMT_FORM_LIST; stmt.form = RT_STMT_FORM_LIST;
if (!ParseStmtList(state, &stmt.list_index)) if (!ParseStmtList(state, &stmt.list_index))
return false; return false;
@ -130,14 +130,14 @@ static bool ParseStmt(vy_parse_state *state, unsigned int *stmt_index) {
/* Consume BEGIN */ /* Consume BEGIN */
state->at += BLOCK_BEGIN_LENGTH; state->at += BLOCK_BEGIN_LENGTH;
stmt.form = VY_STMT_FORM_BLOCK; stmt.form = RT_STMT_FORM_BLOCK;
if (!ParseBlock(state, &stmt.block)) if (!ParseBlock(state, &stmt.block))
return false; return false;
/* Consume END */ /* Consume END */
state->at += BLOCK_END_LENGTH; state->at += BLOCK_END_LENGTH;
} else { } else {
stmt.form = VY_STMT_FORM_VALUE; stmt.form = RT_STMT_FORM_VALUE;
if (!ParseValue(state, &stmt.value)) if (!ParseValue(state, &stmt.value))
return false; return false;
@ -151,9 +151,9 @@ static bool ParseStmt(vy_parse_state *state, unsigned int *stmt_index) {
/* Add statement to array */ /* Add statement to array */
if (state->statement_count == state->statement_capacity) { if (state->statement_count == state->statement_capacity) {
unsigned int cap = (state->statement_capacity > 0) ? state->statement_capacity * 2 : 64; unsigned int cap = (state->statement_capacity > 0) ? state->statement_capacity * 2 : 64;
vy_parsed_stmt *temp = realloc(state->statements, sizeof(vy_parsed_stmt) * cap); rt_parsed_stmt *temp = realloc(state->statements, sizeof(rt_parsed_stmt) * cap);
if (!temp) { if (!temp) {
vyReportError("GFX", "While parsing %s: Out of memory\n", state->file); rtReportError("GFX", "While parsing %s: Out of memory\n", state->file);
return false; return false;
} }
state->statements = temp; state->statements = temp;
@ -165,8 +165,8 @@ static bool ParseStmt(vy_parse_state *state, unsigned int *stmt_index) {
return true; return true;
} }
static bool ParseStmtList(vy_parse_state *state, unsigned int *list_index) { static bool ParseStmtList(rt_parse_state *state, unsigned int *list_index) {
vy_parsed_stmt_list list; rt_parsed_stmt_list list;
list.first = UINT_MAX; list.first = UINT_MAX;
list.count = 0; list.count = 0;
@ -190,10 +190,10 @@ static bool ParseStmtList(vy_parse_state *state, unsigned int *list_index) {
if (state->statement_list_count == state->statement_list_capacity) { if (state->statement_list_count == state->statement_list_capacity) {
unsigned int cap = unsigned int cap =
(state->statement_list_capacity > 0) ? state->statement_list_capacity * 2 : 64; (state->statement_list_capacity > 0) ? state->statement_list_capacity * 2 : 64;
vy_parsed_stmt_list *temp = rt_parsed_stmt_list *temp =
realloc(state->statement_lists, sizeof(vy_parsed_stmt_list) * cap); realloc(state->statement_lists, sizeof(rt_parsed_stmt_list) * cap);
if (!temp) { if (!temp) {
vyReportError("GFX", "While parsing %s: Out of memory\n", state->file); rtReportError("GFX", "While parsing %s: Out of memory\n", state->file);
return false; return false;
} }
state->statement_lists = temp; state->statement_lists = temp;
@ -204,14 +204,14 @@ static bool ParseStmtList(vy_parse_state *state, unsigned int *list_index) {
return true; return true;
} }
const vy_parsed_stmt * vyFindStatement(const vy_parse_state *state, unsigned int list_index, const char *attribute) { const rt_parsed_stmt * rtFindStatement(const rt_parse_state *state, unsigned int list_index, const char *attribute) {
if (list_index >= state->statement_list_count) if (list_index >= state->statement_list_count)
return NULL; return NULL;
const vy_parsed_stmt_list *list = &state->statement_lists[list_index]; const rt_parsed_stmt_list *list = &state->statement_lists[list_index];
unsigned int stmt_index = list->first; unsigned int stmt_index = list->first;
for (unsigned int i = 0; i < list->count; ++i) { for (unsigned int i = 0; i < list->count; ++i) {
const vy_parsed_stmt *stmt = &state->statements[stmt_index]; const rt_parsed_stmt *stmt = &state->statements[stmt_index];
if (vyCompareSpanToString(stmt->attribute, attribute) == 0) if (rtCompareSpanToString(stmt->attribute, attribute) == 0)
return stmt; return stmt;
stmt_index = stmt->next; stmt_index = stmt->next;
} }
@ -219,13 +219,13 @@ const vy_parsed_stmt * vyFindStatement(const vy_parse_state *state, unsigned int
} }
vy_result vyParseDescription(const char *text, rt_result rtParseDescription(const char *text,
size_t length, size_t length,
const char *file_path, const char *file_path,
unsigned int *_root_list, unsigned int *_root_list,
vy_parse_state *_state) { rt_parse_state *_state) {
vy_parse_state state = {.text = text, rt_parse_state state = {.text = text,
.at = 0, .at = 0,
.length = length, .length = length,
.line = 1, .line = 1,
@ -242,11 +242,11 @@ vy_result vyParseDescription(const char *text,
*_root_list = root_list; *_root_list = root_list;
*_state = state; *_state = state;
return VY_SUCCESS; return RT_SUCCESS;
} }
void vyReleaseParseState(vy_parse_state *state) { void rtReleaseParseState(rt_parse_state *state) {
free(state->statements); free(state->statements);
free(state->statement_lists); free(state->statement_lists);
} }

View File

@ -1,30 +1,30 @@
#ifndef VY_ASSETC_DESCRIPTION_PARSER_H #ifndef RT_ASSETC_DESCRIPTION_PARSER_H
#define VY_ASSETC_DESCRIPTION_PARSER_H #define RT_ASSETC_DESCRIPTION_PARSER_H
#include "runtime/runtime.h" #include "runtime/runtime.h"
typedef enum { typedef enum {
VY_STMT_FORM_VALUE, RT_STMT_FORM_VALUE,
VY_STMT_FORM_LIST, RT_STMT_FORM_LIST,
VY_STMT_FORM_BLOCK, RT_STMT_FORM_BLOCK,
} vy_stmt_form; } rt_stmt_form;
typedef struct { typedef struct {
unsigned int first; unsigned int first;
unsigned int count; unsigned int count;
} vy_parsed_stmt_list; } rt_parsed_stmt_list;
typedef struct { typedef struct {
vy_stmt_form form; rt_stmt_form form;
vy_text_span attribute; rt_text_span attribute;
union { union {
vy_text_span value; rt_text_span value;
vy_text_span block; rt_text_span block;
unsigned int list_index; unsigned int list_index;
}; };
/* For lists */ /* For lists */
unsigned int next; unsigned int next;
} vy_parsed_stmt; } rt_parsed_stmt;
typedef struct { typedef struct {
const char *file; const char *file;
@ -33,23 +33,23 @@ typedef struct {
size_t length; size_t length;
int line; int line;
vy_parsed_stmt *statements; rt_parsed_stmt *statements;
unsigned int statement_count; unsigned int statement_count;
unsigned int statement_capacity; unsigned int statement_capacity;
vy_parsed_stmt_list *statement_lists; rt_parsed_stmt_list *statement_lists;
unsigned int statement_list_count; unsigned int statement_list_count;
unsigned int statement_list_capacity; unsigned int statement_list_capacity;
} vy_parse_state; } rt_parse_state;
vy_result vyParseDescription(const char *text, rt_result rtParseDescription(const char *text,
size_t length, size_t length,
const char *file_path, const char *file_path,
unsigned int *root_list, unsigned int *root_list,
vy_parse_state *state); rt_parse_state *state);
const vy_parsed_stmt *vyFindStatement(const vy_parse_state *state, unsigned int list_index, const char *attribute); const rt_parsed_stmt *rtFindStatement(const rt_parse_state *state, unsigned int list_index, const char *attribute);
void vyReleaseParseState(vy_parse_state *state); void rtReleaseParseState(rt_parse_state *state);
#endif #endif

View File

@ -11,32 +11,32 @@
typedef struct { typedef struct {
char path_scratch[1024]; char path_scratch[1024];
unsigned int path_end; unsigned int path_end;
} vy_discovery_data; } rt_discovery_data;
static vy_result LoadCompressedAsset(vy_uid uid, void **buffer, size_t size) { static rt_result LoadCompressedAsset(rt_uid uid, void **buffer, size_t size) {
} }
static vy_result DirectoryHandler(const char *name, vyIterateDirElementType type, void *user) { static rt_result DirectoryHandler(const char *name, rtIterateDirElementType type, void *user) {
vy_discovery_data *data = user; rt_discovery_data *data = user;
size_t name_len = strlen(name); size_t name_len = strlen(name);
if (type == VY_DIR_ELEMENT_TYPE_FILE) { if (type == RT_DIR_ELEMENT_TYPE_FILE) {
/* Skip files we don't want to process */ /* Skip files we don't want to process */
if (name_len >= 3) { if (name_len >= 3) {
if (memcmp(&name[name_len - 3], ".as", 3) == 0) if (memcmp(&name[name_len - 3], ".as", 3) == 0)
return VY_SUCCESS; return RT_SUCCESS;
} }
if (name_len >= 4) { if (name_len >= 4) {
if (memcmp(&name[name_len - 4], ".pkg", 4) == 0) if (memcmp(&name[name_len - 4], ".pkg", 4) == 0)
return VY_SUCCESS; return RT_SUCCESS;
else if (memcmp(&name[name_len - 4], ".bin", 4) == 0) else if (memcmp(&name[name_len - 4], ".bin", 4) == 0)
return VY_SUCCESS; return RT_SUCCESS;
} }
if (strcmp(name, "packages.txt") == 0) if (strcmp(name, "packages.txt") == 0)
return VY_SUCCESS; return RT_SUCCESS;
if (name[0] == '.') { if (name[0] == '.') {
return VY_SUCCESS; return RT_SUCCESS;
} }
/* Check if we know that file */ /* Check if we know that file */
@ -49,49 +49,49 @@ static vy_result DirectoryHandler(const char *name, vyIterateDirElementType type
data->path_scratch[name_len] = '\0'; data->path_scratch[name_len] = '\0';
} }
vy_file_id fid = vyAddFile(data->path_scratch); rt_file_id fid = rtAddFile(data->path_scratch);
if (vyLookupUID(fid) != VY_INVALID_UID) { if (rtLookupUID(fid) != RT_INVALID_UID) {
vy_assetmeta meta = {0}; rt_assetmeta meta = {0};
if (!vyGetAssetMeta(fid, &meta) || (meta.last_changed >= meta.compiled_ts)) { if (!rtGetAssetMeta(fid, &meta) || (meta.last_changed >= meta.compiled_ts)) {
/* The file (may have) changed */ /* The file (may have) changed */
vy_result res = vyAddFileToProcessingQueue(fid, meta.processing_flags); rt_result res = rtAddFileToProcessingQueue(fid, meta.processing_flags);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
} }
else { else {
/* The file is unchanged, we just need to add it to the output again. */ /* The file is unchanged, we just need to add it to the output again. */
vyLog("ASSETC", "File %s is unchanged.", data->path_scratch); rtLog("ASSETC", "File %s is unchanged.", data->path_scratch);
vy_asset_settings settings = {0}; rt_asset_settings settings = {0};
if (vyLoadAssetSettings(data->path_scratch, &settings) != VY_SUCCESS) { if (rtLoadAssetSettings(data->path_scratch, &settings) != RT_SUCCESS) {
vyLog("ASSETC", "Failed to load settings for %s", data->path_scratch); rtLog("ASSETC", "Failed to load settings for %s", data->path_scratch);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
/* We need to load the processed data and add it to the package */ /* We need to load the processed data and add it to the package */
vy_uid uid = vyLookupUID(fid); rt_uid uid = rtLookupUID(fid);
if (uid == VY_INVALID_UID) { if (uid == RT_INVALID_UID) {
vyLog("ASSETC", "Failed to lookup UID of known asset %s", data->path_scratch); rtLog("ASSETC", "Failed to lookup UID of known asset %s", data->path_scratch);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
vyAddUnchangedAssetToPackage(settings.package, uid); rtAddUnchangedAssetToPackage(settings.package, uid);
} }
} else { } else {
/* Process it */ /* Process it */
vy_asset_settings settings = {0}; rt_asset_settings settings = {0};
if (vyLoadAssetSettings(data->path_scratch, &settings) != VY_SUCCESS) { if (rtLoadAssetSettings(data->path_scratch, &settings) != RT_SUCCESS) {
vyLog("ASSETC", "Failed to load settings for %s", data->path_scratch); rtLog("ASSETC", "Failed to load settings for %s", data->path_scratch);
} }
vy_result res = vyAddFileToProcessingQueue(fid, settings.processing_flags); rt_result res = rtAddFileToProcessingQueue(fid, settings.processing_flags);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
} }
} else if (type == VY_DIR_ELEMENT_TYPE_DIRECTORY) { } else if (type == RT_DIR_ELEMENT_TYPE_DIRECTORY) {
if (strcmp(name, ".") == 0) if (strcmp(name, ".") == 0)
return VY_SUCCESS; return RT_SUCCESS;
if (strcmp(name, "..") == 0) if (strcmp(name, "..") == 0)
return VY_SUCCESS; return RT_SUCCESS;
unsigned int path_end_before = data->path_end; unsigned int path_end_before = data->path_end;
if (data->path_end > 0) if (data->path_end > 0)
@ -100,20 +100,20 @@ static vy_result DirectoryHandler(const char *name, vyIterateDirElementType type
data->path_scratch[data->path_end + name_len] = '\0'; data->path_scratch[data->path_end + name_len] = '\0';
data->path_end += (unsigned int)name_len; data->path_end += (unsigned int)name_len;
vy_result res = vyIterateDirectory(data->path_scratch, user, DirectoryHandler); rt_result res = rtIterateDirectory(data->path_scratch, user, DirectoryHandler);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
data->path_end = path_end_before; data->path_end = path_end_before;
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
void vyDiscoverAssets(void) { void rtDiscoverAssets(void) {
vy_discovery_data data; rt_discovery_data data;
memcpy(data.path_scratch, "assets", sizeof("assets")); memcpy(data.path_scratch, "assets", sizeof("assets"));
data.path_end = sizeof("assets") - 1; data.path_end = sizeof("assets") - 1;
vyIterateDirectory("assets", &data, DirectoryHandler); rtIterateDirectory("assets", &data, DirectoryHandler);
} }

View File

@ -1,28 +1,28 @@
#ifndef VY_ASSETC_OPTIONS_H #ifndef RT_ASSETC_OPTIONS_H
#define VY_ASSETC_OPTIONS_H #define RT_ASSETC_OPTIONS_H
#include "runtime/assets.h" #include "runtime/assets.h"
typedef enum { typedef enum {
/* No optimization */ /* No optimization */
VY_ASSET_OPTIMIZATION_NONE, RT_ASSET_OPTIMIZATION_NONE,
/* Create small assets */ /* Create small assets */
VY_ASSET_OPTIMIZATION_SPACE, RT_ASSET_OPTIMIZATION_SPACE,
/* Create assets for fast execution */ /* Create assets for fast execution */
VY_ASSET_OPTIMIZATION_PERFORMANCE, RT_ASSET_OPTIMIZATION_PERFORMANCE,
} vy_asset_optimization_level; } rt_asset_optimization_level;
/* Options parsed from command line arguments */ /* Options parsed from command line arguments */
typedef struct { typedef struct {
const char *root_directory; const char *root_directory;
vy_renderer_backend_code renderer_backend; rt_renderer_backend_code renderer_backend;
vy_asset_optimization_level optimization; rt_asset_optimization_level optimization;
} vy_assetc_options; } rt_assetc_options;
#ifndef VY_ASSETC_DONT_DEFINE_OPTIONS_GLOBAL #ifndef RT_ASSETC_DONT_DEFINE_OPTIONS_GLOBAL
extern vy_assetc_options g_assetc_options; extern rt_assetc_options g_assetc_options;
#endif #endif
#endif #endif

View File

@ -2,7 +2,7 @@
#include "processing.h" #include "processing.h"
#include "utils.h" #include "utils.h"
#define VY_DEFINE_PACKAGE_FILE_STRUCTURES #define RT_DEFINE_PACKAGE_FILE_STRUCTURES
#include "runtime/threading.h" #include "runtime/threading.h"
#include "runtime/assets.h" #include "runtime/assets.h"
#include "runtime/file_tab.h" #include "runtime/file_tab.h"
@ -19,30 +19,30 @@
#include "lz4/lz4.h" #include "lz4/lz4.h"
typedef struct { typedef struct {
vy_uid uid; rt_uid uid;
size_t disk_size; size_t disk_size;
} vy_package_entry; } rt_package_entry;
typedef struct { typedef struct {
char *name; char *name;
unsigned int num_entries; unsigned int num_entries;
unsigned int entry_capacity; unsigned int entry_capacity;
vy_package_entry *entries; rt_package_entry *entries;
} vy_package; } rt_package;
#define MAX_PACKAGES 1024 #define MAX_PACKAGES 1024
vy_package _packages[MAX_PACKAGES]; rt_package _packages[MAX_PACKAGES];
unsigned int _package_count = 0; unsigned int _package_count = 0;
vy_mutex *_guard; rt_mutex *_guard;
unsigned int vyAddPackageFile(vy_text_span name) { unsigned int rtAddPackageFile(rt_text_span name) {
vyLockMutex(_guard); rtLockMutex(_guard);
for (unsigned int i = 0; i < _package_count; ++i) { for (unsigned int i = 0; i < _package_count; ++i) {
if (vyCompareSpanToString(name, _packages[i].name + 5) == 0) { if (rtCompareSpanToString(name, _packages[i].name + 5) == 0) {
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return i; return i;
} }
} }
@ -50,11 +50,11 @@ unsigned int vyAddPackageFile(vy_text_span name) {
/* Create a new package */ /* Create a new package */
_packages[_package_count].name = malloc(name.length + 1 + 5); _packages[_package_count].name = malloc(name.length + 1 + 5);
if (!_packages[_package_count].name) { if (!_packages[_package_count].name) {
vyReportError("ASSETC", rtReportError("ASSETC",
"Failed to allocate storage for new package %*.s", "Failed to allocate storage for new package %*.s",
name.length, name.length,
name.start); name.start);
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return UINT_MAX; return UINT_MAX;
} }
memcpy(_packages[_package_count].name, "data/", 5); memcpy(_packages[_package_count].name, "data/", 5);
@ -63,42 +63,42 @@ unsigned int vyAddPackageFile(vy_text_span name) {
unsigned int index = _package_count++; unsigned int index = _package_count++;
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return index; return index;
} }
void vyInitPackages(void) { void rtInitPackages(void) {
_guard = vyCreateMutex(); _guard = rtCreateMutex();
/* Create the default package (0) */ /* Create the default package (0) */
vyAddPackageFile((vy_text_span){.start = "default.pkg", .length = 12}); rtAddPackageFile((rt_text_span){.start = "default.pkg", .length = 12});
} }
static void AddAssetToPackageImpl(unsigned int package, static void AddAssetToPackageImpl(unsigned int package,
vy_uid uid, rt_uid uid,
void *buffer, void *buffer,
size_t size, size_t size,
bool needs_compression) { bool needs_compression) {
vyLockMutex(_guard); rtLockMutex(_guard);
if (package >= _package_count) { if (package >= _package_count) {
vyReportError("ASSETC", "Trying to add an asset to a non-existing package."); rtReportError("ASSETC", "Trying to add an asset to a non-existing package.");
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return; return;
} }
vy_package *pkg = &_packages[package]; rt_package *pkg = &_packages[package];
for (unsigned int i = 0; i < pkg->num_entries; ++i) { for (unsigned int i = 0; i < pkg->num_entries; ++i) {
if (pkg->entries[i].uid == uid) { if (pkg->entries[i].uid == uid) {
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return; return;
} }
} }
if (pkg->num_entries == pkg->entry_capacity) { if (pkg->num_entries == pkg->entry_capacity) {
unsigned int new_cap = (pkg->entry_capacity > 0) ? 2 * pkg->entry_capacity : 256; unsigned int new_cap = (pkg->entry_capacity > 0) ? 2 * pkg->entry_capacity : 256;
vy_package_entry *n = realloc(pkg->entries, new_cap * sizeof(vy_package_entry)); rt_package_entry *n = realloc(pkg->entries, new_cap * sizeof(rt_package_entry));
if (!n) { if (!n) {
vyReportError("ASSETC", "Failed to grow storage for package %u.", package); rtReportError("ASSETC", "Failed to grow storage for package %u.", package);
return; return;
} }
pkg->entry_capacity = new_cap; pkg->entry_capacity = new_cap;
@ -110,7 +110,7 @@ static void AddAssetToPackageImpl(unsigned int package,
if (needs_compression) { if (needs_compression) {
FILE *tmp_f = fopen(tmp_path, "wb"); FILE *tmp_f = fopen(tmp_path, "wb");
if (!tmp_f) { if (!tmp_f) {
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return; return;
} }
@ -118,7 +118,7 @@ static void AddAssetToPackageImpl(unsigned int package,
void *compressed_buffer = malloc(required_size); void *compressed_buffer = malloc(required_size);
if (!compressed_buffer) { if (!compressed_buffer) {
fclose(tmp_f); fclose(tmp_f);
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return; return;
} }
@ -127,23 +127,23 @@ static void AddAssetToPackageImpl(unsigned int package,
if (compressed_bytes == 0) { if (compressed_bytes == 0) {
free(compressed_buffer); free(compressed_buffer);
fclose(tmp_f); fclose(tmp_f);
vyReportError("ASSETC", "Failed to compress asset %x of package %s", uid, pkg->name); rtReportError("ASSETC", "Failed to compress asset %x of package %s", uid, pkg->name);
return; return;
} }
vy_package_asset_header header; rt_package_asset_header header;
XXH64_hash_t checksum = XXH3_64bits_withSeed(buffer, (size_t)compressed_bytes, 0); XXH64_hash_t checksum = XXH3_64bits_withSeed(buffer, (size_t)compressed_bytes, 0);
XXH64_canonicalFromHash(&header.checksum, checksum); XXH64_canonicalFromHash(&header.checksum, checksum);
header.decompressed_size = (uint32_t)size; header.decompressed_size = (uint32_t)size;
if (fwrite(&header, sizeof(header), 1, tmp_f) != 1) { if (fwrite(&header, sizeof(header), 1, tmp_f) != 1) {
vyReportError("ASSETC", "Failed to write to actemp/%u.bin", uid); rtReportError("ASSETC", "Failed to write to actemp/%u.bin", uid);
free(compressed_buffer); free(compressed_buffer);
fclose(tmp_f); fclose(tmp_f);
return; return;
} }
if (fwrite(buffer, compressed_bytes, 1, tmp_f) != 1) { if (fwrite(buffer, compressed_bytes, 1, tmp_f) != 1) {
vyReportError("ASSETC", "Failed to write to actemp/%u.bin", uid); rtReportError("ASSETC", "Failed to write to actemp/%u.bin", uid);
free(compressed_buffer); free(compressed_buffer);
fclose(tmp_f); fclose(tmp_f);
return; return;
@ -151,11 +151,11 @@ static void AddAssetToPackageImpl(unsigned int package,
fclose(tmp_f); fclose(tmp_f);
pkg->entries[pkg->num_entries].disk_size = pkg->entries[pkg->num_entries].disk_size =
(size_t)compressed_bytes + sizeof(vy_package_asset_header); (size_t)compressed_bytes + sizeof(rt_package_asset_header);
} else { } else {
pkg->entries[pkg->num_entries].disk_size = vyGetFileSize(tmp_path); pkg->entries[pkg->num_entries].disk_size = rtGetFileSize(tmp_path);
if (pkg->entries[pkg->num_entries].disk_size == 0) { if (pkg->entries[pkg->num_entries].disk_size == 0) {
vyReportError("ASSETC", "Failed to determine size of actemp/%u.bin", uid); rtReportError("ASSETC", "Failed to determine size of actemp/%u.bin", uid);
} }
} }
@ -163,21 +163,21 @@ static void AddAssetToPackageImpl(unsigned int package,
++pkg->num_entries; ++pkg->num_entries;
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
} }
void vyAddAssetToPackage(unsigned int package, vy_uid uid, void *buffer, size_t size) { void rtAddAssetToPackage(unsigned int package, rt_uid uid, void *buffer, size_t size) {
AddAssetToPackageImpl(package, uid, buffer, size, true); AddAssetToPackageImpl(package, uid, buffer, size, true);
} }
void vyAddUnchangedAssetToPackage(unsigned int package, vy_uid uid) { void rtAddUnchangedAssetToPackage(unsigned int package, rt_uid uid) {
AddAssetToPackageImpl(package, uid, NULL, 0, false); AddAssetToPackageImpl(package, uid, NULL, 0, false);
} }
static vy_result SavePackage(vy_package *pkg) { static rt_result SavePackage(rt_package *pkg) {
if (pkg->num_entries == 0) { if (pkg->num_entries == 0) {
vyLog("ASSETC", "Package %s has no entries.", pkg->name); rtLog("ASSETC", "Package %s has no entries.", pkg->name);
return VY_SUCCESS; return RT_SUCCESS;
} }
size_t current_buffer_size = 0; size_t current_buffer_size = 0;
@ -185,12 +185,12 @@ static vy_result SavePackage(vy_package *pkg) {
size_t offset_in_file = 0; size_t offset_in_file = 0;
vy_file_id package_fid = vyAddFile(pkg->name); rt_file_id package_fid = rtAddFile(pkg->name);
FILE *f = fopen(pkg->name, "wb"); FILE *f = fopen(pkg->name, "wb");
if (!f) { if (!f) {
vyReportError("ASSETC", "Failed to open %s for writing.", pkg->name); rtReportError("ASSETC", "Failed to open %s for writing.", pkg->name);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
for (unsigned int i = 0; i < pkg->num_entries; ++i) { for (unsigned int i = 0; i < pkg->num_entries; ++i) {
@ -198,42 +198,42 @@ static vy_result SavePackage(vy_package *pkg) {
snprintf(tmp_path, 256, "actemp/%u.bin", pkg->entries[i].uid); snprintf(tmp_path, 256, "actemp/%u.bin", pkg->entries[i].uid);
FILE *tmp_f = fopen(tmp_path, "rb"); FILE *tmp_f = fopen(tmp_path, "rb");
if (!tmp_f) { if (!tmp_f) {
vyReportError("ASSETC", "Failed to open %s for reading.", tmp_path); rtReportError("ASSETC", "Failed to open %s for reading.", tmp_path);
fclose(f); fclose(f);
free(buffer); free(buffer);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
if (current_buffer_size < pkg->entries[i].disk_size) { if (current_buffer_size < pkg->entries[i].disk_size) {
void *tmp = realloc(buffer, pkg->entries[i].disk_size); void *tmp = realloc(buffer, pkg->entries[i].disk_size);
if (!tmp) { if (!tmp) {
vyReportError("ASSETC", "Failed to allocate buffer (%zu bytes) for reading %s.", pkg->entries[i].disk_size, tmp_path); rtReportError("ASSETC", "Failed to allocate buffer (%zu bytes) for reading %s.", pkg->entries[i].disk_size, tmp_path);
fclose(f); fclose(f);
fclose(tmp_f); fclose(tmp_f);
free(buffer); free(buffer);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
buffer = tmp; buffer = tmp;
current_buffer_size = pkg->entries[i].disk_size; current_buffer_size = pkg->entries[i].disk_size;
} }
if (fread(buffer, pkg->entries[i].disk_size, 1, tmp_f) != 1) { if (fread(buffer, pkg->entries[i].disk_size, 1, tmp_f) != 1) {
vyReportError("ASSETC", "Failed to read %s.", tmp_path); rtReportError("ASSETC", "Failed to read %s.", tmp_path);
fclose(f); fclose(f);
fclose(tmp_f); fclose(tmp_f);
free(buffer); free(buffer);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
if (fwrite(buffer, pkg->entries[i].disk_size, 1, f) != 1) { if (fwrite(buffer, pkg->entries[i].disk_size, 1, f) != 1) {
vyReportError("ASSETC", "Failed to write (%zu bytes) to %s.", pkg->entries[i].disk_size, pkg->name); rtReportError("ASSETC", "Failed to write (%zu bytes) to %s.", pkg->entries[i].disk_size, pkg->name);
fclose(f); fclose(f);
fclose(tmp_f); fclose(tmp_f);
free(buffer); free(buffer);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
vyAddUIDTabEntry(package_fid, rtAddUIDTabEntry(package_fid,
pkg->entries[i].uid, pkg->entries[i].uid,
offset_in_file, offset_in_file,
pkg->entries[i].disk_size); pkg->entries[i].disk_size);
@ -245,18 +245,18 @@ static vy_result SavePackage(vy_package *pkg) {
free(buffer); free(buffer);
fclose(f); fclose(f);
return VY_SUCCESS; return RT_SUCCESS;
} }
vy_result vySavePackages(void) { rt_result rtSavePackages(void) {
assert(vyIsMainThread()); assert(rtIsMainThread());
/* Save a .txt file with one line per package. /* Save a .txt file with one line per package.
* Enables us to re-init the file-tab in future runs. */ * Enables us to re-init the file-tab in future runs. */
FILE *f = fopen("data/packages.txt", "w"); FILE *f = fopen("data/packages.txt", "w");
if (!f) { if (!f) {
vyReportError("ASSETC", "Failed to write to 'packages.txt'"); rtReportError("ASSETC", "Failed to write to 'packages.txt'");
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
for (unsigned int i = 0; i < _package_count; ++i) { for (unsigned int i = 0; i < _package_count; ++i) {
if (_packages[i].num_entries == 0) if (_packages[i].num_entries == 0)
@ -266,9 +266,9 @@ vy_result vySavePackages(void) {
fclose(f); fclose(f);
for (unsigned int i = 0; i < _package_count; ++i) { for (unsigned int i = 0; i < _package_count; ++i) {
vy_result res = SavePackage(&_packages[i]); rt_result res = SavePackage(&_packages[i]);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
} }
return VY_SUCCESS; return RT_SUCCESS;
} }

View File

@ -1,16 +1,16 @@
#ifndef VY_ASSETC_PACKAGES_H #ifndef RT_ASSETC_PACKAGES_H
#define VY_ASSETC_PACKAGES_H #define RT_ASSETC_PACKAGES_H
#include "runtime/runtime.h" #include "runtime/runtime.h"
#include "runtime/assets.h" #include "runtime/assets.h"
void vyInitPackages(void); void rtInitPackages(void);
unsigned int vyAddPackageFile(vy_text_span name); unsigned int rtAddPackageFile(rt_text_span name);
void vyAddAssetToPackage(unsigned int package, vy_uid uid, void *buffer, size_t size); void rtAddAssetToPackage(unsigned int package, rt_uid uid, void *buffer, size_t size);
void vyAddUnchangedAssetToPackage(unsigned int package, vy_uid uid); void rtAddUnchangedAssetToPackage(unsigned int package, rt_uid uid);
vy_result vySavePackages(void); rt_result rtSavePackages(void);
#endif #endif

View File

@ -22,13 +22,13 @@
#include "dependency_tracking.h" #include "dependency_tracking.h"
typedef struct { typedef struct {
vy_attribute_binding *uniform_bindings; rt_attribute_binding *uniform_bindings;
vy_attribute_binding *storage_bindings; rt_attribute_binding *storage_bindings;
vy_attribute_binding *texture_bindings; rt_attribute_binding *texture_bindings;
vy_uid vertex_shader; rt_uid vertex_shader;
vy_uid fragment_shader; rt_uid fragment_shader;
vy_uid compute_shader; rt_uid compute_shader;
/* TODO Fixed function settings */ /* TODO Fixed function settings */
@ -37,20 +37,20 @@ typedef struct {
uint16_t uniform_binding_count; uint16_t uniform_binding_count;
uint16_t storage_binding_count; uint16_t storage_binding_count;
uint16_t texture_binding_count; uint16_t texture_binding_count;
} vy_parsed_pipeline_data; } rt_parsed_pipeline_data;
static void static void
DbgPrintShaderFile(const vy_parse_state *state, unsigned int list_index, unsigned int indent) { DbgPrintShaderFile(const rt_parse_state *state, unsigned int list_index, unsigned int indent) {
assert(list_index < state->statement_list_count); assert(list_index < state->statement_list_count);
const vy_parsed_stmt_list *list = &state->statement_lists[list_index]; const rt_parsed_stmt_list *list = &state->statement_lists[list_index];
unsigned int stmt_index = list->first; unsigned int stmt_index = list->first;
for (unsigned int i = 0; i < list->count; ++i) { for (unsigned int i = 0; i < list->count; ++i) {
const vy_parsed_stmt *stmt = &state->statements[stmt_index]; const rt_parsed_stmt *stmt = &state->statements[stmt_index];
for (unsigned int j = 0; j < indent; ++j) for (unsigned int j = 0; j < indent; ++j)
printf(" "); printf(" ");
printf("%.*s: ", stmt->attribute.length, stmt->attribute.start); printf("%.*s: ", stmt->attribute.length, stmt->attribute.start);
if (stmt->form == VY_STMT_FORM_VALUE) { if (stmt->form == RT_STMT_FORM_VALUE) {
printf("%.*s\n", stmt->value.length, stmt->value.start); printf("%.*s\n", stmt->value.length, stmt->value.start);
} else { } else {
printf("{\n"); printf("{\n");
@ -62,7 +62,7 @@ DbgPrintShaderFile(const vy_parse_state *state, unsigned int list_index, unsigne
assert(stmt_index == UINT_MAX || stmt_index == 0); assert(stmt_index == UINT_MAX || stmt_index == 0);
} }
static bool ParseBindingIndex(vy_text_span span, unsigned int *index) { static bool ParseBindingIndex(rt_text_span span, unsigned int *index) {
if (span.length == 0) if (span.length == 0)
return false; return false;
int at = (int)span.length - 1; int at = (int)span.length - 1;
@ -73,7 +73,7 @@ static bool ParseBindingIndex(vy_text_span span, unsigned int *index) {
unsigned int digit = (unsigned int)(span.start[at] - '0'); unsigned int digit = (unsigned int)(span.start[at] - '0');
n += digit * exp; n += digit * exp;
} else { } else {
vyReportError("GFX", "Unexpected non-digit character in binding index"); rtReportError("GFX", "Unexpected non-digit character in binding index");
return false; return false;
} }
--at; --at;
@ -83,54 +83,54 @@ static bool ParseBindingIndex(vy_text_span span, unsigned int *index) {
return true; return true;
} }
static vy_attribute_value ParseBindingValue(vy_text_span span) { static rt_attribute_value ParseBindingValue(rt_text_span span) {
if (vyCompareSpanToString(span, "MATERIAL_ALBEDO") == 0) { if (rtCompareSpanToString(span, "MATERIAL_ALBEDO") == 0) {
return VY_ATTRIBUTE_VALUE_MATERIAL_ALBEDO; return RT_ATTRIBUTE_VALUE_MATERIAL_ALBEDO;
} else if (vyCompareSpanToString(span, "MATERIAL_NORMAL") == 0) { } else if (rtCompareSpanToString(span, "MATERIAL_NORMAL") == 0) {
return VY_ATTRIBUTE_VALUE_MATERIAL_NORMAL; return RT_ATTRIBUTE_VALUE_MATERIAL_NORMAL;
} }
vyReportError("GFX", "Unsupported binding value %*.s", span.length, span.start); rtReportError("GFX", "Unsupported binding value %*.s", span.length, span.start);
return VY_ATTRIBUTE_VALUE_UNDEFINED; return RT_ATTRIBUTE_VALUE_UNDEFINED;
} }
static bool ParseBindings(vy_parse_state *state, static bool ParseBindings(rt_parse_state *state,
unsigned int root_list, unsigned int root_list,
const char *name, const char *name,
const char *file_path, const char *file_path,
vy_attribute_binding **p_bindings, rt_attribute_binding **p_bindings,
uint16_t *p_binding_count) { uint16_t *p_binding_count) {
const vy_parsed_stmt *bindings = vyFindStatement(state, root_list, name); const rt_parsed_stmt *bindings = rtFindStatement(state, root_list, name);
if (bindings) { if (bindings) {
if (bindings->form != VY_STMT_FORM_LIST) { if (bindings->form != RT_STMT_FORM_LIST) {
vyReportError("GFX", rtReportError("GFX",
"Expected list of bindings as the value of " "Expected list of bindings as the value of "
"\"%s\" in %s", "\"%s\" in %s",
name, name,
file_path); file_path);
return false; return false;
} }
const vy_parsed_stmt_list *binding_list = &state->statement_lists[bindings->list_index]; const rt_parsed_stmt_list *binding_list = &state->statement_lists[bindings->list_index];
vy_attribute_binding *shader_bindings = rt_attribute_binding *shader_bindings =
vyAllocBuffer(sizeof(vy_attribute_binding) * binding_list->count); rtAllocBuffer(sizeof(rt_attribute_binding) * binding_list->count);
if (!bindings) { if (!bindings) {
vyReportError("GFX", "Out of memory"); rtReportError("GFX", "Out of memory");
return false; return false;
} }
unsigned int binding_count = binding_list->count; unsigned int binding_count = binding_list->count;
unsigned int stmt_index = binding_list->first; unsigned int stmt_index = binding_list->first;
for (unsigned int i = 0; i < binding_list->count; ++i) { for (unsigned int i = 0; i < binding_list->count; ++i) {
const vy_parsed_stmt *stmt = &state->statements[stmt_index]; const rt_parsed_stmt *stmt = &state->statements[stmt_index];
if (!ParseBindingIndex(stmt->attribute, &shader_bindings[i].index)) { if (!ParseBindingIndex(stmt->attribute, &shader_bindings[i].index)) {
vyReleaseBuffer(shader_bindings, rtReleaseBuffer(shader_bindings,
sizeof(vy_attribute_binding) * binding_list->count); sizeof(rt_attribute_binding) * binding_list->count);
return false; return false;
} }
shader_bindings[i].value = ParseBindingValue(stmt->value); shader_bindings[i].value = ParseBindingValue(stmt->value);
if (shader_bindings[i].value == VY_ATTRIBUTE_VALUE_UNDEFINED) { if (shader_bindings[i].value == RT_ATTRIBUTE_VALUE_UNDEFINED) {
vyReleaseBuffer(shader_bindings, rtReleaseBuffer(shader_bindings,
sizeof(vy_attribute_binding) * binding_list->count); sizeof(rt_attribute_binding) * binding_list->count);
return false; return false;
} }
stmt_index = stmt->next; stmt_index = stmt->next;
@ -146,60 +146,60 @@ static bool ParseBindings(vy_parse_state *state,
} }
} }
static vy_result ParseShader(vy_parse_state *state, static rt_result ParseShader(rt_parse_state *state,
unsigned int root_list, unsigned int root_list,
const char *name, const char *name,
const char *file_path, const char *file_path,
uint32_t processing_flags, uint32_t processing_flags,
vy_uid *p_shader_uid) { rt_uid *p_shader_uid) {
const vy_parsed_stmt *stmt = vyFindStatement(state, root_list, name); const rt_parsed_stmt *stmt = rtFindStatement(state, root_list, name);
if (stmt) { if (stmt) {
if (stmt->form != VY_STMT_FORM_LIST) { if (stmt->form != RT_STMT_FORM_LIST) {
vyReportError("GFX", rtReportError("GFX",
"Expected a list as the value of " "Expected a list as the value of "
"\"%s\" in %s", "\"%s\" in %s",
name, name,
file_path); file_path);
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
const vy_parsed_stmt_list *shader_list = &state->statement_lists[stmt->list_index]; const rt_parsed_stmt_list *shader_list = &state->statement_lists[stmt->list_index];
unsigned int stmt_index = shader_list->first; unsigned int stmt_index = shader_list->first;
for (unsigned int i = 0; i < shader_list->count; ++i) { for (unsigned int i = 0; i < shader_list->count; ++i) {
const vy_parsed_stmt *shader = &state->statements[stmt_index]; const rt_parsed_stmt *shader = &state->statements[stmt_index];
if (shader->form != VY_STMT_FORM_VALUE) { if (shader->form != RT_STMT_FORM_VALUE) {
vyReportError("GFX", rtReportError("GFX",
"Expected a list as the value of " "Expected a list as the value of "
"\"%s.%*s\" in %s", "\"%s.%*s\" in %s",
name, name,
(int)shader->attribute.length, (int)shader->attribute.length,
shader->attribute.start, shader->attribute.start,
file_path); file_path);
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
vy_renderer_backend_code backend = VY_INVALID_RENDERER_BACKEND_CODE; rt_renderer_backend_code backend = RT_INVALID_RENDERER_BACKEND_CODE;
if (vyCompareSpanToString(shader->attribute, "vk") == 0) { if (rtCompareSpanToString(shader->attribute, "vk") == 0) {
backend = VY_RENDERER_BACKEND_CODE_VK; backend = RT_RENDERER_BACKEND_CODE_VK;
} else { } else {
vyReportError("GFX", rtReportError("GFX",
"Invalid renderer backend" "Invalid renderer backend"
"\"%*s\" in %s of file %s", "\"%*s\" in %s of file %s",
(int)shader->attribute.length, (int)shader->attribute.length,
shader->attribute.start, shader->attribute.start,
name, name,
file_path); file_path);
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
if (backend == g_assetc_options.renderer_backend) { if (backend == g_assetc_options.renderer_backend) {
vy_file_id shader_file = vyAddFileFromSpan(shader->value); rt_file_id shader_file = rtAddFileFromSpan(shader->value);
vy_uid uid = vyLookupUID(shader_file); rt_uid uid = rtLookupUID(shader_file);
if (uid == VY_INVALID_UID) { if (uid == RT_INVALID_UID) {
/* Add the shader file to processing and wait until its done /* Add the shader file to processing and wait until its done
*/ */
if (vyAddFileToProcessingQueue(shader_file, processing_flags) != VY_SUCCESS) if (rtAddFileToProcessingQueue(shader_file, processing_flags) != RT_SUCCESS)
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
return VY_PROCESSING_TRY_AGAIN; return RT_PROCESSING_TRY_AGAIN;
} }
*p_shader_uid = uid; *p_shader_uid = uid;
@ -208,44 +208,44 @@ static vy_result ParseShader(vy_parse_state *state,
} }
stmt_index = shader->next; stmt_index = shader->next;
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
static uint32_t static uint32_t
ParseOptimizationLevel(vy_parse_state *state, unsigned int root_list, const char *file_path) { ParseOptimizationLevel(rt_parse_state *state, unsigned int root_list, const char *file_path) {
uint32_t optimization_level; uint32_t optimization_level;
switch (g_assetc_options.optimization) { switch (g_assetc_options.optimization) {
case VY_ASSET_OPTIMIZATION_PERFORMANCE: case RT_ASSET_OPTIMIZATION_PERFORMANCE:
optimization_level = VY_SHADER_FLAG_OPTIMIZE_SPEED; optimization_level = RT_SHADER_FLAG_OPTIMIZE_SPEED;
break; break;
case VY_ASSET_OPTIMIZATION_SPACE: case RT_ASSET_OPTIMIZATION_SPACE:
optimization_level = VY_SHADER_FLAG_OPTIMIZE_SIZE; optimization_level = RT_SHADER_FLAG_OPTIMIZE_SIZE;
break; break;
default: default:
optimization_level = 0; optimization_level = 0;
} }
const vy_parsed_stmt *stmt = vyFindStatement(state, root_list, "optimization"); const rt_parsed_stmt *stmt = rtFindStatement(state, root_list, "optimization");
if (stmt) { if (stmt) {
if (stmt->form != VY_STMT_FORM_VALUE) { if (stmt->form != RT_STMT_FORM_VALUE) {
vyReportError("GFX", rtReportError("GFX",
"Expected a simple statement for" "Expected a simple statement for"
"\"optimization\" in %s", "\"optimization\" in %s",
file_path); file_path);
return optimization_level; return optimization_level;
} }
if (vyCompareSpanToString(stmt->value, "speed") == 0) { if (rtCompareSpanToString(stmt->value, "speed") == 0) {
optimization_level = VY_SHADER_FLAG_OPTIMIZE_SPEED; optimization_level = RT_SHADER_FLAG_OPTIMIZE_SPEED;
} else if (vyCompareSpanToString(stmt->value, "size") == 0) { } else if (rtCompareSpanToString(stmt->value, "size") == 0) {
optimization_level = VY_SHADER_FLAG_OPTIMIZE_SIZE; optimization_level = RT_SHADER_FLAG_OPTIMIZE_SIZE;
} else if (vyCompareSpanToString(stmt->value, "none") == 0) { } else if (rtCompareSpanToString(stmt->value, "none") == 0) {
optimization_level = 0; optimization_level = 0;
} else { } else {
vyReportError("GFX", rtReportError("GFX",
"Expected one of 'speed', 'size' and 'none' for \"optimization\" in %s", "Expected one of 'speed', 'size' and 'none' for \"optimization\" in %s",
file_path); file_path);
} }
@ -254,18 +254,18 @@ ParseOptimizationLevel(vy_parse_state *state, unsigned int root_list, const char
return optimization_level; return optimization_level;
} }
static vy_result static rt_result
ParsePipelineFile(vy_file_id fid, const char *text, size_t length, vy_parsed_pipeline_data *pipeline) { ParsePipelineFile(rt_file_id fid, const char *text, size_t length, rt_parsed_pipeline_data *pipeline) {
/* This is the grammar for pipeline files: /* This is the grammar for pipeline files:
* <stmt-list> ::= <stmt>* * <stmt-list> ::= <stmt>*
* <stmt> ::= <attribute> ( ( <value> ';' ) | ( '{' <stmt-list> '}' ) ) * <stmt> ::= <attribute> ( ( <value> ';' ) | ( '{' <stmt-list> '}' ) )
* <attribute> ::= [:alnum:]* * <attribute> ::= [:alnum:]*
* <value>:: = [:alnum:]* */ * <value>:: = [:alnum:]* */
const char *file_path = vyGetFilePath(fid); const char *file_path = rtGetFilePath(fid);
vy_parse_state state; rt_parse_state state;
unsigned int root_list; unsigned int root_list;
vy_result result = vyParseDescription(text, length, file_path, &root_list, &state); rt_result result = rtParseDescription(text, length, file_path, &root_list, &state);
if (result != VY_SUCCESS) { if (result != RT_SUCCESS) {
goto out; goto out;
} }
@ -277,27 +277,27 @@ ParsePipelineFile(vy_file_id fid, const char *text, size_t length, vy_parsed_pip
root_list, root_list,
"vertex", "vertex",
file_path, file_path,
VY_SHADER_FLAG_VERTEX | optimization, RT_SHADER_FLAG_VERTEX | optimization,
&pipeline->vertex_shader) == VY_PROCESSING_TRY_AGAIN) { &pipeline->vertex_shader) == RT_PROCESSING_TRY_AGAIN) {
result = VY_PROCESSING_TRY_AGAIN; result = RT_PROCESSING_TRY_AGAIN;
goto out; goto out;
} }
if (ParseShader(&state, if (ParseShader(&state,
root_list, root_list,
"fragment", "fragment",
file_path, file_path,
VY_SHADER_FLAG_FRAGMENT | optimization, RT_SHADER_FLAG_FRAGMENT | optimization,
&pipeline->fragment_shader) == VY_PROCESSING_TRY_AGAIN) { &pipeline->fragment_shader) == RT_PROCESSING_TRY_AGAIN) {
result = VY_PROCESSING_TRY_AGAIN; result = RT_PROCESSING_TRY_AGAIN;
goto out; goto out;
} }
if (ParseShader(&state, if (ParseShader(&state,
root_list, root_list,
"compute", "compute",
file_path, file_path,
VY_SHADER_FLAG_COMPUTE | optimization, RT_SHADER_FLAG_COMPUTE | optimization,
&pipeline->compute_shader) == VY_PROCESSING_TRY_AGAIN) { &pipeline->compute_shader) == RT_PROCESSING_TRY_AGAIN) {
result = VY_PROCESSING_TRY_AGAIN; result = RT_PROCESSING_TRY_AGAIN;
goto out; goto out;
} }
@ -315,7 +315,7 @@ ParsePipelineFile(vy_file_id fid, const char *text, size_t length, vy_parsed_pip
file_path, file_path,
&pipeline->texture_bindings, &pipeline->texture_bindings,
&pipeline->texture_binding_count)) { &pipeline->texture_binding_count)) {
result = VY_AIO_STATE_FAILED; result = RT_AIO_STATE_FAILED;
goto out; goto out;
} }
@ -325,7 +325,7 @@ ParsePipelineFile(vy_file_id fid, const char *text, size_t length, vy_parsed_pip
file_path, file_path,
&pipeline->uniform_bindings, &pipeline->uniform_bindings,
&pipeline->uniform_binding_count)) { &pipeline->uniform_binding_count)) {
result = VY_AIO_STATE_FAILED; result = RT_AIO_STATE_FAILED;
goto out; goto out;
} }
@ -335,7 +335,7 @@ ParsePipelineFile(vy_file_id fid, const char *text, size_t length, vy_parsed_pip
file_path, file_path,
&pipeline->storage_bindings, &pipeline->storage_bindings,
&pipeline->storage_binding_count)) { &pipeline->storage_binding_count)) {
result = VY_AIO_STATE_FAILED; result = RT_AIO_STATE_FAILED;
goto out; goto out;
} }
@ -345,29 +345,29 @@ out:
return result; return result;
} }
vy_result vyProcessPipelineFile(vy_file_id file, rt_result rtProcessPipelineFile(rt_file_id file,
void *buffer, void *buffer,
size_t size, size_t size,
uint32_t flags, uint32_t flags,
vy_processor_output *output) { rt_processor_output *output) {
VY_UNUSED(flags); RT_UNUSED(flags);
vy_parsed_pipeline_data tmp; rt_parsed_pipeline_data tmp;
memset(&tmp, 0, sizeof(tmp)); memset(&tmp, 0, sizeof(tmp));
vy_result result = ParsePipelineFile(file, buffer, size, &tmp); rt_result result = ParsePipelineFile(file, buffer, size, &tmp);
if (result == VY_SUCCESS) { if (result == RT_SUCCESS) {
/* parsed_pipeline_data contains arrays of bindings. /* parsed_pipeline_data contains arrays of bindings.
* We need to convert these to a flat buffer that can be written to a file */ * We need to convert these to a flat buffer that can be written to a file */
size_t outbuffer_size = size_t outbuffer_size =
sizeof(vy_pipeline_info) + sizeof(rt_pipeline_info) +
sizeof(vy_attribute_binding) * sizeof(rt_attribute_binding) *
(tmp.storage_binding_count + tmp.texture_binding_count + tmp.uniform_binding_count); (tmp.storage_binding_count + tmp.texture_binding_count + tmp.uniform_binding_count);
void *out_buffer = vyAllocBuffer(outbuffer_size); void *out_buffer = rtAllocBuffer(outbuffer_size);
if (!buffer) { if (!buffer) {
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
vy_pipeline_info *info = out_buffer; rt_pipeline_info *info = out_buffer;
info->vertex_shader = tmp.vertex_shader; info->vertex_shader = tmp.vertex_shader;
info->fragment_shader = tmp.fragment_shader; info->fragment_shader = tmp.fragment_shader;
info->compute_shader = tmp.compute_shader; info->compute_shader = tmp.compute_shader;
@ -375,49 +375,49 @@ vy_result vyProcessPipelineFile(vy_file_id file,
info->uniform_binding_count = tmp.uniform_binding_count; info->uniform_binding_count = tmp.uniform_binding_count;
info->storage_binding_count = tmp.storage_binding_count; info->storage_binding_count = tmp.storage_binding_count;
vy_attribute_binding *texture_bindings = NULL; rt_attribute_binding *texture_bindings = NULL;
if (tmp.texture_binding_count > 0) { if (tmp.texture_binding_count > 0) {
texture_bindings = (vy_attribute_binding *)(info + 1); texture_bindings = (rt_attribute_binding *)(info + 1);
memcpy(texture_bindings, memcpy(texture_bindings,
tmp.texture_bindings, tmp.texture_bindings,
sizeof(vy_attribute_binding) * tmp.texture_binding_count); sizeof(rt_attribute_binding) * tmp.texture_binding_count);
} }
vy_attribute_binding *uniform_bindings = NULL; rt_attribute_binding *uniform_bindings = NULL;
if (tmp.uniform_binding_count > 0) { if (tmp.uniform_binding_count > 0) {
uniform_bindings = texture_bindings + tmp.texture_binding_count; uniform_bindings = texture_bindings + tmp.texture_binding_count;
memcpy(uniform_bindings, memcpy(uniform_bindings,
tmp.uniform_bindings, tmp.uniform_bindings,
sizeof(vy_attribute_binding) * tmp.uniform_binding_count); sizeof(rt_attribute_binding) * tmp.uniform_binding_count);
} }
vy_attribute_binding *storage_bindings = NULL; rt_attribute_binding *storage_bindings = NULL;
if (tmp.storage_binding_count > 0) { if (tmp.storage_binding_count > 0) {
storage_bindings = uniform_bindings + tmp.uniform_binding_count; storage_bindings = uniform_bindings + tmp.uniform_binding_count;
memcpy(storage_bindings, memcpy(storage_bindings,
tmp.storage_bindings, tmp.storage_bindings,
sizeof(vy_attribute_binding) * tmp.storage_binding_count); sizeof(rt_attribute_binding) * tmp.storage_binding_count);
} }
vySetRelptr(&info->texture_bindings, texture_bindings); rtSetRelptr(&info->texture_bindings, texture_bindings);
vySetRelptr(&info->uniform_bindings, uniform_bindings); rtSetRelptr(&info->uniform_bindings, uniform_bindings);
vySetRelptr(&info->storage_bindings, storage_bindings); rtSetRelptr(&info->storage_bindings, storage_bindings);
vyReleaseBuffer(tmp.texture_bindings, rtReleaseBuffer(tmp.texture_bindings,
sizeof(vy_attribute_binding) * tmp.texture_binding_count); sizeof(rt_attribute_binding) * tmp.texture_binding_count);
vyReleaseBuffer(tmp.storage_bindings, rtReleaseBuffer(tmp.storage_bindings,
sizeof(vy_attribute_binding) * tmp.storage_binding_count); sizeof(rt_attribute_binding) * tmp.storage_binding_count);
vyReleaseBuffer(tmp.uniform_bindings, rtReleaseBuffer(tmp.uniform_bindings,
sizeof(vy_attribute_binding) * tmp.uniform_binding_count); sizeof(rt_attribute_binding) * tmp.uniform_binding_count);
output->data = out_buffer; output->data = out_buffer;
output->size = outbuffer_size; output->size = outbuffer_size;
output->asset_uid = vyCalculateUID(vyGetFilePath(file)); output->asset_uid = rtCalculateUID(rtGetFilePath(file));
/* Store dependencies to shaders */ /* Store dependencies to shaders */
if (info->vertex_shader != VY_INVALID_UID) if (info->vertex_shader != RT_INVALID_UID)
result = vyAddAssetDependency(output->asset_uid, info->vertex_shader); result = rtAddAssetDependency(output->asset_uid, info->vertex_shader);
if (info->fragment_shader != VY_INVALID_UID) if (info->fragment_shader != RT_INVALID_UID)
result = vyAddAssetDependency(output->asset_uid, info->fragment_shader); result = rtAddAssetDependency(output->asset_uid, info->fragment_shader);
if (info->compute_shader != VY_INVALID_UID) if (info->compute_shader != RT_INVALID_UID)
result = vyAddAssetDependency(output->asset_uid, info->compute_shader); result = rtAddAssetDependency(output->asset_uid, info->compute_shader);
} }
return result; return result;
} }

View File

@ -1,46 +1,46 @@
#ifndef VY_ASSETC_PROCESSING_H #ifndef RT_ASSETC_PROCESSING_H
#define VY_ASSETC_PROCESSING_H #define RT_ASSETC_PROCESSING_H
#include "runtime/assets.h" #include "runtime/assets.h"
#include "runtime/file_tab.h" #include "runtime/file_tab.h"
enum { enum {
VY_PROCESSING_FAILED = VY_CUSTOM_ERROR_START, RT_PROCESSING_FAILED = RT_CUSTOM_ERROR_START,
/* Used if the processing depends on other files beeing processed first. */ /* Used if the processing depends on other files beeing processed first. */
VY_PROCESSING_TRY_AGAIN, RT_PROCESSING_TRY_AGAIN,
}; };
typedef struct { typedef struct {
vy_file_id output_file; rt_file_id output_file;
} vy_asset_options; } rt_asset_options;
typedef struct { typedef struct {
vy_uid asset_uid; rt_uid asset_uid;
/* Allocated via the vyAllocBuffer API */ /* Allocated via the rtAllocBuffer API */
void *data; void *data;
size_t size; size_t size;
} vy_processor_output; } rt_processor_output;
typedef vy_result vy_processor_fn(vy_file_id file, typedef rt_result rt_processor_fn(rt_file_id file,
void *buffer, void *buffer,
size_t size, size_t size,
uint32_t flags, uint32_t flags,
vy_processor_output *output); rt_processor_output *output);
vy_result vyAddAssetProcessor(const char *file_extension, vy_processor_fn fn); rt_result rtAddAssetProcessor(const char *file_extension, rt_processor_fn fn);
/* Flags are file type specific */ /* Flags are file type specific */
vy_result vyAddFileToProcessingQueue(vy_file_id file, uint32_t flags); rt_result rtAddFileToProcessingQueue(rt_file_id file, uint32_t flags);
vy_result vyStartProcessing(void); rt_result rtStartProcessing(void);
void vyStopProcessing(void); void rtStopProcessing(void);
vy_uid vyCalculateUID(const char *name); rt_uid rtCalculateUID(const char *name);
vy_result vyWriteUIDTab(void); rt_result rtWriteUIDTab(void);
vy_result vyAddUIDTabEntry(vy_file_id package_fid, vy_uid uid, uint64_t offset, uint64_t size); rt_result rtAddUIDTabEntry(rt_file_id package_fid, rt_uid uid, uint64_t offset, uint64_t size);
void vyWaitUntilProcessingIsFinished(void); void rtWaitUntilProcessingIsFinished(void);
#endif #endif

View File

@ -1,19 +1,19 @@
#ifndef VY_ASSETC_PROCESSING_FLAGS_H #ifndef RT_ASSETC_PROCESSING_FLAGS_H
#define VY_ASSETC_PROCESSING_FLAGS_H #define RT_ASSETC_PROCESSING_FLAGS_H
/* Shader processing flags */ /* Shader processing flags */
enum { enum {
/* Type is encoded in the lower bits */ /* Type is encoded in the lower bits */
VY_SHADER_FLAG_VERTEX = 0x01, RT_SHADER_FLAG_VERTEX = 0x01,
VY_SHADER_FLAG_FRAGMENT = 0x02, RT_SHADER_FLAG_FRAGMENT = 0x02,
VY_SHADER_FLAG_COMPUTE = 0x03, RT_SHADER_FLAG_COMPUTE = 0x03,
VY_SHADER_FLAG_TYPE_MASK = RT_SHADER_FLAG_TYPE_MASK =
VY_SHADER_FLAG_VERTEX | VY_SHADER_FLAG_FRAGMENT | VY_SHADER_FLAG_COMPUTE, RT_SHADER_FLAG_VERTEX | RT_SHADER_FLAG_FRAGMENT | RT_SHADER_FLAG_COMPUTE,
VY_SHADER_FLAG_OPTIMIZE_SPEED = 0x04, RT_SHADER_FLAG_OPTIMIZE_SPEED = 0x04,
VY_SHADER_FLAG_OPTIMIZE_SIZE = 0x08, RT_SHADER_FLAG_OPTIMIZE_SIZE = 0x08,
VY_SHADER_FLAG_OPTIMIZE_MASK = VY_SHADER_FLAG_OPTIMIZE_SPEED | VY_SHADER_FLAG_OPTIMIZE_SIZE, RT_SHADER_FLAG_OPTIMIZE_MASK = RT_SHADER_FLAG_OPTIMIZE_SPEED | RT_SHADER_FLAG_OPTIMIZE_SIZE,
}; };

View File

@ -17,26 +17,26 @@
typedef struct { typedef struct {
vy_file_id fid; rt_file_id fid;
uint32_t flags; uint32_t flags;
/* How many times has this file been added? */ /* How many times has this file been added? */
unsigned int turn; unsigned int turn;
} vy_file_processing_queue_entry; } rt_file_processing_queue_entry;
#define QUEUE_LENGTH 1024 #define QUEUE_LENGTH 1024
typedef struct { typedef struct {
vy_file_processing_queue_entry entries[QUEUE_LENGTH]; rt_file_processing_queue_entry entries[QUEUE_LENGTH];
unsigned int head; unsigned int head;
unsigned int tail; unsigned int tail;
} vy_file_processing_queue; } rt_file_processing_queue;
static vy_file_processing_queue _queues[2]; static rt_file_processing_queue _queues[2];
static vy_file_processing_queue *_processing_queue; static rt_file_processing_queue *_processing_queue;
static vy_file_processing_queue *_retry_queue; static rt_file_processing_queue *_retry_queue;
static vy_mutex *_guard; static rt_mutex *_guard;
static bool _keep_running; static bool _keep_running;
/* A single file could have a lot of dependencies. */ /* A single file could have a lot of dependencies. */
@ -47,20 +47,20 @@ static bool _keep_running;
#define FORCE_SINGLE_THREAD 1 #define FORCE_SINGLE_THREAD 1
static unsigned int _num_processing_threads = 0; static unsigned int _num_processing_threads = 0;
static vy_thread *_processing_threads[MAX_PROCESSING_THREADS]; static rt_thread *_processing_threads[MAX_PROCESSING_THREADS];
static unsigned int _processing_thread_count = 0; static unsigned int _processing_thread_count = 0;
static vy_result vyAddFileToProcessingQueueImpl(vy_file_processing_queue *queue, static rt_result rtAddFileToProcessingQueueImpl(rt_file_processing_queue *queue,
vy_file_id file, rt_file_id file,
uint32_t flags, uint32_t flags,
unsigned int turn) { unsigned int turn) {
vy_result result = VY_SUCCESS; rt_result result = RT_SUCCESS;
vyLog("ASSETC", "Adding %s to processing queue.", vyGetFilePath(file)); rtLog("ASSETC", "Adding %s to processing queue.", rtGetFilePath(file));
vy_file_processing_queue_entry entry = { rt_file_processing_queue_entry entry = {
.fid = file, .fid = file,
.flags = flags, .flags = flags,
.turn = turn, .turn = turn,
@ -70,42 +70,42 @@ static vy_result vyAddFileToProcessingQueueImpl(vy_file_processing_queue *queue,
queue->entries[slot] = entry; queue->entries[slot] = entry;
queue->head = (queue->head + 1) % QUEUE_LENGTH; queue->head = (queue->head + 1) % QUEUE_LENGTH;
} else { } else {
vyReportError("ASSETC", "The processing queue is full!"); rtReportError("ASSETC", "The processing queue is full!");
result = 1; result = 1;
} }
return result; return result;
} }
vy_result vyAddFileToProcessingQueue(vy_file_id file, uint32_t flags) { rt_result rtAddFileToProcessingQueue(rt_file_id file, uint32_t flags) {
assert(_guard != NULL); assert(_guard != NULL);
vyLockMutex(_guard); rtLockMutex(_guard);
vy_result res = vyAddFileToProcessingQueueImpl(_processing_queue, file, flags, 1); rt_result res = rtAddFileToProcessingQueueImpl(_processing_queue, file, flags, 1);
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
return res; return res;
} }
#define MAX_PROCESSORS 256 #define MAX_PROCESSORS 256
static vy_processor_fn *_processor_fns[MAX_PROCESSORS]; static rt_processor_fn *_processor_fns[MAX_PROCESSORS];
static const char *_processor_exts[MAX_PROCESSORS]; static const char *_processor_exts[MAX_PROCESSORS];
static unsigned int _processor_count; static unsigned int _processor_count;
vy_result vyAddAssetProcessor(const char *file_extension, vy_processor_fn fn) { rt_result rtAddAssetProcessor(const char *file_extension, rt_processor_fn fn) {
/* Should only be called from main thread */ /* Should only be called from main thread */
if (_processor_count == MAX_PROCESSORS) { if (_processor_count == MAX_PROCESSORS) {
vyReportError("ASSETC", "Too many asset processor functions!"); rtReportError("ASSETC", "Too many asset processor functions!");
return 1; return 1;
} }
_processor_fns[_processor_count] = fn; _processor_fns[_processor_count] = fn;
_processor_exts[_processor_count] = file_extension; _processor_exts[_processor_count] = file_extension;
++_processor_count; ++_processor_count;
return VY_SUCCESS; return RT_SUCCESS;
} }
static void PopAndSwapSubmittedData(unsigned int at, static void PopAndSwapSubmittedData(unsigned int at,
unsigned int *count, unsigned int *count,
vy_file_processing_queue_entry *queue_entries, rt_file_processing_queue_entry *queue_entries,
vy_aio_handle *handles, rt_aio_handle *handles,
void **buffers, void **buffers,
size_t *sizes) { size_t *sizes) {
if (at < *count - 1) { if (at < *count - 1) {
@ -117,9 +117,9 @@ static void PopAndSwapSubmittedData(unsigned int at,
*count = *count - 1; *count = *count - 1;
} }
static vy_result ProcessLoadedFile(vy_file_processing_queue_entry entry, void *buffer, size_t size) { static rt_result ProcessLoadedFile(rt_file_processing_queue_entry entry, void *buffer, size_t size) {
/* Search for a matching processor function */ /* Search for a matching processor function */
const char *path = vyGetFilePath(entry.fid); const char *path = rtGetFilePath(entry.fid);
size_t path_len = strlen(path); size_t path_len = strlen(path);
for (unsigned int i = 0; i < _processor_count; ++i) { for (unsigned int i = 0; i < _processor_count; ++i) {
size_t ext_len = strlen(_processor_exts[i]); size_t ext_len = strlen(_processor_exts[i]);
@ -132,97 +132,97 @@ static vy_result ProcessLoadedFile(vy_file_processing_queue_entry entry, void *b
/* Load the corresponding .as file. /* Load the corresponding .as file.
* TODO: Using malloc here is probably relatively slow. * TODO: Using malloc here is probably relatively slow.
*/ */
vy_result res; rt_result res;
vy_asset_settings settings; rt_asset_settings settings;
if ((res = vyLoadAssetSettings(path, &settings)) != VY_SUCCESS) { if ((res = rtLoadAssetSettings(path, &settings)) != RT_SUCCESS) {
return res; return res;
} }
/* Process the asset */ /* Process the asset */
vy_processor_output out; rt_processor_output out;
res = _processor_fns[i](entry.fid, buffer, size, entry.flags, &out); res = _processor_fns[i](entry.fid, buffer, size, entry.flags, &out);
if (res == VY_SUCCESS) { if (res == RT_SUCCESS) {
/* Add the output to the appropriate package file */ /* Add the output to the appropriate package file */
vy_assetmeta meta; rt_assetmeta meta;
meta.compiled_ts = vyGetCurrentTimestamp(); meta.compiled_ts = rtGetCurrentTimestamp();
meta.last_changed = vyGetFileModificationTimestamp(entry.fid); meta.last_changed = rtGetFileModificationTimestamp(entry.fid);
meta.processing_flags = entry.flags; meta.processing_flags = entry.flags;
vyAddUIDMapping(entry.fid, out.asset_uid, &meta); rtAddUIDMapping(entry.fid, out.asset_uid, &meta);
vyAddAssetToPackage(settings.package, out.asset_uid, out.data, out.size); rtAddAssetToPackage(settings.package, out.asset_uid, out.data, out.size);
} else if (res == VY_PROCESSING_TRY_AGAIN) { } else if (res == RT_PROCESSING_TRY_AGAIN) {
if (entry.turn < MAX_TURNS) { if (entry.turn < MAX_TURNS) {
vyLockMutex(_guard); rtLockMutex(_guard);
vyAddFileToProcessingQueueImpl(_retry_queue, entry.fid, entry.flags, entry.turn + 1); rtAddFileToProcessingQueueImpl(_retry_queue, entry.fid, entry.flags, entry.turn + 1);
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
} else { } else {
vyLog("ASSETC", rtLog("ASSETC",
"File '%s' took too many turns to process: %u", "File '%s' took too many turns to process: %u",
path, path,
entry.turn); entry.turn);
} }
} else { } else {
vyLog("ASSETC", "Failed to process file: %s (Result %u)", path, res); rtLog("ASSETC", "Failed to process file: %s (Result %u)", path, res);
} }
return res; return res;
} }
} }
vyLog("ASSETC", "No asset processor for file: %s", path); rtLog("ASSETC", "No asset processor for file: %s", path);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
static void ProcessingThread(void *_param) { static void ProcessingThread(void *_param) {
VY_UNUSED(_param); RT_UNUSED(_param);
vy_file_processing_queue_entry submitted_entries[VY_LOAD_BATCH_MAX_SIZE]; rt_file_processing_queue_entry submitted_entries[RT_LOAD_BATCH_MAX_SIZE];
vy_aio_handle submitted_handles[VY_LOAD_BATCH_MAX_SIZE]; rt_aio_handle submitted_handles[RT_LOAD_BATCH_MAX_SIZE];
void *submitted_buffers[VY_LOAD_BATCH_MAX_SIZE]; void *submitted_buffers[RT_LOAD_BATCH_MAX_SIZE];
size_t submitted_sizes[VY_LOAD_BATCH_MAX_SIZE]; size_t submitted_sizes[RT_LOAD_BATCH_MAX_SIZE];
unsigned int submitted_outstanding = 0; unsigned int submitted_outstanding = 0;
while (_keep_running) { while (_keep_running) {
vy_load_batch load_batch; rt_load_batch load_batch;
vy_file_processing_queue_entry load_entries[VY_LOAD_BATCH_MAX_SIZE]; rt_file_processing_queue_entry load_entries[RT_LOAD_BATCH_MAX_SIZE];
void *load_buffers[VY_LOAD_BATCH_MAX_SIZE]; void *load_buffers[RT_LOAD_BATCH_MAX_SIZE];
size_t load_sizes[VY_LOAD_BATCH_MAX_SIZE]; size_t load_sizes[RT_LOAD_BATCH_MAX_SIZE];
load_batch.num_loads = 0; load_batch.num_loads = 0;
bool got_entry = false; bool got_entry = false;
do { do {
got_entry = false; got_entry = false;
vy_file_processing_queue_entry entry = {0}; rt_file_processing_queue_entry entry = {0};
vyLockMutex(_guard); rtLockMutex(_guard);
if (_processing_queue->head != _processing_queue->tail) { if (_processing_queue->head != _processing_queue->tail) {
entry = _processing_queue->entries[_processing_queue->tail]; entry = _processing_queue->entries[_processing_queue->tail];
_processing_queue->tail = (_processing_queue->tail + 1) % QUEUE_LENGTH; _processing_queue->tail = (_processing_queue->tail + 1) % QUEUE_LENGTH;
got_entry = true; got_entry = true;
} else if (load_batch.num_loads == 0) { } else if (load_batch.num_loads == 0) {
/* Switch the queues -> Retry all the entries that returned VY_PROCESSING_TRY_AGAIN */ /* Switch the queues -> Retry all the entries that returned RT_PROCESSING_TRY_AGAIN */
if (_retry_queue->head != _retry_queue->tail) { if (_retry_queue->head != _retry_queue->tail) {
vy_file_processing_queue *tmp = _retry_queue; rt_file_processing_queue *tmp = _retry_queue;
_retry_queue = _processing_queue; _retry_queue = _processing_queue;
_processing_queue = tmp; _processing_queue = tmp;
} }
} }
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
/* Retry, if we did not get an entry */ /* Retry, if we did not get an entry */
if (!got_entry) if (!got_entry)
continue; continue;
const char *path = vyGetFilePath(entry.fid); const char *path = rtGetFilePath(entry.fid);
if (!path) { if (!path) {
vyLog("ASSETC", "Invalid file id: %#x", entry.fid); rtLog("ASSETC", "Invalid file id: %#x", entry.fid);
continue; continue;
} }
vyLog("ASSETC", "Processing %s", path); rtLog("ASSETC", "Processing %s", path);
size_t fsz = vyGetFileSize(path); size_t fsz = rtGetFileSize(path);
void *dest = vyAllocBuffer(fsz); void *dest = rtAllocBuffer(fsz);
if (!dest) { if (!dest) {
vyLog("ASSETC", "Ran out of memory for loading the file: %s", path); rtLog("ASSETC", "Ran out of memory for loading the file: %s", path);
continue; continue;
} }
memset(dest, 0, fsz); memset(dest, 0, fsz);
@ -235,34 +235,34 @@ static void ProcessingThread(void *_param) {
load_batch.loads[load_batch.num_loads].offset = 0; load_batch.loads[load_batch.num_loads].offset = 0;
load_entries[load_batch.num_loads] = entry; load_entries[load_batch.num_loads] = entry;
++load_batch.num_loads; ++load_batch.num_loads;
} while (got_entry && load_batch.num_loads < VY_LOAD_BATCH_MAX_SIZE); } while (got_entry && load_batch.num_loads < RT_LOAD_BATCH_MAX_SIZE);
vy_aio_handle load_handles[VY_LOAD_BATCH_MAX_SIZE]; rt_aio_handle load_handles[RT_LOAD_BATCH_MAX_SIZE];
if (load_batch.num_loads > 0) { if (load_batch.num_loads > 0) {
vy_result submit_result = vySubmitLoadBatch(&load_batch, load_handles); rt_result submit_result = rtSubmitLoadBatch(&load_batch, load_handles);
if (submit_result != VY_SUCCESS) { if (submit_result != RT_SUCCESS) {
vyLog("ASSETC", "SubmitLoadBatch failed: %u", submit_result); rtLog("ASSETC", "SubmitLoadBatch failed: %u", submit_result);
continue; continue;
} }
} }
/* Process the previously submitted loads */ /* Process the previously submitted loads */
while (submitted_outstanding > 0) { while (submitted_outstanding > 0) {
vyLockMutex(_guard); rtLockMutex(_guard);
_processing_thread_count += 1; _processing_thread_count += 1;
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
for (unsigned int i = 0; i < submitted_outstanding; ++i) { for (unsigned int i = 0; i < submitted_outstanding; ++i) {
vy_aio_state state = vyGetAIOState(submitted_handles[i]); rt_aio_state state = rtGetAIOState(submitted_handles[i]);
switch (state) { switch (state) {
case VY_AIO_STATE_PENDING: case RT_AIO_STATE_PENDING:
continue; continue;
case VY_AIO_STATE_FAILED: case RT_AIO_STATE_FAILED:
vyLog("ASSETC", rtLog("ASSETC",
"Loading file %s failed.", "Loading file %s failed.",
vyGetFilePath(submitted_entries[i].fid)); rtGetFilePath(submitted_entries[i].fid));
vyReleaseAIO(submitted_handles[i]); rtReleaseAIO(submitted_handles[i]);
vyReleaseBuffer(submitted_buffers[i], submitted_sizes[i]); rtReleaseBuffer(submitted_buffers[i], submitted_sizes[i]);
PopAndSwapSubmittedData(i, PopAndSwapSubmittedData(i,
&submitted_outstanding, &submitted_outstanding,
submitted_entries, submitted_entries,
@ -271,11 +271,11 @@ static void ProcessingThread(void *_param) {
submitted_sizes); submitted_sizes);
--i; --i;
break; break;
case VY_AIO_STATE_INVALID: case RT_AIO_STATE_INVALID:
vyLog("ASSETC", rtLog("ASSETC",
"Got invalid AIO handle for file: %s", "Got invalid AIO handle for file: %s",
vyGetFilePath(submitted_entries[i].fid)); rtGetFilePath(submitted_entries[i].fid));
vyReleaseBuffer(submitted_buffers[i], submitted_sizes[i]); rtReleaseBuffer(submitted_buffers[i], submitted_sizes[i]);
PopAndSwapSubmittedData(i, PopAndSwapSubmittedData(i,
&submitted_outstanding, &submitted_outstanding,
submitted_entries, submitted_entries,
@ -284,12 +284,12 @@ static void ProcessingThread(void *_param) {
submitted_sizes); submitted_sizes);
--i; --i;
break; break;
case VY_AIO_STATE_FINISHED: case RT_AIO_STATE_FINISHED:
ProcessLoadedFile(submitted_entries[i], ProcessLoadedFile(submitted_entries[i],
submitted_buffers[i], submitted_buffers[i],
submitted_sizes[i]); submitted_sizes[i]);
vyReleaseAIO(submitted_handles[i]); rtReleaseAIO(submitted_handles[i]);
vyReleaseBuffer(submitted_buffers[i], submitted_sizes[i]); rtReleaseBuffer(submitted_buffers[i], submitted_sizes[i]);
PopAndSwapSubmittedData(i, PopAndSwapSubmittedData(i,
&submitted_outstanding, &submitted_outstanding,
submitted_entries, submitted_entries,
@ -300,9 +300,9 @@ static void ProcessingThread(void *_param) {
} }
} }
vyLockMutex(_guard); rtLockMutex(_guard);
_processing_thread_count -= 1; _processing_thread_count -= 1;
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
} }
/* Start new round */ /* Start new round */
@ -318,12 +318,12 @@ static void ProcessingThread(void *_param) {
} }
} }
vy_result vyStartProcessing(void) { rt_result rtStartProcessing(void) {
if (!_guard) if (!_guard)
_guard = vyCreateMutex(); _guard = rtCreateMutex();
#if !FORCE_SINGLE_THREAD #if !FORCE_SINGLE_THREAD
_num_processing_threads = vyGetCPUCoreCount(); _num_processing_threads = rtGetCPUCoreCount();
if (_num_processing_threads > MAX_PROCESSING_THREADS) if (_num_processing_threads > MAX_PROCESSING_THREADS)
_num_processing_threads = MAX_PROCESSING_THREADS; _num_processing_threads = MAX_PROCESSING_THREADS;
#else #else
@ -335,20 +335,20 @@ vy_result vyStartProcessing(void) {
_keep_running = true; _keep_running = true;
for (unsigned int i = 0; i < _num_processing_threads; ++i) { for (unsigned int i = 0; i < _num_processing_threads; ++i) {
_processing_threads[i] = vySpawnThread(ProcessingThread, NULL, "Processor"); _processing_threads[i] = rtSpawnThread(ProcessingThread, NULL, "Processor");
if (!_processing_threads[i]) { if (!_processing_threads[i]) {
vyReportError("ASSETC", "Failed to spawn processing thread %u!", i); rtReportError("ASSETC", "Failed to spawn processing thread %u!", i);
_keep_running = false; _keep_running = false;
return 1; return 1;
} }
} }
return VY_SUCCESS; return RT_SUCCESS;
} }
void vyStopProcessing(void) { void rtStopProcessing(void) {
_keep_running = false; _keep_running = false;
for (unsigned int i = 0; i < _num_processing_threads; ++i) for (unsigned int i = 0; i < _num_processing_threads; ++i)
vyJoinThread(_processing_threads[i]); rtJoinThread(_processing_threads[i]);
} }
@ -360,7 +360,7 @@ void vyStopProcessing(void) {
#endif #endif
void vyWaitUntilProcessingIsFinished(void) { void rtWaitUntilProcessingIsFinished(void) {
unsigned int done_counter = 0; unsigned int done_counter = 0;
while (done_counter < 3) { while (done_counter < 3) {
#ifdef _WIN32 #ifdef _WIN32
@ -368,11 +368,11 @@ void vyWaitUntilProcessingIsFinished(void) {
#else #else
sleep(1); sleep(1);
#endif #endif
vyLockMutex(_guard); rtLockMutex(_guard);
volatile bool done = _processing_queue->head == _processing_queue->tail && volatile bool done = _processing_queue->head == _processing_queue->tail &&
_retry_queue->head == _retry_queue->tail && _retry_queue->head == _retry_queue->tail &&
_processing_thread_count == 0; _processing_thread_count == 0;
vyUnlockMutex(_guard); rtUnlockMutex(_guard);
if (done) if (done)
++done_counter; ++done_counter;
else else

View File

@ -21,27 +21,27 @@ static shaderc_include_result *ResolveInclude(void *user_data,
static void ReleaseIncludeResult(void *user_data, shaderc_include_result *result) { static void ReleaseIncludeResult(void *user_data, shaderc_include_result *result) {
} }
vy_result vyProcessShaderFile(vy_file_id file, rt_result rtProcessShaderFile(rt_file_id file,
void *buffer, void *buffer,
size_t size, size_t size,
uint32_t flags, uint32_t flags,
vy_processor_output *output) { rt_processor_output *output) {
/* If we determine that shader compilation takes too long, we can instead /* If we determine that shader compilation takes too long, we can instead
* keep the compiler around */ * keep the compiler around */
shaderc_compiler_t compiler = shaderc_compiler_initialize(); shaderc_compiler_t compiler = shaderc_compiler_initialize();
if (!compiler) { if (!compiler) {
vyLog("ASSETC", "Failed to initialize the shaderc compiler."); rtLog("ASSETC", "Failed to initialize the shaderc compiler.");
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
const char *path = vyGetFilePath(file); const char *path = rtGetFilePath(file);
shaderc_compile_options_t options = shaderc_compile_options_initialize(); shaderc_compile_options_t options = shaderc_compile_options_initialize();
if (!options) { if (!options) {
vyLog("ASSETC", "Failed to initialize shader compile options."); rtLog("ASSETC", "Failed to initialize shader compile options.");
shaderc_compiler_release(compiler); shaderc_compiler_release(compiler);
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
shaderc_compile_options_set_include_callbacks(options, shaderc_compile_options_set_include_callbacks(options,
@ -49,32 +49,32 @@ vy_result vyProcessShaderFile(vy_file_id file,
ReleaseIncludeResult, ReleaseIncludeResult,
NULL); NULL);
uint32_t optimize_from_flags = flags & VY_SHADER_FLAG_OPTIMIZE_MASK; uint32_t optimize_from_flags = flags & RT_SHADER_FLAG_OPTIMIZE_MASK;
if (optimize_from_flags == VY_SHADER_FLAG_OPTIMIZE_SPEED) if (optimize_from_flags == RT_SHADER_FLAG_OPTIMIZE_SPEED)
shaderc_compile_options_set_optimization_level(options, shaderc_compile_options_set_optimization_level(options,
shaderc_optimization_level_performance); shaderc_optimization_level_performance);
else if (optimize_from_flags == VY_SHADER_FLAG_OPTIMIZE_SIZE) else if (optimize_from_flags == RT_SHADER_FLAG_OPTIMIZE_SIZE)
shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_size); shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_size);
else else
shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_zero); shaderc_compile_options_set_optimization_level(options, shaderc_optimization_level_zero);
uint32_t type_from_flags = flags & VY_SHADER_FLAG_TYPE_MASK; uint32_t type_from_flags = flags & RT_SHADER_FLAG_TYPE_MASK;
shaderc_shader_kind shaderc_kind; shaderc_shader_kind shaderc_kind;
switch (type_from_flags) { switch (type_from_flags) {
case VY_SHADER_FLAG_VERTEX: case RT_SHADER_FLAG_VERTEX:
shaderc_kind = shaderc_glsl_vertex_shader; shaderc_kind = shaderc_glsl_vertex_shader;
break; break;
case VY_SHADER_FLAG_FRAGMENT: case RT_SHADER_FLAG_FRAGMENT:
shaderc_kind = shaderc_glsl_fragment_shader; shaderc_kind = shaderc_glsl_fragment_shader;
break; break;
case VY_SHADER_FLAG_COMPUTE: case RT_SHADER_FLAG_COMPUTE:
shaderc_kind = shaderc_glsl_compute_shader; shaderc_kind = shaderc_glsl_compute_shader;
break; break;
default: default:
vyLog("ASSETC", "Invalid shader stage flag %u", type_from_flags); rtLog("ASSETC", "Invalid shader stage flag %u", type_from_flags);
shaderc_compile_options_release(options); shaderc_compile_options_release(options);
shaderc_compiler_release(compiler); shaderc_compiler_release(compiler);
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
shaderc_compilation_result_t result = shaderc_compile_into_spv(compiler, shaderc_compilation_result_t result = shaderc_compile_into_spv(compiler,
@ -89,7 +89,7 @@ vy_result vyProcessShaderFile(vy_file_id file,
shaderc_compilation_status status = shaderc_result_get_compilation_status(result); shaderc_compilation_status status = shaderc_result_get_compilation_status(result);
if (status != shaderc_compilation_status_success || shaderc_result_get_num_errors(result) > 0) { if (status != shaderc_compilation_status_success || shaderc_result_get_num_errors(result) > 0) {
vyLog("ASSETC", rtLog("ASSETC",
"Compilation of %s failed: %s", "Compilation of %s failed: %s",
path, path,
shaderc_result_get_error_message(result)); shaderc_result_get_error_message(result));
@ -97,17 +97,17 @@ vy_result vyProcessShaderFile(vy_file_id file,
shaderc_result_release(result); shaderc_result_release(result);
shaderc_compile_options_release(options); shaderc_compile_options_release(options);
shaderc_compiler_release(compiler); shaderc_compiler_release(compiler);
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
size_t output_size = shaderc_result_get_length(result); size_t output_size = shaderc_result_get_length(result);
output->data = vyAllocBuffer(output_size); output->data = rtAllocBuffer(output_size);
if (!output->data) { if (!output->data) {
shaderc_result_release(result); shaderc_result_release(result);
shaderc_compile_options_release(options); shaderc_compile_options_release(options);
shaderc_compiler_release(compiler); shaderc_compiler_release(compiler);
vyLog("ASSETC", "Failed to allocate %zu bytes for shader compilation output.", output_size); rtLog("ASSETC", "Failed to allocate %zu bytes for shader compilation output.", output_size);
return VY_PROCESSING_FAILED; return RT_PROCESSING_FAILED;
} }
const uint32_t *spv_bytes = (uint32_t *)shaderc_result_get_bytes(result); const uint32_t *spv_bytes = (uint32_t *)shaderc_result_get_bytes(result);
memcpy(output->data, spv_bytes, output_size); memcpy(output->data, spv_bytes, output_size);
@ -117,7 +117,7 @@ vy_result vyProcessShaderFile(vy_file_id file,
shaderc_compile_options_release(options); shaderc_compile_options_release(options);
shaderc_compiler_release(compiler); shaderc_compiler_release(compiler);
output->asset_uid = vyCalculateUID(path); output->asset_uid = rtCalculateUID(path);
return VY_SUCCESS; return RT_SUCCESS;
} }

View File

@ -1,7 +1,7 @@
#include "processing.h" #include "processing.h"
#include "utils.h" #include "utils.h"
#define VY_DEFINE_UIDTAB_FILE_STRUCTURES #define RT_DEFINE_UIDTAB_FILE_STRUCTURES
#include "runtime/threading.h" #include "runtime/threading.h"
#include "runtime/uidtab.h" #include "runtime/uidtab.h"
@ -11,25 +11,25 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
static vy_uidtab_entry *_entries; static rt_uidtab_entry *_entries;
static size_t _entry_capacity; static size_t _entry_capacity;
static size_t _entry_count; static size_t _entry_count;
vy_uid vyCalculateUID(const char *name) { rt_uid rtCalculateUID(const char *name) {
assert(sizeof(XXH32_hash_t) == sizeof(vy_uid)); assert(sizeof(XXH32_hash_t) == sizeof(rt_uid));
size_t len = strlen(name); size_t len = strlen(name);
return (vy_uid)XXH32(name, len, 0); return (rt_uid)XXH32(name, len, 0);
} }
vy_result vyAddUIDTabEntry(vy_file_id package_fid, vy_uid uid, uint64_t offset, uint64_t size) { rt_result rtAddUIDTabEntry(rt_file_id package_fid, rt_uid uid, uint64_t offset, uint64_t size) {
assert(vyIsMainThread()); assert(rtIsMainThread());
if (_entry_count == _entry_capacity) { if (_entry_count == _entry_capacity) {
size_t new_cap = (_entry_capacity > 0) ? _entry_capacity * 2 : 256; size_t new_cap = (_entry_capacity > 0) ? _entry_capacity * 2 : 256;
void *t = realloc(_entries, sizeof(vy_uidtab_entry) * new_cap); void *t = realloc(_entries, sizeof(rt_uidtab_entry) * new_cap);
if (!t) if (!t)
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
_entry_capacity = new_cap; _entry_capacity = new_cap;
_entries = t; _entries = t;
} }
@ -38,32 +38,32 @@ vy_result vyAddUIDTabEntry(vy_file_id package_fid, vy_uid uid, uint64_t offset,
_entries[_entry_count].size = size; _entries[_entry_count].size = size;
_entries[_entry_count].uid = uid; _entries[_entry_count].uid = uid;
_entry_count++; _entry_count++;
return VY_SUCCESS; return RT_SUCCESS;
} }
vy_result vyWriteUIDTab(void) { rt_result rtWriteUIDTab(void) {
vy_uidtab_header header; rt_uidtab_header header;
XXH64_hash_t checksum = XXH3_64bits(_entries, sizeof(vy_uidtab_entry) * _entry_count); XXH64_hash_t checksum = XXH3_64bits(_entries, sizeof(rt_uidtab_entry) * _entry_count);
XXH64_canonicalFromHash(&header.checksum, checksum); XXH64_canonicalFromHash(&header.checksum, checksum);
header.num_entries = (uint32_t)_entry_count; header.num_entries = (uint32_t)_entry_count;
FILE *f = fopen("data/uidtab.bin", "wb"); FILE *f = fopen("data/uidtab.bin", "wb");
if (!f) { if (!f) {
vyReportError("ASSETC", "Failed to open 'uidtab.bin' for writing."); rtReportError("ASSETC", "Failed to open 'uidtab.bin' for writing.");
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
if (fwrite(&header, sizeof(header), 1, f) != 1) { if (fwrite(&header, sizeof(header), 1, f) != 1) {
vyReportError("ASSETC", "Failed to write header to 'uidtab.bin'"); rtReportError("ASSETC", "Failed to write header to 'uidtab.bin'");
fclose(f); fclose(f);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
if (fwrite(_entries, sizeof(vy_uidtab_entry), _entry_count, f) != _entry_count) { if (fwrite(_entries, sizeof(rt_uidtab_entry), _entry_count, f) != _entry_count) {
vyReportError("ASSETC", "Failed to write entries to 'uidtab.bin'"); rtReportError("ASSETC", "Failed to write entries to 'uidtab.bin'");
fclose(f); fclose(f);
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
} }
fclose(f); fclose(f);
return VY_SUCCESS; return RT_SUCCESS;
} }

View File

@ -5,7 +5,7 @@
#include <Windows.h> #include <Windows.h>
#endif #endif
size_t vyGetFileSize(const char *path) { size_t rtGetFileSize(const char *path) {
#ifdef _WIN32 #ifdef _WIN32
WCHAR wpath[MAX_PATH]; WCHAR wpath[MAX_PATH];
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, path, -1, wpath, MAX_PATH); MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, path, -1, wpath, MAX_PATH);
@ -16,7 +16,7 @@ size_t vyGetFileSize(const char *path) {
#endif #endif
} }
void vySetWorkingDirectory(const char *path) { void rtSetWorkingDirectory(const char *path) {
#ifdef _WIN32 #ifdef _WIN32
WCHAR wpath[MAX_PATH]; WCHAR wpath[MAX_PATH];
MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, path, -1, wpath, MAX_PATH); MultiByteToWideChar(CP_UTF8, MB_PRECOMPOSED, path, -1, wpath, MAX_PATH);
@ -24,7 +24,7 @@ void vySetWorkingDirectory(const char *path) {
#endif #endif
} }
uint64_t vyGetCurrentTimestamp(void) { uint64_t rtGetCurrentTimestamp(void) {
#ifdef _WIN32 #ifdef _WIN32
FILETIME ft; FILETIME ft;
GetSystemTimeAsFileTime(&ft); GetSystemTimeAsFileTime(&ft);
@ -34,11 +34,11 @@ uint64_t vyGetCurrentTimestamp(void) {
#endif #endif
} }
uint64_t vyGetFileModificationTimestamp(vy_file_id fid) { uint64_t rtGetFileModificationTimestamp(rt_file_id fid) {
#ifdef _WIN32 #ifdef _WIN32
const char *path = vyGetFilePath(fid); const char *path = rtGetFilePath(fid);
if (!path) { if (!path) {
vyLog("ASSETC", "Tried to get modification timestamp of unknown file."); rtLog("ASSETC", "Tried to get modification timestamp of unknown file.");
return 0; return 0;
} }
WCHAR wpath[MAX_PATH]; WCHAR wpath[MAX_PATH];
@ -52,34 +52,34 @@ uint64_t vyGetFileModificationTimestamp(vy_file_id fid) {
#endif #endif
} }
vy_result vyIterateDirectory(const char *path, void *user, vy_iterate_directory_cb_func iterate_cb) { rt_result rtIterateDirectory(const char *path, void *user, rt_iterate_directory_cb_func iterate_cb) {
#ifdef _WIN32 #ifdef _WIN32
vy_result res; rt_result res;
WCHAR wpath[MAX_PATH]; WCHAR wpath[MAX_PATH];
char wildcard_path[MAX_PATH]; char wildcard_path[MAX_PATH];
strncpy(wildcard_path, path, MAX_PATH); strncpy(wildcard_path, path, MAX_PATH);
strncat(wildcard_path, "\\*", MAX_PATH - strlen(path)); strncat(wildcard_path, "\\*", MAX_PATH - strlen(path));
res = vyUTF8ToWStr(wildcard_path, wpath, MAX_PATH); res = rtUTF8ToWStr(wildcard_path, wpath, MAX_PATH);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
WIN32_FIND_DATAW find; WIN32_FIND_DATAW find;
HANDLE h = FindFirstFileW(wpath, &find); HANDLE h = FindFirstFileW(wpath, &find);
if (h == INVALID_HANDLE_VALUE) if (h == INVALID_HANDLE_VALUE)
return VY_UNKNOWN_ERROR; return RT_UNKNOWN_ERROR;
do { do {
char utf8_file[MAX_PATH]; char utf8_file[MAX_PATH];
res = vyWStrToUTF8(find.cFileName, utf8_file, MAX_PATH); res = rtWStrToUTF8(find.cFileName, utf8_file, MAX_PATH);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
break; break;
vyIterateDirElementType type; rtIterateDirElementType type;
if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) if (find.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
type = VY_DIR_ELEMENT_TYPE_DIRECTORY; type = RT_DIR_ELEMENT_TYPE_DIRECTORY;
else else
type = VY_DIR_ELEMENT_TYPE_FILE; type = RT_DIR_ELEMENT_TYPE_FILE;
res = iterate_cb(utf8_file, type, user); res = iterate_cb(utf8_file, type, user);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
break; break;
} while (FindNextFileW(h, &find) != 0); } while (FindNextFileW(h, &find) != 0);
@ -88,14 +88,14 @@ vy_result vyIterateDirectory(const char *path, void *user, vy_iterate_directory_
#endif #endif
} }
vy_result vyCreateDirectory(const char *path) { rt_result rtCreateDirectory(const char *path) {
#ifdef _WIN32 #ifdef _WIN32
WCHAR wpath[MAX_PATH]; WCHAR wpath[MAX_PATH];
vy_result res = vyUTF8ToWStr(path, wpath, MAX_PATH); rt_result res = rtUTF8ToWStr(path, wpath, MAX_PATH);
if (res != VY_SUCCESS) if (res != RT_SUCCESS)
return res; return res;
if (!CreateDirectoryW(wpath, NULL)) if (!CreateDirectoryW(wpath, NULL))
res = VY_UNKNOWN_ERROR; res = RT_UNKNOWN_ERROR;
return res; return res;
#endif #endif
} }

View File

@ -1,27 +1,27 @@
#ifndef VY_ASSETC_UTILS_H #ifndef RT_ASSETC_UTILS_H
#define VY_ASSETC_UTILS_H #define RT_ASSETC_UTILS_H
#include <stdint.h> #include <stdint.h>
#include "runtime/file_tab.h" #include "runtime/file_tab.h"
size_t vyGetFileSize(const char *path); size_t rtGetFileSize(const char *path);
void vySetWorkingDirectory(const char *path); void rtSetWorkingDirectory(const char *path);
uint64_t vyGetCurrentTimestamp(void); uint64_t rtGetCurrentTimestamp(void);
uint64_t vyGetFileModificationTimestamp(vy_file_id fid); uint64_t rtGetFileModificationTimestamp(rt_file_id fid);
typedef enum { typedef enum {
VY_DIR_ELEMENT_TYPE_FILE, RT_DIR_ELEMENT_TYPE_FILE,
VY_DIR_ELEMENT_TYPE_DIRECTORY, RT_DIR_ELEMENT_TYPE_DIRECTORY,
} vyIterateDirElementType; } rtIterateDirElementType;
typedef vy_result vy_iterate_directory_cb_func(const char *name, vyIterateDirElementType type, void *user); typedef rt_result rt_iterate_directory_cb_func(const char *name, rtIterateDirElementType type, void *user);
vy_result vyIterateDirectory(const char *path, void *user, vy_iterate_directory_cb_func iterate_cb); rt_result rtIterateDirectory(const char *path, void *user, rt_iterate_directory_cb_func iterate_cb);
vy_result vyCreateDirectory(const char *path); rt_result rtCreateDirectory(const char *path);
#endif #endif