diff --git a/backends/gpu/opengl/includes/kore3/opengl/commandlist_structs.h b/backends/gpu/opengl/includes/kore3/opengl/commandlist_structs.h index 2990223ed..6a5f7ae63 100644 --- a/backends/gpu/opengl/includes/kore3/opengl/commandlist_structs.h +++ b/backends/gpu/opengl/includes/kore3/opengl/commandlist_structs.h @@ -18,7 +18,9 @@ typedef struct kore_opengl_buffer_access { } kore_opengl_buffer_access; typedef struct kore_opengl_command_list { - int nothing; + uint8_t *commands; + uint64_t commands_offset; + bool presents; } kore_opengl_command_list; #ifdef __cplusplus diff --git a/backends/gpu/opengl/sources/commandlist.c b/backends/gpu/opengl/sources/commandlist.c index 11ceae33e..32947787c 100644 --- a/backends/gpu/opengl/sources/commandlist.c +++ b/backends/gpu/opengl/sources/commandlist.c @@ -13,19 +13,83 @@ #include +typedef enum command_type { + COMMAND_SET_INDEX_BUFFER, + COMMAND_SET_VERTEX_BUFFER, + COMMAND_DRAW_INDEXED, +} command_type; + +typedef struct set_index_buffer_data { + kore_gpu_buffer *buffer; + kore_gpu_index_format index_format; + uint64_t offset; + uint64_t size; +} set_index_buffer_data; + +typedef struct set_vertex_buffer_data { + uint32_t slot; + kore_opengl_buffer *buffer; + uint64_t offset; + uint64_t size; + uint64_t stride; +} set_vertex_buffer_data; + +typedef struct draw_indexed_data { + uint32_t index_count; + uint32_t instance_count; + uint32_t first_index; + int32_t base_vertex; + uint32_t first_instance; +} draw_indexed_data; + +typedef struct command { + command_type type; + uint32_t size; + uint32_t data; +} command; + void kore_opengl_command_list_destroy(kore_gpu_command_list *list) {} void kore_opengl_command_list_begin_render_pass(kore_gpu_command_list *list, const kore_gpu_render_pass_parameters *parameters) {} void kore_opengl_command_list_end_render_pass(kore_gpu_command_list *list) {} -void kore_opengl_command_list_present(kore_gpu_command_list *list) {} +void kore_opengl_command_list_present(kore_gpu_command_list *list) { + list->opengl.presents = true; +} void kore_opengl_command_list_set_index_buffer(kore_gpu_command_list *list, kore_gpu_buffer *buffer, kore_gpu_index_format index_format, uint64_t offset, - uint64_t size) {} + uint64_t size) { + command *c = (command *)&list->opengl.commands[list->opengl.commands_offset]; + + c->type = COMMAND_SET_INDEX_BUFFER; + + set_index_buffer_data *data = (set_index_buffer_data *)&c->data; + data->buffer = buffer; + data->index_format = index_format; + data->offset = offset; + data->size = size; + + c->size = sizeof(command) - sizeof(c->data) + sizeof(*data); + list->opengl.commands_offset += c->size; +} void kore_opengl_command_list_set_vertex_buffer(kore_gpu_command_list *list, uint32_t slot, kore_opengl_buffer *buffer, uint64_t offset, uint64_t size, - uint64_t stride) {} + uint64_t stride) { + command *c = (command *)&list->opengl.commands[list->opengl.commands_offset]; + + c->type = COMMAND_SET_VERTEX_BUFFER; + + set_vertex_buffer_data *data = (set_vertex_buffer_data *)&c->data; + data->slot = slot; + data->buffer = buffer; + data->offset = offset; + data->size = size; + data->stride = stride; + + c->size = sizeof(command) - sizeof(c->data) + sizeof(*data); + list->opengl.commands_offset += c->size; +} void kore_opengl_command_list_set_render_pipeline(kore_gpu_command_list *list, kore_opengl_render_pipeline *pipeline) {} @@ -33,7 +97,21 @@ void kore_opengl_command_list_draw(kore_gpu_command_list *list, uint32_t vertex_ uint32_t first_instance) {} void kore_opengl_command_list_draw_indexed(kore_gpu_command_list *list, uint32_t index_count, uint32_t instance_count, uint32_t first_index, - int32_t base_vertex, uint32_t first_instance) {} + int32_t base_vertex, uint32_t first_instance) { + command *c = (command *)&list->opengl.commands[list->opengl.commands_offset]; + + c->type = COMMAND_DRAW_INDEXED; + + draw_indexed_data *data = (draw_indexed_data *)&c->data; + data->index_count = index_count; + data->instance_count = instance_count; + data->first_index = first_index; + data->base_vertex = base_vertex; + data->first_instance = first_instance; + + c->size = sizeof(command) - sizeof(c->data) + sizeof(*data); + list->opengl.commands_offset += c->size; +} void kore_opengl_command_list_set_descriptor_table(kore_gpu_command_list *list, uint32_t table_index, kore_opengl_descriptor_set *set, kore_gpu_buffer **dynamic_buffers, uint32_t *dynamic_offsets, uint32_t *dynamic_sizes) {} diff --git a/backends/gpu/opengl/sources/device.c b/backends/gpu/opengl/sources/device.c index 6f8cdab6f..1fd640b30 100644 --- a/backends/gpu/opengl/sources/device.c +++ b/backends/gpu/opengl/sources/device.c @@ -24,6 +24,7 @@ static HDC device_context; #endif static GLint framebuffer; +static GLuint vertex_array; #if defined(KORE_WINDOWS) && !defined(NDEBUG) static void __stdcall debug_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *userParam) { @@ -82,6 +83,9 @@ void kore_opengl_device_create(kore_gpu_device *device, const kore_gpu_device_wi glGetIntegerv(GL_FRAMEBUFFER_BINDING, &framebuffer); #endif + + glGenVertexArrays(1, &vertex_array); + glBindVertexArray(vertex_array); } void kore_opengl_device_destroy(kore_gpu_device *device) {} @@ -106,7 +110,11 @@ void kore_opengl_device_create_buffer(kore_gpu_device *device, const kore_gpu_bu glBindBuffer(buffer->opengl.buffer_type, 0); } -void kore_opengl_device_create_command_list(kore_gpu_device *device, kore_gpu_command_list_type type, kore_gpu_command_list *list) {} +void kore_opengl_device_create_command_list(kore_gpu_device *device, kore_gpu_command_list_type type, kore_gpu_command_list *list) { + list->opengl.commands = malloc(1024 * 1024); + list->opengl.commands_offset = 0; + list->opengl.presents = false; +} void kore_opengl_device_create_texture(kore_gpu_device *device, const kore_gpu_texture_parameters *parameters, kore_gpu_texture *texture) {} @@ -119,9 +127,44 @@ kore_gpu_texture_format kore_opengl_device_framebuffer_format(kore_gpu_device *d } void kore_opengl_device_execute_command_list(kore_gpu_device *device, kore_gpu_command_list *list) { + kore_gpu_index_format index_format = KORE_GPU_INDEX_FORMAT_UINT16; + + uint64_t offset = 0; + + while (offset < list->opengl.commands_offset) { + command *c = (command *)&list->opengl.commands[offset]; + + switch (c->type) { + case COMMAND_SET_INDEX_BUFFER: { + set_index_buffer_data *data = (set_index_buffer_data *)&c->data; + index_format = data->index_format; + glBindBuffer(data->buffer->opengl.buffer_type, data->buffer->opengl.buffer); + break; + } + case COMMAND_SET_VERTEX_BUFFER: { + set_vertex_buffer_data *data = (set_vertex_buffer_data *)&c->data; + glBindBuffer(data->buffer->buffer_type, data->buffer->buffer); + break; + } + case COMMAND_DRAW_INDEXED: { + draw_indexed_data *data = (draw_indexed_data *)&c->data; + + void *start = + index_format == KORE_GPU_INDEX_FORMAT_UINT16 ? (void *)(data->first_index * sizeof(uint16_t)) : (void *)(data->first_index * sizeof(uint32_t)); + glDrawElements(GL_TRIANGLES, data->index_count, index_format == KORE_GPU_INDEX_FORMAT_UINT16 ? GL_UNSIGNED_SHORT : GL_UNSIGNED_INT, start); + } + } + + kore_opengl_check_errors(); + + offset += c->size; + } + + if (list->opengl.presents) { #ifdef KORE_WINDOWS - SwapBuffers(device_context); + SwapBuffers(device_context); #endif + } } void kore_opengl_device_wait_until_idle(kore_gpu_device *device) {}