diff options
author | Brian Paul <[email protected]> | 2010-03-24 16:27:31 -0600 |
---|---|---|
committer | Brian Paul <[email protected]> | 2010-03-24 16:29:17 -0600 |
commit | 2ad8692aad0f4ad49643d5f697a036afccdeb9f0 (patch) | |
tree | a3f34c4390cb0022e343128ac199db5dcfc14b10 | |
parent | f0e04b094412d358e913d3d1107d7260047f6fb2 (diff) |
llvmpipe: fix texture reference counting bug
We weren't saving the per-scene texture references at the right point.
Fixes piglit cubemap segfault. The segfault resulted from referencing
texture memory which was prematurely freed because of a missed reference
count.
Fixes fd.o bug 27276.
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup.c | 27 | ||||
-rw-r--r-- | src/gallium/drivers/llvmpipe/lp_setup_context.h | 1 |
2 files changed, 22 insertions, 6 deletions
diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index fbb0d6f8a60..76a8b87a309 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -489,6 +489,12 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, jit_tex->height = tex->height0; jit_tex->depth = tex->depth0; jit_tex->last_level = tex->last_level; + + /* We're referencing the texture's internal data, so save a + * reference to it. + */ + pipe_texture_reference(&setup->fs.current_tex[i], tex); + if (!lp_tex->dt) { /* regular texture - setup array of mipmap level pointers */ int j; @@ -511,12 +517,6 @@ lp_setup_set_fragment_sampler_views(struct lp_setup_context *setup, jit_tex->row_stride[0] = lp_tex->stride[0]; assert(jit_tex->data[0]); } - - /* the scene references this texture */ - { - struct lp_scene *scene = lp_setup_get_current_scene(setup); - lp_scene_texture_reference(scene, tex); - } } } @@ -651,6 +651,7 @@ lp_setup_update_state( struct lp_setup_context *setup ) * the new, current state. So allocate a new lp_rast_state object * and append it to the bin's setup data buffer. */ + uint i; struct lp_rast_state *stored = (struct lp_rast_state *) lp_scene_alloc(scene, sizeof *stored); if(stored) { @@ -664,6 +665,14 @@ lp_setup_update_state( struct lp_setup_context *setup ) lp_rast_set_state, lp_rast_arg_state(setup->fs.stored) ); } + + /* The scene now references the textures in the rasterization + * state record. Note that now. + */ + for (i = 0; i < Elements(setup->fs.current_tex); i++) { + if (setup->fs.current_tex[i]) + lp_scene_texture_reference(scene, setup->fs.current_tex[i]); + } } } @@ -679,8 +688,14 @@ lp_setup_update_state( struct lp_setup_context *setup ) void lp_setup_destroy( struct lp_setup_context *setup ) { + uint i; + reset_context( setup ); + for (i = 0; i < Elements(setup->fs.current_tex); i++) { + pipe_texture_reference(&setup->fs.current_tex[i], NULL); + } + pipe_buffer_reference(&setup->constants.current, NULL); /* free the scenes in the 'empty' queue */ diff --git a/src/gallium/drivers/llvmpipe/lp_setup_context.h b/src/gallium/drivers/llvmpipe/lp_setup_context.h index 464fb369840..ca0dafab627 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup_context.h +++ b/src/gallium/drivers/llvmpipe/lp_setup_context.h @@ -111,6 +111,7 @@ struct lp_setup_context const struct lp_rast_state *stored; /**< what's in the scene */ struct lp_rast_state current; /**< currently set state */ + struct pipe_texture *current_tex[PIPE_MAX_SAMPLERS]; } fs; /** fragment shader constants */ |