summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2021-10-06 22:42:36 +0200
committerThierry Reding <treding@nvidia.com>2022-02-16 16:20:40 +0100
commite8ce0a335704af54b8269d6e862835703700392b (patch)
tree66044d0b32598868766e3278a8a4f7a71c9f8d4a
parent4e252cbc7dfdc272a9b18a6044a169eaa3a88568 (diff)
tegra: Use private reference count for sampler views
With the recent addition of the shortcuts aiming to avoid atomic operations, the reference count on sampler views can become unbalanced in the Tegra driver since they are wrapped and then proxied to the Nouveau driver. Fix this by keeping a private reference count. Fixes: ef5d42741327 ("st/mesa: add a mechanism to bypass atomics when binding sampler views") Reviewed-by: Karol Herbst <kherbst@redhat.com> Tested-by: Karol Herbst <kherbst@redhat.com>
-rw-r--r--src/gallium/drivers/tegra/tegra_context.c30
-rw-r--r--src/gallium/drivers/tegra/tegra_context.h1
2 files changed, 25 insertions, 6 deletions
diff --git a/src/gallium/drivers/tegra/tegra_context.c b/src/gallium/drivers/tegra/tegra_context.c
index b170f5eb547..405e67c1478 100644
--- a/src/gallium/drivers/tegra/tegra_context.c
+++ b/src/gallium/drivers/tegra/tegra_context.c
@@ -567,10 +567,22 @@ tegra_set_sampler_views(struct pipe_context *pcontext, unsigned shader,
{
struct pipe_sampler_view *views[PIPE_MAX_SHADER_SAMPLER_VIEWS];
struct tegra_context *context = to_tegra_context(pcontext);
+ struct tegra_sampler_view *view;
unsigned i;
- for (i = 0; i < num_views; i++)
+ for (i = 0; i < num_views; i++) {
+ /* adjust private reference count */
+ view = to_tegra_sampler_view(pviews[i]);
+ if (view) {
+ view->refcount--;
+ if (!view->refcount) {
+ view->refcount = 100000000;
+ p_atomic_add(&view->gpu->reference.count, view->refcount);
+ }
+ }
+
views[i] = tegra_sampler_view_unwrap(pviews[i]);
+ }
context->gpu->set_sampler_views(context->gpu, shader, start_slot,
num_views, unbind_num_trailing_slots,
@@ -836,15 +848,19 @@ tegra_create_sampler_view(struct pipe_context *pcontext,
if (!view)
return NULL;
- view->gpu = context->gpu->create_sampler_view(context->gpu, resource->gpu,
- template);
- memcpy(&view->base, view->gpu, sizeof(*view->gpu));
+ view->base = *template;
+ view->base.context = pcontext;
/* overwrite to prevent reference from being released */
view->base.texture = NULL;
-
pipe_reference_init(&view->base.reference, 1);
pipe_resource_reference(&view->base.texture, presource);
- view->base.context = pcontext;
+
+ view->gpu = context->gpu->create_sampler_view(context->gpu, resource->gpu,
+ template);
+
+ /* use private reference count */
+ view->gpu->reference.count += 100000000;
+ view->refcount = 100000000;
return &view->base;
}
@@ -856,6 +872,8 @@ tegra_sampler_view_destroy(struct pipe_context *pcontext,
struct tegra_sampler_view *view = to_tegra_sampler_view(pview);
pipe_resource_reference(&view->base.texture, NULL);
+ /* adjust private reference count */
+ p_atomic_add(&view->gpu->reference.count, -view->refcount);
pipe_sampler_view_reference(&view->gpu, NULL);
free(view);
}
diff --git a/src/gallium/drivers/tegra/tegra_context.h b/src/gallium/drivers/tegra/tegra_context.h
index 4869b0913a6..c2d8eb33ca5 100644
--- a/src/gallium/drivers/tegra/tegra_context.h
+++ b/src/gallium/drivers/tegra/tegra_context.h
@@ -47,6 +47,7 @@ tegra_screen_context_create(struct pipe_screen *pscreen, void *priv,
struct tegra_sampler_view {
struct pipe_sampler_view base;
struct pipe_sampler_view *gpu;
+ unsigned int refcount;
};
static inline struct tegra_sampler_view *