[Mesa-dev] [PATCH 3/4] freedreno/a6xx: MSAA

Rob Clark robdclark at gmail.com
Tue Nov 6 20:34:30 UTC 2018


On Tue, Nov 6, 2018 at 3:14 PM Ilia Mirkin <imirkin at alum.mit.edu> wrote:
>
> On Tue, Nov 6, 2018 at 2:31 PM Kristian H. Kristensen
> <hoegsberg at gmail.com> wrote:
> >
> > From: Rob Clark <robdclark at gmail.com>
> >
> > Signed-off-by: Rob Clark <robdclark at gmail.com>
> > ---
> >  .../drivers/freedreno/a6xx/fd6_blend.c        |  2 +
> >  .../drivers/freedreno/a6xx/fd6_context.c      |  2 +
> >  src/gallium/drivers/freedreno/a6xx/fd6_draw.c |  3 ++
> >  src/gallium/drivers/freedreno/a6xx/fd6_emit.c | 12 ++++--
> >  src/gallium/drivers/freedreno/a6xx/fd6_gmem.c | 37 +++++++++++--------
> >  .../drivers/freedreno/a6xx/fd6_rasterizer.c   |  4 +-
> >  .../drivers/freedreno/a6xx/fd6_screen.c       | 21 +++++++++--
> >  .../drivers/freedreno/a6xx/fd6_texture.c      |  1 +
> >  .../drivers/freedreno/adreno_common.xml.h     |  1 +
> >  .../drivers/freedreno/freedreno_resource.c    |  9 +++++
> >  .../drivers/freedreno/freedreno_util.h        |  2 +
> >  11 files changed, 70 insertions(+), 24 deletions(-)
> >
> > diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_blend.c b/src/gallium/drivers/freedreno/a6xx/fd6_blend.c
> > index 185b061cd1e..f888e162cf9 100644
> > --- a/src/gallium/drivers/freedreno/a6xx/fd6_blend.c
> > +++ b/src/gallium/drivers/freedreno/a6xx/fd6_blend.c
> > @@ -138,8 +138,10 @@ fd6_blend_state_create(struct pipe_context *pctx,
> >         }
> >
> >         so->rb_blend_cntl = A6XX_RB_BLEND_CNTL_ENABLE_BLEND(mrt_blend) |
> > +               COND(cso->alpha_to_coverage, A6XX_RB_BLEND_CNTL_ALPHA_TO_COVERAGE) |
> >                 COND(cso->independent_blend_enable, A6XX_RB_BLEND_CNTL_INDEPENDENT_BLEND);
> >         so->sp_blend_cntl = A6XX_SP_BLEND_CNTL_UNK8 |
> > +               COND(cso->alpha_to_coverage, A6XX_SP_BLEND_CNTL_ALPHA_TO_COVERAGE) |
> >                 COND(mrt_blend, A6XX_SP_BLEND_CNTL_ENABLED);
> >
> >         return so;
> > diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_context.c b/src/gallium/drivers/freedreno/a6xx/fd6_context.c
> > index 3282b7d86cf..35fd03c3d99 100644
> > --- a/src/gallium/drivers/freedreno/a6xx/fd6_context.c
> > +++ b/src/gallium/drivers/freedreno/a6xx/fd6_context.c
> > @@ -104,6 +104,8 @@ fd6_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
> >         if (!pctx)
> >                 return NULL;
> >
> > +       util_blitter_set_texture_multisample(fd6_ctx->base.blitter, true);
> > +
> >         /* fd_context_init overwrites delete_rasterizer_state, so set this
> >          * here. */
> >         pctx->delete_rasterizer_state = fd6_rasterizer_state_delete;
> > diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c
> > index d921a33f5f4..2ac916f03b9 100644
> > --- a/src/gallium/drivers/freedreno/a6xx/fd6_draw.c
> > +++ b/src/gallium/drivers/freedreno/a6xx/fd6_draw.c
> > @@ -378,6 +378,7 @@ fd6_clear(struct fd_context *ctx, unsigned buffers,
> >         struct pipe_framebuffer_state *pfb = &ctx->batch->framebuffer;
> >         struct pipe_scissor_state *scissor = fd_context_get_scissor(ctx);
> >         struct fd_ringbuffer *ring = ctx->batch->draw;
> > +       enum a3xx_msaa_samples samples = fd_msaa_samples(pfb->samples);
> >
> >         OUT_PKT4(ring, REG_A6XX_RB_BLIT_SCISSOR_TL, 2);
> >         OUT_RING(ring, A6XX_RB_BLIT_SCISSOR_TL_X(scissor->minx) |
> > @@ -436,6 +437,7 @@ fd6_clear(struct fd_context *ctx, unsigned buffers,
> >
> >                         OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1);
> >                         OUT_RING(ring, A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) |
> > +                               A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) |
> >                                 A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(fd6_pipe2color(pfmt)));
> >
> >                         OUT_PKT4(ring, REG_A6XX_RB_BLIT_INFO, 1);
> > @@ -485,6 +487,7 @@ fd6_clear(struct fd_context *ctx, unsigned buffers,
> >
> >                 OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 1);
> >                 OUT_RING(ring, A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) |
> > +                       A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) |
> >                         A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(fd6_pipe2color(pfmt)));
> >
> >                 OUT_PKT4(ring, REG_A6XX_RB_BLIT_INFO, 1);
> > diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
> > index 16b0def6a40..deb31b7d360 100644
> > --- a/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
> > +++ b/src/gallium/drivers/freedreno/a6xx/fd6_emit.c
> > @@ -871,14 +871,18 @@ fd6_emit_state(struct fd_ringbuffer *ring, struct fd6_emit *emit)
> >                         OUT_RING(ring, blend_control);
> >                 }
> >
> > -               OUT_PKT4(ring, REG_A6XX_RB_BLEND_CNTL, 1);
> > -               OUT_RING(ring, blend->rb_blend_cntl |
> > -                               A6XX_RB_BLEND_CNTL_SAMPLE_MASK(0xffff));
> > -
> >                 OUT_PKT4(ring, REG_A6XX_SP_BLEND_CNTL, 1);
> >                 OUT_RING(ring, blend->sp_blend_cntl);
> >         }
> >
> > +       if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_SAMPLE_MASK)) {
> > +               struct fd6_blend_stateobj *blend = fd6_blend_stateobj(ctx->blend);
> > +
> > +               OUT_PKT4(ring, REG_A6XX_RB_BLEND_CNTL, 1);
> > +               OUT_RING(ring, blend->rb_blend_cntl |
> > +                               A6XX_RB_BLEND_CNTL_SAMPLE_MASK(ctx->sample_mask));
> > +       }
> > +
> >         if (dirty & FD_DIRTY_BLEND_COLOR) {
> >                 struct pipe_blend_color *bcolor = &ctx->blend_color;
> >
> > diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
> > index 75bbcc7bac4..abe32693c66 100644
> > --- a/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
> > +++ b/src/gallium/drivers/freedreno/a6xx/fd6_gmem.c
> > @@ -89,7 +89,7 @@ emit_mrt(struct fd_ringbuffer *ring, struct pipe_framebuffer_state *pfb,
> >                 offset = fd_resource_offset(rsc, psurf->u.tex.level,
> >                                                                         psurf->u.tex.first_layer);
> >
> > -               stride = slice->pitch * rsc->cpp;
> > +               stride = slice->pitch * rsc->cpp * pfb->samples;
> >
> >                 debug_assert(psurf->u.tex.first_layer == psurf->u.tex.last_layer);
> >                 debug_assert((offset + slice->size0) <= fd_bo_size(rsc->bo));
> > @@ -430,23 +430,27 @@ emit_binning_pass(struct fd_batch *batch)
> >  }
> >
> >  static void
> > -disable_msaa(struct fd_ringbuffer *ring)
> > +emit_msaa(struct fd_ringbuffer *ring, unsigned nr)
> >  {
> > -       // TODO MSAA
> > +       enum a3xx_msaa_samples samples = fd_msaa_samples(nr);
> > +
> >         OUT_PKT4(ring, REG_A6XX_SP_TP_RAS_MSAA_CNTL, 2);
> > -       OUT_RING(ring, A6XX_SP_TP_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE));
> > -       OUT_RING(ring, A6XX_SP_TP_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE) |
> > -                        A6XX_SP_TP_DEST_MSAA_CNTL_MSAA_DISABLE);
> > +       OUT_RING(ring, A6XX_SP_TP_RAS_MSAA_CNTL_SAMPLES(samples));
> > +       OUT_RING(ring, A6XX_SP_TP_DEST_MSAA_CNTL_SAMPLES(samples) |
> > +                        COND(samples == MSAA_ONE, A6XX_SP_TP_DEST_MSAA_CNTL_MSAA_DISABLE));
> >
> >         OUT_PKT4(ring, REG_A6XX_GRAS_RAS_MSAA_CNTL, 2);
> > -       OUT_RING(ring, A6XX_GRAS_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE));
> > -       OUT_RING(ring, A6XX_GRAS_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE) |
> > -                        A6XX_GRAS_DEST_MSAA_CNTL_MSAA_DISABLE);
> > +       OUT_RING(ring, A6XX_GRAS_RAS_MSAA_CNTL_SAMPLES(samples));
> > +       OUT_RING(ring, A6XX_GRAS_DEST_MSAA_CNTL_SAMPLES(samples) |
> > +                        COND(samples == MSAA_ONE, A6XX_GRAS_DEST_MSAA_CNTL_MSAA_DISABLE));
> >
> >         OUT_PKT4(ring, REG_A6XX_RB_RAS_MSAA_CNTL, 2);
> > -       OUT_RING(ring, A6XX_RB_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE));
> > -       OUT_RING(ring, A6XX_RB_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE) |
> > -                        A6XX_RB_DEST_MSAA_CNTL_MSAA_DISABLE);
> > +       OUT_RING(ring, A6XX_RB_RAS_MSAA_CNTL_SAMPLES(samples));
> > +       OUT_RING(ring, A6XX_RB_DEST_MSAA_CNTL_SAMPLES(samples) |
> > +                        COND(samples == MSAA_ONE, A6XX_RB_DEST_MSAA_CNTL_MSAA_DISABLE));
> > +
> > +       OUT_PKT4(ring, REG_A6XX_RB_MSAA_CNTL, 1);
> > +       OUT_RING(ring, A6XX_RB_MSAA_CNTL_SAMPLES(samples));
> >  }
> >
> >  /* before first tile */
> > @@ -477,11 +481,10 @@ fd6_emit_tile_init(struct fd_batch *batch)
> >
> >         emit_zs(ring, pfb->zsbuf, &ctx->gmem);
> >         emit_mrt(ring, pfb, &ctx->gmem);
> > +       emit_msaa(ring, pfb->samples);
> >
> >         patch_gmem_bases(batch);
> >
> > -       disable_msaa(ring);
> > -
> >         if (use_hw_binning(batch)) {
> >                 set_bin_size(ring, gmem->bin_w, gmem->bin_h,
> >                                 A6XX_RB_BIN_CONTROL_BINNING_PASS | 0x6000000);
> > @@ -620,6 +623,8 @@ emit_blit(struct fd_batch *batch, uint32_t base,
> >         uint32_t stride = slice->pitch * rsc->cpp;
> >         uint32_t size = slice->size0;
> >         enum a3xx_color_swap swap = fd6_pipe2swap(pfmt);
> > +       enum a3xx_msaa_samples samples =
> > +                       fd_msaa_samples(rsc->base.nr_samples);
> >
> >         // TODO: tile mode
> >         // bool tiled;
> > @@ -629,6 +634,7 @@ emit_blit(struct fd_batch *batch, uint32_t base,
> >         OUT_PKT4(ring, REG_A6XX_RB_BLIT_DST_INFO, 5);
> >         OUT_RING(ring,
> >                          A6XX_RB_BLIT_DST_INFO_TILE_MODE(TILE6_LINEAR) |
> > +                        A6XX_RB_BLIT_DST_INFO_SAMPLES(samples) |
> >                          A6XX_RB_BLIT_DST_INFO_COLOR_FORMAT(format) |
> >                          A6XX_RB_BLIT_DST_INFO_COLOR_SWAP(swap));
> >         OUT_RELOCW(ring, rsc->bo, offset, 0, 0);  /* RB_BLIT_DST_LO/HI */
> > @@ -871,8 +877,7 @@ fd6_emit_sysmem_prep(struct fd_batch *batch)
> >
> >         emit_zs(ring, pfb->zsbuf, NULL);
> >         emit_mrt(ring, pfb, NULL);
> > -
> > -       disable_msaa(ring);
> > +       emit_msaa(ring, pfb->samples);
> >  }
> >
> >  static void
> > diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c b/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c
> > index 26bb567f65c..a50e471c68f 100644
> > --- a/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c
> > +++ b/src/gallium/drivers/freedreno/a6xx/fd6_rasterizer.c
> > @@ -69,7 +69,9 @@ fd6_rasterizer_state_create(struct pipe_context *pctx,
> >                         A6XX_GRAS_SU_POLY_OFFSET_OFFSET_CLAMP(cso->offset_clamp);
> >
> >         so->gras_su_cntl =
> > -                       A6XX_GRAS_SU_CNTL_LINEHALFWIDTH(cso->line_width/2.0);
> > +                       A6XX_GRAS_SU_CNTL_LINEHALFWIDTH(cso->line_width/2.0) |
> > +                       COND(cso->multisample, A6XX_GRAS_SU_CNTL_MSAA_ENABLE);
> > +
> >  #if 0
> >         so->pc_raster_cntl =
> >                 A6XX_PC_RASTER_CNTL_POLYMODE_FRONT_PTYPE(fd_polygon_mode(cso->fill_front)) |
> > diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_screen.c b/src/gallium/drivers/freedreno/a6xx/fd6_screen.c
> > index 9e039bf87a9..380b6aaff70 100644
> > --- a/src/gallium/drivers/freedreno/a6xx/fd6_screen.c
> > +++ b/src/gallium/drivers/freedreno/a6xx/fd6_screen.c
> > @@ -35,6 +35,21 @@
> >
> >  #include "ir3_compiler.h"
> >
> > +static bool
> > +valid_sample_count(unsigned sample_count)
> > +{
> > +       switch (sample_count) {
> > +       case 0:
> > +       case 1:
> > +       case 2:
> > +       case 4:
> > +       case 8:
> > +               return true;
> > +       default:
> > +               return false;
> > +       }
> > +}
> > +
> >  static boolean
> >  fd6_screen_is_format_supported(struct pipe_screen *pscreen,
> >                 enum pipe_format format,
> > @@ -46,7 +61,7 @@ fd6_screen_is_format_supported(struct pipe_screen *pscreen,
> >         unsigned retval = 0;
> >
> >         if ((target >= PIPE_MAX_TEXTURE_TYPES) ||
> > -                       (sample_count > 1)) { /* TODO add MSAA */
> > +                       !valid_sample_count(sample_count)) {
> >                 DBG("not supported: format=%s, target=%d, sample_count=%d, usage=%x",
> >                                 util_format_name(format), target, sample_count, usage);
> >                 return FALSE;
> > @@ -60,11 +75,11 @@ fd6_screen_is_format_supported(struct pipe_screen *pscreen,
> >                 retval |= PIPE_BIND_VERTEX_BUFFER;
> >         }
> >
> > -       if ((usage & PIPE_BIND_SAMPLER_VIEW) &&
> > +       if ((usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SHADER_IMAGE)) &&
> >                         (target == PIPE_BUFFER ||
> >                          util_format_get_blocksize(format) != 12) &&
> >                         (fd6_pipe2tex(format) != (enum a6xx_tex_fmt)~0)) {
> > -               retval |= PIPE_BIND_SAMPLER_VIEW;
> > +               retval |= usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SHADER_IMAGE);
> >         }
> >
> >         if ((usage & (PIPE_BIND_RENDER_TARGET |
> > diff --git a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c
> > index 0fa20e01e67..373a7937e40 100644
> > --- a/src/gallium/drivers/freedreno/a6xx/fd6_texture.c
> > +++ b/src/gallium/drivers/freedreno/a6xx/fd6_texture.c
> > @@ -245,6 +245,7 @@ fd6_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
> >
> >         so->texconst0 =
> >                 A6XX_TEX_CONST_0_FMT(fd6_pipe2tex(format)) |
> > +               A6XX_TEX_CONST_0_SAMPLES(fd_msaa_samples(prsc->nr_samples)) |
> >                 fd6_tex_swiz(format, cso->swizzle_r, cso->swizzle_g,
> >                                 cso->swizzle_b, cso->swizzle_a);
> >
> > diff --git a/src/gallium/drivers/freedreno/adreno_common.xml.h b/src/gallium/drivers/freedreno/adreno_common.xml.h
> > index 50fab2998e3..4524732db7f 100644
> > --- a/src/gallium/drivers/freedreno/adreno_common.xml.h
> > +++ b/src/gallium/drivers/freedreno/adreno_common.xml.h
> > @@ -161,6 +161,7 @@ enum a3xx_msaa_samples {
> >         MSAA_ONE = 0,
> >         MSAA_TWO = 1,
> >         MSAA_FOUR = 2,
> > +       MSAA_EIGHT = 3,
> >  };
> >
> >  enum a3xx_threadmode {
> > diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
> > index 54d73858962..9c5de2aa6ea 100644
> > --- a/src/gallium/drivers/freedreno/freedreno_resource.c
> > +++ b/src/gallium/drivers/freedreno/freedreno_resource.c
> > @@ -851,6 +851,15 @@ fd_resource_create(struct pipe_screen *pscreen,
> >                                 DRM_FREEDRENO_GEM_TYPE_KMEM; /* TODO */
> >                 unsigned lrz_pitch  = align(DIV_ROUND_UP(tmpl->width0, 8), 64);
> >                 unsigned lrz_height = DIV_ROUND_UP(tmpl->height0, 8);
> > +
> > +               /* LRZ buffer is super-sampled: */
> > +               switch (prsc->nr_samples) {
>
> case 8? Or is that prevented in some way I didn't notice?

quite likely, but I'd need to trace blob to see which way the
dimensions increase.

(otoh this was broken on a5xx for a while before coming across a case
where it was noticed..)

BR,
-R

>
> > +               case 4:
> > +                       lrz_pitch *= 2;
>
> Some people like seeing a /* fallthrough */ in cases like this.
>
> > +               case 2:
> > +                       lrz_height *= 2;
> > +               }
> > +
> >                 unsigned size = lrz_pitch * lrz_height * 2;
> >
> >                 size += 0x1000; /* for GRAS_LRZ_FAST_CLEAR_BUFFER */
> > diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h
> > index 81622506f1e..ff18266b82d 100644
> > --- a/src/gallium/drivers/freedreno/freedreno_util.h
> > +++ b/src/gallium/drivers/freedreno/freedreno_util.h
> > @@ -453,9 +453,11 @@ fd_msaa_samples(unsigned samples)
> >         switch (samples) {
> >         default:
> >                 debug_assert(0);
> > +       case 0:
> >         case 1: return MSAA_ONE;
> >         case 2: return MSAA_TWO;
> >         case 4: return MSAA_FOUR;
> > +       case 8: return MSAA_EIGHT;
> >         }
> >  }
> >
> > --
> > 2.19.1.930.g4563a0d9d0-goog
> >
> > _______________________________________________
> > mesa-dev mailing list
> > mesa-dev at lists.freedesktop.org
> > https://lists.freedesktop.org/mailman/listinfo/mesa-dev
> _______________________________________________
> mesa-dev mailing list
> mesa-dev at lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/mesa-dev


More information about the mesa-dev mailing list