vk/image: Define anv_surface, refactor anv_image
authorChad Versace <chad.versace@intel.com>
Sat, 27 Jun 2015 01:48:34 +0000 (18:48 -0700)
committerChad Versace <chad.versace@intel.com>
Sat, 27 Jun 2015 04:45:53 +0000 (21:45 -0700)
This prepares for upcoming miptree support.

anv_surface is a proxy for color surfaces, depth surfaces, and stencil
surfaces.  Embed two instances of anv_surface into anv_image: the
primary surface (color or depth), and an optional stencil surface.

src/vulkan/image.c
src/vulkan/intel.c
src/vulkan/private.h
src/vulkan/x11.c

index 584e4bc62f374fedf742b2876bcd6819f94d31eb..4a42aecba4133fc81aa35c7f25e2d4e1271e2485 100644 (file)
@@ -96,6 +96,9 @@ anv_image_choose_tile_mode(const struct anv_image_create_info *anv_info)
    if (anv_info->force_tile_mode)
       return anv_info->tile_mode;
 
+   if (anv_info->vk_info->format == VK_FORMAT_S8_UINT)
+      return WMAJOR;
+
    switch (anv_info->vk_info->tiling) {
    case VK_IMAGE_TILING_LINEAR:
       return LINEAR;
@@ -107,6 +110,43 @@ anv_image_choose_tile_mode(const struct anv_image_create_info *anv_info)
    }
 }
 
