diff options
author | Michel Dänzer <[email protected]> | 2012-11-13 17:35:09 +0100 |
---|---|---|
committer | Michel Dänzer <[email protected]> | 2012-11-28 13:35:16 +0100 |
commit | 1a616c10095473538f4d26d32afb4de95263a7e5 (patch) | |
tree | 75ca8232d0d2f66708a9bedc277adcacef06d8d5 /src | |
parent | 49003a5cb658751a85383cd6600006e094f453bc (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')
-rw-r--r-- | src/gallium/drivers/radeonsi/radeonsi_shader.c | 61 | ||||
-rw-r--r-- | src/gallium/drivers/radeonsi/si_state_draw.c | 13 |
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); |