~mmach/netext73/mesa-ryzen

« back to all changes in this revision

Viewing changes to src/intel/isl/isl.c

  • Committer: mmach
  • Date: 2023-11-02 21:31:35 UTC
  • Revision ID: netbit73@gmail.com-20231102213135-18d4tzh7tj0uz752
2023-11-02 22:11:57

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
#include <assert.h>
25
25
#include <stdarg.h>
26
26
#include <stdio.h>
 
27
#include <inttypes.h>
27
28
 
 
29
#include "dev/intel_debug.h"
28
30
#include "genxml/genX_bits.h"
 
31
#include "util/log.h"
29
32
 
30
33
#include "isl.h"
31
34
#include "isl_gfx4.h"
112
115
         dev->mocs.internal = 1 << 1;
113
116
         /* Displayables cached to L3+L4:WT */
114
117
         dev->mocs.external = 14 << 1;
 
118
         /* Uncached - GO:Mem */
 
119
         dev->mocs.uncached = 5 << 1;
115
120
      } else if (intel_device_info_is_dg2(dev->info)) {
116
121
         /* L3CC=WB; BSpec: 45101 */
117
122
         dev->mocs.internal = 3 << 1;
118
123
         dev->mocs.external = 3 << 1;
 
124
         /* UC - Coherent; GO:Memory */
 
125
         dev->mocs.uncached = 1 << 1;
119
126
 
120
127
         /* XY_BLOCK_COPY_BLT MOCS fields have programming notes which say:
121
128
          *
147
154
          * and flushed at bottom of each submission.
148
155
          */
149
156
         dev->mocs.external = 5 << 1;
 
157
         /* UC */
 
158
         dev->mocs.uncached = 1 << 1;
150
159
      } else {
151
160
         /* TC=1/LLC Only, LeCC=1/UC, LRUM=0, L3CC=3/WB */
152
161
         dev->mocs.external = 61 << 1;
153
162
         /* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */
154
163
         dev->mocs.internal = 2 << 1;
 
164
         /* Uncached */
 
165
         dev->mocs.uncached = 3 << 1;
155
166
 
156
167
         /* L1 - HDC:L1 + L3 + LLC */
157
168
         dev->mocs.l1_hdc_l3_llc = 48 << 1;
163
174
      dev->mocs.external = 1 << 1;
164
175
      /* TC=LLC/eLLC, LeCC=WB, LRUM=3, L3CC=WB */
165
176
      dev->mocs.internal = 2 << 1;
 
177
      /* Uncached */
 
178
      dev->mocs.uncached = (dev->info->ver >= 11 ? 3 : 0) << 1;
166
179
   } else if (dev->info->ver >= 8) {
167
180
      /* MEMORY_OBJECT_CONTROL_STATE:
168
181
       * .MemoryTypeLLCeLLCCacheabilityControl = UCwithFenceifcoherentcycle,
176
189
       * .AgeforQUADLRU = 0
177
190
       */
178
191
      dev->mocs.internal = 0x78;
 
192
      if (dev->info->platform == INTEL_PLATFORM_CHV) {
 
193
         /* MEMORY_OBJECT_CONTROL_STATE:
 
194
          * .MemoryType = UC,
 
195
          * .TargetCache = NoCaching,
 
196
          */
 
197
         dev->mocs.uncached = 0;
 
198
      } else {
 
199
         /* MEMORY_OBJECT_CONTROL_STATE:
 
200
          * .MemoryTypeLLCeLLCCacheabilityControl = UCUncacheable,
 
201
          * .TargetCache = eLLCOnlywheneDRAMispresentelsegetsallocatedinLLC,
 
202
          * .AgeforQUADLRU = 0
 
203
          */
 
204
         dev->mocs.uncached = 0x20;
 
205
      }
179
206
   } else if (dev->info->ver >= 7) {
180
207
      if (dev->info->platform == INTEL_PLATFORM_HSW) {
181
208
         /* MEMORY_OBJECT_CONTROL_STATE:
184
211
          */
185
212
         dev->mocs.internal = 1;
186
213
         dev->mocs.external = 1;
 
214
         /* MEMORY_OBJECT_CONTROL_STATE:
 
215
          * .LLCeLLCCacheabilityControlLLCCC             = 1,
 
216
          * .L3CacheabilityControlL3CC                   = 0,
 
217
          */
 
218
         dev->mocs.uncached = 2;
187
219
      } else {
188
220
         /* MEMORY_OBJECT_CONTROL_STATE:
189
221
          * .GraphicsDataTypeGFDT                        = 0,
192
224
          */
193
225
         dev->mocs.internal = 1;
194
226
         dev->mocs.external = 1;
 
227
         /* MEMORY_OBJECT_CONTROL_STATE:
 
228
          * .GraphicsDataTypeGFDT                        = 0,
 
229
          * .LLCCacheabilityControlLLCCC                 = 0,
 
230
          * .L3CacheabilityControlL3CC                   = 0,
 
231
          */
 
232
         dev->mocs.uncached = 0;
195
233
      }
196
234
   } else {
197
235
      dev->mocs.internal = 0;
198
236
      dev->mocs.external = 0;
 
237
      dev->mocs.uncached = 0;
199
238
   }
