From 960ca7d5e32997a5367cf798f7930cbb890b3ab4 Mon Sep 17 00:00:00 2001 From: Chia-I Wu Date: Mon, 11 May 2015 19:48:52 +0800 Subject: [PATCH] ilo: embed ilo_state_cc in ilo_blend_state --- .../drivers/ilo/core/ilo_builder_3d_bottom.h | 199 +---- src/gallium/drivers/ilo/core/ilo_state_3d.h | 44 +- .../drivers/ilo/core/ilo_state_3d_bottom.c | 680 +----------------- src/gallium/drivers/ilo/ilo_blitter.h | 8 +- .../drivers/ilo/ilo_blitter_rectlist.c | 70 +- src/gallium/drivers/ilo/ilo_render.c | 9 + src/gallium/drivers/ilo/ilo_render_dynamic.c | 33 +- src/gallium/drivers/ilo/ilo_render_gen.h | 2 + src/gallium/drivers/ilo/ilo_render_gen6.c | 9 +- src/gallium/drivers/ilo/ilo_render_gen7.c | 9 +- src/gallium/drivers/ilo/ilo_render_gen8.c | 16 +- src/gallium/drivers/ilo/ilo_state.c | 328 ++++++++- src/gallium/drivers/ilo/ilo_state.h | 34 +- 13 files changed, 462 insertions(+), 979 deletions(-) diff --git a/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h b/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h index 2d7b9e0035f..cd1a6821ca6 100644 --- a/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h +++ b/src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h @@ -35,6 +35,7 @@ #include "ilo_core.h" #include "ilo_dev.h" #include "ilo_format.h" +#include "ilo_state_cc.h" #include "ilo_state_raster.h" #include "ilo_state_viewport.h" #include "ilo_builder.h" @@ -406,21 +407,19 @@ gen8_3DSTATE_WM(struct ilo_builder *builder, static inline void gen8_3DSTATE_WM_DEPTH_STENCIL(struct ilo_builder *builder, - const struct ilo_dsa_state *dsa) + const struct ilo_state_cc *cc) { const uint8_t cmd_len = 3; - uint32_t dw1, dw2, *dw; + uint32_t *dw; ILO_DEV_ASSERT(builder->dev, 8, 8); - dw1 = dsa->payload[0]; - dw2 = dsa->payload[1]; - ilo_builder_batch_pointer(builder, cmd_len, &dw); dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_WM_DEPTH_STENCIL) | (cmd_len - 2); - dw[1] = dw1; - dw[2] = dw2; + /* see cc_set_gen8_3DSTATE_WM_DEPTH_STENCIL() */ + dw[1] = cc->ds[0]; + dw[2] = cc->ds[1]; } static inline void @@ -605,40 +604,18 @@ gen8_3DSTATE_PS_EXTRA(struct ilo_builder *builder, static inline void gen8_3DSTATE_PS_BLEND(struct ilo_builder *builder, - const struct ilo_blend_state *blend, - const struct ilo_fb_state *fb, - const struct ilo_dsa_state *dsa) + const struct ilo_state_cc *cc) { const uint8_t cmd_len = 2; - uint32_t dw1, *dw; + uint32_t *dw; ILO_DEV_ASSERT(builder->dev, 8, 8); - dw1 = 0; - if (blend->alpha_to_coverage && fb->num_samples > 1) - dw1 |= GEN8_PS_BLEND_DW1_ALPHA_TO_COVERAGE; - - if (fb->state.nr_cbufs && fb->state.cbufs[0]) { - const struct ilo_fb_blend_caps *caps = &fb->blend_caps[0]; - - dw1 |= GEN8_PS_BLEND_DW1_WRITABLE_RT; - if (caps->can_blend) { - if (caps->dst_alpha_forced_one) - dw1 |= blend->dw_ps_blend_dst_alpha_forced_one; - else - dw1 |= blend->dw_ps_blend; - } - - if (caps->can_alpha_test) - dw1 |= dsa->dw_ps_blend_alpha; - } else { - dw1 |= dsa->dw_ps_blend_alpha; - } - ilo_builder_batch_pointer(builder, cmd_len, &dw); dw[0] = GEN8_RENDER_CMD(3D, 3DSTATE_PS_BLEND) | (cmd_len - 2); - dw[1] = dw1; + /* see cc_set_gen8_3DSTATE_PS_BLEND() */ + dw[1] = cc->blend[0]; } static inline void @@ -1282,179 +1259,61 @@ gen6_SCISSOR_RECT(struct ilo_builder *builder, static inline uint32_t gen6_COLOR_CALC_STATE(struct ilo_builder *builder, - const struct pipe_stencil_ref *stencil_ref, - ubyte alpha_ref, - const struct pipe_blend_color *blend_color) + const struct ilo_state_cc *cc) { const int state_align = 64; const int state_len = 6; - uint32_t state_offset, *dw; ILO_DEV_ASSERT(builder->dev, 6, 8); - state_offset = ilo_builder_dynamic_pointer(builder, - ILO_BUILDER_ITEM_COLOR_CALC, state_align, state_len, &dw); - - dw[0] = stencil_ref->ref_value[0] << 24 | - stencil_ref->ref_value[1] << 16 | - GEN6_CC_DW0_ALPHATEST_UNORM8; - dw[1] = alpha_ref; - dw[2] = fui(blend_color->color[0]); - dw[3] = fui(blend_color->color[1]); - dw[4] = fui(blend_color->color[2]); - dw[5] = fui(blend_color->color[3]); - - return state_offset; + /* see cc_params_set_gen6_COLOR_CALC_STATE() */ + return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_COLOR_CALC, + state_align, state_len, cc->cc); } static inline uint32_t gen6_DEPTH_STENCIL_STATE(struct ilo_builder *builder, - const struct ilo_dsa_state *dsa) + const struct ilo_state_cc *cc) { const int state_align = 64; const int state_len = 3; ILO_DEV_ASSERT(builder->dev, 6, 7.5); - STATIC_ASSERT(Elements(dsa->payload) >= state_len); - + /* see cc_set_gen6_DEPTH_STENCIL_STATE() */ return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_DEPTH_STENCIL, - state_align, state_len, dsa->payload); + state_align, state_len, cc->ds); } static inline uint32_t gen6_BLEND_STATE(struct ilo_builder *builder, - const struct ilo_blend_state *blend, - const struct ilo_fb_state *fb, - const struct ilo_dsa_state *dsa) + const struct ilo_state_cc *cc) { const int state_align = 64; - int state_len; - uint32_t state_offset, *dw; - unsigned num_targets, i; + const int state_len = 2 * cc->blend_state_count; ILO_DEV_ASSERT(builder->dev, 6, 7.5); - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 376: - * - * "The blend state is stored as an array of up to 8 elements..." - */ - num_targets = fb->state.nr_cbufs; - assert(num_targets <= 8); - - if (!num_targets) { - if (!dsa->dw_blend_alpha) - return 0; - /* to be able to reference alpha func */ - num_targets = 1; - } - - state_len = 2 * num_targets; - - state_offset = ilo_builder_dynamic_pointer(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[i]; - - dw[0] = cso->payload[0]; - 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]; - - 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; - } - - if (caps->can_logicop) - dw[1] |= blend->dw_logicop; - - if (caps->can_alpha_test) - dw[1] |= dsa->dw_blend_alpha; - } else { - dw[1] |= GEN6_RT_DW1_WRITE_DISABLES_A | - GEN6_RT_DW1_WRITE_DISABLES_R | - GEN6_RT_DW1_WRITE_DISABLES_G | - GEN6_RT_DW1_WRITE_DISABLES_B | - dsa->dw_blend_alpha; - } - - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 356: - * - * "When NumSamples = 1, AlphaToCoverage and AlphaToCoverage - * Dither both must be disabled." - * - * There is no such limitation on GEN7, or for AlphaToOne. But GL - * requires that anyway. - */ - if (fb->num_samples > 1) - dw[1] |= blend->dw_alpha_mod; - - dw += 2; - } + if (!state_len) + return 0; - return state_offset; + /* see cc_set_gen6_BLEND_STATE() */ + return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLEND, + state_align, state_len, cc->blend); } static inline uint32_t gen8_BLEND_STATE(struct ilo_builder *builder, - const struct ilo_blend_state *blend, - const struct ilo_fb_state *fb, - const struct ilo_dsa_state *dsa) + const struct ilo_state_cc *cc) { const int state_align = 64; - const int state_len = 1 + 2 * fb->state.nr_cbufs; - uint32_t state_offset, *dw; - unsigned i; + const int state_len = 1 + 2 * cc->blend_state_count; ILO_DEV_ASSERT(builder->dev, 8, 8); - assert(fb->state.nr_cbufs <= 8); - - state_offset = ilo_builder_dynamic_pointer(builder, - ILO_BUILDER_ITEM_BLEND, state_align, state_len, &dw); - - dw[0] = blend->dw_shared; - if (fb->num_samples > 1) - dw[0] |= blend->dw_alpha_mod; - if (!fb->state.nr_cbufs || fb->blend_caps[0].can_alpha_test) - dw[0] |= dsa->dw_blend_alpha; - dw++; - - for (i = 0; i < fb->state.nr_cbufs; i++) { - const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i]; - const struct ilo_blend_cso *cso = &blend->cso[i]; - - dw[0] = cso->payload[0]; - dw[1] = cso->payload[1]; - - if (fb->state.cbufs[i]) { - 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; - } - - if (caps->can_logicop) - dw[1] |= blend->dw_logicop; - } else { - dw[0] |= GEN8_RT_DW0_WRITE_DISABLES_A | - GEN8_RT_DW0_WRITE_DISABLES_R | - GEN8_RT_DW0_WRITE_DISABLES_G | - GEN8_RT_DW0_WRITE_DISABLES_B; - } - - dw += 2; - } - - return state_offset; + /* see cc_set_gen8_BLEND_STATE() */ + return ilo_builder_dynamic_write(builder, ILO_BUILDER_ITEM_BLEND, + state_align, state_len, &cc->blend[1]); } #endif /* ILO_BUILDER_3D_BOTTOM_H */ diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d.h b/src/gallium/drivers/ilo/core/ilo_state_3d.h index 78cd67128af..45929b2226d 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_3d.h +++ b/src/gallium/drivers/ilo/core/ilo_state_3d.h @@ -101,38 +101,6 @@ struct ilo_so_state { bool enabled; }; -struct ilo_dsa_state { - /* DEPTH_STENCIL_STATE or Gen8+ 3DSTATE_WM_DEPTH_STENCIL */ - uint32_t payload[3]; - - uint32_t dw_blend_alpha; - uint32_t dw_ps_blend_alpha; - ubyte alpha_ref; -}; - -struct ilo_blend_cso { - /* BLEND_STATE */ - uint32_t payload[2]; - - uint32_t dw_blend; - uint32_t dw_blend_dst_alpha_forced_one; -}; - -struct ilo_blend_state { - struct ilo_blend_cso cso[ILO_MAX_DRAW_BUFFERS]; - - bool dual_blend; - bool alpha_to_coverage; - - uint32_t dw_shared; - uint32_t dw_alpha_mod; - uint32_t dw_logicop; - - /* a part of 3DSTATE_PS_BLEND */ - uint32_t dw_ps_blend; - uint32_t dw_ps_blend_dst_alpha_forced_one; -}; - struct ilo_surface_cso { struct pipe_surface base; @@ -152,11 +120,11 @@ struct ilo_fb_state { struct ilo_fb_blend_caps { bool is_unorm; bool is_integer; + bool force_dst_alpha_one; bool can_logicop; bool can_blend; bool can_alpha_test; - bool dst_alpha_forced_one; } blend_caps[PIPE_MAX_COLOR_BUFS]; unsigned num_samples; @@ -185,16 +153,6 @@ ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev, int comp0, int comp1, int comp2, int comp3, struct ilo_ve_cso *cso); -void -ilo_gpe_init_dsa(const struct ilo_dev *dev, - const struct pipe_depth_stencil_alpha_state *state, - struct ilo_dsa_state *dsa); - -void -ilo_gpe_init_blend(const struct ilo_dev *dev, - const struct pipe_blend_state *state, - struct ilo_blend_state *blend); - void ilo_gpe_init_vs_cso(const struct ilo_dev *dev, const struct ilo_shader_state *vs, diff --git a/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c b/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c index 83da224811e..932b80dd0aa 100644 --- a/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c +++ b/src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c @@ -26,7 +26,6 @@ */ #include "genhw/genhw.h" -#include "util/u_dual_blend.h" #include "util/u_framebuffer.h" #include "util/u_half.h" @@ -314,681 +313,6 @@ ilo_gpe_init_fs_cso(const struct ilo_dev *dev, fs_init_cso_gen6(dev, fs, cso); } -/** - * Translate a pipe logicop to the matching hardware logicop. - */ -static int -gen6_translate_pipe_logicop(unsigned logicop) -{ - switch (logicop) { - case PIPE_LOGICOP_CLEAR: return GEN6_LOGICOP_CLEAR; - case PIPE_LOGICOP_NOR: return GEN6_LOGICOP_NOR; - case PIPE_LOGICOP_AND_INVERTED: return GEN6_LOGICOP_AND_INVERTED; - case PIPE_LOGICOP_COPY_INVERTED: return GEN6_LOGICOP_COPY_INVERTED; - case PIPE_LOGICOP_AND_REVERSE: return GEN6_LOGICOP_AND_REVERSE; - case PIPE_LOGICOP_INVERT: return GEN6_LOGICOP_INVERT; - case PIPE_LOGICOP_XOR: return GEN6_LOGICOP_XOR; - case PIPE_LOGICOP_NAND: return GEN6_LOGICOP_NAND; - case PIPE_LOGICOP_AND: return GEN6_LOGICOP_AND; - case PIPE_LOGICOP_EQUIV: return GEN6_LOGICOP_EQUIV; - case PIPE_LOGICOP_NOOP: return GEN6_LOGICOP_NOOP; - case PIPE_LOGICOP_OR_INVERTED: return GEN6_LOGICOP_OR_INVERTED; - case PIPE_LOGICOP_COPY: return GEN6_LOGICOP_COPY; - case PIPE_LOGICOP_OR_REVERSE: return GEN6_LOGICOP_OR_REVERSE; - case PIPE_LOGICOP_OR: return GEN6_LOGICOP_OR; - case PIPE_LOGICOP_SET: return GEN6_LOGICOP_SET; - default: - assert(!"unknown logicop function"); - return GEN6_LOGICOP_CLEAR; - } -} - -/** - * Translate a pipe blend function to the matching hardware blend function. - */ -static int -gen6_translate_pipe_blend(unsigned blend) -{ - switch (blend) { - case PIPE_BLEND_ADD: return GEN6_BLENDFUNCTION_ADD; - case PIPE_BLEND_SUBTRACT: return GEN6_BLENDFUNCTION_SUBTRACT; - case PIPE_BLEND_REVERSE_SUBTRACT: return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT; - case PIPE_BLEND_MIN: return GEN6_BLENDFUNCTION_MIN; - case PIPE_BLEND_MAX: return GEN6_BLENDFUNCTION_MAX; - default: - assert(!"unknown blend function"); - return GEN6_BLENDFUNCTION_ADD; - }; -} - -/** - * Translate a pipe blend factor to the matching hardware blend factor. - */ -static int -gen6_translate_pipe_blendfactor(unsigned blendfactor) -{ - switch (blendfactor) { - case PIPE_BLENDFACTOR_ONE: return GEN6_BLENDFACTOR_ONE; - case PIPE_BLENDFACTOR_SRC_COLOR: return GEN6_BLENDFACTOR_SRC_COLOR; - case PIPE_BLENDFACTOR_SRC_ALPHA: return GEN6_BLENDFACTOR_SRC_ALPHA; - case PIPE_BLENDFACTOR_DST_ALPHA: return GEN6_BLENDFACTOR_DST_ALPHA; - case PIPE_BLENDFACTOR_DST_COLOR: return GEN6_BLENDFACTOR_DST_COLOR; - case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE; - case PIPE_BLENDFACTOR_CONST_COLOR: return GEN6_BLENDFACTOR_CONST_COLOR; - case PIPE_BLENDFACTOR_CONST_ALPHA: return GEN6_BLENDFACTOR_CONST_ALPHA; - case PIPE_BLENDFACTOR_SRC1_COLOR: return GEN6_BLENDFACTOR_SRC1_COLOR; - case PIPE_BLENDFACTOR_SRC1_ALPHA: return GEN6_BLENDFACTOR_SRC1_ALPHA; - case PIPE_BLENDFACTOR_ZERO: return GEN6_BLENDFACTOR_ZERO; - case PIPE_BLENDFACTOR_INV_SRC_COLOR: return GEN6_BLENDFACTOR_INV_SRC_COLOR; - case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return GEN6_BLENDFACTOR_INV_SRC_ALPHA; - case PIPE_BLENDFACTOR_INV_DST_ALPHA: return GEN6_BLENDFACTOR_INV_DST_ALPHA; - case PIPE_BLENDFACTOR_INV_DST_COLOR: return GEN6_BLENDFACTOR_INV_DST_COLOR; - case PIPE_BLENDFACTOR_INV_CONST_COLOR: return GEN6_BLENDFACTOR_INV_CONST_COLOR; - case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return GEN6_BLENDFACTOR_INV_CONST_ALPHA; - case PIPE_BLENDFACTOR_INV_SRC1_COLOR: return GEN6_BLENDFACTOR_INV_SRC1_COLOR; - case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: return GEN6_BLENDFACTOR_INV_SRC1_ALPHA; - default: - assert(!"unknown blend factor"); - return GEN6_BLENDFACTOR_ONE; - }; -} - -/** - * Translate a pipe stencil op to the matching hardware stencil op. - */ -static int -gen6_translate_pipe_stencil_op(unsigned stencil_op) -{ - switch (stencil_op) { - case PIPE_STENCIL_OP_KEEP: return GEN6_STENCILOP_KEEP; - case PIPE_STENCIL_OP_ZERO: return GEN6_STENCILOP_ZERO; - case PIPE_STENCIL_OP_REPLACE: return GEN6_STENCILOP_REPLACE; - case PIPE_STENCIL_OP_INCR: return GEN6_STENCILOP_INCRSAT; - case PIPE_STENCIL_OP_DECR: return GEN6_STENCILOP_DECRSAT; - case PIPE_STENCIL_OP_INCR_WRAP: return GEN6_STENCILOP_INCR; - case PIPE_STENCIL_OP_DECR_WRAP: return GEN6_STENCILOP_DECR; - case PIPE_STENCIL_OP_INVERT: return GEN6_STENCILOP_INVERT; - default: - assert(!"unknown stencil op"); - return GEN6_STENCILOP_KEEP; - } -} - -static int -gen6_blend_factor_dst_alpha_forced_one(int factor) -{ - switch (factor) { - case GEN6_BLENDFACTOR_DST_ALPHA: - return GEN6_BLENDFACTOR_ONE; - case GEN6_BLENDFACTOR_INV_DST_ALPHA: - case GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE: - return GEN6_BLENDFACTOR_ZERO; - default: - return factor; - } -} - -static uint32_t -blend_get_rt_blend_enable_gen6(const struct ilo_dev *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; - - rgb_src = gen6_translate_pipe_blendfactor(rt->rgb_src_factor); - rgb_dst = gen6_translate_pipe_blendfactor(rt->rgb_dst_factor); - a_src = gen6_translate_pipe_blendfactor(rt->alpha_src_factor); - a_dst = gen6_translate_pipe_blendfactor(rt->alpha_dst_factor); - - if (dst_alpha_forced_one) { - rgb_src = gen6_blend_factor_dst_alpha_forced_one(rgb_src); - rgb_dst = gen6_blend_factor_dst_alpha_forced_one(rgb_dst); - a_src = gen6_blend_factor_dst_alpha_forced_one(a_src); - a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst); - } - - dw = GEN6_RT_DW0_BLEND_ENABLE | - gen6_translate_pipe_blend(rt->alpha_func) << 26 | - a_src << 20 | - a_dst << 15 | - gen6_translate_pipe_blend(rt->rgb_func) << 11 | - rgb_src << 5 | - rgb_dst; - - if (rt->rgb_func != rt->alpha_func || - rgb_src != a_src || rgb_dst != a_dst) - dw |= GEN6_RT_DW0_INDEPENDENT_ALPHA_ENABLE; - - return dw; -} - -static uint32_t -blend_get_rt_blend_enable_gen8(const struct ilo_dev *dev, - const struct pipe_rt_blend_state *rt, - bool dst_alpha_forced_one, - bool *independent_alpha) -{ - int rgb_src, rgb_dst, a_src, a_dst; - uint32_t dw; - - ILO_DEV_ASSERT(dev, 8, 8); - - if (!rt->blend_enable) { - *independent_alpha = false; - return 0; - } - - rgb_src = gen6_translate_pipe_blendfactor(rt->rgb_src_factor); - rgb_dst = gen6_translate_pipe_blendfactor(rt->rgb_dst_factor); - a_src = gen6_translate_pipe_blendfactor(rt->alpha_src_factor); - a_dst = gen6_translate_pipe_blendfactor(rt->alpha_dst_factor); - - if (dst_alpha_forced_one) { - rgb_src = gen6_blend_factor_dst_alpha_forced_one(rgb_src); - rgb_dst = gen6_blend_factor_dst_alpha_forced_one(rgb_dst); - a_src = gen6_blend_factor_dst_alpha_forced_one(a_src); - a_dst = gen6_blend_factor_dst_alpha_forced_one(a_dst); - } - - dw = GEN8_RT_DW0_BLEND_ENABLE | - rgb_src << 26 | - rgb_dst << 21 | - gen6_translate_pipe_blend(rt->rgb_func) << 18 | - a_src << 13 | - a_dst << 8 | - gen6_translate_pipe_blend(rt->alpha_func) << 5; - - *independent_alpha = (rt->rgb_func != rt->alpha_func || - rgb_src != a_src || - rgb_dst != a_dst); - - return dw; -} - -static void -blend_init_cso_gen6(const struct ilo_dev *dev, - const struct pipe_blend_state *state, - struct ilo_blend_state *blend, - unsigned index) -{ - 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); - - cso->payload[0] = 0; - cso->payload[1] = GEN6_RT_DW1_COLORCLAMP_RTFORMAT | - GEN6_RT_DW1_PRE_BLEND_CLAMP | - GEN6_RT_DW1_POST_BLEND_CLAMP; - - if (!(rt->colormask & PIPE_MASK_A)) - cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_A; - if (!(rt->colormask & PIPE_MASK_R)) - cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_R; - if (!(rt->colormask & PIPE_MASK_G)) - cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_G; - if (!(rt->colormask & PIPE_MASK_B)) - cso->payload[1] |= GEN6_RT_DW1_WRITE_DISABLES_B; - - /* - * 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); - } -} - -static bool -blend_init_cso_gen8(const struct ilo_dev *dev, - const struct pipe_blend_state *state, - struct ilo_blend_state *blend, - unsigned index) -{ - const struct pipe_rt_blend_state *rt = &state->rt[index]; - struct ilo_blend_cso *cso = &blend->cso[index]; - bool independent_alpha = false; - - ILO_DEV_ASSERT(dev, 8, 8); - - cso->payload[0] = 0; - cso->payload[1] = GEN8_RT_DW1_COLORCLAMP_RTFORMAT | - GEN8_RT_DW1_PRE_BLEND_CLAMP | - GEN8_RT_DW1_POST_BLEND_CLAMP; - - if (!(rt->colormask & PIPE_MASK_A)) - cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_A; - if (!(rt->colormask & PIPE_MASK_R)) - cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_R; - if (!(rt->colormask & PIPE_MASK_G)) - cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_G; - if (!(rt->colormask & PIPE_MASK_B)) - cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLES_B; - - if (state->logicop_enable) { - cso->dw_blend = 0; - cso->dw_blend_dst_alpha_forced_one = 0; - } else { - bool tmp[2]; - - cso->dw_blend = blend_get_rt_blend_enable_gen8(dev, rt, false, &tmp[0]); - cso->dw_blend_dst_alpha_forced_one = - blend_get_rt_blend_enable_gen8(dev, rt, true, &tmp[1]); - - if (tmp[0] || tmp[1]) - independent_alpha = true; - } - - return independent_alpha; -} - -static uint32_t -blend_get_logicop_enable_gen6(const struct ilo_dev *dev, - const struct pipe_blend_state *state) -{ - ILO_DEV_ASSERT(dev, 6, 7.5); - - if (!state->logicop_enable) - return 0; - - return GEN6_RT_DW1_LOGICOP_ENABLE | - gen6_translate_pipe_logicop(state->logicop_func) << 18; -} - -static uint32_t -blend_get_logicop_enable_gen8(const struct ilo_dev *dev, - const struct pipe_blend_state *state) -{ - ILO_DEV_ASSERT(dev, 8, 8); - - if (!state->logicop_enable) - return 0; - - return GEN8_RT_DW1_LOGICOP_ENABLE | - gen6_translate_pipe_logicop(state->logicop_func) << 27; -} - -static uint32_t -blend_get_alpha_mod_gen6(const struct ilo_dev *dev, - const struct pipe_blend_state *state, - bool dual_blend) -{ - uint32_t dw = 0; - - ILO_DEV_ASSERT(dev, 6, 7.5); - - if (state->alpha_to_coverage) { - dw |= GEN6_RT_DW1_ALPHA_TO_COVERAGE; - if (ilo_dev_gen(dev) >= ILO_GEN(7)) - dw |= GEN6_RT_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_RT_DW1_ALPHA_TO_ONE; - - return dw; -} - -static uint32_t -blend_get_alpha_mod_gen8(const struct ilo_dev *dev, - const struct pipe_blend_state *state, - bool dual_blend) -{ - uint32_t dw = 0; - - ILO_DEV_ASSERT(dev, 8, 8); - - if (state->alpha_to_coverage) { - dw |= GEN8_BLEND_DW0_ALPHA_TO_COVERAGE | - GEN8_BLEND_DW0_ALPHA_TO_COVERAGE_DITHER; - } - - if (state->alpha_to_one && !dual_blend) - dw |= GEN8_BLEND_DW0_ALPHA_TO_ONE; - - return dw; -} - -static uint32_t -blend_get_ps_blend_gen8(const struct ilo_dev *dev, uint32_t rt_dw0) -{ - int rgb_src, rgb_dst, a_src, a_dst; - uint32_t dw; - - ILO_DEV_ASSERT(dev, 8, 8); - - if (!(rt_dw0 & GEN8_RT_DW0_BLEND_ENABLE)) - return 0; - - a_src = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_SRC_ALPHA_FACTOR); - a_dst = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_DST_ALPHA_FACTOR); - rgb_src = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_SRC_COLOR_FACTOR); - rgb_dst = GEN_EXTRACT(rt_dw0, GEN8_RT_DW0_DST_COLOR_FACTOR); - - dw = GEN8_PS_BLEND_DW1_BLEND_ENABLE; - dw |= GEN_SHIFT32(a_src, GEN8_PS_BLEND_DW1_SRC_ALPHA_FACTOR); - dw |= GEN_SHIFT32(a_dst, GEN8_PS_BLEND_DW1_DST_ALPHA_FACTOR); - dw |= GEN_SHIFT32(rgb_src, GEN8_PS_BLEND_DW1_SRC_COLOR_FACTOR); - dw |= GEN_SHIFT32(rgb_dst, GEN8_PS_BLEND_DW1_DST_COLOR_FACTOR); - - if (a_src != rgb_src || a_dst != rgb_dst) - dw |= GEN8_PS_BLEND_DW1_INDEPENDENT_ALPHA_ENABLE; - - return dw; -} - -void -ilo_gpe_init_blend(const struct ilo_dev *dev, - const struct pipe_blend_state *state, - struct ilo_blend_state *blend) -{ - unsigned i; - - ILO_DEV_ASSERT(dev, 6, 8); - - 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; - - if (ilo_dev_gen(dev) >= ILO_GEN(8)) { - bool independent_alpha; - - blend->dw_alpha_mod = - blend_get_alpha_mod_gen8(dev, state, blend->dual_blend); - blend->dw_logicop = blend_get_logicop_enable_gen8(dev, state); - blend->dw_shared = (state->dither) ? GEN8_BLEND_DW0_DITHER_ENABLE : 0; - - independent_alpha = blend_init_cso_gen8(dev, state, blend, 0); - if (independent_alpha) - blend->dw_shared |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE; - - blend->dw_ps_blend = blend_get_ps_blend_gen8(dev, - blend->cso[0].dw_blend); - blend->dw_ps_blend_dst_alpha_forced_one = blend_get_ps_blend_gen8(dev, - blend->cso[0].dw_blend_dst_alpha_forced_one); - - if (state->independent_blend_enable) { - for (i = 1; i < Elements(blend->cso); i++) { - independent_alpha = blend_init_cso_gen8(dev, state, blend, i); - if (independent_alpha) - blend->dw_shared |= GEN8_BLEND_DW0_INDEPENDENT_ALPHA_ENABLE; - } - } else { - for (i = 1; i < Elements(blend->cso); i++) - blend->cso[i] = blend->cso[0]; - } - } else { - 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_RT_DW1_DITHER_ENABLE : 0; - - blend->dw_ps_blend = 0; - blend->dw_ps_blend_dst_alpha_forced_one = 0; - - 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]; - } - } -} - -/** - * Translate a pipe DSA test function to the matching hardware compare - * function. - */ -static int -gen6_translate_dsa_func(unsigned func) -{ - switch (func) { - case PIPE_FUNC_NEVER: return GEN6_COMPAREFUNCTION_NEVER; - case PIPE_FUNC_LESS: return GEN6_COMPAREFUNCTION_LESS; - case PIPE_FUNC_EQUAL: return GEN6_COMPAREFUNCTION_EQUAL; - case PIPE_FUNC_LEQUAL: return GEN6_COMPAREFUNCTION_LEQUAL; - case PIPE_FUNC_GREATER: return GEN6_COMPAREFUNCTION_GREATER; - case PIPE_FUNC_NOTEQUAL: return GEN6_COMPAREFUNCTION_NOTEQUAL; - case PIPE_FUNC_GEQUAL: return GEN6_COMPAREFUNCTION_GEQUAL; - case PIPE_FUNC_ALWAYS: return GEN6_COMPAREFUNCTION_ALWAYS; - default: - assert(!"unknown depth/stencil/alpha test function"); - return GEN6_COMPAREFUNCTION_NEVER; - } -} - -static uint32_t -dsa_get_stencil_enable_gen6(const struct ilo_dev *dev, - const struct pipe_stencil_state *stencil0, - const struct pipe_stencil_state *stencil1) -{ - uint32_t dw; - - ILO_DEV_ASSERT(dev, 6, 7.5); - - if (!stencil0->enabled) - return 0; - - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 359: - * - * "If the Depth Buffer is either undefined or does not have a surface - * format of D32_FLOAT_S8X24_UINT or D24_UNORM_S8_UINT and separate - * stencil buffer is disabled, Stencil Test Enable must be DISABLED" - * - * From the Sandy Bridge PRM, volume 2 part 1, page 370: - * - * "This field (Stencil Test Enable) cannot be enabled if - * Surface Format in 3DSTATE_DEPTH_BUFFER is set to D16_UNORM." - * - * TODO We do not check these yet. - */ - dw = GEN6_ZS_DW0_STENCIL_TEST_ENABLE | - gen6_translate_dsa_func(stencil0->func) << 28 | - gen6_translate_pipe_stencil_op(stencil0->fail_op) << 25 | - gen6_translate_pipe_stencil_op(stencil0->zfail_op) << 22 | - gen6_translate_pipe_stencil_op(stencil0->zpass_op) << 19; - if (stencil0->writemask) - dw |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE; - - if (stencil1->enabled) { - dw |= GEN6_ZS_DW0_STENCIL1_ENABLE | - gen6_translate_dsa_func(stencil1->func) << 12 | - gen6_translate_pipe_stencil_op(stencil1->fail_op) << 9 | - gen6_translate_pipe_stencil_op(stencil1->zfail_op) << 6 | - gen6_translate_pipe_stencil_op(stencil1->zpass_op) << 3; - if (stencil1->writemask) - dw |= GEN6_ZS_DW0_STENCIL_WRITE_ENABLE; - } - - return dw; -} - -static uint32_t -dsa_get_stencil_enable_gen8(const struct ilo_dev *dev, - const struct pipe_stencil_state *stencil0, - const struct pipe_stencil_state *stencil1) -{ - uint32_t dw; - - ILO_DEV_ASSERT(dev, 8, 8); - - if (!stencil0->enabled) - return 0; - - dw = gen6_translate_pipe_stencil_op(stencil0->fail_op) << 29 | - gen6_translate_pipe_stencil_op(stencil0->zfail_op) << 26 | - gen6_translate_pipe_stencil_op(stencil0->zpass_op) << 23 | - gen6_translate_dsa_func(stencil0->func) << 8 | - GEN8_ZS_DW1_STENCIL_TEST_ENABLE; - if (stencil0->writemask) - dw |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE; - - if (stencil1->enabled) { - dw |= gen6_translate_dsa_func(stencil1->func) << 20 | - gen6_translate_pipe_stencil_op(stencil1->fail_op) << 17 | - gen6_translate_pipe_stencil_op(stencil1->zfail_op) << 14 | - gen6_translate_pipe_stencil_op(stencil1->zpass_op) << 11 | - GEN8_ZS_DW1_STENCIL1_ENABLE; - if (stencil1->writemask) - dw |= GEN8_ZS_DW1_STENCIL_WRITE_ENABLE; - } - - return dw; -} - -static uint32_t -dsa_get_depth_enable_gen6(const struct ilo_dev *dev, - const struct pipe_depth_state *state) -{ - uint32_t dw; - - ILO_DEV_ASSERT(dev, 6, 7.5); - - /* - * From the Sandy Bridge PRM, volume 2 part 1, page 360: - * - * "Enabling the Depth Test function without defining a Depth Buffer is - * UNDEFINED." - * - * From the Sandy Bridge PRM, volume 2 part 1, page 375: - * - * "A Depth Buffer must be defined before enabling writes to it, or - * operation is UNDEFINED." - * - * TODO We do not check these yet. - */ - if (state->enabled) { - dw = GEN6_ZS_DW2_DEPTH_TEST_ENABLE | - gen6_translate_dsa_func(state->func) << 27; - } else { - dw = GEN6_COMPAREFUNCTION_ALWAYS << 27; - } - - if (state->writemask) - dw |= GEN6_ZS_DW2_DEPTH_WRITE_ENABLE; - - return dw; -} - -static uint32_t -dsa_get_depth_enable_gen8(const struct ilo_dev *dev, - const struct pipe_depth_state *state) -{ - uint32_t dw; - - ILO_DEV_ASSERT(dev, 8, 8); - - if (state->enabled) { - dw = GEN8_ZS_DW1_DEPTH_TEST_ENABLE | - gen6_translate_dsa_func(state->func) << 5; - } else { - dw = GEN6_COMPAREFUNCTION_ALWAYS << 5; - } - - if (state->writemask) - dw |= GEN8_ZS_DW1_DEPTH_WRITE_ENABLE; - - return dw; -} - -static uint32_t -dsa_get_alpha_enable_gen6(const struct ilo_dev *dev, - const struct pipe_alpha_state *state) -{ - uint32_t dw; - - ILO_DEV_ASSERT(dev, 6, 7.5); - - if (!state->enabled) - return 0; - - /* this will be ORed to BLEND_STATE */ - dw = GEN6_RT_DW1_ALPHA_TEST_ENABLE | - gen6_translate_dsa_func(state->func) << 13; - - return dw; -} - -static uint32_t -dsa_get_alpha_enable_gen8(const struct ilo_dev *dev, - const struct pipe_alpha_state *state) -{ - uint32_t dw; - - ILO_DEV_ASSERT(dev, 8, 8); - - if (!state->enabled) - return 0; - - /* this will be ORed to BLEND_STATE */ - dw = GEN8_BLEND_DW0_ALPHA_TEST_ENABLE | - gen6_translate_dsa_func(state->func) << 24; - - return dw; -} - -void -ilo_gpe_init_dsa(const struct ilo_dev *dev, - const struct pipe_depth_stencil_alpha_state *state, - struct ilo_dsa_state *dsa) -{ - ILO_DEV_ASSERT(dev, 6, 8); - - STATIC_ASSERT(Elements(dsa->payload) >= 3); - - if (ilo_dev_gen(dev) >= ILO_GEN(8)) { - const uint32_t dw_stencil = dsa_get_stencil_enable_gen8(dev, - &state->stencil[0], &state->stencil[1]); - const uint32_t dw_depth = dsa_get_depth_enable_gen8(dev, &state->depth); - - assert(!(dw_stencil & dw_depth)); - dsa->payload[0] = dw_stencil | dw_depth; - - dsa->dw_blend_alpha = dsa_get_alpha_enable_gen8(dev, &state->alpha); - dsa->dw_ps_blend_alpha = (state->alpha.enabled) ? - GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE : 0; - } else { - dsa->payload[0] = dsa_get_stencil_enable_gen6(dev, - &state->stencil[0], &state->stencil[1]); - dsa->payload[2] = dsa_get_depth_enable_gen6(dev, &state->depth); - - dsa->dw_blend_alpha = dsa_get_alpha_enable_gen6(dev, &state->alpha); - dsa->dw_ps_blend_alpha = 0; - } - - dsa->payload[1] = state->stencil[0].valuemask << 24 | - state->stencil[0].writemask << 16 | - state->stencil[1].valuemask << 8 | - state->stencil[1].writemask; - - dsa->alpha_ref = float_to_ubyte(state->alpha.ref_value); -} - static void fb_set_blend_caps(const struct ilo_dev *dev, enum pipe_format format, @@ -1029,12 +353,12 @@ fb_set_blend_caps(const struct ilo_dev *dev, */ caps->can_alpha_test = !caps->is_integer; - caps->dst_alpha_forced_one = + caps->force_dst_alpha_one = (ilo_format_translate_render(dev, format) != ilo_format_translate_color(dev, format)); /* sanity check */ - if (caps->dst_alpha_forced_one) { + if (caps->force_dst_alpha_one) { enum pipe_format render_format; switch (format) { diff --git a/src/gallium/drivers/ilo/ilo_blitter.h b/src/gallium/drivers/ilo/ilo_blitter.h index a092aff1993..072f0f7f7fc 100644 --- a/src/gallium/drivers/ilo/ilo_blitter.h +++ b/src/gallium/drivers/ilo/ilo_blitter.h @@ -64,13 +64,7 @@ struct ilo_blitter { struct ilo_state_viewport vp; uint32_t vp_data[20]; - struct ilo_dsa_state dsa; - - struct { - struct pipe_stencil_ref stencil_ref; - ubyte alpha_ref; - struct pipe_blend_color blend_color; - } cc; + struct ilo_state_cc cc; uint32_t depth_clear_value; diff --git a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c index 51e640d5236..9d431956314 100644 --- a/src/gallium/drivers/ilo/ilo_blitter_rectlist.c +++ b/src/gallium/drivers/ilo/ilo_blitter_rectlist.c @@ -115,18 +115,18 @@ ilo_blitter_set_rectlist(struct ilo_blitter *blitter, } static void -ilo_blitter_set_clear_values(struct ilo_blitter *blitter, - uint32_t depth, ubyte stencil) +ilo_blitter_set_depth_clear_value(struct ilo_blitter *blitter, + uint32_t depth) { blitter->depth_clear_value = depth; - blitter->cc.stencil_ref.ref_value[0] = stencil; } static void -ilo_blitter_set_dsa(struct ilo_blitter *blitter, - const struct pipe_depth_stencil_alpha_state *state) +ilo_blitter_set_cc(struct ilo_blitter *blitter, + const struct ilo_state_cc_info *info) { - ilo_gpe_init_dsa(blitter->ilo->dev, state, &blitter->dsa); + memset(&blitter->cc, 0, sizeof(blitter->cc)); + ilo_state_cc_init(&blitter->cc, blitter->ilo->dev, info); } static void @@ -337,7 +337,7 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter, double depth, unsigned stencil) { struct ilo_texture *tex = ilo_texture(zs->texture); - struct pipe_depth_stencil_alpha_state dsa_state; + struct ilo_state_cc_info info; uint32_t uses, clear_value; if (!ilo_image_can_enable_aux(&tex->image, zs->u.tex.level)) @@ -377,17 +377,20 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter, * - [DevSNB] errata: For stencil buffer only clear, the previous * depth clear value must be delivered during the clear." */ - memset(&dsa_state, 0, sizeof(dsa_state)); + memset(&info, 0, sizeof(info)); - if (clear_flags & PIPE_CLEAR_DEPTH) - dsa_state.depth.writemask = true; + if (clear_flags & PIPE_CLEAR_DEPTH) { + info.depth.cv_has_buffer = true; + info.depth.write_enable = true; + } if (clear_flags & PIPE_CLEAR_STENCIL) { - dsa_state.stencil[0].enabled = true; - dsa_state.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa_state.stencil[0].fail_op = PIPE_STENCIL_OP_KEEP; - dsa_state.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; - dsa_state.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; + info.stencil.cv_has_buffer = true; + info.stencil.test_enable = true; + info.stencil.front.test_func = GEN6_COMPAREFUNCTION_ALWAYS; + info.stencil.front.fail_op = GEN6_STENCILOP_KEEP; + info.stencil.front.zfail_op = GEN6_STENCILOP_KEEP; + info.stencil.front.zpass_op = GEN6_STENCILOP_REPLACE; /* * From the Ivy Bridge PRM, volume 2 part 1, page 277: @@ -398,11 +401,12 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter, * - DEPTH_STENCIL_STATE::Stencil Test Mask must be 0xFF * - DEPTH_STENCIL_STATE::Back Face Stencil Write Mask must be 0xFF * - DEPTH_STENCIL_STATE::Back Face Stencil Test Mask must be 0xFF" + * + * Back frace masks will be copied from front face masks. */ - dsa_state.stencil[0].valuemask = 0xff; - dsa_state.stencil[0].writemask = 0xff; - dsa_state.stencil[1].valuemask = 0xff; - dsa_state.stencil[1].writemask = 0xff; + info.params.stencil_front.test_ref = (uint8_t) stencil; + info.params.stencil_front.test_mask = 0xff; + info.params.stencil_front.write_mask = 0xff; } ilo_blitter_set_invariants(blitter); @@ -410,8 +414,8 @@ ilo_blitter_rectlist_clear_zs(struct ilo_blitter *blitter, ILO_STATE_RASTER_EARLYZ_DEPTH_CLEAR, clear_flags & PIPE_CLEAR_STENCIL); - ilo_blitter_set_dsa(blitter, &dsa_state); - ilo_blitter_set_clear_values(blitter, clear_value, (ubyte) stencil); + ilo_blitter_set_cc(blitter, &info); + ilo_blitter_set_depth_clear_value(blitter, clear_value); ilo_blitter_set_fb_from_surface(blitter, zs); uses = ILO_BLITTER_USE_DSA; @@ -432,7 +436,7 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter, unsigned level, unsigned slice) { struct ilo_texture *tex = ilo_texture(res); - struct pipe_depth_stencil_alpha_state dsa_state; + struct ilo_state_cc_info info; const struct ilo_texture_slice *s = ilo_texture_get_slice(tex, level, slice); @@ -446,17 +450,18 @@ ilo_blitter_rectlist_resolve_z(struct ilo_blitter *blitter, * to NEVER. Depth Buffer Write Enable must be enabled. Stencil Test * Enable and Stencil Buffer Write Enable must be disabled." */ - memset(&dsa_state, 0, sizeof(dsa_state)); - dsa_state.depth.writemask = true; - dsa_state.depth.enabled = true; - dsa_state.depth.func = PIPE_FUNC_NEVER; + memset(&info, 0, sizeof(info)); + info.depth.cv_has_buffer = true; + info.depth.test_enable = true; + info.depth.write_enable = true; + info.depth.test_func = GEN6_COMPAREFUNCTION_NEVER; ilo_blitter_set_invariants(blitter); ilo_blitter_set_earlyz_op(blitter, ILO_STATE_RASTER_EARLYZ_DEPTH_RESOLVE, false); - ilo_blitter_set_dsa(blitter, &dsa_state); - ilo_blitter_set_clear_values(blitter, s->clear_value, 0); + ilo_blitter_set_cc(blitter, &info); + ilo_blitter_set_depth_clear_value(blitter, s->clear_value); ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice); ilo_blitter_set_uses(blitter, ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH); @@ -470,7 +475,7 @@ ilo_blitter_rectlist_resolve_hiz(struct ilo_blitter *blitter, unsigned level, unsigned slice) { struct ilo_texture *tex = ilo_texture(res); - struct pipe_depth_stencil_alpha_state dsa_state; + struct ilo_state_cc_info info; if (!ilo_image_can_enable_aux(&tex->image, level)) return; @@ -482,14 +487,15 @@ ilo_blitter_rectlist_resolve_hiz(struct ilo_blitter *blitter, * disabled. Depth Buffer Write Enable must be enabled. Stencil Test * Enable and Stencil Buffer Write Enable must be disabled." */ - memset(&dsa_state, 0, sizeof(dsa_state)); - dsa_state.depth.writemask = true; + memset(&info, 0, sizeof(info)); + info.depth.cv_has_buffer = true; + info.depth.write_enable = true; ilo_blitter_set_invariants(blitter); ilo_blitter_set_earlyz_op(blitter, ILO_STATE_RASTER_EARLYZ_HIZ_RESOLVE, false); - ilo_blitter_set_dsa(blitter, &dsa_state); + ilo_blitter_set_cc(blitter, &info); ilo_blitter_set_fb_from_resource(blitter, res, res->format, level, slice); ilo_blitter_set_uses(blitter, ILO_BLITTER_USE_DSA | ILO_BLITTER_USE_FB_DEPTH); diff --git a/src/gallium/drivers/ilo/ilo_render.c b/src/gallium/drivers/ilo/ilo_render.c index f71059857c6..6935138f8d9 100644 --- a/src/gallium/drivers/ilo/ilo_render.c +++ b/src/gallium/drivers/ilo/ilo_render.c @@ -453,6 +453,9 @@ draw_session_prepare(struct ilo_render *render, ilo_state_viewport_full_delta(&vec->viewport.vp, render->dev, &session->vp_delta); + + ilo_state_cc_full_delta(&vec->blend->cc, render->dev, + &session->cc_delta); } else { session->prim_changed = (render->state.reduced_prim != session->reduced_prim); @@ -468,6 +471,11 @@ draw_session_prepare(struct ilo_render *render, ilo_state_viewport_full_delta(&vec->viewport.vp, render->dev, &session->vp_delta); } + + if (vec->dirty & ILO_DIRTY_BLEND) { + ilo_state_cc_get_delta(&vec->blend->cc, render->dev, + &render->state.cc, &session->cc_delta); + } } } @@ -486,6 +494,7 @@ draw_session_end(struct ilo_render *render, render->state.primitive_restart = vec->draw->primitive_restart; render->state.rs = vec->rasterizer->rs; + render->state.cc = vec->blend->cc; } void diff --git a/src/gallium/drivers/ilo/ilo_render_dynamic.c b/src/gallium/drivers/ilo/ilo_render_dynamic.c index cc3791eb470..5618920a507 100644 --- a/src/gallium/drivers/ilo/ilo_render_dynamic.c +++ b/src/gallium/drivers/ilo/ilo_render_dynamic.c @@ -99,32 +99,30 @@ gen6_emit_draw_dynamic_cc(struct ilo_render *r, ILO_DEV_ASSERT(r->dev, 6, 8); /* BLEND_STATE */ - if (DIRTY(BLEND) || DIRTY(FB) || DIRTY(DSA)) { - if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) { - r->state.BLEND_STATE = gen8_BLEND_STATE(r->builder, - vec->blend, &vec->fb, vec->dsa); - } else { - r->state.BLEND_STATE = gen6_BLEND_STATE(r->builder, - vec->blend, &vec->fb, vec->dsa); - } + if ((session->cc_delta.dirty & ILO_STATE_CC_BLEND_STATE) || + r->state_bo_changed) { + if (ilo_dev_gen(r->dev) >= ILO_GEN(8)) + r->state.BLEND_STATE = gen8_BLEND_STATE(r->builder, &vec->blend->cc); + else + r->state.BLEND_STATE = gen6_BLEND_STATE(r->builder, &vec->blend->cc); session->blend_changed = true; } /* COLOR_CALC_STATE */ - if (DIRTY(DSA) || DIRTY(STENCIL_REF) || DIRTY(BLEND_COLOR)) { + if ((session->cc_delta.dirty & ILO_STATE_CC_COLOR_CALC_STATE) || + r->state_bo_changed) { r->state.COLOR_CALC_STATE = - gen6_COLOR_CALC_STATE(r->builder, &vec->stencil_ref, - vec->dsa->alpha_ref, &vec->blend_color); - + gen6_COLOR_CALC_STATE(r->builder, &vec->blend->cc); session->cc_changed = true; } /* DEPTH_STENCIL_STATE */ - if (ilo_dev_gen(r->dev) < ILO_GEN(8) && DIRTY(DSA)) { + if (ilo_dev_gen(r->dev) < ILO_GEN(8) && + ((session->cc_delta.dirty & ILO_STATE_CC_DEPTH_STENCIL_STATE) || + r->state_bo_changed)) { r->state.DEPTH_STENCIL_STATE = - gen6_DEPTH_STENCIL_STATE(r->builder, vec->dsa); - + gen6_DEPTH_STENCIL_STATE(r->builder, &vec->blend->cc); session->dsa_changed = true; } } @@ -450,13 +448,12 @@ ilo_render_emit_rectlist_dynamic_states(struct ilo_render *render, if (blitter->uses & ILO_BLITTER_USE_DSA) { render->state.DEPTH_STENCIL_STATE = - gen6_DEPTH_STENCIL_STATE(render->builder, &blitter->dsa); + gen6_DEPTH_STENCIL_STATE(render->builder, &blitter->cc); } if (blitter->uses & ILO_BLITTER_USE_CC) { render->state.COLOR_CALC_STATE = - gen6_COLOR_CALC_STATE(render->builder, &blitter->cc.stencil_ref, - blitter->cc.alpha_ref, &blitter->cc.blend_color); + gen6_COLOR_CALC_STATE(render->builder, &blitter->cc); } if (blitter->uses & ILO_BLITTER_USE_VIEWPORT) { diff --git a/src/gallium/drivers/ilo/ilo_render_gen.h b/src/gallium/drivers/ilo/ilo_render_gen.h index 2bf51724733..cc6f77d9750 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen.h +++ b/src/gallium/drivers/ilo/ilo_render_gen.h @@ -91,6 +91,7 @@ struct ilo_render { int so_max_vertices; struct ilo_state_raster rs; + struct ilo_state_cc cc; uint32_t SF_VIEWPORT; uint32_t CLIP_VIEWPORT; @@ -149,6 +150,7 @@ struct ilo_render_draw_session { struct ilo_state_raster_delta rs_delta; struct ilo_state_viewport_delta vp_delta; + struct ilo_state_cc_delta cc_delta; /* dynamic states */ bool viewport_changed; diff --git a/src/gallium/drivers/ilo/ilo_render_gen6.c b/src/gallium/drivers/ilo/ilo_render_gen6.c index e292ae8f3f9..ff0bf2fb820 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen6.c +++ b/src/gallium/drivers/ilo/ilo_render_gen6.c @@ -29,7 +29,6 @@ #include "core/ilo_builder_3d.h" #include "core/ilo_builder_mi.h" #include "core/ilo_builder_render.h" -#include "util/u_dual_blend.h" #include "util/u_prim.h" #include "ilo_blitter.h" @@ -679,18 +678,14 @@ gen6_draw_wm(struct ilo_render *r, } /* 3DSTATE_WM */ - if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) || + if (DIRTY(FS) || DIRTY(BLEND) || (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM) || r->instruction_bo_changed) { - const bool dual_blend = vec->blend->dual_blend; - const bool cc_may_kill = (vec->dsa->dw_blend_alpha || - vec->blend->alpha_to_coverage); - if (ilo_dev_gen(r->dev) == ILO_GEN(6) && r->hw_ctx_changed) gen6_wa_pre_3dstate_wm_max_threads(r); gen6_3DSTATE_WM(r->builder, &vec->rasterizer->rs, vec->fs, - dual_blend, cc_may_kill); + vec->blend->dual_blend, vec->blend->alpha_may_kill); } } diff --git a/src/gallium/drivers/ilo/ilo_render_gen7.c b/src/gallium/drivers/ilo/ilo_render_gen7.c index b427b2920f8..0931a771876 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen7.c +++ b/src/gallium/drivers/ilo/ilo_render_gen7.c @@ -28,7 +28,6 @@ #include "genhw/genhw.h" #include "core/ilo_builder_3d.h" #include "core/ilo_builder_render.h" -#include "util/u_dual_blend.h" #include "ilo_blitter.h" #include "ilo_shader.h" @@ -497,12 +496,10 @@ gen7_draw_wm(struct ilo_render *r, struct ilo_render_draw_session *session) { /* 3DSTATE_WM */ - if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) || + if (DIRTY(FS) || DIRTY(BLEND) || (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM)) { - const bool cc_may_kill = (vec->dsa->dw_blend_alpha || - vec->blend->alpha_to_coverage); - - gen7_3DSTATE_WM(r->builder, &vec->rasterizer->rs, vec->fs, cc_may_kill); + gen7_3DSTATE_WM(r->builder, &vec->rasterizer->rs, vec->fs, + vec->blend->alpha_may_kill); } /* 3DSTATE_BINDING_TABLE_POINTERS_PS */ diff --git a/src/gallium/drivers/ilo/ilo_render_gen8.c b/src/gallium/drivers/ilo/ilo_render_gen8.c index 7afb35e8b6b..e0e1a854ebc 100644 --- a/src/gallium/drivers/ilo/ilo_render_gen8.c +++ b/src/gallium/drivers/ilo/ilo_render_gen8.c @@ -28,7 +28,6 @@ #include "genhw/genhw.h" #include "core/ilo_builder_3d.h" #include "core/ilo_builder_render.h" -#include "util/u_dual_blend.h" #include "ilo_blitter.h" #include "ilo_shader.h" @@ -93,8 +92,8 @@ gen8_draw_wm(struct ilo_render *r, if (session->rs_delta.dirty & ILO_STATE_RASTER_3DSTATE_WM) gen8_3DSTATE_WM(r->builder, &vec->rasterizer->rs); - if (DIRTY(DSA)) - gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, vec->dsa); + if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_WM_DEPTH_STENCIL) + gen8_3DSTATE_WM_DEPTH_STENCIL(r->builder, &vec->blend->cc); /* 3DSTATE_WM_HZ_OP and 3DSTATE_WM_CHROMAKEY */ if (r->hw_ctx_changed) { @@ -127,15 +126,14 @@ gen8_draw_wm(struct ilo_render *r, gen8_3DSTATE_PS(r->builder, vec->fs); /* 3DSTATE_PS_EXTRA */ - if (DIRTY(FS) || DIRTY(DSA) || DIRTY(BLEND)) { - const bool cc_may_kill = (vec->dsa->dw_blend_alpha || - vec->blend->alpha_to_coverage); - gen8_3DSTATE_PS_EXTRA(r->builder, vec->fs, cc_may_kill, false); + if (DIRTY(FS) || DIRTY(BLEND)) { + gen8_3DSTATE_PS_EXTRA(r->builder, vec->fs, + vec->blend->alpha_may_kill, false); } /* 3DSTATE_PS_BLEND */ - if (DIRTY(BLEND) || DIRTY(FB) || DIRTY(DSA)) - gen8_3DSTATE_PS_BLEND(r->builder, vec->blend, &vec->fb, vec->dsa); + if (session->cc_delta.dirty & ILO_STATE_CC_3DSTATE_PS_BLEND) + gen8_3DSTATE_PS_BLEND(r->builder, &vec->blend->cc); /* 3DSTATE_SCISSOR_STATE_POINTERS */ if (session->scissor_changed) { diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c index 048152158eb..0a568bfbdc2 100644 --- a/src/gallium/drivers/ilo/ilo_state.c +++ b/src/gallium/drivers/ilo/ilo_state.c @@ -28,6 +28,7 @@ #include "core/ilo_builder_3d.h" /* for gen6_3d_translate_pipe_prim() */ #include "core/ilo_format.h" #include "core/ilo_state_3d.h" +#include "util/u_dual_blend.h" #include "util/u_dynarray.h" #include "util/u_helpers.h" #include "util/u_resource.h" @@ -160,6 +161,112 @@ ilo_translate_half_pixel_center(bool half_pixel_center) return (half_pixel_center) ? GEN6_PIXLOC_CENTER : GEN6_PIXLOC_UL_CORNER; } +static enum gen_compare_function +ilo_translate_compare_func(unsigned func) +{ + switch (func) { + case PIPE_FUNC_NEVER: return GEN6_COMPAREFUNCTION_NEVER; + case PIPE_FUNC_LESS: return GEN6_COMPAREFUNCTION_LESS; + case PIPE_FUNC_EQUAL: return GEN6_COMPAREFUNCTION_EQUAL; + case PIPE_FUNC_LEQUAL: return GEN6_COMPAREFUNCTION_LEQUAL; + case PIPE_FUNC_GREATER: return GEN6_COMPAREFUNCTION_GREATER; + case PIPE_FUNC_NOTEQUAL: return GEN6_COMPAREFUNCTION_NOTEQUAL; + case PIPE_FUNC_GEQUAL: return GEN6_COMPAREFUNCTION_GEQUAL; + case PIPE_FUNC_ALWAYS: return GEN6_COMPAREFUNCTION_ALWAYS; + default: + assert(!"unknown compare function"); + return GEN6_COMPAREFUNCTION_NEVER; + } +} + +static enum gen_stencil_op +ilo_translate_stencil_op(unsigned stencil_op) +{ + switch (stencil_op) { + case PIPE_STENCIL_OP_KEEP: return GEN6_STENCILOP_KEEP; + case PIPE_STENCIL_OP_ZERO: return GEN6_STENCILOP_ZERO; + case PIPE_STENCIL_OP_REPLACE: return GEN6_STENCILOP_REPLACE; + case PIPE_STENCIL_OP_INCR: return GEN6_STENCILOP_INCRSAT; + case PIPE_STENCIL_OP_DECR: return GEN6_STENCILOP_DECRSAT; + case PIPE_STENCIL_OP_INCR_WRAP: return GEN6_STENCILOP_INCR; + case PIPE_STENCIL_OP_DECR_WRAP: return GEN6_STENCILOP_DECR; + case PIPE_STENCIL_OP_INVERT: return GEN6_STENCILOP_INVERT; + default: + assert(!"unknown stencil op"); + return GEN6_STENCILOP_KEEP; + } +} + +static enum gen_logic_op +ilo_translate_logicop(unsigned logicop) +{ + switch (logicop) { + case PIPE_LOGICOP_CLEAR: return GEN6_LOGICOP_CLEAR; + case PIPE_LOGICOP_NOR: return GEN6_LOGICOP_NOR; + case PIPE_LOGICOP_AND_INVERTED: return GEN6_LOGICOP_AND_INVERTED; + case PIPE_LOGICOP_COPY_INVERTED: return GEN6_LOGICOP_COPY_INVERTED; + case PIPE_LOGICOP_AND_REVERSE: return GEN6_LOGICOP_AND_REVERSE; + case PIPE_LOGICOP_INVERT: return GEN6_LOGICOP_INVERT; + case PIPE_LOGICOP_XOR: return GEN6_LOGICOP_XOR; + case PIPE_LOGICOP_NAND: return GEN6_LOGICOP_NAND; + case PIPE_LOGICOP_AND: return GEN6_LOGICOP_AND; + case PIPE_LOGICOP_EQUIV: return GEN6_LOGICOP_EQUIV; + case PIPE_LOGICOP_NOOP: return GEN6_LOGICOP_NOOP; + case PIPE_LOGICOP_OR_INVERTED: return GEN6_LOGICOP_OR_INVERTED; + case PIPE_LOGICOP_COPY: return GEN6_LOGICOP_COPY; + case PIPE_LOGICOP_OR_REVERSE: return GEN6_LOGICOP_OR_REVERSE; + case PIPE_LOGICOP_OR: return GEN6_LOGICOP_OR; + case PIPE_LOGICOP_SET: return GEN6_LOGICOP_SET; + default: + assert(!"unknown logicop function"); + return GEN6_LOGICOP_CLEAR; + } +} + +static int +ilo_translate_blend_func(unsigned blend) +{ + switch (blend) { + case PIPE_BLEND_ADD: return GEN6_BLENDFUNCTION_ADD; + case PIPE_BLEND_SUBTRACT: return GEN6_BLENDFUNCTION_SUBTRACT; + case PIPE_BLEND_REVERSE_SUBTRACT: return GEN6_BLENDFUNCTION_REVERSE_SUBTRACT; + case PIPE_BLEND_MIN: return GEN6_BLENDFUNCTION_MIN; + case PIPE_BLEND_MAX: return GEN6_BLENDFUNCTION_MAX; + default: + assert(!"unknown blend function"); + return GEN6_BLENDFUNCTION_ADD; + } +} + +static int +ilo_translate_blend_factor(unsigned factor) +{ + switch (factor) { + case PIPE_BLENDFACTOR_ONE: return GEN6_BLENDFACTOR_ONE; + case PIPE_BLENDFACTOR_SRC_COLOR: return GEN6_BLENDFACTOR_SRC_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA: return GEN6_BLENDFACTOR_SRC_ALPHA; + case PIPE_BLENDFACTOR_DST_ALPHA: return GEN6_BLENDFACTOR_DST_ALPHA; + case PIPE_BLENDFACTOR_DST_COLOR: return GEN6_BLENDFACTOR_DST_COLOR; + case PIPE_BLENDFACTOR_SRC_ALPHA_SATURATE: return GEN6_BLENDFACTOR_SRC_ALPHA_SATURATE; + case PIPE_BLENDFACTOR_CONST_COLOR: return GEN6_BLENDFACTOR_CONST_COLOR; + case PIPE_BLENDFACTOR_CONST_ALPHA: return GEN6_BLENDFACTOR_CONST_ALPHA; + case PIPE_BLENDFACTOR_SRC1_COLOR: return GEN6_BLENDFACTOR_SRC1_COLOR; + case PIPE_BLENDFACTOR_SRC1_ALPHA: return GEN6_BLENDFACTOR_SRC1_ALPHA; + case PIPE_BLENDFACTOR_ZERO: return GEN6_BLENDFACTOR_ZERO; + case PIPE_BLENDFACTOR_INV_SRC_COLOR: return GEN6_BLENDFACTOR_INV_SRC_COLOR; + case PIPE_BLENDFACTOR_INV_SRC_ALPHA: return GEN6_BLENDFACTOR_INV_SRC_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_ALPHA: return GEN6_BLENDFACTOR_INV_DST_ALPHA; + case PIPE_BLENDFACTOR_INV_DST_COLOR: return GEN6_BLENDFACTOR_INV_DST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_COLOR: return GEN6_BLENDFACTOR_INV_CONST_COLOR; + case PIPE_BLENDFACTOR_INV_CONST_ALPHA: return GEN6_BLENDFACTOR_INV_CONST_ALPHA; + case PIPE_BLENDFACTOR_INV_SRC1_COLOR: return GEN6_BLENDFACTOR_INV_SRC1_COLOR; + case PIPE_BLENDFACTOR_INV_SRC1_ALPHA: return GEN6_BLENDFACTOR_INV_SRC1_ALPHA; + default: + assert(!"unknown blend factor"); + return GEN6_BLENDFACTOR_ONE; + } +} + static void finalize_shader_states(struct ilo_state_vector *vec) { @@ -466,6 +573,98 @@ finalize_rasterizer(struct ilo_context *ilo) } } +static bool +finalize_blend_rt(struct ilo_context *ilo) +{ + struct ilo_state_vector *vec = &ilo->state_vector; + const struct ilo_fb_state *fb = &vec->fb; + struct ilo_blend_state *blend = vec->blend; + struct ilo_state_cc_blend_info *info = &vec->blend->info.blend; + bool changed = false; + unsigned i; + + if (!(vec->dirty & (ILO_DIRTY_FB | ILO_DIRTY_BLEND))) + return false; + + /* set up one for dummy RT writes */ + if (!fb->state.nr_cbufs) { + if (info->rt != &blend->dummy_rt) { + info->rt = &blend->dummy_rt; + info->rt_count = 1; + changed = true; + } + + return changed; + } + + if (info->rt != blend->effective_rt || + info->rt_count != fb->state.nr_cbufs) { + info->rt = blend->effective_rt; + info->rt_count = fb->state.nr_cbufs; + changed = true; + } + + for (i = 0; i < fb->state.nr_cbufs; i++) { + const struct ilo_fb_blend_caps *caps = &fb->blend_caps[i]; + struct ilo_state_cc_blend_rt_info *rt = &blend->effective_rt[i]; + /* ignore logicop when not UNORM */ + const bool logicop_enable = + (blend->rt[i].logicop_enable && caps->is_unorm); + + if (rt->cv_is_unorm != caps->is_unorm || + rt->cv_is_integer != caps->is_integer || + rt->logicop_enable != logicop_enable || + rt->force_dst_alpha_one != caps->force_dst_alpha_one) { + rt->cv_is_unorm = caps->is_unorm; + rt->cv_is_integer = caps->is_integer; + rt->logicop_enable = logicop_enable; + rt->force_dst_alpha_one = caps->force_dst_alpha_one; + + changed = true; + } + } + + return changed; +} + +static void +finalize_blend(struct ilo_context *ilo) +{ + const struct ilo_dev *dev = ilo->dev; + struct ilo_state_vector *vec = &ilo->state_vector; + struct ilo_blend_state *blend = vec->blend; + struct ilo_state_cc_info *info = &blend->info; + const bool sample_count_one = (vec->fb.num_samples <= 1); + const bool float_source0_alpha = + (!vec->fb.state.nr_cbufs || !vec->fb.state.cbufs[0] || + !util_format_is_pure_integer(vec->fb.state.cbufs[0]->format)); + + /* check for non-orthogonal states */ + if (finalize_blend_rt(ilo) || + info->alpha.cv_sample_count_one != sample_count_one || + info->alpha.cv_float_source0_alpha != float_source0_alpha || + info->alpha.test_enable != vec->dsa->alpha_test || + info->alpha.test_func != vec->dsa->alpha_func || + memcmp(&info->stencil, &vec->dsa->stencil, sizeof(info->stencil)) || + memcmp(&info->depth, &vec->dsa->depth, sizeof(info->depth)) || + memcmp(&info->params, &vec->cc_params, sizeof(info->params))) { + info->alpha.cv_sample_count_one = sample_count_one; + info->alpha.cv_float_source0_alpha = float_source0_alpha; + info->alpha.test_enable = vec->dsa->alpha_test; + info->alpha.test_func = vec->dsa->alpha_func; + info->stencil = vec->dsa->stencil; + info->depth = vec->dsa->depth; + info->params = vec->cc_params; + + ilo_state_cc_set_info(&blend->cc, dev, info); + + blend->alpha_may_kill = (info->alpha.alpha_to_coverage || + info->alpha.test_enable); + + vec->dirty |= ILO_DIRTY_BLEND; + } +} + /** * Finalize states. Some states depend on other states and are * incomplete/invalid until finalized. @@ -483,6 +682,7 @@ ilo_finalize_3d_states(struct ilo_context *ilo, finalize_rasterizer(ilo); finalize_viewport(ilo); + finalize_blend(ilo); u_upload_unmap(ilo->uploader); } @@ -526,12 +726,79 @@ ilo_create_blend_state(struct pipe_context *pipe, const struct pipe_blend_state *state) { const struct ilo_dev *dev = ilo_context(pipe)->dev; + struct ilo_state_cc_info *info; struct ilo_blend_state *blend; + int i; - blend = MALLOC_STRUCT(ilo_blend_state); + blend = CALLOC_STRUCT(ilo_blend_state); assert(blend); - ilo_gpe_init_blend(dev, state, blend); + info = &blend->info; + + info->alpha.cv_float_source0_alpha = true; + info->alpha.cv_sample_count_one = true; + info->alpha.alpha_to_one = state->alpha_to_one; + info->alpha.alpha_to_coverage = state->alpha_to_coverage; + info->alpha.test_enable = false; + info->alpha.test_func = GEN6_COMPAREFUNCTION_ALWAYS; + + info->stencil.cv_has_buffer = true; + info->depth.cv_has_buffer= true; + + info->blend.rt = blend->effective_rt; + info->blend.rt_count = 1; + info->blend.dither_enable = state->dither; + + for (i = 0; i < ARRAY_SIZE(blend->rt); i++) { + const struct pipe_rt_blend_state *rt = &state->rt[i]; + struct ilo_state_cc_blend_rt_info *rt_info = &blend->rt[i]; + + rt_info->cv_has_buffer = true; + rt_info->cv_is_unorm = true; + rt_info->cv_is_integer = false; + + /* logic op takes precedence over blending */ + if (state->logicop_enable) { + rt_info->logicop_enable = true; + rt_info->logicop_func = ilo_translate_logicop(state->logicop_func); + } else if (rt->blend_enable) { + rt_info->blend_enable = true; + + rt_info->rgb_src = ilo_translate_blend_factor(rt->rgb_src_factor); + rt_info->rgb_dst = ilo_translate_blend_factor(rt->rgb_dst_factor); + rt_info->rgb_func = ilo_translate_blend_func(rt->rgb_func); + + rt_info->a_src = ilo_translate_blend_factor(rt->alpha_src_factor); + rt_info->a_dst = ilo_translate_blend_factor(rt->alpha_dst_factor); + rt_info->a_func = ilo_translate_blend_func(rt->alpha_func); + } + + if (!(rt->colormask & PIPE_MASK_A)) + rt_info->argb_write_disables |= (1 << 3); + if (!(rt->colormask & PIPE_MASK_R)) + rt_info->argb_write_disables |= (1 << 2); + if (!(rt->colormask & PIPE_MASK_G)) + rt_info->argb_write_disables |= (1 << 1); + if (!(rt->colormask & PIPE_MASK_B)) + rt_info->argb_write_disables |= (1 << 0); + + if (!state->independent_blend_enable) { + for (i = 1; i < ARRAY_SIZE(blend->rt); i++) + blend->rt[i] = *rt_info; + break; + } + } + + memcpy(blend->effective_rt, blend->rt, sizeof(blend->rt)); + + blend->dummy_rt.argb_write_disables = 0xf; + + if (!ilo_state_cc_init(&blend->cc, dev, &blend->info)) { + FREE(blend); + return NULL; + } + + blend->dual_blend = util_blend_state_is_dual(state, 0); return blend; } @@ -814,13 +1081,48 @@ static void * ilo_create_depth_stencil_alpha_state(struct pipe_context *pipe, const struct pipe_depth_stencil_alpha_state *state) { - const struct ilo_dev *dev = ilo_context(pipe)->dev; struct ilo_dsa_state *dsa; + int i; - dsa = MALLOC_STRUCT(ilo_dsa_state); + dsa = CALLOC_STRUCT(ilo_dsa_state); assert(dsa); - ilo_gpe_init_dsa(dev, state, dsa); + dsa->depth.cv_has_buffer = true; + dsa->depth.test_enable = state->depth.enabled; + dsa->depth.write_enable = state->depth.writemask; + dsa->depth.test_func = ilo_translate_compare_func(state->depth.func); + + dsa->stencil.cv_has_buffer = true; + for (i = 0; i < ARRAY_SIZE(state->stencil); i++) { + const struct pipe_stencil_state *stencil = &state->stencil[i]; + struct ilo_state_cc_stencil_op_info *op; + + if (!stencil->enabled) + break; + + if (i == 0) { + dsa->stencil.test_enable = true; + dsa->stencil_front.test_mask = stencil->valuemask; + dsa->stencil_front.write_mask = stencil->writemask; + + op = &dsa->stencil.front; + } else { + dsa->stencil.twosided_enable = true; + dsa->stencil_back.test_mask = stencil->valuemask; + dsa->stencil_back.write_mask = stencil->writemask; + + op = &dsa->stencil.back; + } + + op->test_func = ilo_translate_compare_func(stencil->func); + op->fail_op = ilo_translate_stencil_op(stencil->fail_op); + op->zfail_op = ilo_translate_stencil_op(stencil->zfail_op); + op->zpass_op = ilo_translate_stencil_op(stencil->zpass_op); + } + + dsa->alpha_test = state->alpha.enabled; + dsa->alpha_ref = state->alpha.ref_value; + dsa->alpha_func = ilo_translate_compare_func(state->alpha.func); return dsa; } @@ -831,6 +1133,17 @@ ilo_bind_depth_stencil_alpha_state(struct pipe_context *pipe, void *state) struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; vec->dsa = state; + if (vec->dsa) { + vec->cc_params.alpha_ref = vec->dsa->alpha_ref; + vec->cc_params.stencil_front.test_mask = + vec->dsa->stencil_front.test_mask; + vec->cc_params.stencil_front.write_mask = + vec->dsa->stencil_front.write_mask; + vec->cc_params.stencil_back.test_mask = + vec->dsa->stencil_back.test_mask; + vec->cc_params.stencil_back.write_mask = + vec->dsa->stencil_back.write_mask; + } vec->dirty |= ILO_DIRTY_DSA; } @@ -990,7 +1303,7 @@ ilo_set_blend_color(struct pipe_context *pipe, { struct ilo_state_vector *vec = &ilo_context(pipe)->state_vector; - vec->blend_color = *state; + memcpy(vec->cc_params.blend_rgba, state->color, sizeof(state->color)); vec->dirty |= ILO_DIRTY_BLEND_COLOR; } @@ -1007,6 +1320,9 @@ ilo_set_stencil_ref(struct pipe_context *pipe, vec->stencil_ref = *state; + vec->cc_params.stencil_front.test_ref = state->ref_value[0]; + vec->cc_params.stencil_back.test_ref = state->ref_value[1]; + vec->dirty |= ILO_DIRTY_STENCIL_REF; } diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h index 8f6cce2b53a..39d0d7eac8b 100644 --- a/src/gallium/drivers/ilo/ilo_state.h +++ b/src/gallium/drivers/ilo/ilo_state.h @@ -29,6 +29,7 @@ #define ILO_STATE_H #include "core/ilo_state_3d.h" +#include "core/ilo_state_cc.h" #include "core/ilo_state_raster.h" #include "core/ilo_state_sampler.h" #include "core/ilo_state_surface.h" @@ -191,6 +192,32 @@ struct ilo_viewport_state { uint32_t vp_data[20 * ILO_MAX_VIEWPORTS]; }; +struct ilo_dsa_state { + struct ilo_state_cc_depth_info depth; + + struct ilo_state_cc_stencil_info stencil; + struct { + uint8_t test_mask; + uint8_t write_mask; + } stencil_front, stencil_back; + + bool alpha_test; + float alpha_ref; + enum gen_compare_function alpha_func; +}; + +struct ilo_blend_state { + struct ilo_state_cc_blend_rt_info rt[PIPE_MAX_COLOR_BUFS]; + struct ilo_state_cc_blend_rt_info dummy_rt; + bool dual_blend; + + /* these are invalid until finalize_blend() */ + struct ilo_state_cc_blend_rt_info effective_rt[PIPE_MAX_COLOR_BUFS]; + struct ilo_state_cc_info info; + struct ilo_state_cc cc; + bool alpha_may_kill; +}; + struct ilo_global_binding_cso { struct pipe_resource *resource; uint32_t *handle; @@ -240,10 +267,11 @@ struct ilo_state_vector { struct ilo_shader_state *fs; - const struct ilo_dsa_state *dsa; + struct ilo_state_cc_params_info cc_params; struct pipe_stencil_ref stencil_ref; - const struct ilo_blend_state *blend; - struct pipe_blend_color blend_color; + const struct ilo_dsa_state *dsa; + struct ilo_blend_state *blend; + struct ilo_fb_state fb; /* shader resources */ -- 2.30.2