summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2013-05-31 16:11:38 +0800
committerChia-I Wu <olvaffe@gmail.com>2013-06-07 11:13:15 +0800
commiteea1be2072a1c980871d80df71d3e39a67fdfb0a (patch)
tree8ad3d587c43ae0c58dc57b95901ef96b48915041 /src/gallium/drivers
parentb3c9e2161f22c3c6b8b2fc83ea4bc7ea883329d7 (diff)
downloadexternal_mesa3d-eea1be2072a1c980871d80df71d3e39a67fdfb0a.zip
external_mesa3d-eea1be2072a1c980871d80df71d3e39a67fdfb0a.tar.gz
external_mesa3d-eea1be2072a1c980871d80df71d3e39a67fdfb0a.tar.bz2
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().
Diffstat (limited to 'src/gallium/drivers')
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c9
-rw-r--r--src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c7
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe.h22
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe_gen6.c237
-rw-r--r--src/gallium/drivers/ilo/ilo_gpe_gen6.h2
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c3
6 files changed, 183 insertions, 97 deletions
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
index 81cd6c2..c94a0bb 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen6.c
@@ -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;
}
diff --git a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
index 33f5a75..1ad19d2 100644
--- a/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
+++ b/src/gallium/drivers/ilo/ilo_3d_pipeline_gen7.c
@@ -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);
diff --git a/src/gallium/drivers/ilo/ilo_gpe.h b/src/gallium/drivers/ilo/ilo_gpe.h
index 467a6b3..dc4e80e 100644
--- a/src/gallium/drivers/ilo/ilo_gpe.h
+++ b/src/gallium/drivers/ilo/ilo_gpe.h
@@ -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 {
@@ -192,6 +207,11 @@ 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,
struct ilo_sampler_cso *sampler);
diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.c b/src/gallium/drivers/ilo/ilo_gpe_gen6.c
index 082392b..dab964f 100644
--- a/src/gallium/drivers/ilo/ilo_gpe_gen6.c
+++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.c
@@ -3230,8 +3230,140 @@ 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;
}
diff --git a/src/gallium/drivers/ilo/ilo_gpe_gen6.h b/src/gallium/drivers/ilo/ilo_gpe_gen6.h
index bb09dc0..16445a0 100644
--- a/src/gallium/drivers/ilo/ilo_gpe_gen6.h
+++ b/src/gallium/drivers/ilo/ilo_gpe_gen6.h
@@ -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);
diff --git a/src/gallium/drivers/ilo/ilo_state.c b/src/gallium/drivers/ilo/ilo_state.c
index ab2a4e9..c032e17 100644
--- a/src/gallium/drivers/ilo/ilo_state.c
+++ b/src/gallium/drivers/ilo/ilo_state.c
@@ -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;
}