blob: 9bba6054fd2ef5bcf287fef218641220ad6afadf [file] [log] [blame]
From 8fb20c7216b406b560565ed23209d71dc2826a97 Mon Sep 17 00:00:00 2001
From: James Ausmus <james.ausmus@intel.com>
Date: Mon, 4 May 2015 15:00:12 -0700
Subject: [PATCH 03/39] CHROMIUM: gallium: Fix renderbuffer destruction crash
Avoid crash on surface/sampler_view destruction when the context is gone
When we delete the context, sometimes there are pending surfaces and
sampler view left. Since mesa doesn't properly refcount them, the
context can go away before its resources. Until mesa is fixed to
properly refcount all these resources, let's just carry the destroy
function on the resource itself, which gives us a way to free it.
BUG=none
TEST=compile
Signed-off-by: Prince Agyeman <prince.agyeman@intel.com>
Signed-off-by: Dhinakaran Pandiyan <dhinakaran.pandiyan@intel.com>
Signed-off-by: James Ausmus <james.ausmus@intel.com>
Signed-off-by: Tomasz Figa <tfiga@chromium.org>
Signed-off-by: Gurchetan Singh <gurchetansingh@chromium.org>
---
src/gallium/auxiliary/util/u_inlines.h | 4 ++--
src/gallium/drivers/i915/i915_state.c | 6 ++++++
src/gallium/drivers/i915/i915_surface.c | 1 +
src/gallium/drivers/llvmpipe/lp_state_sampler.c | 4 ++++
src/gallium/drivers/llvmpipe/lp_surface.c | 1 +
src/gallium/drivers/r300/r300_state.c | 5 +++++
src/gallium/drivers/r300/r300_texture.c | 1 +
src/gallium/drivers/r600/r600_pipe.h | 2 ++
src/gallium/drivers/r600/r600_state.c | 1 +
src/gallium/drivers/r600/r600_state_common.c | 4 ++--
src/gallium/drivers/radeon/r600_texture.c | 1 +
src/gallium/drivers/softpipe/sp_tex_sample.c | 1 +
src/gallium/drivers/softpipe/sp_texture.c | 1 +
src/gallium/include/pipe/p_state.h | 6 ++++++
14 files changed, 34 insertions(+), 4 deletions(-)
diff --git a/src/gallium/auxiliary/util/u_inlines.h b/src/gallium/auxiliary/util/u_inlines.h
index 4fc683a..1dc63d1 100644
--- a/src/gallium/auxiliary/util/u_inlines.h
+++ b/src/gallium/auxiliary/util/u_inlines.h
@@ -110,7 +110,7 @@ pipe_surface_reference(struct pipe_surface **ptr, struct pipe_surface *surf)
if (pipe_reference_described(&(*ptr)->reference, &surf->reference,
(debug_reference_descriptor)debug_describe_surface))
- old_surf->context->surface_destroy(old_surf->context, old_surf);
+ old_surf->surface_destroy(old_surf->context, old_surf);
*ptr = surf;
}
@@ -156,7 +156,7 @@ pipe_sampler_view_reference(struct pipe_sampler_view **ptr, struct pipe_sampler_
if (pipe_reference_described(&(*ptr)->reference, &view->reference,
(debug_reference_descriptor)debug_describe_sampler_view))
- old_view->context->sampler_view_destroy(old_view->context, old_view);
+ old_view->sampler_view_destroy(old_view->context, old_view);
*ptr = view;
}
diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c
index ddc2709..1672164 100644
--- a/src/gallium/drivers/i915/i915_state.c
+++ b/src/gallium/drivers/i915/i915_state.c
@@ -44,6 +44,10 @@
#include "i915_resource.h"
#include "i915_state.h"
+static void
+i915_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view);
+
/* The i915 (and related graphics cores) do not support GL_CLAMP. The
* Intel drivers for "other operating systems" implement GL_CLAMP as
* GL_CLAMP_TO_EDGE, so the same is done here.
@@ -827,6 +831,7 @@ i915_create_sampler_view_custom(struct pipe_context *pipe,
view->texture = NULL;
pipe_resource_reference(&view->texture, texture);
view->context = pipe;
+ view->sampler_view_destroy = i915_sampler_view_destroy;
}
return view;
@@ -845,6 +850,7 @@ i915_create_sampler_view(struct pipe_context *pipe,
view->texture = NULL;
pipe_resource_reference(&view->texture, texture);
view->context = pipe;
+ view->sampler_view_destroy = i915_sampler_view_destroy;
}
return view;
diff --git a/src/gallium/drivers/i915/i915_surface.c b/src/gallium/drivers/i915/i915_surface.c
index 57e90c6..225072b 100644
--- a/src/gallium/drivers/i915/i915_surface.c
+++ b/src/gallium/drivers/i915/i915_surface.c
@@ -376,6 +376,7 @@ i915_create_surface_custom(struct pipe_context *ctx,
ps->u.tex.first_layer = surf_tmpl->u.tex.first_layer;
ps->u.tex.last_layer = surf_tmpl->u.tex.last_layer;
ps->context = ctx;
+ ps->surface_destroy = ctx->surface_destroy;
}
return ps;
}
diff --git a/src/gallium/drivers/llvmpipe/lp_state_sampler.c b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
index c9aba1a..1e7c996 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_sampler.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_sampler.c
@@ -40,6 +40,9 @@
#include "lp_debug.h"
#include "state_tracker/sw_winsys.h"
+static void
+llvmpipe_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view);
static void *
llvmpipe_create_sampler_state(struct pipe_context *pipe,
@@ -183,6 +186,7 @@ llvmpipe_create_sampler_view(struct pipe_context *pipe,
view->texture = NULL;
pipe_resource_reference(&view->texture, texture);
view->context = pipe;
+ view->sampler_view_destroy = llvmpipe_sampler_view_destroy;
#ifdef DEBUG
/*
diff --git a/src/gallium/drivers/llvmpipe/lp_surface.c b/src/gallium/drivers/llvmpipe/lp_surface.c
index 953b26e..831b598 100644
--- a/src/gallium/drivers/llvmpipe/lp_surface.c
+++ b/src/gallium/drivers/llvmpipe/lp_surface.c
@@ -147,6 +147,7 @@ llvmpipe_create_surface(struct pipe_context *pipe,
pipe_resource_reference(&ps->texture, pt);
ps->context = pipe;
ps->format = surf_tmpl->format;
+ ps->surface_destroy = pipe->surface_destroy;
if (llvmpipe_resource_is_texture(pt)) {
assert(surf_tmpl->u.tex.level <= pt->last_level);
assert(surf_tmpl->u.tex.first_layer <= surf_tmpl->u.tex.last_layer);
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index c2b9937..4cdd01f 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -47,6 +47,10 @@
#include "r300_texture.h"
#include "r300_vs.h"
+static void
+r300_sampler_view_destroy(struct pipe_context *pipe,
+ struct pipe_sampler_view *view);
+
/* r300_state: Functions used to intialize state context by translating
* Gallium state objects into semi-native r300 state objects. */
@@ -1610,6 +1614,7 @@ r300_create_sampler_view_custom(struct pipe_context *pipe,
view->base.reference.count = 1;
view->base.context = pipe;
view->base.texture = NULL;
+ view->base.sampler_view_destroy = r300_sampler_view_destroy;
pipe_resource_reference(&view->base.texture, texture);
view->width0_override = width0_override;
diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c
index cdf9ccb..0070cfd 100644
--- a/src/gallium/drivers/r300/r300_texture.c
+++ b/src/gallium/drivers/r300/r300_texture.c
@@ -1232,6 +1232,7 @@ struct pipe_surface* r300_create_surface_custom(struct pipe_context * ctx,
pipe_reference_init(&surface->base.reference, 1);
pipe_resource_reference(&surface->base.texture, texture);
surface->base.context = ctx;
+ surface->base.surface_destroy = ctx->surface_destroy;
surface->base.format = surf_tmpl->format;
surface->base.width = u_minify(width0_override, level);
surface->base.height = u_minify(height0_override, level);
diff --git a/src/gallium/drivers/r600/r600_pipe.h b/src/gallium/drivers/r600/r600_pipe.h
index 3fa7d77..4d11819 100644
--- a/src/gallium/drivers/r600/r600_pipe.h
+++ b/src/gallium/drivers/r600/r600_pipe.h
@@ -737,6 +737,8 @@ void r600_sampler_views_dirty(struct r600_context *rctx,
struct r600_samplerview_state *state);
void r600_sampler_states_dirty(struct r600_context *rctx,
struct r600_sampler_states *state);
+void r600_sampler_view_destroy(struct pipe_context *ctx,
+ struct pipe_sampler_view *state);
void r600_constant_buffers_dirty(struct r600_context *rctx, struct r600_constbuf_state *state);
void r600_set_sample_locations_constant_buffer(struct r600_context *rctx);
uint32_t r600_translate_stencil_op(int s_op);
diff --git a/src/gallium/drivers/r600/r600_state.c b/src/gallium/drivers/r600/r600_state.c
index dca8fe5..e6d0ab7 100644
--- a/src/gallium/drivers/r600/r600_state.c
+++ b/src/gallium/drivers/r600/r600_state.c
@@ -682,6 +682,7 @@ r600_create_sampler_view_custom(struct pipe_context *ctx,
view->base.texture = texture;
view->base.reference.count = 1;
view->base.context = ctx;
+ view->base.sampler_view_destroy = r600_sampler_view_destroy;
if (texture->target == PIPE_BUFFER)
return texture_buffer_sampler_view(view, texture->width0, 1);
diff --git a/src/gallium/drivers/r600/r600_state_common.c b/src/gallium/drivers/r600/r600_state_common.c
index 4c97efa..11edee3 100644
--- a/src/gallium/drivers/r600/r600_state_common.c
+++ b/src/gallium/drivers/r600/r600_state_common.c
@@ -385,8 +385,8 @@ static void r600_delete_rs_state(struct pipe_context *ctx, void *state)
FREE(rs);
}
-static void r600_sampler_view_destroy(struct pipe_context *ctx,
- struct pipe_sampler_view *state)
+void r600_sampler_view_destroy(struct pipe_context *ctx,
+ struct pipe_sampler_view *state)
{
struct r600_pipe_sampler_view *view = (struct r600_pipe_sampler_view *)state;
diff --git a/src/gallium/drivers/radeon/r600_texture.c b/src/gallium/drivers/radeon/r600_texture.c
index 3aac3c7..1c74c8e 100644
--- a/src/gallium/drivers/radeon/r600_texture.c
+++ b/src/gallium/drivers/radeon/r600_texture.c
@@ -2010,6 +2010,7 @@ struct pipe_surface *r600_create_surface_custom(struct pipe_context *pipe,
pipe_reference_init(&surface->base.reference, 1);
pipe_resource_reference(&surface->base.texture, texture);
surface->base.context = pipe;
+ surface->base.surface_destroy = pipe->surface_destroy;
surface->base.format = templ->format;
surface->base.width = width;
surface->base.height = height;
diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c
index 92c78da..de2b074 100644
--- a/src/gallium/drivers/softpipe/sp_tex_sample.c
+++ b/src/gallium/drivers/softpipe/sp_tex_sample.c
@@ -3467,6 +3467,7 @@ softpipe_create_sampler_view(struct pipe_context *pipe,
view->texture = NULL;
pipe_resource_reference(&view->texture, resource);
view->context = pipe;
+ view->sampler_view_destroy = pipe->sampler_view_destroy;
#ifdef DEBUG
/*
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index ea5e2c6..e0c1914 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -300,6 +300,7 @@ softpipe_create_surface(struct pipe_context *pipe,
pipe_resource_reference(&ps->texture, pt);
ps->context = pipe;
ps->format = surf_tmpl->format;
+ ps->surface_destroy = pipe->surface_destroy;
if (pt->target != PIPE_BUFFER) {
assert(surf_tmpl->u.tex.level <= pt->last_level);
ps->width = u_minify(pt->width0, surf_tmpl->u.tex.level);
diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h
index 15be8cb..e4b9087 100644
--- a/src/gallium/include/pipe/p_state.h
+++ b/src/gallium/include/pipe/p_state.h
@@ -417,6 +417,9 @@ struct pipe_surface
uint16_t height; /**< logical height in pixels */
union pipe_surface_desc u;
+
+ void (*surface_destroy)(struct pipe_context *ctx,
+ struct pipe_surface *);
};
@@ -446,6 +449,9 @@ struct pipe_sampler_view
unsigned size; /**< size of the readable sub-range in bytes */
} buf;
} u;
+
+ void (*sampler_view_destroy)(struct pipe_context *ctx,
+ struct pipe_sampler_view *view);
};
--
2.7.4