working on OpenGL loading

This commit is contained in:
2025-03-23 00:43:40 +01:00
parent 3e6aa18fbe
commit 6c2119d806
28 changed files with 1088 additions and 63 deletions

1
.gitignore vendored
View File

@@ -7,6 +7,7 @@
!/Includes/
!/Sources/
!/Tests/
!/Scripts/
!/Examples/
!/Xmake/
!/.github/

View File

@@ -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;

71
Scripts/GenerateOpenGLDefs.py git.filemode.normal_file
View File

@@ -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()

View File

@@ -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)

View File

@@ -2,8 +2,12 @@
// This file is part of "Pulse"
// For conditions of distribution and use, see copyright notice in LICENSE
#include <string.h>
#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 <stdio.h>
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);

View File

@@ -9,6 +9,7 @@
#define EGL_EGL_PROTOTYPES 0
#include <EGL/egl.h>
#include <EGL/eglext.h>
#include <Pulse.h>
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_

View File

@@ -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

View File

@@ -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 <GLES3/gl31.h>
#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

32
Sources/Backends/OpenGL/OpenGLBuffer.c git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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)
{
}

26
Sources/Backends/OpenGL/OpenGLBuffer.h git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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

21
Sources/Backends/OpenGL/OpenGLCommandList.c git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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)
{
}

24
Sources/Backends/OpenGL/OpenGLCommandList.h git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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

45
Sources/Backends/OpenGL/OpenGLComputePass.c git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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)
{
}

33
Sources/Backends/OpenGL/OpenGLComputePass.h git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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

View File

@@ -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 <Pulse.h>
#include "../../PulseInternal.h"
#include "OpenGL.h"
#include "OpenGLComputePipeline.h"
PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info)
{
}
void OpenGLDestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline)
{
}

View File

@@ -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 <Pulse.h>
#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

213
Sources/Backends/OpenGL/OpenGLDevice.c git.filemode.normal_file
View File

@@ -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 <stdio.h>
#include <string.h>
#include <Pulse.h>
#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);
}

42
Sources/Backends/OpenGL/OpenGLDevice.h git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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

29
Sources/Backends/OpenGL/OpenGLEnums.h git.filemode.normal_file
View File

@@ -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

25
Sources/Backends/OpenGL/OpenGLFence.c git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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)
{
}

24
Sources/Backends/OpenGL/OpenGLFence.h git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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

142
Sources/Backends/OpenGL/OpenGLFunctions.h git.filemode.normal_file
View File

@@ -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)

29
Sources/Backends/OpenGL/OpenGLImage.c git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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)
{
}

25
Sources/Backends/OpenGL/OpenGLImage.h git.filemode.normal_file
View File

@@ -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 <Pulse.h>
#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

135
Sources/Backends/OpenGL/OpenGLWraps.h git.filemode.normal_file
View File

@@ -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)

View File

@@ -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;
}

View File

@@ -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