[PATCH 2/2] wined3d: Introduce struct wined3d_image_vk and its create/destroy helpers.

Jan Sikorski jsikorski at codeweavers.com
Tue Mar 23 06:57:50 CDT 2021


Signed-off-by: Jan Sikorski <jsikorski at codeweavers.com>
---
 dlls/wined3d/context_vk.c      |  97 +++++++++++++++++++++
 dlls/wined3d/device.c          |  95 ++++-----------------
 dlls/wined3d/swapchain.c       |  26 ++----
 dlls/wined3d/texture.c         | 150 +++++++++------------------------
 dlls/wined3d/view.c            |  18 ++--
 dlls/wined3d/wined3d_private.h |  42 +++++----
 6 files changed, 195 insertions(+), 233 deletions(-)

diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c
index 88a20f979ed..3216f1fbd92 100644
--- a/dlls/wined3d/context_vk.c
+++ b/dlls/wined3d/context_vk.c
@@ -501,6 +501,89 @@ BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDevic
     return TRUE;
 }
 
+BOOL wined3d_context_vk_create_image(struct wined3d_context_vk *context_vk, VkImageType vk_image_type,
+        VkImageUsageFlags usage, VkFormat vk_format, unsigned int width, unsigned int height, unsigned int depth,
+        unsigned int sample_count, unsigned int mip_levels, unsigned int layer_count, unsigned int flags,
+        struct wined3d_image_vk *image)
+{
+    struct wined3d_adapter_vk *adapter_vk = wined3d_adapter_vk(context_vk->c.device->adapter);
+    struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
+    const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+    VkMemoryRequirements memory_requirements;
+    VkImageCreateInfo create_info;
+    unsigned int memory_type_idx;
+    VkResult vr;
+
+    create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
+    create_info.pNext = NULL;
+    create_info.flags = flags;
+    create_info.imageType = vk_image_type;
+    create_info.format = vk_format;
+    create_info.extent.width = width;
+    create_info.extent.height = height;
+    create_info.extent.depth = depth;
+    create_info.mipLevels = mip_levels;
+    create_info.arrayLayers = layer_count;
+    create_info.samples = sample_count;
+    create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
+    create_info.usage = usage;
+    create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
+    create_info.queueFamilyIndexCount = 0;
+    create_info.pQueueFamilyIndices = NULL;
+    create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
+
+    image->command_buffer_id = 0;
+
+    vr = VK_CALL(vkCreateImage(device_vk->vk_device, &create_info, NULL, &image->vk_image));
+    if (vr != VK_SUCCESS)
+    {
+        ERR("Failed to create image, vr %#x.\n", vr);
+        image->vk_image = VK_NULL_HANDLE;
+        return FALSE;
+    }
+
+    VK_CALL(vkGetImageMemoryRequirements(device_vk->vk_device, image->vk_image,
+            &memory_requirements));
+
+    memory_type_idx = wined3d_adapter_vk_get_memory_type_index(adapter_vk,
+            memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
+    if (memory_type_idx == ~0u)
+    {
+        ERR("Failed to find suitable image memory type.\n");
+        VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
+        image->vk_image = VK_NULL_HANDLE;
+        return FALSE;
+    }
+
+    image->memory = wined3d_context_vk_allocate_memory(context_vk, memory_type_idx,
+            memory_requirements.size, &image->vk_memory);
+    if (!image->vk_memory)
+    {
+        ERR("Failed to allocate image memory.\n");
+        VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
+        image->vk_image = VK_NULL_HANDLE;
+        return FALSE;
+    }
+
+    vr = VK_CALL(vkBindImageMemory(device_vk->vk_device, image->vk_image, image->vk_memory,
+            image->memory ? image->memory->offset : 0));
+    if (vr != VK_SUCCESS)
+    {
+        VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
+        if (image->memory)
+            wined3d_allocator_block_free(image->memory);
+        else
+            VK_CALL(vkFreeMemory(device_vk->vk_device, image->vk_memory, NULL));
+        ERR("Failed to bind image memory, vr %#x.\n", vr);
+        image->memory = NULL;
+        image->vk_memory = VK_NULL_HANDLE;
+        image->vk_image = VK_NULL_HANDLE;
+        return FALSE;
+    }
+
+    return TRUE;
+}
+
 static struct wined3d_retired_object_vk *wined3d_context_vk_get_retired_object_vk(struct wined3d_context_vk *context_vk)
 {
     struct wined3d_retired_objects_vk *retired = &context_vk->retired;
@@ -793,6 +876,20 @@ void wined3d_context_vk_destroy_vk_sampler(struct wined3d_context_vk *context_vk
     o->command_buffer_id = command_buffer_id;
 }
 
+void wined3d_context_vk_destroy_image(struct wined3d_context_vk *context_vk, struct wined3d_image_vk *image)
+{
+    wined3d_context_vk_destroy_vk_image(context_vk, image->vk_image, image->command_buffer_id);
+    if (image->memory)
+        wined3d_context_vk_destroy_allocator_block(context_vk, image->memory,
+                image->command_buffer_id);
+    else
+        wined3d_context_vk_destroy_vk_memory(context_vk, image->vk_memory, image->command_buffer_id);
+
+    image->vk_image = VK_NULL_HANDLE;
+    image->vk_memory = VK_NULL_HANDLE;
+    image->memory = NULL;
+}
+
 void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk, const struct wined3d_bo_vk *bo)
 {
     struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
diff --git a/dlls/wined3d/device.c b/dlls/wined3d/device.c
index bbf1bada7b6..9d70eb62eaa 100644
--- a/dlls/wined3d/device.c
+++ b/dlls/wined3d/device.c
@@ -581,27 +581,12 @@ void wined3d_device_destroy_default_samplers(struct wined3d_device *device, stru
     device->null_sampler = NULL;
 }
 
-static void wined3d_null_image_vk_cleanup(struct wined3d_null_image_vk *image,
-        struct wined3d_context_vk *context_vk, uint64_t command_buffer_id)
-{
-    wined3d_context_vk_destroy_vk_image(context_vk, image->vk_image, command_buffer_id);
-    if (image->memory)
-        wined3d_context_vk_destroy_allocator_block(context_vk, image->memory, command_buffer_id);
-    else
-        wined3d_context_vk_destroy_vk_memory(context_vk, image->vk_memory, command_buffer_id);
-}
-
-static bool wined3d_null_image_vk_init(struct wined3d_null_image_vk *image, struct wined3d_context_vk *context_vk,
+static bool wined3d_null_image_vk_init(struct wined3d_image_vk *image, struct wined3d_context_vk *context_vk,
         VkCommandBuffer vk_command_buffer, VkImageType type, unsigned int layer_count, unsigned int sample_count)
 {
-    struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
     const struct wined3d_vk_info *vk_info = context_vk->vk_info;
-    VkMemoryRequirements memory_requirements;
     VkImageSubresourceRange range;
-    VkImageCreateInfo image_desc;
-    unsigned int memory_type_idx;
     uint32_t flags = 0;
-    VkResult vr;
 
     static const VkClearColorValue colour = {{0}};
 
@@ -611,63 +596,14 @@ static bool wined3d_null_image_vk_init(struct wined3d_null_image_vk *image, stru
     if (type == VK_IMAGE_TYPE_2D && layer_count >= 6)
         flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
 
-    image_desc.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
-    image_desc.pNext = NULL;
-    image_desc.flags = flags;
-    image_desc.imageType = type;
-    image_desc.format = VK_FORMAT_R8G8B8A8_UNORM;
-    image_desc.extent.width = 1;
-    image_desc.extent.height = 1;
-    image_desc.extent.depth = 1;
-    image_desc.mipLevels = 1;
-    image_desc.arrayLayers = layer_count;
-    image_desc.samples = sample_count;
-    image_desc.tiling = VK_IMAGE_TILING_OPTIMAL;
-    image_desc.usage = VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT;
-    image_desc.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-    image_desc.queueFamilyIndexCount = 0;
-    image_desc.pQueueFamilyIndices = NULL;
-    image_desc.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-    if ((vr = VK_CALL(vkCreateImage(device_vk->vk_device, &image_desc, NULL, &image->vk_image))) < 0)
-    {
-        ERR("Failed to create Vulkan image, vr %s.\n", wined3d_debug_vkresult(vr));
-        return false;
-    }
-
-    VK_CALL(vkGetImageMemoryRequirements(device_vk->vk_device, image->vk_image, &memory_requirements));
-
-    memory_type_idx = wined3d_adapter_vk_get_memory_type_index(wined3d_adapter_vk(device_vk->d.adapter),
-            memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
-    if (memory_type_idx == ~0u)
+    if (!wined3d_context_vk_create_image(context_vk, type,
+            VK_IMAGE_USAGE_TRANSFER_DST_BIT | VK_IMAGE_USAGE_SAMPLED_BIT, VK_FORMAT_R8G8B8A8_UNORM,
+            1, 1, 1, sample_count, 1, layer_count, flags, image))
     {
-        ERR("Failed to find suitable image memory type.\n");
-        VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
-        image->vk_image = VK_NULL_HANDLE;
         return false;
     }
 
-    image->memory = wined3d_context_vk_allocate_memory(context_vk,
-            memory_type_idx, memory_requirements.size, &image->vk_memory);
-    if (!image->vk_memory)
-    {
-        ERR("Failed to allocate image memory.\n");
-        VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
-        image->vk_image = VK_NULL_HANDLE;
-        return false;
-    }
-
-    if ((vr = VK_CALL(vkBindImageMemory(device_vk->vk_device, image->vk_image,
-            image->vk_memory, image->memory ? image->memory->offset : 0))) < 0)
-    {
-        ERR("Failed to bind image memory, vr %s.\n", wined3d_debug_vkresult(vr));
-        if (image->memory)
-            wined3d_allocator_block_free(image->memory);
-        else
-            VK_CALL(vkFreeMemory(device_vk->vk_device, image->vk_memory, NULL));
-        VK_CALL(vkDestroyImage(device_vk->vk_device, image->vk_image, NULL));
-        image->vk_image = VK_NULL_HANDLE;
-        return false;
-    }
+    wined3d_context_vk_reference_image(context_vk, image);
 
     range.aspectMask = VK_IMAGE_ASPECT_COLOR_BIT;
     range.baseMipLevel = 0;
@@ -702,7 +638,6 @@ bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk
     VkCommandBuffer vk_command_buffer;
     unsigned int sample_count = 2;
     VkBufferUsageFlags usage;
-    uint64_t id;
 
     format = wined3d_get_format(device_vk->d.adapter, WINED3DFMT_R8G8B8A8_UNORM, WINED3D_BIND_SHADER_RESOURCE);
     while (sample_count && !(sample_count & format->multisample_types))
@@ -753,13 +688,12 @@ bool wined3d_device_vk_create_null_resources(struct wined3d_device_vk *device_vk
     return true;
 
 fail:
-    id = context_vk->current_command_buffer.id;
     if (r->image_2dms.vk_image)
-        wined3d_null_image_vk_cleanup(&r->image_2dms, context_vk, id);
+        wined3d_context_vk_destroy_image(context_vk, &r->image_2dms);
     if (r->image_2d.vk_image)
-        wined3d_null_image_vk_cleanup(&r->image_2d, context_vk, id);
+        wined3d_context_vk_destroy_image(context_vk, &r->image_2d);
     if (r->image_1d.vk_image)
-        wined3d_null_image_vk_cleanup(&r->image_1d, context_vk, id);
+        wined3d_context_vk_destroy_image(context_vk, &r->image_1d);
     wined3d_context_vk_reference_bo(context_vk, &r->bo);
     wined3d_context_vk_destroy_bo(context_vk, &r->bo);
     return false;
@@ -769,14 +703,17 @@ void wined3d_device_vk_destroy_null_resources(struct wined3d_device_vk *device_v
         struct wined3d_context_vk *context_vk)
 {
     struct wined3d_null_resources_vk *r = &device_vk->null_resources_vk;
-    uint64_t id = context_vk->current_command_buffer.id;
 
     /* We don't track command buffer references to NULL resources. We easily
      * could, but it doesn't seem worth it. */
-    wined3d_null_image_vk_cleanup(&r->image_3d, context_vk, id);
-    wined3d_null_image_vk_cleanup(&r->image_2dms, context_vk, id);
-    wined3d_null_image_vk_cleanup(&r->image_2d, context_vk, id);
-    wined3d_null_image_vk_cleanup(&r->image_1d, context_vk, id);
+    wined3d_context_vk_reference_image(context_vk, &r->image_3d);
+    wined3d_context_vk_destroy_image(context_vk, &r->image_3d);
+    wined3d_context_vk_reference_image(context_vk, &r->image_2dms);
+    wined3d_context_vk_destroy_image(context_vk, &r->image_2dms);
+    wined3d_context_vk_reference_image(context_vk, &r->image_2d);
+    wined3d_context_vk_destroy_image(context_vk, &r->image_2d);
+    wined3d_context_vk_reference_image(context_vk, &r->image_1d);
+    wined3d_context_vk_destroy_image(context_vk, &r->image_1d);
     wined3d_context_vk_reference_bo(context_vk, &r->bo);
     wined3d_context_vk_destroy_bo(context_vk, &r->bo);
 }
diff --git a/dlls/wined3d/swapchain.c b/dlls/wined3d/swapchain.c
index 7210d5352dd..8f365c88c15 100644
--- a/dlls/wined3d/swapchain.c
+++ b/dlls/wined3d/swapchain.c
@@ -1092,7 +1092,7 @@ static VkResult wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain
             vk_access_mask_from_bind_flags(back_buffer_vk->t.resource.bind_flags),
             VK_ACCESS_TRANSFER_READ_BIT,
             back_buffer_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-            back_buffer_vk->vk_image, &vk_range);
+            back_buffer_vk->image.vk_image, &vk_range);
 
     wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
             VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
@@ -1118,7 +1118,7 @@ static VkResult wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain
     blit.dstOffsets[1].y = dst_rect->bottom;
     blit.dstOffsets[1].z = 1;
     VK_CALL(vkCmdBlitImage(vk_command_buffer,
-            back_buffer_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+            back_buffer_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
             swapchain_vk->vk_images[image_idx], VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
             1, &blit, filter));
 
@@ -1138,7 +1138,7 @@ static VkResult wined3d_swapchain_vk_blit(struct wined3d_swapchain_vk *swapchain
             VK_ACCESS_TRANSFER_READ_BIT,
             vk_access_mask_from_bind_flags(back_buffer_vk->t.resource.bind_flags),
             vk_layout, back_buffer_vk->layout,
-            back_buffer_vk->vk_image, &vk_range);
+            back_buffer_vk->image.vk_image, &vk_range);
     back_buffer_vk->bind_mask = 0;
 
     swapchain_vk->vk_semaphores[present_idx].command_buffer_id = context_vk->current_command_buffer.id;
@@ -1161,14 +1161,11 @@ static void wined3d_swapchain_vk_rotate(struct wined3d_swapchain *swapchain, str
 {
     struct wined3d_texture_sub_resource *sub_resource;
     struct wined3d_texture_vk *texture, *texture_prev;
-    struct wined3d_allocator_block *memory0;
+    struct wined3d_image_vk image0;
     VkDescriptorImageInfo vk_info0;
-    VkDeviceMemory vk_memory0;
     VkImageLayout vk_layout0;
-    VkImage vk_image0;
     DWORD locations0;
     unsigned int i;
-    uint64_t id0;
 
     static const DWORD supported_locations = WINED3D_LOCATION_TEXTURE_RGB | WINED3D_LOCATION_RB_MULTISAMPLE;
 
@@ -1178,11 +1175,8 @@ static void wined3d_swapchain_vk_rotate(struct wined3d_swapchain *swapchain, str
     texture_prev = wined3d_texture_vk(swapchain->back_buffers[0]);
 
     /* Back buffer 0 is already in the draw binding. */
-    vk_image0 = texture_prev->vk_image;
-    memory0 = texture_prev->memory;
-    vk_memory0 = texture_prev->vk_memory;
+    image0 = texture_prev->image;
     vk_layout0 = texture_prev->layout;
-    id0 = texture_prev->command_buffer_id;
     vk_info0 = texture_prev->default_image_info;
     locations0 = texture_prev->t.sub_resources[0].locations;
 
@@ -1194,11 +1188,8 @@ static void wined3d_swapchain_vk_rotate(struct wined3d_swapchain *swapchain, str
         if (!(sub_resource->locations & supported_locations))
             wined3d_texture_load_location(&texture->t, 0, &context_vk->c, texture->t.resource.draw_binding);
 
-        texture_prev->vk_image = texture->vk_image;
-        texture_prev->memory = texture->memory;
-        texture_prev->vk_memory = texture->vk_memory;
+        texture_prev->image = texture->image;
         texture_prev->layout = texture->layout;
-        texture_prev->command_buffer_id = texture->command_buffer_id;
         texture_prev->default_image_info = texture->default_image_info;
 
         wined3d_texture_validate_location(&texture_prev->t, 0, sub_resource->locations & supported_locations);
@@ -1207,11 +1198,8 @@ static void wined3d_swapchain_vk_rotate(struct wined3d_swapchain *swapchain, str
         texture_prev = texture;
     }
 
-    texture_prev->vk_image = vk_image0;
-    texture_prev->memory = memory0;
-    texture_prev->vk_memory = vk_memory0;
+    texture_prev->image = image0;
     texture_prev->layout = vk_layout0;
-    texture_prev->command_buffer_id = id0;
     texture_prev->default_image_info = vk_info0;
 
     wined3d_texture_validate_location(&texture_prev->t, 0, locations0 & supported_locations);
diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 0b64cc3f03d..752b6b4cf9b 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -4544,7 +4544,7 @@ const VkDescriptorImageInfo *wined3d_texture_vk_get_default_image_info(struct wi
     create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
     create_info.pNext = NULL;
     create_info.flags = 0;
-    create_info.image = texture_vk->vk_image;
+    create_info.image = texture_vk->image.vk_image;
     create_info.viewType = vk_image_view_type_from_wined3d(texture_vk->t.resource.type, flags);
     create_info.format = format_vk->vk_format;
     fixup = format_vk->f.color_fixup;
@@ -4696,7 +4696,7 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context,
             vk_access_mask_from_bind_flags(dst_texture_vk->t.resource.bind_flags),
             VK_ACCESS_TRANSFER_WRITE_BIT,
             dst_texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-            dst_texture_vk->vk_image, &vk_range);
+            dst_texture_vk->image.vk_image, &vk_range);
 
     region.bufferOffset = staging_bo.buffer_offset;
     region.bufferRowLength = (dst_row_pitch / src_format->block_byte_count) * src_format->block_width;
@@ -4716,14 +4716,14 @@ static void wined3d_texture_vk_upload_data(struct wined3d_context *context,
     region.imageExtent.depth = src_box->back - src_box->front;
 
     VK_CALL(vkCmdCopyBufferToImage(vk_command_buffer, staging_bo.vk_buffer,
-            dst_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region));
+            dst_texture_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region));
 
     wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
             VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
             VK_ACCESS_TRANSFER_WRITE_BIT,
             vk_access_mask_from_bind_flags(dst_texture_vk->t.resource.bind_flags),
             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_texture_vk->layout,
-            dst_texture_vk->vk_image, &vk_range);
+            dst_texture_vk->image.vk_image, &vk_range);
     wined3d_context_vk_reference_texture(context_vk, dst_texture_vk);
     wined3d_context_vk_reference_bo(context_vk, &staging_bo);
     wined3d_context_vk_destroy_bo(context_vk, &staging_bo);
@@ -4837,7 +4837,7 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
             vk_access_mask_from_bind_flags(src_texture_vk->t.resource.bind_flags),
             VK_ACCESS_TRANSFER_READ_BIT,
             src_texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-            src_texture_vk->vk_image, &vk_range);
+            src_texture_vk->image.vk_image, &vk_range);
 
     region.bufferOffset = staging_bo.buffer_offset;
     region.bufferRowLength = 0;
@@ -4853,7 +4853,7 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
     region.imageExtent.height = src_height;
     region.imageExtent.depth = src_depth;
 
-    VK_CALL(vkCmdCopyImageToBuffer(vk_command_buffer, src_texture_vk->vk_image,
+    VK_CALL(vkCmdCopyImageToBuffer(vk_command_buffer, src_texture_vk->image.vk_image,
             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, staging_bo.vk_buffer, 1, &region));
 
     wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
@@ -4861,12 +4861,12 @@ static void wined3d_texture_vk_download_data(struct wined3d_context *context,
             VK_ACCESS_TRANSFER_READ_BIT,
             vk_access_mask_from_bind_flags(src_texture_vk->t.resource.bind_flags),
             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,  src_texture_vk->layout,
-            src_texture_vk->vk_image, &vk_range);
+            src_texture_vk->image.vk_image, &vk_range);
 
     wined3d_context_vk_reference_texture(context_vk, src_texture_vk);
     wined3d_context_vk_reference_bo(context_vk, &staging_bo);
     wined3d_context_vk_submit_command_buffer(context_vk, 0, NULL, NULL, 0, NULL);
-    wined3d_context_vk_wait_command_buffer(context_vk, src_texture_vk->command_buffer_id);
+    wined3d_context_vk_wait_command_buffer(context_vk, src_texture_vk->image.command_buffer_id);
 
     staging_bo_addr.buffer_object = (uintptr_t)&staging_bo;
     staging_bo_addr.addr = (uint8_t *)NULL;
@@ -4941,16 +4941,12 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk,
         struct wined3d_context_vk *context_vk)
 {
     const struct wined3d_format_vk *format_vk;
-    VkMemoryRequirements memory_requirements;
-    const struct wined3d_vk_info *vk_info;
-    struct wined3d_adapter_vk *adapter_vk;
-    struct wined3d_device_vk *device_vk;
     struct wined3d_resource *resource;
     VkCommandBuffer vk_command_buffer;
     VkImageSubresourceRange vk_range;
-    VkImageCreateInfo create_info;
-    unsigned int memory_type_idx;
-    VkResult vr;
+    VkImageUsageFlags vk_usage;
+    VkImageType vk_image_type;
+    unsigned int flags = 0;
 
     if (texture_vk->t.flags & WINED3D_TEXTURE_RGB_ALLOCATED)
         return TRUE;
@@ -4962,57 +4958,41 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk,
     }
 
     resource = &texture_vk->t.resource;
-    device_vk = wined3d_device_vk(resource->device);
-    adapter_vk = wined3d_adapter_vk(device_vk->d.adapter);
     format_vk = wined3d_format_vk(resource->format);
-    vk_info = context_vk->vk_info;
 
-    create_info.sType = VK_STRUCTURE_TYPE_IMAGE_CREATE_INFO;
-    create_info.pNext = NULL;
-
-    create_info.flags = 0;
     if (wined3d_format_is_typeless(&format_vk->f) || texture_vk->t.swapchain)
-        create_info.flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
+        flags |= VK_IMAGE_CREATE_MUTABLE_FORMAT_BIT;
 
     switch (resource->type)
     {
         case WINED3D_RTYPE_TEXTURE_1D:
-            create_info.imageType = VK_IMAGE_TYPE_1D;
+            vk_image_type = VK_IMAGE_TYPE_1D;
             break;
         case WINED3D_RTYPE_TEXTURE_2D:
-            create_info.imageType = VK_IMAGE_TYPE_2D;
+            vk_image_type = VK_IMAGE_TYPE_2D;
             if (texture_vk->t.layer_count >= 6 && resource->width == resource->height)
-                create_info.flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
+                flags |= VK_IMAGE_CREATE_CUBE_COMPATIBLE_BIT;
             break;
         case WINED3D_RTYPE_TEXTURE_3D:
-            create_info.imageType = VK_IMAGE_TYPE_3D;
+            vk_image_type = VK_IMAGE_TYPE_3D;
             if (resource->bind_flags & (WINED3D_BIND_RENDER_TARGET | WINED3D_BIND_UNORDERED_ACCESS))
-                create_info.flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
+                flags |= VK_IMAGE_CREATE_2D_ARRAY_COMPATIBLE_BIT;
             break;
         default:
             ERR("Invalid resource type %s.\n", debug_d3dresourcetype(resource->type));
-            create_info.imageType = VK_IMAGE_TYPE_2D;
+            vk_image_type = VK_IMAGE_TYPE_2D;
             break;
     }
 
-    create_info.format = format_vk->vk_format;
-    create_info.extent.width = resource->width;
-    create_info.extent.height = resource->height;
-    create_info.extent.depth = resource->depth;
-    create_info.mipLevels = texture_vk->t.level_count;
-    create_info.arrayLayers = texture_vk->t.layer_count;
-    create_info.samples = max(1, wined3d_resource_get_sample_count(resource));
-    create_info.tiling = VK_IMAGE_TILING_OPTIMAL;
-
-    create_info.usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
+    vk_usage = VK_IMAGE_USAGE_TRANSFER_SRC_BIT | VK_IMAGE_USAGE_TRANSFER_DST_BIT;
     if (resource->bind_flags & WINED3D_BIND_SHADER_RESOURCE)
-        create_info.usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
+        vk_usage |= VK_IMAGE_USAGE_SAMPLED_BIT;
     if (resource->bind_flags & WINED3D_BIND_RENDER_TARGET)
-        create_info.usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
+        vk_usage |= VK_IMAGE_USAGE_COLOR_ATTACHMENT_BIT;
     if (resource->bind_flags & WINED3D_BIND_DEPTH_STENCIL)
-        create_info.usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
+        vk_usage |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
     if (resource->bind_flags & WINED3D_BIND_UNORDERED_ACCESS)
-        create_info.usage |= VK_IMAGE_USAGE_STORAGE_BIT;
+        vk_usage |= VK_IMAGE_USAGE_STORAGE_BIT;
 
     texture_vk->layout = VK_IMAGE_LAYOUT_GENERAL;
     if (wined3d_popcount(resource->bind_flags == 1))
@@ -5036,49 +5016,10 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk,
         }
     }
 