200
239
}
201
240
 
212
251
   if (external)
213
252
      return dev->mocs.external | mask;
214
253
 
 
254
   if (intel_device_info_is_mtl(dev->info) &&
 
255
       (usage & ISL_SURF_USAGE_STREAM_OUT_BIT))
 
256
      return dev->mocs.uncached | mask;
 
257
 
215
258
   if (dev->info->verx10 == 120 && dev->info->platform != INTEL_PLATFORM_DG1) {
216
259
      if (usage & ISL_SURF_USAGE_STAGING_BIT)
217
260
         return dev->mocs.internal | mask;
491
534
#define tile_extent(bs, cv, cu, a) \
492
535
      isl_extent4d((1 << cu) / bs, 1 << cv, 1, a)
493
536
 
494
 
      /* Only 2D surfaces are handled. */
495
 
      assert(dim == ISL_SURF_DIM_2D);
 
537
      /* Only 1D and 2D surfaces are handled. */
 
538
      assert(dim != ISL_SURF_DIM_3D);
496
539
 
497
540
      if (samples == 1 || msaa_layout == ISL_MSAA_LAYOUT_INTERLEAVED) {
498
541
         switch (format_bpb) {
715
758
   #undef CHOOSE
716
759
 
717
760
   /* No tiling mode accommodates the inputs. */
718
 
   return false;
 
761
   assert(tiling_flags == 0);
 
762
   return notify_failure(info, "no supported tiling");
719
763
}
720
764
 
721
765
static bool
899
943
       * Height, width, and layout of MCS buffer in this case must match with
900
944
       * Render Target height, width, and layout. MCS buffer is tiledY.
901
945
       *
902
 
       * To avoid wasting memory, choose the smallest alignment possible:
903
 
       * HALIGN_4 and VALIGN_4.
 
946
       * Pick a vertical and horizontal alignment that matches the main render
 
947
       * target. Vertical alignment is important for properly spacing an array
 
948
       * of MCS images. Horizontal alignment is not expected to matter because
 
949
       * MCS is not mipmapped. Regardless, we pick a valid value here.
904
950
       */
905
 
      *image_align_el = isl_extent3d(4, 4, 1);
 
951
      if (ISL_GFX_VERX10(dev) >= 125) {
 
952
         *image_align_el = isl_extent3d(128 * 8 / fmtl->bpb, 4, 1);
 
953
      } else if (ISL_GFX_VER(dev) >= 8) {
 
954
         *image_align_el = isl_extent3d(16, 4, 1);
 
955
      } else {
 
956
         *image_align_el = isl_extent3d(4, 4, 1);
 
957
      }
906
958
      return;
907
959
   } else if (fmtl->txc == ISL_TXC_HIZ) {
908
960
      assert(ISL_GFX_VER(dev) >= 6);
1763
1815
   return likely(bits != 0 && 1 <= n && n <= (1 << bits));
1764
1816
}
1765
1817
 
 
1818
void PRINTFLIKE(4, 5)
 
1819
_isl_notify_failure(const struct isl_surf_init_info *surf_info,
 
1820
                    const char *file, int line, const char *fmt, ...)
 
1821
{
 
1822
   if (!INTEL_DEBUG(DEBUG_ISL))
 
1823
      return;
 
1824
 
 
1825
   char msg[512];
 
1826
   va_list ap;
 
1827
   va_start(ap, fmt);
 
1828
   int ret = vsnprintf(msg, sizeof(msg), fmt, ap);
 
1829
   assert(ret < sizeof(msg));
 
1830
   va_end(ap);
 
1831
 
 
1832
#define PRINT_USAGE(bit, str) \
 
1833
            (surf_info->usage & ISL_SURF_USAGE_##bit##_BIT) ? ("+"str) : ""
 
1834
#define PRINT_TILING(bit, str) \
 
1835
            (surf_info->tiling_flags & ISL_TILING_##bit##_BIT) ? ("+"str) : ""
 
1836
 
 
1837
   snprintf(msg + ret, sizeof(msg) - ret,
 
1838
            " extent=%ux%ux%u dim=%s msaa=%ux levels=%u rpitch=%u fmt=%s "
 
1839
            "usages=%s%s%s%s%s%s%s%s%s%s%s%s%s%s "
 
1840
            "tiling_flags=%s%s%s%s%s%s%s%s%s%s%s",
 
1841
            surf_info->width, surf_info->height,
 
1842
            surf_info->dim == ISL_SURF_DIM_3D ?
 
1843
            surf_info->depth : surf_info->array_len,
 
1844
            surf_info->dim == ISL_SURF_DIM_1D ? "1d" :
 
1845
            surf_info->dim == ISL_SURF_DIM_2D ? "2d" : "3d",
 
1846
            surf_info->samples, surf_info->levels,
 
1847
            surf_info->row_pitch_B,
 
1848
            isl_format_get_name(surf_info->format) + strlen("ISL_FORMAT_"),
 
1849
 
 
1850
            PRINT_USAGE(RENDER_TARGET,   "rt"),
 
1851
            PRINT_USAGE(DEPTH,           "depth"),
 
1852
            PRINT_USAGE(STENCIL,         "stenc"),
 
1853
            PRINT_USAGE(TEXTURE,         "tex"),
 
1854
            PRINT_USAGE(CUBE,            "cube"),
 
1855
            PRINT_USAGE(DISABLE_AUX,     "noaux"),
 
1856
            PRINT_USAGE(DISPLAY,         "disp"),
 
1857
            PRINT_USAGE(HIZ,             "hiz"),
 
1858
            PRINT_USAGE(MCS,             "mcs"),
 
1859
            PRINT_USAGE(CCS,             "ccs"),
 
1860
            PRINT_USAGE(VERTEX_BUFFER,   "vb"),
 
1861
            PRINT_USAGE(INDEX_BUFFER,    "ib"),
 
1862
            PRINT_USAGE(CONSTANT_BUFFER, "const"),
 
1863
            PRINT_USAGE(STAGING,         "stage"),
 
1864
 
 
1865
            PRINT_TILING(LINEAR,         "linear"),
 
1866
            PRINT_TILING(W,              "W"),
 
1867
            PRINT_TILING(X,              "X"),
 
1868
            PRINT_TILING(Y0,             "Y0"),
 
1869
            PRINT_TILING(Yf,             "Yf"),
 
1870
            PRINT_TILING(Ys,             "Ys"),
 
1871
            PRINT_TILING(4,              "4"),
 
1872
            PRINT_TILING(64,             "64"),
 
1873
            PRINT_TILING(HIZ,            "hiz"),
 
1874
            PRINT_TILING(CCS,            "ccs"),
 
1875
            PRINT_TILING(GFX12_CCS,      "ccs12"));
 
1876
 
 
1877
#undef PRINT_USAGE
 
1878
#undef PRINT_TILING
 
1879
 
 
1880
   mesa_logd("%s:%i: %s", file, line, msg);
 
1881
}
 
1882
 
1766
1883
static bool
1767
1884
isl_calc_row_pitch(const struct isl_device *dev,
1768
1885
                   const struct isl_surf_init_info *surf_info,
1779
1896
                             alignment_B);
1780
1897
 
1781
1898
   if (surf_info->row_pitch_B != 0) {
1782
 
      if (surf_info->row_pitch_B < min_row_pitch_B)
1783
 
         return false;
 
1899
      if (surf_info->row_pitch_B < min_row_pitch_B) {
 
1900
         return notify_failure(surf_info,
 
1901
                               "requested row pitch (%uB) less than minimum "
 
1902
                               "allowed (%uB)",
 
1903
                               surf_info->row_pitch_B, min_row_pitch_B);
 
1904
      }
1784
1905
 
1785
 
      if (surf_info->row_pitch_B % alignment_B != 0)
1786
 
         return false;
 
1906
      if (surf_info->row_pitch_B % alignment_B != 0) {
 
1907
         return notify_failure(surf_info,
 
1908
                               "requested row pitch (%uB) doesn't satisfy the "
 
1909
                               "minimum alignment requirement (%uB)",
 
1910
                               surf_info->row_pitch_B, alignment_B);
 
1911
      }
1787
1912
   }
1788
1913
 
1789
1914
   const uint32_t row_pitch_B =
1792
1917
   const uint32_t row_pitch_tl = row_pitch_B / tile_info->phys_extent_B.width;
1793
1918
 
1794
1919
   if (row_pitch_B == 0)
1795
 
      return false;
 
1920
      return notify_failure(surf_info, "calculated row pitch is zero");
1796
1921
 
1797
1922
   if (dim_layout == ISL_DIM_LAYOUT_GFX9_1D) {
1798
1923
      /* SurfacePitch is ignored for this layout. */
1802
1927
   if ((surf_info->usage & (ISL_SURF_USAGE_RENDER_TARGET_BIT |
1803
1928
                            ISL_SURF_USAGE_TEXTURE_BIT |
1804
1929
                            ISL_SURF_USAGE_STORAGE_BIT)) &&
1805
 
       !pitch_in_range(row_pitch_B, RENDER_SURFACE_STATE_SurfacePitch_bits(dev->info)))
1806
 
      return false;
 
1930
       !pitch_in_range(row_pitch_B, RENDER_SURFACE_STATE_SurfacePitch_bits(dev->info))) {
 
1931
      return notify_failure(surf_info,
 
1932
                            "row pitch (%uB) not in range of "
 
1933
                            "RENDER_SURFACE_STATE::SurfacePitch",
 
1934
                            row_pitch_B);
 
1935
   }
1807
1936
 
1808
1937
   if ((surf_info->usage & (ISL_SURF_USAGE_CCS_BIT |
1809
1938
                            ISL_SURF_USAGE_MCS_BIT)) &&
1810
 
       !pitch_in_range(row_pitch_tl, RENDER_SURFACE_STATE_AuxiliarySurfacePitch_bits(dev->info)))
1811
 
      return false;
 
1939
       !pitch_in_range(row_pitch_tl, RENDER_SURFACE_STATE_AuxiliarySurfacePitch_bits(dev->info))) {
 
1940
      return notify_failure(surf_info,
 
1941
                            "row_pitch_tl=%u not in range of "
 
1942
                            "RENDER_SURFACE_STATE::AuxiliarySurfacePitch",
 
1943
                            row_pitch_tl);
 
1944
   }
1812
1945
 
1813
1946
   if ((surf_info->usage & ISL_SURF_USAGE_DEPTH_BIT) &&
1814
 
       !pitch_in_range(row_pitch_B, _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info)))
1815
 
      return false;
 
1947
       !pitch_in_range(row_pitch_B, _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info))) {
 
1948
      return notify_failure(surf_info,
 
1949
                            "row pitch (%uB) not in range of "
 
1950
                            "3DSTATE_DEPTH_BUFFER::SurfacePitch",
 
1951
                            row_pitch_B);
 
1952
   }
