drm/radeon/kms: manage r300 CMASK RAM access and allow CMASK clear
authorMarek Olšák <maraeo@gmail.com>
Wed, 5 Jan 2011 04:46:48 +0000 (05:46 +0100)
committerDave Airlie <airlied@redhat.com>
Thu, 6 Jan 2011 03:00:45 +0000 (13:00 +1000)
The CMASK RAM is for colorbuffer compression (used in conjunction
with MSAA). Only one user (filp) can access it.

The CMASK RAM access is managed in the same way as Hyper-Z, but there is
a separate ioctl, because an app that uses MSAA does not necessarily
have to use zbuffering.

Signed-off-by: Marek Olšák <maraeo@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
drivers/gpu/drm/radeon/r300.c
drivers/gpu/drm/radeon/r300d.h
drivers/gpu/drm/radeon/radeon.h
drivers/gpu/drm/radeon/radeon_drv.c
drivers/gpu/drm/radeon/radeon_kms.c
include/drm/radeon_drm.h

index 36b4f7b48d6aa9eec29108fb282a7270db82bc4a..23fee54c3b753fe928d615a5214f096ecd94f568 100644 (file)
@@ -745,6 +745,11 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
                break;
        case 0x4E00:
                /* RB3D_CCTL */
+               if ((idx_value & (1 << 10)) && /* CMASK_ENABLE */
+                   p->rdev->cmask_filp != p->filp) {
+                       DRM_ERROR("Invalid RB3D_CCTL: Cannot enable CMASK.\n");
+                       return -EINVAL;
+               }
                track->num_cb = ((idx_value >> 5) & 0x3) + 1;
                break;
        case 0x4E38:
@@ -1206,6 +1211,10 @@ static int r300_packet3_check(struct radeon_cs_parser *p,
                if (p->rdev->hyperz_filp != p->filp)
                        return -EINVAL;
                break;
+       case PACKET3_3D_CLEAR_CMASK:
+               if (p->rdev->cmask_filp != p->filp)
+                       return -EINVAL;
+               break;
        case PACKET3_NOP:
                break;
        default:
index 0c036c60d9df4f8d167ece6b9dfe4909f67c583e..1f519a5ffb8c11d94adf2980445d90828e2ca88e 100644 (file)
@@ -54,6 +54,7 @@
 #define                PACKET3_3D_DRAW_IMMD_2          0x35
 #define                PACKET3_3D_DRAW_INDX_2          0x36
 #define                PACKET3_3D_CLEAR_HIZ            0x37
+#define                PACKET3_3D_CLEAR_CMASK          0x38
 #define                PACKET3_BITBLT_MULTI            0x9B
 
 #define PACKET0(reg, n)        (CP_PACKET0 |                                   \
index 140eaceab2796bbefbe32abdf83d0226ae062c04..a835d95021d13df6470fad05e7fa388aff6795cc 100644 (file)
@@ -1168,8 +1168,9 @@ struct radeon_device {
        uint8_t                 audio_category_code;
 
        struct notifier_block acpi_nb;
-       /* only one userspace can use Hyperz features at a time */
+       /* only one userspace can use Hyperz features or CMASK at a time */
        struct drm_file *hyperz_filp;
+       struct drm_file *cmask_filp;
        /* i2c buses */
        struct radeon_i2c_chan *i2c_bus[RADEON_MAX_I2C_BUS];
 };
index 18225f21ee0f2d0997560f08964f1e9d3aae4ac0..be5cb4f28c294b0713d915db5ae60c669e8e3aff 100644 (file)
@@ -48,7 +48,7 @@
  * - 2.5.0 - add get accel 2 to work around ddx breakage for evergreen
  * - 2.6.0 - add tiling config query (r6xx+), add initial HiZ support (r300->r500)
  *   2.7.0 - fixups for r600 2D tiling support. (no external ABI change), add eg dyn gpr regs
- *   2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf
+ *   2.8.0 - pageflip support, r500 US_FORMAT regs. r500 ARGB2101010 colorbuf, r300->r500 CMASK
  */
 #define KMS_DRIVER_MAJOR       2
 #define KMS_DRIVER_MINOR       8
index b2686334d46bf9356441bd7fd086cf5988493fcc..28a53e4a925f0c15a23b0d85dbc8145c1e4036a5 100644 (file)
@@ -96,9 +96,27 @@ out:
        return r;
 }
 
+static void radeon_set_filp_rights(struct drm_device *dev,
+                                  struct drm_file **owner,
+                                  struct drm_file *applier,
+                                  uint32_t *value)
+{
+       mutex_lock(&dev->struct_mutex);
+       if (*value == 1) {
+               /* wants rights */
+               if (!*owner)
+                       *owner = applier;
+       } else if (*value == 0) {
+               /* revokes rights */
+               if (*owner == applier)
+                       *owner = NULL;
+       }
+       *value = *owner == applier ? 1 : 0;
+       mutex_unlock(&dev->struct_mutex);
+}
 
 /*
- * Userspace get informations ioctl
+ * Userspace get information ioctl
  */
 int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
 {
@@ -173,18 +191,15 @@ int radeon_info_ioctl(struct drm_device *dev, void *data, struct drm_file *filp)
                        DRM_DEBUG_KMS("WANT_HYPERZ: invalid value %d\n", value);
                        return -EINVAL;
                }
-               mutex_lock(&dev->struct_mutex);
-               if (value == 1) {
-                       /* wants hyper-z */
-                       if (!rdev->hyperz_filp)
-                               rdev->hyperz_filp = filp;
-               } else if (value == 0) {
-                       /* revokes hyper-z */
-                       if (rdev->hyperz_filp == filp)
-                               rdev->hyperz_filp = NULL;
+               radeon_set_filp_rights(dev, &rdev->hyperz_filp, filp, &value);
+               break;
+       case RADEON_INFO_WANT_CMASK:
+               /* The same logic as Hyper-Z. */
+               if (value >= 2) {
+                       DRM_DEBUG_KMS("WANT_CMASK: invalid value %d\n", value);
+                       return -EINVAL;
                }
-               value = rdev->hyperz_filp == filp ?  1 : 0;
-               mutex_unlock(&dev->struct_mutex);
+               radeon_set_filp_rights(dev, &rdev->cmask_filp, filp, &value);
                break;
        default:
                DRM_DEBUG_KMS("Invalid request %d\n", info->request);
index 10f8b53bdd404d47c80cd8d9ee876c57b1c2b8a5..e95a86b8b689b530ec8981ad1525bb6b49c2f142 100644 (file)
@@ -906,6 +906,7 @@ struct drm_radeon_cs {
 #define RADEON_INFO_ACCEL_WORKING2     0x05
 #define RADEON_INFO_TILING_CONFIG      0x06
 #define RADEON_INFO_WANT_HYPERZ                0x07
+#define RADEON_INFO_WANT_CMASK         0x08 /* get access to CMASK on r300 */
 
 struct drm_radeon_info {
        uint32_t                request;