From fd47c939f447657387f051c50837997598240eb8 Mon Sep 17 00:00:00 2001 From: "Juan A. Suarez Romero" Date: Wed, 13 Oct 2021 12:56:15 +0200 Subject: [PATCH] st/pbo: add the image format in the download FS MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit In the V3D driver there is a NIR lowering step for `image_store` intrinsic, where the image store format is required for doing the proper lowering. Thus, let's define it for the download FS instead of keeping it as NONE. v2 (Illia) - Use format only for drivers not supporting format-less writing. v4 (Illia): - Use PIPE_CAP_IMAGE_STORE_FORMATTED to reduce combinations. v5 (Ilia): - Use indirect array for download FS in not formatless-store support drivers. Signed-off-by: Juan A. Suarez Romero Reviewed-by: Alejandro Piñeiro Reviewed-by: Iago Toral Quiroga Reviewed-by: Ilia Mirkin Part-of: --- .../compiler/v3d_nir_lower_image_load_store.c | 1 + src/mesa/state_tracker/st_context.h | 7 ++++ src/mesa/state_tracker/st_pbo.c | 41 ++++++++++++++++++---- 3 files changed, 42 insertions(+), 7 deletions(-) diff --git a/src/broadcom/compiler/v3d_nir_lower_image_load_store.c b/src/broadcom/compiler/v3d_nir_lower_image_load_store.c index 2706432..6b459e1 100644 --- a/src/broadcom/compiler/v3d_nir_lower_image_load_store.c +++ b/src/broadcom/compiler/v3d_nir_lower_image_load_store.c @@ -88,6 +88,7 @@ static void v3d_nir_lower_image_store(nir_builder *b, nir_intrinsic_instr *instr) { enum pipe_format format = nir_intrinsic_format(instr); + assert(format != PIPE_FORMAT_NONE); const struct util_format_description *desc = util_format_description(format); const struct util_format_channel_description *r_chan = &desc->channel[0]; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index 4f2a020..9a2be69 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -326,6 +326,13 @@ struct st_context void *vs; void *gs; void *upload_fs[5][2]; + /** + * For drivers supporting formatless storing + * (PIPE_CAP_IMAGE_STORE_FORMATTED) it is a pointer to the download FS; + * for those not supporting it, it is a pointer to an array of + * PIPE_FORMAT_COUNT elements, where each element is a pointer to the + * download FS using that PIPE_FORMAT as the storing format. + */ void *download_fs[5][PIPE_MAX_TEXTURE_TYPES][2]; struct hash_table *shaders; bool upload_enabled; diff --git a/src/mesa/state_tracker/st_pbo.c b/src/mesa/state_tracker/st_pbo.c index a3fb0e6..51a29e8 100644 --- a/src/mesa/state_tracker/st_pbo.c +++ b/src/mesa/state_tracker/st_pbo.c @@ -33,6 +33,7 @@ #include "state_tracker/st_pbo.h" #include "state_tracker/st_cb_bufferobjects.h" +#include "main/context.h" #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "pipe/p_screen.h" @@ -407,6 +408,7 @@ static void * create_fs(struct st_context *st, bool download, enum pipe_texture_target target, enum st_pbo_conversion conversion, + enum pipe_format format, bool need_layer) { struct pipe_screen *screen = st->screen; @@ -552,6 +554,7 @@ create_fs(struct st_context *st, bool download, img_var->data.access = ACCESS_NON_READABLE; img_var->data.explicit_binding = true; img_var->data.binding = 0; + img_var->data.image.format = format; nir_deref_instr *img_deref = nir_build_deref_var(&b, img_var); nir_image_deref_store(&b, &img_deref->dest.ssa, @@ -601,7 +604,7 @@ st_pbo_get_upload_fs(struct st_context *st, enum st_pbo_conversion conversion = get_pbo_conversion(src_format, dst_format); if (!st->pbo.upload_fs[conversion][need_layer]) - st->pbo.upload_fs[conversion][need_layer] = create_fs(st, false, 0, conversion, need_layer); + st->pbo.upload_fs[conversion][need_layer] = create_fs(st, false, 0, conversion, PIPE_FORMAT_NONE, need_layer); return st->pbo.upload_fs[conversion][need_layer]; } @@ -615,12 +618,26 @@ st_pbo_get_download_fs(struct st_context *st, enum pipe_texture_target target, STATIC_ASSERT(ARRAY_SIZE(st->pbo.download_fs) == ST_NUM_PBO_CONVERSIONS); assert(target < PIPE_MAX_TEXTURE_TYPES); + struct pipe_screen *screen = st->screen; enum st_pbo_conversion conversion = get_pbo_conversion(src_format, dst_format); - - if (!st->pbo.download_fs[conversion][target][need_layer]) - st->pbo.download_fs[conversion][target][need_layer] = create_fs(st, true, target, conversion, need_layer); - - return st->pbo.download_fs[conversion][target][need_layer]; + bool formatless_store = screen->get_param(screen, PIPE_CAP_IMAGE_STORE_FORMATTED); + + /* For drivers not supporting formatless storing, download FS is stored in an + * indirect dynamically allocated array of storing formats. + */ + if (!formatless_store && !st->pbo.download_fs[conversion][target][need_layer]) + st->pbo.download_fs[conversion][target][need_layer] = calloc(sizeof(void *), PIPE_FORMAT_COUNT); + + if (formatless_store) { + if (!st->pbo.download_fs[conversion][target][need_layer]) + st->pbo.download_fs[conversion][target][need_layer] = create_fs(st, true, target, conversion, PIPE_FORMAT_NONE, need_layer); + return st->pbo.download_fs[conversion][target][need_layer]; + } else { + void **fs_array = (void **)st->pbo.download_fs[conversion][target][need_layer]; + if (!fs_array[dst_format]) + fs_array[dst_format] = create_fs(st, true, target, conversion, dst_format, need_layer); + return fs_array[dst_format]; + } } void @@ -675,6 +692,8 @@ st_init_pbo_helpers(struct st_context *st) void st_destroy_pbo_helpers(struct st_context *st) { + struct pipe_screen *screen = st->screen; + bool formatless_store = screen->get_param(screen, PIPE_CAP_IMAGE_STORE_FORMATTED); unsigned i; for (i = 0; i < ARRAY_SIZE(st->pbo.upload_fs); ++i) { @@ -690,7 +709,15 @@ st_destroy_pbo_helpers(struct st_context *st) for (unsigned j = 0; j < ARRAY_SIZE(st->pbo.download_fs[0]); ++j) { for (unsigned k = 0; k < ARRAY_SIZE(st->pbo.download_fs[0][0]); k++) { if (st->pbo.download_fs[i][j][k]) { - st->pipe->delete_fs_state(st->pipe, st->pbo.download_fs[i][j][k]); + if (formatless_store) { + st->pipe->delete_fs_state(st->pipe, st->pbo.download_fs[i][j][k]); + } else { + void **fs_array = (void **)st->pbo.download_fs[i][j][k]; + for (unsigned l = 0; l < PIPE_FORMAT_COUNT; l++) + if (fs_array[l]) + st->pipe->delete_fs_state(st->pipe, fs_array[l]); + free(st->pbo.download_fs[i][j][k]); + } st->pbo.download_fs[i][j][k] = NULL; } } -- 2.7.4