ilo: update ilo_blend_state and related functions for Gen8
This commit is contained in:
@@ -705,6 +705,44 @@ gen8_3DSTATE_PS_EXTRA(struct ilo_builder *builder,
|
||||
dw[1] = dw1;
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -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 */
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
@@ -1586,6 +1672,19 @@ blend_get_logicop_enable_gen6(const struct ilo_dev_info *dev,
|
||||
gen6_translate_pipe_logicop(state->logicop_func) << 18;
|
||||
}
|
||||
|
||||
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,
|
||||
@@ -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;
|
||||
if (ilo_dev_gen(dev) >= ILO_GEN(8)) {
|
||||
bool independent_alpha;
|
||||
|
||||
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);
|
||||
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);
|
||||
|
||||
Reference in New Issue
Block a user