1 2/* 3 * Copyright 2003 Tungsten Graphics, inc. 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 "Software"), 8 * to deal in the Software without restriction, including without limitation 9 * on the rights to use, copy, modify, merge, publish, distribute, sub 10 * license, and/or sell copies of the Software, and to permit persons to whom 11 * the Software is furnished to do so, subject to the following conditions: 12 * 13 * The above copyright notice and this permission notice (including the next 14 * paragraph) shall be included in all copies or substantial portions of the 15 * Software. 16 * 17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL 20 * TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, 21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 23 * USE OR OTHER DEALINGS IN THE SOFTWARE. 24 * 25 * Authors: 26 * Keith Whitwell <keithw@tungstengraphics.com> 27 */ 28 29#include "main/glheader.h" 30#include "main/context.h" 31#include "main/colormac.h" 32#include "main/simple_list.h" 33#include "swrast/s_chan.h" 34#include "t_context.h" 35#include "t_vertex.h" 36 37 38#if 0 39#define DEBUG_INSERT printf("%s\n", __FUNCTION__) 40#else 41#define DEBUG_INSERT 42#endif 43 44 45/* 46 * These functions take the NDC coordinates pointed to by 'in', apply the 47 * NDC->Viewport mapping and store the results at 'v'. 48 */ 49 50static inline void insert_4f_viewport_4( const struct tnl_clipspace_attr *a, GLubyte *v, 51 const GLfloat *in ) 52{ 53 GLfloat *out = (GLfloat *)v; 54 const GLfloat * const vp = a->vp; 55 DEBUG_INSERT; 56 out[0] = vp[0] * in[0] + vp[12]; 57 out[1] = vp[5] * in[1] + vp[13]; 58 out[2] = vp[10] * in[2] + vp[14]; 59 out[3] = in[3]; 60} 61 62static inline void insert_4f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v, 63 const GLfloat *in ) 64{ 65 GLfloat *out = (GLfloat *)v; 66 const GLfloat * const vp = a->vp; 67 DEBUG_INSERT; 68 out[0] = vp[0] * in[0] + vp[12]; 69 out[1] = vp[5] * in[1] + vp[13]; 70 out[2] = vp[10] * in[2] + vp[14]; 71 out[3] = 1; 72} 73 74static inline void insert_4f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v, 75 const GLfloat *in ) 76{ 77 GLfloat *out = (GLfloat *)v; 78 const GLfloat * const vp = a->vp; 79 DEBUG_INSERT; 80 out[0] = vp[0] * in[0] + vp[12]; 81 out[1] = vp[5] * in[1] + vp[13]; 82 out[2] = vp[14]; 83 out[3] = 1; 84} 85 86static inline void insert_4f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v, 87 const GLfloat *in ) 88{ 89 GLfloat *out = (GLfloat *)v; 90 const GLfloat * const vp = a->vp; 91 DEBUG_INSERT; 92 out[0] = vp[0] * in[0] + vp[12]; 93 out[1] = vp[13]; 94 out[2] = vp[14]; 95 out[3] = 1; 96} 97 98static inline void insert_3f_viewport_3( const struct tnl_clipspace_attr *a, GLubyte *v, 99 const GLfloat *in ) 100{ 101 GLfloat *out = (GLfloat *)v; 102 const GLfloat * const vp = a->vp; 103 DEBUG_INSERT; 104 out[0] = vp[0] * in[0] + vp[12]; 105 out[1] = vp[5] * in[1] + vp[13]; 106 out[2] = vp[10] * in[2] + vp[14]; 107} 108 109static inline void insert_3f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v, 110 const GLfloat *in ) 111{ 112 GLfloat *out = (GLfloat *)v; 113 const GLfloat * const vp = a->vp; 114 DEBUG_INSERT; 115 out[0] = vp[0] * in[0] + vp[12]; 116 out[1] = vp[5] * in[1] + vp[13]; 117 out[2] = vp[14]; 118} 119 120static inline void insert_3f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v, 121 const GLfloat *in ) 122{ 123 GLfloat *out = (GLfloat *)v; 124 const GLfloat * const vp = a->vp; 125 DEBUG_INSERT; 126 out[0] = vp[0] * in[0] + vp[12]; 127 out[1] = vp[13]; 128 out[2] = vp[14]; 129} 130 131static inline void insert_2f_viewport_2( const struct tnl_clipspace_attr *a, GLubyte *v, 132 const GLfloat *in ) 133{ 134 GLfloat *out = (GLfloat *)v; 135 const GLfloat * const vp = a->vp; 136 DEBUG_INSERT; 137 out[0] = vp[0] * in[0] + vp[12]; 138 out[1] = vp[5] * in[1] + vp[13]; 139} 140 141static inline void insert_2f_viewport_1( const struct tnl_clipspace_attr *a, GLubyte *v, 142 const GLfloat *in ) 143{ 144 GLfloat *out = (GLfloat *)v; 145 const GLfloat * const vp = a->vp; 146 DEBUG_INSERT; 147 out[0] = vp[0] * in[0] + vp[12]; 148 out[1] = vp[13]; 149} 150 151 152/* 153 * These functions do the same as above, except for the viewport mapping. 154 */ 155 156static inline void insert_4f_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 157{ 158 GLfloat *out = (GLfloat *)(v); 159 (void) a; 160 DEBUG_INSERT; 161 out[0] = in[0]; 162 out[1] = in[1]; 163 out[2] = in[2]; 164 out[3] = in[3]; 165} 166 167static inline void insert_4f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 168{ 169 GLfloat *out = (GLfloat *)(v); 170 (void) a; 171 DEBUG_INSERT; 172 out[0] = in[0]; 173 out[1] = in[1]; 174 out[2] = in[2]; 175 out[3] = 1; 176} 177 178static inline void insert_4f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 179{ 180 GLfloat *out = (GLfloat *)(v); 181 (void) a; 182 DEBUG_INSERT; 183 out[0] = in[0]; 184 out[1] = in[1]; 185 out[2] = 0; 186 out[3] = 1; 187} 188 189static inline void insert_4f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 190{ 191 GLfloat *out = (GLfloat *)(v); 192 (void) a; 193 DEBUG_INSERT; 194 out[0] = in[0]; 195 out[1] = 0; 196 out[2] = 0; 197 out[3] = 1; 198} 199 200static inline void insert_3f_xyw_4( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 201{ 202 GLfloat *out = (GLfloat *)(v); 203 (void) a; 204 DEBUG_INSERT; 205 out[0] = in[0]; 206 out[1] = in[1]; 207 out[2] = in[3]; 208} 209 210static inline void insert_3f_xyw_err( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 211{ 212 (void) a; (void) v; (void) in; 213 DEBUG_INSERT; 214 exit(1); 215} 216 217static inline void insert_3f_3( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 218{ 219 GLfloat *out = (GLfloat *)(v); 220 (void) a; 221 DEBUG_INSERT; 222 out[0] = in[0]; 223 out[1] = in[1]; 224 out[2] = in[2]; 225} 226 227static inline void insert_3f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 228{ 229 GLfloat *out = (GLfloat *)(v); 230 (void) a; 231 DEBUG_INSERT; 232 out[0] = in[0]; 233 out[1] = in[1]; 234 out[2] = 0; 235} 236 237static inline void insert_3f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 238{ 239 GLfloat *out = (GLfloat *)(v); 240 (void) a; 241 DEBUG_INSERT; 242 out[0] = in[0]; 243 out[1] = 0; 244 out[2] = 0; 245} 246 247 248static inline void insert_2f_2( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 249{ 250 GLfloat *out = (GLfloat *)(v); 251 (void) a; 252 DEBUG_INSERT; 253 out[0] = in[0]; 254 out[1] = in[1]; 255} 256 257static inline void insert_2f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 258{ 259 GLfloat *out = (GLfloat *)(v); 260 (void) a; 261 DEBUG_INSERT; 262 out[0] = in[0]; 263 out[1] = 0; 264} 265 266static inline void insert_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 267{ 268 GLfloat *out = (GLfloat *)(v); 269 (void) a; 270 DEBUG_INSERT; 271 out[0] = in[0]; 272} 273 274static inline void insert_null( const struct tnl_clipspace_attr *a, GLubyte *v, const GLfloat *in ) 275{ 276 DEBUG_INSERT; 277 (void) a; (void) v; (void) in; 278} 279 280static inline void insert_4chan_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, 281 const GLfloat *in ) 282{ 283 GLchan *c = (GLchan *)v; 284 DEBUG_INSERT; 285 (void) a; 286 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 287 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 288 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 289 UNCLAMPED_FLOAT_TO_CHAN(c[3], in[3]); 290} 291 292static inline void insert_4chan_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v, 293 const GLfloat *in ) 294{ 295 GLchan *c = (GLchan *)v; 296 DEBUG_INSERT; 297 (void) a; 298 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 299 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 300 UNCLAMPED_FLOAT_TO_CHAN(c[2], in[2]); 301 c[3] = CHAN_MAX; 302} 303 304static inline void insert_4chan_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, 305 const GLfloat *in ) 306{ 307 GLchan *c = (GLchan *)v; 308 DEBUG_INSERT; 309 (void) a; 310 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 311 UNCLAMPED_FLOAT_TO_CHAN(c[1], in[1]); 312 c[2] = 0; 313 c[3] = CHAN_MAX; 314} 315 316static inline void insert_4chan_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v, 317 const GLfloat *in ) 318{ 319 GLchan *c = (GLchan *)v; 320 DEBUG_INSERT; 321 (void) a; 322 UNCLAMPED_FLOAT_TO_CHAN(c[0], in[0]); 323 c[1] = 0; 324 c[2] = 0; 325 c[3] = CHAN_MAX; 326} 327 328static inline void insert_4ub_4f_rgba_4( const struct tnl_clipspace_attr *a, GLubyte *v, 329 const GLfloat *in ) 330{ 331 DEBUG_INSERT; 332 (void) a; 333 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); 334 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 335 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); 336 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); 337} 338 339static inline void insert_4ub_4f_rgba_3( const struct tnl_clipspace_attr *a, GLubyte *v, 340 const GLfloat *in ) 341{ 342 DEBUG_INSERT; 343 (void) a; 344 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); 345 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 346 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); 347 v[3] = 0xff; 348} 349 350static inline void insert_4ub_4f_rgba_2( const struct tnl_clipspace_attr *a, GLubyte *v, 351 const GLfloat *in ) 352{ 353 DEBUG_INSERT; 354 (void) a; 355 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); 356 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 357 v[2] = 0; 358 v[3] = 0xff; 359} 360 361static inline void insert_4ub_4f_rgba_1( const struct tnl_clipspace_attr *a, GLubyte *v, 362 const GLfloat *in ) 363{ 364 DEBUG_INSERT; 365 (void) a; 366 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); 367 v[1] = 0; 368 v[2] = 0; 369 v[3] = 0xff; 370} 371 372static inline void insert_4ub_4f_bgra_4( const struct tnl_clipspace_attr *a, GLubyte *v, 373 const GLfloat *in ) 374{ 375 DEBUG_INSERT; 376 (void) a; 377 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); 378 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 379 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); 380 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[3]); 381} 382 383static inline void insert_4ub_4f_bgra_3( const struct tnl_clipspace_attr *a, GLubyte *v, 384 const GLfloat *in ) 385{ 386 DEBUG_INSERT; 387 (void) a; 388 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); 389 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 390 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); 391 v[3] = 0xff; 392} 393 394static inline void insert_4ub_4f_bgra_2( const struct tnl_clipspace_attr *a, GLubyte *v, 395 const GLfloat *in ) 396{ 397 DEBUG_INSERT; 398 (void) a; 399 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); 400 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 401 v[0] = 0; 402 v[3] = 0xff; 403} 404 405static inline void insert_4ub_4f_bgra_1( const struct tnl_clipspace_attr *a, GLubyte *v, 406 const GLfloat *in ) 407{ 408 DEBUG_INSERT; 409 (void) a; 410 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); 411 v[1] = 0; 412 v[0] = 0; 413 v[3] = 0xff; 414} 415 416static inline void insert_4ub_4f_argb_4( const struct tnl_clipspace_attr *a, GLubyte *v, 417 const GLfloat *in ) 418{ 419 DEBUG_INSERT; 420 (void) a; 421 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); 422 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); 423 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); 424 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); 425} 426 427static inline void insert_4ub_4f_argb_3( const struct tnl_clipspace_attr *a, GLubyte *v, 428 const GLfloat *in ) 429{ 430 DEBUG_INSERT; 431 (void) a; 432 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); 433 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); 434 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[2]); 435 v[0] = 0xff; 436} 437 438static inline void insert_4ub_4f_argb_2( const struct tnl_clipspace_attr *a, GLubyte *v, 439 const GLfloat *in ) 440{ 441 DEBUG_INSERT; 442 (void) a; 443 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); 444 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); 445 v[3] = 0x00; 446 v[0] = 0xff; 447} 448 449static inline void insert_4ub_4f_argb_1( const struct tnl_clipspace_attr *a, GLubyte *v, 450 const GLfloat *in ) 451{ 452 DEBUG_INSERT; 453 (void) a; 454 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[0]); 455 v[2] = 0x00; 456 v[3] = 0x00; 457 v[0] = 0xff; 458} 459 460static inline void insert_4ub_4f_abgr_4( const struct tnl_clipspace_attr *a, GLubyte *v, 461 const GLfloat *in ) 462{ 463 DEBUG_INSERT; 464 (void) a; 465 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); 466 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); 467 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); 468 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[3]); 469} 470 471static inline void insert_4ub_4f_abgr_3( const struct tnl_clipspace_attr *a, GLubyte *v, 472 const GLfloat *in ) 473{ 474 DEBUG_INSERT; 475 (void) a; 476 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); 477 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); 478 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[2]); 479 v[0] = 0xff; 480} 481 482static inline void insert_4ub_4f_abgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, 483 const GLfloat *in ) 484{ 485 DEBUG_INSERT; 486 (void) a; 487 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); 488 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[1]); 489 v[1] = 0x00; 490 v[0] = 0xff; 491} 492 493static inline void insert_4ub_4f_abgr_1( const struct tnl_clipspace_attr *a, GLubyte *v, 494 const GLfloat *in ) 495{ 496 DEBUG_INSERT; 497 (void) a; 498 UNCLAMPED_FLOAT_TO_UBYTE(v[3], in[0]); 499 v[2] = 0x00; 500 v[1] = 0x00; 501 v[0] = 0xff; 502} 503 504static inline void insert_3ub_3f_rgb_3( const struct tnl_clipspace_attr *a, GLubyte *v, 505 const GLfloat *in ) 506{ 507 DEBUG_INSERT; 508 (void) a; 509 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); 510 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 511 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[2]); 512} 513 514static inline void insert_3ub_3f_rgb_2( const struct tnl_clipspace_attr *a, GLubyte *v, 515 const GLfloat *in ) 516{ 517 DEBUG_INSERT; 518 (void) a; 519 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); 520 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 521 v[2] = 0; 522} 523 524static inline void insert_3ub_3f_rgb_1( const struct tnl_clipspace_attr *a, GLubyte *v, 525 const GLfloat *in ) 526{ 527 DEBUG_INSERT; 528 (void) a; 529 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); 530 v[1] = 0; 531 v[2] = 0; 532} 533 534static inline void insert_3ub_3f_bgr_3( const struct tnl_clipspace_attr *a, GLubyte *v, 535 const GLfloat *in ) 536{ 537 DEBUG_INSERT; 538 (void) a; 539 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); 540 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 541 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[2]); 542} 543 544static inline void insert_3ub_3f_bgr_2( const struct tnl_clipspace_attr *a, GLubyte *v, 545 const GLfloat *in ) 546{ 547 DEBUG_INSERT; 548 (void) a; 549 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); 550 UNCLAMPED_FLOAT_TO_UBYTE(v[1], in[1]); 551 v[0] = 0; 552} 553 554static inline void insert_3ub_3f_bgr_1( const struct tnl_clipspace_attr *a, GLubyte *v, 555 const GLfloat *in ) 556{ 557 DEBUG_INSERT; 558 (void) a; 559 UNCLAMPED_FLOAT_TO_UBYTE(v[2], in[0]); 560 v[1] = 0; 561 v[0] = 0; 562} 563 564 565static inline void insert_1ub_1f_1( const struct tnl_clipspace_attr *a, GLubyte *v, 566 const GLfloat *in ) 567{ 568 DEBUG_INSERT; 569 (void) a; 570 UNCLAMPED_FLOAT_TO_UBYTE(v[0], in[0]); 571} 572 573 574/*********************************************************************** 575 * Functions to perform the reverse operations to the above, for 576 * swrast translation and clip-interpolation. 577 * 578 * Currently always extracts a full 4 floats. 579 */ 580 581static void extract_4f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 582 const GLubyte *v ) 583{ 584 const GLfloat *in = (const GLfloat *)v; 585 const GLfloat * const vp = a->vp; 586 587 /* Although included for completeness, the position coordinate is 588 * usually handled differently during clipping. 589 */ 590 DEBUG_INSERT; 591 out[0] = (in[0] - vp[12]) / vp[0]; 592 out[1] = (in[1] - vp[13]) / vp[5]; 593 out[2] = (in[2] - vp[14]) / vp[10]; 594 out[3] = in[3]; 595} 596 597static void extract_3f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 598 const GLubyte *v ) 599{ 600 const GLfloat *in = (const GLfloat *)v; 601 const GLfloat * const vp = a->vp; 602 DEBUG_INSERT; 603 out[0] = (in[0] - vp[12]) / vp[0]; 604 out[1] = (in[1] - vp[13]) / vp[5]; 605 out[2] = (in[2] - vp[14]) / vp[10]; 606 out[3] = 1; 607} 608 609 610static void extract_2f_viewport( const struct tnl_clipspace_attr *a, GLfloat *out, 611 const GLubyte *v ) 612{ 613 const GLfloat *in = (const GLfloat *)v; 614 const GLfloat * const vp = a->vp; 615 DEBUG_INSERT; 616 out[0] = (in[0] - vp[12]) / vp[0]; 617 out[1] = (in[1] - vp[13]) / vp[5]; 618 out[2] = 0; 619 out[3] = 1; 620} 621 622 623static void extract_4f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) 624{ 625 const GLfloat *in = (const GLfloat *)v; 626 (void) a; 627 628 out[0] = in[0]; 629 out[1] = in[1]; 630 out[2] = in[2]; 631 out[3] = in[3]; 632} 633 634static void extract_3f_xyw( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) 635{ 636 const GLfloat *in = (const GLfloat *)v; 637 (void) a; 638 639 out[0] = in[0]; 640 out[1] = in[1]; 641 out[2] = 0; 642 out[3] = in[2]; 643} 644 645 646static void extract_3f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) 647{ 648 const GLfloat *in = (const GLfloat *)v; 649 (void) a; 650 651 out[0] = in[0]; 652 out[1] = in[1]; 653 out[2] = in[2]; 654 out[3] = 1; 655} 656 657 658static void extract_2f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) 659{ 660 const GLfloat *in = (const GLfloat *)v; 661 (void) a; 662 663 out[0] = in[0]; 664 out[1] = in[1]; 665 out[2] = 0; 666 out[3] = 1; 667} 668 669static void extract_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) 670{ 671 const GLfloat *in = (const GLfloat *)v; 672 (void) a; 673 674 out[0] = in[0]; 675 out[1] = 0; 676 out[2] = 0; 677 out[3] = 1; 678} 679 680static void extract_4chan_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 681 const GLubyte *v ) 682{ 683 GLchan *c = (GLchan *)v; 684 (void) a; 685 686 out[0] = CHAN_TO_FLOAT(c[0]); 687 out[1] = CHAN_TO_FLOAT(c[1]); 688 out[2] = CHAN_TO_FLOAT(c[2]); 689 out[3] = CHAN_TO_FLOAT(c[3]); 690} 691 692static void extract_4ub_4f_rgba( const struct tnl_clipspace_attr *a, GLfloat *out, 693 const GLubyte *v ) 694{ 695 (void) a; 696 out[0] = UBYTE_TO_FLOAT(v[0]); 697 out[1] = UBYTE_TO_FLOAT(v[1]); 698 out[2] = UBYTE_TO_FLOAT(v[2]); 699 out[3] = UBYTE_TO_FLOAT(v[3]); 700} 701 702static void extract_4ub_4f_bgra( const struct tnl_clipspace_attr *a, GLfloat *out, 703 const GLubyte *v ) 704{ 705 (void) a; 706 out[2] = UBYTE_TO_FLOAT(v[0]); 707 out[1] = UBYTE_TO_FLOAT(v[1]); 708 out[0] = UBYTE_TO_FLOAT(v[2]); 709 out[3] = UBYTE_TO_FLOAT(v[3]); 710} 711 712static void extract_4ub_4f_argb( const struct tnl_clipspace_attr *a, GLfloat *out, 713 const GLubyte *v ) 714{ 715 (void) a; 716 out[3] = UBYTE_TO_FLOAT(v[0]); 717 out[0] = UBYTE_TO_FLOAT(v[1]); 718 out[1] = UBYTE_TO_FLOAT(v[2]); 719 out[2] = UBYTE_TO_FLOAT(v[3]); 720} 721 722static void extract_4ub_4f_abgr( const struct tnl_clipspace_attr *a, GLfloat *out, 723 const GLubyte *v ) 724{ 725 (void) a; 726 out[3] = UBYTE_TO_FLOAT(v[0]); 727 out[2] = UBYTE_TO_FLOAT(v[1]); 728 out[1] = UBYTE_TO_FLOAT(v[2]); 729 out[0] = UBYTE_TO_FLOAT(v[3]); 730} 731 732static void extract_3ub_3f_rgb( const struct tnl_clipspace_attr *a, GLfloat *out, 733 const GLubyte *v ) 734{ 735 (void) a; 736 out[0] = UBYTE_TO_FLOAT(v[0]); 737 out[1] = UBYTE_TO_FLOAT(v[1]); 738 out[2] = UBYTE_TO_FLOAT(v[2]); 739 out[3] = 1; 740} 741 742static void extract_3ub_3f_bgr( const struct tnl_clipspace_attr *a, GLfloat *out, 743 const GLubyte *v ) 744{ 745 (void) a; 746 out[2] = UBYTE_TO_FLOAT(v[0]); 747 out[1] = UBYTE_TO_FLOAT(v[1]); 748 out[0] = UBYTE_TO_FLOAT(v[2]); 749 out[3] = 1; 750} 751 752static void extract_1ub_1f( const struct tnl_clipspace_attr *a, GLfloat *out, const GLubyte *v ) 753{ 754 (void) a; 755 out[0] = UBYTE_TO_FLOAT(v[0]); 756 out[1] = 0; 757 out[2] = 0; 758 out[3] = 1; 759} 760 761 762const struct tnl_format_info _tnl_format_info[EMIT_MAX] = 763{ 764 { "1f", 765 extract_1f, 766 { insert_1f_1, insert_1f_1, insert_1f_1, insert_1f_1 }, 767 sizeof(GLfloat) }, 768 769 { "2f", 770 extract_2f, 771 { insert_2f_1, insert_2f_2, insert_2f_2, insert_2f_2 }, 772 2 * sizeof(GLfloat) }, 773 774 { "3f", 775 extract_3f, 776 { insert_3f_1, insert_3f_2, insert_3f_3, insert_3f_3 }, 777 3 * sizeof(GLfloat) }, 778 779 { "4f", 780 extract_4f, 781 { insert_4f_1, insert_4f_2, insert_4f_3, insert_4f_4 }, 782 4 * sizeof(GLfloat) }, 783 784 { "2f_viewport", 785 extract_2f_viewport, 786 { insert_2f_viewport_1, insert_2f_viewport_2, insert_2f_viewport_2, 787 insert_2f_viewport_2 }, 788 2 * sizeof(GLfloat) }, 789 790 { "3f_viewport", 791 extract_3f_viewport, 792 { insert_3f_viewport_1, insert_3f_viewport_2, insert_3f_viewport_3, 793 insert_3f_viewport_3 }, 794 3 * sizeof(GLfloat) }, 795 796 { "4f_viewport", 797 extract_4f_viewport, 798 { insert_4f_viewport_1, insert_4f_viewport_2, insert_4f_viewport_3, 799 insert_4f_viewport_4 }, 800 4 * sizeof(GLfloat) }, 801 802 { "3f_xyw", 803 extract_3f_xyw, 804 { insert_3f_xyw_err, insert_3f_xyw_err, insert_3f_xyw_err, 805 insert_3f_xyw_4 }, 806 3 * sizeof(GLfloat) }, 807 808 { "1ub_1f", 809 extract_1ub_1f, 810 { insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1, insert_1ub_1f_1 }, 811 sizeof(GLubyte) }, 812 813 { "3ub_3f_rgb", 814 extract_3ub_3f_rgb, 815 { insert_3ub_3f_rgb_1, insert_3ub_3f_rgb_2, insert_3ub_3f_rgb_3, 816 insert_3ub_3f_rgb_3 }, 817 3 * sizeof(GLubyte) }, 818 819 { "3ub_3f_bgr", 820 extract_3ub_3f_bgr, 821 { insert_3ub_3f_bgr_1, insert_3ub_3f_bgr_2, insert_3ub_3f_bgr_3, 822 insert_3ub_3f_bgr_3 }, 823 3 * sizeof(GLubyte) }, 824 825 { "4ub_4f_rgba", 826 extract_4ub_4f_rgba, 827 { insert_4ub_4f_rgba_1, insert_4ub_4f_rgba_2, insert_4ub_4f_rgba_3, 828 insert_4ub_4f_rgba_4 }, 829 4 * sizeof(GLubyte) }, 830 831 { "4ub_4f_bgra", 832 extract_4ub_4f_bgra, 833 { insert_4ub_4f_bgra_1, insert_4ub_4f_bgra_2, insert_4ub_4f_bgra_3, 834 insert_4ub_4f_bgra_4 }, 835 4 * sizeof(GLubyte) }, 836 837 { "4ub_4f_argb", 838 extract_4ub_4f_argb, 839 { insert_4ub_4f_argb_1, insert_4ub_4f_argb_2, insert_4ub_4f_argb_3, 840 insert_4ub_4f_argb_4 }, 841 4 * sizeof(GLubyte) }, 842 843 { "4ub_4f_abgr", 844 extract_4ub_4f_abgr, 845 { insert_4ub_4f_abgr_1, insert_4ub_4f_abgr_2, insert_4ub_4f_abgr_3, 846 insert_4ub_4f_abgr_4 }, 847 4 * sizeof(GLubyte) }, 848 849 { "4chan_4f_rgba", 850 extract_4chan_4f_rgba, 851 { insert_4chan_4f_rgba_1, insert_4chan_4f_rgba_2, insert_4chan_4f_rgba_3, 852 insert_4chan_4f_rgba_4 }, 853 4 * sizeof(GLchan) }, 854 855 { "pad", 856 NULL, 857 { NULL, NULL, NULL, NULL }, 858 0 } 859 860}; 861 862 863 864 865/*********************************************************************** 866 * Hardwired fastpaths for emitting whole vertices or groups of 867 * vertices 868 */ 869#define EMIT5(NR, F0, F1, F2, F3, F4, NAME) \ 870static void NAME( struct gl_context *ctx, \ 871 GLuint count, \ 872 GLubyte *v ) \ 873{ \ 874 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); \ 875 struct tnl_clipspace_attr *a = vtx->attr; \ 876 GLuint i; \ 877 \ 878 for (i = 0 ; i < count ; i++, v += vtx->vertex_size) { \ 879 if (NR > 0) { \ 880 F0( &a[0], v + a[0].vertoffset, (GLfloat *)a[0].inputptr ); \ 881 a[0].inputptr += a[0].inputstride; \ 882 } \ 883 \ 884 if (NR > 1) { \ 885 F1( &a[1], v + a[1].vertoffset, (GLfloat *)a[1].inputptr ); \ 886 a[1].inputptr += a[1].inputstride; \ 887 } \ 888 \ 889 if (NR > 2) { \ 890 F2( &a[2], v + a[2].vertoffset, (GLfloat *)a[2].inputptr ); \ 891 a[2].inputptr += a[2].inputstride; \ 892 } \ 893 \ 894 if (NR > 3) { \ 895 F3( &a[3], v + a[3].vertoffset, (GLfloat *)a[3].inputptr ); \ 896 a[3].inputptr += a[3].inputstride; \ 897 } \ 898 \ 899 if (NR > 4) { \ 900 F4( &a[4], v + a[4].vertoffset, (GLfloat *)a[4].inputptr ); \ 901 a[4].inputptr += a[4].inputstride; \ 902 } \ 903 } \ 904} 905 906 907#define EMIT2(F0, F1, NAME) EMIT5(2, F0, F1, insert_null, \ 908 insert_null, insert_null, NAME) 909 910#define EMIT3(F0, F1, F2, NAME) EMIT5(3, F0, F1, F2, insert_null, \ 911 insert_null, NAME) 912 913#define EMIT4(F0, F1, F2, F3, NAME) EMIT5(4, F0, F1, F2, F3, \ 914 insert_null, NAME) 915 916 917EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4) 918EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4) 919EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4) 920 921EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2) 922EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, emit_viewport4_bgra4_st2) 923EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2) 924 925EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2) 926EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2, emit_viewport4_bgra4_st2_st2) 927EMIT4(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_xyzw4_rgba4_st2_st2) 928 929 930/* Use the codegen paths to select one of a number of hardwired 931 * fastpaths. 932 */ 933void _tnl_generate_hardwired_emit( struct gl_context *ctx ) 934{ 935 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); 936 tnl_emit_func func = NULL; 937 938 /* Does it fit a hardwired fastpath? Help! this is growing out of 939 * control! 940 */ 941 switch (vtx->attr_count) { 942 case 2: 943 if (vtx->attr[0].emit == insert_3f_viewport_3) { 944 if (vtx->attr[1].emit == insert_4ub_4f_bgra_4) 945 func = emit_viewport3_bgra4; 946 else if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) 947 func = emit_viewport3_rgba4; 948 } 949 else if (vtx->attr[0].emit == insert_3f_3 && 950 vtx->attr[1].emit == insert_4ub_4f_rgba_4) { 951 func = emit_xyz3_rgba4; 952 } 953 break; 954 case 3: 955 if (vtx->attr[2].emit == insert_2f_2) { 956 if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) { 957 if (vtx->attr[0].emit == insert_4f_viewport_4) 958 func = emit_viewport4_rgba4_st2; 959 else if (vtx->attr[0].emit == insert_4f_4) 960 func = emit_xyzw4_rgba4_st2; 961 } 962 else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 && 963 vtx->attr[0].emit == insert_4f_viewport_4) 964 func = emit_viewport4_bgra4_st2; 965 } 966 break; 967 case 4: 968 if (vtx->attr[2].emit == insert_2f_2 && 969 vtx->attr[3].emit == insert_2f_2) { 970 if (vtx->attr[1].emit == insert_4ub_4f_rgba_4) { 971 if (vtx->attr[0].emit == insert_4f_viewport_4) 972 func = emit_viewport4_rgba4_st2_st2; 973 else if (vtx->attr[0].emit == insert_4f_4) 974 func = emit_xyzw4_rgba4_st2_st2; 975 } 976 else if (vtx->attr[1].emit == insert_4ub_4f_bgra_4 && 977 vtx->attr[0].emit == insert_4f_viewport_4) 978 func = emit_viewport4_bgra4_st2_st2; 979 } 980 break; 981 } 982 983 vtx->emit = func; 984} 985 986/*********************************************************************** 987 * Generic (non-codegen) functions for whole vertices or groups of 988 * vertices 989 */ 990 991void _tnl_generic_emit( struct gl_context *ctx, 992 GLuint count, 993 GLubyte *v ) 994{ 995 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); 996 struct tnl_clipspace_attr *a = vtx->attr; 997 const GLuint attr_count = vtx->attr_count; 998 const GLuint stride = vtx->vertex_size; 999 GLuint i, j; 1000 1001 for (i = 0 ; i < count ; i++, v += stride) { 1002 for (j = 0; j < attr_count; j++) { 1003 GLfloat *in = (GLfloat *)a[j].inputptr; 1004 a[j].inputptr += a[j].inputstride; 1005 a[j].emit( &a[j], v + a[j].vertoffset, in ); 1006 } 1007 } 1008} 1009 1010 1011void _tnl_generic_interp( struct gl_context *ctx, 1012 GLfloat t, 1013 GLuint edst, GLuint eout, GLuint ein, 1014 GLboolean force_boundary ) 1015{ 1016 TNLcontext *tnl = TNL_CONTEXT(ctx); 1017 struct vertex_buffer *VB = &tnl->vb; 1018 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); 1019 const GLubyte *vin = vtx->vertex_buf + ein * vtx->vertex_size; 1020 const GLubyte *vout = vtx->vertex_buf + eout * vtx->vertex_size; 1021 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size; 1022 const struct tnl_clipspace_attr *a = vtx->attr; 1023 const GLuint attr_count = vtx->attr_count; 1024 GLuint j; 1025 (void) force_boundary; 1026 1027 if (tnl->NeedNdcCoords) { 1028 const GLfloat *dstclip = VB->ClipPtr->data[edst]; 1029 if (dstclip[3] != 0.0) { 1030 const GLfloat w = 1.0f / dstclip[3]; 1031 GLfloat pos[4]; 1032 1033 pos[0] = dstclip[0] * w; 1034 pos[1] = dstclip[1] * w; 1035 pos[2] = dstclip[2] * w; 1036 pos[3] = w; 1037 1038 a[0].insert[4-1]( &a[0], vdst, pos ); 1039 } 1040 } 1041 else { 1042 a[0].insert[4-1]( &a[0], vdst, VB->ClipPtr->data[edst] ); 1043 } 1044 1045 1046 for (j = 1; j < attr_count; j++) { 1047 GLfloat fin[4], fout[4], fdst[4]; 1048 1049 a[j].extract( &a[j], fin, vin + a[j].vertoffset ); 1050 a[j].extract( &a[j], fout, vout + a[j].vertoffset ); 1051 1052 INTERP_4F(t, fdst, fout, fin); 1053 1054 a[j].insert[4-1]( &a[j], vdst + a[j].vertoffset, fdst ); 1055 } 1056} 1057 1058 1059/* Extract color attributes from one vertex and insert them into 1060 * another. (Shortcircuit extract/insert with memcpy). 1061 */ 1062void _tnl_generic_copy_pv( struct gl_context *ctx, GLuint edst, GLuint esrc ) 1063{ 1064 struct tnl_clipspace *vtx = GET_VERTEX_STATE(ctx); 1065 GLubyte *vsrc = vtx->vertex_buf + esrc * vtx->vertex_size; 1066 GLubyte *vdst = vtx->vertex_buf + edst * vtx->vertex_size; 1067 const struct tnl_clipspace_attr *a = vtx->attr; 1068 const GLuint attr_count = vtx->attr_count; 1069 GLuint j; 1070 1071 for (j = 0; j < attr_count; j++) { 1072 if (a[j].attrib == VERT_ATTRIB_COLOR0 || 1073 a[j].attrib == VERT_ATTRIB_COLOR1) { 1074 1075 memcpy( vdst + a[j].vertoffset, 1076 vsrc + a[j].vertoffset, 1077 a[j].vertattrsize ); 1078 } 1079 } 1080} 1081 1082 1083/* Helper functions for hardware which doesn't put back colors and/or 1084 * edgeflags into vertices. 1085 */ 1086void _tnl_generic_interp_extras( struct gl_context *ctx, 1087 GLfloat t, 1088 GLuint dst, GLuint out, GLuint in, 1089 GLboolean force_boundary ) 1090{ 1091 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 1092 1093 /* If stride is zero, BackfaceColorPtr is constant across the VB, so 1094 * there is no point interpolating between two values as they will 1095 * be identical. In all other cases, this value is generated by 1096 * t_vb_lighttmp.h and has a stride of 4 dwords. 1097 */ 1098 if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) { 1099 assert(VB->BackfaceColorPtr->stride == 4 * sizeof(GLfloat)); 1100 1101 INTERP_4F( t, 1102 VB->BackfaceColorPtr->data[dst], 1103 VB->BackfaceColorPtr->data[out], 1104 VB->BackfaceColorPtr->data[in] ); 1105 } 1106 1107 if (VB->BackfaceSecondaryColorPtr) { 1108 assert(VB->BackfaceSecondaryColorPtr->stride == 4 * sizeof(GLfloat)); 1109 1110 INTERP_3F( t, 1111 VB->BackfaceSecondaryColorPtr->data[dst], 1112 VB->BackfaceSecondaryColorPtr->data[out], 1113 VB->BackfaceSecondaryColorPtr->data[in] ); 1114 } 1115 1116 if (VB->BackfaceIndexPtr) { 1117 VB->BackfaceIndexPtr->data[dst][0] = LINTERP( t, 1118 VB->BackfaceIndexPtr->data[out][0], 1119 VB->BackfaceIndexPtr->data[in][0] ); 1120 } 1121 1122 if (VB->EdgeFlag) { 1123 VB->EdgeFlag[dst] = VB->EdgeFlag[out] || force_boundary; 1124 } 1125 1126 _tnl_generic_interp(ctx, t, dst, out, in, force_boundary); 1127} 1128 1129void _tnl_generic_copy_pv_extras( struct gl_context *ctx, 1130 GLuint dst, GLuint src ) 1131{ 1132 struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; 1133 1134 /* See above comment: 1135 */ 1136 if (VB->BackfaceColorPtr && VB->BackfaceColorPtr->stride) { 1137 COPY_4FV( VB->BackfaceColorPtr->data[dst], 1138 VB->BackfaceColorPtr->data[src] ); 1139 } 1140 1141 if (VB->BackfaceSecondaryColorPtr) { 1142 COPY_4FV( VB->BackfaceSecondaryColorPtr->data[dst], 1143 VB->BackfaceSecondaryColorPtr->data[src] ); 1144 } 1145 1146 if (VB->BackfaceIndexPtr) { 1147 VB->BackfaceIndexPtr->data[dst][0] = VB->BackfaceIndexPtr->data[src][0]; 1148 } 1149 1150 _tnl_generic_copy_pv(ctx, dst, src); 1151} 1152 1153 1154