1816
1953
 
1817
1954
   if ((surf_info->usage & ISL_SURF_USAGE_HIZ_BIT) &&
1818
 
       !pitch_in_range(row_pitch_B, _3DSTATE_HIER_DEPTH_BUFFER_SurfacePitch_bits(dev->info)))
1819
 
      return false;
 
1955
       !pitch_in_range(row_pitch_B, _3DSTATE_HIER_DEPTH_BUFFER_SurfacePitch_bits(dev->info))) {
 
1956
      return notify_failure(surf_info,
 
1957
                            "row pitch (%uB) not in range of "
 
1958
                            "3DSTATE_HIER_DEPTH_BUFFER::SurfacePitch",
 
1959
                            row_pitch_B);
 
1960
   }
1820
1961
 
1821
1962
   const uint32_t stencil_pitch_bits = dev->use_separate_stencil ?
1822
1963
      _3DSTATE_STENCIL_BUFFER_SurfacePitch_bits(dev->info) :
1823
1964
      _3DSTATE_DEPTH_BUFFER_SurfacePitch_bits(dev->info);
1824
1965
 
1825
1966
   if ((surf_info->usage & ISL_SURF_USAGE_STENCIL_BIT) &&
1826
 
       !pitch_in_range(row_pitch_B, stencil_pitch_bits))
