1 /* 2 * Copyright 2009 VMware, Inc. 3 * All Rights Reserved. 4 * 5 * Permission is hereby granted, free of charge, to any person obtaining a 6 * copy of this software and associated documentation files (the "Software"), 7 * to deal in the Software without restriction, including without limitation 8 * on the rights to use, copy, modify, merge, publish, distribute, sub 9 * license, and/or sell copies of the Software, and to permit persons to whom 10 * the Software is furnished to do so, subject to the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the next 13 * paragraph) shall be included in all copies or substantial portions of the 14 * Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 19 * VMWARE AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 * USE OR OTHER DEALINGS IN THE SOFTWARE. 23 */ 24 25 #include "u_indices.h" 26 #include "u_indices_priv.h" 27 28 static void translate_memcpy_ushort( const void *in, 29 unsigned nr, 30 void *out ) 31 { 32 memcpy(out, in, nr*sizeof(short)); 33 } 34 35 static void translate_memcpy_uint( const void *in, 36 unsigned nr, 37 void *out ) 38 { 39 memcpy(out, in, nr*sizeof(int)); 40 } 41 42 43 int u_index_translator( unsigned hw_mask, 44 unsigned prim, 45 unsigned in_index_size, 46 unsigned nr, 47 unsigned in_pv, 48 unsigned out_pv, 49 unsigned *out_prim, 50 unsigned *out_index_size, 51 unsigned *out_nr, 52 u_translate_func *out_translate ) 53 { 54 unsigned in_idx; 55 unsigned out_idx; 56 int ret = U_TRANSLATE_NORMAL; 57 58 u_index_init(); 59 60 in_idx = in_size_idx(in_index_size); 61 *out_index_size = (in_index_size == 4) ? 4 : 2; 62 out_idx = out_size_idx(*out_index_size); 63 64 if ((hw_mask & (1<<prim)) && 65 in_index_size == *out_index_size && 66 in_pv == out_pv) 67 { 68 if (in_index_size == 4) 69 *out_translate = translate_memcpy_uint; 70 else 71 *out_translate = translate_memcpy_ushort; 72 73 *out_prim = prim; 74 *out_nr = nr; 75 76 return U_TRANSLATE_MEMCPY; 77 } 78 else { 79 switch (prim) { 80 case PIPE_PRIM_POINTS: 81 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 82 *out_prim = PIPE_PRIM_POINTS; 83 *out_nr = nr; 84 break; 85 86 case PIPE_PRIM_LINES: 87 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 88 *out_prim = PIPE_PRIM_LINES; 89 *out_nr = nr; 90 break; 91 92 case PIPE_PRIM_LINE_STRIP: 93 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 94 *out_prim = PIPE_PRIM_LINES; 95 *out_nr = (nr - 1) * 2; 96 break; 97 98 case PIPE_PRIM_LINE_LOOP: 99 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 100 *out_prim = PIPE_PRIM_LINES; 101 *out_nr = nr * 2; 102 break; 103 104 case PIPE_PRIM_TRIANGLES: 105 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 106 *out_prim = PIPE_PRIM_TRIANGLES; 107 *out_nr = nr; 108 break; 109 110 case PIPE_PRIM_TRIANGLE_STRIP: 111 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 112 *out_prim = PIPE_PRIM_TRIANGLES; 113 *out_nr = (nr - 2) * 3; 114 break; 115 116 case PIPE_PRIM_TRIANGLE_FAN: 117 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 118 *out_prim = PIPE_PRIM_TRIANGLES; 119 *out_nr = (nr - 2) * 3; 120 break; 121 122 case PIPE_PRIM_QUADS: 123 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 124 *out_prim = PIPE_PRIM_TRIANGLES; 125 *out_nr = (nr / 4) * 6; 126 break; 127 128 case PIPE_PRIM_QUAD_STRIP: 129 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 130 *out_prim = PIPE_PRIM_TRIANGLES; 131 *out_nr = (nr - 2) * 3; 132 break; 133 134 case PIPE_PRIM_POLYGON: 135 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 136 *out_prim = PIPE_PRIM_TRIANGLES; 137 *out_nr = (nr - 2) * 3; 138 break; 139 140 default: 141 assert(0); 142 *out_translate = translate[in_idx][out_idx][in_pv][out_pv][prim]; 143 *out_prim = PIPE_PRIM_POINTS; 144 *out_nr = nr; 145 return U_TRANSLATE_ERROR; 146 } 147 } 148 149 return ret; 150 } 151 152 153 154 155 156 int u_index_generator( unsigned hw_mask, 157 unsigned prim, 158 unsigned start, 159 unsigned nr, 160 unsigned in_pv, 161 unsigned out_pv, 162 unsigned *out_prim, 163 unsigned *out_index_size, 164 unsigned *out_nr, 165 u_generate_func *out_generate ) 166 167 { 168 unsigned out_idx; 169 170 u_index_init(); 171 172 *out_index_size = ((start + nr) > 0xfffe) ? 4 : 2; 173 out_idx = out_size_idx(*out_index_size); 174 175 if ((hw_mask & (1<<prim)) && 176 (in_pv == out_pv)) { 177 178 *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS]; 179 *out_prim = prim; 180 *out_nr = nr; 181 return U_GENERATE_LINEAR; 182 } 183 else { 184 switch (prim) { 185 case PIPE_PRIM_POINTS: 186 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 187 *out_prim = PIPE_PRIM_POINTS; 188 *out_nr = nr; 189 return U_GENERATE_REUSABLE; 190 191 case PIPE_PRIM_LINES: 192 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 193 *out_prim = PIPE_PRIM_LINES; 194 *out_nr = nr; 195 return U_GENERATE_REUSABLE; 196 197 case PIPE_PRIM_LINE_STRIP: 198 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 199 *out_prim = PIPE_PRIM_LINES; 200 *out_nr = (nr - 1) * 2; 201 return U_GENERATE_REUSABLE; 202 203 case PIPE_PRIM_LINE_LOOP: 204 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 205 *out_prim = PIPE_PRIM_LINES; 206 *out_nr = nr * 2; 207 return U_GENERATE_ONE_OFF; 208 209 case PIPE_PRIM_TRIANGLES: 210 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 211 *out_prim = PIPE_PRIM_TRIANGLES; 212 *out_nr = nr; 213 return U_GENERATE_REUSABLE; 214 215 case PIPE_PRIM_TRIANGLE_STRIP: 216 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 217 *out_prim = PIPE_PRIM_TRIANGLES; 218 *out_nr = (nr - 2) * 3; 219 return U_GENERATE_REUSABLE; 220 221 case PIPE_PRIM_TRIANGLE_FAN: 222 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 223 *out_prim = PIPE_PRIM_TRIANGLES; 224 *out_nr = (nr - 2) * 3; 225 return U_GENERATE_REUSABLE; 226 227 case PIPE_PRIM_QUADS: 228 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 229 *out_prim = PIPE_PRIM_TRIANGLES; 230 *out_nr = (nr / 4) * 6; 231 return U_GENERATE_REUSABLE; 232 233 case PIPE_PRIM_QUAD_STRIP: 234 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 235 *out_prim = PIPE_PRIM_TRIANGLES; 236 *out_nr = (nr - 2) * 3; 237 return U_GENERATE_REUSABLE; 238 239 case PIPE_PRIM_POLYGON: 240 *out_generate = generate[out_idx][in_pv][out_pv][prim]; 241 *out_prim = PIPE_PRIM_TRIANGLES; 242 *out_nr = (nr - 2) * 3; 243 return U_GENERATE_REUSABLE; 244 245 default: 246 assert(0); 247 *out_generate = generate[out_idx][in_pv][out_pv][PIPE_PRIM_POINTS]; 248 *out_prim = PIPE_PRIM_POINTS; 249 *out_nr = nr; 250 return U_TRANSLATE_ERROR; 251 } 252 } 253 } 254