-    create_info.sharingMode = VK_SHARING_MODE_EXCLUSIVE;
-    create_info.queueFamilyIndexCount = 0;
-    create_info.pQueueFamilyIndices = NULL;
-    create_info.initialLayout = VK_IMAGE_LAYOUT_UNDEFINED;
-    if ((vr = VK_CALL(vkCreateImage(device_vk->vk_device, &create_info, NULL, &texture_vk->vk_image))) < 0)
-    {
-        ERR("Failed to create Vulkan image, vr %s.\n", wined3d_debug_vkresult(vr));
-        return FALSE;
-    }
-
-    VK_CALL(vkGetImageMemoryRequirements(device_vk->vk_device, texture_vk->vk_image, &memory_requirements));
-
-    memory_type_idx = wined3d_adapter_vk_get_memory_type_index(adapter_vk,
-            memory_requirements.memoryTypeBits, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT);
-    if (memory_type_idx == ~0u)
+    if (!wined3d_context_vk_create_image(context_vk, vk_image_type, vk_usage, format_vk->vk_format,
+            resource->width, resource->height, resource->depth, max(1, wined3d_resource_get_sample_count(resource)),
+            texture_vk->t.level_count, texture_vk->t.layer_count, flags, &texture_vk->image))
     {
-        ERR("Failed to find suitable memory type.\n");
-        VK_CALL(vkDestroyImage(device_vk->vk_device, texture_vk->vk_image, NULL));
-        texture_vk->vk_image = VK_NULL_HANDLE;
-        return FALSE;
-    }
-
-    texture_vk->memory = wined3d_context_vk_allocate_memory(context_vk,
-            memory_type_idx, memory_requirements.size, &texture_vk->vk_memory);
-    if (!texture_vk->vk_memory)
-    {
-        ERR("Failed to allocate image memory.\n");
-        VK_CALL(vkDestroyImage(device_vk->vk_device, texture_vk->vk_image, NULL));
-        texture_vk->vk_image = VK_NULL_HANDLE;
-        return FALSE;
-    }
-
-    if ((vr = VK_CALL(vkBindImageMemory(device_vk->vk_device, texture_vk->vk_image,
-            texture_vk->vk_memory, texture_vk->memory ? texture_vk->memory->offset : 0))) < 0)
-    {
-        WARN("Failed to bind memory, vr %s.\n", wined3d_debug_vkresult(vr));
-        if (texture_vk->memory)
-            wined3d_allocator_block_free(texture_vk->memory);
-        else
-            VK_CALL(vkFreeMemory(device_vk->vk_device, texture_vk->vk_memory, NULL));
-        texture_vk->vk_memory = VK_NULL_HANDLE;
-        VK_CALL(vkDestroyImage(device_vk->vk_device, texture_vk->vk_image, NULL));
-        texture_vk->vk_image = VK_NULL_HANDLE;
         return FALSE;
     }
 