1827
 
      return false;
 
1967
       !pitch_in_range(row_pitch_B, stencil_pitch_bits)) {
 
1968
      return notify_failure(surf_info,
 
1969
                            "row pitch (%uB) not in range of "
 
1970
                            "3DSTATE_STENCIL_BUFFER/3DSTATE_DEPTH_BUFFER::SurfacePitch",
 
1971
                            row_pitch_B);
 
1972
   }
1828
1973
 
1829
1974
   if ((surf_info->usage & ISL_SURF_USAGE_CPB_BIT) &&
1830
1975
       !pitch_in_range(row_pitch_B, _3DSTATE_CPSIZE_CONTROL_BUFFER_SurfacePitch_bits(dev->info)))
1835
1980
   return true;
1836
1981
}
1837
1982
 
 
1983
static bool
 
1984
isl_calc_size(const struct isl_device *dev,
 
1985
              const struct isl_surf_init_info *info,
 
1986
              const struct isl_tile_info *tile_info,
 
1987
              const struct isl_extent4d *phys_total_el,
 
1988
              uint32_t array_pitch_el_rows,
 
1989
              uint32_t row_pitch_B,
 
1990
              uint64_t *out_size_B)
 
1991
{
 
1992
   uint64_t size_B;
 
1993
   if (tile_info->tiling == ISL_TILING_LINEAR) {
 
1994
      /* LINEAR tiling has no concept of intra-tile arrays */
 
1995
      assert(phys_total_el->d == 1 && phys_total_el->a == 1);
 
1996
 
 
1997
      size_B = (uint64_t) row_pitch_B * phys_total_el->h;
 
1998
 
 
1999
   } else {
 
2000
      /* Pitches must make sense with the tiling */
 
2001
      assert(row_pitch_B % tile_info->phys_extent_B.width == 0);
 
2002
 
 
2003
      uint32_t array_slices, array_pitch_tl_rows;
 
2004
      if (phys_total_el->d > 1) {
 
2005
         assert(phys_total_el->a == 1);
 
2006
         array_pitch_tl_rows = isl_assert_div(array_pitch_el_rows,
 
2007
                                              tile_info->logical_extent_el.h);
 
2008
         array_slices = isl_align_div(phys_total_el->d,
 
2009
                                      tile_info->logical_extent_el.d);
 
2010
      } else if (phys_total_el->a > 1) {
 
2011
         assert(phys_total_el->d == 1);
 
2012
         array_pitch_tl_rows = isl_assert_div(array_pitch_el_rows,
 
2013
                                              tile_info->logical_extent_el.h);
 
2014
         array_slices = isl_align_div(phys_total_el->a,
 
2015
                                      tile_info->logical_extent_el.a);
 
2016
      } else {
 
2017
         assert(phys_total_el->d == 1 && phys_total_el->a == 1);
 
2018
         array_pitch_tl_rows = 0;
 
2019
         array_slices = 1;
 
2020
      }
 
2021
 
 
2022
      const uint32_t total_h_tl =
 
2023
         (array_slices - 1) * array_pitch_tl_rows +
 
2024
         isl_align_div(phys_total_el->h, tile_info->logical_extent_el.height);
 
2025
 
 
2026
      size_B = (uint64_t) total_h_tl * tile_info->phys_extent_B.height *
 
2027
               row_pitch_B;
 
2028
   }
 
2029
 
 
2030
   if (ISL_GFX_VER(dev) < 9) {
 
2031
      /* From the Broadwell PRM Vol 5, Surface Layout:
 
2032
       *
 
2033
       *    "In addition to restrictions on maximum height, width, and depth,
 
2034
       *     surfaces are also restricted to a maximum size in bytes. This
 
2035
       *     maximum is 2 GB for all products and all surface types."
 
2036
       *
 
2037
       * This comment is applicable to all Pre-gfx9 platforms.
 
2038
       */
 
2039
      if (size_B > (uint64_t) 1 << 31) {
 
2040
         return notify_failure(
 
2041
            info,
 
2042
            "calculated size (%"PRIu64"B) exceeds platform limit of (1 << 31)",
 
2043
            size_B);
 
2044
      }
 
2045
   } else if (ISL_GFX_VER(dev) < 11) {
 
2046
      /* From the Skylake PRM Vol 5, Maximum Surface Size in Bytes:
 
2047
       *    "In addition to restrictions on maximum height, width, and depth,
 
2048
       *     surfaces are also restricted to a maximum size of 2^38 bytes.
 
2049
       *     All pixels within the surface must be contained within 2^38 bytes
 
2050
       *     of the base address."
 
2051
       */
 
2052
      if (size_B > (uint64_t) 1 << 38) {
 
2053
         return notify_failure(
 
2054
            info,
 
2055
            "calculated size (%"PRIu64"B) exceeds platform limit of (1 << 38)",
 
2056
            size_B);
 
2057
      }
 
2058
   } else {
 
2059
      /* gfx11+ platforms raised this limit to 2^44 bytes. */
 
2060
      if (size_B > (uint64_t) 1 << 44) {
 
2061
         return notify_failure(
 
2062
            info,
 
2063
            "calculated size (%"PRIu64"B) exceeds platform limit of (1 << 44)",
 
2064
            size_B);
 
2065
      }
 
2066
   }
 
2067
 
 
2068
   *out_size_B = size_B;
 
2069
   return true;
 
2070
}
 
2071
 
 
2072
static uint32_t
 
2073
isl_calc_base_alignment(const struct isl_device *dev,
 
2074
                        const struct isl_surf_init_info *info,
 
2075
                        const struct isl_tile_info *tile_info)
 
2076
{
 
2077
   uint32_t base_alignment_B;
 
2078
   if (tile_info->tiling == ISL_TILING_LINEAR) {
 
2079
      /* From the Broadwell PRM Vol 2d,
 
2080
       * RENDER_SURFACE_STATE::SurfaceBaseAddress:
 
2081
       *
 
2082
       *    "The Base Address for linear render target surfaces and surfaces
 
2083
       *    accessed with the typed surface read/write data port messages must
 
2084
       *    be element-size aligned, for non-YUV surface formats, or a
 
2085
       *    multiple of 2 element-sizes for YUV surface formats. Other linear
 
2086
       *    surfaces have no alignment requirements (byte alignment is
 
2087
       *    sufficient.)"
 
2088
       */
 
2089
      base_alignment_B = MAX(1, info->min_alignment_B);
 
2090
      if (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) {
 
2091
         if (isl_format_is_yuv(info->format)) {
 
2092
            base_alignment_B =
 
2093
               MAX(base_alignment_B, tile_info->format_bpb / 4);
 
2094
         } else {
 
2095
            base_alignment_B =
 
2096
               MAX(base_alignment_B, tile_info->format_bpb / 8);
 
2097
         }
 
2098
      }
 
2099
      base_alignment_B = isl_round_up_to_power_of_two(base_alignment_B);
 
2100
 
 
2101
      /* From the Skylake PRM Vol 2c, PLANE_STRIDE::Stride:
 
2102
       *
 
2103
       *     "For Linear memory, this field specifies the stride in chunks of
 
2104
       *     64 bytes (1 cache line)."
 
2105
       */
 
2106
      if (isl_surf_usage_is_display(info->usage))
 
2107
         base_alignment_B = MAX(base_alignment_B, 64);
 
2108
   } else {
 
2109
      const uint32_t tile_size_B = tile_info->phys_extent_B.width *
 
2110
                                   tile_info->phys_extent_B.height;
 
2111
      assert(isl_is_pow2(info->min_alignment_B) && isl_is_pow2(tile_size_B));
 
2112
      base_alignment_B = MAX(info->min_alignment_B, tile_size_B);
 
2113
 
 
2114
      /* The diagram in the Bspec section Memory Compression - Gfx12, shows
 
2115
       * that the CCS is indexed in 256B chunks. However, the
 
2116
       * PLANE_AUX_DIST::Auxiliary Surface Distance field is in units of 4K
 
2117
       * pages. We currently don't assign the usage field like we do for main
 
2118
       * surfaces, so just use 4K for now.
 
2119
       */
 
2120
      if (tile_info->tiling == ISL_TILING_GFX12_CCS)
 
2121
         base_alignment_B = MAX(base_alignment_B, 4096);
 
2122
 
 
2123
      /* Platforms using an aux map require that images be granularity-aligned
 
2124
       * if they're going to used with CCS. This is because the Aux
 
2125
       * translation table maps main surface addresses to aux addresses at a
 
2126
       * granularity in the main surface. Because we don't know for sure in
 
2127
       * ISL if a surface will use CCS, we have to guess based on the
 
2128
       * DISABLE_AUX usage bit. The one thing we do know is that we haven't
 
2129
       * enable CCS on linear images yet so we can avoid the extra alignment
 
2130
       * there.
 
2131
       */
 
2132
      if (dev->info->has_aux_map &&
 
2133
          !(info->usage & ISL_SURF_USAGE_DISABLE_AUX_BIT)) {
 
2134
         base_alignment_B = MAX(base_alignment_B, dev->info->verx10 >= 125 ?
 
2135
               1024 * 1024 : 64 * 1024);
 
2136
      }
 
2137
   }
 
2138
 
 
2139
   return base_alignment_B;
 
2140
}
 
