From 1adb2e9e959d9de9601b9d5dc8d733a065ac1d1d Mon Sep 17 00:00:00 2001 From: "Eric R. Smith" Date: Wed, 21 Feb 2024 13:02:52 -0400 Subject: [PATCH] panfrost: support multi-sampled image load/store On panfrost we can treat 2DMS image access like 3D access. Use a lowering pass to do this to implement 2DMS image load/store. Signed-off-by: Eric R. Smith Reviewed-by: Erik Faye-Lund Part-of: --- src/gallium/drivers/panfrost/pan_cmdstream.c | 25 +++++++++++++------- src/panfrost/compiler/bifrost_compile.c | 11 ++++----- src/panfrost/midgard/midgard_compile.c | 6 +++-- 3 files changed, 26 insertions(+), 16 deletions(-) diff --git a/src/gallium/drivers/panfrost/pan_cmdstream.c b/src/gallium/drivers/panfrost/pan_cmdstream.c index 83f7eb5ff0e..5f1a7d10106 100644 --- a/src/gallium/drivers/panfrost/pan_cmdstream.c +++ b/src/gallium/drivers/panfrost/pan_cmdstream.c @@ -1771,8 +1771,7 @@ emit_image_bufs(struct panfrost_batch *batch, enum pipe_shader_type shader, struct panfrost_resource *rsrc = pan_resource(image->resource); - /* TODO: MSAA */ - assert(image->resource->nr_samples <= 1 && "MSAA'd images not supported"); + bool is_msaa = image->resource->nr_samples > 1; bool is_3d = rsrc->base.target == PIPE_TEXTURE_3D; bool is_buffer = rsrc->base.target == PIPE_BUFFER; @@ -1780,8 +1779,8 @@ emit_image_bufs(struct panfrost_batch *batch, enum pipe_shader_type shader, unsigned offset = is_buffer ? image->u.buf.offset : panfrost_texture_offset( &rsrc->image.layout, image->u.tex.level, - is_3d ? 0 : image->u.tex.first_layer, - is_3d ? image->u.tex.first_layer : 0); + (is_3d || is_msaa) ? 0 : image->u.tex.first_layer, + (is_3d || is_msaa) ? image->u.tex.first_layer : 0); panfrost_track_image_access(batch, shader, image); @@ -1804,16 +1803,26 @@ emit_image_bufs(struct panfrost_batch *batch, enum pipe_shader_type shader, pan_pack(bufs + (i * 2) + 1, ATTRIBUTE_BUFFER_CONTINUATION_3D, cfg) { unsigned level = image->u.tex.level; + unsigned r_dim; + if (is_3d) { + r_dim = u_minify(rsrc->base.depth0, level); + } else if (is_msaa) { + r_dim = u_minify(image->resource->nr_samples, level); + } else { + r_dim = image->u.tex.last_layer - image->u.tex.first_layer + 1; + } cfg.s_dimension = u_minify(rsrc->base.width0, level); cfg.t_dimension = u_minify(rsrc->base.height0, level); - cfg.r_dimension = - is_3d ? u_minify(rsrc->base.depth0, level) - : image->u.tex.last_layer - image->u.tex.first_layer + 1; + cfg.r_dimension = r_dim; cfg.row_stride = rsrc->image.layout.slices[level].row_stride; - if (rsrc->base.target != PIPE_TEXTURE_2D) { + if (is_msaa) { + unsigned samples = rsrc->base.nr_samples; + cfg.slice_stride = + panfrost_get_layer_stride(&rsrc->image.layout, level) / samples; + } else if (rsrc->base.target != PIPE_TEXTURE_2D) { cfg.slice_stride = panfrost_get_layer_stride(&rsrc->image.layout, level); } diff --git a/src/panfrost/compiler/bifrost_compile.c b/src/panfrost/compiler/bifrost_compile.c index 90020640329..5f2f3a971a1 100644 --- a/src/panfrost/compiler/bifrost_compile.c +++ b/src/panfrost/compiler/bifrost_compile.c @@ -1328,7 +1328,6 @@ bi_emit_image_load(bi_builder *b, nir_intrinsic_instr *instr) enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr); unsigned coord_comps = nir_image_intrinsic_coord_components(instr); bool array = nir_intrinsic_image_array(instr); - ASSERTED unsigned nr_dim = glsl_get_sampler_dim_coordinate_components(dim); bi_index coords = bi_src_index(&instr->src[1]); bi_index xy = bi_emit_image_coord(b, coords, 0, coord_comps, array); @@ -1338,8 +1337,7 @@ bi_emit_image_load(bi_builder *b, nir_intrinsic_instr *instr) bi_reg_fmt_for_nir(nir_intrinsic_dest_type(instr)); enum bi_vecsize vecsize = instr->num_components - 1; - /* TODO: MSAA */ - assert(nr_dim != GLSL_SAMPLER_DIM_MS && "MSAA'd images not supported"); + assert(dim != GLSL_SAMPLER_DIM_MS && "MSAA'd image not lowered"); if (b->shader->arch >= 9 && nir_src_is_const(instr->src[0])) { bi_instr *I = bi_ld_tex_imm_to(b, dest, xy, zw, regfmt, vecsize, @@ -1361,11 +1359,9 @@ bi_emit_lea_image_to(bi_builder *b, bi_index dest, nir_intrinsic_instr *instr) { enum glsl_sampler_dim dim = nir_intrinsic_image_dim(instr); bool array = nir_intrinsic_image_array(instr); - ASSERTED unsigned nr_dim = glsl_get_sampler_dim_coordinate_components(dim); unsigned coord_comps = nir_image_intrinsic_coord_components(instr); - /* TODO: MSAA */ - assert(nr_dim != GLSL_SAMPLER_DIM_MS && "MSAA'd images not supported"); + assert(dim != GLSL_SAMPLER_DIM_MS && "MSAA'd image not lowered"); enum bi_register_format type = (instr->intrinsic == nir_intrinsic_image_store) @@ -4644,6 +4640,9 @@ bifrost_preprocess_nir(nir_shader *nir, unsigned gpu_id) psiz->data.precision = GLSL_PRECISION_MEDIUM; } + /* lower MSAA load/stores to 3D load/stores */ + NIR_PASS_V(nir, pan_nir_lower_image_ms); + /* Get rid of any global vars before we lower to scratch. */ NIR_PASS_V(nir, nir_lower_global_vars_to_local); diff --git a/src/panfrost/midgard/midgard_compile.c b/src/panfrost/midgard/midgard_compile.c index 2864b3195bc..92308929345 100644 --- a/src/panfrost/midgard/midgard_compile.c +++ b/src/panfrost/midgard/midgard_compile.c @@ -388,6 +388,9 @@ midgard_preprocess_nir(nir_shader *nir, unsigned gpu_id) if (quirks & MIDGARD_BROKEN_LOD) NIR_PASS_V(nir, midgard_nir_lod_errata); + /* lower MSAA image operations to 3D load before coordinate lowering */ + NIR_PASS_V(nir, pan_nir_lower_image_ms); + /* Midgard image ops coordinates are 16-bit instead of 32-bit */ NIR_PASS_V(nir, midgard_nir_lower_image_bitsize); @@ -1292,8 +1295,7 @@ emit_image_op(compiler_context *ctx, nir_intrinsic_instr *instr) bool is_array = nir_intrinsic_image_array(instr); bool is_store = instr->intrinsic == nir_intrinsic_image_store; - /* TODO: MSAA */ - assert(dim != GLSL_SAMPLER_DIM_MS && "MSAA'd images not supported"); + assert(dim != GLSL_SAMPLER_DIM_MS && "MSAA'd image not lowered"); unsigned coord_reg = nir_src_index(ctx, &instr->src[1]); emit_explicit_constant(ctx, coord_reg);