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:
parent
7bda838c56
commit
7ffee7f1ab
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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++) {
|
||||
|
|
Loading…
Reference in New Issue