vk: Embed two surface states in anv_image_view
authorChad Versace <chad.versace@intel.com>
Wed, 7 Oct 2015 02:11:58 +0000 (19:11 -0700)
committerChad Versace <chad.versace@intel.com>
Wed, 7 Oct 2015 04:22:18 +0000 (21:22 -0700)
This prepares for merging VkAttachmentView into VkImageView.  The two
surface states are:

   anv_image_view::color_rt_surface_state:
       RENDER_SURFACE_STATE when using image as a color render target.

   anv_image_view::nonrt_surface_state;
       RENDER_SURFACE_STATE when using image as a non render target.

No Crucible regressions.

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

index 470ea11df6ff57fe3544fdc7a0c1549c7ff94072..7587f2ed1038a787a326b8cadf7e4d9bd341bd7e 100644 (file)
@@ -434,8 +434,8 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
       const struct anv_image_view *iview =
          fb->attachments[subpass->color_attachments[a]];
 
-      bt_map[a] = iview->surface_state.offset + state_offset;
-      add_surface_state_reloc(cmd_buffer, iview->surface_state,
+      bt_map[a] = iview->color_rt_surface_state.offset + state_offset;
+      add_surface_state_reloc(cmd_buffer, iview->color_rt_surface_state,
                               iview->bo, iview->offset);
    }
 
