diff mbox

drm/radeon: fix htile buffer size computation for command stream checker

Message ID 1355418491-3904-1-git-send-email-j.glisse@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Jerome Glisse Dec. 13, 2012, 5:08 p.m. UTC
From: Jerome Glisse <jglisse@redhat.com>

Fix the size computation of the htile buffer.

Signed-off-by: Jerome Glisse <jglisse@redhat.com>
---
 drivers/gpu/drm/radeon/evergreen_cs.c | 17 +++++--
 drivers/gpu/drm/radeon/r600_cs.c      | 92 ++++++++---------------------------
 drivers/gpu/drm/radeon/radeon_drv.c   |  3 +-
 3 files changed, 35 insertions(+), 77 deletions(-)

Comments

Alex Deucher Dec. 13, 2012, 11:52 p.m. UTC | #1
On Thu, Dec 13, 2012 at 12:08 PM,  <j.glisse@gmail.com> wrote:
> From: Jerome Glisse <jglisse@redhat.com>
>
> Fix the size computation of the htile buffer.
>
> Signed-off-by: Jerome Glisse <jglisse@redhat.com>

Reviewed-by: Alex Deucher <alexander.deucher@amd.com>

> ---
>  drivers/gpu/drm/radeon/evergreen_cs.c | 17 +++++--
>  drivers/gpu/drm/radeon/r600_cs.c      | 92 ++++++++---------------------------
>  drivers/gpu/drm/radeon/radeon_drv.c   |  3 +-
>  3 files changed, 35 insertions(+), 77 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
> index 62c2271..fc7e613 100644
> --- a/drivers/gpu/drm/radeon/evergreen_cs.c
> +++ b/drivers/gpu/drm/radeon/evergreen_cs.c
> @@ -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:
> diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
> index 5d6e7f9..0b4d833 100644
> --- a/drivers/gpu/drm/radeon/r600_cs.c
> +++ b/drivers/gpu/drm/radeon/r600_cs.c
> @@ -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:
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
> index 91b6427..12e9912 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -66,9 +66,10 @@
>   *   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);
> --
> 1.7.11.7
>
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel
diff mbox

Patch

diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 62c2271..fc7e613 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -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:
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 5d6e7f9..0b4d833 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -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:
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 91b6427..12e9912 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -66,9 +66,10 @@ 
  *   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);