From 0e856b95c59d4b9d1909bd96eca0296dd14b41ff Mon Sep 17 00:00:00 2001 From: Yogesh Mohanmarimuthu Date: Mon, 3 May 2021 23:52:40 +0530 Subject: [PATCH] loader: allocate VRAM in display GPU in case of prime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Allocates VRAM in display GPU in case of prime. Then the dma_buf is imported into prime GPU. v2: add comments to make code more readable (Pierre-Eric) removed if check limiting p2p only for matching driver name v3: keep old path for non mesa driver (Michel Dänzer) v4: destroy linear_buffer_display_gpu after import (Michel Dänzer) fall back if linear_buffer_display_gpu alloc fail (Michel Dänzer) Signed-off-by: Yogesh Mohanmarimuthu Acked-by: Pierre-Eric Pelloux-Prayer Reviewed-by: Marek Olšák Part-of: --- src/loader/loader_dri3_helper.c | 63 ++++++++++++++++++++++++++------- src/loader/loader_dri3_helper.h | 8 ++++- 2 files changed, 58 insertions(+), 13 deletions(-) diff --git a/src/loader/loader_dri3_helper.c b/src/loader/loader_dri3_helper.c index c5e340e6942..6428ee5422a 100644 --- a/src/loader/loader_dri3_helper.c +++ b/src/loader/loader_dri3_helper.c @@ -1309,7 +1309,7 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format, int width, int height, int depth) { struct loader_dri3_buffer *buffer; - __DRIimage *pixmap_buffer; + __DRIimage *pixmap_buffer = NULL, *linear_buffer_display_gpu = NULL; xcb_pixmap_t pixmap; xcb_sync_fence_t sync_fence; struct xshmfence *shm_fence; @@ -1422,18 +1422,37 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format, if (!buffer->image) goto no_image; - buffer->linear_buffer = - draw->ext->image->createImage(draw->dri_screen, - width, height, - dri3_linear_format_for_format(draw, format), - __DRI_IMAGE_USE_SHARE | - __DRI_IMAGE_USE_LINEAR | - __DRI_IMAGE_USE_BACKBUFFER, - buffer); - pixmap_buffer = buffer->linear_buffer; + /* if driver name is same only then dri_screen_display_gpu is set. + * This check is needed because for simplicity render gpu image extension + * is also used for display gpu. + */ + if (draw->dri_screen_display_gpu) { + linear_buffer_display_gpu = + draw->ext->image->createImage(draw->dri_screen_display_gpu, + width, height, + dri3_linear_format_for_format(draw, format), + __DRI_IMAGE_USE_SHARE | + __DRI_IMAGE_USE_LINEAR | + __DRI_IMAGE_USE_BACKBUFFER, + buffer); + pixmap_buffer = linear_buffer_display_gpu; + } - if (!buffer->linear_buffer) - goto no_linear_buffer; + if (!pixmap_buffer) { + buffer->linear_buffer = + draw->ext->image->createImage(draw->dri_screen, + width, height, + dri3_linear_format_for_format(draw, format), + __DRI_IMAGE_USE_SHARE | + __DRI_IMAGE_USE_LINEAR | + __DRI_IMAGE_USE_BACKBUFFER, + buffer); + + pixmap_buffer = buffer->linear_buffer; + if (!buffer->linear_buffer) { + goto no_linear_buffer; + } + } } /* X want some information about the planes, so ask the image for it @@ -1475,6 +1494,26 @@ dri3_alloc_render_buffer(struct loader_dri3_drawable *draw, unsigned int format, if (!ret) buffer->modifier = DRM_FORMAT_MOD_INVALID; + if (draw->is_different_gpu && draw->dri_screen_display_gpu && + linear_buffer_display_gpu) { + /* The linear buffer was created in the display GPU's vram, so we + * need to make it visible to render GPU + */ + buffer->linear_buffer = + draw->ext->image->createImageFromFds(draw->dri_screen, + width, + height, + image_format_to_fourcc(format), + &buffer_fds[0], num_planes, + &buffer->strides[0], + &buffer->offsets[0], + buffer); + if (!buffer->linear_buffer) + goto no_buffer_attrib; + + draw->ext->image->destroyImage(linear_buffer_display_gpu); + } + pixmap = xcb_generate_id(draw->conn); #ifdef HAVE_DRI3_MODIFIERS if (draw->multiplanes_available && diff --git a/src/loader/loader_dri3_helper.h b/src/loader/loader_dri3_helper.h index a256c377e6e..c70f1145caa 100644 --- a/src/loader/loader_dri3_helper.h +++ b/src/loader/loader_dri3_helper.h @@ -42,9 +42,15 @@ enum loader_dri3_buffer_type { struct loader_dri3_buffer { __DRIimage *image; - __DRIimage *linear_buffer; uint32_t pixmap; + /* default case: linear buffer allocated in render gpu vram. + * p2p case: linear buffer allocated in display gpu vram and imported + * to render gpu. p2p case is enabled when driver name matches + * while creating screen in dri3_create_screen() function. + */ + __DRIimage *linear_buffer; + /* Synchronization between the client and X server is done using an * xshmfence that is mapped into an X server SyncFence. This lets the * client check whether the X server is done using a buffer with a simple