diff options
| author | Brian Paul <brianp@vmware.com> | 2010-03-24 16:27:31 -0600 | 
|---|---|---|
| committer | Brian Paul <brianp@vmware.com> | 2010-03-24 16:29:17 -0600 | 
| commit | 2ad8692aad0f4ad49643d5f697a036afccdeb9f0 (patch) | |
| tree | a3f34c4390cb0022e343128ac199db5dcfc14b10 /src/gallium/drivers | |
| 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.
Diffstat (limited to 'src/gallium/drivers')
| -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 fbb0d6f8a6..76a8b87a30 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 464fb36984..ca0dafab62 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 */  | 
