[PATCH 2/5] wined3d: Clear Vulkan textures on the GPU if loading to TEXTURE_RGB.

Zebediah Figura zfigura at codeweavers.com
Tue Apr 19 20:20:36 CDT 2022


Signed-off-by: Zebediah Figura <zfigura at codeweavers.com>
---
 dlls/wined3d/texture.c | 62 +++++++++++++++++++++++++++++++++++++++---
 1 file changed, 58 insertions(+), 4 deletions(-)

diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c
index 18fd0847296..27ce651422e 100644
--- a/dlls/wined3d/texture.c
+++ b/dlls/wined3d/texture.c
@@ -5482,15 +5482,69 @@ static void wined3d_texture_vk_unload_location(struct wined3d_texture *texture,
 static void wined3d_texture_vk_clear(struct wined3d_texture *texture,
         unsigned int sub_resource_idx, struct wined3d_context *context, unsigned int location)
 {
+    struct wined3d_context_vk *context_vk = wined3d_context_vk(context);
+    struct wined3d_texture_vk *texture_vk = wined3d_texture_vk(texture);
+    const struct wined3d_format *format = texture->resource.format;
+    const struct wined3d_vk_info *vk_info = context_vk->vk_info;
+    static const VkClearDepthStencilValue depth_value;
+    static const VkClearColorValue colour_value;
+    VkCommandBuffer vk_command_buffer;
+    VkImageSubresourceRange vk_range;
     struct wined3d_bo_address addr;
+    VkImageAspectFlags aspect_mask;
+    VkImage vk_image;
 
     TRACE("texture %p, sub_resource_idx %u, context %p, location %s.\n",
             texture, sub_resource_idx, context, wined3d_debug_location(location));
 
-    wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM);
-    wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM);
-    memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size);
-    wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM);
+    if (location == WINED3D_LOCATION_TEXTURE_RGB)
+    {
+        wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_TEXTURE_RGB);
+        vk_image = texture_vk->image.vk_image;
+
+        if (!(vk_command_buffer = wined3d_context_vk_get_command_buffer(context_vk)))
+        {
+            ERR("Failed to get command buffer.\n");
+            return;
+        }
+
+        aspect_mask = vk_aspect_mask_from_format(format);
+
+        vk_range.aspectMask = aspect_mask;
+        vk_range.baseMipLevel = sub_resource_idx % texture->level_count;
+        vk_range.levelCount = 1;
+        vk_range.baseArrayLayer = sub_resource_idx / texture->level_count;
+        vk_range.layerCount = 1;
+
+        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->resource.bind_flags), VK_ACCESS_TRANSFER_WRITE_BIT,
+                texture_vk->layout, VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, vk_image, &vk_range);
+
+        if (format->depth_size || format->stencil_size)
+            VK_CALL(vkCmdClearDepthStencilImage(vk_command_buffer, vk_image, 
+                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &depth_value, 1, &vk_range));
+        else
+            VK_CALL(vkCmdClearColorImage(vk_command_buffer, vk_image,
+                    VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, &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->resource.bind_flags),
+                VK_IMAGE_LAYOUT_TRANSFER_DST_OPTIMAL, texture_vk->layout, vk_image, &vk_range);
+        wined3d_context_vk_reference_texture(context_vk, texture_vk);
+
+        wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_TEXTURE_RGB);
+    }
+    else
+    {
+        wined3d_texture_prepare_location(texture, sub_resource_idx, context, WINED3D_LOCATION_SYSMEM);
+        wined3d_texture_get_bo_address(texture, sub_resource_idx, &addr, WINED3D_LOCATION_SYSMEM);
+        memset(addr.addr, 0, texture->sub_resources[sub_resource_idx].size);
+        wined3d_texture_validate_location(texture, sub_resource_idx, WINED3D_LOCATION_SYSMEM);
+    }
 }
 
 static const struct wined3d_texture_ops wined3d_texture_vk_ops =
-- 
2.35.1




More information about the wine-devel mailing list