updates from Daniel Borca
[mesa.git] / src / mesa / drivers / dos / dmesa.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 5.0.1
4 *
5 * Copyright (C) 1999-2003 Brian Paul All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
21 * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 */
24
25 /*
26 * DOS/DJGPP device driver v1.4 for Mesa
27 *
28 * Copyright (c) 2003 - Borca Daniel
29 * Email : dborca@users.sourceforge.net
30 * Web : http://www.geocities.com/dborca
31 */
32
33
34 #include "glheader.h"
35 #include "context.h"
36 #ifndef FX
37 #include "extensions.h"
38 #include "macros.h"
39 #include "matrix.h"
40 #include "mtypes.h"
41 #include "texformat.h"
42 #include "teximage.h"
43 #include "texstore.h"
44 #include "imports.h"
45 #include "array_cache/acache.h"
46 #include "swrast/s_context.h"
47 #include "swrast/s_depth.h"
48 #include "swrast/s_lines.h"
49 #include "swrast/s_triangle.h"
50 #include "swrast/swrast.h"
51 #include "swrast_setup/swrast_setup.h"
52 #include "tnl/tnl.h"
53 #include "tnl/t_context.h"
54 #include "tnl/t_pipeline.h"
55 #ifndef MATROX
56 #include "video.h"
57 #else /* MATROX */
58 #include "mga/mga.h"
59 #endif /* MATROX */
60 #else /* FX */
61 #include "GL/fxmesa.h"
62 #endif /* FX */
63
64 #include "GL/dmesa.h"
65
66
67
68 /*
69 * In C++ terms, this class derives from the GLvisual class.
70 * Add system-specific fields to it.
71 */
72 struct dmesa_visual {
73 GLvisual gl_visual;
74 GLboolean db_flag; /* double buffered? */
75 GLboolean rgb_flag; /* RGB mode? */
76 GLuint depth; /* bits per pixel (1, 8, 24, etc) */
77 #ifdef MATROX
78 int stride_in_pixels;
79 #endif
80 int zbuffer; /* Z=buffer: 0=no, 1=SW, -1=HW */
81 };
82
83 /*
84 * In C++ terms, this class derives from the GLframebuffer class.
85 * Add system-specific fields to it.
86 */
87 struct dmesa_buffer {
88 GLframebuffer gl_buffer; /* The depth, stencil, accum, etc buffers */
89 void *the_window; /* your window handle, etc */
90
91 int xpos, ypos; /* position */
92 int width, height; /* size in pixels */
93 };
94
95 /*
96 * In C++ terms, this class derives from the GLcontext class.
97 * Add system-specific fields to it.
98 */
99 struct dmesa_context {
100 GLcontext gl_ctx; /* the core library context */
101 DMesaVisual visual;
102 DMesaBuffer Buffer;
103 GLuint ClearColor;
104 GLuint ClearIndex;
105 /* etc... */
106 };
107
108
109
110 #ifndef FX
111 /****************************************************************************
112 * Read/Write pixels
113 ***************************************************************************/
114 #define FLIP(y) (dmesa->Buffer->height - (y) - 1)
115 #define FLIP2(y) (_b_ - (y))
116
117
118 #ifndef MATROX
119 #define DSTRIDE dmesa->Buffer->width
120 #else
121 #define DSTRIDE dmesa->visual->stride_in_pixels
122 #define vl_putpixel mga_putpixel
123 #define vl_mixrgba mga_mixrgb
124 #define vl_mixrgb mga_mixrgb
125 #define vl_getrgba mga_getrgba
126 #define vl_setz mga_setz
127 #define vl_getz mga_getz
128 #endif
129
130 /****************************************************************************
131 * RGB[A]
132 ***************************************************************************/
133 static void write_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
134 const GLubyte rgba[][4], const GLubyte mask[])
135 {
136 const DMesaContext dmesa = (DMesaContext)ctx;
137 GLuint i, offset;
138
139 #ifndef MATROX
140 offset = DSTRIDE * FLIP(y) + x;
141 if (mask) {
142 /* draw some pixels */
143 for (i=0; i<n; i++, offset++) {
144 if (mask[i]) {
145 vl_putpixel(offset, vl_mixrgba(rgba[i]));
146 }
147 }
148 } else {
149 /* draw all pixels */
150 for (i=0; i<n; i++, offset++) {
151 vl_putpixel(offset, vl_mixrgba(rgba[i]));
152 }
153 }
154 #else /* MATROX */
155 y = FLIP(y);
156 if (mask) {
157 /* draw some pixels */
158 offset = 0;
159 for (i = 0; i < n; i++) {
160 if (mask[i]) {
161 ++offset;
162 } else {
163 if (offset != 0) {
164 mga_draw_span_rgb_tx32(x + i - offset, y, offset, (const unsigned long *)(&rgba[i-offset]));
165 offset = 0;
166 }
167 }
168 }
169 if (offset != 0) {
170 mga_draw_span_rgb_tx32(x + n - offset, y, offset, (const unsigned long *)(&rgba[n-offset]));
171 }
172 } else {
173 /* draw all pixels */
174 mga_draw_span_rgb_tx32(x, y, n, (const unsigned long *)rgba);
175 }
176 #endif /* MATROX */
177 }
178
179
180
181 static void write_rgb_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
182 const GLubyte rgb[][3], const GLubyte mask[])
183 {
184 const DMesaContext dmesa = (DMesaContext)ctx;
185 GLuint i, offset;
186
187 offset = DSTRIDE * FLIP(y) + x;
188 if (mask) {
189 /* draw some pixels */
190 for (i=0; i<n; i++, offset++) {
191 if (mask[i]) {
192 vl_putpixel(offset, vl_mixrgb(rgb[i]));
193 }
194 }
195 } else {
196 /* draw all pixels */
197 for (i=0; i<n; i++, offset++) {
198 vl_putpixel(offset, vl_mixrgb(rgb[i]));
199 }
200 }
201 }
202
203
204
205 static void write_mono_rgba_span (const GLcontext *ctx,
206 GLuint n, GLint x, GLint y,
207 const GLchan color[4], const GLubyte mask[])
208 {
209 const DMesaContext dmesa = (DMesaContext)ctx;
210 GLuint i, offset, rgba = vl_mixrgba(color);
211
212 offset = DSTRIDE * FLIP(y) + x;
213 if (mask) {
214 /* draw some pixels */
215 for (i=0; i<n; i++, offset++) {
216 if (mask[i]) {
217 vl_putpixel(offset, rgba);
218 }
219 }
220 } else {
221 /* draw all pixels */
222 for (i=0; i<n; i++, offset++) {
223 vl_putpixel(offset, rgba);
224 }
225 }
226 }
227
228
229
230 static void read_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
231 GLubyte rgba[][4])
232 {
233 const DMesaContext dmesa = (DMesaContext)ctx;
234 GLuint i, offset;
235
236 offset = DSTRIDE * FLIP(y) + x;
237 /* read all pixels */
238 for (i=0; i<n; i++, offset++) {
239 vl_getrgba(offset, rgba[i]);
240 }
241 }
242
243
244
245 static void write_rgba_pixels (const GLcontext *ctx,
246 GLuint n, const GLint x[], const GLint y[],
247 const GLubyte rgba[][4], const GLubyte mask[])
248 {
249 const DMesaContext dmesa = (DMesaContext)ctx;
250 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;
251
252 if (mask) {
253 /* draw some pixels */
254 for (i=0; i<n; i++) {
255 if (mask[i]) {
256 vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i]));
257 }
258 }
259 } else {
260 /* draw all pixels */
261 for (i=0; i<n; i++) {
262 vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i]));
263 }
264 }
265 }
266
267
268
269 static void write_mono_rgba_pixels (const GLcontext *ctx,
270 GLuint n, const GLint x[], const GLint y[],
271 const GLchan color[4], const GLubyte mask[])
272 {
273 const DMesaContext dmesa = (DMesaContext)ctx;
274 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1, rgba = vl_mixrgba(color);
275
276 if (mask) {
277 /* draw some pixels */
278 for (i=0; i<n; i++) {
279 if (mask[i]) {
280 vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba);
281 }
282 }
283 } else {
284 /* draw all pixels */
285 for (i=0; i<n; i++) {
286 vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba);
287 }
288 }
289 }
290
291
292
293 static void read_rgba_pixels (const GLcontext *ctx,
294 GLuint n, const GLint x[], const GLint y[],
295 GLubyte rgba[][4], const GLubyte mask[])
296 {
297 const DMesaContext dmesa = (DMesaContext)ctx;
298 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;
299
300 if (mask) {
301 /* read some pixels */
302 for (i=0; i<n; i++) {
303 if (mask[i]) {
304 vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]);
305 }
306 }
307 } else {
308 /* read all pixels */
309 for (i=0; i<n; i++) {
310 vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]);
311 }
312 }
313 }
314
315
316
317 /****************************************************************************
318 * Index
319 ***************************************************************************/
320 #ifndef MATROX
321 static void write_index_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
322 const GLuint index[], const GLubyte mask[])
323 {
324 const DMesaContext dmesa = (DMesaContext)ctx;
325 GLuint i, offset;
326
327 offset = DSTRIDE * FLIP(y) + x;
328 if (mask) {
329 /* draw some pixels */
330 for (i=0; i<n; i++, offset++) {
331 if (mask[i]) {
332 vl_putpixel(offset, index[i]);
333 }
334 }
335 } else {
336 /* draw all pixels */
337 for (i=0; i<n; i++, offset++) {
338 vl_putpixel(offset, index[i]);
339 }
340 }
341 }
342
343
344
345 static void write_index8_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
346 const GLubyte index[], const GLubyte mask[])
347 {
348 const DMesaContext dmesa = (DMesaContext)ctx;
349 GLuint i, offset;
350
351 offset = DSTRIDE * FLIP(y) + x;
352 if (mask) {
353 /* draw some pixels */
354 for (i=0; i<n; i++, offset++) {
355 if (mask[i]) {
356 vl_putpixel(offset, index[i]);
357 }
358 }
359 } else {
360 /* draw all pixels */
361 for (i=0; i<n; i++, offset++) {
362 vl_putpixel(offset, index[i]);
363 }
364 }
365 }
366
367
368
369 static void write_mono_index_span (const GLcontext *ctx,
370 GLuint n, GLint x, GLint y,
371 GLuint colorIndex, const GLubyte mask[])
372 {
373 const DMesaContext dmesa = (DMesaContext)ctx;
374 GLuint i, offset;
375
376 offset = DSTRIDE * FLIP(y) + x;
377 if (mask) {
378 /* draw some pixels */
379 for (i=0; i<n; i++, offset++) {
380 if (mask[i]) {
381 vl_putpixel(offset, colorIndex);
382 }
383 }
384 } else {
385 /* draw all pixels */
386 for (i=0; i<n; i++, offset++) {
387 vl_putpixel(offset, colorIndex);
388 }
389 }
390 }
391
392
393
394 static void read_index_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
395 GLuint index[])
396 {
397 const DMesaContext dmesa = (DMesaContext)ctx;
398 GLuint i, offset;
399
400 offset = DSTRIDE * FLIP(y) + x;
401 /* read all pixels */
402 for (i=0; i<n; i++, offset++) {
403 index[i] = vl_getpixel(offset);
404 }
405 }
406
407
408
409 static void write_index_pixels (const GLcontext *ctx,
410 GLuint n, const GLint x[], const GLint y[],
411 const GLuint index[], const GLubyte mask[])
412 {
413 const DMesaContext dmesa = (DMesaContext)ctx;
414 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;
415
416 if (mask) {
417 /* draw some pixels */
418 for (i=0; i<n; i++) {
419 if (mask[i]) {
420 vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]);
421 }
422 }
423 } else {
424 /* draw all pixels */
425 for (i=0; i<n; i++) {
426 vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]);
427 }
428 }
429 }
430
431
432
433 static void write_mono_index_pixels (const GLcontext *ctx,
434 GLuint n, const GLint x[], const GLint y[],
435 GLuint colorIndex, const GLubyte mask[])
436 {
437 const DMesaContext dmesa = (DMesaContext)ctx;
438 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;
439
440 if (mask) {
441 /* draw some pixels */
442 for (i=0; i<n; i++) {
443 if (mask[i]) {
444 vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex);
445 }
446 }
447 } else {
448 /* draw all pixels */
449 for (i=0; i<n; i++) {
450 vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex);
451 }
452 }
453 }
454
455
456
457 static void read_index_pixels (const GLcontext *ctx,
458 GLuint n, const GLint x[], const GLint y[],
459 GLuint index[], const GLubyte mask[])
460 {
461 const DMesaContext dmesa = (DMesaContext)ctx;
462 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;
463
464 if (mask) {
465 /* read some pixels */
466 for (i=0; i<n; i++) {
467 if (mask[i]) {
468 index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]);
469 }
470 }
471 } else {
472 /* read all pixels */
473 for (i=0; i<n; i++) {
474 index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]);
475 }
476 }
477 }
478 #endif /* !MATROX */
479
480
481
482 /****************************************************************************
483 * Z-buffer
484 ***************************************************************************/
485 #ifdef MATROX
486 static void write_depth_span (GLcontext *ctx, GLuint n, GLint x, GLint y,
487 const GLdepth depth[], const GLubyte mask[])
488 {
489 const DMesaContext dmesa = (DMesaContext)ctx;
490 GLuint i, offset;
491
492 offset = DSTRIDE * FLIP(y) + x;
493 if (mask) {
494 /* draw some values */
495 for (i=0; i<n; i++, offset++) {
496 if (mask[i]) {
497 vl_setz(offset, depth[i]);
498 }
499 }
500 } else {
501 /* draw all values */
502 for (i=0; i<n; i++, offset++) {
503 vl_setz(offset, depth[i]);
504 }
505 }
506 }
507
508
509
510 static void read_depth_span (GLcontext *ctx, GLuint n, GLint x, GLint y,
511 GLdepth depth[])
512 {
513 const DMesaContext dmesa = (DMesaContext)ctx;
514 GLuint i, offset;
515
516 offset = DSTRIDE * FLIP(y) + x;
517 /* read all values */
518 for (i=0; i<n; i++, offset++) {
519 depth[i] = vl_getz(offset);
520 }
521 }
522
523
524
525 static void write_depth_pixels (GLcontext *ctx, GLuint n,
526 const GLint x[], const GLint y[],
527 const GLdepth depth[], const GLubyte mask[])
528 {
529 const DMesaContext dmesa = (DMesaContext)ctx;
530 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;
531
532 if (mask) {
533 /* draw some values */
534 for (i=0; i<n; i++) {
535 if (mask[i]) {
536 vl_setz(FLIP2(y[i])*_w_ + x[i], depth[i]);
537 }
538 }
539 } else {
540 /* draw all values */
541 for (i=0; i<n; i++) {
542 vl_setz(FLIP2(y[i])*_w_ + x[i], depth[i]);
543 }
544 }
545 }
546
547
548
549 static void read_depth_pixels (GLcontext *ctx, GLuint n,
550 const GLint x[], const GLint y[],
551 GLdepth depth[])
552 {
553 const DMesaContext dmesa = (DMesaContext)ctx;
554 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;
555
556 /* read all values */
557 for (i=0; i<n; i++) {
558 depth[i] = vl_getz(FLIP2(y[i])*_w_ + x[i]);
559 }
560 }
561 #endif /* MATROX */
562
563
564
565 /****************************************************************************
566 * Optimized triangle rendering
567 ***************************************************************************/
568
569 /*
570 * NON-depth-buffered flat triangle.
571 */
572 #ifndef MATROX
573
574 #define NAME tri_rgb_flat
575
576 #define SETUP_CODE \
577 const DMesaContext dmesa = (DMesaContext)ctx; \
578 GLuint _b_ = dmesa->Buffer->height - 1; \
579 GLuint _w_ = dmesa->Buffer->width; \
580 GLuint rgb = vl_mixrgb(v2->color);
581
582 #define RENDER_SPAN(span) \
583 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
584 for (i = 0; i < span.end; i++, offset++) { \
585 vl_putpixel(offset, rgb); \
586 }
587
588 #include "swrast/s_tritemp.h"
589
590 #else /* MATROX */
591
592 static void tri_rgb_flat (GLcontext *ctx,
593 const SWvertex *v0,
594 const SWvertex *v1,
595 const SWvertex *v2)
596 {
597 const DMesaContext dmesa = (DMesaContext)ctx;
598 GLuint _b_ = dmesa->Buffer->height - 1;
599 MGAvertex m0, m1, m2;
600 m0.win[0] = v0->win[0];
601 m0.win[1] = FLIP2(v0->win[1]);
602 m1.win[0] = v1->win[0];
603 m1.win[1] = FLIP2(v1->win[1]);
604 m2.win[0] = v2->win[0];
605 m2.win[1] = FLIP2(v2->win[1]);
606 *(unsigned long *)m2.color = *(unsigned long *)v2->color;
607 mga_draw_tri_rgb_flat((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);
608 }
609 #endif /* MATROX */
610
611
612
613 /*
614 * Z-less flat triangle.
615 */
616 #ifndef MATROX
617
618 #define NAME tri_rgb_flat_zless
619
620 #define INTERP_Z 1
621 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
622
623 #define SETUP_CODE \
624 const DMesaContext dmesa = (DMesaContext)ctx; \
625 GLuint _b_ = dmesa->Buffer->height - 1; \
626 GLuint _w_ = dmesa->Buffer->width; \
627 GLuint rgb = vl_mixrgb(v2->color);
628
629 #define RENDER_SPAN(span) \
630 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
631 for (i = 0; i < span.end; i++, offset++) { \
632 const DEPTH_TYPE z = FixedToDepth(span.z); \
633 if (z < zRow[i]) { \
634 vl_putpixel(offset, rgb); \
635 zRow[i] = z; \
636 } \
637 span.z += span.zStep; \
638 }
639
640 #include "swrast/s_tritemp.h"
641
642 #else /* MATROX */
643
644 static void tri_rgb_flat_zless (GLcontext *ctx,
645 const SWvertex *v0,
646 const SWvertex *v1,
647 const SWvertex *v2)
648 {
649 const DMesaContext dmesa = (DMesaContext)ctx;
650 GLuint _b_ = dmesa->Buffer->height - 1;
651 MGAvertex m0, m1, m2;
652 m0.win[0] = v0->win[0];
653 m0.win[1] = FLIP2(v0->win[1]);
654 m0.win[2] = v0->win[2];
655 m1.win[0] = v1->win[0];
656 m1.win[1] = FLIP2(v1->win[1]);
657 m1.win[2] = v1->win[2];
658 m2.win[0] = v2->win[0];
659 m2.win[1] = FLIP2(v2->win[1]);
660 m2.win[2] = v2->win[2];
661 *(unsigned long *)m2.color = *(unsigned long *)v2->color;
662 mga_draw_tri_rgb_flat_zless((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);
663 }
664 #endif /* MATROX */
665
666
667
668 /*
669 * NON-depth-buffered iterated triangle.
670 */
671 #ifndef MATROX
672
673 #define NAME tri_rgb_iter
674
675 #define INTERP_RGB 1
676
677 #define SETUP_CODE \
678 const DMesaContext dmesa = (DMesaContext)ctx; \
679 GLuint _b_ = dmesa->Buffer->height - 1; \
680 GLuint _w_ = dmesa->Buffer->width;
681
682 #define RENDER_SPAN(span) \
683 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
684 for (i = 0; i < span.end; i++, offset++) { \
685 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue)); \
686 span.red += span.redStep; \
687 span.green += span.greenStep; \
688 span.blue += span.blueStep; \
689 }
690
691 #include "swrast/s_tritemp.h"
692
693 #else /* MATROX */
694
695 static void tri_rgb_iter (GLcontext *ctx,
696 const SWvertex *v0,
697 const SWvertex *v1,
698 const SWvertex *v2)
699 {
700 const DMesaContext dmesa = (DMesaContext)ctx;
701 GLuint _b_ = dmesa->Buffer->height - 1;
702 MGAvertex m0, m1, m2;
703 m0.win[0] = v0->win[0];
704 m0.win[1] = FLIP2(v0->win[1]);
705 m1.win[0] = v1->win[0];
706 m1.win[1] = FLIP2(v1->win[1]);
707 m2.win[0] = v2->win[0];
708 m2.win[1] = FLIP2(v2->win[1]);
709 *(unsigned long *)m0.color = *(unsigned long *)v0->color;
710 *(unsigned long *)m1.color = *(unsigned long *)v1->color;
711 *(unsigned long *)m2.color = *(unsigned long *)v2->color;
712 mga_draw_tri_rgb_iter((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);
713 }
714 #endif /* MATROX */
715
716
717
718 /*
719 * Z-less iterated triangle.
720 */
721 #ifndef MATROX
722
723 #define NAME tri_rgb_iter_zless
724
725 #define INTERP_Z 1
726 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
727 #define INTERP_RGB 1
728
729 #define SETUP_CODE \
730 const DMesaContext dmesa = (DMesaContext)ctx; \
731 GLuint _b_ = dmesa->Buffer->height - 1; \
732 GLuint _w_ = dmesa->Buffer->width;
733
734 #define RENDER_SPAN(span) \
735 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
736 for (i = 0; i < span.end; i++, offset++) { \
737 const DEPTH_TYPE z = FixedToDepth(span.z); \
738 if (z < zRow[i]) { \
739 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\
740 zRow[i] = z; \
741 } \
742 span.red += span.redStep; \
743 span.green += span.greenStep; \
744 span.blue += span.blueStep; \
745 span.z += span.zStep; \
746 }
747
748 #include "swrast/s_tritemp.h"
749
750 #else /* MATROX */
751
752 static void tri_rgb_iter_zless (GLcontext *ctx,
753 const SWvertex *v0,
754 const SWvertex *v1,
755 const SWvertex *v2)
756 {
757 const DMesaContext dmesa = (DMesaContext)ctx;
758 GLuint _b_ = dmesa->Buffer->height - 1;
759 MGAvertex m0, m1, m2;
760 m0.win[0] = v0->win[0];
761 m0.win[1] = FLIP2(v0->win[1]);
762 m0.win[2] = v0->win[2];
763 m1.win[0] = v1->win[0];
764 m1.win[1] = FLIP2(v1->win[1]);
765 m1.win[2] = v1->win[2];
766 m2.win[0] = v2->win[0];
767 m2.win[1] = FLIP2(v2->win[1]);
768 m2.win[2] = v2->win[2];
769 *(unsigned long *)m0.color = *(unsigned long *)v0->color;
770 *(unsigned long *)m1.color = *(unsigned long *)v1->color;
771 *(unsigned long *)m2.color = *(unsigned long *)v2->color;
772 mga_draw_tri_rgb_iter_zless((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);
773 }
774 #endif /* MATROX */
775
776
777
778 /*
779 * Analyze context state to see if we can provide a fast triangle function
780 * Otherwise, return NULL.
781 */
782 static swrast_tri_func dmesa_choose_tri_function (GLcontext *ctx)
783 {
784 const SWcontext *swrast = SWRAST_CONTEXT(ctx);
785
786 if ((ctx->RenderMode != GL_RENDER)
787 || (ctx->Polygon.SmoothFlag)
788 || (ctx->Polygon.StippleFlag)
789 || (ctx->Texture._EnabledUnits)
790 || (swrast->_RasterMask & MULTI_DRAW_BIT)
791 || (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)) {
792 return (swrast_tri_func)NULL;
793 }
794
795 if (swrast->_RasterMask==DEPTH_BIT
796 && ctx->Depth.Func==GL_LESS
797 && ctx->Depth.Mask==GL_TRUE
798 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
799 return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter_zless : tri_rgb_flat_zless;
800 }
801
802 if (swrast->_RasterMask==0) { /* no depth test */
803 return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter : tri_rgb_flat;
804 }
805
806 return (swrast_tri_func)NULL;
807 }
808
809
810
811 /* Override for the swrast triangle-selection function. Try to use one
812 * of our internal triangle functions, otherwise fall back to the
813 * standard swrast functions.
814 */
815 static void dmesa_choose_tri (GLcontext *ctx)
816 {
817 SWcontext *swrast = SWRAST_CONTEXT(ctx);
818
819 if (!(swrast->Triangle=dmesa_choose_tri_function(ctx)))
820 _swrast_choose_triangle(ctx);
821 }
822
823
824
825 /****************************************************************************
826 * Optimized line rendering
827 ***************************************************************************/
828
829 #ifdef MATROX
830 static __inline void matrox_line_clip_hack (GLcontext *ctx, int _b_, MGAvertex *m0, const SWvertex *vert0, MGAvertex *m1, const SWvertex *vert1)
831 {
832 int x0 = vert0->win[0];
833 int y0 = vert0->win[1];
834 int x1 = vert1->win[0];
835 int y1 = vert1->win[1];
836 /* s_linetemp.h { */
837 GLint w = ctx->DrawBuffer->Width;
838 GLint h = ctx->DrawBuffer->Height;
839 if ((x0==w) | (x1==w)) {
840 if ((x0==w) & (x1==w))
841 return;
842 x0 -= x0==w;
843 x1 -= x1==w;
844 }
845 if ((y0==h) | (y1==h)) {
846 if ((y0==h) & (y1==h))
847 return;
848 y0 -= y0==h;
849 y1 -= y1==h;
850 }
851 /* } s_linetemp.h */
852 m0->win[0] = x0;
853 m0->win[1] = FLIP2(y0);
854 m1->win[0] = x1;
855 m1->win[1] = FLIP2(y1);
856 }
857 #endif
858
859 /*
860 * NON-depth-buffered flat line.
861 */
862 #ifndef MATROX
863
864 #define NAME line_rgb_flat
865
866 #define INTERP_XY 1
867 #define CLIP_HACK 1
868
869 #define SETUP_CODE \
870 const DMesaContext dmesa = (DMesaContext)ctx; \
871 GLuint _b_ = dmesa->Buffer->height - 1; \
872 GLuint _w_ = dmesa->Buffer->width; \
873 GLuint rgb = vl_mixrgb(vert1->color);
874
875 #define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb);
876
877 #include "swrast/s_linetemp.h"
878
879 #else /* MATROX */
880
881 static void line_rgb_flat (GLcontext *ctx,
882 const SWvertex *vert0,
883 const SWvertex *vert1)
884 {
885 const DMesaContext dmesa = (DMesaContext)ctx;
886 GLuint _b_ = dmesa->Buffer->height - 1;
887 MGAvertex m0, m1;
888 matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);
889 *(unsigned long *)m1.color = *(unsigned long *)vert1->color;
890 mga_draw_line_rgb_flat(&m0, &m1);
891 }
892 #endif /* MATROX */
893
894
895
896 /*
897 * Z-less flat line.
898 */
899 #ifndef MATROX
900
901 #define NAME line_rgb_flat_zless
902
903 #define INTERP_XY 1
904 #define INTERP_Z 1
905 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
906 #define CLIP_HACK 1
907
908 #define SETUP_CODE \
909 const DMesaContext dmesa = (DMesaContext)ctx; \
910 GLuint _b_ = dmesa->Buffer->height - 1; \
911 GLuint _w_ = dmesa->Buffer->width; \
912 GLuint rgb = vl_mixrgb(vert1->color);
913
914 #define PLOT(X,Y) \
915 if (Z < *zPtr) { \
916 *zPtr = Z; \
917 vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \
918 }
919
920 #include "swrast/s_linetemp.h"
921
922 #else /* MATROX */
923
924 static void line_rgb_flat_zless (GLcontext *ctx,
925 const SWvertex *vert0,
926 const SWvertex *vert1)
927 {
928 const DMesaContext dmesa = (DMesaContext)ctx;
929 GLuint _b_ = dmesa->Buffer->height - 1;
930 MGAvertex m0, m1;
931 matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);
932 m0.win[2] = vert0->win[2];
933 m1.win[2] = vert1->win[2];
934 *(unsigned long *)m1.color = *(unsigned long *)vert1->color;
935 mga_draw_line_rgb_flat_zless(&m0, &m1);
936 }
937 #endif /* MATROX */
938
939
940
941 #ifndef MATROX
942 #define line_rgb_iter NULL
943 #define line_rgb_iter_zless NULL
944 #else /* MATROX */
945 /*
946 * NON-depth-buffered iterated line.
947 */
948 static void line_rgb_iter (GLcontext *ctx,
949 const SWvertex *vert0,
950 const SWvertex *vert1)
951 {
952 const DMesaContext dmesa = (DMesaContext)ctx;
953 GLuint _b_ = dmesa->Buffer->height - 1;
954 MGAvertex m0, m1;
955 matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);
956 *(unsigned long *)m0.color = *(unsigned long *)vert0->color;
957 *(unsigned long *)m1.color = *(unsigned long *)vert1->color;
958 mga_draw_line_rgb_iter(&m0, &m1);
959 }
960
961
962
963 /*
964 * Z-less iterated line.
965 */
966 static void line_rgb_iter_zless (GLcontext *ctx,
967 const SWvertex *vert0,
968 const SWvertex *vert1)
969 {
970 const DMesaContext dmesa = (DMesaContext)ctx;
971 GLuint _b_ = dmesa->Buffer->height - 1;
972 MGAvertex m0, m1;
973 matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);
974 m0.win[2] = vert0->win[2];
975 m1.win[2] = vert1->win[2];
976 *(unsigned long *)m0.color = *(unsigned long *)vert0->color;
977 *(unsigned long *)m1.color = *(unsigned long *)vert1->color;
978 mga_draw_line_rgb_iter_zless(&m0, &m1);
979 }
980 #endif /* MATROX */
981
982
983
984 /*
985 * Analyze context state to see if we can provide a fast line function
986 * Otherwise, return NULL.
987 */
988 static swrast_line_func dmesa_choose_line_function (GLcontext *ctx)
989 {
990 const SWcontext *swrast = SWRAST_CONTEXT(ctx);
991
992 if ((ctx->RenderMode != GL_RENDER)
993 || (ctx->Line.SmoothFlag)
994 || (ctx->Texture._EnabledUnits)
995 || (ctx->Line.StippleFlag)
996 || (swrast->_RasterMask & MULTI_DRAW_BIT)
997 || (ctx->Line.Width!=1.0F)) {
998 return (swrast_line_func)NULL;
999 }
1000
1001 if (swrast->_RasterMask==DEPTH_BIT
1002 && ctx->Depth.Func==GL_LESS
1003 && ctx->Depth.Mask==GL_TRUE
1004 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
1005 return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter_zless : line_rgb_flat_zless;
1006 }
1007
1008 if (swrast->_RasterMask==0) { /* no depth test */
1009 return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter : line_rgb_flat;
1010 }
1011
1012 return (swrast_line_func)NULL;
1013 }
1014
1015
1016
1017 /* Override for the swrast line-selection function. Try to use one
1018 * of our internal line functions, otherwise fall back to the
1019 * standard swrast functions.
1020 */
1021 static void dmesa_choose_line (GLcontext *ctx)
1022 {
1023 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1024
1025 if (!(swrast->Line=dmesa_choose_line_function(ctx)))
1026 _swrast_choose_line(ctx);
1027 }
1028
1029
1030
1031 /****************************************************************************
1032 * Miscellaneous device driver funcs
1033 ***************************************************************************/
1034
1035 static void clear_index (GLcontext *ctx, GLuint index)
1036 {
1037 ((DMesaContext)ctx)->ClearIndex = index;
1038 }
1039
1040 static void clear_color (GLcontext *ctx, const GLfloat color[4])
1041 {
1042 GLubyte col[4];
1043 CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
1044 CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
1045 CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
1046 CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]);
1047 ((DMesaContext)ctx)->ClearColor = vl_mixrgba(col);
1048 }
1049
1050
1051
1052 static void clear (GLcontext *ctx, GLbitfield mask, GLboolean all,
1053 GLint x, GLint y, GLint width, GLint height)
1054 {
1055 const DMesaContext c = (DMesaContext)ctx;
1056 const GLuint *colorMask = (GLuint *)&ctx->Color.ColorMask;
1057
1058 /*
1059 * Clear the specified region of the buffers indicated by 'mask'
1060 * using the clear color or index as specified by one of the two
1061 * functions above.
1062 * If all==GL_TRUE, clear whole buffer, else just clear region defined
1063 * by x,y,width,height
1064 */
1065
1066 /* we can't handle color or index masking */
1067 if ((*colorMask == 0xffffffff) && (ctx->Color.IndexMask == 0xffffffff)) {
1068 #ifndef MATROX
1069 if (mask & DD_BACK_LEFT_BIT) {
1070 int color = c->visual->rgb_flag ? c->ClearColor : c->ClearIndex;
1071
1072 if (all) {
1073 vl_clear(color);
1074 } else {
1075 vl_rect(x, y, width, height, color);
1076 }
1077
1078 mask &= ~DD_BACK_LEFT_BIT;
1079 }
1080 #else /* MATROX */
1081 unsigned short z = -1;
1082 int color = c->ClearColor;
1083 if (mask & DD_DEPTH_BIT) {
1084 z = ctx->Depth.Clear * 0xffff;
1085 }
1086 if (all) {
1087 mga_clear(mask & DD_FRONT_LEFT_BIT,
1088 mask & DD_BACK_LEFT_BIT,
1089 mask & DD_DEPTH_BIT,
1090 0, 0, c->Buffer->width, c->Buffer->height,
1091 color, z);
1092 } else {
1093 mga_clear(mask & DD_FRONT_LEFT_BIT,
1094 mask & DD_BACK_LEFT_BIT,
1095 mask & DD_DEPTH_BIT,
1096 x, y, width, height,
1097 color, z);
1098 }
1099 mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT);
1100 #endif /* MATROX */
1101 }
1102
1103 if (mask) {
1104 _swrast_Clear(ctx, mask, all, x, y, width, height);
1105 }
1106 }
1107
1108
1109
1110 static void set_buffer (GLcontext *ctx, GLframebuffer *colorBuffer, GLuint bufferBit)
1111 {
1112 /*
1113 * XXX todo - examine bufferBit and set read/write pointers
1114 */
1115 }
1116
1117
1118
1119 /*
1120 * Return the width and height of the current buffer.
1121 * If anything special has to been done when the buffer/window is
1122 * resized, do it now.
1123 */
1124 static void get_buffer_size (GLframebuffer *buffer, GLuint *width, GLuint *height)
1125 {
1126 DMesaBuffer b = (DMesaBuffer)buffer;
1127
1128 *width = b->width;
1129 *height = b->height;
1130 }
1131
1132
1133
1134 static const GLubyte* get_string (GLcontext *ctx, GLenum name)
1135 {
1136 switch (name) {
1137 case GL_RENDERER:
1138 return (const GLubyte *)"Mesa DJGPP"
1139 #ifdef FX
1140 " (FX)"
1141 #endif
1142 #ifdef MATROX
1143 " (MGA)"
1144 #endif
1145 "\0port (c) Borca Daniel aug-2003";
1146 default:
1147 return NULL;
1148 }
1149 }
1150
1151
1152
1153 static void finish (GLcontext *ctx)
1154 {
1155 /*
1156 * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible
1157 */
1158 }
1159
1160
1161
1162 static void flush (GLcontext *ctx)
1163 {
1164 /*
1165 * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible
1166 */
1167 }
1168
1169
1170
1171 /****************************************************************************
1172 * State
1173 ***************************************************************************/
1174 #define DMESA_NEW_LINE (_NEW_LINE | \
1175 _NEW_TEXTURE | \
1176 _NEW_LIGHT | \
1177 _NEW_DEPTH | \
1178 _NEW_RENDERMODE | \
1179 _SWRAST_NEW_RASTERMASK)
1180
1181 #define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \
1182 _NEW_TEXTURE | \
1183 _NEW_LIGHT | \
1184 _NEW_DEPTH | \
1185 _NEW_RENDERMODE | \
1186 _SWRAST_NEW_RASTERMASK)
1187
1188 /* Extend the software rasterizer with our line and triangle
1189 * functions.
1190 */
1191 static void dmesa_register_swrast_functions (GLcontext *ctx)
1192 {
1193 SWcontext *swrast = SWRAST_CONTEXT(ctx);
1194
1195 swrast->choose_line = dmesa_choose_line;
1196 swrast->choose_triangle = dmesa_choose_tri;
1197
1198 swrast->invalidate_line |= DMESA_NEW_LINE;
1199 swrast->invalidate_triangle |= DMESA_NEW_TRIANGLE;
1200 }
1201
1202
1203
1204 /* Setup pointers and other driver state that is constant for the life
1205 * of a context.
1206 */
1207 static void dmesa_init_pointers (GLcontext *ctx)
1208 {
1209 TNLcontext *tnl;
1210 struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference(ctx);
1211
1212 ctx->Driver.GetString = get_string;
1213 ctx->Driver.GetBufferSize = get_buffer_size;
1214 ctx->Driver.Flush = flush;
1215 ctx->Driver.Finish = finish;
1216
1217 /* Software rasterizer pixel paths:
1218 */
1219 ctx->Driver.Accum = _swrast_Accum;
1220 ctx->Driver.Bitmap = _swrast_Bitmap;
1221 ctx->Driver.Clear = clear;
1222 ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;
1223 ctx->Driver.CopyPixels = _swrast_CopyPixels;
1224 ctx->Driver.DrawPixels = _swrast_DrawPixels;
1225 ctx->Driver.ReadPixels = _swrast_ReadPixels;
1226 ctx->Driver.DrawBuffer = _swrast_DrawBuffer;
1227
1228 /* Software texture functions:
1229 */
1230 ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;
1231 ctx->Driver.TexImage1D = _mesa_store_teximage1d;
1232 ctx->Driver.TexImage2D = _mesa_store_teximage2d;
1233 ctx->Driver.TexImage3D = _mesa_store_teximage3d;
1234 ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;
1235 ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;
1236 ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;
1237 ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;
1238
1239 ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;
1240 ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;
1241 ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;
1242 ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;
1243 ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;
1244
1245 ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;
1246 ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;
1247 ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;
1248 ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;
1249 ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;
1250 ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;
1251
1252 /* Swrast hooks for imaging extensions:
1253 */
1254 ctx->Driver.CopyColorTable = _swrast_CopyColorTable;
1255 ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;
1256 ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;
1257 ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;
1258
1259 /* Statechange callbacks:
1260 */
1261 ctx->Driver.ClearColor = clear_color;
1262 ctx->Driver.ClearIndex = clear_index;
1263
1264 /* Initialize the TNL driver interface:
1265 */
1266 tnl = TNL_CONTEXT(ctx);
1267 tnl->Driver.RunPipeline = _tnl_run_pipeline;
1268
1269 dd->SetBuffer = set_buffer;
1270
1271 /* Install swsetup for tnl->Driver.Render.*:
1272 */
1273 _swsetup_Wakeup(ctx);
1274
1275 /* The span functions should be in `dmesa_update_state', but I'm
1276 * pretty sure they will never change during the life of the Visual
1277 */
1278 #ifdef MATROX
1279 if (((DMesaContext)ctx)->visual->zbuffer == -1) {
1280 /* Depth span/pixel functions */
1281 dd->WriteDepthSpan = write_depth_span;
1282 dd->WriteDepthPixels = write_depth_pixels;
1283 dd->ReadDepthSpan = read_depth_span;
1284 dd->ReadDepthPixels = read_depth_pixels;
1285 }
1286 #endif
1287
1288 #ifndef MATROX
1289 /* Index span/pixel functions */
1290 dd->WriteCI32Span = write_index_span;
1291 dd->WriteCI8Span = write_index8_span;
1292 dd->WriteMonoCISpan = write_mono_index_span;
1293 dd->WriteCI32Pixels = write_index_pixels;
1294 dd->WriteMonoCIPixels = write_mono_index_pixels;
1295 dd->ReadCI32Span = read_index_span;
1296 dd->ReadCI32Pixels = read_index_pixels;
1297 #endif
1298
1299 /* RGB(A) span/pixel functions */
1300 dd->WriteRGBASpan = write_rgba_span;
1301 dd->WriteRGBSpan = write_rgb_span;
1302 dd->WriteMonoRGBASpan = write_mono_rgba_span;
1303 dd->WriteRGBAPixels = write_rgba_pixels;
1304 dd->WriteMonoRGBAPixels = write_mono_rgba_pixels;
1305 dd->ReadRGBASpan = read_rgba_span;
1306 dd->ReadRGBAPixels = read_rgba_pixels;
1307 }
1308
1309
1310
1311 static void dmesa_update_state (GLcontext *ctx, GLuint new_state)
1312 {
1313 /* Propogate statechange information to swrast and swrast_setup
1314 * modules. The DMesa driver has no internal GL-dependent state.
1315 */
1316 _swrast_InvalidateState( ctx, new_state );
1317 _ac_InvalidateState( ctx, new_state );
1318 _tnl_InvalidateState( ctx, new_state );
1319 _swsetup_InvalidateState( ctx, new_state );
1320 }
1321 #endif /* FX */
1322
1323
1324
1325 /****************************************************************************
1326 * DMesa Public API Functions
1327 ***************************************************************************/
1328
1329 /*
1330 * The exact arguments to this function will depend on your window system
1331 */
1332 DMesaVisual DMesaCreateVisual (GLint width,
1333 GLint height,
1334 GLint colDepth,
1335 GLint refresh,
1336 GLboolean dbFlag,
1337 GLboolean rgbFlag,
1338 GLboolean alphaFlag,
1339 GLint depthSize,
1340 GLint stencilSize,
1341 GLint accumSize)
1342 {
1343 #ifndef FX
1344 DMesaVisual v;
1345 GLint redBits, greenBits, blueBits, alphaBits, indexBits;
1346
1347 #ifndef MATROX
1348 if (!dbFlag) {
1349 return NULL;
1350 }
1351 #else
1352 if (!rgbFlag) {
1353 return NULL;
1354 }
1355 #endif
1356
1357 alphaBits = 0;
1358
1359 if (!rgbFlag) {
1360 indexBits = 8;
1361 redBits = 0;
1362 greenBits = 0;
1363 blueBits = 0;
1364 } else {
1365 indexBits = 0;
1366 switch (colDepth) {
1367 case 8:
1368 redBits = 8;
1369 greenBits = 8;
1370 blueBits = 8;
1371 break;
1372 case 15:
1373 redBits = 5;
1374 greenBits = 5;
1375 blueBits = 5;
1376 break;
1377 case 16:
1378 redBits = 5;
1379 greenBits = 6;
1380 blueBits = 5;
1381 break;
1382 case 32:
1383 alphaBits = 8;
1384 case 24:
1385 redBits = 8;
1386 greenBits = 8;
1387 blueBits = 8;
1388 break;
1389 default:
1390 return NULL;
1391 }
1392 }
1393
1394 #ifndef MATROX
1395 if ((colDepth=vl_video_init(width, height, colDepth, rgbFlag, refresh)) <= 0) {
1396 return NULL;
1397 }
1398 #else
1399 if (mga_open(width, height, colDepth, dbFlag ? 2 : 1, depthSize == 16, refresh) < 0) {
1400 return NULL;
1401 }
1402 #endif
1403
1404 if (alphaFlag && (alphaBits==0)) {
1405 alphaBits = 8;
1406 }
1407
1408 if ((v=(DMesaVisual)CALLOC_STRUCT(dmesa_visual)) != NULL) {
1409 /* Create core visual */
1410 _mesa_initialize_visual((GLvisual *)v,
1411 rgbFlag, /* rgb */
1412 dbFlag,
1413 GL_FALSE, /* stereo */
1414 redBits,
1415 greenBits,
1416 blueBits,
1417 alphaBits,
1418 indexBits, /* indexBits */
1419 depthSize,
1420 stencilSize,
1421 accumSize, /* accumRed */
1422 accumSize, /* accumGreen */
1423 accumSize, /* accumBlue */
1424 alphaFlag?accumSize:0, /* accumAlpha */
1425 1); /* numSamples */
1426
1427 v->depth = colDepth;
1428 v->db_flag = dbFlag;
1429 v->rgb_flag = rgbFlag;
1430
1431 v->zbuffer = (depthSize > 0) ? 1 : 0;
1432 #ifdef MATROX
1433 mga_get(MGA_GET_HPIXELS, &v->stride_in_pixels);
1434 if (depthSize == 16) {
1435 v->zbuffer = -1;
1436 }
1437 #endif
1438 }
1439
1440 return v;
1441
1442 #else /* FX */
1443
1444 int i = 0, fx_attrib[32];
1445
1446 if (!rgbFlag) {
1447 return NULL;
1448 }
1449
1450 if (dbFlag) fx_attrib[i++] = FXMESA_DOUBLEBUFFER;
1451 if (depthSize > 0) { fx_attrib[i++] = FXMESA_DEPTH_SIZE; fx_attrib[i++] = depthSize; }
1452 if (stencilSize > 0) { fx_attrib[i++] = FXMESA_STENCIL_SIZE; fx_attrib[i++] = stencilSize; }
1453 if (accumSize > 0) { fx_attrib[i++] = FXMESA_ACCUM_SIZE; fx_attrib[i++] = accumSize; }
1454 if (alphaFlag) { fx_attrib[i++] = FXMESA_ALPHA_SIZE; fx_attrib[i++] = 1; }
1455 fx_attrib[i++] = FXMESA_COLORDEPTH;
1456 fx_attrib[i++] = colDepth;
1457 fx_attrib[i] = FXMESA_NONE;
1458
1459 return (DMesaVisual)fxMesaCreateBestContext(-1, width, height, fx_attrib);
1460 #endif /* FX */
1461 }
1462
1463
1464
1465 void DMesaDestroyVisual (DMesaVisual v)
1466 {
1467 #ifndef FX
1468 _mesa_destroy_visual((GLvisual *)v);
1469
1470 #ifndef MATROX
1471 vl_video_exit();
1472 #else
1473 mga_close(1, 1);
1474 #endif
1475
1476 #else
1477 fxMesaDestroyContext((fxMesaContext)v);
1478 #endif
1479 }
1480
1481
1482
1483 DMesaBuffer DMesaCreateBuffer (DMesaVisual visual,
1484 GLint xpos, GLint ypos,
1485 GLint width, GLint height)
1486 {
1487 #ifndef FX
1488 DMesaBuffer b;
1489
1490 if ((b=(DMesaBuffer)CALLOC_STRUCT(dmesa_buffer)) != NULL) {
1491 _mesa_initialize_framebuffer((GLframebuffer *)b,
1492 (GLvisual *)visual,
1493 visual->zbuffer == 1,
1494 ((GLvisual *)visual)->stencilBits > 0,
1495 ((GLvisual *)visual)->accumRedBits > 0,
1496 ((GLvisual *)visual)->alphaBits > 0);
1497 b->xpos = xpos;
1498 b->ypos = ypos;
1499 b->width = width;
1500 b->height = height;
1501 }
1502
1503 return b;
1504 #else
1505 return (DMesaBuffer)visual;
1506 #endif
1507 }
1508
1509
1510
1511 void DMesaDestroyBuffer (DMesaBuffer b)
1512 {
1513 #ifndef FX
1514 #ifndef MATROX
1515 free(b->the_window);
1516 #endif
1517 _mesa_destroy_framebuffer((GLframebuffer *)b);
1518 #endif
1519 }
1520
1521
1522
1523 DMesaContext DMesaCreateContext (DMesaVisual visual,
1524 DMesaContext share)
1525 {
1526 #ifndef FX
1527 DMesaContext c;
1528 GLboolean direct = GL_FALSE;
1529
1530 if ((c=(DMesaContext)CALLOC_STRUCT(dmesa_context)) != NULL) {
1531 _mesa_initialize_context((GLcontext *)c,
1532 (GLvisual *)visual,
1533 (GLcontext *)share,
1534 (void *)c, direct);
1535
1536 _mesa_enable_sw_extensions((GLcontext *)c);
1537 _mesa_enable_1_3_extensions((GLcontext *)c);
1538 _mesa_enable_1_4_extensions((GLcontext *)c);
1539 _mesa_enable_1_5_extensions((GLcontext *)c);
1540
1541 /* you probably have to do a bunch of other initializations here. */
1542 c->visual = visual;
1543
1544 ((GLcontext *)c)->Driver.UpdateState = dmesa_update_state;
1545
1546 /* Initialize the software rasterizer and helper modules.
1547 */
1548 _swrast_CreateContext((GLcontext *)c);
1549 _ac_CreateContext((GLcontext *)c);
1550 _tnl_CreateContext((GLcontext *)c);
1551 _swsetup_CreateContext((GLcontext *)c);
1552 if (visual->rgb_flag) dmesa_register_swrast_functions((GLcontext *)c);
1553 dmesa_init_pointers((GLcontext *)c);
1554 }
1555
1556 return c;
1557
1558 #else /* FX */
1559 return (DMesaContext)visual;
1560 #endif /* FX */
1561 }
1562
1563
1564
1565 void DMesaDestroyContext (DMesaContext c)
1566 {
1567 #ifndef FX
1568 if (c) {
1569 _swsetup_DestroyContext((GLcontext *)c);
1570 _swrast_DestroyContext((GLcontext *)c);
1571 _tnl_DestroyContext((GLcontext *)c);
1572 _ac_DestroyContext((GLcontext *)c);
1573 _mesa_destroy_context((GLcontext *)c);
1574 }
1575 #endif
1576 }
1577
1578
1579
1580 GLboolean DMesaMoveBuffer (GLint xpos, GLint ypos)
1581 {
1582 #if !defined(FX) && !defined(MATROX)
1583 GET_CURRENT_CONTEXT(ctx);
1584 DMesaBuffer b = ((DMesaContext)ctx)->Buffer;
1585
1586 if (vl_sync_buffer(&b->the_window, xpos, ypos, b->width, b->height) != 0) {
1587 return GL_FALSE;
1588 } else {
1589 b->xpos = xpos;
1590 b->ypos = ypos;
1591 return GL_TRUE;
1592 }
1593
1594 #else
1595 return GL_FALSE;
1596 #endif
1597 }
1598
1599
1600
1601 GLboolean DMesaResizeBuffer (GLint width, GLint height)
1602 {
1603 #if !defined(FX) && !defined(MATROX)
1604 GET_CURRENT_CONTEXT(ctx);
1605 DMesaBuffer b = ((DMesaContext)ctx)->Buffer;
1606
1607 if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, width, height) != 0) {
1608 return GL_FALSE;
1609 } else {
1610 b->width = width;
1611 b->height = height;
1612 return GL_TRUE;
1613 }
1614
1615 #else
1616 return GL_FALSE;
1617 #endif
1618 }
1619
1620
1621
1622 /*
1623 * Make the specified context and buffer the current one.
1624 */
1625 GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b)
1626 {
1627 #ifndef FX
1628 if ((c != NULL) && (b != NULL)) {
1629 #ifndef MATROX
1630 if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, b->width, b->height) != 0) {
1631 return GL_FALSE;
1632 }
1633 #endif
1634
1635 c->Buffer = b;
1636
1637 _mesa_make_current((GLcontext *)c, (GLframebuffer *)b);
1638 if (((GLcontext *)c)->Viewport.Width == 0) {
1639 /* initialize viewport to window size */
1640 _mesa_Viewport(0, 0, b->width, b->height);
1641 }
1642 } else {
1643 /* Detach */
1644 _mesa_make_current(NULL, NULL);
1645 }
1646
1647 #else
1648 fxMesaMakeCurrent((fxMesaContext)c);
1649 #endif
1650
1651 return GL_TRUE;
1652 }
1653
1654
1655
1656 void DMesaSwapBuffers (DMesaBuffer b)
1657 {
1658 /* copy/swap back buffer to front if applicable */
1659 #ifndef FX
1660 GET_CURRENT_CONTEXT(ctx);
1661 _mesa_notifySwapBuffers(ctx);
1662 #ifndef MATROX
1663 vl_flip();
1664 #else
1665 if (((DMesaContext)ctx)->visual->db_flag) {
1666 mga_swapbuffers(1);
1667 }
1668 #endif
1669 #else
1670 fxMesaSwapBuffers();
1671 #endif
1672 }
1673
1674
1675
1676 void DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue)
1677 {
1678 #if !defined(FX) && !defined(MATROX)
1679 vl_setCI(ndx, red, green, blue);
1680 #endif
1681 }
1682
1683
1684
1685 void *DMesaGetCurrentContext (void)
1686 {
1687 #ifndef FX
1688 GET_CURRENT_CONTEXT(ctx);
1689 return ctx;
1690 #else
1691 return fxMesaGetCurrentContext();
1692 #endif
1693 }
1694
1695
1696
1697 int DMesaGetIntegerv (GLenum pname, GLint *params)
1698 {
1699 if (DMesaGetCurrentContext() == NULL) {
1700 return -1;
1701 }
1702
1703 switch (pname) {
1704 case DMESA_GET_SCREEN_SIZE:
1705 #ifndef FX
1706 #ifndef MATROX
1707 vl_get(VL_GET_SCREEN_SIZE, params);
1708 #else
1709 mga_get(MGA_GET_SCREEN_SIZE, params);
1710 #endif
1711 #else
1712 fxGetScreenGeometry(&params[0], &params[1]);
1713 #endif
1714 break;
1715 case DMESA_GET_DRIVER_CAPS:
1716 #ifndef FX
1717 #ifndef MATROX
1718 params[0] = DMESA_DRIVER_SWDB_BIT;
1719 #else
1720 params[0] = 0;
1721 #endif
1722 #else
1723 params[0] = DMESA_DRIVER_LLWO_BIT;
1724 #endif
1725 break;
1726 default:
1727 return -1;
1728 }
1729
1730 return 0;
1731 }