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;
                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;
        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]);
        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)) {
 
        /* 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:
         */
        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 */
                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:
 
 #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
 
  *   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);