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