2141
 
1838
2142
bool
1839
2143
isl_surf_init_s(const struct isl_device *dev,
1840
2144
                struct isl_surf *surf,
1895
2199
                           &phys_total_el, &row_pitch_B))
1896
2200
      return false;
1897
2201
 
1898
 
   uint32_t base_alignment_B;
1899
2202
   uint64_t size_B;
1900
 
   if (tiling == ISL_TILING_LINEAR) {
1901
 
      /* LINEAR tiling has no concept of intra-tile arrays */
1902
 
      assert(phys_total_el.d == 1 && phys_total_el.a == 1);
1903
 
 
1904
 
      size_B = (uint64_t) row_pitch_B * phys_total_el.h;
1905
 
 
1906
 
      /* From the Broadwell PRM Vol 2d, RENDER_SURFACE_STATE::SurfaceBaseAddress:
1907
 
       *
1908
 
       *    "The Base Address for linear render target surfaces and surfaces
1909
 
       *    accessed with the typed surface read/write data port messages must
1910
 
       *    be element-size aligned, for non-YUV surface formats, or a
1911
 
       *    multiple of 2 element-sizes for YUV surface formats. Other linear
1912
 
       *    surfaces have no alignment requirements (byte alignment is
1913
 
       *    sufficient.)"
1914
 
       */
1915
 
      base_alignment_B = MAX(1, info->min_alignment_B);
1916
 
      if (info->usage & ISL_SURF_USAGE_RENDER_TARGET_BIT) {
1917
 
         if (isl_format_is_yuv(info->format)) {
1918
 
            base_alignment_B = MAX(base_alignment_B, fmtl->bpb / 4);
1919
 
         } else {
1920
 
            base_alignment_B = MAX(base_alignment_B, fmtl->bpb / 8);
1921
 
         }
1922
 
      }
1923
 
      base_alignment_B = isl_round_up_to_power_of_two(base_alignment_B);
1924
 
 
1925
 
      /* From the Skylake PRM Vol 2c, PLANE_STRIDE::Stride:
1926
 
       *
1927
 
       *     "For Linear memory, this field specifies the stride in chunks of
1928
 
       *     64 bytes (1 cache line)."
1929
 
       */
1930
 
      if (isl_surf_usage_is_display(info->usage))
1931
 
         base_alignment_B = MAX(base_alignment_B, 64);
1932
 
   } else {
1933
 
      /* Pitches must make sense with the tiling */
1934
 
      assert(row_pitch_B % tile_info.phys_extent_B.width == 0);
1935
 
 
1936
 
      uint32_t array_slices, array_pitch_tl_rows;
1937
 
      if (phys_total_el.d > 1) {
1938
 
         assert(phys_total_el.a == 1);
1939
 
         array_pitch_tl_rows = isl_assert_div(array_pitch_el_rows,
1940
 
                                              tile_info.logical_extent_el.h);
1941
 
         array_slices = isl_align_div(phys_total_el.d,
1942
 
                                      tile_info.logical_extent_el.d);
1943
 
      } else if (phys_total_el.a > 1) {
1944
 
         assert(phys_total_el.d == 1);
1945
 
         array_pitch_tl_rows = isl_assert_div(array_pitch_el_rows,
1946
 
                                              tile_info.logical_extent_el.h);
1947
 
         array_slices = isl_align_div(phys_total_el.a,
1948
 
                                      tile_info.logical_extent_el.a);
1949
 
      } else {
1950
 
         assert(phys_total_el.d == 1 && phys_total_el.a == 1);
1951
 
         array_pitch_tl_rows = 0;
1952
 
         array_slices = 1;
1953
 
      }
1954
 
 
1955
 
      const uint32_t total_h_tl =
1956
 
         (array_slices - 1) * array_pitch_tl_rows +
1957
 
         isl_align_div(phys_total_el.h, tile_info.logical_extent_el.height);
1958
 
 
1959
 
      size_B = (uint64_t) total_h_tl * tile_info.phys_extent_B.height * row_pitch_B;
1960
 
 
1961
 
      const uint32_t tile_size_B = tile_info.phys_extent_B.width *
1962
 
                                   tile_info.phys_extent_B.height;
1963
 
      assert(isl_is_pow2(info->min_alignment_B) && isl_is_pow2(tile_size_B));
1964
 
      base_alignment_B = MAX(info->min_alignment_B, tile_size_B);
1965
 
 
1966
 
      /* The diagram in the Bspec section Memory Compression - Gfx12, shows
1967
 
       * that the CCS is indexed in 256B chunks. However, the
1968
 
       * PLANE_AUX_DIST::Auxiliary Surface Distance field is in units of 4K
1969
 
       * pages. We currently don't assign the usage field like we do for main
1970
 
       * surfaces, so just use 4K for now.
1971
 
       */
1972
 
      if (tiling == ISL_TILING_GFX12_CCS)
1973
 
         base_alignment_B = MAX(base_alignment_B, 4096);
1974
 
 
1975
 
      /* Platforms using an aux map require that images be granularity-aligned
1976
 
       * if they're going to used with CCS. This is because the Aux translation
1977
 
       * table maps main surface addresses to aux addresses at a granularity in
1978
 
       * the main surface. Because we don't know for sure in ISL if a surface
1979
 
       * will use CCS, we have to guess based on the DISABLE_AUX usage bit. The
1980
 
       * one thing we do know is that we haven't enable CCS on linear images
1981
 
       * yet so we can avoid the extra alignment there.
1982
 
       */
1983
 
      if (dev->info->has_aux_map &&
1984
 
          !(info->usage & ISL_SURF_USAGE_DISABLE_AUX_BIT)) {
1985
 
         base_alignment_B = MAX(base_alignment_B, dev->info->verx10 >= 125 ?
1986
 
               1024 * 1024 : 64 * 1024);
1987
 
      }
1988
 
   }
