[Bf-blender-cvs] [6222cb575fa] master: Fix T68950: Adding lots of edge loops to cylinder produces a crash

Huseyin Karakullukcu noreply at git.blender.org
Fri Sep 6 17:08:38 CEST 2019


Commit: 6222cb575fa51184ad8929aa097939d1dd1c92bc
Author: Huseyin Karakullukcu
Date:   Fri Sep 6 17:01:33 2019 +0200
Branches: master
https://developer.blender.org/rB6222cb575fa51184ad8929aa097939d1dd1c92bc

Fix T68950: Adding lots of edge loops to cylinder produces a crash

Instead of fixed size, `IMM_BUFFER_SIZE` is adjustable now. The internal buffer can expand if there is a need a bigger buffer. All other behaviors are still the same.

Reviewed By: fclem, #gpu_viewport

Differential Revision: https://developer.blender.org/D5570

===================================================================

M	source/blender/gpu/intern/gpu_immediate.c

===================================================================

diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c
index 0e3019ad122..938deadaa13 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;
   }



More information about the Bf-blender-cvs mailing list