From e18431273a3c3cd1aef86446a540c8510b4fbf85 Mon Sep 17 00:00:00 2001 From: Lionel Landwerlin Date: Mon, 4 Nov 2024 14:04:03 +0200 Subject: [PATCH] blorp: relax depth/stencil<->color copy restriction Currently blorp assumes that copies of depth/stencil is restricted to/from depth/stencil formats. We want to allow color<->depth copies. Signed-off-by: Lionel Landwerlin Reviewed-by: Nanley Chery Acked-by: Ivan Briano Part-of: --- src/intel/blorp/blorp.h | 5 +++++ src/intel/blorp/blorp_blit.c | 21 +++++++++++++++++++-- src/intel/blorp/blorp_brw.c | 12 +++++++++--- src/intel/blorp/blorp_elk.c | 12 +++++++++--- 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/src/intel/blorp/blorp.h b/src/intel/blorp/blorp.h index 407d00de5fa..32ad4996ba9 100644 --- a/src/intel/blorp/blorp.h +++ b/src/intel/blorp/blorp.h @@ -36,6 +36,8 @@ extern "C" { struct brw_compiler; struct elk_compiler; +typedef struct nir_shader nir_shader; + enum blorp_op { BLORP_OP_BLIT, BLORP_OP_COPY, @@ -80,6 +82,8 @@ struct blorp_context { bool enable_tbimr; + nir_shader *(*get_fp64_nir)(struct blorp_context *context); + void (*upload_dynamic_state)(struct blorp_context *context, const void *data, uint32_t size, uint32_t alignment, @@ -247,6 +251,7 @@ blorp_blit(struct blorp_batch *batch, enum isl_format blorp_copy_get_color_format(const struct isl_device *isl_dev, enum isl_format surf_format); + void blorp_copy_get_formats(const struct isl_device *isl_dev, const struct isl_surf *src_surf, diff --git a/src/intel/blorp/blorp_blit.c b/src/intel/blorp/blorp_blit.c index 2f7d9be7a8d..3cf00681871 100644 --- a/src/intel/blorp/blorp_blit.c +++ b/src/intel/blorp/blorp_blit.c @@ -909,7 +909,10 @@ bit_cast_color(struct nir_builder *b, nir_def *color, BITFIELD_MASK(chan_bits)); if (dst_fmtl->channels_array[c].type == ISL_UNORM) { - chans[c] = nir_format_unorm_to_float(b, chans[c], &chan_bits); + chans[c] = + dst_fmtl->format == ISL_FORMAT_R24_UNORM_X8_TYPELESS ? + nir_format_unorm_to_float_precise(b, chans[c], &chan_bits) : + nir_format_unorm_to_float(b, chans[c], &chan_bits); /* Don't touch the alpha channel */ if (c < 3 && dst_fmtl->colorspace == ISL_COLORSPACE_SRGB) @@ -2880,7 +2883,6 @@ blorp_copy_get_formats(const struct isl_device *isl_dev, if (ISL_GFX_VER(isl_dev) >= 8 && isl_surf_usage_is_depth(src_surf->usage)) { /* In order to use HiZ, we have to use the real format for the source. - * Depth <-> Color copies are not allowed. */ *src_view_format = src_surf->format; *dst_view_format = src_surf->format; @@ -2891,6 +2893,21 @@ blorp_copy_get_formats(const struct isl_device *isl_dev, */ *src_view_format = dst_surf->format; *dst_view_format = dst_surf->format; + + /* Some generations like Gfx9/11 have a CCS_E dependent on the + * bits-per-channel of the format. If we reinterpret a R32 source image + * as D24_UNORM we'll read invalid data from the sampler. + * + * Instead keep the source as R32_UINT (so it stays bits-per-channel + * compatible according to the VK_KHR_maintenance8 copy operations + * compatibility format list) and have the shader do a conversion + * to a floating point value out of 24bits of data to write into the + * depth output. + */ + if (dst_surf->format == ISL_FORMAT_R24_UNORM_X8_TYPELESS && + src_surf->format != ISL_FORMAT_R24_UNORM_X8_TYPELESS) { + *src_view_format = ISL_FORMAT_R32_UINT; + } } else if (isl_surf_usage_is_depth_or_stencil(src_surf->usage) || isl_surf_usage_is_depth_or_stencil(dst_surf->usage)) { assert(src_fmtl->bpb == dst_fmtl->bpb); diff --git a/src/intel/blorp/blorp_brw.c b/src/intel/blorp/blorp_brw.c index 989bf9a6a5c..96e19482ccf 100644 --- a/src/intel/blorp/blorp_brw.c +++ b/src/intel/blorp/blorp_brw.c @@ -30,7 +30,9 @@ blorp_compile_fs_brw(struct blorp_context *blorp, void *mem_ctx, wm_prog_data->base.nr_params = 0; wm_prog_data->base.param = NULL; - struct brw_nir_compiler_opts opts = {}; + struct brw_nir_compiler_opts opts = { + .softfp64 = blorp->get_fp64_nir ? blorp->get_fp64_nir(blorp) : NULL, + }; brw_preprocess_nir(compiler, nir, &opts); nir_remove_dead_variables(nir, nir_var_shader_in, NULL); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); @@ -71,7 +73,9 @@ blorp_compile_vs_brw(struct blorp_context *blorp, void *mem_ctx, { const struct brw_compiler *compiler = blorp->compiler->brw; - struct brw_nir_compiler_opts opts = {}; + struct brw_nir_compiler_opts opts = { + .softfp64 = blorp->get_fp64_nir ? blorp->get_fp64_nir(blorp) : NULL, + }; brw_preprocess_nir(compiler, nir, &opts); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); @@ -124,7 +128,9 @@ blorp_compile_cs_brw(struct blorp_context *blorp, void *mem_ctx, { const struct brw_compiler *compiler = blorp->compiler->brw; - struct brw_nir_compiler_opts opts = {}; + struct brw_nir_compiler_opts opts = { + .softfp64 = blorp->get_fp64_nir ? blorp->get_fp64_nir(blorp) : NULL, + }; brw_preprocess_nir(compiler, nir, &opts); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); diff --git a/src/intel/blorp/blorp_elk.c b/src/intel/blorp/blorp_elk.c index d0dfd5ad829..cac5315278b 100644 --- a/src/intel/blorp/blorp_elk.c +++ b/src/intel/blorp/blorp_elk.c @@ -31,7 +31,9 @@ blorp_compile_fs_elk(struct blorp_context *blorp, void *mem_ctx, wm_prog_data->base.nr_params = 0; wm_prog_data->base.param = NULL; - struct elk_nir_compiler_opts opts = {}; + struct elk_nir_compiler_opts opts = { + .softfp64 = blorp->get_fp64_nir ? blorp->get_fp64_nir(blorp) : NULL, + }; elk_preprocess_nir(compiler, nir, &opts); nir_remove_dead_variables(nir, nir_var_shader_in, NULL); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); @@ -77,7 +79,9 @@ blorp_compile_vs_elk(struct blorp_context *blorp, void *mem_ctx, { const struct elk_compiler *compiler = blorp->compiler->elk; - struct elk_nir_compiler_opts opts = {}; + struct elk_nir_compiler_opts opts = { + .softfp64 = blorp->get_fp64_nir ? blorp->get_fp64_nir(blorp) : NULL, + }; elk_preprocess_nir(compiler, nir, &opts); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir)); @@ -130,7 +134,9 @@ blorp_compile_cs_elk(struct blorp_context *blorp, void *mem_ctx, { const struct elk_compiler *compiler = blorp->compiler->elk; - struct elk_nir_compiler_opts opts = {}; + struct elk_nir_compiler_opts opts = { + .softfp64 = blorp->get_fp64_nir ? blorp->get_fp64_nir(blorp) : NULL, + }; elk_preprocess_nir(compiler, nir, &opts); nir_shader_gather_info(nir, nir_shader_get_entrypoint(nir));