anv/image: Use RENDER_SURFACE_STATE::X/Y Offset on SKL+
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 11 Jul 2017 22:32:30 +0000 (15:32 -0700)
committerJason Ekstrand <jason.ekstrand@intel.com>
Thu, 21 Sep 2017 00:21:06 +0000 (17:21 -0700)
The Broadwell method of handling uncompressed views of compressed
textures was to make the texture linear and have a tiled shadow copy.
This isn't needed on Sky Lake because the HALIGN and VALIGN parameters
are specified in surface elements and required to be a multiple of 4.
This means that we can just use the X/Y Offset fields and we can avoid
the shadow copy song and dance.  This also makes ASTC work because ASTC
can't be linear and so the shadow copy method doesn't work there.

Reviewed-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
src/intel/vulkan/anv_image.c

index 837b6a4e8ddd2fa9b579d9116ab37c4811b39937..7561b9b52b4d17a7d99dee3c985b4395a3ca4628 100644 (file)
@@ -269,11 +269,14 @@ make_surface(const struct anv_device *dev,
    assert(format != ISL_FORMAT_UNSUPPORTED);
 
    /* If an image is created as BLOCK_TEXEL_VIEW_COMPATIBLE, then we need to
-    * fall back to linear because we aren't guaranteed that we can handle
-    * offsets correctly.
+    * fall back to linear on Broadwell and earlier because we aren't
+    * guaranteed that we can handle offsets correctly.  On Sky Lake, the
+    * horizontal and vertical alignments are sufficiently high that we can
+    * just use RENDER_SURFACE_STATE::X/Y Offset.
     */
    bool needs_shadow = false;
-   if ((vk_info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR) &&
+   if (dev->info.gen <= 8 &&
+       (vk_info->flags & VK_IMAGE_CREATE_BLOCK_TEXEL_VIEW_COMPATIBLE_BIT_KHR) &&
        vk_info->tiling == VK_IMAGE_TILING_OPTIMAL) {
       assert(isl_format_is_compressed(format));
       tiling_flags = ISL_TILING_LINEAR_BIT;
@@ -872,12 +875,16 @@ anv_image_fill_surface_state(struct anv_device *device,
             DIV_ROUND_UP(tmp_surf.logical_level0_px.height, fmtl->bh);
          tmp_surf.phys_level0_sa.width /= fmtl->bw;
          tmp_surf.phys_level0_sa.height /= fmtl->bh;
+         tile_x_sa /= fmtl->bw;
+         tile_y_sa /= fmtl->bh;
 
          isl_surf = &tmp_surf;
 
-         assert(surface->isl.tiling == ISL_TILING_LINEAR);
-         assert(tile_x_sa == 0);
-         assert(tile_y_sa == 0);
+         if (device->info.gen <= 8) {
+            assert(surface->isl.tiling == ISL_TILING_LINEAR);
+            assert(tile_x_sa == 0);
+            assert(tile_y_sa == 0);
+         }
       }
 
       isl_surf_fill_state(&device->isl_dev, state_inout->state.map,
@@ -888,7 +895,9 @@ anv_image_fill_surface_state(struct anv_device *device,
                           .aux_surf = &image->aux_surface.isl,
                           .aux_usage = aux_usage,
                           .aux_address = aux_address,
-                          .mocs = device->default_mocs);
+                          .mocs = device->default_mocs,
+                          .x_offset_sa = tile_x_sa,
+                          .y_offset_sa = tile_y_sa);
       state_inout->address = address + offset_B;
       if (device->info.gen >= 8) {
          state_inout->aux_address = aux_address;