From ab96d1baf40d67b4ea9e685e4f5ea5c90f77d269 Mon Sep 17 00:00:00 2001 From: Charmaine Lee Date: Tue, 4 Apr 2017 13:02:45 -0600 Subject: [PATCH] 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 --- src/gallium/drivers/svga/svga_surface.c | 91 +++++++++++++++++++------ 1 file 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); -- 2.30.2