summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRob Clark <[email protected]>2018-06-15 16:32:42 -0400
committerRob Clark <[email protected]>2018-06-21 08:54:47 -0400
commitcf0c7258ee0524709ab6d05a9aafc7415361bd23 (patch)
tree1d22ac00b91293e71253373586dd79c1506a3442
parentb6e690ef80f71cc62fa1095a2601087341be22a3 (diff)
freedreno/a5xx: MSAA
Signed-off-by: Rob Clark <[email protected]>
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_blend.c2
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_context.c2
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_draw.c5
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_emit.c17
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_gmem.c31
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_screen.c20
-rw-r--r--src/gallium/drivers/freedreno/a5xx/fd5_texture.c1
-rw-r--r--src/gallium/drivers/freedreno/freedreno_batch.h1
-rw-r--r--src/gallium/drivers/freedreno/freedreno_draw.c3
-rw-r--r--src/gallium/drivers/freedreno/freedreno_gmem.c10
-rw-r--r--src/gallium/drivers/freedreno/freedreno_resource.c13
-rw-r--r--src/gallium/drivers/freedreno/freedreno_screen.c8
-rw-r--r--src/gallium/drivers/freedreno/freedreno_state.c2
-rw-r--r--src/gallium/drivers/freedreno/freedreno_util.h16
14 files changed, 89 insertions, 42 deletions
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_blend.c b/src/gallium/drivers/freedreno/a5xx/fd5_blend.c
index 98b6d4498e5..fee6ba346b7 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_blend.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_blend.c
@@ -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;
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_context.c b/src/gallium/drivers/freedreno/a5xx/fd5_context.c
index 426a8e0b046..c43a8ad2eca 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_context.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_context.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
index 8c3be5eabc8..56525e0a9a4 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_draw.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
index 9d17bda476c..d891e68aabc 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_emit.c
@@ -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;
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c b/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
index 1dacef067b3..4a883eefd5c 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_gmem.c
@@ -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) |
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_screen.c b/src/gallium/drivers/freedreno/a5xx/fd5_screen.c
index 7d7e76e869c..6f614751f46 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_screen.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_screen.c
@@ -35,6 +35,20 @@
#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 |
diff --git a/src/gallium/drivers/freedreno/a5xx/fd5_texture.c b/src/gallium/drivers/freedreno/a5xx/fd5_texture.c
index 9795189b6ef..e8e29d0367a 100644
--- a/src/gallium/drivers/freedreno/a5xx/fd5_texture.c
+++ b/src/gallium/drivers/freedreno/a5xx/fd5_texture.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/freedreno_batch.h b/src/gallium/drivers/freedreno/freedreno_batch.h
index 56665b70390..b113c071360 100644
--- a/src/gallium/drivers/freedreno/freedreno_batch.h
+++ b/src/gallium/drivers/freedreno/freedreno_batch.h
@@ -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;
diff --git a/src/gallium/drivers/freedreno/freedreno_draw.c b/src/gallium/drivers/freedreno/freedreno_draw.c
index eb36a930751..3bcda342fb8 100644
--- a/src/gallium/drivers/freedreno/freedreno_draw.c
+++ b/src/gallium/drivers/freedreno/freedreno_draw.c
@@ -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;
}
diff --git a/src/gallium/drivers/freedreno/freedreno_gmem.c b/src/gallium/drivers/freedreno/freedreno_gmem.c
index 37a2f33365d..1cd254b3629 100644
--- a/src/gallium/drivers/freedreno/freedreno_gmem.c
+++ b/src/gallium/drivers/freedreno/freedreno_gmem.c
@@ -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;
}
diff --git a/src/gallium/drivers/freedreno/freedreno_resource.c b/src/gallium/drivers/freedreno/freedreno_resource.c
index 7e6de8c057f..8147ff57a99 100644
--- a/src/gallium/drivers/freedreno/freedreno_resource.c
+++ b/src/gallium/drivers/freedreno/freedreno_resource.c
@@ -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;
diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c
index 4d830712165..2e842a8da7d 100644
--- a/src/gallium/drivers/freedreno/freedreno_screen.c
+++ b/src/gallium/drivers/freedreno/freedreno_screen.c
@@ -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);
diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c
index 7f9d19aa526..88f6fb557d0 100644
--- a/src/gallium/drivers/freedreno/freedreno_state.c
+++ b/src/gallium/drivers/freedreno/freedreno_state.c
@@ -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;
diff --git a/src/gallium/drivers/freedreno/freedreno_util.h b/src/gallium/drivers/freedreno/freedreno_util.h
index b3511d8f15e..9645561e071 100644
--- a/src/gallium/drivers/freedreno/freedreno_util.h
+++ b/src/gallium/drivers/freedreno/freedreno_util.h
@@ -431,6 +431,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:
*/