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