[PATCH 8/9] wined3d: Store clear colors in subresources.
Stefan Dösinger
stefan at codeweavers.com
Sun May 1 13:39:10 CDT 2022
Signed-off-by: Stefan Dösinger <stefan at 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;
--
2.35.1
More information about the wine-devel
mailing list