|
|
@@ -561,7 +561,8 @@ brw_workaround_depthstencil_alignment(struct brw_context *brw, |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
static void emit_depthbuffer(struct brw_context *brw) |
|
|
|
void |
|
|
|
brw_emit_depthbuffer(struct brw_context *brw) |
|
|
|
{ |
|
|
|
struct intel_context *intel = &brw->intel; |
|
|
|
struct gl_context *ctx = &intel->ctx; |
|
|
@@ -574,18 +575,17 @@ static void emit_depthbuffer(struct brw_context *brw) |
|
|
|
struct intel_mipmap_tree *hiz_mt = brw->depthstencil.hiz_mt; |
|
|
|
uint32_t tile_x = brw->depthstencil.tile_x; |
|
|
|
uint32_t tile_y = brw->depthstencil.tile_y; |
|
|
|
unsigned int len; |
|
|
|
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 && stencil_mt->format == MESA_FORMAT_S8) |
|
|
|
separate_stencil = true; |
|
|
|
if (stencil_mt) { |
|
|
|
separate_stencil = stencil_mt->format == MESA_FORMAT_S8; |
|
|
|
|
|
|
|
/* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both |
|
|
|
* non-pipelined state that will need the PIPE_CONTROL workaround. |
|
|
|
*/ |
|
|
|
if (intel->gen == 6) { |
|
|
|
intel_emit_post_sync_nonzero_flush(intel); |
|
|
|
intel_emit_depth_stall_flushes(intel); |
|
|
|
/* Gen7 supports only separate stencil */ |
|
|
|
assert(separate_stencil || intel->gen < 7); |
|
|
|
} |
|
|
|
|
|
|
|
/* If there's a packed depth/stencil bound to stencil only, we need to |
|
|
@@ -596,31 +596,33 @@ static void emit_depthbuffer(struct brw_context *brw) |
|
|
|
depth_mt = stencil_mt; |
|
|
|
} |
|
|
|
|
|
|
|
if (intel->gen >= 6) |
|
|
|
len = 7; |
|
|
|
else if (intel->is_g4x || intel->gen == 5) |
|
|
|
len = 6; |
|
|
|
else |
|
|
|
len = 5; |
|
|
|
|
|
|
|
if (!depth_irb && !separate_stencil) { |
|
|
|
BEGIN_BATCH(len); |
|
|
|
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2)); |
|
|
|
OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) | |
|
|
|
(BRW_SURFACE_NULL << 29)); |
|
|
|
OUT_BATCH(0); |
|
|
|
OUT_BATCH(0); |
|
|
|
OUT_BATCH(0); |
|
|
|
if (depth_irb) { |
|
|
|
struct intel_region *region = depth_mt->region; |
|
|
|
|
|
|
|
if (intel->is_g4x || intel->gen >= 5) |
|
|
|
OUT_BATCH(0); |
|
|
|
/* 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 ((intel->gen < 7 && depth_mt->hiz_mt) || intel->gen >= 7) { |
|
|
|
assert(!_mesa_is_format_packed_depth_stencil(depth_mt->format)); |
|
|
|
} |
|
|
|
|
|
|
|
if (intel->gen >= 6) |
|
|
|
OUT_BATCH(0); |
|
|
|
/* Prior to Gen7, if using separate stencil, hiz must be enabled. */ |
|
|
|
assert(intel->gen >= 7 || !separate_stencil || hiz_mt); |
|
|
|
|
|
|
|
ADVANCE_BATCH(); |
|
|
|
assert(intel->gen < 6 || region->tiling == I915_TILING_Y); |
|
|
|
assert(!hiz_mt || region->tiling == I915_TILING_Y); |
|
|
|
|
|
|
|
} else if (!depth_irb && separate_stencil) { |
|
|
|
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. |
|
|
|
* |
|
|
@@ -628,80 +630,95 @@ static void emit_depthbuffer(struct brw_context *brw) |
|
|
|
* 3DSTATE_DEPTH_BUFFER: namely the tile walk, surface type, width, and |
|
|
|
* height. |
|
|
|
* |
|
|
|
* Enable the hiz bit 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 |
|
|
|
* |
|
|
|
* 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(intel->has_separate_stencil); |
|
|
|
|
|
|
|
BEGIN_BATCH(len); |
|
|
|
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2)); |
|
|
|
OUT_BATCH((BRW_DEPTHFORMAT_D32_FLOAT << 18) | |
|
|
|
(1 << 21) | /* separate stencil enable */ |
|
|
|
(1 << 22) | /* hiz enable */ |
|
|
|
(BRW_TILEWALK_YMAJOR << 26) | |
|
|
|
(1 << 27) | /* tiled surface */ |
|
|
|
(BRW_SURFACE_2D << 29)); |
|
|
|
OUT_BATCH(0); |
|
|
|
OUT_BATCH(((stencil_irb->Base.Base.Width + tile_x - 1) << 6) | |
|
|
|
(stencil_irb->Base.Base.Height + tile_y - 1) << 19); |
|
|
|
OUT_BATCH(0); |
|
|
|
depth_surface_type = BRW_SURFACE_2D; |
|
|
|
width = stencil_irb->Base.Base.Width; |
|
|
|
height = stencil_irb->Base.Base.Height; |
|
|
|
} |
|
|
|
|
|
|
|
if (intel->is_g4x || intel->gen >= 5) |
|
|
|
OUT_BATCH(tile_x | (tile_y << 16)); |
|
|
|
else |
|
|
|
assert(tile_x == 0 && tile_y == 0); |
|
|
|
intel->vtbl.emit_depth_stencil_hiz(brw, depth_mt, depth_offset, |
|
|
|
depthbuffer_format, depth_surface_type, |
|
|
|
stencil_mt, hiz_mt, separate_stencil, |
|
|
|
width, height, tile_x, tile_y); |
|
|
|
} |
|
|
|
|
|
|
|
if (intel->gen >= 6) |
|
|
|
OUT_BATCH(0); |
|
|
|
void |
|
|
|
brw_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, |
|
|
|
struct intel_mipmap_tree *hiz_mt, |
|
|
|
bool separate_stencil, uint32_t width, |
|
|
|
uint32_t height, uint32_t tile_x, uint32_t tile_y) |
|
|
|
{ |
|
|
|
struct intel_context *intel = &brw->intel; |
|
|
|
|
|
|
|
ADVANCE_BATCH(); |
|
|
|
/* 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_mt || separate_stencil; |
|
|
|
|
|
|
|
} else { |
|
|
|
struct intel_region *region = depth_mt->region; |
|
|
|
|
|
|
|
/* If using separate stencil, hiz must be enabled. */ |
|
|
|
assert(!separate_stencil || hiz_mt); |
|
|
|
/* 3DSTATE_DEPTH_BUFFER, 3DSTATE_STENCIL_BUFFER are both |
|
|
|
* non-pipelined state that will need the PIPE_CONTROL workaround. |
|
|
|
*/ |
|
|
|
if (intel->gen == 6) { |
|
|
|
intel_emit_post_sync_nonzero_flush(intel); |
|
|
|
intel_emit_depth_stall_flushes(intel); |
|
|
|
} |
|
|
|
|
|
|
|
assert(intel->gen < 6 || region->tiling == I915_TILING_Y); |
|
|
|
assert(!hiz_mt || region->tiling == I915_TILING_Y); |
|
|
|
unsigned int len; |
|
|
|
if (intel->gen >= 6) |
|
|
|
len = 7; |
|
|
|
else if (intel->is_g4x || intel->gen == 5) |
|
|
|
len = 6; |
|
|
|
else |
|
|
|
len = 5; |
|
|
|
|
|
|
|
BEGIN_BATCH(len); |
|
|
|
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2)); |
|
|
|
OUT_BATCH((region->pitch - 1) | |
|
|
|
(brw_depthbuffer_format(brw) << 18) | |
|
|
|
((hiz_mt ? 1 : 0) << 21) | /* separate stencil enable */ |
|
|
|
((hiz_mt ? 1 : 0) << 22) | /* hiz enable */ |
|
|
|
(BRW_TILEWALK_YMAJOR << 26) | |
|
|
|
((region->tiling != I915_TILING_NONE) << 27) | |
|
|
|
(BRW_SURFACE_2D << 29)); |
|
|
|
OUT_RELOC(region->bo, |
|
|
|
BEGIN_BATCH(len); |
|
|
|
OUT_BATCH(_3DSTATE_DEPTH_BUFFER << 16 | (len - 2)); |
|
|
|
OUT_BATCH((depth_mt ? depth_mt->region->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->region->tiling != I915_TILING_NONE : 1) |
|
|
|
<< 27) | |
|
|
|
(depth_surface_type << 29)); |
|
|
|
|
|
|
|
if (depth_mt) { |
|
|
|
OUT_RELOC(depth_mt->region->bo, |
|
|
|
I915_GEM_DOMAIN_RENDER, I915_GEM_DOMAIN_RENDER, |
|
|
|
brw->depthstencil.depth_offset); |
|
|
|
OUT_BATCH((BRW_SURFACE_MIPMAPLAYOUT_BELOW << 1) | |
|
|
|
(((depth_irb->Base.Base.Width + tile_x) - 1) << 6) | |
|
|
|
(((depth_irb->Base.Base.Height + tile_y) - 1) << 19)); |
|
|
|
depth_offset); |
|
|
|
} else { |
|
|
|
OUT_BATCH(0); |
|
|
|
} |
|
|
|
|
|
|
|
if (intel->is_g4x || intel->gen >= 5) |
|
|
|
OUT_BATCH(tile_x | (tile_y << 16)); |
|
|
|
else |
|
|
|
assert(tile_x == 0 && tile_y == 0); |
|
|
|
OUT_BATCH(((width + tile_x - 1) << 6) | |
|
|
|
((height + tile_y - 1) << 19)); |
|
|
|
OUT_BATCH(0); |
|
|
|
|
|
|
|
if (intel->gen >= 6) |
|
|
|
OUT_BATCH(0); |
|
|
|
if (intel->is_g4x || intel->gen >= 5) |
|
|
|
OUT_BATCH(tile_x | (tile_y << 16)); |
|
|
|
else |
|
|
|
assert(tile_x == 0 && tile_y == 0); |
|
|
|
|
|
|
|
ADVANCE_BATCH(); |
|
|
|
} |
|
|
|
if (intel->gen >= 6) |
|
|
|
OUT_BATCH(0); |
|
|
|
|
|
|
|
ADVANCE_BATCH(); |
|
|
|
|
|
|
|
if (hiz_mt || separate_stencil) { |
|
|
|
/* |
|
|
@@ -770,7 +787,7 @@ static void emit_depthbuffer(struct brw_context *brw) |
|
|
|
OUT_BATCH(_3DSTATE_CLEAR_PARAMS << 16 | |
|
|
|
GEN5_DEPTH_CLEAR_VALID | |
|
|
|
(2 - 2)); |
|
|
|
OUT_BATCH(depth_irb ? depth_irb->mt->depth_clear_value : 0); |
|
|
|
OUT_BATCH(depth_mt ? depth_mt->depth_clear_value : 0); |
|
|
|
ADVANCE_BATCH(); |
|
|
|
} |
|
|
|
} |
|
|
@@ -781,7 +798,7 @@ const struct brw_tracked_state brw_depthbuffer = { |
|
|
|
.brw = BRW_NEW_BATCH, |
|
|
|
.cache = 0, |
|
|
|
}, |
|
|
|
.emit = emit_depthbuffer, |
|
|
|
.emit = brw_emit_depthbuffer, |
|
|
|
}; |
|
|
|
|
|
|
|
|