renderer: link shaders and programs so things can be freed.

We need to link the shaders to the programs to ensure things
can be freed properly. This fixes a problem with glean
texCombine also.
macos/master
Marc-André Lureau 10 years ago committed by Dave Airlie
parent 5ddb7c3d0a
commit 6fc3a2c9b5
  1. 17
      src/vrend_renderer.c

@ -133,6 +133,7 @@ static struct global_renderer_state vrend_state;
struct vrend_linked_shader_program { struct vrend_linked_shader_program {
struct list_head head; struct list_head head;
struct list_head sl[PIPE_SHADER_TYPES];
GLuint id; GLuint id;
boolean dual_src_linked; boolean dual_src_linked;
@ -165,6 +166,7 @@ struct vrend_shader {
GLuint id; GLuint id;
GLuint compiled_fs_id; GLuint compiled_fs_id;
struct vrend_shader_key key; struct vrend_shader_key key;
struct list_head programs;
}; };
struct vrend_shader_selector { struct vrend_shader_selector {
@ -367,6 +369,7 @@ struct vrend_context {
}; };
static struct vrend_nontimer_hw_query *vrend_create_hw_query(struct vrend_query *query); static struct vrend_nontimer_hw_query *vrend_create_hw_query(struct vrend_query *query);
static void vrend_destroy_program(struct vrend_linked_shader_program *ent);
static struct vrend_format_table tex_conv_table[VIRGL_FORMAT_MAX]; static struct vrend_format_table tex_conv_table[VIRGL_FORMAT_MAX];
@ -488,6 +491,12 @@ vrend_so_target_reference(struct vrend_so_target **ptr, struct vrend_so_target *
static void vrend_shader_destroy(struct vrend_shader *shader) static void vrend_shader_destroy(struct vrend_shader *shader)
{ {
struct vrend_linked_shader_program *ent, *tmp;
LIST_FOR_EACH_ENTRY_SAFE(ent, tmp, &shader->programs, sl[shader->sel->type]) {
vrend_destroy_program(ent);
}
glDeleteShader(shader->id); glDeleteShader(shader->id);
free(shader->glsl_prog); free(shader->glsl_prog);
free(shader); free(shader);
@ -744,6 +753,11 @@ static struct vrend_linked_shader_program *add_shader_program(struct vrend_conte
sprog->ss[PIPE_SHADER_FRAGMENT] = fs; sprog->ss[PIPE_SHADER_FRAGMENT] = fs;
sprog->ss[PIPE_SHADER_GEOMETRY] = gs; sprog->ss[PIPE_SHADER_GEOMETRY] = gs;
list_add(&sprog->sl[PIPE_SHADER_VERTEX], &vs->programs);
list_add(&sprog->sl[PIPE_SHADER_FRAGMENT], &fs->programs);
if (gs)
list_add(&sprog->sl[PIPE_SHADER_GEOMETRY], &gs->programs);
sprog->id = prog_id; sprog->id = prog_id;
list_add(&sprog->head, &ctx->sub->programs); list_add(&sprog->head, &ctx->sub->programs);
@ -862,6 +876,8 @@ static void vrend_destroy_program(struct vrend_linked_shader_program *ent)
list_del(&ent->head); list_del(&ent->head);
for (i = PIPE_SHADER_VERTEX; i <= PIPE_SHADER_GEOMETRY; i++) { for (i = PIPE_SHADER_VERTEX; i <= PIPE_SHADER_GEOMETRY; i++) {
if (ent->ss[i])
list_del(&ent->sl[i]);
free(ent->shadow_samp_mask_locs[i]); free(ent->shadow_samp_mask_locs[i]);
free(ent->shadow_samp_add_locs[i]); free(ent->shadow_samp_add_locs[i]);
free(ent->samp_locs[i]); free(ent->samp_locs[i]);
@ -1823,6 +1839,7 @@ static int vrend_shader_select(struct vrend_context *ctx,
if (!shader) { if (!shader) {
shader = CALLOC_STRUCT(vrend_shader); shader = CALLOC_STRUCT(vrend_shader);
shader->sel = sel; shader->sel = sel;
list_inithead(&shader->programs);
r = vrend_shader_create(ctx, shader, key); r = vrend_shader_create(ctx, shader, key);
if (r) { if (r) {

Loading…
Cancel
Save