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);
   }
}
Пример #2
0
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));
}