+static void
+anv_image_make_surface(const struct anv_image_create_info *create_info,
+                       uint64_t *inout_image_size,
+                       uint32_t *inout_image_alignment,
+                       struct anv_surface *out_surface)
+{
+   const VkExtent3D *restrict extent = &create_info->vk_info->extent;
+
+   const uint8_t tile_mode = anv_image_choose_tile_mode(create_info);
+
+   const struct anv_tile_info *tile_info =
+       &anv_tile_info_table[tile_mode];
+
+   const struct anv_format *format_info =
+      anv_format_for_vk_format(create_info->vk_info->format);
+
+   uint32_t stride = align_u32(extent->width * format_info->cpp,
+                               tile_info->width);
+   uint32_t size = stride * align_u32(extent->height, tile_info->height);
+   uint32_t offset = align_u32(*inout_image_size,
+                               tile_info->surface_alignment);
+
+   *inout_image_size = offset + size;
+   *inout_image_alignment = MAX(*inout_image_alignment,
+                                tile_info->surface_alignment);
+
+   *out_surface = (struct anv_surface) {
+      .offset = offset,
+      .stride = stride,
+      .tile_mode = tile_mode,
+
+      /* FINISHME: Stop hardcoding miptree subimage alignment */
+      .h_align = 4,
+      .v_align = 4,
+   };
+}
+
 VkResult
 anv_image_create(VkDevice _device,
                  const struct anv_image_create_info *create_info,
@@ -115,6 +155,7 @@ anv_image_create(VkDevice _device,
    struct anv_device *device = (struct anv_device *) _device;
    const VkImageCreateInfo *pCreateInfo = create_info->vk_info;
    const VkExtent3D *restrict extent = &pCreateInfo->extent;
+   struct anv_image *image;
 
    assert(pCreateInfo->sType == VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO);
 
@@ -127,8 +168,6 @@ anv_image_create(VkDevice _device,
    anv_assert(pCreateInfo->extent.height > 0);
    anv_assert(pCreateInfo->extent.depth == 1);
 
-   const uint32_t tile_mode = anv_image_choose_tile_mode(create_info);
-
    /* TODO(chadv): How should we validate inputs? */
    const uint8_t surf_type =
       anv_surf_type_from_image_type[pCreateInfo->imageType];
@@ -136,9 +175,6 @@ anv_image_create(VkDevice _device,
    const struct anv_surf_type_limits *limits =
       &anv_surf_type_limits[surf_type];
 
-   const struct anv_tile_info *tile_info =
-       &anv_tile_info_table[tile_mode];
-
    if (extent->width > limits->width ||
        extent->height > limits->height ||
        extent->depth > limits->depth) {
@@ -150,19 +186,21 @@ anv_image_create(VkDevice _device,
    const struct anv_format *format_info =
       anv_format_for_vk_format(pCreateInfo->format);
 
-   uint32_t image_stride = 0;
-   uint32_t image_size = 0;
-   uint32_t stencil_offset = 0;
-   uint32_t stencil_stride = 0;
+   image = anv_device_alloc(device, sizeof(*image), 8,
+                            VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
+   if (!image)
+      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
 
-   if (!format_info->has_stencil || format_info->depth_format) {
-      /* The format has a color or depth component. Calculate space for it. */
-      uint32_t aligned_height;
+   memset(image, 0, sizeof(*image));
+   image->type = pCreateInfo->imageType;
+   image->extent = pCreateInfo->extent;
+   image->format = pCreateInfo->format;
+   image->surf_type = surf_type;
 
-      image_stride = align_i32(extent->width * format_info->cpp,
-                               tile_info->width);
-      aligned_height = align_i32(extent->height, tile_info->height);
-      image_size = image_stride * aligned_height;
+   if (likely(!format_info->has_stencil || format_info->depth_format)) {
+      /* The image's primary surface is a color or depth surface. */
+      anv_image_make_surface(create_info, &image->size, &image->alignment,
+                             &image->primary_surface);
    }
 
    if (format_info->has_stencil) {
@@ -171,51 +209,16 @@ anv_image_create(VkDevice _device,
        * stencil reside in the same image.  To satisfy Vulkan and the GPU, we
        * place the depth and stencil buffers in the same bo.
        */
-      const struct anv_tile_info *w_info = &anv_tile_info_table[WMAJOR];
-      uint32_t aligned_height;
-      uint32_t stencil_size;
-
-      stencil_offset = align_u32(image_size, w_info->surface_alignment);
-      stencil_stride = align_i32(extent->width, w_info->width);
-      aligned_height = align_i32(extent->height, w_info->height);
-      stencil_size = stencil_stride * aligned_height;
-      image_size = stencil_offset + stencil_size;
+      VkImageCreateInfo stencil_info = *pCreateInfo;
+      stencil_info.format = VK_FORMAT_S8_UINT;
+
+      anv_image_make_surface(
+         &(struct anv_image_create_info) {
+            .vk_info = &stencil_info,
+         },
+         &image->size, &image->alignment, &image->stencil_surface);
    }
 
-   struct anv_image *image = anv_device_alloc(device, sizeof(*image), 8,
-                                              VK_SYSTEM_ALLOC_TYPE_API_OBJECT);
-   if (!image)
-      return vk_error(VK_ERROR_OUT_OF_HOST_MEMORY);
-
-   /* To eliminate the risk of using unitialized struct members above, fill the
-    * image struct here at the function bottom instead of piecemeal throughout
-    * the function body.
-    */
-   *image = (struct anv_image) {
-      .type = pCreateInfo->imageType,
-      .extent = pCreateInfo->extent,
-      .format = pCreateInfo->format,
-
-      .size = image_size,
-      .alignment = tile_info->surface_alignment,
-      .stride = image_stride,
-
-      .bo = NULL,
-      .offset = 0,
-
-      .stencil_offset = stencil_offset,
-      .stencil_stride = stencil_stride,
-
-      .tile_mode = tile_mode,
-      .surf_type = surf_type,
-
-      /* FINISHME: Stop hardcoding miptree image alignment */
-      .h_align = 4,
-      .v_align = 4,
-
-      .swap_chain = NULL,
-   };
-
    *pImage = (VkImage) image;
 
    return VK_SUCCESS;
@@ -266,6 +269,7 @@ anv_image_view_init(struct anv_surface_view *view,
                     struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_image *image = (struct anv_image *) pCreateInfo->image;
+   struct anv_surface *surface = NULL;
 
    const struct anv_format *format_info =
       anv_format_for_vk_format(pCreateInfo->format);
@@ -287,12 +291,15 @@ anv_image_view_init(struct anv_surface_view *view,
    case VK_IMAGE_ASPECT_DEPTH:
    case VK_IMAGE_ASPECT_COLOR:
       view->offset = image->offset;
+      surface = &image->primary_surface;
       break;
    default:
       unreachable("");
       break;
    }
 
+   view->offset = image->offset + surface->offset;
+
    /* TODO: Miplevels */
    view->extent = image->extent;
 
@@ -309,9 +316,9 @@ anv_image_view_init(struct anv_surface_view *view,
       .SurfaceType = anv_surf_type_from_image_view_type[pCreateInfo->viewType],
       .SurfaceArray = false,
       .SurfaceFormat = format_info->surface_format,
-      .SurfaceVerticalAlignment = anv_valign[image->v_align],
-      .SurfaceHorizontalAlignment = anv_halign[image->h_align],
-      .TileMode = image->tile_mode,
+      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
+      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
+      .TileMode = surface->tile_mode,
       .VerticalLineStride = 0,
       .VerticalLineStrideOffset = 0,
       .SamplerL2BypassModeDisable = true,
@@ -322,7 +329,7 @@ anv_image_view_init(struct anv_surface_view *view,
       .Height = image->extent.height - 1,
       .Width = image->extent.width - 1,
       .Depth = image->extent.depth - 1,
-      .SurfacePitch = image->stride - 1,
+      .SurfacePitch = surface->stride - 1,
       .MinimumArrayElement = 0,
       .NumberofMultisamples = MULTISAMPLECOUNT_1,
       .XOffset = 0,
@@ -383,6 +390,7 @@ anv_color_attachment_view_init(struct anv_surface_view *view,
                                struct anv_cmd_buffer *cmd_buffer)
 {
    struct anv_image *image = (struct anv_image *) pCreateInfo->image;
+   struct anv_surface *surface = &image->primary_surface;
    const struct anv_format *format =
       anv_format_for_vk_format(pCreateInfo->format);
 
@@ -408,9 +416,9 @@ anv_color_attachment_view_init(struct anv_surface_view *view,
       .SurfaceType = SURFTYPE_2D,
       .SurfaceArray = false,
       .SurfaceFormat = format->surface_format,
-      .SurfaceVerticalAlignment = anv_valign[image->v_align],
-      .SurfaceHorizontalAlignment = anv_halign[image->h_align],
-      .TileMode = image->tile_mode,
+      .SurfaceVerticalAlignment = anv_valign[surface->v_align],
+      .SurfaceHorizontalAlignment = anv_halign[surface->h_align],
+      .TileMode = surface->tile_mode,
       .VerticalLineStride = 0,
       .VerticalLineStrideOffset = 0,
       .SamplerL2BypassModeDisable = true,
@@ -421,7 +429,7 @@ anv_color_attachment_view_init(struct anv_surface_view *view,
       .Height = image->extent.height - 1,
       .Width = image->extent.width - 1,
       .Depth = image->extent.depth - 1,
-      .SurfacePitch = image->stride - 1,
+      .SurfacePitch = surface->stride - 1,
       .MinimumArrayElement = 0,
       .NumberofMultisamples = MULTISAMPLECOUNT_1,
       .XOffset = 0,
@@ -476,6 +484,8 @@ anv_CreateDepthStencilView(VkDevice _device,
    struct anv_device *device = (struct anv_device *) _device;
    struct anv_depth_stencil_view *view;
    struct anv_image *image = (struct anv_image *) pCreateInfo->image;
+   struct anv_surface *depth_surface = &image->primary_surface;
+   struct anv_surface *stencil_surface = &image->stencil_surface;
    const struct anv_format *format =
       anv_format_for_vk_format(image->format);
 
@@ -494,13 +504,13 @@ anv_CreateDepthStencilView(VkDevice _device,
 
    view->bo = image->bo;
 
-   view->depth_stride = image->stride;
-   view->depth_offset = image->offset;
+   view->depth_stride = depth_surface->stride;
+   view->depth_offset = image->offset + depth_surface->offset;
    view->depth_format = format->depth_format;
    view->depth_qpitch = 0; /* FINISHME: QPitch */
 
-   view->stencil_stride = image->stencil_stride;
-   view->stencil_offset = image->offset + image->stencil_offset;
+   view->stencil_stride = stencil_surface->stride;
+   view->stencil_offset = image->offset + stencil_surface->offset;
    view->stencil_qpitch = 0; /* FINISHME: QPitch */
 
    *pView = (VkDepthStencilView) view;
index fbfed596397457db54f307ff96888cfbd6319baa..06e79591ee4d84a59356c201a2d32a080cb241cb 100644 (file)
@@ -65,13 +65,19 @@ VkResult anv_CreateDmaBufImageINTEL(
       goto fail_mem;
    }
 
-   image->bo = &mem->bo;
-   image->offset = 0;
-   image->type = VK_IMAGE_TYPE_2D;
-   image->extent = pCreateInfo->extent;
-   image->tile_mode = XMAJOR;
-   image->stride = pCreateInfo->strideInBytes;
-   image->size = mem->bo.size;
+   *image = (struct anv_image) {
+      .bo = &mem->bo,
+      .offset = 0,
+      .type = VK_IMAGE_TYPE_2D,
+      .extent = pCreateInfo->extent,
+      .size = mem->bo.size,
+
+      .primary_surface = {
+         .offset = 0,
+         .stride = pCreateInfo->strideInBytes,
+         .tile_mode = XMAJOR,
+      },
+   };
 
    assert(image->extent.width > 0);
    assert(image->extent.height > 0);
index d55912d7543df1085a244960f342f41d3d790cc2..9a1d0a2c53a45da2284da3feec2fb4abdb1f0724 100644 (file)
@@ -784,17 +784,38 @@ struct anv_format {
 const struct anv_format *
 anv_format_for_vk_format(VkFormat format);
 
+/**
+ * A proxy for the color surfaces, depth surfaces, and stencil surfaces.
+ */
+struct anv_surface {
+   /**
+    * Offset from VkImage's base address, as bound by vkBindImageMemory().
+    */
+   uint32_t offset;
+
+   uint32_t stride; /**< RENDER_SURFACE_STATE.SurfacePitch */
+
+   /**
+    * \name Alignment of miptree images, in units of pixels.
+    *
+    * These fields contain the real alignment values, not the values to be
+    * given to the GPU.  For example, if h_align is 4, then program the GPU
+    * with HALIGN_4.
+    * \{
+    */
+   uint8_t h_align; /**< RENDER_SURFACE_STATE.SurfaceHorizontalAlignment */
+   uint8_t v_align; /**< RENDER_SURFACE_STATE.SurfaceVerticalAlignment */
+   /** \} */
+
+   uint8_t tile_mode; /**< RENDER_SURFACE_STATE.TileMode */
+};
+
 struct anv_image {
    VkImageType type;
    VkExtent3D extent;
    VkFormat format;
-   uint32_t tile_mode;
    VkDeviceSize size;
    uint32_t alignment;
-   uint32_t stride;
-
-   uint32_t stencil_offset;
-   uint32_t stencil_stride;
 
    /* Set when bound */
    struct anv_bo *bo;
@@ -802,23 +823,14 @@ struct anv_image {
 
    struct anv_swap_chain *swap_chain;
 
-   /**
-    * \name Alignment of miptree images, in units of pixels.
-    *
-    * These fields contain the actual alignment values, not the values the
-    * hardware expects. For example, if h_align is 4, then program the hardware
-    * with HALIGN_4.
-    *
-    * \see RENDER_SURFACE_STATE.SurfaceHorizontalAlignment
-    * \see RENDER_SURFACE_STATE.SurfaceVerticalAlignment
-    * \{
-    */
-   uint8_t h_align;
-   uint8_t v_align;
-   /** \} */
-
    /** RENDER_SURFACE_STATE.SurfaceType */
    uint8_t surf_type;
+
+   /** Primary surface is either color or depth. */
+   struct anv_surface primary_surface;
+
+   /** Stencil surface is optional. */
+   struct anv_surface stencil_surface;
 };
 
 struct anv_surface_view {
index 6aeb34b9b56dd7a253b40bdd5e5e6bca400b6235..d49b93331a824946350613fefbca6e5f2a6307f5 100644 (file)
@@ -104,6 +104,7 @@ VkResult anv_CreateSwapChainWSI(
 
    for (uint32_t i = 0; i < chain->count; i++) {
       struct anv_image *image;
+      struct anv_surface *surface;
       struct anv_device_memory *memory;
 
       anv_image_create((VkDevice) device,
@@ -130,6 +131,8 @@ VkResult anv_CreateSwapChainWSI(
          }},
          (VkImage *) &image);
 
+      surface = &image->primary_surface;
+
       anv_AllocMemory((VkDevice) device,
                       &(VkMemoryAllocInfo) {
                          .sType = VK_STRUCTURE_TYPE_MEMORY_ALLOC_INFO,
@@ -143,7 +146,7 @@ VkResult anv_CreateSwapChainWSI(
                                 (VkDeviceMemory) memory, 0);
 
       ret = anv_gem_set_tiling(device, memory->bo.gem_handle,
-                               image->stride, I915_TILING_X);
+                               surface->stride, I915_TILING_X);
       if (ret) {
          result = vk_error(VK_ERROR_UNKNOWN);
          goto fail;
@@ -166,7 +169,7 @@ VkResult anv_CreateSwapChainWSI(
                                              image->size,
                                              pCreateInfo->imageExtent.width,
                                              pCreateInfo->imageExtent.height,
-                                             image->stride,
+                                             surface->stride,
                                              depth, bpp, fd);
 
       chain->images[i].image = image;