mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-01-07 04:20:18 +01:00
ilo: introduce blend CSO
Introduce ilo_blend_cso and initialize it in create_blend_state(). This saves us from having to construct hardware blend states in draw_vbo().
This commit is contained in:
parent
b3c9e2161f
commit
eea1be2072
6 changed files with 183 additions and 97 deletions
|
|
@ -669,12 +669,9 @@ gen6_pipeline_wm(struct ilo_3d_pipeline *p,
|
|||
DIRTY(RASTERIZER)) {
|
||||
const struct ilo_shader *fs = (ilo->fs)? ilo->fs->shader : NULL;
|
||||
const int num_samplers = ilo->sampler[PIPE_SHADER_FRAGMENT].count;
|
||||
const bool dual_blend =
|
||||
(!ilo->blend->state.logicop_enable &&
|
||||
ilo->blend->state.rt[0].blend_enable &&
|
||||
util_blend_state_is_dual(&ilo->blend->state, 0));
|
||||
const bool dual_blend = ilo->blend->dual_blend;
|
||||
const bool cc_may_kill = (ilo->dsa->state.alpha.enabled ||
|
||||
ilo->blend->state.alpha_to_coverage);
|
||||
ilo->blend->alpha_to_coverage);
|
||||
|
||||
if (fs)
|
||||
assert(!fs->pcb.clip_state_size);
|
||||
|
|
@ -807,7 +804,7 @@ gen6_pipeline_state_cc(struct ilo_3d_pipeline *p,
|
|||
/* BLEND_STATE */
|
||||
if (DIRTY(BLEND) || DIRTY(FRAMEBUFFER) || DIRTY(DEPTH_STENCIL_ALPHA)) {
|
||||
p->state.BLEND_STATE = p->gen6_BLEND_STATE(p->dev,
|
||||
&ilo->blend->state, &ilo->fb, &ilo->dsa->state.alpha, p->cp);
|
||||
ilo->blend, &ilo->fb, &ilo->dsa->state.alpha, p->cp);
|
||||
|
||||
session->cc_state_blend_changed = true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -463,7 +463,7 @@ gen7_pipeline_wm(struct ilo_3d_pipeline *p,
|
|||
DIRTY(RASTERIZER)) {
|
||||
const struct ilo_shader *fs = (ilo->fs)? ilo->fs->shader : NULL;
|
||||
const bool cc_may_kill = (ilo->dsa->state.alpha.enabled ||
|
||||
ilo->blend->state.alpha_to_coverage);
|
||||
ilo->blend->alpha_to_coverage);
|
||||
|
||||
if (fs)
|
||||
assert(!fs->pcb.clip_state_size);
|
||||
|
|
@ -496,10 +496,7 @@ gen7_pipeline_wm(struct ilo_3d_pipeline *p,
|
|||
DIRTY(BLEND)) {
|
||||
const struct ilo_shader *fs = (ilo->fs)? ilo->fs->shader : NULL;
|
||||
const int num_samplers = ilo->sampler[PIPE_SHADER_FRAGMENT].count;
|
||||
const bool dual_blend =
|
||||
(!ilo->blend->state.logicop_enable &&
|
||||
ilo->blend->state.rt[0].blend_enable &&
|
||||
util_blend_state_is_dual(&ilo->blend->state, 0));
|
||||
const bool dual_blend = ilo->blend->dual_blend;
|
||||
|
||||
if (fs)
|
||||
assert(!fs->pcb.clip_state_size);
|
||||
|
|
|
|||
|
|
@ -107,8 +107,23 @@ struct ilo_dsa_state {
|
|||
struct pipe_depth_stencil_alpha_state state;
|
||||
};
|
||||
|
||||
struct ilo_blend_cso {
|
||||
/* BLEND_STATE */
|
||||
uint32_t payload[2];
|
||||
|
||||
uint32_t dw_blend;
|
||||
uint32_t dw_blend_dst_alpha_forced_one;
|
||||
|
||||
uint32_t dw_logicop;
|
||||
uint32_t dw_alpha_mod;
|
||||
};
|
||||
|
||||
struct ilo_blend_state {
|
||||
struct pipe_blend_state state;
|
||||
struct ilo_blend_cso cso[ILO_MAX_DRAW_BUFFERS];
|
||||
|
||||
bool independent_blend_enable;
|
||||
bool dual_blend;
|
||||
bool alpha_to_coverage;
|
||||
};
|
||||
|
||||
struct ilo_sampler_cso {
|
||||
|
|
@ -191,6 +206,11 @@ void
|
|||
ilo_gpe_set_scissor_null(const struct ilo_dev_info *dev,
|
||||
struct ilo_scissor_state *scissor);
|
||||
|
||||
void
|
||||
ilo_gpe_init_blend(const struct ilo_dev_info *dev,
|
||||
const struct pipe_blend_state *state,
|
||||
struct ilo_blend_state *blend);
|
||||
|
||||
void
|
||||
ilo_gpe_init_sampler_cso(const struct ilo_dev_info *dev,
|
||||
const struct pipe_sampler_state *state,
|
||||
|
|
|
|||
|
|
@ -3229,9 +3229,141 @@ gen6_blend_factor_dst_alpha_forced_one(int factor)
|
|||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
blend_get_rt_blend_enable(const struct ilo_dev_info *dev,
|
||||
const struct pipe_rt_blend_state *rt,
|
||||
bool dst_alpha_forced_one)
|
||||
{
|
||||
int rgb_src, rgb_dst, a_src, a_dst;
|
||||
uint32_t dw;
|
||||
|
||||
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 = 1 << 31 |
|
||||
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 |= 1 << 30;
|
||||
|
||||
return dw;
|
||||
}
|
||||
|
||||
void
|
||||
ilo_gpe_init_blend(const struct ilo_dev_info *dev,
|
||||
const struct pipe_blend_state *state,
|
||||
struct ilo_blend_state *blend)
|
||||
{
|
||||
unsigned num_cso, i;
|
||||
|
||||
ILO_GPE_VALID_GEN(dev, 6, 7);
|
||||
|
||||
if (state->independent_blend_enable) {
|
||||
num_cso = Elements(blend->cso);
|
||||
}
|
||||
else {
|
||||
memset(blend->cso, 0, sizeof(blend->cso));
|
||||
num_cso = 1;
|
||||
}
|
||||
|
||||
blend->independent_blend_enable = state->independent_blend_enable;
|
||||
blend->alpha_to_coverage = state->alpha_to_coverage;
|
||||
blend->dual_blend = false;
|
||||
|
||||
for (i = 0; i < num_cso; i++) {
|
||||
const struct pipe_rt_blend_state *rt = &state->rt[i];
|
||||
struct ilo_blend_cso *cso = &blend->cso[i];
|
||||
bool dual_blend;
|
||||
|
||||
cso->payload[0] = 0;
|
||||
cso->payload[1] = BRW_RENDERTARGET_CLAMPRANGE_FORMAT << 2 |
|
||||
0x3;
|
||||
|
||||
if (!(rt->colormask & PIPE_MASK_A))
|
||||
cso->payload[1] |= 1 << 27;
|
||||
if (!(rt->colormask & PIPE_MASK_R))
|
||||
cso->payload[1] |= 1 << 26;
|
||||
if (!(rt->colormask & PIPE_MASK_G))
|
||||
cso->payload[1] |= 1 << 25;
|
||||
if (!(rt->colormask & PIPE_MASK_B))
|
||||
cso->payload[1] |= 1 << 24;
|
||||
|
||||
if (state->dither)
|
||||
cso->payload[1] |= 1 << 12;
|
||||
|
||||
/*
|
||||
* From the Sandy Bridge PRM, volume 2 part 1, page 365:
|
||||
*
|
||||
* "Color Buffer Blending and Logic Ops must not be enabled
|
||||
* simultaneously, or behavior is UNDEFINED."
|
||||
*
|
||||
* Since state->logicop_enable takes precedence over rt->blend_enable,
|
||||
* no special care is needed.
|
||||
*/
|
||||
if (state->logicop_enable) {
|
||||
cso->dw_logicop = 1 << 22 |
|
||||
gen6_translate_pipe_logicop(state->logicop_func) << 18;
|
||||
|
||||
cso->dw_blend = 0;
|
||||
cso->dw_blend_dst_alpha_forced_one = 0;
|
||||
|
||||
dual_blend = false;
|
||||
}
|
||||
else {
|
||||
cso->dw_logicop = 0;
|
||||
|
||||
cso->dw_blend = blend_get_rt_blend_enable(dev, rt, false);
|
||||
cso->dw_blend_dst_alpha_forced_one =
|
||||
blend_get_rt_blend_enable(dev, rt, true);
|
||||
|
||||
dual_blend = (rt->blend_enable &&
|
||||
util_blend_state_is_dual(state, i));
|
||||
}
|
||||
|
||||
cso->dw_alpha_mod = 0;
|
||||
|
||||
if (state->alpha_to_coverage) {
|
||||
cso->dw_alpha_mod |= 1 << 31;
|
||||
|
||||
if (dev->gen >= ILO_GEN(7))
|
||||
cso->dw_alpha_mod |= 1 << 29;
|
||||
}
|
||||
|
||||
/*
|
||||
* From the Sandy Bridge PRM, volume 2 part 1, page 378:
|
||||
*
|
||||
* "If Dual Source Blending is enabled, this bit (AlphaToOne Enable)
|
||||
* must be disabled."
|
||||
*/
|
||||
if (state->alpha_to_one && !dual_blend)
|
||||
cso->dw_alpha_mod |= 1 << 30;
|
||||
|
||||
if (dual_blend)
|
||||
blend->dual_blend = true;
|
||||
}
|
||||
}
|
||||
|
||||
static uint32_t
|
||||
gen6_emit_BLEND_STATE(const struct ilo_dev_info *dev,
|
||||
const struct pipe_blend_state *blend,
|
||||
const struct ilo_blend_state *blend,
|
||||
const struct ilo_fb_state *fb,
|
||||
const struct pipe_alpha_state *alpha,
|
||||
struct ilo_cp *cp)
|
||||
|
|
@ -3239,7 +3371,7 @@ gen6_emit_BLEND_STATE(const struct ilo_dev_info *dev,
|
|||
const int state_align = 64 / 4;
|
||||
int state_len;
|
||||
uint32_t state_offset, *dw;
|
||||
int num_targets, i;
|
||||
unsigned num_targets, i;
|
||||
|
||||
ILO_GPE_VALID_GEN(dev, 6, 7);
|
||||
|
||||
|
|
@ -3264,12 +3396,12 @@ gen6_emit_BLEND_STATE(const struct ilo_dev_info *dev,
|
|||
state_len, state_align, &state_offset);
|
||||
|
||||
for (i = 0; i < num_targets; i++) {
|
||||
const int target = (blend->independent_blend_enable) ? i : 0;
|
||||
const struct pipe_rt_blend_state *rt = &blend->rt[target];
|
||||
const unsigned idx = (blend->independent_blend_enable) ? i : 0;
|
||||
const struct ilo_blend_cso *cso = &blend->cso[idx];
|
||||
const int num_samples = fb->num_samples;
|
||||
const struct util_format_description *format_desc =
|
||||
(target < fb->state.nr_cbufs) ?
|
||||
util_format_description(fb->state.cbufs[target]->format) : NULL;
|
||||
(idx < fb->state.nr_cbufs) ?
|
||||
util_format_description(fb->state.cbufs[idx]->format) : NULL;
|
||||
bool rt_is_unorm, rt_is_pure_integer, rt_dst_alpha_forced_one;
|
||||
|
||||
rt_is_unorm = true;
|
||||
|
|
@ -3306,56 +3438,27 @@ gen6_emit_BLEND_STATE(const struct ilo_dev_info *dev,
|
|||
}
|
||||
}
|
||||
|
||||
dw[0] = 0;
|
||||
dw[1] = BRW_RENDERTARGET_CLAMPRANGE_FORMAT << 2 | 0x3;
|
||||
dw[0] = cso->payload[0];
|
||||
dw[1] = cso->payload[1];
|
||||
|
||||
if (!rt_is_pure_integer) {
|
||||
if (rt_dst_alpha_forced_one)
|
||||
dw[0] |= cso->dw_blend_dst_alpha_forced_one;
|
||||
else
|
||||
dw[0] |= cso->dw_blend;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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.
|
||||
* "Logic Ops are only supported on *_UNORM surfaces (excluding
|
||||
* _SRGB variants), otherwise Logic Ops must be DISABLED."
|
||||
*
|
||||
* * Logic Ops are only supported on *_UNORM surfaces (excluding
|
||||
* _SRGB variants), otherwise Logic Ops must be DISABLED."
|
||||
*
|
||||
* Since blend->logicop_enable takes precedence over rt->blend_enable,
|
||||
* and logicop is ignored for non-UNORM color buffers, no special care
|
||||
* Since logicop is ignored for non-UNORM color buffers, no special care
|
||||
* is needed.
|
||||
*/
|
||||
if (blend->logicop_enable) {
|
||||
if (rt_is_unorm) {
|
||||
dw[1] |= 1 << 22 |
|
||||
gen6_translate_pipe_logicop(blend->logicop_func) << 18;
|
||||
}
|
||||
}
|
||||
else if (rt->blend_enable && !rt_is_pure_integer) {
|
||||
int rgb_src, rgb_dst, a_src, a_dst;
|
||||
|
||||
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 (rt_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[0] |= 1 << 31 |
|
||||
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[0] |= 1 << 30;
|
||||
}
|
||||
if (rt_is_unorm)
|
||||
dw[1] |= cso->dw_logicop;
|
||||
|
||||
/*
|
||||
* From the Sandy Bridge PRM, volume 2 part 1, page 356:
|
||||
|
|
@ -3366,37 +3469,8 @@ gen6_emit_BLEND_STATE(const struct ilo_dev_info *dev,
|
|||
* There is no such limitation on GEN7, or for AlphaToOne. But GL
|
||||
* requires that anyway.
|
||||
*/
|
||||
if (num_samples > 1) {
|
||||
if (blend->alpha_to_coverage)
|
||||
dw[1] |= 1 << 31;
|
||||
|
||||
if (blend->alpha_to_one) {
|
||||
const bool dual_blend =
|
||||
(!blend->logicop_enable && rt->blend_enable &&
|
||||
util_blend_state_is_dual(blend, target));
|
||||
|
||||
/*
|
||||
* 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 (!dual_blend)
|
||||
dw[1] |= 1 << 30;
|
||||
}
|
||||
|
||||
if (dev->gen >= ILO_GEN(7))
|
||||
dw[1] |= 1 << 29;
|
||||
}
|
||||
|
||||
if (!(rt->colormask & PIPE_MASK_A))
|
||||
dw[1] |= 1 << 27;
|
||||
if (!(rt->colormask & PIPE_MASK_R))
|
||||
dw[1] |= 1 << 26;
|
||||
if (!(rt->colormask & PIPE_MASK_G))
|
||||
dw[1] |= 1 << 25;
|
||||
if (!(rt->colormask & PIPE_MASK_B))
|
||||
dw[1] |= 1 << 24;
|
||||
if (num_samples > 1)
|
||||
dw[1] |= cso->dw_alpha_mod;
|
||||
|
||||
/*
|
||||
* From the Sandy Bridge PRM, volume 2 part 1, page 382:
|
||||
|
|
@ -3409,9 +3483,6 @@ gen6_emit_BLEND_STATE(const struct ilo_dev_info *dev,
|
|||
gen6_translate_dsa_func(alpha->func) << 13;
|
||||
}
|
||||
|
||||
if (blend->dither)
|
||||
dw[1] |= 1 << 12;
|
||||
|
||||
dw += 2;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -402,7 +402,7 @@ typedef uint32_t
|
|||
|
||||
typedef uint32_t
|
||||
(*ilo_gpe_gen6_BLEND_STATE)(const struct ilo_dev_info *dev,
|
||||
const struct pipe_blend_state *blend,
|
||||
const struct ilo_blend_state *blend,
|
||||
const struct ilo_fb_state *fb,
|
||||
const struct pipe_alpha_state *alpha,
|
||||
struct ilo_cp *cp);
|
||||
|
|
|
|||
|
|
@ -156,12 +156,13 @@ static void *
|
|||
ilo_create_blend_state(struct pipe_context *pipe,
|
||||
const struct pipe_blend_state *state)
|
||||
{
|
||||
struct ilo_context *ilo = ilo_context(pipe);
|
||||
struct ilo_blend_state *blend;
|
||||
|
||||
blend = MALLOC_STRUCT(ilo_blend_state);
|
||||
assert(blend);
|
||||
|
||||
blend->state = *state;
|
||||
ilo_gpe_init_blend(ilo->dev, state, blend);
|
||||
|
||||
return blend;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue