drm/radeon: fix htile buffer size computation for command stream checker
Jerome Glisse [Thu, 13 Dec 2012 17:08:11 +0000 (12:08 -0500)]
Fix the size computation of the htile buffer.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>

drivers/gpu/drm/radeon/evergreen_cs.c
drivers/gpu/drm/radeon/r600_cs.c
drivers/gpu/drm/radeon/radeon_drv.c

index 62c2271..fc7e613 100644 (file)
@@ -507,20 +507,28 @@ static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p,
                /* height is npipes htiles aligned == npipes * 8 pixel aligned */
                nby = round_up(nby, track->npipes * 8);
        } else {
+               /* always assume 8x8 htile */
+               /* align is htile align * 8, htile align vary according to
+                * number of pipe and tile width and nby
+                */
                switch (track->npipes) {
                case 8:
+                       /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
                        nbx = round_up(nbx, 64 * 8);
                        nby = round_up(nby, 64 * 8);
                        break;
                case 4:
+                       /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
                        nbx = round_up(nbx, 64 * 8);
                        nby = round_up(nby, 32 * 8);
                        break;
                case 2:
+                       /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
                        nbx = round_up(nbx, 32 * 8);
                        nby = round_up(nby, 32 * 8);
                        break;
                case 1:
+                       /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
                        nbx = round_up(nbx, 32 * 8);
                        nby = round_up(nby, 16 * 8);
                        break;
@@ -531,9 +539,10 @@ static int evergreen_cs_track_validate_htile(struct radeon_cs_parser *p,
                }
        }
        /* compute number of htile */
-       nbx = nbx / 8;
-       nby = nby / 8;
-       size = nbx * nby * 4;
+       nbx = nbx >> 3;
+       nby = nby >> 3;
+       /* size must be aligned on npipes * 2K boundary */
+       size = roundup(nbx * nby * 4, track->npipes * (2 << 10));
        size += track->htile_offset;
 
        if (size > radeon_bo_size(track->htile_bo)) {
@@ -1790,6 +1799,8 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
        case DB_HTILE_SURFACE:
                /* 8x8 only */
                track->htile_surface = radeon_get_ib_value(p, idx);
+               /* force 8x8 htile width and height */
+               ib[idx] |= 3;
                track->db_dirty = true;
                break;
        case CB_IMMED0_BASE:
index 5d6e7f9..0b4d833 100644 (file)
@@ -657,87 +657,30 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p)
                        /* nby is npipes htiles aligned == npipes * 8 pixel aligned */
                        nby = round_up(nby, track->npipes * 8);
                } else {
-                       /* htile widht & nby (8 or 4) make 2 bits number */
-                       tmp = track->htile_surface & 3;
+                       /* always assume 8x8 htile */
                        /* align is htile align * 8, htile align vary according to
                         * number of pipe and tile width and nby
                         */
                        switch (track->npipes) {
                        case 8:
-                               switch (tmp) {
-                               case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
-                                       nbx = round_up(nbx, 64 * 8);
-                                       nby = round_up(nby, 64 * 8);
-                                       break;
-                               case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
-                               case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
-                                       nbx = round_up(nbx, 64 * 8);
-                                       nby = round_up(nby, 32 * 8);
-                                       break;
-                               case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
-                                       nbx = round_up(nbx, 32 * 8);
-                                       nby = round_up(nby, 32 * 8);
-                                       break;
-                               default:
-                                       return -EINVAL;
-                               }
+                               /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+                               nbx = round_up(nbx, 64 * 8);
+                               nby = round_up(nby, 64 * 8);
                                break;
                        case 4:
-                               switch (tmp) {
-                               case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
-                                       nbx = round_up(nbx, 64 * 8);
-                                       nby = round_up(nby, 32 * 8);
-                                       break;
-                               case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
-                               case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
-                                       nbx = round_up(nbx, 32 * 8);
-                                       nby = round_up(nby, 32 * 8);
-                                       break;
-                               case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
-                                       nbx = round_up(nbx, 32 * 8);
-                                       nby = round_up(nby, 16 * 8);
-                                       break;
-                               default:
-                                       return -EINVAL;
-                               }
+                               /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+                               nbx = round_up(nbx, 64 * 8);
+                               nby = round_up(nby, 32 * 8);
                                break;
                        case 2:
-                               switch (tmp) {
-                               case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
-                                       nbx = round_up(nbx, 32 * 8);
-                                       nby = round_up(nby, 32 * 8);
-                                       break;
-                               case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
-                               case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
-                                       nbx = round_up(nbx, 32 * 8);
-                                       nby = round_up(nby, 16 * 8);
-                                       break;
-                               case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
-                                       nbx = round_up(nbx, 16 * 8);
-                                       nby = round_up(nby, 16 * 8);
-                                       break;
-                               default:
-                                       return -EINVAL;
-                               }
+                               /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+                               nbx = round_up(nbx, 32 * 8);
+                               nby = round_up(nby, 32 * 8);
                                break;
                        case 1:
-                               switch (tmp) {
-                               case 3: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
-                                       nbx = round_up(nbx, 32 * 8);
-                                       nby = round_up(nby, 16 * 8);
-                                       break;
-                               case 2: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 8*/
-                               case 1: /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 4*/
-                                       nbx = round_up(nbx, 16 * 8);
-                                       nby = round_up(nby, 16 * 8);
-                                       break;
-                               case 0: /* HTILE_WIDTH = 4 & HTILE_HEIGHT = 4*/
-                                       nbx = round_up(nbx, 16 * 8);
-                                       nby = round_up(nby, 8 * 8);
-                                       break;
-                               default:
-                                       return -EINVAL;
-                               }
+                               /* HTILE_WIDTH = 8 & HTILE_HEIGHT = 8*/
+                               nbx = round_up(nbx, 32 * 8);
+                               nby = round_up(nby, 16 * 8);
                                break;
                        default:
                                dev_warn(p->dev, "%s:%d invalid num pipes %d\n",
@@ -746,9 +689,10 @@ static int r600_cs_track_validate_db(struct radeon_cs_parser *p)
                        }
                }
                /* compute number of htile */
-               nbx = G_028D24_HTILE_WIDTH(track->htile_surface) ? nbx / 8 : nbx / 4;
-               nby = G_028D24_HTILE_HEIGHT(track->htile_surface) ? nby / 8 : nby / 4;
-               size = nbx * nby * 4;
+               nbx = nbx >> 3;
+               nby = nby >> 3;
+               /* size must be aligned on npipes * 2K boundary */
+               size = roundup(nbx * nby * 4, track->npipes * (2 << 10));
                size += track->htile_offset;
 
                if (size > radeon_bo_size(track->htile_bo)) {
@@ -1492,6 +1436,8 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
                break;
        case DB_HTILE_SURFACE:
                track->htile_surface = radeon_get_ib_value(p, idx);
+               /* force 8x8 htile width and height */
+               ib[idx] |= 3;
                track->db_dirty = true;
                break;
        case SQ_PGM_START_FS:
index 91b6427..12e9912 100644 (file)
  *   2.23.0 - allow STRMOUT_BASE_UPDATE on RS780 and RS880
  *   2.24.0 - eg only: allow MIP_ADDRESS=0 for MSAA textures
  *   2.25.0 - eg+: new info request for num SE and num SH
+ *   2.26.0 - r600-eg: fix htile size computation
  */
 #define KMS_DRIVER_MAJOR       2
-#define KMS_DRIVER_MINOR       25
+#define KMS_DRIVER_MINOR       26
 #define KMS_DRIVER_PATCHLEVEL  0
 int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
 int radeon_driver_unload_kms(struct drm_device *dev);