@@ -5093,12 +5034,12 @@ BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk,
             VK_PIPELINE_STAGE_TOP_OF_PIPE_BIT, VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
             0, 0,
             VK_IMAGE_LAYOUT_UNDEFINED, texture_vk->layout,
-            texture_vk->vk_image, &vk_range);
+            texture_vk->image.vk_image, &vk_range);
 
     texture_vk->t.flags |= WINED3D_TEXTURE_RGB_ALLOCATED;
 
     TRACE("Created image 0x%s, memory 0x%s for texture %p.\n",
-            wine_dbgstr_longlong(texture_vk->vk_image), wine_dbgstr_longlong(texture_vk->vk_memory), texture_vk);
+            wine_dbgstr_longlong(texture_vk->image.vk_image), wine_dbgstr_longlong(texture_vk->image.vk_memory), texture_vk);
 
     return TRUE;
 }
@@ -5155,23 +5096,12 @@ static void wined3d_texture_vk_unload_location(struct wined3d_texture *texture,
             if (texture_vk->default_image_info.imageView)
             {
                 wined3d_context_vk_destroy_vk_image_view(context_vk,
-                        texture_vk->default_image_info.imageView, texture_vk->command_buffer_id);
+                        texture_vk->default_image_info.imageView, texture_vk->image.command_buffer_id);
                 texture_vk->default_image_info.imageView = VK_NULL_HANDLE;
             }
 
