tc: do a GPU->CPU copy to initialize cpu_storage

If the GPU-side storage has been written to without using cpu_storage,
then we have to initialize the CPU-side storage correctly.

This requires a sync + copy but it's a one time operation so it shouldn't
affect performance much.

I don't think it fixes any existing bug, but the next commit will need
this to behave correctly.

cc: mesa-stable

Reviewed-by: Rob Clark <robdclark@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/18774>
(cherry picked from commit 8af8dc97bc)
This commit is contained in:
Pierre-Eric Pelloux-Prayer
2022-09-23 12:16:59 +02:00
committed by Dylan Baker
parent b4c91f086a
commit 9372399842
2 changed files with 24 additions and 2 deletions

View File

@@ -76,7 +76,7 @@
"description": "tc: do a GPU->CPU copy to initialize cpu_storage",
"nominated": true,
"nomination_type": 0,
"resolution": 0,
"resolution": 1,
"main_sha": null,
"because_sha": null
},

View File

@@ -2183,9 +2183,31 @@ tc_buffer_map(struct pipe_context *_pipe,
/* 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)
if (!tres->cpu_storage) {
tres->cpu_storage = align_malloc(resource->width0, tc->map_buffer_alignment);
if (tres->cpu_storage && tres->valid_buffer_range.end) {
/* The GPU buffer contains valid data. Copy them to the CPU storage. */
struct pipe_box box2;
struct pipe_transfer *transfer2;
unsigned valid_range_len = tres->valid_buffer_range.end - tres->valid_buffer_range.start;
u_box_1d(tres->valid_buffer_range.start, valid_range_len, &box2);
tc_sync_msg(tc, "cpu storage GPU -> CPU copy");
tc_set_driver_thread(tc);
void *ret = pipe->buffer_map(pipe, tres->latest ? tres->latest : resource,
0, PIPE_MAP_READ, &box2, &transfer2);
memcpy(&((uint8_t*)tres->cpu_storage)[tres->valid_buffer_range.start],
ret,
valid_range_len);
pipe->buffer_unmap(pipe, transfer2);
tc_clear_driver_thread(tc);
}
}
if (tres->cpu_storage) {
struct threaded_transfer *ttrans = slab_zalloc(&tc->pool_transfers);
ttrans->b.resource = resource;