From b95986729ef3522a65b7357aea99c6358f9d53c8 Mon Sep 17 00:00:00 2001 From: Chad Versace Date: Tue, 15 Nov 2011 18:20:34 -0800 Subject: [PATCH] i965: Prevent recursive calls to FLUSH_VERTICES [v2] 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. v2: - Fix typo: s/enusure/ensure/. - In brwPrepareExecBegin(), do the same resolves as done by brw_predraw_resolve_buffers(). Reviewed-by: Eric Anholt Signed-off-by: Chad Versace --- src/mesa/drivers/dri/i965/brw_context.c | 66 +++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 9b506a6529f..531ce5bd0d8 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,66 @@ * Mesa's Driver Functions ***************************************/ +/** + * \brief Prepare for entry into glBegin/glEnd block. + * + * Resolve buffers before entering a glBegin/glEnd block. This is + * necessary to prevent recursive calls to FLUSH_VERTICES. + * + * This resolves the depth buffer of each enabled depth texture and the HiZ + * buffer of the attached depth renderbuffer. + * + * Details + * ------- + * When vertices are queued during a glBegin/glEnd block, those vertices must + * be drawn before any rendering state changes. To ensure 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 occurring while any + * vertices are queued. To prevent that situation, we resolve some 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_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_depth(intel, tex_obj->mt); + } + + /* Resolve the attached depth buffer. */ + draw_irb = intel_get_renderbuffer(ctx->DrawBuffer, BUFFER_DEPTH); + if (draw_irb) { + intel_renderbuffer_resolve_hiz(intel, draw_irb); + } +} + static void brwInitDriverFunctions( struct dd_function_table *functions ) { intelInitDriverFunctions( functions ); brwInitFragProgFuncs( functions ); brw_init_queryobj_functions(functions); + + functions->PrepareExecBegin = brwPrepareExecBegin; } bool -- 2.30.2