summaryrefslogtreecommitdiffstats
path: root/src/gallium/drivers/svga
diff options
context:
space:
mode:
authorCharmaine Lee <[email protected]>2017-04-04 13:02:45 -0600
committerBrian Paul <[email protected]>2017-04-07 13:46:43 -0600
commitab96d1baf40d67b4ea9e685e4f5ea5c90f77d269 (patch)
tree0305661984c2dc861479856a5eb9b22fbc96e783 /src/gallium/drivers/svga
parenta08e3b88ab71b147145f60e56ce02392437c6866 (diff)
svga: Fix out-of-sync backing surface
When a backing surface is reused, it is possible that the original surface has been changed. So before the backing surface is bound again, we need to sync up the surface. This patch creates a new helper function svga_texture_copy_handle_resource() to sync up the backing surface resource. This patch, together with the backing surface dirty bit fix, fixes the rendering corruption in NobelClinicianViewer when rotating the model. Also tested with MTT glretrace, piglit, Cinebench, Turbine. Reviewed-by: Brian Paul <[email protected]>
Diffstat (limited to 'src/gallium/drivers/svga')
-rw-r--r--src/gallium/drivers/svga/svga_surface.c91
1 files changed, 70 insertions, 21 deletions
diff --git a/src/gallium/drivers/svga/svga_surface.c b/src/gallium/drivers/svga/svga_surface.c
index 846acccacec..18bce3467fd 100644
--- a/src/gallium/drivers/svga/svga_surface.c
+++ b/src/gallium/drivers/svga/svga_surface.c
@@ -103,6 +103,43 @@ svga_texture_copy_handle(struct svga_context *svga,
}
+/* A helper function to sync up the two surface handles.
+ */
+static void
+svga_texture_copy_handle_resource(struct svga_context *svga,
+ struct svga_texture *src_tex,
+ struct svga_winsys_surface *dst,
+ unsigned int numMipLevels,
+ unsigned int numLayers,
+ unsigned int zoffset,
+ unsigned int mipoffset,
+ unsigned int layeroffset)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < numMipLevels; i++) {
+ unsigned int miplevel = i + mipoffset;
+
+ for (j = 0; j < numLayers; j++) {
+ if (svga_is_texture_level_defined(src_tex, j+layeroffset, miplevel)) {
+ unsigned depth = (zoffset < 0 ?
+ u_minify(src_tex->b.b.depth0, miplevel) : 1);
+
+ svga_texture_copy_handle(svga,
+ src_tex->handle,
+ 0, 0, zoffset,
+ miplevel,
+ j + layeroffset,
+ dst, 0, 0, 0, i, j,
+ u_minify(src_tex->b.b.width0, miplevel),
+ u_minify(src_tex->b.b.height0, miplevel),
+ depth);
+ }
+ }
+ }
+}
+
+
struct svga_winsys_surface *
svga_texture_view_surface(struct svga_context *svga,
struct svga_texture *tex,
@@ -118,7 +155,6 @@ svga_texture_view_surface(struct svga_context *svga,
{
struct svga_screen *ss = svga_screen(svga->pipe.screen);
struct svga_winsys_surface *handle;
- uint32_t i, j;
unsigned z_offset = 0;
boolean validated;
@@ -172,25 +208,10 @@ svga_texture_view_surface(struct svga_context *svga,
if (zslice_pick >= 0)
z_offset = zslice_pick;
- for (i = 0; i < key->numMipLevels; i++) {
- for (j = 0; j < key->numFaces * key->arraySize; j++) {
- if (svga_is_texture_level_defined(tex, j + layer_pick, i + start_mip)) {
- unsigned depth = (zslice_pick < 0 ?
- u_minify(tex->b.b.depth0, i + start_mip) :
- 1);
-
- svga_texture_copy_handle(svga,
- tex->handle,
- 0, 0, z_offset,
- i + start_mip,
- j + layer_pick,
- handle, 0, 0, 0, i, j,
- u_minify(tex->b.b.width0, i + start_mip),
- u_minify(tex->b.b.height0, i + start_mip),
- depth);
- }
- }
- }
+ svga_texture_copy_handle_resource(svga, tex, handle,
+ key->numMipLevels,
+ key->numFaces * key->arraySize,
+ z_offset, start_mip, layer_pick);
return handle;
}
@@ -374,11 +395,12 @@ svga_create_surface(struct pipe_context *pipe,
static struct svga_surface *
create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
{
+ struct svga_texture *tex = svga_texture(s->base.texture);
+
SVGA_STATS_TIME_PUSH(svga_sws(svga),
SVGA_STATS_TIME_CREATEBACKEDSURFACEVIEW);
if (!s->backed) {
- struct svga_texture *tex = svga_texture(s->base.texture);
struct pipe_surface *backed_view;
backed_view = svga_create_surface_view(&svga->pipe,
@@ -390,6 +412,33 @@ create_backed_surface_view(struct svga_context *svga, struct svga_surface *s)
s->backed = svga_surface(backed_view);
}
+ else {
+ /*
+ * There is already an existing backing surface, but we still need to
+ * sync the handles.
+ */
+ struct svga_surface *bs = s->backed;
+ unsigned int layer, zslice;
+
+ assert(bs->handle);
+
+ switch (tex->b.b.target) {
+ case PIPE_TEXTURE_CUBE:
+ case PIPE_TEXTURE_1D_ARRAY:
+ case PIPE_TEXTURE_2D_ARRAY:
+ layer = s->base.u.tex.first_layer;
+ zslice = 0;
+ break;
+ default:
+ layer = 0;
+ zslice = s->base.u.tex.first_layer;
+ }
+
+ svga_texture_copy_handle_resource(svga, tex, bs->handle,
+ bs->key.numMipLevels,
+ bs->key.numFaces * bs->key.arraySize,
+ zslice, s->base.u.tex.level, layer);
+ }
svga_mark_surface_dirty(&s->backed->base);