@@ -468,7 +468,7 @@ anv_cmd_buffer_emit_binding_table(struct anv_cmd_buffer *cmd_buffer,
             bo_offset = desc->buffer_view->offset;
             break;
          case ANV_DESCRIPTOR_TYPE_IMAGE_VIEW:
-            surface_state = &desc->image_view->surface_state;
+            surface_state = &desc->image_view->nonrt_surface_state;
             bo = desc->image_view->bo;
             bo_offset = desc->image_view->offset;
             break;
index 2b3c444428f24305c7b7500985bfa1756bddb22a..3f4d9b15c924b2f152d651196a8b7131b1237730 100644 (file)
@@ -45,7 +45,6 @@ static const uint8_t anv_surf_type_from_image_type[] = {
    [VK_IMAGE_TYPE_1D] = SURFTYPE_1D,
    [VK_IMAGE_TYPE_2D] = SURFTYPE_2D,
    [VK_IMAGE_TYPE_3D] = SURFTYPE_3D,
-
 };
 
 static const struct anv_image_view_info
@@ -259,6 +258,26 @@ anv_image_make_surface(const struct anv_image_create_info *create_info,
    return VK_SUCCESS;
 }
 
+static VkImageUsageFlags
+anv_image_get_full_usage(const VkImageCreateInfo *info)
+{
+   VkImageUsageFlags usage = info->usage;
+
+   if (usage & VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT) {
+      /* Meta will transfer from the image by binding it as a texture. */
+      usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+   }
+
+   if (usage & VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT) {
+      /* Meta will transfer to the image by binding it as a color attachment,
+       * even if the image format is not a color format.
+       */
+      usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+   }
+
+   return usage;
+}
+
 VkResult
 anv_image_create(VkDevice _device,
                  const struct anv_image_create_info *create_info,
@@ -304,19 +323,16 @@ anv_image_create(VkDevice _device,
    image->format = anv_format_for_vk_format(pCreateInfo->format);
    image->levels = pCreateInfo->mipLevels;
    image->array_size = pCreateInfo->arraySize;
-   image->usage = pCreateInfo->usage;
-   image->surf_type = surf_type;
+   image->usage = anv_image_get_full_usage(pCreateInfo);
+   image->surface_type = surf_type;
 
-   if (pCreateInfo->usage & VK_IMAGE_USAGE_TRANSFER_SOURCE_BIT) {
-      /* Meta will transfer from the image by binding it as a texture. */
-      image->usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+   if (image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
+                       VK_IMAGE_USAGE_STORAGE_BIT)) {
+      image->needs_nonrt_surface_state = true;
    }
 
-   if (pCreateInfo->usage & VK_IMAGE_USAGE_TRANSFER_DESTINATION_BIT) {
-      /* Meta will transfer to the image by binding it as a color attachment,
-       * even if the image format is not a color format.
-       */
-      image->usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+   if (image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT) {
+      image->needs_color_rt_surface_state = true;
    }
 
    if (likely(anv_format_is_color(image->format))) {
@@ -472,9 +488,27 @@ anv_image_view_init(struct anv_image_view *iview,
                     struct anv_cmd_buffer *cmd_buffer)
 {
    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
+   const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
 
+   assert(range->arraySize > 0);
+   assert(range->baseMipLevel < image->levels);
    assert(image->usage & (VK_IMAGE_USAGE_SAMPLED_BIT |
-                          VK_IMAGE_USAGE_STORAGE_BIT));
+                          VK_IMAGE_USAGE_STORAGE_BIT |
+                          VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT |
+                          VK_IMAGE_USAGE_DEPTH_STENCIL_BIT));
+
+   switch (image->type) {
+   default:
+      unreachable("bad VkImageType");
+   case VK_IMAGE_TYPE_1D:
+   case VK_IMAGE_TYPE_2D:
+      assert(range->baseArrayLayer + range->arraySize - 1 <= image->array_size);
+      break;
+   case VK_IMAGE_TYPE_3D:
+      assert(range->baseArrayLayer + range->arraySize - 1
+             <= anv_minify(image->extent.depth, range->baseMipLevel));
+      break;
+   }
 
    switch (device->info.gen) {
    case 7:
@@ -508,29 +542,30 @@ anv_CreateImageView(VkDevice _device,
    return VK_SUCCESS;
 }
 
-void
-anv_DestroyImageView(VkDevice _device, VkImageView _iview)
+static void
+anv_image_view_destroy(struct anv_device *device,
+                       struct anv_image_view *iview)
 {
-   ANV_FROM_HANDLE(anv_device, device, _device);
-   ANV_FROM_HANDLE(anv_image_view, iview, _iview);
+   if (iview->image->needs_color_rt_surface_state) {
+      anv_state_pool_free(&device->surface_state_pool,
+                          iview->color_rt_surface_state);
+   }
+
+   if (iview->image->needs_nonrt_surface_state) {
+      anv_state_pool_free(&device->surface_state_pool,
+                          iview->nonrt_surface_state);
+   }
 
-   anv_state_pool_free(&device->surface_state_pool, iview->surface_state);
    anv_device_free(device, iview);
 }
 
-static void
-anv_depth_stencil_view_init(struct anv_image_view *iview,
-                            const VkAttachmentViewCreateInfo *pCreateInfo)
+void
+anv_DestroyImageView(VkDevice _device, VkImageView _iview)
 {
-   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-
-   assert(image->usage & VK_IMAGE_USAGE_DEPTH_STENCIL_BIT);
-
-   iview->image = image;
-   iview->format = anv_format_for_vk_format(pCreateInfo->format);
+   ANV_FROM_HANDLE(anv_device, device, _device);
+   ANV_FROM_HANDLE(anv_image_view, iview, _iview);
 
-   assert(anv_format_is_depth_or_stencil(image->format));
-   assert(anv_format_is_depth_or_stencil(iview->format));
+   anv_image_view_destroy(device, iview);
 }
 
 struct anv_surface *
@@ -538,8 +573,22 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag
 {
    switch (aspect_mask) {
    case VK_IMAGE_ASPECT_COLOR_BIT:
-      assert(anv_format_is_color(image->format));
-      return &image->color_surface;
+      /* Dragons will eat you.
+       *
+       * Meta attaches all destination surfaces as color render targets. Guess
+       * what surface the Meta Dragons really want.
+       */
+      if (image->format->depth_format && image->format->has_stencil) {
+         anv_finishme("combined depth stencil formats");
+         return &image->depth_surface;
+      } else if (image->format->depth_format) {
+         return &image->depth_surface;
+      } else if (image->format->has_stencil) {
+         return &image->stencil_surface;
+      } else {
+         return &image->color_surface;
+      }
+      break;
    case VK_IMAGE_ASPECT_DEPTH_BIT:
       assert(image->format->depth_format);
       return &image->depth_surface;
@@ -562,67 +611,52 @@ anv_image_get_surface_for_aspect_mask(struct anv_image *image, VkImageAspectFlag
    }
 }
 
-/** The attachment may be a color view into a non-color image.  */
-struct anv_surface *
-anv_image_get_surface_for_color_attachment(struct anv_image *image)
-{
-   if (anv_format_is_color(image->format)) {
-      return &image->color_surface;
-   } else if (image->format->depth_format) {
-      return &image->depth_surface;
-   } else if (image->format->has_stencil) {
-      return &image->stencil_surface;
-   } else {
-      unreachable("image has bad format");
-      return NULL;
-   }
-}
-
-void
-anv_color_attachment_view_init(struct anv_image_view *iview,
-                               struct anv_device *device,
-                               const VkAttachmentViewCreateInfo* pCreateInfo,
-                               struct anv_cmd_buffer *cmd_buffer)
-{
-   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-
-   assert(image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
-
-   switch (device->info.gen) {
-   case 7:
-      gen7_color_attachment_view_init(iview, device, pCreateInfo, cmd_buffer);
-      break;
-   case 8:
-      gen8_color_attachment_view_init(iview, device, pCreateInfo, cmd_buffer);
-      break;
-   default:
-      unreachable("unsupported gen\n");
-   }
-}
-
 VkResult
 anv_CreateAttachmentView(VkDevice _device,
-                         const VkAttachmentViewCreateInfo *pCreateInfo,
+                         const VkAttachmentViewCreateInfo *info,
                          VkAttachmentView *pView)
 {
    ANV_FROM_HANDLE(anv_device, device, _device);
    struct anv_image_view *iview;
 
-   assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO);
+   assert(info->sType == VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO);
 
    iview = anv_device_alloc(device, sizeof(*iview), 8,
                             VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
    if (iview == NULL)
       return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   const struct anv_format *format =
-      anv_format_for_vk_format(pCreateInfo->format);
-
-   if (anv_format_is_depth_or_stencil(format)) {
-      anv_depth_stencil_view_init(iview, pCreateInfo);
-   } else {
-      anv_color_attachment_view_init(iview, device, pCreateInfo, NULL);
-   }
+   const struct anv_format *format = anv_format_for_vk_format(info->format);
+
+   VkImageAspectFlags aspect_mask = 0;
+   if (format->depth_format)
+      aspect_mask |= VK_IMAGE_ASPECT_DEPTH_BIT;
+   if (format->has_stencil)
+      aspect_mask |= VK_IMAGE_ASPECT_STENCIL_BIT;
+   if (!aspect_mask)
+      aspect_mask |= VK_IMAGE_ASPECT_COLOR_BIT;
+
+   anv_image_view_init(iview, device,
+      &(VkImageViewCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
+         .image = info->image,
+         .viewType = VK_IMAGE_VIEW_TYPE_2D,
+         .format = info->format,
+         .channels = {
+            .r = VK_CHANNEL_SWIZZLE_R,
+            .g = VK_CHANNEL_SWIZZLE_G,
+            .b = VK_CHANNEL_SWIZZLE_B,
+            .a = VK_CHANNEL_SWIZZLE_A,
+         },
+         .subresourceRange = {
+            .aspectMask = aspect_mask,
+            .baseMipLevel = info->mipLevel,
+            .mipLevels = 1,
+            .baseArrayLayer = info->baseArraySlice,
+            .arraySize = info->arraySize,
+         },
+      },
+      NULL);
 
    pView->handle = anv_image_view_to_handle(iview).handle;
 
@@ -636,12 +670,5 @@ anv_DestroyAttachmentView(VkDevice _device, VkAttachmentView _aview)
    VkImageView _iview = { .handle = _aview.handle };
    ANV_FROM_HANDLE(anv_image_view, iview, _iview);
 
-   /* Depth and stencil render targets have no RENDER_SURFACE_STATE.  Instead,
-    * they use 3DSTATE_DEPTH_BUFFER and 3DSTATE_STENCIL_BUFFER.
-    */
-   if (!anv_format_is_depth_or_stencil(iview->format)) {
-      anv_state_pool_free(&device->surface_state_pool, iview->surface_state);
-   }
-
-   anv_device_free(device, iview);
+   anv_image_view_destroy(device, iview);
 }
index d69863b8375f31dc8cb07c9a9330be9ef1922cce..c7c50ef87a96b874440b5de3590a01ba75b3871b 100644 (file)
@@ -1029,14 +1029,25 @@ do_buffer_copy(struct anv_cmd_buffer *cmd_buffer,
       cmd_buffer);
 
    struct anv_image_view dest_iview;
-   anv_color_attachment_view_init(&dest_iview, cmd_buffer->device,
-      &(VkAttachmentViewCreateInfo) {
-         .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+   anv_image_view_init(&dest_iview, cmd_buffer->device,
+      &(VkImageViewCreateInfo) {
+         .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
          .image = dest_image,
+         .viewType = VK_IMAGE_VIEW_TYPE_2D,
          .format = copy_format,
-         .mipLevel = 0,
-         .baseArraySlice = 0,
-         .arraySize = 1,
+         .channels = {
+            .r = VK_CHANNEL_SWIZZLE_R,
+            .g = VK_CHANNEL_SWIZZLE_G,
+            .b = VK_CHANNEL_SWIZZLE_B,
+            .a = VK_CHANNEL_SWIZZLE_A,
+         },
+         .subresourceRange = {
+            .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+            .baseMipLevel = 0,
+            .mipLevels = 1,
+            .baseArrayLayer = 0,
+            .arraySize = 1,
+         },
       },
       cmd_buffer);
 
@@ -1194,14 +1205,25 @@ void anv_CmdCopyImage(
          anv_finishme("FINISHME: copy multiple depth layers");
 
       struct anv_image_view dest_iview;
-      anv_color_attachment_view_init(&dest_iview, cmd_buffer->device,
-         &(VkAttachmentViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+      anv_image_view_init(&dest_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
             .image = destImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
             .format = dest_image->format->vk_format,
-            .mipLevel = pRegions[r].destSubresource.mipLevel,
-            .baseArraySlice = dest_array_slice,
-            .arraySize = 1,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+               .baseMipLevel = pRegions[r].destSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = dest_array_slice,
+               .arraySize = 1
+            },
          },
          cmd_buffer);
 
@@ -1283,14 +1305,25 @@ void anv_CmdBlitImage(
          anv_finishme("FINISHME: copy multiple depth layers");
 
       struct anv_image_view dest_iview;
-      anv_color_attachment_view_init(&dest_iview, cmd_buffer->device,
-         &(VkAttachmentViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+      anv_image_view_init(&dest_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
             .image = destImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
             .format = dest_image->format->vk_format,
-            .mipLevel = pRegions[r].destSubresource.mipLevel,
-            .baseArraySlice = dest_array_slice,
-            .arraySize = 1,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+               .baseMipLevel = pRegions[r].destSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = dest_array_slice,
+               .arraySize = 1
+            },
          },
          cmd_buffer);
 
@@ -1413,14 +1446,25 @@ void anv_CmdCopyBufferToImage(
          anv_finishme("FINISHME: copy multiple depth layers");
 
       struct anv_image_view dest_iview;
-      anv_color_attachment_view_init(&dest_iview, cmd_buffer->device,
-         &(VkAttachmentViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+      anv_image_view_init(&dest_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
             .image = anv_image_to_handle(dest_image),
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
             .format = proxy_format,
-            .mipLevel = pRegions[r].imageSubresource.mipLevel,
-            .baseArraySlice = dest_array_slice,
-            .arraySize = 1,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+               .baseMipLevel = pRegions[r].imageSubresource.mipLevel,
+               .mipLevels = 1,
+               .baseArrayLayer = dest_array_slice,
+               .arraySize = 1
+            },
          },
          cmd_buffer);
 
@@ -1497,14 +1541,25 @@ void anv_CmdCopyImageToBuffer(
             dest_format, VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT, &pRegions[r]);
 
       struct anv_image_view dest_iview;
-      anv_color_attachment_view_init(&dest_iview, cmd_buffer->device,
-         &(VkAttachmentViewCreateInfo) {
-            .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+      anv_image_view_init(&dest_iview, cmd_buffer->device,
+         &(VkImageViewCreateInfo) {
+            .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
             .image = destImage,
+            .viewType = VK_IMAGE_VIEW_TYPE_2D,
             .format = dest_format,
-            .mipLevel = 0,
-            .baseArraySlice = 0,
-            .arraySize = 1,
+            .channels = {
+               VK_CHANNEL_SWIZZLE_R,
+               VK_CHANNEL_SWIZZLE_G,
+               VK_CHANNEL_SWIZZLE_B,
+               VK_CHANNEL_SWIZZLE_A
+            },
+            .subresourceRange = {
+               .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+               .baseMipLevel = 0,
+               .mipLevels = 1,
+               .baseArrayLayer = 0,
+               .arraySize = 1
+            },
          },
          cmd_buffer);
 
@@ -1562,14 +1617,25 @@ void anv_CmdClearColorImage(
       for (uint32_t l = 0; l < pRanges[r].mipLevels; l++) {
          for (uint32_t s = 0; s < pRanges[r].arraySize; s++) {
             struct anv_image_view iview;
-            anv_color_attachment_view_init(&iview, cmd_buffer->device,
-               &(VkAttachmentViewCreateInfo) {
-                  .sType = VK_STRUCTURE_TYPE_ATTACHMENT_VIEW_CREATE_INFO,
+            anv_image_view_init(&iview, cmd_buffer->device,
+               &(VkImageViewCreateInfo) {
+                  .sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO,
                   .image = _image,
+                  .viewType = VK_IMAGE_VIEW_TYPE_2D,
                   .format = image->format->vk_format,
-                  .mipLevel = pRanges[r].baseMipLevel + l,
-                  .baseArraySlice = pRanges[r].baseArrayLayer + s,
-                  .arraySize = 1,
+                  .channels = {
+                     VK_CHANNEL_SWIZZLE_R,
+                     VK_CHANNEL_SWIZZLE_G,
+                     VK_CHANNEL_SWIZZLE_B,
+                     VK_CHANNEL_SWIZZLE_A
+                  },
+                  .subresourceRange = {
+                     .aspectMask = VK_IMAGE_ASPECT_COLOR_BIT,
+                     .baseMipLevel = pRanges[r].baseMipLevel + l,
+                     .mipLevels = 1,
+                     .baseArrayLayer = pRanges[r].baseArrayLayer + s,
+                     .arraySize = 1
+                  },
                },
                cmd_buffer);
 
index 06ab1dc65a6c6aff9e5f0ca07f8eb88edc9749b6..e9735706a67128cc79f79ce394dedb8dd2cbec67 100644 (file)
@@ -1202,7 +1202,7 @@ struct anv_image {
    VkExtent3D extent;
    uint32_t levels;
    uint32_t array_size;
-   VkImageUsageFlags usage; /**< VkImageCreateInfo::usage */
+   VkImageUsageFlags usage; /**< Superset of VkImageCreateInfo::usage. */
 
    VkDeviceSize size;
    uint32_t alignment;
@@ -1211,8 +1211,10 @@ struct anv_image {
    struct anv_bo *bo;
    VkDeviceSize offset;
 
-   /** RENDER_SURFACE_STATE.SurfaceType */
-   uint8_t surf_type;
+   uint8_t surface_type; /**< RENDER_SURFACE_STATE.SurfaceType */
+
+   bool needs_nonrt_surface_state:1;
+   bool needs_color_rt_surface_state:1;
 
    /**
     * Image subsurfaces
@@ -1247,10 +1249,15 @@ struct anv_buffer_view {
 struct anv_image_view {
    const struct anv_image *image; /**< VkImageViewCreateInfo::image */
    const struct anv_format *format; /**< VkImageViewCreateInfo::format */
-   struct anv_state surface_state; /**< RENDER_SURFACE_STATE */
    struct anv_bo *bo;
    uint32_t offset; /**< Offset into bo. */
    VkExtent3D extent; /**< Extent of VkImageViewCreateInfo::baseMipLevel. */
+
+   /** RENDER_SURFACE_STATE when using image as a color render target. */
+   struct anv_state color_rt_surface_state;
+
+   /** RENDER_SURFACE_STATE when using image as a non render target. */
+   struct anv_state nonrt_surface_state;
 };
 
 struct anv_image_create_info {
@@ -1268,9 +1275,6 @@ struct anv_surface *
 anv_image_get_surface_for_aspect_mask(struct anv_image *image,
                                       VkImageAspectFlags aspect_mask);
 
-struct anv_surface *
-anv_image_get_surface_for_color_attachment(struct anv_image *image);
-
 void anv_image_view_init(struct anv_image_view *view,
                          struct anv_device *device,
                          const VkImageViewCreateInfo* pCreateInfo,
@@ -1288,21 +1292,6 @@ gen8_image_view_init(struct anv_image_view *iview,
                      const VkImageViewCreateInfo* pCreateInfo,
                      struct anv_cmd_buffer *cmd_buffer);
 
-void anv_color_attachment_view_init(struct anv_image_view *iview,
-                                    struct anv_device *device,
-                                    const VkAttachmentViewCreateInfo* pCreateInfo,
-                                    struct anv_cmd_buffer *cmd_buffer);
-
-void gen7_color_attachment_view_init(struct anv_image_view *iview,
-                                     struct anv_device *device,
-                                     const VkAttachmentViewCreateInfo* pCreateInfo,
-                                     struct anv_cmd_buffer *cmd_buffer);
-
-void gen8_color_attachment_view_init(struct anv_image_view *iview,
-                                     struct anv_device *device,
-                                     const VkAttachmentViewCreateInfo* pCreateInfo,
-                                     struct anv_cmd_buffer *cmd_buffer);
-
 VkResult anv_buffer_view_create(struct anv_device *device,
                                 const VkBufferViewCreateInfo *pCreateInfo,
                                 struct anv_buffer_view **bview_out);
index 5829d03d3e3e7d285cc29e4c1b6ebe7ab2110513..2497e39490de664c7a63ec1fc8b28580127b9a11 100644 (file)
@@ -113,6 +113,18 @@ static const uint32_t vk_to_gen_compare_op[] = {
    [VK_COMPARE_OP_ALWAYS]                       = PREFILTEROPALWAYS,
 };
 
+static struct anv_state
+gen7_alloc_surface_state(struct anv_device *device,
+                         struct anv_cmd_buffer *cmd_buffer)
+{
+      if (cmd_buffer) {
+         return anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
+                                      64, 64);
+      } else {
+         return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+      }
+}
+
 VkResult gen7_CreateSampler(
     VkDevice                                    _device,
     const VkSamplerCreateInfo*                  pCreateInfo,
@@ -272,18 +284,17 @@ gen7_image_view_init(struct anv_image_view *iview,
    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);
 
    const struct anv_format *format =
       anv_format_for_vk_format(pCreateInfo->format);
 
-   const struct anv_image_view_info view_type_info =
-      anv_image_view_info_for_vk_image_view_type(pCreateInfo->viewType);
-
    if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
       anv_finishme("non-2D image views");
 
+   iview->image = image;
    iview->bo = image->bo;
    iview->offset = image->offset + surface->offset;
    iview->format = anv_format_for_vk_format(pCreateInfo->format);
@@ -302,7 +313,7 @@ gen7_image_view_init(struct anv_image_view *iview,
    }
 
    struct GEN7_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = view_type_info.surface_type,
+      .SurfaceType = image->surface_type,
       .SurfaceArray = image->array_size > 1,
       .SurfaceFormat = format->surface_format,
       .SurfaceVerticalAlignment = anv_valign[surface->v_align],
@@ -316,7 +327,8 @@ gen7_image_view_init(struct anv_image_view *iview,
 
       .VerticalLineStride = 0,
       .VerticalLineStrideOffset = 0,
-      .RenderCacheReadWriteMode = false,
+
+      .RenderCacheReadWriteMode = 0, /* TEMPLATE */
 
       .Height = image->extent.height - 1,
       .Width = image->extent.width - 1,
@@ -329,14 +341,8 @@ gen7_image_view_init(struct anv_image_view *iview,
 
       .SurfaceObjectControlState = GEN7_MOCS,
 
-      /* 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.
-       */
-      .MIPCountLOD = range->mipLevels - 1,
-      .SurfaceMinLOD = range->baseMipLevel,
+      .MIPCountLOD = 0, /* TEMPLATE */
+      .SurfaceMinLOD = 0, /* TEMPLATE */
 
       .MCSEnable = false,
       .RedClearColor = 0,
@@ -347,85 +353,28 @@ gen7_image_view_init(struct anv_image_view *iview,
       .SurfaceBaseAddress = { NULL, iview->offset },
    };
 
-   if (cmd_buffer) {
-      iview->surface_state =
-         anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
-   } else {
-      iview->surface_state =
-         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
-   }
-
-   GEN7_RENDER_SURFACE_STATE_pack(NULL, iview->surface_state.map,
-                                  &surface_state);
-}
-
-void
-gen7_color_attachment_view_init(struct anv_image_view *iview,
-                                struct anv_device *device,
-                                const VkAttachmentViewCreateInfo* pCreateInfo,
-                                struct anv_cmd_buffer *cmd_buffer)
-{
-   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-   struct anv_surface *surface =
-      anv_image_get_surface_for_color_attachment(image);
+   if (image->needs_nonrt_surface_state) {
+      iview->nonrt_surface_state =
+         gen7_alloc_surface_state(device, cmd_buffer);
 
-   assert(image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
-   anv_assert(pCreateInfo->arraySize > 0);
-   anv_assert(pCreateInfo->mipLevel < image->levels);
-   anv_assert(pCreateInfo->baseArraySlice + pCreateInfo->arraySize <= image->array_size);
+      surface_state.RenderCacheReadWriteMode = false;
 
-   iview->bo = image->bo;
-   iview->offset = image->offset + surface->offset;
-   iview->format = anv_format_for_vk_format(pCreateInfo->format);
-
-   iview->extent = (VkExtent3D) {
-      .width = anv_minify(image->extent.width, pCreateInfo->mipLevel),
-      .height = anv_minify(image->extent.height, pCreateInfo->mipLevel),
-      .depth = anv_minify(image->extent.depth, pCreateInfo->mipLevel),
-   };
-
-   uint32_t depth = 1;
-   if (pCreateInfo->arraySize > 1) {
-      depth = pCreateInfo->arraySize;
-   } else if (image->extent.depth > 1) {
-      depth = image->extent.depth;
-   }
-
-   if (cmd_buffer) {
-      iview->surface_state =
-         anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
-   } else {
-      iview->surface_state =
-         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
-   }
-
-   struct GEN7_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = SURFTYPE_2D,
-      .SurfaceArray = image->array_size > 1,
-      .SurfaceFormat = iview->format->surface_format,
-      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
-      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
-
-      /* From bspec (DevSNB, DevIVB): "Set Tile Walk to TILEWALK_XMAJOR if
-       * Tiled Surface is False."
+      /* 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].
        */
-      .TiledSurface = surface->tile_mode > LINEAR,
-      .TileWalk = surface->tile_mode == YMAJOR ? TILEWALK_YMAJOR : TILEWALK_XMAJOR,
+      surface_state.SurfaceMinLOD = range->baseMipLevel;
+      surface_state.MIPCountLOD = range->mipLevels - 1;
 
-      .VerticalLineStride = 0,
-      .VerticalLineStrideOffset = 0,
-      .RenderCacheReadWriteMode = WriteOnlyCache,
+      GEN7_RENDER_SURFACE_STATE_pack(NULL, iview->nonrt_surface_state.map,
+                                     &surface_state);
+   }
 
-      .Height = image->extent.height - 1,
-      .Width = image->extent.width - 1,
-      .Depth = depth - 1,
-      .SurfacePitch = surface->stride - 1,
-      .MinimumArrayElement = pCreateInfo->baseArraySlice,
-      .NumberofMultisamples = MULTISAMPLECOUNT_1,
-      .XOffset = 0,
-      .YOffset = 0,
+   if (image->needs_color_rt_surface_state) {
+      iview->color_rt_surface_state =
+         gen7_alloc_surface_state(device, cmd_buffer);
 
-      .SurfaceObjectControlState = GEN7_MOCS,
+      surface_state.RenderCacheReadWriteMode = WriteOnlyCache;
 
       /* For render target surfaces, the hardware interprets field MIPCount/LOD as
        * LOD. The Broadwell PRM says:
@@ -433,19 +382,10 @@ gen7_color_attachment_view_init(struct anv_image_view *iview,
        *    MIPCountLOD defines the LOD that will be rendered into.
        *    SurfaceMinLOD is ignored.
        */
-      .SurfaceMinLOD = 0,
-      .MIPCountLOD = pCreateInfo->mipLevel,
-
-      .MCSEnable = false,
-      .RedClearColor = 0,
-      .GreenClearColor = 0,
-      .BlueClearColor = 0,
-      .AlphaClearColor = 0,
-      .ResourceMinLOD = 0.0,
-      .SurfaceBaseAddress = { NULL, iview->offset },
-
-   };
+      surface_state.MIPCountLOD = range->baseMipLevel;
+      surface_state.SurfaceMinLOD = 0;
 
-   GEN7_RENDER_SURFACE_STATE_pack(NULL, iview->surface_state.map,
-                                  &surface_state);
+      GEN7_RENDER_SURFACE_STATE_pack(NULL, iview->color_rt_surface_state.map,
+                                     &surface_state);
+   }
 }
index 3c479e1c23ee31f3137a0f4e88741d769d2bb2c0..5095ce060bffeeae7863e0ff716f37ea775465eb 100644 (file)
@@ -139,6 +139,18 @@ static const uint8_t anv_valign[] = {
     [16] = VALIGN16,
 };
 
+static struct anv_state
+gen8_alloc_surface_state(struct anv_device *device,
+                         struct anv_cmd_buffer *cmd_buffer)
+{
+      if (cmd_buffer) {
+         return anv_state_stream_alloc(&cmd_buffer->surface_state_stream,
+                                      64, 64);
+      } else {
+         return anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+      }
+}
+
 void
 gen8_image_view_init(struct anv_image_view *iview,
                      struct anv_device *device,
@@ -148,6 +160,7 @@ gen8_image_view_init(struct anv_image_view *iview,
    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);
 
@@ -157,9 +170,7 @@ gen8_image_view_init(struct anv_image_view *iview,
    const struct anv_format *format_info =
       anv_format_for_vk_format(pCreateInfo->format);
 
-   const struct anv_image_view_info view_type_info =
-      anv_image_view_info_for_vk_image_view_type(pCreateInfo->viewType);
-
+   iview->image = image;
    iview->bo = image->bo;
    iview->offset = image->offset + surface->offset;
    iview->format = format_info;
@@ -219,7 +230,7 @@ gen8_image_view_init(struct anv_image_view *iview,
    };
 
    struct GEN8_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = view_type_info.surface_type,
+      .SurfaceType = image->surface_type,
       .SurfaceArray = image->array_size > 1,
       .SurfaceFormat = format_info->surface_format,
       .SurfaceVerticalAlignment = anv_valign[surface->v_align],
@@ -248,12 +259,8 @@ gen8_image_view_init(struct anv_image_view *iview,
       .XOffset = 0,
       .YOffset = 0,
 
-      /* For sampler surfaces, the hardware interprets field MIPCount/LOD as
-       * MIPCount.  The range of levels accessible by the sampler engine is
-       * [SurfaceMinLOD, SurfaceMinLOD + MIPCountLOD].
-       */
-      .MIPCountLOD = range->mipLevels - 1,
-      .SurfaceMinLOD = range->baseMipLevel,
+      .MIPCountLOD = 0, /* TEMPLATE */
+      .SurfaceMinLOD = 0, /* TEMPLATE */
 
       .AuxiliarySurfaceMode = AUX_NONE,
       .RedClearColor = 0,
@@ -268,149 +275,37 @@ gen8_image_view_init(struct anv_image_view *iview,
       .SurfaceBaseAddress = { NULL, iview->offset },
    };
 
-   if (cmd_buffer) {
-      iview->surface_state =
-         anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
-   } else {
-      iview->surface_state =
-         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
-   }
-
-   GEN8_RENDER_SURFACE_STATE_pack(NULL, iview->surface_state.map,
-                                  &surface_state);
-}
-
-void
-gen8_color_attachment_view_init(struct anv_image_view *iview,
-                                struct anv_device *device,
-                                const VkAttachmentViewCreateInfo* pCreateInfo,
-                                struct anv_cmd_buffer *cmd_buffer)
-{
-   ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-   struct anv_surface *surface =
-      anv_image_get_surface_for_color_attachment(image);
-   const struct anv_format *format_info =
-      anv_format_for_vk_format(pCreateInfo->format);
-
-   uint32_t depth = 1; /* RENDER_SURFACE_STATE::Depth */
-   uint32_t rt_view_extent = 1; /* RENDER_SURFACE_STATE::RenderTargetViewExtent */
-
-   assert(image->usage & VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT);
-   anv_assert(pCreateInfo->arraySize > 0);
-   anv_assert(pCreateInfo->mipLevel < image->levels);
-   anv_assert(pCreateInfo->baseArraySlice + pCreateInfo->arraySize <= image->array_size);
-
-   iview->bo = image->bo;
-   iview->offset = image->offset + surface->offset;
-   iview->format = anv_format_for_vk_format(pCreateInfo->format);
-
-   iview->extent = (VkExtent3D) {
-      .width = anv_minify(image->extent.width, pCreateInfo->mipLevel),
-      .height = anv_minify(image->extent.height, pCreateInfo->mipLevel),
-      .depth = anv_minify(image->extent.depth, pCreateInfo->mipLevel),
-   };
+   if (image->needs_nonrt_surface_state) {
+      iview->nonrt_surface_state =
+         gen8_alloc_surface_state(device, cmd_buffer);
 
-   switch (image->type) {
-   case VK_IMAGE_TYPE_1D:
-   case VK_IMAGE_TYPE_2D:
-      /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
-       *
-       *    For SURFTYPE_1D, 2D, and CUBE: The range of this field is reduced
-       *    by one for each increase from zero of Minimum Array Element. For
-       *    example, if Minimum Array Element is set to 1024 on a 2D surface,
-       *    the range of this field is reduced to [0,1023].
-       */
-      depth = pCreateInfo->arraySize;
-
-      /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
-       *
-       *    For Render Target and Typed Dataport 1D and 2D Surfaces:
-       *    This field must be set to the same value as the Depth field.
+      /* 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].
        */
-      rt_view_extent = depth;
-      break;
-   case VK_IMAGE_TYPE_3D:
-      /* From the Broadwell PRM >> RENDER_SURFACE_STATE::Depth:
-       *
-       *    If the volume texture is MIP-mapped, this field specifies the
-       *    depth of the base MIP level.
-       */
-      depth = image->extent.depth;
+      surface_state.SurfaceMinLOD = range->baseMipLevel;
+      surface_state.MIPCountLOD = range->mipLevels - 1;
 
-      /* From the Broadwell PRM >> RENDER_SURFACE_STATE::RenderTargetViewExtent:
-       *
-       *    For Render Target and Typed Dataport 3D Surfaces: This field
-       *    indicates the extent of the accessible 'R' coordinates minus 1 on
-       *    the LOD currently being rendered to.
-       */
-      rt_view_extent = iview->extent.depth;
-      break;
-   default:
-      unreachable(!"bad VkImageType");
-   }
-
-   if (cmd_buffer) {
-      iview->surface_state =
-         anv_state_stream_alloc(&cmd_buffer->surface_state_stream, 64, 64);
-   } else {
-      iview->surface_state =
-         anv_state_pool_alloc(&device->surface_state_pool, 64, 64);
+      GEN8_RENDER_SURFACE_STATE_pack(NULL, iview->nonrt_surface_state.map,
+                                     &surface_state);
    }
 
-   struct GEN8_RENDER_SURFACE_STATE surface_state = {
-      .SurfaceType = image->type,
-      .SurfaceArray = image->array_size > 1,
-      .SurfaceFormat = format_info->surface_format,
-      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
-      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
-      .TileMode = surface->tile_mode,
-      .VerticalLineStride = 0,
-      .VerticalLineStrideOffset = 0,
-      .SamplerL2BypassModeDisable = true,
-      .RenderCacheReadWriteMode = WriteOnlyCache,
-      .MemoryObjectControlState = GEN8_MOCS,
-
-      /* The driver sets BaseMipLevel in SAMPLER_STATE, not here in
-       * RENDER_SURFACE_STATE. The Broadwell PRM says "it is illegal to have
-       * both Base Mip Level fields nonzero".
-       */
-      .BaseMipLevel = 0.0,
-
-      .SurfaceQPitch = surface->qpitch >> 2,
-      .Height = image->extent.height - 1,
-      .Width = image->extent.width - 1,
-      .Depth = depth - 1,
-      .SurfacePitch = surface->stride - 1,
-      .RenderTargetViewExtent = rt_view_extent - 1,
-      .MinimumArrayElement = pCreateInfo->baseArraySlice,
-      .NumberofMultisamples = MULTISAMPLECOUNT_1,
-      .XOffset = 0,
-      .YOffset = 0,
+   if (image->needs_color_rt_surface_state) {
+      iview->color_rt_surface_state =
+         gen8_alloc_surface_state(device, cmd_buffer);
 
-      /* For render target surfaces, the hardware interprets field MIPCount/LOD as
-       * LOD. The Broadwell PRM says:
+      /* 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.
        */
-      .SurfaceMinLOD = 0,
-      .MIPCountLOD = pCreateInfo->mipLevel,
-
-      .AuxiliarySurfaceMode = AUX_NONE,
-      .RedClearColor = 0,
-      .GreenClearColor = 0,
-      .BlueClearColor = 0,
-      .AlphaClearColor = 0,
-      .ShaderChannelSelectRed = SCS_RED,
-      .ShaderChannelSelectGreen = SCS_GREEN,
-      .ShaderChannelSelectBlue = SCS_BLUE,
-      .ShaderChannelSelectAlpha = SCS_ALPHA,
-      .ResourceMinLOD = 0.0,
-      .SurfaceBaseAddress = { NULL, iview->offset },
-   };
+      surface_state.MIPCountLOD = range->baseMipLevel;
+      surface_state.SurfaceMinLOD = 0;
 
-   GEN8_RENDER_SURFACE_STATE_pack(NULL, iview->surface_state.map,
-                                  &surface_state);
+      GEN8_RENDER_SURFACE_STATE_pack(NULL, iview->color_rt_surface_state.map,
+                                     &surface_state);
+   }
 }
 
 VkResult gen8_CreateSampler(