Commit: a47a64d9e4d83b7a2e7f240d89870ca73897d1af Author: Clément Foucault Date: Mon Aug 31 15:14:47 2020 +0200 Branches: lanpr-under-gp https://developer.blender.org/rBa47a64d9e4d83b7a2e7f240d89870ca73897d1af
GPUImmediate: GL backend isolation This is part of the Vulkan backend task T68990. This is mostly a cleanup, however, there is a small change: We don't use a special Vertex Array binding function for Immediate anymore and just reuse the one for batches. This might create a bit more state changes but this could be fixed easily if it causes perf regression. # Conflicts: # source/blender/gpu/intern/gpu_context.cc =================================================================== M source/blender/gpu/CMakeLists.txt M source/blender/gpu/intern/gpu_context.cc M source/blender/gpu/intern/gpu_context_private.hh M source/blender/gpu/intern/gpu_immediate.cc A source/blender/gpu/intern/gpu_immediate_private.hh M source/blender/gpu/opengl/gl_context.cc A source/blender/gpu/opengl/gl_immediate.cc A source/blender/gpu/opengl/gl_immediate.hh A source/blender/gpu/opengl/gl_primitive.hh M source/blender/gpu/opengl/gl_vertex_array.cc M source/blender/gpu/opengl/gl_vertex_array.hh =================================================================== diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 1cb13d815a2..6dadde398b9 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -93,6 +93,7 @@ set(SRC opengl/gl_context.cc opengl/gl_drawlist.cc opengl/gl_framebuffer.cc + opengl/gl_immediate.cc opengl/gl_shader.cc opengl/gl_shader_interface.cc opengl/gl_state.cc @@ -136,6 +137,7 @@ set(SRC intern/gpu_context_private.hh intern/gpu_drawlist_private.hh intern/gpu_framebuffer_private.hh + intern/gpu_immediate_private.hh intern/gpu_material_library.h intern/gpu_matrix_private.h intern/gpu_node_graph.h @@ -153,6 +155,8 @@ set(SRC opengl/gl_context.hh opengl/gl_drawlist.hh opengl/gl_framebuffer.hh + opengl/gl_immediate.hh + opengl/gl_primitive.hh opengl/gl_shader.hh opengl/gl_shader_interface.hh opengl/gl_state.hh diff --git a/source/blender/gpu/intern/gpu_context.cc b/source/blender/gpu/intern/gpu_context.cc index f188f5e9fda..229456f9aa5 100644 --- a/source/blender/gpu/intern/gpu_context.cc +++ b/source/blender/gpu/intern/gpu_context.cc @@ -75,6 +75,7 @@ GPUContext::~GPUContext() delete back_left; delete front_right; delete back_right; + delete imm; } bool GPUContext::is_active_on_thread(void) diff --git a/source/blender/gpu/intern/gpu_context_private.hh b/source/blender/gpu/intern/gpu_context_private.hh index 04b347d1bff..b32406bfc44 100644 --- a/source/blender/gpu/intern/gpu_context_private.hh +++ b/source/blender/gpu/intern/gpu_context_private.hh @@ -30,6 +30,7 @@ #include "GPU_context.h" #include "gpu_framebuffer_private.hh" +#include "gpu_immediate_private.hh" #include "gpu_shader_private.hh" #include "gpu_state_private.hh" @@ -48,6 +49,7 @@ struct GPUContext { blender::gpu::FrameBuffer *active_fb = NULL; GPUMatrixState *matrix_state = NULL; blender::gpu::GPUStateManager *state_manager = NULL; + blender::gpu::Immediate *imm = NULL; /** * All 4 window framebuffers. diff --git a/source/blender/gpu/intern/gpu_immediate.cc b/source/blender/gpu/intern/gpu_immediate.cc index b0deb1d9551..51843917f58 100644 --- a/source/blender/gpu/intern/gpu_immediate.cc +++ b/source/blender/gpu/intern/gpu_immediate.cc @@ -20,7 +20,7 @@ /** \file * \ingroup gpu * - * GPU immediate mode work-alike + * Mimics old style opengl immediate mode drawing. */ #ifndef GPU_STANDALONE @@ -34,122 +34,53 @@ #include "gpu_attr_binding_private.h" #include "gpu_context_private.hh" +#include "gpu_immediate_private.hh" #include "gpu_primitive_private.h" #include "gpu_shader_private.hh" #include "gpu_vertex_format_private.h" -#include <stdlib.h> -#include <string.h> - -typedef struct ImmediateDrawBuffer { - GLuint vbo_id; - GLubyte *buffer_data; - uint buffer_offset; - uint buffer_size; -} ImmediateDrawBuffer; - -typedef struct { - GPUBatch *batch; - GPUContext *context; - - /* current draw call */ - bool strict_vertex_len; - uint vertex_len; - uint buffer_bytes_mapped; - ImmediateDrawBuffer *active_buffer; - GPUPrimType prim_type; - GPUVertFormat vertex_format; - ImmediateDrawBuffer draw_buffer; - ImmediateDrawBuffer draw_buffer_strict; - - /* current vertex */ - uint vertex_idx; - GLubyte *vertex_data; - /** which attributes of current vertex have not been given values? */ - uint16_t unassigned_attr_bits; - - GLuint vao_id; - - GPUShader *bound_program; - GPUAttrBinding attr_binding; - uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */ -} Immediate; - -/* size of internal buffer */ -#define DEFAULT_INTERNAL_BUFFER_SIZE (4 * 1024 * 1024) - -static bool initialized = false; -static Immediate imm; +using namespace blender::gpu; + +static Immediate *imm = NULL; void immInit(void) { - BLI_assert(!initialized); - - memset(&imm, 0, sizeof(Immediate)); - - imm.draw_buffer.vbo_id = GPU_buf_alloc(); - imm.draw_buffer.buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE; - glBindBuffer(GL_ARRAY_BUFFER, imm.draw_buffer.vbo_id); - glBufferData(GL_ARRAY_BUFFER, imm.draw_buffer.buffer_size, NULL, GL_DYNAMIC_DRAW); - - imm.draw_buffer_strict.vbo_id = GPU_buf_alloc(); - imm.draw_buffer_strict.buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE; - glBindBuffer(GL_ARRAY_BUFFER, imm.draw_buffer_strict.vbo_id); - glBufferData(GL_ARRAY_BUFFER, imm.draw_buffer_strict.buffer_size, NULL, GL_DYNAMIC_DRAW); - - imm.prim_type = GPU_PRIM_NONE; - imm.strict_vertex_len = true; - - glBindBuffer(GL_ARRAY_BUFFER, 0); - initialized = true; + /* TODO Remove */ } void immActivate(void) { - BLI_assert(initialized); - BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */ - BLI_assert(imm.vao_id == 0); - - imm.vao_id = GPU_vao_alloc(); - imm.context = GPU_context_active_get(); + imm = GPU_context_active_get()->imm; } void immDeactivate(void) { - BLI_assert(initialized); - BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we're not between a Begin/End pair */ - BLI_assert(imm.vao_id != 0); - - GPU_vao_free(imm.vao_id, imm.context); - imm.vao_id = 0; - imm.prev_enabled_attr_bits = 0; + imm = NULL; } void immDestroy(void) { - GPU_buf_free(imm.draw_buffer.vbo_id); - GPU_buf_free(imm.draw_buffer_strict.vbo_id); - initialized = false; + /* TODO Remove */ } GPUVertFormat *immVertexFormat(void) { - GPU_vertformat_clear(&imm.vertex_format); - return &imm.vertex_format; + GPU_vertformat_clear(&imm->vertex_format); + return &imm->vertex_format; } void immBindShader(GPUShader *shader) { - BLI_assert(imm.bound_program == NULL); + BLI_assert(imm->shader == NULL); - imm.bound_program = shader; + imm->shader = shader; - if (!imm.vertex_format.packed) { - VertexFormat_pack(&imm.vertex_format); + if (!imm->vertex_format.packed) { + VertexFormat_pack(&imm->vertex_format); + imm->enabled_attr_bits = 0xFFFFu & ~(0xFFFFu << imm->vertex_format.attr_len); } GPU_shader_bind(shader); - get_attr_locations(&imm.vertex_format, &imm.attr_binding, shader); GPU_matrix_bind(shader); GPU_shader_set_srgb_uniform(shader); } @@ -162,16 +93,16 @@ void immBindBuiltinProgram(eGPUBuiltinShader shader_id) void immUnbindProgram(void) { - BLI_assert(imm.bound_program != NULL); + BLI_assert(imm->shader != NULL); GPU_shader_unbind(); - imm.bound_program = NULL; + imm->shader = NULL; } /* XXX do not use it. Special hack to use OCIO with batch API. */ GPUShader *immGetShader(void) { - return imm.bound_program; + return imm->shader; } #ifndef NDEBUG @@ -205,267 +136,122 @@ static bool vertex_count_makes_sense_for_primitive(uint vertex_len, GPUPrimType void immBegin(GPUPrimType prim_type, uint vertex_len) { - BLI_assert(initialized); - BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */ + BLI_assert(imm->prim_type == GPU_PRIM_NONE); /* Make sure we haven't already begun. */ BLI_assert(vertex_count_makes_sense_for_primitive(vertex_len, prim_type)); - BLI_assert(imm.active_buffer == NULL); - - GPU_context_active_get()->state_manager->apply_state(); - - imm.prim_type = prim_type; - imm.vertex_len = vertex_len; - imm.vertex_idx = 0; - imm.unassigned_attr_bits = imm.attr_binding.enabled_bits; - - /* how many bytes do we need for this draw call? */ - const uint bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len); - ImmediateDrawBuffer *active_buffer = imm.strict_vertex_len ? &imm.draw_buffer_strict : - &imm.draw_buffer; - imm.active_buffer = active_buffer; - - glBindBuffer(GL_ARRAY_BUFFER, active_buffer->vbo_id); - - /* does the current buffer have enough room? */ - const uint available_bytes = active_buffer->buffer_size - active_buffer->buffer_offset; - - bool recreate_buffer = false; - if (bytes_needed > active_buffer->buffer_size) { - /* expand the internal buffer */ - active_buffer->buffer_size = bytes_needed; - recreate_buffer = true; - } - else if (bytes_needed < DEFAULT_INTERNAL_BUFFER_SIZE && - active_buffer->buffer_size > DEFAULT_INTERNAL_BUFFER_SIZE) { - /* shrink the internal buffer */ - active_buffer->buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE; - recreate_buffer = true; - } - - /* ensure vertex data is aligned */ - /* Might waste a little space, but it's safe. */ - const uint pre_padding = padding(active_buffer->buffer_offset, imm.vertex_format.stride); - - if (!recreate_buffer && ((bytes_needed + pre_padding) <= available_bytes)) { - active_buffer->buffer_offset += pre_padding; - } - else { - /* orphan this buffer & start with a fresh one */ - /* this method works on all platforms, old & new */ - glBufferData(GL_ARRAY_BUFFER, active_buffer->buffer_size, NULL, GL_DYNAMIC_DRAW); - - active_buffer->buffer_offset = 0; - } - - /* printf("mapping %u to %u\n", imm.buffer_offset, imm.buffer_offset + bytes_needed - 1); */ - -#ifndef NDEBUG - { - GLint bufsize; - glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &bufsize); - BLI_assert(active_buffer->buffer_offset + bytes_needed <= bufsize); - } -#endif - - active_buffer->buffer_data = (GLubyte *)glMapBufferRange( - GL_ARRAY_BUFFER, - active_buffer->buffer_offset, - bytes_needed, - GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | - (imm.strict_vertex_len ? 0 : GL_MAP_FLUSH_EXPLICIT_BIT)); - BLI_assert(active_buffer->buffer_data != NULL); + imm->prim_type = prim_type; + imm->vertex_len = vertex_len; + imm->vertex_idx = 0; + imm->unassigned_attr_bits = imm->enabled_attr_bits; - imm.buffer_bytes_mapped = bytes_needed; - imm.vertex_data = active_buffer->buffer_data; + imm->vertex_data = imm->begin(); } void immBeginAtMost(GPUPrimType prim_type, uint vertex_len) { BLI_assert(vertex_len > 0); - - imm.strict_vertex_len = false; + imm->strict_vertex_len = false; immBegin(prim_type, vertex_len); } GPUBatch *immBeginBatch(GPUPrimType prim_type, uint vertex_len) { - BLI_assert(initialized); - BLI_assert(imm.prim_type == GPU_PRIM_NONE); /* make sure we haven't already begun */ + BLI_assert(imm->prim_type == GPU_PRIM_NONE); /* Make sure @@ Diff output truncated at 10240 characters. @@ _______________________________________________ Bf-blender-cvs mailing list Bf-blender-cvs@blender.org https://lists.blender.org/mailman/listinfo/bf-blender-cvs