From e3befbca5ed9f22effcdc91c5886c86b644bc190 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Michel=20D=C3=A4nzer?= Date: Wed, 15 May 2013 18:09:50 +0200 Subject: [PATCH] radeonsi: Handle TGSI_SEMANTIC_CLIPVERTEX 17 more little piglits. NOTE: This is a candidate for the 9.1 branch. --- src/gallium/drivers/radeonsi/radeonsi_pipe.h | 1 - .../drivers/radeonsi/radeonsi_shader.c | 62 +++++++++++++++++++ .../drivers/radeonsi/radeonsi_shader.h | 1 + src/gallium/drivers/radeonsi/si_state.c | 10 ++- src/gallium/drivers/radeonsi/si_state.h | 1 + src/gallium/drivers/radeonsi/si_state_draw.c | 19 ++++-- 6 files changed, 86 insertions(+), 8 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeonsi_pipe.h b/src/gallium/drivers/radeonsi/radeonsi_pipe.h index e50088f6e3b..32740498b11 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_pipe.h +++ b/src/gallium/drivers/radeonsi/radeonsi_pipe.h @@ -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; diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c index e6ed5459cea..484f7ecfcdb 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_shader.c +++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c @@ -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; diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h index 667f2c33985..01b8b5d3b73 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_shader.h +++ b/src/gallium/drivers/radeonsi/radeonsi_shader.h @@ -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 { diff --git a/src/gallium/drivers/radeonsi/si_state.c b/src/gallium/drivers/radeonsi/si_state.c index de86b1e38de..dec535ca597 100644 --- a/src/gallium/drivers/radeonsi/si_state.c +++ b/src/gallium/drivers/radeonsi/si_state.c @@ -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); diff --git a/src/gallium/drivers/radeonsi/si_state.h b/src/gallium/drivers/radeonsi/si_state.h index c49b029d71a..7ce084e5794 100644 --- a/src/gallium/drivers/radeonsi/si_state.h +++ b/src/gallium/drivers/radeonsi/si_state.h @@ -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; }; diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 1c63b140204..4380d2ca310 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -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)*/); -- 2.30.2