-            if (texture_vk->vk_image)
-            {
-                wined3d_context_vk_destroy_vk_image(context_vk, texture_vk->vk_image, texture_vk->command_buffer_id);
-                texture_vk->vk_image = VK_NULL_HANDLE;
-                if (texture_vk->memory)
-                    wined3d_context_vk_destroy_allocator_block(context_vk,
-                            texture_vk->memory, texture_vk->command_buffer_id);
-                else
-                    wined3d_context_vk_destroy_vk_memory(context_vk,
-                            texture_vk->vk_memory, texture_vk->command_buffer_id);
-                texture_vk->vk_memory = VK_NULL_HANDLE;
-                texture_vk->memory = NULL;
-            }
+            if (texture_vk->image.vk_image)
+                wined3d_context_vk_destroy_image(context_vk, &texture_vk->image);
             break;
 
         case WINED3D_LOCATION_BUFFER:
@@ -5231,7 +5161,7 @@ void wined3d_texture_vk_barrier(struct wined3d_texture_vk *texture_vk,
                 vk_pipeline_stage_mask_from_bind_flags(texture_vk->bind_mask),
                 vk_pipeline_stage_mask_from_bind_flags(bind_mask),
                 vk_access_mask_from_bind_flags(texture_vk->bind_mask), vk_access_mask_from_bind_flags(bind_mask),
-                texture_vk->layout, texture_vk->layout, texture_vk->vk_image, &vk_range);
+                texture_vk->layout, texture_vk->layout, texture_vk->image.vk_image, &vk_range);
     }
     texture_vk->bind_mask = bind_mask;
 }
