aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2018-07-03 16:24:35 -0700
committerEric Anholt <[email protected]>2018-07-05 12:39:36 -0700
commit572f6ab489db2d2311d89ab5910764ebb83cb49d (patch)
treee1262aaddc51fb1af74b4476aff645829483531c
parent5601ab3981c8ab5872230a6a9afc236d76fa1405 (diff)
v3d: Add proper support for GL_EXT_draw_buffers2's blending enables.
I had flagged it as enabled on V3D 4.x, but not actually implemented the per-RT enables. Fixes piglit fbo_drawbuffers2-blend.
-rw-r--r--src/gallium/drivers/v3d/v3d_context.h9
-rw-r--r--src/gallium/drivers/v3d/v3d_program.c8
-rw-r--r--src/gallium/drivers/v3d/v3dx_emit.c26
-rw-r--r--src/gallium/drivers/v3d/v3dx_state.c28
4 files changed, 46 insertions, 25 deletions
diff --git a/src/gallium/drivers/v3d/v3d_context.h b/src/gallium/drivers/v3d/v3d_context.h
index 7c920dbc3db..dea9f9f3d2c 100644
--- a/src/gallium/drivers/v3d/v3d_context.h
+++ b/src/gallium/drivers/v3d/v3d_context.h
@@ -375,7 +375,7 @@ struct v3d_context {
/** @{ Current pipeline state objects */
struct pipe_scissor_state scissor;
- struct pipe_blend_state *blend;
+ struct v3d_blend_state *blend;
struct v3d_rasterizer_state *rasterizer;
struct v3d_depth_stencil_alpha_state *zsa;
@@ -454,6 +454,13 @@ struct v3d_depth_stencil_alpha_state {
uint8_t stencil_back[6];
};
+struct v3d_blend_state {
+ struct pipe_blend_state base;
+
+ /* Per-RT mask of whether blending is enabled. */
+ uint8_t blend_enables;
+};
+
#define perf_debug(...) do { \
if (unlikely(V3D_DEBUG & V3D_DEBUG_PERF)) \
fprintf(stderr, __VA_ARGS__); \
diff --git a/src/gallium/drivers/v3d/v3d_program.c b/src/gallium/drivers/v3d/v3d_program.c
index c67104df234..b5742b3bb1e 100644
--- a/src/gallium/drivers/v3d/v3d_program.c
+++ b/src/gallium/drivers/v3d/v3d_program.c
@@ -414,8 +414,8 @@ v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode)
key->is_lines = (prim_mode >= PIPE_PRIM_LINES &&
prim_mode <= PIPE_PRIM_LINE_STRIP);
key->clamp_color = v3d->rasterizer->base.clamp_fragment_color;
- if (v3d->blend->logicop_enable) {
- key->logicop_func = v3d->blend->logicop_func;
+ if (v3d->blend->base.logicop_enable) {
+ key->logicop_func = v3d->blend->base.logicop_func;
} else {
key->logicop_func = PIPE_LOGICOP_COPY;
}
@@ -423,8 +423,8 @@ v3d_update_compiled_fs(struct v3d_context *v3d, uint8_t prim_mode)
key->msaa = v3d->rasterizer->base.multisample;
key->sample_coverage = (v3d->rasterizer->base.multisample &&
v3d->sample_mask != (1 << VC5_MAX_SAMPLES) - 1);
- key->sample_alpha_to_coverage = v3d->blend->alpha_to_coverage;
- key->sample_alpha_to_one = v3d->blend->alpha_to_one;
+ key->sample_alpha_to_coverage = v3d->blend->base.alpha_to_coverage;
+ key->sample_alpha_to_one = v3d->blend->base.alpha_to_one;
}
key->depth_enabled = (v3d->zsa->base.depth.enabled ||
diff --git a/src/gallium/drivers/v3d/v3dx_emit.c b/src/gallium/drivers/v3d/v3dx_emit.c
index 03e47d66156..78edf02d79a 100644
--- a/src/gallium/drivers/v3d/v3dx_emit.c
+++ b/src/gallium/drivers/v3d/v3dx_emit.c
@@ -400,7 +400,7 @@ v3dX(emit_state)(struct pipe_context *pctx)
config.direct3d_provoking_vertex =
v3d->rasterizer->base.flatshade_first;
- config.blend_enable = v3d->blend->rt[0].blend_enable;
+ config.blend_enable = v3d->blend->blend_enables;
/* Note: EZ state may update based on the compiled FS,
* along with ZSA
@@ -481,19 +481,27 @@ v3dX(emit_state)(struct pipe_context *pctx)
}
}
- if (v3d->dirty & VC5_DIRTY_BLEND && v3d->blend->rt[0].blend_enable) {
- struct pipe_blend_state *blend = v3d->blend;
+ if (v3d->dirty & VC5_DIRTY_BLEND) {
+ struct v3d_blend_state *blend = v3d->blend;
- if (blend->independent_blend_enable) {
- for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++)
- emit_rt_blend(v3d, job, blend, i);
- } else {
- emit_rt_blend(v3d, job, blend, 0);
+ if (blend->blend_enables) {
+#if V3D_VERSION >= 40
+ cl_emit(&job->bcl, BLEND_ENABLES, enables) {
+ enables.mask = blend->blend_enables;
+ }
+#endif
+
+ if (blend->base.independent_blend_enable) {
+ for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++)
+ emit_rt_blend(v3d, job, &blend->base, i);
+ } else {
+ emit_rt_blend(v3d, job, &blend->base, 0);
+ }
}
}
if (v3d->dirty & VC5_DIRTY_BLEND) {
- struct pipe_blend_state *blend = v3d->blend;
+ struct pipe_blend_state *blend = &v3d->blend->base;
cl_emit(&job->bcl, COLOUR_WRITE_MASKS, mask) {
for (int i = 0; i < 4; i++) {
diff --git a/src/gallium/drivers/v3d/v3dx_state.c b/src/gallium/drivers/v3d/v3dx_state.c
index c0f43d800ea..ff1c4b52125 100644
--- a/src/gallium/drivers/v3d/v3dx_state.c
+++ b/src/gallium/drivers/v3d/v3dx_state.c
@@ -36,16 +36,6 @@
#include "broadcom/common/v3d_macros.h"
#include "broadcom/cle/v3dx_pack.h"
-static void *
-v3d_generic_cso_state_create(const void *src, uint32_t size)
-{
- void *dst = calloc(1, size);
- if (!dst)
- return NULL;
- memcpy(dst, src, size);
- return dst;
-}
-
static void
v3d_generic_cso_state_delete(struct pipe_context *pctx, void *hwcso)
{
@@ -128,7 +118,23 @@ static void *
v3d_create_blend_state(struct pipe_context *pctx,
const struct pipe_blend_state *cso)
{
- return v3d_generic_cso_state_create(cso, sizeof(*cso));
+ struct v3d_blend_state *so;
+
+ so = CALLOC_STRUCT(v3d_blend_state);
+ if (!so)
+ return NULL;
+
+ so->base = *cso;
+
+ for (int i = 0; i < VC5_MAX_DRAW_BUFFERS; i++) {
+ so->blend_enables |= cso->rt[i].blend_enable << i;
+
+ /* V3D 4.x is when we got independent blend enables. */
+ assert(V3D_VERSION >= 40 ||
+ cso->rt[i].blend_enable == cso->rt[0].blend_enable);
+ }
+
+ return so;
}
static uint32_t