The caller can then free the token array immediately.
#include "draw_vs.h"
#include "tgsi/util/tgsi_parse.h"
+#include "tgsi/util/tgsi_scan.h"
struct exec_vertex_shader {
const struct pipe_shader_state *state)
{
struct exec_vertex_shader *vs = CALLOC_STRUCT( exec_vertex_shader );
- uint nt = tgsi_num_tokens(state->tokens);
if (vs == NULL)
return NULL;
/* we make a private copy of the tokens */
- vs->base.state.tokens = mem_dup(state->tokens, nt * sizeof(state->tokens[0]));
- tgsi_scan_shader(state->tokens, &vs->base.info);
+ vs->base.state.tokens = tgsi_dup_tokens(state->tokens);
+ if (!vs->base.state.tokens) {
+ FREE(vs);
+ return NULL;
+ }
+ tgsi_scan_shader(state->tokens, &vs->base.info);
vs->base.prepare = vs_exec_prepare;
vs->base.run_linear = vs_exec_run_linear;
vs->base.delete = vs_exec_delete;
vs->machine = &draw->machine;
-
return &vs->base;
}
const struct pipe_shader_state *templ)
{
struct draw_llvm_vertex_shader *vs;
- uint nt = tgsi_num_tokens(templ->tokens);
vs = CALLOC_STRUCT( draw_llvm_vertex_shader );
if (vs == NULL)
return NULL;
/* we make a private copy of the tokens */
- vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0]));
+ vs->base.state.tokens = tgsi_dup_tokens(templ->tokens);
+ if (!vs->base.state.tokens) {
+ FREE(vs);
+ return NULL;
+ }
tgsi_scan_shader(vs->base.state.tokens, &vs->base.info);
const struct pipe_shader_state *templ)
{
struct draw_sse_vertex_shader *vs;
- uint nt = tgsi_num_tokens(templ->tokens);
if (!rtasm_cpu_has_sse2())
return NULL;
return NULL;
/* we make a private copy of the tokens */
- vs->base.state.tokens = mem_dup(templ->tokens, nt * sizeof(templ->tokens[0]));
+ vs->base.state.tokens = tgsi_dup_tokens(templ->tokens);
+ if (!vs->base.state.tokens)
+ goto fail;
tgsi_scan_shader(templ->tokens, &vs->base.info);
}
return 0;
}
+
+
+/**
+ * Make a new copy of a token array.
+ */
+struct tgsi_token *
+tgsi_dup_tokens(const struct tgsi_token *tokens)
+{
+ unsigned n = tgsi_num_tokens(tokens);
+ unsigned bytes = n * sizeof(struct tgsi_token);
+ struct tgsi_token *new_tokens = (struct tgsi_token *) MALLOC(bytes);
+ if (new_tokens)
+ memcpy(new_tokens, tokens, bytes);
+ return new_tokens;
+}
-#if !defined TGSI_PARSE_H
+/**************************************************************************
+ *
+ * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sub license, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
+ * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
+ * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
+ * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
+ * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
+ * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ **************************************************************************/
+
+#ifndef TGSI_PARSE_H
#define TGSI_PARSE_H
#include "pipe/p_shader_tokens.h"
unsigned
tgsi_num_tokens(const struct tgsi_token *tokens);
+struct tgsi_token *
+tgsi_dup_tokens(const struct tgsi_token *tokens);
#if defined __cplusplus
}
#include "pipe/p_inlines.h"
#include "pipe/p_winsys.h"
#include "draw/draw_context.h"
-#if 0
-#include "pipe/p_shader_tokens.h"
-#include "gallivm/gallivm.h"
-#include "tgsi/util/tgsi_dump.h"
-#include "tgsi/exec/tgsi_sse2.h"
-#endif
+#include "tgsi/util/tgsi_parse.h"
#include "cell_context.h"
#include "cell_state.h"
+
+/** cast wrapper */
+static INLINE struct cell_fragment_shader_state *
+cell_fragment_shader_state(void *shader)
+{
+ return (struct pipe_shader_state *) shader;
+}
+
+
+/** cast wrapper */
+static INLINE struct cell_vertex_shader_state *
+cell_vertex_shader_state(void *shader)
+{
+ return (struct pipe_shader_state *) shader;
+}
+
+
+
static void *
cell_create_fs_state(struct pipe_context *pipe,
const struct pipe_shader_state *templ)
{
/*struct cell_context *cell = cell_context(pipe);*/
- struct cell_fragment_shader_state *state;
+ struct cell_fragment_shader_state *cfs;
- state = CALLOC_STRUCT(cell_fragment_shader_state);
- if (!state)
+ cfs = CALLOC_STRUCT(cell_fragment_shader_state);
+ if (!cfs)
return NULL;
- state->shader = *templ;
+ cfs->shader.tokens = tgsi_dup_tokens(templ->tokens);
+ if (!cfs->shader.tokens) {
+ FREE(cfs);
+ return NULL;
+ }
- tgsi_scan_shader(templ->tokens, &state->info);
+ tgsi_scan_shader(templ->tokens, &cfs->info);
- return state;
+ return cfs;
}
{
struct cell_context *cell = cell_context(pipe);
- cell->fs = (struct cell_fragment_shader_state *) fs;
+ cell->fs = cell_fragment_shader_state(fs);
cell->dirty |= CELL_NEW_FS;
}
static void
cell_delete_fs_state(struct pipe_context *pipe, void *fs)
{
- struct cell_fragment_shader_state *state =
- (struct cell_fragment_shader_state *) fs;
+ struct cell_fragment_shader_state *cfs = cell_fragment_shader_state(fs);
- FREE( state );
+ FREE((void *) cfs->shader.tokens);
+ FREE(cfs);
}
const struct pipe_shader_state *templ)
{
struct cell_context *cell = cell_context(pipe);
- struct cell_vertex_shader_state *state;
+ struct cell_vertex_shader_state *cvs;
- state = CALLOC_STRUCT(cell_vertex_shader_state);
- if (!state)
+ cvs = CALLOC_STRUCT(cell_vertex_shader_state);
+ if (!cvs)
return NULL;
- state->shader = *templ;
- tgsi_scan_shader(templ->tokens, &state->info);
+ cvs->shader.tokens = tgsi_dup_tokens(templ->tokens);
+ if (!cvs->shader.tokens) {
+ FREE(cvs);
+ return NULL;
+ }
- state->draw_data = draw_create_vertex_shader(cell->draw, &state->shader);
- if (state->draw_data == NULL) {
- FREE( state );
+ tgsi_scan_shader(templ->tokens, &cvs->info);
+
+ cvs->draw_data = draw_create_vertex_shader(cell->draw, &cvs->shader);
+ if (cvs->draw_data == NULL) {
+ FREE( (void *) cvs->shader.tokens );
+ FREE( cvs );
return NULL;
}
- return state;
+ return cvs;
}
{
struct cell_context *cell = cell_context(pipe);
- cell->vs = (const struct cell_vertex_shader_state *) vs;
+ cell->vs = cell_vertex_shader_state(vs);
draw_bind_vertex_shader(cell->draw,
(cell->vs ? cell->vs->draw_data : NULL));
cell_delete_vs_state(struct pipe_context *pipe, void *vs)
{
struct cell_context *cell = cell_context(pipe);
+ struct cell_vertex_shader_state *cvs = cell_vertex_shader_state(vs);
- struct cell_vertex_shader_state *state =
- (struct cell_vertex_shader_state *) vs;
-
- draw_delete_vertex_shader(cell->draw, state->draw_data);
- FREE( state );
+ draw_delete_vertex_shader(cell->draw, cvs->draw_data);
+ FREE( (void *) cvs->shader.tokens );
+ FREE( cvs );
}
#include "pipe/p_winsys.h"
#include "pipe/p_util.h"
#include "pipe/p_inlines.h"
+#include "tgsi/util/tgsi_parse.h"
#include "i915_context.h"
#include "i915_reg.h"
if (!ifs)
return NULL;
- ifs->state = *templ;
+ ifs->state.tokens = tgsi_dup_tokens(templ->tokens);
tgsi_scan_shader(templ->tokens, &ifs->info);
FREE(ifs->program);
ifs->program_len = 0;
+ FREE(ifs->state.tokens);
+
FREE(ifs);
}
#include "pipe/p_inlines.h"\r
#include "pipe/p_shader_tokens.h"\r
#include "tgsi/util/tgsi_dump.h"\r
+#include "tgsi/util/tgsi_parse.h"\r
\r
#include "brw_context.h"\r
#include "brw_defines.h"\r
{\r
struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);\r
\r
- /* XXX: Do I have to duplicate the tokens as well??\r
- */\r
- brw_fp->program = *shader;\r
+ brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens);\r
brw_fp->id = brw_context(pipe)->program_id++;\r
\r
tgsi_scan_shader(shader->tokens, &brw_fp->info);\r
\r
static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)\r
{\r
- FREE(shader);\r
+ struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader;\r
+\r
+ FREE((void *) brw_fp->program.tokens);\r
+ FREE(brw_fp);\r
}\r
\r
\r
{\r
struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);\r
\r
- /* XXX: Do I have to duplicate the tokens as well??\r
- */\r
- brw_vp->program = *shader;\r
+ brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens);\r
brw_vp->id = brw_context(pipe)->program_id++;\r
\r
tgsi_scan_shader(shader->tokens, &brw_vp->info);\r
\r
static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)\r
{\r
- FREE(shader);\r
+ struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader;\r
+\r
+ FREE((void *) brw_vp->program.tokens);\r
+ FREE(brw_vp);\r
}\r
\r
\r
#include "pipe/p_util.h"
#include "pipe/p_inlines.h"
#include "tgsi/exec/tgsi_exec.h"
+#include "tgsi/util/tgsi_parse.h"
struct sp_exec_fragment_shader {
struct sp_fragment_shader base;
static void
exec_delete( struct sp_fragment_shader *base )
{
+ FREE((void *) base->shader.tokens);
FREE(base);
}
if (!shader)
return NULL;
- shader->base.shader = *templ;
+ /* we need to keep a local copy of the tokens */
+ shader->base.shader.tokens = tgsi_dup_tokens(templ->tokens);
shader->base.prepare = exec_prepare;
shader->base.run = exec_run;
shader->base.delete = exec_delete;
struct tgsi_sampler;
struct tgsi_exec_machine;
+struct vertex_info;
-/** Subclass of pipe_shader_state (though it doesn't really need to be).
+/**
+ * Subclass of pipe_shader_state (though it doesn't really need to be).
*
* This is starting to look an awful lot like a quad pipeline stage...
*/
void (*delete)( struct sp_fragment_shader * );
};
-struct vertex_info;
/** Subclass of pipe_shader_state */
struct sp_vertex_shader {
- struct pipe_shader_state shader;
+ struct pipe_shader_state shader; /* Note: this field not actually used */
struct draw_vertex_shader *draw_data;
};
return NULL;
}
- state->shader = *templ;
-
- state->draw_data = draw_create_vertex_shader(softpipe->draw,
- &state->shader);
+ state->draw_data = draw_create_vertex_shader(softpipe->draw, templ);
if (state->draw_data == NULL) {
FREE( state );
return NULL;