Remove fio
This commit is contained in:
		
							parent
							
								
									1a4a2109ca
								
							
						
					
					
						commit
						937ca92d9f
					
				@ -44,7 +44,6 @@ runtime_lib = library('vyrt',
 | 
			
		||||
  'src/runtime/runtime.h',
 | 
			
		||||
  'src/runtime/gfx.h',
 | 
			
		||||
  'src/runtime/renderer_api.h',
 | 
			
		||||
  'src/runtime/fio.h',
 | 
			
		||||
  'src/runtime/config.h',
 | 
			
		||||
  'src/runtime/threading.h',
 | 
			
		||||
  'src/runtime/app.h',
 | 
			
		||||
@ -61,7 +60,6 @@ runtime_lib = library('vyrt',
 | 
			
		||||
  'src/runtime/threading_mutex.c',
 | 
			
		||||
  'src/runtime/threading_thread.c',
 | 
			
		||||
  'src/runtime/threading_cond.c',
 | 
			
		||||
  'src/runtime/fio.c',
 | 
			
		||||
  'src/runtime/app.c',
 | 
			
		||||
  'src/runtime/dynamic_libs.c',
 | 
			
		||||
  'src/runtime/jobs.c',
 | 
			
		||||
 | 
			
		||||
@ -135,6 +135,7 @@ VY_DLLEXPORT int vyWin32Entry(HINSTANCE hInstance,
 | 
			
		||||
    DestroyWindow(wnd);
 | 
			
		||||
    UnregisterClassW(L"vyWndClass", hInstance);
 | 
			
		||||
 | 
			
		||||
    vyShutdownAIO();
 | 
			
		||||
    vyShutdownFIO();
 | 
			
		||||
 | 
			
		||||
    return 0;
 | 
			
		||||
 | 
			
		||||
@ -1,314 +0,0 @@
 | 
			
		||||
#include "fio.h"
 | 
			
		||||
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    #include <pthread.h>
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    #define WIN32_LEAN_AND_MEAN
 | 
			
		||||
    #include <Windows.h>
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#define FLAGS_FINISHED  0x001
 | 
			
		||||
#define FLAGS_RETRIEVED 0x002
 | 
			
		||||
#define FLAGS_IN_USE    0x004
 | 
			
		||||
typedef struct {
 | 
			
		||||
    vy_file_id fid;
 | 
			
		||||
    vy_file_buffer buffer;
 | 
			
		||||
    unsigned int flags;
 | 
			
		||||
} vy_file_op;
 | 
			
		||||
 | 
			
		||||
/* Ringbuffer of file io operations */
 | 
			
		||||
typedef struct {
 | 
			
		||||
    vy_file_op *ops;
 | 
			
		||||
    unsigned int size;
 | 
			
		||||
    unsigned int write_pos;
 | 
			
		||||
    unsigned int read_pos;
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_mutex_t mutex;
 | 
			
		||||
    pthread_cond_t pending_cond;
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    CRITICAL_SECTION critical_section;
 | 
			
		||||
    CONDITION_VARIABLE pending_cond;
 | 
			
		||||
#endif
 | 
			
		||||
} vy_fio_queue;
 | 
			
		||||
 | 
			
		||||
static vy_fio_queue _queue;
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
static pthread_t _thread;
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
static HANDLE _fio_thread     = NULL;
 | 
			
		||||
static HANDLE _fio_term_event = NULL;
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static bool InitFIOQueue(unsigned int size) {
 | 
			
		||||
    _queue.ops = calloc(size, sizeof(vy_file_op));
 | 
			
		||||
    if (!_queue.ops)
 | 
			
		||||
        return false;
 | 
			
		||||
    _queue.write_pos = 0;
 | 
			
		||||
    _queue.read_pos  = 0;
 | 
			
		||||
    _queue.size      = size;
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    if (pthread_cond_init(&_queue.pending_cond, NULL) != 0)
 | 
			
		||||
        return false;
 | 
			
		||||
    if (pthread_mutex_init(&_queue.mutex, NULL) != 0)
 | 
			
		||||
        return false;
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    if (!InitializeCriticalSectionAndSpinCount(&_queue.critical_section, 4000))
 | 
			
		||||
        return false;
 | 
			
		||||
    InitializeConditionVariable(&_queue.pending_cond);
 | 
			
		||||
#endif
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ShutdownFIOQueue(void) {
 | 
			
		||||
    for (unsigned int i = 0; i < _queue.size; ++i) {
 | 
			
		||||
        free(_queue.ops[i].buffer.data);
 | 
			
		||||
    }
 | 
			
		||||
    free(_queue.ops);
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_cond_destroy(&_queue.pending_cond);
 | 
			
		||||
    pthread_mutex_destroy(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    DeleteCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
static void *linuxFIOThreadProc(void *);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
static DWORD WINAPI win32FIOThreadProc(_In_ LPVOID);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT bool vyInitFIO(const vy_fio_config *config) {
 | 
			
		||||
    unsigned int queue_size = (config->queue_size) ? config->queue_size : 512;
 | 
			
		||||
    if (!InitFIOQueue(queue_size))
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    if (pthread_create(&_thread, NULL, linuxFIOThreadProc, NULL) != 0)
 | 
			
		||||
        return false;
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    _fio_term_event = CreateEventW(NULL, FALSE, FALSE, NULL);
 | 
			
		||||
    if (!_fio_term_event)
 | 
			
		||||
        return false;
 | 
			
		||||
    _fio_thread = CreateThread(NULL, 0, win32FIOThreadProc, NULL, 0, NULL);
 | 
			
		||||
    if (!_fio_thread)
 | 
			
		||||
        return false;
 | 
			
		||||
    SetThreadDescription(_fio_thread, L"FIO Thread");
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT void vyShutdownFIO(void) {
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_cancel(_thread);
 | 
			
		||||
    pthread_join(_thread, NULL);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    if (SetEvent(_fio_term_event)) {
 | 
			
		||||
        WakeAllConditionVariable(&_queue.pending_cond);
 | 
			
		||||
        WaitForSingleObject(_fio_thread, INFINITE);
 | 
			
		||||
        CloseHandle(_fio_thread);
 | 
			
		||||
        CloseHandle(_fio_term_event);
 | 
			
		||||
    } else {
 | 
			
		||||
        vyReportError("FIO", "Failed to signal the termination event.");
 | 
			
		||||
    }
 | 
			
		||||
#endif
 | 
			
		||||
    ShutdownFIOQueue();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT vy_fio_handle vyEnqueueRead(vy_file_id fid) {
 | 
			
		||||
    vy_fio_handle handle = 0;
 | 
			
		||||
 | 
			
		||||
    do {
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
        pthread_mutex_lock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
        EnterCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
        if (_queue.ops[_queue.write_pos].flags == 0 ||
 | 
			
		||||
            ((_queue.ops[_queue.write_pos].flags & FLAGS_FINISHED) != 0 &&
 | 
			
		||||
             (_queue.ops[_queue.write_pos].flags & FLAGS_RETRIEVED) != 0)) {
 | 
			
		||||
 | 
			
		||||
            _queue.ops[_queue.write_pos].fid   = fid;
 | 
			
		||||
            _queue.ops[_queue.write_pos].flags = FLAGS_IN_USE;
 | 
			
		||||
 | 
			
		||||
            handle           = _queue.write_pos + 1;
 | 
			
		||||
            _queue.write_pos = (_queue.write_pos + 1) % _queue.size;
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
            pthread_cond_signal(&_queue.pending_cond);
 | 
			
		||||
            pthread_mutex_unlock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
            LeaveCriticalSection(&_queue.critical_section);
 | 
			
		||||
            WakeAllConditionVariable(&_queue.pending_cond);
 | 
			
		||||
#endif
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
        pthread_mutex_unlock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
        LeaveCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
    } while (1);
 | 
			
		||||
 | 
			
		||||
    return handle;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT void vyAbortFIO(vy_fio_handle fio) {
 | 
			
		||||
    if (fio == 0)
 | 
			
		||||
        return;
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_mutex_lock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    EnterCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
    _queue.ops[fio - 1].flags = 0;
 | 
			
		||||
    if (_queue.ops[fio - 1].buffer.data) {
 | 
			
		||||
        free(_queue.ops[fio - 1].buffer.data);
 | 
			
		||||
        _queue.ops[fio - 1].buffer.size = 0;
 | 
			
		||||
    }
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_mutex_unlock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    LeaveCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT bool vyIsFIOFinished(vy_fio_handle fio) {
 | 
			
		||||
    if (fio == 0)
 | 
			
		||||
        return false;
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_mutex_lock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    EnterCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
    bool result = (_queue.ops[fio - 1].flags & FLAGS_FINISHED) != 0;
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_mutex_unlock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    LeaveCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT bool vyRetrieveReadBuffer(vy_fio_handle fio,
 | 
			
		||||
                                       vy_file_buffer *buffer) {
 | 
			
		||||
    if (fio == 0)
 | 
			
		||||
        return false;
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_mutex_lock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    EnterCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    bool is_finished = (_queue.ops[fio - 1].flags & FLAGS_FINISHED) != 0;
 | 
			
		||||
    if (is_finished) {
 | 
			
		||||
        size_t sz    = _queue.ops[fio - 1].buffer.size;
 | 
			
		||||
        buffer->data = malloc(sz);
 | 
			
		||||
        if (!buffer->data)
 | 
			
		||||
            return false;
 | 
			
		||||
        buffer->size = sz;
 | 
			
		||||
        memcpy(buffer->data, _queue.ops[fio - 1].buffer.data, sz);
 | 
			
		||||
        buffer->flags = _queue.ops[fio - 1].buffer.flags;
 | 
			
		||||
        _queue.ops[fio - 1].flags |= FLAGS_RETRIEVED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
    pthread_mutex_unlock(&_queue.mutex);
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
    LeaveCriticalSection(&_queue.critical_section);
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
    return is_finished;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT void vyFreeFileBuffer(vy_file_buffer buffer) {
 | 
			
		||||
    free(buffer.data);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static void ProcessRead(vy_file_op *op) {
 | 
			
		||||
    const char *path = vyGetFilePath(op->fid);
 | 
			
		||||
    if (!path) {
 | 
			
		||||
        op->flags |= FLAGS_FINISHED;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    op->buffer.data  = NULL;
 | 
			
		||||
    op->buffer.size  = 0;
 | 
			
		||||
    op->buffer.flags = 0;
 | 
			
		||||
 | 
			
		||||
    FILE *file = fopen(path, "rb");
 | 
			
		||||
    if (!file) {
 | 
			
		||||
        op->flags |= FLAGS_FINISHED;
 | 
			
		||||
        op->buffer.flags = VY_FILE_BUFFER_FLAG_FILE_NOT_FOUND;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    fseek(file, 0, SEEK_END);
 | 
			
		||||
    long fsz = ftell(file);
 | 
			
		||||
    fseek(file, 0, SEEK_SET);
 | 
			
		||||
 | 
			
		||||
    op->buffer.data = malloc(fsz);
 | 
			
		||||
    op->buffer.size = (size_t)fsz;
 | 
			
		||||
    if (fread(op->buffer.data, fsz, 1, file) != 1) {
 | 
			
		||||
        free(op->buffer.data);
 | 
			
		||||
        op->buffer.data  = NULL;
 | 
			
		||||
        op->buffer.size  = 0;
 | 
			
		||||
        op->buffer.flags = VY_FILE_BUFFER_FLAG_READ_FAILED;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    fclose(file);
 | 
			
		||||
    op->flags |= FLAGS_FINISHED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#ifdef __linux__
 | 
			
		||||
static void *linuxFIOThreadProc(void *_param) {
 | 
			
		||||
    while (true) {
 | 
			
		||||
        pthread_mutex_lock(&_queue.mutex);
 | 
			
		||||
        while (_queue.write_pos == _queue.read_pos) {
 | 
			
		||||
            pthread_cond_wait(&_queue.pending_cond, &_queue.mutex);
 | 
			
		||||
        }
 | 
			
		||||
        ProcessRead(&_queue.ops[_queue.read_pos]);
 | 
			
		||||
        _queue.read_pos = (_queue.read_pos + 1) % _queue.size;
 | 
			
		||||
        pthread_mutex_unlock(&_queue.mutex);
 | 
			
		||||
    }
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
#elif defined(_WIN32)
 | 
			
		||||
static DWORD WINAPI win32FIOThreadProc(_In_ LPVOID lpParam) {
 | 
			
		||||
    VY_UNUSED(lpParam);
 | 
			
		||||
 | 
			
		||||
    bool keep_running = true;
 | 
			
		||||
    while (keep_running) {
 | 
			
		||||
        EnterCriticalSection(&_queue.critical_section);
 | 
			
		||||
        while (_queue.read_pos == _queue.write_pos && keep_running) {
 | 
			
		||||
            SleepConditionVariableCS(&_queue.pending_cond,
 | 
			
		||||
                                     &_queue.critical_section,
 | 
			
		||||
                                     INFINITE);
 | 
			
		||||
            DWORD wfs = WaitForSingleObject(_fio_term_event, 0);
 | 
			
		||||
            if (wfs != WAIT_FAILED) {
 | 
			
		||||
                keep_running = wfs != WAIT_OBJECT_0;
 | 
			
		||||
            } else {
 | 
			
		||||
                vyLog("FIO", "ThreadProc wait error: %d", GetLastError());
 | 
			
		||||
                keep_running = false;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
        /* It's possible that we were awoken during application shutdown. */
 | 
			
		||||
        if (_queue.write_pos != _queue.read_pos) {
 | 
			
		||||
            ProcessRead(&_queue.ops[_queue.read_pos]);
 | 
			
		||||
            _queue.read_pos = (_queue.read_pos + 1) % _queue.size;
 | 
			
		||||
        }
 | 
			
		||||
        LeaveCriticalSection(&_queue.critical_section);
 | 
			
		||||
    }
 | 
			
		||||
    vyLog("FIO", "Exit FIO thread");
 | 
			
		||||
    return 0;
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
@ -1,49 +0,0 @@
 | 
			
		||||
#ifndef VY_FIO_H
 | 
			
		||||
#define VY_FIO_H
 | 
			
		||||
 | 
			
		||||
#include <stdbool.h>
 | 
			
		||||
#include <stddef.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
#include "runtime.h"
 | 
			
		||||
#include "file_tab.h"
 | 
			
		||||
 | 
			
		||||
enum {
 | 
			
		||||
    VY_FILE_BUFFER_FLAG_FILE_NOT_FOUND = 0x1,
 | 
			
		||||
    VY_FILE_BUFFER_FLAG_READ_FAILED    = 0x2,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    void *data;
 | 
			
		||||
    size_t size;
 | 
			
		||||
    uint32_t flags;
 | 
			
		||||
} vy_file_buffer;
 | 
			
		||||
 | 
			
		||||
static inline bool vyWasFileBufferSuccessful(const vy_file_buffer *fb) {
 | 
			
		||||
    return fb->flags == 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
typedef unsigned int vy_fio_handle;
 | 
			
		||||
 | 
			
		||||
typedef struct {
 | 
			
		||||
    unsigned int queue_size;
 | 
			
		||||
    unsigned int max_file_count;
 | 
			
		||||
} vy_fio_config;
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT bool vyInitFIO(const vy_fio_config *config);
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT void vyShutdownFIO(void);
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT vy_fio_handle vyEnqueueRead(vy_file_id fid);
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT void vyAbortFIO(vy_fio_handle fio);
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT bool vyIsFIOFinished(vy_fio_handle fio);
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT bool vyRetrieveReadBuffer(vy_fio_handle fio,
 | 
			
		||||
                                       vy_file_buffer *buffer);
 | 
			
		||||
 | 
			
		||||
VY_DLLEXPORT void vyFreeFileBuffer(vy_file_buffer buffer);
 | 
			
		||||
 | 
			
		||||
#endif
 | 
			
		||||
@ -6,7 +6,7 @@
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "fio.h"
 | 
			
		||||
#include "aio.h"
 | 
			
		||||
#include "gfx.h"
 | 
			
		||||
#include "handles.h"
 | 
			
		||||
#include "renderer_api.h"
 | 
			
		||||
@ -264,6 +264,7 @@ static const vy_parsed_stmt *FindStatement(const vy_parse_state *state,
 | 
			
		||||
    return NULL;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#if 0
 | 
			
		||||
static vy_fio_handle DispatchFileRead(vy_text_span path) {
 | 
			
		||||
    vy_file_id fid = vyAddFileFromSpan(path);
 | 
			
		||||
    if (fid == 0)
 | 
			
		||||
@ -289,122 +290,15 @@ static vy_fio_handle DispatchShaderRead(const char *shader,
 | 
			
		||||
    }
 | 
			
		||||
    return DispatchFileRead(path->value);
 | 
			
		||||
}
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
static vy_gfx_pipeline_handle CreatePipeline(vy_parse_state *state,
 | 
			
		||||
                                             const char *file_path,
 | 
			
		||||
                                             unsigned int root_list) {
 | 
			
		||||
    /* Process the data */
 | 
			
		||||
    vy_fio_handle vertex_read =
 | 
			
		||||
        DispatchShaderRead("vertex", state, root_list, file_path);
 | 
			
		||||
    vy_fio_handle fragment_read =
 | 
			
		||||
        DispatchShaderRead("fragment", state, root_list, file_path);
 | 
			
		||||
    vy_fio_handle compute_read =
 | 
			
		||||
        DispatchShaderRead("compute", state, root_list, file_path);
 | 
			
		||||
    vy_aio_handle reads[3];
 | 
			
		||||
    vy_load_batch read_batch = {.num_loads = 0};
 | 
			
		||||
 | 
			
		||||
    if (compute_read) {
 | 
			
		||||
        if (vertex_read || fragment_read) {
 | 
			
		||||
            vyReportError("GFX",
 | 
			
		||||
                          "A shader program can not contain a compute "
 | 
			
		||||
                          "shader and graphics shaders: %s",
 | 
			
		||||
                          file_path);
 | 
			
		||||
            vyAbortFIO(vertex_read);
 | 
			
		||||
            vyAbortFIO(fragment_read);
 | 
			
		||||
            vyAbortFIO(compute_read);
 | 
			
		||||
            return (vy_gfx_pipeline_handle){0};
 | 
			
		||||
        }
 | 
			
		||||
        while (!vyIsFIOFinished(compute_read)) {
 | 
			
		||||
            /* wait */
 | 
			
		||||
        }
 | 
			
		||||
        vy_file_buffer compute_code;
 | 
			
		||||
        if (!vyRetrieveReadBuffer(compute_read, &compute_code) ||
 | 
			
		||||
            !vyWasFileBufferSuccessful(&compute_code)) {
 | 
			
		||||
            vyReportError("GFX",
 | 
			
		||||
                          "Failed to load compute shader required by: %s",
 | 
			
		||||
                          file_path);
 | 
			
		||||
            return (vy_gfx_pipeline_handle){0};
 | 
			
		||||
        }
 | 
			
		||||
        vy_compute_pipeline_info info;
 | 
			
		||||
        info.compute_source        = compute_code.data;
 | 
			
		||||
        info.compute_source_length = compute_code.size;
 | 
			
		||||
        vy_gfx_pipeline_handle pipeline =
 | 
			
		||||
            g_renderer.CompileComputePipeline(&info);
 | 
			
		||||
        vyFreeFileBuffer(compute_code);
 | 
			
		||||
        return pipeline;
 | 
			
		||||
    } else if (vertex_read || fragment_read) {
 | 
			
		||||
        if (compute_read) {
 | 
			
		||||
            vyReportError("GFX",
 | 
			
		||||
                          "A shader program can not contain a compute "
 | 
			
		||||
                          "shader and graphics shaders: %s",
 | 
			
		||||
                          file_path);
 | 
			
		||||
            vyAbortFIO(vertex_read);
 | 
			
		||||
            vyAbortFIO(fragment_read);
 | 
			
		||||
            vyAbortFIO(compute_read);
 | 
			
		||||
            return (vy_gfx_pipeline_handle){0};
 | 
			
		||||
        }
 | 
			
		||||
        if (!vertex_read || !fragment_read) {
 | 
			
		||||
            vyReportError("GFX",
 | 
			
		||||
                          "A shader program must contain at least a vertex and "
 | 
			
		||||
                          "a fragment shader: %s",
 | 
			
		||||
                          file_path);
 | 
			
		||||
            vyAbortFIO(vertex_read);
 | 
			
		||||
            vyAbortFIO(fragment_read);
 | 
			
		||||
            vyAbortFIO(compute_read);
 | 
			
		||||
            return (vy_gfx_pipeline_handle){0};
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        vy_graphics_pipeline_info info;
 | 
			
		||||
        vy_file_buffer vertex_code   = {NULL, 0};
 | 
			
		||||
        vy_file_buffer fragment_code = {NULL, 0};
 | 
			
		||||
 | 
			
		||||
        int remaining = 2;
 | 
			
		||||
        while (remaining > 0) {
 | 
			
		||||
            if (vyIsFIOFinished(vertex_read)) {
 | 
			
		||||
                if (!vyRetrieveReadBuffer(vertex_read, &vertex_code) ||
 | 
			
		||||
                    !vyWasFileBufferSuccessful(&vertex_code)) {
 | 
			
		||||
                    vyReportError(
 | 
			
		||||
                        "GFX",
 | 
			
		||||
                        "Failed to load vertex shader required by: %s",
 | 
			
		||||
                        file_path);
 | 
			
		||||
                    vyFreeFileBuffer(fragment_code);
 | 
			
		||||
                    return (vy_gfx_pipeline_handle){0};
 | 
			
		||||
                }
 | 
			
		||||
                info.vertex_source        = vertex_code.data;
 | 
			
		||||
                info.vertex_source_length = vertex_code.size;
 | 
			
		||||
                --remaining;
 | 
			
		||||
                vertex_read = 0;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (vyIsFIOFinished(fragment_read)) {
 | 
			
		||||
                if (!vyRetrieveReadBuffer(fragment_read, &fragment_code) ||
 | 
			
		||||
                    !vyWasFileBufferSuccessful(&fragment_code)) {
 | 
			
		||||
                    vyReportError(
 | 
			
		||||
                        "GFX",
 | 
			
		||||
                        "Failed to load fragment shader required by: %s",
 | 
			
		||||
                        file_path);
 | 
			
		||||
                    vyFreeFileBuffer(vertex_code);
 | 
			
		||||
                    return (vy_gfx_pipeline_handle){0};
 | 
			
		||||
                }
 | 
			
		||||
                info.fragment_source        = fragment_code.data;
 | 
			
		||||
                info.fragment_source_length = fragment_code.size;
 | 
			
		||||
                --remaining;
 | 
			
		||||
                fragment_read = 0;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        vy_gfx_pipeline_handle pipeline =
 | 
			
		||||
            g_renderer.CompileGraphicsPipeline(&info);
 | 
			
		||||
        vyFreeFileBuffer(vertex_code);
 | 
			
		||||
        vyFreeFileBuffer(fragment_code);
 | 
			
		||||
        return pipeline;
 | 
			
		||||
    } else if (!compute_read && !vertex_read && !fragment_read) {
 | 
			
		||||
        vyReportError("GFX",
 | 
			
		||||
                      "Either \"compute\" or \"vertex\" and \"fragment\" "
 | 
			
		||||
                      "are required in %s",
 | 
			
		||||
                      file_path);
 | 
			
		||||
        vyAbortFIO(vertex_read);
 | 
			
		||||
        vyAbortFIO(fragment_read);
 | 
			
		||||
        vyAbortFIO(compute_read);
 | 
			
		||||
    }
 | 
			
		||||
    return (vy_gfx_pipeline_handle){0};
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -495,16 +389,16 @@ static bool ParseBindings(vy_parse_state *state,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
static bool
 | 
			
		||||
ParseShaderFile(vy_file_id fid, vy_file_buffer fbuf, vy_shader *shader) {
 | 
			
		||||
ParseShaderFile(vy_file_id fid, const char *text, size_t length, vy_shader *shader) {
 | 
			
		||||
    /* This is the grammar for shader files:
 | 
			
		||||
     * <stmt-list> ::= <stmt>*
 | 
			
		||||
     * <stmt> ::= <attribute> ( ( <value> ';' ) | ( '{' <stmt-list> '}' ) )
 | 
			
		||||
     * <attribute> ::= [:alnum:]*
 | 
			
		||||
     * <value>:: = [:alnum:]* */
 | 
			
		||||
    const char *file_path = vyGetFilePath(fid);
 | 
			
		||||
    vy_parse_state state  = {.text                    = (const char *)fbuf.data,
 | 
			
		||||
    vy_parse_state state  = {.text                    = text,
 | 
			
		||||
                             .at                      = 0,
 | 
			
		||||
                             .length                  = fbuf.size,
 | 
			
		||||
                             .length                  = length,
 | 
			
		||||
                             .line                    = 1,
 | 
			
		||||
                             .file                    = file_path,
 | 
			
		||||
                             .statements              = NULL,
 | 
			
		||||
@ -572,30 +466,37 @@ out:
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool vyLoadShaders(const char **paths, vy_shader *shaders, unsigned int count) {
 | 
			
		||||
    vy_fio_handle fios[64];
 | 
			
		||||
    vy_aio_handle aios[64];
 | 
			
		||||
    vy_file_id fids[64];
 | 
			
		||||
    for (unsigned int i = 0; i < count; i += 64) {
 | 
			
		||||
        unsigned int chunk_size = count - i;
 | 
			
		||||
        if (chunk_size > 64)
 | 
			
		||||
            chunk_size = 64;
 | 
			
		||||
        vy_load_batch chunk;
 | 
			
		||||
        chunk.num_loads = chunk_size;
 | 
			
		||||
        for (unsigned int j = 0; j < chunk_size; ++j) {
 | 
			
		||||
            vy_file_id fid = vyAddFile(paths[i + j]);
 | 
			
		||||
            if (!fid)
 | 
			
		||||
                return false;
 | 
			
		||||
            fids[j] = fid;
 | 
			
		||||
            fios[j] = vyEnqueueRead(fid);
 | 
			
		||||
 | 
			
		||||
            /* Setup the chunk
 | 
			
		||||
            chunk.loads[j].offset = 0;
 | 
			
		||||
            chunk.loads[j].file   = fid;
 | 
			
		||||
            chunk.loads[j].
 | 
			
		||||
 | 
			
		||||
            */
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        unsigned int remaining = chunk_size;
 | 
			
		||||
        while (remaining > 0) {
 | 
			
		||||
            for (unsigned int j = 0; j < chunk_size; ++j) {
 | 
			
		||||
                if (vyIsFIOFinished(fios[j])) {
 | 
			
		||||
                    vy_file_buffer fbuf;
 | 
			
		||||
                    if (!vyRetrieveReadBuffer(fios[j], &fbuf)) {
 | 
			
		||||
                        return false;
 | 
			
		||||
                    }
 | 
			
		||||
                switch (vyGetAIOState(aios[j])) {
 | 
			
		||||
                case VY_AIO_STATE_FINISHED:
 | 
			
		||||
                    /*
 | 
			
		||||
                    ParseShaderFile(fids[j], fbuf, &shaders[i + j]);
 | 
			
		||||
                    vyFreeFileBuffer(fbuf);
 | 
			
		||||
                    */
 | 
			
		||||
                    --remaining;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user