| From 1376f9218c227c1dc33bdc8e973adf4aad438df0 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/24] CHROMIUM: |
| 10.3-state_tracker-gallium-fix-crash-with-st_renderbuffer.patch |
| |
| 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. |
| |
| Change-Id: I06bc1feeab87f18a07d065e192328a052295196d |
| Signed-off-by: James Ausmus <james.ausmus@intel.com> |
| --- |
| 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 bb99a02ce49a..3bdf5b0635e4 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; |
| } |
| |
| @@ -148,7 +148,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 6ba9646f7ab6..00e5c6c4656b 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. |
| @@ -826,6 +830,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; |
| @@ -844,6 +849,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 b2a639cb0f18..ebc9f2f2743a 100644 |
| --- a/src/gallium/drivers/i915/i915_surface.c |
| +++ b/src/gallium/drivers/i915/i915_surface.c |
| @@ -372,6 +372,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 b205f02fdba6..f1c7f4d61180 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, |
| @@ -170,6 +173,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 96f8ed82cd86..c6e44b7d340a 100644 |
| --- a/src/gallium/drivers/llvmpipe/lp_surface.c |
| +++ b/src/gallium/drivers/llvmpipe/lp_surface.c |
| @@ -140,6 +140,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 d99d5ae0152b..463ee922efde 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. */ |
| |
| @@ -1655,6 +1659,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 5e4d50df27d3..ba1289921c2e 100644 |
| --- a/src/gallium/drivers/r300/r300_texture.c |
| +++ b/src/gallium/drivers/r300/r300_texture.c |
| @@ -1161,6 +1161,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 bb91f830828f..b0b2ae97ae23 100644 |
| --- a/src/gallium/drivers/r600/r600_pipe.h |
| +++ b/src/gallium/drivers/r600/r600_pipe.h |
| @@ -720,6 +720,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 2c727815d2d8..f4cab0b2a5d4 100644 |
| --- a/src/gallium/drivers/r600/r600_state.c |
| +++ b/src/gallium/drivers/r600/r600_state.c |
| @@ -652,6 +652,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 bdd9337ecc04..dd49cbf35239 100644 |
| --- a/src/gallium/drivers/r600/r600_state_common.c |
| +++ b/src/gallium/drivers/r600/r600_state_common.c |
| @@ -388,8 +388,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 54696910e43b..7e9c0614b0d3 100644 |
| --- a/src/gallium/drivers/radeon/r600_texture.c |
| +++ b/src/gallium/drivers/radeon/r600_texture.c |
| @@ -1113,6 +1113,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 565fca6..07eb5ff 100644 |
| --- a/src/gallium/drivers/softpipe/sp_tex_sample.c |
| +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c |
| @@ -3306,6 +3306,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 e1ea5df..d192344 100644 |
| --- a/src/gallium/drivers/softpipe/sp_texture.c |
| +++ b/src/gallium/drivers/softpipe/sp_texture.c |
| @@ -287,6 +287,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 266ebbafe36b..6294fcaf24f0 100644 |
| --- a/src/gallium/include/pipe/p_state.h |
| +++ b/src/gallium/include/pipe/p_state.h |
| @@ -359,6 +359,9 @@ struct pipe_surface |
| unsigned last_element; |
| } buf; |
| } u; |
| + |
| + void (*surface_destroy)(struct pipe_context *ctx, |
| + struct pipe_surface *); |
| }; |
| |
| |
| @@ -388,6 +391,9 @@ struct pipe_sampler_view |
| unsigned swizzle_g:3; /**< PIPE_SWIZZLE_x for green component */ |
| unsigned swizzle_b:3; /**< PIPE_SWIZZLE_x for blue component */ |
| unsigned swizzle_a:3; /**< PIPE_SWIZZLE_x for alpha component */ |
| + |
| + void (*sampler_view_destroy)(struct pipe_context *ctx, |
| + struct pipe_sampler_view *view); |
| }; |
| |
| |
| -- |
| 2.5.1 |
| |