From: Jason Ekstrand Date: Tue, 6 Jun 2017 00:10:24 +0000 (-0700) Subject: i965: Use BLORP for all HiZ ops X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=dd294fd2d99fd3b244c869e00fb855bf84d180e8;p=mesa.git 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 --- diff --git a/src/mesa/drivers/dri/i965/brw_blorp.c b/src/mesa/drivers/dri/i965/brw_blorp.c index 568ff6980e8..8fb9973d5cf 100644 --- a/src/mesa/drivers/dri/i965/brw_blorp.c +++ b/src/mesa/drivers/dri/i965/brw_blorp.c @@ -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 diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h index 4c5bc3ba75e..6d38cbfaf82 100644 --- a/src/mesa/drivers/dri/i965/brw_context.h +++ b/src/mesa/drivers/dri/i965/brw_context.h @@ -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 diff --git a/src/mesa/drivers/dri/i965/gen8_depth_state.c b/src/mesa/drivers/dri/i965/gen8_depth_state.c index e7c7b9a4bd7..9460ff4b778 100644 --- a/src/mesa/drivers/dri/i965/gen8_depth_state.c +++ b/src/mesa/drivers/dri/i965/gen8_depth_state.c @@ -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; -}