mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-08 04:48:08 +02:00
svga: sync resource content from backing resource before image upload
When a backing resource is created for a render target view when the same resource is currently bound to a shader resource view, the content update back to the original resource happens when the associated render target view is unbound. But state update only happens at clear or draw time. So if TexSubImage happens after BindFrameBuffer and before Draw, the original texture resource that is mapped to for subimage update would not have been updated. As a matter of fact at the subsequent state update at the next draw, the render target views will be updated, the content from the previous backing resource will be propogated to the original resource, hence overwriting the changes from the last TexSubImage. To fix the problem, this patch validates the texture resource, updates any pending changes from the backing resource before transfer map upload occurs. Fixes the rendering issue demonstrated from the fbo_texsubimage_update trace Reviewed-by: Martin Krastev <krastevm@vmware.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/25386>
This commit is contained in:
parent
83c76cceaf
commit
25c771a778
3 changed files with 66 additions and 12 deletions
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue