OSDN Git Service

modetest: Adding amdgpu to module list
[android-x86/external-libdrm.git] / radeon / radeon_surface.c
index 15127d4..1424660 100644 (file)
  * Authors:
  *      Jérôme Glisse <jglisse@redhat.com>
  */
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 #include <stdbool.h>
 #include <assert.h>
 #include <errno.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <sys/mman.h>
 #include <sys/ioctl.h>
 #include "drm.h"
+#include "libdrm_macros.h"
 #include "xf86drm.h"
 #include "radeon_drm.h"
 #include "radeon_surface.h"
@@ -80,6 +83,7 @@ enum radeon_family {
     CHIP_KAVERI,
     CHIP_KABINI,
     CHIP_HAWAII,
+    CHIP_MULLINS,
     CHIP_LAST,
 };
 
@@ -159,7 +163,7 @@ static void surf_minify(struct radeon_surface *surf,
                         struct radeon_surface_level *surflevel,
                         unsigned bpe, unsigned level,
                         uint32_t xalign, uint32_t yalign, uint32_t zalign,
-                        unsigned offset)
+                        uint64_t offset)
 {
     surflevel->npix_x = mip_minify(surf->npix_x, level);
     surflevel->npix_y = mip_minify(surf->npix_y, level);
@@ -180,7 +184,7 @@ static void surf_minify(struct radeon_surface *surf,
 
     surflevel->offset = offset;
     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
-    surflevel->slice_size = surflevel->pitch_bytes * surflevel->nblk_y;
+    surflevel->slice_size = (uint64_t)surflevel->pitch_bytes * surflevel->nblk_y;
 
     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
 }
@@ -281,7 +285,7 @@ static int r6_surface_init_linear(struct radeon_surface_manager *surf_man,
         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
         /* level0 and first mipmap need to have alignment */
         offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             offset = ALIGN(offset, surf->bo_alignment);
         }
     }
@@ -309,7 +313,7 @@ static int r6_surface_init_linear_aligned(struct radeon_surface_manager *surf_ma
         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
         /* level0 and first mipmap need to have alignment */
         offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             offset = ALIGN(offset, surf->bo_alignment);
         }
     }
@@ -342,7 +346,7 @@ static int r6_surface_init_1d(struct radeon_surface_manager *surf_man,
         surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, offset);
         /* level0 and first mipmap need to have alignment */
         offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             offset = ALIGN(offset, surf->bo_alignment);
         }
     }
@@ -362,6 +366,8 @@ static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
     xalign = (surf_man->hw_info.group_bytes * surf_man->hw_info.num_banks) /
              (tilew * surf->bpe * surf->nsamples);
     xalign = MAX2(tilew * surf_man->hw_info.num_banks, xalign);
+    if (surf->flags & RADEON_SURF_FMASK)
+       xalign = MAX2(128, xalign);
     yalign = tilew * surf_man->hw_info.num_pipes;
     if (surf->flags & RADEON_SURF_SCANOUT) {
         xalign = MAX2((surf->bpe == 1) ? 64 : 32, xalign);
@@ -383,7 +389,7 @@ static int r6_surface_init_2d(struct radeon_surface_manager *surf_man,
         }
         /* level0 and first mipmap need to have alignment */
         offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             offset = ALIGN(offset, surf->bo_alignment);
         }
     }
@@ -564,7 +570,7 @@ static void eg_surf_minify(struct radeon_surface *surf,
                            unsigned mtilew,
                            unsigned mtileh,
                            unsigned mtileb,
-                           unsigned offset)
+                           uint64_t offset)
 {
     unsigned mtile_pr, mtile_ps;
 
@@ -591,8 +597,8 @@ static void eg_surf_minify(struct radeon_surface *surf,
     mtile_ps = (mtile_pr * surflevel->nblk_y) / mtileh;
 
     surflevel->offset = offset;
-    surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
-    surflevel->slice_size = mtile_ps * mtileb * slice_pt;
+    surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
+    surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
 
     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
 }
@@ -631,7 +637,7 @@ static int eg_surface_init_1d(struct radeon_surface_manager *surf_man,
         surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, offset);
         /* level0 and first mipmap need to have alignment */
         offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             offset = ALIGN(offset, surf->bo_alignment);
         }
     }
@@ -684,7 +690,7 @@ static int eg_surface_init_2d(struct radeon_surface_manager *surf_man,
         }
         /* level0 and first mipmap need to have alignment */
         offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             offset = ALIGN(offset, surf->bo_alignment);
         }
     }
