aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMathias Fröhlich <[email protected]>2018-02-03 15:06:16 +0100
committerMathias Fröhlich <[email protected]>2018-02-06 21:20:14 +0100
commit2313c33e950a1b17e7787dd8a3b2f1e823d0cfd4 (patch)
treea885ab8dd272795da341bfd1747cb36d9de90a84
parent6c691081a183aec51d5305592b9fa391ebb447ab (diff)
mesa: Use atomics for buffer objects reference counts.
The mutex is currently used for reference counting and updating the minmax index cache. The change uses atomics directly for reference counting and the mutex for the minmax cache. This is safe since the reference count is not modified beside in _mesa_reference_buffer_object where atomics aim to be used. While using the minmax cache, the calling code holds a reference to the buffer object. Thus unreferencing or even referencing the buffer object does not need to be serialized with accessing the minmax cache. The change reduces the time _mesa_reference_buffer_object_ takes by about a factor of two when looking at perf results for some of my favorite use cases. Signed-off-by: Mathias Fröhlich <[email protected]> Reviewed-by: Brian Paul <[email protected]>
-rw-r--r--src/mesa/main/bufferobj.c22
-rw-r--r--src/mesa/main/mtypes.h2
-rw-r--r--src/mesa/vbo/vbo_minmax_index.c8
3 files changed, 11 insertions, 21 deletions
diff --git a/src/mesa/main/bufferobj.c b/src/mesa/main/bufferobj.c
index c1dfdfba823..67f9cd0a902 100644
--- a/src/mesa/main/bufferobj.c
+++ b/src/mesa/main/bufferobj.c
@@ -46,6 +46,7 @@
#include "texstore.h"
#include "transformfeedback.h"
#include "varray.h"
+#include "util/u_atomic.h"
/* Debug flags */
@@ -471,7 +472,7 @@ _mesa_delete_buffer_object(struct gl_context *ctx,
bufObj->RefCount = -1000;
bufObj->Name = ~0;
- simple_mtx_destroy(&bufObj->Mutex);
+ simple_mtx_destroy(&bufObj->MinMaxCacheMutex);
free(bufObj->Label);
free(bufObj);
}
@@ -490,16 +491,9 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
{
if (*ptr) {
/* Unreference the old buffer */
- GLboolean deleteFlag = GL_FALSE;
struct gl_buffer_object *oldObj = *ptr;
- simple_mtx_lock(&oldObj->Mutex);
- assert(oldObj->RefCount > 0);
- oldObj->RefCount--;
- deleteFlag = (oldObj->RefCount == 0);
- simple_mtx_unlock(&oldObj->Mutex);
-
- if (deleteFlag) {
+ if (p_atomic_dec_zero(&oldObj->RefCount)) {
assert(ctx->Driver.DeleteBuffer);
ctx->Driver.DeleteBuffer(ctx, oldObj);
}
@@ -510,12 +504,8 @@ _mesa_reference_buffer_object_(struct gl_context *ctx,
if (bufObj) {
/* reference new buffer */
- simple_mtx_lock(&bufObj->Mutex);
- assert(bufObj->RefCount > 0);
-
- bufObj->RefCount++;
+ p_atomic_inc(&bufObj->RefCount);
*ptr = bufObj;
- simple_mtx_unlock(&bufObj->Mutex);
}
}
@@ -547,11 +537,11 @@ _mesa_initialize_buffer_object(struct gl_context *ctx,
GLuint name)
{
memset(obj, 0, sizeof(struct gl_buffer_object));
- simple_mtx_init(&obj->Mutex, mtx_plain);
obj->RefCount = 1;
obj->Name = name;
obj->Usage = GL_STATIC_DRAW_ARB;
+ simple_mtx_init(&obj->MinMaxCacheMutex, mtx_plain);
if (get_no_minmax_cache())
obj->UsageHistory |= USAGE_DISABLE_MINMAX_CACHE;
}
@@ -870,7 +860,7 @@ _mesa_init_buffer_objects( struct gl_context *ctx )
GLuint i;
memset(&DummyBufferObject, 0, sizeof(DummyBufferObject));
- simple_mtx_init(&DummyBufferObject.Mutex, mtx_plain);
+ simple_mtx_init(&DummyBufferObject.MinMaxCacheMutex, mtx_plain);
DummyBufferObject.RefCount = 1000*1000*1000; /* never delete */
_mesa_reference_buffer_object(ctx, &ctx->Array.ArrayBufferObj,
diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h
index 3a67d43420f..b6d606386e5 100644
--- a/src/mesa/main/mtypes.h
+++ b/src/mesa/main/mtypes.h
@@ -1443,7 +1443,6 @@ typedef enum
*/
struct gl_buffer_object
{
- simple_mtx_t Mutex;
GLint RefCount;
GLuint Name;
GLchar *Label; /**< GL_KHR_debug */
@@ -1464,6 +1463,7 @@ struct gl_buffer_object
struct gl_buffer_mapping Mappings[MAP_COUNT];
/** Memoization of min/max index computations for static index buffers */
+ simple_mtx_t MinMaxCacheMutex;
struct hash_table *MinMaxCache;
unsigned MinMaxCacheHitIndices;
unsigned MinMaxCacheMissIndices;
diff --git a/src/mesa/vbo/vbo_minmax_index.c b/src/mesa/vbo/vbo_minmax_index.c
index c9d20201672..d1298dcdc3a 100644
--- a/src/mesa/vbo/vbo_minmax_index.c
+++ b/src/mesa/vbo/vbo_minmax_index.c
@@ -115,7 +115,7 @@ vbo_get_minmax_cached(struct gl_buffer_object *bufferObj,
if (!vbo_use_minmax_cache(bufferObj))
return GL_FALSE;
- simple_mtx_lock(&bufferObj->Mutex);
+ simple_mtx_lock(&bufferObj->MinMaxCacheMutex);
if (bufferObj->MinMaxCacheDirty) {
/* Disable the cache permanently for this BO if the number of hits
@@ -166,7 +166,7 @@ out_invalidate:
}
out_disable:
- simple_mtx_unlock(&bufferObj->Mutex);
+ simple_mtx_unlock(&bufferObj->MinMaxCacheMutex);
return found;
}
@@ -184,7 +184,7 @@ vbo_minmax_cache_store(struct gl_context *ctx,
if (!vbo_use_minmax_cache(bufferObj))
return;
- simple_mtx_lock(&bufferObj->Mutex);
+ simple_mtx_lock(&bufferObj->MinMaxCacheMutex);
if (!bufferObj->MinMaxCache) {
bufferObj->MinMaxCache =
@@ -223,7 +223,7 @@ vbo_minmax_cache_store(struct gl_context *ctx,
free(entry);
out:
- simple_mtx_unlock(&bufferObj->Mutex);
+ simple_mtx_unlock(&bufferObj->MinMaxCacheMutex);
}