summaryrefslogtreecommitdiffstats
path: root/src/gallium
diff options
context:
space:
mode:
authorMichel Dänzer <[email protected]>2012-11-13 17:35:09 +0100
committerMichel Dänzer <[email protected]>2012-11-28 13:35:16 +0100
commit1a616c10095473538f4d26d32afb4de95263a7e5 (patch)
tree75ca8232d0d2f66708a9bedc277adcacef06d8d5 /src/gallium
parent49003a5cb658751a85383cd6600006e094f453bc (diff)
radeonsi: Flesh out support for depth/stencil exports from the pixel shader.
Signed-off-by: Michel Dänzer <[email protected]>
Diffstat (limited to 'src/gallium')
-rw-r--r--src/gallium/drivers/radeonsi/radeonsi_shader.c61
-rw-r--r--src/gallium/drivers/radeonsi/si_state_draw.c13
2 files changed, 68 insertions, 6 deletions
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index 21e9018f2e0..d6e37acaa96 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -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);
diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c
index b608f201093..257bf1ec98d 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -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);