[Mesa-dev] [PATCH v2 2/2] llvmpipe: lp_build_gather_elem_vec BE fix for 3x16 load

Roland Scheidegger sroland at vmware.com
Thu Aug 24 14:49:01 UTC 2017


Series looks alright to me. Long term I still think doing the 3x16 fixup
in gather is rather confusing, and it probably might break again, but if
it works...

For the series:
Reviewed-by: Roland Scheidegger <sroland at vmware.com>


Am 23.08.2017 um 22:32 schrieb Ben Crocker:
> Fix loading of a 3x16 vector as a single 48-bit load
> on big-endian systems (PPC64, S390).
> 
> Roland Scheidegger's commit e827d9175675aaa6cfc0b981e2a80685fb7b3a74
> plus Ray Strode's patch reduce pre-Roland Piglit failures from ~4000 to ~2000.  This patch fixes
> three of the four regressions observed by Ray:
> 
> - draw-vertices
> - draw-vertices-half-float
> - draw-vertices-half-float_gles2
> 
> One regression remains:
> - draw-vertices-2101010
> 
> Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=100613
> Cc: "17.2" "17.1" <mesa-stable at lists.freedesktop.org>
> 
> 
> Signed-off-by: Ben Crocker <bcrocker at redhat.com>
> ---
>  src/gallium/auxiliary/gallivm/lp_bld_gather.c | 30 +++++++++++++++++++++++++--
>  1 file changed, 28 insertions(+), 2 deletions(-)
> 
> diff --git a/src/gallium/auxiliary/gallivm/lp_bld_gather.c b/src/gallium/auxiliary/gallivm/lp_bld_gather.c
> index ccd0376..7d11dcd 100644
> --- a/src/gallium/auxiliary/gallivm/lp_bld_gather.c
> +++ b/src/gallium/auxiliary/gallivm/lp_bld_gather.c
> @@ -234,13 +234,39 @@ lp_build_gather_elem_vec(struct gallivm_state *gallivm,
>            */
>           res = LLVMBuildZExt(gallivm->builder, res, dst_elem_type, "");
>  
> -         if (vector_justify) {
>  #ifdef PIPE_ARCH_BIG_ENDIAN
> +         if (vector_justify) {
>           res = LLVMBuildShl(gallivm->builder, res,
>                              LLVMConstInt(dst_elem_type,
>                                           dst_type.width - src_width, 0), "");
> -#endif
>           }
> +         if (src_width == 48) {
> +            /* Load 3x16 bit vector.
> +             * The sequence of loads on big-endian hardware proceeds as follows.
> +             * 16-bit fields are denoted by X, Y, Z, and 0.  In memory, the sequence
> +             * of three fields appears in the order X, Y, Z.
> +             *
> +             * Load 32-bit word: 0.0.X.Y
> +             * Load 16-bit halfword: 0.0.0.Z
> +             * Rotate left: 0.X.Y.0
> +             * Bitwise OR: 0.X.Y.Z
> +             *
> +             * The order in which we need the fields in the result is 0.Z.Y.X,
> +             * the same as on little-endian; permute 16-bit fields accordingly
> +             * within 64-bit register:
> +             */
> +            LLVMValueRef shuffles[4] = {
> +               lp_build_const_int32(gallivm, 2),
> +               lp_build_const_int32(gallivm, 1),
> +               lp_build_const_int32(gallivm, 0),
> +               lp_build_const_int32(gallivm, 3),
> +            };
> +            res = LLVMBuildBitCast(gallivm->builder, res,
> +                                   lp_build_vec_type(gallivm, lp_type_uint_vec(16, 4*16)), "");
> +            res = LLVMBuildShuffleVector(gallivm->builder, res, res, LLVMConstVector(shuffles, 4), "");
> +            res = LLVMBuildBitCast(gallivm->builder, res, dst_elem_type, "");
> +         }
> +#endif
>        }
>     }
>     return res;
> 



More information about the mesa-dev mailing list