[Mesa-dev] [PATCH 1/2] radeonsi: Don't leave gaps between position exports from vertex shader
Michel Dänzer
michel at daenzer.net
Fri Aug 9 09:50:20 PDT 2013
From: Michel Dänzer <michel.daenzer at amd.com>
Exporting position 2/3 (clip distances) but not position 1 (point size)
causes geometry corruption for some reason.
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66974
Cc: mesa-stable at lists.freedesktop.org
Signed-off-by: Michel Dänzer <michel.daenzer at amd.com>
---
src/gallium/drivers/radeonsi/radeonsi_shader.c | 135 ++++++++++++++-----------
src/gallium/drivers/radeonsi/radeonsi_shader.h | 2 +-
src/gallium/drivers/radeonsi/si_state_draw.c | 12 +--
3 files changed, 85 insertions(+), 64 deletions(-)
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c b/src/gallium/drivers/radeonsi/radeonsi_shader.c
index fee6262..6756e65 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.c
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.c
@@ -562,12 +562,11 @@ 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)
+ LLVMValueRef (*pos)[9], 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;
@@ -582,6 +581,8 @@ static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context * bld_base,
}
for (reg_index = 0; reg_index < 2; reg_index ++) {
+ LLVMValueRef *args = pos[2 + reg_index];
+
args[5] =
args[6] =
args[7] =
@@ -612,10 +613,6 @@ static void si_llvm_emit_clipvertex(struct lp_build_tgsi_context * bld_base,
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);
}
}
@@ -630,17 +627,18 @@ static void si_llvm_emit_epilogue(struct lp_build_tgsi_context * bld_base)
struct tgsi_parse_context *parse = &si_shader_ctx->parse;
LLVMValueRef args[9];
LLVMValueRef last_args[9] = { 0 };
+ LLVMValueRef pos_args[4][9] = { { 0 } };
unsigned semantic_name;
unsigned color_count = 0;
unsigned param_count = 0;
int depth_index = -1, stencil_index = -1;
+ int i;
while (!tgsi_parse_end_of_tokens(parse)) {
struct tgsi_full_declaration *d =
&parse->FullToken.FullDeclaration;
unsigned target;
unsigned index;
- int i;
tgsi_parse_token(parse);
@@ -680,7 +678,6 @@ 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;
@@ -716,7 +713,7 @@ handle_semantic:
target = V_008DFC_SQ_EXP_POS + 2 + d->Semantic.Index;
break;
case TGSI_SEMANTIC_CLIPVERTEX:
- si_llvm_emit_clipvertex(bld_base, index);
+ si_llvm_emit_clipvertex(bld_base, pos_args, index);
shader->clip_dist_write = 0xFF;
continue;
case TGSI_SEMANTIC_FOG:
@@ -734,9 +731,13 @@ handle_semantic:
si_llvm_init_export_args(bld_base, d, index, target, args);
- if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX ?
- (semantic_name == TGSI_SEMANTIC_POSITION) :
- (semantic_name == TGSI_SEMANTIC_COLOR)) {
+ if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX &&
+ target >= V_008DFC_SQ_EXP_POS &&
+ target <= (V_008DFC_SQ_EXP_POS + 3)) {
+ memcpy(pos_args[target - V_008DFC_SQ_EXP_POS],
+ args, sizeof(args));
+ } else if (si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT &&
+ semantic_name == TGSI_SEMANTIC_COLOR) {
if (last_args[0]) {
lp_build_intrinsic(base->gallivm->builder,
"llvm.SI.export",
@@ -806,66 +807,86 @@ handle_semantic:
memcpy(last_args, args, sizeof(args));
}
- if (!last_args[0]) {
- assert(si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT);
+ if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
+ for (i = 0; i < 4; i++)
+ if (pos_args[i][0])
+ shader->nr_pos_exports = i + 1;
+
+ for (i = 0; i < shader->nr_pos_exports; i++) {
+ if (!pos_args[i][0]) {
+ assert(i > 0);
+ memcpy(pos_args[i], pos_args[i - 1], sizeof(pos_args[i]));
+ /* Specify the target we are exporting */
+ pos_args[i][3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_POS + i);
+ }
- /* Specify which components to enable */
- last_args[0] = lp_build_const_int32(base->gallivm, 0x0);
+ if ((i + 1) == shader->nr_pos_exports)
+ /* Specify that this is the last export */
+ pos_args[i][2] = uint->one;
- /* Specify the target we are exporting */
- last_args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRT);
+ lp_build_intrinsic(base->gallivm->builder,
+ "llvm.SI.export",
+ LLVMVoidTypeInContext(base->gallivm->context),
+ pos_args[i], 9);
+ }
+ } else {
+ if (!last_args[0]) {
+ /* Specify which components to enable */
+ last_args[0] = lp_build_const_int32(base->gallivm, 0x0);
- /* Set COMPR flag to zero to export data as 32-bit */
- last_args[4] = uint->zero;
+ /* Specify the target we are exporting */
+ last_args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRT);
- /* dummy bits */
- last_args[5]= uint->zero;
- last_args[6]= uint->zero;
- last_args[7]= uint->zero;
- last_args[8]= uint->zero;
+ /* Set COMPR flag to zero to export data as 32-bit */
+ last_args[4] = uint->zero;
- si_shader_ctx->shader->spi_shader_col_format |=
- V_028714_SPI_SHADER_32_ABGR;
- si_shader_ctx->shader->cb_shader_mask |= S_02823C_OUTPUT0_ENABLE(0xf);
- }
+ /* dummy bits */
+ last_args[5]= uint->zero;
+ last_args[6]= uint->zero;
+ last_args[7]= uint->zero;
+ last_args[8]= uint->zero;
- /* Specify whether the EXEC mask represents the valid mask */
- last_args[1] = lp_build_const_int32(base->gallivm,
- si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT);
+ si_shader_ctx->shader->spi_shader_col_format |=
+ V_028714_SPI_SHADER_32_ABGR;
+ si_shader_ctx->shader->cb_shader_mask |= S_02823C_OUTPUT0_ENABLE(0xf);
+ }
- if (shader->fs_write_all && shader->nr_cbufs > 1) {
- int i;
+ /* Specify whether the EXEC mask represents the valid mask */
+ last_args[1] = uint->one;
- /* Specify that this is not yet the last export */
- last_args[2] = lp_build_const_int32(base->gallivm, 0);
+ if (shader->fs_write_all && shader->nr_cbufs > 1) {
+ int i;
- for (i = 1; i < shader->nr_cbufs; i++) {
- /* Specify the target we are exporting */
- last_args[3] = lp_build_const_int32(base->gallivm,
- V_008DFC_SQ_EXP_MRT + i);
+ /* Specify that this is not yet the last export */
+ last_args[2] = lp_build_const_int32(base->gallivm, 0);
- lp_build_intrinsic(base->gallivm->builder,
- "llvm.SI.export",
- LLVMVoidTypeInContext(base->gallivm->context),
- last_args, 9);
+ for (i = 1; i < shader->nr_cbufs; i++) {
+ /* Specify the target we are exporting */
+ last_args[3] = lp_build_const_int32(base->gallivm,
+ V_008DFC_SQ_EXP_MRT + i);
- si_shader_ctx->shader->spi_shader_col_format |=
- si_shader_ctx->shader->spi_shader_col_format << 4;
- si_shader_ctx->shader->cb_shader_mask |=
- si_shader_ctx->shader->cb_shader_mask << 4;
- }
+ lp_build_intrinsic(base->gallivm->builder,
+ "llvm.SI.export",
+ LLVMVoidTypeInContext(base->gallivm->context),
+ last_args, 9);
- last_args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRT);
- }
+ si_shader_ctx->shader->spi_shader_col_format |=
+ si_shader_ctx->shader->spi_shader_col_format << 4;
+ si_shader_ctx->shader->cb_shader_mask |=
+ si_shader_ctx->shader->cb_shader_mask << 4;
+ }
- /* Specify that this is the last export */
- last_args[2] = lp_build_const_int32(base->gallivm, 1);
+ last_args[3] = lp_build_const_int32(base->gallivm, V_008DFC_SQ_EXP_MRT);
+ }
- lp_build_intrinsic(base->gallivm->builder,
- "llvm.SI.export",
- LLVMVoidTypeInContext(base->gallivm->context),
- last_args, 9);
+ /* Specify that this is the last export */
+ last_args[2] = lp_build_const_int32(base->gallivm, 1);
+ lp_build_intrinsic(base->gallivm->builder,
+ "llvm.SI.export",
+ LLVMVoidTypeInContext(base->gallivm->context),
+ last_args, 9);
+ }
/* XXX: Look up what this function does */
/* ctx->shader->output[i].spi_sid = r600_spi_sid(&ctx->shader->output[i]);*/
}
diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.h b/src/gallium/drivers/radeonsi/radeonsi_shader.h
index 60a48f4..9c3156d 100644
--- a/src/gallium/drivers/radeonsi/radeonsi_shader.h
+++ b/src/gallium/drivers/radeonsi/radeonsi_shader.h
@@ -110,9 +110,9 @@ struct si_shader {
bool uses_kill;
bool uses_instanceid;
bool fs_write_all;
- bool vs_out_misc_write;
bool vs_out_point_size;
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 0d1bd81..979d509 100644
--- a/src/gallium/drivers/radeonsi/si_state_draw.c
+++ b/src/gallium/drivers/radeonsi/si_state_draw.c
@@ -74,13 +74,13 @@ static void si_pipe_shader_vs(struct pipe_context *ctx, struct si_pipe_shader *s
si_pm4_set_reg(pm4, R_02870C_SPI_SHADER_POS_FORMAT,
S_02870C_POS0_EXPORT_FORMAT(V_02870C_SPI_SHADER_4COMP) |
- S_02870C_POS1_EXPORT_FORMAT(shader->shader.vs_out_misc_write ?
+ S_02870C_POS1_EXPORT_FORMAT(shader->shader.nr_pos_exports > 1 ?
V_02870C_SPI_SHADER_4COMP :
V_02870C_SPI_SHADER_NONE) |
- S_02870C_POS2_EXPORT_FORMAT((shader->shader.clip_dist_write & 0x0F) ?
+ S_02870C_POS2_EXPORT_FORMAT(shader->shader.nr_pos_exports > 2 ?
V_02870C_SPI_SHADER_4COMP :
V_02870C_SPI_SHADER_NONE) |
- S_02870C_POS3_EXPORT_FORMAT((shader->shader.clip_dist_write & 0xF0) ?
+ S_02870C_POS3_EXPORT_FORMAT(shader->shader.nr_pos_exports > 3 ?
V_02870C_SPI_SHADER_4COMP :
V_02870C_SPI_SHADER_NONE));
@@ -332,9 +332,9 @@ 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_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) |
+ S_02881C_VS_OUT_CCDIST0_VEC_ENA(vs->nr_pos_exports > 2) |
+ S_02881C_VS_OUT_CCDIST1_VEC_ENA(vs->nr_pos_exports > 3) |
+ S_02881C_VS_OUT_MISC_VEC_ENA(vs->nr_pos_exports > 1) |
(rctx->queued.named.rasterizer->clip_plane_enable &
vs->clip_dist_write));
si_pm4_set_reg(pm4, R_028810_PA_CL_CLIP_CNTL,
--
1.8.4.rc1
More information about the mesa-dev
mailing list