On Tue, Jun 7, 2016 at 7:00 PM, Nicolai Hähnle <nhaeh...@gmail.com> wrote: > From: Nicolai Hähnle <nicolai.haeh...@amd.com> > > The width0/height0/depth0 on stObj may not have been set at this point. > Observed in a trace that set up levels 2..9 of a 2d texture, and set the base > level to 2, with height 1. This made the guess logic always bail. > > Originally investigated by Ilia Mirkin, this patch gets rid of the somewhat > redundant storage of width0/height0/depth0 and makes sure we always compute > pipe texture sizes that are compatible with the base level image of the > GL texture. > > Fixes the gl-1.2-texture-base-level piglit test provided by Brian Paul. > > v2: > - try to re-use an existing pipe texture when possible > - handle a corner case where the base level is not level 0 and it is of > size 1x1x1 > > Cc: "12.0" <mesa-sta...@lists.freedesktop.org> > -- > Tested with Piglit on radeonsi, no change except for the > gl-1.2-texture-base-level test. > --- > src/mesa/state_tracker/st_cb_eglimage.c | 3 -- > src/mesa/state_tracker/st_cb_texture.c | 86 > ++++++++++++++++++--------------- > src/mesa/state_tracker/st_manager.c | 3 -- > src/mesa/state_tracker/st_texture.h | 6 --- > src/mesa/state_tracker/st_vdpau.c | 3 -- > 5 files changed, 48 insertions(+), 53 deletions(-) > > diff --git a/src/mesa/state_tracker/st_cb_eglimage.c > b/src/mesa/state_tracker/st_cb_eglimage.c > index 8531afb..1782d15 100644 > --- a/src/mesa/state_tracker/st_cb_eglimage.c > +++ b/src/mesa/state_tracker/st_cb_eglimage.c > @@ -128,9 +128,6 @@ st_bind_surface(struct gl_context *ctx, GLenum target, > st_texture_release_all_sampler_views(st, stObj); > pipe_resource_reference(&stImage->pt, stObj->pt); > > - stObj->width0 = ps->width; > - stObj->height0 = ps->height; > - stObj->depth0 = 1; > stObj->surface_format = ps->format; > > _mesa_dirty_texobj(ctx, texObj); > diff --git a/src/mesa/state_tracker/st_cb_texture.c > b/src/mesa/state_tracker/st_cb_texture.c > index 44e21b1..3a3d6b9 100644 > --- a/src/mesa/state_tracker/st_cb_texture.c > +++ b/src/mesa/state_tracker/st_cb_texture.c > @@ -493,7 +493,6 @@ guess_and_alloc_texture(struct st_context *st, > > if (!guessed_box) { > /* we can't determine the image size at level=0 */ > - stObj->width0 = stObj->height0 = stObj->depth0 = 0; > /* this is not an out of memory error */ > return GL_TRUE; > } > @@ -518,11 +517,6 @@ guess_and_alloc_texture(struct st_context *st, > lastLevel = 0; > } > > - /* Save the level=0 dimensions */ > - stObj->width0 = width; > - stObj->height0 = height; > - stObj->depth0 = depth; > - > fmt = st_mesa_format_to_pipe_format(st, stImage->base.TexFormat); > > bindings = default_bindings(st, fmt); > @@ -2443,9 +2437,6 @@ st_finalize_texture(struct gl_context *ctx, > if (st_obj->buffer != stObj->pt) { > pipe_resource_reference(&stObj->pt, st_obj->buffer); > st_texture_release_all_sampler_views(st, stObj); > - stObj->width0 = stObj->pt->width0 / > _mesa_get_format_bytes(tObj->_BufferObjectFormat); > - stObj->height0 = 1; > - stObj->depth0 = 1; > } > return GL_TRUE; > > @@ -2478,25 +2469,44 @@ st_finalize_texture(struct gl_context *ctx, > /* Find size of level=0 Gallium mipmap image, plus number of texture > layers */ > { > GLuint width, height, depth; > - if (!guess_base_level_size(stObj->base.Target, > - firstImage->base.Width2, > - firstImage->base.Height2, > - firstImage->base.Depth2, > - firstImage->base.Level, > - &width, &height, &depth)) { > - width = stObj->width0; > - height = stObj->height0; > - depth = stObj->depth0; > + > + st_gl_texture_dims_to_pipe_dims(stObj->base.Target, > + firstImage->base.Width2, > + firstImage->base.Height2, > + firstImage->base.Depth2, > + &width, &height, &depth, &ptLayers); > + > + /* If we previously allocated a pipe texture and its sizes are > + * compatible, use them. > + */ > + if (stObj->pt && > + u_minify(stObj->pt->width0, firstImage->base.Level) == width && > + u_minify(stObj->pt->height0, firstImage->base.Level) == height && > + u_minify(stObj->pt->depth0, firstImage->base.Level) == depth) { > + ptWidth = stObj->pt->width0; > + ptHeight = stObj->pt->height0; > + ptDepth = stObj->pt->depth0; > } else { > - /* The width/height/depth may have been previously reset in > - * guess_and_alloc_texture. */ > - stObj->width0 = width; > - stObj->height0 = height; > - stObj->depth0 = depth; > + /* Otherwise, compute a new level=0 size that is compatible with the > + * base level image. > + */ > + ptWidth = width > 1 ? width << firstImage->base.Level : 1; > + ptHeight = height > 1 ? height << firstImage->base.Level : 1; > + ptDepth = depth > 1 ? depth << firstImage->base.Level : 1; > + > + /* If the base level image is 1x1x1, we still need to ensure that > the > + * resulting pipe texture ends up with the required number of levels > + * in total. > + */ > + if (ptWidth == 1 && ptHeight == 1 && ptDepth == 1) { > + ptWidth <<= firstImage->base.Level; > + > + if (stObj->base.Target == GL_TEXTURE_CUBE_MAP || > + stObj->base.Target == GL_TEXTURE_CUBE_MAP_ARRAY) > + ptHeight <<= firstImage->base.Level; > + } > } > - /* convert GL dims to Gallium dims */ > - st_gl_texture_dims_to_pipe_dims(stObj->base.Target, width, height, > depth, > - &ptWidth, &ptHeight, &ptDepth, > &ptLayers); > + > ptNumSamples = firstImage->base.NumSamples; > } > > @@ -2554,16 +2564,23 @@ st_finalize_texture(struct gl_context *ctx, > /* Need to import images in main memory or held in other textures. > */ > if (stImage && stObj->pt != stImage->pt) { > - GLuint height = stObj->height0; > - GLuint depth = stObj->depth0; > + GLuint height; > + GLuint depth; > > if (stObj->base.Target != GL_TEXTURE_1D_ARRAY) > - height = u_minify(height, level); > + height = u_minify(ptHeight, level); > + else > + height = ptLayers; > + > if (stObj->base.Target == GL_TEXTURE_3D) > - depth = u_minify(depth, level); > + depth = u_minify(ptDepth, level); > + else if (stObj->base.Target == GL_TEXTURE_CUBE_MAP) > + depth = 1;
Should this be 6? If not, should you divide ptLayers by 6 for CUBE_MAP_ARRAY? [haven't carefully grok'd what you're doing... just observed this inconsistency] > + else > + depth = ptLayers; > > if (level == 0 || > - (stImage->base.Width == u_minify(stObj->width0, level) && > + (stImage->base.Width == u_minify(ptWidth, level) && > stImage->base.Height == height && > stImage->base.Depth == depth)) { > /* src image fits expected dest mipmap level size */ > @@ -2599,10 +2616,6 @@ st_AllocTextureStorage(struct gl_context *ctx, > > assert(levels > 0); > > - /* Save the level=0 dimensions */ > - stObj->width0 = width; > - stObj->height0 = height; > - stObj->depth0 = depth; > stObj->lastLevel = levels - 1; > > fmt = st_mesa_format_to_pipe_format(st, texImage->TexFormat); > @@ -2740,9 +2753,6 @@ st_TextureView(struct gl_context *ctx, > tex->surface_format = > st_mesa_format_to_pipe_format(st_context(ctx), image->TexFormat); > > - tex->width0 = image->Width; > - tex->height0 = image->Height; > - tex->depth0 = image->Depth; > tex->lastLevel = numLevels - 1; > > return GL_TRUE; > diff --git a/src/mesa/state_tracker/st_manager.c > b/src/mesa/state_tracker/st_manager.c > index a983d64..33f56ea 100644 > --- a/src/mesa/state_tracker/st_manager.c > +++ b/src/mesa/state_tracker/st_manager.c > @@ -587,9 +587,6 @@ st_context_teximage(struct st_context_iface *stctxi, > } > > pipe_resource_reference(&stImage->pt, tex); > - stObj->width0 = width; > - stObj->height0 = height; > - stObj->depth0 = depth; > stObj->surface_format = pipe_format; > > _mesa_dirty_texobj(ctx, texObj); > diff --git a/src/mesa/state_tracker/st_texture.h > b/src/mesa/state_tracker/st_texture.h > index d8cd7c7..ae9e2b4 100644 > --- a/src/mesa/state_tracker/st_texture.h > +++ b/src/mesa/state_tracker/st_texture.h > @@ -79,12 +79,6 @@ struct st_texture_object > */ > GLuint lastLevel; > > - /** The size of the level=0 mipmap image. > - * Note that the number of 1D array layers will be in height0 and the > - * number of 2D array layers will be in depth0, as in GL. > - */ > - GLuint width0, height0, depth0; > - > /* On validation any active images held in main memory or in other > * textures will be copied to this texture and the old storage freed. > */ > diff --git a/src/mesa/state_tracker/st_vdpau.c > b/src/mesa/state_tracker/st_vdpau.c > index 08f2553..dffa52f 100644 > --- a/src/mesa/state_tracker/st_vdpau.c > +++ b/src/mesa/state_tracker/st_vdpau.c > @@ -238,9 +238,6 @@ st_vdpau_map_surface(struct gl_context *ctx, GLenum > target, GLenum access, > sampler_view = st_texture_get_sampler_view(st, stObj); > *sampler_view = st->pipe->create_sampler_view(st->pipe, res, &templ); > > - stObj->width0 = res->width0; > - stObj->height0 = res->height0; > - stObj->depth0 = 1; > stObj->surface_format = res->format; > > _mesa_dirty_texobj(ctx, texObj); > -- > 2.7.4 > > _______________________________________________ > mesa-dev mailing list > mesa-dev@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/mesa-dev _______________________________________________ mesa-dev mailing list mesa-dev@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/mesa-dev