This commit is contained in:
2025-04-05 21:48:51 +02:00
parent bd0c564566
commit 82619762fe
10 changed files with 67 additions and 26 deletions

View File

@@ -21,10 +21,17 @@ void DebugCallBack(PulseDebugMessageSeverity severity, const char* message)
printf("Pulse: %s\n", 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; layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main() 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; 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); PulseBuffer buffer = PulseCreateBuffer(device, &buffer_create_info);
/*
// GPU computations // GPU computations
{ {
PulseComputePipelineCreateInfo info = { 0 }; PulseComputePipelineCreateInfo info = { 0 };
@@ -69,7 +75,6 @@ int main(int ac, char** av)
PulseDestroyFence(device, fence); PulseDestroyFence(device, fence);
PulseDestroyComputePipeline(device, pipeline); PulseDestroyComputePipeline(device, pipeline);
} }
*/
// Get result and read it on CPU // Get result and read it on CPU
{ {

View File

@@ -43,7 +43,7 @@ bool OpenGLMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data)
OpenGLBuffer* opengl_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer, OpenGLBuffer*); OpenGLBuffer* opengl_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer, OpenGLBuffer*);
OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer->device, OpenGLDevice*); OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer->device, OpenGLDevice*);
opengl_device->glBindBuffer(buffer->device, GL_SHADER_STORAGE_BUFFER, opengl_buffer->buffer); 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; return *data != PULSE_NULLPTR;
} }

View File

@@ -10,6 +10,7 @@
#include "OpenGLDevice.h" #include "OpenGLDevice.h"
#include "OpenGLBuffer.h" #include "OpenGLBuffer.h"
#include "OpenGLFence.h" #include "OpenGLFence.h"
#include "OpenGLComputePipeline.h"
#include "OpenGLComputePass.h" #include "OpenGLComputePass.h"
static void OpenGLCommandCopyBufferToBuffer(PulseDevice device, OpenGLCommand* cmd) 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) static void OpenGLCommandDispatch(PulseDevice device, OpenGLCommand* cmd)
{ {
OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); 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); opengl_device->glDispatchCompute(device, cmd->Dispatch.groupcount_x, cmd->Dispatch.groupcount_y, cmd->Dispatch.groupcount_z);
} }

View File

@@ -7,11 +7,52 @@
#include "../../PulseInternal.h" #include "../../PulseInternal.h"
#include "OpenGL.h" #include "OpenGL.h"
#include "OpenGLComputePipeline.h" #include "OpenGLComputePipeline.h"
#include "OpenGLDevice.h"
PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info) 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) 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);
} }

View File

@@ -12,7 +12,7 @@
typedef struct OpenGLComputePipeline typedef struct OpenGLComputePipeline
{ {
int dummy; GLuint program;
} OpenGLComputePipeline; } OpenGLComputePipeline;
PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info); PulseComputePipeline OpenGLCreateComputePipeline(PulseDevice device, const PulseComputePipelineCreateInfo* info);

View File

@@ -30,15 +30,14 @@ const char* OpenGLVerbaliseError(GLenum code)
switch (code) switch (code)
{ {
// OpenGL / OpenGL ES error codes // OpenGL / OpenGL ES error codes
case GL_INVALID_ENUM: return "an unacceptable value is specified for an enumerated argument"; case GL_INVALID_ENUM: return "(GL_INVALID_ENUM) an unacceptable value is specified for an enumerated argument";
case GL_INVALID_VALUE: return "a numeric argument is out of range"; case GL_INVALID_VALUE: return "(GL_INVALID_VALUE) 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_OPERATION: return "(GL_INVALID_OPERATION) 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 "(GL_OUT_OF_MEMORY) there is not enough memory left to execute the command";
case GL_OUT_OF_MEMORY: return "there is not enough memory left to execute the command";
// OpenGL error codes // 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_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 "an attempt has been made to perform an operation that would cause an internal stack to overflow"; 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; 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) 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); 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_NOTIFICATION, 0, PULSE_NULLPTR, GL_FALSE);
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); PULSE_LOAD_DRIVER_DEVICE(OpenGL);

View File

@@ -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, glGetProgramResourceIndex, PFNGLGETPROGRAMRESOURCEINDEXPROC)
PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glGetProgramResourceLocation, PFNGLGETPROGRAMRESOURCELOCATIONPROC) 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, glGetProgramResourceName, PFNGLGETPROGRAMRESOURCENAMEPROC)
PULSE_OPENGL_GL_GLES_FUNCTION(430, 310, glCreateShaderProgramv, PFNGLCREATESHADERPROGRAMVPROC)
// OpenGL 4.3 - OpenGL ES 3.2 // OpenGL 4.3 - OpenGL ES 3.2
PULSE_OPENGL_GL_GLES_FUNCTION(430, 320, glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC) PULSE_OPENGL_GL_GLES_FUNCTION(430, 320, glDebugMessageCallback, PFNGLDEBUGMESSAGECALLBACKPROC)

View File

@@ -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(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(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(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(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(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(glMemoryBarrier, (PulseDevice device, GLbitfield barriers), (barriers), PFNGLMEMORYBARRIERPROC)

View File

@@ -37,9 +37,8 @@ PULSE_API bool PulseMapBuffer(PulseBuffer buffer, PulseMapMode mode, void** data
if(buffer->is_mapped) if(buffer->is_mapped)
{ {
if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(buffer->device->backend)) if(PULSE_IS_BACKEND_LOW_LEVEL_DEBUG(buffer->device->backend))
PulseLogError(buffer->device->backend, "buffer is already mapped"); PulseLogWarning(buffer->device->backend, "buffer is already mapped");
PulseSetInternalError(PULSE_ERROR_MAP_FAILED); return true;
return false;
} }
PulseFlags storage_flags = PULSE_BUFFER_USAGE_STORAGE_READ | PULSE_BUFFER_USAGE_STORAGE_WRITE; PulseFlags storage_flags = PULSE_BUFFER_USAGE_STORAGE_READ | PULSE_BUFFER_USAGE_STORAGE_WRITE;

View File

@@ -78,7 +78,6 @@ add_rules("mode.debug", "mode.release")
add_includedirs("Includes") add_includedirs("Includes")
set_languages("c17", "cxx20") set_languages("c17", "cxx20")
set_encodings("utf-8") set_encodings("utf-8")
set_warnings("allextra")
set_objectdir("build/Objs/$(os)_$(arch)") set_objectdir("build/Objs/$(os)_$(arch)")
set_targetdir("build/Bin/$(os)_$(arch)") set_targetdir("build/Bin/$(os)_$(arch)")