This commit is contained in:
2025-03-24 17:41:51 +01:00
parent d7679857aa
commit bd0c564566
18 changed files with 310 additions and 33 deletions

View File

@@ -4,7 +4,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#define GLSL_SOURCE(...) #__VA_ARGS__ #define GLSL_SOURCE(version, ...) "#version " version "\n" #__VA_ARGS__
#define BUFFER_SIZE (256 * sizeof(uint32_t)) #define BUFFER_SIZE (256 * sizeof(uint32_t))
@@ -21,6 +21,13 @@ 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",
layout(local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
void main()
{
}
);
int main(int ac, char** av) int main(int ac, char** av)
{ {
PulseBackendFlags backend_type = PULSE_BACKEND_OPENGL; 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; 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
{
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); PulseDestroyBuffer(device, buffer);
PulseDestroyDevice(device); PulseDestroyDevice(device);

View File

@@ -166,6 +166,7 @@ bool EGLLoadInstance(EGLInstance* instance, PulseDevice* forbiden_devices, uint3
uint32_t device_id = PulseHashString((const char*)glGetString(GL_VENDOR)); uint32_t device_id = PulseHashString((const char*)glGetString(GL_VENDOR));
device_id = PulseHashCombine(device_id, PulseHashString((const char*)glGetString(GL_RENDERER))); device_id = PulseHashCombine(device_id, PulseHashString((const char*)glGetString(GL_RENDERER)));
GLint gl_extension_count = 0; GLint gl_extension_count = 0;
glGetIntegerv(GL_NUM_EXTENSIONS, &gl_extension_count);
for(int i = 0; i < gl_extension_count; i++) for(int i = 0; i < gl_extension_count; i++)
device_id = PulseHashCombine(device_id, PulseHashString((const char*)glGetStringi(GL_EXTENSIONS, i))); device_id = PulseHashCombine(device_id, PulseHashString((const char*)glGetStringi(GL_EXTENSIONS, i)));

View File

@@ -14,10 +14,7 @@
#include "OpenGLEnums.h" #include "OpenGLEnums.h"
#define GL_GLES_PROTOTYPES 0 #define GL_GLES_PROTOTYPES 0
#include <GLES3/gl31.h> #include <GLES3/gl32.h>
#define GL_STACK_UNDERFLOW 0x0504
#define GL_STACK_OVERFLOW 0x0503
typedef void(*GLFunction)(void); typedef void(*GLFunction)(void);

View File

@@ -26,7 +26,14 @@ PulseBuffer OpenGLCreateBuffer(PulseDevice device, const PulseBufferCreateInfo*
buffer->size = create_infos->size; buffer->size = create_infos->size;
buffer->usage = create_infos->usage; 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->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; return buffer;
} }

View File

@@ -7,6 +7,34 @@
#include "../../PulseInternal.h" #include "../../PulseInternal.h"
#include "OpenGL.h" #include "OpenGL.h"
#include "OpenGLCommandList.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) static void OpenGLCommandsRunner(PulseCommandList cmd)
{ {
@@ -20,26 +48,40 @@ static void OpenGLCommandsRunner(PulseCommandList cmd)
OpenGLCommand* command = &opengl_cmd->commands[i]; OpenGLCommand* command = &opengl_cmd->commands[i];
switch(command->type) 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_BUFFER_TO_IMAGE: break;
case OPENGL_COMMAND_COPY_IMAGE_TO_BUFFER: 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; case OPENGL_COMMAND_DISPATCH_INDIRECT: break;
default: 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; cmd->state = PULSE_COMMAND_LIST_STATE_READY;
} }
PulseCommandList OpenGLRequestCommandList(PulseDevice device, PulseCommandListUsage usage) 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) void OpenGLQueueCommand(PulseCommandList cmd, OpenGLCommand command)
@@ -52,8 +94,17 @@ void OpenGLQueueCommand(PulseCommandList cmd, OpenGLCommand command)
bool OpenGLSubmitCommandList(PulseDevice device, PulseCommandList cmd, PulseFence fence) 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) void OpenGLReleaseCommandList(PulseDevice device, PulseCommandList cmd)
{ {
OpenGLDestroyComputePass(device, cmd->pass);
free(cmd->driver_data);
free(cmd);
} }

View File

@@ -10,18 +10,34 @@
PulseComputePass OpenGLCreateComputePass(PulseDevice device, PulseCommandList cmd) 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) void OpenGLDestroyComputePass(PulseDevice device, PulseComputePass pass)
{ {
PULSE_UNUSED(device);
free(pass->driver_data);
free(pass);
} }
PulseComputePass OpenGLBeginComputePass(PulseCommandList cmd) PulseComputePass OpenGLBeginComputePass(PulseCommandList cmd)
{ {
return cmd->pass;
} }
void OpenGLEndComputePass(PulseComputePass pass) void OpenGLEndComputePass(PulseComputePass pass)
{ {
PULSE_UNUSED(pass);
} }
void OpenGLBindStorageBuffers(PulseComputePass pass, const PulseBuffer* buffers, uint32_t num_buffers) 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) 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) 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);
} }

