[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