@@ -779,7 +785,7 @@ static int eg_surface_init_1d_miptrees(struct radeon_surface_manager *surf_man,
 {
     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
-    /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
+    /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
     struct radeon_surface_level *stencil_level =
         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
@@ -801,7 +807,7 @@ static int eg_surface_init_2d_miptrees(struct radeon_surface_manager *surf_man,
 {
     unsigned zs_flags = RADEON_SURF_ZBUFFER | RADEON_SURF_SBUFFER;
     int r, is_depth_stencil = (surf->flags & zs_flags) == zs_flags;
-    /* Old libdrm headers didn't have stencil_level in it. This prevents crashes. */
+    /* Old libdrm_macros.headers didn't have stencil_level in it. This prevents crashes. */
     struct radeon_surface_level tmp[RADEON_SURF_MAX_LEVEL];
     struct radeon_surface_level *stencil_level =
         (surf->flags & RADEON_SURF_HAS_SBUFFER_MIPTREE) ? surf->stencil_level : tmp;
@@ -951,8 +957,10 @@ static int eg_surface_best(struct radeon_surface_manager *surf_man,
             }
             surf->stencil_tile_split = 64;
         } else {
-            /* tile split must be >= 256 for colorbuffer surfaces */
-            surf->tile_split = MAX2(surf->nsamples * surf->bpe * 64, 256);
+            /* tile split must be >= 256 for colorbuffer surfaces,
+             * SAMPLE_SPLIT = tile_split / (bpe * 64), the optimal value is 2
+             */
+            surf->tile_split = MAX2(2 * surf->bpe * 64, 256);
             if (surf->tile_split > 4096)
                 surf->tile_split = 4096;
         }
@@ -1306,7 +1314,7 @@ static int si_surface_sanity(struct radeon_surface_manager *surf_man,
         /* default value */
         surf->mtilea = 1;
         surf->bankw = 1;
-        surf->bankw = 1;
+        surf->bankh = 1;
         surf->tile_split = 64;
         surf->stencil_tile_split = 64;
     }
@@ -1409,7 +1417,7 @@ static void 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, unsigned offset)
+                           uint32_t slice_align, uint64_t offset)
 {
     if (level == 0) {
         surflevel->npix_x = surf->npix_x;
@@ -1447,7 +1455,8 @@ static void si_surf_minify(struct radeon_surface *surf,
 
     surflevel->offset = offset;
     surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
-    surflevel->slice_size = ALIGN(surflevel->pitch_bytes * surflevel->nblk_y, slice_align);
+    surflevel->slice_size = ALIGN((uint64_t)surflevel->pitch_bytes * surflevel->nblk_y,
+                                 (uint64_t)slice_align);
 
     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
 }
@@ -1456,7 +1465,7 @@ static void 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, unsigned offset)
+                              unsigned mtileb, uint64_t offset)
 {
     unsigned mtile_pr, mtile_ps;
 
@@ -1494,8 +1503,8 @@ static void si_surf_minify_2d(struct radeon_surface *surf,
     /* macro tile per slice */
     mtile_ps = (mtile_pr * surflevel->nblk_y) / yalign;
     surflevel->offset = offset;
-    surflevel->pitch_bytes = surflevel->nblk_x * bpe * slice_pt;
-    surflevel->slice_size = mtile_ps * mtileb * slice_pt;
+    surflevel->pitch_bytes = surflevel->nblk_x * bpe * surf->nsamples;
+    surflevel->slice_size = (uint64_t)mtile_ps * mtileb * slice_pt;
 
     surf->bo_size = offset + surflevel->slice_size * surflevel->nblk_z * surf->array_size;
 }
@@ -1523,7 +1532,7 @@ static int si_surface_init_linear_aligned(struct radeon_surface_manager *surf_ma
         si_surf_minify(surf, surf->level+i, surf->bpe, i, xalign, yalign, zalign, slice_align, offset);
         /* level0 and first mipmap need to have alignment */
         offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             offset = ALIGN(offset, surf->bo_alignment);
         }
         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
@@ -1566,7 +1575,7 @@ static int si_surface_init_1d(struct radeon_surface_manager *surf_man,
         si_surf_minify(surf, level+i, bpe, i, xalign, yalign, zalign, slice_align, offset);
         /* level0 and first mipmap need to have alignment */
         offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             offset = ALIGN(offset, alignment);
         }
         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
@@ -1668,7 +1677,7 @@ static int si_surface_init_2d(struct radeon_surface_manager *surf_man,
         }
         /* level0 and first mipmap need to have alignment */
         aligned_offset = offset = surf->bo_size;
-        if ((i == 0)) {
+        if (i == 0) {
             aligned_offset = ALIGN(aligned_offset, surf->bo_alignment);
         }
         if (surf->flags & RADEON_SURF_HAS_TILE_MODE_INDEX) {
@@ -1913,7 +1922,7 @@ static void cik_get_2d_params(struct radeon_surface_manager *surf_man,
         sample_split = 1;
         break;
     case CIK__SAMPLE_SPLIT__2:
-        sample_split = 1;
+        sample_split = 2;
         break;
     case CIK__SAMPLE_SPLIT__4:
         sample_split = 4;
@@ -2133,7 +2142,7 @@ static int cik_surface_sanity(struct radeon_surface_manager *surf_man,
         /* default value */
         surf->mtilea = 1;
         surf->bankw = 1;
-        surf->bankw = 1;
+        surf->bankh = 1;
         surf->tile_split = 64;
         surf->stencil_tile_split = 64;
     }
@@ -2394,7 +2403,8 @@ static int cik_surface_best(struct radeon_surface_manager *surf_man,
 /* ===========================================================================
  * public API
  */
-struct radeon_surface_manager *radeon_surface_manager_new(int fd)
+struct radeon_surface_manager *
+radeon_surface_manager_new(int fd)
 {
     struct radeon_surface_manager *surf_man;
 
@@ -2442,7 +2452,8 @@ out_err:
     return NULL;
 }
 
-void radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
+void
+radeon_surface_manager_free(struct radeon_surface_manager *surf_man)
 {
     free(surf_man);
 }
@@ -2514,8 +2525,9 @@ static int radeon_surface_sanity(struct radeon_surface_manager *surf_man,
     return 0;
 }
 
-int radeon_surface_init(struct radeon_surface_manager *surf_man,
-                        struct radeon_surface *surf)
+int
+radeon_surface_init(struct radeon_surface_manager *surf_man,
+                    struct radeon_surface *surf)
 {
     unsigned mode, type;
     int r;
@@ -2530,8 +2542,9 @@ int radeon_surface_init(struct radeon_surface_manager *surf_man,
     return surf_man->surface_init(surf_man, surf);
 }
 
-int radeon_surface_best(struct radeon_surface_manager *surf_man,
-                        struct radeon_surface *surf)
+int
+radeon_surface_best(struct radeon_surface_manager *surf_man,
+                    struct radeon_surface *surf)
 {
     unsigned mode, type;
     int r;