[Mesa-dev] [PATCH 07/20] i965/fs: Import image memory offset calculation code.

Michael Schellenberger Costa schellenberger at inb.uni-luebeck.de
Thu Jul 23 22:53:37 PDT 2015


-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi,
Am 21.07.2015 um 18:38 schrieb Francisco Jerez:
> Define a function to calculate the memory address of the image 
> location given by a vector of coordinates.  This is required in
> cases where we need to fall back to untyped surface access, which
> take a raw memory offset and know nothing about surface
> coordinates, type conversion or memory tiling and swizzling.  They
> are still useful because typed surface reads don't support any 64
> or 128-bit formats on IVB, and they don't support any 128-bit
> formats on HSW and BDW.
> 
> The tiling algorithm is implemented based on a number of
> parameters which are passed in as uniforms and determine whether
> the surface layout is X-tiled, Y-tiled or untiled.  This allows
> binding surfaces of different tiling layouts to the pipeline
> without recompiling the program.
> 
> v2: Drop VEC4 suport. v3: Rebase. --- 
> .../drivers/dri/i965/brw_fs_surface_builder.cpp    | 108
> +++++++++++++++++++++ 1 file changed, 108 insertions(+)
> 
> diff --git a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp
> b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp index
> 5ee04de..0c879db 100644 ---
> a/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp +++
> b/src/mesa/drivers/dri/i965/brw_fs_surface_builder.cpp @@ -215,4
> +215,112 @@ namespace { return BRW_PREDICATE_NORMAL; } } + +
> namespace image_coordinates { +      /** +       * Calculate the
> offset in memory of the texel given by \p coord. +       * +
> * This is meant to be used with untyped surface messages to access
> a +       * tiled surface, what involves taking into account the
> tiling and +       * swizzling modes of the surface manually so it
> will hopefully not +       * happen very often. +       */ +
> fs_reg +      emit_address_calculation(const fs_builder &bld, const
> fs_reg &image, +                               const fs_reg &coord,
> unsigned dims) +      { +         const brw_device_info *devinfo =
> bld.shader->devinfo; +         const fs_reg off = offset(image,
> bld, BRW_IMAGE_PARAM_OFFSET_OFFSET); +         const fs_reg stride
> = offset(image, bld, BRW_IMAGE_PARAM_STRIDE_OFFSET); +
> const fs_reg tile = offset(image, bld,
> BRW_IMAGE_PARAM_TILING_OFFSET); +         const fs_reg swz =
> offset(image, bld, BRW_IMAGE_PARAM_SWIZZLING_OFFSET); +
> const fs_reg addr = bld.vgrf(BRW_REGISTER_TYPE_UD, 2); +
> const fs_reg tmp = bld.vgrf(BRW_REGISTER_TYPE_UD, 2); +
> const fs_reg minor = bld.vgrf(BRW_REGISTER_TYPE_UD, 2); +
> const fs_reg major = bld.vgrf(BRW_REGISTER_TYPE_UD, 2); +
> const fs_reg dst = bld.vgrf(BRW_REGISTER_TYPE_UD); + +         /*
> Shift the coordinates by the fixed surface offset. */ +         for
> (unsigned c = 0; c < 2; ++c) +            bld.ADD(offset(addr, bld,
> c), offset(off, bld, c), +                    (c < dims ? +
> offset(retype(coord, BRW_REGISTER_TYPE_UD), bld, c) : +
> fs_reg(0)));

^That loop should have curly braces for readability
.
Regards
Michael
> + +         if (dims > 2) { +            /* Decompose z into a
> major (tmp.y) and a minor (tmp.x) +             * index. +
> */ +            bld.BFE(offset(tmp, bld, 0), offset(tile, bld, 2),
> fs_reg(0), +                    offset(retype(coord,
> BRW_REGISTER_TYPE_UD), bld, 2)); +            bld.SHR(offset(tmp,
> bld, 1), +                    offset(retype(coord,
> BRW_REGISTER_TYPE_UD), bld, 2), +                    offset(tile,
> bld, 2)); + +            /* Take into account the horizontal
> (tmp.x) and vertical (tmp.y) +             * slice offset. +
> */ +            for (unsigned c = 0; c < 2; ++c) { +
> bld.MUL(offset(tmp, bld, c), +                       offset(stride,
> bld, 2 + c), offset(tmp, bld, c)); +
> bld.ADD(offset(addr, bld, c), +                       offset(addr,
> bld, c), offset(tmp, bld, c)); +            } +         } + +
> if (dims > 1) { +            for (unsigned c = 0; c < 2; ++c) { +
> /* Calculate the minor x and y indices. */ +
> bld.BFE(offset(minor, bld, c), offset(tile, bld, c), +
> fs_reg(0), offset(addr, bld, c)); + +               /* Calculate
> the major x and y indices. */ +               bld.SHR(offset(major,
> bld, c), +                       offset(addr, bld, c), offset(tile,
> bld, c)); +            } + +            /* Calculate the texel
> index from the start of the tile row and +             * the
> vertical coordinate of the row. +             * Equivalent to: +
> *   tmp.x = (major.x << tile.y << tile.x) + +             *
> (minor.y << tile.x) + minor.x +             *   tmp.y = major.y <<
> tile.y +             */ +            bld.SHL(tmp, major,
> offset(tile, bld, 1)); +            bld.ADD(tmp, tmp, offset(minor,
> bld, 1)); +            bld.SHL(tmp, tmp, offset(tile, bld, 0)); +
> bld.ADD(tmp, tmp, minor); +            bld.SHL(offset(tmp, bld,
> 1), +                    offset(major, bld, 1), offset(tile, bld,
> 1)); + +            /* Add it to the start of the tile row. */ +
> bld.MUL(offset(tmp, bld, 1), +                    offset(tmp, bld,
> 1), offset(stride, bld, 1)); +            bld.ADD(tmp, tmp,
> offset(tmp, bld, 1)); + +            /* Multiply by the Bpp value.
> */ +            bld.MUL(dst, tmp, stride); + +            if
> (devinfo->gen < 8 && !devinfo->is_baytrail) { +               /*
> Take into account the two dynamically specified shifts. */ +
> for (unsigned c = 0; c < 2; ++c) +
> bld.SHR(offset(tmp, bld, c), dst, offset(swz, bld, c)); + +
> /* XOR tmp.x and tmp.y with bit 6 of the memory address. */ +
> bld.XOR(tmp, tmp, offset(tmp, bld, 1)); +
> bld.AND(tmp, tmp, fs_reg(1 << 6)); +               bld.XOR(dst,
> dst, tmp); +            } + +         } else { +            /*
> Multiply by the Bpp/stride value. */ +
> bld.MUL(offset(addr, bld, 1), +                    offset(addr,
> bld, 1), offset(stride, bld, 1)); +            bld.ADD(addr, addr,
> offset(addr, bld, 1)); +            bld.MUL(dst, addr, stride); +
> } + +         return dst; +      } +   } }
> 

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.22 (GNU/Linux)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iQEcBAEBAgAGBQJVsdLhAAoJECfkpCAi2eFKXKsH/19EiTWApmcKdFvd7Kav3FBB
uiBAzRGCrdK9UomcG54iZqPLMpR5NGdEUgcoSTE28Rcy7wi4vyZwm86Soj7GVNxM
9dad1AJADIgoEIQIAL+qs8Z5mj6c6qZ3hy0db9eeLv02IInEOaq9d5xJqZ/o0ThW
7VWf3DbBO1mBINZoUblJsqHDsygguGzdQ/U/v4Xw06RT8fLF/wPmI465mxfGFBss
GDu/dpV/pk656T+lv1DJ+i/USq4Ia8sqVUj1rsL9E6KsIxWsSD5oSPBUT31fqvgh
EUn63Q3MOf1ex+/eK9UZ+xGMpiy5wpthW/IqdFUkW03rZwJbEmV5FWedT+r95GY=
=IKG5
-----END PGP SIGNATURE-----


More information about the mesa-dev mailing list