freedreno/a5xx: MSAA
authorRob Clark <robdclark@gmail.com>
Fri, 15 Jun 2018 20:32:42 +0000 (16:32 -0400)
committerRob Clark <robdclark@gmail.com>
Thu, 21 Jun 2018 12:54:47 +0000 (08:54 -0400)
Signed-off-by: Rob Clark <robdclark@gmail.com>
14 files changed:
src/gallium/drivers/freedreno/a5xx/fd5_blend.c
src/gallium/drivers/freedreno/a5xx/fd5_context.c
src/gallium/drivers/freedreno/a5xx/fd5_draw.c
src/gallium/drivers/freedreno/a5xx/fd5_emit.c
src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
src/gallium/drivers/freedreno/a5xx/fd5_screen.c
src/gallium/drivers/freedreno/a5xx/fd5_texture.c
src/gallium/drivers/freedreno/freedreno_batch.h
src/gallium/drivers/freedreno/freedreno_draw.c
src/gallium/drivers/freedreno/freedreno_gmem.c
src/gallium/drivers/freedreno/freedreno_resource.c
src/gallium/drivers/freedreno/freedreno_screen.c
src/gallium/drivers/freedreno/freedreno_state.c
src/gallium/drivers/freedreno/freedreno_util.h

index 98b6d4498e5cfcc1017d3bf08dd9814d212ba246..fee6ba346b769d1882cdef77cefb6f7ea27c6a44 100644 (file)
@@ -140,8 +140,10 @@ fd5_blend_state_create(struct pipe_context *pctx,
        }
 
        so->rb_blend_cntl = A5XX_RB_BLEND_CNTL_ENABLE_BLEND(mrt_blend) |
+               COND(cso->alpha_to_coverage, A5XX_RB_BLEND_CNTL_ALPHA_TO_COVERAGE) |
                COND(cso->independent_blend_enable, A5XX_RB_BLEND_CNTL_INDEPENDENT_BLEND);
        so->sp_blend_cntl = A5XX_SP_BLEND_CNTL_UNK8 |
+               COND(cso->alpha_to_coverage, A5XX_SP_BLEND_CNTL_ALPHA_TO_COVERAGE) |
                COND(mrt_blend, A5XX_SP_BLEND_CNTL_ENABLED);
 
        return so;
index 426a8e0b046fc30c2718c518b3e0cfb941ad628f..c43a8ad2eca7815c6fd2d74da7dc64f734fa82af 100644 (file)
@@ -101,6 +101,8 @@ fd5_context_create(struct pipe_screen *pscreen, void *priv, unsigned flags)
        if (!pctx)
                return NULL;
 
+       util_blitter_set_texture_multisample(fd5_ctx->base.blitter, true);
+
        fd5_ctx->vs_pvt_mem = fd_bo_new(screen->dev, 0x2000,
                        DRM_FREEDRENO_GEM_TYPE_KMEM);
 
index 8c3be5eabc891c2f4005492adf7fec8b0a82f611..56525e0a9a4b37685ad223846f39b1fb50b56d2c 100644 (file)
@@ -106,8 +106,6 @@ fd5_draw_vbo(struct fd_context *ctx, const struct pipe_draw_info *info,
                        .vclamp_color = ctx->rasterizer->clamp_vertex_color,
                        .fclamp_color = ctx->rasterizer->clamp_fragment_color,
                        .rasterflat = ctx->rasterizer->flatshade,
-                       .half_precision = ctx->in_blit &&
-                                       fd_half_precision(&ctx->batch->framebuffer),
                        .ucp_enables = ctx->rasterizer->clip_plane_enable,
                        .has_per_samp = (fd5_ctx->fsaturate || fd5_ctx->vsaturate ||
                                        fd5_ctx->fastc_srgb || fd5_ctx->vastc_srgb),
@@ -209,7 +207,8 @@ fd5_clear_lrz(struct fd_batch *batch, struct fd_resource *zsbuf, double depth)
        OUT_RING(ring, 0x20fffff);
 
        OUT_PKT4(ring, REG_A5XX_GRAS_SU_CNTL, 1);
-       OUT_RING(ring, A5XX_GRAS_SU_CNTL_LINEHALFWIDTH(0.0));
+       OUT_RING(ring, A5XX_GRAS_SU_CNTL_LINEHALFWIDTH(0.0) |
+                       COND(zsbuf->base.nr_samples > 1, A5XX_GRAS_SU_CNTL_MSAA_ENABLE));
 
        OUT_PKT4(ring, REG_A5XX_GRAS_CNTL, 1);
        OUT_RING(ring, 0x00000000);
index 9d17bda476cc848e1c9ea4f24d29419f50d5c4c8..d891e68aabcc2d9208b9b09c904fb6926f5aaa70 100644 (file)
@@ -641,7 +641,8 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                                fd5_rasterizer_stateobj(ctx->rasterizer);
 
                OUT_PKT4(ring, REG_A5XX_GRAS_SU_CNTL, 1);
-               OUT_RING(ring, rasterizer->gras_su_cntl);
+               OUT_RING(ring, rasterizer->gras_su_cntl |
+                               COND(pfb->samples > 1, A5XX_GRAS_SU_CNTL_MSAA_ENABLE));
 
                OUT_PKT4(ring, REG_A5XX_GRAS_SU_POINT_MINMAX, 2);
                OUT_RING(ring, rasterizer->gras_su_point_minmax);
@@ -734,7 +735,7 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                }
        }
 
