From aa354b92d259d9fc5e85c49c76719ebc8e3c1b4a Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 26 Jan 2015 01:08:31 +0800 Subject: [PATCH] ilo: clean up ilo_gpe_init_blend() Make ilo_blend_state more space efficient and forward-looking. --- .../drivers/ilo/ilo_builder_3d_bottom.h | 9 +- src/gallium/drivers/ilo/ilo_state.h | 8 +- src/gallium/drivers/ilo/ilo_state_3d_bottom.c | 176 ++++++++++-------- 3 files changed, 106 insertions(+), 87 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h index f137232bcaa..2c3efb6ca2f 100644 --- a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h +++ b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h @@ -1232,11 +1232,10 @@ gen6_BLEND_STATE(struct ilo_builder *builder, ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw); for (i = 0; i < num_targets; i++) { - const struct ilo_blend_cso *cso = - &blend->cso[(blend->independent_blend_enable) ? i : 0]; + const struct ilo_blend_cso *cso = &blend->cso[i]; dw[0] = cso->payload[0]; - dw[1] = cso->payload[1]; + dw[1] = cso->payload[1] | blend->dw_shared; if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) { const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i]; @@ -1249,7 +1248,7 @@ gen6_BLEND_STATE(struct ilo_builder *builder, } if (caps->can_logicop) - dw[1] |= cso->dw_logicop; + dw[1] |= blend->dw_logicop; if (caps->can_alpha_test) dw[1] |= dsa->dw_alpha; @@ -1271,7 +1270,7 @@ gen6_BLEND_STATE(struct ilo_builder *builder, * requires that anyway. */ if (fb->num_samples > 1) - dw[1] |= cso->dw_alpha_mod; + dw[1] |= blend->dw_alpha_mod; dw += 2; } diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h index afe27847a93..cecca3e4abd 100644 --- a/src/gallium/drivers/ilo/ilo_state.h +++ b/src/gallium/drivers/ilo/ilo_state.h @@ -252,17 +252,17 @@ struct ilo_blend_cso { uint32_t dw_blend; uint32_t dw_blend_dst_alpha_forced_one; - - uint32_t dw_logicop; - uint32_t dw_alpha_mod; }; struct ilo_blend_state { struct ilo_blend_cso cso[ILO_MAX_DRAW_BUFFERS]; - bool independent_blend_enable; bool dual_blend; bool alpha_to_coverage; + + uint32_t dw_shared; + uint32_t dw_alpha_mod; + uint32_t dw_logicop; }; struct ilo_sampler_cso { diff --git a/src/gallium/drivers/ilo/ilo_state_3d_bottom.c b/src/gallium/drivers/ilo/ilo_state_3d_bottom.c index 822f8a46f68..d926ec5e7ae 100644 --- a/src/gallium/drivers/ilo/ilo_state_3d_bottom.c +++ b/src/gallium/drivers/ilo/ilo_state_3d_bottom.c @@ -1245,13 +1245,15 @@ gen6_blend_factor_dst_alpha_forced_one(int factor) } static uint32_t -blend_get_rt_blend_enable(const struct ilo_dev_info *dev, - const struct pipe_rt_blend_state *rt, - bool dst_alpha_forced_one) +blend_get_rt_blend_enable_gen6(const struct ilo_dev_info *dev, + const struct pipe_rt_blend_state *rt, + bool dst_alpha_forced_one) { int rgb_src, rgb_dst, a_src, a_dst; uint32_t dw; + ILO_DEV_ASSERT(dev, 6, 7.5); + if (!rt->blend_enable) return 0; @@ -1267,7 +1269,7 @@ blend_get_rt_blend_enable(const struct ilo_dev_info *dev, a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst); } - dw = 1 << 31 | + dw = GEN6_BLEND_DW0_BLEND_ENABLE | gen6_translate_pipe_blend(rt->alpha_func) << 26 | a_src << 20 | a_dst << 15 | @@ -1277,102 +1279,120 @@ blend_get_rt_blend_enable(const struct ilo_dev_info *dev, if (rt->rgb_func != rt->alpha_func || rgb_src != a_src || rgb_dst != a_dst) - dw |= 1 << 30; + dw |= GEN6_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE; return dw; } -void -ilo_gpe_init_blend(const struct ilo_dev_info *dev, - const struct pipe_blend_state *state, - struct ilo_blend_state *blend) +static void +blend_init_cso_gen6(const struct ilo_dev_info *dev, + const struct pipe_blend_state *state, + struct ilo_blend_state *blend, + unsigned index) { - unsigned num_cso, i; + const struct pipe_rt_blend_state *rt = &state->rt[index]; + struct ilo_blend_cso *cso = &blend->cso[index]; ILO_DEV_ASSERT(dev, 6, 7.5); - if (state->independent_blend_enable) { - num_cso = Elements(blend->cso); - } - else { - memset(blend->cso, 0, sizeof(blend->cso)); - num_cso = 1; - } + cso->payload[0] = 0; + cso->payload[1] = GEN6_BLEND_DW1_COLORCLAMP_RTFORMAT | + GEN6_BLEND_DW1_PRE_BLEND_CLAMP | + GEN6_BLEND_DW1_POST_BLEND_CLAMP; - blend->independent_blend_enable = state->independent_blend_enable; - blend->alpha_to_coverage = state->alpha_to_coverage; - blend->dual_blend = false; - - for (i = 0; i < num_cso; i++) { - const struct pipe_rt_blend_state *rt = &state->rt[i]; - struct ilo_blend_cso *cso = &blend->cso[i]; - bool dual_blend; + if (!(rt->colormask & PIPE_MASK_A)) + cso->payload[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_A; + if (!(rt->colormask & PIPE_MASK_R)) + cso->payload[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_R; + if (!(rt->colormask & PIPE_MASK_G)) + cso->payload[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_G; + if (!(rt->colormask & PIPE_MASK_B)) + cso->payload[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_B; - cso->payload[0] = 0; - cso->payload[1] = GEN6_BLEND_DW1_COLORCLAMP_RTFORMAT | - 0x3; + /* + * From the Sandy Bridge PRM, volume 2 part 1, page 365: + * + * "Color Buffer Blending and Logic Ops must not be enabled + * simultaneously, or behavior is UNDEFINED." + * + * Since state->logicop_enable takes precedence over rt->blend_enable, + * no special care is needed. + */ + if (state->logicop_enable) { + cso->dw_blend = 0; + cso->dw_blend_dst_alpha_forced_one = 0; + } else { + cso->dw_blend = blend_get_rt_blend_enable_gen6(dev, rt, false); + cso->dw_blend_dst_alpha_forced_one = + blend_get_rt_blend_enable_gen6(dev, rt, true); + } +} - if (!(rt->colormask & PIPE_MASK_A)) - cso->payload[1] |= 1 << 27; - if (!(rt->colormask & PIPE_MASK_R)) - cso->payload[1] |= 1 << 26; - if (!(rt->colormask & PIPE_MASK_G)) - cso->payload[1] |= 1 << 25; - if (!(rt->colormask & PIPE_MASK_B)) - cso->payload[1] |= 1 << 24; +static uint32_t +blend_get_logicop_enable_gen6(const struct ilo_dev_info *dev, + const struct pipe_blend_state *state) +{ + ILO_DEV_ASSERT(dev, 6, 7.5); - if (state->dither) - cso->payload[1] |= 1 << 12; + if (!state->logicop_enable) + return 0; - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 365: - * - * "Color Buffer Blending and Logic Ops must not be enabled - * simultaneously, or behavior is UNDEFINED." - * - * Since state->logicop_enable takes precedence over rt->blend_enable, - * no special care is needed. - */ - if (state->logicop_enable) { - cso->dw_logicop = 1 << 22 | - gen6_translate_pipe_logicop(state->logicop_func) << 18; + return GEN6_BLEND_DW1_LOGICOP_ENABLE | + gen6_translate_pipe_logicop(state->logicop_func) << 18; +} - cso->dw_blend = 0; - cso->dw_blend_dst_alpha_forced_one = 0; +static uint32_t +blend_get_alpha_mod_gen6(const struct ilo_dev_info *dev, + const struct pipe_blend_state *state, + bool dual_blend) +{ + uint32_t dw = 0; - dual_blend = false; - } - else { - cso->dw_logicop = 0; + ILO_DEV_ASSERT(dev, 6, 7.5); - cso->dw_blend = blend_get_rt_blend_enable(dev, rt, false); - cso->dw_blend_dst_alpha_forced_one = - blend_get_rt_blend_enable(dev, rt, true); + if (state->alpha_to_coverage) { + dw |= GEN6_BLEND_DW1_ALPHA_TO_COVERAGE; + if (ilo_dev_gen(dev) >= ILO_GEN(7)) + dw |= GEN6_BLEND_DW1_ALPHA_TO_COVERAGE_DITHER; + } + /* + * From the Sandy Bridge PRM, volume 2 part 1, page 378: + * + * "If Dual Source Blending is enabled, this bit (AlphaToOne Enable) + * must be disabled." + */ + if (state->alpha_to_one && !dual_blend) + dw |= GEN6_BLEND_DW1_ALPHA_TO_ONE; - dual_blend = (rt->blend_enable && - util_blend_state_is_dual(state, i)); - } + return dw; +} - cso->dw_alpha_mod = 0; +void +ilo_gpe_init_blend(const struct ilo_dev_info *dev, + const struct pipe_blend_state *state, + struct ilo_blend_state *blend) +{ + unsigned i; - if (state->alpha_to_coverage) { - cso->dw_alpha_mod |= 1 << 31; + ILO_DEV_ASSERT(dev, 6, 7.5); - if (ilo_dev_gen(dev) >= ILO_GEN(7)) - cso->dw_alpha_mod |= 1 << 29; - } + blend->dual_blend = (util_blend_state_is_dual(state, 0) && + state->rt[0].blend_enable && + !state->logicop_enable); + blend->alpha_to_coverage = state->alpha_to_coverage; - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 378: - * - * "If Dual Source Blending is enabled, this bit (AlphaToOne Enable) - * must be disabled." - */ - if (state->alpha_to_one && !dual_blend) - cso->dw_alpha_mod |= 1 << 30; + blend->dw_alpha_mod = + blend_get_alpha_mod_gen6(dev, state, blend->dual_blend); + blend->dw_logicop = blend_get_logicop_enable_gen6(dev, state); + blend->dw_shared = (state->dither) ? GEN6_BLEND_DW1_DITHER_ENABLE : 0; - if (dual_blend) - blend->dual_blend = true; + blend_init_cso_gen6(dev, state, blend, 0); + if (state->independent_blend_enable) { + for (i = 1; i < Elements(blend->cso); i++) + blend_init_cso_gen6(dev, state, blend, i); + } else { + for (i = 1; i < Elements(blend->cso); i++) + blend->cso[i] = blend->cso[0]; } } -- 2.30.2