summaryrefslogtreecommitdiffstats
path: root/src/mesa/main
diff options
context:
space:
mode:
authorNicolai Hähnle <[email protected]>2016-01-11 14:54:53 -0500
committerNicolai Hähnle <[email protected]>2016-02-03 14:03:49 +0100
commit6b057f8ecc43be2e190e53599bdd6b8cc96b6f19 (patch)
treeff6dcf3039d870a4a6089a86b2c1e3009d72befb /src/mesa/main
parent1a570d96a606249ba406da50a61e2eabb88c77ac (diff)
vbo: cache/memoize the result of vbo_get_minmax_indices (v3)
Some games developers are unaware that an index buffer in a VBO still needs to be read by the CPU if some varying data comes from a user pointer (unless glDrawRangeElements and friends are used). This is particularly bad when they tell us that the index buffer should live in VRAM. This cache helps, e.g. lifting This War Of Mine (a particularly bad offender) from under 10fps to slightly over 20fps on a Carrizo. Note that there is nothing prohibiting a user from rendering from multiple threads simultaneously with the same index buffer, hence the locking. (The internal buffer map taken for the buffer still leads to a race, but at least the locks are a move in the right direction.) v2: disable the cache on USAGE_TEXTURE_BUFFER as well (Chris Forbes) v3: - use bool instead of GLboolean for MinMaxCacheDirty (Ian Romanick) - replace the sticky USAGE_PERSISTENT_WRITE_MAP bit by a direct AccessFlags check Reviewed-by: Chris Forbes <[email protected]> (v2) Reviewed-by: Marek Olšák <[email protected]>
Diffstat (limited to 'src/mesa/main')
-rw-r--r--src/mesa/main/bufferobj.c12
-rw-r--r--src/mesa/main/mtypes.h4
2 files changed, 15 insertions, 1 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index 2fcad6501ae..3d93cf826b2 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -458,6 +458,7 @@ _mesa_delete_buffer_object(struct gl_context *ctx,
{
(void) ctx;
+ vbo_delete_minmax_cache(bufObj);
_mesa_align_free(bufObj->Data);
/* assign strange values here to help w/ debugging */
@@ -1528,6 +1529,7 @@ _mesa_buffer_storage(struct gl_context *ctx, struct gl_buffer_object *bufObj,
bufObj->Written = GL_TRUE;
bufObj->Immutable = GL_TRUE;
+ bufObj->MinMaxCacheDirty = true;
assert(ctx->Driver.BufferData);
if (!ctx->Driver.BufferData(ctx, target, size, data, GL_DYNAMIC_DRAW,
@@ -1641,6 +1643,7 @@ _mesa_buffer_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
FLUSH_VERTICES(ctx, _NEW_BUFFER_OBJECT);
bufObj->Written = GL_TRUE;
+ bufObj->MinMaxCacheDirty = true;
#ifdef VBO_DEBUG
printf("glBufferDataARB(%u, sz %ld, from %p, usage 0x%x)\n",
@@ -1753,6 +1756,7 @@ _mesa_buffer_sub_data(struct gl_context *ctx, struct gl_buffer_object *bufObj,
}
bufObj->Written = GL_TRUE;
+ bufObj->MinMaxCacheDirty = true;
assert(ctx->Driver.BufferSubData);
ctx->Driver.BufferSubData(ctx, offset, size, data, bufObj);
@@ -1872,6 +1876,8 @@ _mesa_clear_buffer_sub_data(struct gl_context *ctx,
if (size == 0)
return;
+ bufObj->MinMaxCacheDirty = true;
+
if (data == NULL) {
/* clear to zeros, per the spec */
ctx->Driver.ClearBufferSubData(ctx, offset, size,
@@ -2285,6 +2291,8 @@ _mesa_copy_buffer_sub_data(struct gl_context *ctx,
}
}
+ dst->MinMaxCacheDirty = true;
+
ctx->Driver.CopyBufferSubData(ctx, src, dst, readOffset, writeOffset, size);
}
@@ -2489,8 +2497,10 @@ _mesa_map_buffer_range(struct gl_context *ctx,
assert(bufObj->Mappings[MAP_USER].AccessFlags == access);
}
- if (access & GL_MAP_WRITE_BIT)
+ if (access & GL_MAP_WRITE_BIT) {
bufObj->Written = GL_TRUE;
+ bufObj->MinMaxCacheDirty = true;
+ }
#ifdef VBO_DEBUG
if (strstr(func, "Range") == NULL) { /* If not MapRange */
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 4446d94b407..28aa781790b 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1282,6 +1282,10 @@ struct gl_buffer_object
GLuint NumMapBufferWriteCalls;
struct gl_buffer_mapping Mappings[MAP_COUNT];
+
+ /** Memoization of min/max index computations for static index buffers */
+ struct hash_table *MinMaxCache;
+ bool MinMaxCacheDirty;
};