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.
This commit is contained in:
Brian Paul 2010-03-24 16:27:31 -06:00
parent f0e04b0944
commit 2ad8692aad
2 changed files with 22 additions and 6 deletions

View file

@ -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 */

View file

@ -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 */