summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBrian Paul <brian.paul@tungstengraphics.com>2008-05-17 10:30:21 -0600
committerBrian Paul <brian.paul@tungstengraphics.com>2008-05-17 10:30:21 -0600
commit9671f7ae476cadb46f9f8f9d0363f24aabaf9f87 (patch)
tree8fb1c3b27bc41cb5b2a5a144746d5eb5991facbc /src
parent718a2d8c7a125609a8dca813703047e24de09653 (diff)
gallium: in drivers, make copy of tokens passed to pipe->create_vs/fs_state()
The caller can then free the token array immediately.
Diffstat (limited to 'src')
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_exec.c11
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_llvm.c7
-rw-r--r--src/gallium/auxiliary/draw/draw_vs_sse.c5
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_parse.c15
-rw-r--r--src/gallium/auxiliary/tgsi/util/tgsi_parse.h31
-rw-r--r--src/gallium/drivers/cell/ppu/cell_state_shader.c84
-rw-r--r--src/gallium/drivers/i915simple/i915_state.c5
-rw-r--r--src/gallium/drivers/i965simple/brw_state.c19
-rw-r--r--src/gallium/drivers/softpipe/sp_fs_exec.c5
-rw-r--r--src/gallium/drivers/softpipe/sp_state.h7
-rw-r--r--src/gallium/drivers/softpipe/sp_state_fs.c5
11 files changed, 137 insertions, 57 deletions
diff --git a/src/gallium/auxiliary/draw/draw_vs_exec.c b/src/gallium/auxiliary/draw/draw_vs_exec.c
index 54a2b2ab04..7a02f6334b 100644
--- a/src/gallium/auxiliary/draw/draw_vs_exec.c
+++ b/src/gallium/auxiliary/draw/draw_vs_exec.c
@@ -39,6 +39,7 @@
#include "draw_vs.h"
#include "tgsi/util/tgsi_parse.h"
+#include "tgsi/util/tgsi_scan.h"
struct exec_vertex_shader {
@@ -165,21 +166,23 @@ draw_create_vs_exec(struct draw_context *draw,
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;
}
diff --git a/src/gallium/auxiliary/draw/draw_vs_llvm.c b/src/gallium/auxiliary/draw/draw_vs_llvm.c
index dcada66514..be6907ed04 100644
--- a/src/gallium/auxiliary/draw/draw_vs_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_vs_llvm.c
@@ -138,14 +138,17 @@ draw_create_vs_llvm(struct draw_context *draw,
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);
diff --git a/src/gallium/auxiliary/draw/draw_vs_sse.c b/src/gallium/auxiliary/draw/draw_vs_sse.c
index a57c938fbf..5929ea76b2 100644
--- a/src/gallium/auxiliary/draw/draw_vs_sse.c
+++ b/src/gallium/auxiliary/draw/draw_vs_sse.c
@@ -188,7 +188,6 @@ draw_create_vs_sse(struct draw_context *draw,
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;
@@ -198,7 +197,9 @@ draw_create_vs_sse(struct draw_context *draw,
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);
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c
index 5bea773840..5c0b0bfd61 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.c
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.c
@@ -330,3 +330,18 @@ tgsi_num_tokens(const struct tgsi_token *tokens)
}
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;
+}
diff --git a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
index 15e76feb7c..4102101093 100644
--- a/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
+++ b/src/gallium/auxiliary/tgsi/util/tgsi_parse.h
@@ -1,4 +1,31 @@
-#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"
@@ -118,6 +145,8 @@ tgsi_parse_token(
unsigned
tgsi_num_tokens(const struct tgsi_token *tokens);
+struct tgsi_token *
+tgsi_dup_tokens(const struct tgsi_token *tokens);
#if defined __cplusplus
}
diff --git a/src/gallium/drivers/cell/ppu/cell_state_shader.c b/src/gallium/drivers/cell/ppu/cell_state_shader.c
index fb2e940348..c3a3fbd066 100644
--- a/src/gallium/drivers/cell/ppu/cell_state_shader.c
+++ b/src/gallium/drivers/cell/ppu/cell_state_shader.c
@@ -30,33 +30,50 @@
#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;
}
@@ -65,7 +82,7 @@ cell_bind_fs_state(struct pipe_context *pipe, void *fs)
{
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;
}
@@ -74,10 +91,10 @@ cell_bind_fs_state(struct pipe_context *pipe, void *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);
}
@@ -86,22 +103,28 @@ cell_create_vs_state(struct pipe_context *pipe,
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;
}
@@ -110,7 +133,7 @@ cell_bind_vs_state(struct pipe_context *pipe, void *vs)
{
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));
@@ -123,12 +146,11 @@ static void
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 );
}
diff --git a/src/gallium/drivers/i915simple/i915_state.c b/src/gallium/drivers/i915simple/i915_state.c
index 3d94b52366..4adeb37e86 100644
--- a/src/gallium/drivers/i915simple/i915_state.c
+++ b/src/gallium/drivers/i915simple/i915_state.c
@@ -33,6 +33,7 @@
#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"
@@ -436,7 +437,7 @@ i915_create_fs_state(struct pipe_context *pipe,
if (!ifs)
return NULL;
- ifs->state = *templ;
+ ifs->state.tokens = tgsi_dup_tokens(templ->tokens);
tgsi_scan_shader(templ->tokens, &ifs->info);
@@ -465,6 +466,8 @@ void i915_delete_fs_state(struct pipe_context *pipe, void *shader)
FREE(ifs->program);
ifs->program_len = 0;
+ FREE(ifs->state.tokens);
+
FREE(ifs);
}
diff --git a/src/gallium/drivers/i965simple/brw_state.c b/src/gallium/drivers/i965simple/brw_state.c
index 376f1487b2..ac243b7e4f 100644
--- a/src/gallium/drivers/i965simple/brw_state.c
+++ b/src/gallium/drivers/i965simple/brw_state.c
@@ -35,6 +35,7 @@
#include "pipe/p_inlines.h"
#include "pipe/p_shader_tokens.h"
#include "tgsi/util/tgsi_dump.h"
+#include "tgsi/util/tgsi_parse.h"
#include "brw_context.h"
#include "brw_defines.h"
@@ -182,9 +183,7 @@ static void * brw_create_fs_state(struct pipe_context *pipe,
{
struct brw_fragment_program *brw_fp = CALLOC_STRUCT(brw_fragment_program);
- /* XXX: Do I have to duplicate the tokens as well??
- */
- brw_fp->program = *shader;
+ brw_fp->program.tokens = tgsi_dup_tokens(shader->tokens);
brw_fp->id = brw_context(pipe)->program_id++;
tgsi_scan_shader(shader->tokens, &brw_fp->info);
@@ -210,7 +209,10 @@ static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
static void brw_delete_fs_state(struct pipe_context *pipe, void *shader)
{
- FREE(shader);
+ struct brw_fragment_program *brw_fp = (struct brw_fragment_program *) shader;
+
+ FREE((void *) brw_fp->program.tokens);
+ FREE(brw_fp);
}
@@ -223,9 +225,7 @@ static void *brw_create_vs_state(struct pipe_context *pipe,
{
struct brw_vertex_program *brw_vp = CALLOC_STRUCT(brw_vertex_program);
- /* XXX: Do I have to duplicate the tokens as well??
- */
- brw_vp->program = *shader;
+ brw_vp->program.tokens = tgsi_dup_tokens(shader->tokens);
brw_vp->id = brw_context(pipe)->program_id++;
tgsi_scan_shader(shader->tokens, &brw_vp->info);
@@ -251,7 +251,10 @@ static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
static void brw_delete_vs_state(struct pipe_context *pipe, void *shader)
{
- FREE(shader);
+ struct brw_vertex_program *brw_vp = (struct brw_vertex_program *) shader;
+
+ FREE((void *) brw_vp->program.tokens);
+ FREE(brw_vp);
}
diff --git a/src/gallium/drivers/softpipe/sp_fs_exec.c b/src/gallium/drivers/softpipe/sp_fs_exec.c
index d5bd7a702f..0b199a2193 100644
--- a/src/gallium/drivers/softpipe/sp_fs_exec.c
+++ b/src/gallium/drivers/softpipe/sp_fs_exec.c
@@ -37,6 +37,7 @@
#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;
@@ -116,6 +117,7 @@ exec_run( const struct sp_fragment_shader *base,
static void
exec_delete( struct sp_fragment_shader *base )
{
+ FREE((void *) base->shader.tokens);
FREE(base);
}
@@ -137,7 +139,8 @@ softpipe_create_fs_exec(struct softpipe_context *softpipe,
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;
diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h
index 45056502b8..452e51fa79 100644
--- a/src/gallium/drivers/softpipe/sp_state.h
+++ b/src/gallium/drivers/softpipe/sp_state.h
@@ -54,9 +54,11 @@
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...
*/
@@ -80,11 +82,10 @@ struct sp_fragment_shader {
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;
};
diff --git a/src/gallium/drivers/softpipe/sp_state_fs.c b/src/gallium/drivers/softpipe/sp_state_fs.c
index 9e77b7e91b..24b91fbc79 100644
--- a/src/gallium/drivers/softpipe/sp_state_fs.c
+++ b/src/gallium/drivers/softpipe/sp_state_fs.c
@@ -102,10 +102,7 @@ softpipe_create_vs_state(struct pipe_context *pipe,
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;