}
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;
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);
.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),
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);
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);
}
}
- if ((dirty & FD_DIRTY_BLEND)) {
+ if (dirty & FD_DIRTY_BLEND) {
struct fd5_blend_stateobj *blend = fd5_blend_stateobj(ctx->blend);
uint32_t i;
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;
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 {
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));
}
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);
}
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) |
#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,
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);
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 |
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);
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;
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;
}
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)) &&
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;
}
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);
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;
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;
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:
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);
util_copy_framebuffer_state(cso, framebuffer);
+ cso->samples = util_framebuffer_get_num_samples(cso);
+
ctx->dirty |= FD_DIRTY_FRAMEBUFFER;
ctx->disabled_scissor.minx = 0;
#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:
*/