[Mesa-dev] [PATCH 4/4] mesa: don't lock hashtables that are not shared across contexts
Timothy Arceri
tarceri at itsqueeze.com
Fri Apr 21 05:20:55 UTC 2017
>From Chapter 5 'Shared Objects and Multiple Contexts' of
the OpenGL 4.5 spec:
"Objects which contain references to other objects include
framebuffer, program pipeline, query, transform feedback,
and vertex array objects. Such objects are called container
objects and are not shared"
For we leave locking in place for framebuffer objects because
the EXT fbo extension allowed sharing.
We could maybe just replace the hash with an ordinary hash table
but for now this should remove most of the unnecessary locking.
---
src/mesa/main/arrayobj.c | 8 ++++----
src/mesa/main/pipelineobj.c | 6 +++---
src/mesa/main/queryobj.c | 8 ++++----
src/mesa/main/queryobj.h | 2 +-
src/mesa/main/transformfeedback.c | 7 ++++---
5 files changed, 16 insertions(+), 15 deletions(-)
diff --git a/src/mesa/main/arrayobj.c b/src/mesa/main/arrayobj.c
index 24555d9..b901a89 100644
--- a/src/mesa/main/arrayobj.c
+++ b/src/mesa/main/arrayobj.c
@@ -64,21 +64,21 @@
* non-existent.
*/
struct gl_vertex_array_object *
_mesa_lookup_vao(struct gl_context *ctx, GLuint id)
{
if (id == 0)
return NULL;
else
return (struct gl_vertex_array_object *)
- _mesa_HashLookup(ctx->Array.Objects, id);
+ _mesa_HashLookupLocked(ctx->Array.Objects, id);
}
/**
* Looks up the array object for the given ID.
*
* Unlike _mesa_lookup_vao, this function generates a GL_INVALID_OPERATION
* error if the array object does not exist. It also returns the default
* array object when ctx is a compatibility profile context and id is zero.
*/
@@ -101,21 +101,21 @@ _mesa_lookup_vao_err(struct gl_context *ctx, GLuint id, const char *caller)
return ctx->Array.DefaultVAO;
} else {
struct gl_vertex_array_object *vao;
if (ctx->Array.LastLookedUpVAO &&
ctx->Array.LastLookedUpVAO->Name == id) {
vao = ctx->Array.LastLookedUpVAO;
} else {
vao = (struct gl_vertex_array_object *)
- _mesa_HashLookup(ctx->Array.Objects, id);
+ _mesa_HashLookupLocked(ctx->Array.Objects, id);
/* The ARB_direct_state_access specification says:
*
* "An INVALID_OPERATION error is generated if <vaobj> is not
* [compatibility profile: zero or] the name of an existing
* vertex array object."
*/
if (!vao || !vao->EverBound) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"%s(non-existent vaobj=%u)", caller, id);
@@ -299,35 +299,35 @@ _mesa_initialize_vao(struct gl_context *ctx,
/**
* Add the given array object to the array object pool.
*/
static void
save_array_object(struct gl_context *ctx, struct gl_vertex_array_object *vao)
{
if (vao->Name > 0) {
/* insert into hash table */
- _mesa_HashInsert(ctx->Array.Objects, vao->Name, vao);
+ _mesa_HashInsertLocked(ctx->Array.Objects, vao->Name, vao);
}
}
/**
* Remove the given array object from the array object pool.
* Do not deallocate the array object though.
*/
static void
remove_array_object(struct gl_context *ctx, struct gl_vertex_array_object *vao)
{
if (vao->Name > 0) {
/* remove from hash table */
- _mesa_HashRemove(ctx->Array.Objects, vao->Name);
+ _mesa_HashRemoveLocked(ctx->Array.Objects, vao->Name);
}
}
/**
* Updates the derived gl_vertex_arrays when a gl_vertex_attrib_array
* or a gl_vertex_buffer_binding has changed.
*/
void
_mesa_update_vao_client_arrays(struct gl_context *ctx,
diff --git a/src/mesa/main/pipelineobj.c b/src/mesa/main/pipelineobj.c
index 9a852be..dbca3c3 100644
--- a/src/mesa/main/pipelineobj.c
+++ b/src/mesa/main/pipelineobj.c
@@ -137,43 +137,43 @@ _mesa_free_pipeline_data(struct gl_context *ctx)
* a non-existent ID. The spec defines ID 0 as being technically
* non-existent.
*/
struct gl_pipeline_object *
_mesa_lookup_pipeline_object(struct gl_context *ctx, GLuint id)
{
if (id == 0)
return NULL;
else
return (struct gl_pipeline_object *)
- _mesa_HashLookup(ctx->Pipeline.Objects, id);
+ _mesa_HashLookupLocked(ctx->Pipeline.Objects, id);
}
/**
* Add the given pipeline object to the pipeline object pool.
*/
static void
save_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj)
{
if (obj->Name > 0) {
- _mesa_HashInsert(ctx->Pipeline.Objects, obj->Name, obj);
+ _mesa_HashInsertLocked(ctx->Pipeline.Objects, obj->Name, obj);
}
}
/**
* Remove the given pipeline object from the pipeline object pool.
* Do not deallocate the pipeline object though.
*/
static void
remove_pipeline_object(struct gl_context *ctx, struct gl_pipeline_object *obj)
{
if (obj->Name > 0) {
- _mesa_HashRemove(ctx->Pipeline.Objects, obj->Name);
+ _mesa_HashRemoveLocked(ctx->Pipeline.Objects, obj->Name);
}
}
/**
* Set ptr to obj w/ reference counting.
* Note: this should only be called from the _mesa_reference_pipeline_object()
* inline function.
*/
void
_mesa_reference_pipeline_object_(struct gl_context *ctx,
diff --git a/src/mesa/main/queryobj.c b/src/mesa/main/queryobj.c
index e4edb51..46535d7 100644
--- a/src/mesa/main/queryobj.c
+++ b/src/mesa/main/queryobj.c
@@ -271,21 +271,21 @@ create_queries(struct gl_context *ctx, GLenum target, GLsizei n, GLuint *ids,
= ctx->Driver.NewQueryObject(ctx, first + i);
if (!q) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
return;
} else if (dsa) {
/* Do the equivalent of binding the buffer with a target */
q->Target = target;
q->EverBound = GL_TRUE;
}
ids[i] = first + i;
- _mesa_HashInsert(ctx->Query.QueryObjects, first + i, q);
+ _mesa_HashInsertLocked(ctx->Query.QueryObjects, first + i, q);
}
}
}
void GLAPIENTRY
_mesa_GenQueries(GLsizei n, GLuint *ids)
{
GET_CURRENT_CONTEXT(ctx);
create_queries(ctx, 0, n, ids, false);
}
@@ -338,21 +338,21 @@ _mesa_DeleteQueries(GLsizei n, const GLuint *ids)
if (q->Active) {
struct gl_query_object **bindpt;
bindpt = get_query_binding_point(ctx, q->Target, q->Stream);
assert(bindpt); /* Should be non-null for active q. */
if (bindpt) {
*bindpt = NULL;
}
q->Active = GL_FALSE;
ctx->Driver.EndQuery(ctx, q);
}
- _mesa_HashRemove(ctx->Query.QueryObjects, ids[i]);
+ _mesa_HashRemoveLocked(ctx->Query.QueryObjects, ids[i]);
ctx->Driver.DeleteQuery(ctx, q);
}
}
}
}
GLboolean GLAPIENTRY
_mesa_IsQuery(GLuint id)
{
@@ -441,21 +441,21 @@ _mesa_BeginQueryIndexed(GLenum target, GLuint index, GLuint id)
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBeginQuery{Indexed}(non-gen name)");
return;
} else {
/* create new object */
q = ctx->Driver.NewQueryObject(ctx, id);
if (!q) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glBeginQuery{Indexed}");
return;
}
- _mesa_HashInsert(ctx->Query.QueryObjects, id, q);
+ _mesa_HashInsertLocked(ctx->Query.QueryObjects, id, q);
}
}
else {
/* pre-existing object */
if (q->Active) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glBeginQuery{Indexed}(query already active)");
return;
}
@@ -583,21 +583,21 @@ _mesa_QueryCounter(GLuint id, GLenum target)
q = _mesa_lookup_query_object(ctx, id);
if (!q) {
/* XXX the Core profile should throw INVALID_OPERATION here */
/* create new object */
q = ctx->Driver.NewQueryObject(ctx, id);
if (!q) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glQueryCounter");
return;
}
- _mesa_HashInsert(ctx->Query.QueryObjects, id, q);
+ _mesa_HashInsertLocked(ctx->Query.QueryObjects, id, q);
}
else {
if (q->Target && q->Target != GL_TIMESTAMP) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glQueryCounter(id has an invalid target)");
return;
}
}
if (q->Active) {
diff --git a/src/mesa/main/queryobj.h b/src/mesa/main/queryobj.h
index d1036fc..24a8257 100644
--- a/src/mesa/main/queryobj.h
+++ b/src/mesa/main/queryobj.h
@@ -28,21 +28,21 @@
#include "main/mtypes.h"
#include "main/hash.h"
static inline struct gl_query_object *
_mesa_lookup_query_object(struct gl_context *ctx, GLuint id)
{
return (struct gl_query_object *)
- _mesa_HashLookup(ctx->Query.QueryObjects, id);
+ _mesa_HashLookupLocked(ctx->Query.QueryObjects, id);
}
extern void
_mesa_init_query_object_functions(struct dd_function_table *driver);
extern void
_mesa_init_queryobj(struct gl_context *ctx);
extern void
diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c
index 131014f..3c72674 100644
--- a/src/mesa/main/transformfeedback.c
+++ b/src/mesa/main/transformfeedback.c
@@ -958,21 +958,21 @@ _mesa_lookup_transform_feedback_object(struct gl_context *ctx, GLuint name)
{
/* OpenGL 4.5 core profile, 13.2 pdf page 444: "xfb must be zero, indicating
* the default transform feedback object, or the name of an existing
* transform feedback object."
*/
if (name == 0) {
return ctx->TransformFeedback.DefaultObject;
}
else
return (struct gl_transform_feedback_object *)
- _mesa_HashLookup(ctx->TransformFeedback.Objects, name);
+ _mesa_HashLookupLocked(ctx->TransformFeedback.Objects, name);
}
static void
create_transform_feedbacks(struct gl_context *ctx, GLsizei n, GLuint *ids,
bool dsa)
{
GLuint first;
const char* func;
if (dsa)
@@ -993,21 +993,22 @@ create_transform_feedbacks(struct gl_context *ctx, GLsizei n, GLuint *ids,
if (first) {
GLsizei i;
for (i = 0; i < n; i++) {
struct gl_transform_feedback_object *obj
= ctx->Driver.NewTransformFeedback(ctx, first + i);
if (!obj) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
return;
}
ids[i] = first + i;
- _mesa_HashInsert(ctx->TransformFeedback.Objects, first + i, obj);
+ _mesa_HashInsertLocked(ctx->TransformFeedback.Objects, first + i,
+ obj);
if (dsa) {
/* this is normally done at bind time in the non-dsa case */
obj->EverBound = GL_TRUE;
}
}
}
else {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "%s", func);
}
}
@@ -1125,21 +1126,21 @@ _mesa_DeleteTransformFeedbacks(GLsizei n, const GLuint *names)
if (names[i] > 0) {
struct gl_transform_feedback_object *obj
= _mesa_lookup_transform_feedback_object(ctx, names[i]);
if (obj) {
if (obj->Active) {
_mesa_error(ctx, GL_INVALID_OPERATION,
"glDeleteTransformFeedbacks(object %u is active)",
names[i]);
return;
}
- _mesa_HashRemove(ctx->TransformFeedback.Objects, names[i]);
+ _mesa_HashRemoveLocked(ctx->TransformFeedback.Objects, names[i]);
/* unref, but object may not be deleted until later */
if (obj == ctx->TransformFeedback.CurrentObject) {
reference_transform_feedback_object(
&ctx->TransformFeedback.CurrentObject,
ctx->TransformFeedback.DefaultObject);
}
reference_transform_feedback_object(&obj, NULL);
}
}
}
--
2.9.3
More information about the mesa-dev
mailing list