broadcom/vc4: Keep pipe_sampler_view->texture matching the original texture.
authorEric Anholt <eric@anholt.net>
Fri, 28 Jul 2017 01:11:19 +0000 (18:11 -0700)
committerEric Anholt <eric@anholt.net>
Tue, 26 Sep 2017 21:49:43 +0000 (14:49 -0700)
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")
src/gallium/drivers/vc4/vc4_context.h
src/gallium/drivers/vc4/vc4_draw.c
src/gallium/drivers/vc4/vc4_resource.c
src/gallium/drivers/vc4/vc4_resource.h
src/gallium/drivers/vc4/vc4_state.c
src/gallium/drivers/vc4/vc4_uniforms.c

index efc37e849ee968daa3e710e3ce101f2686cdb483..99ec7e5d2e827a7af22f23f89555ffdb4ad40484 100644 (file)
@@ -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 {
index da748cdc14d5eeb6c159aee8af47534f0470b7f6..1370867293f7dd6d0549a995501c5b5fc09ebbf0 100644 (file)
@@ -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);
         }
index 2018dc36d93bf109b2ab4e7f712822d2d93c08cb..853f7bbfa17ddf25e9b7b5f63b37dca43c9f1011 100644 (file)
@@ -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,
index 32e73dddb34a5c84edd6db54977b09c2e854bf13..d4c491e50b86389e2a8b7422c30c3fb1f0aa4f7c 100644 (file)
@@ -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 *
index 9a3438f8493564b6d340c7df7249b868f6bb4268..d6d44793e383bdaf400a1178271fb88fb14d5505 100644 (file)
@@ -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);
 }
index 07781b8524ea960ffc328b941382234c2595a1dd..b8169347fedd1b9678d8922e3ff847aa6ebc29af 100644 (file)
@@ -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);
 }