@@ -6541,13 +6471,13 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_
             vk_access_mask_from_bind_flags(src_texture_vk->t.resource.bind_flags),
             VK_ACCESS_TRANSFER_READ_BIT,
             src_texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-            src_texture_vk->vk_image, &vk_src_range);
+            src_texture_vk->image.vk_image, &vk_src_range);
     wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
             vk_access_mask_from_bind_flags(dst_texture_vk->t.resource.bind_flags),
             VK_ACCESS_TRANSFER_WRITE_BIT,
             dst_texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-            dst_texture_vk->vk_image, &vk_dst_range);
+            dst_texture_vk->image.vk_image, &vk_dst_range);
 
     if (resolve)
     {
@@ -6571,8 +6501,8 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_
         region.extent.height = src_rect->bottom - src_rect->top;
         region.extent.depth = 1;
 
-        VK_CALL(vkCmdResolveImage(vk_command_buffer, src_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                dst_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region));
+        VK_CALL(vkCmdResolveImage(vk_command_buffer, src_texture_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                dst_texture_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region));
     }
     else
     {
@@ -6596,8 +6526,8 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_
         region.extent.height = src_rect->bottom - src_rect->top;
         region.extent.depth = 1;
 
-        VK_CALL(vkCmdCopyImage(vk_command_buffer, src_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                dst_texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region));
+        VK_CALL(vkCmdCopyImage(vk_command_buffer, src_texture_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                dst_texture_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region));
     }
 
     wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
