radeonsi: Handle TGSI_SEMANTIC_CLIPVERTEX
authorMichel Dänzer <michel.daenzer@amd.com>
Wed, 15 May 2013 16:09:50 +0000 (18:09 +0200)
committerMichel Dänzer <michel@daenzer.net>
Tue, 21 May 2013 15:50:13 +0000 (17:50 +0200)
17 more little piglits.

NOTE: This is a candidate for the 9.1 branch.

src/gallium/drivers/radeonsi/radeonsi_pipe.h
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 e50088f6e3b6822f54bea6afe5d947df3bc8af04..32740498b11ea15b15f8cc892149ddea6923ef88 100644 (file)
@@ -146,7 +146,6 @@ struct r600_context {
        struct pipe_framebuffer_state   framebuffer;
        unsigned                        pa_sc_line_stipple;
        unsigned                        pa_su_sc_mode_cntl;
-       unsigned                        pa_cl_clip_cntl;
        /* for saving when using blitter */
        struct pipe_stencil_ref         stencil_ref;
        struct si_pipe_shader_selector  *ps_shader;
index e6ed5459ceadd80ed56ce8922df89ddbd79114a4..484f7ecfcdb0bbddd0a67d0f3f62e57ac4d29fba 100644 (file)
@@ -554,6 +554,64 @@ static void si_alpha_test(struct lp_build_tgsi_context *bld_base,
        }
 }
 
+static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context * bld_base,
+                                   unsigned index)
+{
+       struct si_shader_context *si_shader_ctx = si_shader_context(bld_base);
+       struct lp_build_context *base = &bld_base->base;
+       struct lp_build_context *uint = &si_shader_ctx->radeon_bld.soa.bld_base.uint_bld;
+       LLVMValueRef args[9];
+       unsigned reg_index;
+       unsigned chan;
+       unsigned const_chan;
+       LLVMValueRef out_elts[4];
+       LLVMValueRef base_elt;
+       LLVMValueRef ptr = LLVMGetParam(si_shader_ctx->radeon_bld.main_fn, SI_PARAM_CONST);
+       LLVMValueRef const_resource = build_indexed_load(si_shader_ctx, ptr, uint->one);
+
+       for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+               LLVMValueRef out_ptr = si_shader_ctx->radeon_bld.soa.outputs[index][chan];
+               out_elts[chan] = LLVMBuildLoad(base->gallivm->builder, out_ptr, "");
+       }
+
+       for (reg_index = 0; reg_index < 2; reg_index ++) {
+               args[5] =
+               args[6] =
+               args[7] =
+               args[8] = lp_build_const_float(base->gallivm, 0.0f);
+
+               /* Compute dot products of position and user clip plane vectors */
+               for (chan = 0; chan < TGSI_NUM_CHANNELS; chan++) {
+                       for (const_chan = 0; const_chan < TGSI_NUM_CHANNELS; const_chan++) {
+                               args[0] = const_resource;
+                               args[1] = lp_build_const_int32(base->gallivm,
+                                                              ((reg_index * 4 + chan) * 4 +
+                                                               const_chan) * 4);
+                               base_elt = build_intrinsic(base->gallivm->builder,
+                                                          "llvm.SI.load.const",
+                                                          base->elem_type,
+                                                          args, 2,
+                                                          LLVMReadNoneAttribute | LLVMNoUnwindAttribute);
+                               args[5 + chan] =
+                                       lp_build_add(base, args[5 + chan],
+                                                    lp_build_mul(base, base_elt,
+                                                                 out_elts[const_chan]));
+                       }
+               }
+
+               args[0] = lp_build_const_int32(base->gallivm, 0xf);
+               args[1] = uint->zero;
+               args[2] = uint->zero;
+               args[3] = lp_build_const_int32(base->gallivm,
+                                              V_008DFC_SQ_EXP_POS + 2 + reg_index);
+               args[4] = uint->zero;
+               lp_build_intrinsic(base->gallivm->builder,
+                                  "llvm.SI.export",
+                                  LLVMVoidTypeInContext(base->gallivm->context),
+                                  args, 9);
+       }
+}
+
 /* XXX: This is partially implemented for VS only at this point.  It is not complete */
 static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
 {
@@ -642,6 +700,10 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
                                        color_count++;
                                }
                                break;
+                       case TGSI_SEMANTIC_CLIPVERTEX:
+                               si_llvm_emit_clipvertex(bld_base, index);
+                               shader->clip_dist_write = 0xFF;
+                               continue;
                        case TGSI_SEMANTIC_FOG:
                        case TGSI_SEMANTIC_GENERIC:
                                target = V_008DFC_SQ_EXP_PARAM + param_count;
