From 053606ddaed6354e8d26d0654d211b6d20051937 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Marek=20Ol=C5=A1=C3=A1k?= Date: Tue, 19 Nov 2013 22:07:30 +0100 Subject: [PATCH] radeonsi: implement OpenGL edge flags MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Reviewed-by: Michel Dänzer --- .../drivers/radeonsi/radeonsi_shader.c | 52 ++++++++++++++++--- .../drivers/radeonsi/radeonsi_shader.h | 1 + src/gallium/drivers/radeonsi/si_state_draw.c | 1 + 3 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c index 61e619ad810..ebe9125c3ea 100644 --- a/src/gallium/drivers/radeonsi/radeonsi_shader.c +++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c @@ -889,7 +889,7 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base) LLVMValueRef pos_args[4][9] = { { 0 } }; unsigned semantic_name; unsigned param_count = 0; - int depth_index = -1, stencil_index = -1; + int depth_index = -1, stencil_index = -1, psize_index = -1, edgeflag_index = -1; int i; if (si_shader_ctx->shader->selector->so.num_outputs) { @@ -940,10 +940,15 @@ handle_semantic: /* Select the correct target */ switch(semantic_name) { case TGSI_SEMANTIC_PSIZE: - shader->vs_out_misc_write = 1; - shader->vs_out_point_size = 1; - target = V_008DFC_SQ_EXP_POS + 1; - break; + shader->vs_out_misc_write = true; + shader->vs_out_point_size = true; + psize_index = index; + continue; + case TGSI_SEMANTIC_EDGEFLAG: + shader->vs_out_misc_write = true; + shader->vs_out_edgeflag = true; + edgeflag_index = index; + continue; case TGSI_SEMANTIC_POSITION: if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) { target = V_008DFC_SQ_EXP_POS; @@ -1018,7 +1023,6 @@ handle_semantic: LLVMVoidTypeInContext(base->gallivm->context), args, 9); } - } if (semantic_name == TGSI_SEMANTIC_CLIPDIST) { @@ -1092,6 +1096,42 @@ handle_semantic: pos_args[0][8] = base->one; /* W */ } + /* Write the misc vector (point size, edgeflag, layer, viewport). */ + if (shader->vs_out_misc_write) { + pos_args[1][0] = lp_build_const_int32(base->gallivm, /* writemask */ + shader->vs_out_point_size | + (shader->vs_out_edgeflag << 1)); + pos_args[1][1] = uint->zero; /* EXEC mask */ + pos_args[1][2] = uint->zero; /* last export? */ + pos_args[1][3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_POS + 1); + pos_args[1][4] = uint->zero; /* COMPR flag */ + pos_args[1][5] = base->zero; /* X */ + pos_args[1][6] = base->zero; /* Y */ + pos_args[1][7] = base->zero; /* Z */ + pos_args[1][8] = base->zero; /* W */ + + if (shader->vs_out_point_size) { + pos_args[1][5] = LLVMBuildLoad(base->gallivm->builder, + si_shader_ctx->radeon_bld.soa.outputs[psize_index][0], ""); + } + + if (shader->vs_out_edgeflag) { + LLVMValueRef output = LLVMBuildLoad(base->gallivm->builder, + si_shader_ctx->radeon_bld.soa.outputs[edgeflag_index][0], ""); + + /* The output is a float, but the hw expects an integer + * with the first bit containing the edge flag. */ + output = LLVMBuildFPToUI(base->gallivm->builder, output, + bld_base->uint_bld.elem_type, ""); + + output = lp_build_min(&bld_base->int_bld, output, bld_base->int_bld.one); + + /* The LLVM intrinsic expects a float. */ + pos_args[1][6] = LLVMBuildBitCast(base->gallivm->builder, output, + base->elem_type, ""); + } + } + for (i = 0; i < 4; i++) if (pos_args[i][0]) shader->nr_pos_exports++; diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h index c9e851a899c..5432a878d5d 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 fs_write_all; bool vs_out_misc_write; bool vs_out_point_size; + bool vs_out_edgeflag; unsigned nr_cbufs; unsigned nr_pos_exports; unsigned clip_dist_write; diff --git a/src/gallium/drivers/radeonsi/si_state_draw.c b/src/gallium/drivers/radeonsi/si_state_draw.c index 1467bb69d4b..d2c8e4c0985 100644 --- a/src/gallium/drivers/radeonsi/si_state_draw.c +++ b/src/gallium/drivers/radeonsi/si_state_draw.c @@ -369,6 +369,7 @@ 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_USE_VTX_EDGE_FLAG(vs->vs_out_edgeflag) | 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) | -- 2.30.2