@@ -6605,13 +6535,13 @@ static DWORD vk_blitter_blit(struct wined3d_blitter *blitter, enum wined3d_blit_
             VK_ACCESS_TRANSFER_WRITE_BIT,
             vk_access_mask_from_bind_flags(dst_texture_vk->t.resource.bind_flags),
             VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, dst_texture_vk->layout,
-            dst_texture_vk->vk_image, &vk_dst_range);
+            dst_texture_vk->image.vk_image, &vk_dst_range);
     wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
             VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
             VK_ACCESS_TRANSFER_READ_BIT,
             vk_access_mask_from_bind_flags(src_texture_vk->t.resource.bind_flags),
             VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, src_texture_vk->layout,
-            src_texture_vk->vk_image, &vk_src_range);
+            src_texture_vk->image.vk_image, &vk_src_range);
 
     wined3d_texture_validate_location(dst_texture, dst_sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
     wined3d_texture_invalidate_location(dst_texture, dst_sub_resource_idx, ~WINED3D_LOCATION_TEXTURE_RGB);
diff --git a/dlls/wined3d/view.c b/dlls/wined3d/view.c
index a1780e8e242..f0833ff9e49 100644
--- a/dlls/wined3d/view.c
+++ b/dlls/wined3d/view.c
@@ -730,7 +730,7 @@ static VkImageView wined3d_view_vk_create_vk_image_view(struct wined3d_context_v
     create_info.sType = VK_STRUCTURE_TYPE_IMAGE_VIEW_CREATE_INFO;
     create_info.pNext = NULL;
     create_info.flags = 0;
-    create_info.image = texture_vk->vk_image;
+    create_info.image = texture_vk->image.vk_image;
     create_info.viewType = vk_image_view_type_from_wined3d(resource->type, desc->flags);
     if (rtv && create_info.viewType == VK_IMAGE_VIEW_TYPE_3D)
     {
@@ -1318,13 +1318,13 @@ void wined3d_shader_resource_view_vk_generate_mipmap(struct wined3d_shader_resou
             vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags),
             VK_ACCESS_TRANSFER_READ_BIT,
             texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-            texture_vk->vk_image, &vk_src_range);
+            texture_vk->image.vk_image, &vk_src_range);
     wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
             VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
             vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags),
             VK_ACCESS_TRANSFER_WRITE_BIT,
             texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-            texture_vk->vk_image, &vk_dst_range);
