[Mesa-dev] [PATCH 1/3] gallium/u_threaded: clean up tc_improve_map_buffer_flags and prevent reentry

Marek Olšák maraeo at gmail.com
Sat Nov 4 13:03:20 UTC 2017


From: Marek Olšák <marek.olsak at amd.com>

---
 src/gallium/auxiliary/util/u_threaded_context.c | 19 ++++++++++++-------
 1 file changed, 12 insertions(+), 7 deletions(-)

diff --git a/src/gallium/auxiliary/util/u_threaded_context.c b/src/gallium/auxiliary/util/u_threaded_context.c
index 7e28b87..0f23258 100644
--- a/src/gallium/auxiliary/util/u_threaded_context.c
+++ b/src/gallium/auxiliary/util/u_threaded_context.c
@@ -1269,45 +1269,53 @@ tc_invalidate_buffer(struct threaded_context *tc,
    tc_set_resource_reference(&p->dst, &tbuf->b);
    tc_set_resource_reference(&p->src, new_buf);
    return true;
 }
 
 static unsigned
 tc_improve_map_buffer_flags(struct threaded_context *tc,
                             struct threaded_resource *tres, unsigned usage,
                             unsigned offset, unsigned size)
 {
+   /* Never invalidate inside the driver and never infer "unsynchronized". */
+   unsigned tc_flags = TC_TRANSFER_MAP_NO_INVALIDATE |
+                       TC_TRANSFER_MAP_NO_INFER_UNSYNCHRONIZED;
+
+   /* Prevent a reentry. */
+   if (usage & tc_flags)
+      return usage;
+
    /* Sparse buffers can't be mapped directly and can't be reallocated
     * (fully invalidated). That may just be a radeonsi limitation, but
     * the threaded context must obey it with radeonsi.
     */
    if (tres->b.flags & PIPE_RESOURCE_FLAG_SPARSE) {
       /* We can use DISCARD_RANGE instead of full discard. This is the only
        * fast path for sparse buffers that doesn't need thread synchronization.
        */
       if (usage & PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE)
          usage |= PIPE_TRANSFER_DISCARD_RANGE;
 
       /* Allow DISCARD_WHOLE_RESOURCE and infering UNSYNCHRONIZED in drivers.
        * The threaded context doesn't do unsychronized mappings and invalida-
        * tions of sparse buffers, therefore a correct driver behavior won't
        * result in an incorrect behavior with the threaded context.
        */
       return usage;
    }
 
+   usage |= tc_flags;
+
    /* Handle CPU reads trivially. */
    if (usage & PIPE_TRANSFER_READ) {
       /* Drivers aren't allowed to do buffer invalidations. */
-      return (usage & ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE) |
-             TC_TRANSFER_MAP_NO_INVALIDATE |
-             TC_TRANSFER_MAP_NO_INFER_UNSYNCHRONIZED;
+      return usage & ~PIPE_TRANSFER_DISCARD_WHOLE_RESOURCE;
    }
 
    /* See if the buffer range being mapped has never been initialized,
     * in which case it can be mapped unsynchronized. */
    if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED) &&
        !tres->is_shared &&
        !util_ranges_intersect(&tres->valid_buffer_range, offset, offset + size))
       usage |= PIPE_TRANSFER_UNSYNCHRONIZED;
 
    if (!(usage & PIPE_TRANSFER_UNSYNCHRONIZED)) {
@@ -1335,24 +1343,21 @@ tc_improve_map_buffer_flags(struct threaded_context *tc,
                 PIPE_TRANSFER_PERSISTENT) ||
        tres->is_user_ptr)
       usage &= ~PIPE_TRANSFER_DISCARD_RANGE;
 
    /* Unsychronized buffer mappings don't have to synchronize the thread. */
    if (usage & PIPE_TRANSFER_UNSYNCHRONIZED) {
       usage &= ~PIPE_TRANSFER_DISCARD_RANGE;
       usage |= TC_TRANSFER_MAP_THREADED_UNSYNC; /* notify the driver */
    }
 
-   /* Never invalidate inside the driver and never infer "unsynchronized". */
-   return usage |
-          TC_TRANSFER_MAP_NO_INVALIDATE |
-          TC_TRANSFER_MAP_NO_INFER_UNSYNCHRONIZED;
+   return usage;
 }
 
 static void *
 tc_transfer_map(struct pipe_context *_pipe,
                 struct pipe_resource *resource, unsigned level,
                 unsigned usage, const struct pipe_box *box,
                 struct pipe_transfer **transfer)
 {
    struct threaded_context *tc = threaded_context(_pipe);
    struct threaded_resource *tres = threaded_resource(resource);
-- 
2.7.4



More information about the mesa-dev mailing list