Module: Mesa
Branch: master
Commit: 1a616c10095473538f4d26d32afb4de95263a7e5
URL:    
http://cgit.freedesktop.org/mesa/mesa/commit/?id=1a616c10095473538f4d26d32afb4de95263a7e5

Author: Michel Dänzer <michel.daen...@amd.com>
Date:   Tue Nov 13 17:35:09 2012 +0100

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

Signed-off-by: Michel Dänzer <michel.daen...@amd.com>

---

 src/gallium/drivers/radeonsi/radeonsi_shader.c |   61 +++++++++++++++++++++++-
 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 21e9018..d6e37ac 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 b608f20..257bf1e 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);

_______________________________________________
mesa-commit mailing list
mesa-commit@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-commit

Reply via email to