diff --git a/Examples/OpenGL/main.c b/Examples/OpenGL/main.c index 54dbc5c..997a276 100644 --- a/Examples/OpenGL/main.c +++ b/Examples/OpenGL/main.c @@ -4,7 +4,7 @@ #include #include -#define GLSL_SOURCE(...) #__VA_ARGS__ +#define GLSL_SOURCE(version, ...) "#version " version "\n" #__VA_ARGS__ #define BUFFER_SIZE (256 * sizeof(uint32_t)) @@ -21,6 +21,13 @@ void DebugCallBack(PulseDebugMessageSeverity severity, const char* message) printf("Pulse: %s\n", message); } +const char* glsl_source = GLSL_SOURCE("430 core", + layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; + void main() + { + } +); + int main(int ac, char** av) { PulseBackendFlags backend_type = PULSE_BACKEND_OPENGL; @@ -35,6 +42,71 @@ int main(int ac, char** av) buffer_create_info.usage = PULSE_BUFFER_USAGE_STORAGE_READ | PULSE_BUFFER_USAGE_STORAGE_WRITE | PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD; PulseBuffer buffer = PulseCreateBuffer(device, &buffer_create_info); +/* + // GPU computations + { + PulseComputePipelineCreateInfo info = { 0 }; + info.code_size = strlen(glsl_source); + info.code = (const uint8_t*)glsl_source; + info.entrypoint = "main"; + info.format = PULSE_SHADER_FORMAT_GLSL_BIT; + info.num_readwrite_storage_buffers = 1; + PulseComputePipeline pipeline = PulseCreateComputePipeline(device, &info); + + PulseFence fence = PulseCreateFence(device); + PulseCommandList cmd = PulseRequestCommandList(device, PULSE_COMMAND_LIST_GENERAL); + + PulseComputePass pass = PulseBeginComputePass(cmd); + //PulseBindStorageBuffers(pass, &buffer, 1); + PulseBindComputePipeline(pass, pipeline); + PulseDispatchComputations(pass, 16, 1, 1); + PulseEndComputePass(pass); + + PulseSubmitCommandList(device, cmd, fence); + PulseWaitForFences(device, &fence, 1, true); + + PulseReleaseCommandList(device, cmd); + PulseDestroyFence(device, fence); + PulseDestroyComputePipeline(device, pipeline); + } +*/ + + // Get result and read it on CPU + { + PulseBufferCreateInfo staging_buffer_create_info = { 0 }; + staging_buffer_create_info.size = BUFFER_SIZE; + staging_buffer_create_info.usage = PULSE_BUFFER_USAGE_TRANSFER_UPLOAD | PULSE_BUFFER_USAGE_TRANSFER_DOWNLOAD; + PulseBuffer staging_buffer = PulseCreateBuffer(device, &staging_buffer_create_info); + + PulseFence fence = PulseCreateFence(device); + PulseCommandList cmd = PulseRequestCommandList(device, PULSE_COMMAND_LIST_TRANSFER_ONLY); + + PulseBufferRegion src_region = { 0 }; + src_region.buffer = buffer; + src_region.size = BUFFER_SIZE; + + PulseBufferRegion dst_region = { 0 }; + dst_region.buffer = staging_buffer; + dst_region.size = BUFFER_SIZE; + + PulseCopyBufferToBuffer(cmd, &src_region, &dst_region); + + PulseSubmitCommandList(device, cmd, fence); + PulseWaitForFences(device, &fence, 1, true); + + void* ptr; + PulseMapBuffer(staging_buffer, PULSE_MAP_READ, &ptr); + for(uint32_t i = 0; i < BUFFER_SIZE / sizeof(uint32_t); i++) + printf("%d, ", ((int32_t*)ptr)[i]); + puts(""); + PulseUnmapBuffer(staging_buffer); + + PulseDestroyBuffer(device, staging_buffer); + + PulseReleaseCommandList(device, cmd); + PulseDestroyFence(device, fence); + } + PulseDestroyBuffer(device, buffer); PulseDestroyDevice(device); diff --git a/Sources/Backends/OpenGL/EGL/EGLInstance.c b/Sources/Backends/OpenGL/EGL/EGLInstance.c index 9166126..ef469d4 100644 --- a/Sources/Backends/OpenGL/EGL/EGLInstance.c +++ b/Sources/Backends/OpenGL/EGL/EGLInstance.c @@ -166,6 +166,7 @@ bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint3 uint32_t device_id = PulseHashString((const char*)glGetString(GL_VENDOR)); device_id = PulseHashCombine(device_id, PulseHashString((const char*)glGetString(GL_RENDERER))); GLint gl_extension_count = 0; + glGetIntegerv(GL_NUM_EXTENSIONS, &gl_extension_count); for(int i = 0; i < gl_extension_count; i++) device_id = PulseHashCombine(device_id, PulseHashString((const char*)glGetStringi(GL_EXTENSIONS, i))); diff --git a/Sources/Backends/OpenGL/OpenGL.h b/Sources/Backends/OpenGL/OpenGL.h index 3bed8fe..8744304 100644 --- a/Sources/Backends/OpenGL/OpenGL.h +++ b/Sources/Backends/OpenGL/OpenGL.h @@ -14,10 +14,7 @@ #include "OpenGLEnums.h" #define GL_GLES_PROTOTYPES 0 -#include - -#define GL_STACK_UNDERFLOW 0x0504 -#define GL_STACK_OVERFLOW 0x0503 +#include typedef void(*GLFunction)(void); diff --git a/Sources/Backends/OpenGL/OpenGLBuffer.c b/Sources/Backends/OpenGL/OpenGLBuffer.c index 1b06f48..0d102a1 100644 --- a/Sources/Backends/OpenGL/OpenGLBuffer.c +++ b/Sources/Backends/OpenGL/OpenGLBuffer.c @@ -26,7 +26,14 @@ PulseBuffer OpenGLCreateBuffer(PulseDevice device, const PulseBufferCreateInfo* buffer->size = create_infos->size; buffer->usage = create_infos->usage; + void* data = calloc(1, create_infos->size); + PULSE_CHECK_ALLOCATION_RETVAL(data, PULSE_NULL_HANDLE); + opengl_device->glGenBuffers(device, 1, &opengl_buffer->buffer); + opengl_device->glBindBuffer(device, GL_SHADER_STORAGE_BUFFER, opengl_buffer->buffer); + opengl_device->glBufferData(device, GL_SHADER_STORAGE_BUFFER, create_infos->size, data, GL_DYNAMIC_COPY); + + free(data); return buffer; } diff --git a/Sources/Backends/OpenGL/OpenGLCommandList.c b/Sources/Backends/OpenGL/OpenGLCommandList.c index 99300bc..666dd0e 100644 --- a/Sources/Backends/OpenGL/OpenGLCommandList.c +++ b/Sources/Backends/OpenGL/OpenGLCommandList.c @@ -7,6 +7,34 @@ #include "../../PulseInternal.h" #include "OpenGL.h" #include "OpenGLCommandList.h" +#include "OpenGLDevice.h" +#include "OpenGLBuffer.h" +#include "OpenGLFence.h" +#include "OpenGLComputePass.h" + +static void OpenGLCommandCopyBufferToBuffer(PulseDevice device, OpenGLCommand* cmd) +{ + const PulseBufferRegion* src = cmd->CopyBufferToBuffer.src; + const PulseBufferRegion* dst = cmd->CopyBufferToBuffer.dst; + OpenGLBuffer* src_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(src->buffer, OpenGLBuffer*); + OpenGLBuffer* dst_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(dst->buffer, OpenGLBuffer*); + + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + opengl_device->glBindBuffer(device, GL_COPY_READ_BUFFER, src_buffer->buffer); + opengl_device->glBindBuffer(device, GL_COPY_WRITE_BUFFER, dst_buffer->buffer); + opengl_device->glCopyBufferSubData(device, GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, src->offset, dst->offset, src->size); + + free((void*)src); + free((void*)dst); +} + +static void OpenGLCommandDispatch(PulseDevice device, OpenGLCommand* cmd) +{ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + opengl_device->glDispatchCompute(device, cmd->Dispatch.groupcount_x, cmd->Dispatch.groupcount_y, cmd->Dispatch.groupcount_z); +} static void OpenGLCommandsRunner(PulseCommandList cmd) { @@ -20,26 +48,40 @@ static void OpenGLCommandsRunner(PulseCommandList cmd) OpenGLCommand* command = &opengl_cmd->commands[i]; switch(command->type) { - case OPENGL_COMMAND_COPY_BUFFER_TO_BUFFER: OpenGLCommandCopyBufferToBuffer(command); break; + case OPENGL_COMMAND_COPY_BUFFER_TO_BUFFER: OpenGLCommandCopyBufferToBuffer(cmd->device, command); break; case OPENGL_COMMAND_COPY_BUFFER_TO_IMAGE: break; case OPENGL_COMMAND_COPY_IMAGE_TO_BUFFER: break; - case OPENGL_COMMAND_DISPATCH: OpenGLCommandDispatch(command); break; + case OPENGL_COMMAND_DISPATCH: OpenGLCommandDispatch(cmd->device, command); break; case OPENGL_COMMAND_DISPATCH_INDIRECT: break; default: break; } } - - if(opengl_cmd->fence != PULSE_NULL_HANDLE) - { - OpenGLFence* fence = OPENGL_RETRIEVE_DRIVER_DATA_AS(opengl_cmd->fence, OpenGLFence*); - atomic_store(&fence->signal, true); - } cmd->state = PULSE_COMMAND_LIST_STATE_READY; } PulseCommandList OpenGLRequestCommandList(PulseDevice device, PulseCommandListUsage usage) { + PULSE_CHECK_HANDLE_RETVAL(device, PULSE_NULL_HANDLE); + + PULSE_UNUSED(usage); + + PulseCommandList cmd = (PulseCommandList)calloc(1, sizeof(PulseCommandListHandler)); + PULSE_CHECK_ALLOCATION_RETVAL(cmd, PULSE_NULL_HANDLE); + + OpenGLCommandList* opengl_cmd = (OpenGLCommandList*)calloc(1, sizeof(OpenGLCommandList)); + PULSE_CHECK_ALLOCATION_RETVAL(opengl_cmd, PULSE_NULL_HANDLE); + + cmd->usage = usage; + cmd->device = device; + cmd->driver_data = opengl_cmd; + cmd->thread_id = PulseGetThreadID(); + + cmd->pass = OpenGLCreateComputePass(device, cmd); + cmd->state = PULSE_COMMAND_LIST_STATE_RECORDING; + cmd->is_available = false; + + return cmd; } void OpenGLQueueCommand(PulseCommandList cmd, OpenGLCommand command) @@ -52,8 +94,17 @@ void OpenGLQueueCommand(PulseCommandList cmd, OpenGLCommand command) bool OpenGLSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence) { + PULSE_UNUSED(device); + cmd->state = PULSE_COMMAND_LIST_STATE_SENT; + if(fence != PULSE_NULL_HANDLE) + fence->cmd = cmd; + OpenGLCommandsRunner(cmd); + return true; } void OpenGLReleaseCommandList(PulseDevice device, PulseCommandList cmd) { + OpenGLDestroyComputePass(device, cmd->pass); + free(cmd->driver_data); + free(cmd); } diff --git a/Sources/Backends/OpenGL/OpenGLComputePass.c b/Sources/Backends/OpenGL/OpenGLComputePass.c index 1d4780b..c01c76b 100644 --- a/Sources/Backends/OpenGL/OpenGLComputePass.c +++ b/Sources/Backends/OpenGL/OpenGLComputePass.c @@ -10,18 +10,34 @@ PulseComputePass OpenGLCreateComputePass(PulseDevice device, PulseCommandList cmd) { + PULSE_UNUSED(device); + PulseComputePass pass = (PulseComputePass)calloc(1, sizeof(PulseComputePassHandler)); + PULSE_CHECK_ALLOCATION_RETVAL(pass, PULSE_NULL_HANDLE); + + OpenGLComputePass* opengl_pass = (OpenGLComputePass*)calloc(1, sizeof(OpenGLComputePass)); + PULSE_CHECK_ALLOCATION_RETVAL(opengl_pass, PULSE_NULL_HANDLE); + + pass->cmd = cmd; + pass->driver_data = opengl_pass; + + return pass; } void OpenGLDestroyComputePass(PulseDevice device, PulseComputePass pass) { + PULSE_UNUSED(device); + free(pass->driver_data); + free(pass); } PulseComputePass OpenGLBeginComputePass(PulseCommandList cmd) { + return cmd->pass; } void OpenGLEndComputePass(PulseComputePass pass) { + PULSE_UNUSED(pass); } void OpenGLBindStorageBuffers(PulseComputePass pass, const PulseBuffer* buffers, uint32_t num_buffers) @@ -38,8 +54,17 @@ void OpenGLBindStorageImages(PulseComputePass pass, const PulseImage* images, ui void OpenGLBindComputePipeline(PulseComputePass pass, PulseComputePipeline pipeline) { + PULSE_UNUSED(pass); + PULSE_UNUSED(pipeline); } void OpenGLDispatchComputations(PulseComputePass pass, uint32_t groupcount_x, uint32_t groupcount_y, uint32_t groupcount_z) { + OpenGLCommand command = { 0 }; + command.type = OPENGL_COMMAND_DISPATCH; + command.Dispatch.groupcount_x = groupcount_x; + command.Dispatch.groupcount_y = groupcount_y; + command.Dispatch.groupcount_z = groupcount_z; + command.Dispatch.pipeline = pass->current_pipeline; + OpenGLQueueCommand(pass->cmd, command); } diff --git a/Sources/Backends/OpenGL/OpenGLComputePass.h b/Sources/Backends/OpenGL/OpenGLComputePass.h index c499868..b816232 100644 --- a/Sources/Backends/OpenGL/OpenGLComputePass.h +++ b/Sources/Backends/OpenGL/OpenGLComputePass.h @@ -14,6 +14,7 @@ typedef struct OpenGLComputePass { + int dummy; } OpenGLComputePass; PulseComputePass OpenGLCreateComputePass(PulseDevice device, PulseCommandList cmd); diff --git a/Sources/Backends/OpenGL/OpenGLComputePipeline.h b/Sources/Backends/OpenGL/OpenGLComputePipeline.h index 95a4be9..65769ed 100644 --- a/Sources/Backends/OpenGL/OpenGLComputePipeline.h +++ b/Sources/Backends/OpenGL/OpenGLComputePipeline.h @@ -12,6 +12,7 @@ typedef struct OpenGLComputePipeline { + int dummy; } OpenGLComputePipeline; PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info); diff --git a/Sources/Backends/OpenGL/OpenGLDevice.c b/Sources/Backends/OpenGL/OpenGLDevice.c index 45e7459..8c1e057 100644 --- a/Sources/Backends/OpenGL/OpenGLDevice.c +++ b/Sources/Backends/OpenGL/OpenGLDevice.c @@ -46,6 +46,12 @@ const char* OpenGLVerbaliseError(GLenum code) return "unknown OpenGL error"; } +static void OpenGLDebugMessageCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar* message, const void* user_param) +{ + PulseDevice device = (PulseDevice)user_param; + PulseLogInfoFmt(device->backend, "%s debug message catched: %.*s", device->backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)", length, message); +} + static void PulseCheckGLError(PulseDevice device, const char* function) { OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); @@ -108,6 +114,26 @@ static void OpenGLDeviceMakeCurrent(PulseDevice device) #undef PULSE_OPENGL_WRAPPER #undef PULSE_OPENGL_WRAPPER_RET +static bool OpenGLLoadFallbackFunction(PulseDevice device, OpenGLFunctionIndex index, GLFunctionLoad load) +{ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + if(index == glDebugMessageCallback) + { + GLFunction fn = PULSE_NULLPTR; + + if(OpenGLDeviceSupportsExtension(device, "GL_KHR_debug")) + fn = load("glDebugMessageCallbackKHR"); + if(!fn && device->backend->backend == PULSE_BACKEND_OPENGL && OpenGLDeviceSupportsExtension(device, "GL_ARB_debug_output")) + fn = load("glDebugMessageCallbackARB"); + + if(fn) + opengl_device->original_function_ptrs[index] = fn; + } + + return opengl_device->original_function_ptrs[index] != PULSE_NULLPTR; +} + static bool OpenGLLoadFunction(PulseDevice device, OpenGLFunctionIndex index) { OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); @@ -123,7 +149,7 @@ static bool OpenGLLoadFunction(PulseDevice device, OpenGLFunctionIndex index) #endif GLFunction fn = load(OpenGLFunctionIndexToFunctionName[index]); - if(!fn) + if(!fn && index > OPENGL_FUNCTION_INDEX_START_ENUM && !OpenGLLoadFallbackFunction(device, index, load)) { PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED); return false; @@ -132,11 +158,11 @@ static bool OpenGLLoadFunction(PulseDevice device, OpenGLFunctionIndex index) return true; } -static bool OpenGLLoadFunctions(PulseDevice device) +static bool OpenGLLoadCoreFunctions(PulseDevice device) { OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); - for(int i = 0; i < OPENGL_FUNCTION_INDEX_END_ENUM; i++) + for(int i = 0; i < OPENGL_CORE_FUNCTION_INDEX_END_ENUM; i++) { if(!OpenGLLoadFunction(device, i)) return false; @@ -149,6 +175,27 @@ static bool OpenGLLoadFunctions(PulseDevice device) return true; } +static bool OpenGLLoadFunctions(PulseDevice device) +{ + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + for(int i = OPENGL_CORE_FUNCTION_INDEX_END_ENUM; i < OPENGL_FUNCTION_INDEX_END_ENUM; i++) + { + if(!OpenGLLoadFunction(device, i)) + return false; + } + + #undef PULSE_OPENGL_GL_GLES_FUNCTION + + #define PULSE_OPENGL_FUNCTION(fn, T) + #define PULSE_OPENGL_GL_GLES_FUNCTION(glver, glesver,fn, T) opengl_device->fn = PulseOpenGLWrapper_##fn; + #include "OpenGLFunctions.h" + #undef PULSE_OPENGL_FUNCTION + #undef PULSE_OPENGL_GL_GLES_FUNCTION + + return true; +} + PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count) { PULSE_CHECK_HANDLE_RETVAL(backend, PULSE_NULLPTR); @@ -179,6 +226,20 @@ PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic device->context_type = OPENGL_CONTEXT_EGL; #endif + if(!OpenGLLoadCoreFunctions(pulse_device)) + { + EGLUnloadInstance(&device->egl_instance); + PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED); + return PULSE_NULL_HANDLE; + } + + GLint gl_extension_count = 0; + device->glGetIntegerv(pulse_device, GL_NUM_EXTENSIONS, &gl_extension_count); + device->supported_extensions_count = gl_extension_count; + device->supported_extensions = (const char**)calloc(device->supported_extensions_count, sizeof(const char*)); + for(uint32_t i = 0; i < device->supported_extensions_count; i++) + device->supported_extensions[i] = (const char*)device->glGetStringi(pulse_device, GL_EXTENSIONS, i); + if(!OpenGLLoadFunctions(pulse_device)) { EGLUnloadInstance(&device->egl_instance); @@ -186,25 +247,48 @@ PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic return PULSE_NULL_HANDLE; } + if(backend->debug_level != PULSE_NO_DEBUG && device->original_function_ptrs[glDebugMessageCallback] != PULSE_NULLPTR) + { + device->glDebugMessageCallback(pulse_device, OpenGLDebugMessageCallback, pulse_device); + if(backend->debug_level >= PULSE_LOW_DEBUG) + device->glDebugMessageControl(pulse_device, GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, PULSE_NULLPTR, GL_FALSE); + if(backend->debug_level >= PULSE_HIGH_DEBUG) + { + device->glDebugMessageControl(pulse_device, GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, PULSE_NULLPTR, GL_FALSE); + device->glDebugMessageControl(pulse_device, GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, PULSE_NULLPTR, GL_FALSE); + device->glDebugMessageControl(pulse_device, GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, PULSE_NULLPTR, GL_FALSE); + //device->glDebugMessageControl(pulse_device, GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, PULSE_NULLPTR, GL_FALSE); + } + } + PULSE_LOAD_DRIVER_DEVICE(OpenGL); device->device_id = PulseHashString((const char*)device->glGetString(pulse_device, GL_VENDOR)); device->device_id = PulseHashCombine(device->device_id, PulseHashString((const char*)device->glGetString(pulse_device, GL_RENDERER))); - GLint gl_extension_count = 0; - for(int i = 0; i < gl_extension_count; i++) - device->device_id = PulseHashCombine(device->device_id, PulseHashString((const char*)device->glGetStringi(pulse_device, GL_EXTENSIONS, i))); + for(uint32_t i = 0; i < device->supported_extensions_count; i++) + device->device_id = PulseHashCombine(device->device_id, PulseHashString(device->supported_extensions[i])); if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(backend)) PulseLogInfoFmt(backend, "%s created device from %s", backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)", device->glGetString(pulse_device, GL_RENDERER)); return pulse_device; } -void OpenGLDestroyDevice(PulseDevice device) +bool OpenGLDeviceSupportsExtension(PulseDevice device, const char* name) { OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); - if(opengl_device == PULSE_NULLPTR) - return; + for(uint32_t i = 0; i < opengl_device->supported_extensions_count; i++) + { + if(strcmp(opengl_device->supported_extensions[i], name) == 0) + return true; + } + return false; +} +void OpenGLDestroyDevice(PulseDevice device) +{ + if(device == PULSE_NULL_HANDLE || device->driver_data == PULSE_NULLPTR) + return; + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); #ifdef PULSE_PLAT_WINDOWS if(opengl_device->context_type == OPENGL_CONTEXT_WGL) {} // TODO: WGL diff --git a/Sources/Backends/OpenGL/OpenGLDevice.h b/Sources/Backends/OpenGL/OpenGLDevice.h index 68c454d..f53508c 100644 --- a/Sources/Backends/OpenGL/OpenGLDevice.h +++ b/Sources/Backends/OpenGL/OpenGLDevice.h @@ -33,10 +33,14 @@ typedef struct OpenGLDevice #undef PULSE_OPENGL_WRAPPER #undef PULSE_OPENGL_WRAPPER_RET + const char** supported_extensions; + uint32_t supported_extensions_count; + uint32_t device_id; } OpenGLDevice; PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count); +bool OpenGLDeviceSupportsExtension(PulseDevice device, const char* name); void OpenGLDestroyDevice(PulseDevice device); #endif // PULSE_OPENGL_DEVICE_H_ diff --git a/Sources/Backends/OpenGL/OpenGLEnums.h b/Sources/Backends/OpenGL/OpenGLEnums.h index b38b019..3d50d24 100644 --- a/Sources/Backends/OpenGL/OpenGLEnums.h +++ b/Sources/Backends/OpenGL/OpenGLEnums.h @@ -15,11 +15,28 @@ typedef enum OpenGLContextType OPENGL_CONTEXT_END_ENUM } OpenGLContextType; -typedef enum OpenGLFunctionIndex +typedef enum OpenGLCoreFunctionIndex { + #undef PULSE_OPENGL_GL_GLES_FUNCTION + #define PULSE_OPENGL_GL_GLES_FUNCTION(glver, glesver, fn, T) #define PULSE_OPENGL_FUNCTION(fn, T) fn, #include "OpenGLFunctions.h" #undef PULSE_OPENGL_FUNCTION + #undef PULSE_OPENGL_GL_GLES_FUNCTION + + OPENGL_CORE_FUNCTION_INDEX_END_ENUM +} OpenGLCoreFunctionIndex; + +typedef enum OpenGLFunctionIndex +{ + OPENGL_FUNCTION_INDEX_START_ENUM = OPENGL_CORE_FUNCTION_INDEX_END_ENUM - 1, + + #undef PULSE_OPENGL_GL_GLES_FUNCTION + #define PULSE_OPENGL_GL_GLES_FUNCTION(glver, glesver, fn, T) fn, + #define PULSE_OPENGL_FUNCTION(fn, T) + #include "OpenGLFunctions.h" + #undef PULSE_OPENGL_FUNCTION + #undef PULSE_OPENGL_GL_GLES_FUNCTION OPENGL_FUNCTION_INDEX_END_ENUM } OpenGLFunctionIndex; diff --git a/Sources/Backends/OpenGL/OpenGLFence.c b/Sources/Backends/OpenGL/OpenGLFence.c index db18f59..0fe3c13 100644 --- a/Sources/Backends/OpenGL/OpenGLFence.c +++ b/Sources/Backends/OpenGL/OpenGLFence.c @@ -7,19 +7,35 @@ #include "../../PulseInternal.h" #include "OpenGL.h" #include "OpenGLFence.h" +#include "OpenGLDevice.h" PulseFence OpenGLCreateFence(PulseDevice device) { + PULSE_UNUSED(device); + PulseFence fence = (PulseFence)calloc(1, sizeof(PulseFence)); + PULSE_CHECK_ALLOCATION_RETVAL(fence, PULSE_NULL_HANDLE); + return fence; } void OpenGLDestroyFence(PulseDevice device, PulseFence fence) { + PULSE_UNUSED(device); + free(fence); } bool OpenGLIsFenceReady(PulseDevice device, PulseFence fence) { + PULSE_UNUSED(device); + PULSE_UNUSED(fence); + return true; } bool OpenGLWaitForFences(PulseDevice device, const PulseFence* fences, uint32_t fences_count, bool wait_for_all) { + PULSE_UNUSED(fences); + PULSE_UNUSED(fences_count); + PULSE_UNUSED(wait_for_all); + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + opengl_device->glFinish(device); + return true; } diff --git a/Sources/Backends/OpenGL/OpenGLFence.h b/Sources/Backends/OpenGL/OpenGLFence.h index c59f109..c996ed0 100644 --- a/Sources/Backends/OpenGL/OpenGLFence.h +++ b/Sources/Backends/OpenGL/OpenGLFence.h @@ -10,10 +10,6 @@ #include #include "OpenGL.h" -typedef struct OpenGLFence -{ -} OpenGLFence; - PulseFence OpenGLCreateFence(PulseDevice device); void OpenGLDestroyFence(PulseDevice device, PulseFence fence); bool OpenGLIsFenceReady(PulseDevice device, PulseFence fence); diff --git a/Sources/Backends/OpenGL/OpenGLFunctions.h b/Sources/Backends/OpenGL/OpenGLFunctions.h index 80b197f..cf08b07 100644 --- a/Sources/Backends/OpenGL/OpenGLFunctions.h +++ b/Sources/Backends/OpenGL/OpenGLFunctions.h @@ -8,10 +8,6 @@ #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 @@ -140,3 +136,8 @@ PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glGetProgramResourceiv, PFNGLGETPROGRAMR 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) + +// OpenGL 4.3 - OpenGL ES 3.2 +PULSE_OPENGL_GL_GLES_FUNCTION(430, 320, glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(430, 320, glDebugMessageControl, PFNGLDEBUGMESSAGECONTROLPROC) +PULSE_OPENGL_GL_GLES_FUNCTION(430, 320, glDispatchComputeIndirect, PFNGLDISPATCHCOMPUTEINDIRECTPROC) diff --git a/Sources/Backends/OpenGL/OpenGLImage.h b/Sources/Backends/OpenGL/OpenGLImage.h index f712bdf..1873080 100644 --- a/Sources/Backends/OpenGL/OpenGLImage.h +++ b/Sources/Backends/OpenGL/OpenGLImage.h @@ -12,6 +12,7 @@ typedef struct OpenGLImage { + int dummy; } OpenGLImage; PulseImage OpenGLCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos); diff --git a/Sources/Backends/OpenGL/OpenGLWraps.h b/Sources/Backends/OpenGL/OpenGLWraps.h index 19f5f8e..add1de5 100644 --- a/Sources/Backends/OpenGL/OpenGLWraps.h +++ b/Sources/Backends/OpenGL/OpenGLWraps.h @@ -124,6 +124,7 @@ PULSE_OPENGL_WRAPPER(glProgramParameteri, (PulseDevice device, GLuint program, G 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(glDispatchComputeIndirect, (PulseDevice device, GLintptr indirect), (indirect), PFNGLDISPATCHCOMPUTEINDIRECTPROC) 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) @@ -133,3 +134,5 @@ PULSE_OPENGL_WRAPPER(glBindImageTexture, (PulseDevice device, GLuint unit, GLuin 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) +PULSE_OPENGL_WRAPPER(glDebugMessageControl, (PulseDevice device, GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled), (source, type, severity, count, ids, enabled), PFNGLDEBUGMESSAGECONTROLPROC) +PULSE_OPENGL_WRAPPER(glDebugMessageCallback, (PulseDevice device, GLDEBUGPROC callback, const void *userParam), (callback, userParam), PFNGLDEBUGMESSAGECALLBACKPROC) diff --git a/Sources/Backends/Software/SoftCommandList.c b/Sources/Backends/Software/SoftCommandList.c index a5aea4e..3879f0d 100644 --- a/Sources/Backends/Software/SoftCommandList.c +++ b/Sources/Backends/Software/SoftCommandList.c @@ -63,7 +63,7 @@ static void SoftCommandDispatch(SoftCommand* cmd) for(uint32_t i = 0; i < local_size; i++) { thrd_create(&invocations[invocation_index], SoftCommandDispatchCore, soft_pipeline); - thrd_join(invocations[invocation_index], NULL); + //thrd_join(invocations[invocation_index], NULL); invocation_index++; } } diff --git a/xmake.lua b/xmake.lua index 61ee651..5eff1b8 100644 --- a/xmake.lua +++ b/xmake.lua @@ -49,7 +49,7 @@ local backends = { 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"}) + os.runv("python", {"Scripts/GenerateOpenGLDefs.py", "Sources/Backends/OpenGL/OpenGLFunctions.h", gles_dir .. "/include/GLES3/gl32.h", "Sources/Backends/OpenGL/OpenGLWraps.h"}) end }, }