diff options
author | Ilia Mirkin <[email protected]> | 2015-09-13 19:50:45 -0400 |
---|---|---|
committer | Ilia Mirkin <[email protected]> | 2015-09-16 15:42:54 -0400 |
commit | ee6b95c82c3dbfad07e75ecdfd993e60fec2ac4f (patch) | |
tree | 54d951f375f0ad3bbd3c24dd57f96357b3c69df1 | |
parent | cfa980f49356eb2d94178f8cc9d67d01b4e3d695 (diff) |
freedreno/a3xx: add support for dual-source blending
Signed-off-by: Ilia Mirkin <[email protected]>
-rw-r--r-- | docs/relnotes/11.1.0.html | 1 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_blend.c | 4 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_blend.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/a3xx/fd3_emit.c | 14 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_context.h | 1 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_screen.c | 3 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_state.c | 10 | ||||
-rw-r--r-- | src/gallium/drivers/freedreno/freedreno_util.c | 5 |
8 files changed, 33 insertions, 6 deletions
diff --git a/docs/relnotes/11.1.0.html b/docs/relnotes/11.1.0.html index 6abdf7ad855..24fdf2e9683 100644 --- a/docs/relnotes/11.1.0.html +++ b/docs/relnotes/11.1.0.html @@ -44,6 +44,7 @@ Note: some of the new features are only available with certain drivers. </p> <ul> +<li>GL_ARB_blend_func_extended on freedreno (a3xx)</li> <li>GL_ARB_shader_texture_image_samples on i965, nv50, nvc0, r600</li> <li>GL_ARB_texture_query_lod on softpipe</li> <li>GL_ARB_gpu_shader_fp64 on r600 for Cypress/Cayman/Aruba chips</li> diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_blend.c b/src/gallium/drivers/freedreno/a3xx/fd3_blend.c index 6f5de9d47f7..35360f33822 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_blend.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_blend.c @@ -28,6 +28,7 @@ #include "pipe/p_state.h" #include "util/u_blend.h" +#include "util/u_dual_blend.h" #include "util/u_string.h" #include "util/u_memory.h" @@ -131,5 +132,8 @@ fd3_blend_state_create(struct pipe_context *pctx, so->rb_mrt[i].control |= A3XX_RB_MRT_CONTROL_DITHER_MODE(DITHER_ALWAYS); } + if (cso->rt[0].blend_enable && util_blend_state_is_dual(cso, 0)) + so->rb_render_control = A3XX_RB_RENDER_CONTROL_DUAL_COLOR_IN_ENABLE; + return so; } diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_blend.h b/src/gallium/drivers/freedreno/a3xx/fd3_blend.h index 142df7c300f..59e0010372d 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_blend.h +++ b/src/gallium/drivers/freedreno/a3xx/fd3_blend.h @@ -36,6 +36,7 @@ struct fd3_blend_stateobj { struct pipe_blend_state base; + uint32_t rb_render_control; struct { /* Blend control bits for color if there is an alpha channel */ uint32_t blend_control_rgb; diff --git a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c index b81bc5a90a4..40301971d90 100644 --- a/src/gallium/drivers/freedreno/a3xx/fd3_emit.c +++ b/src/gallium/drivers/freedreno/a3xx/fd3_emit.c @@ -443,8 +443,10 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, A3XX_RB_MSAA_CONTROL_SAMPLE_MASK(ctx->sample_mask)); } - if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG)) && !emit->key.binning_pass) { - uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_render_control; + if ((dirty & (FD_DIRTY_ZSA | FD_DIRTY_PROG | FD_DIRTY_BLEND_DUAL)) && + !emit->key.binning_pass) { + uint32_t val = fd3_zsa_stateobj(ctx->zsa)->rb_render_control | + fd3_blend_stateobj(ctx->blend)->rb_render_control; val |= COND(fp->frag_face, A3XX_RB_RENDER_CONTROL_FACENESS); val |= COND(fp->frag_coord, A3XX_RB_RENDER_CONTROL_XCOORD | @@ -590,9 +592,13 @@ fd3_emit_state(struct fd_context *ctx, struct fd_ringbuffer *ring, OUT_RING(ring, A3XX_GRAS_CL_VPORT_ZSCALE(ctx->viewport.scale[2])); } - if (dirty & (FD_DIRTY_PROG | FD_DIRTY_FRAMEBUFFER)) { + if (dirty & (FD_DIRTY_PROG | FD_DIRTY_FRAMEBUFFER | FD_DIRTY_BLEND_DUAL)) { struct pipe_framebuffer_state *pfb = &ctx->framebuffer; - fd3_program_emit(ring, emit, pfb->nr_cbufs, pfb->cbufs); + int nr_cbufs = pfb->nr_cbufs; + if (fd3_blend_stateobj(ctx->blend)->rb_render_control & + A3XX_RB_RENDER_CONTROL_DUAL_COLOR_IN_ENABLE) + nr_cbufs++; + fd3_program_emit(ring, emit, nr_cbufs, pfb->cbufs); } /* TODO we should not need this or fd_wfi() before emit_constants(): diff --git a/src/gallium/drivers/freedreno/freedreno_context.h b/src/gallium/drivers/freedreno/freedreno_context.h index 3486c2fd1b7..61c4c6d6e24 100644 --- a/src/gallium/drivers/freedreno/freedreno_context.h +++ b/src/gallium/drivers/freedreno/freedreno_context.h @@ -335,6 +335,7 @@ struct fd_context { FD_DIRTY_SCISSOR = (1 << 17), FD_DIRTY_STREAMOUT = (1 << 18), FD_DIRTY_UCP = (1 << 19), + FD_DIRTY_BLEND_DUAL = (1 << 20), } dirty; struct pipe_blend_state *blend; diff --git a/src/gallium/drivers/freedreno/freedreno_screen.c b/src/gallium/drivers/freedreno/freedreno_screen.c index a3dede2500e..9a684d4ffbb 100644 --- a/src/gallium/drivers/freedreno/freedreno_screen.c +++ b/src/gallium/drivers/freedreno/freedreno_screen.c @@ -163,7 +163,6 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) case PIPE_CAP_TEXTURE_MULTISAMPLE: case PIPE_CAP_TEXTURE_BARRIER: case PIPE_CAP_TEXTURE_MIRROR_CLAMP: - case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: case PIPE_CAP_START_INSTANCE: case PIPE_CAP_COMPUTE: return 0; @@ -278,6 +277,8 @@ fd_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param) /* Render targets. */ case PIPE_CAP_MAX_RENDER_TARGETS: return screen->max_rts; + case PIPE_CAP_MAX_DUAL_SOURCE_RENDER_TARGETS: + return is_a3xx(screen) ? 1 : 0; /* Queries. */ case PIPE_CAP_QUERY_TIME_ELAPSED: diff --git a/src/gallium/drivers/freedreno/freedreno_state.c b/src/gallium/drivers/freedreno/freedreno_state.c index e75865a9387..685d3a75659 100644 --- a/src/gallium/drivers/freedreno/freedreno_state.c +++ b/src/gallium/drivers/freedreno/freedreno_state.c @@ -27,6 +27,7 @@ */ #include "pipe/p_state.h" +#include "util/u_dual_blend.h" #include "util/u_string.h" #include "util/u_memory.h" #include "util/u_helpers.h" @@ -225,8 +226,17 @@ static void fd_blend_state_bind(struct pipe_context *pctx, void *hwcso) { struct fd_context *ctx = fd_context(pctx); + struct pipe_blend_state *cso = hwcso; + bool old_is_dual = ctx->blend ? + ctx->blend->rt[0].blend_enable && util_blend_state_is_dual(ctx->blend, 0) : + false; + bool new_is_dual = cso ? + cso->rt[0].blend_enable && util_blend_state_is_dual(cso, 0) : + false; ctx->blend = hwcso; ctx->dirty |= FD_DIRTY_BLEND; + if (old_is_dual != new_is_dual) + ctx->dirty |= FD_DIRTY_BLEND_DUAL; } static void diff --git a/src/gallium/drivers/freedreno/freedreno_util.c b/src/gallium/drivers/freedreno/freedreno_util.c index 2acce06d148..c8f2127c910 100644 --- a/src/gallium/drivers/freedreno/freedreno_util.c +++ b/src/gallium/drivers/freedreno/freedreno_util.c @@ -104,10 +104,13 @@ fd_blend_factor(unsigned factor) case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return FACTOR_ONE_MINUS_CONSTANT_ALPHA; case PIPE_BLENDFACTOR_INV_SRC1_COLOR: + return FACTOR_ONE_MINUS_SRC1_COLOR; case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: + return FACTOR_ONE_MINUS_SRC1_ALPHA; case PIPE_BLENDFACTOR_SRC1_COLOR: + return FACTOR_SRC1_COLOR; case PIPE_BLENDFACTOR_SRC1_ALPHA: - /* I don't think these are supported */ + return FACTOR_SRC1_ALPHA; default: DBG("invalid blend factor: %x", factor); return 0; |