diff options
-rw-r--r-- | src/gallium/auxiliary/postprocess/filters.h | 18 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/postprocess.h | 22 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_celshade.c | 10 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_colors.c | 21 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_init.c | 145 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_mlaa.c | 121 | ||||
-rw-r--r-- | src/gallium/auxiliary/postprocess/pp_run.c | 39 |
7 files changed, 281 insertions, 95 deletions
diff --git a/src/gallium/auxiliary/postprocess/filters.h b/src/gallium/auxiliary/postprocess/filters.h index 9ea7462..1aa1e3a 100644 --- a/src/gallium/auxiliary/postprocess/filters.h +++ b/src/gallium/auxiliary/postprocess/filters.h @@ -30,8 +30,9 @@ #include "postprocess/postprocess.h" -typedef void (*pp_init_func) (struct pp_queue_t *, unsigned int, +typedef bool (*pp_init_func) (struct pp_queue_t *, unsigned int, unsigned int); +typedef void (*pp_free_func) (struct pp_queue_t *, unsigned int); struct pp_filter_t { @@ -41,18 +42,19 @@ struct pp_filter_t unsigned int verts; /* How many are vertex shaders */ pp_init_func init; /* Init function */ pp_func main; /* Run function */ + pp_free_func free; /* Free function */ }; /* Order matters. Put new filters in a suitable place. */ static const struct pp_filter_t pp_filters[PP_FILTERS] = { -/* name inner shaders verts init run */ - { "pp_noblue", 0, 2, 1, pp_noblue_init, pp_nocolor }, - { "pp_nogreen", 0, 2, 1, pp_nogreen_init, pp_nocolor }, - { "pp_nored", 0, 2, 1, pp_nored_init, pp_nocolor }, - { "pp_celshade", 0, 2, 1, pp_celshade_init, pp_nocolor }, - { "pp_jimenezmlaa", 2, 5, 2, pp_jimenezmlaa_init, pp_jimenezmlaa }, - { "pp_jimenezmlaa_color", 2, 5, 2, pp_jimenezmlaa_init_color, pp_jimenezmlaa_color }, +/* name inner shaders verts init run free */ + { "pp_noblue", 0, 2, 1, pp_noblue_init, pp_nocolor, pp_nocolor_free }, + { "pp_nogreen", 0, 2, 1, pp_nogreen_init, pp_nocolor, pp_nocolor_free }, + { "pp_nored", 0, 2, 1, pp_nored_init, pp_nocolor, pp_nocolor_free }, + { "pp_celshade", 0, 2, 1, pp_celshade_init, pp_nocolor, pp_celshade_free }, + { "pp_jimenezmlaa", 2, 5, 2, pp_jimenezmlaa_init, pp_jimenezmlaa, pp_jimenezmlaa_free }, + { "pp_jimenezmlaa_color", 2, 5, 2, pp_jimenezmlaa_init_color, pp_jimenezmlaa_color, pp_jimenezmlaa_free }, }; #endif diff --git a/src/gallium/auxiliary/postprocess/postprocess.h b/src/gallium/auxiliary/postprocess/postprocess.h index 9ae1896..52c6c75 100644 --- a/src/gallium/auxiliary/postprocess/postprocess.h +++ b/src/gallium/auxiliary/postprocess/postprocess.h @@ -53,11 +53,13 @@ struct pp_queue_t struct pipe_resource *depth; /* depth of original input */ struct pipe_resource *stencil; /* stencil shared by inner_tmps */ + struct pipe_resource *constbuf; /* MLAA constant buffer */ + struct pipe_resource *areamaptex; /* MLAA area map texture */ struct pipe_surface *tmps[2], *inner_tmps[3], *stencils; void ***shaders; /* Shaders in TGSI form */ - unsigned int *verts; + unsigned int *filters; /* Active filter to filters.h mapping. */ struct program *p; bool fbos_init; @@ -88,14 +90,20 @@ void pp_jimenezmlaa_color(struct pp_queue_t *, struct pipe_resource *, /* The filter init functions */ -void pp_celshade_init(struct pp_queue_t *, unsigned int, unsigned int); +bool pp_celshade_init(struct pp_queue_t *, unsigned int, unsigned int); -void pp_nored_init(struct pp_queue_t *, unsigned int, unsigned int); -void pp_nogreen_init(struct pp_queue_t *, unsigned int, unsigned int); -void pp_noblue_init(struct pp_queue_t *, unsigned int, unsigned int); +bool pp_nored_init(struct pp_queue_t *, unsigned int, unsigned int); +bool pp_nogreen_init(struct pp_queue_t *, unsigned int, unsigned int); +bool pp_noblue_init(struct pp_queue_t *, unsigned int, unsigned int); -void pp_jimenezmlaa_init(struct pp_queue_t *, unsigned int, unsigned int); -void pp_jimenezmlaa_init_color(struct pp_queue_t *, unsigned int, +bool pp_jimenezmlaa_init(struct pp_queue_t *, unsigned int, unsigned int); +bool pp_jimenezmlaa_init_color(struct pp_queue_t *, unsigned int, unsigned int); +/* The filter free functions */ + +void pp_celshade_free(struct pp_queue_t *, unsigned int); +void pp_nocolor_free(struct pp_queue_t *, unsigned int); +void pp_jimenezmlaa_free(struct pp_queue_t *, unsigned int); + #endif diff --git a/src/gallium/auxiliary/postprocess/pp_celshade.c b/src/gallium/auxiliary/postprocess/pp_celshade.c index 447b401..471ec38 100644 --- a/src/gallium/auxiliary/postprocess/pp_celshade.c +++ b/src/gallium/auxiliary/postprocess/pp_celshade.c @@ -30,9 +30,17 @@ #include "postprocess/pp_filters.h" /** Init function */ -void +bool pp_celshade_init(struct pp_queue_t *ppq, unsigned int n, unsigned int val) { ppq->shaders[n][1] = pp_tgsi_to_state(ppq->p->pipe, celshade, false, "celshade"); + + return (ppq->shaders[n][1] != NULL) ? TRUE : FALSE; +} + +/** Free function */ +void +pp_celshade_free(struct pp_queue_t *ppq, unsigned int n) +{ } diff --git a/src/gallium/auxiliary/postprocess/pp_colors.c b/src/gallium/auxiliary/postprocess/pp_colors.c index 82576a7..c30e92e 100644 --- a/src/gallium/auxiliary/postprocess/pp_colors.c +++ b/src/gallium/auxiliary/postprocess/pp_colors.c @@ -57,24 +57,37 @@ pp_nocolor(struct pp_queue_t *ppq, struct pipe_resource *in, /* Init functions */ -void +bool pp_nored_init(struct pp_queue_t *ppq, unsigned int n, unsigned int val) { - ppq->shaders[n][1] = pp_tgsi_to_state(ppq->p->pipe, nored, false, "nored"); + ppq->shaders[n][1] = + pp_tgsi_to_state(ppq->p->pipe, nored, false, "nored"); + + return (ppq->shaders[n][1] != NULL) ? TRUE : FALSE; } -void +bool pp_nogreen_init(struct pp_queue_t *ppq, unsigned int n, unsigned int val) { ppq->shaders[n][1] = pp_tgsi_to_state(ppq->p->pipe, nogreen, false, "nogreen"); + + return (ppq->shaders[n][1] != NULL) ? TRUE : FALSE; } -void +bool pp_noblue_init(struct pp_queue_t *ppq, unsigned int n, unsigned int val) { ppq->shaders[n][1] = pp_tgsi_to_state(ppq->p->pipe, noblue, false, "noblue"); + + return (ppq->shaders[n][1] != NULL) ? TRUE : FALSE; +} + +/* Free functions */ +void +pp_nocolor_free(struct pp_queue_t *ppq, unsigned int n) +{ } diff --git a/src/gallium/auxiliary/postprocess/pp_init.c b/src/gallium/auxiliary/postprocess/pp_init.c index 137c82b..1130248 100644 --- a/src/gallium/auxiliary/postprocess/pp_init.c +++ b/src/gallium/auxiliary/postprocess/pp_init.c @@ -42,57 +42,81 @@ struct pp_queue_t * pp_init(struct pipe_context *pipe, const unsigned int *enabled, struct cso_context *cso) { - + unsigned int num_filters = 0; unsigned int curpos = 0, i, tmp_req = 0; struct pp_queue_t *ppq; - pp_func *tmp_q; pp_debug("Initializing the post-processing queue.\n"); /* How many filters were requested? */ for (i = 0; i < PP_FILTERS; i++) { if (enabled[i]) - curpos++; + num_filters++; } - if (!curpos) + if (num_filters == 0) return NULL; ppq = CALLOC(1, sizeof(struct pp_queue_t)); - tmp_q = CALLOC(curpos, sizeof(pp_func)); - ppq->shaders = CALLOC(curpos, sizeof(void *)); - ppq->verts = CALLOC(curpos, sizeof(unsigned int)); - if (!tmp_q || !ppq || !ppq->shaders || !ppq->verts) + if (ppq == NULL) { + pp_debug("Unable to allocate memory for ppq.\n"); goto error; + } + + ppq->pp_queue = CALLOC(num_filters, sizeof(pp_func)); + if (ppq->pp_queue == NULL) { + pp_debug("Unable to allocate memory for pp_queue.\n"); + goto error; + } + + ppq->shaders = CALLOC(num_filters, sizeof(void *)); + ppq->filters = CALLOC(num_filters, sizeof(unsigned int)); + + if ((ppq->shaders == NULL) || + (ppq->filters == NULL)) { + pp_debug("Unable to allocate memory for shaders and filter arrays.\n"); + goto error; + } ppq->p = pp_init_prog(ppq, pipe, cso); - if (!ppq->p) + if (ppq->p == NULL) { + pp_debug("pp_init_prog returned NULL.\n"); goto error; + } /* Add the enabled filters to the queue, in order */ curpos = 0; - ppq->pp_queue = tmp_q; for (i = 0; i < PP_FILTERS; i++) { if (enabled[i]) { ppq->pp_queue[curpos] = pp_filters[i].main; tmp_req = MAX2(tmp_req, pp_filters[i].inner_tmps); + ppq->filters[curpos] = i; if (pp_filters[i].shaders) { ppq->shaders[curpos] = CALLOC(pp_filters[i].shaders + 1, sizeof(void *)); - ppq->verts[curpos] = pp_filters[i].verts; - if (!ppq->shaders[curpos]) + if (!ppq->shaders[curpos]) { + pp_debug("Unable to allocate memory for shader list.\n"); goto error; + } } - pp_filters[i].init(ppq, curpos, enabled[i]); + + /* Call the initialization function for the filter. */ + if (!pp_filters[i].init(ppq, curpos, enabled[i])) { + pp_debug("Initialization for filter %u failed.\n", i); + goto error; + } curpos++; } } ppq->p->blitctx = util_create_blit(ppq->p->pipe, cso); - if (!ppq->p->blitctx) + + if (ppq->p->blitctx == NULL) { + pp_debug("Unable to create a blit context.\n"); goto error; + } ppq->n_filters = curpos; ppq->n_tmp = (curpos > 2 ? 2 : 1); @@ -104,16 +128,18 @@ pp_init(struct pipe_context *pipe, const unsigned int *enabled, ppq->shaders[i][0] = ppq->p->passvs; pp_debug("Queue successfully allocated. %u filter(s).\n", curpos); - + return ppq; error: - pp_debug("Error setting up pp\n"); - if (ppq) - FREE(ppq->p); - FREE(ppq); - FREE(tmp_q); + if (ppq) { + /* Assign curpos, since we only need to destroy initialized filters. */ + ppq->n_filters = curpos; + + /* Call the common free function which must handle partial initialization. */ + pp_free(ppq); + } return NULL; } @@ -142,33 +168,81 @@ pp_free_fbos(struct pp_queue_t *ppq) ppq->fbos_init = false; } -/** Free the pp queue. Called on context termination. */ +/** + * Free the pp queue. Called on context termination and failure in + * pp_init. + */ void pp_free(struct pp_queue_t *ppq) { - unsigned int i, j; pp_free_fbos(ppq); - util_destroy_blit(ppq->p->blitctx); + if (ppq && ppq->p) { + /* Only destroy created contexts. */ + if (ppq->p->blitctx) { + util_destroy_blit(ppq->p->blitctx); + } - for (i = 0; i < ppq->n_filters; i++) { - for (j = 0; j < PP_MAX_PASSES && ppq->shaders[i][j]; j++) { - if (j >= ppq->verts[i]) { - ppq->p->pipe->delete_fs_state(ppq->p->pipe, ppq->shaders[i][j]); - ppq->shaders[i][j] = NULL; - } - else if (ppq->shaders[i][j] != ppq->p->passvs) { - ppq->p->pipe->delete_vs_state(ppq->p->pipe, ppq->shaders[i][j]); - ppq->shaders[i][j] = NULL; + if (ppq->p->pipe && ppq->filters && ppq->shaders) { + for (i = 0; i < ppq->n_filters; i++) { + unsigned int filter = ppq->filters[i]; + + if (ppq->shaders[i] == NULL) { + continue; + } + + /* + * Common shader destruction code for all postprocessing + * filters. + */ + for (j = 0; j < pp_filters[filter].shaders; j++) { + if (ppq->shaders[i][j] == NULL) { + /* We reached the end of initialized shaders. */ + break; + } + + if (ppq->shaders[i][j] == ppq->p->passvs) { + continue; + } + + assert(ppq); + assert(ppq->p); + assert(ppq->p->pipe); + + if (j >= pp_filters[filter].verts) { + assert(ppq->p->pipe->delete_fs_state); + ppq->p->pipe->delete_fs_state(ppq->p->pipe, + ppq->shaders[i][j]); + ppq->shaders[i][j] = NULL; + } else { + assert(ppq->p->pipe->delete_vs_state); + ppq->p->pipe->delete_vs_state(ppq->p->pipe, + ppq->shaders[i][j]); + ppq->shaders[i][j] = NULL; + } + } + + /* Finally call each filter type's free functionality. */ + pp_filters[filter].free(ppq, i); } } + + FREE(ppq->p); } - FREE(ppq->p); - FREE(ppq->pp_queue); - FREE(ppq); + if (ppq) { + /* + * Handle partial initialization for common resource destruction + * in the create path. + */ + FREE(ppq->filters); + FREE(ppq->shaders); + FREE(ppq->pp_queue); + + FREE(ppq); + } pp_debug("Queue taken down.\n"); } @@ -256,7 +330,6 @@ pp_init_fbos(struct pp_queue_t *ppq, unsigned int w, if (!ppq->stencil || !ppq->stencils) goto error; - p->framebuffer.width = w; p->framebuffer.height = h; diff --git a/src/gallium/auxiliary/postprocess/pp_mlaa.c b/src/gallium/auxiliary/postprocess/pp_mlaa.c index 6d9fa9a..503749b 100644 --- a/src/gallium/auxiliary/postprocess/pp_mlaa.c +++ b/src/gallium/auxiliary/postprocess/pp_mlaa.c @@ -56,16 +56,16 @@ static float constants[] = { 1, 1, 0, 0 }; static unsigned int dimensions[2] = { 0, 0 }; -static struct pipe_resource *constbuf, *areamaptex; - /** Upload the constants. */ static void -up_consts(struct pipe_context *pipe) +up_consts(struct pp_queue_t *ppq) { + struct pipe_context *pipe = ppq->p->pipe; struct pipe_box box; u_box_2d(0, 0, sizeof(constants), 1, &box); - pipe->transfer_inline_write(pipe, constbuf, 0, PIPE_TRANSFER_WRITE, + + pipe->transfer_inline_write(pipe, ppq->constbuf, 0, PIPE_TRANSFER_WRITE, &box, constants, sizeof(constants), sizeof(constants)); } @@ -81,11 +81,24 @@ pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in, struct pipe_depth_stencil_alpha_state mstencil; struct pipe_sampler_view v_tmp, *arr[3]; - unsigned int w = p->framebuffer.width; - unsigned int h = p->framebuffer.height; + unsigned int w = 0; + unsigned int h = 0; const struct pipe_stencil_ref ref = { {1} }; + + /* Insufficient initialization checks. */ + assert(p); + assert(ppq); + assert(ppq->constbuf); + assert(ppq->areamaptex); + assert(ppq->inner_tmp); + assert(ppq->shaders[n]); + + w = p->framebuffer.width; + h = p->framebuffer.height; + memset(&mstencil, 0, sizeof(mstencil)); + cso_set_stencil_ref(p->cso, &ref); /* Init the pixel size constant */ @@ -94,13 +107,15 @@ pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in, constants[0] = 1.0f / p->framebuffer.width; constants[1] = 1.0f / p->framebuffer.height; - up_consts(p->pipe); + up_consts(ppq); dimensions[0] = p->framebuffer.width; dimensions[1] = p->framebuffer.height; } - cso_set_constant_buffer_resource(p->cso, PIPE_SHADER_VERTEX, 0, constbuf); - cso_set_constant_buffer_resource(p->cso, PIPE_SHADER_FRAGMENT, 0, constbuf); + cso_set_constant_buffer_resource(p->cso, PIPE_SHADER_VERTEX, + 0, ppq->constbuf); + cso_set_constant_buffer_resource(p->cso, PIPE_SHADER_FRAGMENT, + 0, ppq->constbuf); mstencil.stencil[0].enabled = 1; mstencil.stencil[0].valuemask = mstencil.stencil[0].writemask = ~0; @@ -142,7 +157,7 @@ pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in, mstencil.stencil[0].zpass_op = PIPE_STENCIL_OP_KEEP; cso_set_depth_stencil_alpha(p->cso, &mstencil); - pp_filter_setup_in(p, areamaptex); + pp_filter_setup_in(p, ppq->areamaptex); pp_filter_setup_out(p, ppq->inner_tmp[1]); u_sampler_view_default_template(&v_tmp, ppq->inner_tmp[0], @@ -206,32 +221,34 @@ pp_jimenezmlaa_run(struct pp_queue_t *ppq, struct pipe_resource *in, } /** The init function of the MLAA filter. */ -static void +static bool pp_jimenezmlaa_init_run(struct pp_queue_t *ppq, unsigned int n, unsigned int val, bool iscolor) { struct pipe_box box; struct pipe_resource res; - char *tmp_text; - - constbuf = pipe_buffer_create(ppq->p->screen, PIPE_BIND_CONSTANT_BUFFER, - PIPE_USAGE_STATIC, sizeof(constants)); - if (!constbuf) { - pp_debug("Failed to allocate constant buffer\n"); - return; - } - - - pp_debug("mlaa: using %u max search steps\n", val); + char *tmp_text = NULL; tmp_text = CALLOC(sizeof(blend2fs_1) + sizeof(blend2fs_2) + IMM_SPACE, sizeof(char)); - if (!tmp_text) { + if (tmp_text == NULL) { pp_debug("Failed to allocate shader space\n"); - return; + return FALSE; + } + + ppq->constbuf = pipe_buffer_create(ppq->p->screen, + PIPE_BIND_CONSTANT_BUFFER, + PIPE_USAGE_STATIC, + sizeof(constants)); + if (ppq->constbuf == NULL) { + pp_debug("Failed to allocate constant buffer\n"); + goto fail; } + + pp_debug("mlaa: using %u max search steps\n", val); + util_sprintf(tmp_text, "%s" "IMM FLT32 { %.8f, 0.0000, 0.0000, 0.0000}\n" "%s\n", blend2fs_1, (float) val, blend2fs_2); @@ -249,15 +266,19 @@ pp_jimenezmlaa_init_run(struct pp_queue_t *ppq, unsigned int n, res.target, 1, res.bind)) pp_debug("Areamap format not supported\n"); - areamaptex = ppq->p->screen->resource_create(ppq->p->screen, &res); + ppq->areamaptex = ppq->p->screen->resource_create(ppq->p->screen, &res); + + if (ppq->areamaptex == NULL) { + pp_debug("Failed to allocate area map texture\n"); + goto fail; + } + u_box_2d(0, 0, 165, 165, &box); - ppq->p->pipe->transfer_inline_write(ppq->p->pipe, areamaptex, 0, + ppq->p->pipe->transfer_inline_write(ppq->p->pipe, ppq->areamaptex, 0, PIPE_TRANSFER_WRITE, &box, areamap, 165 * 2, sizeof(areamap)); - - ppq->shaders[n][1] = pp_tgsi_to_state(ppq->p->pipe, offsetvs, true, "offsetvs"); if (iscolor) @@ -272,23 +293,35 @@ pp_jimenezmlaa_init_run(struct pp_queue_t *ppq, unsigned int n, "neigh3fs"); FREE(tmp_text); + + return TRUE; + + fail: + + FREE(tmp_text); + + /* + * Call the common free function for destruction of partially initialized + * resources. + */ + pp_jimenezmlaa_free(ppq, n); + + return FALSE; } /** Short wrapper to init the depth version. */ -void +bool pp_jimenezmlaa_init(struct pp_queue_t *ppq, unsigned int n, unsigned int val) { - - pp_jimenezmlaa_init_run(ppq, n, val, false); + return pp_jimenezmlaa_init_run(ppq, n, val, false); } /** Short wrapper to init the color version. */ -void +bool pp_jimenezmlaa_init_color(struct pp_queue_t *ppq, unsigned int n, unsigned int val) { - - pp_jimenezmlaa_init_run(ppq, n, val, true); + return pp_jimenezmlaa_init_run(ppq, n, val, true); } /** Short wrapper to run the depth version. */ @@ -306,3 +339,23 @@ pp_jimenezmlaa_color(struct pp_queue_t *ppq, struct pipe_resource *in, { pp_jimenezmlaa_run(ppq, in, out, n, true); } + + +/** + * Short wrapper to free the mlaa filter resources. Shaders are freed in + * the common code in pp_free. + */ +void +pp_jimenezmlaa_free(struct pp_queue_t *ppq, unsigned int n) +{ + if (ppq->areamaptex) { + ppq->p->screen->resource_destroy(ppq->p->screen, ppq->areamaptex); + ppq->areamaptex = NULL; + } + + if (ppq->constbuf) { + ppq->p->screen->resource_destroy(ppq->p->screen, ppq->constbuf); + ppq->constbuf = NULL; + } +} + diff --git a/src/gallium/auxiliary/postprocess/pp_run.c b/src/gallium/auxiliary/postprocess/pp_run.c index 54253f4..9bd977b 100644 --- a/src/gallium/auxiliary/postprocess/pp_run.c +++ b/src/gallium/auxiliary/postprocess/pp_run.c @@ -32,6 +32,8 @@ #include "util/u_inlines.h" #include "util/u_sampler.h" +#include "tgsi/tgsi_parse.h" + /** * Main run function of the PP queue. Called on swapbuffers/flush. * @@ -46,6 +48,13 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in, unsigned int i; struct cso_context *cso = ppq->p->cso; + if (ppq->n_filters == 0) + return; + + assert(ppq->pp_queue); + assert(ppq->tmp[0]); + assert(ppq->tmp[1]); + if (in->width0 != ppq->p->framebuffer.width || in->height0 != ppq->p->framebuffer.height) { pp_debug("Resizing the temp pp buffers\n"); @@ -98,6 +107,9 @@ pp_run(struct pp_queue_t *ppq, struct pipe_resource *in, pipe_resource_reference(&refout, out); switch (ppq->n_filters) { + case 0: + /* Failsafe, but never reached. */ + break; case 1: /* No temp buf */ ppq->pp_queue[0] (ppq, in, out, 0); break; @@ -192,7 +204,19 @@ pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs, const char *name) { struct pipe_shader_state state; - struct tgsi_token tokens[PP_MAX_TOKENS]; + struct tgsi_token *tokens = NULL; + void *ret_state = NULL; + + /* + * Allocate temporary token storage. State creation will duplicate + * tokens so we must free them on exit. + */ + tokens = tgsi_alloc_tokens(PP_MAX_TOKENS); + + if (tokens == NULL) { + pp_debug("Failed to allocate temporary token storage.\n"); + return NULL; + } if (tgsi_text_translate(text, tokens, Elements(tokens)) == FALSE) { pp_debug("Failed to translate %s\n", name); @@ -202,10 +226,15 @@ pp_tgsi_to_state(struct pipe_context *pipe, const char *text, bool isvs, state.tokens = tokens; memset(&state.stream_output, 0, sizeof(state.stream_output)); - if (isvs) - return pipe->create_vs_state(pipe, &state); - else - return pipe->create_fs_state(pipe, &state); + if (isvs) { + ret_state = pipe->create_vs_state(pipe, &state); + FREE(tokens); + } else { + ret_state = pipe->create_fs_state(pipe, &state); + FREE(tokens); + } + + return ret_state; } /** Setup misc state for the filter. */ |