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
00037 #include "pipe/p_shader_tokens.h"
00038
00039 #include "draw_private.h"
00040 #include "draw_context.h"
00041 #include "draw_vs.h"
00042
00043 #include "translate/translate.h"
00044 #include "translate/translate_cache.h"
00045
00046
00047
00048
00049 void draw_vs_set_constants( struct draw_context *draw,
00050 const float (*constants)[4],
00051 unsigned size )
00052 {
00053 if (((unsigned)constants) & 0xf) {
00054 if (size > draw->vs.const_storage_size) {
00055 if (draw->vs.aligned_constant_storage)
00056 align_free((void *)draw->vs.aligned_constant_storage);
00057 draw->vs.aligned_constant_storage = align_malloc( size, 16 );
00058 }
00059 memcpy( (void*)draw->vs.aligned_constant_storage,
00060 constants,
00061 size );
00062 constants = draw->vs.aligned_constant_storage;
00063 }
00064
00065 draw->vs.aligned_constants = constants;
00066 draw_vs_aos_machine_constants( draw->vs.aos_machine, constants );
00067 }
00068
00069
00070 void draw_vs_set_viewport( struct draw_context *draw,
00071 const struct pipe_viewport_state *viewport )
00072 {
00073 draw_vs_aos_machine_viewport( draw->vs.aos_machine, viewport );
00074 }
00075
00076
00077
00078 struct draw_vertex_shader *
00079 draw_create_vertex_shader(struct draw_context *draw,
00080 const struct pipe_shader_state *shader)
00081 {
00082 struct draw_vertex_shader *vs;
00083
00084 vs = draw_create_vs_llvm( draw, shader );
00085 if (!vs) {
00086 vs = draw_create_vs_sse( draw, shader );
00087 if (!vs) {
00088 vs = draw_create_vs_exec( draw, shader );
00089 }
00090 }
00091
00092 if (vs)
00093 {
00094 uint i;
00095 for (i = 0; i < vs->info.num_outputs; i++) {
00096 if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION &&
00097 vs->info.output_semantic_index[i] == 0)
00098 vs->position_output = i;
00099 }
00100 }
00101
00102 assert(vs);
00103 return vs;
00104 }
00105
00106
00107 void
00108 draw_bind_vertex_shader(struct draw_context *draw,
00109 struct draw_vertex_shader *dvs)
00110 {
00111 draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE );
00112
00113 if (dvs)
00114 {
00115 draw->vs.vertex_shader = dvs;
00116 draw->vs.num_vs_outputs = dvs->info.num_outputs;
00117 draw->vs.position_output = dvs->position_output;
00118 dvs->prepare( dvs, draw );
00119 }
00120 else {
00121 draw->vs.vertex_shader = NULL;
00122 draw->vs.num_vs_outputs = 0;
00123 }
00124 }
00125
00126
00127 void
00128 draw_delete_vertex_shader(struct draw_context *draw,
00129 struct draw_vertex_shader *dvs)
00130 {
00131 unsigned i;
00132
00133 for (i = 0; i < dvs->nr_varients; i++)
00134 dvs->varient[i]->destroy( dvs->varient[i] );
00135
00136 dvs->nr_varients = 0;
00137
00138 dvs->delete( dvs );
00139 }
00140
00141
00142
00143 boolean
00144 draw_vs_init( struct draw_context *draw )
00145 {
00146 tgsi_exec_machine_init(&draw->vs.machine);
00147
00148
00149
00150 draw->vs.machine.Inputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16);
00151 if (!draw->vs.machine.Inputs)
00152 return FALSE;
00153
00154 draw->vs.machine.Outputs = align_malloc(PIPE_MAX_ATTRIBS * sizeof(struct tgsi_exec_vector), 16);
00155 if (!draw->vs.machine.Outputs)
00156 return FALSE;
00157
00158 draw->vs.emit_cache = translate_cache_create();
00159 if (!draw->vs.emit_cache)
00160 return FALSE;
00161
00162 draw->vs.fetch_cache = translate_cache_create();
00163 if (!draw->vs.fetch_cache)
00164 return FALSE;
00165
00166 draw->vs.aos_machine = draw_vs_aos_machine();
00167 #ifdef PIPE_ARCH_X86
00168 if (!draw->vs.aos_machine)
00169 return FALSE;
00170 #endif
00171
00172 return TRUE;
00173 }
00174
00175 void
00176 draw_vs_destroy( struct draw_context *draw )
00177 {
00178 if (draw->vs.machine.Inputs)
00179 align_free(draw->vs.machine.Inputs);
00180
00181 if (draw->vs.machine.Outputs)
00182 align_free(draw->vs.machine.Outputs);
00183
00184 if (draw->vs.fetch_cache)
00185 translate_cache_destroy(draw->vs.fetch_cache);
00186
00187 if (draw->vs.emit_cache)
00188 translate_cache_destroy(draw->vs.emit_cache);
00189
00190 if (draw->vs.aos_machine)
00191 draw_vs_aos_machine_destroy(draw->vs.aos_machine);
00192
00193 if (draw->vs.aligned_constant_storage)
00194 align_free((void*)draw->vs.aligned_constant_storage);
00195
00196 tgsi_exec_machine_free_data(&draw->vs.machine);
00197
00198 }
00199
00200
00201 struct draw_vs_varient *
00202 draw_vs_lookup_varient( struct draw_vertex_shader *vs,
00203 const struct draw_vs_varient_key *key )
00204 {
00205 struct draw_vs_varient *varient;
00206 unsigned i;
00207
00208
00209
00210 for (i = 0; i < vs->nr_varients; i++)
00211 if (draw_vs_varient_key_compare(key, &vs->varient[i]->key) == 0)
00212 return vs->varient[i];
00213
00214
00215
00216 varient = vs->create_varient( vs, key );
00217 if (varient == NULL)
00218 return NULL;
00219
00220
00221
00222 if (vs->nr_varients < Elements(vs->varient)) {
00223 vs->varient[vs->nr_varients++] = varient;
00224 }
00225 else {
00226 vs->last_varient++;
00227 vs->last_varient %= Elements(vs->varient);
00228 vs->varient[vs->last_varient]->destroy(vs->varient[vs->last_varient]);
00229 vs->varient[vs->last_varient] = varient;
00230 }
00231
00232
00233
00234 return varient;
00235 }
00236
00237
00238 struct translate *
00239 draw_vs_get_fetch( struct draw_context *draw,
00240 struct translate_key *key )
00241 {
00242 if (!draw->vs.fetch ||
00243 translate_key_compare(&draw->vs.fetch->key, key) != 0)
00244 {
00245 translate_key_sanitize(key);
00246 draw->vs.fetch = translate_cache_find(draw->vs.fetch_cache, key);
00247 }
00248
00249 return draw->vs.fetch;
00250 }
00251
00252 struct translate *
00253 draw_vs_get_emit( struct draw_context *draw,
00254 struct translate_key *key )
00255 {
00256 if (!draw->vs.emit ||
00257 translate_key_compare(&draw->vs.emit->key, key) != 0)
00258 {
00259 translate_key_sanitize(key);
00260 draw->vs.emit = translate_cache_find(draw->vs.emit_cache, key);
00261 }
00262
00263 return draw->vs.emit;
00264 }