1/**************************************************************************** 2* Copyright (C) 2014-2015 Intel Corporation. All Rights Reserved. 3* 4* Permission is hereby granted, free of charge, to any person obtaining a 5* copy of this software and associated documentation files (the "Software"), 6* to deal in the Software without restriction, including without limitation 7* the rights to use, copy, modify, merge, publish, distribute, sublicense, 8* and/or sell copies of the Software, and to permit persons to whom the 9* Software is furnished to do so, subject to the following conditions: 10* 11* The above copyright notice and this permission notice (including the next 12* paragraph) shall be included in all copies or substantial portions of the 13* Software. 14* 15* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 18* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21* IN THE SOFTWARE. 22* 23* @file tilingtraits.h 24* 25* @brief Tiling traits. 26* 27******************************************************************************/ 28#pragma once 29 30#include "core/state.h" 31#include "common/intrin.h" 32 33template<SWR_TILE_MODE mode, int> 34struct TilingTraits 35{ 36 static const SWR_TILE_MODE TileMode{ mode }; 37 static UINT GetCu() { SWR_NOT_IMPL; return 0; } 38 static UINT GetCv() { SWR_NOT_IMPL; return 0; } 39 static UINT GetCr() { SWR_NOT_IMPL; return 0; } 40 static UINT GetTileIDShift() { SWR_NOT_IMPL; return 0; } 41 42 /// @todo correct pdep shifts for all rastertile dims. Unused for now 43 static UINT GetPdepX() { SWR_NOT_IMPL; return 0x37; } 44 static UINT GetPdepY() { SWR_NOT_IMPL; return 0xC8; } 45}; 46 47template<int X> struct TilingTraits <SWR_TILE_NONE, X> 48{ 49 static const SWR_TILE_MODE TileMode{ SWR_TILE_NONE }; 50 static UINT GetCu() { return 0; } 51 static UINT GetCv() { return 0; } 52 static UINT GetCr() { return 0; } 53 static UINT GetTileIDShift() { return 0; } 54 static UINT GetPdepX() { return 0x00; } 55 static UINT GetPdepY() { return 0x00; } 56}; 57 58template<> struct TilingTraits <SWR_TILE_SWRZ, 8> 59{ 60 static const SWR_TILE_MODE TileMode{ SWR_TILE_SWRZ }; 61 static UINT GetCu() { return KNOB_TILE_X_DIM_SHIFT; } 62 static UINT GetCv() { return KNOB_TILE_Y_DIM_SHIFT; } 63 static UINT GetCr() { return 0; } 64 static UINT GetTileIDShift() { return KNOB_TILE_X_DIM_SHIFT + KNOB_TILE_Y_DIM_SHIFT; } 65 66 /// @todo correct pdep shifts for all rastertile dims. Unused for now 67 static UINT GetPdepX() { SWR_NOT_IMPL; return 0x00; } 68 static UINT GetPdepY() { SWR_NOT_IMPL; return 0x00; } 69}; 70 71template<> struct TilingTraits <SWR_TILE_SWRZ, 32> 72{ 73 static const SWR_TILE_MODE TileMode{ SWR_TILE_SWRZ }; 74 static UINT GetCu() { return KNOB_TILE_X_DIM_SHIFT + 2; } 75 static UINT GetCv() { return KNOB_TILE_Y_DIM_SHIFT; } 76 static UINT GetCr() { return 0; } 77 static UINT GetTileIDShift() { return KNOB_TILE_X_DIM_SHIFT + KNOB_TILE_Y_DIM_SHIFT + 2; } 78 79 static UINT GetPdepX() { return 0x37; } 80 static UINT GetPdepY() { return 0xC8; } 81}; 82 83template<> struct TilingTraits <SWR_TILE_SWRZ, 128> 84{ 85 static const SWR_TILE_MODE TileMode{ SWR_TILE_SWRZ }; 86 static UINT GetCu() { return KNOB_TILE_X_DIM_SHIFT + 4; } 87 static UINT GetCv() { return KNOB_TILE_Y_DIM_SHIFT; } 88 static UINT GetCr() { return 0; } 89 static UINT GetTileIDShift() { return KNOB_TILE_X_DIM_SHIFT + KNOB_TILE_Y_DIM_SHIFT + 4; } 90 91 /// @todo correct pdep shifts for all rastertile dims. Unused for now 92 static UINT GetPdepX() { SWR_NOT_IMPL; return 0x37; } 93 static UINT GetPdepY() { SWR_NOT_IMPL; return 0xC8; } 94}; 95 96// y-major tiling layout unaffected by element size 97template<int X> struct TilingTraits <SWR_TILE_MODE_YMAJOR, X> 98{ 99 static const SWR_TILE_MODE TileMode{ SWR_TILE_MODE_YMAJOR }; 100 static UINT GetCu() { return 7; } 101 static UINT GetCv() { return 5; } 102 static UINT GetCr() { return 0; } 103 static UINT GetTileIDShift() { return 12; } 104 105 static UINT GetPdepX() { return 0xe0f; } 106 static UINT GetPdepY() { return 0x1f0; } 107}; 108 109// x-major tiling layout unaffected by element size 110template<int X> struct TilingTraits <SWR_TILE_MODE_XMAJOR, X> 111{ 112 static const SWR_TILE_MODE TileMode{ SWR_TILE_MODE_XMAJOR }; 113 static UINT GetCu() { return 9; } 114 static UINT GetCv() { return 3; } 115 static UINT GetCr() { return 0; } 116 static UINT GetTileIDShift() { return 12; } 117 118 static UINT GetPdepX() { return 0x1ff; } 119 static UINT GetPdepY() { return 0xe00; } 120}; 121 122template<int X> struct TilingTraits <SWR_TILE_MODE_WMAJOR, X> 123{ 124 static const SWR_TILE_MODE TileMode{ SWR_TILE_MODE_WMAJOR }; 125 static UINT GetCu() { return 6; } 126 static UINT GetCv() { return 6; } 127 static UINT GetCr() { return 0; } 128 static UINT GetTileIDShift() { return 12; } 129 130 static UINT GetPdepX() { return 0xe15; } 131 static UINT GetPdepY() { return 0x1ea; } 132}; 133 134////////////////////////////////////////////////////////////////////////// 135/// @brief Computes the tileID for 2D tiled surfaces 136/// @param pitch - surface pitch in bytes 137/// @param tileX - x offset in tiles 138/// @param tileY - y offset in tiles 139template<typename TTraits> 140INLINE UINT ComputeTileOffset2D(UINT pitch, UINT tileX, UINT tileY) 141{ 142 UINT tileID = tileY * (pitch >> TTraits::GetCu()) + tileX; 143 return tileID << TTraits::GetTileIDShift(); 144} 145 146////////////////////////////////////////////////////////////////////////// 147/// @brief Computes the tileID for 3D tiled surfaces 148/// @param qpitch - surface qpitch in rows 149/// @param pitch - surface pitch in bytes 150/// @param tileX - x offset in tiles 151/// @param tileY - y offset in tiles 152/// @param tileZ - y offset in tiles 153template<typename TTraits> 154INLINE UINT ComputeTileOffset3D(UINT qpitch, UINT pitch, UINT tileX, UINT tileY, UINT tileZ) 155{ 156 UINT tileID = (tileZ * (qpitch >> TTraits::GetCv()) + tileY) * (pitch >> TTraits::GetCu()) + tileX; 157 return tileID << TTraits::GetTileIDShift(); 158} 159 160////////////////////////////////////////////////////////////////////////// 161/// @brief Computes the byte offset for 2D tiled surfaces 162/// @param pitch - surface pitch in bytes 163/// @param x - x offset in bytes 164/// @param y - y offset in rows 165template<typename TTraits> 166INLINE UINT ComputeOffset2D(UINT pitch, UINT x, UINT y) 167{ 168 UINT tileID = ComputeTileOffset2D<TTraits>(pitch, x >> TTraits::GetCu(), y >> TTraits::GetCv()); 169 UINT xSwizzle = pdep_u32(x, TTraits::GetPdepX()); 170 UINT ySwizzle = pdep_u32(y, TTraits::GetPdepY()); 171 return (tileID | xSwizzle | ySwizzle); 172} 173 174#if KNOB_ARCH <= KNOB_ARCH_AVX 175////////////////////////////////////////////////////////////////////////// 176/// @brief Computes the byte offset for 2D tiled surfaces. Specialization 177/// for tile-y surfaces that uses bit twiddling instead of pdep emulation. 178/// @param pitch - surface pitch in bytes 179/// @param x - x offset in bytes 180/// @param y - y offset in rows 181template<> 182INLINE UINT ComputeOffset2D<TilingTraits<SWR_TILE_MODE_YMAJOR, 32> >(UINT pitch, UINT x, UINT y) 183{ 184 typedef TilingTraits<SWR_TILE_MODE_YMAJOR, 32> TTraits; 185 186 UINT tileID = ComputeTileOffset2D<TTraits>(pitch, x >> TTraits::GetCu(), y >> TTraits::GetCv()); 187 UINT xSwizzle = ((x << 5) & 0xe00) | (x & 0xf); 188 UINT ySwizzle = (y << 4) & 0x1f0; 189 return (tileID | xSwizzle | ySwizzle); 190} 191#endif 192 193////////////////////////////////////////////////////////////////////////// 194/// @brief Computes the byte offset for 3D tiled surfaces 195/// @param qpitch - depth pitch in rows 196/// @param pitch - surface pitch in bytes 197/// @param x - x offset in bytes 198/// @param y - y offset in rows 199/// @param z - y offset in slices 200template<typename TTraits> 201INLINE UINT ComputeOffset3D(UINT qpitch, UINT pitch, UINT x, UINT y, UINT z) 202{ 203 UINT tileID = ComputeTileOffset3D<TTraits>(qpitch, pitch, x >> TTraits::GetCu(), y >> TTraits::GetCv(), z >> TTraits::GetCr()); 204 UINT xSwizzle = pdep_u32(x, TTraits::GetPdepX()); 205 UINT ySwizzle = pdep_u32(y, TTraits::GetPdepY()); 206 return (tileID | xSwizzle | ySwizzle); 207} 208