wined3d: Fall back to general layout if necessary.

If a texture is used as shader resource and DS/RT at the same time, including
cases where a different subresource is bound to each.

In theory this could be handled better, but would require per-subresource layout
tracking.
This commit is contained in:
Stefan Dösinger 2023-03-18 23:47:00 +03:00 committed by Alexandre Julliard
parent 9d4e4e496f
commit 31cb8d8aa6
4 changed files with 62 additions and 3 deletions

View file

@ -2599,6 +2599,14 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
continue;
rtv_vk = wined3d_rendertarget_view_vk(view);
if (rtv_vk->v.resource->bind_count)
{
struct wined3d_texture_vk *texture_vk;
texture_vk = wined3d_texture_vk(wined3d_texture_from_resource(rtv_vk->v.resource));
wined3d_texture_vk_make_generic(texture_vk, context_vk);
}
vk_views[attachment_count] = wined3d_rendertarget_view_vk_get_image_view(rtv_vk, context_vk);
wined3d_rendertarget_view_vk_barrier(rtv_vk, context_vk, WINED3D_BIND_RENDER_TARGET);
wined3d_context_vk_reference_rendertarget_view(context_vk, rtv_vk);
@ -2634,6 +2642,14 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
if ((view = state->fb.depth_stencil))
{
rtv_vk = wined3d_rendertarget_view_vk(view);
if (rtv_vk->v.resource->bind_count)
{
struct wined3d_texture_vk *texture_vk;
texture_vk = wined3d_texture_vk(wined3d_texture_from_resource(rtv_vk->v.resource));
wined3d_texture_vk_make_generic(texture_vk, context_vk);
}
vk_views[attachment_count] = wined3d_rendertarget_view_vk_get_image_view(rtv_vk, context_vk);
wined3d_rendertarget_view_vk_barrier(rtv_vk, context_vk, WINED3D_BIND_DEPTH_STENCIL);
wined3d_context_vk_reference_rendertarget_view(context_vk, rtv_vk);
@ -3023,7 +3039,11 @@ static bool wined3d_shader_descriptor_writes_vk_add_srv_write(struct wined3d_sha
struct wined3d_texture_vk *texture_vk = wined3d_texture_vk(texture_from_resource(resource));
if (view_vk->u.vk_image_info.imageView)
{
image_info = &view_vk->u.vk_image_info;
if (image_info->imageLayout != texture_vk->layout)
wined3d_shader_resource_view_vk_update_layout(srv_vk, texture_vk->layout);
}
else
image_info = wined3d_texture_vk_get_default_image_info(texture_vk, context_vk);
buffer_view = NULL;
@ -3389,7 +3409,7 @@ static void wined3d_context_vk_load_shader_resources(struct wined3d_context_vk *
{
if (!srv_vk->view_vk.bo_user.valid)
{
wined3d_shader_resource_view_vk_update(srv_vk, context_vk);
wined3d_shader_resource_view_vk_update_buffer(srv_vk, context_vk);
if (pipeline == WINED3D_PIPELINE_GRAPHICS)
context_invalidate_state(&context_vk->c, STATE_GRAPHICS_SHADER_RESOURCE_BINDING);
else

View file

@ -5794,6 +5794,35 @@ void wined3d_texture_vk_barrier(struct wined3d_texture_vk *texture_vk,
}
}
/* This is called when a texture is used as render target and shader resource
* or depth stencil and shader resource at the same time. This can either be
* read-only simultaneos use as depth stencil, but also for rendering to one
* subresource while reading from another. Without tracking of barriers and
* layouts per subresource VK_IMAGE_LAYOUT_GENERAL is the only thing we can do. */
void wined3d_texture_vk_make_generic(struct wined3d_texture_vk *texture_vk,
struct wined3d_context_vk *context_vk)
{
VkImageSubresourceRange vk_range;
if (texture_vk->layout == VK_IMAGE_LAYOUT_GENERAL)
return;
vk_range.aspectMask = vk_aspect_mask_from_format(texture_vk->t.resource.format);
vk_range.baseMipLevel = 0;
vk_range.levelCount = VK_REMAINING_MIP_LEVELS;
vk_range.baseArrayLayer = 0;
vk_range.layerCount = VK_REMAINING_ARRAY_LAYERS;
wined3d_context_vk_image_barrier(context_vk, wined3d_context_vk_get_command_buffer(context_vk),
VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
VK_PIPELINE_STAGE_BOTTOM_OF_PIPE_BIT,
0, 0,
texture_vk->layout, VK_IMAGE_LAYOUT_GENERAL, texture_vk->image.vk_image, &vk_range);
texture_vk->layout = VK_IMAGE_LAYOUT_GENERAL;
texture_vk->default_image_info.imageLayout = VK_IMAGE_LAYOUT_GENERAL;
}
static void ffp_blitter_destroy(struct wined3d_blitter *blitter, struct wined3d_context *context)
{
struct wined3d_blitter *next;

View file

@ -1101,7 +1101,7 @@ HRESULT wined3d_shader_resource_view_gl_init(struct wined3d_shader_resource_view
return hr;
}
void wined3d_shader_resource_view_vk_update(struct wined3d_shader_resource_view_vk *srv_vk,
void wined3d_shader_resource_view_vk_update_buffer(struct wined3d_shader_resource_view_vk *srv_vk,
struct wined3d_context_vk *context_vk)
{
const struct wined3d_format_vk *view_format_vk = wined3d_format_vk(srv_vk->v.format);
@ -1120,6 +1120,12 @@ void wined3d_shader_resource_view_vk_update(struct wined3d_shader_resource_view_
}
}
void wined3d_shader_resource_view_vk_update_layout(struct wined3d_shader_resource_view_vk *srv_vk,
VkImageLayout layout)
{
srv_vk->view_vk.u.vk_image_info.imageLayout = layout;
}
static void wined3d_shader_resource_view_vk_cs_init(void *object)
{
struct wined3d_shader_resource_view_vk *srv_vk = object;

View file

@ -4878,6 +4878,8 @@ const VkDescriptorImageInfo *wined3d_texture_vk_get_default_image_info(struct wi
HRESULT wined3d_texture_vk_init(struct wined3d_texture_vk *texture_vk, struct wined3d_device *device,
const struct wined3d_resource_desc *desc, unsigned int layer_count, unsigned int level_count,
uint32_t flags, void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
void wined3d_texture_vk_make_generic(struct wined3d_texture_vk *texture_vk,
struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
BOOL wined3d_texture_vk_prepare_texture(struct wined3d_texture_vk *texture_vk,
struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
@ -5595,8 +5597,10 @@ void wined3d_shader_resource_view_vk_generate_mipmap(struct wined3d_shader_resou
HRESULT wined3d_shader_resource_view_vk_init(struct wined3d_shader_resource_view_vk *view_vk,
const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
void *parent, const struct wined3d_parent_ops *parent_ops) DECLSPEC_HIDDEN;
void wined3d_shader_resource_view_vk_update(struct wined3d_shader_resource_view_vk *view_vk,
void wined3d_shader_resource_view_vk_update_buffer(struct wined3d_shader_resource_view_vk *view_vk,
struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
void wined3d_shader_resource_view_vk_update_layout(struct wined3d_shader_resource_view_vk *srv_vk,
VkImageLayout layout) DECLSPEC_HIDDEN;
struct wined3d_unordered_access_view
{