-       if ((dirty & FD_DIRTY_BLEND)) {
+       if (dirty & FD_DIRTY_BLEND) {
                struct fd5_blend_stateobj *blend = fd5_blend_stateobj(ctx->blend);
                uint32_t i;
 
@@ -764,14 +765,18 @@ fd5_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring,
                        OUT_RING(ring, blend_control);
                }
 
-               OUT_PKT4(ring, REG_A5XX_RB_BLEND_CNTL, 1);
-               OUT_RING(ring, blend->rb_blend_cntl |
-                               A5XX_RB_BLEND_CNTL_SAMPLE_MASK(0xffff));
-
                OUT_PKT4(ring, REG_A5XX_SP_BLEND_CNTL, 1);
                OUT_RING(ring, blend->sp_blend_cntl);
        }
 
+       if (dirty & (FD_DIRTY_BLEND | FD_DIRTY_SAMPLE_MASK)) {
+               struct fd5_blend_stateobj *blend = fd5_blend_stateobj(ctx->blend);
+
+               OUT_PKT4(ring, REG_A5XX_RB_BLEND_CNTL, 1);
+               OUT_RING(ring, blend->rb_blend_cntl |
+                               A5XX_RB_BLEND_CNTL_SAMPLE_MASK(ctx->sample_mask));
+       }
+
        if (dirty & FD_DIRTY_BLEND_COLOR) {
                struct pipe_blend_color *bcolor = &ctx->blend_color;
 
index 1dacef067b3f5a2bba9366f8ed095c5c5bc6504a..4a883eefd5cbe38f6368144cee5ddda1d1418cdd 100644 (file)
@@ -85,7 +85,7 @@ emit_mrt(struct fd_ringbuffer *ring, unsigned nr_bufs,
                                        psurf->u.tex.first_layer);
 
                        if (gmem) {
-                               stride = gmem->bin_w * rsc->cpp;
+                               stride = gmem->bin_w * gmem->cbuf_cpp[i];
                                size = stride * gmem->bin_h;
                                base = gmem->cbuf_base[i];
                        } else {
@@ -580,21 +580,23 @@ fd5_emit_tile_renderprep(struct fd_batch *batch, struct fd_tile *tile)
        emit_zs(ring, pfb->zsbuf, gmem);
        emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, gmem);
 
-       // TODO MSAA
+       enum a3xx_msaa_samples samples = fd_msaa_samples(pfb->samples);
+
        OUT_PKT4(ring, REG_A5XX_TPL1_TP_RAS_MSAA_CNTL, 2);
-       OUT_RING(ring, A5XX_TPL1_TP_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE));
-       OUT_RING(ring, A5XX_TPL1_TP_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE) |
-                       A5XX_TPL1_TP_DEST_MSAA_CNTL_MSAA_DISABLE);
+       OUT_RING(ring, A5XX_TPL1_TP_RAS_MSAA_CNTL_SAMPLES(samples));
+       OUT_RING(ring, A5XX_TPL1_TP_DEST_MSAA_CNTL_SAMPLES(samples) |
+                       COND(samples == MSAA_ONE, A5XX_TPL1_TP_DEST_MSAA_CNTL_MSAA_DISABLE));
 
        OUT_PKT4(ring, REG_A5XX_RB_RAS_MSAA_CNTL, 2);
