From 82619762fe833e5fa1573fd2168d188161cf79bc Mon Sep 17 00:00:00 2001 From: Kbz-8 Date: Sat, 5 Apr 2025 21:48:51 +0200 Subject: [PATCH] yes --- Examples/OpenGL/main.c | 11 +++-- Sources/Backends/OpenGL/OpenGLBuffer.c | 2 +- Sources/Backends/OpenGL/OpenGLCommandList.c | 4 +- .../Backends/OpenGL/OpenGLComputePipeline.c | 41 +++++++++++++++++++ .../Backends/OpenGL/OpenGLComputePipeline.h | 2 +- Sources/Backends/OpenGL/OpenGLDevice.c | 25 ++++------- Sources/Backends/OpenGL/OpenGLFunctions.h | 1 + Sources/Backends/OpenGL/OpenGLWraps.h | 1 + Sources/PulseBuffer.c | 5 +-- xmake.lua | 1 - 10 files changed, 67 insertions(+), 26 deletions(-) diff --git a/Examples/OpenGL/main.c b/Examples/OpenGL/main.c index 997a276..da81c5a 100644 --- a/Examples/OpenGL/main.c +++ b/Examples/OpenGL/main.c @@ -21,10 +21,17 @@ void DebugCallBack(PulseDebugMessageSeverity severity, const char* message) printf("Pulse: %s\n", message); } -const char* glsl_source = GLSL_SOURCE("430 core", +const char* glsl_source = GLSL_SOURCE("310 es", + layout(std430, binding = 0) buffer SSBO + { + int data[]; + } ssbo; + layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in; void main() { + uvec3 indices = gl_GlobalInvocationID; + ssbo.data[indices.x * indices.y] = int(indices.x * indices.y); } ); @@ -42,7 +49,6 @@ 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 }; @@ -69,7 +75,6 @@ int main(int ac, char** av) PulseDestroyFence(device, fence); PulseDestroyComputePipeline(device, pipeline); } -*/ // Get result and read it on CPU { diff --git a/Sources/Backends/OpenGL/OpenGLBuffer.c b/Sources/Backends/OpenGL/OpenGLBuffer.c index 0d102a1..40be4b8 100644 --- a/Sources/Backends/OpenGL/OpenGLBuffer.c +++ b/Sources/Backends/OpenGL/OpenGLBuffer.c @@ -43,7 +43,7 @@ bool OpenGLMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data) OpenGLBuffer* opengl_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer, OpenGLBuffer*); OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer->device, OpenGLDevice*); opengl_device->glBindBuffer(buffer->device, GL_SHADER_STORAGE_BUFFER, opengl_buffer->buffer); - *data = opengl_device->glMapBufferRange(buffer->device, GL_SHADER_STORAGE_BUFFER, mode == PULSE_MAP_READ ? GL_READ_ONLY : GL_WRITE_ONLY, 0, buffer->size); + *data = opengl_device->glMapBufferRange(buffer->device, GL_SHADER_STORAGE_BUFFER, 0, buffer->size, mode == PULSE_MAP_READ ? GL_MAP_READ_BIT : GL_MAP_WRITE_BIT); return *data != PULSE_NULLPTR; } diff --git a/Sources/Backends/OpenGL/OpenGLCommandList.c b/Sources/Backends/OpenGL/OpenGLCommandList.c index 666dd0e..36dae2d 100644 --- a/Sources/Backends/OpenGL/OpenGLCommandList.c +++ b/Sources/Backends/OpenGL/OpenGLCommandList.c @@ -10,6 +10,7 @@ #include "OpenGLDevice.h" #include "OpenGLBuffer.h" #include "OpenGLFence.h" +#include "OpenGLComputePipeline.h" #include "OpenGLComputePass.h" static void OpenGLCommandCopyBufferToBuffer(PulseDevice device, OpenGLCommand* cmd) @@ -32,7 +33,8 @@ static void OpenGLCommandCopyBufferToBuffer(PulseDevice device, OpenGLCommand* c static void OpenGLCommandDispatch(PulseDevice device, OpenGLCommand* cmd) { OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); - + OpenGLComputePipeline* opengl_pipeline = OPENGL_RETRIEVE_DRIVER_DATA_AS(cmd->Dispatch.pipeline, OpenGLComputePipeline*); + opengl_device->glUseProgram(device, opengl_pipeline->program); opengl_device->glDispatchCompute(device, cmd->Dispatch.groupcount_x, cmd->Dispatch.groupcount_y, cmd->Dispatch.groupcount_z); } diff --git a/Sources/Backends/OpenGL/OpenGLComputePipeline.c b/Sources/Backends/OpenGL/OpenGLComputePipeline.c index bc5228c..56be2b5 100644 --- a/Sources/Backends/OpenGL/OpenGLComputePipeline.c +++ b/Sources/Backends/OpenGL/OpenGLComputePipeline.c @@ -7,11 +7,52 @@ #include "../../PulseInternal.h" #include "OpenGL.h" #include "OpenGLComputePipeline.h" +#include "OpenGLDevice.h" PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info) { + OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); + + PulseComputePipelineHandler* pipeline = (PulseComputePipelineHandler*)calloc(1, sizeof(PulseComputePipelineHandler)); + PULSE_CHECK_ALLOCATION_RETVAL(pipeline, PULSE_NULL_HANDLE); + + OpenGLComputePipeline* opengl_pipeline = (OpenGLComputePipeline*)calloc(1, sizeof(OpenGLComputePipeline)); + PULSE_CHECK_ALLOCATION_RETVAL(opengl_pipeline, PULSE_NULL_HANDLE); + + pipeline->driver_data = opengl_pipeline; + + if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) + { + if(info->code == PULSE_NULLPTR) + PulseLogError(device->backend, "invalid code pointer passed to PulseComputePipelineCreateInfo"); + if(info->entrypoint == PULSE_NULLPTR) + PulseLogError(device->backend, "invalid entrypoint pointer passed to PulseComputePipelineCreateInfo"); + if(info->format == PULSE_SHADER_FORMAT_WGSL_BIT && (device->backend->supported_shader_formats & PULSE_SHADER_FORMAT_WGSL_BIT) == 0) + PulseLogError(device->backend, "invalid shader format passed to PulseComputePipelineCreateInfo"); + } + + opengl_pipeline->program = opengl_device->glCreateShaderProgramv(device, GL_COMPUTE_SHADER, 1, (const GLchar**)(&info->code)); + + if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend)) + PulseLogInfoFmt(device->backend, "%s created new compute pipeline %p", device->backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)", pipeline); + return pipeline; } void OpenGLDestroyComputePipeline(PulseDevice device, PulseComputePipeline pipeline) { + if(pipeline == PULSE_NULL_HANDLE) + { + if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(device->backend)) + PulseLogWarning(device->backend, "compute pipeline is NULL, this may be a bug in your application"); + return; + } + + PULSE_UNUSED(device); + OpenGLComputePipeline* opengl_pipeline = OPENGL_RETRIEVE_DRIVER_DATA_AS(pipeline, OpenGLComputePipeline*); + free(opengl_pipeline); + + if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(device->backend)) + PulseLogInfoFmt(device->backend, "%s destroyed compute pipeline %p", device->backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)", pipeline); + + free(pipeline); } diff --git a/Sources/Backends/OpenGL/OpenGLComputePipeline.h b/Sources/Backends/OpenGL/OpenGLComputePipeline.h index 65769ed..a97d478 100644 --- a/Sources/Backends/OpenGL/OpenGLComputePipeline.h +++ b/Sources/Backends/OpenGL/OpenGLComputePipeline.h @@ -12,7 +12,7 @@ typedef struct OpenGLComputePipeline { - int dummy; + GLuint program; } OpenGLComputePipeline; PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info); diff --git a/Sources/Backends/OpenGL/OpenGLDevice.c b/Sources/Backends/OpenGL/OpenGLDevice.c index 8c1e057..6e424b5 100644 --- a/Sources/Backends/OpenGL/OpenGLDevice.c +++ b/Sources/Backends/OpenGL/OpenGLDevice.c @@ -30,15 +30,14 @@ 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"; + case GL_INVALID_ENUM: return "(GL_INVALID_ENUM) an unacceptable value is specified for an enumerated argument"; + case GL_INVALID_VALUE: return "(GL_INVALID_VALUE) a numeric argument is out of range"; + case GL_INVALID_OPERATION: return "(GL_INVALID_OPERATION) the specified operation is not allowed in the current state"; + case GL_OUT_OF_MEMORY: return "(GL_OUT_OF_MEMORY) 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"; + case GL_STACK_UNDERFLOW: return "(GL_STACK_UNDERFLOW) an attempt has been made to perform an operation that would cause an internal stack to underflow"; + case GL_STACK_OVERFLOW: return "(GL_STACK_OVERFLOW) an attempt has been made to perform an operation that would cause an internal stack to overflow"; default: break; } @@ -249,16 +248,10 @@ PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic if(backend->debug_level != PULSE_NO_DEBUG && device->original_function_ptrs[glDebugMessageCallback] != PULSE_NULLPTR) { + device->glEnable(pulse_device, GL_DEBUG_OUTPUT); + //device->glEnable(pulse_device, GL_DEBUG_OUTPUT_SYNCHRONOUS); 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); - } + device->glDebugMessageControl(pulse_device, GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, PULSE_NULLPTR, GL_FALSE); } PULSE_LOAD_DRIVER_DEVICE(OpenGL); diff --git a/Sources/Backends/OpenGL/OpenGLFunctions.h b/Sources/Backends/OpenGL/OpenGLFunctions.h index cf08b07..b422e2e 100644 --- a/Sources/Backends/OpenGL/OpenGLFunctions.h +++ b/Sources/Backends/OpenGL/OpenGLFunctions.h @@ -136,6 +136,7 @@ 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) +PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glCreateShaderProgramv, PFNGLCREATESHADERPROGRAMVPROC) // OpenGL 4.3 - OpenGL ES 3.2 PULSE_OPENGL_GL_GLES_FUNCTION(430, 320, glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) diff --git a/Sources/Backends/OpenGL/OpenGLWraps.h b/Sources/Backends/OpenGL/OpenGLWraps.h index add1de5..dfc0c1a 100644 --- a/Sources/Backends/OpenGL/OpenGLWraps.h +++ b/Sources/Backends/OpenGL/OpenGLWraps.h @@ -130,6 +130,7 @@ PULSE_OPENGL_WRAPPER_RET(GLuint, glGetProgramResourceIndex, (PulseDevice device, 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_RET(GLuint, glCreateShaderProgramv, (PulseDevice device, GLenum type, GLsizei count, const GLchar *const*strings), (type, count, strings), PFNGLCREATESHADERPROGRAMVPROC) 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) diff --git a/Sources/PulseBuffer.c b/Sources/PulseBuffer.c index 8c8fa47..7b85fd3 100644 --- a/Sources/PulseBuffer.c +++ b/Sources/PulseBuffer.c @@ -37,9 +37,8 @@ PULSE_API bool PulseMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data if(buffer->is_mapped) { if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(buffer->device->backend)) - PulseLogError(buffer->device->backend, "buffer is already mapped"); - PulseSetInternalError(PULSE_ERROR_MAP_FAILED); - return false; + PulseLogWarning(buffer->device->backend, "buffer is already mapped"); + return true; } PulseFlags storage_flags = PULSE_BUFFER_USAGE_STORAGE_READ | PULSE_BUFFER_USAGE_STORAGE_WRITE; diff --git a/xmake.lua b/xmake.lua index 5eff1b8..2c55a69 100644 --- a/xmake.lua +++ b/xmake.lua @@ -78,7 +78,6 @@ add_rules("mode.debug", "mode.release") add_includedirs("Includes") set_languages("c17", "cxx20") set_encodings("utf-8") -set_warnings("allextra") set_objectdir("build/Objs/$(os)_$(arch)") set_targetdir("build/Bin/$(os)_$(arch)")