diff mbox

drm/radeon: add proper checking of RESOLVE_BOX command for r600-r700

Message ID 1345811256-21680-1-git-send-email-maraeo@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Marek Olšák Aug. 24, 2012, 12:27 p.m. UTC
Checking of the second colorbuffer was skipped on r700, because
CB_TARGET_MASK was 0xf. With r600, CB_TARGET_MASK is changed to 0xff,
so we must set the number of samples of the second colorbuffer to 1 in order
to pass the CS checker.
The DRM version is bumped, because RESOLVE_BOX is always rejected without this
fix on r600.

Signed-off-by: Marek Olšák <maraeo@gmail.com>
---
 drivers/gpu/drm/radeon/r600_cs.c     |   19 +++++++++++++++++--
 drivers/gpu/drm/radeon/r600d.h       |    8 ++++++++
 drivers/gpu/drm/radeon/radeon_drv.c  |    3 ++-
 drivers/gpu/drm/radeon/reg_srcs/r600 |    1 -
 4 files changed, 27 insertions(+), 4 deletions(-)

Comments

Jerome Glisse Aug. 24, 2012, 2:39 p.m. UTC | #1
On Fri, Aug 24, 2012 at 8:27 AM, Marek Olšák <maraeo@gmail.com> wrote:
> Checking of the second colorbuffer was skipped on r700, because
> CB_TARGET_MASK was 0xf. With r600, CB_TARGET_MASK is changed to 0xff,
> so we must set the number of samples of the second colorbuffer to 1 in order
> to pass the CS checker.
> The DRM version is bumped, because RESOLVE_BOX is always rejected without this
> fix on r600.
>
> Signed-off-by: Marek Olšák <maraeo@gmail.com>

Reviewed-by: Jerome Glisse <jglisse@redhat.com>

