void intel_renderbuffer_set_needs_hiz_resolve(struct intel_renderbuffer *irb) { if (irb->mt) { intel_miptree_slice_set_needs_hiz_resolve(irb->mt, irb->mt_level, irb->mt_layer); } }
static void blorp_surf_for_miptree(struct brw_context *brw, struct blorp_surf *surf, struct intel_mipmap_tree *mt, bool is_render_target, uint32_t safe_aux_usage, unsigned *level, unsigned start_layer, unsigned num_layers, struct isl_surf tmp_surfs[2]) { if (mt->msaa_layout == INTEL_MSAA_LAYOUT_UMS || mt->msaa_layout == INTEL_MSAA_LAYOUT_CMS) { const unsigned num_samples = MAX2(1, mt->num_samples); for (unsigned i = 0; i < num_layers; i++) { for (unsigned s = 0; s < num_samples; s++) { const unsigned phys_layer = (start_layer + i) * num_samples + s; intel_miptree_check_level_layer(mt, *level, phys_layer); } } } else { for (unsigned i = 0; i < num_layers; i++) intel_miptree_check_level_layer(mt, *level, start_layer + i); } intel_miptree_get_isl_surf(brw, mt, &tmp_surfs[0]); surf->surf = &tmp_surfs[0]; surf->addr = (struct blorp_address) { .buffer = mt->bo, .offset = mt->offset, .read_domains = is_render_target ? I915_GEM_DOMAIN_RENDER : I915_GEM_DOMAIN_SAMPLER, .write_domain = is_render_target ? I915_GEM_DOMAIN_RENDER : 0, }; if (brw->gen == 6 && mt->format == MESA_FORMAT_S_UINT8 && mt->array_layout == ALL_SLICES_AT_EACH_LOD) { /* Sandy bridge stencil and HiZ use this ALL_SLICES_AT_EACH_LOD hack in * order to allow for layered rendering. The hack makes each LOD of the * stencil or HiZ buffer a single tightly packed array surface at some * offset into the surface. Since ISL doesn't know how to deal with the * crazy ALL_SLICES_AT_EACH_LOD layout and since we have to do a manual * offset of it anyway, we might as well do the offset here and keep the * hacks inside the i965 driver. * * See also gen6_depth_stencil_state.c */ uint32_t offset; apply_gen6_stencil_hiz_offset(&tmp_surfs[0], mt, *level, &offset); surf->addr.offset += offset; *level = 0; } struct isl_surf *aux_surf = &tmp_surfs[1]; intel_miptree_get_aux_isl_surf(brw, mt, aux_surf, &surf->aux_usage); if (surf->aux_usage != ISL_AUX_USAGE_NONE) { if (surf->aux_usage == ISL_AUX_USAGE_HIZ) { /* If we're not going to use it as a depth buffer, resolve HiZ */ if (!(safe_aux_usage & (1 << ISL_AUX_USAGE_HIZ))) { for (unsigned i = 0; i < num_layers; i++) { intel_miptree_slice_resolve_depth(brw, mt, *level, start_layer + i); /* If we're rendering to it then we'll need a HiZ resolve once * we're done before we can use it with HiZ again. */ if (is_render_target) intel_miptree_slice_set_needs_hiz_resolve(mt, *level, start_layer + i); } surf->aux_usage = ISL_AUX_USAGE_NONE; } } else if (!(safe_aux_usage & (1 << surf->aux_usage))) { uint32_t flags = 0; if (safe_aux_usage & (1 << ISL_AUX_USAGE_CCS_E)) flags |= INTEL_MIPTREE_IGNORE_CCS_E; intel_miptree_resolve_color(brw, mt, *level, start_layer, num_layers, flags); assert(!intel_miptree_has_color_unresolved(mt, *level, 1, start_layer, num_layers)); surf->aux_usage = ISL_AUX_USAGE_NONE; } } if (is_render_target) intel_miptree_used_for_rendering(brw, mt, *level, start_layer, num_layers); if (surf->aux_usage != ISL_AUX_USAGE_NONE) { /* We only really need a clear color if we also have an auxiliary * surface. Without one, it does nothing. */ surf->clear_color = intel_miptree_get_isl_clear_color(brw, mt); surf->aux_surf = aux_surf; surf->aux_addr = (struct blorp_address) { .read_domains = is_render_target ? I915_GEM_DOMAIN_RENDER : I915_GEM_DOMAIN_SAMPLER, .write_domain = is_render_target ? I915_GEM_DOMAIN_RENDER : 0, }; if (mt->mcs_buf) { surf->aux_addr.buffer = mt->mcs_buf->bo; surf->aux_addr.offset = mt->mcs_buf->offset; } else { assert(surf->aux_usage == ISL_AUX_USAGE_HIZ); struct intel_mipmap_tree *hiz_mt = mt->hiz_buf->mt; if (hiz_mt) { surf->aux_addr.buffer = hiz_mt->bo; if (brw->gen == 6 && hiz_mt->array_layout == ALL_SLICES_AT_EACH_LOD) { /* gen6 requires the HiZ buffer to be manually offset to the * right location. We could fixup the surf but it doesn't * matter since most of those fields don't matter. */ apply_gen6_stencil_hiz_offset(aux_surf, hiz_mt, *level, &surf->aux_addr.offset); } else { surf->aux_addr.offset = 0; } assert(hiz_mt->pitch == aux_surf->row_pitch); } else { surf->aux_addr.buffer = mt->hiz_buf->aux_base.bo; surf->aux_addr.offset = mt->hiz_buf->aux_base.offset; } } } else { surf->aux_addr = (struct blorp_address) { .buffer = NULL, }; memset(&surf->clear_color, 0, sizeof(surf->clear_color)); } assert((surf->aux_usage == ISL_AUX_USAGE_NONE) == (surf->aux_addr.buffer == NULL)); }