mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-31 01:10:16 +01:00
i965: Use BLORP for all HiZ ops
BLORP has been capable of doing gen8-style HiZ ops for a while now. We might as well start using it. The one downside is that this may cause a bit more state emission since we still re-emit most things for BLORP. Reviewed-by: Topi Pohjolainen <topi.pohjolainen@intel.com>
This commit is contained in:
parent
bacae7221b
commit
dd294fd2d9
3 changed files with 10 additions and 162 deletions
|
|
@ -993,6 +993,8 @@ intel_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
|
|||
unsigned int level, unsigned int start_layer,
|
||||
unsigned int num_layers, enum blorp_hiz_op op)
|
||||
{
|
||||
assert(intel_miptree_level_has_hiz(mt, level));
|
||||
assert(op != BLORP_HIZ_OP_NONE);
|
||||
const char *opname = NULL;
|
||||
|
||||
switch (op) {
|
||||
|
|
@ -1061,23 +1063,16 @@ intel_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
|
|||
}
|
||||
}
|
||||
|
||||
if (brw->gen >= 8) {
|
||||
for (unsigned a = 0; a < num_layers; a++)
|
||||
gen8_hiz_exec(brw, mt, level, start_layer + a, op);
|
||||
} else {
|
||||
assert(intel_miptree_level_has_hiz(mt, level));
|
||||
|
||||
struct isl_surf isl_tmp[2];
|
||||
struct blorp_surf surf;
|
||||
blorp_surf_for_miptree(brw, &surf, mt, true, (1 << ISL_AUX_USAGE_HIZ),
|
||||
&level, start_layer, num_layers, isl_tmp);
|
||||
|
||||
struct blorp_batch batch;
|
||||
blorp_batch_init(&brw->blorp, &batch, brw, 0);
|
||||
blorp_hiz_op(&batch, &surf, level, start_layer, num_layers, op);
|
||||
blorp_batch_finish(&batch);
|
||||
}
|
||||
struct isl_surf isl_tmp[2];
|
||||
struct blorp_surf surf;
|
||||
blorp_surf_for_miptree(brw, &surf, mt, true, (1 << ISL_AUX_USAGE_HIZ),
|
||||
&level, start_layer, num_layers, isl_tmp);
|
||||
|
||||
struct blorp_batch batch;
|
||||
blorp_batch_init(&brw->blorp, &batch, brw, 0);
|
||||
blorp_hiz_op(&batch, &surf, level, start_layer, num_layers, op);
|
||||
blorp_batch_finish(&batch);
|
||||
|
||||
/* The following stalls and flushes are only documented to be required for
|
||||
* HiZ clear operations. However, they also seem to be required for the
|
||||
|
|
|
|||
|
|
@ -1634,9 +1634,6 @@ gen8_emit_depth_stencil_hiz(struct brw_context *brw,
|
|||
uint32_t width, uint32_t height,
|
||||
uint32_t tile_x, uint32_t tile_y);
|
||||
|
||||
void gen8_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
|
||||
unsigned int level, unsigned int layer, enum blorp_hiz_op op);
|
||||
|
||||
uint32_t get_hw_prim_for_gl_prim(int mode);
|
||||
|
||||
void
|
||||
|
|
|
|||
|
|
@ -391,147 +391,3 @@ const struct brw_tracked_state gen8_pma_fix = {
|
|||
},
|
||||
.emit = gen8_emit_pma_stall_workaround
|
||||
};
|
||||
|
||||
/**
|
||||
* Emit packets to perform a depth/HiZ resolve or fast depth/stencil clear.
|
||||
*
|
||||
* See the "Optimized Depth Buffer Clear and/or Stencil Buffer Clear" section
|
||||
* of the hardware documentation for details.
|
||||
*/
|
||||
void
|
||||
gen8_hiz_exec(struct brw_context *brw, struct intel_mipmap_tree *mt,
|
||||
unsigned int level, unsigned int layer, enum blorp_hiz_op op)
|
||||
{
|
||||
if (op == BLORP_HIZ_OP_NONE)
|
||||
return;
|
||||
|
||||
/* Disable the PMA stall fix since we're about to do a HiZ operation. */
|
||||
if (brw->gen == 8)
|
||||
gen8_write_pma_stall_bits(brw, 0);
|
||||
|
||||
assert(mt->first_level == 0);
|
||||
assert(mt->logical_depth0 >= 1);
|
||||
|
||||
/* If we're operating on LOD 0, align to 8x4 to meet the alignment
|
||||
* requirements for most HiZ operations. Otherwise, use the actual size
|
||||
* to allow the hardware to calculate the miplevel offsets correctly.
|
||||
*/
|
||||
uint32_t surface_width = ALIGN(mt->logical_width0, level == 0 ? 8 : 1);
|
||||
uint32_t surface_height = ALIGN(mt->logical_height0, level == 0 ? 4 : 1);
|
||||
|
||||
/* From the documentation for 3DSTATE_WM_HZ_OP: "3DSTATE_MULTISAMPLE packet
|
||||
* must be used prior to this packet to change the Number of Multisamples.
|
||||
* This packet must not be used to change Number of Multisamples in a
|
||||
* rendering sequence."
|
||||
*/
|
||||
if (brw->num_samples != mt->num_samples) {
|
||||
gen8_emit_3dstate_multisample(brw, mt->num_samples);
|
||||
brw->NewGLState |= _NEW_MULTISAMPLE;
|
||||
}
|
||||
|
||||
/* The basic algorithm is:
|
||||
* - If needed, emit 3DSTATE_{DEPTH,HIER_DEPTH,STENCIL}_BUFFER and
|
||||
* 3DSTATE_CLEAR_PARAMS packets to set up the relevant buffers.
|
||||
* - If needed, emit 3DSTATE_DRAWING_RECTANGLE.
|
||||
* - Emit 3DSTATE_WM_HZ_OP with a bit set for the particular operation.
|
||||
* - Do a special PIPE_CONTROL to trigger an implicit rectangle primitive.
|
||||
* - Emit 3DSTATE_WM_HZ_OP with no bits set to return to normal rendering.
|
||||
*/
|
||||
emit_depth_packets(brw, mt,
|
||||
brw_depth_format(brw, mt->format),
|
||||
BRW_SURFACE_2D,
|
||||
true, /* depth writes */
|
||||
NULL, false, /* no stencil for now */
|
||||
true, /* hiz */
|
||||
surface_width,
|
||||
surface_height,
|
||||
mt->logical_depth0,
|
||||
level,
|
||||
layer); /* min_array_element */
|
||||
|
||||
/* Depth buffer clears and HiZ resolves must use an 8x4 aligned rectangle.
|
||||
* Note that intel_miptree_level_enable_hiz disables HiZ for miplevels > 0
|
||||
* which aren't 8x4 aligned, so expanding the size is safe - it'll just
|
||||
* draw into empty padding space.
|
||||
*/
|
||||
unsigned rect_width = ALIGN(minify(mt->logical_width0, level), 8);
|
||||
unsigned rect_height = ALIGN(minify(mt->logical_height0, level), 4);
|
||||
|
||||
BEGIN_BATCH(4);
|
||||
OUT_BATCH(_3DSTATE_DRAWING_RECTANGLE << 16 | (4 - 2));
|
||||
OUT_BATCH(0);
|
||||
OUT_BATCH(((rect_width - 1) & 0xffff) | ((rect_height - 1) << 16));
|
||||
OUT_BATCH(0);
|
||||
ADVANCE_BATCH();
|
||||
|
||||
/* Emit 3DSTATE_WM_HZ_OP to override pipeline state for the particular
|
||||
* resolve or clear operation we want to perform.
|
||||
*/
|
||||
uint32_t dw1 = 0;
|
||||
|
||||
switch (op) {
|
||||
case BLORP_HIZ_OP_DEPTH_RESOLVE:
|
||||
dw1 |= GEN8_WM_HZ_DEPTH_RESOLVE;
|
||||
break;
|
||||
case BLORP_HIZ_OP_HIZ_RESOLVE:
|
||||
dw1 |= GEN8_WM_HZ_HIZ_RESOLVE;
|
||||
break;
|
||||
case BLORP_HIZ_OP_DEPTH_CLEAR:
|
||||
dw1 |= GEN8_WM_HZ_DEPTH_CLEAR;
|
||||
|
||||
/* The "Clear Rectangle X Max" (and Y Max) fields are exclusive,
|
||||
* rather than inclusive, and limited to 16383. This means that
|
||||
* for a 16384x16384 render target, we would miss the last row
|
||||
* or column of pixels along the edge.
|
||||
*
|
||||
* To work around this, we have to set the "Full Surface Depth
|
||||
* and Stencil Clear" bit. We can do this in all cases because
|
||||
* we always clear the full rectangle anyway. We'll need to
|
||||
* change this if we ever add scissored clear support.
|
||||
*/
|
||||
dw1 |= GEN8_WM_HZ_FULL_SURFACE_DEPTH_CLEAR;
|
||||
break;
|
||||
case BLORP_HIZ_OP_NONE:
|
||||
unreachable("Should not get here.");
|
||||
}
|
||||
|
||||
if (mt->num_samples > 0)
|
||||
dw1 |= SET_FIELD(ffs(mt->num_samples) - 1, GEN8_WM_HZ_NUM_SAMPLES);
|
||||
|
||||
BEGIN_BATCH(5);
|
||||
OUT_BATCH(_3DSTATE_WM_HZ_OP << 16 | (5 - 2));
|
||||
OUT_BATCH(dw1);
|
||||
OUT_BATCH(0);
|
||||
OUT_BATCH(SET_FIELD(rect_width, GEN8_WM_HZ_CLEAR_RECTANGLE_X_MAX) |
|
||||
SET_FIELD(rect_height, GEN8_WM_HZ_CLEAR_RECTANGLE_Y_MAX));
|
||||
OUT_BATCH(SET_FIELD(0xFFFF, GEN8_WM_HZ_SAMPLE_MASK));
|
||||
ADVANCE_BATCH();
|
||||
|
||||
/* Emit a PIPE_CONTROL with "Post-Sync Operation" set to "Write Immediate
|
||||
* Data", and no other bits set. This causes 3DSTATE_WM_HZ_OP's state to
|
||||
* take effect, and spawns a rectangle primitive.
|
||||
*/
|
||||
brw_emit_pipe_control_write(brw,
|
||||
PIPE_CONTROL_WRITE_IMMEDIATE,
|
||||
brw->workaround_bo, 0, 0, 0);
|
||||
|
||||
/* Emit 3DSTATE_WM_HZ_OP again to disable the state overrides. */
|
||||
BEGIN_BATCH(5);
|
||||
OUT_BATCH(_3DSTATE_WM_HZ_OP << 16 | (5 - 2));
|
||||
OUT_BATCH(0);
|
||||
OUT_BATCH(0);
|
||||
OUT_BATCH(0);
|
||||
OUT_BATCH(0);
|
||||
ADVANCE_BATCH();
|
||||
|
||||
/* Mark this buffer as needing a TC flush, as we've rendered to it. */
|
||||
brw_render_cache_set_add_bo(brw, mt->bo);
|
||||
|
||||
/* We've clobbered all of the depth packets, and the drawing rectangle,
|
||||
* so we need to ensure those packets are re-emitted before the next
|
||||
* primitive.
|
||||
*
|
||||
* Setting _NEW_DEPTH and _NEW_BUFFERS covers it, but is rather overkill.
|
||||
*/
|
||||
brw->NewGLState |= _NEW_DEPTH | _NEW_BUFFERS;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue