gallium: in drivers, make copy of tokens passed to pipe->create_vs/fs_state()
authorBrian Paul <brian.paul@tungstengraphics.com>
Sat, 17 May 2008 16:30:21 +0000 (10:30 -0600)
committerBrian Paul <brian.paul@tungstengraphics.com>
Sat, 17 May 2008 16:30:21 +0000 (10:30 -0600)
The caller can then free the token array immediately.

src/gallium/auxiliary/draw/draw_vs_exec.c
src/gallium/auxiliary/draw/draw_vs_llvm.c
src/gallium/auxiliary/draw/draw_vs_sse.c
src/gallium/auxiliary/tgsi/util/tgsi_parse.c
src/gallium/auxiliary/tgsi/util/tgsi_parse.h
src/gallium/drivers/cell/ppu/cell_state_shader.c
src/gallium/drivers/i915simple/i915_state.c
src/gallium/drivers/i965simple/brw_state.c
src/gallium/drivers/softpipe/sp_fs_exec.c
src/gallium/drivers/softpipe/sp_state.h
src/gallium/drivers/softpipe/sp_state_fs.c

index 54a2b2ab040fd3acf6f9b80d9ef6459a691f8181..7a02f6334b139a9ed51bf19354f8a293c6d628d2 100644 (file)
@@ -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;
 }
index dcada665143d496901d0d51556ee2c531a7ecb5c..be6907ed04271870975f45549e37b79c7c79bcee 100644 (file)
@@ -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);
 
index a57c938fbf1fa07a7ca5f7907037addf857e59d5..5929ea76b23d17441558d0fadbd8c9bfb6484b08 100644 (file)
@@ -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);
 
index 5bea7738401af9ea90ad7f00e3819a0cf113dcff..5c0b0bfd61b18e077c25ae72fb29ceb9ecfc360a 100644 (file)
@@ -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;
+}
index 15e76feb7ca3234e9008f8fc09b35d666935a976..41021010936c452f91910bee4c5bd6188fab150a 100644 (file)
@@ -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
 }
index fb2e940348ac131f9295d92baa42dc3b850197c5..c3a3fbd066d5055e4b3085c1b4417a1ac21ddad7 100644 (file)
 #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 );
 }
 
 
index 3d94b52366004bacccae22b951f6b19b2eeb527a..4adeb37e86005650c1eae2303d4a3661aa72df3c 100644 (file)
@@ -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);
 }
 
index 376f1487b293cba97b1c975d13a620ec81e1e5f4..ac243b7e4f9b1963e56180b8d1e8e318b4da70c1 100644 (file)
@@ -35,6 +35,7 @@
 #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
@@ -182,9 +183,7 @@ static void * brw_create_fs_state(struct pipe_context *pipe,
 {\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
@@ -210,7 +209,10 @@ static void brw_bind_fs_state(struct pipe_context *pipe, void *shader)
 \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
@@ -223,9 +225,7 @@ static void *brw_create_vs_state(struct pipe_context *pipe,
 {\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
@@ -251,7 +251,10 @@ static void brw_bind_vs_state(struct pipe_context *pipe, void *vs)
 \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
index d5bd7a702f11b96b576ef6c53d3ef55691d00760..0b199a2193e9fa579b07556c45b4b64d0ed644ce 100644 (file)
@@ -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;
index 45056502b8e5c141e1e7c78cacc707f637b1720a..452e51fa7912902d7f7550435ae97971d42a9cf9 100644 (file)
 
 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;
 };
 
index 9e77b7e91bc79e83d91389c376cb0e8e9606a371..24b91fbc79435aa7c390b7e65c7cde30ceb22f64 100644 (file)
@@ -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;