Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1137 lines
28 KiB

  1. /*
  2. ** Copyright 1991, 1992, 1993, Silicon Graphics, Inc.
  3. ** All Rights Reserved.
  4. **
  5. ** This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6. ** the contents of this file may not be disclosed to third parties, copied or
  7. ** duplicated in any form, in whole or in part, without the prior written
  8. ** permission of Silicon Graphics, Inc.
  9. **
  10. ** RESTRICTED RIGHTS LEGEND:
  11. ** Use, duplication or disclosure by the Government is subject to restrictions
  12. ** as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13. ** and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14. ** successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15. ** rights reserved under the Copyright Laws of the United States.
  16. */
  17. #include "precomp.h"
  18. #pragma hdrstop
  19. /*
  20. ** Process the incoming span by calling all of the appropriate span procs.
  21. */
  22. GLboolean FASTCALL __glProcessSpan(__GLcontext *gc)
  23. {
  24. GLint m, i;
  25. m = gc->procs.span.m;
  26. gc->polygon.shader.done = GL_FALSE;
  27. for (i = 0; i < m; i++) {
  28. if ((*gc->procs.span.spanFuncs[i])(gc)) {
  29. i++;
  30. break;
  31. }
  32. }
  33. if (i != m && !gc->polygon.shader.done) {
  34. for (; i<m; i++) {
  35. if ((*gc->procs.span.stippledSpanFuncs[i])(gc)) {
  36. break;
  37. }
  38. }
  39. }
  40. return GL_FALSE;
  41. }
  42. /*
  43. ** Process the incoming span by calling all of the appropriate span procs.
  44. **
  45. ** This routine sets gc->polygon.shader.cfb to &gc->frontBuffer and then
  46. ** to &gc->backBuffer.
  47. */
  48. GLboolean FASTCALL __glProcessReplicateSpan(__GLcontext *gc)
  49. {
  50. GLint n, m, i;
  51. __GLcolor colors[__GL_MAX_MAX_VIEWPORT], *fcp, *tcp;
  52. GLint w;
  53. w = gc->polygon.shader.length;
  54. n = gc->procs.span.n;
  55. m = gc->procs.span.m;
  56. gc->polygon.shader.done = GL_FALSE;
  57. for (i = 0; i < n; i++) {
  58. if ((*gc->procs.span.spanFuncs[i])(gc)) {
  59. i++;
  60. goto earlyStipple;
  61. }
  62. }
  63. fcp = gc->polygon.shader.colors;
  64. tcp = colors;
  65. if (gc->modes.rgbMode) {
  66. for (i = 0; i < w; i++) {
  67. *tcp++ = *fcp++;
  68. }
  69. } else {
  70. for (i = 0; i < w; i++) {
  71. tcp->r = fcp->r;
  72. fcp++;
  73. tcp++;
  74. }
  75. }
  76. ASSERTOPENGL (m == n + 1, "m != n+1, wrong spanProc will be chosen");
  77. gc->polygon.shader.cfb = &gc->frontBuffer;
  78. (*gc->frontBuffer.storeSpan)(gc);
  79. // for (i = n; i < m; i++) {
  80. // (*gc->procs.span.spanFuncs[i])(gc);
  81. // }
  82. fcp = colors;
  83. tcp = gc->polygon.shader.colors;
  84. if (gc->modes.rgbMode) {
  85. for (i = 0; i < w; i++) {
  86. *tcp++ = *fcp++;
  87. }
  88. } else {
  89. for (i = 0; i < w; i++) {
  90. tcp->r = fcp->r;
  91. fcp++;
  92. tcp++;
  93. }
  94. }
  95. gc->polygon.shader.cfb = &gc->backBuffer;
  96. (*gc->backBuffer.storeSpan)(gc);
  97. // for (i = n; i < m; i++) {
  98. // (*gc->procs.span.spanFuncs[i])(gc);
  99. // }
  100. return GL_FALSE;
  101. earlyStipple:
  102. if (gc->polygon.shader.done) return GL_FALSE;
  103. for (; i < n; i++) {
  104. if ((*gc->procs.span.stippledSpanFuncs[i])(gc)) {
  105. return GL_FALSE;
  106. }
  107. }
  108. fcp = gc->polygon.shader.colors;
  109. tcp = colors;
  110. if (gc->modes.rgbMode) {
  111. for (i = 0; i < w; i++) {
  112. *tcp++ = *fcp++;
  113. }
  114. } else {
  115. for (i = 0; i < w; i++) {
  116. tcp->r = fcp->r;
  117. fcp++;
  118. tcp++;
  119. }
  120. }
  121. gc->polygon.shader.cfb = &gc->frontBuffer;
  122. (*gc->frontBuffer.storeStippledSpan)(gc);
  123. // for (i = n; i < m; i++) {
  124. // (*gc->procs.span.stippledSpanFuncs[i])(gc);
  125. // }
  126. fcp = colors;
  127. tcp = gc->polygon.shader.colors;
  128. if (gc->modes.rgbMode) {
  129. for (i = 0; i < w; i++) {
  130. *tcp++ = *fcp++;
  131. }
  132. } else {
  133. for (i = 0; i < w; i++) {
  134. tcp->r = fcp->r;
  135. fcp++;
  136. tcp++;
  137. }
  138. }
  139. gc->polygon.shader.cfb = &gc->backBuffer;
  140. (*gc->backBuffer.storeStippledSpan)(gc);
  141. // for (i = n; i < m; i++) {
  142. // (*gc->procs.span.stippledSpanFuncs[i])(gc);
  143. // }
  144. return GL_FALSE;
  145. }
  146. /*
  147. ** Perform scissoring on the incoming span, advancing parameter
  148. ** values only if necessary.
  149. **
  150. ** Returns GL_TRUE if span was entirely (or sometimes when partially) clipped,
  151. ** GL_FALSE otherwise.
  152. */
  153. GLboolean FASTCALL __glClipSpan(__GLcontext *gc)
  154. {
  155. GLint clipX0, clipX1, delta;
  156. GLint x, xr;
  157. GLint w, w2;
  158. GLboolean stippled;
  159. w = gc->polygon.shader.length;
  160. x = gc->polygon.shader.frag.x;
  161. stippled = GL_FALSE;
  162. clipX0 = gc->transform.clipX0;
  163. clipX1 = gc->transform.clipX1;
  164. xr = x + w;
  165. if ((x < clipX0) || (xr > clipX1)) {
  166. /*
  167. ** Span needs to be scissored in some fashion
  168. */
  169. if ((xr <= clipX0) || (x >= clipX1)) {
  170. /* Scissor out the entire span */
  171. gc->polygon.shader.done = GL_TRUE;
  172. return GL_TRUE;
  173. }
  174. if (xr > clipX1) {
  175. /*
  176. ** Span is clipped by the right edge of the scissor. This is
  177. ** easy, we will simply reduce the width of this span!
  178. */
  179. w = clipX1 - x;
  180. }
  181. if (x < clipX0) {
  182. __GLstippleWord bit, outMask, *osp;
  183. GLint count;
  184. /*
  185. ** Span is clipped by the left edge of the scissor. This is hard.
  186. ** We have two choices.
  187. **
  188. ** 1) We can stipple the first half of the span.
  189. ** 2) We can bump all of the iterator values.
  190. **
  191. ** The problem with approach number 2 is that the routine
  192. ** which originally asks to have a span processed has assumed
  193. ** that the iterator values will not be munged. So, if we
  194. ** wanted to implement 2 (which would make this case faster),
  195. ** we would need to change that assumption, and make the higher
  196. ** routine shadow all of the iterator values, which would slow
  197. ** down all paths. This is probably not a good trade to speed
  198. ** this path up, since this path will only occur when the scissor
  199. ** region (or window) is smaller than the viewport, and this span
  200. ** happens to hit the left edge of the scissor region (or window).
  201. **
  202. ** Therefore, we choose number 1.
  203. */
  204. delta = clipX0 - x;
  205. osp = gc->polygon.shader.stipplePat;
  206. w2 = w;
  207. while (w2) {
  208. count = w2;
  209. if (count > __GL_STIPPLE_BITS) {
  210. count = __GL_STIPPLE_BITS;
  211. }
  212. w2 -= count;
  213. outMask = (__GLstippleWord) ~0;
  214. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  215. while (--count >= 0) {
  216. if (delta > 0) {
  217. delta--;
  218. outMask &= ~bit;
  219. }
  220. #ifdef __GL_STIPPLE_MSB
  221. bit >>= 1;
  222. #else
  223. bit <<= 1;
  224. #endif
  225. }
  226. *osp++ = outMask;
  227. }
  228. stippled = GL_TRUE;
  229. }
  230. }
  231. ASSERTOPENGL(w <= __GL_MAX_MAX_VIEWPORT,
  232. "Too many pixels generated by clip\n");
  233. gc->polygon.shader.length = w;
  234. return stippled;
  235. }
  236. /*
  237. ** Generate the polygon stipple for a span.
  238. */
  239. GLboolean FASTCALL __glStippleSpan(__GLcontext *gc)
  240. {
  241. __GLstippleWord stipple;
  242. __GLstippleWord *sp;
  243. GLint count;
  244. GLint shift;
  245. GLint w;
  246. w = gc->polygon.shader.length;
  247. if (gc->constants.yInverted) {
  248. stipple = gc->polygon.stipple[(gc->constants.height -
  249. (gc->polygon.shader.frag.y - gc->constants.viewportYAdjust)-1)
  250. & (__GL_STIPPLE_BITS-1)];
  251. } else {
  252. stipple = gc->polygon.stipple[gc->polygon.shader.frag.y &
  253. (__GL_STIPPLE_BITS-1)];
  254. }
  255. shift = gc->polygon.shader.frag.x & (__GL_STIPPLE_BITS - 1);
  256. #ifdef __GL_STIPPLE_MSB
  257. stipple = (stipple << shift) | (stipple >> (__GL_STIPPLE_BITS - shift));
  258. #else
  259. stipple = (stipple >> shift) | (stipple << (__GL_STIPPLE_BITS - shift));
  260. #endif
  261. if (stipple == 0) {
  262. /* No point in continuing */
  263. gc->polygon.shader.done = GL_TRUE;
  264. return GL_TRUE;
  265. }
  266. /* Replicate stipple word */
  267. count = w;
  268. sp = gc->polygon.shader.stipplePat;
  269. while (count > 0) {
  270. *sp++ = stipple;
  271. count -= __GL_STIPPLE_BITS;
  272. }
  273. return GL_TRUE;
  274. }
  275. /*
  276. ** Generate the polygon stipple for a stippled span.
  277. */
  278. GLboolean FASTCALL __glStippleStippledSpan(__GLcontext *gc)
  279. {
  280. __GLstippleWord stipple;
  281. __GLstippleWord *sp;
  282. GLint count;
  283. GLint shift;
  284. GLint w;
  285. w = gc->polygon.shader.length;
  286. if (gc->constants.yInverted) {
  287. stipple = gc->polygon.stipple[(gc->constants.height -
  288. (gc->polygon.shader.frag.y - gc->constants.viewportYAdjust)-1)
  289. & (__GL_STIPPLE_BITS-1)];
  290. } else {
  291. stipple = gc->polygon.stipple[gc->polygon.shader.frag.y &
  292. (__GL_STIPPLE_BITS-1)];
  293. }
  294. shift = gc->polygon.shader.frag.x & (__GL_STIPPLE_BITS - 1);
  295. #ifdef __GL_STIPPLE_MSB
  296. stipple = (stipple << shift) | (stipple >> (__GL_STIPPLE_BITS - shift));
  297. #else
  298. stipple = (stipple >> shift) | (stipple << (__GL_STIPPLE_BITS - shift));
  299. #endif
  300. if (stipple == 0) {
  301. /* No point in continuing */
  302. gc->polygon.shader.done = GL_TRUE;
  303. return GL_TRUE;
  304. }
  305. /* Replicate stipple word */
  306. count = w;
  307. sp = gc->polygon.shader.stipplePat;
  308. while (count > 0) {
  309. *sp++ &= stipple;
  310. count -= __GL_STIPPLE_BITS;
  311. }
  312. return GL_FALSE;
  313. }
  314. /************************************************************************/
  315. /*
  316. ** Alpha test span uses a lookup table to do the alpha test function.
  317. ** Output a stipple with 1's where the test passed, and 0's where the
  318. ** test failed.
  319. */
  320. GLboolean FASTCALL __glAlphaTestSpan(__GLcontext *gc)
  321. {
  322. GLubyte *atft;
  323. GLint failed, count, ia;
  324. __GLstippleWord bit, outMask, *osp;
  325. __GLcolor *cp;
  326. GLint maxAlpha;
  327. GLint w;
  328. w = gc->polygon.shader.length;
  329. atft = &gc->alphaTestFuncTable[0];
  330. cp = gc->polygon.shader.colors;
  331. maxAlpha = gc->constants.alphaTestSize - 1;
  332. osp = gc->polygon.shader.stipplePat;
  333. failed = 0;
  334. while (w) {
  335. count = w;
  336. if (count > __GL_STIPPLE_BITS) {
  337. count = __GL_STIPPLE_BITS;
  338. }
  339. w -= count;
  340. outMask = (__GLstippleWord) ~0;
  341. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  342. while (--count >= 0) {
  343. ia = (GLint)(gc->constants.alphaTableConv * cp->a);
  344. if (ia < 0) ia = 0;
  345. if (ia > maxAlpha) ia = maxAlpha;
  346. if (!atft[ia]) {
  347. /* Test failed */
  348. outMask &= ~bit;
  349. failed++;
  350. }
  351. cp++;
  352. #ifdef __GL_STIPPLE_MSB
  353. bit >>= 1;
  354. #else
  355. bit <<= 1;
  356. #endif
  357. }
  358. *osp++ = outMask;
  359. }
  360. if (failed == 0) {
  361. /* Call next span proc */
  362. return GL_FALSE;
  363. } else {
  364. if (failed != gc->polygon.shader.length) {
  365. /* Call next stippled span proc */
  366. return GL_TRUE;
  367. }
  368. }
  369. gc->polygon.shader.done = GL_TRUE;
  370. return GL_TRUE;
  371. }
  372. /*
  373. ** Stippled form of alpha test span that checks the stipple at each
  374. ** pixel and avoids the test where the stipple disallows it.
  375. */
  376. GLboolean FASTCALL __glAlphaTestStippledSpan(__GLcontext *gc)
  377. {
  378. GLubyte *atft;
  379. GLint count, ia, failed;
  380. __GLstippleWord bit, inMask, outMask, *isp;
  381. __GLcolor *cp;
  382. GLint maxAlpha;
  383. GLint w;
  384. w = gc->polygon.shader.length;
  385. isp = gc->polygon.shader.stipplePat;
  386. atft = &gc->alphaTestFuncTable[0];
  387. cp = gc->polygon.shader.colors;
  388. maxAlpha = gc->constants.alphaTestSize - 1;
  389. failed = 0;
  390. while (w) {
  391. count = w;
  392. if (count > __GL_STIPPLE_BITS) {
  393. count = __GL_STIPPLE_BITS;
  394. }
  395. w -= count;
  396. inMask = *isp;
  397. outMask = (__GLstippleWord) ~0;
  398. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  399. while (--count >= 0) {
  400. if (inMask & bit) {
  401. ia = (GLint)(gc->constants.alphaTableConv * cp->a);
  402. if (ia < 0) ia = 0;
  403. if (ia > maxAlpha) ia = maxAlpha;
  404. if (!atft[ia]) {
  405. /* Test failed */
  406. outMask &= ~bit;
  407. failed++;
  408. }
  409. } else failed++;
  410. cp++;
  411. #ifdef __GL_STIPPLE_MSB
  412. bit >>= 1;
  413. #else
  414. bit <<= 1;
  415. #endif
  416. }
  417. *isp++ = outMask & inMask;
  418. }
  419. if (failed != gc->polygon.shader.length) {
  420. /* Call next stippled span proc */
  421. return GL_FALSE;
  422. }
  423. return GL_TRUE;
  424. }
  425. /************************************************************************/
  426. /*
  427. ** Perform stencil testing. Apply test fail operation as we go.
  428. ** Generate a stipple with 1's where the test passed and 0's where the
  429. ** test failed.
  430. */
  431. GLboolean FASTCALL __glStencilTestSpan(__GLcontext *gc)
  432. {
  433. __GLstencilCell *tft, *sfb, *fail, cell;
  434. GLint count, failed;
  435. __GLstippleWord bit, outMask, *osp;
  436. GLint w;
  437. w = gc->polygon.shader.length;
  438. sfb = gc->polygon.shader.sbuf;
  439. tft = gc->stencilBuffer.testFuncTable;
  440. #ifdef NT
  441. if (!tft)
  442. return GL_FALSE;
  443. #endif // NT
  444. fail = gc->stencilBuffer.failOpTable;
  445. osp = gc->polygon.shader.stipplePat;
  446. failed = 0;
  447. while (w) {
  448. count = w;
  449. if (count > __GL_STIPPLE_BITS) {
  450. count = __GL_STIPPLE_BITS;
  451. }
  452. w -= count;
  453. outMask = (__GLstippleWord) ~0;
  454. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  455. while (--count >= 0) {
  456. cell = sfb[0];
  457. /* test func table already anded cell values with mask */
  458. if (!tft[cell]) {
  459. /* Test failed */
  460. outMask &= ~bit;
  461. sfb[0] = fail[cell];
  462. failed++;
  463. }
  464. sfb++;
  465. #ifdef __GL_STIPPLE_MSB
  466. bit >>= 1;
  467. #else
  468. bit <<= 1;
  469. #endif
  470. }
  471. *osp++ = outMask;
  472. }
  473. if (failed == 0) {
  474. return GL_FALSE;
  475. } else {
  476. if (failed != gc->polygon.shader.length) {
  477. /* Call next proc */
  478. return GL_TRUE;
  479. }
  480. }
  481. gc->polygon.shader.done = GL_TRUE;
  482. return GL_TRUE;
  483. }
  484. /*
  485. ** Stippled form of stencil test.
  486. */
  487. GLboolean FASTCALL __glStencilTestStippledSpan(__GLcontext *gc)
  488. {
  489. __GLstencilCell *tft, *sfb, *fail, cell;
  490. GLint failed, count;
  491. __GLstippleWord bit, inMask, outMask, *sp;
  492. GLuint smask;
  493. GLint w;
  494. w = gc->polygon.shader.length;
  495. sp = gc->polygon.shader.stipplePat;
  496. sfb = gc->polygon.shader.sbuf;
  497. tft = gc->stencilBuffer.testFuncTable;
  498. #ifdef NT
  499. if (!tft)
  500. return GL_FALSE;
  501. #endif // NT
  502. fail = gc->stencilBuffer.failOpTable;
  503. smask = gc->state.stencil.mask;
  504. failed = 0;
  505. while (w) {
  506. count = w;
  507. if (count > __GL_STIPPLE_BITS) {
  508. count = __GL_STIPPLE_BITS;
  509. }
  510. w -= count;
  511. inMask = *sp;
  512. outMask = (__GLstippleWord) ~0;
  513. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  514. while (--count >= 0) {
  515. if (inMask & bit) {
  516. cell = sfb[0];
  517. if (!tft[cell & smask]) {
  518. /* Test failed */
  519. outMask &= ~bit;
  520. sfb[0] = fail[cell];
  521. failed++;
  522. }
  523. } else failed++;
  524. sfb++;
  525. #ifdef __GL_STIPPLE_MSB
  526. bit >>= 1;
  527. #else
  528. bit <<= 1;
  529. #endif
  530. }
  531. *sp++ = outMask & inMask;
  532. }
  533. if (failed != gc->polygon.shader.length) {
  534. /* Call next proc */
  535. return GL_FALSE;
  536. }
  537. return GL_TRUE;
  538. }
  539. /************************************************************************/
  540. /*
  541. ** Depth test a span, when stenciling is disabled.
  542. */
  543. GLboolean FASTCALL __glDepthTestSpan(__GLcontext *gc)
  544. {
  545. __GLzValue z, dzdx, *zfb;
  546. GLint failed, count;
  547. GLboolean (FASTCALL *testFunc)( __GLzValue, __GLzValue * );
  548. GLint stride = gc->depthBuffer.buf.elementSize;
  549. __GLstippleWord bit, outMask, *osp;
  550. GLboolean writeEnabled, passed;
  551. GLint w;
  552. w = gc->polygon.shader.length;
  553. zfb = gc->polygon.shader.zbuf;
  554. testFunc = gc->procs.DTPixel;
  555. z = gc->polygon.shader.frag.z;
  556. dzdx = gc->polygon.shader.dzdx;
  557. writeEnabled = gc->state.depth.writeEnable;
  558. osp = gc->polygon.shader.stipplePat;
  559. failed = 0;
  560. while (w) {
  561. count = w;
  562. if (count > __GL_STIPPLE_BITS) {
  563. count = __GL_STIPPLE_BITS;
  564. }
  565. w -= count;
  566. outMask = (__GLstippleWord) ~0;
  567. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  568. while (--count >= 0) {
  569. if( (*testFunc)(z, zfb) == GL_FALSE ) {
  570. outMask &= ~bit;
  571. failed++;
  572. }
  573. z += dzdx;
  574. (GLubyte *) zfb += stride;
  575. #ifdef __GL_STIPPLE_MSB
  576. bit >>= 1;
  577. #else
  578. bit <<= 1;
  579. #endif
  580. }
  581. *osp++ = outMask;
  582. }
  583. if (failed == 0) {
  584. /* Call next span proc */
  585. return GL_FALSE;
  586. } else {
  587. if (failed != gc->polygon.shader.length) {
  588. /* Call next stippled span proc */
  589. return GL_TRUE;
  590. }
  591. }
  592. gc->polygon.shader.done = GL_TRUE;
  593. return GL_TRUE;
  594. }
  595. /*
  596. ** Stippled form of depth test span, when stenciling is disabled.
  597. */
  598. GLboolean FASTCALL __glDepthTestStippledSpan(__GLcontext *gc)
  599. {
  600. __GLzValue z, dzdx, *zfb;
  601. GLint failed, count;
  602. GLboolean (FASTCALL *testFunc)( __GLzValue, __GLzValue * );
  603. GLint stride = gc->depthBuffer.buf.elementSize;
  604. __GLstippleWord bit, inMask, outMask, *sp;
  605. GLboolean writeEnabled, passed;
  606. GLint w;
  607. sp = gc->polygon.shader.stipplePat;
  608. w = gc->polygon.shader.length;
  609. zfb = gc->polygon.shader.zbuf;
  610. testFunc = gc->procs.DTPixel;
  611. z = gc->polygon.shader.frag.z;
  612. dzdx = gc->polygon.shader.dzdx;
  613. writeEnabled = gc->state.depth.writeEnable;
  614. failed = 0;
  615. while (w) {
  616. count = w;
  617. if (count > __GL_STIPPLE_BITS) {
  618. count = __GL_STIPPLE_BITS;
  619. }
  620. w -= count;
  621. inMask = *sp;
  622. outMask = (__GLstippleWord) ~0;
  623. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  624. while (--count >= 0) {
  625. if (inMask & bit) {
  626. if( (*testFunc)(z, zfb) == GL_FALSE ) {
  627. outMask &= ~bit;
  628. failed++;
  629. }
  630. } else failed++;
  631. z += dzdx;
  632. (GLubyte *) zfb += stride;
  633. #ifdef __GL_STIPPLE_MSB
  634. bit >>= 1;
  635. #else
  636. bit <<= 1;
  637. #endif
  638. }
  639. *sp++ = outMask & inMask;
  640. }
  641. if (failed != gc->polygon.shader.length) {
  642. /* Call next proc */
  643. return GL_FALSE;
  644. }
  645. return GL_TRUE;
  646. }
  647. /*
  648. ** Depth test a span when stenciling is enabled.
  649. */
  650. GLboolean FASTCALL __glDepthTestStencilSpan(__GLcontext *gc)
  651. {
  652. __GLstencilCell *sfb, *zPassOp, *zFailOp;
  653. __GLzValue z, dzdx, *zfb;
  654. GLint failed, count;
  655. GLboolean (FASTCALL *testFunc)( __GLzValue, __GLzValue * );
  656. GLint stride = gc->depthBuffer.buf.elementSize;
  657. __GLstippleWord bit, outMask, *osp;
  658. GLboolean writeEnabled, passed;
  659. GLint w;
  660. w = gc->polygon.shader.length;
  661. zfb = gc->polygon.shader.zbuf;
  662. sfb = gc->polygon.shader.sbuf;
  663. zFailOp = gc->stencilBuffer.depthFailOpTable;
  664. #ifdef NT
  665. if (!zFailOp)
  666. return GL_FALSE;
  667. #endif // NT
  668. zPassOp = gc->stencilBuffer.depthPassOpTable;
  669. testFunc = gc->procs.DTPixel;
  670. z = gc->polygon.shader.frag.z;
  671. dzdx = gc->polygon.shader.dzdx;
  672. writeEnabled = gc->state.depth.writeEnable;
  673. osp = gc->polygon.shader.stipplePat;
  674. failed = 0;
  675. while (w) {
  676. count = w;
  677. if (count > __GL_STIPPLE_BITS) {
  678. count = __GL_STIPPLE_BITS;
  679. }
  680. w -= count;
  681. outMask = (__GLstippleWord) ~0;
  682. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  683. while (--count >= 0) {
  684. if( (*testFunc)(z, zfb) ) {
  685. sfb[0] = zPassOp[sfb[0]];
  686. } else {
  687. sfb[0] = zFailOp[sfb[0]];
  688. outMask &= ~bit;
  689. failed++;
  690. }
  691. z += dzdx;
  692. (GLubyte *) zfb += stride;
  693. sfb++;
  694. #ifdef __GL_STIPPLE_MSB
  695. bit >>= 1;
  696. #else
  697. bit <<= 1;
  698. #endif
  699. }
  700. *osp++ = outMask;
  701. }
  702. if (failed == 0) {
  703. /* Call next span proc */
  704. return GL_FALSE;
  705. } else {
  706. if (failed != gc->polygon.shader.length) {
  707. /* Call next stippled span proc */
  708. return GL_TRUE;
  709. }
  710. }
  711. gc->polygon.shader.done = GL_TRUE;
  712. return GL_TRUE;
  713. }
  714. GLboolean FASTCALL __glDepthTestStencilStippledSpan(__GLcontext *gc)
  715. {
  716. __GLstencilCell *sfb, *zPassOp, *zFailOp;
  717. __GLzValue z, dzdx, *zfb;
  718. GLint failed, count;
  719. GLboolean (FASTCALL *testFunc)( __GLzValue, __GLzValue * );
  720. GLint stride = gc->depthBuffer.buf.elementSize;
  721. __GLstippleWord bit, inMask, outMask, *sp;
  722. GLboolean writeEnabled, passed;
  723. GLint w;
  724. w = gc->polygon.shader.length;
  725. sp = gc->polygon.shader.stipplePat;
  726. zfb = gc->polygon.shader.zbuf;
  727. sfb = gc->polygon.shader.sbuf;
  728. testFunc = gc->procs.DTPixel;
  729. zFailOp = gc->stencilBuffer.depthFailOpTable;
  730. #ifdef NT
  731. if (!zFailOp)
  732. return GL_FALSE;
  733. #endif // NT
  734. zPassOp = gc->stencilBuffer.depthPassOpTable;
  735. z = gc->polygon.shader.frag.z;
  736. dzdx = gc->polygon.shader.dzdx;
  737. writeEnabled = gc->state.depth.writeEnable;
  738. failed = 0;
  739. while (w) {
  740. count = w;
  741. if (count > __GL_STIPPLE_BITS) {
  742. count = __GL_STIPPLE_BITS;
  743. }
  744. w -= count;
  745. inMask = *sp;
  746. outMask = (__GLstippleWord) ~0;
  747. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  748. while (--count >= 0) {
  749. if (inMask & bit) {
  750. if( (*testFunc)(z, zfb) ) {
  751. sfb[0] = zPassOp[sfb[0]];
  752. } else {
  753. sfb[0] = zFailOp[sfb[0]];
  754. outMask &= ~bit;
  755. failed++;
  756. }
  757. } else failed++;
  758. z += dzdx;
  759. (GLubyte *) zfb += stride;
  760. sfb++;
  761. #ifdef __GL_STIPPLE_MSB
  762. bit >>= 1;
  763. #else
  764. bit <<= 1;
  765. #endif
  766. }
  767. *sp++ = outMask & inMask;
  768. }
  769. if (failed != gc->polygon.shader.length) {
  770. /* Call next proc */
  771. return GL_FALSE;
  772. }
  773. return GL_TRUE;
  774. }
  775. /*
  776. ** Apply stencil depth pass op when depth testing is off.
  777. */
  778. GLboolean FASTCALL __glDepthPassSpan(__GLcontext *gc)
  779. {
  780. __GLstencilCell *sfb, *zPassOp;
  781. GLint count;
  782. GLint w;
  783. w = gc->polygon.shader.length;
  784. sfb = gc->polygon.shader.sbuf;
  785. zPassOp = gc->stencilBuffer.depthPassOpTable;
  786. #ifdef NT
  787. if (!zPassOp)
  788. return GL_FALSE;
  789. #endif // NT
  790. count = w;
  791. while (--count >= 0) {
  792. sfb[0] = zPassOp[sfb[0]];
  793. sfb++;
  794. }
  795. return GL_FALSE;
  796. }
  797. /*
  798. ** Apply stencil depth pass op when depth testing is off.
  799. */
  800. GLboolean FASTCALL __glDepthPassStippledSpan(__GLcontext *gc)
  801. {
  802. __GLstencilCell *sfb, *zPassOp;
  803. GLint count;
  804. __GLstippleWord bit, inMask, *sp;
  805. GLint w;
  806. w = gc->polygon.shader.length;
  807. sp = gc->polygon.shader.stipplePat;
  808. sfb = gc->polygon.shader.sbuf;
  809. zPassOp = gc->stencilBuffer.depthPassOpTable;
  810. #ifdef NT
  811. if (!zPassOp)
  812. return GL_FALSE;
  813. #endif // NT
  814. while (w) {
  815. count = w;
  816. if (count > __GL_STIPPLE_BITS) {
  817. count = __GL_STIPPLE_BITS;
  818. }
  819. w -= count;
  820. inMask = *sp++;
  821. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  822. while (--count >= 0) {
  823. if (inMask & bit) {
  824. sfb[0] = zPassOp[sfb[0]];
  825. }
  826. sfb++;
  827. #ifdef __GL_STIPPLE_MSB
  828. bit >>= 1;
  829. #else
  830. bit <<= 1;
  831. #endif
  832. }
  833. }
  834. /* Call next proc */
  835. return GL_FALSE;
  836. }
  837. /************************************************************************/
  838. GLboolean FASTCALL __glShadeCISpan(__GLcontext *gc)
  839. {
  840. __GLcolor *cp;
  841. __GLfloat r, drdx;
  842. GLint w;
  843. w = gc->polygon.shader.length;
  844. r = gc->polygon.shader.frag.color.r;
  845. drdx = gc->polygon.shader.drdx;
  846. cp = gc->polygon.shader.colors;
  847. while (--w >= 0) {
  848. cp->r = r;
  849. r += drdx;
  850. cp++;
  851. }
  852. return GL_FALSE;
  853. }
  854. GLboolean FASTCALL __glShadeRGBASpan(__GLcontext *gc)
  855. {
  856. __GLcolor *cp;
  857. __GLfloat r, g, b, a;
  858. __GLfloat drdx, dgdx, dbdx, dadx;
  859. GLint w;
  860. w = gc->polygon.shader.length;
  861. r = gc->polygon.shader.frag.color.r;
  862. g = gc->polygon.shader.frag.color.g;
  863. b = gc->polygon.shader.frag.color.b;
  864. a = gc->polygon.shader.frag.color.a;
  865. drdx = gc->polygon.shader.drdx;
  866. dgdx = gc->polygon.shader.dgdx;
  867. dbdx = gc->polygon.shader.dbdx;
  868. dadx = gc->polygon.shader.dadx;
  869. cp = gc->polygon.shader.colors;
  870. while (--w >= 0) {
  871. cp->r = r;
  872. cp->g = g;
  873. cp->b = b;
  874. cp->a = a;
  875. r += drdx;
  876. g += dgdx;
  877. b += dbdx;
  878. a += dadx;
  879. cp++;
  880. }
  881. return GL_FALSE;
  882. }
  883. GLboolean FASTCALL __glFlatCISpan(__GLcontext *gc)
  884. {
  885. __GLcolor *cp;
  886. __GLfloat r;
  887. GLint w;
  888. w = gc->polygon.shader.length;
  889. r = gc->polygon.shader.frag.color.r;
  890. cp = gc->polygon.shader.colors;
  891. while (--w >= 0) {
  892. cp->r = r;
  893. cp++;
  894. }
  895. return GL_FALSE;
  896. }
  897. GLboolean FASTCALL __glFlatRGBASpan(__GLcontext *gc)
  898. {
  899. __GLcolor *cp;
  900. __GLfloat r, g, b, a;
  901. GLint w;
  902. w = gc->polygon.shader.length;
  903. r = gc->polygon.shader.frag.color.r;
  904. g = gc->polygon.shader.frag.color.g;
  905. b = gc->polygon.shader.frag.color.b;
  906. a = gc->polygon.shader.frag.color.a;
  907. cp = gc->polygon.shader.colors;
  908. while (--w >= 0) {
  909. cp->r = r;
  910. cp->g = g;
  911. cp->b = b;
  912. cp->a = a;
  913. cp++;
  914. }
  915. return GL_FALSE;
  916. }
  917. /************************************************************************/
  918. // Special case where qw = 0 for the span
  919. GLboolean FASTCALL __glTextureSpanZeroQW(__GLcontext *gc)
  920. {
  921. __GLcolor *cp;
  922. GLint w;
  923. w = gc->polygon.shader.length;
  924. cp = gc->polygon.shader.colors;
  925. while (--w >= 0) {
  926. // No need to compute rho here - it is undefined for qw = 0
  927. (*gc->procs.texture)(gc, cp, __glZero, __glZero, __glZero);
  928. cp++;
  929. }
  930. return GL_FALSE;
  931. }
  932. GLboolean FASTCALL __glTextureSpan(__GLcontext *gc)
  933. {
  934. __GLcolor *cp;
  935. __GLfloat s, t, qw;
  936. GLint w;
  937. qw = gc->polygon.shader.frag.qw;
  938. if( qw == (__GLfloat) 0.0 ) {
  939. return __glTextureSpanZeroQW( gc );
  940. }
  941. w = gc->polygon.shader.length;
  942. s = gc->polygon.shader.frag.s;
  943. t = gc->polygon.shader.frag.t;
  944. cp = gc->polygon.shader.colors;
  945. while (--w >= 0) {
  946. __GLfloat sw, tw, rho, qwinv;
  947. qwinv = __glOne / qw;
  948. sw = s * qwinv;
  949. tw = t * qwinv;
  950. rho = (*gc->procs.calcPolygonRho)(gc, &gc->polygon.shader,
  951. s, t, qw);
  952. (*gc->procs.texture)(gc, cp, sw, tw, rho);
  953. s += gc->polygon.shader.dsdx;
  954. t += gc->polygon.shader.dtdx;
  955. qw += gc->polygon.shader.dqwdx;
  956. cp++;
  957. }
  958. return GL_FALSE;
  959. }
  960. GLboolean FASTCALL __glTextureStippledSpan(__GLcontext *gc)
  961. {
  962. __GLstippleWord inMask, bit, *sp;
  963. GLint count;
  964. __GLcolor *cp;
  965. __GLfloat s, t, qw;
  966. GLint w;
  967. w = gc->polygon.shader.length;
  968. sp = gc->polygon.shader.stipplePat;
  969. s = gc->polygon.shader.frag.s;
  970. t = gc->polygon.shader.frag.t;
  971. qw = gc->polygon.shader.frag.qw;
  972. cp = gc->polygon.shader.colors;
  973. while (w) {
  974. count = w;
  975. if (count > __GL_STIPPLE_BITS) {
  976. count = __GL_STIPPLE_BITS;
  977. }
  978. w -= count;
  979. inMask = *sp++;
  980. bit = (__GLstippleWord) __GL_STIPPLE_SHIFT(0);
  981. while (--count >= 0) {
  982. if (inMask & bit) {
  983. __GLfloat sw, tw, rho, qwinv;
  984. if( qw == (__GLfloat) 0.0 ) {
  985. sw = tw = (__GLfloat) 0.0;
  986. }
  987. else {
  988. qwinv = __glOne / qw;
  989. sw = s * qwinv;
  990. tw = t * qwinv;
  991. }
  992. rho = (*gc->procs.calcPolygonRho)(gc, &gc->polygon.shader,
  993. s, t, qw);
  994. (*gc->procs.texture)(gc, cp, sw, tw, rho);
  995. }
  996. s += gc->polygon.shader.dsdx;
  997. t += gc->polygon.shader.dtdx;
  998. qw += gc->polygon.shader.dqwdx;
  999. cp++;
  1000. #ifdef __GL_STIPPLE_MSB
  1001. bit >>= 1;
  1002. #else
  1003. bit <<= 1;
  1004. #endif
  1005. }
  1006. }
  1007. return GL_FALSE;
  1008. }