mirror of
https://github.com/Kbz-8/Pulse.git
synced 2026-01-11 07:23:35 +00:00
154 lines
5.4 KiB
C
154 lines
5.4 KiB
C
// Copyright (C) 2025 kbz_8
|
|
// This file is part of "Pulse"
|
|
// For conditions of distribution and use, see copyright notice in LICENSE
|
|
|
|
#include <Pulse.h>
|
|
|
|
#include "../../PulseInternal.h"
|
|
#include "OpenGL.h"
|
|
#include "OpenGLCommandList.h"
|
|
#include "OpenGLDevice.h"
|
|
#include "OpenGLBuffer.h"
|
|
#include "OpenGLFence.h"
|
|
#include "OpenGLComputePipeline.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*);
|
|
OpenGLComputePipeline* opengl_pipeline = OPENGL_RETRIEVE_DRIVER_DATA_AS(cmd->Dispatch.pipeline, OpenGLComputePipeline*);
|
|
|
|
opengl_device->glUseProgram(device, opengl_pipeline->program);
|
|
|
|
uint32_t buffer_index = 0;
|
|
uint32_t image_index = 0;
|
|
|
|
if(cmd->Dispatch.read_only_group != PULSE_NULLPTR)
|
|
{
|
|
for(uint32_t i = 0; cmd->Dispatch.read_only_group->ReadOnly.images[i] != PULSE_NULLPTR; i++, image_index++)
|
|
{
|
|
PulseImage image = cmd->Dispatch.read_only_group->ReadOnly.images[i];
|
|
}
|
|
for(uint32_t i = 0; cmd->Dispatch.read_only_group->ReadOnly.storage_buffers[i] != PULSE_NULLPTR; i++, buffer_index++)
|
|
{
|
|
PulseBuffer buffer = cmd->Dispatch.read_only_group->ReadOnly.storage_buffers[i];
|
|
OpenGLBuffer* opengl_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer, OpenGLBuffer*);
|
|
opengl_device->glBindBufferRange(device, GL_SHADER_STORAGE_BUFFER, buffer_index, opengl_buffer->buffer, 0, buffer->size);
|
|
}
|
|
}
|
|
|
|
if(cmd->Dispatch.read_write_group != PULSE_NULLPTR)
|
|
{
|
|
for(uint32_t i = 0; cmd->Dispatch.read_write_group->ReadWrite.images[i] != PULSE_NULLPTR; i++, image_index++)
|
|
{
|
|
PulseImage image = cmd->Dispatch.read_write_group->ReadWrite.images[i];
|
|
}
|
|
for(uint32_t i = 0; cmd->Dispatch.read_write_group->ReadWrite.storage_buffers[i] != PULSE_NULLPTR; i++, buffer_index++)
|
|
{
|
|
PulseBuffer buffer = cmd->Dispatch.read_write_group->ReadWrite.storage_buffers[i];
|
|
OpenGLBuffer* opengl_buffer = OPENGL_RETRIEVE_DRIVER_DATA_AS(buffer, OpenGLBuffer*);
|
|
opengl_device->glBindBufferRange(device, GL_SHADER_STORAGE_BUFFER, buffer_index, opengl_buffer->buffer, 0, buffer->size);
|
|
}
|
|
}
|
|
|
|
if(cmd->Dispatch.uniform_group != PULSE_NULLPTR)
|
|
{
|
|
}
|
|
|
|
opengl_device->glDispatchCompute(device, cmd->Dispatch.groupcount_x, cmd->Dispatch.groupcount_y, cmd->Dispatch.groupcount_z);
|
|
|
|
free(cmd->Dispatch.read_only_group);
|
|
free(cmd->Dispatch.read_write_group);
|
|
free(cmd->Dispatch.uniform_group);
|
|
}
|
|
|
|
static void OpenGLCommandsRunner(PulseCommandList cmd)
|
|
{
|
|
PULSE_CHECK_PTR(cmd);
|
|
|
|
OpenGLCommandList* opengl_cmd = OPENGL_RETRIEVE_DRIVER_DATA_AS(cmd, OpenGLCommandList*);
|
|
PULSE_CHECK_PTR(opengl_cmd);
|
|
|
|
for(uint32_t i = 0; i < opengl_cmd->commands_count; i++)
|
|
{
|
|
OpenGLCommand* command = &opengl_cmd->commands[i];
|
|
switch(command->type)
|
|
{
|
|
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(cmd->device, command); break;
|
|
case OPENGL_COMMAND_DISPATCH_INDIRECT: break;
|
|
|
|
default: break;
|
|
}
|
|
}
|
|
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)
|
|
{
|
|
OpenGLCommandList* opengl_cmd = OPENGL_RETRIEVE_DRIVER_DATA_AS(cmd, OpenGLCommandList*);
|
|
PULSE_EXPAND_ARRAY_IF_NEEDED(opengl_cmd->commands, OpenGLCommand, opengl_cmd->commands_count, opengl_cmd->commands_capacity, 8);
|
|
opengl_cmd->commands[opengl_cmd->commands_count] = command;
|
|
opengl_cmd->commands_count++;
|
|
}
|
|
|
|
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);
|
|
}
|