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