diff --git a/src/gallium/drivers/svga/svga_pipe_draw.c b/src/gallium/drivers/svga/svga_pipe_draw.c index bd88f5bb173..72087561b06 100644 --- a/src/gallium/drivers/svga/svga_pipe_draw.c +++ b/src/gallium/drivers/svga/svga_pipe_draw.c @@ -1,5 +1,5 @@ /********************************************************** - * Copyright 2008-2009 VMware, Inc. All rights reserved. + * Copyright 2008-2023 VMware, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -245,15 +245,6 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, svga->curr.rast->templ.cull_face == PIPE_FACE_FRONT_AND_BACK) goto done; - /* - * Mark currently bound target surfaces as dirty - * doesn't really matter if it is done before drawing. - * - * TODO If we ever normaly return something other then - * true we should not mark it as dirty then. - */ - svga_mark_surfaces_dirty(svga_context(pipe)); - if (svga->curr.reduced_prim != reduced_prim) { svga->curr.reduced_prim = reduced_prim; svga->dirty |= SVGA_NEW_REDUCED_PRIMITIVE; @@ -373,6 +364,11 @@ svga_draw_vbo(struct pipe_context *pipe, const struct pipe_draw_info *info, } } + /* + * Mark currently bound target surfaces as dirty after draw is completed. + */ + svga_mark_surfaces_dirty(svga_context(pipe)); + /* XXX: Silence warnings, do something sensible here? */ (void)ret; diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c index 8ce5b945520..17d91d16fcd 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.c +++ b/src/gallium/drivers/svga/svga_resource_texture.c @@ -43,6 +43,7 @@ #include "svga_resource_texture.h" #include "svga_resource_buffer.h" #include "svga_sampler_view.h" +#include "svga_surface.h" #include "svga_winsys.h" #include "svga_debug.h" @@ -1346,6 +1347,51 @@ svga_texture_transfer_map_can_upload(const struct svga_screen *svgascreen, } +/** + * Return TRUE if the same texture is bound to the specified + * surface view and a backing resource is created for the surface view. + */ +static bool +need_update_texture_resource(struct pipe_surface *surf, + struct svga_texture *tex) +{ + struct svga_texture *stex = svga_texture(surf->texture); + struct svga_surface *s = svga_surface(surf); + + return (stex == tex && s->handle != tex->handle); +} + + +/** + * Make sure the texture resource is up-to-date. If the texture is + * currently bound to a render target view and a backing resource is + * created, we will need to update the original resource with the + * changes in the backing resource. + */ +static void +svga_validate_texture_resource(struct svga_context *svga, + struct svga_texture *tex) +{ + if (svga_was_texture_rendered_to(tex) == false) + return; + + if ((svga->state.hw_draw.has_backed_views == false) || + (tex->backed_handle == NULL)) + return; + + struct pipe_surface *s; + for (unsigned i = 0; i < svga->state.hw_clear.num_rendertargets; i++) { + s = svga->state.hw_clear.rtv[i]; + if (s && need_update_texture_resource(s, tex)) + svga_propagate_surface(svga, s, true); + } + + s = svga->state.hw_clear.dsv; + if (s && need_update_texture_resource(s, tex)) + svga_propagate_surface(svga, s, true); +} + + /** * Use upload buffer for the transfer map request. */ @@ -1355,6 +1401,7 @@ svga_texture_transfer_map_upload(struct svga_context *svga, { struct pipe_resource *texture = st->base.resource; struct pipe_resource *tex_buffer = NULL; + struct svga_texture *tex = svga_texture(texture); void *tex_map; unsigned nblocksx, nblocksy; unsigned offset; @@ -1362,6 +1409,14 @@ svga_texture_transfer_map_upload(struct svga_context *svga, assert(svga->tex_upload); + /* Validate the texture resource in case there is any changes + * in the backing resource that needs to be updated to the original + * texture resource first before the transfer upload occurs, otherwise, + * the later update from backing resource to original will overwrite the + * changes in this transfer map update. + */ + svga_validate_texture_resource(svga, tex); + st->upload.box.x = st->base.box.x; st->upload.box.y = st->base.box.y; st->upload.box.z = st->base.box.z; @@ -1407,7 +1462,6 @@ svga_texture_transfer_map_upload(struct svga_context *svga, #ifdef DEBUG if (util_format_is_compressed(texture->format)) { - struct svga_texture *tex = svga_texture(texture); unsigned blockw, blockh, bytesPerBlock; svga_format_size(tex->key.format, &blockw, &blockh, &bytesPerBlock); diff --git a/src/gallium/drivers/svga/svga_surface.h b/src/gallium/drivers/svga/svga_surface.h index b2745f44dfe..48ad4b406fd 100644 --- a/src/gallium/drivers/svga/svga_surface.h +++ b/src/gallium/drivers/svga/svga_surface.h @@ -1,5 +1,5 @@ /********************************************************** - * Copyright 2008-2009 VMware, Inc. All rights reserved. + * Copyright 2008-2023 VMware, Inc. All rights reserved. * * Permission is hereby granted, free of charge, to any person * obtaining a copy of this software and associated documentation @@ -142,6 +142,10 @@ svga_surface_const(const struct pipe_surface *surface) struct pipe_surface * svga_validate_surface_view(struct svga_context *svga, struct svga_surface *s); +void +svga_propagate_surface(struct svga_context *svga, struct pipe_surface *surf, + bool reset); + static inline SVGA3dResourceType svga_resource_type(enum pipe_texture_target target) {