draw_vs.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 
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    /* FIXME: give this machine thing a proper constructor:
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    /* Lookup existing varient: 
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    /* Else have to create a new one: 
00215     */
00216    varient = vs->create_varient( vs, key );
00217    if (varient == NULL)
00218       return NULL;
00219 
00220    /* Add it to our list, could be smarter: 
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    /* Done 
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 }

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