From 379de4cdcebcb5131d3b61362b886cbc8cebefc1 Mon Sep 17 00:00:00 2001 From: Robert Mader Date: Thu, 21 Nov 2024 15:26:31 +0100 Subject: [PATCH] freedreno: Support offset query for multi-planar planes This allows `gbm_bo_get_offset()` to return the correct offset for e.g. the second plane of a resource with the NV12 format. Crucially this fixes direct scanout / hardware plane usage in Mutter and possibly other clients. While on it also add support for stride, modifier and n_planes queries. The later two should not change in behavior and just safe a few CPU cycles. The stride query support in theory fixes queries for multi-plane formats, however in practice most/all currently used formats such as NV12, P010 and YUV420 use the same stride for all planes. Cc: mesa-stable Acked-by: Rob Clark Signed-off-by: Robert Mader Part-of: --- .../drivers/freedreno/freedreno_resource.c | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c index 828983519cc..4a1dc734d3c 100644 --- a/src/gallium/drivers/freedreno/freedreno_resource.c +++ b/src/gallium/drivers/freedreno/freedreno_resource.c @@ -12,6 +12,7 @@ #include "util/set.h" #include "util/u_drm.h" #include "util/u_inlines.h" +#include "util/u_resource.h" #include "util/u_sample_positions.h" #include "util/u_string.h" #include "util/u_surface.h" @@ -1135,6 +1136,39 @@ fd_resource_get_handle(struct pipe_screen *pscreen, struct pipe_context *pctx, return ret; } +static bool +fd_resource_get_param(struct pipe_screen *pscreen, + struct pipe_context *pctx, struct pipe_resource *prsc, + unsigned plane, unsigned layer, unsigned level, + enum pipe_resource_param param, + unsigned usage, uint64_t *value) +{ + struct fd_resource *rsc = fd_resource(util_resource_at_index(prsc, plane)); + + switch (param) { + case PIPE_RESOURCE_PARAM_STRIDE: + *value = fd_resource_pitch(rsc, 0); + return true; + case PIPE_RESOURCE_PARAM_OFFSET: + if (fd_resource_ubwc_enabled(rsc, level)) { + if (plane > 0) + debug_warning("Unsupported offset query!\n"); + *value = fd_resource_ubwc_offset(rsc, level, layer); + } else { + *value = fd_resource_offset(rsc, level, layer); + } + return true; + case PIPE_RESOURCE_PARAM_MODIFIER: + *value = fd_resource_modifier(rsc); + return true; + case PIPE_RESOURCE_PARAM_NPLANES: + *value = util_resource_num(prsc); + return true; + default: + return false; + } +} + /* special case to resize query buf after allocated.. */ void fd_resource_resize(struct pipe_resource *prsc, uint32_t sz) @@ -1740,6 +1774,7 @@ fd_resource_screen_init(struct pipe_screen *pscreen) pscreen->resource_create_with_modifiers = fd_resource_create_with_modifiers; pscreen->resource_from_handle = fd_resource_from_handle; pscreen->resource_get_handle = fd_resource_get_handle; + pscreen->resource_get_param = fd_resource_get_param; pscreen->resource_destroy = u_transfer_helper_resource_destroy; pscreen->transfer_helper =