draw_vs_exec.c

Go to the documentation of this file.
00001 /**************************************************************************
00002  * 
00003  * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas.
00004  * All Rights Reserved.
00005  * 
00006  * Permission is hereby granted, free of charge, to any person obtaining a
00007  * copy of this software and associated documentation files (the
00008  * "Software"), to deal in the Software without restriction, including
00009  * without limitation the rights to use, copy, modify, merge, publish,
00010  * distribute, sub license, and/or sell copies of the Software, and to
00011  * permit persons to whom the Software is furnished to do so, subject to
00012  * the following conditions:
00013  * 
00014  * The above copyright notice and this permission notice (including the
00015  * next paragraph) shall be included in all copies or substantial portions
00016  * of the Software.
00017  * 
00018  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00019  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00020  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
00021  * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
00022  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
00023  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
00024  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
00025  * 
00026  **************************************************************************/
00027 
00028  /*
00029   * Authors:
00030   *   Keith Whitwell <keith@tungstengraphics.com>
00031   *   Brian Paul
00032   */
00033 
00034 #include "util/u_math.h"
00035 #include "util/u_memory.h"
00036 #include "pipe/p_shader_tokens.h"
00037 
00038 #include "draw_private.h"
00039 #include "draw_context.h"
00040 #include "draw_vs.h"
00041 
00042 #include "tgsi/tgsi_parse.h"
00043 #include "tgsi/tgsi_scan.h"
00044 
00045 
00046 struct exec_vertex_shader {
00047    struct draw_vertex_shader base;
00048    struct tgsi_exec_machine *machine;
00049 };
00050 
00051 static struct exec_vertex_shader *exec_vertex_shader( struct draw_vertex_shader *vs )
00052 {
00053    return (struct exec_vertex_shader *)vs;
00054 }
00055 
00056 
00057 /* Not required for run_linear.
00058  */
00059 static void
00060 vs_exec_prepare( struct draw_vertex_shader *shader,
00061                  struct draw_context *draw )
00062 {
00063    struct exec_vertex_shader *evs = exec_vertex_shader(shader);
00064 
00065    /* specify the vertex program to interpret/execute */
00066    tgsi_exec_machine_bind_shader(evs->machine,
00067                                  shader->state.tokens,
00068                                  PIPE_MAX_SAMPLERS,
00069                                  NULL /*samplers*/ );
00070 
00071 }
00072 
00073 
00074 
00075 
00076 /* Simplified vertex shader interface for the pt paths.  Given the
00077  * complexity of code-generating all the above operations together,
00078  * it's time to try doing all the other stuff separately.
00079  */
00080 static void
00081 vs_exec_run_linear( struct draw_vertex_shader *shader,
00082                     const float (*input)[4],
00083                     float (*output)[4],
00084                     const float (*constants)[4],
00085                     unsigned count,
00086                     unsigned input_stride,
00087                     unsigned output_stride )
00088 {
00089    struct exec_vertex_shader *evs = exec_vertex_shader(shader);
00090    struct tgsi_exec_machine *machine = evs->machine;
00091    unsigned int i, j;
00092    unsigned slot;
00093 
00094    machine->Consts = constants;
00095 
00096    for (i = 0; i < count; i += MAX_TGSI_VERTICES) {
00097       unsigned int max_vertices = MIN2(MAX_TGSI_VERTICES, count - i);
00098 
00099       /* Swizzle inputs.  
00100        */
00101       for (j = 0; j < max_vertices; j++) {
00102 #if 0
00103          debug_printf("%d) Input vert:\n", i + j);
00104          for (slot = 0; slot < shader->info.num_inputs; slot++) {
00105             debug_printf("\t%d: %f %f %f %f\n", slot,
00106                          input[slot][0],
00107                          input[slot][1],
00108                          input[slot][2],
00109                          input[slot][3]);
00110          }
00111 #endif
00112 
00113          for (slot = 0; slot < shader->info.num_inputs; slot++) {
00114             machine->Inputs[slot].xyzw[0].f[j] = input[slot][0];
00115             machine->Inputs[slot].xyzw[1].f[j] = input[slot][1];
00116             machine->Inputs[slot].xyzw[2].f[j] = input[slot][2];
00117             machine->Inputs[slot].xyzw[3].f[j] = input[slot][3];
00118          }
00119 
00120          input = (const float (*)[4])((const char *)input + input_stride);
00121       } 
00122 
00123       tgsi_set_exec_mask(machine,
00124                          1,
00125                          max_vertices > 1,
00126                          max_vertices > 2,
00127                          max_vertices > 3);
00128 
00129       /* run interpreter */
00130       tgsi_exec_machine_run( machine );
00131 
00132       /* Unswizzle all output results.  
00133        */
00134       for (j = 0; j < max_vertices; j++) {
00135          for (slot = 0; slot < shader->info.num_outputs; slot++) {
00136             output[slot][0] = machine->Outputs[slot].xyzw[0].f[j];
00137             output[slot][1] = machine->Outputs[slot].xyzw[1].f[j];
00138             output[slot][2] = machine->Outputs[slot].xyzw[2].f[j];
00139             output[slot][3] = machine->Outputs[slot].xyzw[3].f[j];
00140 
00141          }
00142 
00143 #if 0
00144          debug_printf("%d) Post xform vert:\n", i + j);
00145          for (slot = 0; slot < shader->info.num_outputs; slot++) {
00146             debug_printf("\t%d: %f %f %f %f\n", slot,
00147                          output[slot][0],
00148                          output[slot][1],
00149                          output[slot][2],
00150                          output[slot][3]);
00151          }
00152 #endif
00153 
00154          output = (float (*)[4])((char *)output + output_stride);
00155       } 
00156 
00157    }
00158 }
00159 
00160 
00161 
00162 
00163 static void
00164 vs_exec_delete( struct draw_vertex_shader *dvs )
00165 {
00166    FREE((void*) dvs->state.tokens);
00167    FREE( dvs );
00168 }
00169 
00170 
00171 struct draw_vertex_shader *
00172 draw_create_vs_exec(struct draw_context *draw,
00173                     const struct pipe_shader_state *state)
00174 {
00175    struct exec_vertex_shader *vs = CALLOC_STRUCT( exec_vertex_shader );
00176 
00177    if (vs == NULL) 
00178       return NULL;
00179 
00180    /* we make a private copy of the tokens */
00181    vs->base.state.tokens = tgsi_dup_tokens(state->tokens);
00182    if (!vs->base.state.tokens) {
00183       FREE(vs);
00184       return NULL;
00185    }
00186 
00187    tgsi_scan_shader(state->tokens, &vs->base.info);
00188 
00189    vs->base.draw = draw;
00190    vs->base.prepare = vs_exec_prepare;
00191    vs->base.run_linear = vs_exec_run_linear;
00192    vs->base.delete = vs_exec_delete;
00193    vs->base.create_varient = draw_vs_varient_generic;
00194    vs->machine = &draw->vs.machine;
00195 
00196    return &vs->base;
00197 }

Generated on Tue Sep 29 06:25:14 2009 for Gallium3D by  doxygen 1.5.4