wined3d: Tell Vulkan about discarded and cleared framebuffer attachments.
Signed-off-by: Stefan Dösinger <stefan@codeweavers.com> Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
767b1c6d75
commit
2a283004ab
|
@ -1250,6 +1250,7 @@ static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk *k
|
|||
struct wined3d_render_pass_attachment_vk *a;
|
||||
struct wined3d_rendertarget_view *view;
|
||||
unsigned int i;
|
||||
DWORD location;
|
||||
|
||||
memset(key, 0, sizeof(*key));
|
||||
|
||||
|
@ -1262,6 +1263,15 @@ static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk *k
|
|||
a->vk_format = wined3d_format_vk(view->format)->vk_format;
|
||||
a->vk_samples = max(1, wined3d_resource_get_sample_count(view->resource));
|
||||
a->vk_layout = wined3d_texture_vk(wined3d_texture_from_resource(view->resource))->layout;
|
||||
location = wined3d_rendertarget_view_get_locations(view);
|
||||
|
||||
if (clear_flags & WINED3DCLEAR_TARGET)
|
||||
a->flags = WINED3D_FB_ATTACHMENT_FLAG_CLEAR_C;
|
||||
else if (location & WINED3D_LOCATION_DISCARDED)
|
||||
a->flags = WINED3D_FB_ATTACHMENT_FLAG_DISCARDED;
|
||||
else if (location & WINED3D_LOCATION_CLEARED)
|
||||
a->flags = WINED3D_FB_ATTACHMENT_FLAG_CLEAR_C;
|
||||
|
||||
key->rt_mask |= 1u << i;
|
||||
}
|
||||
|
||||
|
@ -1271,10 +1281,19 @@ static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk *k
|
|||
a->vk_format = wined3d_format_vk(view->format)->vk_format;
|
||||
a->vk_samples = max(1, wined3d_resource_get_sample_count(view->resource));
|
||||
a->vk_layout = wined3d_texture_vk(wined3d_texture_from_resource(view->resource))->layout;
|
||||
location = wined3d_rendertarget_view_get_locations(view);
|
||||
key->rt_mask |= 1u << WINED3D_MAX_RENDER_TARGETS;
|
||||
}
|
||||
|
||||
key->clear_flags = clear_flags;
|
||||
if (clear_flags & WINED3DCLEAR_STENCIL)
|
||||
a->flags = WINED3D_FB_ATTACHMENT_FLAG_CLEAR_S;
|
||||
if (clear_flags & WINED3DCLEAR_ZBUFFER)
|
||||
a->flags |= WINED3D_FB_ATTACHMENT_FLAG_CLEAR_Z;
|
||||
|
||||
if (!a->flags && (location & WINED3D_LOCATION_DISCARDED))
|
||||
a->flags = WINED3D_FB_ATTACHMENT_FLAG_DISCARDED;
|
||||
else if (location & WINED3D_LOCATION_CLEARED)
|
||||
a->flags = WINED3D_FB_ATTACHMENT_FLAG_CLEAR_S | WINED3D_FB_ATTACHMENT_FLAG_CLEAR_Z;
|
||||
}
|
||||
}
|
||||
|
||||
static void wined3d_render_pass_vk_cleanup(struct wined3d_render_pass_vk *pass,
|
||||
|
@ -1315,10 +1334,14 @@ static bool wined3d_render_pass_vk_init(struct wined3d_render_pass_vk *pass,
|
|||
attachment->flags = 0;
|
||||
attachment->format = a->vk_format;
|
||||
attachment->samples = a->vk_samples;
|
||||
if (key->clear_flags & WINED3DCLEAR_TARGET)
|
||||
|
||||
if (a->flags & WINED3D_FB_ATTACHMENT_FLAG_DISCARDED)
|
||||
attachment->loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
else if (a->flags & WINED3D_FB_ATTACHMENT_FLAG_CLEAR_C)
|
||||
attachment->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
else
|
||||
attachment->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
|
||||
attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
attachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_DONT_CARE;
|
||||
|
@ -1348,15 +1371,22 @@ static bool wined3d_render_pass_vk_init(struct wined3d_render_pass_vk *pass,
|
|||
attachment->flags = 0;
|
||||
attachment->format = a->vk_format;
|
||||
attachment->samples = a->vk_samples;
|
||||
if (key->clear_flags & WINED3DCLEAR_ZBUFFER)
|
||||
|
||||
if (a->flags & WINED3D_FB_ATTACHMENT_FLAG_DISCARDED)
|
||||
attachment->loadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
else if (a->flags & WINED3D_FB_ATTACHMENT_FLAG_CLEAR_Z)
|
||||
attachment->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
else
|
||||
attachment->loadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
if (key->clear_flags & WINED3DCLEAR_STENCIL)
|
||||
|
||||
if (a->flags & WINED3D_FB_ATTACHMENT_FLAG_DISCARDED)
|
||||
attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_DONT_CARE;
|
||||
else if (a->flags & WINED3D_FB_ATTACHMENT_FLAG_CLEAR_S)
|
||||
attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
else
|
||||
attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
|
||||
attachment->storeOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment->initialLayout = a->vk_layout;
|
||||
attachment->finalLayout = a->vk_layout;
|
||||
|
@ -2464,6 +2494,7 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
|
|||
VkCommandBuffer vk_command_buffer, const struct wined3d_state *state, const struct wined3d_vk_info *vk_info)
|
||||
{
|
||||
struct wined3d_device_vk *device_vk = wined3d_device_vk(context_vk->c.device);
|
||||
static const VkClearValue clear_values[WINED3D_MAX_RENDER_TARGETS + 1];
|
||||
VkImageView vk_views[WINED3D_MAX_RENDER_TARGETS + 1];
|
||||
unsigned int fb_width, fb_height, fb_layer_count;
|
||||
struct wined3d_rendertarget_view_vk *rtv_vk;
|
||||
|
@ -2485,6 +2516,7 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
|
|||
attachment_count = 0;
|
||||
|
||||
context_vk->rt_count = 0;
|
||||
begin_info.clearValueCount = 0;
|
||||
for (i = 0; i < ARRAY_SIZE(state->fb.render_targets); ++i)
|
||||
{
|
||||
if (!(view = state->fb.render_targets[i]) || view->format->id == WINED3DFMT_NULL)
|
||||
|
@ -2503,6 +2535,9 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
|
|||
fb_layer_count = view->layer_count;
|
||||
context_vk->rt_count = i + 1;
|
||||
++attachment_count;
|
||||
|
||||
if (wined3d_rendertarget_view_get_locations(view) & WINED3D_LOCATION_CLEARED)
|
||||
begin_info.clearValueCount = attachment_count;
|
||||
}
|
||||
|
||||
if ((view = state->fb.depth_stencil))
|
||||
|
@ -2519,6 +2554,9 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
|
|||
if (view->layer_count < fb_layer_count)
|
||||
fb_layer_count = view->layer_count;
|
||||
++attachment_count;
|
||||
|
||||
if (wined3d_rendertarget_view_get_locations(view) & WINED3D_LOCATION_CLEARED)
|
||||
begin_info.clearValueCount = attachment_count;
|
||||
}
|
||||
|
||||
if (!(context_vk->vk_render_pass = wined3d_context_vk_get_render_pass(context_vk, &state->fb,
|
||||
|
@ -2552,8 +2590,7 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont
|
|||
begin_info.renderArea.offset.y = 0;
|
||||
begin_info.renderArea.extent.width = fb_width;
|
||||
begin_info.renderArea.extent.height = fb_height;
|
||||
begin_info.clearValueCount = 0;
|
||||
begin_info.pClearValues = NULL;
|
||||
begin_info.pClearValues = clear_values;
|
||||
VK_CALL(vkCmdBeginRenderPass(vk_command_buffer, &begin_info, VK_SUBPASS_CONTENTS_INLINE));
|
||||
|
||||
LIST_FOR_EACH_ENTRY(query_vk, &context_vk->render_pass_queries, struct wined3d_query_vk, entry)
|
||||
|
|
|
@ -511,6 +511,29 @@ void wined3d_rendertarget_view_invalidate_location(struct wined3d_rendertarget_v
|
|||
wined3d_view_invalidate_location(view->resource, &view->desc, location);
|
||||
}
|
||||
|
||||
/* Note: This may return 0 if the selected layers do not have a location in common. */
|
||||
DWORD wined3d_rendertarget_view_get_locations(const struct wined3d_rendertarget_view *view)
|
||||
{
|
||||
struct wined3d_resource *resource = view->resource;
|
||||
unsigned int i, sub_resource_idx, layer_count;
|
||||
const struct wined3d_texture *texture;
|
||||
DWORD ret = ~0u;
|
||||
|
||||
if (resource->type == WINED3D_RTYPE_BUFFER)
|
||||
return buffer_from_resource(resource)->locations;
|
||||
|
||||
texture = texture_from_resource(resource);
|
||||
sub_resource_idx = view->sub_resource_idx;
|
||||
layer_count = resource->type != WINED3D_RTYPE_TEXTURE_3D ? view->layer_count : 1;
|
||||
for (i = 0; i < layer_count; ++i, sub_resource_idx += texture->level_count)
|
||||
ret &= texture->sub_resources[sub_resource_idx].locations;
|
||||
|
||||
if (!ret)
|
||||
WARN("View %p (texture %p) layers do not have a location in common.\n", view, texture);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wined3d_render_target_view_gl_cs_init(void *object)
|
||||
{
|
||||
struct wined3d_rendertarget_view_gl *view_gl = object;
|
||||
|
|
|
@ -2456,11 +2456,17 @@ struct wined3d_retired_objects_vk
|
|||
SIZE_T count;
|
||||
};
|
||||
|
||||
#define WINED3D_FB_ATTACHMENT_FLAG_DISCARDED 1
|
||||
#define WINED3D_FB_ATTACHMENT_FLAG_CLEAR_C 2
|
||||
#define WINED3D_FB_ATTACHMENT_FLAG_CLEAR_S 4
|
||||
#define WINED3D_FB_ATTACHMENT_FLAG_CLEAR_Z 8
|
||||
|
||||
struct wined3d_render_pass_attachment_vk
|
||||
{
|
||||
VkFormat vk_format;
|
||||
VkSampleCountFlagBits vk_samples;
|
||||
VkImageLayout vk_layout;
|
||||
uint32_t flags;
|
||||
};
|
||||
|
||||
struct wined3d_render_pass_key_vk
|
||||
|
@ -2468,7 +2474,6 @@ struct wined3d_render_pass_key_vk
|
|||
struct wined3d_render_pass_attachment_vk rt[WINED3D_MAX_RENDER_TARGETS];
|
||||
struct wined3d_render_pass_attachment_vk ds;
|
||||
uint32_t rt_mask;
|
||||
uint32_t clear_flags;
|
||||
};
|
||||
|
||||
struct wined3d_render_pass_vk
|
||||
|
@ -5283,6 +5288,8 @@ void wined3d_rendertarget_view_prepare_location(struct wined3d_rendertarget_view
|
|||
struct wined3d_context *context, DWORD location) DECLSPEC_HIDDEN;
|
||||
void wined3d_rendertarget_view_validate_location(struct wined3d_rendertarget_view *view,
|
||||
DWORD location) DECLSPEC_HIDDEN;
|
||||
DWORD wined3d_rendertarget_view_get_locations(const struct wined3d_rendertarget_view *view)
|
||||
DECLSPEC_HIDDEN;
|
||||
|
||||
HRESULT wined3d_rendertarget_view_no3d_init(struct wined3d_rendertarget_view *view_no3d,
|
||||
const struct wined3d_view_desc *desc, struct wined3d_resource *resource,
|
||||
|
|
Loading…
Reference in New Issue