diff options
author | Chad Versace <[email protected]> | 2012-01-26 11:01:36 -0800 |
---|---|---|
committer | Chad Versace <[email protected]> | 2012-02-07 15:15:03 -0800 |
commit | 7b36c68ba6899c7f30fd56b7ef07a78b027771ac (patch) | |
tree | 3e6e875015a3cc4463bd0df938a302d787b13ee3 /src/mesa/drivers/dri/i965/brw_context.c | |
parent | d59466279e45a1e9c3f9081f72fedbdf961afbe1 (diff) |
i965: Rewrite the HiZ op
The HiZ op was implemented as a meta-op. This patch reimplements it by
emitting a special HiZ batch. This fixes several known bugs, and likely
a lot of undiscovered ones too.
==== Why the HiZ meta-op needed to die ====
The HiZ op was implemented as a meta-op, which caused lots of trouble. All
other meta-ops occur as a result of some GL call (for example, glClear and
glGenerateMipmap), but the HiZ meta-op was special. It was called in
places that Mesa (in particular, the vbo and swrast modules) did not
expect---and were not prepared for---state changes to occur (for example:
glDraw; glCallList; within glBegin/End blocks; and within
swrast_prepare_render as a result of intel_miptree_map).
In an attempt to work around these unexpected state changes, I added two
hooks in i965:
- A hook for glDraw, located in brw_predraw_resolve_buffers (which is
called in the glDraw path). This hook detected if a predraw resolve
meta-op had occurred, and would hackishly repropagate some GL state
if necessary. This ensured that the meta-op state changes would not
intefere with the vbo module's subsequent execution of glDraw.
- A hook for glBegin, implemented by brwPrepareExecBegin. This hook
resolved all buffers before entering
a glBegin/End block, thus preventing an infinitely recurring call to
vbo_exec_FlushVertices. The vbo module calls vbo_exec_FlushVertices to
flush its vertex queue in response to GL state changes.
Unfortunately, these hooks were not sufficient. The meta-op state changes
still interacted badly with glPopAttrib (as discovered in bug 44927) and
with swrast rendering (as discovered by debugging gen6's swrast fallback
for glBitmap). I expect there are more undiscovered bugs. Rather than play
whack-a-mole in a minefield, the sane approach is to replace the HiZ
meta-op with something safer.
==== How it was killed ====
This patch consists of several logical components:
1. Rewrite the HiZ op by replacing function gen6_resolve_slice with
gen6_hiz_exec and gen7_hiz_exec. The new functions do not call
a meta-op, but instead manually construct and emit a batch to "draw"
the HiZ op's rectangle primitive. The new functions alter no GL
state.
2. Add fields to brw_context::hiz for the new HiZ op.
3. Emit a workaround flush when toggling 3DSTATE_VS.VsFunctionEnable.
4. Kill all dead HiZ code:
- the function gen6_resolve_slice
- the dirty flag BRW_NEW_HIZ
- the dead fields in brw_context::hiz
- the state packet manipulation triggered by the now removed
brw_context::hiz::op
- the meta-op workaround in brw_predraw_resolve_buffers (discussed
above)
- the meta-op workaround brwPrepareExecBegin (discussed above)
Note: This is a candidate for the 8.0 branch.
Reviewed-by: Eric Anholt <[email protected]>
Reviewed-by: Kenneth Graunke <[email protected]>
Acked-by: Paul Berry <[email protected]>
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=43327
Reported-by: [email protected]
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=44927
Reported-by: [email protected]
Signed-off-by: Chad Versace <[email protected]>
Diffstat (limited to 'src/mesa/drivers/dri/i965/brw_context.c')
-rw-r--r-- | src/mesa/drivers/dri/i965/brw_context.c | 55 |
1 files changed, 0 insertions, 55 deletions
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c index 1ab6310482f..65de260fdd1 100644 --- a/src/mesa/drivers/dri/i965/brw_context.c +++ b/src/mesa/drivers/dri/i965/brw_context.c @@ -41,8 +41,6 @@ #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" @@ -57,58 +55,6 @@ * 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 intel_screen *screen, struct dd_function_table *functions) { @@ -117,7 +63,6 @@ static void brwInitDriverFunctions(struct intel_screen *screen, brwInitFragProgFuncs( functions ); brw_init_queryobj_functions(functions); - functions->PrepareExecBegin = brwPrepareExecBegin; functions->BeginTransformFeedback = brw_begin_transform_feedback; if (screen->gen >= 7) |