radeonsi: Handle TGSI_SEMANTIC_BCOLOR.
authorMichel Dänzer <michel.daenzer@amd.com>
Thu, 6 Sep 2012 16:03:38 +0000 (18:03 +0200)
committerMichel Dänzer <michel@daenzer.net>
Fri, 26 Oct 2012 13:51:17 +0000 (15:51 +0200)
Put the back face colour right after the front face colour in the LDS parameter
space.

Fixes 18 piglit tests related to two sided lighting.

Signed-off-by: Michel Dänzer <michel.daenzer@amd.com>
Reviewed-by: Tom Stellard <thomas.stellard@amd.com>
src/gallium/drivers/radeonsi/radeonsi_shader.c
src/gallium/drivers/radeonsi/radeonsi_shader.h
src/gallium/drivers/radeonsi/si_state.c
src/gallium/drivers/radeonsi/si_state.h
src/gallium/drivers/radeonsi/si_state_draw.c

index 32755127b58568a0f7576d444bfe45a3aa4f3dde..aec5c2ea2227d811183c0eaf085d650bc4159dce 100644 (file)
@@ -320,16 +320,59 @@ static void declare_input_fs(
        }
 
        /* XXX: Could there be more than TGSI_NUM_CHANNELS (4) ? */
-       for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+       if (decl->Semantic.Name == TGSI_SEMANTIC_COLOR &&
+           si_shader_ctx->key.color_two_side) {
                LLVMValueRef args[3];
-               LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
-               unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
-               args[0] = llvm_chan;
-               args[1] = attr_number;
+               LLVMValueRef face, is_face_positive;
+               LLVMValueRef back_attr_number =
+                       lp_build_const_int32(gallivm,
+                                            shader->input[input_index].param_offset + 1);
+
+               face = build_intrinsic(gallivm->builder,
+                                      "llvm.SI.fs.read.face",
+                                      input_type,
+                                      NULL, 0, LLVMReadNoneAttribute);
+               is_face_positive = LLVMBuildFCmp(gallivm->builder,
+                                                LLVMRealUGT, face,
+                                                lp_build_const_float(gallivm, 0.0f),
+                                                "");
+
                args[2] = params;
-               si_shader_ctx->radeon_bld.inputs[soa_index] =
-                       build_intrinsic(base->gallivm->builder, intr_name,
-                               input_type, args, 3, LLVMReadOnlyAttribute);
+               for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+                       LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
+                       unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+                       LLVMValueRef front, back;
+
+                       args[0] = llvm_chan;
+                       args[1] = attr_number;
+                       front = build_intrinsic(base->gallivm->builder, intr_name,
+                                               input_type, args, 3, LLVMReadOnlyAttribute);
+
+                       args[1] = back_attr_number;
+                       back = build_intrinsic(base->gallivm->builder, intr_name,
+                                              input_type, args, 3, LLVMReadOnlyAttribute);
+
+                       si_shader_ctx->radeon_bld.inputs[soa_index] =
+                               LLVMBuildSelect(gallivm->builder,
+                                               is_face_positive,
+                                               front,
+                                               back,
+                                               "");
+               }
+
+               shader->ninterp++;
+       } else {
+               for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+                       LLVMValueRef args[3];
+                       LLVMValueRef llvm_chan = lp_build_const_int32(gallivm, chan);
+                       unsigned soa_index = radeon_llvm_reg_index_soa(input_index, chan);
+                       args[0] = llvm_chan;
+                       args[1] = attr_number;
+                       args[2] = params;
+                       si_shader_ctx->radeon_bld.inputs[soa_index] =
+                               build_intrinsic(base->gallivm->builder, intr_name,
+                                               input_type, args, 3, LLVMReadOnlyAttribute);
+               }
        }
 }
 
@@ -530,6 +573,7 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
                                break;
                        case TGSI_SEMANTIC_COLOR:
                                if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
+                       case TGSI_SEMANTIC_BCOLOR:
                                        target = V_008DFC_SQ_EXP_PARAM + param_count;
                                        shader->output[i].param_offset = param_count;
                                        param_count++;
index 9d382d5628658be16d1b2036fa280a3104817938..23030bc4f63a63cc847011e22c883a743f41cb23 100644 (file)
@@ -80,6 +80,7 @@ struct si_shader {
 struct si_shader_key {
        unsigned                export_16bpc:8;
        unsigned                nr_cbufs:4;
+       unsigned                color_two_side:1;
 };
 
 struct si_pipe_shader {
index 20f4be3d8f2099e652804249bd65dd1ce9e5be14..66f0bd886fe330eb1faaa72a33c6a12fa6d54a07 100644 (file)
@@ -379,6 +379,8 @@ static void *si_create_rs_state(struct pipe_context *ctx,
                return NULL;
        }
 
+       rs->two_side = state->light_twoside;
+
        polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
                                state->fill_back != PIPE_POLYGON_MODE_FILL);
 
@@ -1841,9 +1843,10 @@ static INLINE struct si_shader_key si_shader_selector_key(struct pipe_context *c
                if (sel->fs_write_all)
                        key.nr_cbufs = rctx->framebuffer.nr_cbufs;
                key.export_16bpc = rctx->export_16bpc;
-               /*if (rctx->queued.named.rasterizer)
-                         key.flatshade = rctx->queued.named.rasterizer->flatshade;*/
-               /*key.color_two_side |== rctx->two_side;*/
+               if (rctx->queued.named.rasterizer) {
+                       key.color_two_side = rctx->queued.named.rasterizer->two_side;
+                       /*key.flatshade = rctx->queued.named.rasterizer->flatshade;*/
+               }
        }
 
        return key;
index 136ac861e2f6b5bf0ba719fce9d850c7d185be65..8f1ab438fffa3a0ea844f64c80b36d4562b0ab4d 100644 (file)
@@ -43,6 +43,7 @@ struct si_state_viewport {
 struct si_state_rasterizer {
        struct si_pm4_state     pm4;
        bool                    flatshade;
+       bool                    two_side;
        unsigned                sprite_coord_enable;
        unsigned                pa_sc_line_stipple;
        unsigned                pa_su_sc_mode_cntl;
index 629ec03e2fb0cc2003a9045e119f83516a1dc41e..3ac80b0a6e495134f375572c96b7aa40667a9544 100644 (file)
@@ -328,11 +328,15 @@ static void si_update_spi_map(struct r600_context *rctx)
        unsigned i, j, tmp;
 
        for (i = 0; i < ps->ninput; i++) {
+               unsigned name = ps->input[i].name;
+               unsigned param_offset = ps->input[i].param_offset;
+
+bcolor:
                tmp = 0;
 
 #if 0
                /* XXX: Flat shading hangs the GPU */
-               if (ps->input[i].name == TGSI_SEMANTIC_POSITION ||
+               if (name == TGSI_SEMANTIC_POSITION ||
                    ps->input[i].interpolate == TGSI_INTERPOLATE_CONSTANT ||
                    (ps->input[i].interpolate == TGSI_INTERPOLATE_COLOR &&
                     rctx->rasterizer && rctx->rasterizer->flatshade)) {
@@ -340,13 +344,13 @@ static void si_update_spi_map(struct r600_context *rctx)
                }
 #endif
 
-               if (ps->input[i].name == TGSI_SEMANTIC_GENERIC &&
+               if (name == TGSI_SEMANTIC_GENERIC &&
                    rctx->sprite_coord_enable & (1 << ps->input[i].sid)) {
                        tmp |= S_028644_PT_SPRITE_TEX(1);
                }
 
                for (j = 0; j < vs->noutput; j++) {
-                       if (ps->input[i].name == vs->output[j].name &&
+                       if (name == vs->output[j].name &&
                            ps->input[i].sid == vs->output[j].sid) {
                                tmp |= S_028644_OFFSET(vs->output[j].param_offset);
                                break;
@@ -359,8 +363,15 @@ static void si_update_spi_map(struct r600_context *rctx)
                }
 
                si_pm4_set_reg(pm4,
-                              R_028644_SPI_PS_INPUT_CNTL_0 + ps->input[i].param_offset * 4,
+                              R_028644_SPI_PS_INPUT_CNTL_0 + param_offset * 4,
                               tmp);
+
+               if (name == TGSI_SEMANTIC_COLOR &&
+                   rctx->ps_shader->current->key.color_two_side) {
+                       name = TGSI_SEMANTIC_BCOLOR;
+                       param_offset++;
+                       goto bcolor;
+               }
        }
 
        si_pm4_set_state(rctx, spi, pm4);