Beispiel #1
0
static bool
tex_create_hiz(struct ilo_texture *tex)
{
   const struct pipe_resource *templ = &tex->base;
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   unsigned lv;

   tex->aux_bo = intel_winsys_alloc_bo(is->winsys, "hiz texture",
         INTEL_TILING_Y, tex->layout.aux_stride, tex->layout.aux_height,
         false);
   if (!tex->aux_bo)
      return false;

   for (lv = 0; lv <= templ->last_level; lv++) {
      if (tex->layout.aux_enables & (1 << lv)) {
         const unsigned num_slices = (templ->target == PIPE_TEXTURE_3D) ?
            u_minify(templ->depth0, lv) : templ->array_size;
         unsigned flags = ILO_TEXTURE_HIZ;

         /* this will trigger a HiZ resolve */
         if (tex->imported)
            flags |= ILO_TEXTURE_CPU_WRITE;

         ilo_texture_set_slice_flags(tex, lv, 0, num_slices, flags, flags);
      }
   }

   return true;
}
Beispiel #2
0
static bool
tex_create_hiz(struct ilo_texture *tex, const struct tex_layout *layout)
{
   struct ilo_screen *is = ilo_screen(tex->base.screen);
   const struct pipe_resource *templ = layout->templ;
   const int hz_align_j = 8;
   unsigned hz_width, hz_height, lv;
   unsigned long pitch;

   /*
    * See the Sandy Bridge PRM, volume 2 part 1, page 312, and the Ivy Bridge
    * PRM, volume 2 part 1, page 312-313.
    *
    * It seems HiZ buffer is aligned to 8x8, with every two rows packed into a
    * memory row.
    */

   hz_width = align(layout->levels[0].w, 16);

   if (templ->target == PIPE_TEXTURE_3D) {
      hz_height = 0;

      for (lv = 0; lv <= templ->last_level; lv++) {
         const unsigned h = align(layout->levels[lv].h, hz_align_j);
         hz_height += h * layout->levels[lv].d;
      }

      hz_height /= 2;
   }
   else {
      const unsigned h0 = align(layout->levels[0].h, hz_align_j);
      unsigned hz_qpitch = h0;

      if (layout->array_spacing_full) {
         const unsigned h1 = align(layout->levels[1].h, hz_align_j);
         const unsigned htail =
            ((layout->dev->gen >= ILO_GEN(7)) ? 12 : 11) * hz_align_j;

         hz_qpitch += h1 + htail;
      }

      hz_height = hz_qpitch * templ->array_size / 2;

      if (layout->dev->gen >= ILO_GEN(7))
         hz_height = align(hz_height, 8);
   }

   tex->hiz.bo = intel_winsys_alloc_texture(is->winsys,
         "hiz texture", hz_width, hz_height, 1,
         INTEL_TILING_Y, INTEL_ALLOC_FOR_RENDER, &pitch);
   if (!tex->hiz.bo)
      return false;

   tex->hiz.bo_stride = pitch;

   /*
    * From the Sandy Bridge PRM, volume 2 part 1, page 313-314:
    *
    *     "A rectangle primitive representing the clear area is delivered. The
    *      primitive must adhere to the following restrictions on size:
    *
    *      - If Number of Multisamples is NUMSAMPLES_1, the rectangle must be
    *        aligned to an 8x4 pixel block relative to the upper left corner
    *        of the depth buffer, and contain an integer number of these pixel
    *        blocks, and all 8x4 pixels must be lit.
    *
    *      - If Number of Multisamples is NUMSAMPLES_4, the rectangle must be
    *        aligned to a 4x2 pixel block (8x4 sample block) relative to the
    *        upper left corner of the depth buffer, and contain an integer
    *        number of these pixel blocks, and all samples of the 4x2 pixels
    *        must be lit
    *
    *      - If Number of Multisamples is NUMSAMPLES_8, the rectangle must be
    *        aligned to a 2x2 pixel block (8x4 sample block) relative to the
    *        upper left corner of the depth buffer, and contain an integer
    *        number of these pixel blocks, and all samples of the 2x2 pixels
    *        must be list."
    *
    *     "The following is required when performing a depth buffer resolve:
    *
    *      - A rectangle primitive of the same size as the previous depth
    *        buffer clear operation must be delivered, and depth buffer state
    *        cannot have changed since the previous depth buffer clear
    *        operation."
    *
    * Experiments on Haswell show that depth buffer resolves have the same
    * alignment requirements, and aligning the RECTLIST primitive and
    * 3DSTATE_DRAWING_RECTANGLE alone are not enough.  The mipmap size must be
    * aligned.
    */
   for (lv = 0; lv <= templ->last_level; lv++) {
      unsigned align_w = 8, align_h = 4;

      switch (templ->nr_samples) {
      case 0:
      case 1:
         break;
      case 2:
         align_w /= 2;
         break;
      case 4:
         align_w /= 2;
         align_h /= 2;
         break;
      case 8:
      default:
         align_w /= 4;
         align_h /= 2;
         break;
      }

      if (u_minify(templ->width0, lv) % align_w == 0 &&
          u_minify(templ->height0, lv) % align_h == 0) {
         const unsigned num_slices = (templ->target == PIPE_TEXTURE_3D) ?
            u_minify(templ->depth0, lv) : templ->array_size;

         ilo_texture_set_slice_flags(tex, lv, 0, num_slices,
               ILO_TEXTURE_HIZ, ILO_TEXTURE_HIZ);
      }
   }

   return true;
}