-       OUT_RING(ring, A5XX_RB_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE));
-       OUT_RING(ring, A5XX_RB_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE) |
-                       A5XX_RB_DEST_MSAA_CNTL_MSAA_DISABLE);
+       OUT_RING(ring, A5XX_RB_RAS_MSAA_CNTL_SAMPLES(samples));
+       OUT_RING(ring, A5XX_RB_DEST_MSAA_CNTL_SAMPLES(samples) |
+                       COND(samples == MSAA_ONE, A5XX_RB_DEST_MSAA_CNTL_MSAA_DISABLE));
+
 
        OUT_PKT4(ring, REG_A5XX_GRAS_SC_RAS_MSAA_CNTL, 2);
-       OUT_RING(ring, A5XX_GRAS_SC_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE));
-       OUT_RING(ring, A5XX_GRAS_SC_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE) |
-                       A5XX_GRAS_SC_DEST_MSAA_CNTL_MSAA_DISABLE);
+       OUT_RING(ring, A5XX_GRAS_SC_RAS_MSAA_CNTL_SAMPLES(samples));
+       OUT_RING(ring, A5XX_GRAS_SC_DEST_MSAA_CNTL_SAMPLES(samples) |
+                       COND(samples == MSAA_ONE, A5XX_GRAS_SC_DEST_MSAA_CNTL_MSAA_DISABLE));
 }
 
 
@@ -640,6 +642,12 @@ emit_gmem2mem_surf(struct fd_batch *batch, uint32_t base,
        OUT_PKT4(ring, REG_A5XX_RB_BLIT_CNTL, 1);
        OUT_RING(ring, A5XX_RB_BLIT_CNTL_BUF(buf));
 
+       struct pipe_framebuffer_state *pfb = &batch->framebuffer;
+//     bool msaa_resolve = pfb->samples > 1;
+       bool msaa_resolve = false;
+       OUT_PKT4(ring, REG_A5XX_RB_CLEAR_CNTL, 1);
+       OUT_RING(ring, COND(msaa_resolve, A5XX_RB_CLEAR_CNTL_MSAA_RESOLVE));
+
        fd5_emit_blit(batch->ctx, ring);
 }
 
@@ -742,7 +750,6 @@ fd5_emit_sysmem_prep(struct fd_batch *batch)
        emit_zs(ring, pfb->zsbuf, NULL);
        emit_mrt(ring, pfb->nr_cbufs, pfb->cbufs, NULL);
 
