freedreno: re-work fd_batch_reference() locking

Annoyingly we still have to briefly drop the lock to unref resources..
but push the lock down into __fd_batch_destroy() so we can invalidate
the batch and reset resources before dropping the lock.

Signed-off-by: Rob Clark <robdclark@gmail.com>
This commit is contained in:
Rob Clark 2018-07-17 10:14:59 -04:00
parent 4b847b38ae
commit 4cf8f329ed
2 changed files with 26 additions and 23 deletions

View file

@ -223,24 +223,26 @@ fd_batch_reset(struct fd_batch *batch)
void
__fd_batch_destroy(struct fd_batch *batch)
{
struct fd_context *ctx = batch->ctx;
DBG("%p", batch);
util_copy_framebuffer_state(&batch->framebuffer, NULL);
fd_context_assert_locked(batch->ctx);
mtx_lock(&batch->ctx->screen->lock);
fd_bc_invalidate_batch(batch, true);
mtx_unlock(&batch->ctx->screen->lock);
batch_fini(batch);
batch_reset_resources(batch);
batch_reset_resources_locked(batch);
debug_assert(batch->resources->entries == 0);
_mesa_set_destroy(batch->resources, NULL);
batch_flush_reset_dependencies(batch, false);
debug_assert(batch->dependents_mask == 0);
fd_context_unlock(ctx);
util_copy_framebuffer_state(&batch->framebuffer, NULL);
batch_fini(batch);
free(batch);
fd_context_lock(ctx);
}
void

View file

@ -228,16 +228,6 @@ void __fd_batch_destroy(struct fd_batch *batch);
* __fd_batch_destroy() needs to unref resources)
*/
static inline void
fd_batch_reference(struct fd_batch **ptr, struct fd_batch *batch)
{
struct fd_batch *old_batch = *ptr;
if (pipe_reference_described(&(*ptr)->reference, &batch->reference,
(debug_reference_descriptor)__fd_batch_describe))
__fd_batch_destroy(old_batch);
*ptr = batch;
}
/* fwd-decl prototypes to untangle header dependency :-/ */
static inline void fd_context_assert_locked(struct fd_context *ctx);
static inline void fd_context_lock(struct fd_context *ctx);
@ -248,21 +238,32 @@ fd_batch_reference_locked(struct fd_batch **ptr, struct fd_batch *batch)
{
struct fd_batch *old_batch = *ptr;
/* only need lock if a reference is dropped: */
if (old_batch)
fd_context_assert_locked(old_batch->ctx);
else if (batch)
fd_context_assert_locked(batch->ctx);
if (pipe_reference_described(&(*ptr)->reference, &batch->reference,
(debug_reference_descriptor)__fd_batch_describe)) {
struct fd_context *ctx = old_batch->ctx;
fd_context_unlock(ctx);
(debug_reference_descriptor)__fd_batch_describe))
__fd_batch_destroy(old_batch);
fd_context_lock(ctx);
}
*ptr = batch;
}
static inline void
fd_batch_reference(struct fd_batch **ptr, struct fd_batch *batch)
{
struct fd_batch *old_batch = *ptr;
struct fd_context *ctx = old_batch ? old_batch->ctx : NULL;
if (ctx)
fd_context_lock(ctx);
fd_batch_reference_locked(ptr, batch);
if (ctx)
fd_context_unlock(ctx);
}
#include "freedreno_context.h"
static inline void