-----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----- _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev