On Fri, May 26, 2017 at 4:30 PM, Jason Ekstrand <ja...@jlekstrand.net> wrote:
> 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); > This should be ISL_AUX_STATE_PASS_THROUGH. I've fixed it locally. > + 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