zink: set up image create bits for sparse textures
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Mon, 3 Jan 2022 19:34:30 +0000 (14:34 -0500)
committerMarge Bot <emma+marge@anholt.net>
Thu, 20 Jan 2022 15:51:30 +0000 (15:51 +0000)
Acked-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/14381>

src/gallium/drivers/zink/zink_resource.c
src/gallium/drivers/zink/zink_resource.h

index d82eef3..dcc8966 100644 (file)
@@ -259,9 +259,6 @@ get_image_usage_for_feats(struct zink_screen *screen, VkFormatFeatureFlags feats
          return 0;
    }
 
-   if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE)
-      usage |= VK_IMAGE_USAGE_TRANSIENT_ATTACHMENT_BIT;
-
    if (bind & PIPE_BIND_STREAM_OUTPUT)
       usage |= VK_IMAGE_USAGE_INPUT_ATTACHMENT_BIT;
 
@@ -340,6 +337,9 @@ create_ici(struct zink_screen *screen, VkImageCreateInfo *ici, const struct pipe
    ici->usage = 0;
    ici->queueFamilyIndexCount = 0;
 
+   if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE)
+      ici->flags |= VK_IMAGE_CREATE_SPARSE_BINDING_BIT | VK_IMAGE_CREATE_SPARSE_RESIDENCY_BIT;
+
    bool need_2D_zs = false;
    switch (templ->target) {
    case PIPE_TEXTURE_1D:
@@ -733,8 +733,9 @@ resource_object_create(struct zink_screen *screen, const struct pipe_resource *t
          if (VKSCR(BindBufferMemory)(screen->dev, obj->buffer, zink_bo_get_mem(obj->bo), obj->offset) != VK_SUCCESS)
             goto fail3;
    } else {
-      if (VKSCR(BindImageMemory)(screen->dev, obj->image, zink_bo_get_mem(obj->bo), obj->offset) != VK_SUCCESS)
-         goto fail3;
+      if (!(templ->flags & PIPE_RESOURCE_FLAG_SPARSE))
+         if (VKSCR(BindImageMemory)(screen->dev, obj->image, zink_bo_get_mem(obj->bo), obj->offset) != VK_SUCCESS)
+            goto fail3;
    }
    return obj;
 
@@ -779,6 +780,8 @@ resource_create(struct pipe_screen *pscreen,
 
    bool optimal_tiling = false;
    struct pipe_resource templ2 = *templ;
+   if (templ2.flags & PIPE_RESOURCE_FLAG_SPARSE)
+      templ2.bind |= PIPE_BIND_SHADER_IMAGE;
    unsigned scanout_flags = templ->bind & (PIPE_BIND_SCANOUT | PIPE_BIND_SHARED);
    if (whandle && whandle->type == ZINK_EXTERNAL_MEMORY_HANDLE)
       scanout_flags = 0;
@@ -792,6 +795,8 @@ resource_create(struct pipe_screen *pscreen,
    }
 
    res->internal_format = templ->format;
+   if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE)
+      res->base.b.bind |= PIPE_BIND_SHADER_IMAGE;
    if (templ->target == PIPE_BUFFER) {
       util_range_init(&res->valid_buffer_range);
       if (!screen->resizable_bar && templ->width0 >= 8196) {
@@ -805,6 +810,11 @@ resource_create(struct pipe_screen *pscreen,
          res->base.b.flags |= PIPE_RESOURCE_FLAG_DONT_MAP_DIRECTLY;
       }
    } else {
+      if (templ->flags & PIPE_RESOURCE_FLAG_SPARSE) {
+         uint32_t count = 1;
+         VKSCR(GetImageSparseMemoryRequirements)(screen->dev, res->obj->image, &count, &res->sparse);
+         res->base.b.nr_sparse_levels = res->sparse.imageMipTailFirstLod;
+      }
       res->format = zink_get_format(screen, templ->format);
       res->need_2D_zs = screen->need_2D_zs && util_format_is_depth_or_stencil(templ->format) &&
                         (templ->target == PIPE_TEXTURE_1D || templ->target == PIPE_TEXTURE_1D_ARRAY);
index f52bb01..5e99dca 100644 (file)
@@ -107,6 +107,7 @@ struct zink_resource {
          uint32_t ssbo_bind_mask[PIPE_SHADER_TYPES];
       };
       struct {
+         VkSparseImageMemoryRequirements sparse;
          VkFormat format;
          VkImageLayout layout;
          VkImageAspectFlags aspect;