vk/image: Let anv_image have one anv_surface per aspect
authorChad Versace <chad.versace@intel.com>
Fri, 28 Aug 2015 14:08:58 +0000 (07:08 -0700)
committerChad Versace <chad.versace@intel.com>
Fri, 28 Aug 2015 14:17:54 +0000 (07:17 -0700)
Split anv_image::primary_surface into two: anv_image::color_surface and
depth_surface.

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

index 15a736c25bc47d1b76edd3a913dabdec1de54973..198f4a40212585793f07f7be05a69e3e440d2fbf 100644 (file)
@@ -258,26 +258,28 @@ anv_image_create(VkDevice _device,
    image->array_size = pCreateInfo->arraySize;
    image->surf_type = surf_type;
 
-   if (likely(!image->format->has_stencil || image->format->depth_format)) {
-      /* The image's primary surface is a color or depth surface. */
+   if (likely(anv_format_is_color(image->format))) {
       r = anv_image_make_surface(create_info, image->format,
                                  &image->size, &image->alignment,
-                                 &image->primary_surface);
-      if (r != VK_SUCCESS)
-         goto fail;
-   }
-
-   if (image->format->has_stencil) {
-      /* From the GPU's perspective, the depth buffer and stencil buffer are
-       * separate buffers.  From Vulkan's perspective, though, depth and
-       * stencil reside in the same image.  To satisfy Vulkan and the GPU, we
-       * place the depth and stencil buffers in the same bo.
-       */
-      r = anv_image_make_surface(create_info, anv_format_s8_uint,
-                                 &image->size, &image->alignment,
-                                 &image->stencil_surface);
+                                 &image->color_surface);
       if (r != VK_SUCCESS)
          goto fail;
+   } else {
+      if (image->format->depth_format) {
+         r = anv_image_make_surface(create_info, image->format,
+                                    &image->size, &image->alignment,
+                                    &image->depth_surface);
+         if (r != VK_SUCCESS)
+            goto fail;
+      }
+
+      if (image->format->has_stencil) {
+         r = anv_image_make_surface(create_info, anv_format_s8_uint,
+                                    &image->size, &image->alignment,
+                                    &image->stencil_surface);
+         if (r != VK_SUCCESS)
+            goto fail;
+      }
    }
 
    *pImage = anv_image_to_handle(image);
@@ -462,28 +464,64 @@ anv_depth_stencil_view_init(struct anv_depth_stencil_view *view,
                             const VkAttachmentViewCreateInfo *pCreateInfo)
 {
    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
-   struct anv_surface *depth_surface = &image->primary_surface;
-   struct anv_surface *stencil_surface = &image->stencil_surface;
 
    view->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_DEPTH_STENCIL;
 
    /* XXX: We don't handle any of these */
+   assert(anv_format_is_depth_or_stencil(image->format));
    anv_assert(pCreateInfo->mipLevel == 0);
    anv_assert(pCreateInfo->baseArraySlice == 0);
    anv_assert(pCreateInfo->arraySize == 1);
 
    view->bo = image->bo;
 
-   view->depth_stride = depth_surface->stride;
-   view->depth_offset = image->offset + depth_surface->offset;
+   view->depth_stride = image->depth_surface.stride;
+   view->depth_offset = image->offset + image->depth_surface.offset;
    view->depth_format = image->format->depth_format;
    view->depth_qpitch = 0; /* FINISHME: QPitch */
 
-   view->stencil_stride = stencil_surface->stride;
-   view->stencil_offset = image->offset + stencil_surface->offset;
+   view->stencil_stride = image->stencil_surface.stride;
+   view->stencil_offset = image->offset + image->stencil_surface.offset;
    view->stencil_qpitch = 0; /* FINISHME: QPitch */
 }
 
+struct anv_surface *
+anv_image_get_surface_for_aspect(struct anv_image *image, VkImageAspect aspect)
+{
+   switch (aspect) {
+   case VK_IMAGE_ASPECT_COLOR:
+      assert(anv_format_is_color(image->format));
+      return &image->color_surface;
+   case VK_IMAGE_ASPECT_DEPTH:
+      assert(image->format->depth_format);
+      return &image->depth_surface;
+   case VK_IMAGE_ASPECT_STENCIL:
+      assert(image->format->has_stencil);
+      anv_finishme("stencil image views");
+      abort();
+      return &image->stencil_surface;
+    default:
+       unreachable("image does not have aspect");
+       return NULL;
+   }
+}
+
+/** 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_color_attachment_view *aview,
                                struct anv_device *device,
index 55affd160d95cc8b4596da852d6bb36796ac5e55..2d037b4cbb30ff5472a3d358dbef3af6535a95cd 100644 (file)
@@ -1063,11 +1063,26 @@ struct anv_image {
    /** RENDER_SURFACE_STATE.SurfaceType */
    uint8_t surf_type;
 
-   /** Primary surface is either color or depth. */
-   struct anv_surface primary_surface;
+   /**
+    * Image subsurfaces
+    *
+    * For each foo, anv_image::foo_surface is valid if and only if
+    * anv_image::format has a foo aspect.
+    *
+    * The hardware requires that the depth buffer and stencil buffer be
+    * separate surfaces.  From Vulkan's perspective, though, depth and stencil
+    * reside in the same VkImage.  To satisfy both the hardware and Vulkan, we
+    * allocate the depth and stencil buffers as separate surfaces in the same
+    * bo.
+    */
+   union {
+      struct anv_surface color_surface;
 
-   /** Stencil surface is optional. */
-   struct anv_surface stencil_surface;
+      struct {
+         struct anv_surface depth_surface;
+         struct anv_surface stencil_surface;
+      };
+   };
 };
 
 struct anv_surface_view {
@@ -1128,6 +1143,12 @@ VkResult anv_image_create(VkDevice _device,
                           const struct anv_image_create_info *info,
                           VkImage *pImage);
 
+struct anv_surface *
+anv_image_get_surface_for_aspect(struct anv_image *image, VkImageAspect aspect);
+
+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,
index aee5775c9deff122cf53b5ca935645753bc9fed0..f65a86487cbffa78a9d983e1621e30a3e9fe1569 100644 (file)
@@ -145,7 +145,7 @@ VkResult anv_CreateSwapChainWSI(
       image = anv_image_from_handle(image_h);
       assert(anv_format_is_color(image->format));
 
-      surface = &image->primary_surface;
+      surface = &image->color_surface;
 
       anv_AllocMemory(_device,
                       &(VkMemoryAllocInfo) {
index 801716ea884c81a47dbb6b59137bd2759a6a01f5..faf99a5aef844c4db6ecfab7ec50ab3d0d7b54d1 100644 (file)
@@ -273,7 +273,8 @@ gen7_image_view_init(struct anv_image_view *iview,
 
    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
    struct anv_surface_view *view = &iview->view;
-   struct anv_surface *surface;
+   struct anv_surface *surface =
+      anv_image_get_surface_for_aspect(image, range->aspect);
 
    const struct anv_format *format =
       anv_format_for_vk_format(pCreateInfo->format);
@@ -284,21 +285,6 @@ gen7_image_view_init(struct anv_image_view *iview,
    if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
       anv_finishme("non-2D image views");
 
-   switch (pCreateInfo->subresourceRange.aspect) {
-   case VK_IMAGE_ASPECT_STENCIL:
-      anv_finishme("stencil image views");
-      abort();
-      break;
-   case VK_IMAGE_ASPECT_DEPTH:
-   case VK_IMAGE_ASPECT_COLOR:
-      view->offset = image->offset;
-      surface = &image->primary_surface;
-      break;
-   default:
-      unreachable("");
-      break;
-   }
-
    view->bo = image->bo;
    view->offset = image->offset + surface->offset;
    view->format = anv_format_for_vk_format(pCreateInfo->format);
@@ -381,7 +367,8 @@ gen7_color_attachment_view_init(struct anv_color_attachment_view *aview,
 {
    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
    struct anv_surface_view *view = &aview->view;
-   struct anv_surface *surface = &image->primary_surface;
+   struct anv_surface *surface =
+      anv_image_get_surface_for_color_attachment(image);
 
    aview->base.attachment_type = ANV_ATTACHMENT_VIEW_TYPE_COLOR;
 
index 0d65f1692314c1f89ef3feecebc9afc91732f8c0..5e79a37f40216f32c035ddbb4bf4a6837b3673ba 100644 (file)
@@ -149,7 +149,8 @@ gen8_image_view_init(struct anv_image_view *iview,
 
    const VkImageSubresourceRange *range = &pCreateInfo->subresourceRange;
    struct anv_surface_view *view = &iview->view;
-   struct anv_surface *surface;
+   struct anv_surface *surface =
+      anv_image_get_surface_for_aspect(image, range->aspect);
 
    const struct anv_format *format_info =
       anv_format_for_vk_format(pCreateInfo->format);
@@ -160,21 +161,6 @@ gen8_image_view_init(struct anv_image_view *iview,
    if (pCreateInfo->viewType != VK_IMAGE_VIEW_TYPE_2D)
       anv_finishme("non-2D image views");
 
-   switch (pCreateInfo->subresourceRange.aspect) {
-   case VK_IMAGE_ASPECT_STENCIL:
-      anv_finishme("stencil image views");
-      abort();
-      break;
-   case VK_IMAGE_ASPECT_DEPTH:
-   case VK_IMAGE_ASPECT_COLOR:
-      view->offset = image->offset;
-      surface = &image->primary_surface;
-      break;
-   default:
-      unreachable("");
-      break;
-   }
-
    view->bo = image->bo;
    view->offset = image->offset + surface->offset;
    view->format = format_info;
@@ -269,7 +255,8 @@ gen8_color_attachment_view_init(struct anv_color_attachment_view *aview,
 {
    ANV_FROM_HANDLE(anv_image, image, pCreateInfo->image);
    struct anv_surface_view *view = &aview->view;
-   struct anv_surface *surface = &image->primary_surface;
+   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);