i965: Resolve buffers before drawing [v2]
authorChad Versace <chad.versace@linux.intel.com>
Wed, 16 Nov 2011 02:20:39 +0000 (18:20 -0800)
committerChad Versace <chad.versace@linux.intel.com>
Tue, 22 Nov 2011 18:50:50 +0000 (10:50 -0800)
Before emitting primitives in brw_try_draw_prims(), resolve the depth
buffer's HiZ buffer and resolve the depth buffer of each enabled depth
texture.

v2: [anholt] The driver no longer validates drm bo's, so update a comment
    to reflect that.

Reviewed-by: Eric Anholt <eric@anholt.net>
Signed-off-by: Chad Versace <chad.versace@linux.intel.com>
src/mesa/drivers/dri/i965/brw_draw.c

index d2ae0877e8dad8b3a3b2d8ac67cc02c6a35164c0..35196a7e1a050a633f0151ebfc22a876c505eab0 100644 (file)
@@ -44,6 +44,9 @@
 #include "brw_state.h"
 
 #include "intel_batchbuffer.h"
+#include "intel_fbo.h"
+#include "intel_mipmap_tree.h"
+#include "intel_regions.h"
 
 #define FILE_DEBUG_FLAG DEBUG_PRIMS
 
@@ -287,6 +290,71 @@ static void brw_merge_inputs( struct brw_context *brw,
       brw->state.dirty.brw |= BRW_NEW_INPUT_DIMENSIONS;
 }
 
+/*
+ * \brief Resolve buffers before drawing.
+ *
+ * Resolve the depth buffer's HiZ buffer and resolve the depth buffer of each
+ * enabled depth texture.
+ *
+ * (In the future, this will also perform MSAA resolves).
+ */
+static void
+brw_predraw_resolve_buffers(struct brw_context *brw)
+{
+   struct gl_context *ctx = &brw->intel.ctx;
+   struct intel_context *intel = &brw->intel;
+   struct intel_renderbuffer *depth_irb;
+   struct intel_texture_object *tex_obj;
+   bool did_resolve = false;
+
+   /* Avoid recursive HiZ op. */
+   if (brw->hiz.op) {
+      return;
+   }
+
+   /* Resolve the depth buffer's HiZ buffer. */
+   depth_irb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_DEPTH);
+   if (depth_irb && depth_irb->mt) {
+      did_resolve |= intel_renderbuffer_resolve_hiz(intel, depth_irb);
+   }
+
+   /* Resolve depth buffer of each enabled depth texture. */
+   for (int i = 0; i < BRW_MAX_TEX_UNIT; i++) {
+      if (!ctx->Texture.Unit[i]._ReallyEnabled)
+        continue;
+      tex_obj = intel_texture_object(ctx->Texture.Unit[i]._Current);
+      if (!tex_obj || !tex_obj->mt)
+        continue;
+      did_resolve |= intel_miptree_all_slices_resolve_depth(intel, tex_obj->mt);
+   }
+
+   if (did_resolve) {
+      /* Call vbo_bind_array() to synchronize the vbo module's vertex
+       * attributes to the gl_context's.
+       *
+       * Details
+       * -------
+       * The vbo module tracks vertex attributes separately from the
+       * gl_context.  Specifically, the vbo module maintins vertex attributes
+       * in vbo_exec_context::array::inputs, which is synchronized with
+       * gl_context::Array::ArrayObj::VertexAttrib by vbo_bind_array().
+       * vbo_draw_arrays() calls vbo_bind_array() to perform the
+       * synchronization before calling the real draw call,
+       * vbo_context::draw_arrays.
+       *
+       * At this point (after performing a resolve meta-op but before calling
+       * vbo_bind_array), the gl_context's vertex attributes have been
+       * restored to their original state (that is, their state before the
+       * meta-op began), but the vbo module's vertex attribute are those used
+       * in the last meta-op. Therefore we must manually synchronize the two with
+       * vbo_bind_array() before continuing with the original draw command.
+       */
+      _mesa_update_state(ctx);
+      vbo_bind_arrays(ctx);
+      _mesa_update_state(ctx);
+   }
+}
+
 /* May fail if out of video memory for texture or vbo upload, or on
  * fallback conditions.
  */
@@ -316,6 +384,11 @@ static bool brw_try_draw_prims( struct gl_context *ctx,
     */
    brw_validate_textures( brw );
 
+   /* Resolves must occur after updating state and finalizing textures but
+    * before setting up any hardware state for this draw call.
+    */
+   brw_predraw_resolve_buffers(brw);
+
    /* Bind all inputs, derive varying and size information:
     */
    brw_merge_inputs( brw, arrays );