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.

2341 lines
70 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: genaline.c *
  3. * *
  4. * This module provides accelerated interpolated line support. *
  5. * *
  6. * Created: 8-Dec-1995 *
  7. * Author: Otto Berkes [ottob] *
  8. * *
  9. * 23-Jan-1996 Drew Bliss [drewb] *
  10. * Cut down antialiasing code to provide aliased versions *
  11. * Optimized line setup *
  12. * *
  13. * Copyright (c) 1995-1996 Microsoft Corporation *
  14. \**************************************************************************/
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. // #define DO_CHECK_PIXELS
  18. #ifdef _X86_
  19. #include <gli386.h>
  20. #endif
  21. #include "genline.h"
  22. #ifndef NO_COMPILER_BUG
  23. #undef __GL_FLOAT_SIMPLE_BEGIN_DIVIDE
  24. #undef __GL_FLOAT_SIMPLE_END_DIVIDE
  25. #define __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(a, b, c) \
  26. __GL_FLOAT_BEGIN_DIVIDE(a, b, &(c))
  27. #define __GL_FLOAT_SIMPLE_END_DIVIDE(r) \
  28. __GL_FLOAT_END_DIVIDE(&(r))
  29. #endif
  30. // Also used by soft line code
  31. BOOL FASTCALL __glInitLineData(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  32. {
  33. GLint start, end;
  34. __GLfloat x0,y0,x1,y1;
  35. __GLfloat minorStart;
  36. __GLfloat fdx, fdy;
  37. __GLfloat offset;
  38. __GLfloat slope;
  39. __GLlineState *ls = &gc->state.line;
  40. __GLfloat halfWidth;
  41. GLint x0frac, x1frac, y0frac, y1frac, totDist;
  42. GLint ix0, ix1, iy0, iy1, idx, idy;
  43. __GLcolorBuffer *cfb = gc->drawBuffer;
  44. ASSERT_CHOP_ROUND();
  45. gc->line.options.v0 = v0;
  46. gc->line.options.v1 = v1;
  47. gc->line.options.width = ls->aliasedWidth;
  48. x0 = v0->window.x;
  49. y0 = v0->window.y;
  50. x1 = v1->window.x;
  51. y1 = v1->window.y;
  52. #ifdef DO_CHECK_PIXELS
  53. if (x0 < gc->transform.fminx || x0 >= gc->transform.fmaxx ||
  54. y0 < gc->transform.fminy || y0 >= gc->transform.fmaxy ||
  55. x1 < gc->transform.fminx || x1 >= gc->transform.fmaxx ||
  56. y1 < gc->transform.fminy || y1 >= gc->transform.fmaxy)
  57. {
  58. DbgPrint("Line coordinates out %.3lf,%.3lf - %.3lf,%.3lf%s\n",
  59. x0, y0, x1, y1,
  60. !gc->transform.reasonableViewport ? " (unreasonable)" : "");
  61. }
  62. #endif
  63. fdx = x1-x0;
  64. fdy = y1-y0;
  65. halfWidth = (ls->aliasedWidth - 1) * __glHalf;
  66. ix0 = __GL_VERTEX_FLOAT_TO_INT(x0);
  67. x0frac = __GL_VERTEX_FLOAT_FRACTION(x0);
  68. iy0 = __GL_VERTEX_FLOAT_TO_INT(y0);
  69. y0frac = __GL_VERTEX_FLOAT_FRACTION(y0);
  70. ix1 = __GL_VERTEX_FLOAT_TO_INT(x1);
  71. x1frac = __GL_VERTEX_FLOAT_FRACTION(x1);
  72. iy1 = __GL_VERTEX_FLOAT_TO_INT(y1);
  73. y1frac = __GL_VERTEX_FLOAT_FRACTION(y1);
  74. #if 0
  75. DbgPrint("Line %.3lf,%.3lf - %.3lf,%.3lf\n", x0, y0, x1, y1);
  76. DbgPrint("Line %d.%03d,%d.%03d - %d.%03d,%d.%03d\n",
  77. ix0, x0frac, iy0, y0frac, ix1, x1frac, iy1, y1frac);
  78. #endif
  79. // An interesting property of window coordinates is that subtracting
  80. // two of them cancels the exponent so the result is the fixed-point
  81. // difference
  82. idx = CASTINT(x1)-CASTINT(x0);
  83. idy = CASTINT(y1)-CASTINT(y0);
  84. if (idx > 0) {
  85. if (idy > 0) {
  86. if (idx > idy) { /* dx > dy > 0 */
  87. gc->line.options.yBig = 1;
  88. gc->polygon.shader.sbufBig =
  89. cfb->buf.outerWidth+GENACCEL(gc).xMultiplier;
  90. gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth+1;
  91. posxmajor: /* dx > |dy| >= 0 */
  92. gc->line.options.yLittle = 0;
  93. gc->line.options.xBig = 1;
  94. gc->line.options.xLittle = 1;
  95. gc->polygon.shader.sbufLittle = GENACCEL(gc).xMultiplier;
  96. gc->polygon.shader.zbufLittle = 1;
  97. __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(__glOne, fdx, slope);
  98. start = ix0;
  99. end = ix1;
  100. y0frac -= __GL_VERTEX_FRAC_HALF;
  101. if (y0frac < 0) y0frac = -y0frac;
  102. totDist = y0frac + x0frac - __GL_VERTEX_FRAC_ONE;
  103. if (totDist > 0) start++;
  104. y1frac -= __GL_VERTEX_FRAC_HALF;
  105. if (y1frac < 0) y1frac = -y1frac;
  106. totDist = y1frac + x1frac - __GL_VERTEX_FRAC_ONE;
  107. if (totDist > 0) end++;
  108. offset = start + __glHalf - x0;
  109. gc->line.options.length = fdx;
  110. gc->line.options.numPixels = end - start;
  111. xmajorfinish:
  112. gc->line.options.axis = __GL_X_MAJOR;
  113. gc->line.options.xStart = start;
  114. gc->line.options.offset = offset;
  115. __GL_FLOAT_SIMPLE_END_DIVIDE(slope);
  116. gc->line.options.oneOverLength = slope;
  117. slope *= fdy;
  118. minorStart = y0 + offset*slope - halfWidth;
  119. gc->line.options.yStart = __GL_VERTEX_FLOAT_TO_INT(minorStart);
  120. if (gc->line.options.yStart < gc->transform.miny)
  121. {
  122. gc->line.options.yStart = gc->transform.miny;
  123. gc->line.options.fraction = 0;
  124. }
  125. else if (gc->line.options.yStart >= gc->transform.maxy)
  126. {
  127. gc->line.options.yStart = gc->transform.maxy-1;
  128. gc->line.options.fraction =
  129. __GL_VERTEX_PROMOTE_FRACTION(
  130. (1 << __GL_VERTEX_FRAC_BITS)-1);
  131. }
  132. else
  133. {
  134. gc->line.options.fraction =
  135. __GL_VERTEX_PROMOTED_FRACTION(minorStart);
  136. }
  137. gc->line.options.dfraction = FLT_FRACTION(slope);
  138. } else { /* dy >= dx > 0 */
  139. gc->line.options.xBig = 1;
  140. gc->polygon.shader.sbufBig =
  141. cfb->buf.outerWidth+GENACCEL(gc).xMultiplier;
  142. gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth+1;
  143. posymajor: /* dy >= |dx| >= 0, dy != 0 */
  144. gc->line.options.xLittle = 0;
  145. gc->line.options.yBig = 1;
  146. gc->line.options.yLittle = 1;
  147. gc->polygon.shader.sbufLittle = cfb->buf.outerWidth;
  148. gc->polygon.shader.zbufLittle = gc->depthBuffer.buf.outerWidth;
  149. __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(__glOne, fdy, slope);
  150. start = iy0;
  151. end = iy1;
  152. x0frac -= __GL_VERTEX_FRAC_HALF;
  153. if (x0frac < 0) x0frac = -x0frac;
  154. totDist = y0frac + x0frac - __GL_VERTEX_FRAC_ONE;
  155. if (totDist > 0) start++;
  156. x1frac -= __GL_VERTEX_FRAC_HALF;
  157. if (x1frac < 0) x1frac = -x1frac;
  158. totDist = y1frac + x1frac - __GL_VERTEX_FRAC_ONE;
  159. if (totDist > 0) end++;
  160. offset = start + __glHalf - y0;
  161. gc->line.options.length = fdy;
  162. gc->line.options.numPixels = end - start;
  163. ymajorfinish:
  164. gc->line.options.axis = __GL_Y_MAJOR;
  165. gc->line.options.yStart = start;
  166. gc->line.options.offset = offset;
  167. __GL_FLOAT_SIMPLE_END_DIVIDE(slope);
  168. gc->line.options.oneOverLength = slope;
  169. slope *= fdx;
  170. minorStart = x0 + offset*slope - halfWidth;
  171. gc->line.options.xStart = __GL_VERTEX_FLOAT_TO_INT(minorStart);
  172. if (gc->line.options.xStart < gc->transform.minx)
  173. {
  174. gc->line.options.xStart = gc->transform.minx;
  175. gc->line.options.fraction = 0;
  176. }
  177. else if (gc->line.options.xStart >= gc->transform.maxx)
  178. {
  179. gc->line.options.xStart = gc->transform.maxx-1;
  180. gc->line.options.fraction =
  181. __GL_VERTEX_PROMOTE_FRACTION(
  182. (1 << __GL_VERTEX_FRAC_BITS)-1);
  183. }
  184. else
  185. {
  186. gc->line.options.fraction =
  187. __GL_VERTEX_PROMOTED_FRACTION(minorStart);
  188. }
  189. gc->line.options.dfraction = FLT_FRACTION(slope);
  190. }
  191. } else {
  192. if (idx > -idy) { /* dx > -dy >= 0 */
  193. gc->line.options.yBig = -1;
  194. gc->polygon.shader.sbufBig =
  195. GENACCEL(gc).xMultiplier-cfb->buf.outerWidth;
  196. gc->polygon.shader.zbufBig = 1-gc->depthBuffer.buf.outerWidth;
  197. goto posxmajor;
  198. } else { /* -dy >= dx >= 0, dy != 0 */
  199. gc->line.options.xBig = 1;
  200. gc->polygon.shader.sbufBig =
  201. GENACCEL(gc).xMultiplier-cfb->buf.outerWidth;
  202. gc->polygon.shader.zbufBig = 1-gc->depthBuffer.buf.outerWidth;
  203. negymajor: /* -dy >= |dx| >= 0, dy != 0 */
  204. gc->line.options.xLittle = 0;
  205. gc->line.options.yBig = -1;
  206. gc->line.options.yLittle = -1;
  207. gc->polygon.shader.sbufLittle = -cfb->buf.outerWidth;
  208. gc->polygon.shader.zbufLittle = -gc->depthBuffer.buf.outerWidth;
  209. __GL_FLOAT_BEGIN_DIVIDE(__glOne, -fdy, &slope);
  210. start = iy0;
  211. end = iy1;
  212. x0frac -= __GL_VERTEX_FRAC_HALF;
  213. if (x0frac < 0) x0frac = -x0frac;
  214. totDist = x0frac - y0frac;
  215. if (totDist > 0) start--;
  216. x1frac -= __GL_VERTEX_FRAC_HALF;
  217. if (x1frac < 0) x1frac = -x1frac;
  218. totDist = x1frac - y1frac;
  219. if (totDist > 0) end--;
  220. offset = y0 - (start + __glHalf);
  221. gc->line.options.length = -fdy;
  222. gc->line.options.numPixels = start - end;
  223. goto ymajorfinish;
  224. }
  225. }
  226. } else {
  227. if (idy > 0) {
  228. if (-idx > idy) { /* -dx > dy > 0 */
  229. gc->line.options.yBig = 1;
  230. gc->polygon.shader.sbufBig =
  231. cfb->buf.outerWidth-GENACCEL(gc).xMultiplier;
  232. gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth-1;
  233. negxmajor: /* -dx > |dy| >= 0 */
  234. gc->line.options.yLittle = 0;
  235. gc->line.options.xBig = -1;
  236. gc->line.options.xLittle = -1;
  237. gc->polygon.shader.sbufLittle = -GENACCEL(gc).xMultiplier;
  238. gc->polygon.shader.zbufLittle = -1;
  239. __GL_FLOAT_BEGIN_DIVIDE(__glOne, -fdx, &slope);
  240. start = ix0;
  241. end = ix1;
  242. y0frac -= __GL_VERTEX_FRAC_HALF;
  243. if (y0frac < 0) y0frac = -y0frac;
  244. totDist = y0frac - x0frac;
  245. if (totDist > 0) start--;
  246. y1frac -= __GL_VERTEX_FRAC_HALF;
  247. if (y1frac < 0) y1frac = -y1frac;
  248. totDist = y1frac - x1frac;
  249. if (totDist > 0) end--;
  250. offset = x0 - (start + __glHalf);
  251. gc->line.options.length = -fdx;
  252. gc->line.options.numPixels = start - end;
  253. goto xmajorfinish;
  254. } else { /* dy >= -dx >= 0, dy != 0 */
  255. gc->line.options.xBig = -1;
  256. gc->polygon.shader.sbufBig =
  257. cfb->buf.outerWidth-GENACCEL(gc).xMultiplier;
  258. gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth-1;
  259. goto posymajor;
  260. }
  261. } else {
  262. if (idx < idy) { /* -dx > -dy >= 0 */
  263. gc->line.options.yBig = -1;
  264. gc->polygon.shader.sbufBig =
  265. -GENACCEL(gc).xMultiplier-cfb->buf.outerWidth;
  266. gc->polygon.shader.zbufBig = -1-gc->depthBuffer.buf.outerWidth;
  267. goto negxmajor;
  268. } else { /* -dy >= -dx >= 0 */
  269. if ((idx | idy) == 0) {
  270. gc->line.options.numPixels = 0;
  271. return FALSE;
  272. }
  273. gc->line.options.xBig = -1;
  274. gc->polygon.shader.sbufBig =
  275. -GENACCEL(gc).xMultiplier-cfb->buf.outerWidth;
  276. gc->polygon.shader.zbufBig = -1-gc->depthBuffer.buf.outerWidth;
  277. goto negymajor;
  278. }
  279. }
  280. }
  281. #ifdef DO_CHECK_PIXELS
  282. if (gc->line.options.numPixels > 0)
  283. {
  284. ix0 = gc->line.options.xStart;
  285. iy0 = gc->line.options.yStart;
  286. if (ix0 < gc->transform.minx || ix0 >= gc->transform.maxx ||
  287. iy0 < gc->transform.miny || iy0 >= gc->transform.maxy)
  288. {
  289. DbgPrint("Start out of bounds %d,%d (%d,%d - %d,%d) for %d,%d\n",
  290. ix0, iy0,
  291. gc->transform.minx, gc->transform.miny,
  292. gc->transform.maxx, gc->transform.maxy,
  293. idx, idy);
  294. DbgPrint(" Line %.3lf,%.3lf - %.3lf,%.3lf\n", x0, y0, x1, y1);
  295. DbgPrint(" Viewport %.3lf,%.3lf - %.3lf,%.3lf%s\n",
  296. gc->state.viewport.xCenter, gc->state.viewport.yCenter,
  297. gc->state.viewport.xScale, gc->state.viewport.yScale,
  298. !gc->transform.reasonableViewport ?
  299. " (unreasonable)" : "");
  300. }
  301. }
  302. #endif
  303. return gc->line.options.numPixels > 0;
  304. }
  305. // Only used by fast single-pixel line code
  306. // It differs from glInitLineData only in the removal of halfWidth
  307. BOOL FASTCALL __glInitThinLineData(__GLcontext *gc, __GLvertex *v0, __GLvertex *v1)
  308. {
  309. GLint start, end;
  310. __GLfloat x0,y0,x1,y1;
  311. __GLfloat minorStart;
  312. __GLfloat fdx, fdy;
  313. __GLfloat offset;
  314. __GLfloat slope;
  315. GLint x0frac, x1frac, y0frac, y1frac, totDist;
  316. GLint ix0, ix1, iy0, iy1, idx, idy;
  317. __GLcolorBuffer *cfb = gc->drawBuffer;
  318. ASSERT_CHOP_ROUND();
  319. ASSERTOPENGL(gc->state.line.aliasedWidth == __glOne,
  320. "ThinAlias setup for wrong line state\n");
  321. x0 = v0->window.x;
  322. y0 = v0->window.y;
  323. x1 = v1->window.x;
  324. y1 = v1->window.y;
  325. #ifdef DO_CHECK_PIXELS
  326. gc->line.options.v0 = v0;
  327. gc->line.options.v1 = v1;
  328. if (x0 < gc->transform.fminx || x0 >= gc->transform.fmaxx ||
  329. y0 < gc->transform.fminy || y0 >= gc->transform.fmaxy ||
  330. x1 < gc->transform.fminx || x1 >= gc->transform.fmaxx ||
  331. y1 < gc->transform.fminy || y1 >= gc->transform.fmaxy)
  332. {
  333. DbgPrint("Line coordinates out %.3lf,%.3lf - %.3lf,%.3lf%s\n",
  334. x0, y0, x1, y1,
  335. !gc->transform.reasonableViewport ? " (unreasonable)" : "");
  336. }
  337. #endif
  338. fdx = x1-x0;
  339. fdy = y1-y0;
  340. ix0 = __GL_VERTEX_FLOAT_TO_INT(x0);
  341. x0frac = __GL_VERTEX_FLOAT_FRACTION(x0);
  342. iy0 = __GL_VERTEX_FLOAT_TO_INT(y0);
  343. y0frac = __GL_VERTEX_FLOAT_FRACTION(y0);
  344. ix1 = __GL_VERTEX_FLOAT_TO_INT(x1);
  345. x1frac = __GL_VERTEX_FLOAT_FRACTION(x1);
  346. iy1 = __GL_VERTEX_FLOAT_TO_INT(y1);
  347. y1frac = __GL_VERTEX_FLOAT_FRACTION(y1);
  348. #if 0
  349. DbgPrint("Line %.3lf,%.3lf - %.3lf,%.3lf\n", x0, y0, x1, y1);
  350. DbgPrint("Line %d.%03d,%d.%03d - %d.%03d,%d.%03d\n",
  351. ix0, x0frac, iy0, y0frac, ix1, x1frac, iy1, y1frac);
  352. #endif
  353. // An interesting property of window coordinates is that subtracting
  354. // two of them cancels the exponent so the result is the fixed-point
  355. // difference
  356. idx = CASTINT(x1)-CASTINT(x0);
  357. idy = CASTINT(y1)-CASTINT(y0);
  358. if (idx > 0) {
  359. if (idy > 0) {
  360. if (idx > idy) { /* dx > dy > 0 */
  361. gc->line.options.yBig = 1;
  362. gc->polygon.shader.sbufBig =
  363. cfb->buf.outerWidth+GENACCEL(gc).xMultiplier;
  364. gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth+1;
  365. posxmajor: /* dx > |dy| >= 0 */
  366. gc->line.options.yLittle = 0;
  367. gc->line.options.xBig = 1;
  368. gc->line.options.xLittle = 1;
  369. gc->polygon.shader.sbufLittle = GENACCEL(gc).xMultiplier;
  370. gc->polygon.shader.zbufLittle = 1;
  371. __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(__glOne, fdx, slope);
  372. start = ix0;
  373. end = ix1;
  374. y0frac -= __GL_VERTEX_FRAC_HALF;
  375. if (y0frac < 0) y0frac = -y0frac;
  376. totDist = y0frac + x0frac - __GL_VERTEX_FRAC_ONE;
  377. if (totDist > 0) start++;
  378. y1frac -= __GL_VERTEX_FRAC_HALF;
  379. if (y1frac < 0) y1frac = -y1frac;
  380. totDist = y1frac + x1frac - __GL_VERTEX_FRAC_ONE;
  381. if (totDist > 0) end++;
  382. offset = start + __glHalf - x0;
  383. gc->line.options.length = fdx;
  384. gc->line.options.numPixels = end - start;
  385. xmajorfinish:
  386. gc->line.options.axis = __GL_X_MAJOR;
  387. gc->line.options.xStart = start;
  388. gc->line.options.offset = offset;
  389. __GL_FLOAT_SIMPLE_END_DIVIDE(slope);
  390. gc->line.options.oneOverLength = slope;
  391. slope *= fdy;
  392. minorStart = y0 + offset*slope;
  393. gc->line.options.yStart = __GL_VERTEX_FLOAT_TO_INT(minorStart);
  394. if (gc->line.options.yStart < gc->transform.miny)
  395. {
  396. gc->line.options.yStart = gc->transform.miny;
  397. gc->line.options.fraction = 0;
  398. }
  399. else if (gc->line.options.yStart >= gc->transform.maxy)
  400. {
  401. gc->line.options.yStart = gc->transform.maxy-1;
  402. gc->line.options.fraction =
  403. __GL_VERTEX_PROMOTE_FRACTION(
  404. (1 << __GL_VERTEX_FRAC_BITS)-1);
  405. }
  406. else
  407. {
  408. gc->line.options.fraction =
  409. __GL_VERTEX_PROMOTED_FRACTION(minorStart);
  410. }
  411. gc->line.options.dfraction = FLT_FRACTION(slope);
  412. } else { /* dy >= dx > 0 */
  413. gc->line.options.xBig = 1;
  414. gc->polygon.shader.sbufBig =
  415. cfb->buf.outerWidth+GENACCEL(gc).xMultiplier;
  416. gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth+1;
  417. posymajor: /* dy >= |dx| >= 0, dy != 0 */
  418. gc->line.options.xLittle = 0;
  419. gc->line.options.yBig = 1;
  420. gc->line.options.yLittle = 1;
  421. gc->polygon.shader.sbufLittle = cfb->buf.outerWidth;
  422. gc->polygon.shader.zbufLittle = gc->depthBuffer.buf.outerWidth;
  423. __GL_FLOAT_SIMPLE_BEGIN_DIVIDE(__glOne, fdy, slope);
  424. start = iy0;
  425. end = iy1;
  426. x0frac -= __GL_VERTEX_FRAC_HALF;
  427. if (x0frac < 0) x0frac = -x0frac;
  428. totDist = y0frac + x0frac - __GL_VERTEX_FRAC_ONE;
  429. if (totDist > 0) start++;
  430. x1frac -= __GL_VERTEX_FRAC_HALF;
  431. if (x1frac < 0) x1frac = -x1frac;
  432. totDist = y1frac + x1frac - __GL_VERTEX_FRAC_ONE;
  433. if (totDist > 0) end++;
  434. offset = start + __glHalf - y0;
  435. gc->line.options.length = fdy;
  436. gc->line.options.numPixels = end - start;
  437. ymajorfinish:
  438. gc->line.options.axis = __GL_Y_MAJOR;
  439. gc->line.options.yStart = start;
  440. gc->line.options.offset = offset;
  441. __GL_FLOAT_SIMPLE_END_DIVIDE(slope);
  442. gc->line.options.oneOverLength = slope;
  443. slope *= fdx;
  444. minorStart = x0 + offset*slope;
  445. gc->line.options.xStart = __GL_VERTEX_FLOAT_TO_INT(minorStart);
  446. if (gc->line.options.xStart < gc->transform.minx)
  447. {
  448. gc->line.options.xStart = gc->transform.minx;
  449. gc->line.options.fraction = 0;
  450. }
  451. else if (gc->line.options.xStart >= gc->transform.maxx)
  452. {
  453. gc->line.options.xStart = gc->transform.maxx-1;
  454. gc->line.options.fraction =
  455. __GL_VERTEX_PROMOTE_FRACTION(
  456. (1 << __GL_VERTEX_FRAC_BITS)-1);
  457. }
  458. else
  459. {
  460. gc->line.options.fraction =
  461. __GL_VERTEX_PROMOTED_FRACTION(minorStart);
  462. }
  463. gc->line.options.dfraction = FLT_FRACTION(slope);
  464. }
  465. } else {
  466. if (idx > -idy) { /* dx > -dy >= 0 */
  467. gc->line.options.yBig = -1;
  468. gc->polygon.shader.sbufBig =
  469. GENACCEL(gc).xMultiplier-cfb->buf.outerWidth;
  470. gc->polygon.shader.zbufBig = 1-gc->depthBuffer.buf.outerWidth;
  471. goto posxmajor;
  472. } else { /* -dy >= dx >= 0, dy != 0 */
  473. gc->line.options.xBig = 1;
  474. gc->polygon.shader.sbufBig =
  475. GENACCEL(gc).xMultiplier-cfb->buf.outerWidth;
  476. gc->polygon.shader.zbufBig = 1-gc->depthBuffer.buf.outerWidth;
  477. negymajor: /* -dy >= |dx| >= 0, dy != 0 */
  478. gc->line.options.xLittle = 0;
  479. gc->line.options.yBig = -1;
  480. gc->line.options.yLittle = -1;
  481. gc->polygon.shader.sbufLittle = -cfb->buf.outerWidth;
  482. gc->polygon.shader.zbufLittle = -gc->depthBuffer.buf.outerWidth;
  483. __GL_FLOAT_BEGIN_DIVIDE(__glOne, -fdy, &slope);
  484. start = iy0;
  485. end = iy1;
  486. x0frac -= __GL_VERTEX_FRAC_HALF;
  487. if (x0frac < 0) x0frac = -x0frac;
  488. totDist = x0frac - y0frac;
  489. if (totDist > 0) start--;
  490. x1frac -= __GL_VERTEX_FRAC_HALF;
  491. if (x1frac < 0) x1frac = -x1frac;
  492. totDist = x1frac - y1frac;
  493. if (totDist > 0) end--;
  494. offset = y0 - (start + __glHalf);
  495. gc->line.options.length = -fdy;
  496. gc->line.options.numPixels = start - end;
  497. goto ymajorfinish;
  498. }
  499. }
  500. } else {
  501. if (idy > 0) {
  502. if (-idx > idy) { /* -dx > dy > 0 */
  503. gc->line.options.yBig = 1;
  504. gc->polygon.shader.sbufBig =
  505. cfb->buf.outerWidth-GENACCEL(gc).xMultiplier;
  506. gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth-1;
  507. negxmajor: /* -dx > |dy| >= 0 */
  508. gc->line.options.yLittle = 0;
  509. gc->line.options.xBig = -1;
  510. gc->line.options.xLittle = -1;
  511. gc->polygon.shader.sbufLittle = -GENACCEL(gc).xMultiplier;
  512. gc->polygon.shader.zbufLittle = -1;
  513. __GL_FLOAT_BEGIN_DIVIDE(__glOne, -fdx, &slope);
  514. start = ix0;
  515. end = ix1;
  516. y0frac -= __GL_VERTEX_FRAC_HALF;
  517. if (y0frac < 0) y0frac = -y0frac;
  518. totDist = y0frac - x0frac;
  519. if (totDist > 0) start--;
  520. y1frac -= __GL_VERTEX_FRAC_HALF;
  521. if (y1frac < 0) y1frac = -y1frac;
  522. totDist = y1frac - x1frac;
  523. if (totDist > 0) end--;
  524. offset = x0 - (start + __glHalf);
  525. gc->line.options.length = -fdx;
  526. gc->line.options.numPixels = start - end;
  527. goto xmajorfinish;
  528. } else { /* dy >= -dx >= 0, dy != 0 */
  529. gc->line.options.xBig = -1;
  530. gc->polygon.shader.sbufBig =
  531. cfb->buf.outerWidth-GENACCEL(gc).xMultiplier;
  532. gc->polygon.shader.zbufBig = gc->depthBuffer.buf.outerWidth-1;
  533. goto posymajor;
  534. }
  535. } else {
  536. if (idx < idy) { /* -dx > -dy >= 0 */
  537. gc->line.options.yBig = -1;
  538. gc->polygon.shader.sbufBig =
  539. -GENACCEL(gc).xMultiplier-cfb->buf.outerWidth;
  540. gc->polygon.shader.zbufBig = -1-gc->depthBuffer.buf.outerWidth;
  541. goto negxmajor;
  542. } else { /* -dy >= -dx >= 0 */
  543. if ((idx | idy) == 0) {
  544. gc->line.options.numPixels = 0;
  545. return FALSE;
  546. }
  547. gc->line.options.xBig = -1;
  548. gc->polygon.shader.sbufBig =
  549. -GENACCEL(gc).xMultiplier-cfb->buf.outerWidth;
  550. gc->polygon.shader.zbufBig = -1-gc->depthBuffer.buf.outerWidth;
  551. goto negymajor;
  552. }
  553. }
  554. }
  555. #ifdef DO_CHECK_PIXELS
  556. if (gc->line.options.numPixels > 0)
  557. {
  558. ix0 = gc->line.options.xStart;
  559. iy0 = gc->line.options.yStart;
  560. if (ix0 < gc->transform.minx || ix0 >= gc->transform.maxx ||
  561. iy0 < gc->transform.miny || iy0 >= gc->transform.maxy)
  562. {
  563. DbgPrint("Start out of bounds %d,%d (%d,%d - %d,%d) for %d,%d\n",
  564. ix0, iy0,
  565. gc->transform.minx, gc->transform.miny,
  566. gc->transform.maxx, gc->transform.maxy,
  567. idx, idy);
  568. DbgPrint(" Line %.3lf,%.3lf - %.3lf,%.3lf\n", x0, y0, x1, y1);
  569. DbgPrint(" Viewport %.3lf,%.3lf - %.3lf,%.3lf%s\n",
  570. gc->state.viewport.xCenter, gc->state.viewport.yCenter,
  571. gc->state.viewport.xScale, gc->state.viewport.yScale,
  572. !gc->transform.reasonableViewport ?
  573. " (unreasonable)" : "");
  574. }
  575. }
  576. #endif
  577. return gc->line.options.numPixels > 0;
  578. }
  579. // Called to render both anti-aliased and aliased lines
  580. void FASTCALL __glGenRenderEitherLine(__GLcontext *gc, __GLvertex *v0,
  581. __GLvertex *v1, GLuint flags)
  582. {
  583. __GLfloat invDelta;
  584. GLuint modeFlags = gc->polygon.shader.modeFlags;
  585. CHOP_ROUND_ON();
  586. if (!(*GENACCEL(gc).__fastGenInitLineData)(gc, v0, v1))
  587. {
  588. CHOP_ROUND_OFF();
  589. return;
  590. }
  591. ASSERTOPENGL(GENACCEL(gc).rAccelScale == FIX_SCALEFACT,
  592. "rAccelScale != FIX_SCALEFACT\n");
  593. ASSERTOPENGL(GENACCEL(gc).gAccelScale == FIX_SCALEFACT,
  594. "gAccelScale != FIX_SCALEFACT\n");
  595. ASSERTOPENGL(GENACCEL(gc).bAccelScale == FIX_SCALEFACT,
  596. "bAccelScale != FIX_SCALEFACT\n");
  597. // Alpha is always scaled between 0 and 255
  598. invDelta = gc->line.options.oneOverLength;
  599. /*
  600. ** Set up increments for any enabled line options.
  601. */
  602. if ((gc->drawBuffer->buf.flags & DIB_FORMAT) == 0)
  603. {
  604. // For non-DIBs we pick up the bytes from ColorsBits so
  605. // the pixel pointer doesn't move
  606. gc->polygon.shader.sbufLittle = 0;
  607. gc->polygon.shader.sbufBig = 0;
  608. }
  609. if (modeFlags & __GL_SHADE_SMOOTH)
  610. {
  611. __GLcolor *c0 = v0->color;
  612. __GLcolor *c1 = v1->color;
  613. /*
  614. ** Calculate red, green, blue and alpha value increments.
  615. */
  616. if (gc->modes.rgbMode)
  617. {
  618. __GLfloat dr, dg, db;
  619. #ifdef _X86_
  620. __asm
  621. {
  622. ; Compute dr, dg and db
  623. mov eax, c0
  624. mov edx, c1
  625. fld DWORD PTR [eax+COLOR_r]
  626. fld DWORD PTR [eax+COLOR_g]
  627. fld DWORD PTR [eax+COLOR_b]
  628. fld DWORD PTR [edx+COLOR_r]
  629. fsub st(0), st(3)
  630. fld DWORD PTR [edx+COLOR_g]
  631. fsub st(0), st(3)
  632. fld DWORD PTR [edx+COLOR_b]
  633. fsub st(0), st(3)
  634. mov edx, gc
  635. fstp db
  636. fstp dg
  637. fstp dr
  638. FLT_STACK_RGB_TO_GC_FIXED(GC_SHADER_R,
  639. GC_SHADER_G,
  640. GC_SHADER_B)
  641. }
  642. #else
  643. dr = c1->r - c0->r;
  644. CASTFIX(gc->polygon.shader.frag.color.r) =
  645. UNSAFE_FLT_TO_FIX(c0->r);
  646. dg = c1->g - c0->g;
  647. CASTFIX(gc->polygon.shader.frag.color.g) =
  648. UNSAFE_FLT_TO_FIX(c0->g);
  649. db = c1->b - c0->b;
  650. CASTFIX(gc->polygon.shader.frag.color.b) =
  651. UNSAFE_FLT_TO_FIX(c0->b);
  652. #endif
  653. if ((CASTINT(dr) | CASTINT(dg) | CASTINT(db)) == 0)
  654. {
  655. CASTINT(gc->polygon.shader.drdx) = 0;
  656. CASTINT(gc->polygon.shader.dgdx) = 0;
  657. CASTINT(gc->polygon.shader.dbdx) = 0;
  658. }
  659. else
  660. {
  661. #ifdef _X86_
  662. __asm
  663. {
  664. fld dr
  665. fld dg
  666. fld db
  667. fld invDelta
  668. fmul __glVal65536
  669. mov edx, gc
  670. fmul st(3), st(0)
  671. fmul st(2), st(0)
  672. fmulp st(1), st(0)
  673. fistp DWORD PTR [edx+GC_SHADE_dbdx]
  674. fistp DWORD PTR [edx+GC_SHADE_dgdx]
  675. fistp DWORD PTR [edx+GC_SHADE_drdx]
  676. }
  677. #else
  678. CASTFIX(gc->polygon.shader.drdx) =
  679. UNSAFE_FLT_TO_FIX(dr * invDelta);
  680. CASTFIX(gc->polygon.shader.dgdx) =
  681. UNSAFE_FLT_TO_FIX(dg * invDelta);
  682. CASTFIX(gc->polygon.shader.dbdx) =
  683. UNSAFE_FLT_TO_FIX(db * invDelta);
  684. #endif
  685. }
  686. if (gc->state.enables.general & __GL_BLEND_ENABLE)
  687. {
  688. __GLfloat da;
  689. da = c1->a - c0->a;
  690. CASTFIX(gc->polygon.shader.frag.color.a) =
  691. UNSAFE_FTOL(c0->a * GENACCEL(gc).aAccelScale);
  692. if (__GL_FLOAT_EQZ(da))
  693. {
  694. CASTINT(gc->polygon.shader.dadx) = 0;
  695. }
  696. else
  697. {
  698. CASTFIX(gc->polygon.shader.dadx) =
  699. UNSAFE_FTOL(da * invDelta * GENACCEL(gc).aAccelScale);
  700. }
  701. }
  702. }
  703. else
  704. {
  705. __GLfloat dr;
  706. dr = c1->r - c0->r;
  707. CASTFIX(gc->polygon.shader.frag.color.r) =
  708. UNSAFE_FLT_TO_FIX(c0->r);
  709. if (__GL_FLOAT_EQZ(dr))
  710. {
  711. CASTINT(gc->polygon.shader.drdx) = 0;
  712. }
  713. else
  714. {
  715. CASTFIX(gc->polygon.shader.drdx) =
  716. UNSAFE_FLT_TO_FIX(dr * invDelta);
  717. }
  718. }
  719. }
  720. else
  721. {
  722. __GLcolor *c1 = v0->color;
  723. if (gc->modes.rgbMode)
  724. {
  725. #ifdef _X86_
  726. __asm
  727. {
  728. mov eax, c1
  729. fld DWORD PTR [eax+COLOR_r]
  730. fld DWORD PTR [eax+COLOR_g]
  731. fld DWORD PTR [eax+COLOR_b]
  732. mov edx, gc
  733. FLT_STACK_RGB_TO_GC_FIXED(GC_SHADER_R,
  734. GC_SHADER_G,
  735. GC_SHADER_B)
  736. }
  737. #else
  738. CASTFIX(gc->polygon.shader.frag.color.r) =
  739. UNSAFE_FLT_TO_FIX(c1->r);
  740. CASTFIX(gc->polygon.shader.frag.color.g) =
  741. UNSAFE_FLT_TO_FIX(c1->g);
  742. CASTFIX(gc->polygon.shader.frag.color.b) =
  743. UNSAFE_FLT_TO_FIX(c1->b);
  744. #endif
  745. if (gc->state.enables.general & __GL_BLEND_ENABLE)
  746. {
  747. CASTFIX(gc->polygon.shader.frag.color.a) =
  748. UNSAFE_FTOL(c1->a * GENACCEL(gc).aAccelScale);
  749. }
  750. }
  751. else
  752. {
  753. CASTFIX(gc->polygon.shader.frag.color.r) =
  754. UNSAFE_FLT_TO_FIX(c1->r);
  755. }
  756. }
  757. if (modeFlags & __GL_SHADE_DEPTH_ITER)
  758. {
  759. // The increment is in USHORT units so it only needs to be
  760. // scaled in the 32-bit Z buffer case
  761. if (gc->depthBuffer.buf.elementSize == 4)
  762. {
  763. gc->polygon.shader.zbufLittle <<= 1;
  764. gc->polygon.shader.zbufBig <<= 1;
  765. }
  766. /*
  767. ** Calculate window z coordinate increment and starting position.
  768. */
  769. if(( gc->modes.depthBits == 16 ) &&
  770. ( gc->depthBuffer.scale <= (GLuint)0xffff ))
  771. {
  772. ASSERTOPENGL(Z16_SCALE == FIX_SCALEFACT,
  773. "Z16 scaling different from fixed\n");
  774. gc->polygon.shader.dzdx =
  775. FLT_TO_Z16_SCALE((v1->window.z - v0->window.z) * invDelta);
  776. gc->polygon.shader.frag.z =
  777. FTOL(v0->window.z*Z16_SCALE + gc->polygon.shader.dzdx *
  778. gc->line.options.offset);
  779. }
  780. else
  781. {
  782. gc->polygon.shader.dzdx =
  783. FTOL((v1->window.z - v0->window.z) * invDelta);
  784. gc->polygon.shader.frag.z =
  785. FTOL(v0->window.z + gc->polygon.shader.dzdx *
  786. gc->line.options.offset);
  787. }
  788. }
  789. (*GENACCEL(gc).__fastGenLineProc)(gc);
  790. CHOP_ROUND_OFF();
  791. }
  792. #define DITHER_PIXEL(pPix, x, y)\
  793. {\
  794. ULONG r, g, b;\
  795. DWORD ditherVal;\
  796. \
  797. ditherVal = ditherShade[((x) & 0x3) + \
  798. (((y) & 0x3) << 3)];\
  799. \
  800. r = ((rAccum + ditherVal) >> (16-RSHIFT)) & RMASK;\
  801. g = ((gAccum + ditherVal) >> (16-GSHIFT)) & GMASK;\
  802. b = ((bAccum + ditherVal) >> (16-BSHIFT)) & BMASK;\
  803. \
  804. WRITE_PIX(pPix);\
  805. }
  806. #define BLEND_PIXEL(pPix, alpha, x, y)\
  807. {\
  808. ULONG pix;\
  809. ULONG rDisplay, gDisplay, bDisplay, aDisplay;\
  810. ULONG r, g, b;\
  811. ULONG invAlpha;\
  812. DWORD ditherVal;\
  813. \
  814. ditherVal = ditherShade[((x) & 0x3) + \
  815. (((y) & 0x3) << 3)];\
  816. \
  817. aDisplay = (gbMulTable[((aAccum >> 16) & 0xff) | (alpha)]) << 8;\
  818. \
  819. pix = READ_PIX(pPix);\
  820. \
  821. rDisplay = ((pix & RMASK) >> RSHIFT) << (8 - RBITS);\
  822. gDisplay = ((pix & GMASK) >> GSHIFT) << (8 - GBITS);\
  823. bDisplay = ((pix & BMASK) >> BSHIFT) << (8 - BBITS);\
  824. \
  825. if (gc->state.raster.blendDst == GL_ONE) { \
  826. \
  827. r = (gbMulTable[((rAccum >> (RBITS+8)) & 0xff) | aDisplay] + rDisplay)\
  828. + (ditherVal >> (RBITS + 8));\
  829. g = (gbMulTable[((gAccum >> (GBITS+8)) & 0xff) | aDisplay] + gDisplay)\
  830. + (ditherVal >> (GBITS + 8));\
  831. b = (gbMulTable[((bAccum >> (BBITS+8)) & 0xff) | aDisplay] + bDisplay)\
  832. + (ditherVal >> (BBITS + 8));\
  833. r = ((gbSatTable[r] << (RBITS+8)) \
  834. >> (16 - RSHIFT)) & RMASK;\
  835. g = ((gbSatTable[g] << (GBITS+8)) \
  836. >> (16 - GSHIFT)) & GMASK;\
  837. b = ((gbSatTable[b] << (BBITS+8)) \
  838. >> (16 - BSHIFT)) & BMASK;\
  839. \
  840. } else { \
  841. \
  842. invAlpha = 0xff00 - (ULONG)aDisplay;\
  843. \
  844. rDisplay = gbMulTable[rDisplay | invAlpha];\
  845. gDisplay = gbMulTable[gDisplay | invAlpha];\
  846. bDisplay = gbMulTable[bDisplay | invAlpha];\
  847. \
  848. r = ((((gbMulTable[((rAccum >> (RBITS+8)) & 0xff) | aDisplay] + rDisplay)\
  849. << (RBITS+8)) + ditherVal) >> (16 - RSHIFT)) & RMASK;\
  850. \
  851. g = ((((gbMulTable[((gAccum >> (GBITS+8)) & 0xff) | aDisplay] + gDisplay)\
  852. << (GBITS+8)) + ditherVal) >> (16 - GSHIFT)) & GMASK;\
  853. \
  854. b = ((((gbMulTable[((bAccum >> (BBITS+8)) & 0xff) | aDisplay] + bDisplay)\
  855. << (BBITS+8)) + ditherVal) >> (16 - BSHIFT)) & BMASK;\
  856. } \
  857. \
  858. WRITE_PIX(pPix);\
  859. }
  860. #define WRITE_PIXEL_GEN(pPix, alpha, x, y)\
  861. if (gc->state.enables.general & __GL_BLEND_ENABLE) {\
  862. ULONG pix;\
  863. ULONG rDisplay, gDisplay, bDisplay, aDisplay;\
  864. ULONG r, g, b;\
  865. ULONG invAlpha;\
  866. DWORD ditherVal;\
  867. \
  868. if (modeFlags & __GL_SHADE_DITHER) {\
  869. ditherVal = ditherShade[((x) & 0x3) + \
  870. (((y) & 0x3) << 3)];\
  871. } else\
  872. ditherVal = 0;\
  873. \
  874. aDisplay = (gbMulTable[((aAccum >> 16) & 0xff) | (alpha)]) << 8;\
  875. \
  876. switch (bytesPerPixel) {\
  877. case 1:\
  878. pix = ((__GLGENcontext *)gc)->pajInvTranslateVector[*((BYTE *)(pPix))];\
  879. rDisplay = ((pix & rMask) >> rShift) << (8 - rBits);\
  880. gDisplay = ((pix & gMask) >> gShift) << (8 - gBits);\
  881. bDisplay = ((pix & bMask) >> bShift) << (8 - bBits);\
  882. break;\
  883. case 2:\
  884. pix = *((USHORT *)(pPix));\
  885. rDisplay = ((pix & rMask) >> rShift) << (8 - rBits);\
  886. gDisplay = ((pix & gMask) >> gShift) << (8 - gBits);\
  887. bDisplay = ((pix & bMask) >> bShift) << (8 - bBits);\
  888. break;\
  889. case 3:\
  890. default:\
  891. if (rShift > bShift) {\
  892. rDisplay = pPix[2];\
  893. gDisplay = pPix[1];\
  894. bDisplay = pPix[0];\
  895. } else {\
  896. rDisplay = pPix[0];\
  897. gDisplay = pPix[1];\
  898. bDisplay = pPix[2];\
  899. }\
  900. break;\
  901. }\
  902. \
  903. if (gc->state.raster.blendDst == GL_ONE) { \
  904. \
  905. r = (gbMulTable[((rAccum >> (rBits+8)) & 0xff) | aDisplay] + rDisplay)\
  906. + (ditherVal >> (rBits + 8));\
  907. g = (gbMulTable[((gAccum >> (gBits+8)) & 0xff) | aDisplay] + gDisplay)\
  908. + (ditherVal >> (gBits + 8));\
  909. b = (gbMulTable[((bAccum >> (bBits+8)) & 0xff) | aDisplay] + bDisplay)\
  910. + (ditherVal >> (bBits + 8));\
  911. r = ((gbSatTable[r] << (rBits+8)) \
  912. >> (16 - rShift)) & rMask;\
  913. g = ((gbSatTable[g] << (gBits+8)) \
  914. >> (16 - gShift)) & gMask;\
  915. b = ((gbSatTable[b] << (bBits+8)) \
  916. >> (16 - bShift)) & bMask;\
  917. \
  918. } else { \
  919. \
  920. invAlpha = 0xff00 - (ULONG)aDisplay;\
  921. \
  922. rDisplay = gbMulTable[rDisplay | invAlpha];\
  923. gDisplay = gbMulTable[gDisplay | invAlpha];\
  924. bDisplay = gbMulTable[bDisplay | invAlpha];\
  925. \
  926. r = ((((gbMulTable[((rAccum >> (rBits+8)) & 0xff) | aDisplay] + rDisplay)\
  927. << (rBits+8)) + ditherVal) >> (16 - rShift)) & rMask;\
  928. \
  929. g = ((((gbMulTable[((gAccum >> (gBits+8)) & 0xff) | aDisplay] + gDisplay)\
  930. << (gBits+8)) + ditherVal) >> (16 - gShift)) & gMask;\
  931. \
  932. b = ((((gbMulTable[((bAccum >> (bBits+8)) & 0xff) | aDisplay] + bDisplay)\
  933. << (bBits+8)) + ditherVal) >> (16 - bShift)) & bMask;\
  934. } \
  935. \
  936. switch (bytesPerPixel) {\
  937. case 1:\
  938. pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b];\
  939. break;\
  940. case 2:\
  941. *((USHORT *)pPix) = (USHORT)(r | g | b);\
  942. break;\
  943. case 3:\
  944. pix = r | g | b;\
  945. *((USHORT UNALIGNED *)pPix) = (USHORT)pix;\
  946. pPix[2] = (BYTE)(pix >> 16);\
  947. break;\
  948. default:\
  949. *((DWORD *)pPix) = (DWORD)(r | g | b);\
  950. break;\
  951. }\
  952. } else {\
  953. ULONG r, g, b;\
  954. DWORD ditherVal;\
  955. ULONG pix;\
  956. \
  957. if (modeFlags & __GL_SHADE_DITHER) {\
  958. ditherVal = ditherShade[((x) & 0x3) + (((y) & 0x3) << 3)];\
  959. } else\
  960. ditherVal = 0;\
  961. \
  962. r = ((rAccum + ditherVal) >> (16-rShift)) & rMask;\
  963. g = ((gAccum + ditherVal) >> (16-gShift)) & gMask;\
  964. b = ((bAccum + ditherVal) >> (16-bShift)) & bMask;\
  965. \
  966. switch (bytesPerPixel) {\
  967. case 1:\
  968. pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b];\
  969. break;\
  970. case 2:\
  971. *((USHORT *)pPix) = (USHORT)(r | g | b);\
  972. break;\
  973. case 3:\
  974. pix = r | g | b;\
  975. *((USHORT UNALIGNED *)pPix) = (USHORT)pix;\
  976. pPix[2] = (BYTE)(pix >> 16);\
  977. break;\
  978. default:\
  979. *((DWORD *)pPix) = (DWORD)(r | g | b);\
  980. break;\
  981. }\
  982. }
  983. #ifdef DO_CHECK_PIXELS
  984. #define CHECK_PIXEL(gc, cfb, count, bx, by) \
  985. {\
  986. GLint fbX, fbY;\
  987. \
  988. fbX = __GL_UNBIAS_X(gc, bx);\
  989. fbY = __GL_UNBIAS_Y(gc, by);\
  990. if (!(fbX >= 0 && fbX < (cfb)->buf.width &&\
  991. fbY >= 0 && fbY < (cfb)->buf.height))\
  992. {\
  993. DbgPrint("Pixel out of bounds at %c %d of %d: %d,%d (%d,%d)\n",\
  994. (gc)->line.options.axis == __GL_Y_MAJOR ? 'Y' : 'X',\
  995. (gc)->line.options.numPixels-(count),\
  996. (gc)->line.options.numPixels,\
  997. fbX, fbY, (cfb)->buf.width, (cfb)->buf.height);\
  998. DbgPrint(" Line %.3lf,%.3lf - %.3lf,%.3lf\n",\
  999. (gc)->line.options.v0->window.x,\
  1000. (gc)->line.options.v0->window.y,\
  1001. (gc)->line.options.v1->window.x,\
  1002. (gc)->line.options.v1->window.y);\
  1003. }\
  1004. }
  1005. #else
  1006. #define CHECK_PIXEL(gc, cfb, w, x, y)
  1007. #endif
  1008. #define FAST_AA_LINE \
  1009. {\
  1010. GLint xLittle, xBig, yLittle, yBig;\
  1011. GLint fragX2, fragY2;\
  1012. BYTE *pPix;\
  1013. BYTE *pPix2;\
  1014. USHORT *pZ;\
  1015. USHORT *pZ2;\
  1016. __GLfragment frag;\
  1017. __GLcolorBuffer *cfb = gc->drawBuffer;\
  1018. LONG rAccum, gAccum, bAccum, aAccum;\
  1019. LONG pixAdjStep;\
  1020. ULONG zAdjStep;\
  1021. ULONG coverage, invCoverage;\
  1022. LONG fragXinc;\
  1023. LONG fragYinc;\
  1024. LONG bytesPerPixel;\
  1025. __GLzValue zAccum;\
  1026. GLint clipX1 = gc->transform.clipX1;\
  1027. GLint clipY1 = gc->transform.clipY1;\
  1028. \
  1029. GLint fraction, dfraction;\
  1030. GLint w;\
  1031. GLuint modeFlags = gc->polygon.shader.modeFlags;\
  1032. \
  1033. ASSERTOPENGL((cfb->buf.flags &\
  1034. (DIB_FORMAT | NO_CLIP)) == (DIB_FORMAT | NO_CLIP),\
  1035. "FAST_AA_LINE on clipping surface\n");\
  1036. \
  1037. fraction = gc->line.options.fraction;\
  1038. dfraction = gc->line.options.dfraction;\
  1039. \
  1040. xBig = gc->line.options.xBig;\
  1041. yBig = gc->line.options.yBig;\
  1042. xLittle = gc->line.options.xLittle;\
  1043. yLittle = gc->line.options.yLittle;\
  1044. \
  1045. frag.x = gc->line.options.xStart;\
  1046. frag.y = gc->line.options.yStart;\
  1047. \
  1048. bytesPerPixel = GENACCEL(gc).xMultiplier;\
  1049. \
  1050. if (gc->line.options.axis == __GL_Y_MAJOR) {\
  1051. pixAdjStep = bytesPerPixel;\
  1052. zAdjStep = 1;\
  1053. fragXinc = 1;\
  1054. fragYinc = 0;\
  1055. } else {\
  1056. pixAdjStep = cfb->buf.outerWidth;\
  1057. zAdjStep = gc->depthBuffer.buf.outerWidth;\
  1058. fragXinc = 0;\
  1059. fragYinc = 1;\
  1060. }\
  1061. \
  1062. pPix = (BYTE *)((ULONG_PTR)cfb->buf.base +\
  1063. (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth +\
  1064. (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel);\
  1065. \
  1066. if (modeFlags & __GL_SHADE_DEPTH_TEST) {\
  1067. zAccum = gc->polygon.shader.frag.z;\
  1068. \
  1069. if( gc->modes.depthBits == 32 ) {\
  1070. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),\
  1071. frag.x, frag.y);\
  1072. \
  1073. zAdjStep *= 2;\
  1074. } else {\
  1075. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer,\
  1076. (__GLz16Value*),\
  1077. frag.x, frag.y);\
  1078. }\
  1079. \
  1080. }\
  1081. \
  1082. rAccum = CASTFIX(gc->polygon.shader.frag.color.r);\
  1083. gAccum = CASTFIX(gc->polygon.shader.frag.color.g);\
  1084. bAccum = CASTFIX(gc->polygon.shader.frag.color.b);\
  1085. aAccum = CASTFIX(gc->polygon.shader.frag.color.a);\
  1086. \
  1087. w = gc->line.options.numPixels;\
  1088. for (;;)\
  1089. {\
  1090. CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);\
  1091. \
  1092. invCoverage = ((fraction << 1) & 0xff000000) >> 16;\
  1093. coverage = 0xff00 - invCoverage;\
  1094. \
  1095. if (modeFlags & __GL_SHADE_DEPTH_TEST) {\
  1096. if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ ))\
  1097. goto noWrite1;\
  1098. }\
  1099. \
  1100. BLEND_PIXEL(pPix, coverage, frag.x, frag.y);\
  1101. noWrite1:\
  1102. \
  1103. fragX2 = frag.x + fragXinc;\
  1104. fragY2 = frag.y + fragYinc;\
  1105. if ((fragX2 >= clipX1) || (fragY2 >= clipY1)) {\
  1106. goto noWrite2;\
  1107. }\
  1108. \
  1109. pZ2 = pZ+zAdjStep;\
  1110. if (modeFlags & __GL_SHADE_DEPTH_TEST) {\
  1111. if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ2 ))\
  1112. goto noWrite2;\
  1113. }\
  1114. \
  1115. pPix2 = pPix + pixAdjStep;\
  1116. BLEND_PIXEL(pPix2, invCoverage, fragX2, fragY2);\
  1117. noWrite2:\
  1118. \
  1119. if (--w <= 0)\
  1120. return GL_TRUE;\
  1121. \
  1122. fraction += dfraction;\
  1123. if (fraction < 0) {\
  1124. fraction &= ~0x80000000;\
  1125. frag.x += xBig;\
  1126. frag.y += yBig;\
  1127. pPix += gc->polygon.shader.sbufBig;\
  1128. pZ += gc->polygon.shader.zbufBig;\
  1129. } else {\
  1130. frag.x += xLittle;\
  1131. frag.y += yLittle;\
  1132. pPix += gc->polygon.shader.sbufLittle;\
  1133. pZ += gc->polygon.shader.zbufLittle;\
  1134. }\
  1135. \
  1136. if (modeFlags & __GL_SHADE_SMOOTH) {\
  1137. rAccum += CASTFIX(gc->polygon.shader.drdx);\
  1138. gAccum += CASTFIX(gc->polygon.shader.dgdx);\
  1139. bAccum += CASTFIX(gc->polygon.shader.dbdx);\
  1140. aAccum += CASTFIX(gc->polygon.shader.dadx);\
  1141. }\
  1142. \
  1143. if (modeFlags & __GL_SHADE_DEPTH_ITER) {\
  1144. zAccum += gc->polygon.shader.dzdx;\
  1145. }\
  1146. }\
  1147. \
  1148. return GL_TRUE;\
  1149. }
  1150. /************************************************************************/
  1151. #undef BPP
  1152. #undef RSHIFT
  1153. #undef GSHIFT
  1154. #undef BSHIFT
  1155. #undef RBITS
  1156. #undef GBITS
  1157. #undef BBITS
  1158. #undef RMASK
  1159. #undef GMASK
  1160. #undef BMASK
  1161. #undef READ_PIX
  1162. #undef WRITE_PIX
  1163. #define RSHIFT 0
  1164. #define GSHIFT 3
  1165. #define BSHIFT 6
  1166. #define RBITS 3
  1167. #define GBITS 3
  1168. #define BBITS 2
  1169. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1170. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1171. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1172. #define BPP 8
  1173. #define READ_PIX(pPix) \
  1174. ((__GLGENcontext *)gc)->pajInvTranslateVector[*((BYTE *)(pPix))]
  1175. #define WRITE_PIX(pPix) \
  1176. pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b]
  1177. GLboolean FASTCALL __fastGenAntiAliasLine332(__GLcontext *gc)
  1178. FAST_AA_LINE
  1179. #undef BPP
  1180. #undef RSHIFT
  1181. #undef GSHIFT
  1182. #undef BSHIFT
  1183. #undef RBITS
  1184. #undef GBITS
  1185. #undef BBITS
  1186. #undef RMASK
  1187. #undef GMASK
  1188. #undef BMASK
  1189. #undef READ_PIX
  1190. #undef WRITE_PIX
  1191. #define RSHIFT 10
  1192. #define GSHIFT 5
  1193. #define BSHIFT 0
  1194. #define RBITS 5
  1195. #define GBITS 5
  1196. #define BBITS 5
  1197. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1198. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1199. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1200. #define BPP 16
  1201. #define READ_PIX(pPix) \
  1202. *((USHORT *)(pPix))
  1203. #define WRITE_PIX(pPix) \
  1204. *((USHORT *)pPix) = (USHORT)(r | g | b)
  1205. GLboolean FASTCALL __fastGenAntiAliasLine555(__GLcontext *gc)
  1206. FAST_AA_LINE
  1207. #undef BPP
  1208. #undef RSHIFT
  1209. #undef GSHIFT
  1210. #undef BSHIFT
  1211. #undef RBITS
  1212. #undef GBITS
  1213. #undef BBITS
  1214. #undef RMASK
  1215. #undef GMASK
  1216. #undef BMASK
  1217. #undef READ_PIX
  1218. #undef WRITE_PIX
  1219. #define RSHIFT 11
  1220. #define GSHIFT 5
  1221. #define BSHIFT 0
  1222. #define RBITS 5
  1223. #define GBITS 6
  1224. #define BBITS 5
  1225. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1226. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1227. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1228. #define BPP 16
  1229. #define READ_PIX(pPix) \
  1230. *((USHORT *)(pPix))
  1231. #define WRITE_PIX(pPix) \
  1232. *((USHORT *)pPix) = (USHORT)(r | g | b)
  1233. GLboolean FASTCALL __fastGenAntiAliasLine565(__GLcontext *gc)
  1234. FAST_AA_LINE
  1235. GLboolean FASTCALL __fastGenAntiAliasLine(__GLcontext *gc)
  1236. {
  1237. GLint xLittle, xBig, yLittle, yBig;
  1238. GLint fragX2, fragY2;
  1239. BYTE *pPix;
  1240. BYTE *pPix2;
  1241. USHORT *pZ;
  1242. USHORT *pZ2;
  1243. __GLfragment frag;
  1244. __GLcolorBuffer *cfb = gc->drawBuffer;
  1245. LONG rAccum, gAccum, bAccum, aAccum;
  1246. ULONG rMask, gMask, bMask;
  1247. ULONG rShift, gShift, bShift;
  1248. ULONG rBits, gBits, bBits;
  1249. LONG bytesPerPixel;
  1250. LONG pixAdjStep;
  1251. ULONG zAdjStep;
  1252. ULONG coverage, invCoverage;
  1253. LONG fragXinc;
  1254. LONG fragYinc;
  1255. GLint cfbX, cfbY;
  1256. int copyPix;
  1257. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  1258. __GLzValue zAccum;
  1259. GLint clipX1 = gc->transform.clipX1;
  1260. GLint clipY1 = gc->transform.clipY1;
  1261. GLint fraction, dfraction;
  1262. GLint w;
  1263. GLuint modeFlags = gc->polygon.shader.modeFlags;
  1264. w = gc->line.options.numPixels;
  1265. fraction = gc->line.options.fraction;
  1266. dfraction = gc->line.options.dfraction;
  1267. xBig = gc->line.options.xBig;
  1268. yBig = gc->line.options.yBig;
  1269. xLittle = gc->line.options.xLittle;
  1270. yLittle = gc->line.options.yLittle;
  1271. frag.x = gc->line.options.xStart;
  1272. frag.y = gc->line.options.yStart;
  1273. bytesPerPixel = GENACCEL(gc).xMultiplier;
  1274. if (gc->line.options.axis == __GL_Y_MAJOR) {
  1275. pixAdjStep = bytesPerPixel;
  1276. zAdjStep = 1;
  1277. fragXinc = 1;
  1278. fragYinc = 0;
  1279. // For Y-major non-DIB lines we can copy both affected pixels
  1280. // at once since they are adjacent in memory
  1281. copyPix = 2;
  1282. } else {
  1283. if ((cfb->buf.flags & DIB_FORMAT) != 0)
  1284. {
  1285. pixAdjStep = cfb->buf.outerWidth;
  1286. }
  1287. else
  1288. {
  1289. pixAdjStep = 0;
  1290. }
  1291. zAdjStep = gc->depthBuffer.buf.outerWidth;
  1292. fragXinc = 0;
  1293. fragYinc = 1;
  1294. copyPix = 1;
  1295. }
  1296. if ((cfb->buf.flags & DIB_FORMAT) != 0)
  1297. {
  1298. pPix = (BYTE *)((ULONG_PTR)cfb->buf.base +
  1299. (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth +
  1300. (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel);
  1301. }
  1302. else
  1303. {
  1304. pPix = gengc->ColorsBits;
  1305. }
  1306. if (modeFlags & __GL_SHADE_DEPTH_TEST) {
  1307. zAccum = gc->polygon.shader.frag.z;
  1308. if( gc->modes.depthBits == 32 ) {
  1309. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),
  1310. frag.x, frag.y);
  1311. // Adjust for pZ being a USHORT * but traversing a 32-bit
  1312. // depth buffer
  1313. zAdjStep *= 2;
  1314. } else {
  1315. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer,
  1316. (__GLz16Value*),
  1317. frag.x, frag.y);
  1318. }
  1319. }
  1320. rShift = cfb->redShift;
  1321. gShift = cfb->greenShift;
  1322. bShift = cfb->blueShift;
  1323. rMask = gc->modes.redMask;
  1324. gMask = gc->modes.greenMask;
  1325. bMask = gc->modes.blueMask;
  1326. rBits = gc->modes.redBits;
  1327. gBits = gc->modes.greenBits;
  1328. bBits = gc->modes.blueBits;
  1329. rAccum = CASTFIX(gc->polygon.shader.frag.color.r);
  1330. gAccum = CASTFIX(gc->polygon.shader.frag.color.g);
  1331. bAccum = CASTFIX(gc->polygon.shader.frag.color.b);
  1332. aAccum = CASTFIX(gc->polygon.shader.frag.color.a);
  1333. for (;;)
  1334. {
  1335. CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);
  1336. invCoverage = ((fraction << 1) & 0xff000000) >> 16;
  1337. coverage = 0xff00 - invCoverage;
  1338. if ((cfb->buf.flags & DIB_FORMAT) == 0)
  1339. {
  1340. cfbX = __GL_UNBIAS_X(gc, frag.x)+cfb->buf.xOrigin;
  1341. cfbY = __GL_UNBIAS_Y(gc, frag.y)+cfb->buf.yOrigin;
  1342. gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, copyPix, FALSE);
  1343. }
  1344. if (modeFlags & __GL_SHADE_DEPTH_TEST) {
  1345. if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ ))
  1346. goto noWrite1;
  1347. }
  1348. if ((cfb->buf.flags & (NO_CLIP | DIB_FORMAT)) == DIB_FORMAT)
  1349. {
  1350. cfbX = __GL_UNBIAS_X(gc, frag.x)+cfb->buf.xOrigin;
  1351. cfbY = __GL_UNBIAS_Y(gc, frag.y)+cfb->buf.yOrigin;
  1352. if (!wglPixelVisible(cfbX, cfbY))
  1353. {
  1354. goto noWrite1;
  1355. }
  1356. }
  1357. WRITE_PIXEL_GEN(pPix, coverage, frag.x, frag.y);
  1358. if ((cfb->buf.flags & DIB_FORMAT) == 0 && copyPix == 1)
  1359. {
  1360. gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, copyPix, TRUE);
  1361. }
  1362. noWrite1:
  1363. fragX2 = frag.x + fragXinc;
  1364. fragY2 = frag.y + fragYinc;
  1365. if ((fragX2 >= clipX1) || (fragY2 >= clipY1)) {
  1366. goto noWrite2;
  1367. }
  1368. pZ2 = pZ+zAdjStep;
  1369. if (modeFlags & __GL_SHADE_DEPTH_TEST) {
  1370. if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ2 ))
  1371. goto noWrite2;
  1372. }
  1373. if ((cfb->buf.flags & (NO_CLIP | DIB_FORMAT)) == DIB_FORMAT)
  1374. {
  1375. cfbX = __GL_UNBIAS_X(gc, fragX2)+cfb->buf.xOrigin;
  1376. cfbY = __GL_UNBIAS_Y(gc, fragY2)+cfb->buf.yOrigin;
  1377. if (!wglPixelVisible(cfbX, cfbY))
  1378. {
  1379. goto noWrite2;
  1380. }
  1381. }
  1382. pPix2 = pPix + pixAdjStep;
  1383. if ((cfb->buf.flags & DIB_FORMAT) == 0 && copyPix == 1)
  1384. {
  1385. cfbX += fragXinc;
  1386. cfbY += fragYinc;
  1387. gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, copyPix, FALSE);
  1388. }
  1389. WRITE_PIXEL_GEN(pPix2, invCoverage, fragX2, fragY2);
  1390. noWrite2:
  1391. if ((cfb->buf.flags & DIB_FORMAT) == 0)
  1392. {
  1393. gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, copyPix, TRUE);
  1394. }
  1395. if (--w <= 0)
  1396. return GL_TRUE;
  1397. fraction += dfraction;
  1398. if (fraction < 0) {
  1399. fraction &= ~0x80000000;
  1400. frag.x += xBig;
  1401. frag.y += yBig;
  1402. pPix += gc->polygon.shader.sbufBig;
  1403. pZ += gc->polygon.shader.zbufBig;
  1404. } else {
  1405. frag.x += xLittle;
  1406. frag.y += yLittle;
  1407. pPix += gc->polygon.shader.sbufLittle;
  1408. pZ += gc->polygon.shader.zbufLittle;
  1409. }
  1410. if (modeFlags & __GL_SHADE_SMOOTH) {
  1411. rAccum += CASTFIX(gc->polygon.shader.drdx);
  1412. gAccum += CASTFIX(gc->polygon.shader.dgdx);
  1413. bAccum += CASTFIX(gc->polygon.shader.dbdx);
  1414. aAccum += CASTFIX(gc->polygon.shader.dadx);
  1415. }
  1416. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  1417. zAccum += gc->polygon.shader.dzdx;
  1418. }
  1419. }
  1420. return GL_TRUE;
  1421. }
  1422. /************************************************************************/
  1423. #define FAST_A_LINE_BLEND \
  1424. {\
  1425. GLint xLittle, xBig, yLittle, yBig;\
  1426. BYTE *pPix;\
  1427. USHORT *pZ;\
  1428. __GLfragment frag;\
  1429. __GLcolorBuffer *cfb = gc->drawBuffer;\
  1430. LONG rAccum, gAccum, bAccum, aAccum;\
  1431. LONG bytesPerPixel;\
  1432. __GLzValue zAccum;\
  1433. GLint fraction, dfraction;\
  1434. GLint w;\
  1435. GLuint modeFlags = gc->polygon.shader.modeFlags;\
  1436. ULONG coverage = 0xff00;\
  1437. \
  1438. ASSERTOPENGL((cfb->buf.flags &\
  1439. (DIB_FORMAT | NO_CLIP)) == (DIB_FORMAT | NO_CLIP),\
  1440. "FAST_A_LINE_BLEND on clipping surface\n");\
  1441. \
  1442. fraction = gc->line.options.fraction;\
  1443. dfraction = gc->line.options.dfraction;\
  1444. \
  1445. xBig = gc->line.options.xBig;\
  1446. yBig = gc->line.options.yBig;\
  1447. xLittle = gc->line.options.xLittle;\
  1448. yLittle = gc->line.options.yLittle;\
  1449. \
  1450. frag.x = gc->line.options.xStart;\
  1451. frag.y = gc->line.options.yStart;\
  1452. \
  1453. bytesPerPixel = GENACCEL(gc).xMultiplier;\
  1454. \
  1455. pPix = (BYTE *)((ULONG_PTR)cfb->buf.base +\
  1456. (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth +\
  1457. (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel);\
  1458. \
  1459. if (modeFlags & __GL_SHADE_DEPTH_TEST) {\
  1460. zAccum = gc->polygon.shader.frag.z;\
  1461. \
  1462. if( gc->modes.depthBits == 32 ) {\
  1463. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),\
  1464. frag.x, frag.y);\
  1465. \
  1466. } else {\
  1467. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer,\
  1468. (__GLz16Value*),\
  1469. frag.x, frag.y);\
  1470. }\
  1471. \
  1472. }\
  1473. \
  1474. rAccum = CASTFIX(gc->polygon.shader.frag.color.r);\
  1475. gAccum = CASTFIX(gc->polygon.shader.frag.color.g);\
  1476. bAccum = CASTFIX(gc->polygon.shader.frag.color.b);\
  1477. aAccum = CASTFIX(gc->polygon.shader.frag.color.a);\
  1478. \
  1479. w = gc->line.options.numPixels;\
  1480. for (;;)\
  1481. {\
  1482. CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);\
  1483. \
  1484. if (modeFlags & __GL_SHADE_DEPTH_TEST) {\
  1485. if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ))\
  1486. goto NoWrite;\
  1487. }\
  1488. \
  1489. BLEND_PIXEL(pPix, coverage, frag.x, frag.y);\
  1490. NoWrite:\
  1491. \
  1492. if (--w <= 0)\
  1493. return GL_TRUE;\
  1494. \
  1495. fraction += dfraction;\
  1496. if (fraction < 0) {\
  1497. fraction &= ~0x80000000;\
  1498. frag.x += xBig;\
  1499. frag.y += yBig;\
  1500. pPix += gc->polygon.shader.sbufBig;\
  1501. pZ += gc->polygon.shader.zbufBig;\
  1502. } else {\
  1503. frag.x += xLittle;\
  1504. frag.y += yLittle;\
  1505. pPix += gc->polygon.shader.sbufLittle;\
  1506. pZ += gc->polygon.shader.zbufLittle;\
  1507. }\
  1508. \
  1509. if (modeFlags & __GL_SHADE_SMOOTH) {\
  1510. rAccum += CASTFIX(gc->polygon.shader.drdx);\
  1511. gAccum += CASTFIX(gc->polygon.shader.dgdx);\
  1512. bAccum += CASTFIX(gc->polygon.shader.dbdx);\
  1513. aAccum += CASTFIX(gc->polygon.shader.dadx);\
  1514. }\
  1515. \
  1516. if (modeFlags & __GL_SHADE_DEPTH_ITER) {\
  1517. zAccum += gc->polygon.shader.dzdx;\
  1518. }\
  1519. }\
  1520. \
  1521. return GL_TRUE;\
  1522. }
  1523. #undef BPP
  1524. #undef RSHIFT
  1525. #undef GSHIFT
  1526. #undef BSHIFT
  1527. #undef RBITS
  1528. #undef GBITS
  1529. #undef BBITS
  1530. #undef RMASK
  1531. #undef GMASK
  1532. #undef BMASK
  1533. #undef READ_PIX
  1534. #undef WRITE_PIX
  1535. #define RSHIFT 0
  1536. #define GSHIFT 3
  1537. #define BSHIFT 6
  1538. #define RBITS 3
  1539. #define GBITS 3
  1540. #define BBITS 2
  1541. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1542. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1543. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1544. #define BPP 8
  1545. #define READ_PIX(pPix) \
  1546. ((__GLGENcontext *)gc)->pajInvTranslateVector[*((BYTE *)(pPix))]
  1547. #define WRITE_PIX(pPix) \
  1548. pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b]
  1549. GLboolean FASTCALL __fastGenBlendAliasLine332(__GLcontext *gc)
  1550. FAST_A_LINE_BLEND
  1551. #undef BPP
  1552. #undef RSHIFT
  1553. #undef GSHIFT
  1554. #undef BSHIFT
  1555. #undef RBITS
  1556. #undef GBITS
  1557. #undef BBITS
  1558. #undef RMASK
  1559. #undef GMASK
  1560. #undef BMASK
  1561. #undef READ_PIX
  1562. #undef WRITE_PIX
  1563. #define RSHIFT 10
  1564. #define GSHIFT 5
  1565. #define BSHIFT 0
  1566. #define RBITS 5
  1567. #define GBITS 5
  1568. #define BBITS 5
  1569. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1570. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1571. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1572. #define BPP 16
  1573. #define READ_PIX(pPix) \
  1574. *((USHORT *)(pPix))
  1575. #define WRITE_PIX(pPix) \
  1576. *((USHORT *)pPix) = (USHORT)(r | g | b)
  1577. GLboolean FASTCALL __fastGenBlendAliasLine555(__GLcontext *gc)
  1578. FAST_A_LINE_BLEND
  1579. #undef BPP
  1580. #undef RSHIFT
  1581. #undef GSHIFT
  1582. #undef BSHIFT
  1583. #undef RBITS
  1584. #undef GBITS
  1585. #undef BBITS
  1586. #undef RMASK
  1587. #undef GMASK
  1588. #undef BMASK
  1589. #undef READ_PIX
  1590. #undef WRITE_PIX
  1591. #define RSHIFT 11
  1592. #define GSHIFT 5
  1593. #define BSHIFT 0
  1594. #define RBITS 5
  1595. #define GBITS 6
  1596. #define BBITS 5
  1597. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1598. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1599. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1600. #define BPP 16
  1601. #define READ_PIX(pPix) \
  1602. *((USHORT *)(pPix))
  1603. #define WRITE_PIX(pPix) \
  1604. *((USHORT *)pPix) = (USHORT)(r | g | b)
  1605. GLboolean FASTCALL __fastGenBlendAliasLine565(__GLcontext *gc)
  1606. FAST_A_LINE_BLEND
  1607. /************************************************************************/
  1608. #define FAST_A_LINE_NO_BLEND \
  1609. {\
  1610. GLint xLittle, xBig, yLittle, yBig;\
  1611. BYTE *pPix;\
  1612. USHORT *pZ;\
  1613. __GLfragment frag;\
  1614. __GLcolorBuffer *cfb = gc->drawBuffer;\
  1615. LONG rAccum, gAccum, bAccum;\
  1616. LONG bytesPerPixel;\
  1617. __GLzValue zAccum;\
  1618. GLint fraction, dfraction;\
  1619. GLint w;\
  1620. GLuint modeFlags = gc->polygon.shader.modeFlags;\
  1621. \
  1622. ASSERTOPENGL((cfb->buf.flags &\
  1623. (DIB_FORMAT | NO_CLIP)) == (DIB_FORMAT | NO_CLIP),\
  1624. "FAST_A_LINE_NO_BLEND on clipping surface\n");\
  1625. \
  1626. fraction = gc->line.options.fraction;\
  1627. dfraction = gc->line.options.dfraction;\
  1628. \
  1629. xBig = gc->line.options.xBig;\
  1630. yBig = gc->line.options.yBig;\
  1631. xLittle = gc->line.options.xLittle;\
  1632. yLittle = gc->line.options.yLittle;\
  1633. \
  1634. frag.x = gc->line.options.xStart;\
  1635. frag.y = gc->line.options.yStart;\
  1636. \
  1637. bytesPerPixel = GENACCEL(gc).xMultiplier;\
  1638. \
  1639. pPix = (BYTE *)((ULONG_PTR)cfb->buf.base +\
  1640. (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth +\
  1641. (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel);\
  1642. \
  1643. if (modeFlags & __GL_SHADE_DEPTH_TEST) {\
  1644. zAccum = gc->polygon.shader.frag.z;\
  1645. \
  1646. if( gc->modes.depthBits == 32 ) {\
  1647. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),\
  1648. frag.x, frag.y);\
  1649. \
  1650. } else {\
  1651. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer,\
  1652. (__GLz16Value*),\
  1653. frag.x, frag.y);\
  1654. }\
  1655. \
  1656. }\
  1657. \
  1658. rAccum = CASTFIX(gc->polygon.shader.frag.color.r);\
  1659. gAccum = CASTFIX(gc->polygon.shader.frag.color.g);\
  1660. bAccum = CASTFIX(gc->polygon.shader.frag.color.b);\
  1661. \
  1662. w = gc->line.options.numPixels;\
  1663. for (;;)\
  1664. {\
  1665. CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);\
  1666. \
  1667. if (modeFlags & __GL_SHADE_DEPTH_TEST) {\
  1668. if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ))\
  1669. goto NoWrite;\
  1670. }\
  1671. \
  1672. DITHER_PIXEL(pPix, frag.x, frag.y);\
  1673. NoWrite:\
  1674. \
  1675. if (--w <= 0)\
  1676. return GL_TRUE;\
  1677. \
  1678. fraction += dfraction;\
  1679. if (fraction < 0) {\
  1680. fraction &= ~0x80000000;\
  1681. frag.x += xBig;\
  1682. frag.y += yBig;\
  1683. pPix += gc->polygon.shader.sbufBig;\
  1684. pZ += gc->polygon.shader.zbufBig;\
  1685. } else {\
  1686. frag.x += xLittle;\
  1687. frag.y += yLittle;\
  1688. pPix += gc->polygon.shader.sbufLittle;\
  1689. pZ += gc->polygon.shader.zbufLittle;\
  1690. }\
  1691. \
  1692. if (modeFlags & __GL_SHADE_SMOOTH) {\
  1693. rAccum += CASTFIX(gc->polygon.shader.drdx);\
  1694. gAccum += CASTFIX(gc->polygon.shader.dgdx);\
  1695. bAccum += CASTFIX(gc->polygon.shader.dbdx);\
  1696. }\
  1697. \
  1698. if (modeFlags & __GL_SHADE_DEPTH_ITER) {\
  1699. zAccum += gc->polygon.shader.dzdx;\
  1700. }\
  1701. }\
  1702. \
  1703. return GL_TRUE;\
  1704. }
  1705. #undef BPP
  1706. #undef RSHIFT
  1707. #undef GSHIFT
  1708. #undef BSHIFT
  1709. #undef RBITS
  1710. #undef GBITS
  1711. #undef BBITS
  1712. #undef RMASK
  1713. #undef GMASK
  1714. #undef BMASK
  1715. #undef READ_PIX
  1716. #undef WRITE_PIX
  1717. #define RSHIFT 0
  1718. #define GSHIFT 3
  1719. #define BSHIFT 6
  1720. #define RBITS 3
  1721. #define GBITS 3
  1722. #define BBITS 2
  1723. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1724. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1725. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1726. #define BPP 8
  1727. #define WRITE_PIX(pPix) \
  1728. pPix[0] = ((__GLGENcontext *)gc)->xlatPalette[r | g | b]
  1729. GLboolean FASTCALL __fastGenNoBlendAliasLine332(__GLcontext *gc)
  1730. FAST_A_LINE_NO_BLEND
  1731. #undef BPP
  1732. #undef RSHIFT
  1733. #undef GSHIFT
  1734. #undef BSHIFT
  1735. #undef RBITS
  1736. #undef GBITS
  1737. #undef BBITS
  1738. #undef RMASK
  1739. #undef GMASK
  1740. #undef BMASK
  1741. #undef READ_PIX
  1742. #undef WRITE_PIX
  1743. #define RSHIFT 10
  1744. #define GSHIFT 5
  1745. #define BSHIFT 0
  1746. #define RBITS 5
  1747. #define GBITS 5
  1748. #define BBITS 5
  1749. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1750. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1751. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1752. #define BPP 16
  1753. #define WRITE_PIX(pPix) \
  1754. *((USHORT *)pPix) = (USHORT)(r | g | b)
  1755. GLboolean FASTCALL __fastGenNoBlendAliasLine555(__GLcontext *gc)
  1756. FAST_A_LINE_NO_BLEND
  1757. #undef BPP
  1758. #undef RSHIFT
  1759. #undef GSHIFT
  1760. #undef BSHIFT
  1761. #undef RBITS
  1762. #undef GBITS
  1763. #undef BBITS
  1764. #undef RMASK
  1765. #undef GMASK
  1766. #undef BMASK
  1767. #undef READ_PIX
  1768. #undef WRITE_PIX
  1769. #define RSHIFT 11
  1770. #define GSHIFT 5
  1771. #define BSHIFT 0
  1772. #define RBITS 5
  1773. #define GBITS 6
  1774. #define BBITS 5
  1775. #define RMASK (((1 << RBITS) - 1) << RSHIFT)
  1776. #define GMASK (((1 << GBITS) - 1) << GSHIFT)
  1777. #define BMASK (((1 << BBITS) - 1) << BSHIFT)
  1778. #define BPP 16
  1779. #define WRITE_PIX(pPix) \
  1780. *((USHORT *)pPix) = (USHORT)(r | g | b)
  1781. GLboolean FASTCALL __fastGenNoBlendAliasLine565(__GLcontext *gc)
  1782. FAST_A_LINE_NO_BLEND
  1783. // WRITE_PIXEL_GEN handles both blending and no blending so this
  1784. // generic routine works for both of those cases
  1785. GLboolean FASTCALL __fastGenAliasLine(__GLcontext *gc)
  1786. {
  1787. GLint xLittle, xBig, yLittle, yBig;
  1788. BYTE *pPix;
  1789. USHORT *pZ;
  1790. __GLfragment frag;
  1791. __GLcolorBuffer *cfb = gc->drawBuffer;
  1792. LONG rAccum, gAccum, bAccum, aAccum;
  1793. ULONG rMask, gMask, bMask;
  1794. ULONG rShift, gShift, bShift;
  1795. ULONG rBits, gBits, bBits;
  1796. LONG bytesPerPixel;
  1797. GLint cfbX, cfbY;
  1798. __GLGENcontext *gengc = (__GLGENcontext *)gc;
  1799. __GLzValue zAccum;
  1800. GLint fraction, dfraction;
  1801. GLint w;
  1802. GLuint modeFlags = gc->polygon.shader.modeFlags;
  1803. // Only present for placeholder in WRITE_PIXEL_GEN macro
  1804. ULONG coverage = 0xff00;
  1805. w = gc->line.options.numPixels;
  1806. fraction = gc->line.options.fraction;
  1807. dfraction = gc->line.options.dfraction;
  1808. xBig = gc->line.options.xBig;
  1809. yBig = gc->line.options.yBig;
  1810. xLittle = gc->line.options.xLittle;
  1811. yLittle = gc->line.options.yLittle;
  1812. frag.x = gc->line.options.xStart;
  1813. frag.y = gc->line.options.yStart;
  1814. bytesPerPixel = GENACCEL(gc).xMultiplier;
  1815. if ((cfb->buf.flags & DIB_FORMAT) != 0)
  1816. {
  1817. pPix = (BYTE *)((ULONG_PTR)cfb->buf.base +
  1818. (__GL_UNBIAS_Y(gc, frag.y) + cfb->buf.yOrigin) * cfb->buf.outerWidth +
  1819. (__GL_UNBIAS_X(gc, frag.x) + cfb->buf.xOrigin) * bytesPerPixel);
  1820. }
  1821. else
  1822. {
  1823. pPix = gengc->ColorsBits;
  1824. }
  1825. if (modeFlags & __GL_SHADE_DEPTH_TEST) {
  1826. zAccum = gc->polygon.shader.frag.z;
  1827. if( gc->modes.depthBits == 32 ) {
  1828. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer, (__GLzValue*),
  1829. frag.x, frag.y);
  1830. } else {
  1831. pZ = (USHORT *)__GL_DEPTH_ADDR(&gc->depthBuffer,
  1832. (__GLz16Value*),
  1833. frag.x, frag.y);
  1834. }
  1835. }
  1836. rShift = cfb->redShift;
  1837. gShift = cfb->greenShift;
  1838. bShift = cfb->blueShift;
  1839. rMask = gc->modes.redMask;
  1840. gMask = gc->modes.greenMask;
  1841. bMask = gc->modes.blueMask;
  1842. rBits = gc->modes.redBits;
  1843. gBits = gc->modes.greenBits;
  1844. bBits = gc->modes.blueBits;
  1845. rAccum = CASTFIX(gc->polygon.shader.frag.color.r);
  1846. gAccum = CASTFIX(gc->polygon.shader.frag.color.g);
  1847. bAccum = CASTFIX(gc->polygon.shader.frag.color.b);
  1848. aAccum = CASTFIX(gc->polygon.shader.frag.color.a);
  1849. for (;;)
  1850. {
  1851. CHECK_PIXEL(gc, cfb, w, frag.x, frag.y);
  1852. if (modeFlags & __GL_SHADE_DEPTH_TEST) {
  1853. if (!(*GENACCEL(gc).__fastGenZStore)(zAccum, (__GLzValue *)pZ))
  1854. goto NoWrite;
  1855. }
  1856. if ((cfb->buf.flags & (NO_CLIP | DIB_FORMAT)) == DIB_FORMAT)
  1857. {
  1858. cfbX = __GL_UNBIAS_X(gc, frag.x)+cfb->buf.xOrigin;
  1859. cfbY = __GL_UNBIAS_Y(gc, frag.y)+cfb->buf.yOrigin;
  1860. if (!wglPixelVisible(cfbX, cfbY))
  1861. {
  1862. goto NoWrite;
  1863. }
  1864. }
  1865. if ((cfb->buf.flags & DIB_FORMAT) == 0)
  1866. {
  1867. cfbX = __GL_UNBIAS_X(gc, frag.x)+cfb->buf.xOrigin;
  1868. cfbY = __GL_UNBIAS_Y(gc, frag.y)+cfb->buf.yOrigin;
  1869. gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, 1, FALSE);
  1870. }
  1871. WRITE_PIXEL_GEN(pPix, coverage, frag.x, frag.y);
  1872. if ((cfb->buf.flags & DIB_FORMAT) == 0)
  1873. {
  1874. gengc->pfnCopyPixels(gengc, cfb, cfbX, cfbY, 1, TRUE);
  1875. }
  1876. NoWrite:
  1877. if (--w <= 0)
  1878. return GL_TRUE;
  1879. fraction += dfraction;
  1880. if (fraction < 0) {
  1881. fraction &= ~0x80000000;
  1882. frag.x += xBig;
  1883. frag.y += yBig;
  1884. pPix += gc->polygon.shader.sbufBig;
  1885. pZ += gc->polygon.shader.zbufBig;
  1886. } else {
  1887. frag.x += xLittle;
  1888. frag.y += yLittle;
  1889. pPix += gc->polygon.shader.sbufLittle;
  1890. pZ += gc->polygon.shader.zbufLittle;
  1891. }
  1892. if (modeFlags & __GL_SHADE_SMOOTH) {
  1893. rAccum += CASTFIX(gc->polygon.shader.drdx);
  1894. gAccum += CASTFIX(gc->polygon.shader.dgdx);
  1895. bAccum += CASTFIX(gc->polygon.shader.dbdx);
  1896. aAccum += CASTFIX(gc->polygon.shader.dadx);
  1897. }
  1898. if (modeFlags & __GL_SHADE_DEPTH_ITER) {
  1899. zAccum += gc->polygon.shader.dzdx;
  1900. }
  1901. }
  1902. return GL_TRUE;
  1903. }
  1904. /************************************************************************/
  1905. // Bits 0-1 are for pixel format
  1906. // Bit 2 is for GL_BLEND enable
  1907. // Bit 3 is for GL_LINE_SMOOTH_ENABLE
  1908. fastGenLineProc pfnFastGenLineProcs[] =
  1909. {
  1910. __fastGenAliasLine,
  1911. __fastGenNoBlendAliasLine332,
  1912. __fastGenNoBlendAliasLine555,
  1913. __fastGenNoBlendAliasLine565,
  1914. __fastGenAliasLine,
  1915. __fastGenBlendAliasLine332,
  1916. __fastGenBlendAliasLine555,
  1917. __fastGenBlendAliasLine565,
  1918. __fastGenAntiAliasLine,
  1919. __fastGenAntiAliasLine,
  1920. __fastGenAntiAliasLine,
  1921. __fastGenAntiAliasLine,
  1922. __fastGenAntiAliasLine,
  1923. __fastGenAntiAliasLine332,
  1924. __fastGenAntiAliasLine555,
  1925. __fastGenAntiAliasLine565
  1926. };
  1927. //
  1928. // Assumptions for accelerated lines:
  1929. //
  1930. // no blending, or (SRC, 1-SRC), or (SRC, 1)
  1931. // not both buffers
  1932. // not stippled
  1933. // not stenciled
  1934. // not textured
  1935. // not alpha-tested
  1936. // not masked, zmasked
  1937. // no logicOp
  1938. // not slow fog
  1939. // not color-indexed
  1940. // not wide
  1941. #define __SLOW_LINE_MODE_FLAGS \
  1942. (__GL_SHADE_TEXTURE | __GL_SHADE_LINE_STIPPLE | \
  1943. __GL_SHADE_STENCIL_TEST | __GL_SHADE_LOGICOP | \
  1944. __GL_SHADE_ALPHA_TEST | __GL_SHADE_MASK | \
  1945. __GL_SHADE_SLOW_FOG)
  1946. BOOL FASTCALL __glGenSetupEitherLines(__GLcontext *gc)
  1947. {
  1948. #ifdef _MCD_
  1949. GENMCDSTATE *pMcdState = ((__GLGENcontext *) gc)->pMcdState;
  1950. #endif
  1951. GLuint modeFlags = gc->polygon.shader.modeFlags;
  1952. LONG bytesPerPixel;
  1953. int fmt;
  1954. BOOL bAccelerate =
  1955. (((__GLGENcontext *)gc)->gsurf.pfd.cColorBits >= 8) &&
  1956. (gc->state.raster.drawBuffer != GL_FRONT_AND_BACK) &&
  1957. (gc->state.raster.drawBuffer != GL_NONE) &&
  1958. ( ! ALPHA_WRITE_ENABLED( gc->drawBuffer ) ) &&
  1959. (
  1960. ((gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_TEST) &&
  1961. (gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_ITER) &&
  1962. (gc->state.depth.writeEnable)) ||
  1963. (!(gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_TEST) &&
  1964. !(gc->polygon.shader.modeFlags & __GL_SHADE_DEPTH_ITER))
  1965. ) &&
  1966. (gc->transform.reasonableViewport) &&
  1967. (gc->state.line.aliasedWidth == 1) &&
  1968. (modeFlags & __GL_SHADE_RGB) &&
  1969. #ifdef GL_WIN_phong_shading
  1970. !(modeFlags & __GL_SHADE_PHONG) &&
  1971. #endif //GL_WIN_phong_shading
  1972. #ifdef GL_WIN_specular_fog
  1973. !(modeFlags & __GL_SHADE_SPEC_FOG) &&
  1974. #endif //GL_WIN_specular_fog
  1975. (!(modeFlags & __SLOW_LINE_MODE_FLAGS)) &&
  1976. (!(gc->state.enables.general & __GL_BLEND_ENABLE) ||
  1977. ((gc->state.raster.blendSrc == GL_SRC_ALPHA) &&
  1978. ((gc->state.raster.blendDst == GL_ONE_MINUS_SRC_ALPHA) ||
  1979. (gc->state.raster.blendDst == GL_ONE)))
  1980. );
  1981. #ifdef _MCD_
  1982. bAccelerate &= (!pMcdState || (pMcdState->McdBuffers.mcdDepthBuf.bufFlags & MCDBUF_ENABLED));
  1983. #endif
  1984. // Resort to soft code if we can't handle the line:
  1985. if (!bAccelerate)
  1986. {
  1987. return FALSE;
  1988. }
  1989. else if (gc->state.enables.general & __GL_LINE_SMOOTH_ENABLE)
  1990. {
  1991. if (gc->state.hints.lineSmooth == GL_NICEST)
  1992. {
  1993. return FALSE;
  1994. }
  1995. }
  1996. else if ((modeFlags & __GL_SHADE_CHEAP_FOG) &&
  1997. (modeFlags & __GL_SHADE_SMOOTH_LIGHT) == 0)
  1998. {
  1999. // We only support cheap fog done by the front end, not
  2000. // flat cheap fog done by the render procs
  2001. return FALSE;
  2002. }
  2003. GENACCEL(gc).xMultiplier = bytesPerPixel =
  2004. (((__GLGENcontext *)gc)->gsurf.pfd.cColorBits + 7) >> 3;
  2005. // Set up our local z-buffer procs:
  2006. if (modeFlags & __GL_SHADE_DEPTH_ITER)
  2007. __fastGenPickZStoreProc(gc);
  2008. gc->procs.renderLine = __glGenRenderEitherLine;
  2009. // Assume generic format
  2010. fmt = 0;
  2011. // For deep-color modes, we don't support most-significant-byte
  2012. // formats...
  2013. // For non-MSB deep-color modes, we only support generic rendering
  2014. if (bytesPerPixel > 2)
  2015. {
  2016. if (((gc->drawBuffer->redShift > 16) ||
  2017. (gc->drawBuffer->greenShift > 16) ||
  2018. (gc->drawBuffer->blueShift > 16)))
  2019. {
  2020. return FALSE;
  2021. }
  2022. else
  2023. {
  2024. goto PickProc;
  2025. }
  2026. }
  2027. // Just use generic acceleration if we're not
  2028. // dithering, since these are hardwired into the fastest routines...
  2029. // We also only support unclipped surfaces in the fastest routines
  2030. if (!(modeFlags & __GL_SHADE_DITHER) ||
  2031. (gc->drawBuffer->buf.flags & (DIB_FORMAT | NO_CLIP)) !=
  2032. (DIB_FORMAT | NO_CLIP))
  2033. {
  2034. goto PickProc;
  2035. }
  2036. // Now, check for supported color formats for fastest modes:
  2037. if ((bytesPerPixel == 1) &&
  2038. (gc->drawBuffer->redShift == 0) &&
  2039. (gc->drawBuffer->greenShift == 3) &&
  2040. (gc->drawBuffer->blueShift == 6))
  2041. {
  2042. fmt = 1;
  2043. }
  2044. else if (bytesPerPixel == 2)
  2045. {
  2046. if ((gc->drawBuffer->greenShift == 5) &&
  2047. (gc->drawBuffer->blueShift == 0))
  2048. {
  2049. if (gc->drawBuffer->redShift == 10)
  2050. {
  2051. fmt = 2;
  2052. }
  2053. else if (gc->drawBuffer->redShift == 11)
  2054. {
  2055. fmt = 3;
  2056. }
  2057. }
  2058. }
  2059. PickProc:
  2060. if (gc->state.enables.general & __GL_BLEND_ENABLE)
  2061. {
  2062. fmt += 4;
  2063. }
  2064. if (gc->state.enables.general & __GL_LINE_SMOOTH_ENABLE)
  2065. {
  2066. fmt += 8;
  2067. }
  2068. GENACCEL(gc).__fastGenLineProc = pfnFastGenLineProcs[fmt];
  2069. if (gc->state.line.aliasedWidth != 1)
  2070. {
  2071. GENACCEL(gc).__fastGenInitLineData = __glInitLineData;
  2072. }
  2073. else
  2074. {
  2075. GENACCEL(gc).__fastGenInitLineData = __glInitThinLineData;
  2076. }
  2077. return TRUE;
  2078. }