+            texture_vk->image.vk_image, &vk_dst_range);
 
     region.srcSubresource.aspectMask = vk_src_range.aspectMask;
     region.srcSubresource.mipLevel = vk_src_range.baseMipLevel;
@@ -1352,15 +1352,15 @@ void wined3d_shader_resource_view_vk_generate_mipmap(struct wined3d_shader_resou
         region.dstOffsets[1].y = wined3d_texture_get_level_height(&texture_vk->t, vk_dst_range.baseMipLevel);
         region.dstOffsets[1].z = wined3d_texture_get_level_depth(&texture_vk->t, vk_dst_range.baseMipLevel);
 
-        VK_CALL(vkCmdBlitImage(vk_command_buffer, texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                texture_vk->vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region, VK_FILTER_LINEAR));
+        VK_CALL(vkCmdBlitImage(vk_command_buffer, texture_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
+                texture_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, &region, VK_FILTER_LINEAR));
 
         wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
                 VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
                 VK_ACCESS_TRANSFER_READ_BIT,
                 vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags),
                 VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL, texture_vk->layout,
-                texture_vk->vk_image, &vk_src_range);
+                texture_vk->image.vk_image, &vk_src_range);
 
         if (i == level_count - 1)
         {
@@ -1369,7 +1369,7 @@ void wined3d_shader_resource_view_vk_generate_mipmap(struct wined3d_shader_resou
                     VK_ACCESS_TRANSFER_WRITE_BIT,
                     vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags),
                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texture_vk->layout,
-                    texture_vk->vk_image, &vk_dst_range);
+                    texture_vk->image.vk_image, &vk_dst_range);
         }
         else
         {
@@ -1380,13 +1380,13 @@ void wined3d_shader_resource_view_vk_generate_mipmap(struct wined3d_shader_resou
                     VK_PIPELINE_STAGE_TRANSFER_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
                     VK_ACCESS_TRANSFER_WRITE_BIT, VK_ACCESS_TRANSFER_READ_BIT,
                     VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, VK_IMAGE_LAYOUT_TRANSFER_SRC_OPTIMAL,
-                    texture_vk->vk_image, &vk_src_range);
+                    texture_vk->image.vk_image, &vk_src_range);
             wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
                     VK_PIPELINE_STAGE_ALL_COMMANDS_BIT, VK_PIPELINE_STAGE_TRANSFER_BIT,
                     vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags),
                     VK_ACCESS_TRANSFER_WRITE_BIT,
                     texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL,
