From 6c2119d8065a05984140b2e199a32171ba118748 Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sun, 23 Mar 2025 00:43:40 +0100 Subject: [PATCH] working on OpenGL loading --- .gitignore | 1 + Examples/OpenGL/main.c | 2 + Scripts/GenerateOpenGLDefs.py | 71 ++++++ Sources/Backends/OpenGL/EGL/EGLFunctions.h | 8 + Sources/Backends/OpenGL/EGL/EGLInstance.c | 64 +++++- Sources/Backends/OpenGL/EGL/EGLInstance.h | 7 +- Sources/Backends/OpenGL/OpenGL.c | 73 +++--- Sources/Backends/OpenGL/OpenGL.h | 16 +- Sources/Backends/OpenGL/OpenGLBuffer.c | 32 +++ Sources/Backends/OpenGL/OpenGLBuffer.h | 26 +++ Sources/Backends/OpenGL/OpenGLCommandList.c | 21 ++ Sources/Backends/OpenGL/OpenGLCommandList.h | 24 ++ Sources/Backends/OpenGL/OpenGLComputePass.c | 45 ++++ Sources/Backends/OpenGL/OpenGLComputePass.h | 33 +++ .../Backends/OpenGL/OpenGLComputePipeline.c | 17 ++ .../Backends/OpenGL/OpenGLComputePipeline.h | 22 ++ Sources/Backends/OpenGL/OpenGLContext.h | 0 Sources/Backends/OpenGL/OpenGLDevice.c | 213 ++++++++++++++++++ Sources/Backends/OpenGL/OpenGLDevice.h | 42 ++++ Sources/Backends/OpenGL/OpenGLEnums.h | 29 +++ Sources/Backends/OpenGL/OpenGLFence.c | 25 ++ Sources/Backends/OpenGL/OpenGLFence.h | 24 ++ Sources/Backends/OpenGL/OpenGLFunctions.h | 142 ++++++++++++ Sources/Backends/OpenGL/OpenGLImage.c | 29 +++ Sources/Backends/OpenGL/OpenGLImage.h | 25 ++ Sources/Backends/OpenGL/OpenGLWraps.h | 135 +++++++++++ Sources/PulseBackend.c | 13 +- xmake.lua | 12 + 28 files changed, 1088 insertions(+), 63 deletions(-) create mode 100644 Scripts/GenerateOpenGLDefs.py create mode 100644 Sources/Backends/OpenGL/OpenGLBuffer.c create mode 100644 Sources/Backends/OpenGL/OpenGLBuffer.h create mode 100644 Sources/Backends/OpenGL/OpenGLCommandList.c create mode 100644 Sources/Backends/OpenGL/OpenGLCommandList.h create mode 100644 Sources/Backends/OpenGL/OpenGLComputePass.c create mode 100644 Sources/Backends/OpenGL/OpenGLComputePass.h create mode 100644 Sources/Backends/OpenGL/OpenGLComputePipeline.c create mode 100644 Sources/Backends/OpenGL/OpenGLComputePipeline.h delete mode 100644 Sources/Backends/OpenGL/OpenGLContext.h create mode 100644 Sources/Backends/OpenGL/OpenGLDevice.c create mode 100644 Sources/Backends/OpenGL/OpenGLDevice.h create mode 100644 Sources/Backends/OpenGL/OpenGLEnums.h create mode 100644 Sources/Backends/OpenGL/OpenGLFence.c create mode 100644 Sources/Backends/OpenGL/OpenGLFence.h create mode 100644 Sources/Backends/OpenGL/OpenGLFunctions.h create mode 100644 Sources/Backends/OpenGL/OpenGLImage.c create mode 100644 Sources/Backends/OpenGL/OpenGLImage.h create mode 100644 Sources/Backends/OpenGL/OpenGLWraps.h diff --git a/.gitignore b/.gitignore index ea1f129..b6c8749 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ !/Includes/ !/Sources/ !/Tests/ +!/Scripts/ !/Examples/ !/Xmake/ !/.github/ diff --git a/Examples/OpenGL/main.c b/Examples/OpenGL/main.c index 9927330..4bef1d8 100644 --- a/Examples/OpenGL/main.c +++ b/Examples/OpenGL/main.c @@ -26,7 +26,9 @@ int main(int ac, char** av) backend_type = PULSE_BACKEND_OPENGL_ES; PulseBackend backend = PulseLoadBackend(backend_type, PULSE_SHADER_FORMAT_GLSL_BIT, PULSE_HIGH_DEBUG); PulseSetDebugCallback(backend, DebugCallBack); + PulseDevice device = PulseCreateDevice(backend, NULL, 0); + PulseDestroyDevice(device); PulseUnloadBackend(backend); printf("Successfully executed Pulse example using %s !\n", backend_type == PULSE_BACKEND_OPENGL ? "OpenGL" : "OpenGL ES"); return 0; diff --git a/Scripts/GenerateOpenGLDefs.py b/Scripts/GenerateOpenGLDefs.py new file mode 100644 index 0000000..ee96d2f --- /dev/null +++ b/Scripts/GenerateOpenGLDefs.py @@ -0,0 +1,71 @@ +import re +import sys + +def extract_function_names(file): + function_names = [] + with open(file, 'r') as f: + for line in f: + match = re.match(r'PULSE_OPENGL_FUNCTION\((\w+),.*\)', line) + if not match: + match = re.match(r'PULSE_OPENGL_GL_GLES_FUNCTION\(.*?,.*?, (\w+),.*\)', line) + if match: + function_name = match.group(1) + function_names.append(function_name) + return function_names + +def extract_prototypes(function_names, header_file): + prototypes = {} + with open(header_file, 'r') as f: + for line in f: + for function_name in function_names: + if re.search(rf'\b{function_name}\b', line): + match = re.match(r'(.*?)\s*\b' + function_name + r'\b\s*\((.*?)\);', line) + if match: + return_type = match.group(1).replace('GL_APICALL ', '').replace(' GL_APIENTRY', '').replace('GL_APIENTRY', '') + arguments = match.group(2).split(', ') + argument_list = ["PulseDevice device"] + parameter_list = [] + for argument in arguments: + parts = argument.split() + arg_name = parts[-1] + arg_type = ' '.join(parts[:-1]) + if arg_name != 'void': + argument_list.append(f'{arg_type} {arg_name}') + parameter_list.append(f'{arg_name.split('*')[-1]}') + if return_type == 'void': + prototype = f'PULSE_OPENGL_WRAPPER({function_name}, ({", ".join(argument_list)}), ({", ".join(parameter_list)}), {"PFN" + function_name.upper() + "PROC"})' + else: + prototype = f'PULSE_OPENGL_WRAPPER_RET({return_type}, {function_name}, ({", ".join(argument_list)}), ({", ".join(parameter_list)}), {"PFN" + function_name.upper() + "PROC"})' + prototypes[function_name] = prototype + break + return prototypes + +def main(): + function_names = extract_function_names(sys.argv[1]) + prototypes = extract_prototypes(function_names, sys.argv[2]) + + try: + with open(sys.argv[3], "x") as f: + f.write("""// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +// This is a generated file + +// No header guards + +#ifndef PULSE_OPENGL_WRAPPER_RET + #error "You must define PULSE_OPENGL_WRAPPER_RET before including this file" +#endif + +#ifndef PULSE_OPENGL_WRAPPER + #error "You must define PULSE_OPENGL_WRAPPER before including this file" +#endif\n +""") + for function_name, prototype in prototypes.items(): + f.write(f'{prototype}\n') + except FileExistsError: + pass + +if __name__ == '__main__': + main() diff --git a/Sources/Backends/OpenGL/EGL/EGLFunctions.h b/Sources/Backends/OpenGL/EGL/EGLFunctions.h index dd06b55..93dff7e 100644 --- a/Sources/Backends/OpenGL/EGL/EGLFunctions.h +++ b/Sources/Backends/OpenGL/EGL/EGLFunctions.h @@ -8,6 +8,10 @@ #error "You must define PULSE_EGL_FUNCTION before including this file" #endif +#ifndef PULSE_EGL_FUNCTION_EXT + #error "You must define PULSE_EGL_FUNCTION_EXT before including this file" +#endif + PULSE_EGL_FUNCTION(eglBindAPI, PFNEGLBINDAPIPROC) PULSE_EGL_FUNCTION(eglChooseConfig, PFNEGLCHOOSECONFIGPROC) PULSE_EGL_FUNCTION(eglCreateContext, PFNEGLCREATECONTEXTPROC) @@ -22,3 +26,7 @@ PULSE_EGL_FUNCTION(eglInitialize, PFNEGLINITIALIZEPROC) PULSE_EGL_FUNCTION(eglMakeCurrent, PFNEGLMAKECURRENTPROC) PULSE_EGL_FUNCTION(eglQueryString, PFNEGLQUERYSTRINGPROC) 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 70e3ee0..1ef797a 100644 --- a/Sources/Backends/OpenGL/EGL/EGLInstance.c +++ b/Sources/Backends/OpenGL/EGL/EGLInstance.c @@ -2,8 +2,12 @@ // This file is part of "Pulse" // For conditions of distribution and use, see copyright notice in LICENSE +#include + #include "EGLInstance.h" #include "../../../PulseInternal.h" +#include "EGL/eglext.h" +#include "../OpenGLDevice.h" static PulseLibModule egl_lib_module = PULSE_NULL_LIB_MODULE; static uint32_t loader_references_count = 0; @@ -49,20 +53,76 @@ static bool EGLLoadFunctions(EGLInstance* instance) instance->fn = (T)instance->eglGetProcAddress(#fn); \ if(!instance->fn) \ return false; + #define PULSE_EGL_FUNCTION_EXT(fn, T) instance->fn = (T)instance->eglGetProcAddress(#fn); #include "EGLFunctions.h" #undef PULSE_EGL_FUNCTION + #undef PULSE_EGL_FUNCTION_EXT return true; } -bool EGLLoadInstance(EGLInstance* instance, bool es_context) +static bool EGLIsDeviceForbidden(EGLInstance* instance, EGLDeviceEXT device, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count) +{ + if(device == EGL_NO_DEVICE_EXT) + return true; + + const char* test_device_vendor = instance->eglQueryDeviceStringEXT(device, EGL_VENDOR); + + for(uint32_t i = 0; i < forbiden_devices_count; i++) + { + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(forbiden_devices[i], OpenGLDevice*); + if(opengl_device->context_type != OPENGL_CONTEXT_EGL) + continue; + + const char* device_vendor = instance->eglQueryDeviceStringEXT(opengl_device->egl_instance.device, EGL_VENDOR); + if(device_vendor && test_device_vendor && strcmp(test_device_vendor, device_vendor) == 0) + return true; + } + return false; +} + +#include + +bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count, bool es_context) { PULSE_CHECK_PTR_RETVAL(instance, false); if(!EGLLoadFunctions(instance)) return false; - instance->display = instance->eglGetDisplay(EGL_DEFAULT_DISPLAY); + instance->device = EGL_NO_DEVICE_EXT; + + if(instance->eglGetPlatformDisplayEXT && instance->eglQueryDevicesEXT && instance->eglQueryDeviceStringEXT) + { + EGLDeviceEXT* devices = PULSE_NULLPTR; + EGLDeviceEXT chosen_one = EGL_NO_DEVICE_EXT; + int32_t device_count; + uint64_t best_device_score = 0; + + instance->eglQueryDevicesEXT(0, PULSE_NULLPTR, &device_count); + devices = (EGLDeviceEXT*)calloc(device_count, sizeof(EGLDeviceEXT)); + PULSE_CHECK_ALLOCATION_RETVAL(devices, false); + instance->eglQueryDevicesEXT(device_count, devices, &device_count); + + for(int32_t i = 0; i < device_count; i++) + { + if(EGLIsDeviceForbidden(instance, devices[i], forbiden_devices, forbiden_devices_count)) + continue; + const char* exts = instance->eglQueryDeviceStringEXT(devices[i], EGL_EXTENSIONS); + uint64_t current_device_score = 0; + if(strstr(exts, "EGL_EXT_device_drm")) // tricky way to check if it is a discrete GPU + current_device_score += 10000; + if(current_device_score > best_device_score) + { + best_device_score = current_device_score; + chosen_one = 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); diff --git a/Sources/Backends/OpenGL/EGL/EGLInstance.h b/Sources/Backends/OpenGL/EGL/EGLInstance.h index 3bb22dc..73b7dd6 100644 --- a/Sources/Backends/OpenGL/EGL/EGLInstance.h +++ b/Sources/Backends/OpenGL/EGL/EGLInstance.h @@ -9,6 +9,7 @@ #define EGL_EGL_PROTOTYPES 0 #include +#include #include typedef struct EGLInstance @@ -18,12 +19,16 @@ typedef struct EGLInstance EGLContext context; EGLConfig config; + EGLDeviceEXT device; + #define PULSE_EGL_FUNCTION(fn, T) T fn; + #define PULSE_EGL_FUNCTION_EXT(fn, T) T fn; #include "EGLFunctions.h" #undef PULSE_EGL_FUNCTION + #undef PULSE_EGL_FUNCTION_EXT } EGLInstance; -bool EGLLoadInstance(EGLInstance* instance, bool es_context); +bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count, bool es_context); void EGLUnloadInstance(EGLInstance* instance); #endif // PULSE_EGL_CONTEXT_H_ diff --git a/Sources/Backends/OpenGL/OpenGL.c b/Sources/Backends/OpenGL/OpenGL.c index 2e5a99b..f769503 100644 --- a/Sources/Backends/OpenGL/OpenGL.c +++ b/Sources/Backends/OpenGL/OpenGL.c @@ -6,82 +6,61 @@ #include "../../PulseInternal.h" #include "OpenGL.h" +#include "OpenGLDevice.h" PulseBackendFlags OpenGLCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used) -{ - if(candidates != PULSE_BACKEND_ANY && ((candidates & PULSE_BACKEND_OPENGL) == 0 || (candidates & PULSE_BACKEND_OPENGL_ES) == 0)) - return PULSE_BACKEND_INVALID; - if((shader_formats_used & PULSE_SHADER_FORMAT_GLSL_BIT) == 0) - return PULSE_BACKEND_INVALID; - - EGLInstance instance; - if(!EGLLoadInstance(&instance, candidates)) - return PULSE_BACKEND_INVALID; - EGLUnloadInstance(&instance); - return PULSE_BACKEND_OPENGL; -} - -bool OpenGLLoadBackend(PulseBackend backend, PulseDebugLevel debug_level) -{ - PULSE_UNUSED(backend); - PULSE_UNUSED(debug_level); - OpenGLDriverData* driver_data = (OpenGLDriverData*)calloc(1, sizeof(OpenGLDriverData)); - PULSE_CHECK_ALLOCATION_RETVAL(driver_data, false); - #ifdef PULSE_PLAT_WINDOWS - // WGL support - #else - EGLLoadInstance(&driver_data->egl_instance, false); - #endif - OpenGLDriver.driver_data = driver_data; - return true; -} - -void OpenGLUnloadBackend(PulseBackend backend) -{ - EGLUnloadInstance(&OPENGL_RETRIEVE_DRIVER_DATA_AS(backend, OpenGLDriverData*)->egl_instance); - free(backend->driver_data); -} - -PulseBackendFlags OpenGLESCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used) { if(candidates != PULSE_BACKEND_ANY && (candidates & PULSE_BACKEND_OPENGL) == 0) return PULSE_BACKEND_INVALID; if((shader_formats_used & PULSE_SHADER_FORMAT_GLSL_BIT) == 0) return PULSE_BACKEND_INVALID; + PulseDevice device = OpenGLCreateDevice(&OpenGLDriver, PULSE_NULLPTR, 0); + PULSE_CHECK_HANDLE_RETVAL(device, PULSE_BACKEND_INVALID); + OpenGLDestroyDevice(device); + return PULSE_BACKEND_OPENGL; } -bool OpenGLESLoadBackend(PulseBackend backend, PulseDebugLevel debug_level) +PulseBackendFlags OpenGLESCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used) +{ + if(candidates != PULSE_BACKEND_ANY && (candidates & PULSE_BACKEND_OPENGL_ES) == 0) + return PULSE_BACKEND_INVALID; + if((shader_formats_used & PULSE_SHADER_FORMAT_GLSL_BIT) == 0) + return PULSE_BACKEND_INVALID; + + PulseDevice device = OpenGLCreateDevice(&OpenGLESDriver, PULSE_NULLPTR, 0); + PULSE_CHECK_HANDLE_RETVAL(device, PULSE_BACKEND_INVALID); + OpenGLDestroyDevice(device); + + return PULSE_BACKEND_OPENGL_ES; +} + +bool OpenGLLoadBackend(PulseBackend backend, PulseDebugLevel debug_level) { PULSE_UNUSED(backend); PULSE_UNUSED(debug_level); - OpenGLDriverData* driver_data = (OpenGLDriverData*)calloc(1, sizeof(OpenGLDriverData)); - PULSE_CHECK_ALLOCATION_RETVAL(driver_data, false); - EGLLoadInstance(&driver_data->egl_instance, true); - OpenGLDriver.driver_data = driver_data; return true; } -void OpenGLESUnloadBackend(PulseBackend backend) +void OpenGLUnloadBackend(PulseBackend backend) { - EGLUnloadInstance(&OPENGL_RETRIEVE_DRIVER_DATA_AS(backend, OpenGLDriverData*)->egl_instance); - free(backend->driver_data); + PULSE_UNUSED(backend); } PulseBackendHandler OpenGLDriver = { .PFN_LoadBackend = OpenGLLoadBackend, .PFN_UnloadBackend = OpenGLUnloadBackend, - .PFN_CreateDevice = PULSE_NULLPTR, + .PFN_CreateDevice = OpenGLCreateDevice, .backend = PULSE_BACKEND_OPENGL, .supported_shader_formats = PULSE_SHADER_FORMAT_GLSL_BIT, .driver_data = PULSE_NULLPTR }; PulseBackendHandler OpenGLESDriver = { - .PFN_LoadBackend = OpenGLESLoadBackend, - .PFN_UnloadBackend = OpenGLESUnloadBackend, - .PFN_CreateDevice = PULSE_NULLPTR, + .PFN_LoadBackend = OpenGLLoadBackend, + .PFN_UnloadBackend = OpenGLUnloadBackend, + .PFN_CreateDevice = OpenGLCreateDevice, .backend = PULSE_BACKEND_OPENGL_ES, .supported_shader_formats = PULSE_SHADER_FORMAT_GLSL_BIT, .driver_data = PULSE_NULLPTR diff --git a/Sources/Backends/OpenGL/OpenGL.h b/Sources/Backends/OpenGL/OpenGL.h index caeff43..3bed8fe 100644 --- a/Sources/Backends/OpenGL/OpenGL.h +++ b/Sources/Backends/OpenGL/OpenGL.h @@ -11,15 +11,15 @@ #define OPENGL_RETRIEVE_DRIVER_DATA_AS(handle, cast) ((cast)handle->driver_data) -#include "EGL/EGLInstance.h" +#include "OpenGLEnums.h" -typedef struct OpenGLDriverData -{ - union - { - EGLInstance egl_instance; - }; -} OpenGLDriverData; +#define GL_GLES_PROTOTYPES 0 +#include + +#define GL_STACK_UNDERFLOW 0x0504 +#define GL_STACK_OVERFLOW 0x0503 + +typedef void(*GLFunction)(void); PulseBackendFlags OpenGLCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used); // Return PULSE_BACKEND_OPENGL in case of success and PULSE_BACKEND_INVALID otherwise PulseBackendFlags OpenGLESCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used); // Return PULSE_BACKEND_OPENGL_ES in case of success and PULSE_BACKEND_INVALID otherwise diff --git a/Sources/Backends/OpenGL/OpenGLBuffer.c b/Sources/Backends/OpenGL/OpenGLBuffer.c new file mode 100644 index 0000000..08c80e0 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLBuffer.c @@ -0,0 +1,32 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#include + +#include "../../PulseInternal.h" +#include "OpenGLBuffer.h" + +PulseBuffer OpenGLCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos) +{ +} + +bool OpenGLMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data) +{ +} + +void OpenGLUnmapBuffer(PulseBuffer buffer) +{ +} + +bool OpenGLCopyBufferToBuffer(PulseCommandList cmd, const PulseBufferRegion* src, const PulseBufferRegion* dst) +{ +} + +bool OpenGLCopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion* src, const PulseImageRegion* dst) +{ +} + +void OpenGLDestroyBuffer(PulseDevice device, PulseBuffer buffer) +{ +} diff --git a/Sources/Backends/OpenGL/OpenGLBuffer.h b/Sources/Backends/OpenGL/OpenGLBuffer.h new file mode 100644 index 0000000..9ccfb90 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLBuffer.h @@ -0,0 +1,26 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_OPENGL_BACKEND + +#ifndef PULSE_OPENGL_BUFFER_H_ +#define PULSE_OPENGL_BUFFER_H_ + +#include +#include "OpenGL.h" + +typedef struct OpenGLBuffer +{ +} OpenGLBuffer; + +PulseBuffer OpenGLCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* create_infos); +bool OpenGLMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data); +void OpenGLUnmapBuffer(PulseBuffer buffer); +bool OpenGLCopyBufferToBuffer(PulseCommandList cmd, const PulseBufferRegion* src, const PulseBufferRegion* dst); +bool OpenGLCopyBufferToImage(PulseCommandList cmd, const PulseBufferRegion* src, const PulseImageRegion* dst); +void OpenGLDestroyBuffer(PulseDevice device, PulseBuffer buffer); + +#endif // PULSE_OPENGL_BUFFER_H_ + +#endif // PULSE_ENABLE_OPENGL_BACKEND diff --git a/Sources/Backends/OpenGL/OpenGLCommandList.c b/Sources/Backends/OpenGL/OpenGLCommandList.c new file mode 100644 index 0000000..17a3105 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLCommandList.c @@ -0,0 +1,21 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#include + +#include "../../PulseInternal.h" +#include "OpenGL.h" +#include "OpenGLCommandList.h" + +PulseCommandList OpenGLRequestCommandList(PulseDevice device, PulseCommandListUsage usage) +{ +} + +bool OpenGLSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence) +{ +} + +void OpenGLReleaseCommandList(PulseDevice device, PulseCommandList cmd) +{ +} diff --git a/Sources/Backends/OpenGL/OpenGLCommandList.h b/Sources/Backends/OpenGL/OpenGLCommandList.h new file mode 100644 index 0000000..44b1362 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLCommandList.h @@ -0,0 +1,24 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_OPENGL_BACKEND + +#ifndef PULSE_OPENGL_COMMAND_LIST_H_ +#define PULSE_OPENGL_COMMAND_LIST_H_ + +#include +#include "OpenGL.h" +#include "OpenGLBuffer.h" + +typedef struct OpenGLCommandList +{ +} OpenGLCommandList; + +PulseCommandList OpenGLRequestCommandList(PulseDevice device, PulseCommandListUsage usage); +bool OpenGLSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence); +void OpenGLReleaseCommandList(PulseDevice device, PulseCommandList cmd); + +#endif // PULSE_OPENGL_COMMAND_LIST_H_ + +#endif // PULSE_ENABLE_OPENGL_BACKEND diff --git a/Sources/Backends/OpenGL/OpenGLComputePass.c b/Sources/Backends/OpenGL/OpenGLComputePass.c new file mode 100644 index 0000000..1d4780b --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLComputePass.c @@ -0,0 +1,45 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#include + +#include "../../PulseInternal.h" +#include "OpenGL.h" +#include "OpenGLComputePass.h" + +PulseComputePass OpenGLCreateComputePass(PulseDevice device, PulseCommandList cmd) +{ +} + +void OpenGLDestroyComputePass(PulseDevice device, PulseComputePass pass) +{ +} + +PulseComputePass OpenGLBeginComputePass(PulseCommandList cmd) +{ +} + +void OpenGLEndComputePass(PulseComputePass pass) +{ +} + +void OpenGLBindStorageBuffers(PulseComputePass pass, const PulseBuffer* buffers, uint32_t num_buffers) +{ +} + +void OpenGLBindUniformData(PulseComputePass pass, uint32_t slot, const void* data, uint32_t data_size) +{ +} + +void OpenGLBindStorageImages(PulseComputePass pass, const PulseImage* images, uint32_t num_images) +{ +} + +void OpenGLBindComputePipeline(PulseComputePass pass, PulseComputePipeline pipeline) +{ +} + +void OpenGLDispatchComputations(PulseComputePass pass, uint32_t groupcount_x, uint32_t groupcount_y, uint32_t groupcount_z) +{ +} diff --git a/Sources/Backends/OpenGL/OpenGLComputePass.h b/Sources/Backends/OpenGL/OpenGLComputePass.h new file mode 100644 index 0000000..c499868 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLComputePass.h @@ -0,0 +1,33 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_OPENGL_BACKEND + +#ifndef PULSE_OPENGL_COMPUTE_PASS_H_ +#define PULSE_OPENGL_COMPUTE_PASS_H_ + +#include +#include "OpenGL.h" +#include "OpenGLBuffer.h" +#include "OpenGLCommandList.h" + +typedef struct OpenGLComputePass +{ +} OpenGLComputePass; + +PulseComputePass OpenGLCreateComputePass(PulseDevice device, PulseCommandList cmd); +void OpenGLDestroyComputePass(PulseDevice device, PulseComputePass pass); + +PulseComputePass OpenGLBeginComputePass(PulseCommandList cmd); +void OpenGLEndComputePass(PulseComputePass pass); +void OpenGLBindStorageBuffers(PulseComputePass pass, const PulseBuffer* buffers, uint32_t num_buffers); +void OpenGLBindUniformData(PulseComputePass pass, uint32_t slot, const void* data, uint32_t data_size); +void OpenGLBindStorageImages(PulseComputePass pass, const PulseImage* images, uint32_t num_images); +void OpenGLBindComputePipeline(PulseComputePass pass, PulseComputePipeline pipeline); +void OpenGLDispatchComputations(PulseComputePass pass, uint32_t groupcount_x, uint32_t groupcount_y, uint32_t groupcount_z); + +#endif // PULSE_OPENGL_COMPUTE_PASS_H_ + +#endif // PULSE_ENABLE_OPENGL_BACKEND + diff --git a/Sources/Backends/OpenGL/OpenGLComputePipeline.c b/Sources/Backends/OpenGL/OpenGLComputePipeline.c new file mode 100644 index 0000000..bc5228c --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLComputePipeline.c @@ -0,0 +1,17 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#include + +#include "../../PulseInternal.h" +#include "OpenGL.h" +#include "OpenGLComputePipeline.h" + +PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info) +{ +} + +void OpenGLDestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline) +{ +} diff --git a/Sources/Backends/OpenGL/OpenGLComputePipeline.h b/Sources/Backends/OpenGL/OpenGLComputePipeline.h new file mode 100644 index 0000000..95a4be9 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLComputePipeline.h @@ -0,0 +1,22 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_OPENGL_BACKEND + +#ifndef PULSE_OPENGL_COMPUTE_PIPELINE_H_ +#define PULSE_OPENGL_COMPUTE_PIPELINE_H_ + +#include +#include "OpenGL.h" + +typedef struct OpenGLComputePipeline +{ +} OpenGLComputePipeline; + +PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info); +void OpenGLDestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline); + +#endif // PULSE_OPENGL_COMPUTE_PIPELINE_H_ + +#endif // PULSE_ENABLE_OPENGL_BACKEND diff --git a/Sources/Backends/OpenGL/OpenGLContext.h b/Sources/Backends/OpenGL/OpenGLContext.h deleted file mode 100644 index e69de29..0000000 diff --git a/Sources/Backends/OpenGL/OpenGLDevice.c b/Sources/Backends/OpenGL/OpenGLDevice.c new file mode 100644 index 0000000..94763db --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLDevice.c @@ -0,0 +1,213 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#include +#include + + +#include + +#include "../../PulseInternal.h" +#include "OpenGL.h" +#include "OpenGLComputePipeline.h" +#include "OpenGLCommandList.h" +#include "OpenGLDevice.h" +#include "OpenGLFence.h" +#include "OpenGLBuffer.h" +#include "OpenGLImage.h" +#include "OpenGLComputePass.h" + +static const char* OpenGLFunctionIndexToFunctionName[] = { + #define PULSE_OPENGL_FUNCTION(fn, T) #fn, + #include "OpenGLFunctions.h" + #undef PULSE_OPENGL_FUNCTION +}; + +typedef GLFunction(*GLFunctionLoad)(const char*); + +const char* OpenGLVerbaliseError(GLenum code) +{ + switch (code) + { + // OpenGL / OpenGL ES error codes + case GL_INVALID_ENUM: return "an unacceptable value is specified for an enumerated argument"; + case GL_INVALID_VALUE: return "a numeric argument is out of range"; + case GL_INVALID_OPERATION: return "the specified operation is not allowed in the current state"; + case GL_INVALID_FRAMEBUFFER_OPERATION: return "the framebuffer object is not complete"; + case GL_OUT_OF_MEMORY: return "there is not enough memory left to execute the command"; + + // OpenGL error codes + case GL_STACK_UNDERFLOW: return "an attempt has been made to perform an operation that would cause an internal stack to underflow"; + case GL_STACK_OVERFLOW: return "an attempt has been made to perform an operation that would cause an internal stack to overflow"; + + default: break; + } + + return "unknown OpenGL error"; +} + +static void PulseCheckGLError(PulseDevice device, const char* function) +{ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + GLenum err = ((PFNGLGETERRORPROC)opengl_device->original_function_ptrs[glGetError])(); + if(err == GL_NO_ERROR) + return; + + char message[4096] = { 0 }; + snprintf(message, 4096, "%s call to %s failed. Unrolling the error stack:\n", device->backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)", function); + + int i = 0; + for(; err != GL_NO_ERROR; err = ((PFNGLGETERRORPROC)opengl_device->original_function_ptrs[glGetError])(), i++) + snprintf(message + strlen(message), 4096 - strlen(message), " #%d %s\n", i, OpenGLVerbaliseError(err)); + + PulseLogBackend(device->backend, PULSE_DEBUG_MESSAGE_SEVERITY_ERROR, message, __FILE__, function, 0); +} + +static void OpenGLDeviceMakeCurrent(PulseDevice device) +{ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + #ifdef PULSE_PLAT_WINDOWS + if(opengl_device->context_type == OPENGL_CONTEXT_WGL) + {} // TODO: WGL + else + { + EGLInstance* instance = &opengl_device->egl_instance; + instance->eglMakeCurrent(instance->display, instance->surface, instance->surface, instance->context); + } + #else + EGLInstance* instance = &opengl_device->egl_instance; + instance->eglMakeCurrent(instance->display, instance->surface, instance->surface, instance->context); + #endif +} + +#define PULSE_OPENGL_WRAPPER_RET(ret, fn, arg_list, param_list, cast) \ + static ret PulseOpenGLWrapper_##fn arg_list \ + { \ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); \ + OpenGLDeviceMakeCurrent(device); \ + ret result = ((cast)opengl_device->original_function_ptrs[fn]) param_list; \ + if(device->backend->debug_level != PULSE_NO_DEBUG) \ + PulseCheckGLError(device, #fn); \ + return result; \ + } + +#define PULSE_OPENGL_WRAPPER(fn, arg_list, param_list, cast) \ + static void PulseOpenGLWrapper_##fn arg_list \ + { \ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); \ + OpenGLDeviceMakeCurrent(device); \ + ((cast)opengl_device->original_function_ptrs[fn]) param_list; \ + if(device->backend->debug_level != PULSE_NO_DEBUG) \ + PulseCheckGLError(device, #fn); \ + } + +#include "OpenGLWraps.h" + +#undef PULSE_OPENGL_WRAPPER +#undef PULSE_OPENGL_WRAPPER_RET + +static bool OpenGLLoadFunction(PulseDevice device, OpenGLFunctionIndex index) +{ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + GLFunctionLoad load = PULSE_NULLPTR; + + #ifdef PULSE_PLAT_WINDOWS + if(opengl_device->context_type == OPENGL_CONTEXT_WGL) + {} // TODO: WGL + else + load = (GLFunctionLoad)opengl_device->egl_instance.eglGetProcAddress; + #else + load = (GLFunctionLoad)opengl_device->egl_instance.eglGetProcAddress; + #endif + + GLFunction fn = load(OpenGLFunctionIndexToFunctionName[index]); + if(!fn) + { + PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED); + return false; + } + opengl_device->original_function_ptrs[index] = fn; + return true; +} + +static bool OpenGLLoadFunctions(PulseDevice device) +{ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + for(int i = 0; i < OPENGL_FUNCTION_INDEX_END_ENUM; i++) + { + if(!OpenGLLoadFunction(device, i)) + return false; + } + + #define PULSE_OPENGL_FUNCTION(fn, T) opengl_device->fn = PulseOpenGLWrapper_##fn; + #include "OpenGLFunctions.h" + #undef PULSE_OPENGL_FUNCTION + + return true; +} + +PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count) +{ + PULSE_CHECK_HANDLE_RETVAL(backend, PULSE_NULLPTR); + + PulseDevice pulse_device = (PulseDeviceHandler*)calloc(1, sizeof(PulseDeviceHandler)); + PULSE_CHECK_ALLOCATION_RETVAL(pulse_device, PULSE_NULL_HANDLE); + + OpenGLDevice* device = (OpenGLDevice*)calloc(1, sizeof(OpenGLDevice)); + PULSE_CHECK_ALLOCATION_RETVAL(device, PULSE_NULL_HANDLE); + + pulse_device->driver_data = device; + pulse_device->backend = backend; + + #ifdef PULSE_PLAT_WINDOWS + // WGL support + if(opengl_device->context_type == OPENGL_CONTEXT_WGL) + { + // TODO: WGL + device->context_type = OPENGL_CONTEXT_WGL; + } + else + { + EGLLoadInstance(&device->egl_instance, forbiden_devices, forbiden_devices_count, backend->backend == PULSE_BACKEND_OPENGL_ES); + device->context_type = OPENGL_CONTEXT_EGL; + } + #else + EGLLoadInstance(&device->egl_instance, forbiden_devices, forbiden_devices_count, backend->backend == PULSE_BACKEND_OPENGL_ES); + device->context_type = OPENGL_CONTEXT_EGL; + #endif + + if(!OpenGLLoadFunctions(pulse_device)) + { + EGLUnloadInstance(&device->egl_instance); + PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED); + return PULSE_NULL_HANDLE; + } + + PULSE_LOAD_DRIVER_DEVICE(OpenGL); + + 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)); + return pulse_device; +} + +void OpenGLDestroyDevice(PulseDevice device) +{ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + if(opengl_device == PULSE_NULLPTR) + return; + + #ifdef PULSE_PLAT_WINDOWS + if(opengl_device->context_type == OPENGL_CONTEXT_WGL) + {} // TODO: WGL + else + EGLUnloadInstance(&opengl_device->egl_instance); + #else + EGLUnloadInstance(&opengl_device->egl_instance); + #endif + free(opengl_device); + free(device); +} diff --git a/Sources/Backends/OpenGL/OpenGLDevice.h b/Sources/Backends/OpenGL/OpenGLDevice.h new file mode 100644 index 0000000..27fffb8 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLDevice.h @@ -0,0 +1,42 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_OPENGL_BACKEND + +#ifndef PULSE_OPENGL_DEVICE_H_ +#define PULSE_OPENGL_DEVICE_H_ + +#include +#include "OpenGL.h" +#include "EGL/EGLInstance.h" + +#define PULSE_OPENGL_WRAPPER_RET(ret, fn, arg_list, param_list, cast) typedef ret (*PulseOpenGLWrapperPFN_##fn) arg_list ; +#define PULSE_OPENGL_WRAPPER(fn, arg_list, param_list, cast) typedef void (*PulseOpenGLWrapperPFN_##fn) arg_list ; + #include "OpenGLWraps.h" +#undef PULSE_OPENGL_WRAPPER +#undef PULSE_OPENGL_WRAPPER_RET + +typedef struct OpenGLDevice +{ + GLFunction original_function_ptrs[OPENGL_FUNCTION_INDEX_END_ENUM]; + + union + { + EGLInstance egl_instance; + }; + OpenGLContextType context_type; + + #define PULSE_OPENGL_WRAPPER_RET(ret, fn, arg_list, param_list, cast) PulseOpenGLWrapperPFN_##fn fn; + #define PULSE_OPENGL_WRAPPER(fn, arg_list, param_list, cast) PulseOpenGLWrapperPFN_##fn fn; + #include "OpenGLWraps.h" + #undef PULSE_OPENGL_WRAPPER + #undef PULSE_OPENGL_WRAPPER_RET +} OpenGLDevice; + +PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count); +void OpenGLDestroyDevice(PulseDevice device); + +#endif // PULSE_OPENGL_DEVICE_H_ + +#endif // PULSE_ENABLE_OPENGL_BACKEND diff --git a/Sources/Backends/OpenGL/OpenGLEnums.h b/Sources/Backends/OpenGL/OpenGLEnums.h new file mode 100644 index 0000000..cf289e4 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLEnums.h @@ -0,0 +1,29 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_OPENGL_BACKEND + +#ifndef PULSE_OPENGL_ENUMS_H_ +#define PULSE_OPENGL_ENUMS_H_ + +typedef enum OpenGLContextType +{ + OPENGL_CONTEXT_EGL = 0, + OPENGL_CONTEXT_WGL, + + OPENGL_CONTEXT_END_ENUM // For internal use only +} OpenGLContextType; + +typedef enum OpenGLFunctionIndex +{ + #define PULSE_OPENGL_FUNCTION(fn, T) fn, + #include "OpenGLFunctions.h" + #undef PULSE_OPENGL_FUNCTION + + OPENGL_FUNCTION_INDEX_END_ENUM +} OpenGLFunctionIndex; + +#endif // PULSE_OPENGL_ENUMS_H_ + +#endif // PULSE_ENABLE_OPENGL_BACKEND diff --git a/Sources/Backends/OpenGL/OpenGLFence.c b/Sources/Backends/OpenGL/OpenGLFence.c new file mode 100644 index 0000000..db18f59 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLFence.c @@ -0,0 +1,25 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#include + +#include "../../PulseInternal.h" +#include "OpenGL.h" +#include "OpenGLFence.h" + +PulseFence OpenGLCreateFence(PulseDevice device) +{ +} + +void OpenGLDestroyFence(PulseDevice device, PulseFence fence) +{ +} + +bool OpenGLIsFenceReady(PulseDevice device, PulseFence fence) +{ +} + +bool OpenGLWaitForFences(PulseDevice device, const PulseFence* fences, uint32_t fences_count, bool wait_for_all) +{ +} diff --git a/Sources/Backends/OpenGL/OpenGLFence.h b/Sources/Backends/OpenGL/OpenGLFence.h new file mode 100644 index 0000000..c59f109 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLFence.h @@ -0,0 +1,24 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_OPENGL_BACKEND + +#ifndef PULSE_OPENGL_FENCE_H_ +#define PULSE_OPENGL_FENCE_H_ + +#include +#include "OpenGL.h" + +typedef struct OpenGLFence +{ +} OpenGLFence; + +PulseFence OpenGLCreateFence(PulseDevice device); +void OpenGLDestroyFence(PulseDevice device, PulseFence fence); +bool OpenGLIsFenceReady(PulseDevice device, PulseFence fence); +bool OpenGLWaitForFences(PulseDevice device, const PulseFence* fences, uint32_t fences_count, bool wait_for_all); + +#endif // PULSE_OPENGL_FENCE_H_ + +#endif // PULSE_ENABLE_OPENGL_BACKEND diff --git a/Sources/Backends/OpenGL/OpenGLFunctions.h b/Sources/Backends/OpenGL/OpenGLFunctions.h new file mode 100644 index 0000000..80b197f --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLFunctions.h @@ -0,0 +1,142 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +// No header guards + +#ifndef PULSE_OPENGL_FUNCTION + #error "You must define PULSE_OPENGL_FUNCTION before including this file" +#endif + +#ifndef PULSE_OPENGL_GL_FUNCTION + #define PULSE_OPENGL_GL_FUNCTION(ver, name, sig) PULSE_OPENGL_FUNCTION(name, sig) +#endif + +#ifndef PULSE_OPENGL_GL_GLES_FUNCTION + #define PULSE_OPENGL_GL_GLES_FUNCTION(glVer, glesVer, name, sig) PULSE_OPENGL_FUNCTION(name, sig) +#endif + +// OpenGL core +PULSE_OPENGL_FUNCTION(glActiveTexture, PFNGLACTIVETEXTUREPROC) +PULSE_OPENGL_FUNCTION(glAttachShader, PFNGLATTACHSHADERPROC) +PULSE_OPENGL_FUNCTION(glBeginQuery, PFNGLBEGINQUERYPROC) +PULSE_OPENGL_FUNCTION(glBindAttribLocation, PFNGLBINDATTRIBLOCATIONPROC) +PULSE_OPENGL_FUNCTION(glBindBuffer, PFNGLBINDBUFFERPROC) +PULSE_OPENGL_FUNCTION(glBindBufferRange, PFNGLBINDBUFFERRANGEPROC) +PULSE_OPENGL_FUNCTION(glBindRenderbuffer, PFNGLBINDRENDERBUFFERPROC) +PULSE_OPENGL_FUNCTION(glBindSampler, PFNGLBINDSAMPLERPROC) +PULSE_OPENGL_FUNCTION(glBindTexture, PFNGLBINDTEXTUREPROC) +PULSE_OPENGL_FUNCTION(glBlendEquationSeparate, PFNGLBLENDEQUATIONSEPARATEPROC) +PULSE_OPENGL_FUNCTION(glBlendFuncSeparate, PFNGLBLENDFUNCSEPARATEPROC) +PULSE_OPENGL_FUNCTION(glBufferData, PFNGLBUFFERDATAPROC) +PULSE_OPENGL_FUNCTION(glBufferSubData, PFNGLBUFFERSUBDATAPROC) +PULSE_OPENGL_FUNCTION(glClear, PFNGLCLEARPROC) +PULSE_OPENGL_FUNCTION(glClearBufferfi, PFNGLCLEARBUFFERFIPROC) +PULSE_OPENGL_FUNCTION(glClearBufferfv, PFNGLCLEARBUFFERFVPROC) +PULSE_OPENGL_FUNCTION(glClearBufferuiv, PFNGLCLEARBUFFERUIVPROC) +PULSE_OPENGL_FUNCTION(glClearDepthf, PFNGLCLEARDEPTHFPROC) +PULSE_OPENGL_FUNCTION(glClearStencil, PFNGLCLEARSTENCILPROC) +PULSE_OPENGL_FUNCTION(glCompileShader, PFNGLCOMPILESHADERPROC) +PULSE_OPENGL_FUNCTION(glCompressedTexSubImage2D, PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) +PULSE_OPENGL_FUNCTION(glCompressedTexSubImage3D, PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) +PULSE_OPENGL_FUNCTION(glCopyBufferSubData, PFNGLCOPYBUFFERSUBDATAPROC) +PULSE_OPENGL_FUNCTION(glCopyTexSubImage2D, PFNGLCOPYTEXSUBIMAGE2DPROC) +PULSE_OPENGL_FUNCTION(glCreateProgram, PFNGLCREATEPROGRAMPROC) +PULSE_OPENGL_FUNCTION(glCreateShader, PFNGLCREATESHADERPROC) +PULSE_OPENGL_FUNCTION(glDeleteBuffers, PFNGLDELETEBUFFERSPROC) +PULSE_OPENGL_FUNCTION(glDeleteProgram, PFNGLDELETEPROGRAMPROC) +PULSE_OPENGL_FUNCTION(glDeleteQueries, PFNGLDELETEQUERIESPROC) +PULSE_OPENGL_FUNCTION(glDeleteSamplers, PFNGLDELETESAMPLERSPROC) +PULSE_OPENGL_FUNCTION(glDeleteShader, PFNGLDELETESHADERPROC) +PULSE_OPENGL_FUNCTION(glDeleteTextures, PFNGLDELETETEXTURESPROC) +PULSE_OPENGL_FUNCTION(glDisable, PFNGLDISABLEPROC) +PULSE_OPENGL_FUNCTION(glEnable, PFNGLENABLEPROC) +PULSE_OPENGL_FUNCTION(glEndQuery, PFNGLENDQUERYPROC) +PULSE_OPENGL_FUNCTION(glFinish, PFNGLFINISHPROC) +PULSE_OPENGL_FUNCTION(glFlush, PFNGLFLUSHPROC) +PULSE_OPENGL_FUNCTION(glGenBuffers, PFNGLGENBUFFERSPROC) +PULSE_OPENGL_FUNCTION(glGenQueries, PFNGLGENQUERIESPROC) +PULSE_OPENGL_FUNCTION(glGenSamplers, PFNGLGENSAMPLERSPROC) +PULSE_OPENGL_FUNCTION(glGenTextures, PFNGLGENTEXTURESPROC) +PULSE_OPENGL_FUNCTION(glGetActiveUniform, PFNGLGETACTIVEUNIFORMPROC) +PULSE_OPENGL_FUNCTION(glGetActiveUniformsiv, PFNGLGETACTIVEUNIFORMSIVPROC) +PULSE_OPENGL_FUNCTION(glGetActiveUniformBlockiv, PFNGLGETACTIVEUNIFORMBLOCKIVPROC) +PULSE_OPENGL_FUNCTION(glGetActiveUniformBlockName, PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) +PULSE_OPENGL_FUNCTION(glGetBooleanv, PFNGLGETBOOLEANVPROC) +PULSE_OPENGL_FUNCTION(glGetBufferParameteriv, PFNGLGETBUFFERPARAMETERIVPROC) +PULSE_OPENGL_FUNCTION(glGetError, PFNGLGETERRORPROC) +PULSE_OPENGL_FUNCTION(glGetFloatv, PFNGLGETFLOATVPROC) +PULSE_OPENGL_FUNCTION(glGetInteger64i_v, PFNGLGETINTEGER64I_VPROC) +PULSE_OPENGL_FUNCTION(glGetInteger64v, PFNGLGETINTEGER64VPROC) +PULSE_OPENGL_FUNCTION(glGetIntegeri_v, PFNGLGETINTEGERI_VPROC) +PULSE_OPENGL_FUNCTION(glGetIntegerv, PFNGLGETINTEGERVPROC) +PULSE_OPENGL_FUNCTION(glGetProgramBinary, PFNGLGETPROGRAMBINARYPROC) +PULSE_OPENGL_FUNCTION(glGetProgramInfoLog, PFNGLGETPROGRAMINFOLOGPROC) +PULSE_OPENGL_FUNCTION(glGetProgramiv, PFNGLGETPROGRAMIVPROC) +PULSE_OPENGL_FUNCTION(glGetQueryObjectuiv, PFNGLGETQUERYOBJECTUIVPROC) +PULSE_OPENGL_FUNCTION(glGetQueryiv, PFNGLGETQUERYIVPROC) +PULSE_OPENGL_FUNCTION(glGetShaderInfoLog, PFNGLGETSHADERINFOLOGPROC) +PULSE_OPENGL_FUNCTION(glGetShaderSource, PFNGLGETSHADERSOURCEPROC) +PULSE_OPENGL_FUNCTION(glGetShaderiv, PFNGLGETSHADERIVPROC) +PULSE_OPENGL_FUNCTION(glGetString, PFNGLGETSTRINGPROC) +PULSE_OPENGL_FUNCTION(glGetStringi, PFNGLGETSTRINGIPROC) +PULSE_OPENGL_FUNCTION(glGetTexParameterfv, PFNGLGETTEXPARAMETERFVPROC) +PULSE_OPENGL_FUNCTION(glGetTexParameteriv, PFNGLGETTEXPARAMETERIVPROC) +PULSE_OPENGL_FUNCTION(glGetUniformLocation, PFNGLGETUNIFORMLOCATIONPROC) +PULSE_OPENGL_FUNCTION(glGetUniformfv, PFNGLGETUNIFORMFVPROC) +PULSE_OPENGL_FUNCTION(glGetUniformiv, PFNGLGETUNIFORMIVPROC) +PULSE_OPENGL_FUNCTION(glGetUniformBlockIndex, PFNGLGETUNIFORMBLOCKINDEXPROC) +PULSE_OPENGL_FUNCTION(glIsEnabled, PFNGLISENABLEDPROC) +PULSE_OPENGL_FUNCTION(glLinkProgram, PFNGLLINKPROGRAMPROC) +PULSE_OPENGL_FUNCTION(glMapBufferRange, PFNGLMAPBUFFERRANGEPROC) +PULSE_OPENGL_FUNCTION(glPixelStorei, PFNGLPIXELSTOREIPROC) +PULSE_OPENGL_FUNCTION(glPolygonOffset, PFNGLPOLYGONOFFSETPROC) +PULSE_OPENGL_FUNCTION(glProgramBinary, PFNGLPROGRAMBINARYPROC) +PULSE_OPENGL_FUNCTION(glProgramParameteri, PFNGLPROGRAMPARAMETERIPROC) +PULSE_OPENGL_FUNCTION(glReadPixels, PFNGLREADPIXELSPROC) +PULSE_OPENGL_FUNCTION(glRenderbufferStorage, PFNGLRENDERBUFFERSTORAGEPROC) +PULSE_OPENGL_FUNCTION(glSamplerParameterf, PFNGLSAMPLERPARAMETERFPROC) +PULSE_OPENGL_FUNCTION(glSamplerParameterfv, PFNGLSAMPLERPARAMETERFVPROC) +PULSE_OPENGL_FUNCTION(glSamplerParameteri, PFNGLSAMPLERPARAMETERIPROC) +PULSE_OPENGL_FUNCTION(glSamplerParameteriv, PFNGLSAMPLERPARAMETERIVPROC) +PULSE_OPENGL_FUNCTION(glShaderBinary, PFNGLSHADERBINARYPROC) +PULSE_OPENGL_FUNCTION(glShaderSource, PFNGLSHADERSOURCEPROC) +PULSE_OPENGL_FUNCTION(glTexImage2D, PFNGLTEXIMAGE2DPROC) +PULSE_OPENGL_FUNCTION(glTexImage3D, PFNGLTEXIMAGE3DPROC) +PULSE_OPENGL_FUNCTION(glTexParameterf, PFNGLTEXPARAMETERFPROC) +PULSE_OPENGL_FUNCTION(glTexParameterfv, PFNGLTEXPARAMETERFVPROC) +PULSE_OPENGL_FUNCTION(glTexParameteri, PFNGLTEXPARAMETERIPROC) +PULSE_OPENGL_FUNCTION(glTexParameteriv, PFNGLTEXPARAMETERIVPROC) +PULSE_OPENGL_FUNCTION(glTexStorage2D, PFNGLTEXSTORAGE2DPROC) +PULSE_OPENGL_FUNCTION(glTexStorage3D, PFNGLTEXSTORAGE3DPROC) +PULSE_OPENGL_FUNCTION(glTexSubImage2D, PFNGLTEXSUBIMAGE2DPROC) +PULSE_OPENGL_FUNCTION(glTexSubImage3D, PFNGLTEXSUBIMAGE3DPROC) +PULSE_OPENGL_FUNCTION(glUniform1f, PFNGLUNIFORM1FPROC) +PULSE_OPENGL_FUNCTION(glUniform1fv, PFNGLUNIFORM1FVPROC) +PULSE_OPENGL_FUNCTION(glUniform1i, PFNGLUNIFORM1IPROC) +PULSE_OPENGL_FUNCTION(glUniform1iv, PFNGLUNIFORM1IVPROC) +PULSE_OPENGL_FUNCTION(glUniform2fv, PFNGLUNIFORM2FVPROC) +PULSE_OPENGL_FUNCTION(glUniform2iv, PFNGLUNIFORM2IVPROC) +PULSE_OPENGL_FUNCTION(glUniform3fv, PFNGLUNIFORM3FVPROC) +PULSE_OPENGL_FUNCTION(glUniform3iv, PFNGLUNIFORM3IVPROC) +PULSE_OPENGL_FUNCTION(glUniform4fv, PFNGLUNIFORM4FVPROC) +PULSE_OPENGL_FUNCTION(glUniform4iv, PFNGLUNIFORM4IVPROC) +PULSE_OPENGL_FUNCTION(glUniformBlockBinding, PFNGLUNIFORMBLOCKBINDINGPROC) +PULSE_OPENGL_FUNCTION(glUniformMatrix4fv, PFNGLUNIFORMMATRIX4FVPROC) +PULSE_OPENGL_FUNCTION(glUnmapBuffer, PFNGLUNMAPBUFFERPROC) +PULSE_OPENGL_FUNCTION(glUseProgram, PFNGLUSEPROGRAMPROC) +PULSE_OPENGL_FUNCTION(glValidateProgram, PFNGLVALIDATEPROGRAMPROC) + +// OpenGL 4.2 - OpenGL ES 3.1 +PULSE_OPENGL_GL_GLES_FUNCTION(420, 310, glBindImageTexture, PFNGLBINDIMAGETEXTUREPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(420, 310, glGetBooleani_v, PFNGLGETBOOLEANI_VPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(420, 310, glMemoryBarrier, PFNGLMEMORYBARRIERPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(420, 310, glMemoryBarrierByRegion, PFNGLMEMORYBARRIERBYREGIONPROC) + +// OpenGL 4.3 - OpenGL ES 3.1 +PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glDispatchCompute, PFNGLDISPATCHCOMPUTEPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glGetProgramInterfaceiv, PFNGLGETPROGRAMINTERFACEIVPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glGetProgramResourceiv, PFNGLGETPROGRAMRESOURCEIVPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glGetProgramResourceIndex, PFNGLGETPROGRAMRESOURCEINDEXPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glGetProgramResourceLocation, PFNGLGETPROGRAMRESOURCELOCATIONPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glGetProgramResourceName, PFNGLGETPROGRAMRESOURCENAMEPROC) diff --git a/Sources/Backends/OpenGL/OpenGLImage.c b/Sources/Backends/OpenGL/OpenGLImage.c new file mode 100644 index 0000000..29f3442 --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLImage.c @@ -0,0 +1,29 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#include + +#include "../../PulseInternal.h" +#include "OpenGL.h" +#include "OpenGLImage.h" + +PulseImage OpenGLCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos) +{ +} + +bool OpenGLIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage) +{ +} + +bool OpenGLCopyImageToBuffer(PulseCommandList cmd, const PulseImageRegion* src, const PulseBufferRegion* dst) +{ +} + +bool OpenGLBlitImage(PulseCommandList cmd, const PulseImageRegion* src, const PulseImageRegion* dst) +{ +} + +void OpenGLDestroyImage(PulseDevice device, PulseImage image) +{ +} diff --git a/Sources/Backends/OpenGL/OpenGLImage.h b/Sources/Backends/OpenGL/OpenGLImage.h new file mode 100644 index 0000000..f712bdf --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLImage.h @@ -0,0 +1,25 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +#ifdef PULSE_ENABLE_OPENGL_BACKEND + +#ifndef PULSE_OPENGL_IMAGE_H_ +#define PULSE_OPENGL_IMAGE_H_ + +#include +#include "OpenGL.h" + +typedef struct OpenGLImage +{ +} OpenGLImage; + +PulseImage OpenGLCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos); +bool OpenGLIsImageFormatValid(PulseDevice device, PulseImageFormat format, PulseImageType type, PulseImageUsageFlags usage); +bool OpenGLCopyImageToBuffer(PulseCommandList cmd, const PulseImageRegion* src, const PulseBufferRegion* dst); +bool OpenGLBlitImage(PulseCommandList cmd, const PulseImageRegion* src, const PulseImageRegion* dst); +void OpenGLDestroyImage(PulseDevice device, PulseImage image); + +#endif // PULSE_OPENGL_IMAGE_H_ + +#endif // PULSE_ENABLE_OPENGL_BACKEND diff --git a/Sources/Backends/OpenGL/OpenGLWraps.h b/Sources/Backends/OpenGL/OpenGLWraps.h new file mode 100644 index 0000000..19f5f8e --- /dev/null +++ b/Sources/Backends/OpenGL/OpenGLWraps.h @@ -0,0 +1,135 @@ +// Copyright (C) 2025 kanel +// This file is part of "Pulse" +// For conditions of distribution and use, see copyright notice in LICENSE + +// This is a generated file + +// No header guards + +#ifndef PULSE_OPENGL_WRAPPER_RET + #error "You must define PULSE_OPENGL_WRAPPER_RET before including this file" +#endif + +#ifndef PULSE_OPENGL_WRAPPER + #error "You must define PULSE_OPENGL_WRAPPER before including this file" +#endif + +PULSE_OPENGL_WRAPPER(glActiveTexture, (PulseDevice device, GLenum texture), (texture), PFNGLACTIVETEXTUREPROC) +PULSE_OPENGL_WRAPPER(glAttachShader, (PulseDevice device, GLuint program, GLuint shader), (program, shader), PFNGLATTACHSHADERPROC) +PULSE_OPENGL_WRAPPER(glBindAttribLocation, (PulseDevice device, GLuint program, GLuint index, const GLchar *name), (program, index, name), PFNGLBINDATTRIBLOCATIONPROC) +PULSE_OPENGL_WRAPPER(glBindBuffer, (PulseDevice device, GLenum target, GLuint buffer), (target, buffer), PFNGLBINDBUFFERPROC) +PULSE_OPENGL_WRAPPER(glBindRenderbuffer, (PulseDevice device, GLenum target, GLuint renderbuffer), (target, renderbuffer), PFNGLBINDRENDERBUFFERPROC) +PULSE_OPENGL_WRAPPER(glBindTexture, (PulseDevice device, GLenum target, GLuint texture), (target, texture), PFNGLBINDTEXTUREPROC) +PULSE_OPENGL_WRAPPER(glBlendEquationSeparate, (PulseDevice device, GLenum modeRGB, GLenum modeAlpha), (modeRGB, modeAlpha), PFNGLBLENDEQUATIONSEPARATEPROC) +PULSE_OPENGL_WRAPPER(glBlendFuncSeparate, (PulseDevice device, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorAlpha, GLenum dfactorAlpha), (sfactorRGB, dfactorRGB, sfactorAlpha, dfactorAlpha), PFNGLBLENDFUNCSEPARATEPROC) +PULSE_OPENGL_WRAPPER(glBufferData, (PulseDevice device, GLenum target, GLsizeiptr size, const void *data, GLenum usage), (target, size, data, usage), PFNGLBUFFERDATAPROC) +PULSE_OPENGL_WRAPPER(glBufferSubData, (PulseDevice device, GLenum target, GLintptr offset, GLsizeiptr size, const void *data), (target, offset, size, data), PFNGLBUFFERSUBDATAPROC) +PULSE_OPENGL_WRAPPER(glClear, (PulseDevice device, GLbitfield mask), (mask), PFNGLCLEARPROC) +PULSE_OPENGL_WRAPPER(glClearDepthf, (PulseDevice device, GLfloat d), (d), PFNGLCLEARDEPTHFPROC) +PULSE_OPENGL_WRAPPER(glClearStencil, (PulseDevice device, GLint s), (s), PFNGLCLEARSTENCILPROC) +PULSE_OPENGL_WRAPPER(glCompileShader, (PulseDevice device, GLuint shader), (shader), PFNGLCOMPILESHADERPROC) +PULSE_OPENGL_WRAPPER(glCompressedTexSubImage2D, (PulseDevice device, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLsizei imageSize, const void *data), (target, level, xoffset, yoffset, width, height, format, imageSize, data), PFNGLCOMPRESSEDTEXSUBIMAGE2DPROC) +PULSE_OPENGL_WRAPPER(glCopyTexSubImage2D, (PulseDevice device, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint x, GLint y, GLsizei width, GLsizei height), (target, level, xoffset, yoffset, x, y, width, height), PFNGLCOPYTEXSUBIMAGE2DPROC) +PULSE_OPENGL_WRAPPER_RET(GLuint, glCreateProgram, (PulseDevice device), (), PFNGLCREATEPROGRAMPROC) +PULSE_OPENGL_WRAPPER_RET(GLuint, glCreateShader, (PulseDevice device, GLenum type), (type), PFNGLCREATESHADERPROC) +PULSE_OPENGL_WRAPPER(glDeleteBuffers, (PulseDevice device, GLsizei n, const GLuint *buffers), (n, buffers), PFNGLDELETEBUFFERSPROC) +PULSE_OPENGL_WRAPPER(glDeleteProgram, (PulseDevice device, GLuint program), (program), PFNGLDELETEPROGRAMPROC) +PULSE_OPENGL_WRAPPER(glDeleteShader, (PulseDevice device, GLuint shader), (shader), PFNGLDELETESHADERPROC) +PULSE_OPENGL_WRAPPER(glDeleteTextures, (PulseDevice device, GLsizei n, const GLuint *textures), (n, textures), PFNGLDELETETEXTURESPROC) +PULSE_OPENGL_WRAPPER(glDisable, (PulseDevice device, GLenum cap), (cap), PFNGLDISABLEPROC) +PULSE_OPENGL_WRAPPER(glEnable, (PulseDevice device, GLenum cap), (cap), PFNGLENABLEPROC) +PULSE_OPENGL_WRAPPER(glFinish, (PulseDevice device), (), PFNGLFINISHPROC) +PULSE_OPENGL_WRAPPER(glFlush, (PulseDevice device), (), PFNGLFLUSHPROC) +PULSE_OPENGL_WRAPPER(glGenBuffers, (PulseDevice device, GLsizei n, GLuint *buffers), (n, buffers), PFNGLGENBUFFERSPROC) +PULSE_OPENGL_WRAPPER(glGenTextures, (PulseDevice device, GLsizei n, GLuint *textures), (n, textures), PFNGLGENTEXTURESPROC) +PULSE_OPENGL_WRAPPER(glGetActiveUniform, (PulseDevice device, GLuint program, GLuint index, GLsizei bufSize, GLsizei *length, GLint *size, GLenum *type, GLchar *name), (program, index, bufSize, length, size, type, name), PFNGLGETACTIVEUNIFORMPROC) +PULSE_OPENGL_WRAPPER(glGetBooleanv, (PulseDevice device, GLenum pname, GLboolean *data), (pname, data), PFNGLGETBOOLEANVPROC) +PULSE_OPENGL_WRAPPER(glGetBufferParameteriv, (PulseDevice device, GLenum target, GLenum pname, GLint *params), (target, pname, params), PFNGLGETBUFFERPARAMETERIVPROC) +PULSE_OPENGL_WRAPPER_RET(GLenum, glGetError, (PulseDevice device), (), PFNGLGETERRORPROC) +PULSE_OPENGL_WRAPPER(glGetFloatv, (PulseDevice device, GLenum pname, GLfloat *data), (pname, data), PFNGLGETFLOATVPROC) +PULSE_OPENGL_WRAPPER(glGetIntegerv, (PulseDevice device, GLenum pname, GLint *data), (pname, data), PFNGLGETINTEGERVPROC) +PULSE_OPENGL_WRAPPER(glGetProgramiv, (PulseDevice device, GLuint program, GLenum pname, GLint *params), (program, pname, params), PFNGLGETPROGRAMIVPROC) +PULSE_OPENGL_WRAPPER(glGetProgramInfoLog, (PulseDevice device, GLuint program, GLsizei bufSize, GLsizei *length, GLchar *infoLog), (program, bufSize, length, infoLog), PFNGLGETPROGRAMINFOLOGPROC) +PULSE_OPENGL_WRAPPER(glGetShaderiv, (PulseDevice device, GLuint shader, GLenum pname, GLint *params), (shader, pname, params), PFNGLGETSHADERIVPROC) +PULSE_OPENGL_WRAPPER(glGetShaderInfoLog, (PulseDevice device, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *infoLog), (shader, bufSize, length, infoLog), PFNGLGETSHADERINFOLOGPROC) +PULSE_OPENGL_WRAPPER(glGetShaderSource, (PulseDevice device, GLuint shader, GLsizei bufSize, GLsizei *length, GLchar *source), (shader, bufSize, length, source), PFNGLGETSHADERSOURCEPROC) +PULSE_OPENGL_WRAPPER_RET(const GLubyte *, glGetString, (PulseDevice device, GLenum name), (name), PFNGLGETSTRINGPROC) +PULSE_OPENGL_WRAPPER(glGetTexParameterfv, (PulseDevice device, GLenum target, GLenum pname, GLfloat *params), (target, pname, params), PFNGLGETTEXPARAMETERFVPROC) +PULSE_OPENGL_WRAPPER(glGetTexParameteriv, (PulseDevice device, GLenum target, GLenum pname, GLint *params), (target, pname, params), PFNGLGETTEXPARAMETERIVPROC) +PULSE_OPENGL_WRAPPER(glGetUniformfv, (PulseDevice device, GLuint program, GLint location, GLfloat *params), (program, location, params), PFNGLGETUNIFORMFVPROC) +PULSE_OPENGL_WRAPPER(glGetUniformiv, (PulseDevice device, GLuint program, GLint location, GLint *params), (program, location, params), PFNGLGETUNIFORMIVPROC) +PULSE_OPENGL_WRAPPER_RET(GLint, glGetUniformLocation, (PulseDevice device, GLuint program, const GLchar *name), (program, name), PFNGLGETUNIFORMLOCATIONPROC) +PULSE_OPENGL_WRAPPER_RET(GLboolean, glIsEnabled, (PulseDevice device, GLenum cap), (cap), PFNGLISENABLEDPROC) +PULSE_OPENGL_WRAPPER(glLinkProgram, (PulseDevice device, GLuint program), (program), PFNGLLINKPROGRAMPROC) +PULSE_OPENGL_WRAPPER(glPixelStorei, (PulseDevice device, GLenum pname, GLint param), (pname, param), PFNGLPIXELSTOREIPROC) +PULSE_OPENGL_WRAPPER(glPolygonOffset, (PulseDevice device, GLfloat factor, GLfloat units), (factor, units), PFNGLPOLYGONOFFSETPROC) +PULSE_OPENGL_WRAPPER(glReadPixels, (PulseDevice device, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, void *pixels), (x, y, width, height, format, type, pixels), PFNGLREADPIXELSPROC) +PULSE_OPENGL_WRAPPER(glRenderbufferStorage, (PulseDevice device, GLenum target, GLenum internalformat, GLsizei width, GLsizei height), (target, internalformat, width, height), PFNGLRENDERBUFFERSTORAGEPROC) +PULSE_OPENGL_WRAPPER(glShaderBinary, (PulseDevice device, GLsizei count, const GLuint *shaders, GLenum binaryformat, const void *binary, GLsizei length), (count, shaders, binaryformat, binary, length), PFNGLSHADERBINARYPROC) +PULSE_OPENGL_WRAPPER(glShaderSource, (PulseDevice device, GLuint shader, GLsizei count, const GLchar *const*string, const GLint *length), (shader, count, string, length), PFNGLSHADERSOURCEPROC) +PULSE_OPENGL_WRAPPER(glTexImage2D, (PulseDevice device, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels), (target, level, internalformat, width, height, border, format, type, pixels), PFNGLTEXIMAGE2DPROC) +PULSE_OPENGL_WRAPPER(glTexParameterf, (PulseDevice device, GLenum target, GLenum pname, GLfloat param), (target, pname, param), PFNGLTEXPARAMETERFPROC) +PULSE_OPENGL_WRAPPER(glTexParameterfv, (PulseDevice device, GLenum target, GLenum pname, const GLfloat *params), (target, pname, params), PFNGLTEXPARAMETERFVPROC) +PULSE_OPENGL_WRAPPER(glTexParameteri, (PulseDevice device, GLenum target, GLenum pname, GLint param), (target, pname, param), PFNGLTEXPARAMETERIPROC) +PULSE_OPENGL_WRAPPER(glTexParameteriv, (PulseDevice device, GLenum target, GLenum pname, const GLint *params), (target, pname, params), PFNGLTEXPARAMETERIVPROC) +PULSE_OPENGL_WRAPPER(glTexSubImage2D, (PulseDevice device, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels), (target, level, xoffset, yoffset, width, height, format, type, pixels), PFNGLTEXSUBIMAGE2DPROC) +PULSE_OPENGL_WRAPPER(glUniform1f, (PulseDevice device, GLint location, GLfloat v0), (location, v0), PFNGLUNIFORM1FPROC) +PULSE_OPENGL_WRAPPER(glUniform1fv, (PulseDevice device, GLint location, GLsizei count, const GLfloat *value), (location, count, value), PFNGLUNIFORM1FVPROC) +PULSE_OPENGL_WRAPPER(glUniform1i, (PulseDevice device, GLint location, GLint v0), (location, v0), PFNGLUNIFORM1IPROC) +PULSE_OPENGL_WRAPPER(glUniform1iv, (PulseDevice device, GLint location, GLsizei count, const GLint *value), (location, count, value), PFNGLUNIFORM1IVPROC) +PULSE_OPENGL_WRAPPER(glUniform2fv, (PulseDevice device, GLint location, GLsizei count, const GLfloat *value), (location, count, value), PFNGLUNIFORM2FVPROC) +PULSE_OPENGL_WRAPPER(glUniform2iv, (PulseDevice device, GLint location, GLsizei count, const GLint *value), (location, count, value), PFNGLUNIFORM2IVPROC) +PULSE_OPENGL_WRAPPER(glUniform3fv, (PulseDevice device, GLint location, GLsizei count, const GLfloat *value), (location, count, value), PFNGLUNIFORM3FVPROC) +PULSE_OPENGL_WRAPPER(glUniform3iv, (PulseDevice device, GLint location, GLsizei count, const GLint *value), (location, count, value), PFNGLUNIFORM3IVPROC) +PULSE_OPENGL_WRAPPER(glUniform4fv, (PulseDevice device, GLint location, GLsizei count, const GLfloat *value), (location, count, value), PFNGLUNIFORM4FVPROC) +PULSE_OPENGL_WRAPPER(glUniform4iv, (PulseDevice device, GLint location, GLsizei count, const GLint *value), (location, count, value), PFNGLUNIFORM4IVPROC) +PULSE_OPENGL_WRAPPER(glUniformMatrix4fv, (PulseDevice device, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value), (location, count, transpose, value), PFNGLUNIFORMMATRIX4FVPROC) +PULSE_OPENGL_WRAPPER(glUseProgram, (PulseDevice device, GLuint program), (program), PFNGLUSEPROGRAMPROC) +PULSE_OPENGL_WRAPPER(glValidateProgram, (PulseDevice device, GLuint program), (program), PFNGLVALIDATEPROGRAMPROC) +PULSE_OPENGL_WRAPPER(glTexImage3D, (PulseDevice device, GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels), (target, level, internalformat, width, height, depth, border, format, type, pixels), PFNGLTEXIMAGE3DPROC) +PULSE_OPENGL_WRAPPER(glTexSubImage3D, (PulseDevice device, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels), PFNGLTEXSUBIMAGE3DPROC) +PULSE_OPENGL_WRAPPER(glCompressedTexSubImage3D, (PulseDevice device, GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLsizei imageSize, const void *data), (target, level, xoffset, yoffset, zoffset, width, height, depth, format, imageSize, data), PFNGLCOMPRESSEDTEXSUBIMAGE3DPROC) +PULSE_OPENGL_WRAPPER(glGenQueries, (PulseDevice device, GLsizei n, GLuint *ids), (n, ids), PFNGLGENQUERIESPROC) +PULSE_OPENGL_WRAPPER(glDeleteQueries, (PulseDevice device, GLsizei n, const GLuint *ids), (n, ids), PFNGLDELETEQUERIESPROC) +PULSE_OPENGL_WRAPPER(glBeginQuery, (PulseDevice device, GLenum target, GLuint id), (target, id), PFNGLBEGINQUERYPROC) +PULSE_OPENGL_WRAPPER(glEndQuery, (PulseDevice device, GLenum target), (target), PFNGLENDQUERYPROC) +PULSE_OPENGL_WRAPPER(glGetQueryiv, (PulseDevice device, GLenum target, GLenum pname, GLint *params), (target, pname, params), PFNGLGETQUERYIVPROC) +PULSE_OPENGL_WRAPPER(glGetQueryObjectuiv, (PulseDevice device, GLuint id, GLenum pname, GLuint *params), (id, pname, params), PFNGLGETQUERYOBJECTUIVPROC) +PULSE_OPENGL_WRAPPER_RET(GLboolean, glUnmapBuffer, (PulseDevice device, GLenum target), (target), PFNGLUNMAPBUFFERPROC) +PULSE_OPENGL_WRAPPER_RET(void *, glMapBufferRange, (PulseDevice device, GLenum target, GLintptr offset, GLsizeiptr length, GLbitfield access), (target, offset, length, access), PFNGLMAPBUFFERRANGEPROC) +PULSE_OPENGL_WRAPPER(glGetIntegeri_v, (PulseDevice device, GLenum target, GLuint index, GLint *data), (target, index, data), PFNGLGETINTEGERI_VPROC) +PULSE_OPENGL_WRAPPER(glBindBufferRange, (PulseDevice device, GLenum target, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size), (target, index, buffer, offset, size), PFNGLBINDBUFFERRANGEPROC) +PULSE_OPENGL_WRAPPER(glClearBufferuiv, (PulseDevice device, GLenum buffer, GLint drawbuffer, const GLuint *value), (buffer, drawbuffer, value), PFNGLCLEARBUFFERUIVPROC) +PULSE_OPENGL_WRAPPER(glClearBufferfv, (PulseDevice device, GLenum buffer, GLint drawbuffer, const GLfloat *value), (buffer, drawbuffer, value), PFNGLCLEARBUFFERFVPROC) +PULSE_OPENGL_WRAPPER(glClearBufferfi, (PulseDevice device, GLenum buffer, GLint drawbuffer, GLfloat depth, GLint stencil), (buffer, drawbuffer, depth, stencil), PFNGLCLEARBUFFERFIPROC) +PULSE_OPENGL_WRAPPER_RET(const GLubyte *, glGetStringi, (PulseDevice device, GLenum name, GLuint index), (name, index), PFNGLGETSTRINGIPROC) +PULSE_OPENGL_WRAPPER(glCopyBufferSubData, (PulseDevice device, GLenum readTarget, GLenum writeTarget, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size), (readTarget, writeTarget, readOffset, writeOffset, size), PFNGLCOPYBUFFERSUBDATAPROC) +PULSE_OPENGL_WRAPPER(glGetActiveUniformsiv, (PulseDevice device, GLuint program, GLsizei uniformCount, const GLuint *uniformIndices, GLenum pname, GLint *params), (program, uniformCount, uniformIndices, pname, params), PFNGLGETACTIVEUNIFORMSIVPROC) +PULSE_OPENGL_WRAPPER_RET(GLuint, glGetUniformBlockIndex, (PulseDevice device, GLuint program, const GLchar *uniformBlockName), (program, uniformBlockName), PFNGLGETUNIFORMBLOCKINDEXPROC) +PULSE_OPENGL_WRAPPER(glGetActiveUniformBlockiv, (PulseDevice device, GLuint program, GLuint uniformBlockIndex, GLenum pname, GLint *params), (program, uniformBlockIndex, pname, params), PFNGLGETACTIVEUNIFORMBLOCKIVPROC) +PULSE_OPENGL_WRAPPER(glGetActiveUniformBlockName, (PulseDevice device, GLuint program, GLuint uniformBlockIndex, GLsizei bufSize, GLsizei *length, GLchar *uniformBlockName), (program, uniformBlockIndex, bufSize, length, uniformBlockName), PFNGLGETACTIVEUNIFORMBLOCKNAMEPROC) +PULSE_OPENGL_WRAPPER(glUniformBlockBinding, (PulseDevice device, GLuint program, GLuint uniformBlockIndex, GLuint uniformBlockBinding), (program, uniformBlockIndex, uniformBlockBinding), PFNGLUNIFORMBLOCKBINDINGPROC) +PULSE_OPENGL_WRAPPER(glGetInteger64v, (PulseDevice device, GLenum pname, GLint64 *data), (pname, data), PFNGLGETINTEGER64VPROC) +PULSE_OPENGL_WRAPPER(glGetInteger64i_v, (PulseDevice device, GLenum target, GLuint index, GLint64 *data), (target, index, data), PFNGLGETINTEGER64I_VPROC) +PULSE_OPENGL_WRAPPER(glGenSamplers, (PulseDevice device, GLsizei count, GLuint *samplers), (count, samplers), PFNGLGENSAMPLERSPROC) +PULSE_OPENGL_WRAPPER(glDeleteSamplers, (PulseDevice device, GLsizei count, const GLuint *samplers), (count, samplers), PFNGLDELETESAMPLERSPROC) +PULSE_OPENGL_WRAPPER(glBindSampler, (PulseDevice device, GLuint unit, GLuint sampler), (unit, sampler), PFNGLBINDSAMPLERPROC) +PULSE_OPENGL_WRAPPER(glSamplerParameteri, (PulseDevice device, GLuint sampler, GLenum pname, GLint param), (sampler, pname, param), PFNGLSAMPLERPARAMETERIPROC) +PULSE_OPENGL_WRAPPER(glSamplerParameteriv, (PulseDevice device, GLuint sampler, GLenum pname, const GLint *param), (sampler, pname, param), PFNGLSAMPLERPARAMETERIVPROC) +PULSE_OPENGL_WRAPPER(glSamplerParameterf, (PulseDevice device, GLuint sampler, GLenum pname, GLfloat param), (sampler, pname, param), PFNGLSAMPLERPARAMETERFPROC) +PULSE_OPENGL_WRAPPER(glSamplerParameterfv, (PulseDevice device, GLuint sampler, GLenum pname, const GLfloat *param), (sampler, pname, param), PFNGLSAMPLERPARAMETERFVPROC) +PULSE_OPENGL_WRAPPER(glGetProgramBinary, (PulseDevice device, GLuint program, GLsizei bufSize, GLsizei *length, GLenum *binaryFormat, void *binary), (program, bufSize, length, binaryFormat, binary), PFNGLGETPROGRAMBINARYPROC) +PULSE_OPENGL_WRAPPER(glProgramBinary, (PulseDevice device, GLuint program, GLenum binaryFormat, const void *binary, GLsizei length), (program, binaryFormat, binary, length), PFNGLPROGRAMBINARYPROC) +PULSE_OPENGL_WRAPPER(glProgramParameteri, (PulseDevice device, GLuint program, GLenum pname, GLint value), (program, pname, value), PFNGLPROGRAMPARAMETERIPROC) +PULSE_OPENGL_WRAPPER(glTexStorage2D, (PulseDevice device, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height), (target, levels, internalformat, width, height), PFNGLTEXSTORAGE2DPROC) +PULSE_OPENGL_WRAPPER(glTexStorage3D, (PulseDevice device, GLenum target, GLsizei levels, GLenum internalformat, GLsizei width, GLsizei height, GLsizei depth), (target, levels, internalformat, width, height, depth), PFNGLTEXSTORAGE3DPROC) +PULSE_OPENGL_WRAPPER(glDispatchCompute, (PulseDevice device, GLuint num_groups_x, GLuint num_groups_y, GLuint num_groups_z), (num_groups_x, num_groups_y, num_groups_z), PFNGLDISPATCHCOMPUTEPROC) +PULSE_OPENGL_WRAPPER(glGetProgramInterfaceiv, (PulseDevice device, GLuint program, GLenum programInterface, GLenum pname, GLint *params), (program, programInterface, pname, params), PFNGLGETPROGRAMINTERFACEIVPROC) +PULSE_OPENGL_WRAPPER_RET(GLuint, glGetProgramResourceIndex, (PulseDevice device, GLuint program, GLenum programInterface, const GLchar *name), (program, programInterface, name), PFNGLGETPROGRAMRESOURCEINDEXPROC) +PULSE_OPENGL_WRAPPER(glGetProgramResourceName, (PulseDevice device, GLuint program, GLenum programInterface, GLuint index, GLsizei bufSize, GLsizei *length, GLchar *name), (program, programInterface, index, bufSize, length, name), PFNGLGETPROGRAMRESOURCENAMEPROC) +PULSE_OPENGL_WRAPPER(glGetProgramResourceiv, (PulseDevice device, GLuint program, GLenum programInterface, GLuint index, GLsizei propCount, const GLenum *props, GLsizei bufSize, GLsizei *length, GLint *params), (program, programInterface, index, propCount, props, bufSize, length, params), PFNGLGETPROGRAMRESOURCEIVPROC) +PULSE_OPENGL_WRAPPER_RET(GLint, glGetProgramResourceLocation, (PulseDevice device, GLuint program, GLenum programInterface, const GLchar *name), (program, programInterface, name), PFNGLGETPROGRAMRESOURCELOCATIONPROC) +PULSE_OPENGL_WRAPPER(glBindImageTexture, (PulseDevice device, GLuint unit, GLuint texture, GLint level, GLboolean layered, GLint layer, GLenum access, GLenum format), (unit, texture, level, layered, layer, access, format), PFNGLBINDIMAGETEXTUREPROC) +PULSE_OPENGL_WRAPPER(glGetBooleani_v, (PulseDevice device, GLenum target, GLuint index, GLboolean *data), (target, index, data), PFNGLGETBOOLEANI_VPROC) +PULSE_OPENGL_WRAPPER(glMemoryBarrier, (PulseDevice device, GLbitfield barriers), (barriers), PFNGLMEMORYBARRIERPROC) +PULSE_OPENGL_WRAPPER(glMemoryBarrierByRegion, (PulseDevice device, GLbitfield barriers), (barriers), PFNGLMEMORYBARRIERBYREGIONPROC) diff --git a/Sources/PulseBackend.c b/Sources/PulseBackend.c index e5b168a..54f4a48 100644 --- a/Sources/PulseBackend.c +++ b/Sources/PulseBackend.c @@ -71,7 +71,10 @@ void PulseLogBackend(PulseBackend backend, PulseDebugMessageSeverity type, const if(type != PULSE_DEBUG_MESSAGE_SEVERITY_INFO) { - shift = snprintf(complete_message, LOG_MESSAGE_MAX_LENGTH, "[%s:%d] ", function, line); + if(line != 0) + shift = snprintf(complete_message, LOG_MESSAGE_MAX_LENGTH, "[%s:%d] ", function, line); + else + shift = snprintf(complete_message, LOG_MESSAGE_MAX_LENGTH, "[%s] ", function); if(backend->debug_level == PULSE_PARANOID_DEBUG && type == PULSE_DEBUG_MESSAGE_SEVERITY_WARNING) type = PULSE_DEBUG_MESSAGE_SEVERITY_ERROR; if(shift == -1) @@ -112,13 +115,13 @@ static PulseBackend PulseGetBackendFromFlag(PulseBackendBits flag) #ifdef PULSE_ENABLE_WEBGPU_BACKEND case PULSE_BACKEND_WEBGPU: return &WebGPUDriver; #endif + #ifdef PULSE_ENABLE_OPENGL_BACKEND + case PULSE_BACKEND_OPENGL: return &OpenGLDriver; + case PULSE_BACKEND_OPENGL_ES: return &OpenGLESDriver; + #endif #ifdef PULSE_ENABLE_SOFTWARE_BACKEND case PULSE_BACKEND_SOFTWARE: return &SoftwareDriver; #endif - #ifdef PULSE_ENABLE_OPENGL_BACKEND - case PULSE_BACKEND_OPENGL: - case PULSE_BACKEND_OPENGL_ES: return &OpenGLESDriver; - #endif default: break; } diff --git a/xmake.lua b/xmake.lua index a6f639b..61ee651 100644 --- a/xmake.lua +++ b/xmake.lua @@ -46,6 +46,10 @@ local backends = { else remove_files("Sources/Backends/OpenGL/WGL/**.c") end + end, + before_build = function(target, os) + local gles_dir = target:pkg("opengl-headers"):installdir() + os.runv("python", {"Scripts/GenerateOpenGLDefs.py", "Sources/Backends/OpenGL/OpenGLFunctions.h", gles_dir .. "/include/GLES3/gl31.h", "Sources/Backends/OpenGL/OpenGLWraps.h"}) end }, } @@ -124,6 +128,14 @@ target("pulse_gpu") add_defines("PULSE_PLAT_WASM") end + before_build(function(target) + for name, module in pairs(backends) do + if module ~= nil and has_config(module.option) and module.before_build then + module.before_build(target, os) + end + end + end) + for name, module in pairs(backends) do if module ~= nil and has_config(module.option) then if module.packages then