From d388d8576f004cbc6e659ab7e7b0e9af938f7068 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 10 Nov 2014 13:44:45 +0800 Subject: [PATCH] ilo: derive fb blending caps at bind time Derive whether a RT supports blending, logicop, and the like when set_framebuffer_state() is called. This enables us to simplify gen6_BLEND_STATE(). Signed-off-by: Chia-I Wu --- .../drivers/ilo/ilo_builder_3d_bottom.h | 91 +++++-------------- src/gallium/drivers/ilo/ilo_state.h | 7 ++ src/gallium/drivers/ilo/ilo_state_3d_bottom.c | 81 +++++++++++++++-- 3 files changed, 101 insertions(+), 78 deletions(-) diff --git a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h index 456a494d12b..2397a2c7943 100644 --- a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h +++ b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h @@ -1224,71 +1224,35 @@ gen6_BLEND_STATE(struct ilo_builder *builder, ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw); for (i = 0; i < num_targets; i++) { - const unsigned idx = (blend->independent_blend_enable) ? i : 0; - const struct ilo_blend_cso *cso = &blend->cso[idx]; - const int num_samples = fb->num_samples; - const struct util_format_description *format_desc = - (idx < fb->state.nr_cbufs && fb->state.cbufs[idx]) ? - util_format_description(fb->state.cbufs[idx]->format) : NULL; - bool rt_is_unorm, rt_is_pure_integer, rt_dst_alpha_forced_one; - - rt_is_unorm = true; - rt_is_pure_integer = false; - rt_dst_alpha_forced_one = false; - - if (format_desc) { - int ch; - - switch (format_desc->format) { - case PIPE_FORMAT_B8G8R8X8_UNORM: - /* force alpha to one when the HW format has alpha */ - assert(ilo_translate_render_format(builder->dev, - PIPE_FORMAT_B8G8R8X8_UNORM) == - GEN6_FORMAT_B8G8R8A8_UNORM); - rt_dst_alpha_forced_one = true; - break; - default: - break; - } + const struct ilo_blend_cso *cso = + &blend->cso[(blend->independent_blend_enable) ? i : 0]; - for (ch = 0; ch < 4; ch++) { - if (format_desc->channel[ch].type == UTIL_FORMAT_TYPE_VOID) - continue; + dw[0] = cso->payload[0]; + dw[1] = cso->payload[1]; - if (format_desc->channel[ch].pure_integer) { - rt_is_unorm = false; - rt_is_pure_integer = true; - break; - } + if (i < fb->state.nr_cbufs && fb->state.cbufs[i]) { + const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i]; - if (!format_desc->channel[ch].normalized || - format_desc->channel[ch].type != UTIL_FORMAT_TYPE_UNSIGNED) - rt_is_unorm = false; + if (caps->can_blend) { + if (caps->dst_alpha_forced_one) + dw[0] |= cso->dw_blend_dst_alpha_forced_one; + else + dw[0] |= cso->dw_blend; } - } - dw[0] = cso->payload[0]; - dw[1] = cso->payload[1]; - - if (!rt_is_pure_integer) { - if (rt_dst_alpha_forced_one) - dw[0] |= cso->dw_blend_dst_alpha_forced_one; - else - dw[0] |= cso->dw_blend; + if (caps->can_logicop) + dw[1] |= cso->dw_logicop; + + if (caps->can_alpha_test) + dw[1] |= dsa->dw_alpha; + } else { + dw[1] |= GEN6_BLEND_DW1_WRITE_DISABLE_A | + GEN6_BLEND_DW1_WRITE_DISABLE_R | + GEN6_BLEND_DW1_WRITE_DISABLE_G | + GEN6_BLEND_DW1_WRITE_DISABLE_B | + dsa->dw_alpha; } - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 365: - * - * "Logic Ops are only supported on *_UNORM surfaces (excluding - * _SRGB variants), otherwise Logic Ops must be DISABLED." - * - * Since logicop is ignored for non-UNORM color buffers, no special care - * is needed. - */ - if (rt_is_unorm) - dw[1] |= cso->dw_logicop; - /* * From the Sandy Bridge PRM, volume 2 part 1, page 356: * @@ -1298,18 +1262,9 @@ gen6_BLEND_STATE(struct ilo_builder *builder, * There is no such limitation on GEN7, or for AlphaToOne. But GL * requires that anyway. */ - if (num_samples > 1) + if (fb->num_samples > 1) dw[1] |= cso->dw_alpha_mod; - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 382: - * - * "Alpha Test can only be enabled if Pixel Shader outputs a float - * alpha value." - */ - if (!rt_is_pure_integer) - dw[1] |= dsa->dw_alpha; - dw += 2; } diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h index 6f544e1f788..afe27847a93 100644 --- a/src/gallium/drivers/ilo/ilo_state.h +++ b/src/gallium/drivers/ilo/ilo_state.h @@ -347,6 +347,13 @@ struct ilo_fb_state { struct ilo_view_surface null_rt; struct ilo_zs_surface null_zs; + struct ilo_fb_blend_caps { + bool can_logicop; + bool can_blend; + bool can_alpha_test; + bool dst_alpha_forced_one; + } blend_caps[PIPE_MAX_COLOR_BUFS]; + unsigned num_samples; }; diff --git a/src/gallium/drivers/ilo/ilo_state_3d_bottom.c b/src/gallium/drivers/ilo/ilo_state_3d_bottom.c index a390124c2e9..822f8a46f68 100644 --- a/src/gallium/drivers/ilo/ilo_state_3d_bottom.c +++ b/src/gallium/drivers/ilo/ilo_state_3d_bottom.c @@ -1540,13 +1540,70 @@ ilo_gpe_set_scissor_null(const struct ilo_dev_info *dev, } } +static void +fb_set_blend_caps(const struct ilo_dev_info *dev, + enum pipe_format format, + struct ilo_fb_blend_caps *caps) +{ + const struct util_format_description *desc = + util_format_description(format); + const int ch = util_format_get_first_non_void_channel(format); + + memset(caps, 0, sizeof(*caps)); + + if (format == PIPE_FORMAT_NONE || desc->is_mixed) + return; + + /* + * From the Sandy Bridge PRM, volume 2 part 1, page 365: + * + * "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB + * variants), otherwise Logic Ops must be DISABLED." + */ + caps->can_logicop = (ch >= 0 && desc->channel[ch].normalized && + desc->channel[ch].type == UTIL_FORMAT_TYPE_UNSIGNED && + desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB); + + /* no blending for pure integer formats */ + caps->can_blend = !util_format_is_pure_integer(format); + + /* + * From the Sandy Bridge PRM, volume 2 part 1, page 382: + * + * "Alpha Test can only be enabled if Pixel Shader outputs a float + * alpha value." + */ + caps->can_alpha_test = !util_format_is_pure_integer(format); + + caps->dst_alpha_forced_one = + (ilo_translate_render_format(dev, format) != + ilo_translate_color_format(dev, format)); + + /* sanity check */ + if (caps->dst_alpha_forced_one) { + enum pipe_format render_format; + + switch (format) { + case PIPE_FORMAT_B8G8R8X8_UNORM: + render_format = PIPE_FORMAT_B8G8R8A8_UNORM; + break; + default: + render_format = PIPE_FORMAT_NONE; + break; + } + + assert(ilo_translate_render_format(dev, format) == + ilo_translate_color_format(dev, render_format)); + } +} + void ilo_gpe_set_fb(const struct ilo_dev_info *dev, const struct pipe_framebuffer_state *state, struct ilo_fb_state *fb) { - const struct pipe_surface *first; - unsigned first_idx; + const struct pipe_surface *first_surf = NULL; + int i; ILO_DEV_ASSERT(dev, 6, 7.5); @@ -1557,17 +1614,21 @@ ilo_gpe_set_fb(const struct ilo_dev_info *dev, (state->height) ? state->height : 1, 1, 0, &fb->null_rt); - first = NULL; - for (first_idx = 0; first_idx < state->nr_cbufs; first_idx++) { - if (state->cbufs[first_idx]) { - first = state->cbufs[first_idx]; - break; + for (i = 0; i < state->nr_cbufs; i++) { + if (state->cbufs[i]) { + fb_set_blend_caps(dev, state->cbufs[i]->format, &fb->blend_caps[i]); + + if (!first_surf) + first_surf = state->cbufs[i]; + } else { + fb_set_blend_caps(dev, PIPE_FORMAT_NONE, &fb->blend_caps[i]); } } - if (!first) - first = state->zsbuf; - fb->num_samples = (first) ? first->texture->nr_samples : 1; + if (!first_surf && state->zsbuf) + first_surf = state->zsbuf; + + fb->num_samples = (first_surf) ? first_surf->texture->nr_samples : 1; if (!fb->num_samples) fb->num_samples = 1; -- 2.30.2