From: Stefan Dösinger stefan@codeweavers.com
Before submitting this in a non-draft MR I'll split out the LAYOUT_GENERAL reuse into a separate patch. --- dlls/wined3d/resource.c | 4 ++++ dlls/wined3d/texture.c | 40 +++++++++++++++++++++++++--------- dlls/wined3d/utils.c | 1 + dlls/wined3d/wined3d_private.h | 2 ++ 4 files changed, 37 insertions(+), 10 deletions(-)
diff --git a/dlls/wined3d/resource.c b/dlls/wined3d/resource.c index e2100627198..48a69c9978a 100644 --- a/dlls/wined3d/resource.c +++ b/dlls/wined3d/resource.c @@ -567,6 +567,8 @@ VkAccessFlags vk_access_mask_from_bind_flags(uint32_t bind_flags) flags |= VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_READ_BIT | VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT; if (bind_flags & WINED3D_BIND_STREAM_OUTPUT) flags |= VK_ACCESS_TRANSFORM_FEEDBACK_WRITE_BIT_EXT; + if (bind_flags & WINED3D_BIND_TRANSFER_DST) + flags |= VK_ACCESS_TRANSFER_WRITE_BIT;
return flags; } @@ -589,6 +591,8 @@ VkPipelineStageFlags vk_pipeline_stage_mask_from_bind_flags(uint32_t bind_flags) flags |= VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT; if (bind_flags & WINED3D_BIND_STREAM_OUTPUT) flags |= VK_PIPELINE_STAGE_TRANSFORM_FEEDBACK_BIT_EXT; + if (bind_flags & WINED3D_BIND_TRANSFER_DST) + flags |= VK_PIPELINE_STAGE_TRANSFER_BIT;
return flags; } diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 54dd24e0f5c..41b883d4343 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -5326,6 +5326,7 @@ static bool wined3d_texture_vk_clear(struct wined3d_texture_vk *texture_vk, VkImageSubresourceRange vk_range; VkClearColorValue colour_value; VkImageAspectFlags aspect_mask; + VkImageLayout layout; VkImage vk_image;
if (texture_vk->t.resource.format_attrs & WINED3D_FORMAT_ATTR_COMPRESSED) @@ -5362,29 +5363,45 @@ static bool wined3d_texture_vk_clear(struct wined3d_texture_vk *texture_vk,
wined3d_context_vk_end_current_render_pass(context_vk);
- 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->bind_mask), VK_ACCESS_TRANSFER_WRITE_BIT, - texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk_image, &vk_range); + if (texture_vk->t.level_count != 1 || texture_vk->t.layer_count != 1) + { + wined3d_texture_vk_barrier(texture_vk, context_vk, WINED3D_BIND_TRANSFER_DST); + layout = texture_vk->layout; + } + else + { + if (texture_vk->layout == VK_IMAGE_LAYOUT_GENERAL) + layout = VK_IMAGE_LAYOUT_GENERAL; + else + layout = VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + + 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->bind_mask), VK_ACCESS_TRANSFER_WRITE_BIT, + texture_vk->layout, layout, vk_image, &vk_range); + }
if (format->depth_size || format->stencil_size) { depth_value.depth = sub_resource->clear_value.depth; depth_value.stencil = sub_resource->clear_value.stencil; VK_CALL(vkCmdClearDepthStencilImage(vk_command_buffer, vk_image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depth_value, 1, &vk_range)); + layout, &depth_value, 1, &vk_range)); } else { wined3d_format_colour_to_vk(format, &sub_resource->clear_value.colour, &colour_value); VK_CALL(vkCmdClearColorImage(vk_command_buffer, vk_image, - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &colour_value, 1, &vk_range)); + layout, &colour_value, 1, &vk_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_WRITE_BIT, vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags), - VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texture_vk->layout, vk_image, &vk_range); + if (texture_vk->t.level_count != 1 || texture_vk->t.layer_count != 1) + { + 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(texture_vk->t.resource.bind_flags), + layout, texture_vk->layout, vk_image, &vk_range); + } wined3d_context_vk_reference_texture(context_vk, texture_vk);
wined3d_texture_validate_location(&texture_vk->t, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB); @@ -5726,6 +5743,9 @@ enum VkImageLayout wined3d_layout_from_bind_mask(const struct wined3d_texture_vk case WINED3D_BIND_SHADER_RESOURCE: return VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL;
+ case WINED3D_BIND_TRANSFER_DST: + return VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL; + default: ERR("Unexpected bind mask %s.\n", wined3d_debug_bind_flags(bind_mask)); return VK_IMAGE_LAYOUT_GENERAL; diff --git a/dlls/wined3d/utils.c b/dlls/wined3d/utils.c index aff2b00e08d..357adda5e2e 100644 --- a/dlls/wined3d/utils.c +++ b/dlls/wined3d/utils.c @@ -4896,6 +4896,7 @@ const char *wined3d_debug_bind_flags(uint32_t bind_flags) BIND_FLAG_TO_STR(WINED3D_BIND_DEPTH_STENCIL); BIND_FLAG_TO_STR(WINED3D_BIND_UNORDERED_ACCESS); BIND_FLAG_TO_STR(WINED3D_BIND_INDIRECT_BUFFER); + BIND_FLAG_TO_STR(WINED3D_BIND_TRANSFER_DST); #undef BIND_FLAG_TO_STR if (bind_flags) FIXME("Unrecognised bind flag(s) %#x.\n", bind_flags); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index bdf871a5f1d..7e0ea489ea6 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -338,6 +338,8 @@ struct min_lookup extern const struct min_lookup minMipLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN; extern const GLenum magLookup[WINED3D_TEXF_LINEAR + 1] DECLSPEC_HIDDEN;
+#define WINED3D_BIND_TRANSFER_DST 0x10000000 + static const uint32_t WINED3D_READ_ONLY_BIND_MASK = WINED3D_BIND_VERTEX_BUFFER | WINED3D_BIND_INDEX_BUFFER | WINED3D_BIND_CONSTANT_BUFFER | WINED3D_BIND_SHADER_RESOURCE | WINED3D_BIND_INDIRECT_BUFFER;