mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-05-05 00:58:05 +02:00
r300g: Fix leaks in failed context creation
This changes r300_destroy_context() so it can be called on a partially-initialized context, and uses it when r300_create_context() hits a fatal error. This makes sure r300_create_context() doesn't leak memory or neglect to call r300_update_num_contexts() when it fails. Signed-off-by: Marek Olšák <maraeo@gmail.com>
This commit is contained in:
parent
b0e1565b5f
commit
1e2cd02eae
1 changed files with 48 additions and 34 deletions
|
|
@ -99,8 +99,10 @@ static void r300_destroy_context(struct pipe_context* context)
|
|||
struct r300_context* r300 = r300_context(context);
|
||||
struct r300_atom *atom;
|
||||
|
||||
util_blitter_destroy(r300->blitter);
|
||||
draw_destroy(r300->draw);
|
||||
if (r300->blitter)
|
||||
util_blitter_destroy(r300->blitter);
|
||||
if (r300->draw)
|
||||
draw_destroy(r300->draw);
|
||||
|
||||
/* Print stats, if enabled. */
|
||||
if (SCREEN_DBG_ON(r300->screen, DBG_STATS)) {
|
||||
|
|
@ -112,40 +114,48 @@ static void r300_destroy_context(struct pipe_context* context)
|
|||
}
|
||||
}
|
||||
|
||||
u_upload_destroy(r300->upload_vb);
|
||||
u_upload_destroy(r300->upload_ib);
|
||||
if (r300->upload_vb)
|
||||
u_upload_destroy(r300->upload_vb);
|
||||
if (r300->upload_ib)
|
||||
u_upload_destroy(r300->upload_ib);
|
||||
|
||||
/* setup hyper-z mm */
|
||||
if (r300->rws->get_value(r300->rws, R300_CAN_HYPERZ))
|
||||
if (r300->zmask_mm)
|
||||
r300_hyperz_destroy_mm(r300);
|
||||
|
||||
translate_cache_destroy(r300->tran.translate_cache);
|
||||
if (r300->tran.translate_cache)
|
||||
translate_cache_destroy(r300->tran.translate_cache);
|
||||
|
||||
/* XXX: This function assumes r300->query_list was initialized */
|
||||
r300_release_referenced_objects(r300);
|
||||
|
||||
r300->rws->cs_destroy(r300->cs);
|
||||
if (r300->cs)
|
||||
r300->rws->cs_destroy(r300->cs);
|
||||
|
||||
/* XXX: No way to tell if this was initialized or not? */
|
||||
util_mempool_destroy(&r300->pool_transfers);
|
||||
|
||||
r300_update_num_contexts(r300->screen, -1);
|
||||
|
||||
FREE(r300->aa_state.state);
|
||||
FREE(r300->blend_color_state.state);
|
||||
FREE(r300->clip_state.state);
|
||||
FREE(r300->fb_state.state);
|
||||
FREE(r300->gpu_flush.state);
|
||||
FREE(r300->hyperz_state.state);
|
||||
FREE(r300->invariant_state.state);
|
||||
FREE(r300->rs_block_state.state);
|
||||
FREE(r300->scissor_state.state);
|
||||
FREE(r300->textures_state.state);
|
||||
FREE(r300->vap_invariant_state.state);
|
||||
FREE(r300->viewport_state.state);
|
||||
FREE(r300->ztop_state.state);
|
||||
FREE(r300->fs_constants.state);
|
||||
FREE(r300->vs_constants.state);
|
||||
if (!r300->screen->caps.has_tcl) {
|
||||
FREE(r300->vertex_stream_state.state);
|
||||
/* Free the structs allocated in r300_setup_atoms() */
|
||||
if (r300->aa_state.state) {
|
||||
FREE(r300->aa_state.state);
|
||||
FREE(r300->blend_color_state.state);
|
||||
FREE(r300->clip_state.state);
|
||||
FREE(r300->fb_state.state);
|
||||
FREE(r300->gpu_flush.state);
|
||||
FREE(r300->hyperz_state.state);
|
||||
FREE(r300->invariant_state.state);
|
||||
FREE(r300->rs_block_state.state);
|
||||
FREE(r300->scissor_state.state);
|
||||
FREE(r300->textures_state.state);
|
||||
FREE(r300->vap_invariant_state.state);
|
||||
FREE(r300->viewport_state.state);
|
||||
FREE(r300->ztop_state.state);
|
||||
FREE(r300->fs_constants.state);
|
||||
FREE(r300->vs_constants.state);
|
||||
if (r300->vertex_stream_state.state) {
|
||||
FREE(r300->vertex_stream_state.state);
|
||||
}
|
||||
}
|
||||
FREE(r300);
|
||||
}
|
||||
|
|
@ -406,12 +416,16 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
|||
|
||||
r300->context.destroy = r300_destroy_context;
|
||||
|
||||
r300->cs = rws->cs_create(rws);
|
||||
make_empty_list(&r300->query_list);
|
||||
|
||||
util_mempool_create(&r300->pool_transfers,
|
||||
sizeof(struct pipe_transfer), 64,
|
||||
UTIL_MEMPOOL_SINGLETHREADED);
|
||||
|
||||
r300->cs = rws->cs_create(rws);
|
||||
if (r300->cs == NULL)
|
||||
goto fail;
|
||||
|
||||
if (!r300screen->caps.has_tcl) {
|
||||
/* Create a Draw. This is used for SW TCL. */
|
||||
r300->draw = draw_create(&r300->context);
|
||||
|
|
@ -426,8 +440,6 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
|||
|
||||
r300_setup_atoms(r300);
|
||||
|
||||
make_empty_list(&r300->query_list);
|
||||
|
||||
r300_init_blit_functions(r300);
|
||||
r300_init_flush_functions(r300);
|
||||
r300_init_query_functions(r300);
|
||||
|
|
@ -435,6 +447,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
|||
r300_init_resource_functions(r300);
|
||||
|
||||
r300->blitter = util_blitter_create(&r300->context);
|
||||
if (r300->blitter == NULL)
|
||||
goto fail;
|
||||
|
||||
/* Render functions must be initialized after blitter. */
|
||||
r300_init_render_functions(r300);
|
||||
|
|
@ -450,15 +464,17 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
|||
PIPE_BIND_INDEX_BUFFER);
|
||||
|
||||
if (r300->upload_ib == NULL)
|
||||
goto no_upload_ib;
|
||||
goto fail;
|
||||
|
||||
r300->upload_vb = u_upload_create(&r300->context,
|
||||
128 * 1024, 16,
|
||||
PIPE_BIND_VERTEX_BUFFER);
|
||||
if (r300->upload_vb == NULL)
|
||||
goto no_upload_vb;
|
||||
goto fail;
|
||||
|
||||
r300->tran.translate_cache = translate_cache_create();
|
||||
if (r300->tran.translate_cache == NULL)
|
||||
goto fail;
|
||||
|
||||
r300_init_states(&r300->context);
|
||||
|
||||
|
|
@ -488,10 +504,8 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
|
|||
|
||||
return &r300->context;
|
||||
|
||||
no_upload_ib:
|
||||
u_upload_destroy(r300->upload_ib);
|
||||
no_upload_vb:
|
||||
FREE(r300);
|
||||
fail:
|
||||
r300_destroy_context(&r300->context);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue