anv/state: Factor out surface state calculation from genX_image_view_init.
authorFrancisco Jerez <currojerez@riseup.net>
Fri, 22 Jan 2016 03:21:34 +0000 (19:21 -0800)
committerJason Ekstrand <jason.ekstrand@intel.com>
Fri, 22 Jan 2016 19:12:09 +0000 (11:12 -0800)
Some fields of the surface state template were dependent on the
surface type, which is dependent on the usage of the image view, which
wasn't known until the bottom of the function after the template had
been constructed.  This caused failures in all image load/store CTS
tests using cubemaps.  Refactor the surface state calculation into a
function that is called once for each required usage.

src/vulkan/gen7_state.c
src/vulkan/gen8_state.c

index 0c830d5c8edb74206378eb14f9c6030e2ff2f6d7..c722ff06f9fd8e0debce7212340156c6f4b557d0 100644 (file)
@@ -148,22 +148,22 @@ static const uint8_t anv_valign[] = {
     [4] = VALIGN_4,
 };
 
-GENX_FUNC(GEN7, GEN75) void
-genX(image_view_init)(struct anv_image_view *iview,
-                      struct anv_device *device,
-                      const VkImageViewCreateInfo* pCreateInfo,
-                      struct anv_cmd_buffer *cmd_buffer)
+static struct GENX(RENDER_SURFACE_STATE)
+surface_state_for_image_view(struct anv_image_view *iview,
+                             struct anv_device *device,
+                             const VkImageViewCreateInfo *pCreateInfo,
+                             VkImageUsageFlagBits usage)
 {
-   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+   assert(usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
+                   VK_IMAGE_USAGE_STORAGE_BIT |
+                   VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
+   assert(util_is_power_of_two(usage));
 
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
-
    struct anv_surface *surface =
       anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
 
-   if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
-      anv_finishme("non-2D image views");
-
    uint32_t depth = 1;
    if (range->layerCount > 1) {
       depth = range->layerCount;
@@ -174,10 +174,13 @@ genX(image_view_init)(struct anv_image_view *iview,
    const struct isl_extent3d image_align_sa =
       isl_surf_get_image_alignment_sa(&surface->isl);
 
-   const struct GENX(RENDER_SURFACE_STATE) template = {
-      .SurfaceType = anv_surftype(image, pCreateInfo->viewType, false),
+   struct GENX(RENDER_SURFACE_STATE) template = {
+      .SurfaceType = anv_surftype(image, pCreateInfo->viewType,
+                                  usage == VK_IMAGE_USAGE_STORAGE_BIT),
       .SurfaceArray = image->array_size > 1,
-      .SurfaceFormat = iview->format,
+      .SurfaceFormat = (usage != VK_IMAGE_USAGE_STORAGE_BIT ? iview->format :
+                        isl_lower_storage_image_format(
+                           &device->isl_dev, iview->format)),
       .SurfaceVerticalAlignment = anv_valign[image_align_sa.height],
       .SurfaceHorizontalAlignment = anv_halign[image_align_sa.width],
 
@@ -227,19 +230,44 @@ genX(image_view_init)(struct anv_image_view *iview,
       .SurfaceBaseAddress = { NULL, iview->offset },
    };
 
-   if (image->needs_nonrt_surface_state) {
-      struct GENX(RENDER_SURFACE_STATE) surface_state = template;
-
-      iview->nonrt_surface_state = alloc_surface_state(device, cmd_buffer);
-
-      surface_state.RenderCacheReadWriteMode = false;
-
+   if (usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+      /* For render target surfaces, the hardware interprets field
+       * MIPCount/LOD as LOD. The Broadwell PRM says:
+       *
+       *    MIPCountLOD defines the LOD that will be rendered into.
+       *    SurfaceMinLOD is ignored.
+       */
+      template.MIPCountLOD = range->baseMipLevel;
+      template.SurfaceMinLOD = 0;
+   } else {
       /* For non render target surfaces, the hardware interprets field
        * MIPCount/LOD as MIPCount.  The range of levels accessible by the
        * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
        */
-      surface_state.SurfaceMinLOD = range->baseMipLevel;
-      surface_state.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
+      template.SurfaceMinLOD = range->baseMipLevel;
+      template.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
+   }
+
+   return template;
+}
+
+GENX_FUNC(GEN7, GEN75) void
+genX(image_view_init)(struct anv_image_view *iview,
+                      struct anv_device *device,
+                      const VkImageViewCreateInfo* pCreateInfo,
+                      struct anv_cmd_buffer *cmd_buffer)
+{
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+
+   if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
+      anv_finishme("non-2D image views");
+
+   if (image->needs_nonrt_surface_state) {
+      struct GENX(RENDER_SURFACE_STATE) surface_state =
+         surface_state_for_image_view(iview, device, pCreateInfo,
+                                      VK_IMAGE_USAGE_SAMPLED_BIT);
+
+      iview->nonrt_surface_state = alloc_surface_state(device, cmd_buffer);
 
       GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->nonrt_surface_state.map,
                                       &surface_state);
@@ -251,21 +279,12 @@ genX(image_view_init)(struct anv_image_view *iview,
    }
 
    if (image->needs_color_rt_surface_state) {
-      struct GENX(RENDER_SURFACE_STATE) surface_state = template;
+      struct GENX(RENDER_SURFACE_STATE) surface_state =
+         surface_state_for_image_view(iview, device, pCreateInfo,
+                                      VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
 
       iview->color_rt_surface_state = alloc_surface_state(device, cmd_buffer);
 
-      surface_state.RenderCacheReadWriteMode = 0; /* Write only */
-
-      /* For render target surfaces, the hardware interprets field MIPCount/LOD as
-       * LOD. The Broadwell PRM says:
-       *
-       *    MIPCountLOD defines the LOD that will be rendered into.
-       *    SurfaceMinLOD is ignored.
-       */
-      surface_state.MIPCountLOD = range->baseMipLevel;
-      surface_state.SurfaceMinLOD = 0;
-
       GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->color_rt_surface_state.map,
                                       &surface_state);
       if (!device->info.has_llc)
@@ -275,19 +294,12 @@ genX(image_view_init)(struct anv_image_view *iview,
    }
 
    if (image->needs_storage_surface_state) {
-      struct GENX(RENDER_SURFACE_STATE) surface_state = template;
+      struct GENX(RENDER_SURFACE_STATE) surface_state =
+         surface_state_for_image_view(iview, device, pCreateInfo,
+                                      VK_IMAGE_USAGE_STORAGE_BIT);
 
       iview->storage_surface_state = alloc_surface_state(device, cmd_buffer);
 
-      surface_state.SurfaceType =
-         anv_surftype(image, pCreateInfo->viewType, true),
-
-      surface_state.SurfaceFormat =
-         isl_lower_storage_image_format(&device->isl_dev, iview->format);
-
-      surface_state.SurfaceMinLOD = range->baseMipLevel;
-      surface_state.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
-
       GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->storage_surface_state.map,
                                       &surface_state);
    } else {
index d42d0b1b5a6d3b7d64e0dc2d6f99462a2f749ada..c71193b7cd6a799fafc9120854761bb5d40b7da8 100644 (file)
@@ -162,16 +162,19 @@ get_qpitch(const struct isl_surf *surf)
    }
 }
 
-void
-genX(image_view_init)(struct anv_image_view *iview,
-                      struct anv_device *device,
-                      const VkImageViewCreateInfo* pCreateInfo,
-                      struct anv_cmd_buffer *cmd_buffer)
+static struct GENX(RENDER_SURFACE_STATE)
+surface_state_for_image_view(struct anv_image_view *iview,
+                             struct anv_device *device,
+                             const VkImageViewCreateInfo *pCreateInfo,
+                             VkImageUsageFlagBits usage)
 {
-   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+   assert(usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
+                   VK_IMAGE_USAGE_STORAGE_BIT |
+                   VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT));
+   assert(util_is_power_of_two(usage));
 
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
-
    struct anv_surface *surface =
       anv_image_get_surface_for_aspect_mask(image, range->aspectMask);
 
@@ -188,9 +191,12 @@ genX(image_view_init)(struct anv_image_view *iview,
    get_halign_valign(&surface->isl, &halign, &valign);
 
    struct GENX(RENDER_SURFACE_STATE) template = {
-      .SurfaceType = anv_surftype(image, pCreateInfo->viewType, false),
+      .SurfaceType = anv_surftype(image, pCreateInfo->viewType,
+                                  usage == VK_IMAGE_USAGE_STORAGE_BIT),
       .SurfaceArray = image->array_size > 1,
-      .SurfaceFormat = iview->format,
+      .SurfaceFormat = (usage != VK_IMAGE_USAGE_STORAGE_BIT ? iview->format :
+                        isl_lower_storage_image_format(
+                           &device->isl_dev, iview->format)),
       .SurfaceVerticalAlignment = valign,
       .SurfaceHorizontalAlignment = halign,
       .TileMode = isl_to_gen_tiling[surface->isl.tiling],
@@ -295,18 +301,42 @@ genX(image_view_init)(struct anv_image_view *iview,
       unreachable(!"bad SurfaceType");
    }
 
-   if (image->needs_nonrt_surface_state) {
-      struct GENX(RENDER_SURFACE_STATE) surface_state = template;
-
-      iview->nonrt_surface_state =
-         alloc_surface_state(device, cmd_buffer);
-
+   if (usage == VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+      /* For render target surfaces, the hardware interprets field
+       * MIPCount/LOD as LOD. The Broadwell PRM says:
+       *
+       *    MIPCountLOD defines the LOD that will be rendered into.
+       *    SurfaceMinLOD is ignored.
+       */
+      template.MIPCountLOD = range->baseMipLevel;
+      template.SurfaceMinLOD = 0;
+   } else {
       /* For non render target surfaces, the hardware interprets field
        * MIPCount/LOD as MIPCount.  The range of levels accessible by the
        * sampler engine is [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
        */
-      surface_state.SurfaceMinLOD = range->baseMipLevel;
-      surface_state.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
+      template.SurfaceMinLOD = range->baseMipLevel;
+      template.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
+   }
+
+   return template;
+}
+
+void
+genX(image_view_init)(struct anv_image_view *iview,
+                      struct anv_device *device,
+                      const VkImageViewCreateInfo* pCreateInfo,
+                      struct anv_cmd_buffer *cmd_buffer)
+{
+   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+
+   if (image->needs_nonrt_surface_state) {
+      const struct GENX(RENDER_SURFACE_STATE) surface_state =
+         surface_state_for_image_view(iview, device, pCreateInfo,
+                                      VK_IMAGE_USAGE_SAMPLED_BIT);
+
+      iview->nonrt_surface_state =
+         alloc_surface_state(device, cmd_buffer);
 
       GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->nonrt_surface_state.map,
                                       &surface_state);
@@ -317,20 +347,13 @@ genX(image_view_init)(struct anv_image_view *iview,
    }
 
    if (image->needs_color_rt_surface_state) {
-      struct GENX(RENDER_SURFACE_STATE) surface_state = template;
+      const struct GENX(RENDER_SURFACE_STATE) surface_state =
+         surface_state_for_image_view(iview, device, pCreateInfo,
+                                      VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
 
       iview->color_rt_surface_state =
          alloc_surface_state(device, cmd_buffer);
 
-      /* For render target surfaces, the hardware interprets field
-       * MIPCount/LOD as LOD. The Broadwell PRM says:
-       *
-       *    MIPCountLOD defines the LOD that will be rendered into.
-       *    SurfaceMinLOD is ignored.
-       */
-      surface_state.MIPCountLOD = range->baseMipLevel;
-      surface_state.SurfaceMinLOD = 0;
-
       GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->color_rt_surface_state.map,
                                       &surface_state);
       if (!device->info.has_llc)
@@ -340,20 +363,13 @@ genX(image_view_init)(struct anv_image_view *iview,
    }
 
    if (image->needs_storage_surface_state) {
-      struct GENX(RENDER_SURFACE_STATE) surface_state = template;
+      struct GENX(RENDER_SURFACE_STATE) surface_state =
+         surface_state_for_image_view(iview, device, pCreateInfo,
+                                      VK_IMAGE_USAGE_STORAGE_BIT);
 
       iview->storage_surface_state =
          alloc_surface_state(device, cmd_buffer);
 
-      surface_state.SurfaceType =
-         anv_surftype(image, pCreateInfo->viewType, true),
-
-      surface_state.SurfaceFormat =
-         isl_lower_storage_image_format(&device->isl_dev, iview->format);
-
-      surface_state.SurfaceMinLOD = range->baseMipLevel;
-      surface_state.MIPCountLOD = MAX2(range->levelCount, 1) - 1;
-
       GENX(RENDER_SURFACE_STATE_pack)(NULL, iview->storage_surface_state.map,
                                       &surface_state);
    } else {