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