draw_vs.c revision f7748d72b46465d807cf4209892d73af62485738
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 if (draw->dump_vs) { 87 tgsi_dump(shader->tokens, 0); 88 } 89 90 vs = draw_create_vs_llvm( draw, shader ); 91 if (!vs) { 92 vs = draw_create_vs_sse( draw, shader ); 93 if (!vs) { 94 vs = draw_create_vs_ppc( draw, shader ); 95 if (!vs) { 96 vs = draw_create_vs_exec( draw, shader ); 97 } 98 } 99 } 100 101 if (vs) 102 { 103 uint i; 104 for (i = 0; i < vs->info.num_outputs; i++) { 105 if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_POSITION && 106 vs->info.output_semantic_index[i] == 0) 107 vs->position_output = i; 108 else if (vs->info.output_semantic_name[i] == TGSI_SEMANTIC_EDGEFLAG && 109 vs->info.output_semantic_index[i] == 0) 110 vs->edgeflag_output = i; 111 } 112 } 113 114 assert(vs); 115 return vs; 116} 117 118 119void 120draw_bind_vertex_shader(struct draw_context *draw, 121 struct draw_vertex_shader *dvs) 122{ 123 draw_do_flush( draw, DRAW_FLUSH_STATE_CHANGE ); 124 125 if (dvs) 126 { 127 draw->vs.vertex_shader = dvs; 128 draw->vs.num_vs_outputs = dvs->info.num_outputs; 129 draw->vs.position_output = dvs->position_output; 130 draw->vs.edgeflag_output = dvs->edgeflag_output; 131 dvs->prepare( dvs, draw ); 132 } 133 else { 134 draw->vs.vertex_shader = NULL; 135 draw->vs.num_vs_outputs = 0; 136 } 137} 138 139 140void 141draw_delete_vertex_shader(struct draw_context *draw, 142 struct draw_vertex_shader *dvs) 143{ 144 unsigned i; 145 146 for (i = 0; i < dvs->nr_varients; i++) 147 dvs->varient[i]->destroy( dvs->varient[i] ); 148 149 dvs->nr_varients = 0; 150 151 dvs->delete( dvs ); 152} 153 154 155 156boolean 157draw_vs_init( struct draw_context *draw ) 158{ 159 draw->dump_vs = debug_get_bool_option("GALLIUM_DUMP_VS", FALSE); 160 161 draw->vs.machine = tgsi_exec_machine_create(); 162 if (!draw->vs.machine) 163 return FALSE; 164 165 draw->vs.emit_cache = translate_cache_create(); 166 if (!draw->vs.emit_cache) 167 return FALSE; 168 169 draw->vs.fetch_cache = translate_cache_create(); 170 if (!draw->vs.fetch_cache) 171 return FALSE; 172 173 draw->vs.aos_machine = draw_vs_aos_machine(); 174#ifdef PIPE_ARCH_X86 175 if (!draw->vs.aos_machine) 176 return FALSE; 177#endif 178 179 return TRUE; 180} 181 182void 183draw_vs_destroy( struct draw_context *draw ) 184{ 185 if (draw->vs.fetch_cache) 186 translate_cache_destroy(draw->vs.fetch_cache); 187 188 if (draw->vs.emit_cache) 189 translate_cache_destroy(draw->vs.emit_cache); 190 191 if (draw->vs.aos_machine) 192 draw_vs_aos_machine_destroy(draw->vs.aos_machine); 193 194 if (draw->vs.aligned_constant_storage) 195 align_free((void*)draw->vs.aligned_constant_storage); 196 197 tgsi_exec_machine_destroy(draw->vs.machine); 198} 199 200 201struct draw_vs_varient * 202draw_vs_lookup_varient( struct draw_vertex_shader *vs, 203 const struct draw_vs_varient_key *key ) 204{ 205 struct draw_vs_varient *varient; 206 unsigned i; 207 208 /* Lookup existing varient: 209 */ 210 for (i = 0; i < vs->nr_varients; i++) 211 if (draw_vs_varient_key_compare(key, &vs->varient[i]->key) == 0) 212 return vs->varient[i]; 213 214 /* Else have to create a new one: 215 */ 216 varient = vs->create_varient( vs, key ); 217 if (varient == NULL) 218 return NULL; 219 220 /* Add it to our list, could be smarter: 221 */ 222 if (vs->nr_varients < Elements(vs->varient)) { 223 vs->varient[vs->nr_varients++] = varient; 224 } 225 else { 226 vs->last_varient++; 227 vs->last_varient %= Elements(vs->varient); 228 vs->varient[vs->last_varient]->destroy(vs->varient[vs->last_varient]); 229 vs->varient[vs->last_varient] = varient; 230 } 231 232 /* Done 233 */ 234 return varient; 235} 236 237 238struct translate * 239draw_vs_get_fetch( struct draw_context *draw, 240 struct translate_key *key ) 241{ 242 if (!draw->vs.fetch || 243 translate_key_compare(&draw->vs.fetch->key, key) != 0) 244 { 245 translate_key_sanitize(key); 246 draw->vs.fetch = translate_cache_find(draw->vs.fetch_cache, key); 247 } 248 249 return draw->vs.fetch; 250} 251 252struct translate * 253draw_vs_get_emit( struct draw_context *draw, 254 struct translate_key *key ) 255{ 256 if (!draw->vs.emit || 257 translate_key_compare(&draw->vs.emit->key, key) != 0) 258 { 259 translate_key_sanitize(key); 260 draw->vs.emit = translate_cache_find(draw->vs.emit_cache, key); 261 } 262 263 return draw->vs.emit; 264} 265