Signed-off-by: Jan Sikorski jsikorski@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, ®ion)); + dst_texture_vk->image.vk_image, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, 1, ®ion));
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, ®ion));
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, ®ion)); + 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, ®ion)); } 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, ®ion)); + 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, ®ion)); }
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, ®ion, 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, ®ion, 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,