Signed-off-by: Stefan Dösinger stefan@codeweavers.com --- dlls/wined3d/context_vk.c | 57 +++++++++++++++++++++++++++++++--- dlls/wined3d/texture.c | 40 ++++++++++++++---------- dlls/wined3d/wined3d_private.h | 9 ++++++ 3 files changed, 85 insertions(+), 21 deletions(-)
diff --git a/dlls/wined3d/context_vk.c b/dlls/wined3d/context_vk.c index b19220c2e34..b9d3375a008 100644 --- a/dlls/wined3d/context_vk.c +++ b/dlls/wined3d/context_vk.c @@ -2494,7 +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]; + 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; @@ -2503,6 +2503,7 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont struct wined3d_query_vk *query_vk; VkRenderPassBeginInfo begin_info; unsigned int attachment_count, i; + struct wined3d_texture *texture; VkFramebufferCreateInfo fb_desc; VkResult vr;
@@ -2519,6 +2520,7 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont 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) continue;
@@ -2534,10 +2536,40 @@ 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; context_vk->rt_count = i + 1; - ++attachment_count;
if (wined3d_rendertarget_view_get_locations(view) & WINED3D_LOCATION_CLEARED) - begin_info.clearValueCount = attachment_count; + { + VkClearColorValue *c = &clear_values[attachment_count].color; + const struct wined3d_color *colour; + + if (view->resource->type == WINED3D_RTYPE_BUFFER) + { + static const struct wined3d_color zero; + colour = &zero; + } + else + { + texture = texture_from_resource(view->resource); + colour = &texture->sub_resources[view->sub_resource_idx].clear_value.colour; + } + + if (view->format_flags & WINED3DFMT_FLAG_INTEGER) + { + c->int32[0] = colour->r; + c->int32[1] = colour->g; + c->int32[2] = colour->b; + c->int32[3] = colour->a; + } + else + { + c->float32[0] = colour->r; + c->float32[1] = colour->g; + c->float32[2] = colour->b; + c->float32[3] = colour->a; + } + begin_info.clearValueCount = attachment_count + 1; + } + ++attachment_count; }
if ((view = state->fb.depth_stencil)) @@ -2553,10 +2585,25 @@ static bool wined3d_context_vk_begin_render_pass(struct wined3d_context_vk *cont fb_height = view->height; 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; + { + VkClearDepthStencilValue *c = &clear_values[attachment_count].depthStencil; + + if (view->resource->type == WINED3D_RTYPE_BUFFER) + { + c->depth = 0.0f; + c->stencil = 0; + } + else + { + texture = texture_from_resource(view->resource); + c->depth = texture->sub_resources[view->sub_resource_idx].clear_value.depth; + c->stencil = texture->sub_resources[view->sub_resource_idx].clear_value.stencil; + } + begin_info.clearValueCount = attachment_count + 1; + } + ++attachment_count; }
if (!(context_vk->vk_render_pass = wined3d_context_vk_get_render_pass(context_vk, &state->fb, diff --git a/dlls/wined3d/texture.c b/dlls/wined3d/texture.c index 6756d1c31e1..dd7f225a2ca 100644 --- a/dlls/wined3d/texture.c +++ b/dlls/wined3d/texture.c @@ -823,10 +823,22 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, range.size = texture->sub_resources[sub_resource_idx].size; if (current & WINED3D_LOCATION_CLEARED) { - static const struct wined3d_color black; unsigned int level_idx = sub_resource_idx % texture->level_count; struct wined3d_map_desc map; struct wined3d_box box; + struct wined3d_color c; + + if (texture->resource.format->flags[WINED3D_GL_RES_TYPE_TEX_2D] + & WINED3DFMT_FLAG_DEPTH_STENCIL) + { + c.r = texture->sub_resources[sub_resource_idx].clear_value.depth; + c.g = texture->sub_resources[sub_resource_idx].clear_value.stencil; + c.b = c.a = 0.0f; + } + else + { + c = texture->sub_resources[sub_resource_idx].clear_value.colour; + }
wined3d_texture_get_pitch(texture, level_idx, &map.row_pitch, &map.slice_pitch); if (destination.buffer_object) @@ -836,7 +848,7 @@ BOOL wined3d_texture_load_location(struct wined3d_texture *texture, map.data = destination.addr;
wined3d_texture_get_level_box(texture, level_idx, &box); - wined3d_resource_memory_colour_fill(&texture->resource, level_idx, &map, &black, &box); + wined3d_resource_memory_colour_fill(&texture->resource, level_idx, &map, &c, &box);
if (destination.buffer_object) wined3d_context_unmap_bo_address(context, &destination, 1, &range); @@ -6607,18 +6619,12 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk
if (is_full_clear(view, draw_rect, clear_rects)) { - if (!colour->r && !colour->g && !colour->b && !colour->a) - { - wined3d_rendertarget_view_validate_location(view, WINED3D_LOCATION_CLEARED); - wined3d_rendertarget_view_invalidate_location(view, ~WINED3D_LOCATION_CLEARED); - delay_count++; - continue; - } - else - { - TRACE_(d3d_perf)("non-zero clear\n"); - wined3d_rendertarget_view_prepare_location(view, &context_vk->c, view->resource->draw_binding); - } + struct wined3d_texture *texture = texture_from_resource(view->resource); + wined3d_rendertarget_view_validate_location(view, WINED3D_LOCATION_CLEARED); + wined3d_rendertarget_view_invalidate_location(view, ~WINED3D_LOCATION_CLEARED); + texture->sub_resources[view->sub_resource_idx].clear_value.colour = *colour; + delay_count++; + continue; } else { @@ -6669,8 +6675,7 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk if (view->format->stencil_size) full_flags |= WINED3DCLEAR_STENCIL;
- if (!is_full_clear(view, draw_rect, clear_rects) - || depth || stencil || (flags & full_flags) != full_flags) + if (!is_full_clear(view, draw_rect, clear_rects) || (flags & full_flags) != full_flags) { wined3d_rendertarget_view_load_location(view, &context_vk->c, view->resource->draw_binding); wined3d_rendertarget_view_validate_location(view, view->resource->draw_binding); @@ -6691,6 +6696,9 @@ static void vk_blitter_clear_rendertargets(struct wined3d_context_vk *context_vk } else { + struct wined3d_texture *texture = texture_from_resource(view->resource); + texture->sub_resources[view->sub_resource_idx].clear_value.depth = depth; + texture->sub_resources[view->sub_resource_idx].clear_value.stencil = stencil; wined3d_rendertarget_view_validate_location(view, WINED3D_LOCATION_CLEARED); wined3d_rendertarget_view_invalidate_location(view, ~WINED3D_LOCATION_CLEARED); flags &= ~(WINED3DCLEAR_ZBUFFER | WINED3DCLEAR_STENCIL); diff --git a/dlls/wined3d/wined3d_private.h b/dlls/wined3d/wined3d_private.h index 98a19e0fd65..a7a26ce1626 100644 --- a/dlls/wined3d/wined3d_private.h +++ b/dlls/wined3d/wined3d_private.h @@ -4560,6 +4560,15 @@ struct wined3d_texture uint32_t map_flags; DWORD locations; struct wined3d_bo *bo; + union + { + struct wined3d_color colour; + struct + { + float depth; + unsigned int stencil; + }; + } clear_value;
void *user_memory; } *sub_resources;