> ---
>  drivers/gpu/drm/radeon/r600_cs.c     |   19 +++++++++++++++++--
>  drivers/gpu/drm/radeon/r600d.h       |    8 ++++++++
>  drivers/gpu/drm/radeon/radeon_drv.c  |    3 ++-
>  drivers/gpu/drm/radeon/reg_srcs/r600 |    1 -
>  4 files changed, 27 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
> index 8866937..f37676d 100644
> --- a/drivers/gpu/drm/radeon/r600_cs.c
> +++ b/drivers/gpu/drm/radeon/r600_cs.c
> @@ -63,6 +63,7 @@ struct r600_cs_track {
>         u32                     cb_color_size_idx[8]; /* unused */
>         u32                     cb_target_mask;
>         u32                     cb_shader_mask;  /* unused */
> +       bool                    is_resolve;
>         u32                     cb_color_size[8];
>         u32                     vgt_strmout_en;
>         u32                     vgt_strmout_buffer_en;
> @@ -321,6 +322,7 @@ static void r600_cs_track_init(struct r600_cs_track *track)
>                 track->cb_color_tile_offset[i] = 0xFFFFFFFF;
>                 track->cb_color_mask[i] = 0xFFFFFFFF;
>         }
> +       track->is_resolve = false;
>         track->nsamples = 16;
>         track->log_nsamples = 4;
>         track->cb_target_mask = 0xFFFFFFFF;
> @@ -359,6 +361,8 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
>         volatile u32 *ib = p->ib.ptr;
>         unsigned array_mode;
>         u32 format;
> +       /* When resolve is used, the second colorbuffer has always 1 sample. */
> +       unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples;
>
>         size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
>         format = G_0280A0_FORMAT(track->cb_color_info[i]);
> @@ -382,7 +386,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
>         array_check.group_size = track->group_size;
>         array_check.nbanks = track->nbanks;
>         array_check.npipes = track->npipes;
> -       array_check.nsamples = track->nsamples;
> +       array_check.nsamples = nsamples;
>         array_check.blocksize = r600_fmt_get_blocksize(format);
>         if (r600_get_array_mode_alignment(&array_check,
>                                           &pitch_align, &height_align, &depth_align, &base_align)) {
> @@ -428,7 +432,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
>
>         /* check offset */
>         tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) *
> -             r600_fmt_get_blocksize(format) * track->nsamples;
> +             r600_fmt_get_blocksize(format) * nsamples;
>         switch (array_mode) {
>         default:
>         case V_0280A0_ARRAY_LINEAR_GENERAL:
> @@ -799,6 +803,12 @@ static int r600_cs_track_check(struct radeon_cs_parser *p)
>          */
>         if (track->cb_dirty) {
>                 tmp = track->cb_target_mask;
> +
> +               /* We must check both colorbuffers for RESOLVE. */
> +               if (track->is_resolve) {
> +                       tmp |= 0xff;
> +               }
> +
>                 for (i = 0; i < 8; i++) {
>                         if ((tmp >> (i * 4)) & 0xF) {
>                                 /* at least one component is enabled */
> @@ -1288,6 +1298,11 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
>                 track->nsamples = 1 << tmp;
>                 track->cb_dirty = true;
>                 break;
> +       case R_028808_CB_COLOR_CONTROL:
> +               tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx));
> +               track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX;
> +               track->cb_dirty = true;
> +               break;
>         case R_0280A0_CB_COLOR0_INFO:
>         case R_0280A4_CB_COLOR1_INFO:
>         case R_0280A8_CB_COLOR2_INFO:
> diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
> index bdb69a6..fa6f370 100644
> --- a/drivers/gpu/drm/radeon/r600d.h
> +++ b/drivers/gpu/drm/radeon/r600d.h
> @@ -66,6 +66,14 @@
>  #define        CC_RB_BACKEND_DISABLE                           0x98F4
>  #define                BACKEND_DISABLE(x)                              ((x) << 16)
>
> +#define R_028808_CB_COLOR_CONTROL                      0x28808
> +#define   S_028808_SPECIAL_OP(x)                       (((x) & 0x7) << 4)
> +#define   G_028808_SPECIAL_OP(x)                       (((x) >> 4) & 0x7)
> +#define   C_028808_SPECIAL_OP                          0xFFFFFF8F
> +#define     V_028808_SPECIAL_NORMAL                     0x00
> +#define     V_028808_SPECIAL_DISABLE                    0x01
> +#define     V_028808_SPECIAL_RESOLVE_BOX                0x07
> +
>  #define        CB_COLOR0_BASE                                  0x28040
>  #define        CB_COLOR1_BASE                                  0x28044
>  #define        CB_COLOR2_BASE                                  0x28048
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
> index 27d22d7..8c593ea 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -63,9 +63,10 @@
>   *   2.19.0 - r600-eg: MSAA textures
>   *   2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query
>   *   2.21.0 - r600-r700: FMASK and CMASK
> + *   2.22.0 - r600 only: RESOLVE_BOX allowed
>   */
>  #define KMS_DRIVER_MAJOR       2
> -#define KMS_DRIVER_MINOR       21
> +#define KMS_DRIVER_MINOR       22
>  #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);
> diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600
> index f93e45d..20bfbda 100644
> --- a/drivers/gpu/drm/radeon/reg_srcs/r600
> +++ b/drivers/gpu/drm/radeon/reg_srcs/r600
> @@ -744,7 +744,6 @@ r600 0x9400
>  0x00028C38 CB_CLRCMP_DST
>  0x00028C3C CB_CLRCMP_MSK
>  0x00028C34 CB_CLRCMP_SRC
> -0x00028808 CB_COLOR_CONTROL
>  0x0002842C CB_FOG_BLUE
>  0x00028428 CB_FOG_GREEN
>  0x00028424 CB_FOG_RED
> --
> 1.7.9.5
>
> _______________________________________________
> 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/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c
index 8866937..f37676d 100644
--- a/drivers/gpu/drm/radeon/r600_cs.c
+++ b/drivers/gpu/drm/radeon/r600_cs.c
@@ -63,6 +63,7 @@  struct r600_cs_track {
 	u32			cb_color_size_idx[8]; /* unused */
 	u32			cb_target_mask;
 	u32			cb_shader_mask;  /* unused */
+	bool			is_resolve;
 	u32			cb_color_size[8];
 	u32			vgt_strmout_en;
 	u32			vgt_strmout_buffer_en;
@@ -321,6 +322,7 @@  static void r600_cs_track_init(struct r600_cs_track *track)
 		track->cb_color_tile_offset[i] = 0xFFFFFFFF;
 		track->cb_color_mask[i] = 0xFFFFFFFF;
 	}
+	track->is_resolve = false;
 	track->nsamples = 16;
 	track->log_nsamples = 4;
 	track->cb_target_mask = 0xFFFFFFFF;
@@ -359,6 +361,8 @@  static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 	volatile u32 *ib = p->ib.ptr;
 	unsigned array_mode;
 	u32 format;
+	/* When resolve is used, the second colorbuffer has always 1 sample. */
+	unsigned nsamples = track->is_resolve && i == 1 ? 1 : track->nsamples;
 
 	size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i];
 	format = G_0280A0_FORMAT(track->cb_color_info[i]);
@@ -382,7 +386,7 @@  static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 	array_check.group_size = track->group_size;
 	array_check.nbanks = track->nbanks;
 	array_check.npipes = track->npipes;
-	array_check.nsamples = track->nsamples;
+	array_check.nsamples = nsamples;
 	array_check.blocksize = r600_fmt_get_blocksize(format);
 	if (r600_get_array_mode_alignment(&array_check,
 					  &pitch_align, &height_align, &depth_align, &base_align)) {
@@ -428,7 +432,7 @@  static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i)
 
 	/* check offset */
 	tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) *
