Mesa (master): r300g: flush zmasks of zbuffers we are going to use as samplers

Marek Olšák mareko at kemper.freedesktop.org
Sun Aug 8 21:01:24 UTC 2010


Module: Mesa
Branch: master
Commit: 4f5e51068bce4e32a9561b4b4d6f3feca33642bf
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=4f5e51068bce4e32a9561b4b4d6f3feca33642bf

Author: Marek Olšák <maraeo at gmail.com>
Date:   Sun Aug  8 18:43:42 2010 +0200

r300g: flush zmasks of zbuffers we are going to use as samplers

It sometimes works, sometimes not. I guess we have the zmask offsets wrong.

---

 src/gallium/drivers/r300/r300_blit.c          |   19 ++++++++-----
 src/gallium/drivers/r300/r300_context.h       |    7 +++++
 src/gallium/drivers/r300/r300_emit.c          |    3 ++
 src/gallium/drivers/r300/r300_state_derived.c |   36 +++++++++++++++++++++++++
 4 files changed, 58 insertions(+), 7 deletions(-)

diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c
index 6f8d9ab..18d00d6 100644
--- a/src/gallium/drivers/r300/r300_blit.c
+++ b/src/gallium/drivers/r300/r300_blit.c
@@ -259,27 +259,32 @@ static void r300_clear_depth_stencil(struct pipe_context *pipe,
     r300_blitter_end(r300);
 }
 
-/* Clear a region of a depth stencil surface. */
-static void r300_flush_depth_stencil(struct pipe_context *pipe,
-                                     struct pipe_resource *dst,
-                                     struct pipe_subresource subdst)
+/* Flush a depth stencil buffer. */
+void r300_flush_depth_stencil(struct pipe_context *pipe,
+                              struct pipe_resource *dst,
+                              struct pipe_subresource subdst,
+                              unsigned zslice)
 {
     struct r300_context *r300 = r300_context(pipe);
     struct pipe_surface *dstsurf;
     struct r300_texture *tex = r300_texture(dst);
 
-    /* only flush the zmask if we have one attached to this texture */
     if (!tex->zmask_mem[subdst.level])
         return;
+    if (!tex->dirty_zmask[subdst.level])
+        return;
 
     dstsurf = pipe->screen->get_tex_surface(pipe->screen, dst,
-                                            subdst.face, subdst.level, 0,
+                                            subdst.face, subdst.level, zslice,
                                             PIPE_BIND_DEPTH_STENCIL);
     r300->z_decomp_rd = TRUE;
     r300_blitter_begin(r300, R300_CLEAR_SURFACE);
     util_blitter_flush_depth_stencil(r300->blitter, dstsurf);
     r300_blitter_end(r300);
     r300->z_decomp_rd = FALSE;
+
+    tex->dirty_zmask[subdst.level] = FALSE;
+    pipe->flush(pipe, 0, NULL);
 }
 
 /* Copy a block of pixels from one surface to another using HW. */
@@ -342,7 +347,7 @@ static void r300_resource_copy_region(struct pipe_context *pipe,
 
     is_depth = util_format_get_component_bits(src->format, UTIL_FORMAT_COLORSPACE_ZS, 0) != 0;
     if (is_depth) {
-        r300_flush_depth_stencil(pipe, src, subsrc);
+        r300_flush_depth_stencil(pipe, src, subsrc, srcz);
     }
     if (old_format != new_format) {
         dst->format = new_format;
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index d86a5c8..8b772f3 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -397,6 +397,7 @@ struct r300_texture {
     /* hyper-z memory allocs */
     struct mem_block *hiz_mem[R300_MAX_TEXTURE_LEVELS];
     struct mem_block *zmask_mem[R300_MAX_TEXTURE_LEVELS];
+    boolean dirty_zmask[R300_MAX_TEXTURE_LEVELS];
 
     /* This is the level tiling flags were last time set for.
      * It's used to prevent redundant tiling-flags changes from happening.*/
@@ -628,6 +629,12 @@ void r300_init_render_functions(struct r300_context *r300);
 void r300_init_state_functions(struct r300_context* r300);
 void r300_init_resource_functions(struct r300_context* r300);
 
+/* r300_blit.c */
+void r300_flush_depth_stencil(struct pipe_context *pipe,
+                              struct pipe_resource *dst,
+                              struct pipe_subresource subdst,
+                              unsigned zslice);
+
 /* r300_query.c */
 void r300_resume_query(struct r300_context *r300,
                        struct r300_query *query);
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 0c40e2d..c35774c 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -1069,6 +1069,9 @@ void r300_emit_zmask_clear(struct r300_context *r300, unsigned size, void *state
         offset <<= offset_shift;
         r300_emit_zmask_line_clear(r300, offset, stride, 0x0);//0xffffffff);
     }
+
+    /* Mark the current zbuffer's zmask as dirty. */
+    tex->dirty_zmask[fb->zsbuf->level] = TRUE;
 }
 
 void r300_emit_ztop_state(struct r300_context* r300,
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index a85b46f..693b1e2 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -677,8 +677,44 @@ static void r300_merge_textures_and_samplers(struct r300_context* r300)
     }
 }
 
+/* We can't use compressed zbuffers as samplers. */
+static void r300_flush_depth_textures(struct r300_context *r300)
+{
+    struct r300_textures_state *state =
+        (struct r300_textures_state*)r300->textures_state.state;
+    unsigned i, level;
+    unsigned count = MIN2(state->sampler_view_count,
+                          state->sampler_state_count);
+
+    if (r300->z_decomp_rd)
+        return;
+
+    for (i = 0; i < count; i++)
+        if (state->sampler_views[i] && state->sampler_states[i]) {
+            struct pipe_resource *tex = state->sampler_views[i]->base.texture;
+
+            if (tex->target == PIPE_TEXTURE_3D ||
+                tex->target == PIPE_TEXTURE_CUBE)
+                continue;
+
+            /* Ignore non-depth textures.
+             * Also ignore reinterpreted depth textures, e.g. resource_copy. */
+            if (!util_format_is_depth_or_stencil(tex->format))
+                continue;
+
+            for (level = 0; level <= tex->last_level; level++)
+                if (r300_texture(tex)->dirty_zmask[level]) {
+                    /* We don't handle 3D textures and cubemaps yet. */
+                    r300_flush_depth_stencil(&r300->context, tex,
+                                             u_subresource(0, level), 0);
+                }
+        }
+}
+
 void r300_update_derived_state(struct r300_context* r300)
 {
+    r300_flush_depth_textures(r300);
+
     if (r300->textures_state.dirty) {
         r300_merge_textures_and_samplers(r300);
     }




More information about the mesa-commit mailing list