i965: Don't disable aux buffers for non-overlapping miplevels.
authorKenneth Graunke <kenneth@whitecape.org>
Fri, 13 Oct 2017 03:47:41 +0000 (20:47 -0700)
committerKenneth Graunke <kenneth@whitecape.org>
Thu, 19 Oct 2017 18:10:00 +0000 (11:10 -0700)
Meta's GenerateMipmap implementation binds the same image for both
sampling and rendering - but it samples from one miplevel while
rendering the next.  This is a false self-dependency, and there's
no need to disable auxiliary buffers in this case.  In fact, we really
want to leave it enabled so the new miplevels gain color compression.

Thankfully, the texture object's _MaxLevel is always one shy of the
miplevel being rendered.  So we can simply check if irb->mt_level is
overlaps with the texture's defined levels.  If not, there's no self-
dependency and we can leave the auxiliary buffers enabled.

Fixes a performance regression in GFXBench4 Car Chase, which apparently
calls glGenerateMipmap() on every frame.

Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=103247
Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
Reviewed-by; Jason Ekstrand <jason@jlekstrand.net>

src/mesa/drivers/dri/i965/brw_draw.c

index 486ada985d46903a0afd080cfa35a105c50b9c2e..b74ab8bde23c9c254bf2543969520ac007a31a69 100644 (file)
@@ -344,6 +344,7 @@ brw_merge_inputs(struct brw_context *brw,
 static bool
 intel_disable_rb_aux_buffer(struct brw_context *brw,
                             struct intel_mipmap_tree *tex_mt,
+                            unsigned min_level, unsigned num_levels,
                             const char *usage)
 {
    const struct gl_framebuffer *fb = brw->ctx.DrawBuffer;
@@ -358,7 +359,9 @@ intel_disable_rb_aux_buffer(struct brw_context *brw,
       const struct intel_renderbuffer *irb =
          intel_renderbuffer(fb->_ColorDrawBuffers[i]);
 
-      if (irb && irb->mt->bo == tex_mt->bo) {
+      if (irb && irb->mt->bo == tex_mt->bo &&
+          irb->mt_level >= min_level &&
+          irb->mt_level < min_level + num_levels) {
          found = brw->draw_aux_buffer_disabled[i] = true;
       }
    }
@@ -414,7 +417,8 @@ brw_predraw_resolve_inputs(struct brw_context *brw)
       }
 
       const bool disable_aux =
-         intel_disable_rb_aux_buffer(brw, tex_obj->mt, "for sampling");
+         intel_disable_rb_aux_buffer(brw, tex_obj->mt, min_level, num_levels,
+                                     "for sampling");
 
       intel_miptree_prepare_texture(brw, tex_obj->mt, view_format,
                                     min_level, num_levels,
@@ -440,7 +444,7 @@ brw_predraw_resolve_inputs(struct brw_context *brw)
             tex_obj = intel_texture_object(u->TexObj);
 
             if (tex_obj && tex_obj->mt) {
-               intel_disable_rb_aux_buffer(brw, tex_obj->mt,
+               intel_disable_rb_aux_buffer(brw, tex_obj->mt, 0, ~0,
                                            "as a shader image");
 
                intel_miptree_prepare_image(brw, tex_obj->mt);