-	      r600_fmt_get_blocksize(format) * track->nsamples;
+	      r600_fmt_get_blocksize(format) * nsamples;
 	switch (array_mode) {
 	default:
 	case V_0280A0_ARRAY_LINEAR_GENERAL:
@@ -799,6 +803,12 @@  static int r600_cs_track_check(struct radeon_cs_parser *p)
 	 */
 	if (track->cb_dirty) {
 		tmp = track->cb_target_mask;
+
+		/* We must check both colorbuffers for RESOLVE. */
+		if (track->is_resolve) {
+			tmp |= 0xff;
+		}
+
 		for (i = 0; i < 8; i++) {
 			if ((tmp >> (i * 4)) & 0xF) {
 				/* at least one component is enabled */
@@ -1288,6 +1298,11 @@  static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx)
 		track->nsamples = 1 << tmp;
 		track->cb_dirty = true;
 		break;
+	case R_028808_CB_COLOR_CONTROL:
+		tmp = G_028808_SPECIAL_OP(radeon_get_ib_value(p, idx));
+		track->is_resolve = tmp == V_028808_SPECIAL_RESOLVE_BOX;
+		track->cb_dirty = true;
+		break;
 	case R_0280A0_CB_COLOR0_INFO:
 	case R_0280A4_CB_COLOR1_INFO:
 	case R_0280A8_CB_COLOR2_INFO:
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h
index bdb69a6..fa6f370 100644
--- a/drivers/gpu/drm/radeon/r600d.h
+++ b/drivers/gpu/drm/radeon/r600d.h
@@ -66,6 +66,14 @@ 
 #define	CC_RB_BACKEND_DISABLE				0x98F4
 #define		BACKEND_DISABLE(x)				((x) << 16)
 
+#define R_028808_CB_COLOR_CONTROL			0x28808
+#define   S_028808_SPECIAL_OP(x)                       (((x) & 0x7) << 4)
+#define   G_028808_SPECIAL_OP(x)                       (((x) >> 4) & 0x7)
+#define   C_028808_SPECIAL_OP                          0xFFFFFF8F
+#define     V_028808_SPECIAL_NORMAL                     0x00
+#define     V_028808_SPECIAL_DISABLE                    0x01
+#define     V_028808_SPECIAL_RESOLVE_BOX                0x07
+
 #define	CB_COLOR0_BASE					0x28040
 #define	CB_COLOR1_BASE					0x28044
 #define	CB_COLOR2_BASE					0x28048
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index 27d22d7..8c593ea 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -63,9 +63,10 @@ 
  *   2.19.0 - r600-eg: MSAA textures
  *   2.20.0 - r600-si: RADEON_INFO_TIMESTAMP query
  *   2.21.0 - r600-r700: FMASK and CMASK
+ *   2.22.0 - r600 only: RESOLVE_BOX allowed
  */
 #define KMS_DRIVER_MAJOR	2
-#define KMS_DRIVER_MINOR	21
+#define KMS_DRIVER_MINOR	22
 #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);
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600
index f93e45d..20bfbda 100644
--- a/drivers/gpu/drm/radeon/reg_srcs/r600
+++ b/drivers/gpu/drm/radeon/reg_srcs/r600
@@ -744,7 +744,6 @@  r600 0x9400
 0x00028C38 CB_CLRCMP_DST
 0x00028C3C CB_CLRCMP_MSK
 0x00028C34 CB_CLRCMP_SRC
-0x00028808 CB_COLOR_CONTROL
 0x0002842C CB_FOG_BLUE
 0x00028428 CB_FOG_GREEN
 0x00028424 CB_FOG_RED