[Mesa-dev] [PATCH 27/41] i965: Prevent recursive calls to FLUSH_VERTICES

Chad Versace chad.versace at linux.intel.com
Thu Nov 17 19:58:54 PST 2011


To do so, we must resolve all buffers on entering a glBegin/glEnd block.
For the detailed explanation, see the Doxygen comments in this patch.

Signed-off-by: Chad Versace <chad.versace at linux.intel.com>
---
 src/mesa/drivers/dri/i965/brw_context.c |   73 +++++++++++++++++++++++++++++++
 1 files changed, 73 insertions(+), 0 deletions(-)

diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 9b506a6..4d51e62 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -33,11 +33,23 @@
 #include "main/imports.h"
 #include "main/macros.h"
 #include "main/simple_list.h"
+
+#include "vbo/vbo_context.h"
+
 #include "brw_context.h"
 #include "brw_defines.h"
 #include "brw_draw.h"
 #include "brw_state.h"
+
+#include "gen6_hiz.h"
+
+#include "intel_fbo.h"
+#include "intel_mipmap_tree.h"
+#include "intel_regions.h"
 #include "intel_span.h"
+#include "intel_tex.h"
+#include "intel_tex_obj.h"
+
 #include "tnl/t_pipeline.h"
 #include "glsl/ralloc.h"
 
@@ -45,12 +57,73 @@
  * Mesa's Driver Functions
  ***************************************/
 
+/**
+ * \brief Prepare for entry into glBegin/glEnd block.
+ *
+ * Resolve all buffers before entering a glBegin/glEnd block. This is
+ * necessary to prevent recursive calls to FLUSH_VERTICES.
+ *
+ * Details
+ * -------
+ * When vertices are queued during a glBegin/glEnd block, those vertices must
+ * be drawn before any rendering state changes. To enusure this, Mesa calls
+ * FLUSH_VERTICES as a prehook to such state changes. Therefore,
+ * FLUSH_VERTICES itself cannot change rendering state without falling into a
+ * recursive trap.
+ *
+ * This precludes meta-ops, namely buffer resolves, from occuring while any
+ * vertices are queued. To prevent that situation, we resolve all buffers on
+ * entering a glBegin/glEnd
+ *
+ * \see brwCleanupExecEnd()
+ */
+static void brwPrepareExecBegin(struct gl_context *ctx)
+{
+   struct brw_context *brw = brw_context(ctx);
+   struct intel_context *intel = &brw->intel;
+   struct intel_renderbuffer *draw_irb;
+   struct intel_renderbuffer *read_irb;
+   struct intel_texture_object *tex_obj;
+
+   if (!intel->has_hiz) {
+      /* The context uses no feature that requires buffer resolves. */
+      return;
+   }
+
+   /* Resolve each enabled texture. */
+   for (int i = 0; i < ctx->Const.MaxTextureImageUnits; 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;
+      intel_miptree_all_slices_resolve_hiz(intel, tex_obj->mt);
+      intel_miptree_all_slices_resolve_depth(intel, tex_obj->mt);
+   }
+
+   /* Resolve each attached depth buffer. */
+   draw_irb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_DEPTH);
+   read_irb = intel_get_renderbuffer(ctx->ReadBuffer, BUFFER_DEPTH);
+
+   if (draw_irb) {
+      intel_renderbuffer_resolve_hiz(intel, draw_irb);
+      intel_renderbuffer_resolve_depth(intel, draw_irb);
+   }
+
+   if (read_irb != draw_irb && read_irb) {
+      intel_renderbuffer_resolve_hiz(intel, read_irb);
+      intel_renderbuffer_resolve_depth(intel, read_irb);
+   }
+}
+
 static void brwInitDriverFunctions( struct dd_function_table *functions )
 {
    intelInitDriverFunctions( functions );
 
    brwInitFragProgFuncs( functions );
    brw_init_queryobj_functions(functions);
+
+   functions->PrepareExecBegin = brwPrepareExecBegin;
 }
 
 bool
-- 
1.7.7.1



More information about the mesa-dev mailing list