summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Anholt <[email protected]>2017-07-27 18:11:19 -0700
committerEric Anholt <[email protected]>2017-09-26 14:49:43 -0700
commit68c91a87d73cfcd947e09803ceb800b50bf9e399 (patch)
treed69de616cf379a03bd166c4167aa17e1d390a7e5
parent4b407a62c757c8344736caa200e706d2bd66fb2c (diff)
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")
-rw-r--r--src/gallium/drivers/vc4/vc4_context.h7
-rw-r--r--src/gallium/drivers/vc4/vc4_draw.c9
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.c15
-rw-r--r--src/gallium/drivers/vc4/vc4_resource.h14
-rw-r--r--src/gallium/drivers/vc4/vc4_state.c34
-rw-r--r--src/gallium/drivers/vc4/vc4_uniforms.c2
6 files changed, 42 insertions, 39 deletions
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);
}