radeonsi: Implement alpha testing in pixel shader.
Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
committed by
Michel Dänzer
parent
e44dfd4b3c
commit
7708a86464
@@ -134,8 +134,6 @@ struct r600_context {
|
||||
unsigned sprite_coord_enable;
|
||||
unsigned export_16bpc;
|
||||
unsigned spi_shader_col_format;
|
||||
unsigned alpha_ref;
|
||||
boolean alpha_ref_dirty;
|
||||
struct r600_textures_info vs_samplers;
|
||||
struct r600_textures_info ps_samplers;
|
||||
struct si_resource *border_color_table;
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
#include "gallivm/lp_bld_const.h"
|
||||
#include "gallivm/lp_bld_gather.h"
|
||||
#include "gallivm/lp_bld_intr.h"
|
||||
#include "gallivm/lp_bld_logic.h"
|
||||
#include "gallivm/lp_bld_tgsi.h"
|
||||
#include "radeon_llvm.h"
|
||||
#include "radeon_llvm_emit.h"
|
||||
@@ -546,6 +547,37 @@ static void si_llvm_emit_prologue(struct lp_build_tgsi_context *bld_base)
|
||||
}
|
||||
|
||||
|
||||
static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
|
||||
unsigned index)
|
||||
{
|
||||
struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
|
||||
struct gallivm_state *gallivm = bld_base->base.gallivm;
|
||||
|
||||
if (si_shader_ctx->key.alpha_func != PIPE_FUNC_NEVER) {
|
||||
LLVMValueRef out_ptr = si_shader_ctx->radeon_bld.soa.outputs[index][3];
|
||||
LLVMValueRef alpha_pass =
|
||||
lp_build_cmp(&bld_base->base,
|
||||
si_shader_ctx->key.alpha_func,
|
||||
LLVMBuildLoad(gallivm->builder, out_ptr, ""),
|
||||
lp_build_const_float(gallivm, si_shader_ctx->key.alpha_ref));
|
||||
LLVMValueRef arg =
|
||||
lp_build_select(&bld_base->base,
|
||||
alpha_pass,
|
||||
lp_build_const_float(gallivm, 1.0f),
|
||||
lp_build_const_float(gallivm, -1.0f));
|
||||
|
||||
build_intrinsic(gallivm->builder,
|
||||
"llvm.AMDGPU.kill",
|
||||
LLVMVoidTypeInContext(gallivm->context),
|
||||
&arg, 1, 0);
|
||||
} else {
|
||||
build_intrinsic(gallivm->builder,
|
||||
"llvm.AMDGPU.kilp",
|
||||
LLVMVoidTypeInContext(gallivm->context),
|
||||
NULL, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX: This is partially implemented for VS only at this point. It is not complete */
|
||||
static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
|
||||
{
|
||||
@@ -606,6 +638,10 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
|
||||
param_count++;
|
||||
} else {
|
||||
target = V_008DFC_SQ_EXP_MRT + color_count;
|
||||
if (color_count == 0 &&
|
||||
si_shader_ctx->key.alpha_func != PIPE_FUNC_ALWAYS)
|
||||
si_alpha_test(bld_base, index);
|
||||
|
||||
color_count++;
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -81,6 +81,8 @@ struct si_shader_key {
|
||||
unsigned export_16bpc:8;
|
||||
unsigned nr_cbufs:4;
|
||||
unsigned color_two_side:1;
|
||||
unsigned alpha_func:3;
|
||||
float alpha_ref;
|
||||
};
|
||||
|
||||
struct si_pipe_shader {
|
||||
|
||||
@@ -564,7 +564,7 @@ static void *si_create_dsa_state(struct pipe_context *ctx,
|
||||
{
|
||||
struct si_state_dsa *dsa = CALLOC_STRUCT(si_state_dsa);
|
||||
struct si_pm4_state *pm4 = &dsa->pm4;
|
||||
unsigned db_depth_control, /* alpha_test_control, */ alpha_ref;
|
||||
unsigned db_depth_control;
|
||||
unsigned db_render_override, db_render_control;
|
||||
uint32_t db_stencil_control = 0;
|
||||
|
||||
@@ -599,14 +599,12 @@ static void *si_create_dsa_state(struct pipe_context *ctx,
|
||||
}
|
||||
|
||||
/* alpha */
|
||||
//alpha_test_control = 0;
|
||||
alpha_ref = 0;
|
||||
if (state->alpha.enabled) {
|
||||
//alpha_test_control = S_028410_ALPHA_FUNC(state->alpha.func);
|
||||
//alpha_test_control |= S_028410_ALPHA_TEST_ENABLE(1);
|
||||
alpha_ref = fui(state->alpha.ref_value);
|
||||
dsa->alpha_func = state->alpha.func;
|
||||
dsa->alpha_ref = state->alpha.ref_value;
|
||||
} else {
|
||||
dsa->alpha_func = PIPE_FUNC_ALWAYS;
|
||||
}
|
||||
dsa->alpha_ref = alpha_ref;
|
||||
|
||||
/* misc */
|
||||
db_render_control = 0;
|
||||
@@ -642,10 +640,6 @@ static void si_bind_dsa_state(struct pipe_context *ctx, void *state)
|
||||
|
||||
si_pm4_bind_state(rctx, dsa, dsa);
|
||||
si_update_dsa_stencil_ref(rctx);
|
||||
|
||||
// TODO
|
||||
rctx->alpha_ref = dsa->alpha_ref;
|
||||
rctx->alpha_ref_dirty = true;
|
||||
}
|
||||
|
||||
static void si_delete_dsa_state(struct pipe_context *ctx, void *state)
|
||||
@@ -1639,8 +1633,6 @@ static void si_cb(struct r600_context *rctx, struct si_pm4_state *pm4,
|
||||
S_028C70_NUMBER_TYPE(ntype) |
|
||||
S_028C70_ENDIAN(endian);
|
||||
|
||||
rctx->alpha_ref_dirty = true;
|
||||
|
||||
offset += r600_resource_va(rctx->context.screen, state->cbufs[cb]->texture);
|
||||
offset >>= 8;
|
||||
|
||||
@@ -1848,6 +1840,12 @@ static INLINE struct si_shader_key si_shader_selector_key(struct pipe_context *c
|
||||
key.color_two_side = rctx->queued.named.rasterizer->two_side;
|
||||
/*key.flatshade = rctx->queued.named.rasterizer->flatshade;*/
|
||||
}
|
||||
if (rctx->queued.named.dsa) {
|
||||
key.alpha_func = rctx->queued.named.dsa->alpha_func;
|
||||
key.alpha_ref = rctx->queued.named.dsa->alpha_ref;
|
||||
} else {
|
||||
key.alpha_func = PIPE_FUNC_ALWAYS;
|
||||
}
|
||||
}
|
||||
|
||||
return key;
|
||||
|
||||
@@ -55,7 +55,8 @@ struct si_state_rasterizer {
|
||||
|
||||
struct si_state_dsa {
|
||||
struct si_pm4_state pm4;
|
||||
unsigned alpha_ref;
|
||||
float alpha_ref;
|
||||
unsigned alpha_func;
|
||||
unsigned db_render_override;
|
||||
unsigned db_render_control;
|
||||
uint8_t valuemask[2];
|
||||
|
||||
@@ -147,7 +147,7 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
|
||||
if (shader->shader.output[i].name == TGSI_SEMANTIC_STENCIL)
|
||||
db_shader_control |= 0; // XXX OP_VAL or TEST_VAL?
|
||||
}
|
||||
if (shader->shader.uses_kill)
|
||||
if (shader->shader.uses_kill || shader->key.alpha_func != PIPE_FUNC_ALWAYS)
|
||||
db_shader_control |= S_02880C_KILL_ENABLE(1);
|
||||
|
||||
exports_ps = 0;
|
||||
@@ -306,23 +306,6 @@ static bool si_update_draw_info_state(struct r600_context *rctx,
|
||||
return true;
|
||||
}
|
||||
|
||||
static void si_update_alpha_ref(struct r600_context *rctx)
|
||||
{
|
||||
#if 0
|
||||
unsigned alpha_ref;
|
||||
struct r600_pipe_state rstate;
|
||||
|
||||
alpha_ref = rctx->alpha_ref;
|
||||
rstate.nregs = 0;
|
||||
if (rctx->export_16bpc)
|
||||
alpha_ref &= ~0x1FFF;
|
||||
si_pm4_set_reg(&rstate, R_028438_SX_ALPHA_REF, alpha_ref);
|
||||
|
||||
si_pm4_set_state(rctx, TODO, pm4);
|
||||
rctx->alpha_ref_dirty = false;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void si_update_spi_map(struct r600_context *rctx)
|
||||
{
|
||||
struct si_shader *ps = &rctx->ps_shader->current->shader;
|
||||
@@ -392,10 +375,6 @@ static void si_update_derived_state(struct r600_context *rctx)
|
||||
|
||||
si_shader_select(ctx, rctx->ps_shader, &ps_dirty);
|
||||
|
||||
if (rctx->alpha_ref_dirty) {
|
||||
si_update_alpha_ref(rctx);
|
||||
}
|
||||
|
||||
if (!rctx->vs_shader->current->pm4) {
|
||||
si_pipe_shader_vs(ctx, rctx->vs_shader->current);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user