r600g: use CP DMA for buffer clears on evergreen+
[mesa.git] / src / gallium / drivers / r300 / r300_emit.c
index cb6c46e5e6c20a54a0755402097b737f3eb1b5bb..b038a9719aebdede7476c2a15f6b8ef506e4f4ed 100644 (file)
@@ -47,6 +47,8 @@ void r300_emit_blend_state(struct r300_context* r300,
     if (fb->nr_cbufs) {
         if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) {
             WRITE_CS_TABLE(blend->cb_noclamp, size);
+        } else if (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16X16_FLOAT) {
+            WRITE_CS_TABLE(blend->cb_noclamp_noalpha, size);
         } else {
             unsigned swz = r300_surface(fb->cbufs[0])->colormask_swizzle;
             WRITE_CS_TABLE(blend->cb_clamp[swz], size);
@@ -86,7 +88,9 @@ void r300_emit_dsa_state(struct r300_context* r300, unsigned size, void* state)
     /* Choose the alpha ref value between 8-bit (FG_ALPHA_FUNC.AM_VAL) and
      * 16-bit (FG_ALPHA_VALUE). */
     if (is_r500 && (alpha_func & R300_FG_ALPHA_FUNC_ENABLE)) {
-        if (fb->nr_cbufs && fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT) {
+        if (fb->nr_cbufs &&
+            (fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16A16_FLOAT ||
+             fb->cbufs[0]->format == PIPE_FORMAT_R16G16B16X16_FLOAT)) {
             alpha_func |= R500_FG_ALPHA_FUNC_FP16_ENABLE;
         } else {
             alpha_func |= R500_FG_ALPHA_FUNC_8BIT;
@@ -399,14 +403,17 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
 
     BEGIN_CS(size);
 
-    /* NUM_MULTIWRITES replicates COLOR[0] to all colorbuffers, which is not
-     * what we usually want. */
     if (r300->screen->caps.is_r500) {
         rb3d_cctl = R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE;
     }
+    /* NUM_MULTIWRITES replicates COLOR[0] to all colorbuffers. */
     if (fb->nr_cbufs && r300->fb_multiwrite) {
         rb3d_cctl |= R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs);
     }
+    if (r300->cmask_in_use) {
+        rb3d_cctl |= R300_RB3D_CCTL_AA_COMPRESSION_ENABLE |
+                     R300_RB3D_CCTL_CMASK_ENABLE;
+    }
 
     OUT_CS_REG(R300_RB3D_CCTL, rb3d_cctl);
 
@@ -419,6 +426,17 @@ void r300_emit_fb_state(struct r300_context* r300, unsigned size, void* state)
 
         OUT_CS_REG(R300_RB3D_COLORPITCH0 + (4 * i), surf->pitch);
         OUT_CS_RELOC(surf);
+
+        if (r300->cmask_in_use && i == 0) {
+            OUT_CS_REG(R300_RB3D_CMASK_OFFSET0, 0);
+            OUT_CS_REG(R300_RB3D_CMASK_PITCH0, surf->pitch_cmask);
+            OUT_CS_REG(R300_RB3D_COLOR_CLEAR_VALUE, r300->color_clear_value);
+            if (r300->screen->caps.is_r500 && r300->screen->info.drm_minor >= 29) {
+                OUT_CS_REG_SEQ(R500_RB3D_COLOR_CLEAR_VALUE_AR, 2);
+                OUT_CS(r300->color_clear_value_ar);
+                OUT_CS(r300->color_clear_value_gb);
+            }
+        }
     }
 
     /* Set up the ZB part of the CBZB clear. */
@@ -1201,9 +1219,6 @@ void r300_emit_hiz_clear(struct r300_context *r300, unsigned size, void *state)
     tex = r300_resource(fb->zsbuf->texture);
 
     BEGIN_CS(size);
-    OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
-        R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
-        R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
     OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_HIZ, 2);
     OUT_CS(0);
     OUT_CS(tex->tex.hiz_dwords[fb->zsbuf->u.tex.level]);
@@ -1226,9 +1241,6 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state
     tex = r300_resource(fb->zsbuf->texture);
 
     BEGIN_CS(size);
-    OUT_CS_REG(R300_ZB_ZCACHE_CTLSTAT,
-        R300_ZB_ZCACHE_CTLSTAT_ZC_FLUSH_FLUSH_AND_FREE |
-        R300_ZB_ZCACHE_CTLSTAT_ZC_FREE_FREE);
     OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_ZMASK, 2);
     OUT_CS(0);
     OUT_CS(tex->tex.zmask_dwords[fb->zsbuf->u.tex.level]);
@@ -1240,6 +1252,27 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state
     r300_mark_atom_dirty(r300, &r300->hyperz_state);
 }
 
+void r300_emit_cmask_clear(struct r300_context *r300, unsigned size, void *state)
+{
+    struct pipe_framebuffer_state *fb =
+        (struct pipe_framebuffer_state*)r300->fb_state.state;
+    struct r300_resource *tex;
+    CS_LOCALS(r300);
+
+    tex = r300_resource(fb->cbufs[0]->texture);
+
+    BEGIN_CS(size);
+    OUT_CS_PKT3(R300_PACKET3_3D_CLEAR_CMASK, 2);
+    OUT_CS(0);
+    OUT_CS(tex->tex.cmask_dwords);
+    OUT_CS(0);
+    END_CS;
+
+    /* Mark the current zbuffer's zmask as in use. */
+    r300->cmask_in_use = TRUE;
+    r300_mark_fb_state_dirty(r300, R300_CHANGED_CMASK_ENABLE);
+}
+
 void r300_emit_ztop_state(struct r300_context* r300,
                           unsigned size, void* state)
 {