test version of startmenu root with big icons
[reactos.git] / reactos / lib / mesa32 / src / tnl / t_vertex_codegen.c
1 /*
2 * Copyright 2003 Tungsten Graphics, 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 * TUNGSTEN GRAPHICS 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 * Authors:
25 * Keith Whitwell <keithw@tungstengraphics.com>
26 */
27
28 #include "glheader.h"
29 #include "context.h"
30 #include "colormac.h"
31
32 #include "t_context.h"
33 #include "t_vertex.h"
34
35 #include "simple_list.h"
36
37 /* Another codegen scheme, hopefully portable to a few different
38 * architectures without too much work.
39 */
40
41
42
43
44 static GLboolean emit_4f_viewport_4( struct tnl_clipspace_codegen *p )
45 {
46 return
47 p->emit_mad(p, out(0), vp(0), in(0), vp(12)) &&
48 p->emit_mad(p, out(1), vp(5), in(1), vp(13)) &&
49 p->emit_mad(p, out(2), vp(10), in(2), vp(14)) &&
50 p->emit_mov(p, out(3), in(3));
51 }
52
53 static GLboolean emit_4f_viewport_3( struct tnl_clipspace_codegen *p )
54 {
55 return
56 p->emit_mad(p, out(0), vp(0), in(0), vp(12)) &&
57 p->emit_mad(p, out(1), vp(5), in(1), vp(13)) &&
58 p->emit_mad(p, out(2), vp(10), in(2), vp(14)) &&
59 p->emit_const(p, out(3), 1.0);
60 }
61
62 static GLboolean emit_4f_viewport_2( struct tnl_clipspace_codegen *p )
63 {
64 return
65 p->emit_mad(p, out(0), vp(0), in(0), vp(12)) &&
66 p->emit_mad(p, out(1), vp(5), in(1), vp(13)) &&
67 p->emit_mov(p, out(2), vp(14)) &&
68 p->emit_const(p, out(3), 1.0);
69 }
70
71 static GLboolean emit_4f_viewport_1( struct tnl_clipspace_codegen *p )
72 {
73 return
74 p->emit_mad(p, out(0), vp(0), in(0), vp(12)) &&
75 p->emit_mov(p, out(1), vp(13)) &&
76 p->emit_mov(p, out(2), vp(14)) &&
77 p->emit_const(p, out(3), 1.0);
78 }
79
80 static GLboolean emit_3f_viewport_3( struct tnl_clipspace_codegen *p )
81 {
82 return
83 p->emit_mad(p, out(0), vp(0), in(0), vp(12)) &&
84 p->emit_mad(p, out(1), vp(5), in(1), vp(13)) &&
85 p->emit_mad(p, out(2), vp(10), in(2), vp(14));
86 }
87
88 static GLboolean emit_3f_viewport_2( struct tnl_clipspace_codegen *p )
89 {
90 return
91 p->emit_mad(p, out(0), vp(0), in(0), vp(12)) &&
92 p->emit_mad(p, out(1), vp(5), in(1), vp(13)) &&
93 p->emit_mov(p, out(2), vp(14));
94 }
95
96 static GLboolean emit_3f_viewport_1( struct tnl_clipspace_codegen *p )
97 {
98 return
99 p->emit_mad(p, out(0), vp(0), in(0), vp(12)) &&
100 p->emit_mov(p, out(1), vp(13)) &&
101 p->emit_mov(p, out(2), vp(14));
102 }
103
104 static GLboolean emit_2f_viewport_2( struct tnl_clipspace_codegen *p )
105 {
106 return
107 p->emit_mad(p, out(0), vp(0), in(0), vp(12)) &&
108 p->emit_mad(p, out(1), vp(5), in(1), vp(13));
109 }
110
111 static GLboolean emit_2f_viewport_1( struct tnl_clipspace_codegen *p )
112 {
113 return
114 p->emit_mad(p, out(0), vp(0), in(0), vp(12));
115 }
116
117
118 static GLboolean emit_4f_4( struct tnl_clipspace_codegen *p )
119 {
120 return
121 p->emit_mov(p, out(0), in(0)) &&
122 p->emit_mov(p, out(1), in(1)) &&
123 p->emit_mov(p, out(2), in(2)) &&
124 p->emit_mov(p, out(3), in(3));
125 }
126
127 static GLboolean emit_4f_3( struct tnl_clipspace_codegen *p )
128 {
129 return
130 p->emit_mov(p, out(0), in(0)) &&
131 p->emit_mov(p, out(1), in(1)) &&
132 p->emit_mov(p, out(2), in(2)) &&
133 p->emit_const(p, out(3), 1.0);
134 }
135
136 static GLboolean emit_4f_2( struct tnl_clipspace_codegen *p )
137 {
138 return
139 p->emit_mov(p, out(0), in(0)) &&
140 p->emit_mov(p, out(1), in(1)) &&
141 p->emit_const(p, out(2), 0.0) &&
142 p->emit_const(p, out(3), 1.0);
143 }
144
145 static GLboolean emit_4f_1( struct tnl_clipspace_codegen *p )
146 {
147 return
148 p->emit_mov(p, out(0), in(0)) &&
149 p->emit_const(p, out(1), 0.0) &&
150 p->emit_const(p, out(2), 0.0) &&
151 p->emit_const(p, out(3), 1.0);
152 }
153
154 static GLboolean emit_3f_xyw_4( struct tnl_clipspace_codegen *p )
155 {
156 return
157 p->emit_mov(p, out(0), in(0)) &&
158 p->emit_mov(p, out(1), in(1)) &&
159 p->emit_mov(p, out(2), in(3));
160 }
161
162 static GLboolean emit_3f_xyw_err( struct tnl_clipspace_codegen *p )
163 {
164 (void) p;
165 assert(0);
166 return GL_FALSE;
167 }
168
169 static GLboolean emit_3f_3( struct tnl_clipspace_codegen *p )
170 {
171 return
172 p->emit_mov(p, out(0), in(0)) &&
173 p->emit_mov(p, out(1), in(1)) &&
174 p->emit_mov(p, out(2), in(2));
175 }
176
177 static GLboolean emit_3f_2( struct tnl_clipspace_codegen *p )
178 {
179 return
180 p->emit_mov(p, out(0), in(0)) &&
181 p->emit_mov(p, out(1), in(1)) &&
182 p->emit_const(p, out(2), 0.0);
183 }
184
185 static GLboolean emit_3f_1( struct tnl_clipspace_codegen *p )
186 {
187 return
188 p->emit_mov(p, out(0), in(0)) &&
189 p->emit_const(p, out(1), 0.0) &&
190 p->emit_const(p, out(2), 0.0);
191 }
192
193
194 static GLboolean emit_2f_2( struct tnl_clipspace_codegen *p )
195 {
196 return
197 p->emit_mov(p, out(0), in(0)) &&
198 p->emit_mov(p, out(1), in(1));
199 }
200
201 static GLboolean emit_2f_1( struct tnl_clipspace_codegen *p )
202 {
203 return
204 p->emit_mov(p, out(0), in(0)) &&
205 p->emit_const(p, out(1), 0.0);
206 }
207
208 static GLboolean emit_1f_1( struct tnl_clipspace_codegen *p )
209 {
210 return
211 p->emit_mov(p, out(0), in(0));
212 }
213
214 static GLboolean emit_4chan_4f_rgba_4( struct tnl_clipspace_codegen *p )
215 {
216 return
217 p->emit_float_to_chan(p, out(0), in(0)) &&
218 p->emit_float_to_chan(p, out(1), in(1)) &&
219 p->emit_float_to_chan(p, out(2), in(2)) &&
220 p->emit_float_to_chan(p, out(3), in(3));
221 }
222
223 static GLboolean emit_4chan_4f_rgba_3( struct tnl_clipspace_codegen *p )
224 {
225 return
226 p->emit_float_to_chan(p, out(0), in(0)) &&
227 p->emit_float_to_chan(p, out(1), in(1)) &&
228 p->emit_float_to_chan(p, out(2), in(2)) &&
229 p->emit_const_chan(p, out(3), CHAN_MAX);
230 }
231
232 static GLboolean emit_4chan_4f_rgba_2( struct tnl_clipspace_codegen *p )
233 {
234 return
235 p->emit_float_to_chan(p, out(0), in(0)) &&
236 p->emit_float_to_chan(p, out(1), in(1)) &&
237 p->emit_const_chan(p, out(2), 0) &&
238 p->emit_const_chan(p, out(3), CHAN_MAX);
239 }
240
241 static GLboolean emit_4chan_4f_rgba_1( struct tnl_clipspace_codegen *p )
242 {
243 return
244 p->emit_float_to_chan(p, out(0), in(0)) &&
245 p->emit_const_chan(p, out(1), 0) &&
246 p->emit_const_chan(p, out(2), 0) &&
247 p->emit_const_chan(p, out(3), CHAN_MAX);
248 }
249
250 static GLboolean emit_4ub_4f_rgba_4( struct tnl_clipspace_codegen *p )
251 {
252 return
253 p->emit_float_to_ubyte(p, out(0), in(0)) &&
254 p->emit_float_to_ubyte(p, out(1), in(1)) &&
255 p->emit_float_to_ubyte(p, out(2), in(2)) &&
256 p->emit_float_to_ubyte(p, out(3), in(3));
257 }
258
259 static GLboolean emit_4ub_4f_rgba_3( struct tnl_clipspace_codegen *p )
260 {
261 return
262 p->emit_float_to_ubyte(p, out(0), in(0)) &&
263 p->emit_float_to_ubyte(p, out(1), in(1)) &&
264 p->emit_float_to_ubyte(p, out(2), in(2)) &&
265 p->emit_const_ubyte(p, out(3), 0xff);
266 }
267
268 static GLboolean emit_4ub_4f_rgba_2( struct tnl_clipspace_codegen *p )
269 {
270 return
271 p->emit_float_to_ubyte(p, out(0), in(0)) &&
272 p->emit_float_to_ubyte(p, out(1), in(1)) &&
273 p->emit_const_ubyte(p, out(2), 0) &&
274 p->emit_const_ubyte(p, out(3), 0xff);
275 }
276
277 static GLboolean emit_4ub_4f_rgba_1( struct tnl_clipspace_codegen *p )
278 {
279 return
280 p->emit_float_to_ubyte(p, out(0), in(0)) &&
281 p->emit_const_ubyte(p, out(1), 0) &&
282 p->emit_const_ubyte(p, out(2), 0) &&
283 p->emit_const_ubyte(p, out(3), 0xff);
284 }
285
286 static GLboolean emit_4ub_4f_bgra_4( struct tnl_clipspace_codegen *p )
287 {
288 return
289 p->emit_float_to_ubyte(p, out(2), in(0)) &&
290 p->emit_float_to_ubyte(p, out(1), in(1)) &&
291 p->emit_float_to_ubyte(p, out(0), in(2)) &&
292 p->emit_float_to_ubyte(p, out(3), in(3));
293 }
294
295 static GLboolean emit_4ub_4f_bgra_3( struct tnl_clipspace_codegen *p )
296 {
297 return
298 p->emit_float_to_ubyte(p, out(2), in(0)) &&
299 p->emit_float_to_ubyte(p, out(1), in(1)) &&
300 p->emit_float_to_ubyte(p, out(0), in(2)) &&
301 p->emit_const_ubyte(p, out(3), 0xff);
302 }
303
304 static GLboolean emit_4ub_4f_bgra_2( struct tnl_clipspace_codegen *p )
305 {
306 return
307 p->emit_float_to_ubyte(p, out(2), in(0)) &&
308 p->emit_float_to_ubyte(p, out(1), in(1)) &&
309 p->emit_const_ubyte(p, out(0), 0) &&
310 p->emit_const_ubyte(p, out(3), 0xff);
311 }
312
313 static GLboolean emit_4ub_4f_bgra_1( struct tnl_clipspace_codegen *p )
314 {
315 return
316 p->emit_float_to_ubyte(p, out(2), in(0)) &&
317 p->emit_const_ubyte(p, out(1), 0) &&
318 p->emit_const_ubyte(p, out(0), 0) &&
319 p->emit_const_ubyte(p, out(3), 0xff);
320 }
321
322 static GLboolean emit_3ub_3f_rgb_3( struct tnl_clipspace_codegen *p )
323 {
324 return
325 p->emit_float_to_ubyte(p, out(0), in(0)) &&
326 p->emit_float_to_ubyte(p, out(1), in(1)) &&
327 p->emit_float_to_ubyte(p, out(2), in(2));
328 }
329
330 static GLboolean emit_3ub_3f_rgb_2( struct tnl_clipspace_codegen *p )
331 {
332 return
333 p->emit_float_to_ubyte(p, out(0), in(0)) &&
334 p->emit_float_to_ubyte(p, out(1), in(1)) &&
335 p->emit_const_ubyte(p, out(2), 0);
336 }
337
338 static GLboolean emit_3ub_3f_rgb_1( struct tnl_clipspace_codegen *p )
339 {
340 return
341 p->emit_float_to_ubyte(p, out(0), in(0)) &&
342 p->emit_const_ubyte(p, out(1), 0) &&
343 p->emit_const_ubyte(p, out(2), 0);
344 }
345
346 static GLboolean emit_3ub_3f_bgr_3( struct tnl_clipspace_codegen *p )
347 {
348 return
349 p->emit_float_to_ubyte(p, out(2), in(0)) &&
350 p->emit_float_to_ubyte(p, out(1), in(1)) &&
351 p->emit_float_to_ubyte(p, out(0), in(2));
352 }
353
354 static GLboolean emit_3ub_3f_bgr_2( struct tnl_clipspace_codegen *p )
355 {
356 return
357 p->emit_float_to_ubyte(p, out(2), in(0)) &&
358 p->emit_float_to_ubyte(p, out(1), in(1)) &&
359 p->emit_const_ubyte(p, out(0), 0);
360 }
361
362 static GLboolean emit_3ub_3f_bgr_1( struct tnl_clipspace_codegen *p )
363 {
364 return
365 p->emit_float_to_ubyte(p, out(2), in(0)) &&
366 p->emit_const_ubyte(p, out(1), 0) &&
367 p->emit_const_ubyte(p, out(0), 0);
368 }
369
370
371 static GLboolean emit_1ub_1f_1( struct tnl_clipspace_codegen *p )
372 {
373 return
374 p->emit_float_to_ubyte(p, out(0), in(0));
375 }
376
377
378
379
380 static struct {
381 const char *name;
382 GLenum out_type;
383 GLboolean need_vp;
384 GLboolean (*emit[4])( struct tnl_clipspace_codegen * );
385 } emit_info[EMIT_MAX] = {
386
387 { "1f", GL_FLOAT, GL_FALSE,
388 { emit_1f_1, emit_1f_1, emit_1f_1, emit_1f_1 } },
389
390 { "2f", GL_FLOAT, GL_FALSE,
391 { emit_2f_1, emit_2f_2, emit_2f_2, emit_2f_2 } },
392
393 { "3f", GL_FLOAT, GL_FALSE,
394 { emit_3f_1, emit_3f_2, emit_3f_3, emit_3f_3 } },
395
396 { "4f", GL_FLOAT, GL_FALSE,
397 { emit_4f_1, emit_4f_2, emit_4f_3, emit_4f_4 } },
398
399 { "2f_viewport", GL_FLOAT, GL_TRUE,
400 { emit_2f_viewport_1, emit_2f_viewport_2, emit_2f_viewport_2,
401 emit_2f_viewport_2 } },
402
403 { "3f_viewport", GL_FLOAT, GL_TRUE,
404 { emit_3f_viewport_1, emit_3f_viewport_2, emit_3f_viewport_3,
405 emit_3f_viewport_3 } },
406
407 { "4f_viewport", GL_FLOAT, GL_TRUE,
408 { emit_4f_viewport_1, emit_4f_viewport_2, emit_4f_viewport_3,
409 emit_4f_viewport_4 } },
410
411 { "3f_xyw", GL_FLOAT, GL_FALSE,
412 { emit_3f_xyw_err, emit_3f_xyw_err, emit_3f_xyw_err,
413 emit_3f_xyw_4 } },
414
415 { "1ub_1f", GL_UNSIGNED_BYTE, GL_FALSE,
416 { emit_1ub_1f_1, emit_1ub_1f_1, emit_1ub_1f_1, emit_1ub_1f_1 } },
417
418 { "3ub_3f_rgb", GL_UNSIGNED_BYTE, GL_FALSE,
419 { emit_3ub_3f_rgb_1, emit_3ub_3f_rgb_2, emit_3ub_3f_rgb_3,
420 emit_3ub_3f_rgb_3 } },
421
422 { "3ub_3f_bgr", GL_UNSIGNED_BYTE, GL_FALSE,
423 { emit_3ub_3f_bgr_1, emit_3ub_3f_bgr_2, emit_3ub_3f_bgr_3,
424 emit_3ub_3f_bgr_3 } },
425
426 { "4ub_4f_rgba", GL_UNSIGNED_BYTE, GL_FALSE,
427 { emit_4ub_4f_rgba_1, emit_4ub_4f_rgba_2, emit_4ub_4f_rgba_3,
428 emit_4ub_4f_rgba_4 } },
429
430 { "4ub_4f_bgra", GL_UNSIGNED_BYTE, GL_FALSE,
431 { emit_4ub_4f_bgra_1, emit_4ub_4f_bgra_2, emit_4ub_4f_bgra_3,
432 emit_4ub_4f_bgra_4 } },
433
434 { "4chan_4f_rgba", CHAN_TYPE, GL_FALSE,
435 { emit_4chan_4f_rgba_1, emit_4chan_4f_rgba_2, emit_4chan_4f_rgba_3,
436 emit_4chan_4f_rgba_4 } },
437
438 { "pad", 0, 0,
439 { 0, 0, 0, 0 } }
440
441 };
442
443
444 /***********************************************************************
445 * list(attrib, size) --> function
446 *
447 * Because of the dependence of size, this all has to take place after
448 * the pipeline has been run.
449 */
450
451 tnl_emit_func _tnl_codegen_emit( GLcontext *ctx )
452 {
453 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
454 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx);
455 struct tnl_clipspace_attr *a = vtx->attr;
456 struct tnl_clipspace_codegen *p = &vtx->codegen;
457 const GLuint count = vtx->attr_count;
458 GLuint j;
459
460 /* Need a faster lookup, or is this linear scan of an MRU list good
461 * enough? MRU chosen based on the guess that consecutive VB's are
462 * likely to be of the same format. A hash of attributes and sizes
463 * might be a better technique.
464 *
465 * With the vtx code now in place, it should be possible to track
466 * changes to the sizes of input arrays (and state, of course) and
467 * only invalidate this function when those sizes have changed.
468 */
469 #if 0
470 foreach (l, p->codegen_list) {
471 if (l->attr_count != count)
472 continue;
473
474 /* Assumptions:
475 * a[j].vp will not change for a given attrib
476 * a[j].vertex_offset will not change nothing else has changed.
477 */
478 for (j = 0; j < count; j++)
479 if (a[j].attrib != l->a[j].attrib ||
480 a[j].sz != l->a[j].sz)
481 break;
482
483 if (j == count) {
484 move_to_head(l, p->codegen_list);
485 return l->func;
486 }
487 }
488 #endif
489
490 p->emit_header( p, vtx );
491
492 for (j = 0; j < count; j++) {
493 GLuint sz = VB->AttribPtr[a[j].attrib]->size - 1;
494 p->emit_attr_header( p, a, j,
495 emit_info[a[j].format].out_type,
496 emit_info[a[j].format].need_vp );
497
498 if (!emit_info[a[j].format].emit[sz]( p )) {
499 fprintf(stderr, "codegen failed\n");
500 return 0;
501 }
502
503 p->emit_attr_footer( p );
504 }
505
506 p->emit_footer( p );
507
508 return p->emit_store_func( p );
509 }
510