radeonsi: Flesh out support for depth/stencil exports from the pixel shader.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
This commit is contained in:
Michel Dänzer 2012-11-13 17:35:09 +01:00 committed by Michel Dänzer
parent 49003a5cb6
commit 1a616c1009
2 changed files with 68 additions and 6 deletions

View file

@ -587,14 +587,15 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
struct lp_build_context * uint =
&si_shader_ctx->radeon_bld.soa.bld_base.uint_bld;
struct tgsi_parse_context *parse = &si_shader_ctx->parse;
LLVMValueRef args[9];
LLVMValueRef last_args[9] = { 0 };
unsigned color_count = 0;
unsigned param_count = 0;
int depth_index = -1, stencil_index = -1;
while (!tgsi_parse_end_of_tokens(parse)) {
struct tgsi_full_declaration *d =
&parse->FullToken.FullDeclaration;
LLVMValueRef args[9];
unsigned target;
unsigned index;
int i;
@ -627,9 +628,19 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
/* Select the correct target */
switch(d->Semantic.Name) {
case TGSI_SEMANTIC_PSIZE:
case TGSI_SEMANTIC_POSITION:
target = V_008DFC_SQ_EXP_POS;
break;
case TGSI_SEMANTIC_POSITION:
if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
target = V_008DFC_SQ_EXP_POS;
break;
} else {
depth_index = index;
continue;
}
case TGSI_SEMANTIC_STENCIL:
stencil_index = index;
continue;
case TGSI_SEMANTIC_COLOR:
if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
case TGSI_SEMANTIC_BCOLOR:
@ -681,6 +692,52 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
}
}
if (depth_index >= 0 || stencil_index >= 0) {
LLVMValueRef out_ptr;
unsigned mask = 0;
/* Specify the target we are exporting */
args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRTZ);
if (depth_index >= 0) {
out_ptr = si_shader_ctx->radeon_bld.soa.outputs[depth_index][2];
args[5] = LLVMBuildLoad(base->gallivm->builder, out_ptr, "");
mask |= 0x1;
if (stencil_index < 0) {
args[6] =
args[7] =
args[8] = args[5];
}
}
if (stencil_index >= 0) {
out_ptr = si_shader_ctx->radeon_bld.soa.outputs[stencil_index][1];
args[7] =
args[8] =
args[6] = LLVMBuildLoad(base->gallivm->builder, out_ptr, "");
mask |= 0x2;
if (depth_index < 0)
args[5] = args[6];
}
/* Specify which components to enable */
args[0] = lp_build_const_int32(base->gallivm, mask);
args[1] =
args[2] =
args[4] = uint->zero;
if (last_args[0])
lp_build_intrinsic(base->gallivm->builder,
"llvm.SI.export",
LLVMVoidTypeInContext(base->gallivm->context),
args, 9);
else
memcpy(last_args, args, sizeof(args));
}
if (!last_args[0]) {
assert(si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT);

View file

@ -100,7 +100,7 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
unsigned num_sgprs, num_user_sgprs;
boolean have_linear = FALSE, have_centroid = FALSE, have_perspective = FALSE;
unsigned fragcoord_interp_mode = 0;
unsigned spi_baryc_cntl, spi_ps_input_ena;
unsigned spi_baryc_cntl, spi_ps_input_ena, spi_shader_z_format;
uint64_t va;
si_pm4_delete_state(rctx, ps, shader->pm4);
@ -145,7 +145,7 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
if (shader->shader.output[i].name == TGSI_SEMANTIC_POSITION)
db_shader_control |= S_02880C_Z_EXPORT_ENABLE(1);
if (shader->shader.output[i].name == TGSI_SEMANTIC_STENCIL)
db_shader_control |= 0; // XXX OP_VAL or TEST_VAL?
db_shader_control |= S_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(1);
}
if (shader->shader.uses_kill || shader->key.alpha_func != PIPE_FUNC_ALWAYS)
db_shader_control |= S_02880C_KILL_ENABLE(1);
@ -195,8 +195,13 @@ static void si_pipe_shader_ps(struct pipe_context *ctx, struct si_pipe_shader *s
si_pm4_set_reg(pm4, R_0286D0_SPI_PS_INPUT_ADDR, spi_ps_input_ena);
si_pm4_set_reg(pm4, R_0286D8_SPI_PS_IN_CONTROL, spi_ps_in_control);
/* XXX: Depends on Z buffer format? */
si_pm4_set_reg(pm4, R_028710_SPI_SHADER_Z_FORMAT, 0);
if (G_02880C_STENCIL_TEST_VAL_EXPORT_ENABLE(db_shader_control))
spi_shader_z_format = V_028710_SPI_SHADER_32_GR;
else if (G_02880C_Z_EXPORT_ENABLE(db_shader_control))
spi_shader_z_format = V_028710_SPI_SHADER_32_R;
else
spi_shader_z_format = 0;
si_pm4_set_reg(pm4, R_028710_SPI_SHADER_Z_FORMAT, spi_shader_z_format);
va = r600_resource_va(ctx->screen, (void *)shader->bo);
si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ);