From 9d7441dcb04875a4f30b144c4ba5d1cb32318507 Mon Sep 17 00:00:00 2001 From: Karol Herbst Date: Wed, 10 Jul 2024 14:54:59 +0200 Subject: [PATCH] gallium: add fixed address resource API MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit cl_ext_buffer_device_address requires us to set a fixed address for a given memory allocation. As this extension is intended to be implemented on top of vulkan we have to take its limitations into account. For SVM we'll add proper VM management interfaces, but zink won't be able to implement those, so here we are. The old interfaces added back in clover's time were modeled after a very bindful resource model and the frontend was require to bind all the used resources ahead of launch_grid. cl_ext_buffer_device_address and also SVM however will require us to dynamically attach a list of buffers used in a dispatch with known addresses, hence set_global_binding isn't really suited for those use cases. So PIPE_RESOURCE_FLAG_FIXED_ADDRESS is added to tell a driver that the address of a resource needs to stay the same over its lifetime, which then can be queried via pipe_screen::resource_get_address. All such buffers then can be either bound via set_global_binding or passed in via pipe_grid_info::globals. Reviewed-by: Adam Jackson Reviewed-by: Alyssa Rosenzweig Reviewed-by: Marek Olšák Part-of: --- docs/gallium/screen.rst | 4 ++++ .../auxiliary/driver_trace/tr_dump_state.c | 4 ++++ .../auxiliary/driver_trace/tr_screen.c | 19 +++++++++++++++++++ src/gallium/include/pipe/p_defines.h | 3 ++- src/gallium/include/pipe/p_screen.h | 9 +++++++++ src/gallium/include/pipe/p_state.h | 4 ++++ 6 files changed, 42 insertions(+), 1 deletion(-) diff --git a/docs/gallium/screen.rst b/docs/gallium/screen.rst index 2ed9211b96f..db6e88968d2 100644 --- a/docs/gallium/screen.rst +++ b/docs/gallium/screen.rst @@ -996,7 +996,11 @@ resource_destroy Destroy a resource. A resource is destroyed if it has no more references. +resource_get_address +^^^^^^^^^^^^^^^^^^^^ +Returns the address of **resource** created with +``PIPE_RESOURCE_FLAG_FIXED_ADDRESS``. get_timestamp ^^^^^^^^^^^^^ diff --git a/src/gallium/auxiliary/driver_trace/tr_dump_state.c b/src/gallium/auxiliary/driver_trace/tr_dump_state.c index abc87ed7a44..e7a9475616d 100644 --- a/src/gallium/auxiliary/driver_trace/tr_dump_state.c +++ b/src/gallium/auxiliary/driver_trace/tr_dump_state.c @@ -1181,6 +1181,10 @@ void trace_dump_grid_info(const struct pipe_grid_info *state) trace_dump_member(ptr, state, indirect); trace_dump_member(uint, state, indirect_offset); + trace_dump_member_begin("globals"); + trace_dump_array(ptr, state->globals, state->num_globals); + trace_dump_member_end(); + trace_dump_struct_end(); } diff --git a/src/gallium/auxiliary/driver_trace/tr_screen.c b/src/gallium/auxiliary/driver_trace/tr_screen.c index e643e054340..223264e2e5e 100644 --- a/src/gallium/auxiliary/driver_trace/tr_screen.c +++ b/src/gallium/auxiliary/driver_trace/tr_screen.c @@ -855,6 +855,24 @@ trace_screen_resource_get_info(struct pipe_screen *_screen, trace_dump_call_end(); } +static uint64_t +trace_screen_resource_get_address(struct pipe_screen *_screen, + struct pipe_resource *resource) +{ + struct trace_screen *tr_screen = trace_screen(_screen); + struct pipe_screen *screen = tr_screen->screen; + + trace_dump_call_begin("pipe_screen", "resource_get_address"); + trace_dump_arg(ptr, screen); + trace_dump_arg(ptr, resource); + + uint64_t res = screen->resource_get_address(screen, resource); + + trace_dump_ret(uint, res); + trace_dump_call_end(); + return res; +} + static struct pipe_resource * trace_screen_resource_from_memobj(struct pipe_screen *_screen, const struct pipe_resource *templ, @@ -1475,6 +1493,7 @@ trace_screen_create(struct pipe_screen *screen) tr_scr->base.resource_get_handle = trace_screen_resource_get_handle; SCR_INIT(resource_get_param); SCR_INIT(resource_get_info); + SCR_INIT(resource_get_address); SCR_INIT(resource_from_memobj); SCR_INIT(resource_changed); tr_scr->base.resource_destroy = trace_screen_resource_destroy; diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h index f356fd02dbb..097d18f14e3 100644 --- a/src/gallium/include/pipe/p_defines.h +++ b/src/gallium/include/pipe/p_defines.h @@ -516,7 +516,8 @@ enum pipe_flush_flags #define PIPE_RESOURCE_FLAG_DONT_OVER_ALLOCATE (1 << 6) #define PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY (1 << 7) /* for small visible VRAM */ #define PIPE_RESOURCE_FLAG_UNMAPPABLE (1 << 8) /* implies staging transfers due to VK interop */ -#define PIPE_RESOURCE_FLAG_DRV_PRIV (1 << 9) /* driver/winsys private */ +#define PIPE_RESOURCE_FLAG_FIXED_ADDRESS (1 << 9) /* virtual memory address never changes */ +#define PIPE_RESOURCE_FLAG_DRV_PRIV (1 << 10) /* driver/winsys private */ #define PIPE_RESOURCE_FLAG_FRONTEND_PRIV (1 << 24) /* gallium frontend private */ /** diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h index d24974f6195..554b9b1cccc 100644 --- a/src/gallium/include/pipe/p_screen.h +++ b/src/gallium/include/pipe/p_screen.h @@ -820,6 +820,15 @@ struct pipe_screen { enum pipe_video_profile profile, enum pipe_video_entrypoint entrypoint); + /** + * Returns the virtual address of \p resource. \p resource needs to be created + * with PIPE_RESOURCE_FLAG_FIXED_ADDRESS. + * + * \return the virtual address of the given resource. Returns 0 on failure. + */ + uint64_t (*resource_get_address)(struct pipe_screen *screen, + struct pipe_resource *resource); + /** * 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 diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 8817ee952b1..96f9167a0e4 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -998,6 +998,10 @@ struct pipe_grid_info unsigned draw_count; unsigned indirect_draw_count_offset; struct pipe_resource *indirect_draw_count; + + /* Resources which might be indirectly accessed through global load/store operations */ + uint32_t num_globals; + struct pipe_resource **globals; }; /**