gallium/u_threaded: late alloc cpu_storage

Instead of allocating cpu_storage in threaded_resource_init, defer the
allocation to first use (in tc_buffer_map).
This avoids needless memory allocation if tc_buffer_disable_cpu_storage is
called before tc_buffer_map.

map_buffer_alignment is stored and serves as a "can cpu_storage be used" flag.

Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15074>
This commit is contained in:
Pierre-Eric Pelloux-Prayer
2022-02-18 10:28:58 +01:00
parent 7070178dfd
commit cd0ef9b3f4
10 changed files with 39 additions and 30 deletions

View File

@@ -120,7 +120,7 @@ static struct pipe_resource *noop_resource_create(struct pipe_screen *screen,
FREE(nresource);
return NULL;
}
threaded_resource_init(&nresource->b.b, false, 0);
threaded_resource_init(&nresource->b.b, false);
return &nresource->b.b;
}

View File

@@ -671,8 +671,7 @@ tc_is_buffer_busy(struct threaded_context *tc, struct threaded_resource *tbuf,
* allow_cpu_storage should be false for user memory and imported buffers.
*/
void
threaded_resource_init(struct pipe_resource *res, bool allow_cpu_storage,
unsigned map_buffer_alignment)
threaded_resource_init(struct pipe_resource *res, bool allow_cpu_storage)
{
struct threaded_resource *tres = threaded_resource(res);
@@ -692,7 +691,9 @@ threaded_resource_init(struct pipe_resource *res, bool allow_cpu_storage,
/* We need buffer invalidation and buffer busyness tracking for the CPU
* storage, which aren't supported with pipe_vertex_state. */
!(res->bind & PIPE_BIND_VERTEX_STATE))
tres->cpu_storage = align_malloc(res->width0, map_buffer_alignment);
tres->allow_cpu_storage = true;
else
tres->allow_cpu_storage = false;
}
void
@@ -2173,10 +2174,14 @@ tc_buffer_map(struct pipe_context *_pipe,
usage = tc_improve_map_buffer_flags(tc, tres, usage, box->x, box->width);
/* If the CPU storage is enabled, return it directly. */
if (tres->cpu_storage && !(usage & TC_TRANSFER_MAP_UPLOAD_CPU_STORAGE)) {
if (tres->allow_cpu_storage && !(usage & TC_TRANSFER_MAP_UPLOAD_CPU_STORAGE)) {
/* We can't let resource_copy_region disable the CPU storage. */
assert(!(tres->b.flags & PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY));
if (!tres->cpu_storage)
tres->cpu_storage = align_malloc(resource->width0, tc->map_buffer_alignment);
if (tres->cpu_storage) {
struct threaded_transfer *ttrans = slab_alloc(&tc->pool_transfers);
ttrans->b.resource = resource;
ttrans->b.level = 0;
@@ -2191,6 +2196,9 @@ tc_buffer_map(struct pipe_context *_pipe,
*transfer = &ttrans->b;
return (uint8_t*)tres->cpu_storage + box->x;
} else {
tres->allow_cpu_storage = false;
}
}
/* Do a staging transfer within the threaded context. The driver should

View File

@@ -346,6 +346,7 @@ struct threaded_resource {
* pointers. */
bool is_shared;
bool is_user_ptr;
bool allow_cpu_storage;
/* Unique buffer ID. Drivers must set it to non-zero for buffers and it must
* be unique. Textures must set 0. Low bits are used as a hash of the ID.
@@ -521,8 +522,7 @@ struct threaded_context {
struct tc_buffer_list buffer_lists[TC_MAX_BUFFER_LISTS];
};
void threaded_resource_init(struct pipe_resource *res, bool allow_cpu_storage,
unsigned map_buffer_alignment);
void threaded_resource_init(struct pipe_resource *res, bool allow_cpu_storage);
void threaded_resource_deinit(struct pipe_resource *res);
struct pipe_context *threaded_context_unwrap_sync(struct pipe_context *pipe);
void tc_driver_internal_flush_notify(struct threaded_context *tc);
@@ -613,6 +613,7 @@ tc_buffer_disable_cpu_storage(struct pipe_resource *buf)
align_free(tres->cpu_storage);
tres->cpu_storage = NULL;
}
tres->allow_cpu_storage = false;
}
static inline void

View File

@@ -365,7 +365,7 @@ crocus_alloc_resource(struct pipe_screen *pscreen,
res->base.b.screen = pscreen;
res->orig_screen = crocus_pscreen_ref(pscreen);
pipe_reference_init(&res->base.b.reference, 1);
threaded_resource_init(&res->base.b, false, 0);
threaded_resource_init(&res->base.b, false);
if (templ->target == PIPE_BUFFER)
util_range_init(&res->valid_buffer_range);

View File

@@ -297,7 +297,7 @@ convert_planar_resource(struct d3d12_resource *res)
*plane_res = *res;
d3d12_bo_reference(plane_res->bo);
pipe_reference_init(&plane_res->base.b.reference, 1);
threaded_resource_init(&plane_res->base.b, false, 0);
threaded_resource_init(&plane_res->base.b, false);
}
plane_res->base.b.next = next;
@@ -357,7 +357,7 @@ d3d12_resource_create(struct pipe_screen *pscreen,
init_valid_range(res);
threaded_resource_init(&res->base.b,
templ->usage == PIPE_USAGE_DEFAULT &&
templ->target == PIPE_BUFFER, 64);
templ->target == PIPE_BUFFER);
memset(&res->bind_counts, 0, sizeof(d3d12_resource::bind_counts));
@@ -556,7 +556,7 @@ d3d12_resource_from_handle(struct pipe_screen *pscreen,
}
init_valid_range(res);
threaded_resource_init(&res->base.b, false, 0);
threaded_resource_init(&res->base.b, false);
convert_planar_resource(res);
return &res->base.b;

View File

@@ -1109,7 +1109,7 @@ alloc_resource_struct(struct pipe_screen *pscreen,
pipe_reference_init(&rsc->track->reference, 1);
threaded_resource_init(prsc, false, 0);
threaded_resource_init(prsc, false);
if (tmpl->target == PIPE_BUFFER)
rsc->b.buffer_id_unique = util_idalloc_mt_alloc(&screen->buffer_ids);

View File

@@ -479,7 +479,7 @@ iris_alloc_resource(struct pipe_screen *pscreen,
res->base.b.screen = pscreen;
res->orig_screen = iris_pscreen_ref(pscreen);
pipe_reference_init(&res->base.b.reference, 1);
threaded_resource_init(&res->base.b, false, 0);
threaded_resource_init(&res->base.b, false);
if (templ->target == PIPE_BUFFER)
util_range_init(&res->valid_buffer_range);

View File

@@ -584,7 +584,7 @@ r600_alloc_buffer_struct(struct pipe_screen *screen,
pipe_reference_init(&rbuffer->b.b.reference, 1);
rbuffer->b.b.screen = screen;
threaded_resource_init(&rbuffer->b.b, false, 0);
threaded_resource_init(&rbuffer->b.b, false);
rbuffer->buf = NULL;
rbuffer->bind_history = 0;

View File

@@ -571,7 +571,7 @@ static struct si_resource *si_alloc_buffer_struct(struct pipe_screen *screen,
pipe_reference_init(&buf->b.b.reference, 1);
buf->b.b.screen = screen;
threaded_resource_init(&buf->b.b, allow_cpu_storage, SI_MAP_BUFFER_ALIGNMENT);
threaded_resource_init(&buf->b.b, allow_cpu_storage);
buf->buf = NULL;
buf->bind_history = 0;

View File

@@ -904,7 +904,7 @@ resource_create(struct pipe_screen *pscreen,
res->base.b = *templ;
threaded_resource_init(&res->base.b, false, 0);
threaded_resource_init(&res->base.b, false);
pipe_reference_init(&res->base.b.reference, 1);
res->base.b.screen = pscreen;