st/pbo: add the image format in the download FS

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 <jasuarez@igalia.com>
Reviewed-by: Alejandro Piñeiro <apinheiro@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Reviewed-by: Ilia Mirkin <imirkin@alum.mit.edu>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13409>
This commit is contained in:
Juan A. Suarez Romero 2021-10-13 12:56:15 +02:00 committed by Marge Bot
parent 38c953e287
commit fd47c939f4
3 changed files with 40 additions and 5 deletions

View File

@ -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];

View File

@ -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;

View File

@ -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);
bool formatless_store = screen->get_param(screen, PIPE_CAP_IMAGE_STORE_FORMATTED);
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);
/* 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);
return st->pbo.download_fs[conversion][target][need_layer];
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;
}
}