diff --git a/Examples/OpenGL/main.c b/Examples/OpenGL/main.c index 4bef1d8..54dbc5c 100644 --- a/Examples/OpenGL/main.c +++ b/Examples/OpenGL/main.c @@ -4,7 +4,9 @@ #include #include -#define WGSL_SOURCE(...) #__VA_ARGS__ +#define GLSL_SOURCE(...) #__VA_ARGS__ + +#define BUFFER_SIZE (256 * sizeof(uint32_t)) void DebugCallBack(PulseDebugMessageSeverity severity, const char* message) { @@ -28,6 +30,13 @@ int main(int ac, char** av) PulseSetDebugCallback(backend, DebugCallBack); PulseDevice device = PulseCreateDevice(backend, NULL, 0); + PulseBufferCreateInfo buffer_create_info = { 0 }; + buffer_create_info.size = BUFFER_SIZE; + buffer_create_info.usage = PULSE_BUFFER_USAGE_STORAGE_READ | PULSE_BUFFER_USAGE_STORAGE_WRITE | PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD; + PulseBuffer buffer = PulseCreateBuffer(device, &buffer_create_info); + + PulseDestroyBuffer(device, buffer); + PulseDestroyDevice(device); PulseUnloadBackend(backend); printf("Successfully executed Pulse example using %s !\n", backend_type == PULSE_BACKEND_OPENGL ? "OpenGL" : "OpenGL ES"); diff --git a/Sources/Backends/OpenGL/EGL/EGLFunctions.h b/Sources/Backends/OpenGL/EGL/EGLFunctions.h index 93dff7e..44e2929 100644 --- a/Sources/Backends/OpenGL/EGL/EGLFunctions.h +++ b/Sources/Backends/OpenGL/EGL/EGLFunctions.h @@ -29,4 +29,3 @@ PULSE_EGL_FUNCTION(eglTerminate, PFNEGLTERMINATEPROC) PULSE_EGL_FUNCTION_EXT(eglQueryDevicesEXT, PFNEGLQUERYDEVICESEXTPROC) PULSE_EGL_FUNCTION_EXT(eglGetPlatformDisplayEXT, PFNEGLGETPLATFORMDISPLAYEXTPROC) -PULSE_EGL_FUNCTION_EXT(eglQueryDeviceStringEXT, PFNEGLQUERYDEVICESTRINGEXTPROC) diff --git a/Sources/Backends/OpenGL/EGL/EGLInstance.c b/Sources/Backends/OpenGL/EGL/EGLInstance.c index 3c1a932..9166126 100644 --- a/Sources/Backends/OpenGL/EGL/EGLInstance.c +++ b/Sources/Backends/OpenGL/EGL/EGLInstance.c @@ -62,6 +62,63 @@ static bool EGLLoadFunctions(EGLInstance* instance) return true; } +bool EGLLoadOpenGLContext(EGLInstance* instance, EGLDisplay* display, EGLDeviceEXT device, EGLConfig* config, EGLSurface* surface, EGLContext* context, bool es_context) +{ + if(device != EGL_NO_DEVICE_EXT) + *display = instance->eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, device, PULSE_NULLPTR); + else + *display = instance->eglGetDisplay(EGL_DEFAULT_DISPLAY); + if(display == EGL_NO_DISPLAY || !instance->eglInitialize(*display, PULSE_NULLPTR, PULSE_NULLPTR)) + return false; + + EGLint attribs[] = { + EGL_RENDERABLE_TYPE, es_context ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_BIT, + EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, + EGL_NONE + }; + EGLint num_configs; + instance->eglChooseConfig(*display, attribs, config, 1, &num_configs); + instance->eglBindAPI(es_context ? EGL_OPENGL_ES_API : EGL_OPENGL_API); + EGLint pbufferAttribs[] = { + EGL_WIDTH, 1, + EGL_HEIGHT, 1, + EGL_NONE + }; + *surface = instance->eglCreatePbufferSurface(*display, *config, pbufferAttribs); + if(es_context) + { + EGLint ctx_attribs[] = { + EGL_CONTEXT_CLIENT_VERSION, 3, + EGL_NONE + }; + *context = instance->eglCreateContext(*display, *config, EGL_NO_CONTEXT, ctx_attribs); + } + else + { + EGLint ctx_attribs[] = { + EGL_CONTEXT_MAJOR_VERSION, 4, + EGL_CONTEXT_MINOR_VERSION_KHR, 3, + EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, + EGL_NONE + }; + *context = instance->eglCreateContext(*display, *config, EGL_NO_CONTEXT, ctx_attribs); + } + if(*context == EGL_NO_CONTEXT) + { + instance->eglDestroySurface(*display, *surface); + instance->eglTerminate(*display); + return false; + } + if(!instance->eglMakeCurrent(*display, *surface, *surface, *context)) + { + instance->eglDestroySurface(*display, *surface); + instance->eglDestroyContext(display, *context); + instance->eglTerminate(*display); + return false; + } + return true; +} + bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count, bool es_context) { PULSE_CHECK_PTR_RETVAL(instance, false); @@ -71,10 +128,9 @@ bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint3 instance->device = EGL_NO_DEVICE_EXT; - if(instance->eglGetPlatformDisplayEXT && instance->eglQueryDevicesEXT && instance->eglQueryDeviceStringEXT) + if(instance->eglGetPlatformDisplayEXT && instance->eglQueryDevicesEXT) { EGLDeviceEXT* devices = PULSE_NULLPTR; - EGLDeviceEXT chosen_one = EGL_NO_DEVICE_EXT; int32_t device_count; uint64_t best_device_score = 0; @@ -85,50 +141,12 @@ bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint3 for(int32_t i = 0; i < device_count; i++) { - EGLDisplay display = instance->eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, devices[i], PULSE_NULLPTR); - if(display == EGL_NO_DISPLAY || !instance->eglInitialize(display, PULSE_NULLPTR, PULSE_NULLPTR)) - continue; - - EGLint attribs[] = { - EGL_RENDERABLE_TYPE, es_context ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_BIT, - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_NONE - }; - EGLint num_configs; + EGLDisplay display; EGLConfig config; - instance->eglChooseConfig(display, attribs, &config, 1, &num_configs); - instance->eglBindAPI(es_context ? EGL_OPENGL_ES_API : EGL_OPENGL_API); - EGLint pbufferAttribs[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_NONE - }; - EGLSurface surface = instance->eglCreatePbufferSurface(display, config, pbufferAttribs); + EGLSurface surface; EGLContext context; - if(es_context) - { - EGLint ctx_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 3, - EGL_NONE - }; - context = instance->eglCreateContext(display, config, EGL_NO_CONTEXT, ctx_attribs); - } - else - { - EGLint ctx_attribs[] = { - EGL_CONTEXT_MAJOR_VERSION, 4, - EGL_CONTEXT_MINOR_VERSION_KHR, 3, - EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, - EGL_NONE - }; - context = instance->eglCreateContext(display, config, EGL_NO_CONTEXT, ctx_attribs); - } - if(context != EGL_NO_CONTEXT && !instance->eglMakeCurrent(display, surface, surface, context)) - { - instance->eglDestroySurface(display, surface); - instance->eglTerminate(display); + if(!EGLLoadOpenGLContext(instance, &display, devices[i], &config, &surface, &context, es_context)) continue; - } PFNGLGETINTEGERI_VPROC glGetIntegeri_v = (PFNGLGETINTEGERI_VPROC)instance->eglGetProcAddress("glGetIntegeri_v"); PFNGLGETINTEGERVPROC glGetIntegerv = (PFNGLGETINTEGERVPROC)instance->eglGetProcAddress("glGetIntegerv"); @@ -145,14 +163,11 @@ bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint3 // Check for forbiden devices { - char* hash_string = (char*)calloc(1024, 1024); - snprintf(hash_string, 1024 * 1024, "%s|%s|", glGetString(GL_VENDOR), glGetString(GL_RENDERER)); + uint32_t device_id = PulseHashString((const char*)glGetString(GL_VENDOR)); + device_id = PulseHashCombine(device_id, PulseHashString((const char*)glGetString(GL_RENDERER))); GLint gl_extension_count = 0; - glGetIntegerv(GL_NUM_EXTENSIONS, &gl_extension_count); for(int i = 0; i < gl_extension_count; i++) - snprintf(hash_string, 1024 * 1024 - strlen(hash_string), "%s|", glGetStringi(GL_EXTENSIONS, i)); - uint32_t device_id = PulseHashString(hash_string); - free(hash_string); + device_id = PulseHashCombine(device_id, PulseHashString((const char*)glGetStringi(GL_EXTENSIONS, i))); for(uint32_t j = 0; j < forbiden_devices_count; j++) { @@ -198,54 +213,12 @@ bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint3 if(current_device_score > best_device_score) { best_device_score = current_device_score; - chosen_one = devices[i]; + instance->device = devices[i]; } } - - instance->display = instance->eglGetPlatformDisplayEXT(EGL_PLATFORM_DEVICE_EXT, chosen_one, PULSE_NULLPTR); } - else - instance->display = instance->eglGetDisplay(EGL_DEFAULT_DISPLAY); - PULSE_CHECK_PTR_RETVAL(instance->display, false); - instance->eglInitialize(instance->display, PULSE_NULLPTR, PULSE_NULLPTR); - EGLint attribs[] = { - EGL_RENDERABLE_TYPE, es_context ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_BIT, - EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, - EGL_NONE - }; - EGLint num_configs; - instance->eglChooseConfig(instance->display, attribs, &instance->config, 1, &num_configs); - instance->eglBindAPI(es_context ? EGL_OPENGL_ES_API : EGL_OPENGL_API); - if(es_context) - { - EGLint ctx_attribs[] = { - EGL_CONTEXT_CLIENT_VERSION, 3, - EGL_NONE - }; - instance->context = instance->eglCreateContext(instance->display, instance->config, EGL_NO_CONTEXT, ctx_attribs); - } - else - { - EGLint ctx_attribs[] = { - EGL_CONTEXT_MAJOR_VERSION, 4, - EGL_CONTEXT_MINOR_VERSION_KHR, 3, - EGL_CONTEXT_OPENGL_PROFILE_MASK, EGL_CONTEXT_OPENGL_CORE_PROFILE_BIT, - EGL_NONE - }; - instance->context = instance->eglCreateContext(instance->display, instance->config, EGL_NO_CONTEXT, ctx_attribs); - } - PULSE_CHECK_PTR_RETVAL(instance->context, false); - - EGLint pbufferAttribs[] = { - EGL_WIDTH, 1, - EGL_HEIGHT, 1, - EGL_NONE - }; - instance->surface = instance->eglCreatePbufferSurface(instance->display, instance->config, pbufferAttribs); - PULSE_CHECK_PTR_RETVAL(instance->surface, false); - - return instance->eglMakeCurrent(instance->display, instance->surface, instance->surface, instance->context); + return EGLLoadOpenGLContext(instance, &instance->display, instance->device, &instance->config, &instance->surface, &instance->context, es_context); } void EGLUnloadInstance(EGLInstance* instance) diff --git a/Sources/Backends/OpenGL/OpenGLBuffer.c b/Sources/Backends/OpenGL/OpenGLBuffer.c index 08c80e0..1b06f48 100644 --- a/Sources/Backends/OpenGL/OpenGLBuffer.c +++ b/Sources/Backends/OpenGL/OpenGLBuffer.c @@ -2,31 +2,81 @@ // This file is part of "Pulse" // For conditions of distribution and use, see copyright notice in LICENSE +#include + #include #include "../../PulseInternal.h" #include "OpenGLBuffer.h" +#include "OpenGLDevice.h" +#include "OpenGLCommandList.h" PulseBuffer OpenGLCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos) { + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + PulseBufferHandler* buffer = (PulseBufferHandler*)calloc(1, sizeof(PulseBufferHandler)); + PULSE_CHECK_ALLOCATION_RETVAL(buffer, PULSE_NULL_HANDLE); + + OpenGLBuffer* opengl_buffer = (OpenGLBuffer*)calloc(1, sizeof(OpenGLBuffer)); + PULSE_CHECK_ALLOCATION_RETVAL(opengl_buffer, PULSE_NULL_HANDLE); + + buffer->device = device; + buffer->driver_data = opengl_buffer; + buffer->size = create_infos->size; + buffer->usage = create_infos->usage; + + opengl_device->glGenBuffers(device, 1, &opengl_buffer->buffer); + + return buffer; } bool OpenGLMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data) { + OpenGLBuffer* opengl_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer, OpenGLBuffer*); + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer->device, OpenGLDevice*); + opengl_device->glBindBuffer(buffer->device, GL_SHADER_STORAGE_BUFFER, opengl_buffer->buffer); + *data = opengl_device->glMapBufferRange(buffer->device, GL_SHADER_STORAGE_BUFFER, mode == PULSE_MAP_READ ? GL_READ_ONLY : GL_WRITE_ONLY, 0, buffer->size); + return *data != PULSE_NULLPTR; } void OpenGLUnmapBuffer(PulseBuffer buffer) { + OpenGLBuffer* opengl_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer, OpenGLBuffer*); + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer->device, OpenGLDevice*); + opengl_device->glBindBuffer(buffer->device, GL_SHADER_STORAGE_BUFFER, opengl_buffer->buffer); + opengl_device->glUnmapBuffer(buffer->device, GL_SHADER_STORAGE_BUFFER); } bool OpenGLCopyBufferToBuffer(PulseCommandList cmd, const PulseBufferRegion* src, const PulseBufferRegion* dst) { + OpenGLCommand command = { 0 }; + command.type = OPENGL_COMMAND_COPY_BUFFER_TO_BUFFER; + command.CopyBufferToBuffer.src = (PulseBufferRegion*)malloc(sizeof(PulseBufferRegion)); + command.CopyBufferToBuffer.dst = (PulseBufferRegion*)malloc(sizeof(PulseBufferRegion)); + memcpy((void*)command.CopyBufferToBuffer.src, src, sizeof(PulseBufferRegion)); + memcpy((void*)command.CopyBufferToBuffer.dst, dst, sizeof(PulseBufferRegion)); + OpenGLQueueCommand(cmd, command); + return true; } bool OpenGLCopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion* src, const PulseImageRegion* dst) { + OpenGLCommand command = { 0 }; + command.type = OPENGL_COMMAND_COPY_BUFFER_TO_IMAGE; + command.CopyBufferToImage.src = (PulseBufferRegion*)malloc(sizeof(PulseBufferRegion)); + command.CopyBufferToImage.dst = (PulseImageRegion*)malloc(sizeof(PulseImageRegion)); + memcpy((void*)command.CopyBufferToImage.src, src, sizeof(PulseBufferRegion)); + memcpy((void*)command.CopyBufferToImage.dst, dst, sizeof(PulseImageRegion)); + OpenGLQueueCommand(cmd, command); + return true; } void OpenGLDestroyBuffer(PulseDevice device, PulseBuffer buffer) { + OpenGLBuffer* opengl_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer, OpenGLBuffer*); + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + opengl_device->glDeleteBuffers(device, 1, &opengl_buffer->buffer); + free(opengl_buffer); + free(buffer); } diff --git a/Sources/Backends/OpenGL/OpenGLBuffer.h b/Sources/Backends/OpenGL/OpenGLBuffer.h index 9ccfb90..e5ae338 100644 --- a/Sources/Backends/OpenGL/OpenGLBuffer.h +++ b/Sources/Backends/OpenGL/OpenGLBuffer.h @@ -12,6 +12,7 @@ typedef struct OpenGLBuffer { + GLuint buffer; } OpenGLBuffer; PulseBuffer OpenGLCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos); diff --git a/Sources/Backends/OpenGL/OpenGLCommandList.c b/Sources/Backends/OpenGL/OpenGLCommandList.c index 17a3105..99300bc 100644 --- a/Sources/Backends/OpenGL/OpenGLCommandList.c +++ b/Sources/Backends/OpenGL/OpenGLCommandList.c @@ -8,10 +8,48 @@ #include "OpenGL.h" #include "OpenGLCommandList.h" +static void OpenGLCommandsRunner(PulseCommandList cmd) +{ + PULSE_CHECK_PTR(cmd); + + OpenGLCommandList* opengl_cmd = OPENGL_RETRIEVE_DRIVER_DATA_AS(cmd, OpenGLCommandList*); + PULSE_CHECK_PTR(opengl_cmd); + + for(uint32_t i = 0; i < opengl_cmd->commands_count; i++) + { + OpenGLCommand* command = &opengl_cmd->commands[i]; + switch(command->type) + { + case OPENGL_COMMAND_COPY_BUFFER_TO_BUFFER: OpenGLCommandCopyBufferToBuffer(command); break; + case OPENGL_COMMAND_COPY_BUFFER_TO_IMAGE: break; + case OPENGL_COMMAND_COPY_IMAGE_TO_BUFFER: break; + case OPENGL_COMMAND_DISPATCH: OpenGLCommandDispatch(command); break; + case OPENGL_COMMAND_DISPATCH_INDIRECT: break; + + default: break; + } + } + + if(opengl_cmd->fence != PULSE_NULL_HANDLE) + { + OpenGLFence* fence = OPENGL_RETRIEVE_DRIVER_DATA_AS(opengl_cmd->fence, OpenGLFence*); + atomic_store(&fence->signal, true); + } + cmd->state = PULSE_COMMAND_LIST_STATE_READY; +} + PulseCommandList OpenGLRequestCommandList(PulseDevice device, PulseCommandListUsage usage) { } +void OpenGLQueueCommand(PulseCommandList cmd, OpenGLCommand command) +{ + OpenGLCommandList* opengl_cmd = OPENGL_RETRIEVE_DRIVER_DATA_AS(cmd, OpenGLCommandList*); + PULSE_EXPAND_ARRAY_IF_NEEDED(opengl_cmd->commands, OpenGLCommand, opengl_cmd->commands_count, opengl_cmd->commands_capacity, 8); + opengl_cmd->commands[opengl_cmd->commands_count] = command; + opengl_cmd->commands_count++; +} + bool OpenGLSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence) { } diff --git a/Sources/Backends/OpenGL/OpenGLCommandList.h b/Sources/Backends/OpenGL/OpenGLCommandList.h index 44b1362..92fe0f2 100644 --- a/Sources/Backends/OpenGL/OpenGLCommandList.h +++ b/Sources/Backends/OpenGL/OpenGLCommandList.h @@ -11,11 +11,61 @@ #include "OpenGL.h" #include "OpenGLBuffer.h" +typedef struct OpenGLCommand +{ + OpenGLCommandType type; + union + { + struct + { + const PulseImageRegion* src; + const PulseImageRegion* dst; + } BlitImages; + + struct + { + const PulseBufferRegion* src; + const PulseBufferRegion* dst; + } CopyBufferToBuffer; + + struct + { + const PulseBufferRegion* src; + const PulseImageRegion* dst; + } CopyBufferToImage; + + struct + { + const PulseImageRegion* src; + const PulseBufferRegion* dst; + } CopyImageToBuffer; + + struct + { + PulseComputePipeline pipeline; + uint32_t groupcount_x; + uint32_t groupcount_y; + uint32_t groupcount_z; + } Dispatch; + + struct + { + PulseComputePipeline pipeline; + PulseBuffer buffer; + uint32_t offset; + } DispatchIndirect; + }; +} OpenGLCommand; + typedef struct OpenGLCommandList { + OpenGLCommand* commands; + uint32_t commands_count; + uint32_t commands_capacity; } OpenGLCommandList; PulseCommandList OpenGLRequestCommandList(PulseDevice device, PulseCommandListUsage usage); +void OpenGLQueueCommand(PulseCommandList cmd, OpenGLCommand command); bool OpenGLSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence); void OpenGLReleaseCommandList(PulseDevice device, PulseCommandList cmd); diff --git a/Sources/Backends/OpenGL/OpenGLDevice.c b/Sources/Backends/OpenGL/OpenGLDevice.c index 5ab9d7b..45e7459 100644 --- a/Sources/Backends/OpenGL/OpenGLDevice.c +++ b/Sources/Backends/OpenGL/OpenGLDevice.c @@ -188,14 +188,11 @@ PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic PULSE_LOAD_DRIVER_DEVICE(OpenGL); - char* hash_string = (char*)calloc(1024, 1024); - snprintf(hash_string, 1024 * 1024, "%s|%s|", device->glGetString(pulse_device, GL_VENDOR), device->glGetString(pulse_device, GL_RENDERER)); + device->device_id = PulseHashString((const char*)device->glGetString(pulse_device, GL_VENDOR)); + device->device_id = PulseHashCombine(device->device_id, PulseHashString((const char*)device->glGetString(pulse_device, GL_RENDERER))); GLint gl_extension_count = 0; - device->glGetIntegerv(pulse_device, GL_NUM_EXTENSIONS, &gl_extension_count); for(int i = 0; i < gl_extension_count; i++) - snprintf(hash_string, 1024 * 1024 - strlen(hash_string), "%s|", device->glGetStringi(pulse_device, GL_EXTENSIONS, i)); - device->device_id = PulseHashString(hash_string); - free(hash_string); + device->device_id = PulseHashCombine(device->device_id, PulseHashString((const char*)device->glGetStringi(pulse_device, GL_EXTENSIONS, i))); if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(backend)) PulseLogInfoFmt(backend, "%s created device from %s", backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)", device->glGetString(pulse_device, GL_RENDERER)); diff --git a/Sources/Backends/OpenGL/OpenGLEnums.h b/Sources/Backends/OpenGL/OpenGLEnums.h index cf289e4..b38b019 100644 --- a/Sources/Backends/OpenGL/OpenGLEnums.h +++ b/Sources/Backends/OpenGL/OpenGLEnums.h @@ -12,7 +12,7 @@ typedef enum OpenGLContextType OPENGL_CONTEXT_EGL = 0, OPENGL_CONTEXT_WGL, - OPENGL_CONTEXT_END_ENUM // For internal use only + OPENGL_CONTEXT_END_ENUM } OpenGLContextType; typedef enum OpenGLFunctionIndex @@ -24,6 +24,19 @@ typedef enum OpenGLFunctionIndex OPENGL_FUNCTION_INDEX_END_ENUM } OpenGLFunctionIndex; +typedef enum OpenGLCommandType +{ + OPENGL_COMMAND_NONE = 0, + OPENGL_COMMAND_BLIT_IMAGES, + OPENGL_COMMAND_COPY_BUFFER_TO_BUFFER, + OPENGL_COMMAND_COPY_BUFFER_TO_IMAGE, + OPENGL_COMMAND_COPY_IMAGE_TO_BUFFER, + OPENGL_COMMAND_DISPATCH, + OPENGL_COMMAND_DISPATCH_INDIRECT, + + OPENGL_COMMAND_END_ENUM +} OpenGLCommandType; + #endif // PULSE_OPENGL_ENUMS_H_ #endif // PULSE_ENABLE_OPENGL_BACKEND diff --git a/Sources/PulseInternal.c b/Sources/PulseInternal.c index 36b125a..5413711 100644 --- a/Sources/PulseInternal.c +++ b/Sources/PulseInternal.c @@ -91,3 +91,9 @@ uint32_t PulseHashString(const char* str) hash = ((hash << 5) + hash) + str[i]; return hash; } + +uint32_t PulseHashCombine(uint32_t lhs, uint32_t rhs) +{ + lhs ^= rhs + 0x9e3779b9 + (lhs << 6) + (lhs >> 2); + return lhs; +} diff --git a/Sources/PulseInternal.h b/Sources/PulseInternal.h index d368ba6..a55fe5d 100644 --- a/Sources/PulseInternal.h +++ b/Sources/PulseInternal.h @@ -187,7 +187,9 @@ PFN_PulseLibFunction PulseLoadSymbolFromLibModule(PulseLibModule module, const c void PulseUnloadLibrary(PulseLibModule module); void PulseSetInternalError(PulseErrorType error); + uint32_t PulseHashString(const char* str); +uint32_t PulseHashCombine(uint32_t lhs, uint32_t rhs); void PulseLogBackend(PulseBackend backend, PulseDebugMessageSeverity type, const char* message, const char* file, const char* function, int line, ...);