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: f0ecd36ef8
("st/mesa: add an entirely separate codepath for setting up buffer views")
This commit is contained in:
parent
4b407a62c7
commit
68c91a87d7
|
@ -84,6 +84,13 @@ struct vc4_sampler_view {
|
||||||
uint32_t texture_p0;
|
uint32_t texture_p0;
|
||||||
uint32_t texture_p1;
|
uint32_t texture_p1;
|
||||||
bool force_first_level;
|
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 {
|
struct vc4_sampler_state {
|
||||||
|
|
|
@ -116,12 +116,13 @@ vc4_predraw_check_textures(struct pipe_context *pctx,
|
||||||
struct vc4_context *vc4 = vc4_context(pctx);
|
struct vc4_context *vc4 = vc4_context(pctx);
|
||||||
|
|
||||||
for (int i = 0; i < stage_tex->num_textures; i++) {
|
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)
|
if (!view)
|
||||||
continue;
|
continue;
|
||||||
struct vc4_resource *rsc = vc4_resource(view->texture);
|
|
||||||
if (rsc->shadow_parent)
|
if (view->texture != view->base.texture)
|
||||||
vc4_update_shadow_baselevel_texture(pctx, view);
|
vc4_update_shadow_baselevel_texture(pctx, &view->base);
|
||||||
|
|
||||||
vc4_flush_jobs_writing_resource(vc4, view->texture);
|
vc4_flush_jobs_writing_resource(vc4, view->texture);
|
||||||
}
|
}
|
||||||
|
|
|
@ -373,7 +373,6 @@ vc4_resource_destroy(struct pipe_screen *pscreen,
|
||||||
{
|
{
|
||||||
struct vc4_screen *screen = vc4_screen(pscreen);
|
struct vc4_screen *screen = vc4_screen(pscreen);
|
||||||
struct vc4_resource *rsc = vc4_resource(prsc);
|
struct vc4_resource *rsc = vc4_resource(prsc);
|
||||||
pipe_resource_reference(&rsc->shadow_parent, NULL);
|
|
||||||
vc4_bo_unreference(&rsc->bo);
|
vc4_bo_unreference(&rsc->bo);
|
||||||
|
|
||||||
if (rsc->scanout)
|
if (rsc->scanout)
|
||||||
|
@ -1078,19 +1077,21 @@ vc4_flush_resource(struct pipe_context *pctx, struct pipe_resource *resource)
|
||||||
|
|
||||||
void
|
void
|
||||||
vc4_update_shadow_baselevel_texture(struct pipe_context *pctx,
|
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 *shadow = vc4_resource(view->texture);
|
||||||
struct vc4_resource *orig = vc4_resource(shadow->shadow_parent);
|
struct vc4_resource *orig = vc4_resource(pview->texture);
|
||||||
assert(orig);
|
|
||||||
|
assert(view->texture != pview->texture);
|
||||||
|
|
||||||
if (shadow->writes == orig->writes && orig->bo->private)
|
if (shadow->writes == orig->writes && orig->bo->private)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
perf_debug("Updating %dx%d@%d shadow texture due to %s\n",
|
perf_debug("Updating %dx%d@%d shadow texture due to %s\n",
|
||||||
orig->base.width0, orig->base.height0,
|
orig->base.width0, orig->base.height0,
|
||||||
view->u.tex.first_level,
|
pview->u.tex.first_level,
|
||||||
view->u.tex.first_level ? "base level" : "raster layout");
|
pview->u.tex.first_level ? "base level" : "raster layout");
|
||||||
|
|
||||||
for (int i = 0; i <= shadow->base.last_level; i++) {
|
for (int i = 0; i <= shadow->base.last_level; i++) {
|
||||||
unsigned width = u_minify(shadow->base.width0, i);
|
unsigned width = u_minify(shadow->base.width0, i);
|
||||||
|
@ -1111,7 +1112,7 @@ vc4_update_shadow_baselevel_texture(struct pipe_context *pctx,
|
||||||
},
|
},
|
||||||
.src = {
|
.src = {
|
||||||
.resource = &orig->base,
|
.resource = &orig->base,
|
||||||
.level = view->u.tex.first_level + i,
|
.level = pview->u.tex.first_level + i,
|
||||||
.box = {
|
.box = {
|
||||||
.x = 0,
|
.x = 0,
|
||||||
.y = 0,
|
.y = 0,
|
||||||
|
|
|
@ -81,20 +81,6 @@ struct vc4_resource {
|
||||||
* buffer) may get marked.
|
* buffer) may get marked.
|
||||||
*/
|
*/
|
||||||
uint32_t initialized_buffers;
|
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 *
|
static inline struct vc4_resource *
|
||||||
|
|
|
@ -556,6 +556,9 @@ vc4_create_sampler_view(struct pipe_context *pctx, struct pipe_resource *prsc,
|
||||||
so->base = *cso;
|
so->base = *cso;
|
||||||
|
|
||||||
pipe_reference(NULL, &prsc->reference);
|
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
|
/* 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
|
* 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 &&
|
if ((cso->u.tex.first_level &&
|
||||||
(cso->u.tex.first_level != cso->u.tex.last_level)) ||
|
(cso->u.tex.first_level != cso->u.tex.last_level)) ||
|
||||||
rsc->vc4_format == VC4_TEXTURE_TYPE_RGBA32R) {
|
rsc->vc4_format == VC4_TEXTURE_TYPE_RGBA32R) {
|
||||||
struct vc4_resource *shadow_parent = vc4_resource(prsc);
|
struct vc4_resource *shadow_parent = rsc;
|
||||||
struct pipe_resource tmpl = shadow_parent->base;
|
struct pipe_resource tmpl = *prsc;
|
||||||
struct vc4_resource *clone;
|
|
||||||
|
|
||||||
tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
tmpl.bind = PIPE_BIND_SAMPLER_VIEW | PIPE_BIND_RENDER_TARGET;
|
||||||
tmpl.width0 = u_minify(tmpl.width0, cso->u.tex.first_level);
|
tmpl.width0 = u_minify(tmpl.width0, cso->u.tex.first_level);
|
||||||
tmpl.height0 = u_minify(tmpl.height0, 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;
|
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);
|
prsc = vc4_resource_create(pctx->screen, &tmpl);
|
||||||
if (!prsc) {
|
if (!prsc) {
|
||||||
free(so);
|
free(so);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
rsc = vc4_resource(prsc);
|
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;
|
|
||||||
|
|
||||||
assert(clone->vc4_format != VC4_TEXTURE_TYPE_RGBA32R);
|
/* Flag it as needing update of the contents from the parent. */
|
||||||
} else if (cso->u.tex.first_level) {
|
rsc->writes = shadow_parent->writes - 1;
|
||||||
so->force_first_level = true;
|
assert(rsc->vc4_format != VC4_TEXTURE_TYPE_RGBA32R);
|
||||||
|
|
||||||
|
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 =
|
so->texture_p0 =
|
||||||
(VC4_SET_FIELD(rsc->slices[0].offset >> 12, VC4_TEX_P0_OFFSET) |
|
(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
|
static void
|
||||||
vc4_sampler_view_destroy(struct pipe_context *pctx,
|
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);
|
pipe_resource_reference(&view->texture, NULL);
|
||||||
free(view);
|
free(view);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ write_texture_p0(struct vc4_job *job,
|
||||||
{
|
{
|
||||||
struct vc4_sampler_view *sview =
|
struct vc4_sampler_view *sview =
|
||||||
vc4_sampler_view(texstate->textures[unit]);
|
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);
|
cl_reloc(job, &job->uniforms, uniforms, rsc->bo, sview->texture_p0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue