• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright © 2011 Red Hat All Rights Reserved.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining
5  * a copy of this software and associated documentation files (the
6  * "Software"), to deal in the Software without restriction, including
7  * without limitation the rights to use, copy, modify, merge, publish,
8  * distribute, sub license, and/or sell copies of the Software, and to
9  * permit persons to whom the Software is furnished to do so, subject to
10  * the following conditions:
11  *
12  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
14  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15  * NON-INFRINGEMENT. IN NO EVENT SHALL THE COPYRIGHT HOLDERS, AUTHORS
16  * AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
19  * USE OR OTHER DEALINGS IN THE SOFTWARE.
20  *
21  * The above copyright notice and this permission notice (including the
22  * next paragraph) shall be included in all copies or substantial portions
23  * of the Software.
24  */
25 /*
26  * Authors:
27  *      Jérôme Glisse <jglisse@redhat.com>
28  */
29 
30 #include "radeon_surface.h"
31 #include "util/compiler.h"
32 #include "util/u_math.h"
33 #include <errno.h>
34 #include <xf86drm.h>
35 #include "drm-uapi/radeon_drm.h"
36 
37 #define CIK_TILE_MODE_COLOR_2D			14
38 #define CIK_TILE_MODE_COLOR_2D_SCANOUT		10
39 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64       0
40 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128      1
41 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256      2
42 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512      3
43 #define CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE 4
44 
45 #define ALIGN(value, alignment) (((value) + alignment - 1) & ~(alignment - 1))
46 
47 /* keep this private */
48 enum radeon_family {
49     CHIP_UNKNOWN,
50     CHIP_R600,
51     CHIP_RV610,
52     CHIP_RV630,
53     CHIP_RV670,
54     CHIP_RV620,
55     CHIP_RV635,
56     CHIP_RS780,
57     CHIP_RS880,
58     CHIP_RV770,
59     CHIP_RV730,
60     CHIP_RV710,
61     CHIP_RV740,
62     CHIP_CEDAR,
63     CHIP_REDWOOD,
64     CHIP_JUNIPER,
65     CHIP_CYPRESS,
66     CHIP_HEMLOCK,
67     CHIP_PALM,
68     CHIP_SUMO,
69     CHIP_SUMO2,
70     CHIP_BARTS,
71     CHIP_TURKS,
72     CHIP_CAICOS,
73     CHIP_CAYMAN,
74     CHIP_ARUBA,
75     CHIP_TAHITI,
76     CHIP_PITCAIRN,
77     CHIP_VERDE,
78     CHIP_OLAND,
79     CHIP_HAINAN,
80     CHIP_BONAIRE,
81     CHIP_KAVERI,
82     CHIP_KABINI,
83     CHIP_HAWAII,
84     CHIP_MULLINS,
85     CHIP_LAST,
86 };
87 
88 typedef int (*hw_init_surface_t)(struct radeon_surface_manager *surf_man,
89                                  struct radeon_surface *surf);
90 typedef int (*hw_best_surface_t)(struct radeon_surface_manager *surf_man,
91                                  struct radeon_surface *surf);
92 
93 struct radeon_hw_info {
94     /* apply to r6, eg */
95     uint32_t                        group_bytes;
96     uint32_t                        num_banks;
97     uint32_t                        num_pipes;
98     /* apply to eg */
99     uint32_t                        row_size;
100     unsigned                        allow_2d;
101     /* apply to si */
102     uint32_t                        tile_mode_array[32];
103     /* apply to cik */
104     uint32_t                        macrotile_mode_array[16];
105 };
106 
107 struct radeon_surface_manager {
108     int                         fd;
109     uint32_t                    device_id;
110     struct radeon_hw_info       hw_info;
111     unsigned                    family;
112     hw_init_surface_t           surface_init;
113     hw_best_surface_t           surface_best;
114 };
115 
116 /* helper */
radeon_get_value(int fd,unsigned req,uint32_t * value)117 static int radeon_get_value(int fd, unsigned req, uint32_t *value)
118 {
119     struct drm_radeon_info info = {};
120     int r;
121 
122     *value = 0;
123     info.request = req;
124     info.value = (uintptr_t)value;
125     r = drmCommandWriteRead(fd, DRM_RADEON_INFO, &info,
126                             sizeof(struct drm_radeon_info));
127     return r;
128 }
129 
radeon_get_family(struct radeon_surface_manager * surf_man)130 static int radeon_get_family(struct radeon_surface_manager *surf_man)
131 {
132     switch (surf_man->device_id) {
133 #define CHIPSET(pci_id, name, fam) case pci_id: surf_man->family = CHIP_##fam; break;
134 #include "pci_ids/r600_pci_ids.h"
135 #undef CHIPSET
136     default:
137         return -EINVAL;
138     }
139     return 0;
140 }
141 
next_power_of_two(unsigned x)142 static unsigned next_power_of_two(unsigned x)
143 {
144    if (x <= 1)
145        return 1;
146 
147    return (1 << ((sizeof(unsigned) * 8) - __builtin_clz(x - 1)));
148 }
149 
mip_minify(unsigned size,unsigned level)150 static unsigned mip_minify(unsigned size, unsigned level)
151 {
152     unsigned val;
153 
154     val = MAX2(1, size >> level);
155     if (level > 0)
156         val = next_power_of_two(val);
157     return val;
158 }
159 
surf_minify(struct radeon_surface * surf,struct radeon_surface_level * surflevel,unsigned bpe,unsigned level,uint32_t xalign,uint32_t yalign,uint32_t zalign,uint64_t offset)160 static void surf_minify(struct radeon_surface *surf,
161                         struct radeon_surface_level *surflevel,
162                         unsigned bpe, unsigned level,
163                         uint32_t xalign, uint32_t yalign, uint32_t zalign,
164                         uint64_t offset)
165 {
166     surflevel->npix_x = mip_minify(surf->npix_x, level);
167     surflevel->npix_y = mip_minify(surf->npix_y, level);
168     surflevel->npix_z = mip_minify(surf->npix_z, level);
169     surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
170     surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
171     surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
172     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
173         !(surf->flags & RADEON_SURF_FMASK)) {
174         if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
175             surflevel->mode = RADEON_SURF_MODE_1D;
176             return;
177         }
178     }
179     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
180     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
181     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
182 
183     surflevel->offset = offset;
184     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
185     surflevel->slice_size = (uint64_t)surflevel->pitch_bytes * surflevel->nblk_y;
186 
187     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
188 }
189 
190 /* ===========================================================================
191  * r600/r700 family
192  */
r6_init_hw_info(struct radeon_surface_manager * surf_man)193 static int r6_init_hw_info(struct radeon_surface_manager *surf_man)
194 {
195     uint32_t tiling_config;
196     drmVersionPtr version;
197     int r;
198 
199     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
200                          &tiling_config);
201     if (r) {
202         return r;
203     }
204 
205     surf_man->hw_info.allow_2d = 0;
206     version = drmGetVersion(surf_man->fd);
207     if (version && version->version_minor >= 14) {
208         surf_man->hw_info.allow_2d = 1;
209     }
210     drmFreeVersion(version);
211 
212     switch ((tiling_config & 0xe) >> 1) {
213     case 0:
214         surf_man->hw_info.num_pipes = 1;
215         break;
216     case 1:
217         surf_man->hw_info.num_pipes = 2;
218         break;
219     case 2:
220         surf_man->hw_info.num_pipes = 4;
221         break;
222     case 3:
223         surf_man->hw_info.num_pipes = 8;
224         break;
225     default:
226         surf_man->hw_info.num_pipes = 8;
227         surf_man->hw_info.allow_2d = 0;
228         break;
229     }
230 
231     switch ((tiling_config & 0x30) >> 4) {
232     case 0:
233         surf_man->hw_info.num_banks = 4;
234         break;
235     case 1:
236         surf_man->hw_info.num_banks = 8;
237         break;
238     default:
239         surf_man->hw_info.num_banks = 8;
240         surf_man->hw_info.allow_2d = 0;
241         break;
242     }
243 
244     switch ((tiling_config & 0xc0) >> 6) {
245     case 0:
246         surf_man->hw_info.group_bytes = 256;
247         break;
248     case 1:
249         surf_man->hw_info.group_bytes = 512;
250         break;
251     default:
252         surf_man->hw_info.group_bytes = 256;
253         surf_man->hw_info.allow_2d = 0;
254         break;
255     }
256     return 0;
257 }
258 
r6_surface_init_linear(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,uint64_t offset,unsigned start_level)259 static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
260                                   struct radeon_surface *surf,
261                                   uint64_t offset, unsigned start_level)
262 {
263     uint32_t xalign, yalign, zalign;
264     unsigned i;
265 
266     /* compute alignment */
267     if (!start_level) {
268         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
269     }
270     /* the 32 alignment is for scanout, cb or db but to allow texture to be
271      * easily bound as such we force this alignment to all surface
272      */
273     xalign = MAX2(1, surf_man->hw_info.group_bytes / surf->bpe);
274     yalign = 1;
275     zalign = 1;
276     if (surf->flags & RADEON_SURF_SCANOUT) {
277         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
278     }
279 
280     /* build mipmap tree */
281     for (i = start_level; i <= surf->last_level; i++) {
282         surf->level[i].mode = RADEON_SURF_MODE_LINEAR;
283         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
284         /* level0 and first mipmap need to have alignment */
285         offset = surf->bo_size;
286         if (i == 0) {
287             offset = ALIGN(offset, surf->bo_alignment);
288         }
289     }
290     return 0;
291 }
292 
r6_surface_init_linear_aligned(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,uint64_t offset,unsigned start_level)293 static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
294                                           struct radeon_surface *surf,
295                                           uint64_t offset, unsigned start_level)
296 {
297     uint32_t xalign, yalign, zalign;
298     unsigned i;
299 
300     /* compute alignment */
301     if (!start_level) {
302         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
303     }
304     xalign = MAX2(64, surf_man->hw_info.group_bytes / surf->bpe);
305     yalign = 1;
306     zalign = 1;
307 
308     /* build mipmap tree */
309     for (i = start_level; i <= surf->last_level; i++) {
310         surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
311         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
312         /* level0 and first mipmap need to have alignment */
313         offset = surf->bo_size;
314         if (i == 0) {
315             offset = ALIGN(offset, surf->bo_alignment);
316         }
317     }
318     return 0;
319 }
320 
r6_surface_init_1d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,uint64_t offset,unsigned start_level)321 static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
322                               struct radeon_surface *surf,
323                               uint64_t offset, unsigned start_level)
324 {
325     uint32_t xalign, yalign, zalign, tilew;
326     unsigned i;
327 
328     /* compute alignment */
329     tilew = 8;
330     xalign = surf_man->hw_info.group_bytes / (tilew * surf->bpe * surf->nsamples);
331     xalign = MAX2(tilew, xalign);
332     yalign = tilew;
333     zalign = 1;
334     if (surf->flags & RADEON_SURF_SCANOUT) {
335         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
336     }
337     if (!start_level) {
338         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
339     }
340 
341     /* build mipmap tree */
342     for (i = start_level; i <= surf->last_level; i++) {
343         surf->level[i].mode = RADEON_SURF_MODE_1D;
344         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
345         /* level0 and first mipmap need to have alignment */
346         offset = surf->bo_size;
347         if (i == 0) {
348             offset = ALIGN(offset, surf->bo_alignment);
349         }
350     }
351     return 0;
352 }
353 
r6_surface_init_2d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,uint64_t offset,unsigned start_level)354 static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
355                               struct radeon_surface *surf,
356                               uint64_t offset, unsigned start_level)
357 {
358     uint32_t xalign, yalign, zalign, tilew;
359     unsigned i;
360 
361     /* compute alignment */
362     tilew = 8;
363     zalign = 1;
364     xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
365              (tilew * surf->bpe * surf->nsamples);
366     xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
367     if (surf->flags & RADEON_SURF_FMASK)
368 	xalign = MAX2(128, xalign);
369     yalign = tilew * surf_man->hw_info.num_pipes;
370     if (surf->flags & RADEON_SURF_SCANOUT) {
371         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
372     }
373     if (!start_level) {
374         surf->bo_alignment =
375             MAX2(surf_man->hw_info.num_pipes *
376                  surf_man->hw_info.num_banks *
377                  surf->nsamples * surf->bpe * 64,
378                  xalign * yalign * surf->nsamples * surf->bpe);
379     }
380 
381     /* build mipmap tree */
382     for (i = start_level; i <= surf->last_level; i++) {
383         surf->level[i].mode = RADEON_SURF_MODE_2D;
384         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
385         if (surf->level[i].mode == RADEON_SURF_MODE_1D) {
386             return r6_surface_init_1d(surf_man, surf, offset, i);
387         }
388         /* level0 and first mipmap need to have alignment */
389         offset = surf->bo_size;
390         if (i == 0) {
391             offset = ALIGN(offset, surf->bo_alignment);
392         }
393     }
394     return 0;
395 }
396 
r6_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)397 static int r6_surface_init(struct radeon_surface_manager *surf_man,
398                            struct radeon_surface *surf)
399 {
400     unsigned mode;
401     int r;
402 
403     /* MSAA surfaces support the 2D mode only. */
404     if (surf->nsamples > 1) {
405         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
406         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
407     }
408 
409     /* tiling mode */
410     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
411 
412     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
413         /* zbuffer only support 1D or 2D tiled surface */
414         switch (mode) {
415         case RADEON_SURF_MODE_1D:
416         case RADEON_SURF_MODE_2D:
417             break;
418         default:
419             mode = RADEON_SURF_MODE_1D;
420             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
421             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
422             break;
423         }
424     }
425 
426     /* force 1d on kernel that can't do 2d */
427     if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
428         if (surf->nsamples > 1) {
429             fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
430             return -EFAULT;
431         }
432         mode = RADEON_SURF_MODE_1D;
433         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
434         surf->flags |= RADEON_SURF_SET(mode, MODE);
435     }
436 
437     /* check surface dimension */
438     if (surf->npix_x > 8192 || surf->npix_y > 8192 || surf->npix_z > 8192) {
439         return -EINVAL;
440     }
441 
442     /* check mipmap last_level */
443     if (surf->last_level > 14) {
444         return -EINVAL;
445     }
446 
447     /* check tiling mode */
448     switch (mode) {
449     case RADEON_SURF_MODE_LINEAR:
450         r = r6_surface_init_linear(surf_man, surf, 0, 0);
451         break;
452     case RADEON_SURF_MODE_LINEAR_ALIGNED:
453         r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
454         break;
455     case RADEON_SURF_MODE_1D:
456         r = r6_surface_init_1d(surf_man, surf, 0, 0);
457         break;
458     case RADEON_SURF_MODE_2D:
459         r = r6_surface_init_2d(surf_man, surf, 0, 0);
460         break;
461     default:
462         return -EINVAL;
463     }
464     return r;
465 }
466 
r6_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)467 static int r6_surface_best(struct radeon_surface_manager *surf_man,
468                            struct radeon_surface *surf)
469 {
470     /* no value to optimize for r6xx/r7xx */
471     return 0;
472 }
473 
474 
475 /* ===========================================================================
476  * evergreen family
477  */
eg_init_hw_info(struct radeon_surface_manager * surf_man)478 static int eg_init_hw_info(struct radeon_surface_manager *surf_man)
479 {
480     uint32_t tiling_config;
481     drmVersionPtr version;
482     int r;
483 
484     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
485                          &tiling_config);
486     if (r) {
487         return r;
488     }
489 
490     surf_man->hw_info.allow_2d = 0;
491     version = drmGetVersion(surf_man->fd);
492     if (version && version->version_minor >= 16) {
493         surf_man->hw_info.allow_2d = 1;
494     }
495     drmFreeVersion(version);
496 
497     switch (tiling_config & 0xf) {
498     case 0:
499         surf_man->hw_info.num_pipes = 1;
500         break;
501     case 1:
502         surf_man->hw_info.num_pipes = 2;
503         break;
504     case 2:
505         surf_man->hw_info.num_pipes = 4;
506         break;
507     case 3:
508         surf_man->hw_info.num_pipes = 8;
509         break;
510     default:
511         surf_man->hw_info.num_pipes = 8;
512         surf_man->hw_info.allow_2d = 0;
513         break;
514     }
515 
516     switch ((tiling_config & 0xf0) >> 4) {
517     case 0:
518         surf_man->hw_info.num_banks = 4;
519         break;
520     case 1:
521         surf_man->hw_info.num_banks = 8;
522         break;
523     case 2:
524         surf_man->hw_info.num_banks = 16;
525         break;
526     default:
527         surf_man->hw_info.num_banks = 8;
528         surf_man->hw_info.allow_2d = 0;
529         break;
530     }
531 
532     switch ((tiling_config & 0xf00) >> 8) {
533     case 0:
534         surf_man->hw_info.group_bytes = 256;
535         break;
536     case 1:
537         surf_man->hw_info.group_bytes = 512;
538         break;
539     default:
540         surf_man->hw_info.group_bytes = 256;
541         surf_man->hw_info.allow_2d = 0;
542         break;
543     }
544 
545     switch ((tiling_config & 0xf000) >> 12) {
546     case 0:
547         surf_man->hw_info.row_size = 1024;
548         break;
549     case 1:
550         surf_man->hw_info.row_size = 2048;
551         break;
552     case 2:
553         surf_man->hw_info.row_size = 4096;
554         break;
555     default:
556         surf_man->hw_info.row_size = 4096;
557         surf_man->hw_info.allow_2d = 0;
558         break;
559     }
560     return 0;
561 }
562 
eg_surf_minify(struct radeon_surface * surf,struct radeon_surface_level * surflevel,unsigned bpe,unsigned level,unsigned slice_pt,unsigned mtilew,unsigned mtileh,unsigned mtileb,uint64_t offset)563 static void eg_surf_minify(struct radeon_surface *surf,
564                            struct radeon_surface_level *surflevel,
565                            unsigned bpe,
566                            unsigned level,
567                            unsigned slice_pt,
568                            unsigned mtilew,
569                            unsigned mtileh,
570                            unsigned mtileb,
571                            uint64_t offset)
572 {
573     unsigned mtile_pr, mtile_ps;
574 
575     surflevel->npix_x = mip_minify(surf->npix_x, level);
576     surflevel->npix_y = mip_minify(surf->npix_y, level);
577     surflevel->npix_z = mip_minify(surf->npix_z, level);
578     surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
579     surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
580     surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
581     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
582         !(surf->flags & RADEON_SURF_FMASK)) {
583         if (surflevel->nblk_x < mtilew || surflevel->nblk_y < mtileh) {
584             surflevel->mode = RADEON_SURF_MODE_1D;
585             return;
586         }
587     }
588     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, mtilew);
589     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, mtileh);
590     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, 1);
591 
592     /* macro tile per row */
593     mtile_pr = surflevel->nblk_x / mtilew;
594     /* macro tile per slice */
595     mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
596 
597     surflevel->offset = offset;
598     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
599     surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
600 
601     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
602 }
603 
eg_surface_init_1d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned align_maginify,uint64_t offset,unsigned start_level)604 static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
605                               struct radeon_surface *surf,
606                               struct radeon_surface_level *level,
607                               unsigned bpe,
608                               unsigned align_maginify,
609                               uint64_t offset, unsigned start_level)
610 {
611     uint32_t xalign, yalign, zalign, tilew;
612     unsigned i;
613 
614     /* compute alignment */
615     tilew = 8;
616     xalign = surf_man->hw_info.group_bytes / (tilew * bpe * surf->nsamples);
617     xalign = MAX2(tilew, xalign * align_maginify);
618     yalign = tilew;
619     zalign = 1;
620     if (surf->flags & RADEON_SURF_SCANOUT) {
621         xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
622     }
623 
624     if (!start_level) {
625         unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
626         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
627 
628         if (offset) {
629             offset = ALIGN(offset, alignment);
630         }
631     }
632 
633     /* build mipmap tree */
634     for (i = start_level; i <= surf->last_level; i++) {
635         level[i].mode = RADEON_SURF_MODE_1D;
636         surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
637         /* level0 and first mipmap need to have alignment */
638         offset = surf->bo_size;
639         if (i == 0) {
640             offset = ALIGN(offset, surf->bo_alignment);
641         }
642     }
643     return 0;
644 }
645 
eg_surface_init_2d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned align_magnify,unsigned tile_split,uint64_t offset,unsigned start_level)646 static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
647                               struct radeon_surface *surf,
648                               struct radeon_surface_level *level,
649                               unsigned bpe, unsigned align_magnify,
650                               unsigned tile_split,
651                               uint64_t offset, unsigned start_level)
652 {
653     unsigned tilew, tileh, tileb;
654     unsigned mtilew, mtileh, mtileb;
655     unsigned slice_pt;
656     unsigned i;
657 
658     /* compute tile values */
659     tilew = 8;
660     tileh = 8;
661     tileb = tilew * tileh * bpe * surf->nsamples;
662     /* slices per tile */
663     slice_pt = 1;
664     if (tileb > tile_split && tile_split) {
665         slice_pt = tileb / tile_split;
666     }
667     tileb = tileb / slice_pt;
668 
669     /* macro tile width & height */
670     mtilew = (tilew * surf->bankw * surf_man->hw_info.num_pipes) * surf->mtilea;
671     mtileh = (tileh * surf->bankh * surf_man->hw_info.num_banks) / surf->mtilea;
672     /* macro tile bytes */
673     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
674 
675     if (!start_level) {
676         unsigned alignment = MAX2(256, mtileb);
677         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
678 
679         if (offset) {
680             offset = ALIGN(offset, alignment);
681         }
682     }
683 
684     /* build mipmap tree */
685     for (i = start_level; i <= surf->last_level; i++) {
686         level[i].mode = RADEON_SURF_MODE_2D;
687         eg_surf_minify(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, mtileb, offset);
688         if (level[i].mode == RADEON_SURF_MODE_1D) {
689             return eg_surface_init_1d(surf_man, surf, level, bpe, align_magnify, offset, i);
690         }
691         /* level0 and first mipmap need to have alignment */
692         offset = surf->bo_size;
693         if (i == 0) {
694             offset = ALIGN(offset, surf->bo_alignment);
695         }
696     }
697     return 0;
698 }
699 
eg_surface_sanity(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned mode)700 static int eg_surface_sanity(struct radeon_surface_manager *surf_man,
701                              struct radeon_surface *surf,
702                              unsigned mode)
703 {
704     unsigned tileb;
705 
706     /* check surface dimension */
707     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
708         return -EINVAL;
709     }
710 
711     /* check mipmap last_level */
712     if (surf->last_level > 15) {
713         return -EINVAL;
714     }
715 
716     /* force 1d on kernel that can't do 2d */
717     if (!surf_man->hw_info.allow_2d && mode > RADEON_SURF_MODE_1D) {
718         if (surf->nsamples > 1) {
719             fprintf(stderr, "radeon: Cannot use 2D tiling for an MSAA surface (%i).\n", __LINE__);
720             return -EFAULT;
721         }
722         mode = RADEON_SURF_MODE_1D;
723         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
724         surf->flags |= RADEON_SURF_SET(mode, MODE);
725     }
726 
727     /* check tile split */
728     if (mode == RADEON_SURF_MODE_2D) {
729         switch (surf->tile_split) {
730         case 64:
731         case 128:
732         case 256:
733         case 512:
734         case 1024:
735         case 2048:
736         case 4096:
737             break;
738         default:
739             return -EINVAL;
740         }
741         switch (surf->mtilea) {
742         case 1:
743         case 2:
744         case 4:
745         case 8:
746             break;
747         default:
748             return -EINVAL;
749         }
750         /* check aspect ratio */
751         if (surf_man->hw_info.num_banks < surf->mtilea) {
752             return -EINVAL;
753         }
754         /* check bank width */
755         switch (surf->bankw) {
756         case 1:
757         case 2:
758         case 4:
759         case 8:
760             break;
761         default:
762             return -EINVAL;
763         }
764         /* check bank height */
765         switch (surf->bankh) {
766         case 1:
767         case 2:
768         case 4:
769         case 8:
770             break;
771         default:
772             return -EINVAL;
773         }
774         tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
775         if ((tileb * surf->bankh * surf->bankw) < surf_man->hw_info.group_bytes) {
776             return -EINVAL;
777         }
778     }
779 
780     return 0;
781 }
782 
eg_surface_init_1d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)783 static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
784                                        struct radeon_surface *surf)
785 {
786     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
787     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
788     /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
789     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
790     struct radeon_surface_level *stencil_level =
791           (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
792 
793     /* With certain sizes the depth and the stencil texture end up being of
794      * different block sizes which later results in wrong rendering for npot
795      * textures. Inflate the alignment requirement for the depth surface by
796      * its bpe in order to make it allocate a texture that is of the same
797      * block size like the stencil texture (The rules used here are deducted by
798      * running dEQP tests and piglits) */
799     int magnify_align = is_depth_stencil &&
800                         ((surf->npix_x < 32)  ||
801                          (!util_is_power_of_two_or_zero(surf->npix_x) &&
802                            !surf->last_level));
803 
804     r = eg_surface_init_1d(surf_man, surf, surf->level, surf->bpe,
805                            magnify_align ? surf->bpe : 1, 0, 0);
806     if (r)
807         return r;
808 
809     if (is_depth_stencil) {
810        r = eg_surface_init_1d(surf_man, surf, stencil_level, 1, 1,
811                               surf->bo_size, 0);
812        surf->stencil_offset = stencil_level[0].offset;
813     }
814     return r;
815 }
816 
eg_surface_init_2d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)817 static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
818                                        struct radeon_surface *surf)
819 {
820     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
821     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
822     /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
823     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
824     struct radeon_surface_level *stencil_level =
825         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
826 
827     /* Inflate the alignment requirement for npot textures to insure that
828      * stencil and depth texture have the same block size. Use this only in
829      * the 1d code path that uses the non-specific minify. */
830     int magnify_align = is_depth_stencil &&
831                         ((surf->npix_x < 32)  ||
832                          (!util_is_power_of_two_or_zero(surf->npix_x) &&
833                           !surf->last_level));
834 
835     r = eg_surface_init_2d(surf_man, surf, surf->level, surf->bpe,
836                            magnify_align ? surf->bpe : 1,
837                            surf->tile_split, 0, 0);
838     if (r)
839         return r;
840 
841     if (is_depth_stencil) {
842        r = eg_surface_init_2d(surf_man, surf, stencil_level, 1, 1,
843                               surf->stencil_tile_split, surf->bo_size, 0);
844        surf->stencil_offset = stencil_level[0].offset;
845 
846     }
847     return r;
848 }
849 
eg_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)850 static int eg_surface_init(struct radeon_surface_manager *surf_man,
851                            struct radeon_surface *surf)
852 {
853     unsigned mode;
854     int r;
855 
856     /* MSAA surfaces support the 2D mode only. */
857     if (surf->nsamples > 1) {
858         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
859         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
860     }
861 
862     /* tiling mode */
863     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
864 
865     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
866         /* zbuffer only support 1D or 2D tiled surface */
867         switch (mode) {
868         case RADEON_SURF_MODE_1D:
869         case RADEON_SURF_MODE_2D:
870             break;
871         default:
872             mode = RADEON_SURF_MODE_1D;
873             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
874             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
875             break;
876         }
877     }
878 
879     r = eg_surface_sanity(surf_man, surf, mode);
880     if (r) {
881         return r;
882     }
883 
884     surf->stencil_offset = 0;
885     surf->bo_alignment = 0;
886 
887     /* check tiling mode */
888     switch (mode) {
889     case RADEON_SURF_MODE_LINEAR:
890         r = r6_surface_init_linear(surf_man, surf, 0, 0);
891         break;
892     case RADEON_SURF_MODE_LINEAR_ALIGNED:
893         r = r6_surface_init_linear_aligned(surf_man, surf, 0, 0);
894         break;
895     case RADEON_SURF_MODE_1D:
896         r = eg_surface_init_1d_miptrees(surf_man, surf);
897         break;
898     case RADEON_SURF_MODE_2D:
899         r = eg_surface_init_2d_miptrees(surf_man, surf);
900         break;
901     default:
902         return -EINVAL;
903     }
904     return r;
905 }
906 
log2_int(unsigned x)907 static unsigned log2_int(unsigned x)
908 {
909     unsigned l;
910 
911     if (x < 2) {
912         return 0;
913     }
914     for (l = 2; ; l++) {
915         if ((unsigned)(1 << l) > x) {
916             return l - 1;
917         }
918     }
919     return 0;
920 }
921 
922 /* compute best tile_split, bankw, bankh, mtilea
923  * depending on surface
924  */
eg_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)925 static int eg_surface_best(struct radeon_surface_manager *surf_man,
926                            struct radeon_surface *surf)
927 {
928     unsigned mode, tileb, h_over_w;
929     int r;
930 
931     /* tiling mode */
932     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
933 
934     /* set some default value to avoid sanity check choking on them */
935     surf->tile_split = 1024;
936     surf->bankw = 1;
937     surf->bankh = 1;
938     surf->mtilea = surf_man->hw_info.num_banks;
939     tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
940     for (; surf->bankh <= 8; surf->bankh *= 2) {
941         if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
942             break;
943         }
944     }
945     if (surf->mtilea > 8) {
946         surf->mtilea = 8;
947     }
948 
949     r = eg_surface_sanity(surf_man, surf, mode);
950     if (r) {
951         return r;
952     }
953 
954     if (mode != RADEON_SURF_MODE_2D) {
955         /* nothing to do for non 2D tiled surface */
956         return 0;
957     }
958 
959     /* Tweak TILE_SPLIT for performance here. */
960     if (surf->nsamples > 1) {
961         if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
962             switch (surf->nsamples) {
963             case 2:
964                 surf->tile_split = 128;
965                 break;
966             case 4:
967                 surf->tile_split = 128;
968                 break;
969             case 8:
970                 surf->tile_split = 256;
971                 break;
972             case 16: /* cayman only */
973                 surf->tile_split = 512;
974                 break;
975             default:
976                 fprintf(stderr, "radeon: Wrong number of samples %i (%i)\n",
977                         surf->nsamples, __LINE__);
978                 return -EINVAL;
979             }
980             surf->stencil_tile_split = 64;
981         } else {
982             /* tile split must be >= 256 for colorbuffer surfaces,
983              * SAMPLE_SPLIT = tile_split / (bpe * 64), the optimal value is 2
984              */
985             surf->tile_split = MAX2(2 * surf->bpe * 64, 256);
986             if (surf->tile_split > 4096)
987                 surf->tile_split = 4096;
988         }
989     } else {
990         /* set tile split to row size */
991         surf->tile_split = surf_man->hw_info.row_size;
992         surf->stencil_tile_split = surf_man->hw_info.row_size / 2;
993     }
994 
995     /* bankw or bankh greater than 1 increase alignment requirement, not
996      * sure if it's worth using smaller bankw & bankh to stick with 2D
997      * tiling on small surface rather than falling back to 1D tiling.
998      * Use recommended value based on tile size for now.
999      *
1000      * fmask buffer has different optimal value figure them out once we
1001      * use it.
1002      */
1003     if (surf->flags & RADEON_SURF_SBUFFER) {
1004         /* assume 1 bytes for stencil, we optimize for stencil as stencil
1005          * and depth shares surface values
1006          */
1007         tileb = MIN2(surf->tile_split, 64 * surf->nsamples);
1008     } else {
1009         tileb = MIN2(surf->tile_split, 64 * surf->bpe * surf->nsamples);
1010     }
1011 
1012     /* use bankw of 1 to minimize width alignment, might be interesting to
1013      * increase it for large surface
1014      */
1015     surf->bankw = 1;
1016     switch (tileb) {
1017     case 64:
1018         surf->bankh = 4;
1019         break;
1020     case 128:
1021     case 256:
1022         surf->bankh = 2;
1023         break;
1024     default:
1025         surf->bankh = 1;
1026         break;
1027     }
1028     /* double check the constraint */
1029     for (; surf->bankh <= 8; surf->bankh *= 2) {
1030         if ((tileb * surf->bankh * surf->bankw) >= surf_man->hw_info.group_bytes) {
1031             break;
1032         }
1033     }
1034 
1035     h_over_w = (((surf->bankh * surf_man->hw_info.num_banks) << 16) /
1036                 (surf->bankw * surf_man->hw_info.num_pipes)) >> 16;
1037     surf->mtilea = 1 << (log2_int(h_over_w) >> 1);
1038 
1039     return 0;
1040 }
1041 
1042 
1043 /* ===========================================================================
1044  * Southern Islands family
1045  */
1046 #define SI__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
1047 #define     SI__PIPE_CONFIG__ADDR_SURF_P2               0
1048 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
1049 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
1050 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
1051 #define     SI__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
1052 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
1053 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
1054 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
1055 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
1056 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
1057 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
1058 #define     SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
1059 #define SI__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
1060 #define     SI__TILE_SPLIT__64B                         0
1061 #define     SI__TILE_SPLIT__128B                        1
1062 #define     SI__TILE_SPLIT__256B                        2
1063 #define     SI__TILE_SPLIT__512B                        3
1064 #define     SI__TILE_SPLIT__1024B                       4
1065 #define     SI__TILE_SPLIT__2048B                       5
1066 #define     SI__TILE_SPLIT__4096B                       6
1067 #define SI__GB_TILE_MODE__BANK_WIDTH(x)         (((x) >> 14) & 0x3)
1068 #define     SI__BANK_WIDTH__1                           0
1069 #define     SI__BANK_WIDTH__2                           1
1070 #define     SI__BANK_WIDTH__4                           2
1071 #define     SI__BANK_WIDTH__8                           3
1072 #define SI__GB_TILE_MODE__BANK_HEIGHT(x)        (((x) >> 16) & 0x3)
1073 #define     SI__BANK_HEIGHT__1                          0
1074 #define     SI__BANK_HEIGHT__2                          1
1075 #define     SI__BANK_HEIGHT__4                          2
1076 #define     SI__BANK_HEIGHT__8                          3
1077 #define SI__GB_TILE_MODE__MACRO_TILE_ASPECT(x)  (((x) >> 18) & 0x3)
1078 #define     SI__MACRO_TILE_ASPECT__1                    0
1079 #define     SI__MACRO_TILE_ASPECT__2                    1
1080 #define     SI__MACRO_TILE_ASPECT__4                    2
1081 #define     SI__MACRO_TILE_ASPECT__8                    3
1082 #define SI__GB_TILE_MODE__NUM_BANKS(x)          (((x) >> 20) & 0x3)
1083 #define     SI__NUM_BANKS__2_BANK                       0
1084 #define     SI__NUM_BANKS__4_BANK                       1
1085 #define     SI__NUM_BANKS__8_BANK                       2
1086 #define     SI__NUM_BANKS__16_BANK                      3
1087 
1088 
si_gb_tile_mode(uint32_t gb_tile_mode,unsigned * num_pipes,unsigned * num_banks,uint32_t * macro_tile_aspect,uint32_t * bank_w,uint32_t * bank_h,uint32_t * tile_split)1089 static void si_gb_tile_mode(uint32_t gb_tile_mode,
1090                             unsigned *num_pipes,
1091                             unsigned *num_banks,
1092                             uint32_t *macro_tile_aspect,
1093                             uint32_t *bank_w,
1094                             uint32_t *bank_h,
1095                             uint32_t *tile_split)
1096 {
1097     if (num_pipes) {
1098         switch (SI__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1099         case SI__PIPE_CONFIG__ADDR_SURF_P2:
1100         default:
1101             *num_pipes = 2;
1102             break;
1103         case SI__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1104         case SI__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1105         case SI__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1106         case SI__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1107             *num_pipes = 4;
1108             break;
1109         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1110         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1111         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1112         case SI__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1113         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1114         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1115         case SI__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1116             *num_pipes = 8;
1117             break;
1118         }
1119     }
1120     if (num_banks) {
1121         switch (SI__GB_TILE_MODE__NUM_BANKS(gb_tile_mode)) {
1122         default:
1123         case SI__NUM_BANKS__2_BANK:
1124             *num_banks = 2;
1125             break;
1126         case SI__NUM_BANKS__4_BANK:
1127             *num_banks = 4;
1128             break;
1129         case SI__NUM_BANKS__8_BANK:
1130             *num_banks = 8;
1131             break;
1132         case SI__NUM_BANKS__16_BANK:
1133             *num_banks = 16;
1134             break;
1135         }
1136     }
1137     if (macro_tile_aspect) {
1138         switch (SI__GB_TILE_MODE__MACRO_TILE_ASPECT(gb_tile_mode)) {
1139         default:
1140         case SI__MACRO_TILE_ASPECT__1:
1141             *macro_tile_aspect = 1;
1142             break;
1143         case SI__MACRO_TILE_ASPECT__2:
1144             *macro_tile_aspect = 2;
1145             break;
1146         case SI__MACRO_TILE_ASPECT__4:
1147             *macro_tile_aspect = 4;
1148             break;
1149         case SI__MACRO_TILE_ASPECT__8:
1150             *macro_tile_aspect = 8;
1151             break;
1152         }
1153     }
1154     if (bank_w) {
1155         switch (SI__GB_TILE_MODE__BANK_WIDTH(gb_tile_mode)) {
1156         default:
1157         case SI__BANK_WIDTH__1:
1158             *bank_w = 1;
1159             break;
1160         case SI__BANK_WIDTH__2:
1161             *bank_w = 2;
1162             break;
1163         case SI__BANK_WIDTH__4:
1164             *bank_w = 4;
1165             break;
1166         case SI__BANK_WIDTH__8:
1167             *bank_w = 8;
1168             break;
1169         }
1170     }
1171     if (bank_h) {
1172         switch (SI__GB_TILE_MODE__BANK_HEIGHT(gb_tile_mode)) {
1173         default:
1174         case SI__BANK_HEIGHT__1:
1175             *bank_h = 1;
1176             break;
1177         case SI__BANK_HEIGHT__2:
1178             *bank_h = 2;
1179             break;
1180         case SI__BANK_HEIGHT__4:
1181             *bank_h = 4;
1182             break;
1183         case SI__BANK_HEIGHT__8:
1184             *bank_h = 8;
1185             break;
1186         }
1187     }
1188     if (tile_split) {
1189         switch (SI__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1190         default:
1191         case SI__TILE_SPLIT__64B:
1192             *tile_split = 64;
1193             break;
1194         case SI__TILE_SPLIT__128B:
1195             *tile_split = 128;
1196             break;
1197         case SI__TILE_SPLIT__256B:
1198             *tile_split = 256;
1199             break;
1200         case SI__TILE_SPLIT__512B:
1201             *tile_split = 512;
1202             break;
1203         case SI__TILE_SPLIT__1024B:
1204             *tile_split = 1024;
1205             break;
1206         case SI__TILE_SPLIT__2048B:
1207             *tile_split = 2048;
1208             break;
1209         case SI__TILE_SPLIT__4096B:
1210             *tile_split = 4096;
1211             break;
1212         }
1213     }
1214 }
1215 
si_init_hw_info(struct radeon_surface_manager * surf_man)1216 static int si_init_hw_info(struct radeon_surface_manager *surf_man)
1217 {
1218     uint32_t tiling_config;
1219     drmVersionPtr version;
1220     int r;
1221 
1222     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
1223                          &tiling_config);
1224     if (r) {
1225         return r;
1226     }
1227 
1228     surf_man->hw_info.allow_2d = 0;
1229     version = drmGetVersion(surf_man->fd);
1230     if (version && version->version_minor >= 33) {
1231         if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array)) {
1232             surf_man->hw_info.allow_2d = 1;
1233         }
1234     }
1235     drmFreeVersion(version);
1236 
1237     switch (tiling_config & 0xf) {
1238     case 0:
1239         surf_man->hw_info.num_pipes = 1;
1240         break;
1241     case 1:
1242         surf_man->hw_info.num_pipes = 2;
1243         break;
1244     case 2:
1245         surf_man->hw_info.num_pipes = 4;
1246         break;
1247     case 3:
1248         surf_man->hw_info.num_pipes = 8;
1249         break;
1250     default:
1251         surf_man->hw_info.num_pipes = 8;
1252         surf_man->hw_info.allow_2d = 0;
1253         break;
1254     }
1255 
1256     switch ((tiling_config & 0xf0) >> 4) {
1257     case 0:
1258         surf_man->hw_info.num_banks = 4;
1259         break;
1260     case 1:
1261         surf_man->hw_info.num_banks = 8;
1262         break;
1263     case 2:
1264         surf_man->hw_info.num_banks = 16;
1265         break;
1266     default:
1267         surf_man->hw_info.num_banks = 8;
1268         surf_man->hw_info.allow_2d = 0;
1269         break;
1270     }
1271 
1272     switch ((tiling_config & 0xf00) >> 8) {
1273     case 0:
1274         surf_man->hw_info.group_bytes = 256;
1275         break;
1276     case 1:
1277         surf_man->hw_info.group_bytes = 512;
1278         break;
1279     default:
1280         surf_man->hw_info.group_bytes = 256;
1281         surf_man->hw_info.allow_2d = 0;
1282         break;
1283     }
1284 
1285     switch ((tiling_config & 0xf000) >> 12) {
1286     case 0:
1287         surf_man->hw_info.row_size = 1024;
1288         break;
1289     case 1:
1290         surf_man->hw_info.row_size = 2048;
1291         break;
1292     case 2:
1293         surf_man->hw_info.row_size = 4096;
1294         break;
1295     default:
1296         surf_man->hw_info.row_size = 4096;
1297         surf_man->hw_info.allow_2d = 0;
1298         break;
1299     }
1300     return 0;
1301 }
1302 
si_surface_sanity(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned mode,unsigned * tile_mode,unsigned * stencil_tile_mode)1303 static int si_surface_sanity(struct radeon_surface_manager *surf_man,
1304                              struct radeon_surface *surf,
1305                              unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
1306 {
1307     uint32_t gb_tile_mode;
1308 
1309     /* check surface dimension */
1310     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
1311         return -EINVAL;
1312     }
1313 
1314     /* check mipmap last_level */
1315     if (surf->last_level > 15) {
1316         return -EINVAL;
1317     }
1318 
1319     /* force 1d on kernel that can't do 2d */
1320     if (mode > RADEON_SURF_MODE_1D &&
1321         (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
1322         if (surf->nsamples > 1) {
1323             fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
1324             return -EFAULT;
1325         }
1326         mode = RADEON_SURF_MODE_1D;
1327         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1328         surf->flags |= RADEON_SURF_SET(mode, MODE);
1329     }
1330 
1331     if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
1332         return -EINVAL;
1333     }
1334 
1335     if (!surf->tile_split) {
1336         /* default value */
1337         surf->mtilea = 1;
1338         surf->bankw = 1;
1339         surf->bankh = 1;
1340         surf->tile_split = 64;
1341         surf->stencil_tile_split = 64;
1342     }
1343 
1344     switch (mode) {
1345     case RADEON_SURF_MODE_2D:
1346         if (surf->flags & RADEON_SURF_SBUFFER) {
1347             switch (surf->nsamples) {
1348             case 1:
1349                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1350                 break;
1351             case 2:
1352                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1353                 break;
1354             case 4:
1355                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1356                 break;
1357             case 8:
1358                 *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1359                 break;
1360             default:
1361                 return -EINVAL;
1362             }
1363             /* retrieve tiling mode value */
1364             gb_tile_mode = surf_man->hw_info.tile_mode_array[*stencil_tile_mode];
1365             si_gb_tile_mode(gb_tile_mode, NULL, NULL, NULL, NULL, NULL, &surf->stencil_tile_split);
1366         }
1367         if (surf->flags & RADEON_SURF_ZBUFFER) {
1368             switch (surf->nsamples) {
1369             case 1:
1370                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D;
1371                 break;
1372             case 2:
1373                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_2AA;
1374                 break;
1375             case 4:
1376                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_4AA;
1377                 break;
1378             case 8:
1379                 *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_2D_8AA;
1380                 break;
1381             default:
1382                 return -EINVAL;
1383             }
1384         } else if (surf->flags & RADEON_SURF_SCANOUT) {
1385             switch (surf->bpe) {
1386             case 2:
1387                 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP;
1388                 break;
1389             case 4:
1390                 *tile_mode = SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP;
1391                 break;
1392             default:
1393                 return -EINVAL;
1394             }
1395         } else {
1396             switch (surf->bpe) {
1397             case 1:
1398                 *tile_mode = SI_TILE_MODE_COLOR_2D_8BPP;
1399                 break;
1400             case 2:
1401                 *tile_mode = SI_TILE_MODE_COLOR_2D_16BPP;
1402                 break;
1403             case 4:
1404                 *tile_mode = SI_TILE_MODE_COLOR_2D_32BPP;
1405                 break;
1406             case 8:
1407             case 16:
1408                 *tile_mode = SI_TILE_MODE_COLOR_2D_64BPP;
1409                 break;
1410             default:
1411                 return -EINVAL;
1412             }
1413         }
1414         /* retrieve tiling mode value */
1415         gb_tile_mode = surf_man->hw_info.tile_mode_array[*tile_mode];
1416         si_gb_tile_mode(gb_tile_mode, NULL, NULL, &surf->mtilea, &surf->bankw, &surf->bankh, &surf->tile_split);
1417         break;
1418     case RADEON_SURF_MODE_1D:
1419         if (surf->flags & RADEON_SURF_SBUFFER) {
1420             *stencil_tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1421         }
1422         if (surf->flags & RADEON_SURF_ZBUFFER) {
1423             *tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1424         } else if (surf->flags & RADEON_SURF_SCANOUT) {
1425             *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1426         } else {
1427             *tile_mode = SI_TILE_MODE_COLOR_1D;
1428         }
1429         break;
1430     case RADEON_SURF_MODE_LINEAR_ALIGNED:
1431     default:
1432         *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
1433     }
1434 
1435     return 0;
1436 }
1437 
si_surf_minify(struct radeon_surface * surf,struct radeon_surface_level * surflevel,unsigned bpe,unsigned level,uint32_t xalign,uint32_t yalign,uint32_t zalign,uint32_t slice_align,uint64_t offset)1438 static void si_surf_minify(struct radeon_surface *surf,
1439                            struct radeon_surface_level *surflevel,
1440                            unsigned bpe, unsigned level,
1441                            uint32_t xalign, uint32_t yalign, uint32_t zalign,
1442                            uint32_t slice_align, uint64_t offset)
1443 {
1444     if (level == 0) {
1445         surflevel->npix_x = surf->npix_x;
1446     } else {
1447         surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1448     }
1449     surflevel->npix_y = mip_minify(surf->npix_y, level);
1450     surflevel->npix_z = mip_minify(surf->npix_z, level);
1451 
1452     if (level == 0 && surf->last_level > 0) {
1453         surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1454         surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1455         surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1456     } else {
1457         surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1458         surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1459         surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1460     }
1461 
1462     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1463 
1464     /* XXX: Texture sampling uses unexpectedly large pitches in some cases,
1465      * these are just guesses for the rules behind those
1466      */
1467     if (level == 0 && surf->last_level == 0)
1468         /* Non-mipmap pitch padded to slice alignment */
1469         /* Using just bpe here breaks stencil blitting; surf->bpe works. */
1470         xalign = MAX2(xalign, slice_align / surf->bpe);
1471     else if (surflevel->mode == RADEON_SURF_MODE_LINEAR_ALIGNED)
1472         /* Small rows evenly distributed across slice */
1473         xalign = MAX2(xalign, slice_align / bpe / surflevel->nblk_y);
1474 
1475     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1476     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1477 
1478     surflevel->offset = offset;
1479     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1480     surflevel->slice_size = ALIGN((uint64_t)surflevel->pitch_bytes * surflevel->nblk_y,
1481 				  (uint64_t)slice_align);
1482 
1483     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1484 }
1485 
si_surf_minify_2d(struct radeon_surface * surf,struct radeon_surface_level * surflevel,unsigned bpe,unsigned level,unsigned slice_pt,uint32_t xalign,uint32_t yalign,uint32_t zalign,unsigned mtileb,uint64_t offset)1486 static void si_surf_minify_2d(struct radeon_surface *surf,
1487                               struct radeon_surface_level *surflevel,
1488                               unsigned bpe, unsigned level, unsigned slice_pt,
1489                               uint32_t xalign, uint32_t yalign, uint32_t zalign,
1490                               unsigned mtileb, uint64_t offset)
1491 {
1492     unsigned mtile_pr, mtile_ps;
1493 
1494     if (level == 0) {
1495         surflevel->npix_x = surf->npix_x;
1496     } else {
1497         surflevel->npix_x = mip_minify(next_power_of_two(surf->npix_x), level);
1498     }
1499     surflevel->npix_y = mip_minify(surf->npix_y, level);
1500     surflevel->npix_z = mip_minify(surf->npix_z, level);
1501 
1502     if (level == 0 && surf->last_level > 0) {
1503         surflevel->nblk_x = (next_power_of_two(surflevel->npix_x) + surf->blk_w - 1) / surf->blk_w;
1504         surflevel->nblk_y = (next_power_of_two(surflevel->npix_y) + surf->blk_h - 1) / surf->blk_h;
1505         surflevel->nblk_z = (next_power_of_two(surflevel->npix_z) + surf->blk_d - 1) / surf->blk_d;
1506     } else {
1507         surflevel->nblk_x = (surflevel->npix_x + surf->blk_w - 1) / surf->blk_w;
1508         surflevel->nblk_y = (surflevel->npix_y + surf->blk_h - 1) / surf->blk_h;
1509         surflevel->nblk_z = (surflevel->npix_z + surf->blk_d - 1) / surf->blk_d;
1510     }
1511 
1512     if (surf->nsamples == 1 && surflevel->mode == RADEON_SURF_MODE_2D &&
1513         !(surf->flags & RADEON_SURF_FMASK)) {
1514         if (surflevel->nblk_x < xalign || surflevel->nblk_y < yalign) {
1515             surflevel->mode = RADEON_SURF_MODE_1D;
1516             return;
1517         }
1518     }
1519     surflevel->nblk_x  = ALIGN(surflevel->nblk_x, xalign);
1520     surflevel->nblk_y  = ALIGN(surflevel->nblk_y, yalign);
1521     surflevel->nblk_z  = ALIGN(surflevel->nblk_z, zalign);
1522 
1523     /* macro tile per row */
1524     mtile_pr = surflevel->nblk_x / xalign;
1525     /* macro tile per slice */
1526     mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
1527     surflevel->offset = offset;
1528     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
1529     surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
1530 
1531     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
1532 }
1533 
si_surface_init_linear_aligned(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned tile_mode,uint64_t offset,unsigned start_level)1534 static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_man,
1535                                           struct radeon_surface *surf,
1536                                           unsigned tile_mode,
1537                                           uint64_t offset, unsigned start_level)
1538 {
1539     uint32_t xalign, yalign, zalign, slice_align;
1540     unsigned i;
1541 
1542     /* compute alignment */
1543     if (!start_level) {
1544         surf->bo_alignment = MAX2(256, surf_man->hw_info.group_bytes);
1545     }
1546     xalign = MAX2(8, 64 / surf->bpe);
1547     yalign = 1;
1548     zalign = 1;
1549     slice_align = MAX2(64 * surf->bpe, surf_man->hw_info.group_bytes);
1550 
1551     /* build mipmap tree */
1552     for (i = start_level; i <= surf->last_level; i++) {
1553         surf->level[i].mode = RADEON_SURF_MODE_LINEAR_ALIGNED;
1554         si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
1555         /* level0 and first mipmap need to have alignment */
1556         offset = surf->bo_size;
1557         if (i == 0) {
1558             offset = ALIGN(offset, surf->bo_alignment);
1559         }
1560         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1561             surf->tiling_index[i] = tile_mode;
1562         }
1563     }
1564     return 0;
1565 }
1566 
si_surface_init_1d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned tile_mode,uint64_t offset,unsigned start_level)1567 static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
1568                               struct radeon_surface *surf,
1569                               struct radeon_surface_level *level,
1570                               unsigned bpe, unsigned tile_mode,
1571                               uint64_t offset, unsigned start_level)
1572 {
1573     uint32_t xalign, yalign, zalign, slice_align;
1574     unsigned alignment = MAX2(256, surf_man->hw_info.group_bytes);
1575     unsigned i;
1576 
1577     /* compute alignment */
1578     xalign = 8;
1579     yalign = 8;
1580     zalign = 1;
1581     slice_align = surf_man->hw_info.group_bytes;
1582     if (surf->flags & RADEON_SURF_SCANOUT) {
1583         xalign = MAX2((bpe == 1) ? 64 : 32, xalign);
1584     }
1585 
1586     if (start_level <= 1) {
1587         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1588 
1589         if (offset) {
1590             offset = ALIGN(offset, alignment);
1591         }
1592     }
1593 
1594     /* build mipmap tree */
1595     for (i = start_level; i <= surf->last_level; i++) {
1596         level[i].mode = RADEON_SURF_MODE_1D;
1597         si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
1598         /* level0 and first mipmap need to have alignment */
1599         offset = surf->bo_size;
1600         if (i == 0) {
1601             offset = ALIGN(offset, alignment);
1602         }
1603         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1604             if (surf->level == level) {
1605                 surf->tiling_index[i] = tile_mode;
1606                 /* it's ok because stencil is done after */
1607                 surf->stencil_tiling_index[i] = tile_mode;
1608             } else {
1609                 surf->stencil_tiling_index[i] = tile_mode;
1610             }
1611         }
1612     }
1613     return 0;
1614 }
1615 
si_surface_init_1d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned tile_mode,unsigned stencil_tile_mode)1616 static int si_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
1617                                        struct radeon_surface *surf,
1618                                        unsigned tile_mode, unsigned stencil_tile_mode)
1619 {
1620     int r;
1621 
1622     r = si_surface_init_1d(surf_man, surf, surf->level, surf->bpe, tile_mode, 0, 0);
1623     if (r) {
1624         return r;
1625     }
1626 
1627     if (surf->flags & RADEON_SURF_SBUFFER) {
1628         r = si_surface_init_1d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, surf->bo_size, 0);
1629         surf->stencil_offset = surf->stencil_level[0].offset;
1630     }
1631     return r;
1632 }
1633 
si_surface_init_2d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned tile_mode,unsigned num_pipes,unsigned num_banks,unsigned tile_split,uint64_t offset,unsigned start_level)1634 static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
1635                               struct radeon_surface *surf,
1636                               struct radeon_surface_level *level,
1637                               unsigned bpe, unsigned tile_mode,
1638                               unsigned num_pipes, unsigned num_banks,
1639                               unsigned tile_split,
1640                               uint64_t offset,
1641                               unsigned start_level)
1642 {
1643     uint64_t aligned_offset = offset;
1644     unsigned tilew, tileh, tileb;
1645     unsigned mtilew, mtileh, mtileb;
1646     unsigned slice_pt;
1647     unsigned i;
1648 
1649     /* compute tile values */
1650     tilew = 8;
1651     tileh = 8;
1652     tileb = tilew * tileh * bpe * surf->nsamples;
1653     /* slices per tile */
1654     slice_pt = 1;
1655     if (tileb > tile_split && tile_split) {
1656         slice_pt = tileb / tile_split;
1657     }
1658     tileb = tileb / slice_pt;
1659 
1660     /* macro tile width & height */
1661     mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
1662     mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
1663 
1664     /* macro tile bytes */
1665     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
1666 
1667     if (start_level <= 1) {
1668         unsigned alignment = MAX2(256, mtileb);
1669         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
1670 
1671         if (aligned_offset) {
1672             aligned_offset = ALIGN(aligned_offset, alignment);
1673         }
1674     }
1675 
1676     /* build mipmap tree */
1677     for (i = start_level; i <= surf->last_level; i++) {
1678         level[i].mode = RADEON_SURF_MODE_2D;
1679         si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
1680         if (level[i].mode == RADEON_SURF_MODE_1D) {
1681             switch (tile_mode) {
1682             case SI_TILE_MODE_COLOR_2D_8BPP:
1683             case SI_TILE_MODE_COLOR_2D_16BPP:
1684             case SI_TILE_MODE_COLOR_2D_32BPP:
1685             case SI_TILE_MODE_COLOR_2D_64BPP:
1686                 tile_mode = SI_TILE_MODE_COLOR_1D;
1687                 break;
1688             case SI_TILE_MODE_COLOR_2D_SCANOUT_16BPP:
1689             case SI_TILE_MODE_COLOR_2D_SCANOUT_32BPP:
1690                 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
1691                 break;
1692             case SI_TILE_MODE_DEPTH_STENCIL_2D:
1693                 tile_mode = SI_TILE_MODE_DEPTH_STENCIL_1D;
1694                 break;
1695             default:
1696                 return -EINVAL;
1697             }
1698             return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
1699         }
1700         /* level0 and first mipmap need to have alignment */
1701         aligned_offset = offset = surf->bo_size;
1702         if (i == 0) {
1703             aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
1704         }
1705         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
1706             if (surf->level == level) {
1707                 surf->tiling_index[i] = tile_mode;
1708                 /* it's ok because stencil is done after */
1709                 surf->stencil_tiling_index[i] = tile_mode;
1710             } else {
1711                 surf->stencil_tiling_index[i] = tile_mode;
1712             }
1713         }
1714     }
1715     return 0;
1716 }
1717 
si_surface_init_2d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned tile_mode,unsigned stencil_tile_mode)1718 static int si_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
1719                                        struct radeon_surface *surf,
1720                                        unsigned tile_mode, unsigned stencil_tile_mode)
1721 {
1722     unsigned num_pipes, num_banks;
1723     uint32_t gb_tile_mode;
1724     int r;
1725 
1726     /* retrieve tiling mode value */
1727     gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1728     si_gb_tile_mode(gb_tile_mode, &num_pipes, &num_banks, NULL, NULL, NULL, NULL);
1729 
1730     r = si_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode, num_pipes, num_banks, surf->tile_split, 0, 0);
1731     if (r) {
1732         return r;
1733     }
1734 
1735     if (surf->flags & RADEON_SURF_SBUFFER) {
1736         r = si_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode, num_pipes, num_banks, surf->stencil_tile_split, surf->bo_size, 0);
1737         surf->stencil_offset = surf->stencil_level[0].offset;
1738     }
1739     return r;
1740 }
1741 
si_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)1742 static int si_surface_init(struct radeon_surface_manager *surf_man,
1743                            struct radeon_surface *surf)
1744 {
1745     unsigned mode, tile_mode, stencil_tile_mode = 0;
1746     int r;
1747 
1748     /* MSAA surfaces support the 2D mode only. */
1749     if (surf->nsamples > 1) {
1750         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1751         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
1752     }
1753 
1754     /* tiling mode */
1755     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1756 
1757     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
1758         /* zbuffer only support 1D or 2D tiled surface */
1759         switch (mode) {
1760         case RADEON_SURF_MODE_1D:
1761         case RADEON_SURF_MODE_2D:
1762             break;
1763         default:
1764             mode = RADEON_SURF_MODE_1D;
1765             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1766             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1767             break;
1768         }
1769     }
1770 
1771     r = si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1772     if (r) {
1773         return r;
1774     }
1775 
1776     surf->stencil_offset = 0;
1777     surf->bo_alignment = 0;
1778 
1779     /* check tiling mode */
1780     switch (mode) {
1781     case RADEON_SURF_MODE_LINEAR:
1782         r = r6_surface_init_linear(surf_man, surf, 0, 0);
1783         break;
1784     case RADEON_SURF_MODE_LINEAR_ALIGNED:
1785         r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
1786         break;
1787     case RADEON_SURF_MODE_1D:
1788         r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1789         break;
1790     case RADEON_SURF_MODE_2D:
1791         r = si_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
1792         break;
1793     default:
1794         return -EINVAL;
1795     }
1796     return r;
1797 }
1798 
1799 /*
1800  * depending on surface
1801  */
si_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)1802 static int si_surface_best(struct radeon_surface_manager *surf_man,
1803                            struct radeon_surface *surf)
1804 {
1805     unsigned mode, tile_mode, stencil_tile_mode;
1806 
1807     /* tiling mode */
1808     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
1809 
1810     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
1811         !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
1812         /* depth/stencil force 1d tiling for old mesa */
1813         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
1814         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
1815     }
1816 
1817     return si_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
1818 }
1819 
1820 
1821 /* ===========================================================================
1822  * Sea Islands family
1823  */
1824 #define CIK__GB_TILE_MODE__PIPE_CONFIG(x)        (((x) >> 6) & 0x1f)
1825 #define     CIK__PIPE_CONFIG__ADDR_SURF_P2               0
1826 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16          4
1827 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16         5
1828 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32         6
1829 #define     CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32         7
1830 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16    8
1831 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16    9
1832 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16    10
1833 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16   11
1834 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16   12
1835 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32   13
1836 #define     CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32   14
1837 #define     CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16   16
1838 #define     CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16  17
1839 #define CIK__GB_TILE_MODE__TILE_SPLIT(x)         (((x) >> 11) & 0x7)
1840 #define     CIK__TILE_SPLIT__64B                         0
1841 #define     CIK__TILE_SPLIT__128B                        1
1842 #define     CIK__TILE_SPLIT__256B                        2
1843 #define     CIK__TILE_SPLIT__512B                        3
1844 #define     CIK__TILE_SPLIT__1024B                       4
1845 #define     CIK__TILE_SPLIT__2048B                       5
1846 #define     CIK__TILE_SPLIT__4096B                       6
1847 #define CIK__GB_TILE_MODE__SAMPLE_SPLIT(x)         (((x) >> 25) & 0x3)
1848 #define     CIK__SAMPLE_SPLIT__1                         0
1849 #define     CIK__SAMPLE_SPLIT__2                         1
1850 #define     CIK__SAMPLE_SPLIT__4                         2
1851 #define     CIK__SAMPLE_SPLIT__8                         3
1852 #define CIK__GB_MACROTILE_MODE__BANK_WIDTH(x)        ((x) & 0x3)
1853 #define     CIK__BANK_WIDTH__1                           0
1854 #define     CIK__BANK_WIDTH__2                           1
1855 #define     CIK__BANK_WIDTH__4                           2
1856 #define     CIK__BANK_WIDTH__8                           3
1857 #define CIK__GB_MACROTILE_MODE__BANK_HEIGHT(x)       (((x) >> 2) & 0x3)
1858 #define     CIK__BANK_HEIGHT__1                          0
1859 #define     CIK__BANK_HEIGHT__2                          1
1860 #define     CIK__BANK_HEIGHT__4                          2
1861 #define     CIK__BANK_HEIGHT__8                          3
1862 #define CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(x) (((x) >> 4) & 0x3)
1863 #define     CIK__MACRO_TILE_ASPECT__1                    0
1864 #define     CIK__MACRO_TILE_ASPECT__2                    1
1865 #define     CIK__MACRO_TILE_ASPECT__4                    2
1866 #define     CIK__MACRO_TILE_ASPECT__8                    3
1867 #define CIK__GB_MACROTILE_MODE__NUM_BANKS(x)         (((x) >> 6) & 0x3)
1868 #define     CIK__NUM_BANKS__2_BANK                       0
1869 #define     CIK__NUM_BANKS__4_BANK                       1
1870 #define     CIK__NUM_BANKS__8_BANK                       2
1871 #define     CIK__NUM_BANKS__16_BANK                      3
1872 
1873 
cik_get_2d_params(struct radeon_surface_manager * surf_man,unsigned bpe,unsigned nsamples,bool is_color,unsigned tile_mode,uint32_t * num_pipes,uint32_t * tile_split_ptr,uint32_t * num_banks,uint32_t * macro_tile_aspect,uint32_t * bank_w,uint32_t * bank_h)1874 static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
1875                               unsigned bpe, unsigned nsamples, bool is_color,
1876                               unsigned tile_mode,
1877                               uint32_t *num_pipes,
1878                               uint32_t *tile_split_ptr,
1879                               uint32_t *num_banks,
1880                               uint32_t *macro_tile_aspect,
1881                               uint32_t *bank_w,
1882                               uint32_t *bank_h)
1883 {
1884     uint32_t gb_tile_mode = surf_man->hw_info.tile_mode_array[tile_mode];
1885     unsigned tileb_1x, tileb;
1886     unsigned gb_macrotile_mode;
1887     unsigned macrotile_index;
1888     unsigned tile_split, sample_split;
1889 
1890     if (num_pipes) {
1891         switch (CIK__GB_TILE_MODE__PIPE_CONFIG(gb_tile_mode)) {
1892         case CIK__PIPE_CONFIG__ADDR_SURF_P2:
1893         default:
1894             *num_pipes = 2;
1895             break;
1896         case CIK__PIPE_CONFIG__ADDR_SURF_P4_8x16:
1897         case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x16:
1898         case CIK__PIPE_CONFIG__ADDR_SURF_P4_16x32:
1899         case CIK__PIPE_CONFIG__ADDR_SURF_P4_32x32:
1900             *num_pipes = 4;
1901             break;
1902         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x16_8x16:
1903         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_8x16:
1904         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_8x16:
1905         case CIK__PIPE_CONFIG__ADDR_SURF_P8_16x32_16x16:
1906         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x16:
1907         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x32_16x32:
1908         case CIK__PIPE_CONFIG__ADDR_SURF_P8_32x64_32x32:
1909             *num_pipes = 8;
1910             break;
1911         case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_8X16:
1912         case CIK__PIPE_CONFIG__ADDR_SURF_P16_32X32_16X16:
1913             *num_pipes = 16;
1914             break;
1915         }
1916     }
1917     switch (CIK__GB_TILE_MODE__TILE_SPLIT(gb_tile_mode)) {
1918     default:
1919     case CIK__TILE_SPLIT__64B:
1920         tile_split = 64;
1921         break;
1922     case CIK__TILE_SPLIT__128B:
1923         tile_split = 128;
1924         break;
1925     case CIK__TILE_SPLIT__256B:
1926         tile_split = 256;
1927         break;
1928     case CIK__TILE_SPLIT__512B:
1929         tile_split = 512;
1930         break;
1931     case CIK__TILE_SPLIT__1024B:
1932         tile_split = 1024;
1933         break;
1934     case CIK__TILE_SPLIT__2048B:
1935         tile_split = 2048;
1936         break;
1937     case CIK__TILE_SPLIT__4096B:
1938         tile_split = 4096;
1939         break;
1940     }
1941     switch (CIK__GB_TILE_MODE__SAMPLE_SPLIT(gb_tile_mode)) {
1942     default:
1943     case CIK__SAMPLE_SPLIT__1:
1944         sample_split = 1;
1945         break;
1946     case CIK__SAMPLE_SPLIT__2:
1947         sample_split = 2;
1948         break;
1949     case CIK__SAMPLE_SPLIT__4:
1950         sample_split = 4;
1951         break;
1952     case CIK__SAMPLE_SPLIT__8:
1953         sample_split = 8;
1954         break;
1955     }
1956 
1957     /* Adjust the tile split. */
1958     tileb_1x = 8 * 8 * bpe;
1959     if (is_color) {
1960         tile_split = MAX2(256, sample_split * tileb_1x);
1961     }
1962     tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
1963 
1964     /* Determine the macrotile index. */
1965     tileb = MIN2(tile_split, nsamples * tileb_1x);
1966 
1967     for (macrotile_index = 0; tileb > 64; macrotile_index++) {
1968         tileb >>= 1;
1969     }
1970     gb_macrotile_mode = surf_man->hw_info.macrotile_mode_array[macrotile_index];
1971 
1972     if (tile_split_ptr) {
1973         *tile_split_ptr = tile_split;
1974     }
1975     if (num_banks) {
1976         switch (CIK__GB_MACROTILE_MODE__NUM_BANKS(gb_macrotile_mode)) {
1977         default:
1978         case CIK__NUM_BANKS__2_BANK:
1979             *num_banks = 2;
1980             break;
1981         case CIK__NUM_BANKS__4_BANK:
1982             *num_banks = 4;
1983             break;
1984         case CIK__NUM_BANKS__8_BANK:
1985             *num_banks = 8;
1986             break;
1987         case CIK__NUM_BANKS__16_BANK:
1988             *num_banks = 16;
1989             break;
1990         }
1991     }
1992     if (macro_tile_aspect) {
1993         switch (CIK__GB_MACROTILE_MODE__MACRO_TILE_ASPECT(gb_macrotile_mode)) {
1994         default:
1995         case CIK__MACRO_TILE_ASPECT__1:
1996             *macro_tile_aspect = 1;
1997             break;
1998         case CIK__MACRO_TILE_ASPECT__2:
1999             *macro_tile_aspect = 2;
2000             break;
2001         case CIK__MACRO_TILE_ASPECT__4:
2002             *macro_tile_aspect = 4;
2003             break;
2004         case CIK__MACRO_TILE_ASPECT__8:
2005             *macro_tile_aspect = 8;
2006             break;
2007         }
2008     }
2009     if (bank_w) {
2010         switch (CIK__GB_MACROTILE_MODE__BANK_WIDTH(gb_macrotile_mode)) {
2011         default:
2012         case CIK__BANK_WIDTH__1:
2013             *bank_w = 1;
2014             break;
2015         case CIK__BANK_WIDTH__2:
2016             *bank_w = 2;
2017             break;
2018         case CIK__BANK_WIDTH__4:
2019             *bank_w = 4;
2020             break;
2021         case CIK__BANK_WIDTH__8:
2022             *bank_w = 8;
2023             break;
2024         }
2025     }
2026     if (bank_h) {
2027         switch (CIK__GB_MACROTILE_MODE__BANK_HEIGHT(gb_macrotile_mode)) {
2028         default:
2029         case CIK__BANK_HEIGHT__1:
2030             *bank_h = 1;
2031             break;
2032         case CIK__BANK_HEIGHT__2:
2033             *bank_h = 2;
2034             break;
2035         case CIK__BANK_HEIGHT__4:
2036             *bank_h = 4;
2037             break;
2038         case CIK__BANK_HEIGHT__8:
2039             *bank_h = 8;
2040             break;
2041         }
2042     }
2043 }
2044 
cik_init_hw_info(struct radeon_surface_manager * surf_man)2045 static int cik_init_hw_info(struct radeon_surface_manager *surf_man)
2046 {
2047     uint32_t tiling_config;
2048     drmVersionPtr version;
2049     int r;
2050 
2051     r = radeon_get_value(surf_man->fd, RADEON_INFO_TILING_CONFIG,
2052                          &tiling_config);
2053     if (r) {
2054         return r;
2055     }
2056 
2057     surf_man->hw_info.allow_2d = 0;
2058     version = drmGetVersion(surf_man->fd);
2059     if (version && version->version_minor >= 35) {
2060         if (!radeon_get_value(surf_man->fd, RADEON_INFO_SI_TILE_MODE_ARRAY, surf_man->hw_info.tile_mode_array) &&
2061 	    !radeon_get_value(surf_man->fd, RADEON_INFO_CIK_MACROTILE_MODE_ARRAY, surf_man->hw_info.macrotile_mode_array)) {
2062             surf_man->hw_info.allow_2d = 1;
2063         }
2064     }
2065     drmFreeVersion(version);
2066 
2067     switch (tiling_config & 0xf) {
2068     case 0:
2069         surf_man->hw_info.num_pipes = 1;
2070         break;
2071     case 1:
2072         surf_man->hw_info.num_pipes = 2;
2073         break;
2074     case 2:
2075         surf_man->hw_info.num_pipes = 4;
2076         break;
2077     case 3:
2078         surf_man->hw_info.num_pipes = 8;
2079         break;
2080     default:
2081         surf_man->hw_info.num_pipes = 8;
2082         surf_man->hw_info.allow_2d = 0;
2083         break;
2084     }
2085 
2086     switch ((tiling_config & 0xf0) >> 4) {
2087     case 0:
2088         surf_man->hw_info.num_banks = 4;
2089         break;
2090     case 1:
2091         surf_man->hw_info.num_banks = 8;
2092         break;
2093     case 2:
2094         surf_man->hw_info.num_banks = 16;
2095         break;
2096     default:
2097         surf_man->hw_info.num_banks = 8;
2098         surf_man->hw_info.allow_2d = 0;
2099         break;
2100     }
2101 
2102     switch ((tiling_config & 0xf00) >> 8) {
2103     case 0:
2104         surf_man->hw_info.group_bytes = 256;
2105         break;
2106     case 1:
2107         surf_man->hw_info.group_bytes = 512;
2108         break;
2109     default:
2110         surf_man->hw_info.group_bytes = 256;
2111         surf_man->hw_info.allow_2d = 0;
2112         break;
2113     }
2114 
2115     switch ((tiling_config & 0xf000) >> 12) {
2116     case 0:
2117         surf_man->hw_info.row_size = 1024;
2118         break;
2119     case 1:
2120         surf_man->hw_info.row_size = 2048;
2121         break;
2122     case 2:
2123         surf_man->hw_info.row_size = 4096;
2124         break;
2125     default:
2126         surf_man->hw_info.row_size = 4096;
2127         surf_man->hw_info.allow_2d = 0;
2128         break;
2129     }
2130     return 0;
2131 }
2132 
cik_surface_sanity(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned mode,unsigned * tile_mode,unsigned * stencil_tile_mode)2133 static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
2134                               struct radeon_surface *surf,
2135                               unsigned mode, unsigned *tile_mode, unsigned *stencil_tile_mode)
2136 {
2137     /* check surface dimension */
2138     if (surf->npix_x > 16384 || surf->npix_y > 16384 || surf->npix_z > 16384) {
2139         return -EINVAL;
2140     }
2141 
2142     /* check mipmap last_level */
2143     if (surf->last_level > 15) {
2144         return -EINVAL;
2145     }
2146 
2147     /* force 1d on kernel that can't do 2d */
2148     if (mode > RADEON_SURF_MODE_1D &&
2149         (!surf_man->hw_info.allow_2d || !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX))) {
2150         if (surf->nsamples > 1) {
2151             fprintf(stderr, "radeon: Cannot use 1D tiling for an MSAA surface (%i).\n", __LINE__);
2152             return -EFAULT;
2153         }
2154         mode = RADEON_SURF_MODE_1D;
2155         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2156         surf->flags |= RADEON_SURF_SET(mode, MODE);
2157     }
2158 
2159     if (surf->nsamples > 1 && mode != RADEON_SURF_MODE_2D) {
2160         return -EINVAL;
2161     }
2162 
2163     if (!surf->tile_split) {
2164         /* default value */
2165         surf->mtilea = 1;
2166         surf->bankw = 1;
2167         surf->bankh = 1;
2168         surf->tile_split = 64;
2169         surf->stencil_tile_split = 64;
2170     }
2171 
2172     switch (mode) {
2173     case RADEON_SURF_MODE_2D: {
2174         if (surf->flags & RADEON_SURF_Z_OR_SBUFFER) {
2175             switch (surf->nsamples) {
2176             case 1:
2177                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64;
2178                 break;
2179             case 2:
2180             case 4:
2181                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128;
2182                 break;
2183             case 8:
2184                 *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256;
2185                 break;
2186             default:
2187                 return -EINVAL;
2188             }
2189 
2190             if (surf->flags & RADEON_SURF_SBUFFER) {
2191                 *stencil_tile_mode = *tile_mode;
2192 
2193                 cik_get_2d_params(surf_man, 1, surf->nsamples, false,
2194                                   *stencil_tile_mode, NULL,
2195                                   &surf->stencil_tile_split,
2196                                   NULL, NULL, NULL, NULL);
2197             }
2198         } else if (surf->flags & RADEON_SURF_SCANOUT) {
2199             *tile_mode = CIK_TILE_MODE_COLOR_2D_SCANOUT;
2200         } else {
2201             *tile_mode = CIK_TILE_MODE_COLOR_2D;
2202         }
2203 
2204         /* retrieve tiling mode values */
2205         cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2206                           !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), *tile_mode,
2207                           NULL, &surf->tile_split, NULL, &surf->mtilea,
2208                           &surf->bankw, &surf->bankh);
2209         break;
2210     }
2211     case RADEON_SURF_MODE_1D:
2212         if (surf->flags & RADEON_SURF_SBUFFER) {
2213             *stencil_tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2214         }
2215         if (surf->flags & RADEON_SURF_ZBUFFER) {
2216             *tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2217         } else if (surf->flags & RADEON_SURF_SCANOUT) {
2218             *tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2219         } else {
2220             *tile_mode = SI_TILE_MODE_COLOR_1D;
2221         }
2222         break;
2223     case RADEON_SURF_MODE_LINEAR_ALIGNED:
2224     default:
2225         *stencil_tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2226         *tile_mode = SI_TILE_MODE_COLOR_LINEAR_ALIGNED;
2227     }
2228 
2229     return 0;
2230 }
2231 
cik_surface_init_2d(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,struct radeon_surface_level * level,unsigned bpe,unsigned tile_mode,unsigned tile_split,unsigned num_pipes,unsigned num_banks,uint64_t offset,unsigned start_level)2232 static int cik_surface_init_2d(struct radeon_surface_manager *surf_man,
2233                                struct radeon_surface *surf,
2234                                struct radeon_surface_level *level,
2235                                unsigned bpe, unsigned tile_mode,
2236                                unsigned tile_split,
2237                                unsigned num_pipes, unsigned num_banks,
2238                                uint64_t offset,
2239                                unsigned start_level)
2240 {
2241     uint64_t aligned_offset = offset;
2242     unsigned tilew, tileh, tileb_1x, tileb;
2243     unsigned mtilew, mtileh, mtileb;
2244     unsigned slice_pt;
2245     unsigned i;
2246 
2247     /* compute tile values */
2248     tilew = 8;
2249     tileh = 8;
2250     tileb_1x = tilew * tileh * bpe;
2251 
2252     tile_split = MIN2(surf_man->hw_info.row_size, tile_split);
2253 
2254     tileb = surf->nsamples * tileb_1x;
2255 
2256     /* slices per tile */
2257     slice_pt = 1;
2258     if (tileb > tile_split && tile_split) {
2259         slice_pt = tileb / tile_split;
2260         tileb = tileb / slice_pt;
2261     }
2262 
2263     /* macro tile width & height */
2264     mtilew = (tilew * surf->bankw * num_pipes) * surf->mtilea;
2265     mtileh = (tileh * surf->bankh * num_banks) / surf->mtilea;
2266 
2267     /* macro tile bytes */
2268     mtileb = (mtilew / tilew) * (mtileh / tileh) * tileb;
2269 
2270     if (start_level <= 1) {
2271         unsigned alignment = MAX2(256, mtileb);
2272         surf->bo_alignment = MAX2(surf->bo_alignment, alignment);
2273 
2274         if (aligned_offset) {
2275             aligned_offset = ALIGN(aligned_offset, alignment);
2276         }
2277     }
2278 
2279     /* build mipmap tree */
2280     for (i = start_level; i <= surf->last_level; i++) {
2281         level[i].mode = RADEON_SURF_MODE_2D;
2282         si_surf_minify_2d(surf, level+i, bpe, i, slice_pt, mtilew, mtileh, 1, mtileb, aligned_offset);
2283         if (level[i].mode == RADEON_SURF_MODE_1D) {
2284             switch (tile_mode) {
2285             case CIK_TILE_MODE_COLOR_2D:
2286                 tile_mode = SI_TILE_MODE_COLOR_1D;
2287                 break;
2288             case CIK_TILE_MODE_COLOR_2D_SCANOUT:
2289                 tile_mode = SI_TILE_MODE_COLOR_1D_SCANOUT;
2290                 break;
2291             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_64:
2292             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_128:
2293             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_256:
2294             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_512:
2295             case CIK_TILE_MODE_DEPTH_STENCIL_2D_TILESPLIT_ROW_SIZE:
2296                 tile_mode = CIK_TILE_MODE_DEPTH_STENCIL_1D;
2297                 break;
2298             default:
2299                 return -EINVAL;
2300             }
2301             return si_surface_init_1d(surf_man, surf, level, bpe, tile_mode, offset, i);
2302         }
2303         /* level0 and first mipmap need to have alignment */
2304         aligned_offset = offset = surf->bo_size;
2305         if (i == 0) {
2306             aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
2307         }
2308         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
2309             if (surf->level == level) {
2310                 surf->tiling_index[i] = tile_mode;
2311                 /* it's ok because stencil is done after */
2312                 surf->stencil_tiling_index[i] = tile_mode;
2313             } else {
2314                 surf->stencil_tiling_index[i] = tile_mode;
2315             }
2316         }
2317     }
2318     return 0;
2319 }
2320 
cik_surface_init_2d_miptrees(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned tile_mode,unsigned stencil_tile_mode)2321 static int cik_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
2322                                         struct radeon_surface *surf,
2323                                         unsigned tile_mode, unsigned stencil_tile_mode)
2324 {
2325     int r;
2326     uint32_t num_pipes, num_banks;
2327 
2328     cik_get_2d_params(surf_man, surf->bpe, surf->nsamples,
2329                         !(surf->flags & RADEON_SURF_Z_OR_SBUFFER), tile_mode,
2330                         &num_pipes, NULL, &num_banks, NULL, NULL, NULL);
2331 
2332     r = cik_surface_init_2d(surf_man, surf, surf->level, surf->bpe, tile_mode,
2333                             surf->tile_split, num_pipes, num_banks, 0, 0);
2334     if (r) {
2335         return r;
2336     }
2337 
2338     if (surf->flags & RADEON_SURF_SBUFFER) {
2339         r = cik_surface_init_2d(surf_man, surf, surf->stencil_level, 1, stencil_tile_mode,
2340                                 surf->stencil_tile_split, num_pipes, num_banks,
2341                                 surf->bo_size, 0);
2342         surf->stencil_offset = surf->stencil_level[0].offset;
2343     }
2344     return r;
2345 }
2346 
cik_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)2347 static int cik_surface_init(struct radeon_surface_manager *surf_man,
2348                             struct radeon_surface *surf)
2349 {
2350     unsigned mode, tile_mode, stencil_tile_mode = 0;
2351     int r;
2352 
2353     /* MSAA surfaces support the 2D mode only. */
2354     if (surf->nsamples > 1) {
2355         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2356         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_2D, MODE);
2357     }
2358 
2359     /* tiling mode */
2360     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2361 
2362     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER)) {
2363         /* zbuffer only support 1D or 2D tiled surface */
2364         switch (mode) {
2365         case RADEON_SURF_MODE_1D:
2366         case RADEON_SURF_MODE_2D:
2367             break;
2368         default:
2369             mode = RADEON_SURF_MODE_1D;
2370             surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2371             surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2372             break;
2373         }
2374     }
2375 
2376     r = cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2377     if (r) {
2378         return r;
2379     }
2380 
2381     surf->stencil_offset = 0;
2382     surf->bo_alignment = 0;
2383 
2384     /* check tiling mode */
2385     switch (mode) {
2386     case RADEON_SURF_MODE_LINEAR:
2387         r = r6_surface_init_linear(surf_man, surf, 0, 0);
2388         break;
2389     case RADEON_SURF_MODE_LINEAR_ALIGNED:
2390         r = si_surface_init_linear_aligned(surf_man, surf, tile_mode, 0, 0);
2391         break;
2392     case RADEON_SURF_MODE_1D:
2393         r = si_surface_init_1d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2394         break;
2395     case RADEON_SURF_MODE_2D:
2396         r = cik_surface_init_2d_miptrees(surf_man, surf, tile_mode, stencil_tile_mode);
2397         break;
2398     default:
2399         return -EINVAL;
2400     }
2401     return r;
2402 }
2403 
2404 /*
2405  * depending on surface
2406  */
cik_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)2407 static int cik_surface_best(struct radeon_surface_manager *surf_man,
2408                             struct radeon_surface *surf)
2409 {
2410     unsigned mode, tile_mode, stencil_tile_mode;
2411 
2412     /* tiling mode */
2413     mode = (surf->flags >> RADEON_SURF_MODE_SHIFT) & RADEON_SURF_MODE_MASK;
2414 
2415     if (surf->flags & (RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER) &&
2416         !(surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX)) {
2417         /* depth/stencil force 1d tiling for old mesa */
2418         surf->flags = RADEON_SURF_CLR(surf->flags, MODE);
2419         surf->flags |= RADEON_SURF_SET(RADEON_SURF_MODE_1D, MODE);
2420     }
2421 
2422     return cik_surface_sanity(surf_man, surf, mode, &tile_mode, &stencil_tile_mode);
2423 }
2424 
2425 
2426 /* ===========================================================================
2427  * public API
2428  */
2429 struct radeon_surface_manager *
radeon_surface_manager_new(int fd)2430 radeon_surface_manager_new(int fd)
2431 {
2432     struct radeon_surface_manager *surf_man;
2433 
2434     surf_man = calloc(1, sizeof(struct radeon_surface_manager));
2435     if (surf_man == NULL) {
2436         return NULL;
2437     }
2438     surf_man->fd = fd;
2439     if (radeon_get_value(fd, RADEON_INFO_DEVICE_ID, &surf_man->device_id)) {
2440         goto out_err;
2441     }
2442     if (radeon_get_family(surf_man)) {
2443         goto out_err;
2444     }
2445 
2446     if (surf_man->family <= CHIP_RV740) {
2447         if (r6_init_hw_info(surf_man)) {
2448             goto out_err;
2449         }
2450         surf_man->surface_init = &r6_surface_init;
2451         surf_man->surface_best = &r6_surface_best;
2452     } else if (surf_man->family <= CHIP_ARUBA) {
2453         if (eg_init_hw_info(surf_man)) {
2454             goto out_err;
2455         }
2456         surf_man->surface_init = &eg_surface_init;
2457         surf_man->surface_best = &eg_surface_best;
2458     } else if (surf_man->family < CHIP_BONAIRE) {
2459         if (si_init_hw_info(surf_man)) {
2460             goto out_err;
2461         }
2462         surf_man->surface_init = &si_surface_init;
2463         surf_man->surface_best = &si_surface_best;
2464     } else {
2465         if (cik_init_hw_info(surf_man)) {
2466             goto out_err;
2467         }
2468         surf_man->surface_init = &cik_surface_init;
2469         surf_man->surface_best = &cik_surface_best;
2470     }
2471 
2472     return surf_man;
2473 out_err:
2474     free(surf_man);
2475     return NULL;
2476 }
2477 
2478 void
radeon_surface_manager_free(struct radeon_surface_manager * surf_man)2479 radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
2480 {
2481     free(surf_man);
2482 }
2483 
radeon_surface_sanity(struct radeon_surface_manager * surf_man,struct radeon_surface * surf,unsigned type,unsigned mode)2484 static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
2485                                  struct radeon_surface *surf,
2486                                  unsigned type,
2487                                  unsigned mode)
2488 {
2489     if (surf_man == NULL || surf_man->surface_init == NULL || surf == NULL) {
2490         return -EINVAL;
2491     }
2492 
2493     /* all dimension must be at least 1 ! */
2494     if (!surf->npix_x || !surf->npix_y || !surf->npix_z) {
2495         return -EINVAL;
2496     }
2497     if (!surf->blk_w || !surf->blk_h || !surf->blk_d) {
2498         return -EINVAL;
2499     }
2500     if (!surf->array_size) {
2501         return -EINVAL;
2502     }
2503     /* array size must be a power of 2 */
2504     surf->array_size = next_power_of_two(surf->array_size);
2505 
2506     switch (surf->nsamples) {
2507     case 1:
2508     case 2:
2509     case 4:
2510     case 8:
2511         break;
2512     default:
2513         return -EINVAL;
2514     }
2515     /* check type */
2516     switch (type) {
2517     case RADEON_SURF_TYPE_1D:
2518         if (surf->npix_y > 1) {
2519             return -EINVAL;
2520         }
2521         FALLTHROUGH;
2522     case RADEON_SURF_TYPE_2D:
2523         if (surf->npix_z > 1) {
2524             return -EINVAL;
2525         }
2526         break;
2527     case RADEON_SURF_TYPE_CUBEMAP:
2528         if (surf->npix_z > 1) {
2529             return -EINVAL;
2530         }
2531         /* deal with cubemap as they were texture array */
2532         if (surf_man->family >= CHIP_RV770) {
2533             surf->array_size = 8;
2534         } else {
2535             surf->array_size = 6;
2536         }
2537         break;
2538     case RADEON_SURF_TYPE_3D:
2539         break;
2540     case RADEON_SURF_TYPE_1D_ARRAY:
2541         if (surf->npix_y > 1) {
2542             return -EINVAL;
2543         }
2544         FALLTHROUGH;
2545     case RADEON_SURF_TYPE_2D_ARRAY:
2546         break;
2547     default:
2548         return -EINVAL;
2549     }
2550     return 0;
2551 }
2552 
2553 int
radeon_surface_init(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)2554 radeon_surface_init(struct radeon_surface_manager *surf_man,
2555                     struct radeon_surface *surf)
2556 {
2557     unsigned mode, type;
2558     int r;
2559 
2560     type = RADEON_SURF_GET(surf->flags, TYPE);
2561     mode = RADEON_SURF_GET(surf->flags, MODE);
2562 
2563     r = radeon_surface_sanity(surf_man, surf, type, mode);
2564     if (r) {
2565         return r;
2566     }
2567     return surf_man->surface_init(surf_man, surf);
2568 }
2569 
2570 int
radeon_surface_best(struct radeon_surface_manager * surf_man,struct radeon_surface * surf)2571 radeon_surface_best(struct radeon_surface_manager *surf_man,
2572                     struct radeon_surface *surf)
2573 {
2574     unsigned mode, type;
2575     int r;
2576 
2577     type = RADEON_SURF_GET(surf->flags, TYPE);
2578     mode = RADEON_SURF_GET(surf->flags, MODE);
2579 
2580     r = radeon_surface_sanity(surf_man, surf, type, mode);
2581     if (r) {
2582         return r;
2583     }
2584     return surf_man->surface_best(surf_man, surf);
2585 }
2586