draw_vs.c revision 4a49301e
1/************************************************************************** 2 * 3 * Copyright 2007 Tungsten Graphics, Inc., Cedar Park, Texas. 4 * All Rights Reserved. 5 * 6 * Permission is hereby granted, free of charge, to any person obtaining a 7 * copy of this software and associated documentation files (the 8 * "Software"), to deal in the Software without restriction, including 9 * without limitation the rights to use, copy, modify, merge, publish, 10 * distribute, sub license, and/or sell copies of the Software, and to 11 * permit persons to whom the Software is furnished to do so, subject to 12 * the following conditions: 13 * 14 * The above copyright notice and this permission notice (including the 15 * next paragraph) shall be included in all copies or substantial portions 16 * of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 * 26 **************************************************************************/ 27 28 /* 29 * Authors: 30 * Keith Whitwell <keith@tungstengraphics.com> 31 * Brian Paul 32 */ 33 34#include "util/u_math.h" 35#include "util/u_memory.h" 36 37#include "pipe/p_shader_tokens.h" 38 39#include "draw_private.h" 40#include "draw_context.h" 41#include "draw_vs.h" 42 43#include "translate/translate.h" 44#include "translate/translate_cache.h" 45 46#include "tgsi/tgsi_exec.h" 47 48 49 50 51void draw_vs_set_constants( struct draw_context *draw, 52 const float (*constants)[4], 53 unsigned size ) 54{ 55 if (((uintptr_t)constants) & 0xf) { 56 if (size > draw->vs.const_storage_size) { 57 if (draw->vs.aligned_constant_storage) 58 align_free((void *)draw->vs.aligned_constant_storage); 59 draw->vs.aligned_constant_storage = align_malloc( size, 16 ); 60 } 61 memcpy( (void*)draw->vs.aligned_constant_storage, 62 constants, 63 size ); 64 constants = draw->vs.aligned_constant_storage; 65 } 66 67 draw->vs.aligned_constants = constants; 68 draw_vs_aos_machine_constants( draw->vs.aos_machine, constants ); 69} 70 71 72void draw_vs_set_viewport( struct draw_context *draw, 73 const struct pipe_viewport_state *viewport ) 74{ 75 draw_vs_aos_machine_viewport( draw->vs.aos_machine, viewport ); 76} 77 78 79 80struct draw_vertex_shader * 81draw_create_vertex_shader(struct draw_context *draw, 82 const struct pipe_shader_state *shader) 83{ 84 struct draw_vertex_shader *vs; 85 86 vs = draw_create_vs_llvm( draw, shader ); 87 if (!vs) { 88 vs = draw_create_vs_sse( draw, shader ); 89 if (!vs) { 90 vs = draw_create_vs_ppc( draw, shader ); 91 if (!vs) { 92 vs = draw_create_vs_exec( draw, shader ); 93 } 94 } 95 } 96 97 if (vs) 98 { 99 uint i; 100 for (i = 0; i < vs->info.num_outputs; i++) { 101 if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION && 102 vs->info.output_semantic_index[i] == 0) 103 vs->position_output = i; 104 } 105 } 106 107 assert(vs); 108 return vs; 109} 110 111 112void 113draw_bind_vertex_shader(struct draw_context *draw, 114 struct draw_vertex_shader *dvs) 115{ 116 draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); 117 118 if (dvs) 119 { 120 draw->vs.vertex_shader = dvs; 121 draw->vs.num_vs_outputs = dvs->info.num_outputs; 122 draw->vs.position_output = dvs->position_output; 123 dvs->prepare( dvs, draw ); 124 } 125 else { 126 draw->vs.vertex_shader = NULL; 127 draw->vs.num_vs_outputs = 0; 128 } 129} 130 131 132void 133draw_delete_vertex_shader(struct draw_context *draw, 134 struct draw_vertex_shader *dvs) 135{ 136 unsigned i; 137 138 for (i = 0; i < dvs->nr_varients; i++) 139 dvs->varient[i]->destroy( dvs->varient[i] ); 140 141 dvs->nr_varients = 0; 142 143 dvs->delete( dvs ); 144} 145 146 147 148boolean 149draw_vs_init( struct draw_context *draw ) 150{ 151 draw->vs.machine = tgsi_exec_machine_create(); 152 if (!draw->vs.machine) 153 return FALSE; 154 155 draw->vs.emit_cache = translate_cache_create(); 156 if (!draw->vs.emit_cache) 157 return FALSE; 158 159 draw->vs.fetch_cache = translate_cache_create(); 160 if (!draw->vs.fetch_cache) 161 return FALSE; 162 163 draw->vs.aos_machine = draw_vs_aos_machine(); 164#ifdef PIPE_ARCH_X86 165 if (!draw->vs.aos_machine) 166 return FALSE; 167#endif 168 169 return TRUE; 170} 171 172void 173draw_vs_destroy( struct draw_context *draw ) 174{ 175 if (draw->vs.fetch_cache) 176 translate_cache_destroy(draw->vs.fetch_cache); 177 178 if (draw->vs.emit_cache) 179 translate_cache_destroy(draw->vs.emit_cache); 180 181 if (draw->vs.aos_machine) 182 draw_vs_aos_machine_destroy(draw->vs.aos_machine); 183 184 if (draw->vs.aligned_constant_storage) 185 align_free((void*)draw->vs.aligned_constant_storage); 186 187 tgsi_exec_machine_destroy(draw->vs.machine); 188} 189 190 191struct draw_vs_varient * 192draw_vs_lookup_varient( struct draw_vertex_shader *vs, 193 const struct draw_vs_varient_key *key ) 194{ 195 struct draw_vs_varient *varient; 196 unsigned i; 197 198 /* Lookup existing varient: 199 */ 200 for (i = 0; i < vs->nr_varients; i++) 201 if (draw_vs_varient_key_compare(key, &vs->varient[i]->key) == 0) 202 return vs->varient[i]; 203 204 /* Else have to create a new one: 205 */ 206 varient = vs->create_varient( vs, key ); 207 if (varient == NULL) 208 return NULL; 209 210 /* Add it to our list, could be smarter: 211 */ 212 if (vs->nr_varients < Elements(vs->varient)) { 213 vs->varient[vs->nr_varients++] = varient; 214 } 215 else { 216 vs->last_varient++; 217 vs->last_varient %= Elements(vs->varient); 218 vs->varient[vs->last_varient]->destroy(vs->varient[vs->last_varient]); 219 vs->varient[vs->last_varient] = varient; 220 } 221 222 /* Done 223 */ 224 return varient; 225} 226 227 228struct translate * 229draw_vs_get_fetch( struct draw_context *draw, 230 struct translate_key *key ) 231{ 232 if (!draw->vs.fetch || 233 translate_key_compare(&draw->vs.fetch->key, key) != 0) 234 { 235 translate_key_sanitize(key); 236 draw->vs.fetch = translate_cache_find(draw->vs.fetch_cache, key); 237 } 238 239 return draw->vs.fetch; 240} 241 242struct translate * 243draw_vs_get_emit( struct draw_context *draw, 244 struct translate_key *key ) 245{ 246 if (!draw->vs.emit || 247 translate_key_compare(&draw->vs.emit->key, key) != 0) 248 { 249 translate_key_sanitize(key); 250 draw->vs.emit = translate_cache_find(draw->vs.emit_cache, key); 251 } 252 253 return draw->vs.emit; 254} 255