-       // TODO MSAA
        OUT_PKT4(ring, REG_A5XX_TPL1_TP_RAS_MSAA_CNTL, 2);
        OUT_RING(ring, A5XX_TPL1_TP_RAS_MSAA_CNTL_SAMPLES(MSAA_ONE));
        OUT_RING(ring, A5XX_TPL1_TP_DEST_MSAA_CNTL_SAMPLES(MSAA_ONE) |
index 7d7e76e869c9bbeae7224ba115564d00974bfb75..6f614751f4609158dcff268600ddad87b06bbe38 100644 (file)
 
 #include "ir3_compiler.h"
 
+static bool
+valid_sample_count(unsigned sample_count)
+{
+       switch (sample_count) {
+       case 0:
+       case 1:
+       case 2:
+       case 4:
+               return true;
+       default:
+               return false;
+       }
+}
+
 static boolean
 fd5_screen_is_format_supported(struct pipe_screen *pscreen,
                enum pipe_format format,
@@ -45,7 +59,7 @@ fd5_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) ||
                        !util_format_is_supported(format, usage)) {
                DBG("not supported: format=%s, target=%d, sample_count=%d, usage=%x",
                                util_format_name(format), target, sample_count, usage);
@@ -57,11 +71,11 @@ fd5_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) &&
                        (fd5_pipe2tex(format) != (enum a5xx_tex_fmt)~0)) {
-               retval |= PIPE_BIND_SAMPLER_VIEW;
+               retval |= usage & (PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_SHADER_IMAGE);
        }
 
        if ((usage & (PIPE_BIND_RENDER_TARGET |
index 9795189b6efc94d211df38a4db9144a0eb0b1b32..e8e29d0367a85f319d4c8ea17ca9dfc5ea048071 100644 (file)
@@ -217,6 +217,7 @@ fd5_sampler_view_create(struct pipe_context *pctx, struct pipe_resource *prsc,
 
        so->texconst0 =
                A5XX_TEX_CONST_0_FMT(fd5_pipe2tex(format)) |
+               A5XX_TEX_CONST_0_SAMPLES(fd_msaa_samples(prsc->nr_samples)) |
                fd5_tex_swiz(format, cso->swizzle_r, cso->swizzle_g,
                                cso->swizzle_b, cso->swizzle_a);
 
index 56665b703900424f76122ac53dddd7a0f8af52f6..b113c0713604a254963aa0c25d63ada3089d3110 100644 (file)
@@ -115,7 +115,6 @@ struct fd_batch {
                FD_GMEM_DEPTH_ENABLED        = 0x02,
                FD_GMEM_STENCIL_ENABLED      = 0x04,
 
-               FD_GMEM_MSAA_ENABLED         = 0x08,
                FD_GMEM_BLEND_ENABLED        = 0x10,
                FD_GMEM_LOGICOP_ENABLED      = 0x20,
        } gmem_reason;
index eb36a930751432a86827ad980c0e7bc2459c8255..3bcda342fb83655fae551492240799f6a87d3cb9 100644 (file)
@@ -170,9 +170,6 @@ fd_draw_vbo(struct pipe_context *pctx, const struct pipe_draw_info *info)
 
                buffers |= PIPE_CLEAR_COLOR0 << i;
 
-               if (surf->nr_samples > 1)
-                       batch->gmem_reason |= FD_GMEM_MSAA_ENABLED;
-
                if (fd_blend_enabled(ctx, i))
                        batch->gmem_reason |= FD_GMEM_BLEND_ENABLED;
        }
index 37a2f33365daae527cb56fe5bf709f3e2a59527e..1cd254b3629540e2edf5690815391df9a6ff0ec2 100644 (file)
@@ -135,6 +135,8 @@ calculate_tiles(struct fd_batch *batch)
                        cbuf_cpp[i] = util_format_get_blocksize(pfb->cbufs[i]->format);
                else
                        cbuf_cpp[i] = 4;
+               /* if MSAA, color buffers are super-sampled in GMEM: */
+               cbuf_cpp[i] *= pfb->samples;
        }
 
        if (!memcmp(gmem->zsbuf_cpp, zsbuf_cpp, sizeof(zsbuf_cpp)) &&
@@ -393,9 +395,11 @@ fd_gmem_render_tiles(struct fd_batch *batch)
 
        if (ctx->emit_sysmem_prep && !batch->nondraw) {
                if (batch->cleared || batch->gmem_reason ||
-                               ((batch->num_draws > 5) && !batch->blit)) {
-                       DBG("GMEM: cleared=%x, gmem_reason=%x, num_draws=%u",
-                               batch->cleared, batch->gmem_reason, batch->num_draws);
+                               ((batch->num_draws > 5) && !batch->blit) ||
+                               (pfb->samples > 1)) {
+                       DBG("GMEM: cleared=%x, gmem_reason=%x, num_draws=%u, samples=%u",
+                               batch->cleared, batch->gmem_reason, batch->num_draws,
+                               pfb->samples);
                } else if (!(fd_mesa_debug & FD_DBG_NOBYPASS)) {
                        sysmem = true;
                }
index 7e6de8c057f3ea74fef43b5b79b2f1dad3be0602..8147ff57a990c880303f2c0b804e88fa885ae5c8 100644 (file)
@@ -837,6 +837,8 @@ fd_resource_create(struct pipe_screen *pscreen,
 
        rsc->internal_format = format;
        rsc->cpp = util_format_get_blocksize(format);
+       prsc->nr_samples = MAX2(1, prsc->nr_samples);
+       rsc->cpp *= prsc->nr_samples;
 
        assert(rsc->cpp);
 
@@ -919,8 +921,9 @@ fd_resource_from_handle(struct pipe_screen *pscreen,
        if (!rsc->bo)
                goto fail;
 
+       prsc->nr_samples = MAX2(1, prsc->nr_samples);
        rsc->internal_format = tmpl->format;
-       rsc->cpp = util_format_get_blocksize(tmpl->format);
+       rsc->cpp = prsc->nr_samples * util_format_get_blocksize(tmpl->format);
        slice->pitch = handle->stride / rsc->cpp;
        slice->offset = handle->offset;
        slice->size0 = handle->stride * prsc->height0;
@@ -1030,14 +1033,6 @@ fd_blit(struct pipe_context *pctx, const struct pipe_blit_info *blit_info)
        struct pipe_blit_info info = *blit_info;
        bool discard = false;
 
-       if (info.src.resource->nr_samples > 1 &&
-                       info.dst.resource->nr_samples <= 1 &&
-                       !util_format_is_depth_or_stencil(info.src.resource->format) &&
-                       !util_format_is_pure_integer(info.src.resource->format)) {
-               DBG("color resolve unimplemented");
-               return;
-       }
-
        if (info.render_condition_enable && !fd_render_condition_check(pctx))
                return;
 
index 4d8307121654ad5298d00c90eb0b9672407a8ff6..2e842a8da7d1d5d5223d9aa7f0a710f5f178ef88 100644 (file)
@@ -197,7 +197,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_SHADER_STENCIL_EXPORT:
        case PIPE_CAP_TGSI_TEXCOORD:
        case PIPE_CAP_PREFER_BLIT_BASED_TEXTURE_TRANSFER:
-       case PIPE_CAP_TEXTURE_MULTISAMPLE:
        case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
        case PIPE_CAP_QUERY_MEMORY_INFO:
        case PIPE_CAP_PCI_GROUP:
@@ -216,11 +215,16 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_TEXTURE_HALF_FLOAT_LINEAR:
        case PIPE_CAP_CONDITIONAL_RENDER:
        case PIPE_CAP_CONDITIONAL_RENDER_INVERTED:
-       case PIPE_CAP_FAKE_SW_MSAA:
        case PIPE_CAP_SEAMLESS_CUBE_MAP_PER_TEXTURE:
        case PIPE_CAP_CLIP_HALFZ:
                return is_a3xx(screen) || is_a4xx(screen) || is_a5xx(screen);
 
+       case PIPE_CAP_FAKE_SW_MSAA:
+               return !fd_screen_get_param(pscreen, PIPE_CAP_TEXTURE_MULTISAMPLE);
+
+       case PIPE_CAP_TEXTURE_MULTISAMPLE:
+               return is_a5xx(screen);
+
        case PIPE_CAP_DEPTH_CLIP_DISABLE:
                return is_a3xx(screen) || is_a4xx(screen);
 
index 7f9d19aa5263159bac40ba2b312d72602a1b1dce..88f6fb557d0ecc0f8a47f726f45fbfc65c2d63c8 100644 (file)
@@ -245,6 +245,8 @@ fd_set_framebuffer_state(struct pipe_context *pctx,
 
        util_copy_framebuffer_state(cso, framebuffer);
 
+       cso->samples = util_framebuffer_get_num_samples(cso);
+
        ctx->dirty |= FD_DIRTY_FRAMEBUFFER;
 
        ctx->disabled_scissor.minx = 0;
index b3511d8f15e95897e175d0af81d56307765ef150..9645561e07105887ccf72af76a6982b43896edf2 100644 (file)
@@ -430,6 +430,22 @@ pack_rgba(enum pipe_format format, const float *rgba)
 
 #define BIT(bit) (1u << bit)
 
+/*
+ * a3xx+ helpers:
+ */
+
+static inline enum a3xx_msaa_samples
+fd_msaa_samples(unsigned samples)
+{
+       switch (samples) {
+       default:
+               debug_assert(0);
+       case 1: return MSAA_ONE;
+       case 2: return MSAA_TWO;
+       case 4: return MSAA_FOUR;
+       }
+}
+
 /*
  * a4xx+ helpers:
  */