-                    texture_vk->vk_image, &vk_dst_range);
+                    texture_vk->image.vk_image, &vk_dst_range);
         }
     }
 
diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h
index 85b29efbb91..ac1e7a3e4ab 100644
--- a/dlls/wined3d/wined3d_private.h
+++ b/dlls/wined3d/wined3d_private.h
@@ -1650,6 +1650,14 @@ static inline struct wined3d_const_bo_address *wined3d_const_bo_address(struct w
     return (struct wined3d_const_bo_address *)data;
 }
 
+struct wined3d_image_vk
+{
+    VkImage vk_image;
+    struct wined3d_allocator_block *memory;
+    VkDeviceMemory vk_memory;
+    uint64_t command_buffer_id;
+};
+
 struct wined3d_stream_info_element
 {
     const struct wined3d_format *format;
@@ -2596,10 +2604,16 @@ VkCommandBuffer wined3d_context_vk_apply_draw_state(struct wined3d_context_vk *c
 void wined3d_context_vk_cleanup(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
 BOOL wined3d_context_vk_create_bo(struct wined3d_context_vk *context_vk, VkDeviceSize size,
         VkBufferUsageFlags usage, VkMemoryPropertyFlags memory_type, struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN;
+BOOL wined3d_context_vk_create_image(struct wined3d_context_vk *context_vk, VkImageType vk_image_type,
+        VkImageUsageFlags usage, VkFormat vk_format, unsigned int width, unsigned int height, unsigned int depth,
+        unsigned int sample_count, unsigned int mip_levels, unsigned int layer_count, unsigned int flags,
+        struct wined3d_image_vk *image) DECLSPEC_HIDDEN;
 void wined3d_context_vk_destroy_allocator_block(struct wined3d_context_vk *context_vk,
         struct wined3d_allocator_block *block, uint64_t command_buffer_id) DECLSPEC_HIDDEN;
 void wined3d_context_vk_destroy_bo(struct wined3d_context_vk *context_vk,
         const struct wined3d_bo_vk *bo) DECLSPEC_HIDDEN;
+void wined3d_context_vk_destroy_image(struct wined3d_context_vk *context_vk,
+        struct wined3d_image_vk *image_vk) DECLSPEC_HIDDEN;
 void wined3d_context_vk_destroy_vk_buffer_view(struct wined3d_context_vk *context_vk,
         VkBufferView vk_view, uint64_t command_buffer_id) DECLSPEC_HIDDEN;
 void wined3d_context_vk_destroy_vk_framebuffer(struct wined3d_context_vk *context_vk,
@@ -3874,22 +3888,15 @@ static inline struct wined3d_device_gl *wined3d_device_gl(struct wined3d_device
     return CONTAINING_RECORD(device, struct wined3d_device_gl, d);
 }
 
-struct wined3d_null_image_vk
-{
-    VkImage vk_image;
-    struct wined3d_allocator_block *memory;
-    VkDeviceMemory vk_memory;
-};
-
 struct wined3d_null_resources_vk
 {
     struct wined3d_bo_vk bo;
     VkDescriptorBufferInfo buffer_info;
 
-    struct wined3d_null_image_vk image_1d;
-    struct wined3d_null_image_vk image_2d;
-    struct wined3d_null_image_vk image_2dms;
-    struct wined3d_null_image_vk image_3d;
+    struct wined3d_image_vk image_1d;
+    struct wined3d_image_vk image_2d;
+    struct wined3d_image_vk image_2dms;
+    struct wined3d_image_vk image_3d;
 };
 
 struct wined3d_null_views_vk
@@ -4448,12 +4455,9 @@ struct wined3d_texture_vk
 {
     struct wined3d_texture t;
 
-    VkImage vk_image;
-    struct wined3d_allocator_block *memory;
-    VkDeviceMemory vk_memory;
+    struct wined3d_image_vk image;
     enum VkImageLayout layout;
     uint32_t bind_mask;
-    uint64_t command_buffer_id;
 
     VkDescriptorImageInfo default_image_info;
 };
@@ -6091,10 +6095,16 @@ static inline void wined3d_context_vk_reference_bo(const struct wined3d_context_
     bo->command_buffer_id = context_vk->current_command_buffer.id;
 }
 
+static inline void wined3d_context_vk_reference_image(const struct wined3d_context_vk *context_vk,
+        struct wined3d_image_vk *image)
+{
+    image->command_buffer_id = context_vk->current_command_buffer.id;
+}
+
 static inline void wined3d_context_vk_reference_texture(const struct wined3d_context_vk *context_vk,
         struct wined3d_texture_vk *texture_vk)
 {
-    texture_vk->command_buffer_id = context_vk->current_command_buffer.id;
+    wined3d_context_vk_reference_image(context_vk, &texture_vk->image);
 }
 
 static inline void wined3d_context_vk_reference_resource(const struct wined3d_context_vk *context_vk,
-- 
2.31.0




More information about the wine-devel mailing list