mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-10 15:03:34 +00:00
starting merge
This commit is contained in:
@@ -28,6 +28,6 @@ int main(int ac, char** av)
|
||||
PulseSetDebugCallback(backend, DebugCallBack);
|
||||
|
||||
PulseUnloadBackend(backend);
|
||||
puts("Successfully executed Pulse example using OpenGL !");
|
||||
printf("Successfully executed Pulse example using %s !\n", backend_type == PULSE_BACKEND_OPENGL ? "OpenGL" : "OpenGL ES");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// 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_EGL_CONTEXT_H_
|
||||
#define PULSE_EGL_CONTEXT_H_
|
||||
|
||||
typedef struct EGLContext
|
||||
{
|
||||
EGLDisplay display;
|
||||
EGLSurface surface;
|
||||
EGLContext handle;
|
||||
} EGLContext;
|
||||
|
||||
#endif // PULSE_EGL_CONTEXT_H_
|
||||
|
||||
#endif // PULSE_ENABLE_OPENGL_BACKEND
|
||||
107
Sources/Backends/OpenGL/EGL/EGLInstance.c
git.filemode.normal_file
107
Sources/Backends/OpenGL/EGL/EGLInstance.c
git.filemode.normal_file
@@ -0,0 +1,107 @@
|
||||
// Copyright (C) 2025 kanel
|
||||
// This file is part of "Pulse"
|
||||
// For conditions of distribution and use, see copyright notice in LICENSE
|
||||
|
||||
#include "EGLInstance.h"
|
||||
#include "../../../PulseInternal.h"
|
||||
|
||||
static PulseLibModule egl_lib_module = PULSE_NULL_LIB_MODULE;
|
||||
static uint32_t loader_references_count = 0;
|
||||
|
||||
static bool EGLLoadFunctions(EGLInstance* instance)
|
||||
{
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
const char* libnames[] = {
|
||||
"libEGL.dll"
|
||||
};
|
||||
#else
|
||||
const char* libnames[] = {
|
||||
"libEGL.so.1",
|
||||
"libEGL.so"
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
for(size_t i = 0; i < sizeof(libnames) / sizeof(const char*); i++)
|
||||
{
|
||||
if(loader_references_count == 0)
|
||||
egl_lib_module = PulseLoadLibrary(libnames[i]);
|
||||
if(egl_lib_module)
|
||||
{
|
||||
instance->eglGetProcAddress = (PFNEGLGETPROCADDRESSPROC)PulseLoadSymbolFromLibModule(egl_lib_module, "eglGetProcAddress");
|
||||
if(instance->eglGetProcAddress == PULSE_NULLPTR)
|
||||
{
|
||||
PulseUnloadLibrary(egl_lib_module);
|
||||
egl_lib_module = PULSE_NULL_LIB_MODULE;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!egl_lib_module)
|
||||
{
|
||||
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
|
||||
return false;
|
||||
}
|
||||
loader_references_count++;
|
||||
|
||||
#define PULSE_EGL_FUNCTION(fn, T) \
|
||||
instance->fn = (T)instance->eglGetProcAddress(#fn); \
|
||||
if(!instance->fn) \
|
||||
return false;
|
||||
#include "EGLFunctions.h"
|
||||
#undef PULSE_EGL_FUNCTION
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool EGLLoadInstance(EGLInstance* instance, bool es_context)
|
||||
{
|
||||
PULSE_CHECK_PTR_RETVAL(instance, false);
|
||||
|
||||
if(!EGLLoadFunctions(instance))
|
||||
return false;
|
||||
|
||||
instance->display = instance->eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
PULSE_CHECK_PTR_RETVAL(instance->display, false);
|
||||
|
||||
instance->eglInitialize(instance->display, PULSE_NULLPTR, PULSE_NULLPTR);
|
||||
EGLint attribs[] = {
|
||||
EGL_RENDERABLE_TYPE, es_context ? EGL_OPENGL_ES3_BIT : EGL_OPENGL_BIT,
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
EGLint num_configs;
|
||||
instance->eglChooseConfig(instance->display, attribs, &instance->config, 1, &num_configs);
|
||||
EGLint ctxAttribs[] = {
|
||||
es_context ? EGL_CONTEXT_CLIENT_VERSION : EGL_CONTEXT_MAJOR_VERSION, 3,
|
||||
EGL_NONE
|
||||
};
|
||||
instance->eglBindAPI(es_context ? EGL_OPENGL_ES_API : EGL_OPENGL_API);
|
||||
instance->context = instance->eglCreateContext(instance->display, instance->config, EGL_NO_CONTEXT, ctxAttribs);
|
||||
PULSE_CHECK_PTR_RETVAL(instance->context, false);
|
||||
|
||||
EGLint pbufferAttribs[] = {
|
||||
EGL_WIDTH, 1,
|
||||
EGL_HEIGHT, 1,
|
||||
EGL_NONE
|
||||
};
|
||||
instance->surface = instance->eglCreatePbufferSurface(instance->display, instance->config, pbufferAttribs);
|
||||
PULSE_CHECK_PTR_RETVAL(instance->surface, false);
|
||||
|
||||
return instance->eglMakeCurrent(instance->display, instance->surface, instance->surface, instance->context);
|
||||
}
|
||||
|
||||
void EGLUnloadInstance(EGLInstance* instance)
|
||||
{
|
||||
PULSE_CHECK_PTR(instance);
|
||||
instance->eglDestroySurface(instance->display, instance->surface);
|
||||
instance->eglDestroyContext(instance->display, instance->context);
|
||||
instance->eglTerminate(instance->display);
|
||||
|
||||
loader_references_count--;
|
||||
if(loader_references_count != 0)
|
||||
return;
|
||||
PulseUnloadLibrary(egl_lib_module);
|
||||
egl_lib_module = PULSE_NULL_LIB_MODULE;
|
||||
}
|
||||
31
Sources/Backends/OpenGL/EGL/EGLInstance.h
git.filemode.normal_file
31
Sources/Backends/OpenGL/EGL/EGLInstance.h
git.filemode.normal_file
@@ -0,0 +1,31 @@
|
||||
// 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_EGL_CONTEXT_H_
|
||||
#define PULSE_EGL_CONTEXT_H_
|
||||
|
||||
#define EGL_EGL_PROTOTYPES 0
|
||||
#include <EGL/egl.h>
|
||||
#include <Pulse.h>
|
||||
|
||||
typedef struct EGLInstance
|
||||
{
|
||||
EGLDisplay display;
|
||||
EGLSurface surface;
|
||||
EGLContext context;
|
||||
EGLConfig config;
|
||||
|
||||
#define PULSE_EGL_FUNCTION(fn, T) T fn;
|
||||
#include "EGLFunctions.h"
|
||||
#undef PULSE_EGL_FUNCTION
|
||||
} EGLInstance;
|
||||
|
||||
bool EGLLoadInstance(EGLInstance* instance, bool es_context);
|
||||
void EGLUnloadInstance(EGLInstance* instance);
|
||||
|
||||
#endif // PULSE_EGL_CONTEXT_H_
|
||||
|
||||
#endif // PULSE_ENABLE_OPENGL_BACKEND
|
||||
@@ -9,11 +9,15 @@
|
||||
|
||||
PulseBackendFlags OpenGLCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used)
|
||||
{
|
||||
if(candidates != PULSE_BACKEND_ANY && (candidates & PULSE_BACKEND_OPENGL) == 0)
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -23,12 +27,18 @@ bool OpenGLLoadBackend(PulseBackend backend, PulseDebugLevel debug_level)
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -48,12 +58,14 @@ bool OpenGLESLoadBackend(PulseBackend backend, PulseDebugLevel debug_level)
|
||||
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)
|
||||
{
|
||||
EGLUnloadInstance(&OPENGL_RETRIEVE_DRIVER_DATA_AS(backend, OpenGLDriverData*)->egl_instance);
|
||||
free(backend->driver_data);
|
||||
}
|
||||
|
||||
|
||||
@@ -11,8 +11,14 @@
|
||||
|
||||
#define OPENGL_RETRIEVE_DRIVER_DATA_AS(handle, cast) ((cast)handle->driver_data)
|
||||
|
||||
#include "EGL/EGLInstance.h"
|
||||
|
||||
typedef struct OpenGLDriverData
|
||||
{
|
||||
union
|
||||
{
|
||||
EGLInstance egl_instance;
|
||||
};
|
||||
} OpenGLDriverData;
|
||||
|
||||
PulseBackendFlags OpenGLCheckSupport(PulseBackendFlags candidates, PulseShaderFormatsFlags shader_formats_used); // Return PULSE_BACKEND_OPENGL in case of success and PULSE_BACKEND_INVALID otherwise
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
static void VulkanInitCommandList(VulkanCommandPool* pool, PulseCommandList cmd)
|
||||
{
|
||||
PULSE_CHECK_PTR(pool);
|
||||
PULSE_CHECK_PTR(cmd);
|
||||
PULSE_CHECK_HANDLE(cmd);
|
||||
|
||||
VulkanDevice* vulkan_device = VULKAN_RETRIEVE_DRIVER_DATA_AS(pool->device, VulkanDevice*);
|
||||
VulkanCommandList* vulkan_cmd = VULKAN_RETRIEVE_DRIVER_DATA_AS(cmd, VulkanCommandList*);
|
||||
|
||||
@@ -11,35 +11,7 @@
|
||||
#include "VulkanDevice.h"
|
||||
#include "VulkanInstance.h"
|
||||
|
||||
#ifdef PULSE_PLAT_MACOS
|
||||
#include <stdlib.h> // getenv
|
||||
#endif
|
||||
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
typedef const char* LPCSTR;
|
||||
typedef struct HINSTANCE__* HINSTANCE;
|
||||
typedef HINSTANCE HMODULE;
|
||||
#if defined(_MINWINDEF_)
|
||||
/* minwindef.h defines FARPROC, and attempting to redefine it may conflict with -Wstrict-prototypes */
|
||||
#elif defined(_WIN64)
|
||||
typedef __int64 (__stdcall* FARPROC)(void);
|
||||
#else
|
||||
typedef int (__stdcall* FARPROC)(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
__declspec(dllimport) HMODULE __stdcall LoadLibraryA(LPCSTR);
|
||||
__declspec(dllimport) FARPROC __stdcall GetProcAddress(HMODULE, LPCSTR);
|
||||
__declspec(dllimport) int __stdcall FreeLibrary(HMODULE);
|
||||
typedef HMODULE LibModule;
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
typedef void* LibModule;
|
||||
#endif
|
||||
|
||||
static LibModule vulkan_lib_module = PULSE_NULLPTR;
|
||||
|
||||
static PulseLibModule vulkan_lib_module = PULSE_NULL_LIB_MODULE;
|
||||
static uint32_t loader_references_count = 0;
|
||||
|
||||
static bool VulkanLoadGlobalFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*));
|
||||
@@ -62,33 +34,6 @@ static inline PFN_vkVoidFunction vkGetDeviceProcAddrStub(VulkanInstance* instanc
|
||||
return fn;
|
||||
}
|
||||
|
||||
static inline LibModule LoadLibrary(const char* libname)
|
||||
{
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
return LoadLibraryA(libname);
|
||||
#else
|
||||
return dlopen(libname, RTLD_NOW | RTLD_LOCAL);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void* GetSymbol(LibModule module, const char* name)
|
||||
{
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
return (void*)(void(*)(void))GetProcAddress(module, name);
|
||||
#else
|
||||
return dlsym(module, name);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void UnloadLibrary(LibModule lib)
|
||||
{
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
FreeLibrary(lib);
|
||||
#else
|
||||
dlclose(lib);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool VulkanInitLoader()
|
||||
{
|
||||
#if defined(PULSE_PLAT_WINDOWS)
|
||||
@@ -116,15 +61,17 @@ bool VulkanInitLoader()
|
||||
|
||||
for(size_t i = 0; i < sizeof(libnames) / sizeof(const char*); i++)
|
||||
{
|
||||
vulkan_lib_module = LoadLibrary(libnames[i]);
|
||||
vulkan_lib_module = PulseLoadLibrary(libnames[i]);
|
||||
if(vulkan_lib_module)
|
||||
{
|
||||
VulkanGetGlobal()->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)GetSymbol(vulkan_lib_module, "vkGetInstanceProcAddr");
|
||||
VulkanGetGlobal()->vkGetInstanceProcAddr = (PFN_vkGetInstanceProcAddr)PulseLoadSymbolFromLibModule(vulkan_lib_module, "vkGetInstanceProcAddr");
|
||||
if(VulkanGetGlobal()->vkGetInstanceProcAddr == PULSE_NULLPTR)
|
||||
{
|
||||
UnloadLibrary(vulkan_lib_module);
|
||||
PulseUnloadLibrary(vulkan_lib_module);
|
||||
vulkan_lib_module = PULSE_NULLPTR;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(!vulkan_lib_module)
|
||||
@@ -151,8 +98,8 @@ void VulkanLoaderShutdown()
|
||||
loader_references_count--;
|
||||
if(loader_references_count != 0)
|
||||
return;
|
||||
UnloadLibrary(vulkan_lib_module);
|
||||
vulkan_lib_module = PULSE_NULLPTR;
|
||||
PulseUnloadLibrary(vulkan_lib_module);
|
||||
vulkan_lib_module = PULSE_NULL_LIB_MODULE;
|
||||
}
|
||||
|
||||
static bool VulkanLoadGlobalFunctions(void* context, PFN_vkVoidFunction (*load)(void*, const char*))
|
||||
|
||||
@@ -116,7 +116,7 @@ static PulseBackend PulseGetBackendFromFlag(PulseBackendBits flag)
|
||||
case PULSE_BACKEND_SOFTWARE: return &SoftwareDriver;
|
||||
#endif
|
||||
#ifdef PULSE_ENABLE_OPENGL_BACKEND
|
||||
case PULSE_BACKEND_OPENGL: return &OpenGLDriver;
|
||||
case PULSE_BACKEND_OPENGL:
|
||||
case PULSE_BACKEND_OPENGL_ES: return &OpenGLESDriver;
|
||||
#endif
|
||||
|
||||
|
||||
@@ -33,3 +33,51 @@
|
||||
emscripten_thread_sleep(ms);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
PULSE_IMPORT_API HMODULE __stdcall LoadLibraryA(LPCSTR);
|
||||
PULSE_IMPORT_API FARPROC __stdcall GetProcAddress(HMODULE, LPCSTR);
|
||||
PULSE_IMPORT_API int __stdcall FreeLibrary(HMODULE);
|
||||
#else
|
||||
#ifdef PULSE_PLAT_MACOS
|
||||
#include <stdlib.h>
|
||||
#endif
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
PulseLibModule PulseLoadLibrary(const char* libpath)
|
||||
{
|
||||
PulseLibModule module;
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
module = LoadLibraryA(libpath);
|
||||
#else
|
||||
dlerror();
|
||||
module = dlopen(libpath, RTLD_NOW | RTLD_LOCAL);
|
||||
#endif
|
||||
return (module ? module : PULSE_NULL_LIB_MODULE);
|
||||
}
|
||||
|
||||
PFN_PulseLibFunction PulseLoadSymbolFromLibModule(PulseLibModule module, const char* symbol)
|
||||
{
|
||||
if(module == PULSE_NULL_LIB_MODULE)
|
||||
return PULSE_NULLPTR;
|
||||
PFN_PulseLibFunction function;
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
function = (PFN_PulseLibFunction)GetProcAddress(module, symbol);
|
||||
#else
|
||||
void* symbol_ptr = (PFN_PulseLibFunction)dlsym(module, symbol);
|
||||
*(void**)(&function) = symbol_ptr;
|
||||
#endif
|
||||
return function;
|
||||
}
|
||||
|
||||
void PulseUnloadLibrary(PulseLibModule module)
|
||||
{
|
||||
if(module == PULSE_NULL_LIB_MODULE)
|
||||
return;
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
FreeLibrary(module);
|
||||
#else
|
||||
dlclose(module);
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -157,6 +157,35 @@ typedef struct PulseComputePassHandler
|
||||
PulseThreadID PulseGetThreadID();
|
||||
void PulseSleep(int32_t ms);
|
||||
|
||||
#ifdef KANEL_CLI_PLAT_WINDOWS
|
||||
typedef const char* LPCSTR;
|
||||
typedef struct HINSTANCE__* HINSTANCE;
|
||||
typedef HINSTANCE HMODULE;
|
||||
#if defined(_MINWINDEF_)
|
||||
/* minwindef.h defines FARPROC, and attempting to redefine it may conflict with -Wstrict-prototypes */
|
||||
#elif defined(_WIN64)
|
||||
typedef __int64 (__stdcall* FARPROC)(void);
|
||||
#else
|
||||
typedef int (__stdcall* FARPROC)(void);
|
||||
#endif
|
||||
#else
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
||||
#ifdef PULSE_PLAT_WINDOWS
|
||||
typedef HMODULE PulseLibModule;
|
||||
#else
|
||||
typedef void* PulseLibModule;
|
||||
#endif
|
||||
|
||||
typedef void(*PFN_PulseLibFunction)(void);
|
||||
|
||||
#define PULSE_NULL_LIB_MODULE PULSE_NULLPTR
|
||||
|
||||
PulseLibModule PulseLoadLibrary(const char* libpath); // Returns PULSE_NULL_LIB_MODULE in case of failure
|
||||
PFN_PulseLibFunction PulseLoadSymbolFromLibModule(PulseLibModule module, const char* symbol);
|
||||
void PulseUnloadLibrary(PulseLibModule module);
|
||||
|
||||
void PulseSetInternalError(PulseErrorType error);
|
||||
|
||||
void PulseLogBackend(PulseBackend backend, PulseDebugMessageSeverity type, const char* message, const char* file, const char* function, int line, ...);
|
||||
|
||||
Reference in New Issue
Block a user