1989
 
 
1990
 
   if (ISL_GFX_VER(dev) < 9) {
1991
 
      /* From the Broadwell PRM Vol 5, Surface Layout:
1992
 
       *
1993
 
       *    "In addition to restrictions on maximum height, width, and depth,
1994
 
       *     surfaces are also restricted to a maximum size in bytes. This
1995
 
       *     maximum is 2 GB for all products and all surface types."
1996
 
       *
1997
 
       * This comment is applicable to all Pre-gfx9 platforms.
1998
 
       */
1999
 
      if (size_B > (uint64_t) 1 << 31)
2000
 
         return false;
2001
 
   } else if (ISL_GFX_VER(dev) < 11) {
2002
 
      /* From the Skylake PRM Vol 5, Maximum Surface Size in Bytes:
2003
 
       *    "In addition to restrictions on maximum height, width, and depth,
2004
 
       *     surfaces are also restricted to a maximum size of 2^38 bytes.
2005
 
       *     All pixels within the surface must be contained within 2^38 bytes
2006
 
       *     of the base address."
2007
 
       */
2008
 
      if (size_B > (uint64_t) 1 << 38)
2009
 
         return false;
2010
 
   } else {
2011
 
      /* gfx11+ platforms raised this limit to 2^44 bytes. */
2012
 
      if (size_B > (uint64_t) 1 << 44)
2013
 
         return false;
2014
 
   }
 
2203
   if (!isl_calc_size(dev, info, &tile_info, &phys_total_el,
 
2204
                      array_pitch_el_rows, row_pitch_B, &size_B))
 
2205
      return false;
 
2206
 
 
2207
   const uint32_t base_alignment_B =
 
2208
      isl_calc_base_alignment(dev, info, &tile_info);
2015
2209
 
2016
2210
   *surf = (struct isl_surf) {
2017
2211
      .dim = info->dim,