v2: check for NULL cbufs
---
 src/gallium/drivers/r600/evergreen_state.c | 24 +++++++++++++++++++-----
 src/gallium/drivers/r600/r600_hw_context.c | 18 ++++++++++++++----
 src/gallium/drivers/r600/r600_resource.h   |  3 +++
 src/gallium/drivers/r600/r600_texture.c    | 25 ++++++++++++++++++++++++-
 4 files changed, 60 insertions(+), 10 deletions(-)

diff --git a/src/gallium/drivers/r600/evergreen_state.c 
b/src/gallium/drivers/r600/evergreen_state.c
index 887f736..469b3a3 100644
--- a/src/gallium/drivers/r600/evergreen_state.c
+++ b/src/gallium/drivers/r600/evergreen_state.c
@@ -1555,8 +1555,11 @@ void evergreen_init_color_surface(struct r600_context 
*rctx,
                surf->export_16bpc = true;
        }
 
-       if (rtex->fmask_size && rtex->cmask_size) {
-               color_info |= S_028C70_COMPRESSION(1) | S_028C70_FAST_CLEAR(1);
+       if (rtex->fmask_size) {
+               color_info |= S_028C70_COMPRESSION(1);
+       }
+       if (rtex->cmask_size) {
+               color_info |= S_028C70_FAST_CLEAR(1);
        }
 
        base_offset = r600_resource_va(rctx->b.b.screen, pipe_tex);
@@ -1574,11 +1577,15 @@ void evergreen_init_color_surface(struct r600_context 
*rctx,
                                      
S_028C6C_SLICE_MAX(surf->base.u.tex.last_layer);
        }
        surf->cb_color_attrib = color_attrib;
-       if (rtex->fmask_size && rtex->cmask_size) {
+       if (rtex->fmask_size) {
                surf->cb_color_fmask = (base_offset + rtex->fmask_offset) >> 8;
-               surf->cb_color_cmask = (base_offset + rtex->cmask_offset) >> 8;
        } else {
                surf->cb_color_fmask = surf->cb_color_base;
+       }
+       if (rtex->cmask_size) {
+               uint64_t va = r600_resource_va(rctx->b.b.screen, 
&rtex->cmask->b.b);
+               surf->cb_color_cmask = (va + rtex->cmask_offset) >> 8;
+       } else {
                surf->cb_color_cmask = surf->cb_color_base;
        }
        surf->cb_color_fmask_slice = 
S_028C88_TILE_MAX(rtex->fmask_slice_tile_max);
@@ -2180,6 +2187,13 @@ static void evergreen_emit_framebuffer_state(struct 
r600_context *rctx, struct r
                                                       &rctx->b.rings.gfx,
                                                       (struct 
r600_resource*)cb->base.texture,
                                                       RADEON_USAGE_READWRITE);
+               unsigned cmask_reloc = 0;
+               if (tex->cmask && tex->cmask != &tex->resource) {
+                       cmask_reloc = r600_context_bo_reloc(&rctx->b, 
&rctx->b.rings.gfx,
+                               tex->cmask, RADEON_USAGE_READWRITE);
+               } else {
+                       cmask_reloc = reloc;
+               }
 
                r600_write_context_reg_seq(cs, R_028C60_CB_COLOR0_BASE + i * 
0x3C, 13);
                radeon_emit(cs, cb->cb_color_base);     /* 
R_028C60_CB_COLOR0_BASE */
@@ -2208,7 +2222,7 @@ static void evergreen_emit_framebuffer_state(struct 
r600_context *rctx, struct r
                radeon_emit(cs, reloc);
 
                radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* 
R_028C7C_CB_COLOR0_CMASK */
-               radeon_emit(cs, reloc);
+               radeon_emit(cs, cmask_reloc);
 
                radeon_emit(cs, PKT3(PKT3_NOP, 0, 0)); /* 
R_028C84_CB_COLOR0_FMASK */
                radeon_emit(cs, reloc);
diff --git a/src/gallium/drivers/r600/r600_hw_context.c 
b/src/gallium/drivers/r600/r600_hw_context.c
index d985af9..9c0a78e 100644
--- a/src/gallium/drivers/r600/r600_hw_context.c
+++ b/src/gallium/drivers/r600/r600_hw_context.c
@@ -644,11 +644,15 @@ void r600_flag_resource_cache_flush(struct r600_context 
*rctx,
 
        /* Check colorbuffers. */
        for (i = 0; i < rctx->framebuffer.state.nr_cbufs; i++) {
-               if (rctx->framebuffer.state.cbufs[i] &&
-                   rctx->framebuffer.state.cbufs[i]->texture == res) {
-                       struct r600_texture *tex =
-                               (struct 
r600_texture*)rctx->framebuffer.state.cbufs[i]->texture;
+               struct r600_texture *tex;
 
+               if (rctx->framebuffer.state.cbufs[i] == NULL) {
+                   continue;
+               }
+
+               tex = (struct 
r600_texture*)rctx->framebuffer.state.cbufs[i]->texture;
+
+               if (rctx->framebuffer.state.cbufs[i]->texture == res) {
                        rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB |
                                       R600_CONTEXT_FLUSH_AND_INV |
                                       R600_CONTEXT_WAIT_3D_IDLE;
@@ -658,6 +662,12 @@ void r600_flag_resource_cache_flush(struct r600_context 
*rctx,
                        }
                        break;
                }
+
+               if (tex && tex->cmask && tex->cmask != &tex->resource && 
&tex->cmask->b.b == res) {
+                       rctx->b.flags |= R600_CONTEXT_FLUSH_AND_INV_CB_META |
+                                      R600_CONTEXT_FLUSH_AND_INV |
+                                      R600_CONTEXT_WAIT_3D_IDLE;
+               }
        }
 
        /* Check a depth buffer. */
diff --git a/src/gallium/drivers/r600/r600_resource.h 
b/src/gallium/drivers/r600/r600_resource.h
index 92b9cc5..92e57b6 100644
--- a/src/gallium/drivers/r600/r600_resource.h
+++ b/src/gallium/drivers/r600/r600_resource.h
@@ -71,6 +71,7 @@ struct r600_texture {
        /* use htile only for first level */
        float                           depth_clear;
 
+       struct r600_resource            *cmask;
        unsigned                        color_clear_value[2];
 };
 
@@ -152,6 +153,8 @@ void r600_texture_get_fmask_info(struct r600_screen 
*rscreen,
 void r600_texture_get_cmask_info(struct r600_screen *rscreen,
                                 struct r600_texture *rtex,
                                 struct r600_cmask_info *out);
+void r600_texture_init_cmask(struct r600_screen *rscreen,
+                            struct r600_texture *rtex);
 struct pipe_resource *r600_texture_create(struct pipe_screen *screen,
                                        const struct pipe_resource *templ);
 struct pipe_resource *r600_texture_from_handle(struct pipe_screen *screen,
diff --git a/src/gallium/drivers/r600/r600_texture.c 
b/src/gallium/drivers/r600/r600_texture.c
index 07e7c6c..8ba41d1 100644
--- a/src/gallium/drivers/r600/r600_texture.c
+++ b/src/gallium/drivers/r600/r600_texture.c
@@ -301,6 +301,9 @@ static void r600_texture_destroy(struct pipe_screen *screen,
                pipe_resource_reference((struct pipe_resource 
**)&rtex->flushed_depth_texture, NULL);
 
         pipe_resource_reference((struct pipe_resource**)&rtex->htile, NULL);
+       if (rtex->cmask != &rtex->resource) {
+           pipe_resource_reference((struct pipe_resource**)&rtex->cmask, NULL);
+       }
        pb_reference(&resource->buf, NULL);
        FREE(rtex);
 }
@@ -431,6 +434,24 @@ static void r600_texture_allocate_cmask(struct r600_screen 
*rscreen,
 #endif
 }
 
+void r600_texture_init_cmask(struct r600_screen *rscreen,
+                            struct r600_texture *rtex) {
+    struct r600_cmask_info cmask;
+
+    assert(rtex->cmask_size == 0);
+
+    r600_texture_get_cmask_info(rscreen, rtex, &cmask);
+    rtex->cmask_slice_tile_max = cmask.slice_tile_max;
+    rtex->cmask_offset = 0;
+    rtex->cmask_size = cmask.size;
+    rtex->cmask = (struct r600_resource *)pipe_buffer_create(&rscreen->b.b,
+           PIPE_BIND_CUSTOM, PIPE_USAGE_STATIC, rtex->cmask_size);
+
+    if (rtex->cmask == NULL) {
+       rtex->cmask_size = 0;
+    }
+}
+
 static struct r600_texture *
 r600_texture_create_object(struct pipe_screen *screen,
                           const struct pipe_resource *base,
@@ -464,9 +485,11 @@ r600_texture_create_object(struct pipe_screen *screen,
                return NULL;
        }
 
+       rtex->cmask = NULL;
        if (base->nr_samples > 1 && !rtex->is_depth && !buf) {
                r600_texture_allocate_fmask(rscreen, rtex);
                r600_texture_allocate_cmask(rscreen, rtex);
+               rtex->cmask = &rtex->resource;
        }
 
        if (!rtex->is_depth && base->nr_samples > 1 &&
@@ -532,7 +555,7 @@ r600_texture_create_object(struct pipe_screen *screen,
 
        if (rtex->cmask_size) {
                /* Initialize the cmask to 0xCC (= compressed state). */
-               r600_screen_clear_buffer(rscreen, &rtex->resource.b.b,
+               r600_screen_clear_buffer(rscreen, &rtex->cmask->b.b,
                                         rtex->cmask_offset, rtex->cmask_size, 
0xCC);
        }
 
-- 
1.8.1.2

_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/mesa-dev

Reply via email to