This is similar to the previous commit only for HiZ. For HiZ, apart from everything looking different, there is really only one functional change: We now track the ISL_AUX_STATE_COMPRESSED_NO_CLEAR state. Previously, if you rendered to a resolved slice of the miptree and then did a fast-clear with a different clear color, that slice would get resolved even though it hadn't been fast-cleared. Now that we can track COMPRESSED_NO_CLEAR, we know that it doesn't have any blocks in the "clear" state so we can skip the resolve. --- src/mesa/drivers/dri/i965/brw_clear.c | 3 +- src/mesa/drivers/dri/i965/intel_mipmap_tree.c | 222 ++++++++++++++------------ src/mesa/drivers/dri/i965/intel_mipmap_tree.h | 24 --- 3 files changed, 124 insertions(+), 125 deletions(-)
diff --git a/src/mesa/drivers/dri/i965/brw_clear.c b/src/mesa/drivers/dri/i965/brw_clear.c index aa2e994..be72d67 100644 --- a/src/mesa/drivers/dri/i965/brw_clear.c +++ b/src/mesa/drivers/dri/i965/brw_clear.c @@ -162,7 +162,8 @@ brw_fast_clear_depth(struct gl_context *ctx) * flags out of the HiZ buffer into the real depth buffer. */ if (mt->fast_clear_color.f32[0] != ctx->Depth.Clear) { - intel_miptree_all_slices_resolve_depth(brw, mt); + intel_miptree_prepare_access(brw, mt, 0, INTEL_REMAINING_LEVELS, + 0, INTEL_REMAINING_LAYERS, true, false); mt->fast_clear_color.f32[0] = ctx->Depth.Clear; } diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c index 3e30b2a..a1a8177 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.c +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.c @@ -325,7 +325,6 @@ intel_miptree_create_layout(struct brw_context *brw, INTEL_AUX_DISABLE_ALL : INTEL_AUX_DISABLE_NONE; mt->aux_disable |= INTEL_AUX_DISABLE_CCS; mt->is_scanout = (layout_flags & MIPTREE_LAYOUT_FOR_SCANOUT) != 0; - exec_list_make_empty(&mt->hiz_map); mt->aux_state = NULL; mt->cpp = _mesa_get_format_bytes(format); mt->num_samples = num_samples; @@ -974,7 +973,6 @@ intel_miptree_release(struct intel_mipmap_tree **mt) brw_bo_unreference((*mt)->mcs_buf->bo); free((*mt)->mcs_buf); } - intel_resolve_map_clear(&(*mt)->hiz_map); free_aux_state_map((*mt)->aux_state); intel_miptree_release(&(*mt)->plane[0]); @@ -1909,6 +1907,11 @@ intel_miptree_alloc_hiz(struct brw_context *brw, assert(mt->hiz_buf == NULL); assert((mt->aux_disable & INTEL_AUX_DISABLE_HIZ) == 0); + enum isl_aux_state **aux_state = + create_aux_state_map(mt, ISL_AUX_STATE_AUX_INVALID); + if (!aux_state) + return false; + if (brw->gen == 7) { mt->hiz_buf = intel_gen7_hiz_buf_create(brw, mt); } else if (brw->gen >= 8) { @@ -1917,24 +1920,15 @@ intel_miptree_alloc_hiz(struct brw_context *brw, mt->hiz_buf = intel_hiz_miptree_buf_create(brw, mt); } - if (!mt->hiz_buf) + if (!mt->hiz_buf) { + free(aux_state); return false; + } - /* Mark that all slices need a HiZ resolve. */ - for (unsigned level = mt->first_level; level <= mt->last_level; ++level) { - if (!intel_miptree_level_enable_hiz(brw, mt, level)) - continue; - - for (unsigned layer = 0; layer < mt->level[level].depth; ++layer) { - struct intel_resolve_map *m = malloc(sizeof(struct intel_resolve_map)); - exec_node_init(&m->link); - m->level = level; - m->layer = layer; - m->need = BLORP_HIZ_OP_HIZ_RESOLVE; + for (unsigned level = mt->first_level; level <= mt->last_level; ++level) + intel_miptree_level_enable_hiz(brw, mt, level); - exec_list_push_tail(&mt->hiz_map, &m->link); - } - } + mt->aux_state = aux_state; return true; } @@ -1993,41 +1987,6 @@ intel_miptree_level_has_hiz(struct intel_mipmap_tree *mt, uint32_t level) return mt->level[level].has_hiz; } -static bool -intel_miptree_depth_hiz_resolve(struct brw_context *brw, - struct intel_mipmap_tree *mt, - uint32_t start_level, uint32_t num_levels, - uint32_t start_layer, uint32_t num_layers, - enum blorp_hiz_op need) -{ - bool did_resolve = false; - - foreach_list_typed_safe(struct intel_resolve_map, map, link, &mt->hiz_map) { - if (map->level < start_level || - map->level >= (start_level + num_levels) || - map->layer < start_layer || - map->layer >= (start_layer + num_layers)) - continue; - - if (map->need != need) - continue; - - intel_hiz_exec(brw, mt, map->level, map->layer, need); - intel_resolve_map_remove(map); - did_resolve = true; - } - - return did_resolve; -} - -bool -intel_miptree_all_slices_resolve_depth(struct brw_context *brw, - struct intel_mipmap_tree *mt) -{ - return intel_miptree_depth_hiz_resolve(brw, mt, 0, UINT32_MAX, 0, UINT32_MAX, - BLORP_HIZ_OP_DEPTH_RESOLVE); -} - bool intel_miptree_has_color_unresolved(const struct intel_mipmap_tree *mt, unsigned start_level, unsigned num_levels, @@ -2267,6 +2226,96 @@ intel_miptree_finish_mcs_write(struct brw_context *brw, } } +static void +intel_miptree_prepare_hiz_access(struct brw_context *brw, + struct intel_mipmap_tree *mt, + uint32_t level, uint32_t layer, + bool hiz_supported, bool fast_clear_supported) +{ + enum blorp_hiz_op hiz_op = BLORP_HIZ_OP_NONE; + switch (intel_miptree_get_aux_state(mt, level, layer)) { + case ISL_AUX_STATE_CLEAR: + case ISL_AUX_STATE_COMPRESSED_CLEAR: + if (!hiz_supported || !fast_clear_supported) + hiz_op = BLORP_HIZ_OP_DEPTH_RESOLVE; + break; + + case ISL_AUX_STATE_COMPRESSED_NO_CLEAR: + if (!hiz_supported) + hiz_op = BLORP_HIZ_OP_DEPTH_RESOLVE; + break; + + case ISL_AUX_STATE_PASS_THROUGH: + case ISL_AUX_STATE_RESOLVED: + break; + + case ISL_AUX_STATE_AUX_INVALID: + if (hiz_supported) + hiz_op = BLORP_HIZ_OP_HIZ_RESOLVE; + break; + } + + if (hiz_op != BLORP_HIZ_OP_NONE) { + intel_hiz_exec(brw, mt, level, layer, hiz_op); + + switch (hiz_op) { + case BLORP_HIZ_OP_DEPTH_RESOLVE: + intel_miptree_set_aux_state(brw, mt, level, layer, 1, + ISL_AUX_STATE_RESOLVED); + break; + + case BLORP_HIZ_OP_HIZ_RESOLVE: + /* The HiZ resolve operation is actually an ambiguate */ + intel_miptree_set_aux_state(brw, mt, level, layer, 1, + ISL_AUX_STATE_RESOLVED); + break; + + default: + unreachable("Invalid HiZ op"); + } + } +} + +static void +intel_miptree_finish_hiz_write(struct brw_context *brw, + struct intel_mipmap_tree *mt, + uint32_t level, uint32_t layer, + bool written_with_hiz) +{ + switch (intel_miptree_get_aux_state(mt, level, layer)) { + case ISL_AUX_STATE_CLEAR: + assert(written_with_hiz); + intel_miptree_set_aux_state(brw, mt, level, layer, 1, + ISL_AUX_STATE_COMPRESSED_CLEAR); + break; + + case ISL_AUX_STATE_COMPRESSED_NO_CLEAR: + case ISL_AUX_STATE_COMPRESSED_CLEAR: + assert(written_with_hiz); + break; /* Nothing to do */ + + case ISL_AUX_STATE_RESOLVED: + if (written_with_hiz) { + intel_miptree_set_aux_state(brw, mt, level, layer, 1, + ISL_AUX_STATE_COMPRESSED_NO_CLEAR); + } else { + intel_miptree_set_aux_state(brw, mt, level, layer, 1, + ISL_AUX_STATE_AUX_INVALID); + } + + case ISL_AUX_STATE_PASS_THROUGH: + if (written_with_hiz) { + intel_miptree_set_aux_state(brw, mt, level, layer, 1, + ISL_AUX_STATE_COMPRESSED_NO_CLEAR); + } + break; + + case ISL_AUX_STATE_AUX_INVALID: + assert(!written_with_hiz); + break; + } +} + void intel_miptree_prepare_access(struct brw_context *brw, struct intel_mipmap_tree *mt, @@ -2305,16 +2354,17 @@ intel_miptree_prepare_access(struct brw_context *brw, if (!mt->hiz_buf) return; - if (aux_supported) { - assert(fast_clear_supported); - intel_miptree_depth_hiz_resolve(brw, mt, start_level, num_levels, - start_layer, num_layers, - BLORP_HIZ_OP_HIZ_RESOLVE); - } else { - assert(!fast_clear_supported); - intel_miptree_depth_hiz_resolve(brw, mt, start_level, num_levels, - start_layer, num_layers, - BLORP_HIZ_OP_DEPTH_RESOLVE); + for (uint32_t level = start_level; level <= last_level; level++) { + if (!intel_miptree_level_has_hiz(mt, level)) + continue; + + const uint32_t level_layers = + MIN2(num_layers, mt->level[level].depth); + for (uint32_t a = 0; a < level_layers; a++) { + intel_miptree_prepare_hiz_access(brw, mt, level, start_layer + a, + aux_supported, + fast_clear_supported); + } } } } @@ -2351,18 +2401,9 @@ intel_miptree_finish_write(struct brw_context *brw, if (!intel_miptree_level_has_hiz(mt, level)) return; - if (written_with_aux) { - for (unsigned a = 0; a < num_layers; a++) { - intel_miptree_check_level_layer(mt, level, start_layer); - intel_resolve_map_set(&mt->hiz_map, level, start_layer + a, - BLORP_HIZ_OP_DEPTH_RESOLVE); - } - } else { - for (unsigned a = 0; a < num_layers; a++) { - intel_miptree_check_level_layer(mt, level, start_layer); - intel_resolve_map_set(&mt->hiz_map, level, start_layer + a, - BLORP_HIZ_OP_HIZ_RESOLVE); - } + for (uint32_t a = 0; a < num_layers; a++) { + intel_miptree_finish_hiz_write(brw, mt, level, start_layer + a, + written_with_aux); } } } @@ -2376,24 +2417,13 @@ intel_miptree_get_aux_state(const struct intel_mipmap_tree *mt, if (_mesa_is_format_color_format(mt->format)) { assert(mt->mcs_buf != NULL); assert(mt->num_samples <= 1 || mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS); - return mt->aux_state[level][layer]; } else if (mt->format == MESA_FORMAT_S_UINT8) { unreachable("Cannot get aux state for stencil"); } else { assert(mt->hiz_buf != NULL); - const struct intel_resolve_map *map = - intel_resolve_map_const_get(&mt->hiz_map, level, layer); - if (!map) - return ISL_AUX_STATE_RESOLVED; - switch (map->need) { - case BLORP_HIZ_OP_DEPTH_RESOLVE: - return ISL_AUX_STATE_COMPRESSED_CLEAR; - case BLORP_HIZ_OP_HIZ_RESOLVE: - return ISL_AUX_STATE_AUX_INVALID; - default: - unreachable("Invalid hiz op"); - } } + + return mt->aux_state[level][layer]; } void @@ -2410,23 +2440,14 @@ intel_miptree_set_aux_state(struct brw_context *brw, if (_mesa_is_format_color_format(mt->format)) { assert(mt->mcs_buf != NULL); assert(mt->num_samples <= 1 || mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS); - - for (unsigned a = 0; a < num_layers; a++) - mt->aux_state[level][start_layer + a] = aux_state; } else if (mt->format == MESA_FORMAT_S_UINT8) { unreachable("Cannot get aux state for stencil"); } else { assert(mt->hiz_buf != NULL); - - /* Right now, this only applies to clears. */ - assert(aux_state == ISL_AUX_STATE_CLEAR); - - for (unsigned a = 0; a < num_layers; a++) { - intel_miptree_check_level_layer(mt, level, start_layer); - intel_resolve_map_set(&mt->hiz_map, level, start_layer + a, - BLORP_HIZ_OP_DEPTH_RESOLVE); - } } + + for (unsigned a = 0; a < num_layers; a++) + mt->aux_state[level][start_layer + a] = aux_state; } /* On Gen9 color buffers may be compressed by the hardware (lossless @@ -2647,7 +2668,8 @@ intel_miptree_make_shareable(struct brw_context *brw, * any will likely crash due to the missing aux buffer. So let's delete * all pending ops. */ - exec_list_make_empty(&mt->hiz_map); + free(mt->aux_state); + mt->aux_state = NULL; } } diff --git a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h index 528c32c..428c097 100644 --- a/src/mesa/drivers/dri/i965/intel_mipmap_tree.h +++ b/src/mesa/drivers/dri/i965/intel_mipmap_tree.h @@ -542,23 +542,6 @@ struct intel_mipmap_tree struct intel_miptree_hiz_buffer *hiz_buf; /** - * \brief Maps of miptree slices to needed resolves. - * - * hiz_map is used only when the miptree has a child HiZ miptree. - * - * Let \c mt be a depth miptree with HiZ enabled. Then the resolve map is - * \c mt->hiz_map. The resolve map of the child HiZ miptree, \c - * mt->hiz_mt->hiz_map, is unused. - * - * - * color_resolve_map is used only when the miptree uses fast clear (Gen7+) - * lossless compression (Gen9+). It should be noted that absence in the - * map means implicitly RESOLVED state. If item is found it always - * indicates state other than RESOLVED. - */ - struct exec_list hiz_map; /* List of intel_resolve_map. */ - - /** * \brief Maps miptree slices to their current aux state * * This two-dimensional array is indexed as [level][layer] and stores an @@ -825,13 +808,6 @@ intel_miptree_alloc_hiz(struct brw_context *brw, bool intel_miptree_level_has_hiz(struct intel_mipmap_tree *mt, uint32_t level); -/** - * \return false if no resolve was needed - */ -bool -intel_miptree_all_slices_resolve_depth(struct brw_context *brw, - struct intel_mipmap_tree *mt); - /**\}*/ bool -- 2.5.0.400.gff86faf _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev