summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/gallium/drivers/ilo/ilo_builder_3d_bottom.h105
-rw-r--r--src/gallium/drivers/ilo/ilo_builder_decode.c5
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen6.c2
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen7.c2
-rw-r--r--src/gallium/drivers/ilo/ilo_state.h7
-rw-r--r--src/gallium/drivers/ilo/ilo_state_3d_bottom.c220
6 files changed, 319 insertions, 22 deletions
diff --git a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h
index fd82d045683..14360af681a 100644
--- a/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h
+++ b/src/gallium/drivers/ilo/ilo_builder_3d_bottom.h
@@ -706,6 +706,44 @@ 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 uint8_t cmd_len = 2;
+ uint32_t dw1, *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;
+}
+
+static inline void
gen6_3DSTATE_CONSTANT_PS(struct ilo_builder *builder,
const uint32_t *bufs, const int *sizes,
int num_bufs)
@@ -1517,7 +1555,7 @@ gen6_BLEND_STATE(struct ilo_builder *builder,
assert(num_targets <= 8);
if (!num_targets) {
- if (!dsa->dw_alpha)
+ if (!dsa->dw_blend_alpha)
return 0;
/* to be able to reference alpha func */
num_targets = 1;
@@ -1548,13 +1586,13 @@ gen6_BLEND_STATE(struct ilo_builder *builder,
dw[1] |= blend->dw_logicop;
if (caps->can_alpha_test)
- dw[1] |= dsa->dw_alpha;
+ dw[1] |= dsa->dw_blend_alpha;
} else {
dw[1] |= GEN6_RT_DW1_WRITE_DISABLE_A |
GEN6_RT_DW1_WRITE_DISABLE_R |
GEN6_RT_DW1_WRITE_DISABLE_G |
GEN6_RT_DW1_WRITE_DISABLE_B |
- dsa->dw_alpha;
+ dsa->dw_blend_alpha;
}
/*
@@ -1575,4 +1613,65 @@ gen6_BLEND_STATE(struct ilo_builder *builder,
return state_offset;
}
+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 int state_align = 64;
+ int state_len;
+ uint32_t state_offset, *dw;
+ unsigned i;
+
+ ILO_DEV_ASSERT(builder->dev, 8, 8);
+
+ assert(fb->state.nr_cbufs <= 8);
+
+ /* may need to reference alpha func even when there is no color buffer */
+ if (!fb->state.nr_cbufs && !dsa->dw_blend_alpha)
+ return 0;
+
+ state_len = 1 + 2 * fb->state.nr_cbufs;
+
+ 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_DISABLE_A |
+ GEN8_RT_DW0_WRITE_DISABLE_R |
+ GEN8_RT_DW0_WRITE_DISABLE_G |
+ GEN8_RT_DW0_WRITE_DISABLE_B;
+ }
+
+ dw += 2;
+ }
+
+ return state_offset;
+}
+
#endif /* ILO_BUILDER_3D_BOTTOM_H */
diff --git a/src/gallium/drivers/ilo/ilo_builder_decode.c b/src/gallium/drivers/ilo/ilo_builder_decode.c
index d645f389fad..f518b49292b 100644
--- a/src/gallium/drivers/ilo/ilo_builder_decode.c
+++ b/src/gallium/drivers/ilo/ilo_builder_decode.c
@@ -371,6 +371,11 @@ writer_decode_blend(const struct ilo_builder *builder,
unsigned offset = item->offset;
unsigned i;
+ if (ilo_dev_gen(builder->dev) >= ILO_GEN(8)) {
+ writer_dw(builder, which, offset, 0, "BLEND\n");
+ offset += 4;
+ }
+
for (i = 0; i < count; i++) {
writer_dw(builder, which, offset, 0, "BLEND%d\n", i);
writer_dw(builder, which, offset, 1, "BLEND%d\n", i);
diff --git a/src/gallium/drivers/ilo/ilo_render_gen6.c b/src/gallium/drivers/ilo/ilo_render_gen6.c
index 3f0aa7cf23c..5e8cb33e0d2 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_render_gen6.c
@@ -702,7 +702,7 @@ gen6_draw_wm(struct ilo_render *r,
if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) ||
DIRTY(RASTERIZER) || r->instruction_bo_changed) {
const bool dual_blend = vec->blend->dual_blend;
- const bool cc_may_kill = (vec->dsa->dw_alpha ||
+ 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)
diff --git a/src/gallium/drivers/ilo/ilo_render_gen7.c b/src/gallium/drivers/ilo/ilo_render_gen7.c
index 5fe6995ef8c..1de6e2b2202 100644
--- a/src/gallium/drivers/ilo/ilo_render_gen7.c
+++ b/src/gallium/drivers/ilo/ilo_render_gen7.c
@@ -516,7 +516,7 @@ gen7_draw_wm(struct ilo_render *r,
{
/* 3DSTATE_WM */
if (DIRTY(FS) || DIRTY(BLEND) || DIRTY(DSA) || DIRTY(RASTERIZER)) {
- const bool cc_may_kill = (vec->dsa->dw_alpha ||
+ const bool cc_may_kill = (vec->dsa->dw_blend_alpha ||
vec->blend->alpha_to_coverage);
gen7_3DSTATE_WM(r->builder, vec->fs, vec->rasterizer, cc_may_kill);
diff --git a/src/gallium/drivers/ilo/ilo_state.h b/src/gallium/drivers/ilo/ilo_state.h
index e935e5d5b78..737f50e31a4 100644
--- a/src/gallium/drivers/ilo/ilo_state.h
+++ b/src/gallium/drivers/ilo/ilo_state.h
@@ -250,7 +250,8 @@ struct ilo_dsa_state {
/* DEPTH_STENCIL_STATE or Gen8+ 3DSTATE_WM_DEPTH_STENCIL */
uint32_t payload[3];
- uint32_t dw_alpha;
+ uint32_t dw_blend_alpha;
+ uint32_t dw_ps_blend_alpha;
ubyte alpha_ref;
};
@@ -271,6 +272,10 @@ struct ilo_blend_state {
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_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 b309c947770..5ad88de2b75 100644
--- a/src/gallium/drivers/ilo/ilo_state_3d_bottom.c
+++ b/src/gallium/drivers/ilo/ilo_state_3d_bottom.c
@@ -1529,6 +1529,49 @@ blend_get_rt_blend_enable_gen6(const struct ilo_dev_info *dev,
return dw;
}
+static uint32_t
+blend_get_rt_blend_enable_gen8(const struct ilo_dev_info *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_info *dev,
const struct pipe_blend_state *state,
@@ -1573,6 +1616,49 @@ blend_init_cso_gen6(const struct ilo_dev_info *dev,
}
}
+static bool
+blend_init_cso_gen8(const struct ilo_dev_info *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_DISABLE_A;
+ if (!(rt->colormask & PIPE_MASK_R))
+ cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLE_R;
+ if (!(rt->colormask & PIPE_MASK_G))
+ cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLE_G;
+ if (!(rt->colormask & PIPE_MASK_B))
+ cso->payload[0] |= GEN8_RT_DW0_WRITE_DISABLE_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_info *dev,
const struct pipe_blend_state *state)
@@ -1587,6 +1673,19 @@ blend_get_logicop_enable_gen6(const struct ilo_dev_info *dev,
}
static uint32_t
+blend_get_logicop_enable_gen8(const struct ilo_dev_info *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_info *dev,
const struct pipe_blend_state *state,
bool dual_blend)
@@ -1612,6 +1711,54 @@ blend_get_alpha_mod_gen6(const struct ilo_dev_info *dev,
return dw;
}
+static uint32_t
+blend_get_alpha_mod_gen8(const struct ilo_dev_info *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_info *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_info *dev,
const struct pipe_blend_state *state,
@@ -1619,25 +1766,57 @@ ilo_gpe_init_blend(const struct ilo_dev_info *dev,
{
unsigned i;
- ILO_DEV_ASSERT(dev, 6, 7.5);
+ 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;
- 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_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);
+ 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 {
- for (i = 1; i < Elements(blend->cso); i++)
- blend->cso[i] = blend->cso[0];
+ 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];
+ }
}
}
@@ -1843,7 +2022,10 @@ ilo_gpe_init_dsa(const struct ilo_dev_info *dev,
state->stencil[1].valuemask << 8 |
state->stencil[1].writemask;
- dsa->dw_alpha = dsa_get_alpha_enable_gen6(dev, &state->alpha);
+ dsa->dw_blend_alpha = dsa_get_alpha_enable_gen6(dev, &state->alpha);
+ dsa->dw_ps_blend_alpha = (state->alpha.enabled) ?
+ GEN8_PS_BLEND_DW1_ALPHA_TEST_ENABLE : 0;
+
dsa->alpha_ref = float_to_ubyte(state->alpha.ref_value);
}
@@ -1916,10 +2098,16 @@ fb_set_blend_caps(const struct ilo_dev_info *dev,
*
* "Logic Ops are only supported on *_UNORM surfaces (excluding _SRGB
* variants), otherwise Logic Ops must be DISABLED."
+ *
+ * According to the classic driver, this is lifted on Gen8+.
*/
- caps->can_logicop = (ch >= 0 && desc->channel[ch].normalized &&
- desc->channel[ch].type == UTIL_FORMAT_TYPE_UNSIGNED &&
- desc->colorspace == UTIL_FORMAT_COLORSPACE_RGB);
+ if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
+ caps->can_logicop = true;
+ } else {
+ 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);