View File

@@ -14,6 +14,7 @@
typedef struct OpenGLComputePass typedef struct OpenGLComputePass
{ {
int dummy;
} OpenGLComputePass; } OpenGLComputePass;
PulseComputePass OpenGLCreateComputePass(PulseDevice device, PulseCommandList cmd); PulseComputePass OpenGLCreateComputePass(PulseDevice device, PulseCommandList cmd);

View File

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

View File

@@ -46,6 +46,12 @@ const char* OpenGLVerbaliseError(GLenum code)
return "unknown OpenGL error"; 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) static void PulseCheckGLError(PulseDevice device, const char* function)
{ {
OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); 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
#undef PULSE_OPENGL_WRAPPER_RET #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) static bool OpenGLLoadFunction(PulseDevice device, OpenGLFunctionIndex index)
{ {
OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*);
@@ -123,7 +149,7 @@ static bool OpenGLLoadFunction(PulseDevice device, OpenGLFunctionIndex index)
#endif #endif
GLFunction fn = load(OpenGLFunctionIndexToFunctionName[index]); GLFunction fn = load(OpenGLFunctionIndexToFunctionName[index]);
if(!fn) if(!fn && index > OPENGL_FUNCTION_INDEX_START_ENUM && !OpenGLLoadFallbackFunction(device, index, load))
{ {
PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED); PulseSetInternalError(PULSE_ERROR_INITIALIZATION_FAILED);
return false; return false;
@@ -132,11 +158,11 @@ static bool OpenGLLoadFunction(PulseDevice device, OpenGLFunctionIndex index)
return true; return true;
} }
static bool OpenGLLoadFunctions(PulseDevice device) static bool OpenGLLoadCoreFunctions(PulseDevice device)
{ {
OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); 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)) if(!OpenGLLoadFunction(device, i))
return false; return false;
@@ -149,6 +175,27 @@ static bool OpenGLLoadFunctions(PulseDevice device)
return true; 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) PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count)
{ {
PULSE_CHECK_HANDLE_RETVAL(backend, PULSE_NULLPTR); PULSE_CHECK_HANDLE_RETVAL(backend, PULSE_NULLPTR);
@@ -179,6 +226,20 @@ PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic
device->context_type = OPENGL_CONTEXT_EGL; device->context_type = OPENGL_CONTEXT_EGL;
#endif #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)) if(!OpenGLLoadFunctions(pulse_device))
{ {
EGLUnloadInstance(&device->egl_instance); EGLUnloadInstance(&device->egl_instance);
@@ -186,25 +247,48 @@ PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devic
return PULSE_NULL_HANDLE; 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); PULSE_LOAD_DRIVER_DEVICE(OpenGL);
device->device_id = PulseHashString((const char*)device->glGetString(pulse_device, GL_VENDOR)); 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))); device->device_id = PulseHashCombine(device->device_id, PulseHashString((const char*)device->glGetString(pulse_device, GL_RENDERER)));
GLint gl_extension_count = 0; for(uint32_t i = 0; i < device->supported_extensions_count; i++)
for(int i = 0; i < gl_extension_count; i++) device->device_id = PulseHashCombine(device->device_id, PulseHashString(device->supported_extensions[i]));
device->device_id = PulseHashCombine(device->device_id, PulseHashString((const char*)device->glGetStringi(pulse_device, GL_EXTENSIONS, i)));
if(PULSE_IS_BACKEND_HIGH_LEVEL_DEBUG(backend)) 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)); PulseLogInfoFmt(backend, "%s created device from %s", backend->backend == PULSE_BACKEND_OPENGL ? "(OpenGL)" : "(OpenGL ES)", device->glGetString(pulse_device, GL_RENDERER));
return pulse_device; return pulse_device;
} }
void OpenGLDestroyDevice(PulseDevice device) bool OpenGLDeviceSupportsExtension(PulseDevice device, const char* name)
{ {
OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*); OpenGLDevice* opengl_device = OPENGL_RETRIEVE_DRIVER_DATA_AS(device, OpenGLDevice*);
if(opengl_device == PULSE_NULLPTR) for(uint32_t i = 0; i < opengl_device->supported_extensions_count; i++)
return; {
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 #ifdef PULSE_PLAT_WINDOWS
if(opengl_device->context_type == OPENGL_CONTEXT_WGL) if(opengl_device->context_type == OPENGL_CONTEXT_WGL)
{} // TODO: WGL {} // TODO: WGL

View File

@@ -33,10 +33,14 @@ typedef struct OpenGLDevice
#undef PULSE_OPENGL_WRAPPER #undef PULSE_OPENGL_WRAPPER
#undef PULSE_OPENGL_WRAPPER_RET #undef PULSE_OPENGL_WRAPPER_RET
const char** supported_extensions;
uint32_t supported_extensions_count;
uint32_t device_id; uint32_t device_id;
} OpenGLDevice; } OpenGLDevice;
PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count); PulseDevice OpenGLCreateDevice(PulseBackend backend, PulseDevice* forbiden_devices, uint32_t forbiden_devices_count);
bool OpenGLDeviceSupportsExtension(PulseDevice device, const char* name);
void OpenGLDestroyDevice(PulseDevice device); void OpenGLDestroyDevice(PulseDevice device);
#endif // PULSE_OPENGL_DEVICE_H_ #endif // PULSE_OPENGL_DEVICE_H_

