diff options
Diffstat (limited to 'source/blender/gpu/intern/gpu_immediate.c')
-rw-r--r-- | source/blender/gpu/intern/gpu_immediate.c | 38 |
1 files changed, 24 insertions, 14 deletions
diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c index 0e3019ad122..bed7ab25bb9 100644 --- a/source/blender/gpu/intern/gpu_immediate.c +++ b/source/blender/gpu/intern/gpu_immediate.c @@ -72,8 +72,9 @@ typedef struct { uint16_t prev_enabled_attr_bits; /* <-- only affects this VAO, so we're ok */ } Immediate; -/* size of internal buffer -- make this adjustable? */ -#define IMM_BUFFER_SIZE (4 * 1024 * 1024) +/* size of internal buffer */ +#define DEFAULT_INTERNAL_BUFFER_SIZE (4 * 1024 * 1024) +static uint imm_buffer_size = DEFAULT_INTERNAL_BUFFER_SIZE; static bool initialized = false; static Immediate imm; @@ -87,7 +88,7 @@ void immInit(void) imm.vbo_id = GPU_buf_alloc(); glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); - glBufferData(GL_ARRAY_BUFFER, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, imm_buffer_size, NULL, GL_DYNAMIC_DRAW); imm.prim_type = GPU_PRIM_NONE; imm.strict_vertex_len = true; @@ -211,26 +212,35 @@ void immBegin(GPUPrimType prim_type, uint vertex_len) /* how many bytes do we need for this draw call? */ const uint bytes_needed = vertex_buffer_size(&imm.vertex_format, vertex_len); -#if TRUST_NO_ONE - assert(bytes_needed <= IMM_BUFFER_SIZE); -#endif - glBindBuffer(GL_ARRAY_BUFFER, imm.vbo_id); /* does the current buffer have enough room? */ - const uint available_bytes = IMM_BUFFER_SIZE - imm.buffer_offset; - /* ensure vertex data is aligned */ + const uint available_bytes = imm_buffer_size - imm.buffer_offset; + bool recreate_buffer = false; + if (bytes_needed > imm_buffer_size) { + /* expand the internal buffer */ + imm_buffer_size = bytes_needed; + recreate_buffer = true; + } + else if (bytes_needed < DEFAULT_INTERNAL_BUFFER_SIZE && + imm_buffer_size > DEFAULT_INTERNAL_BUFFER_SIZE) { + /* shrink the internal buffer */ + imm_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(imm.buffer_offset, imm.vertex_format.stride); - if ((bytes_needed + pre_padding) <= available_bytes) { + if (!recreate_buffer && ((bytes_needed + pre_padding) <= available_bytes)) { imm.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, IMM_BUFFER_SIZE, NULL, GL_DYNAMIC_DRAW); + glBufferData(GL_ARRAY_BUFFER, imm_buffer_size, NULL, GL_DYNAMIC_DRAW); imm.buffer_offset = 0; } @@ -298,7 +308,7 @@ static void immDrawSetup(void) /* Enable/Disable vertex attributes as needed. */ if (imm.attr_binding.enabled_bits != imm.prev_enabled_attr_bits) { - for (uint loc = 0; loc < GPU_VERT_ATTR_MAX_LEN; ++loc) { + for (uint loc = 0; loc < GPU_VERT_ATTR_MAX_LEN; loc++) { bool is_enabled = imm.attr_binding.enabled_bits & (1 << loc); bool was_enabled = imm.prev_enabled_attr_bits & (1 << loc); @@ -315,7 +325,7 @@ static void immDrawSetup(void) const uint stride = imm.vertex_format.stride; - for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { + for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; a_idx++) { const GPUVertAttr *a = &imm.vertex_format.attrs[a_idx]; const uint offset = imm.buffer_offset + a->offset; @@ -640,7 +650,7 @@ static void immEndVertex(void) /* and move on to the next vertex */ #if TRUST_NO_ONE assert(imm.vertex_idx > 0); /* first vertex must have all attributes specified */ #endif - for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; ++a_idx) { + for (uint a_idx = 0; a_idx < imm.vertex_format.attr_len; a_idx++) { if ((imm.unassigned_attr_bits >> a_idx) & 1) { const GPUVertAttr *a = &imm.vertex_format.attrs[a_idx]; |