From ccc0d8f9b40db622ee30e1bd1b07d031b2c8b0e0 Mon Sep 17 00:00:00 2001 From: "Steinar H. Gunderson" Date: Thu, 5 May 2016 12:51:59 +0200 Subject: [PATCH] Remove the Mesa patch; replace with a recommendation to run 11.2.x. This is now upstream, so it's probably just as easy for people to get 11.2.x as to patch and build a Mesa 11.0.x version. --- README | 13 +- .../mesa-fix-locking-of-glsync-objects.diff | 321 ------------------ 2 files changed, 9 insertions(+), 325 deletions(-) delete mode 100644 patches/mesa-fix-locking-of-glsync-objects.diff diff --git a/README b/README index 5e6c2e2..513e6de 100644 --- a/README +++ b/README @@ -52,10 +52,10 @@ Nageru is in beta stage. It currently needs: - ffmpeg for muxing, and for encoding audio. - Working OpenGL; Movit works with almost any modern OpenGL implementation. - Nageru has been tested with Intel on Mesa 10.x and 11.x (you probably want - 11.x), and with NVIDIA's proprietary drivers. AMD's proprietary drivers - (fglrx) are known not to work due to driver bugs; I am in contact with - AMD to try to get this resolved. + Nageru has been tested with Intel on Mesa (you want 11.2 or newer, due + to critical stability bugfixes), and with NVIDIA's proprietary drivers. + AMD's proprietary drivers (fglrx) are known not to work due to driver bugs; + I am in contact with AMD to try to get this resolved. - libzita-resampler, for resampling sound sources so that they are in sync between sources, and also for oversampling for the peak meter. @@ -72,6 +72,11 @@ with: libavcodec-dev libavformat-dev libswscale-dev libavresample-dev \ libmovit-dev libegl1-mesa-dev libasound2-dev libx264-dev +Exceptions as of May 2016: + + - Mesa in stretch is too old; you need Mesa from experimental to get + 11.2.x. + The patches/ directory contains some patches for upstream software that help Nageru performance and/or stability. They are all meant for upstream, but diff --git a/patches/mesa-fix-locking-of-glsync-objects.diff b/patches/mesa-fix-locking-of-glsync-objects.diff deleted file mode 100644 index a1c880a..0000000 --- a/patches/mesa-fix-locking-of-glsync-objects.diff +++ /dev/null @@ -1,321 +0,0 @@ -From 6e3d1880fa78a3a965cb7eb51ee12b1f785f84bb Mon Sep 17 00:00:00 2001 -From: "Steinar H. Gunderson" -Date: Tue, 1 Dec 2015 22:05:11 +0100 -Subject: [PATCH] Fix locking of GLsync objects. - -GLsync objects had a race condition when used from multiple threads -(which is the main point of the extension, really); it could be -validated as a sync object at the beginning of the function, and then -deleted by another thread before use, causing crashes. Fix this by -changing all casts from GLsync to struct gl_sync_object to a new -function _mesa_get_sync() that validates and increases the refcount. - -In a similar vein, validation itself uses _mesa_set_search(), which -requires synchronization -- it was called without a mutex held, causing -spurious error returns and other issues. Since _mesa_get_sync() now -takes the shared context mutex, this problem is also resolved. - -Signed-off-by: Steinar H. Gunderson ---- - src/mesa/main/objectlabel.c | 11 ++++-- - src/mesa/main/shared.c | 2 +- - src/mesa/main/syncobj.c | 89 ++++++++++++++++++++++++++------------------- - src/mesa/main/syncobj.h | 11 ++---- - 4 files changed, 64 insertions(+), 49 deletions(-) - -diff --git a/src/mesa/main/objectlabel.c b/src/mesa/main/objectlabel.c -index 41f370c..b083c43 100644 ---- a/src/mesa/main/objectlabel.c -+++ b/src/mesa/main/objectlabel.c -@@ -288,7 +288,7 @@ void GLAPIENTRY - _mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) - { - GET_CURRENT_CONTEXT(ctx); -- struct gl_sync_object *const syncObj = (struct gl_sync_object *) ptr; -+ struct gl_sync_object *syncObj = _mesa_get_sync(ctx, sync, true); - const char *callerstr; - char **labelPtr; - -@@ -297,7 +297,7 @@ _mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) - else - callerstr = "glObjectPtrLabelKHR"; - -- if (!_mesa_validate_sync(ctx, syncObj)) { -+ if (!syncObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s (not a valid sync object)", - callerstr); - return; -@@ -306,6 +306,7 @@ _mesa_ObjectPtrLabel(const void *ptr, GLsizei length, const GLchar *label) - labelPtr = &syncObj->Label; - - set_label(ctx, labelPtr, label, length, callerstr); -+ _mesa_unref_sync_object(ctx, syncObj, 1); - } - - void GLAPIENTRY -@@ -313,7 +314,7 @@ _mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, - GLchar *label) - { - GET_CURRENT_CONTEXT(ctx); -- struct gl_sync_object *const syncObj = (struct gl_sync_object *) ptr; -+ struct gl_sync_object *syncObj; - const char *callerstr; - char **labelPtr; - -@@ -328,7 +329,8 @@ _mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, - return; - } - -- if (!_mesa_validate_sync(ctx, syncObj)) { -+ syncObj = _mesa_get_sync(ctx, sync, true); -+ if (!syncObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "%s (not a valid sync object)", - callerstr); - return; -@@ -337,4 +339,5 @@ _mesa_GetObjectPtrLabel(const void *ptr, GLsizei bufSize, GLsizei *length, - labelPtr = &syncObj->Label; - - copy_label(*labelPtr, label, length, bufSize); -+ _mesa_unref_sync_object(ctx, syncObj, 1); - } -diff --git a/src/mesa/main/shared.c b/src/mesa/main/shared.c -index c37b31d..b9f7bb6 100644 ---- a/src/mesa/main/shared.c -+++ b/src/mesa/main/shared.c -@@ -338,7 +338,7 @@ free_shared_state(struct gl_context *ctx, struct gl_shared_state *shared) - struct set_entry *entry; - - set_foreach(shared->SyncObjects, entry) { -- _mesa_unref_sync_object(ctx, (struct gl_sync_object *) entry->key); -+ _mesa_unref_sync_object(ctx, (struct gl_sync_object *) entry->key, 1); - } - } - _mesa_set_destroy(shared->SyncObjects, NULL); -diff --git a/src/mesa/main/syncobj.c b/src/mesa/main/syncobj.c -index c1b2d3b..d1c6c06 100644 ---- a/src/mesa/main/syncobj.c -+++ b/src/mesa/main/syncobj.c -@@ -167,34 +167,42 @@ _mesa_free_sync_data(struct gl_context *ctx) - * - not in sync objects hash table - * - type is GL_SYNC_FENCE - * - not marked as deleted -+ * -+ * Returns the internal gl_sync_object pointer if the sync object is valid -+ * or NULL if it isn't. -+ * -+ * If "incRefCount" is true, the reference count is incremented, which is -+ * normally what you want; otherwise, a glDeleteSync from another thread -+ * could delete the sync object while you are still working on it. - */ --bool --_mesa_validate_sync(struct gl_context *ctx, -- const struct gl_sync_object *syncObj) -+struct gl_sync_object * -+_mesa_get_sync(struct gl_context *ctx, GLsync sync, bool incRefCount) - { -- return (syncObj != NULL) -+ struct gl_sync_object *syncObj = (struct gl_sync_object *) sync; -+ mtx_lock(&ctx->Shared->Mutex); -+ if (syncObj != NULL - && _mesa_set_search(ctx->Shared->SyncObjects, syncObj) != NULL - && (syncObj->Type == GL_SYNC_FENCE) -- && !syncObj->DeletePending; --} -- -- --void --_mesa_ref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj) --{ -- mtx_lock(&ctx->Shared->Mutex); -- syncObj->RefCount++; -+ && !syncObj->DeletePending) { -+ if (incRefCount) { -+ syncObj->RefCount++; -+ } -+ } else { -+ syncObj = NULL; -+ } - mtx_unlock(&ctx->Shared->Mutex); -+ return syncObj; - } - - - void --_mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj) -+_mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj, -+ int amount) - { - struct set_entry *entry; - - mtx_lock(&ctx->Shared->Mutex); -- syncObj->RefCount--; -+ syncObj->RefCount -= amount; - if (syncObj->RefCount == 0) { - entry = _mesa_set_search(ctx->Shared->SyncObjects, syncObj); - assert (entry != NULL); -@@ -212,10 +220,9 @@ GLboolean GLAPIENTRY - _mesa_IsSync(GLsync sync) - { - GET_CURRENT_CONTEXT(ctx); -- struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_FALSE); - -- return _mesa_validate_sync(ctx, syncObj) ? GL_TRUE : GL_FALSE; -+ return _mesa_get_sync(ctx, sync, false) ? GL_TRUE : GL_FALSE; - } - - -@@ -223,7 +230,7 @@ void GLAPIENTRY - _mesa_DeleteSync(GLsync sync) - { - GET_CURRENT_CONTEXT(ctx); -- struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; -+ struct gl_sync_object *syncObj; - - /* From the GL_ARB_sync spec: - * -@@ -235,16 +242,19 @@ _mesa_DeleteSync(GLsync sync) - return; - } - -- if (!_mesa_validate_sync(ctx, syncObj)) { -+ syncObj = _mesa_get_sync(ctx, sync, true); -+ if (!syncObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glDeleteSync (not a valid sync object)"); - return; - } - - /* If there are no client-waits or server-waits pending on this sync, delete -- * the underlying object. -+ * the underlying object. Note that we double-unref the object, as _mesa_get_sync -+ * above took an extra refcount to make sure the pointer is valid for us to -+ * manipulate. - */ - syncObj->DeletePending = GL_TRUE; -- _mesa_unref_sync_object(ctx, syncObj); -+ _mesa_unref_sync_object(ctx, syncObj, 2); - } - - -@@ -299,21 +309,20 @@ GLenum GLAPIENTRY - _mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) - { - GET_CURRENT_CONTEXT(ctx); -- struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; -+ struct gl_sync_object *syncObj; - GLenum ret; - ASSERT_OUTSIDE_BEGIN_END_WITH_RETVAL(ctx, GL_WAIT_FAILED); - -- if (!_mesa_validate_sync(ctx, syncObj)) { -- _mesa_error(ctx, GL_INVALID_VALUE, "glClientWaitSync (not a valid sync object)"); -- return GL_WAIT_FAILED; -- } -- - if ((flags & ~GL_SYNC_FLUSH_COMMANDS_BIT) != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glClientWaitSync(flags=0x%x)", flags); - return GL_WAIT_FAILED; - } - -- _mesa_ref_sync_object(ctx, syncObj); -+ syncObj = _mesa_get_sync(ctx, sync, true); -+ if (!syncObj) { -+ _mesa_error(ctx, GL_INVALID_VALUE, "glClientWaitSync (not a valid sync object)"); -+ return GL_WAIT_FAILED; -+ } - - /* From the GL_ARB_sync spec: - * -@@ -335,7 +344,7 @@ _mesa_ClientWaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) - } - } - -- _mesa_unref_sync_object(ctx, syncObj); -+ _mesa_unref_sync_object(ctx, syncObj, 1); - return ret; - } - -@@ -344,12 +353,7 @@ void GLAPIENTRY - _mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) - { - GET_CURRENT_CONTEXT(ctx); -- struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; -- -- if (!_mesa_validate_sync(ctx, syncObj)) { -- _mesa_error(ctx, GL_INVALID_VALUE, "glWaitSync (not a valid sync object)"); -- return; -- } -+ struct gl_sync_object *syncObj; - - if (flags != 0) { - _mesa_error(ctx, GL_INVALID_VALUE, "glWaitSync(flags=0x%x)", flags); -@@ -362,7 +366,14 @@ _mesa_WaitSync(GLsync sync, GLbitfield flags, GLuint64 timeout) - return; - } - -+ syncObj = _mesa_get_sync(ctx, sync, true); -+ if (!syncObj) { -+ _mesa_error(ctx, GL_INVALID_VALUE, "glWaitSync (not a valid sync object)"); -+ return; -+ } -+ - ctx->Driver.ServerWaitSync(ctx, syncObj, flags, timeout); -+ _mesa_unref_sync_object(ctx, syncObj, 1); - } - - -@@ -371,11 +382,12 @@ _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, - GLint *values) - { - GET_CURRENT_CONTEXT(ctx); -- struct gl_sync_object *const syncObj = (struct gl_sync_object *) sync; -+ struct gl_sync_object *syncObj; - GLsizei size = 0; - GLint v[1]; - -- if (!_mesa_validate_sync(ctx, syncObj)) { -+ syncObj = _mesa_get_sync(ctx, sync, true); -+ if (!syncObj) { - _mesa_error(ctx, GL_INVALID_VALUE, "glGetSynciv (not a valid sync object)"); - return; - } -@@ -409,6 +421,7 @@ _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, - - default: - _mesa_error(ctx, GL_INVALID_ENUM, "glGetSynciv(pname=0x%x)\n", pname); -+ _mesa_unref_sync_object(ctx, syncObj, 1); - return; - } - -@@ -421,4 +434,6 @@ _mesa_GetSynciv(GLsync sync, GLenum pname, GLsizei bufSize, GLsizei *length, - if (length != NULL) { - *length = size; - } -+ -+ _mesa_unref_sync_object(ctx, syncObj, 1); - } -diff --git a/src/mesa/main/syncobj.h b/src/mesa/main/syncobj.h -index 5d510e8..e8dbded 100644 ---- a/src/mesa/main/syncobj.h -+++ b/src/mesa/main/syncobj.h -@@ -47,15 +47,12 @@ _mesa_init_sync(struct gl_context *); - extern void - _mesa_free_sync_data(struct gl_context *); - --extern void --_mesa_ref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj); -+struct gl_sync_object * -+_mesa_get_sync(struct gl_context *ctx, GLsync sync, bool incRefCount); - - extern void --_mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj); -- --extern bool --_mesa_validate_sync(struct gl_context *ctx, -- const struct gl_sync_object *syncObj); -+_mesa_unref_sync_object(struct gl_context *ctx, struct gl_sync_object *syncObj, -+ int amount); - - extern GLboolean GLAPIENTRY - _mesa_IsSync(GLsync sync); --- -2.6.2 -- 2.39.2