From b3d3239fc1194e77f21364bdc2b0c51d7e5318af Mon Sep 17 00:00:00 2001 From: Lucas Fryzek Date: Wed, 28 Feb 2024 13:02:42 -0500 Subject: [PATCH] llvmpipe: make it possible to import and bind unbacked resources this reworks the existing import to just set some metadata and then apply the memory region during bind with the assumption that something else is doing the import Also adjust ci failures for llvmpipe to represent multiplanar surfaces as not supported Co-authored-by: Mike Blumenkrantz Reviewed-By: Mike Blumenkrantz Part-of: --- .../drivers/llvmpipe/ci/llvmpipe-fails.txt | 4 + src/gallium/drivers/llvmpipe/lp_texture.c | 107 ++++++++++++------ 2 files changed, 76 insertions(+), 35 deletions(-) diff --git a/src/gallium/drivers/llvmpipe/ci/llvmpipe-fails.txt b/src/gallium/drivers/llvmpipe/ci/llvmpipe-fails.txt index 5824f5e6934c4..61cb03543b521 100644 --- a/src/gallium/drivers/llvmpipe/ci/llvmpipe-fails.txt +++ b/src/gallium/drivers/llvmpipe/ci/llvmpipe-fails.txt @@ -93,6 +93,10 @@ spec@ext_framebuffer_multisample@clip-and-scissor-blit 4 upsample,Fail spec@ext_framebuffer_multisample@interpolation 2 centroid-edges,Fail spec@ext_framebuffer_multisample@interpolation 4 centroid-edges,Fail +# YUV multiplanar formats are not supported +spec@ext_image_dma_buf_import@ext_image_dma_buf_import-sample_nv12,Fail +spec@ext_image_dma_buf_import@ext_image_dma_buf_import-sample_yuv420,Fail + spec@khr_texture_compression_astc@miptree-gl srgb-fp,Fail spec@khr_texture_compression_astc@miptree-gl srgb-fp@sRGB decode full precision,Fail spec@khr_texture_compression_astc@miptree-gles srgb-fp,Fail diff --git a/src/gallium/drivers/llvmpipe/lp_texture.c b/src/gallium/drivers/llvmpipe/lp_texture.c index 143ac2210cdbc..e10d73306a6dd 100644 --- a/src/gallium/drivers/llvmpipe/lp_texture.c +++ b/src/gallium/drivers/llvmpipe/lp_texture.c @@ -627,6 +627,10 @@ llvmpipe_resource_from_handle(struct pipe_screen *_screen, /* no miplevels */ assert(template->last_level == 0); + /* Multiplanar surfaces are not supported */ + if (whandle->plane > 0) + return NULL; + lpr = CALLOC_STRUCT(llvmpipe_resource); if (!lpr) { goto no_lpr; @@ -647,42 +651,55 @@ llvmpipe_resource_from_handle(struct pipe_screen *_screen, assert(lpr->base.height0 == height); #endif - void *data; -#ifdef HAVE_LIBDRM - struct llvmpipe_memory_fd_alloc *alloc; - uint64_t size; - if(_screen->import_memory_fd(_screen, whandle->handle, (struct pipe_memory_allocation**)&alloc, &size, true)) { - data = alloc->data; - lpr->dt = winsys->displaytarget_create_mapped(winsys, template->bind, - template->format, template->width0, template->height0, - whandle->stride, data); - if (!lpr->dt) - goto no_dt; - lpr->dmabuf_alloc = alloc; - } else -#endif - { - lpr->dt = winsys->displaytarget_from_handle(winsys, - template, - whandle, - &lpr->row_stride[0]); - if (!lpr->dt) - goto no_dt; - data = winsys->displaytarget_map(winsys, lpr->dt, PIPE_MAP_READ_WRITE); - } - if (!data) { - winsys->displaytarget_destroy(winsys, lpr->dt); - goto no_dt; - } - - lpr->row_stride[0] = whandle->stride; unsigned nblocksy = util_format_get_nblocksy(template->format, align(template->height0, LP_RASTER_BLOCK_SIZE)); - lpr->img_stride[0] = whandle->stride * nblocksy; + if (whandle->type == WINSYS_HANDLE_TYPE_UNBACKED && whandle->image_stride) + lpr->img_stride[0] = whandle->image_stride; + else + lpr->img_stride[0] = whandle->stride * nblocksy; lpr->sample_stride = lpr->img_stride[0]; lpr->size_required = lpr->sample_stride; - assert(llvmpipe_resource_is_texture(&lpr->base)); - lpr->tex_data = data; + if (whandle->type != WINSYS_HANDLE_TYPE_UNBACKED) { + void *data; +#ifdef HAVE_LIBDRM + struct llvmpipe_memory_fd_alloc *alloc; + uint64_t size; + if(_screen->import_memory_fd(_screen, whandle->handle, (struct pipe_memory_allocation**)&alloc, &size, true)) { + data = alloc->data; + lpr->dt = winsys->displaytarget_create_mapped(winsys, template->bind, + template->format, template->width0, template->height0, + whandle->stride, data); + if (!lpr->dt) + goto no_dt; + lpr->dmabuf_alloc = alloc; + whandle->size = size; + } else +#endif + { + lpr->dt = winsys->displaytarget_from_handle(winsys, + template, + whandle, + &lpr->row_stride[0]); + if (!lpr->dt) + goto no_dt; + data = winsys->displaytarget_map(winsys, lpr->dt, PIPE_MAP_READ_WRITE); + if (!data) { + winsys->displaytarget_destroy(winsys, lpr->dt); + goto no_dt; + } + + whandle->size = lpr->size_required; + } + + assert(llvmpipe_resource_is_texture(&lpr->base)); + lpr->tex_data = data; + } else { + whandle->size = lpr->size_required; + lpr->backable = true; + } + + lpr->row_stride[0] = whandle->stride; + lpr->id = id_counter++; lpr->dmabuf = true; @@ -733,7 +750,7 @@ llvmpipe_resource_get_handle(struct pipe_screen *_screen, if (!lpr->imported_memory) align_free(is_tex ? lpr->tex_data : lpr->data); if (is_tex) - lpr->tex_data = lpr->dmabuf_alloc; + lpr->tex_data = lpr->dmabuf_alloc->data; else lpr->data = lpr->dmabuf_alloc->data; /* reuse lavapipe codepath to handle destruction */ @@ -1261,14 +1278,15 @@ llvmpipe_free_memory_fd(struct pipe_screen *screen, #endif - static bool -llvmpipe_resource_bind_backing(struct pipe_screen *screen, +llvmpipe_resource_bind_backing(struct pipe_screen *pscreen, struct pipe_resource *pt, struct pipe_memory_allocation *pmem, uint64_t offset) { + struct llvmpipe_screen *screen = llvmpipe_screen(pscreen); struct llvmpipe_resource *lpr = llvmpipe_resource(pt); + struct sw_winsys *winsys = screen->winsys; if (!lpr->backable) return false; @@ -1278,6 +1296,25 @@ llvmpipe_resource_bind_backing(struct pipe_screen *screen, return false; lpr->tex_data = (char *)pmem + offset; + + if (lpr->dmabuf) { + if (lpr->dt) + winsys->displaytarget_destroy(winsys, lpr->dt); + if (pmem) { + /* Round up the surface size to a multiple of the tile size to + * avoid tile clipping. + */ + const unsigned width = MAX2(1, align(lpr->base.width0, TILE_SIZE)); + const unsigned height = MAX2(1, align(lpr->base.height0, TILE_SIZE)); + + lpr->dt = winsys->displaytarget_create_mapped(winsys, + lpr->base.bind, + lpr->base.format, + width, height, + lpr->row_stride[0], + lpr->tex_data); + } + } } else lpr->data = (char *)pmem + offset; lpr->backing_offset = offset;