wined3d: Implement depth/stencil clears in the Vulkan blitter.
Signed-off-by: Henri Verbeet <hverbeet@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
28ec279518
commit
f793f4446c
|
@ -630,7 +630,7 @@ static void wined3d_context_vk_destroy_bo_slab(struct wine_rb_entry *entry, void
|
|||
}
|
||||
|
||||
static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk *key,
|
||||
const struct wined3d_fb_state *fb, unsigned int rt_count)
|
||||
const struct wined3d_fb_state *fb, unsigned int rt_count, bool depth_stencil, uint32_t clear_flags)
|
||||
{
|
||||
struct wined3d_render_pass_attachment_vk *a;
|
||||
struct wined3d_rendertarget_view *view;
|
||||
|
@ -649,6 +649,17 @@ static void wined3d_render_pass_key_vk_init(struct wined3d_render_pass_key_vk *k
|
|||
a->vk_layout = wined3d_texture_vk(wined3d_texture_from_resource(view->resource))->layout;
|
||||
key->rt_mask |= 1u << i;
|
||||
}
|
||||
|
||||
if (depth_stencil && (view = fb->depth_stencil))
|
||||
{
|
||||
a = &key->ds;
|
||||
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;
|
||||
key->rt_mask |= 1u << WINED3D_MAX_RENDER_TARGETS;
|
||||
}
|
||||
|
||||
key->clear_flags = clear_flags;
|
||||
}
|
||||
|
||||
static void wined3d_render_pass_vk_cleanup(struct wined3d_render_pass_vk *pass,
|
||||
|
@ -668,6 +679,8 @@ static bool wined3d_render_pass_vk_init(struct wined3d_render_pass_vk *pass,
|
|||
VkAttachmentDescription attachments[WINED3D_MAX_RENDER_TARGETS + 1];
|
||||
const struct wined3d_vk_info *vk_info = context_vk->vk_info;
|
||||
const struct wined3d_render_pass_attachment_vk *a;
|
||||
VkAttachmentReference ds_attachment_reference;
|
||||
VkAttachmentReference *ds_reference = NULL;
|
||||
unsigned int attachment_count, rt_count, i;
|
||||
VkAttachmentDescription *attachment;
|
||||
VkSubpassDescription sub_pass_desc;
|
||||
|
@ -687,7 +700,10 @@ 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;
|
||||
attachment->loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
if (key->clear_flags & WINED3DCLEAR_TARGET)
|
||||
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;
|
||||
|
@ -709,6 +725,34 @@ static bool wined3d_render_pass_vk_init(struct wined3d_render_pass_vk *pass,
|
|||
attachment_references[i].layout = VK_IMAGE_LAYOUT_UNDEFINED;
|
||||
}
|
||||
|
||||
if (key->rt_mask & (1u << WINED3D_MAX_RENDER_TARGETS))
|
||||
{
|
||||
a = &key->ds;
|
||||
|
||||
attachment = &attachments[attachment_count];
|
||||
attachment->flags = 0;
|
||||
attachment->format = a->vk_format;
|
||||
attachment->samples = a->vk_samples;
|
||||
if (key->clear_flags & WINED3DCLEAR_ZBUFFER)
|
||||
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)
|
||||
attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
|
||||
else
|
||||
attachment->stencilLoadOp = VK_ATTACHMENT_LOAD_OP_LOAD;
|
||||
attachment->stencilStoreOp = VK_ATTACHMENT_STORE_OP_STORE;
|
||||
attachment->initialLayout = a->vk_layout;
|
||||
attachment->finalLayout = a->vk_layout;
|
||||
|
||||
ds_reference = &ds_attachment_reference;
|
||||
ds_reference->attachment = attachment_count;
|
||||
ds_reference->layout = a->vk_layout;
|
||||
|
||||
++attachment_count;
|
||||
}
|
||||
|
||||
sub_pass_desc.flags = 0;
|
||||
sub_pass_desc.pipelineBindPoint = VK_PIPELINE_BIND_POINT_GRAPHICS;
|
||||
sub_pass_desc.inputAttachmentCount = 0;
|
||||
|
@ -716,7 +760,7 @@ static bool wined3d_render_pass_vk_init(struct wined3d_render_pass_vk *pass,
|
|||
sub_pass_desc.colorAttachmentCount = rt_count;
|
||||
sub_pass_desc.pColorAttachments = attachment_references;
|
||||
sub_pass_desc.pResolveAttachments = NULL;
|
||||
sub_pass_desc.pDepthStencilAttachment = NULL;
|
||||
sub_pass_desc.pDepthStencilAttachment = ds_reference;
|
||||
sub_pass_desc.preserveAttachmentCount = 0;
|
||||
sub_pass_desc.pPreserveAttachments = NULL;
|
||||
|
||||
|
@ -742,13 +786,13 @@ static bool wined3d_render_pass_vk_init(struct wined3d_render_pass_vk *pass,
|
|||
}
|
||||
|
||||
VkRenderPass wined3d_context_vk_get_render_pass(struct wined3d_context_vk *context_vk,
|
||||
const struct wined3d_fb_state *fb, unsigned int rt_count)
|
||||
const struct wined3d_fb_state *fb, unsigned int rt_count, bool depth_stencil, uint32_t clear_flags)
|
||||
{
|
||||
struct wined3d_render_pass_key_vk key;
|
||||
struct wined3d_render_pass_vk *pass;
|
||||
struct wine_rb_entry *entry;
|
||||
|
||||
wined3d_render_pass_key_vk_init(&key, fb, rt_count);
|
||||
wined3d_render_pass_key_vk_init(&key, fb, rt_count, depth_stencil, clear_flags);
|
||||
if ((entry = wine_rb_get(&context_vk->render_passes, &key)))
|
||||
return WINE_RB_ENTRY_VALUE(entry, struct wined3d_render_pass_vk, entry)->vk_render_pass;
|
||||
|
||||
|
|
|
@ -6052,8 +6052,8 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk
|
|||
const struct wined3d_fb_state *fb, unsigned int rect_count, const RECT *clear_rects, const RECT *draw_rect,
|
||||
uint32_t flags, const struct wined3d_color *colour, float depth, unsigned int stencil)
|
||||
{
|
||||
VkClearValue clear_values[WINED3D_MAX_RENDER_TARGETS];
|
||||
VkImageView views[WINED3D_MAX_RENDER_TARGETS];
|
||||
VkClearValue clear_values[WINED3D_MAX_RENDER_TARGETS + 1];
|
||||
VkImageView views[WINED3D_MAX_RENDER_TARGETS + 1];
|
||||
struct wined3d_rendertarget_view_vk *rtv_vk;
|
||||
struct wined3d_rendertarget_view *view;
|
||||
const struct wined3d_vk_info *vk_info;
|
||||
|
@ -6065,6 +6065,7 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk
|
|||
VkFramebufferCreateInfo fb_desc;
|
||||
VkFramebuffer vk_framebuffer;
|
||||
VkRenderPass vk_render_pass;
|
||||
bool depth_stencil = false;
|
||||
unsigned int layer_count;
|
||||
VkClearColorValue *c;
|
||||
VkResult vr;
|
||||
|
@ -6078,6 +6079,9 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk
|
|||
device_vk = wined3d_device_vk(context_vk->c.device);
|
||||
vk_info = context_vk->vk_info;
|
||||
|
||||
if (!(flags & WINED3DCLEAR_TARGET))
|
||||
rt_count = 0;
|
||||
|
||||
for (i = 0, attachment_count = 0, layer_count = 1; i < rt_count; ++i)
|
||||
{
|
||||
if (!(view = fb->render_targets[i]))
|
||||
|
@ -6115,7 +6119,33 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk
|
|||
++attachment_count;
|
||||
}
|
||||
|
||||
if (!(vk_render_pass = wined3d_context_vk_get_render_pass(context_vk, fb, rt_count)))
|
||||
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL) && (view = fb->depth_stencil))
|
||||
{
|
||||
if (!is_full_clear(view, draw_rect, clear_rects))
|
||||
wined3d_rendertarget_view_load_location(view, &context_vk->c, view->resource->draw_binding);
|
||||
else
|
||||
wined3d_rendertarget_view_prepare_location(view, &context_vk->c, view->resource->draw_binding);
|
||||
wined3d_rendertarget_view_validate_location(view, view->resource->draw_binding);
|
||||
wined3d_rendertarget_view_invalidate_location(view, ~view->resource->draw_binding);
|
||||
|
||||
rtv_vk = wined3d_rendertarget_view_vk(view);
|
||||
views[attachment_count] = wined3d_rendertarget_view_vk_get_image_view(rtv_vk, context_vk);
|
||||
|
||||
clear_values[attachment_count].depthStencil.depth = depth;
|
||||
clear_values[attachment_count].depthStencil.stencil = stencil;
|
||||
|
||||
if (view->layer_count > layer_count)
|
||||
layer_count = view->layer_count;
|
||||
|
||||
depth_stencil = true;
|
||||
++attachment_count;
|
||||
}
|
||||
|
||||
if (!attachment_count)
|
||||
return;
|
||||
|
||||
if (!(vk_render_pass = wined3d_context_vk_get_render_pass(context_vk, fb,
|
||||
rt_count, flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL), flags)))
|
||||
{
|
||||
ERR("Failed to get render pass.\n");
|
||||
return;
|
||||
|
@ -6183,6 +6213,19 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk
|
|||
texture_vk->layout, texture_vk->layout,
|
||||
texture_vk->vk_image, VK_IMAGE_ASPECT_COLOR_BIT);
|
||||
}
|
||||
|
||||
if (depth_stencil)
|
||||
{
|
||||
view = fb->depth_stencil;
|
||||
wined3d_context_vk_reference_rendertarget_view(context_vk, wined3d_rendertarget_view_vk(view));
|
||||
texture_vk = wined3d_texture_vk(wined3d_texture_from_resource(view->resource));
|
||||
wined3d_context_vk_image_barrier(context_vk, vk_command_buffer,
|
||||
VK_PIPELINE_STAGE_LATE_FRAGMENT_TESTS_BIT, VK_PIPELINE_STAGE_ALL_COMMANDS_BIT,
|
||||
VK_ACCESS_DEPTH_STENCIL_ATTACHMENT_WRITE_BIT,
|
||||
vk_access_mask_from_bind_flags(texture_vk->t.resource.bind_flags),
|
||||
texture_vk->layout, texture_vk->layout,
|
||||
texture_vk->vk_image, vk_aspect_mask_from_format(texture_vk->t.resource.format));
|
||||
}
|
||||
}
|
||||
|
||||
static void vk_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_device *device,
|
||||
|
@ -6228,7 +6271,10 @@ static void vk_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_dev
|
|||
}
|
||||
}
|
||||
|
||||
if ((flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) && fb->depth_stencil)
|
||||
if ((flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL)) && (view = fb->depth_stencil)
|
||||
&& (!view->format->depth_size || (flags & WINED3DCLEAR_ZBUFFER))
|
||||
&& (!view->format->stencil_size || (flags & WINED3DCLEAR_STENCIL))
|
||||
&& blitter_use_cpu_clear(view))
|
||||
{
|
||||
next_flags |= flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL);
|
||||
flags &= ~(WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL);
|
||||
|
@ -6247,6 +6293,13 @@ static void vk_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_dev
|
|||
have_identical_size = false;
|
||||
previous = view;
|
||||
}
|
||||
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
|
||||
{
|
||||
view = fb->depth_stencil;
|
||||
|
||||
if (previous && (previous->width != view->width || previous->height != view->height))
|
||||
have_identical_size = false;
|
||||
}
|
||||
|
||||
if (have_identical_size)
|
||||
{
|
||||
|
@ -6265,6 +6318,13 @@ static void vk_blitter_clear(struct wined3d_blitter *blitter, struct wined3d_dev
|
|||
vk_blitter_clear_rendertargets(context_vk, 1, &tmp_fb, rect_count,
|
||||
clear_rects, draw_rect, WINED3DCLEAR_TARGET, colour, depth, stencil);
|
||||
}
|
||||
if (flags & (WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL))
|
||||
{
|
||||
tmp_fb.render_targets[0] = NULL;
|
||||
tmp_fb.depth_stencil = fb->depth_stencil;
|
||||
vk_blitter_clear_rendertargets(context_vk, 0, &tmp_fb, rect_count,
|
||||
clear_rects, draw_rect, flags & ~WINED3DCLEAR_TARGET, colour, depth, stencil);
|
||||
}
|
||||
}
|
||||
|
||||
context_release(&context_vk->c);
|
||||
|
|
|
@ -2272,7 +2272,9 @@ struct wined3d_render_pass_attachment_vk
|
|||
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
|
||||
|
@ -2330,7 +2332,8 @@ void wined3d_context_vk_destroy_memory(struct wined3d_context_vk *context_vk,
|
|||
VkDeviceMemory vk_memory, uint64_t command_buffer_id) DECLSPEC_HIDDEN;
|
||||
VkCommandBuffer wined3d_context_vk_get_command_buffer(struct wined3d_context_vk *context_vk) DECLSPEC_HIDDEN;
|
||||
VkRenderPass wined3d_context_vk_get_render_pass(struct wined3d_context_vk *context_vk,
|
||||
const struct wined3d_fb_state *fb, unsigned int rt_count) DECLSPEC_HIDDEN;
|
||||
const struct wined3d_fb_state *fb, unsigned int rt_count,
|
||||
bool depth_stencil, uint32_t clear_flags) DECLSPEC_HIDDEN;
|
||||
void wined3d_context_vk_image_barrier(struct wined3d_context_vk *context_vk,
|
||||
VkCommandBuffer vk_command_buffer, VkPipelineStageFlags src_stage_mask, VkPipelineStageFlags dst_stage_mask,
|
||||
VkAccessFlags src_access_mask, VkAccessFlags dst_access_mask, VkImageLayout old_layout,
|
||||
|
|
Loading…
Reference in New Issue