Commit 2a283004 authored by Stefan Dösinger's avatar Stefan Dösinger Committed by Alexandre Julliard

wined3d: Tell Vulkan about discarded and cleared framebuffer attachments.

parent 767b1c6d
......@@ -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,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment