summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2014-09-24 13:17:11 -0700
committerEric Anholt <[email protected]>2014-09-24 15:56:39 -0700
commit8cd165051b52a9d70512fd138463aa165bea849a (patch)
tree1d0a0a09cc4fbe9427642eaf4d698f7bbc8e8970 /src
parenta87e44da3a801028783979cfd3548d0ebc9fdd88 (diff)
vc4: Add support for alpha test.
Fixes most of piglit fbo-alphatest-formats (but not RGB565/332).
Diffstat (limited to 'src')
-rw-r--r--src/gallium/drivers/vc4/vc4_program.c68
-rw-r--r--src/gallium/drivers/vc4/vc4_qir.h2
2 files changed, 70 insertions, 0 deletions
diff --git a/src/gallium/drivers/vc4/vc4_program.c b/src/gallium/drivers/vc4/vc4_program.c
index 38e80dd5ba9..315a8570f82 100644
--- a/src/gallium/drivers/vc4/vc4_program.c
+++ b/src/gallium/drivers/vc4/vc4_program.c
@@ -58,6 +58,8 @@ struct vc4_fs_key {
bool stencil_full_writemasks;
bool is_points;
bool is_lines;
+ bool alpha_test;
+ uint8_t alpha_test_func;
struct pipe_rt_blend_state blend;
};
@@ -1227,8 +1229,66 @@ vc4_blend(struct vc4_compile *c, struct qreg *result,
}
static void
+alpha_test_discard(struct vc4_compile *c)
+{
+ struct qreg src_alpha;
+ struct qreg alpha_ref = get_temp_for_uniform(c, QUNIFORM_ALPHA_REF, 0);
+
+ if (!c->fs_key->alpha_test)
+ return;
+
+ if (c->output_color_index != -1)
+ src_alpha = c->outputs[c->output_color_index + 3];
+ else
+ src_alpha = qir_uniform_f(c, 1.0);
+
+ if (c->discard.file == QFILE_NULL)
+ c->discard = qir_uniform_f(c, 0.0);
+
+ switch (c->fs_key->alpha_test_func) {
+ case PIPE_FUNC_NEVER:
+ c->discard = qir_uniform_f(c, 1.0);
+ break;
+ case PIPE_FUNC_ALWAYS:
+ break;
+ case PIPE_FUNC_EQUAL:
+ qir_SF(c, qir_FSUB(c, src_alpha, alpha_ref));
+ c->discard = qir_SEL_X_Y_ZS(c, c->discard,
+ qir_uniform_f(c, 1.0));
+ break;
+ case PIPE_FUNC_NOTEQUAL:
+ qir_SF(c, qir_FSUB(c, src_alpha, alpha_ref));
+ c->discard = qir_SEL_X_Y_ZC(c, c->discard,
+ qir_uniform_f(c, 1.0));
+ break;
+ case PIPE_FUNC_GREATER:
+ qir_SF(c, qir_FSUB(c, src_alpha, alpha_ref));
+ c->discard = qir_SEL_X_Y_NC(c, c->discard,
+ qir_uniform_f(c, 1.0));
+ break;
+ case PIPE_FUNC_GEQUAL:
+ qir_SF(c, qir_FSUB(c, alpha_ref, src_alpha));
+ c->discard = qir_SEL_X_Y_NS(c, c->discard,
+ qir_uniform_f(c, 1.0));
+ break;
+ case PIPE_FUNC_LESS:
+ qir_SF(c, qir_FSUB(c, src_alpha, alpha_ref));
+ c->discard = qir_SEL_X_Y_NS(c, c->discard,
+ qir_uniform_f(c, 1.0));
+ break;
+ case PIPE_FUNC_LEQUAL:
+ qir_SF(c, qir_FSUB(c, alpha_ref, src_alpha));
+ c->discard = qir_SEL_X_Y_NC(c, c->discard,
+ qir_uniform_f(c, 1.0));
+ break;
+ }
+}
+
+static void
emit_frag_end(struct vc4_compile *c)
{
+ alpha_test_discard(c);
+
enum pipe_format color_format = c->fs_key->color_format;
const uint8_t *format_swiz = vc4_get_format_swizzle(color_format);
struct qreg tlb_read_color[4] = { c->undef, c->undef, c->undef, c->undef };
@@ -1614,6 +1674,10 @@ vc4_update_compiled_fs(struct vc4_context *vc4, uint8_t prim_mode)
key->stencil_full_writemasks = vc4->zsa->stencil_uniforms[2] != 0;
key->depth_enabled = (vc4->zsa->base.depth.enabled ||
key->stencil_enabled);
+ if (vc4->zsa->base.alpha.enabled) {
+ key->alpha_test = true;
+ key->alpha_test_func = vc4->zsa->base.alpha.func;
+ }
vc4->prog.fs = util_hash_table_get(vc4->fs_cache, key);
if (vc4->prog.fs)
@@ -1886,6 +1950,10 @@ vc4_write_uniforms(struct vc4_context *vc4, struct vc4_compiled_shader *shader,
(vc4->stencil_ref.ref_value[uinfo->data[i]] << 8) :
0));
break;
+
+ case QUNIFORM_ALPHA_REF:
+ cl_f(&vc4->uniforms, vc4->zsa->base.alpha.ref_value);
+ break;
}
#if 0
uint32_t written_val = *(uint32_t *)(vc4->uniforms.next - 4);
diff --git a/src/gallium/drivers/vc4/vc4_qir.h b/src/gallium/drivers/vc4/vc4_qir.h
index 04a81c95459..0a2c6857966 100644
--- a/src/gallium/drivers/vc4/vc4_qir.h
+++ b/src/gallium/drivers/vc4/vc4_qir.h
@@ -206,6 +206,8 @@ enum quniform_contents {
QUNIFORM_BLEND_CONST_COLOR,
QUNIFORM_STENCIL,
+
+ QUNIFORM_ALPHA_REF,
};
struct vc4_compile {