zink: split out backing resource object create/destroy
authorMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Tue, 27 Oct 2020 15:59:33 +0000 (11:59 -0400)
committerMike Blumenkrantz <michael.blumenkrantz@gmail.com>
Tue, 16 Mar 2021 02:08:06 +0000 (22:08 -0400)
moving towards these being able to exist semi-independently...

Reviewed-by: Dave Airlie <airlied@redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/9544>

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

index 17ca72d..76168d0 100644 (file)
@@ -210,7 +210,7 @@ zink_batch_reference_resource_rw(struct zink_batch *batch, struct zink_resource
       }
    }
    /* multiple array entries are fine */
-   if (res->persistent_maps)
+   if (res->obj->persistent_maps)
       util_dynarray_append(&batch->persistent_resources, struct zink_resource*, res);
    /* the batch_uses value for this batch is guaranteed to not be in use now because
     * zink_reset_batch() waits on the fence and removes access before resetting
index d326c25..9da0961 100644 (file)
@@ -97,27 +97,39 @@ mem_equals(const void *a, const void *b)
 }
 
 static void
-cache_or_free_mem(struct zink_screen *screen, struct zink_resource *res)
+cache_or_free_mem(struct zink_screen *screen, struct zink_resource_object *obj)
 {
-   if (res->obj->mkey.flags) {
+   if (obj->mkey.flags) {
       simple_mtx_lock(&screen->mem_cache_mtx);
-      struct hash_entry *he = _mesa_hash_table_search_pre_hashed(screen->resource_mem_cache, res->obj->mem_hash, &res->obj->mkey);
+      struct hash_entry *he = _mesa_hash_table_search_pre_hashed(screen->resource_mem_cache, obj->mem_hash, &obj->mkey);
       struct util_dynarray *array = he ? (void*)he->data : NULL;
       if (!array) {
          struct mem_key *mkey = rzalloc(screen->resource_mem_cache, struct mem_key);
-         memcpy(mkey, &res->obj->mkey, sizeof(struct mem_key));
+         memcpy(mkey, &obj->mkey, sizeof(struct mem_key));
          array = rzalloc(screen->resource_mem_cache, struct util_dynarray);
          util_dynarray_init(array, screen->resource_mem_cache);
-         _mesa_hash_table_insert_pre_hashed(screen->resource_mem_cache, res->obj->mem_hash, mkey, array);
+         _mesa_hash_table_insert_pre_hashed(screen->resource_mem_cache, obj->mem_hash, mkey, array);
       }
       if (util_dynarray_num_elements(array, VkDeviceMemory) < 5) {
-         util_dynarray_append(array, VkDeviceMemory, res->obj->mem);
+         util_dynarray_append(array, VkDeviceMemory, obj->mem);
          simple_mtx_unlock(&screen->mem_cache_mtx);
          return;
       }
       simple_mtx_unlock(&screen->mem_cache_mtx);
    }
-   vkFreeMemory(screen->dev, res->obj->mem, NULL);
+   vkFreeMemory(screen->dev, obj->mem, NULL);
+}
+
+static void
+resource_object_destroy(struct zink_screen *screen, struct zink_resource_object *obj)
+{
+   if (obj->is_buffer)
+      vkDestroyBuffer(screen->dev, obj->buffer, NULL);
+   else
+      vkDestroyImage(screen->dev, obj->image, NULL);
+
+   cache_or_free_mem(screen, obj);
+   FREE(obj);
 }
 
 static void
@@ -126,16 +138,11 @@ zink_resource_destroy(struct pipe_screen *pscreen,
 {
    struct zink_screen *screen = zink_screen(pscreen);
    struct zink_resource *res = zink_resource(pres);
-   if (pres->target == PIPE_BUFFER) {
-      vkDestroyBuffer(screen->dev, res->obj->buffer, NULL);
+   if (pres->target == PIPE_BUFFER)
       util_range_destroy(&res->valid_buffer_range);
-   } else
-      vkDestroyImage(screen->dev, res->obj->image, NULL);
 
    zink_descriptor_set_refs_clear(&res->desc_set_refs, res);
-
-   cache_or_free_mem(screen, res);
-   FREE(res->obj);
+   resource_object_destroy(screen, res->obj);
    FREE(res);
 }
 
@@ -172,29 +179,16 @@ aspect_from_format(enum pipe_format fmt)
      return VK_IMAGE_ASPECT_COLOR_BIT;
 }
 
-static struct pipe_resource *
-resource_create(struct pipe_screen *pscreen,
-                const struct pipe_resource *templ,
-                struct winsys_handle *whandle,
-                unsigned external_usage)
+static struct zink_resource_object *
+resource_object_create(struct zink_screen *screen, const struct pipe_resource *templ, struct winsys_handle *whandle, bool *optimal_tiling)
 {
-   struct zink_screen *screen = zink_screen(pscreen);
-   struct zink_resource *res = CALLOC_STRUCT(zink_resource);
-
-   res->base = *templ;
-
-   pipe_reference_init(&res->base.reference, 1);
-   res->base.screen = pscreen;
-   res->obj = CALLOC_STRUCT(zink_resource_object);
-   if (!res->obj) {
-      FREE(res);
+   struct zink_resource_object *obj = CALLOC_STRUCT(zink_resource_object);
+   if (!obj)
       return NULL;
-   }
 
    VkMemoryRequirements reqs = {};
    VkMemoryPropertyFlags flags;
 
-   res->internal_format = templ->format;
    if (templ->target == PIPE_BUFFER) {
       VkBufferCreateInfo bci = {};
       bci.sType = VK_STRUCTURE_TYPE_BUFFER_CREATE_INFO;
@@ -248,19 +242,15 @@ resource_create(struct pipe_screen *pscreen,
                       VK_BUFFER_USAGE_TRANSFORM_FEEDBACK_BUFFER_BIT_EXT;
       }
 
-      if (vkCreateBuffer(screen->dev, &bci, NULL, &res->obj->buffer) !=
-          VK_SUCCESS) {
+      if (vkCreateBuffer(screen->dev, &bci, NULL, &obj->buffer) != VK_SUCCESS) {
          debug_printf("vkCreateBuffer failed\n");
-         FREE(res->obj);
-         FREE(res);
-         return NULL;
+         goto fail1;
       }
 
-      vkGetBufferMemoryRequirements(screen->dev, res->obj->buffer, &reqs);
+      vkGetBufferMemoryRequirements(screen->dev, obj->buffer, &reqs);
       flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
+      obj->is_buffer = true;
    } else {
-      res->format = zink_get_format(screen, templ->format);
-
       VkImageCreateInfo ici = {};
       VkExternalMemoryImageCreateInfo emici = {};
       ici.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
@@ -295,7 +285,7 @@ resource_create(struct pipe_screen *pscreen,
          unreachable("Unknown target");
       }
 
-      ici.format = res->format;
+      ici.format = zink_get_format(screen, templ->format);
       ici.extent.width = templ->width0;
       ici.extent.height = templ->height0;
       ici.extent.depth = templ->depth0;
@@ -336,6 +326,8 @@ resource_create(struct pipe_screen *pscreen,
              (ici.tiling == VK_IMAGE_TILING_OPTIMAL && props.optimalTilingFeatures & VK_FORMAT_FEATURE_STORAGE_IMAGE_BIT))
             ici.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
       }
+      if (optimal_tiling)
+         *optimal_tiling = ici.tiling != VK_IMAGE_TILING_LINEAR;
 
       if (templ->bind & PIPE_BIND_RENDER_TARGET)
          ici.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
@@ -351,7 +343,6 @@ resource_create(struct pipe_screen *pscreen,
 
       ici.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
       ici.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-      res->layout = VK_IMAGE_LAYOUT_UNDEFINED;
 
       struct wsi_image_create_info image_wsi_info = {
          VK_STRUCTURE_TYPE_WSI_IMAGE_CREATE_INFO_MESA,
@@ -362,18 +353,13 @@ resource_create(struct pipe_screen *pscreen,
       if (screen->needs_mesa_wsi && (templ->bind & PIPE_BIND_SCANOUT))
          ici.pNext = &image_wsi_info;
 
-      VkResult result = vkCreateImage(screen->dev, &ici, NULL, &res->obj->image);
+      VkResult result = vkCreateImage(screen->dev, &ici, NULL, &obj->image);
       if (result != VK_SUCCESS) {
          debug_printf("vkCreateImage failed\n");
-         FREE(res->obj);
-         FREE(res);
-         return NULL;
+         goto fail1;
       }
 
-      res->optimal_tiling = ici.tiling != VK_IMAGE_TILING_LINEAR;
-      res->aspect = aspect_from_format(templ->format);
-
-      vkGetImageMemoryRequirements(screen->dev, res->obj->image, &reqs);
+      vkGetImageMemoryRequirements(screen->dev, obj->image, &reqs);
       if (templ->usage == PIPE_USAGE_STAGING)
         flags = VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
       else
@@ -391,10 +377,10 @@ resource_create(struct pipe_screen *pscreen,
    if (templ->target != PIPE_BUFFER) {
       VkMemoryType mem_type =
          screen->info.mem_props.memoryTypes[mai.memoryTypeIndex];
-      res->obj->host_visible = mem_type.propertyFlags &
+      obj->host_visible = mem_type.propertyFlags &
                           VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT;
    } else
-      res->obj->host_visible = true;
+      obj->host_visible = true;
 
    VkExportMemoryAllocateInfo emai = {};
    if (templ->bind & PIPE_BIND_SHARED) {
@@ -432,33 +418,74 @@ resource_create(struct pipe_screen *pscreen,
    }
 
    if (!mai.pNext && !(templ->flags & PIPE_RESOURCE_FLAG_MAP_COHERENT)) {
-      res->obj->mkey.reqs = reqs;
-      res->obj->mkey.flags = flags;
-      res->obj->mem_hash = mem_hash(&res->obj->mkey);
+      obj->mkey.reqs = reqs;
+      obj->mkey.flags = flags;
+      obj->mem_hash = mem_hash(&obj->mkey);
       simple_mtx_lock(&screen->mem_cache_mtx);
 
-      struct hash_entry *he = _mesa_hash_table_search_pre_hashed(screen->resource_mem_cache, res->obj->mem_hash, &res->obj->mkey);
+      struct hash_entry *he = _mesa_hash_table_search_pre_hashed(screen->resource_mem_cache, obj->mem_hash, &obj->mkey);
 
       struct util_dynarray *array = he ? (void*)he->data : NULL;
       if (array && util_dynarray_num_elements(array, VkDeviceMemory)) {
-         res->obj->mem = util_dynarray_pop(array, VkDeviceMemory);
+         obj->mem = util_dynarray_pop(array, VkDeviceMemory);
       }
       simple_mtx_unlock(&screen->mem_cache_mtx);
    }
 
-   if (!res->obj->mem && vkAllocateMemory(screen->dev, &mai, NULL, &res->obj->mem) != VK_SUCCESS) {
+   if (!obj->mem && vkAllocateMemory(screen->dev, &mai, NULL, &obj->mem) != VK_SUCCESS) {
       debug_printf("vkAllocateMemory failed\n");
-      goto fail;
+      goto fail2;
    }
 
-   res->obj->offset = 0;
-   res->obj->size = reqs.size;
+   obj->offset = 0;
+   obj->size = reqs.size;
+
+   if (templ->target == PIPE_BUFFER)
+      vkBindBufferMemory(screen->dev, obj->buffer, obj->mem, obj->offset);
+   else
+      vkBindImageMemory(screen->dev, obj->image, obj->mem, obj->offset);
+   return obj;
+
+fail2:
+   if (templ->target == PIPE_BUFFER)
+      vkDestroyBuffer(screen->dev, obj->buffer, NULL);
+   else
+      vkDestroyImage(screen->dev, obj->image, NULL);
+fail1:
+   FREE(obj);
+   return NULL;
+}
+
+static struct pipe_resource *
+resource_create(struct pipe_screen *pscreen,
+                const struct pipe_resource *templ,
+                struct winsys_handle *whandle,
+                unsigned external_usage)
+{
+   struct zink_screen *screen = zink_screen(pscreen);
+   struct zink_resource *res = CALLOC_STRUCT(zink_resource);
+
+   res->base = *templ;
+
+   pipe_reference_init(&res->base.reference, 1);
+   res->base.screen = pscreen;
 
+   bool optimal_tiling = false;
+   res->obj = resource_object_create(screen, templ, whandle, &optimal_tiling);
+   if (!res->obj) {
+      FREE(res);
+      return NULL;
+   }
+
+   res->internal_format = templ->format;
    if (templ->target == PIPE_BUFFER) {
-      vkBindBufferMemory(screen->dev, res->obj->buffer, res->obj->mem, res->obj->offset);
       util_range_init(&res->valid_buffer_range);
-   } else
-      vkBindImageMemory(screen->dev, res->obj->image, res->obj->mem, res->obj->offset);
+   } else {
+      res->format = zink_get_format(screen, templ->format);
+      res->layout = VK_IMAGE_LAYOUT_UNDEFINED;
+      res->optimal_tiling = optimal_tiling;
+      res->aspect = aspect_from_format(templ->format);
+   }
 
    if (screen->winsys && (templ->bind & PIPE_BIND_DISPLAY_TARGET)) {
       struct sw_winsys *winsys = screen->winsys;
@@ -473,16 +500,6 @@ resource_create(struct pipe_screen *pscreen,
 
    util_dynarray_init(&res->desc_set_refs.refs, NULL);
    return &res->base;
-
-fail:
-   if (templ->target == PIPE_BUFFER)
-      vkDestroyBuffer(screen->dev, res->obj->buffer, NULL);
-   else
-      vkDestroyImage(screen->dev, res->obj->image, NULL);
-   FREE(res->obj);
-   FREE(res);
-
-   return NULL;
 }
 
 static struct pipe_resource *
@@ -740,7 +757,7 @@ zink_transfer_map(struct pipe_context *pctx,
       }
    }
    if ((usage & PIPE_MAP_PERSISTENT) && !(usage & PIPE_MAP_COHERENT))
-      res->persistent_maps++;
+      res->obj->persistent_maps++;
 
    *transfer = &trans->base;
    return ptr;
@@ -788,7 +805,7 @@ zink_transfer_unmap(struct pipe_context *pctx,
    } else
       vkUnmapMemory(screen->dev, res->obj->mem);
    if ((trans->base.usage & PIPE_MAP_PERSISTENT) && !(trans->base.usage & PIPE_MAP_COHERENT))
-      res->persistent_maps--;
+      res->obj->persistent_maps--;
    if (!(trans->base.usage & (PIPE_MAP_FLUSH_EXPLICIT | PIPE_MAP_COHERENT))) {
       zink_transfer_flush_region(pctx, ptrans, &ptrans->box);
    }
index cad908d..85b4ff8 100644 (file)
@@ -56,6 +56,8 @@ struct zink_resource_object {
    struct mem_key mkey;
    VkDeviceSize offset, size;
 
+   unsigned persistent_maps; //if nonzero, requires vkFlushMappedMemoryRanges during batch use
+   bool is_buffer;
    bool host_visible;
 };
 
@@ -80,7 +82,6 @@ struct zink_resource {
 
    struct sw_displaytarget *dt;
    unsigned dt_stride;
-   unsigned persistent_maps; //if nonzero, requires vkFlushMappedMemoryRanges during batch use
 
    struct zink_descriptor_refs desc_set_refs;