gallium: add pipe_screen::get_driver_pipe_screen

pipe_resource has a screen pointer, and some drivers expect to be able
to cast it to their specialized version.
This works fine until one of the debug driver is used, because in this
case the driver's pipe_screen subclass can't be obtained with a simple
cast.
To overcome this limitation, this commit introduce a new function with
a default implementation to get the real driver pipe_screen from the
generic interface.

Reviewed-By: Mike Blumenkrantz <michael.blumenkrantz@gmail.com>
Reviewed-by: Marek Olšák <marek.olsak@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/30587>
This commit is contained in:
Pierre-Eric Pelloux-Prayer 2024-08-06 09:57:22 +02:00 committed by Marge Bot
parent 06d903920e
commit c9806b3595
6 changed files with 43 additions and 1 deletions

View file

@ -545,6 +545,15 @@ match_uint(const char **cur, unsigned *value)
return true;
}
static struct pipe_screen * dd_get_driver_pipe_screen(struct pipe_screen *_screen)
{
struct pipe_screen * screen = dd_screen(_screen)->screen;
if (screen->get_driver_pipe_screen)
return screen->get_driver_pipe_screen(screen);
return screen;
}
struct pipe_screen *
ddebug_screen_create(struct pipe_screen *screen)
{
@ -688,6 +697,7 @@ ddebug_screen_create(struct pipe_screen *screen)
SCR_INIT(get_sparse_texture_virtual_page_size);
SCR_INIT(create_vertex_state);
SCR_INIT(vertex_state_destroy);
dscreen->base.get_driver_pipe_screen = dd_get_driver_pipe_screen;
#undef SCR_INIT

View file

@ -788,6 +788,15 @@ static void noop_set_fence_timeline_value(struct pipe_screen *screen,
oscreen->set_fence_timeline_value(oscreen, fence, value);
}
static struct pipe_screen * noop_get_driver_pipe_screen(struct pipe_screen *_screen)
{
struct pipe_screen * screen = ((struct noop_pipe_screen*)_screen)->oscreen;
if (screen->get_driver_pipe_screen)
return screen->get_driver_pipe_screen(screen);
return screen;
}
struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen)
{
struct noop_pipe_screen *noop_screen;
@ -850,6 +859,7 @@ struct pipe_screen *noop_screen_create(struct pipe_screen *oscreen)
screen->query_compression_rates = noop_query_compression_rates;
screen->query_compression_modifiers = noop_query_compression_modifiers;
screen->is_compression_modifier = noop_is_compression_modifier;
screen->get_driver_pipe_screen = noop_get_driver_pipe_screen;
slab_create_parent(&noop_screen->pool_transfers,
sizeof(struct pipe_transfer), 64);

View file

@ -1524,6 +1524,15 @@ trace_enabled(void)
return trace;
}
static struct pipe_screen * tr_get_driver_pipe_screen(struct pipe_screen *_screen)
{
struct pipe_screen *screen = trace_screen(_screen)->screen;
if (screen->get_driver_pipe_screen)
return screen->get_driver_pipe_screen(screen);
return screen;
}
struct pipe_screen *
trace_screen_create(struct pipe_screen *screen)
{
@ -1618,6 +1627,7 @@ trace_screen_create(struct pipe_screen *screen)
SCR_INIT(query_compression_rates);
SCR_INIT(query_compression_modifiers);
SCR_INIT(is_compression_modifier);
tr_scr->base.get_driver_pipe_screen = tr_get_driver_pipe_screen;
tr_scr->screen = screen;

View file

@ -15,6 +15,8 @@
#include "driver_trace/tr_public.h"
#include "driver_noop/noop_public.h"
#include "pipe/p_screen.h"
#ifdef __cplusplus
extern "C" {
#endif

View file

@ -862,6 +862,13 @@ struct pipe_screen {
struct pipe_video_buffer *target,
enum pipe_video_profile profile,
enum pipe_video_entrypoint entrypoint);
/**
* pipe_screen is inherited by driver's screen but a simple cast to convert
* from the generic interface to the driver version won't work if dd_pipe
* is used.
*/
struct pipe_screen* (*get_driver_pipe_screen)(struct pipe_screen *screen);
};

View file

@ -591,7 +591,10 @@ struct pipe_resource
* next plane.
*/
struct pipe_resource *next;
/* The screen pointer should be last for optimal structure packing. */
/* The screen pointer should be last for optimal structure packing.
* This pointer cannot be casted directly to a driver's screen. Use
* screen::get_driver_pipe_screen instead if it's non-NULL.
*/
struct pipe_screen *screen; /**< screen that this texture belongs to */
};