View File

@@ -15,11 +15,28 @@ typedef enum OpenGLContextType
OPENGL_CONTEXT_END_ENUM OPENGL_CONTEXT_END_ENUM
} OpenGLContextType; } 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, #define PULSE_OPENGL_FUNCTION(fn, T) fn,
#include "OpenGLFunctions.h" #include "OpenGLFunctions.h"
#undef PULSE_OPENGL_FUNCTION #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 OPENGL_FUNCTION_INDEX_END_ENUM
} OpenGLFunctionIndex; } OpenGLFunctionIndex;

View File

@@ -7,19 +7,35 @@
#include "../../PulseInternal.h" #include "../../PulseInternal.h"
#include "OpenGL.h" #include "OpenGL.h"
#include "OpenGLFence.h" #include "OpenGLFence.h"
#include "OpenGLDevice.h"
PulseFence OpenGLCreateFence(PulseDevice device) 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) void OpenGLDestroyFence(PulseDevice device, PulseFence fence)
{ {
PULSE_UNUSED(device);
free(fence);
} }
bool OpenGLIsFenceReady(PulseDevice device, PulseFence 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) 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;
} }

View File

@@ -10,10 +10,6 @@
#include <Pulse.h> #include <Pulse.h>
#include "OpenGL.h" #include "OpenGL.h"
typedef struct OpenGLFence
{
} OpenGLFence;
PulseFence OpenGLCreateFence(PulseDevice device); PulseFence OpenGLCreateFence(PulseDevice device);
void OpenGLDestroyFence(PulseDevice device, PulseFence fence); void OpenGLDestroyFence(PulseDevice device, PulseFence fence);
bool OpenGLIsFenceReady(PulseDevice device, PulseFence fence); bool OpenGLIsFenceReady(PulseDevice device, PulseFence fence);

View File

@@ -8,10 +8,6 @@
#error "You must define PULSE_OPENGL_FUNCTION before including this file" #error "You must define PULSE_OPENGL_FUNCTION before including this file"
#endif #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 #ifndef PULSE_OPENGL_GL_GLES_FUNCTION
#define PULSE_OPENGL_GL_GLES_FUNCTION(glVer, glesVer, name, sig) PULSE_OPENGL_FUNCTION(name, sig) #define PULSE_OPENGL_GL_GLES_FUNCTION(glVer, glesVer, name, sig) PULSE_OPENGL_FUNCTION(name, sig)
#endif #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, 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)
// 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)

View File

@@ -12,6 +12,7 @@
typedef struct OpenGLImage typedef struct OpenGLImage
{ {
int dummy;
} OpenGLImage; } OpenGLImage;
PulseImage OpenGLCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos); PulseImage OpenGLCreateImage(PulseDevice device, const PulseImageCreateInfo* create_infos);

View File

@@ -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(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(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(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(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_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(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(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)
PULSE_OPENGL_WRAPPER(glMemoryBarrierByRegion, (PulseDevice device, GLbitfield barriers), (barriers), PFNGLMEMORYBARRIERBYREGIONPROC) 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)

View File

@@ -63,7 +63,7 @@ static void SoftCommandDispatch(SoftCommand* cmd)
for(uint32_t i = 0; i < local_size; i++) for(uint32_t i = 0; i < local_size; i++)
{ {
thrd_create(&invocations[invocation_index], SoftCommandDispatchCore, soft_pipeline); thrd_create(&invocations[invocation_index], SoftCommandDispatchCore, soft_pipeline);
thrd_join(invocations[invocation_index], NULL); //thrd_join(invocations[invocation_index], NULL);
invocation_index++; invocation_index++;
} }
} }

View File

@@ -49,7 +49,7 @@ local backends = {
end, end,
before_build = function(target, os) before_build = function(target, os)
local gles_dir = target:pkg("opengl-headers"):installdir() 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 end
}, },
} }