[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