On Tue, Aug 13, 2013 at 07:39:10PM +0200, Michel Dänzer wrote:
> From: Michel Dänzer <michel.daen...@amd.com>
> 
> If the vertex shader exports clip distances but not point size, use
> position exports 1/2 instead of 2/3 for the clip distances. Fixes
> geometry corruption in that case.
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=66974
> 
> Cc: mesa-sta...@lists.freedesktop.org
> Signed-off-by: Michel Dänzer <michel.daen...@amd.com>

I took a look through the LLVM calls in these patches and they look OK
to me.

Reviewed-by: Tom Stellard <thomas.stell...@amd.com>

> ---
> 
> v2: No need to export unused position vectors, just export to consecutive
>     position export slots.
> 
>  src/gallium/drivers/radeonsi/radeonsi_shader.c | 135 
> +++++++++++++++----------
>  src/gallium/drivers/radeonsi/radeonsi_shader.h |   1 +
>  src/gallium/drivers/radeonsi/si_state_draw.c   |   6 +-
>  3 files changed, 83 insertions(+), 59 deletions(-)
> 
> diff --git a/src/gallium/drivers/radeonsi/radeonsi_shader.c 
> b/src/gallium/drivers/radeonsi/radeonsi_shader.c
> index fee6262..dd9581d 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);
>  
> @@ -716,7 +714,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 +732,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 +808,87 @@ handle_semantic:
>                       memcpy(last_args, args, sizeof(args));
>       }
>  
> -     if (!last_args[0]) {
> -             assert(si_shader_ctx->type == TGSI_PROCESSOR_FRAGMENT);
> -
> -             /* Specify which components to enable */
> -             last_args[0] = lp_build_const_int32(base->gallivm, 0x0);
> -
> -             /* Specify the target we are exporting */
> -             last_args[3] = lp_build_const_int32(base->gallivm, 
> V_008DFC_SQ_EXP_MRT);
> -
> -             /* Set COMPR flag to zero to export data as 32-bit */
> -             last_args[4] = uint->zero;
> -
> -             /* dummy bits */
> -             last_args[5]= uint->zero;
> -             last_args[6]= uint->zero;
> -             last_args[7]= uint->zero;
> -             last_args[8]= 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);
> -     }
> -
> -     /* 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);
> +     if (si_shader_ctx->type == TGSI_PROCESSOR_VERTEX) {
> +             unsigned pos_idx = 0;
>  
> -     if (shader->fs_write_all && shader->nr_cbufs > 1) {
> -             int i;
> +             for (i = 0; i < 4; i++)
> +                     if (pos_args[i][0])
> +                             shader->nr_pos_exports++;
>  
> -             /* Specify that this is not yet the last export */
> -             last_args[2] = lp_build_const_int32(base->gallivm, 0);
> +             for (i = 0; i < 4; i++) {
> +                     if (!pos_args[i][0])
> +                             continue;
>  
> -             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);
> +                     pos_args[i][3] = lp_build_const_int32(base->gallivm, 
> V_008DFC_SQ_EXP_POS + pos_idx++);
> +
> +                     if (pos_idx == shader->nr_pos_exports)
> +                             /* Specify that this is the last export */
> +                             pos_args[i][2] = uint->one;
>  
>                       lp_build_intrinsic(base->gallivm->builder,
>                                          "llvm.SI.export",
>                                          
> LLVMVoidTypeInContext(base->gallivm->context),
> -                                        last_args, 9);
> +                                        pos_args[i], 9);
> +             }
> +     } else {
> +             if (!last_args[0]) {
> +                     /* Specify which components to enable */
> +                     last_args[0] = lp_build_const_int32(base->gallivm, 0x0);
> +
> +                     /* Specify the target we are exporting */
> +                     last_args[3] = lp_build_const_int32(base->gallivm, 
> V_008DFC_SQ_EXP_MRT);
> +
> +                     /* Set COMPR flag to zero to export data as 32-bit */
> +                     last_args[4] = uint->zero;
> +
> +                     /* dummy bits */
> +                     last_args[5]= uint->zero;
> +                     last_args[6]= uint->zero;
> +                     last_args[7]= uint->zero;
> +                     last_args[8]= uint->zero;
>  
>                       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;
> +                             V_028714_SPI_SHADER_32_ABGR;
> +                     si_shader_ctx->shader->cb_shader_mask |= 
> S_02823C_OUTPUT0_ENABLE(0xf);
>               }
>  
> -             last_args[3] = lp_build_const_int32(base->gallivm, 
> V_008DFC_SQ_EXP_MRT);
> -     }
> +             /* Specify whether the EXEC mask represents the valid mask */
> +             last_args[1] = uint->one;
> +
> +             if (shader->fs_write_all && shader->nr_cbufs > 1) {
> +                     int i;
> +
> +                     /* Specify that this is not yet the last export */
> +                     last_args[2] = lp_build_const_int32(base->gallivm, 0);
> +
> +                     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);
> +
> +                             lp_build_intrinsic(base->gallivm->builder,
> +                                                "llvm.SI.export",
> +                                                
> LLVMVoidTypeInContext(base->gallivm->context),
> +                                                last_args, 9);
> +
> +                             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..f28a0ea 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                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..7d037d0 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));
>  
> -- 
> 1.8.4.rc2
> 
> _______________________________________________
> mesa-dev mailing list
> mesa-dev@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/mesa-dev
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to