Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Erwin <significant.bit@gmail.com>2016-09-06 23:56:08 +0300
committerMike Erwin <significant.bit@gmail.com>2016-09-06 23:56:08 +0300
commit18d49a8283f2490b0751798685770533cc814d29 (patch)
treed6b742efcf60af45c1ebe26b97b1a03ef078f652 /source/blender/gpu/intern/gpu_immediate.c
parent031c5bad87693f263d2ee69192fb6f7512a5f6dc (diff)
Gawain: add immBeginAtMost
immBegin requires us to know how many vertices will be drawn. Most times this is fine, but sometimes it can be tricky. Do we make the effort to count everything in one pass, then draw it in a second? immBeginAtMost makes this simple. Example: I'll draw at most 100 vertices. Supply only 6 verts and it draws only 6. Any unused space is reclaimed and given to the next immBegin.
Diffstat (limited to 'source/blender/gpu/intern/gpu_immediate.c')
-rw-r--r--source/blender/gpu/intern/gpu_immediate.c73
1 files changed, 52 insertions, 21 deletions
diff --git a/source/blender/gpu/intern/gpu_immediate.c b/source/blender/gpu/intern/gpu_immediate.c
index 88a147959a3..98568d14482 100644
--- a/source/blender/gpu/intern/gpu_immediate.c
+++ b/source/blender/gpu/intern/gpu_immediate.c
@@ -242,6 +242,7 @@ typedef struct {
unsigned buffer_offset;
unsigned buffer_bytes_mapped;
unsigned vertex_ct;
+ bool strict_vertex_ct;
GLenum primitive;
VertexFormat vertex_format;
@@ -285,7 +286,8 @@ void immInit()
#endif
imm.primitive = PRIM_NONE;
-
+ imm.strict_vertex_ct = true;
+
glBindBuffer(GL_ARRAY_BUFFER, 0);
glBindVertexArray(0);
initialized = true;
@@ -334,36 +336,38 @@ void immUnbindProgram()
imm.bound_program = 0;
}
-void immBegin(GLenum primitive, unsigned vertex_ct)
+static bool vertex_count_makes_sense_for_primitive(unsigned vertex_ct, GLenum primitive)
{
-#if TRUST_NO_ONE
- assert(initialized);
- assert(imm.primitive == PRIM_NONE); // make sure we haven't already begun
-
// does vertex_ct make sense for this primitive type?
- assert(vertex_ct > 0);
+ if (vertex_ct == 0)
+ return false;
+
switch (primitive)
{
case GL_POINTS:
- break;
+ return true;
case GL_LINES:
- assert(vertex_ct % 2 == 0);
- break;
+ return vertex_ct % 2 == 0;
case GL_LINE_STRIP:
case GL_LINE_LOOP:
- assert(vertex_ct > 2); // otherwise why bother?
- break;
+ return vertex_ct > 2; // otherwise why bother?
case GL_TRIANGLES:
- assert(vertex_ct % 3 == 0);
- break;
+ return vertex_ct % 3 == 0;
#ifdef WITH_GL_PROFILE_COMPAT
case GL_QUADS:
- assert(vertex_ct % 4 == 0);
- break;
+ return vertex_ct % 4 == 0;
#endif
default:
- assert(false);
+ return false;
}
+ }
+
+void immBegin(GLenum primitive, unsigned vertex_ct)
+ {
+#if TRUST_NO_ONE
+ assert(initialized);
+ assert(imm.primitive == PRIM_NONE); // make sure we haven't already begun
+ assert(vertex_count_makes_sense_for_primitive(vertex_ct, primitive));
#endif
imm.primitive = primitive;
@@ -417,17 +421,43 @@ void immBegin(GLenum primitive, unsigned vertex_ct)
imm.vertex_data = imm.buffer_data;
}
+void immBeginAtMost(GLenum primitive, unsigned vertex_ct)
+ {
+ imm.strict_vertex_ct = false;
+ immBegin(primitive, vertex_ct);
+ }
+
void immEnd()
{
#if TRUST_NO_ONE
assert(imm.primitive != PRIM_NONE); // make sure we're between a Begin/End pair
- assert(imm.vertex_idx == imm.vertex_ct); // with all vertices defined
#endif
+ unsigned buffer_bytes_used;
+ if (imm.strict_vertex_ct)
+ {
+#if TRUST_NO_ONE
+ assert(imm.vertex_idx == imm.vertex_ct); // with all vertices defined
+#endif
+ buffer_bytes_used = imm.buffer_bytes_mapped;
+ }
+ else
+ {
+#if TRUST_NO_ONE
+ assert(imm.vertex_idx <= imm.vertex_ct);
+ assert(vertex_count_makes_sense_for_primitive(imm.vertex_idx, imm.primitive));
+#endif
+ // printf("used %u of %u verts,", imm.vertex_idx, imm.vertex_ct);
+ imm.vertex_ct = imm.vertex_idx;
+ buffer_bytes_used = vertex_buffer_size(&imm.vertex_format, imm.vertex_ct);
+ // unused buffer bytes are available to the next immBegin
+ // printf(" %u of %u bytes\n", buffer_bytes_used, imm.buffer_bytes_mapped);
+ }
+
#if APPLE_LEGACY
// tell OpenGL what range was modified so it doesn't copy the whole buffer
- glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, imm.buffer_offset, imm.buffer_bytes_mapped);
-// printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + imm.buffer_bytes_mapped - 1);
+ glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER, imm.buffer_offset, buffer_bytes_used);
+// printf("flushing %u to %u\n", imm.buffer_offset, imm.buffer_offset + buffer_bytes_used - 1);
#endif
glUnmapBuffer(GL_ARRAY_BUFFER);
@@ -490,8 +520,9 @@ void immEnd()
glBindVertexArray(0);
// prep for next immBegin
- imm.buffer_offset += imm.buffer_bytes_mapped;
+ imm.buffer_offset += buffer_bytes_used;
imm.primitive = PRIM_NONE;
+ imm.strict_vertex_ct = true;
// further optional cleanup
imm.buffer_bytes_mapped = 0;