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 }