00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
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
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
00066 tgsi_exec_machine_bind_shader(evs->machine,
00067 shader->state.tokens,
00068 PIPE_MAX_SAMPLERS,
00069 NULL );
00070
00071 }
00072
00073
00074
00075
00076
00077
00078
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
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
00130 tgsi_exec_machine_run( machine );
00131
00132
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
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 }