summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChia-I Wu <olvaffe@gmail.com>2015-05-11 19:48:52 +0800
committerChia-I Wu <olvaffe@gmail.com>2015-06-15 01:07:09 +0800
commit960ca7d5e32997a5367cf798f7930cbb890b3ab4 (patch)
tree3d634946bd611623a953e5c9de85059b40c4a8b9
parent402e155cd3a757a583f81fa6545c855b63947e7c (diff)
ilo: embed ilo_state_cc in ilo_blend_state
-rw-r--r--src/gallium/drivers/ilo/core/ilo_builder_3d_bottom.h199
-rw-r--r--src/gallium/drivers/ilo/core/ilo_state_3d.h44
-rw-r--r--src/gallium/drivers/ilo/core/ilo_state_3d_bottom.c680
-rw-r--r--src/gallium/drivers/ilo/ilo_blitter.h8
-rw-r--r--src/gallium/drivers/ilo/ilo_blitter_rectlist.c70
-rw-r--r--src/gallium/drivers/ilo/ilo_render.c9
-rw-r--r--src/gallium/drivers/ilo/ilo_render_dynamic.c33
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen.h2
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen6.c9
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen7.c9
-rw-r--r--src/gallium/drivers/ilo/ilo_render_gen8.c16
-rw-r--r--src/gallium/drivers/ilo/ilo_state.c328
-rw-r--r--src/gallium/drivers/ilo/ilo_state.h34
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;
@@ -186,16 +154,6 @@ ilo_gpe_init_ve_nosrc(const struct ilo_dev *dev,
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,
struct ilo_shader_cso *cso);
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 */