ilo: initialize ilo_image from ilo_image_info
authorChia-I Wu <olvaffe@gmail.com>
Wed, 24 Jun 2015 14:46:36 +0000 (22:46 +0800)
committerChia-I Wu <olvaffe@gmail.com>
Fri, 26 Jun 2015 05:45:28 +0000 (13:45 +0800)
Convert pipe_resource to ilo_image_info for image initialization.

src/gallium/drivers/ilo/core/ilo_image.c
src/gallium/drivers/ilo/core/ilo_image.h
src/gallium/drivers/ilo/ilo_resource.c

index ed9b288..39c6daa 100644 (file)
@@ -42,7 +42,7 @@ enum {
 
 struct ilo_image_params {
    const struct ilo_dev *dev;
-   const struct pipe_resource *templ;
+   const struct ilo_image_info *info;
    unsigned valid_tilings;
 
    bool compressed;
@@ -56,7 +56,7 @@ img_get_slice_size(const struct ilo_image *img,
                    const struct ilo_image_params *params,
                    unsigned level, unsigned *width, unsigned *height)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    unsigned w, h;
 
    w = u_minify(img->width0, level);
@@ -112,8 +112,7 @@ img_get_slice_size(const struct ilo_image *img,
     *   y = align(y, 2) * 2;
     */
    if (img->interleaved_samples) {
-      switch (templ->nr_samples) {
-      case 0:
+      switch (info->sample_count) {
       case 1:
          break;
       case 2:
@@ -157,12 +156,12 @@ static unsigned
 img_get_num_layers(const struct ilo_image *img,
                    const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
-   unsigned num_layers = templ->array_size;
+   const struct ilo_image_info *info = params->info;
+   unsigned num_layers = info->array_size;
 
    /* samples of the same index are stored in a layer */
-   if (templ->nr_samples > 1 && !img->interleaved_samples)
-      num_layers *= templ->nr_samples;
+   if (info->sample_count > 1 && !img->interleaved_samples)
+      num_layers *= info->sample_count;
 
    return num_layers;
 }
@@ -171,7 +170,7 @@ static void
 img_init_layer_height(struct ilo_image *img,
                       struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    unsigned num_layers;
 
    if (img->walk != ILO_IMAGE_WALK_LAYER)
@@ -218,7 +217,7 @@ img_init_layer_height(struct ilo_image *img,
    img->walk_layer_height = params->h0 + params->h1 +
       ((ilo_dev_gen(params->dev) >= ILO_GEN(7)) ? 12 : 11) * img->align_j;
 
-   if (ilo_dev_gen(params->dev) == ILO_GEN(6) && templ->nr_samples > 1 &&
+   if (ilo_dev_gen(params->dev) == ILO_GEN(6) && info->sample_count > 1 &&
        img->height0 % 4 == 1)
       img->walk_layer_height += 4;
 
@@ -229,13 +228,13 @@ static void
 img_init_lods(struct ilo_image *img,
               struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    unsigned cur_x, cur_y;
    unsigned lv;
 
    cur_x = 0;
    cur_y = 0;
-   for (lv = 0; lv <= templ->last_level; lv++) {
+   for (lv = 0; lv < info->level_count; lv++) {
       unsigned lod_w, lod_h;
 
       img_get_slice_size(img, params, lv, &lod_w, &lod_h);
@@ -261,7 +260,7 @@ img_init_lods(struct ilo_image *img,
             cur_y += lod_h;
 
          /* every LOD begins at tile boundaries */
-         if (templ->last_level > 0) {
+         if (info->level_count > 1) {
             assert(img->format == PIPE_FORMAT_S8_UINT);
             cur_x = align(cur_x, 64);
             cur_y = align(cur_y, 64);
@@ -269,7 +268,7 @@ img_init_lods(struct ilo_image *img,
          break;
       case ILO_IMAGE_WALK_3D:
          {
-            const unsigned num_slices = u_minify(templ->depth0, lv);
+            const unsigned num_slices = u_minify(info->depth, lv);
             const unsigned num_slices_per_row = 1 << lv;
             const unsigned num_rows =
                (num_slices + num_slices_per_row - 1) / num_slices_per_row;
@@ -291,7 +290,7 @@ img_init_lods(struct ilo_image *img,
    if (img->walk == ILO_IMAGE_WALK_LAYER) {
       params->h0 = img->lods[0].slice_height;
 
-      if (templ->last_level > 0)
+      if (info->level_count > 1)
          params->h1 = img->lods[1].slice_height;
       else
          img_get_slice_size(img, params, 1, &cur_x, &params->h1);
@@ -302,7 +301,7 @@ static void
 img_init_alignments(struct ilo_image *img,
                     const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
 
    /*
     * From the Sandy Bridge PRM, volume 1 part 1, page 113:
@@ -396,7 +395,7 @@ img_init_alignments(struct ilo_image *img,
       /* this happens to be the case */
       img->align_i = img->block_width;
       img->align_j = img->block_height;
-   } else if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
+   } else if (info->bind_zs) {
       if (ilo_dev_gen(params->dev) >= ILO_GEN(7)) {
          switch (img->format) {
          case PIPE_FORMAT_Z16_UNORM:
@@ -426,11 +425,11 @@ img_init_alignments(struct ilo_image *img,
       }
    } else {
       const bool valign_4 =
-         (templ->nr_samples > 1) ||
+         (info->sample_count > 1) ||
          (ilo_dev_gen(params->dev) >= ILO_GEN(8)) ||
          (ilo_dev_gen(params->dev) >= ILO_GEN(7) &&
           img->tiling == GEN6_TILING_Y &&
-          (templ->bind & PIPE_BIND_RENDER_TARGET));
+          info->bind_surface_dp_render);
 
       if (ilo_dev_gen(params->dev) >= ILO_GEN(7) &&
           ilo_dev_gen(params->dev) <= ILO_GEN(7.5) && valign_4)
@@ -460,14 +459,14 @@ static void
 img_init_tiling(struct ilo_image *img,
                 const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    unsigned preferred_tilings = params->valid_tilings;
 
    /* no fencing nor BLT support */
    if (preferred_tilings & ~IMAGE_TILING_W)
       preferred_tilings &= ~IMAGE_TILING_W;
 
-   if (templ->bind & (PIPE_BIND_RENDER_TARGET | PIPE_BIND_SAMPLER_VIEW)) {
+   if (info->bind_surface_dp_render || info->bind_surface_sampler) {
       /*
        * heuristically set a minimum width/height for enabling tiling
        */
@@ -499,7 +498,7 @@ static void
 img_init_walk_gen7(struct ilo_image *img,
                    const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
 
    /*
     * It is not explicitly states, but render targets are expected to be
@@ -508,14 +507,14 @@ img_init_walk_gen7(struct ilo_image *img,
     *
     * See "Multisampled Surface Storage Format" field of SURFACE_STATE.
     */
-   if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
+   if (info->bind_zs) {
       /*
        * From the Ivy Bridge PRM, volume 1 part 1, page 111:
        *
        *     "note that the depth buffer and stencil buffer have an implied
        *      value of ARYSPC_FULL"
        */
-      img->walk = (templ->target == PIPE_TEXTURE_3D) ?
+      img->walk = (info->target == PIPE_TEXTURE_3D) ?
          ILO_IMAGE_WALK_3D : ILO_IMAGE_WALK_LAYER;
 
       img->interleaved_samples = true;
@@ -530,12 +529,12 @@ img_init_walk_gen7(struct ilo_image *img,
        * As multisampled resources are not mipmapped, we never use
        * ARYSPC_FULL for them.
        */
-      if (templ->nr_samples > 1)
-         assert(templ->last_level == 0);
+      if (info->sample_count > 1)
+         assert(info->level_count == 1);
 
       img->walk =
-         (templ->target == PIPE_TEXTURE_3D) ? ILO_IMAGE_WALK_3D :
-         (templ->last_level > 0) ? ILO_IMAGE_WALK_LAYER :
+         (info->target == PIPE_TEXTURE_3D) ? ILO_IMAGE_WALK_3D :
+         (info->level_count > 1) ? ILO_IMAGE_WALK_LAYER :
          ILO_IMAGE_WALK_LOD;
 
       img->interleaved_samples = false;
@@ -558,7 +557,7 @@ img_init_walk_gen6(struct ilo_image *img,
     * GEN6 does not support compact spacing otherwise.
     */
    img->walk =
-      (params->templ->target == PIPE_TEXTURE_3D) ? ILO_IMAGE_WALK_3D :
+      (params->info->target == PIPE_TEXTURE_3D) ? ILO_IMAGE_WALK_3D :
       (img->format == PIPE_FORMAT_S8_UINT) ? ILO_IMAGE_WALK_LOD :
       ILO_IMAGE_WALK_LAYER;
 
@@ -580,7 +579,7 @@ static unsigned
 img_get_valid_tilings(const struct ilo_image *img,
                       const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    const enum pipe_format format = img->format;
    unsigned valid_tilings = params->valid_tilings;
 
@@ -590,7 +589,7 @@ img_get_valid_tilings(const struct ilo_image *img,
     *     "Display/Overlay   Y-Major not supported.
     *                        X-Major required for Async Flips"
     */
-   if (unlikely(templ->bind & PIPE_BIND_SCANOUT))
+   if (unlikely(info->bind_scanout))
       valid_tilings &= IMAGE_TILING_X;
 
    /*
@@ -599,7 +598,7 @@ img_get_valid_tilings(const struct ilo_image *img,
     *     "The cursor surface address must be 4K byte aligned. The cursor must
     *      be in linear memory, it cannot be tiled."
     */
-   if (unlikely(templ->bind & (PIPE_BIND_CURSOR | PIPE_BIND_LINEAR)))
+   if (unlikely(info->bind_cursor))
       valid_tilings &= IMAGE_TILING_NONE;
 
    /*
@@ -614,7 +613,7 @@ img_get_valid_tilings(const struct ilo_image *img,
     *
     *     "W-Major Tile Format is used for separate stencil."
     */
-   if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
+   if (info->bind_zs) {
       switch (format) {
       case PIPE_FORMAT_S8_UINT:
          valid_tilings &= IMAGE_TILING_W;
@@ -625,7 +624,7 @@ img_get_valid_tilings(const struct ilo_image *img,
       }
    }
 
-   if (templ->bind & PIPE_BIND_RENDER_TARGET) {
+   if (info->bind_surface_dp_render) {
       /*
        * From the Sandy Bridge PRM, volume 1 part 2, page 32:
        *
@@ -656,7 +655,7 @@ img_get_valid_tilings(const struct ilo_image *img,
       valid_tilings &= ~IMAGE_TILING_W;
    }
 
-   if (templ->bind & PIPE_BIND_SAMPLER_VIEW) {
+   if (info->bind_surface_sampler) {
       if (ilo_dev_gen(params->dev) < ILO_GEN(8))
          valid_tilings &= ~IMAGE_TILING_W;
    }
@@ -671,17 +670,17 @@ static void
 img_init_size_and_format(struct ilo_image *img,
                          struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
-   enum pipe_format format = templ->format;
+   const struct ilo_image_info *info = params->info;
+   enum pipe_format format = info->format;
    bool require_separate_stencil = false;
 
-   img->target = templ->target;
-   img->width0 = templ->width0;
-   img->height0 = templ->height0;
-   img->depth0 = templ->depth0;
-   img->array_size = templ->array_size;
-   img->level_count = templ->last_level + 1;
-   img->sample_count = (templ->nr_samples) ? templ->nr_samples : 1;
+   img->target = info->target;
+   img->width0 = info->width;
+   img->height0 = info->height;
+   img->depth0 = info->depth;
+   img->array_size = info->array_size;
+   img->level_count = info->level_count;
+   img->sample_count = info->sample_count;
 
    /*
     * From the Sandy Bridge PRM, volume 2 part 1, page 317:
@@ -691,7 +690,7 @@ img_init_size_and_format(struct ilo_image *img,
     *
     * GEN7+ requires separate stencil buffers.
     */
-   if (templ->bind & PIPE_BIND_DEPTH_STENCIL) {
+   if (info->bind_zs) {
       if (ilo_dev_gen(params->dev) >= ILO_GEN(7))
          require_separate_stencil = true;
       else
@@ -731,15 +730,14 @@ static bool
 img_want_mcs(const struct ilo_image *img,
              const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    bool want_mcs = false;
 
    /* MCS is for RT on GEN7+ */
    if (ilo_dev_gen(params->dev) < ILO_GEN(7))
       return false;
 
-   if (templ->target != PIPE_TEXTURE_2D ||
-       !(templ->bind & PIPE_BIND_RENDER_TARGET))
+   if (info->target != PIPE_TEXTURE_2D || !info->bind_surface_dp_render)
       return false;
 
    /*
@@ -752,9 +750,9 @@ img_want_mcs(const struct ilo_image *img,
     *     "This field must be set to 0 for all SINT MSRTs when all RT channels
     *      are not written"
     */
-   if (templ->nr_samples > 1 && !util_format_is_pure_sint(templ->format)) {
+   if (info->sample_count > 1 && !util_format_is_pure_sint(info->format)) {
       want_mcs = true;
-   } else if (templ->nr_samples <= 1) {
+   } else if (info->sample_count == 1 && !info->aux_disable) {
       /*
        * From the Ivy Bridge PRM, volume 2 part 1, page 326:
        *
@@ -770,7 +768,7 @@ img_want_mcs(const struct ilo_image *img,
        *      ..."
        */
       if (img->tiling != GEN6_TILING_NONE &&
-          templ->last_level == 0 && templ->array_size == 1) {
+          info->level_count == 1 && info->array_size == 1) {
          switch (img->block_size) {
          case 4:
          case 8:
@@ -790,25 +788,24 @@ static bool
 img_want_hiz(const struct ilo_image *img,
              const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    const struct util_format_description *desc =
-      util_format_description(templ->format);
+      util_format_description(info->format);
 
    if (ilo_debug & ILO_DEBUG_NOHIZ)
       return false;
 
-   /* we want 8x4 aligned levels */
-   if (templ->target == PIPE_TEXTURE_1D)
+   if (info->aux_disable)
       return false;
 
-   if (!(templ->bind & PIPE_BIND_DEPTH_STENCIL))
+   /* we want 8x4 aligned levels */
+   if (info->target == PIPE_TEXTURE_1D)
       return false;
 
-   if (!util_format_has_depth(desc))
+   if (!info->bind_zs)
       return false;
 
-   /* no point in having HiZ */
-   if (templ->usage == PIPE_USAGE_STAGING)
+   if (!util_format_has_depth(desc))
       return false;
 
    /*
@@ -819,8 +816,8 @@ img_want_hiz(const struct ilo_image *img,
     * can result in incompatible formats.
     */
    if (ilo_dev_gen(params->dev) == ILO_GEN(6) &&
-       templ->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
-       templ->last_level)
+       info->format == PIPE_FORMAT_Z32_FLOAT_S8X24_UINT &&
+       info->level_count > 1)
       return false;
 
    return true;
@@ -839,7 +836,7 @@ img_init_aux(struct ilo_image *img,
 static void
 img_align(struct ilo_image *img, struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    int align_w = 1, align_h = 1, pad_h = 0;
 
    /*
@@ -864,11 +861,11 @@ img_align(struct ilo_image *img, struct ilo_image_params *params)
     *      padding purposes. The value of 4 for j still applies for mip level
     *      alignment and QPitch calculation."
     */
-   if (templ->bind & PIPE_BIND_SAMPLER_VIEW) {
+   if (info->bind_surface_sampler) {
       align_w = MAX2(align_w, img->align_i);
       align_h = MAX2(align_h, img->align_j);
 
-      if (templ->target == PIPE_TEXTURE_CUBE)
+      if (info->target == PIPE_TEXTURE_CUBE)
          pad_h += 2;
 
       if (params->compressed)
@@ -881,7 +878,7 @@ img_align(struct ilo_image *img, struct ilo_image_params *params)
     *     "If the surface contains an odd number of rows of data, a final row
     *      below the surface must be allocated."
     */
-   if (templ->bind & PIPE_BIND_RENDER_TARGET)
+   if (info->bind_surface_dp_render)
       align_h = MAX2(align_h, 2);
 
    /*
@@ -889,9 +886,9 @@ img_align(struct ilo_image *img, struct ilo_image_params *params)
     * for unaligned non-mipmapped and non-array images.
     */
    if (img->aux.type == ILO_IMAGE_AUX_HIZ &&
-       templ->last_level == 0 &&
-       templ->array_size == 1 &&
-       templ->depth0 == 1) {
+       info->level_count == 1 &&
+       info->array_size == 1 &&
+       info->depth == 1) {
       align_w = MAX2(align_w, 8);
       align_h = MAX2(align_h, 4);
    }
@@ -925,7 +922,7 @@ img_calculate_bo_size(struct ilo_image *img,
        *      required above."
        */
       if (ilo_dev_gen(params->dev) >= ILO_GEN(7.5) &&
-          (params->templ->bind & PIPE_BIND_SAMPLER_VIEW) &&
+          params->info->bind_surface_sampler &&
           img->tiling == GEN6_TILING_NONE)
          h += (64 + img->bo_stride - 1) / img->bo_stride;
 
@@ -943,7 +940,7 @@ img_calculate_bo_size(struct ilo_image *img,
        *
        * Different requirements may exist when the bo is used in different
        * places, but our alignments here should be good enough that we do not
-       * need to check params->templ->bind.
+       * need to check params->info->bind_x.
        */
       switch (img->tiling) {
       case GEN6_TILING_X:
@@ -994,7 +991,7 @@ img_calculate_bo_size(struct ilo_image *img,
                img->tiling = GEN6_TILING_NONE;
                /* MCS support for non-MSRTs is limited to tiled RTs */
                if (img->aux.type == ILO_IMAGE_AUX_MCS &&
-                   params->templ->nr_samples <= 1)
+                   params->info->sample_count == 1)
                   img->aux.type = ILO_IMAGE_AUX_NONE;
 
                continue;
@@ -1014,7 +1011,7 @@ static void
 img_calculate_hiz_size(struct ilo_image *img,
                        const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    const unsigned hz_align_j = 8;
    enum ilo_image_walk_type hz_walk;
    unsigned hz_width, hz_height, lv;
@@ -1059,7 +1056,7 @@ img_calculate_hiz_size(struct ilo_image *img,
 
          hz_width = align(img->lods[0].slice_width, 16);
 
-         hz_height = hz_qpitch * templ->array_size / 2;
+         hz_height = hz_qpitch * info->array_size / 2;
          if (ilo_dev_gen(params->dev) >= ILO_GEN(7))
             hz_height = align(hz_height, 8);
 
@@ -1077,7 +1074,7 @@ img_calculate_hiz_size(struct ilo_image *img,
          hz_height = 0;
          cur_tx = 0;
          cur_ty = 0;
-         for (lv = 0; lv <= templ->last_level; lv++) {
+         for (lv = 0; lv < info->level_count; lv++) {
             unsigned tw, th;
 
             lod_tx[lv] = cur_tx;
@@ -1085,7 +1082,7 @@ img_calculate_hiz_size(struct ilo_image *img,
 
             tw = align(img->lods[lv].slice_width, 16);
             th = align(img->lods[lv].slice_height, hz_align_j) *
-               templ->array_size / 2;
+               info->array_size / 2;
             /* convert to Y-tiles */
             tw = align(tw, 128) / 128;
             th = align(th, 32) / 32;
@@ -1102,7 +1099,7 @@ img_calculate_hiz_size(struct ilo_image *img,
          }
 
          /* convert tile offsets to memory offsets */
-         for (lv = 0; lv <= templ->last_level; lv++) {
+         for (lv = 0; lv < info->level_count; lv++) {
             img->aux.walk_lod_offsets[lv] =
                (lod_ty[lv] * hz_width + lod_tx[lv]) * 4096;
          }
@@ -1114,10 +1111,10 @@ img_calculate_hiz_size(struct ilo_image *img,
       hz_width = align(img->lods[0].slice_width, 16);
 
       hz_height = 0;
-      for (lv = 0; lv <= templ->last_level; lv++) {
+      for (lv = 0; lv < info->level_count; lv++) {
          const unsigned h = align(img->lods[lv].slice_height, hz_align_j);
          /* according to the formula, slices are packed together vertically */
-         hz_height += h * u_minify(templ->depth0, lv);
+         hz_height += h * u_minify(info->depth, lv);
       }
       hz_height /= 2;
       break;
@@ -1136,8 +1133,7 @@ img_calculate_hiz_size(struct ilo_image *img,
     */
    hz_clear_w = 8;
    hz_clear_h = 4;
-   switch (templ->nr_samples) {
-   case 0:
+   switch (info->sample_count) {
    case 1:
    default:
       break;
@@ -1158,7 +1154,7 @@ img_calculate_hiz_size(struct ilo_image *img,
       break;
    }
 
-   for (lv = 0; lv <= templ->last_level; lv++) {
+   for (lv = 0; lv < info->level_count; lv++) {
       if (u_minify(img->width0, lv) % hz_clear_w ||
           u_minify(img->height0, lv) % hz_clear_h)
          break;
@@ -1166,7 +1162,7 @@ img_calculate_hiz_size(struct ilo_image *img,
    }
 
    /* we padded to allow this in img_align() */
-   if (templ->last_level == 0 && templ->array_size == 1 && templ->depth0 == 1)
+   if (info->level_count == 1 && info->array_size == 1 && info->depth == 1)
       img->aux.enables |= 0x1;
 
    /* align to Y-tile */
@@ -1178,13 +1174,13 @@ static void
 img_calculate_mcs_size(struct ilo_image *img,
                        const struct ilo_image_params *params)
 {
-   const struct pipe_resource *templ = params->templ;
+   const struct ilo_image_info *info = params->info;
    int mcs_width, mcs_height, mcs_cpp;
    int downscale_x, downscale_y;
 
    assert(img->aux.type == ILO_IMAGE_AUX_MCS);
 
-   if (templ->nr_samples > 1) {
+   if (info->sample_count > 1) {
       /*
        * From the Ivy Bridge PRM, volume 2 part 1, page 326, the clear
        * rectangle is scaled down by 8x2 for 4X MSAA and 2x2 for 8X MSAA.  The
@@ -1198,7 +1194,7 @@ img_calculate_mcs_size(struct ilo_image *img,
        * RT.  Similarly, we could reason that an OWord in 4X MCS maps to a 8x2
        * pixel block in the RT.
        */
-      switch (templ->nr_samples) {
+      switch (info->sample_count) {
       case 2:
       case 4:
          downscale_x = 8;
@@ -1295,13 +1291,13 @@ img_calculate_mcs_size(struct ilo_image *img,
       mcs_cpp = 16; /* an OWord */
    }
 
-   img->aux.enables = (1 << (templ->last_level + 1)) - 1;
+   img->aux.enables = (1 << info->level_count) - 1;
    /* align to Y-tile */
    img->aux.bo_stride = align(mcs_width * mcs_cpp, 128);
    img->aux.bo_height = align(mcs_height, 32);
 }
 
-static void
+static bool
 img_init(struct ilo_image *img,
          struct ilo_image_params *params)
 {
@@ -1318,7 +1314,7 @@ img_init(struct ilo_image *img,
    img_align(img, params);
    img_calculate_bo_size(img, params);
 
-   img->scanout = (params->templ->bind & PIPE_BIND_SCANOUT);
+   img->scanout = params->info->bind_scanout;
 
    switch (img->aux.type) {
    case ILO_IMAGE_AUX_HIZ:
@@ -1330,6 +1326,8 @@ img_init(struct ilo_image *img,
    default:
       break;
    }
+
+   return true;
 }
 
 /**
@@ -1339,29 +1337,29 @@ img_init(struct ilo_image *img,
 static void
 img_init_for_transfer(struct ilo_image *img,
                       const struct ilo_dev *dev,
-                      const struct pipe_resource *templ)
+                      const struct ilo_image_info *info)
 {
-   const unsigned num_layers = (templ->target == PIPE_TEXTURE_3D) ?
-      templ->depth0 : templ->array_size;
+   const unsigned num_layers = (info->target == PIPE_TEXTURE_3D) ?
+      info->depth : info->array_size;
    unsigned layer_width, layer_height;
 
-   assert(templ->last_level == 0);
-   assert(templ->nr_samples <= 1);
+   assert(info->level_count == 1);
+   assert(info->sample_count == 1);
 
    img->aux.type = ILO_IMAGE_AUX_NONE;
 
-   img->target = templ->target;
-   img->width0 = templ->width0;
-   img->height0 = templ->height0;
-   img->depth0 = templ->depth0;
-   img->array_size = templ->array_size;
+   img->target = info->target;
+   img->width0 = info->width;
+   img->height0 = info->height;
+   img->depth0 = info->depth;
+   img->array_size = info->array_size;
    img->level_count = 1;
    img->sample_count = 1;
 
-   img->format = templ->format;
-   img->block_width = util_format_get_blockwidth(templ->format);
-   img->block_height = util_format_get_blockheight(templ->format);
-   img->block_size = util_format_get_blocksize(templ->format);
+   img->format = info->format;
+   img->block_width = util_format_get_blockwidth(info->format);
+   img->block_height = util_format_get_blockheight(info->format);
+   img->block_size = util_format_get_blocksize(info->format);
 
    img->walk = ILO_IMAGE_WALK_LOD;
 
@@ -1374,8 +1372,8 @@ img_init_for_transfer(struct ilo_image *img,
           util_is_power_of_two(img->block_height));
 
    /* use packed layout */
-   layer_width = align(templ->width0, img->align_i);
-   layer_height = align(templ->height0, img->align_j);
+   layer_width = align(info->width, img->align_i);
+   layer_height = align(info->height, img->align_j);
 
    img->lods[0].slice_width = layer_width;
    img->lods[0].slice_height = layer_height;
@@ -1386,66 +1384,57 @@ img_init_for_transfer(struct ilo_image *img,
    img->bo_height = (layer_height / img->block_height) * num_layers;
 }
 
+static bool
+img_is_bind_gpu(const struct ilo_image_info *info)
+{
+   return (info->bind_surface_sampler ||
+           info->bind_surface_dp_render ||
+           info->bind_surface_dp_typed ||
+           info->bind_zs ||
+           info->bind_scanout ||
+           info->bind_cursor);
+}
+
 /**
  * Initialize the image.  Callers should zero-initialize \p img first.
  */
-void ilo_image_init(struct ilo_image *img,
-                    const struct ilo_dev *dev,
-                    const struct pipe_resource *templ)
+bool
+ilo_image_init(struct ilo_image *img,
+               const struct ilo_dev *dev,
+               const struct ilo_image_info *info)
 {
    struct ilo_image_params params;
-   bool transfer_only;
 
    assert(ilo_is_zeroed(img, sizeof(*img)));
 
    /* use transfer layout when the texture is never bound to GPU */
-   transfer_only = !(templ->bind & ~(PIPE_BIND_TRANSFER_WRITE |
-                                     PIPE_BIND_TRANSFER_READ));
-   if (transfer_only && templ->last_level == 0 && templ->nr_samples <= 1) {
-      img_init_for_transfer(img, dev, templ);
-      return;
+   if (!img_is_bind_gpu(info) &&
+       info->level_count == 1 &&
+       info->sample_count == 1) {
+      img_init_for_transfer(img, dev, info);
+      return true;
    }
 
    memset(&params, 0, sizeof(params));
    params.dev = dev;
-   params.templ = templ;
-   params.valid_tilings = IMAGE_TILING_ALL;
+   params.info = info;
+   params.valid_tilings = (info->valid_tilings) ?
+      info->valid_tilings : IMAGE_TILING_ALL;
 
-   img_init(img, &params);
-}
-
-bool
-ilo_image_init_for_imported(struct ilo_image *img,
-                            const struct ilo_dev *dev,
-                            const struct pipe_resource *templ,
-                            enum gen_surface_tiling tiling,
-                            unsigned bo_stride)
-{
-   struct ilo_image_params params;
-
-   assert(ilo_is_zeroed(img, sizeof(*img)));
-
-   if ((tiling == GEN6_TILING_X && bo_stride % 512) ||
-       (tiling == GEN6_TILING_Y && bo_stride % 128) ||
-       (tiling == GEN8_TILING_W && bo_stride % 64))
+   if (!img_init(img, &params))
       return false;
 
-   memset(&params, 0, sizeof(params));
-   params.dev = dev;
-   params.templ = templ;
-   params.valid_tilings = 1 << tiling;
+   if (info->force_bo_stride) {
+      if ((img->tiling == GEN6_TILING_X && info->force_bo_stride % 512) ||
+          (img->tiling == GEN6_TILING_Y && info->force_bo_stride % 128) ||
+          (img->tiling == GEN8_TILING_W && info->force_bo_stride % 64))
+         return false;
 
-   img_init(img, &params);
+      if (img->bo_stride > info->force_bo_stride)
+         return false;
 
-   assert(img->tiling == tiling);
-   if (img->bo_stride > bo_stride)
-      return false;
-
-   img->bo_stride = bo_stride;
-
-   /* assume imported RTs are also scanouts */
-   if (!img->scanout)
-      img->scanout = (templ->bind & PIPE_BIND_RENDER_TARGET);
+      img->bo_stride = info->force_bo_stride;
+   }
 
    return true;
 }
index e5dcc43..e488bef 100644 (file)
@@ -67,6 +67,36 @@ enum ilo_image_walk_type {
    ILO_IMAGE_WALK_3D,
 };
 
+struct ilo_image_info {
+   enum pipe_texture_target target;
+
+   enum pipe_format format;
+
+   /* image size */
+   uint16_t width;
+   uint16_t height;
+   uint16_t depth;
+   uint16_t array_size;
+   uint8_t level_count;
+   uint8_t sample_count;
+
+   /* disable optional aux */
+   bool aux_disable;
+
+   /* tilings to consider, if any bit is set */
+   uint8_t valid_tilings;
+
+   /* force a stride */
+   uint32_t force_bo_stride;
+
+   bool bind_surface_sampler;
+   bool bind_surface_dp_render;
+   bool bind_surface_dp_typed;
+   bool bind_zs;
+   bool bind_scanout;
+   bool bind_cursor;
+};
+
 /*
  * When the walk type is ILO_IMAGE_WALK_LAYER, there is only a slice in each
  * LOD and this is used to describe LODs in the first array layer.  Otherwise,
@@ -143,19 +173,10 @@ struct ilo_image {
    } aux;
 };
 
-struct pipe_resource;
-
-void
+bool
 ilo_image_init(struct ilo_image *img,
                const struct ilo_dev *dev,
-               const struct pipe_resource *templ);
-
-bool
-ilo_image_init_for_imported(struct ilo_image *img,
-                            const struct ilo_dev *dev,
-                            const struct pipe_resource *templ,
-                            enum gen_surface_tiling tiling,
-                            unsigned bo_stride);
+               const struct ilo_image_info *info);
 
 static inline bool
 ilo_image_can_enable_aux(const struct ilo_image *img, unsigned level)
index 3b8e607..0b0f69c 100644 (file)
@@ -87,6 +87,38 @@ resource_get_cpu_init(const struct pipe_resource *templ)
                           PIPE_BIND_STREAM_OUTPUT)) ? false : true;
 }
 
+static void
+resource_get_image_info(const struct pipe_resource *templ,
+                        const struct ilo_dev *dev,
+                        enum pipe_format image_format,
+                        struct ilo_image_info *info)
+{
+   memset(info, 0, sizeof(*info));
+
+   info->target = templ->target;
+   info->format = image_format;
+
+   info->width = templ->width0;
+   info->height = templ->height0;
+   info->depth = templ->depth0;
+   info->array_size = templ->array_size;
+   info->level_count = templ->last_level + 1;
+   info->sample_count = (templ->nr_samples) ? templ->nr_samples : 1;
+
+   info->aux_disable = (templ->usage == PIPE_USAGE_STAGING);
+
+   if (templ->bind & PIPE_BIND_LINEAR)
+      info->valid_tilings = 1 << GEN6_TILING_NONE;
+
+   info->bind_surface_sampler = (templ->bind & PIPE_BIND_SAMPLER_VIEW);
+   info->bind_surface_dp_render = (templ->bind & PIPE_BIND_RENDER_TARGET);
+   info->bind_surface_dp_typed = (templ->bind &
+         (PIPE_BIND_SHADER_RESOURCE | PIPE_BIND_COMPUTE_RESOURCE));
+   info->bind_zs = (templ->bind & PIPE_BIND_DEPTH_STENCIL);
+   info->bind_scanout = (templ->bind & PIPE_BIND_SCANOUT);
+   info->bind_cursor = (templ->bind & PIPE_BIND_CURSOR);
+}
+
 static enum gen_surface_tiling
 winsys_to_surface_tiling(enum intel_tiling_mode tiling)
 {
@@ -306,9 +338,10 @@ tex_alloc_bos(struct ilo_texture *tex)
    return true;
 }
 
-static bool
+static struct intel_bo *
 tex_import_handle(struct ilo_texture *tex,
-                  const struct winsys_handle *handle)
+                  const struct winsys_handle *handle,
+                  struct ilo_image_info *info)
 {
    struct ilo_screen *is = ilo_screen(tex->base.screen);
    const struct pipe_resource *templ = &tex->base;
@@ -319,23 +352,24 @@ tex_import_handle(struct ilo_texture *tex,
 
    bo = intel_winsys_import_handle(is->dev.winsys, name, handle,
          tex->image.bo_height, &tiling, &pitch);
-   if (!bo)
-      return false;
+   /* modify image info */
+   if (bo) {
+      const uint8_t valid_tilings = 1 << winsys_to_surface_tiling(tiling);
 
-   if (!ilo_image_init_for_imported(&tex->image, &is->dev, templ,
-            winsys_to_surface_tiling(tiling), pitch)) {
-      ilo_err("failed to import handle for texture\n");
-      intel_bo_unref(bo);
-      return false;
-   }
+      if (info->valid_tilings && !(info->valid_tilings & valid_tilings)) {
+         intel_bo_unref(bo);
+         return NULL;
+      }
 
-   ilo_vma_init(&tex->vma, &is->dev,
-         tex->image.bo_stride * tex->image.bo_height, 4096);
-   ilo_vma_set_bo(&tex->vma, &is->dev, bo, 0);
+      info->valid_tilings = valid_tilings;
+      info->force_bo_stride = pitch;
 
-   tex->imported = true;
+      /* assume imported RTs are also scanouts */
+      if (!info->bind_scanout)
+         info->bind_scanout = (templ->usage & PIPE_BIND_RENDER_TARGET);
+   }
 
-   return true;
+   return bo;
 }
 
 static bool
@@ -345,18 +379,33 @@ tex_init_image(struct ilo_texture *tex,
    struct ilo_screen *is = ilo_screen(tex->base.screen);
    const struct pipe_resource *templ = &tex->base;
    struct ilo_image *img = &tex->image;
+   struct intel_bo *imported_bo = NULL;;
+   struct ilo_image_info info;
+
+   resource_get_image_info(templ, &is->dev, templ->format, &info);
 
    if (handle) {
-      if (!tex_import_handle(tex, handle))
+      imported_bo = tex_import_handle(tex, handle, &info);
+      if (!imported_bo)
          return false;
-   } else {
-      ilo_image_init(img, &is->dev, templ);
-      ilo_vma_init(&tex->vma, &is->dev,
-            img->bo_stride * img->bo_height, 4096);
    }
 
-   if (img->bo_height > ilo_max_resource_size / img->bo_stride)
+   if (!ilo_image_init(img, &is->dev, &info)) {
+      intel_bo_unref(imported_bo);
       return false;
+   }
+
+   if (img->bo_height > ilo_max_resource_size / img->bo_stride ||
+       !ilo_vma_init(&tex->vma, &is->dev, img->bo_stride * img->bo_height,
+          4096)) {
+      intel_bo_unref(imported_bo);
+      return false;
+   }
+
+   if (imported_bo) {
+      ilo_vma_set_bo(&tex->vma, &is->dev, imported_bo, 0);
+      tex->imported = true;
+   }
 
    if (templ->flags & PIPE_RESOURCE_FLAG_MAP_PERSISTENT) {
       /* require on-the-fly tiling/untiling or format conversion */
@@ -500,13 +549,17 @@ static boolean
 ilo_can_create_resource(struct pipe_screen *screen,
                         const struct pipe_resource *templ)
 {
+   struct ilo_screen *is = ilo_screen(screen);
+   struct ilo_image_info info;
    struct ilo_image img;
 
    if (templ->target == PIPE_BUFFER)
       return (templ->width0 <= ilo_max_resource_size);
 
+   resource_get_image_info(templ, &is->dev, templ->format, &info);
+
    memset(&img, 0, sizeof(img));
-   ilo_image_init(&img, &ilo_screen(screen)->dev, templ);
+   ilo_image_init(&img, &ilo_screen(screen)->dev, &info);
 
    return (img.bo_height <= ilo_max_resource_size / img.bo_stride);
 }