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