From 9fdfa9d9bbca09697efa0bc1e40ed13a978f716a Mon Sep 17 00:00:00 2001 From: Charmaine Lee Date: Tue, 14 Feb 2023 03:47:39 +0200 Subject: [PATCH] svga: use upload buffer if texture has pending changes When establishing a texture transfer map, if there is any pending changes on the texture, instead of trying direct map with DONTBLOCK first, just use the upload buffer path. Fixes piglit tests gen-teximages, arb_copy_images-formats Cc: mesa-stable Reviewed-by: Neha Bhende Part-of: (cherry picked from commit 1b9b060f0eee19da426daffe37de30a9200b15b2) --- .pick_status.json | 2 +- .../drivers/svga/svga_resource_texture.c | 11 ++++++----- .../drivers/svga/svga_resource_texture.h | 19 ++++++++++++++++--- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/.pick_status.json b/.pick_status.json index 62b52a9702f..c58741cde52 100644 --- a/.pick_status.json +++ b/.pick_status.json @@ -256,7 +256,7 @@ "description": "svga: use upload buffer if texture has pending changes", "nominated": true, "nomination_type": 0, - "resolution": 0, + "resolution": 1, "main_sha": null, "because_sha": null }, diff --git a/src/gallium/drivers/svga/svga_resource_texture.c b/src/gallium/drivers/svga/svga_resource_texture.c index 38f32ce3b84..3a5c744540e 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.c +++ b/src/gallium/drivers/svga/svga_resource_texture.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 @@ -357,7 +357,7 @@ svga_texture_transfer_map_direct(struct svga_context *svga, else { assert(usage & PIPE_MAP_WRITE); if ((usage & PIPE_MAP_UNSYNCHRONIZED) == 0) { - if (svga_is_texture_dirty(tex, st->slice, level)) { + if (svga_is_texture_level_dirty(tex, st->slice, level)) { /* * do a surface flush if the subresource has been modified * in this command buffer. @@ -567,14 +567,15 @@ svga_texture_transfer_map(struct pipe_context *pipe, !(st->base.usage & PIPE_MAP_READ); boolean was_rendered_to = svga_was_texture_rendered_to(svga_texture(texture)); + boolean is_dirty = svga_is_texture_dirty(svga_texture(texture)); - /* If the texture was already rendered to and upload buffer - * is supported, then we will use upload buffer to + /* If the texture was already rendered to or has pending changes and + * upload buffer is supported, then we will use upload buffer to * avoid the need to read back the texture content; otherwise, * we'll first try to map directly to the GB surface, if it is blocked, * then we'll try the upload buffer. */ - if (was_rendered_to && can_use_upload) { + if ((was_rendered_to || is_dirty) && can_use_upload) { map = svga_texture_transfer_map_upload(svga, st); } else { diff --git a/src/gallium/drivers/svga/svga_resource_texture.h b/src/gallium/drivers/svga/svga_resource_texture.h index e1872faad61..32b42dd0ee7 100644 --- a/src/gallium/drivers/svga/svga_resource_texture.h +++ b/src/gallium/drivers/svga/svga_resource_texture.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 @@ -85,6 +85,11 @@ struct svga_texture */ boolean can_use_upload; + /** + * Whether texture is modified. Set if any of the dirty bits is set. + */ + boolean modified; + unsigned size; /**< Approximate size in bytes */ /** array indexed by cube face or 3D/array slice, one bit per mipmap level */ @@ -242,6 +247,7 @@ svga_set_texture_dirty(struct svga_texture *tex, { check_face_level(tex, face, level); tex->dirty[face] |= 1 << level; + tex->modified = TRUE; } static inline void @@ -251,16 +257,23 @@ svga_clear_texture_dirty(struct svga_texture *tex) for (i = 0; i < tex->b.depth0 * tex->b.array_size; i++) { tex->dirty[i] = 0; } + tex->modified = FALSE; } static inline boolean -svga_is_texture_dirty(const struct svga_texture *tex, - unsigned face, unsigned level) +svga_is_texture_level_dirty(const struct svga_texture *tex, + unsigned face, unsigned level) { check_face_level(tex, face, level); return !!(tex->dirty[face] & (1 << level)); } +static inline boolean +svga_is_texture_dirty(const struct svga_texture *tex) +{ + return tex->modified; +} + struct pipe_resource * svga_texture_create(struct pipe_screen *screen, const struct pipe_resource *template);