v3d: rebind sampler view if resource changed the BO

When discarding the whole resource to create a new one, if this resource
is used by a sampler view, a rebind must be done to use the new
resource.

But this must be done when setting the sampler views, because we don't
have access to those samplers before.

v2:
 - Pack shader state on setting sampler views (Iago)
 - Use a serial ID to know when to rebind sampler views (Juan)

v3:
 - Move check to caller (Iago)
 - Keep rebind sampler view on BO change (Iago)

v4:
 - Rename "serial_bo" to "serial_id" (Iago)
 - Add comments (Iago)

Fixes: https://gitlab.freedesktop.org/mesa/mesa/-/issues/6027
Signed-off-by: Juan A. Suarez Romero <jasuarez@igalia.com>
Reviewed-by: Iago Toral Quiroga <itoral@igalia.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/15171>
This commit is contained in:
Juan A. Suarez Romero 2022-03-03 12:09:32 +01:00 committed by Marge Bot
parent 7bda838c56
commit 7ffee7f1ab
4 changed files with 41 additions and 0 deletions

View File

@ -165,6 +165,12 @@ struct v3d_sampler_view {
* raster texture.
*/
struct pipe_resource *texture;
/* A serial ID used to identify cases where a new BO has been created
* and we need to rebind a sampler view that was created against the
* previous BO to to point to the new one.
*/
uint32_t serial_id;
};
struct v3d_sampler_state {

View File

@ -103,6 +103,7 @@ v3d_resource_bo_alloc(struct v3d_resource *rsc)
if (bo) {
v3d_bo_unreference(&rsc->bo);
rsc->bo = bo;
rsc->serial_id++;
v3d_debug_resource_layout(rsc, "alloc");
return true;
} else {
@ -186,6 +187,13 @@ v3d_map_usage_prep(struct pipe_context *pctx,
v3d->dirty |= V3D_DIRTY_VTXBUF;
if (prsc->bind & PIPE_BIND_CONSTANT_BUFFER)
v3d->dirty |= V3D_DIRTY_CONSTBUF;
/* Since we are changing the texture BO we need to
* update any bound samplers to point to the new
* BO. Notice we can have samplers that are not
* currently bound to the state that won't be
* updated. These will be fixed when they are bound in
* v3d_set_sampler_views.
*/
if (prsc->bind & PIPE_BIND_SAMPLER_VIEW)
rebind_sampler_views(v3d, rsc);
} else {
@ -740,6 +748,8 @@ v3d_resource_setup(struct pipe_screen *pscreen,
}
}
rsc->serial_id++;
assert(rsc->cpp);
return rsc;

View File

@ -119,6 +119,14 @@ struct v3d_resource {
*/
uint32_t initialized_buffers;
/**
* A serial ID that is incremented every time a new BO is bound to a
* resource. We use this to track scenarios where we might need to
* update other resources to point to the new BO (like sampler states
* when a texture BO changes).
*/
uint32_t serial_id;
enum pipe_format internal_format;
/* Resource storing the S8 part of a Z32F_S8 resource, or NULL. */

View File

@ -923,11 +923,14 @@ v3dX(create_texture_shader_state_bo)(struct v3d_context *v3d,
struct v3d_sampler_view *so)
{
struct pipe_resource *prsc = so->texture;
struct v3d_resource *rsc = v3d_resource(prsc);
const struct pipe_sampler_view *cso = &so->base;
struct v3d_screen *screen = v3d->screen;
void *map;
assert(so->serial_id != rsc->serial_id);
#if V3D_VERSION >= 40
v3d_bo_unreference(&so->bo);
so->bo = v3d_bo_alloc(v3d->screen,
@ -1010,6 +1013,8 @@ v3dX(create_texture_shader_state_bo)(struct v3d_context *v3d,
cso->format);
}
};
so->serial_id = rsc->serial_id;
}
static struct pipe_sampler_view *
@ -1205,6 +1210,18 @@ v3d_set_sampler_views(struct pipe_context *pctx,
} else {
pipe_sampler_view_reference(&stage_tex->textures[i], views[i]);
}
/* If our sampler serial doesn't match our texture serial it
* means the texture has been updated with a new BO, in which
* case we need to update the sampler state to point to the
* new BO as well
*/
if (stage_tex->textures[i]) {
struct v3d_sampler_view *so =
v3d_sampler_view(stage_tex->textures[i]);
struct v3d_resource *rsc = v3d_resource(so->texture);
if (so->serial_id != rsc->serial_id)
v3d_create_texture_shader_state_bo(v3d, so);
}
}
for (; i < stage_tex->num_textures; i++) {