index 667f2c339852cba9770390a0bb0709cbf49c3dce..01b8b5d3b734c5eef8c6ced19ff948e6c621d010 100644 (file)
@@ -113,6 +113,7 @@ struct si_shader {
        bool                    vs_out_misc_write;
        bool                    vs_out_point_size;
        unsigned                nr_cbufs;
+       unsigned                clip_dist_write;
 };
 
 union si_shader_key {
index de86b1e38de62fbf7ae794d2d6e92e74aa9cde6f..dec535ca597218d86dca09be6407427b61b50d27 100644 (file)
@@ -237,6 +237,7 @@ static void si_set_clip_state(struct pipe_context *ctx,
 {
        struct r600_context *rctx = (struct r600_context *)ctx;
        struct si_pm4_state *pm4 = CALLOC_STRUCT(si_pm4_state);
+       struct pipe_constant_buffer cb;
 
        if (pm4 == NULL)
                return;
@@ -252,6 +253,13 @@ static void si_set_clip_state(struct pipe_context *ctx,
                               fui(state->ucp[i][3]));
         }
 
+       cb.buffer = NULL;
+       cb.user_buffer = state->ucp;
+       cb.buffer_offset = 0;
+       cb.buffer_size = 4*4*8;
+       ctx->set_constant_buffer(ctx, PIPE_SHADER_VERTEX, 1, &cb);
+       pipe_resource_reference(&cb.buffer, NULL);
+
        si_pm4_set_state(rctx, clip, pm4);
 }
 
@@ -387,6 +395,7 @@ static void *si_create_rs_state(struct pipe_context *ctx,
        }
 
        rs->two_side = state->light_twoside;
+       rs->clip_plane_enable = state->clip_plane_enable;
 
        polygon_dual_mode = (state->fill_front != PIPE_POLYGON_MODE_FILL ||
                                state->fill_back != PIPE_POLYGON_MODE_FILL);
@@ -484,7 +493,6 @@ static void si_bind_rs_state(struct pipe_context *ctx, void *state)
        rctx->sprite_coord_enable = rs->sprite_coord_enable;
        rctx->pa_sc_line_stipple = rs->pa_sc_line_stipple;
        rctx->pa_su_sc_mode_cntl = rs->pa_su_sc_mode_cntl;
-       rctx->pa_cl_clip_cntl = rs->pa_cl_clip_cntl;
 
        si_pm4_bind_state(rctx, rasterizer, rs);
        si_update_fb_rs_state(rctx);
index c49b029d71a4282c12ddb472fceb4aa1024a0610..7ce084e579411ec94f3b31262fef40171bb5a353 100644 (file)
@@ -49,6 +49,7 @@ struct si_state_rasterizer {
        unsigned                pa_su_sc_mode_cntl;
        unsigned                pa_cl_clip_cntl;
        unsigned                pa_cl_vs_out_cntl;
+       unsigned                clip_plane_enable;
        float                   offset_units;
        float                   offset_scale;
 };
index 1c63b140204ef82be944b4daf794b23bcc8b5e69..4380d2ca310f5caf49125867c7ec7c55fb1cee6a 100644 (file)
@@ -74,8 +74,12 @@ static void si_pipe_shader_vs(struct pipe_context *ctx, struct si_pipe_shader *s
                       S_02870C_POS1_EXPORT_FORMAT(shader->shader.vs_out_misc_write ?
                                                   V_02870C_SPI_SHADER_4COMP :
                                                   V_02870C_SPI_SHADER_NONE) |
-                      S_02870C_POS2_EXPORT_FORMAT(V_02870C_SPI_SHADER_NONE) |
-                      S_02870C_POS3_EXPORT_FORMAT(V_02870C_SPI_SHADER_NONE));
+                      S_02870C_POS2_EXPORT_FORMAT((shader->shader.clip_dist_write & 0x0F) ?
+                                                  V_02870C_SPI_SHADER_4COMP :
+                                                  V_02870C_SPI_SHADER_NONE) |
+                      S_02870C_POS3_EXPORT_FORMAT((shader->shader.clip_dist_write & 0xF0) ?
+                                                  V_02870C_SPI_SHADER_4COMP :
+                                                  V_02870C_SPI_SHADER_NONE));
 
        va = r600_resource_va(ctx->screen, (void *)shader->bo);
        si_pm4_add_bo(pm4, shader->bo, RADEON_USAGE_READ);
@@ -306,10 +310,13 @@ static bool si_update_draw_info_state(struct r600_context *rctx,
         }
        si_pm4_set_reg(pm4, R_02881C_PA_CL_VS_OUT_CNTL,
                       S_02881C_USE_VTX_POINT_SIZE(vs->vs_out_point_size) |
-                      S_02881C_VS_OUT_MISC_VEC_ENA(vs->vs_out_misc_write)
-                      /*| (rctx->rasterizer->clip_plane_enable &
-                      rctx->vs_shader->shader.clip_dist_write)*/);
-       si_pm4_set_reg(pm4, R_028810_PA_CL_CLIP_CNTL, rctx->pa_cl_clip_cntl
+                      S_02881C_VS_OUT_CCDIST0_VEC_ENA((vs->clip_dist_write & 0x0F) != 0) |
+                      S_02881C_VS_OUT_CCDIST1_VEC_ENA((vs->clip_dist_write & 0xF0) != 0) |
+                      S_02881C_VS_OUT_MISC_VEC_ENA(vs->vs_out_misc_write) |
+                      (rctx->queued.named.rasterizer->clip_plane_enable &
+                       vs->clip_dist_write));
+       si_pm4_set_reg(pm4, R_028810_PA_CL_CLIP_CNTL,
+                      rctx->queued.named.rasterizer->pa_cl_clip_cntl
                        /*| (rctx->vs_shader->shader.clip_dist_write ||
                        rctx->vs_shader->shader.vs_prohibit_ucps ?
                        0 : rctx->rasterizer->clip_plane_enable & 0x3F)*/);