From 36097fc7ef70471ecfecd428f990233276e9c45b Mon Sep 17 00:00:00 2001 From: Mike Blumenkrantz Date: Mon, 14 Dec 2020 11:48:39 -0500 Subject: [PATCH] st/pbo: fix pbo uploads without PIPE_CAP_TGSI_VS_LAYER_VIEWPORT and skip gs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit the previous commit handling this forced geometry shader usage for all cases, but this is not ideal, so instead there are now fragment shader variants for both depth==1 and depth!=1, corresponding to the existence of gl_Layer in the shader Fixes: 614c77772ac ("st/pbo: fix pbo uploads without PIPE_CAP_TGSI_VS_LAYER_VIEWPORT") Acked-by: Marek Olšák Part-of: --- src/mesa/state_tracker/st_cb_readpixels.c | 2 +- src/mesa/state_tracker/st_cb_texture.c | 2 +- src/mesa/state_tracker/st_context.h | 4 +- src/mesa/state_tracker/st_pbo.c | 49 +++++++++++++---------- src/mesa/state_tracker/st_pbo.h | 6 ++- 5 files changed, 36 insertions(+), 27 deletions(-) diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c index 69e74f5d57e..1fd84b02420 100644 --- a/src/mesa/state_tracker/st_cb_readpixels.c +++ b/src/mesa/state_tracker/st_cb_readpixels.c @@ -242,7 +242,7 @@ try_pbo_readpixels(struct st_context *st, struct st_renderbuffer *strb, /* Set up the fragment shader */ { - void *fs = st_pbo_get_download_fs(st, view_target, src_format, dst_format); + void *fs = st_pbo_get_download_fs(st, view_target, src_format, dst_format, addr.depth != 1); if (!fs) goto fail; diff --git a/src/mesa/state_tracker/st_cb_texture.c b/src/mesa/state_tracker/st_cb_texture.c index 0f344a88fb7..f7a6660ff15 100644 --- a/src/mesa/state_tracker/st_cb_texture.c +++ b/src/mesa/state_tracker/st_cb_texture.c @@ -1271,7 +1271,7 @@ try_pbo_upload_common(struct gl_context *ctx, bool success = false; void *fs; - fs = st_pbo_get_upload_fs(st, src_format, surface->format); + fs = st_pbo_get_upload_fs(st, src_format, surface->format, addr->depth != 1); if (!fs) return false; diff --git a/src/mesa/state_tracker/st_context.h b/src/mesa/state_tracker/st_context.h index d197cff1614..0967567826a 100644 --- a/src/mesa/state_tracker/st_context.h +++ b/src/mesa/state_tracker/st_context.h @@ -316,8 +316,8 @@ struct st_context struct pipe_blend_state upload_blend; void *vs; void *gs; - void *upload_fs[3]; - void *download_fs[3][PIPE_MAX_TEXTURE_TYPES]; + void *upload_fs[3][2]; + void *download_fs[3][PIPE_MAX_TEXTURE_TYPES][2]; bool upload_enabled; bool download_enabled; bool rgba_only; diff --git a/src/mesa/state_tracker/st_pbo.c b/src/mesa/state_tracker/st_pbo.c index 3c197d89b53..530e1cd4e9b 100644 --- a/src/mesa/state_tracker/st_pbo.c +++ b/src/mesa/state_tracker/st_pbo.c @@ -202,7 +202,7 @@ st_pbo_draw(struct st_context *st, const struct st_pbo_addresses *addr, return false; } - if (st->pbo.use_gs && !st->pbo.gs) { + if (addr->depth != 1 && st->pbo.use_gs && !st->pbo.gs) { st->pbo.gs = st_pbo_create_gs(st); if (!st->pbo.gs) return false; @@ -403,7 +403,8 @@ sampler_type_for_target(enum pipe_texture_target target) static void * create_fs(struct st_context *st, bool download, enum pipe_texture_target target, - enum st_pbo_conversion conversion) + enum st_pbo_conversion conversion, + bool need_layer) { struct pipe_screen *screen = st->screen; const nir_shader_compiler_options *options = @@ -432,11 +433,11 @@ create_fs(struct st_context *st, bool download, nir_ssa_def *coord = nir_load_var(&b, fragcoord); nir_ssa_def *layer = NULL; - if (st->pbo.layers && (!download || target == PIPE_TEXTURE_1D_ARRAY || - target == PIPE_TEXTURE_2D_ARRAY || - target == PIPE_TEXTURE_3D || - target == PIPE_TEXTURE_CUBE || - target == PIPE_TEXTURE_CUBE_ARRAY)) { + if (st->pbo.layers && need_layer && (!download || target == PIPE_TEXTURE_1D_ARRAY || + target == PIPE_TEXTURE_2D_ARRAY || + target == PIPE_TEXTURE_3D || + target == PIPE_TEXTURE_CUBE || + target == PIPE_TEXTURE_CUBE_ARRAY)) { nir_variable *var = nir_variable_create(b.shader, nir_var_shader_in, glsl_int_type(), "gl_Layer"); var->data.location = VARYING_SLOT_LAYER; @@ -563,32 +564,34 @@ get_pbo_conversion(enum pipe_format src_format, enum pipe_format dst_format) void * st_pbo_get_upload_fs(struct st_context *st, enum pipe_format src_format, - enum pipe_format dst_format) + enum pipe_format dst_format, + bool need_layer) { STATIC_ASSERT(ARRAY_SIZE(st->pbo.upload_fs) == ST_NUM_PBO_CONVERSIONS); enum st_pbo_conversion conversion = get_pbo_conversion(src_format, dst_format); - if (!st->pbo.upload_fs[conversion]) - st->pbo.upload_fs[conversion] = create_fs(st, false, 0, conversion); + if (!st->pbo.upload_fs[conversion][need_layer]) + st->pbo.upload_fs[conversion][need_layer] = create_fs(st, false, 0, conversion, need_layer); - return st->pbo.upload_fs[conversion]; + return st->pbo.upload_fs[conversion][need_layer]; } void * st_pbo_get_download_fs(struct st_context *st, enum pipe_texture_target target, enum pipe_format src_format, - enum pipe_format dst_format) + enum pipe_format dst_format, + bool need_layer) { STATIC_ASSERT(ARRAY_SIZE(st->pbo.download_fs) == ST_NUM_PBO_CONVERSIONS); assert(target < PIPE_MAX_TEXTURE_TYPES); enum st_pbo_conversion conversion = get_pbo_conversion(src_format, dst_format); - if (!st->pbo.download_fs[conversion][target]) - st->pbo.download_fs[conversion][target] = create_fs(st, true, target, conversion); + 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]; + return st->pbo.download_fs[conversion][target][need_layer]; } void @@ -637,17 +640,21 @@ st_destroy_pbo_helpers(struct st_context *st) unsigned i; for (i = 0; i < ARRAY_SIZE(st->pbo.upload_fs); ++i) { - if (st->pbo.upload_fs[i]) { - st->pipe->delete_fs_state(st->pipe, st->pbo.upload_fs[i]); - st->pbo.upload_fs[i] = NULL; + for (unsigned j = 0; j < ARRAY_SIZE(st->pbo.upload_fs[0]); j++) { + if (st->pbo.upload_fs[i][j]) { + st->pipe->delete_fs_state(st->pipe, st->pbo.upload_fs[i][j]); + st->pbo.upload_fs[i][j] = NULL; + } } } for (i = 0; i < ARRAY_SIZE(st->pbo.download_fs); ++i) { for (unsigned j = 0; j < ARRAY_SIZE(st->pbo.download_fs[0]); ++j) { - if (st->pbo.download_fs[i][j]) { - st->pipe->delete_fs_state(st->pipe, st->pbo.download_fs[i][j]); - st->pbo.download_fs[i][j] = NULL; + 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]); + st->pbo.download_fs[i][j][k] = NULL; + } } } } diff --git a/src/mesa/state_tracker/st_pbo.h b/src/mesa/state_tracker/st_pbo.h index 54ae7768b4f..54626580f01 100644 --- a/src/mesa/state_tracker/st_pbo.h +++ b/src/mesa/state_tracker/st_pbo.h @@ -87,12 +87,14 @@ st_pbo_create_gs(struct st_context *st); void * st_pbo_get_upload_fs(struct st_context *st, enum pipe_format src_format, - enum pipe_format dst_format); + enum pipe_format dst_format, + bool need_layer); void * st_pbo_get_download_fs(struct st_context *st, enum pipe_texture_target target, enum pipe_format src_format, - enum pipe_format dst_format); + enum pipe_format dst_format, + bool need_layer); extern void st_init_pbo_helpers(struct st_context *st);