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@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 49static 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 61static 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 73static 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 85static 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 97static 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 108static 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 119static 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 130static 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 140static 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 155static 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 166static 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 177static 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 188static 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 199static 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 209static 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 216static 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 226static 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 236static 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 247static 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 256static 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 265static 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 273static 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 279static 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 291static 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 303static 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 315static 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 327static 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 338static 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 349static 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 360static 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 371static 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 382static 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 393static 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 404static 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 415static 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 426static 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 437static 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 448static 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 459static 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 470static 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 481static 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 492static 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 503static 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 513static 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 523static 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 533static 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 543static 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 553static 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 564static 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 580static 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 596static 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 609static 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 622static 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 633static 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 645static 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 657static 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 668static 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 679static 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 691static 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 701static 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 711static 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 721static 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 731static 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 741static 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 751static 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 761const 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) \ 869static 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 916EMIT2(insert_3f_viewport_3, insert_4ub_4f_rgba_4, emit_viewport3_rgba4) 917EMIT2(insert_3f_viewport_3, insert_4ub_4f_bgra_4, emit_viewport3_bgra4) 918EMIT2(insert_3f_3, insert_4ub_4f_rgba_4, emit_xyz3_rgba4) 919 920EMIT3(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_viewport4_rgba4_st2) 921EMIT3(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, emit_viewport4_bgra4_st2) 922EMIT3(insert_4f_4, insert_4ub_4f_rgba_4, insert_2f_2, emit_xyzw4_rgba4_st2) 923 924EMIT4(insert_4f_viewport_4, insert_4ub_4f_rgba_4, insert_2f_2, insert_2f_2, emit_viewport4_rgba4_st2_st2) 925EMIT4(insert_4f_viewport_4, insert_4ub_4f_bgra_4, insert_2f_2, insert_2f_2, emit_viewport4_bgra4_st2_st2) 926EMIT4(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 */ 932void _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 990void _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 1010void _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 */ 1061void _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 */ 1085void _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 1128void _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