anv/image: Add a separate storage image surface state
authorJason Ekstrand <jason.ekstrand@intel.com>
Tue, 8 Dec 2015 01:17:30 +0000 (17:17 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Tue, 8 Dec 2015 05:08:22 +0000 (21:08 -0800)
Thanks to hardware limitations, storage images may need a different surface
format and/or other bits in the surface state.

src/vulkan/anv_image.c
src/vulkan/anv_private.h
src/vulkan/gen7_state.c
src/vulkan/gen8_state.c

index 37a0d8faaa9550d79e8bcc1b0bb912c41fb8c58a..09993180e7ec2431e441e909bdd61b1234344776 100644 (file)
@@ -252,8 +252,7 @@ anv_image_create(VkDevice _device,
    image->usage = anv_image_get_full_usage(pCreateInfo);
    image->surface_type = surf_type;
 
-   if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
-                       VK_IMAGE_USAGE_STORAGE_BIT)) {
+   if (image->usage & VK_IMAGE_USAGE_SAMPLED_BIT) {
       image->needs_nonrt_surface_state = true;
    }
 
@@ -261,6 +260,10 @@ anv_image_create(VkDevice _device,
       image->needs_color_rt_surface_state = true;
    }
 
+   if (image->usage & VK_IMAGE_USAGE_STORAGE_BIT) {
+      image->needs_storage_surface_state = true;
+   }
+
    if (likely(anv_format_is_color(image->format))) {
       r = make_surface(device, image, create_info,
                        VK_IMAGE_ASPECT_COLOR_BIT);
@@ -533,6 +536,11 @@ anv_DestroyImageView(VkDevice _device, VkImageView _iview,
                           iview->nonrt_surface_state);
    }
 
+   if (iview->image->needs_storage_surface_state) {
+      anv_state_pool_free(&device->surface_state_pool,
+                          iview->storage_surface_state);
+   }
+
    anv_free2(&device->alloc, pAllocator, iview);
 }
 
index cb3f9a7b367576641e284d833d03c61bb7ac0b12..a6db547e5e3ce8124222467ec000c38589ae769b 100644 (file)
@@ -1433,6 +1433,7 @@ struct anv_image {
 
    bool needs_nonrt_surface_state:1;
    bool needs_color_rt_surface_state:1;
+   bool needs_storage_surface_state:1;
 
    /**
     * Image subsurfaces
@@ -1468,6 +1469,9 @@ struct anv_image_view {
 
    /** RENDER_SURFACE_STATE when using image as a non render target. */
    struct anv_state nonrt_surface_state;
+
+   /** RENDER_SURFACE_STATE when using image as a storage image. */
+   struct anv_state storage_surface_state;
 };
 
 struct anv_image_create_info {
index 6ffbacd8e775911876cd3c2b81a5ee67308dd61a..4101e84f827972dd54893494636c8bff6785f173 100644 (file)
@@ -332,4 +332,18 @@ genX(image_view_init)(struct anv_image_view *iview,
       if (!device->info.has_llc)
          anv_state_clflush(iview->color_rt_surface_state);
    }
+
+   if (image->needs_storage_surface_state) {
+      iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
+
+      surface_state.SurfaceFormat =
+         isl_lower_storage_image_format(&device->isl_dev,
+                                        format->surface_format);
+
+      surface_state.SurfaceMinLOD = range->baseMipLevel;
+      surface_state.MIPCountLOD = range->levelCount - 1;
+
+      GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->storage_surface_state.map,
+                                      &surface_state);
+   }
 }
index 901cc3b25a8076d6ff76788fb1d68b27d0a20fd9..59134d5214e95053e03a1076a6bbb95c9635776a 100644 (file)
@@ -302,6 +302,21 @@ genX(image_view_init)(struct anv_image_view *iview,
       if (!device->info.has_llc)
          anv_state_clflush(iview->color_rt_surface_state);
    }
+
+   if (image->needs_storage_surface_state) {
+      iview->storage_surface_state =
+         alloc_surface_state(device, cmd_buffer);
+
+      surface_state.SurfaceFormat =
+         isl_lower_storage_image_format(&device->isl_dev,
+                                        format_info->surface_format);
+
+      surface_state.SurfaceMinLOD = range->baseMipLevel;
+      surface_state.MIPCountLOD = range->levelCount - 1;
+
+      GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->storage_surface_state.map,
+                                      &surface_state);
+   }
 }
 
 VkResult genX(CreateSampler)(