On Thu, May 29, 2014 at 01:53:43PM -0700, Jordan Justen wrote: > We will program the gen6 depth state differently to enable layered > rendering on gen6. > > Signed-off-by: Jordan Justen <jordan.l.jus...@intel.com> > --- > src/mesa/drivers/dri/i965/Makefile.sources | 1 + > src/mesa/drivers/dri/i965/brw_context.c | 2 +- > src/mesa/drivers/dri/i965/brw_context.h | 13 ++ > src/mesa/drivers/dri/i965/brw_state.h | 1 + > src/mesa/drivers/dri/i965/brw_state_upload.c | 2 +- > src/mesa/drivers/dri/i965/gen6_depth_state.c | 273 > +++++++++++++++++++++++++++ > 6 files changed, 290 insertions(+), 2 deletions(-) > create mode 100644 src/mesa/drivers/dri/i965/gen6_depth_state.c > > diff --git a/src/mesa/drivers/dri/i965/Makefile.sources > b/src/mesa/drivers/dri/i965/Makefile.sources > index 1871449..bcd7930 100644 > --- a/src/mesa/drivers/dri/i965/Makefile.sources > +++ b/src/mesa/drivers/dri/i965/Makefile.sources > @@ -121,6 +121,7 @@ i965_FILES = \ > gen6_blorp.cpp \ > gen6_cc.c \ > gen6_clip_state.c \ > + gen6_depth_state.c \ > gen6_depthstencil.c \ > gen6_gs_state.c \ > gen6_multisample_state.c \ > diff --git a/src/mesa/drivers/dri/i965/brw_context.c > b/src/mesa/drivers/dri/i965/brw_context.c > index d35dea5..ddee815 100644 > --- a/src/mesa/drivers/dri/i965/brw_context.c > +++ b/src/mesa/drivers/dri/i965/brw_context.c > @@ -642,7 +642,7 @@ brwCreateContext(gl_api api, > } else if (brw->gen >= 6) { > gen6_init_vtable_surface_functions(brw); > gen4_init_vtable_sampler_functions(brw); > - brw->vtbl.emit_depth_stencil_hiz = brw_emit_depth_stencil_hiz; > + brw->vtbl.emit_depth_stencil_hiz = gen6_emit_depth_stencil_hiz; > } else { > gen4_init_vtable_surface_functions(brw); > gen4_init_vtable_sampler_functions(brw); > diff --git a/src/mesa/drivers/dri/i965/brw_context.h > b/src/mesa/drivers/dri/i965/brw_context.h > index 283c576..3f10d55 100644 > --- a/src/mesa/drivers/dri/i965/brw_context.h > +++ b/src/mesa/drivers/dri/i965/brw_context.h > @@ -1819,6 +1819,19 @@ brw_emit_depth_stencil_hiz(struct brw_context *brw, > uint32_t tile_x, uint32_t tile_y); > > void > +gen6_emit_depthbuffer(struct brw_context *brw); > + > +void > +gen6_emit_depth_stencil_hiz(struct brw_context *brw, > + struct intel_mipmap_tree *depth_mt, > + uint32_t depth_offset, uint32_t > depthbuffer_format, > + uint32_t depth_surface_type, > + struct intel_mipmap_tree *stencil_mt, > + bool hiz, bool separate_stencil, > + uint32_t width, uint32_t height, > + uint32_t tile_x, uint32_t tile_y); > + > +void > gen7_emit_depth_stencil_hiz(struct brw_context *brw, > struct intel_mipmap_tree *depth_mt, > uint32_t depth_offset, uint32_t > depthbuffer_format, > diff --git a/src/mesa/drivers/dri/i965/brw_state.h > b/src/mesa/drivers/dri/i965/brw_state.h > index 1669b77..a8051cd 100644 > --- a/src/mesa/drivers/dri/i965/brw_state.h > +++ b/src/mesa/drivers/dri/i965/brw_state.h > @@ -100,6 +100,7 @@ extern const struct brw_tracked_state gen6_clip_state; > extern const struct brw_tracked_state gen6_clip_vp; > extern const struct brw_tracked_state gen6_color_calc_state; > extern const struct brw_tracked_state gen6_depth_stencil_state; > +extern const struct brw_tracked_state gen6_depthbuffer; > extern const struct brw_tracked_state gen6_gs_state; > extern const struct brw_tracked_state gen6_gs_binding_table; > extern const struct brw_tracked_state gen6_multisample_state; > diff --git a/src/mesa/drivers/dri/i965/brw_state_upload.c > b/src/mesa/drivers/dri/i965/brw_state_upload.c > index 3a452c3..15e61d4 100644 > --- a/src/mesa/drivers/dri/i965/brw_state_upload.c > +++ b/src/mesa/drivers/dri/i965/brw_state_upload.c > @@ -159,7 +159,7 @@ static const struct brw_tracked_state *gen6_atoms[] = > > &gen6_binding_table_pointers, > > - &brw_depthbuffer, > + &gen6_depthbuffer, > > &brw_polygon_stipple, > &brw_polygon_stipple_offset, > diff --git a/src/mesa/drivers/dri/i965/gen6_depth_state.c > b/src/mesa/drivers/dri/i965/gen6_depth_state.c > new file mode 100644 > index 0000000..4c659c6 > --- /dev/null > +++ b/src/mesa/drivers/dri/i965/gen6_depth_state.c > @@ -0,0 +1,273 @@ > +/* > + * Copyright (c) 2014 Intel Corporation > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice (including the next > + * paragraph) shall be included in all copies or substantial portions of the > + * Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER > + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING > + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER > DEALINGS > + * IN THE SOFTWARE. > + */ > + > + > +#include "intel_batchbuffer.h" > +#include "intel_fbo.h" > +#include "intel_mipmap_tree.h" > + > +#include "brw_context.h" > +#include "brw_state.h" > +#include "brw_defines.h" > + > +#include "main/fbobject.h" > +#include "main/glformats.h" > + > +void > +gen6_emit_depthbuffer(struct brw_context *brw) > +{ > + struct gl_context *ctx = &brw->ctx; > + struct gl_framebuffer *fb = ctx->DrawBuffer; > + /* _NEW_BUFFERS */ > + struct intel_renderbuffer *depth_irb = intel_get_renderbuffer(fb, > BUFFER_DEPTH); > + struct intel_renderbuffer *stencil_irb = intel_get_renderbuffer(fb, > BUFFER_STENCIL); > + struct intel_mipmap_tree *depth_mt = brw->depthstencil.depth_mt; > + struct intel_mipmap_tree *stencil_mt = brw->depthstencil.stencil_mt; > + uint32_t tile_x = brw->depthstencil.tile_x; > + uint32_t tile_y = brw->depthstencil.tile_y; > + bool hiz = depth_irb && intel_renderbuffer_has_hiz(depth_irb); > + bool separate_stencil = false; > + uint32_t depth_surface_type = BRW_SURFACE_NULL; > + uint32_t depthbuffer_format = BRW_DEPTHFORMAT_D32_FLOAT; > + uint32_t depth_offset = 0; > + uint32_t width = 1, height = 1; > + > + if (stencil_mt) { > + separate_stencil = stencil_mt->format == MESA_FORMAT_S_UINT8; > + > + /* Gen7 supports only separate stencil */ > + assert(separate_stencil || brw->gen < 7); > + } > + > + /* If there's a packed depth/stencil bound to stencil only, we need to > + * emit the packed depth/stencil buffer packet. > + */ > + if (!depth_irb && stencil_irb && !separate_stencil) { > + depth_irb = stencil_irb; > + depth_mt = stencil_mt; > + } > + > + if (depth_irb && depth_mt) { > + /* When 3DSTATE_DEPTH_BUFFER.Separate_Stencil_Enable is set, then > + * 3DSTATE_DEPTH_BUFFER.Surface_Format is not permitted to be a packed > + * depthstencil format. > + * > + * Gens prior to 7 require that HiZ_Enable and Separate_Stencil_Enable > be > + * set to the same value. Gens after 7 implicitly always set > + * Separate_Stencil_Enable; software cannot disable it. > + */ > + if ((brw->gen < 7 && hiz) || brw->gen >= 7) { > + assert(!_mesa_is_format_packed_depth_stencil(depth_mt->format)); > + } > + > + /* Prior to Gen7, if using separate stencil, hiz must be enabled. */ > + assert(brw->gen >= 7 || !separate_stencil || hiz); > + > + assert(brw->gen < 6 || depth_mt->tiling == I915_TILING_Y); > + assert(!hiz || depth_mt->tiling == I915_TILING_Y); > + > + depthbuffer_format = brw_depthbuffer_format(brw); > + depth_surface_type = BRW_SURFACE_2D; > + depth_offset = brw->depthstencil.depth_offset; > + width = depth_irb->Base.Base.Width; > + height = depth_irb->Base.Base.Height; > + } else if (separate_stencil) { > + /* > + * There exists a separate stencil buffer but no depth buffer. > + * > + * The stencil buffer inherits most of its fields from > + * 3DSTATE_DEPTH_BUFFER: namely the tile walk, surface type, width, and > + * height. > + * > + * The tiled bit must be set. From the Sandybridge PRM, Volume 2, Part > 1, > + * Section 7.5.5.1.1 3DSTATE_DEPTH_BUFFER, Bit 1.27 Tiled Surface: > + * [DevGT+]: This field must be set to TRUE. > + */ > + assert(brw->has_separate_stencil); > + > + depth_surface_type = BRW_SURFACE_2D; > + width = stencil_irb->Base.Base.Width; > + height = stencil_irb->Base.Base.Height; > + } > + > + if (depth_mt) > + brw_render_cache_set_check_flush(brw, depth_mt->bo); > + if (stencil_mt) > + brw_render_cache_set_check_flush(brw, stencil_mt->bo); > + > + brw->vtbl.emit_depth_stencil_hiz(brw, depth_mt, depth_offset, > + depthbuffer_format, depth_surface_type, > + stencil_mt, hiz, separate_stencil, > + width, height, tile_x, tile_y); > +}
In the end of the series "gen6_emit_depthbuffer()" is still identical to original. I think you can keep on using the generic. This is how gen7 is setup, it has its own emit_depth_stencil_hiz() but uses the generic emit_depthbuffer(). > + > +void > +gen6_emit_depth_stencil_hiz(struct brw_context *brw, > + struct intel_mipmap_tree *depth_mt, > + uint32_t depth_offset, uint32_t > depthbuffer_format, > + uint32_t depth_surface_type, > + struct intel_mipmap_tree *stencil_mt, > + bool hiz, bool separate_stencil, > + uint32_t width, uint32_t height, > + uint32_t tile_x, uint32_t tile_y) > +{ > + /* Enable the hiz bit if we're doing separate stencil, because it and the > + * separate stencil bit must have the same value. From Section > 2.11.5.6.1.1 > + * 3DSTATE_DEPTH_BUFFER, Bit 1.21 "Separate Stencil Enable": > + * [DevIL]: If this field is enabled, Hierarchical Depth Buffer > + * Enable must also be enabled. > + * > + * [DevGT]: This field must be set to the same value (enabled or > + * disabled) as Hierarchical Depth Buffer Enable > + */ > + bool enable_hiz_ss = hiz || separate_stencil; > + > + > + /* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both > + * non-pipelined state that will need the PIPE_CONTROL workaround. > + */ > + if (brw->gen == 6) { > + intel_emit_post_sync_nonzero_flush(brw); > + intel_emit_depth_stall_flushes(brw); > + } > + > + unsigned int len; > + if (brw->gen >= 6) > + len = 7; > + else if (brw->is_g4x || brw->gen == 5) > + len = 6; > + else > + len = 5; > + > + BEGIN_BATCH(len); > + OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2)); > + OUT_BATCH((depth_mt ? depth_mt->pitch - 1 : 0) | > + (depthbuffer_format << 18) | > + ((enable_hiz_ss ? 1 : 0) << 21) | /* separate stencil enable */ > + ((enable_hiz_ss ? 1 : 0) << 22) | /* hiz enable */ > + (BRW_TILEWALK_YMAJOR << 26) | > + ((depth_mt ? depth_mt->tiling != I915_TILING_NONE : 1) > + << 27) | > + (depth_surface_type << 29)); > + > + if (depth_mt) { > + OUT_RELOC(depth_mt->bo, > + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, > + depth_offset); > + } else { > + OUT_BATCH(0); > + } > + > + OUT_BATCH(((width + tile_x - 1) << 6) | > + ((height + tile_y - 1) << 19)); > + OUT_BATCH(0); > + > + if (brw->is_g4x || brw->gen >= 5) > + OUT_BATCH(tile_x | (tile_y << 16)); > + else > + assert(tile_x == 0 && tile_y == 0); > + > + if (brw->gen >= 6) > + OUT_BATCH(0); > + > + ADVANCE_BATCH(); > + > + if (hiz || separate_stencil) { > + /* > + * In the 3DSTATE_DEPTH_BUFFER batch emitted above, the 'separate > + * stencil enable' and 'hiz enable' bits were set. Therefore we must > + * emit 3DSTATE_HIER_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER. Even if > + * there is no stencil buffer, 3DSTATE_STENCIL_BUFFER must be emitted; > + * failure to do so causes hangs on gen5 and a stall on gen6. > + */ > + > + /* Emit hiz buffer. */ > + if (hiz) { > + struct intel_mipmap_tree *hiz_mt = depth_mt->hiz_mt; > + BEGIN_BATCH(3); > + OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2)); > + OUT_BATCH(hiz_mt->pitch - 1); > + OUT_RELOC(hiz_mt->bo, > + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, > + brw->depthstencil.hiz_offset); > + ADVANCE_BATCH(); > + } else { > + BEGIN_BATCH(3); > + OUT_BATCH((_3DSTATE_HIER_DEPTH_BUFFER << 16) | (3 - 2)); > + OUT_BATCH(0); > + OUT_BATCH(0); > + ADVANCE_BATCH(); > + } > + > + /* Emit stencil buffer. */ > + if (separate_stencil) { > + BEGIN_BATCH(3); > + OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2)); > + /* The stencil buffer has quirky pitch requirements. From Vol 2a, > + * 11.5.6.2.1 3DSTATE_STENCIL_BUFFER, field "Surface Pitch": > + * The pitch must be set to 2x the value computed based on > width, as > + * the stencil buffer is stored with two rows interleaved. > + */ > + OUT_BATCH(2 * stencil_mt->pitch - 1); > + OUT_RELOC(stencil_mt->bo, > + I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, > + brw->depthstencil.stencil_offset); > + ADVANCE_BATCH(); > + } else { > + BEGIN_BATCH(3); > + OUT_BATCH((_3DSTATE_STENCIL_BUFFER << 16) | (3 - 2)); > + OUT_BATCH(0); > + OUT_BATCH(0); > + ADVANCE_BATCH(); > + } > + } > + > + /* > + * On Gen >= 6, emit clear params for safety. If using hiz, then clear > + * params must be emitted. > + * > + * From Section 2.11.5.6.4.1 3DSTATE_CLEAR_PARAMS: > + * 3DSTATE_CLEAR_PARAMS packet must follow the DEPTH_BUFFER_STATE > packet > + * when HiZ is enabled and the DEPTH_BUFFER_STATE changes. > + */ > + if (brw->gen >= 6 || hiz) { > + if (brw->gen == 6) > + intel_emit_post_sync_nonzero_flush(brw); > + > + BEGIN_BATCH(2); > + OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 | > + GEN5_DEPTH_CLEAR_VALID | > + (2 - 2)); > + OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0); > + ADVANCE_BATCH(); > + } > +} > + > +const struct brw_tracked_state gen6_depthbuffer = { > + .dirty = { > + .mesa = _NEW_BUFFERS, > + .brw = BRW_NEW_BATCH, > + .cache = 0, > + }, > + .emit = gen6_emit_depthbuffer, > +}; > -- > 2.0.0.rc4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > http://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/mesa-dev