From: Eric Anholt Date: Fri, 28 Jul 2017 01:11:19 +0000 (-0700) Subject: broadcom/vc4: Keep pipe_sampler_view->texture matching the original texture. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=68c91a87d73cfcd947e09803ceb800b50bf9e399;p=mesa.git broadcom/vc4: Keep pipe_sampler_view->texture matching the original texture. I was overwriting view->texture with the shadow resource when we need to do shadow copies (retiling or baselevel rebase), but that tripped up some critical new sanity checking in state_tracker (making sure that stObj->pt hasn't changed from view->texture through TexImage-related paths). To avoid that, move the shadow resource to the vc4_sampler_view struct. Fixes: f0ecd36ef8e1 ("st/mesa: add an entirely separate codepath for setting up buffer views") --- diff --git a/src/gallium/drivers/vc4/vc4_context.h b/src/gallium/drivers/vc4/vc4_context.h index efc37e849ee..99ec7e5d2e8 100644 --- a/src/gallium/drivers/vc4/vc4_context.h +++ b/src/gallium/drivers/vc4/vc4_context.h @@ -84,6 +84,13 @@ struct vc4_sampler_view { uint32_t texture_p0; uint32_t texture_p1; bool force_first_level; + /** + * Resource containing the actual texture that will be sampled. + * + * We may need to rebase the .base.texture resource to work around the + * lack of GL_TEXTURE_BASE_LEVEL, or to upload the texture as tiled. + */ + struct pipe_resource *texture; }; struct vc4_sampler_state { diff --git a/src/gallium/drivers/vc4/vc4_draw.c b/src/gallium/drivers/vc4/vc4_draw.c index da748cdc14d..1370867293f 100644 --- a/src/gallium/drivers/vc4/vc4_draw.c +++ b/src/gallium/drivers/vc4/vc4_draw.c @@ -116,12 +116,13 @@ vc4_predraw_check_textures(struct pipe_context *pctx, struct vc4_context *vc4 = vc4_context(pctx); for (int i = 0; i < stage_tex->num_textures; i++) { - struct pipe_sampler_view *view = stage_tex->textures[i]; + struct vc4_sampler_view *view = + vc4_sampler_view(stage_tex->textures[i]); if (!view) continue; - struct vc4_resource *rsc = vc4_resource(view->texture); - if (rsc->shadow_parent) - vc4_update_shadow_baselevel_texture(pctx, view); + + if (view->texture != view->base.texture) + vc4_update_shadow_baselevel_texture(pctx, &view->base); vc4_flush_jobs_writing_resource(vc4, view->texture); } diff --git a/src/gallium/drivers/vc4/vc4_resource.c b/src/gallium/drivers/vc4/vc4_resource.c index 2018dc36d93..853f7bbfa17 100644 --- a/src/gallium/drivers/vc4/vc4_resource.c +++ b/src/gallium/drivers/vc4/vc4_resource.c @@ -373,7 +373,6 @@ vc4_resource_destroy(struct pipe_screen *pscreen, { struct vc4_screen *screen = vc4_screen(pscreen); struct vc4_resource *rsc = vc4_resource(prsc); - pipe_resource_reference(&rsc->shadow_parent, NULL); vc4_bo_unreference(&rsc->bo); if (rsc->scanout) @@ -1078,19 +1077,21 @@ vc4_flush_resource(struct pipe_context *pctx, struct pipe_resource *resource) void vc4_update_shadow_baselevel_texture(struct pipe_context *pctx, - struct pipe_sampler_view *view) + struct pipe_sampler_view *pview) { + struct vc4_sampler_view *view = vc4_sampler_view(pview); struct vc4_resource *shadow = vc4_resource(view->texture); - struct vc4_resource *orig = vc4_resource(shadow->shadow_parent); - assert(orig); + struct vc4_resource *orig = vc4_resource(pview->texture); + + assert(view->texture != pview->texture); if (shadow->writes == orig->writes && orig->bo->private) return; perf_debug("Updating %dx%d@%d shadow texture due to %s\n", orig->base.width0, orig->base.height0, - view->u.tex.first_level, - view->u.tex.first_level ? "base level" : "raster layout"); + pview->u.tex.first_level, + pview->u.tex.first_level ? "base level" : "raster layout"); for (int i = 0; i <= shadow->base.last_level; i++) { unsigned width = u_minify(shadow->base.width0, i); @@ -1111,7 +1112,7 @@ vc4_update_shadow_baselevel_texture(struct pipe_context *pctx, }, .src = { .resource = &orig->base, - .level = view->u.tex.first_level + i, + .level = pview->u.tex.first_level + i, .box = { .x = 0, .y = 0, diff --git a/src/gallium/drivers/vc4/vc4_resource.h b/src/gallium/drivers/vc4/vc4_resource.h index 32e73dddb34..d4c491e50b8 100644 --- a/src/gallium/drivers/vc4/vc4_resource.h +++ b/src/gallium/drivers/vc4/vc4_resource.h @@ -81,20 +81,6 @@ struct vc4_resource { * buffer) may get marked. */ uint32_t initialized_buffers; - - /** - * Resource containing the non-GL_TEXTURE_BASE_LEVEL-rebased texture - * contents, or the 4-byte index buffer. - * - * If the parent is set for an texture, then this resource is actually - * the texture contents just starting from the sampler_view's - * first_level. - * - * If the parent is set for an index index buffer, then this resource - * is actually a shadow containing a 2-byte index buffer starting from - * the ib's offset. - */ - struct pipe_resource *shadow_parent; }; static inline struct vc4_resource * diff --git a/src/gallium/drivers/vc4/vc4_state.c b/src/gallium/drivers/vc4/vc4_state.c index 9a3438f8493..d6d44793e38 100644 --- a/src/gallium/drivers/vc4/vc4_state.c +++ b/src/gallium/drivers/vc4/vc4_state.c @@ -556,6 +556,9 @@ vc4_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, so->base = *cso; pipe_reference(NULL, &prsc->reference); + so->base.texture = prsc; + so->base.reference.count = 1; + so->base.context = pctx; /* There is no hardware level clamping, and the start address of a * texture may be misaligned, so in that case we have to copy to a @@ -567,33 +570,36 @@ vc4_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, if ((cso->u.tex.first_level && (cso->u.tex.first_level != cso->u.tex.last_level)) || rsc->vc4_format == VC4_TEXTURE_TYPE_RGBA32R) { - struct vc4_resource *shadow_parent = vc4_resource(prsc); - struct pipe_resource tmpl = shadow_parent->base; - struct vc4_resource *clone; + struct vc4_resource *shadow_parent = rsc; + struct pipe_resource tmpl = *prsc; tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET; tmpl.width0 = u_minify(tmpl.width0, cso->u.tex.first_level); tmpl.height0 = u_minify(tmpl.height0, cso->u.tex.first_level); tmpl.last_level = cso->u.tex.last_level - cso->u.tex.first_level; + /* Create the shadow texture. The rest of the texture + * parameter setup will use the shadow. + */ prsc = vc4_resource_create(pctx->screen, &tmpl); if (!prsc) { free(so); return NULL; } rsc = vc4_resource(prsc); - clone = vc4_resource(prsc); - clone->shadow_parent = &shadow_parent->base; + /* Flag it as needing update of the contents from the parent. */ - clone->writes = shadow_parent->writes - 1; + rsc->writes = shadow_parent->writes - 1; + assert(rsc->vc4_format != VC4_TEXTURE_TYPE_RGBA32R); - assert(clone->vc4_format != VC4_TEXTURE_TYPE_RGBA32R); - } else if (cso->u.tex.first_level) { - so->force_first_level = true; + so->texture = prsc; + } else { + pipe_resource_reference(&so->texture, prsc); + + if (cso->u.tex.first_level) { + so->force_first_level = true; + } } - so->base.texture = prsc; - so->base.reference.count = 1; - so->base.context = pctx; so->texture_p0 = (VC4_SET_FIELD(rsc->slices[0].offset >> 12, VC4_TEX_P0_OFFSET) | @@ -617,8 +623,10 @@ vc4_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc, static void vc4_sampler_view_destroy(struct pipe_context *pctx, - struct pipe_sampler_view *view) + struct pipe_sampler_view *pview) { + struct vc4_sampler_view *view = vc4_sampler_view(pview); + pipe_resource_reference(&pview->texture, NULL); pipe_resource_reference(&view->texture, NULL); free(view); } diff --git a/src/gallium/drivers/vc4/vc4_uniforms.c b/src/gallium/drivers/vc4/vc4_uniforms.c index 07781b8524e..b8169347fed 100644 --- a/src/gallium/drivers/vc4/vc4_uniforms.c +++ b/src/gallium/drivers/vc4/vc4_uniforms.c @@ -35,7 +35,7 @@ write_texture_p0(struct vc4_job *job, { struct vc4_sampler_view *sview = vc4_sampler_view(texstate->textures[unit]); - struct vc4_resource *rsc = vc4_resource(sview->base.texture); + struct vc4_resource *rsc = vc4_resource(sview->texture); cl_reloc(job, &job->uniforms, uniforms, rsc->bo, sview->texture_p0); }