remove set_buffer()
[mesa.git] / src / mesa / drivers / dos / dmesa.c
1 /*
2 * Mesa 3-D graphics library
3 * Version: 6.3
4 *
5 * Copyright (C) 1999-2004 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.7 for Mesa
27 *
28 * Copyright (c) 2003 - Daniel Borca
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 #include "imports.h"
37 #ifndef FX
38 #include "bufferobj.h"
39 #include "buffers.h"
40 #include "extensions.h"
41 #include "macros.h"
42 #include "matrix.h"
43 #include "mtypes.h"
44 #include "texformat.h"
45 #include "teximage.h"
46 #include "texstore.h"
47 #include "array_cache/acache.h"
48 #include "swrast/s_context.h"
49 #include "swrast/s_depth.h"
50 #include "swrast/s_lines.h"
51 #include "swrast/s_triangle.h"
52 #include "swrast/swrast.h"
53 #include "swrast_setup/swrast_setup.h"
54 #include "tnl/tnl.h"
55 #include "tnl/t_context.h"
56 #include "tnl/t_pipeline.h"
57 #include "drivers/common/driverfuncs.h"
58 #include "video.h"
59 #else /* FX */
60 #include "GL/fxmesa.h"
61 #endif /* FX */
62
63 #include "GL/dmesa.h"
64
65
66 #define SWTC 0 /* SW texture compression */
67
68
69 /*
70 * In C++ terms, this class derives from the GLvisual class.
71 * Add system-specific fields to it.
72 */
73 struct dmesa_visual {
74 GLvisual gl_visual;
75 GLboolean sw_alpha; /* use Mesa's alpha buffer? */
76 int z_buffer; /* Z=buffer: 0=no, 1=SW, -1=HW */
77 };
78
79 /*
80 * In C++ terms, this class derives from the GLframebuffer class.
81 * Add system-specific fields to it.
82 */
83 struct dmesa_buffer {
84 GLframebuffer gl_buffer; /* The depth, stencil, accum, etc buffers */
85 void *the_window; /* your window handle, etc */
86
87 int xpos, ypos; /* position */
88 int width, height; /* size in pixels */
89 };
90
91 /*
92 * In C++ terms, this class derives from the GLcontext class.
93 * Add system-specific fields to it.
94 */
95 struct dmesa_context {
96 GLcontext gl_ctx; /* the core library context */
97 DMesaVisual visual;
98 DMesaBuffer buffer;
99 GLuint ClearColor;
100 GLuint ClearIndex;
101 /* etc... */
102 };
103
104
105 /*
106 * SPAN FUNCTIONS
107 * XXX: These need to be updated to take the new gl_renderbuffer parameter
108 * introduced in Mesa 6.3. That parameter will indicate whether the front
109 * or back color buffer is to be read/written.
110 */
111
112 #ifndef FX
113 /****************************************************************************
114 * Read/Write pixels
115 ***************************************************************************/
116 #define FLIP(y) (dmesa->buffer->height - (y) - 1)
117 #define FLIP2(y) (_b_ - (y))
118
119 #define DSTRIDE dmesa->buffer->width
120
121 /****************************************************************************
122 * RGB[A]
123 ***************************************************************************/
124 static void
125 write_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
126 const GLubyte rgba[][4], const GLubyte mask[])
127 {
128 const DMesaContext dmesa = (DMesaContext)ctx;
129 GLuint i, offset;
130
131 offset = DSTRIDE * FLIP(y) + x;
132 if (mask) {
133 /* draw some pixels */
134 for (i = 0; i < n; i++, offset++) {
135 if (mask[i]) {
136 vl_putpixel(offset, vl_mixrgba(rgba[i]));
137 }
138 }
139 } else {
140 /* draw all pixels */
141 for (i = 0; i < n; i++, offset++) {
142 vl_putpixel(offset, vl_mixrgba(rgba[i]));
143 }
144 }
145 }
146
147
148 static void
149 write_rgb_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
150 const GLubyte rgb[][3], const GLubyte mask[])
151 {
152 const DMesaContext dmesa = (DMesaContext)ctx;
153 GLuint i, offset;
154
155 offset = DSTRIDE * FLIP(y) + x;
156 if (mask) {
157 /* draw some pixels */
158 for (i = 0; i < n; i++, offset++) {
159 if (mask[i]) {
160 vl_putpixel(offset, vl_mixrgb(rgb[i]));
161 }
162 }
163 } else {
164 /* draw all pixels */
165 for (i = 0; i < n; i++, offset++) {
166 vl_putpixel(offset, vl_mixrgb(rgb[i]));
167 }
168 }
169 }
170
171
172 static void
173 write_mono_rgba_span (const GLcontext *ctx,
174 GLuint n, GLint x, GLint y,
175 const GLchan color[4], const GLubyte mask[])
176 {
177 const DMesaContext dmesa = (DMesaContext)ctx;
178 GLuint i, offset, rgba = vl_mixrgba(color);
179
180 offset = DSTRIDE * FLIP(y) + x;
181 if (mask) {
182 /* draw some pixels */
183 for (i = 0; i < n; i++, offset++) {
184 if (mask[i]) {
185 vl_putpixel(offset, rgba);
186 }
187 }
188 } else {
189 /* draw all pixels */
190 for (i = 0; i < n; i++, offset++) {
191 vl_putpixel(offset, rgba);
192 }
193 }
194 }
195
196
197 static void
198 read_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,
199 GLubyte rgba[][4])
200 {
201 const DMesaContext dmesa = (DMesaContext)ctx;
202 GLuint i, offset;
203
204 offset = DSTRIDE * FLIP(y) + x;
205 /* read all pixels */
206 for (i = 0; i < n; i++, offset++) {
207 vl_getrgba(offset, rgba[i]);
208 }
209 }
210
211
212 static void
213 write_rgba_pixels (const GLcontext *ctx,
214 GLuint n, const GLint x[], const GLint y[],
215 const GLubyte rgba[][4], const GLubyte mask[])
216 {
217 const DMesaContext dmesa = (DMesaContext)ctx;
218 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1;
219
220 if (mask) {
221 /* draw some pixels */
222 for (i = 0; i < n; i++) {
223 if (mask[i]) {
224 vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i]));
225 }
226 }
227 } else {
228 /* draw all pixels */
229 for (i = 0; i < n; i++) {
230 vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i]));
231 }
232 }
233 }
234
235
236 static void
237 write_mono_rgba_pixels (const GLcontext *ctx,
238 GLuint n, const GLint x[], const GLint y[],
239 const GLchan color[4], const GLubyte mask[])
240 {
241 const DMesaContext dmesa = (DMesaContext)ctx;
242 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1, rgba = vl_mixrgba(color);
243
244 if (mask) {
245 /* draw some pixels */
246 for (i = 0; i < n; i++) {
247 if (mask[i]) {
248 vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba);
249 }
250 }
251 } else {
252 /* draw all pixels */
253 for (i = 0; i < n; i++) {
254 vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba);
255 }
256 }
257 }
258
259
260 static void
261 read_rgba_pixels (const GLcontext *ctx,
262 GLuint n, const GLint x[], const GLint y[],
263 GLubyte rgba[][4], const GLubyte mask[])
264 {
265 const DMesaContext dmesa = (DMesaContext)ctx;
266 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1;
267
268 if (mask) {
269 /* read some pixels */
270 for (i = 0; i < n; i++) {
271 if (mask[i]) {
272 vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]);
273 }
274 }
275 } else {
276 /* read all pixels */
277 for (i = 0; i < n; i++) {
278 vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]);
279 }
280 }
281 }
282
283
284 /****************************************************************************
285 * Index
286 ***************************************************************************/
287 static void
288 write_index_span (const GLcontext *ctx, struct gl_renderbuffer *rb,
289 GLuint n, GLint x, GLint y,
290 const GLuint index[], const GLubyte mask[])
291 {
292 const DMesaContext dmesa = (DMesaContext)ctx;
293 GLuint i, offset;
294
295 offset = DSTRIDE * FLIP(y) + x;
296 if (mask) {
297 /* draw some pixels */
298 for (i = 0; i < n; i++, offset++) {
299 if (mask[i]) {
300 vl_putpixel(offset, index[i]);
301 }
302 }
303 } else {
304 /* draw all pixels */
305 for (i = 0; i < n; i++, offset++) {
306 vl_putpixel(offset, index[i]);
307 }
308 }
309 }
310
311
312 static void
313 write_index8_span (const GLcontext *ctx, struct gl_renderbuffer *rb,
314 GLuint n, GLint x, GLint y,
315 const GLubyte index[], const GLubyte mask[])
316 {
317 const DMesaContext dmesa = (DMesaContext)ctx;
318 GLuint i, offset;
319
320 offset = DSTRIDE * FLIP(y) + x;
321 if (mask) {
322 /* draw some pixels */
323 for (i = 0; i < n; i++, offset++) {
324 if (mask[i]) {
325 vl_putpixel(offset, index[i]);
326 }
327 }
328 } else {
329 /* draw all pixels */
330 for (i = 0; i < n; i++, offset++) {
331 vl_putpixel(offset, index[i]);
332 }
333 }
334 }
335
336
337 static void
338 write_mono_index_span (const GLcontext *ctx, struct gl_renderbuffer *rb,
339 GLuint n, GLint x, GLint y,
340 GLuint colorIndex, const GLubyte mask[])
341 {
342 const DMesaContext dmesa = (DMesaContext)ctx;
343 GLuint i, offset;
344
345 offset = DSTRIDE * FLIP(y) + x;
346 if (mask) {
347 /* draw some pixels */
348 for (i = 0; i < n; i++, offset++) {
349 if (mask[i]) {
350 vl_putpixel(offset, colorIndex);
351 }
352 }
353 } else {
354 /* draw all pixels */
355 for (i = 0; i < n; i++, offset++) {
356 vl_putpixel(offset, colorIndex);
357 }
358 }
359 }
360
361
362 static void
363 read_index_span (const GLcontext *ctx, struct gl_renderbuffer *rb,
364 GLuint n, GLint x, GLint y, GLuint index[])
365 {
366 const DMesaContext dmesa = (DMesaContext)ctx;
367 GLuint i, offset;
368
369 offset = DSTRIDE * FLIP(y) + x;
370 /* read all pixels */
371 for (i = 0; i < n; i++, offset++) {
372 index[i] = vl_getpixel(offset);
373 }
374 }
375
376
377 static void
378 write_index_pixels (const GLcontext *ctx, struct gl_renderbuffer *rb,
379 GLuint n, const GLint x[], const GLint y[],
380 const GLuint index[], const GLubyte mask[])
381 {
382 const DMesaContext dmesa = (DMesaContext)ctx;
383 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1;
384
385 if (mask) {
386 /* draw some pixels */
387 for (i = 0; i < n; i++) {
388 if (mask[i]) {
389 vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]);
390 }
391 }
392 } else {
393 /* draw all pixels */
394 for (i = 0; i < n; i++) {
395 vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]);
396 }
397 }
398 }
399
400
401 static void
402 write_mono_index_pixels (const GLcontext *ctx, struct gl_renderbuffer *rb,
403 GLuint n, const GLint x[], const GLint y[],
404 GLuint colorIndex, const GLubyte mask[])
405 {
406 const DMesaContext dmesa = (DMesaContext)ctx;
407 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1;
408
409 if (mask) {
410 /* draw some pixels */
411 for (i = 0; i < n; i++) {
412 if (mask[i]) {
413 vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex);
414 }
415 }
416 } else {
417 /* draw all pixels */
418 for (i = 0; i < n; i++) {
419 vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex);
420 }
421 }
422 }
423
424
425 static void
426 read_index_pixels (const GLcontext *ctx, struct gl_renderbuffer *rb,
427 GLuint n, const GLint x[], const GLint y[],
428 GLuint index[], const GLubyte mask[])
429 {
430 const DMesaContext dmesa = (DMesaContext)ctx;
431 GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1;
432
433 if (mask) {
434 /* read some pixels */
435 for (i = 0; i < n; i++) {
436 if (mask[i]) {
437 index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]);
438 }
439 }
440 } else {
441 /* read all pixels */
442 for (i = 0; i < n; i++) {
443 index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]);
444 }
445 }
446 }
447
448
449 /****************************************************************************
450 * Z-buffer
451 ***************************************************************************/
452
453
454 /****************************************************************************
455 * Optimized triangle rendering
456 ***************************************************************************/
457
458 /*
459 * NON-depth-buffered flat triangle.
460 */
461 #define NAME tri_rgb_flat
462
463 #define SETUP_CODE \
464 const DMesaContext dmesa = (DMesaContext)ctx;\
465 GLuint _b_ = dmesa->buffer->height - 1; \
466 GLuint _w_ = dmesa->buffer->width; \
467 GLuint rgb = vl_mixrgb(v2->color);
468
469 #define RENDER_SPAN(span) \
470 GLuint i, offset = FLIP2(span.y)*_w_ + span.x;\
471 for (i = 0; i < span.end; i++, offset++) { \
472 vl_putpixel(offset, rgb); \
473 }
474
475 #include "swrast/s_tritemp.h"
476
477
478 /*
479 * Z-less flat triangle.
480 */
481 #define NAME tri_rgb_flat_zless
482
483 #define INTERP_Z 1
484 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
485
486 #define SETUP_CODE \
487 const DMesaContext dmesa = (DMesaContext)ctx; \
488 GLuint _b_ = dmesa->buffer->height - 1; \
489 GLuint _w_ = dmesa->buffer->width; \
490 GLuint rgb = vl_mixrgb(v2->color);
491
492 #define RENDER_SPAN(span) \
493 GLuint i, offset = FLIP2(span.y)*_w_ + span.x;\
494 for (i = 0; i < span.end; i++, offset++) { \
495 const DEPTH_TYPE z = FixedToDepth(span.z);\
496 if (z < zRow[i]) { \
497 vl_putpixel(offset, rgb); \
498 zRow[i] = z; \
499 } \
500 span.z += span.zStep; \
501 }
502
503 #include "swrast/s_tritemp.h"
504
505
506 /*
507 * NON-depth-buffered iterated triangle.
508 */
509 #define NAME tri_rgb_iter
510
511 #define INTERP_RGB 1
512
513 #define SETUP_CODE \
514 const DMesaContext dmesa = (DMesaContext)ctx;\
515 GLuint _b_ = dmesa->buffer->height - 1; \
516 GLuint _w_ = dmesa->buffer->width;
517
518 #define RENDER_SPAN(span) \
519 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
520 for (i = 0; i < span.end; i++, offset++) { \
521 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue)); \
522 span.red += span.redStep; \
523 span.green += span.greenStep; \
524 span.blue += span.blueStep; \
525 }
526
527 #include "swrast/s_tritemp.h"
528
529
530 /*
531 * Z-less iterated triangle.
532 */
533 #define NAME tri_rgb_iter_zless
534
535 #define INTERP_Z 1
536 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
537 #define INTERP_RGB 1
538
539 #define SETUP_CODE \
540 const DMesaContext dmesa = (DMesaContext)ctx;\
541 GLuint _b_ = dmesa->buffer->height - 1; \
542 GLuint _w_ = dmesa->buffer->width;
543
544 #define RENDER_SPAN(span) \
545 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
546 for (i = 0; i < span.end; i++, offset++) { \
547 const DEPTH_TYPE z = FixedToDepth(span.z); \
548 if (z < zRow[i]) { \
549 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\
550 zRow[i] = z; \
551 } \
552 span.red += span.redStep; \
553 span.green += span.greenStep; \
554 span.blue += span.blueStep; \
555 span.z += span.zStep; \
556 }
557
558 #include "swrast/s_tritemp.h"
559
560
561 /*
562 * Analyze context state to see if we can provide a fast triangle function
563 * Otherwise, return NULL.
564 */
565 static swrast_tri_func
566 dmesa_choose_tri_function (GLcontext *ctx)
567 {
568 const SWcontext *swrast = SWRAST_CONTEXT(ctx);
569
570 if ((ctx->RenderMode != GL_RENDER)
571 || (ctx->Polygon.SmoothFlag)
572 || (ctx->Polygon.StippleFlag)
573 || (ctx->Texture._EnabledUnits)
574 || (swrast->_RasterMask & MULTI_DRAW_BIT)
575 || (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)) {
576 return (swrast_tri_func)NULL;
577 }
578
579 if (swrast->_RasterMask==DEPTH_BIT
580 && ctx->Depth.Func==GL_LESS
581 && ctx->Depth.Mask==GL_TRUE
582 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
583 return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter_zless : tri_rgb_flat_zless;
584 }
585
586 if (swrast->_RasterMask==0) { /* no depth test */
587 return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter : tri_rgb_flat;
588 }
589
590 return (swrast_tri_func)NULL;
591 }
592
593
594 /* Override for the swrast triangle-selection function. Try to use one
595 * of our internal triangle functions, otherwise fall back to the
596 * standard swrast functions.
597 */
598 static void
599 dmesa_choose_tri (GLcontext *ctx)
600 {
601 SWcontext *swrast = SWRAST_CONTEXT(ctx);
602
603 if (!(swrast->Triangle=dmesa_choose_tri_function(ctx))) {
604 _swrast_choose_triangle(ctx);
605 }
606 }
607
608
609 /****************************************************************************
610 * Optimized line rendering
611 ***************************************************************************/
612
613 /*
614 * NON-depth-buffered flat line.
615 */
616 #define NAME line_rgb_flat
617
618 #define INTERP_XY 1
619 #define CLIP_HACK 1
620
621 #define SETUP_CODE \
622 const DMesaContext dmesa = (DMesaContext)ctx;\
623 GLuint _b_ = dmesa->buffer->height - 1; \
624 GLuint _w_ = dmesa->buffer->width; \
625 GLuint rgb = vl_mixrgb(vert1->color);
626
627 #define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb);
628
629 #include "swrast/s_linetemp.h"
630
631
632 /*
633 * Z-less flat line.
634 */
635 #define NAME line_rgb_flat_zless
636
637 #define INTERP_XY 1
638 #define INTERP_Z 1
639 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
640 #define CLIP_HACK 1
641
642 #define SETUP_CODE \
643 const DMesaContext dmesa = (DMesaContext)ctx;\
644 GLuint _b_ = dmesa->buffer->height - 1; \
645 GLuint _w_ = dmesa->buffer->width; \
646 GLuint rgb = vl_mixrgb(vert1->color);
647
648 #define PLOT(X,Y) \
649 if (Z < *zPtr) { \
650 *zPtr = Z; \
651 vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \
652 }
653
654 #include "swrast/s_linetemp.h"
655
656
657 /*
658 * NON-depth-buffered iterated line.
659 */
660 #define line_rgb_iter NULL
661
662
663 /*
664 * Z-less iterated line.
665 */
666 #define line_rgb_iter_zless NULL
667
668
669 /*
670 * Analyze context state to see if we can provide a fast line function
671 * Otherwise, return NULL.
672 */
673 static swrast_line_func
674 dmesa_choose_line_function (GLcontext *ctx)
675 {
676 const SWcontext *swrast = SWRAST_CONTEXT(ctx);
677
678 if ((ctx->RenderMode != GL_RENDER)
679 || (ctx->Line.SmoothFlag)
680 || (ctx->Texture._EnabledUnits)
681 || (ctx->Line.StippleFlag)
682 || (swrast->_RasterMask & MULTI_DRAW_BIT)
683 || (ctx->Line.Width!=1.0F)) {
684 return (swrast_line_func)NULL;
685 }
686
687 if (swrast->_RasterMask==DEPTH_BIT
688 && ctx->Depth.Func==GL_LESS
689 && ctx->Depth.Mask==GL_TRUE
690 && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {
691 return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter_zless : line_rgb_flat_zless;
692 }
693
694 if (swrast->_RasterMask==0) { /* no depth test */
695 return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter : line_rgb_flat;
696 }
697
698 return (swrast_line_func)NULL;
699 }
700
701
702 /* Override for the swrast line-selection function. Try to use one
703 * of our internal line functions, otherwise fall back to the
704 * standard swrast functions.
705 */
706 static void
707 dmesa_choose_line (GLcontext *ctx)
708 {
709 SWcontext *swrast = SWRAST_CONTEXT(ctx);
710
711 if (!(swrast->Line=dmesa_choose_line_function(ctx))) {
712 _swrast_choose_line(ctx);
713 }
714 }
715
716
717 /****************************************************************************
718 * Miscellaneous device driver funcs
719 ***************************************************************************/
720 static const struct gl_texture_format *
721 choose_tex_format (GLcontext *ctx, GLint internalFormat,
722 GLenum format, GLenum type)
723 {
724 switch (internalFormat) {
725 case GL_COMPRESSED_RGB_ARB:
726 return &_mesa_texformat_rgb;
727 case GL_COMPRESSED_RGBA_ARB:
728 return &_mesa_texformat_rgba;
729 default:
730 return _mesa_choose_tex_format(ctx, internalFormat, format, type);
731 }
732 }
733
734
735 static void
736 clear_index (GLcontext *ctx, GLuint index)
737 {
738 ((DMesaContext)ctx)->ClearIndex = index;
739 }
740
741
742 static void
743 clear_color (GLcontext *ctx, const GLfloat color[4])
744 {
745 GLubyte col[4];
746 CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);
747 CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);
748 CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);
749 CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]);
750 ((DMesaContext)ctx)->ClearColor = vl_mixrgba(col);
751 }
752
753
754 static void
755 clear (GLcontext *ctx, GLbitfield mask, GLboolean all,
756 GLint x, GLint y, GLint width, GLint height)
757 {
758 const DMesaContext c = (DMesaContext)ctx;
759 const GLuint *colorMask = (GLuint *)&ctx->Color.ColorMask;
760
761 /*
762 * Clear the specified region of the buffers indicated by 'mask'
763 * using the clear color or index as specified by one of the two
764 * functions above.
765 * If all==GL_TRUE, clear whole buffer, else just clear region defined
766 * by x,y,width,height
767 */
768
769 /* we can't handle color or index masking */
770 if ((*colorMask == 0xffffffff) && (ctx->Color.IndexMask == 0xffffffff)) {
771 if (mask & DD_BACK_LEFT_BIT) {
772 int color = ((GLvisual *)(c->visual))->rgbMode ? c->ClearColor : c->ClearIndex;
773
774 if (all) {
775 vl_clear(color);
776 } else {
777 vl_rect(x, c->buffer->height - y - height, width, height, color);
778 }
779
780 mask &= ~DD_BACK_LEFT_BIT;
781 }
782 }
783
784 if (mask) {
785 _swrast_Clear(ctx, mask, all, x, y, width, height);
786 }
787 }
788
789
790 /*
791 * Return the width and height of the current buffer.
792 * If anything special has to been done when the buffer/window is
793 * resized, do it now.
794 */
795 static void
796 get_buffer_size (GLframebuffer *buffer, GLuint *width, GLuint *height)
797 {
798 DMesaBuffer b = (DMesaBuffer)buffer;
799
800 *width = b->width;
801 *height = b->height;
802 }
803
804
805 static void
806 viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
807 {
808 /* poll for window size change and realloc software Z/stencil/etc if needed */
809 _mesa_ResizeBuffersMESA();
810 }
811
812
813 static const GLubyte *
814 get_string (GLcontext *ctx, GLenum name)
815 {
816 switch (name) {
817 case GL_RENDERER:
818 return (const GLubyte *)"Mesa DJGPP";
819 default:
820 return NULL;
821 }
822 }
823
824
825 static void
826 finish (GLcontext *ctx)
827 {
828 /*
829 * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible
830 */
831 }
832
833
834 static void
835 flush (GLcontext *ctx)
836 {
837 /*
838 * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible
839 */
840 }
841
842
843 /****************************************************************************
844 * State
845 ***************************************************************************/
846 #define DMESA_NEW_LINE (_NEW_LINE | \
847 _NEW_TEXTURE | \
848 _NEW_LIGHT | \
849 _NEW_DEPTH | \
850 _NEW_RENDERMODE | \
851 _SWRAST_NEW_RASTERMASK)
852
853 #define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \
854 _NEW_TEXTURE | \
855 _NEW_LIGHT | \
856 _NEW_DEPTH | \
857 _NEW_RENDERMODE | \
858 _SWRAST_NEW_RASTERMASK)
859
860 /* Extend the software rasterizer with our line and triangle
861 * functions.
862 */
863 static void
864 dmesa_register_swrast_functions (GLcontext *ctx)
865 {
866 SWcontext *swrast = SWRAST_CONTEXT(ctx);
867
868 swrast->choose_line = dmesa_choose_line;
869 swrast->choose_triangle = dmesa_choose_tri;
870
871 swrast->invalidate_line |= DMESA_NEW_LINE;
872 swrast->invalidate_triangle |= DMESA_NEW_TRIANGLE;
873 }
874
875
876 static void
877 dmesa_update_state (GLcontext *ctx, GLuint new_state)
878 {
879 /* Propagate statechange information to swrast and swrast_setup
880 * modules. The DMesa driver has no internal GL-dependent state.
881 */
882 _swrast_InvalidateState( ctx, new_state );
883 _ac_InvalidateState( ctx, new_state );
884 _tnl_InvalidateState( ctx, new_state );
885 _swsetup_InvalidateState( ctx, new_state );
886 }
887
888
889 /* Initialize the device driver function table with the functions
890 * we implement in this driver.
891 */
892 static void
893 dmesa_init_driver_functions (DMesaVisual visual,
894 struct dd_function_table *driver)
895 {
896 driver->UpdateState = dmesa_update_state;
897 driver->GetString = get_string;
898 driver->GetBufferSize = get_buffer_size;
899 driver->Viewport = viewport;
900 driver->Flush = flush;
901 driver->Finish = finish;
902 driver->Clear = clear;
903 driver->ClearColor = clear_color;
904 driver->ClearIndex = clear_index;
905 #if SWTC
906 driver->ChooseTextureFormat = choose_tex_format;
907 #endif
908 }
909
910
911 /* Setup pointers and other driver state that is constant for the life
912 * of a context.
913 */
914 static void
915 dmesa_init_pointers (GLcontext *ctx)
916 {
917 struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference(ctx);
918
919 /* The span functions should be in `dmesa_update_state', but I'm
920 * pretty sure they will never change during the life of the Visual
921 */
922
923 /* Index span/pixel functions */
924 dd->WriteCI32Span = write_index_span;
925 dd->WriteCI8Span = write_index8_span;
926 dd->WriteMonoCISpan = write_mono_index_span;
927 dd->WriteCI32Pixels = write_index_pixels;
928 dd->WriteMonoCIPixels = write_mono_index_pixels;
929 dd->ReadCI32Span = read_index_span;
930 dd->ReadCI32Pixels = read_index_pixels;
931
932 /* RGB(A) span/pixel functions */
933 dd->WriteRGBASpan = write_rgba_span;
934 dd->WriteRGBSpan = write_rgb_span;
935 dd->WriteMonoRGBASpan = write_mono_rgba_span;
936 dd->WriteRGBAPixels = write_rgba_pixels;
937 dd->WriteMonoRGBAPixels = write_mono_rgba_pixels;
938 dd->ReadRGBASpan = read_rgba_span;
939 dd->ReadRGBAPixels = read_rgba_pixels;
940 }
941 #endif /* FX */
942
943
944 /****************************************************************************
945 * DMesa Public API Functions
946 ***************************************************************************/
947
948 /*
949 * The exact arguments to this function will depend on your window system
950 */
951 DMesaVisual
952 DMesaCreateVisual (GLint width,
953 GLint height,
954 GLint colDepth,
955 GLint refresh,
956 GLboolean dbFlag,
957 GLboolean rgbFlag,
958 GLint alphaSize,
959 GLint depthSize,
960 GLint stencilSize,
961 GLint accumSize)
962 {
963 DMesaVisual v;
964 GLint redBits, greenBits, blueBits, alphaBits, indexBits;
965 GLboolean sw_alpha;
966
967 alphaBits = 0;
968
969 if (!rgbFlag) {
970 indexBits = 8;
971 redBits = 0;
972 greenBits = 0;
973 blueBits = 0;
974 } else {
975 indexBits = 0;
976 switch (colDepth) {
977 case 8:
978 redBits = 8;
979 greenBits = 8;
980 blueBits = 8;
981 break;
982 case 15:
983 alphaBits = 1;
984 redBits = 5;
985 greenBits = 5;
986 blueBits = 5;
987 break;
988 case 16:
989 redBits = 5;
990 greenBits = 6;
991 blueBits = 5;
992 break;
993 case 32:
994 alphaBits = 8;
995 case 24:
996 redBits = 8;
997 greenBits = 8;
998 blueBits = 8;
999 break;
1000 default:
1001 return NULL;
1002 }
1003 }
1004
1005 /* Okay,
1006 * `alphaBits' is what we can provide
1007 * `alphaSize' is what app requests
1008 *
1009 * Note that alpha buffering is required only if destination alpha is used
1010 * in alpha blending; alpha blending modes that do not use destination alpha
1011 * can be used w/o alpha buffer.
1012 *
1013 * We will use whatever ALPHA app requests. Later, in `CreateBuffer' we'll
1014 * instruct Mesa to use its own ALPHA buffer, by passing a non-FALSE value
1015 * for ALPHA to `_mesa_initialize_framebuffer'.
1016 *
1017 * Basically, 32bit modes provide ALPHA storage, but can we rely on this?
1018 */
1019 alphaBits = alphaSize;
1020 sw_alpha = (alphaBits > 0);
1021
1022 #ifndef FX
1023 if (!dbFlag) {
1024 return NULL;
1025 }
1026 if ((colDepth=vl_video_init(width, height, colDepth, rgbFlag, refresh)) <= 0) {
1027 return NULL;
1028 }
1029 #else /* FX */
1030 if (!rgbFlag) {
1031 return NULL;
1032 } else {
1033 char *env;
1034
1035 if ((env = getenv("MESA_FX_INFO")) && (env[0] == 'r')) {
1036 freopen("MESA.LOG", "w", stderr);
1037 }
1038
1039 if (refresh && (((env = getenv("FX_GLIDE_REFRESH")) == NULL) || !atoi(env))) {
1040 /* if we are passed non-zero value for refresh, we need to override
1041 * default refresh rate. However, if FX_GLIDE_REFRESH is already set
1042 * to 0, we won't override it, because it has a special meaning for
1043 * DJGPP Glide3x (switch via VESA, using BIOS default refresh).
1044 */
1045 char tmp[32];
1046 sprintf(tmp, "FX_GLIDE_REFRESH=%u", refresh);
1047 putenv(tmp);
1048 }
1049 }
1050 #endif /* FX */
1051
1052 if ((v=(DMesaVisual)CALLOC_STRUCT(dmesa_visual)) != NULL) {
1053 /* Create core visual */
1054 _mesa_initialize_visual((GLvisual *)v,
1055 rgbFlag, /* rgb */
1056 dbFlag,
1057 GL_FALSE, /* stereo */
1058 redBits,
1059 greenBits,
1060 blueBits,
1061 alphaBits,
1062 indexBits, /* indexBits */
1063 depthSize,
1064 stencilSize,
1065 accumSize, /* accumRed */
1066 accumSize, /* accumGreen */
1067 accumSize, /* accumBlue */
1068 alphaBits?accumSize:0, /* accumAlpha */
1069 1); /* numSamples */
1070
1071 #ifndef FX
1072 v->sw_alpha = sw_alpha;
1073 v->z_buffer = (depthSize > 0) ? 1 : 0;
1074 #endif
1075 }
1076
1077 return v;
1078 }
1079
1080
1081 void
1082 DMesaDestroyVisual (DMesaVisual v)
1083 {
1084 #ifndef FX
1085 vl_video_exit();
1086 #endif
1087 _mesa_destroy_visual((GLvisual *)v);
1088 }
1089
1090
1091 DMesaBuffer
1092 DMesaCreateBuffer (DMesaVisual visual,
1093 GLint xpos, GLint ypos,
1094 GLint width, GLint height)
1095 {
1096 #ifndef FX
1097 DMesaBuffer b;
1098
1099 if ((b=(DMesaBuffer)CALLOC_STRUCT(dmesa_buffer)) != NULL) {
1100 _mesa_initialize_framebuffer((GLframebuffer *)b,
1101 (GLvisual *)visual,
1102 visual->z_buffer == 1,
1103 ((GLvisual *)visual)->stencilBits > 0,
1104 ((GLvisual *)visual)->accumRedBits > 0,
1105 visual->sw_alpha);
1106 b->xpos = xpos;
1107 b->ypos = ypos;
1108 b->width = width;
1109 b->height = height;
1110 }
1111
1112 return b;
1113 #else /* FX */
1114
1115 GLvisual *v = (GLvisual *)visual;
1116 int i = 0, fx_attrib[32];
1117
1118 if (v->doubleBufferMode) fx_attrib[i++] = FXMESA_DOUBLEBUFFER;
1119 if (v->depthBits > 0) { fx_attrib[i++] = FXMESA_DEPTH_SIZE; fx_attrib[i++] = v->depthBits; }
1120 if (v->stencilBits > 0) { fx_attrib[i++] = FXMESA_STENCIL_SIZE; fx_attrib[i++] = v->stencilBits; }
1121 if (v->accumRedBits > 0) { fx_attrib[i++] = FXMESA_ACCUM_SIZE; fx_attrib[i++] = v->accumRedBits; }
1122 if (v->alphaBits) { fx_attrib[i++] = FXMESA_ALPHA_SIZE; fx_attrib[i++] = v->alphaBits; }
1123 fx_attrib[i++] = FXMESA_COLORDEPTH;
1124 fx_attrib[i++] = v->redBits + v->greenBits + v->blueBits;
1125 fx_attrib[i] = FXMESA_NONE;
1126
1127 return (DMesaBuffer)fxMesaCreateBestContext(-1, width, height, fx_attrib);
1128 #endif /* FX */
1129 }
1130
1131
1132 void
1133 DMesaDestroyBuffer (DMesaBuffer b)
1134 {
1135 #ifndef FX
1136 if (b->the_window != NULL) {
1137 free(b->the_window);
1138 }
1139 _mesa_destroy_framebuffer((GLframebuffer *)b);
1140 #else
1141 fxMesaDestroyContext((fxMesaContext)b);
1142 #endif
1143 }
1144
1145
1146 DMesaContext
1147 DMesaCreateContext (DMesaVisual visual, DMesaContext share)
1148 {
1149 GLcontext *c;
1150 #ifndef FX
1151 TNLcontext *tnl;
1152 struct dd_function_table functions;
1153
1154 if ((c=(GLcontext *)CALLOC_STRUCT(dmesa_context)) != NULL) {
1155 /* Initialize device driver function table */
1156 _mesa_init_driver_functions(&functions);
1157 /* override with our functions */
1158 dmesa_init_driver_functions(visual, &functions);
1159
1160 _mesa_initialize_context(c,
1161 (GLvisual *)visual,
1162 (GLcontext *)share,
1163 &functions,
1164 (void *)c);
1165
1166 _mesa_enable_sw_extensions(c);
1167 _mesa_enable_1_3_extensions(c);
1168 _mesa_enable_1_4_extensions(c);
1169 _mesa_enable_1_5_extensions(c);
1170 _mesa_enable_2_0_extensions(c);
1171 #if SWTC
1172 if (c->Mesa_DXTn) {
1173 _mesa_enable_extension(c, "GL_EXT_texture_compression_s3tc");
1174 _mesa_enable_extension(c, "GL_S3_s3tc");
1175 }
1176 _mesa_enable_extension(c, "GL_3DFX_texture_compression_FXT1");
1177 #endif
1178
1179 /* you probably have to do a bunch of other initializations here. */
1180 ((DMesaContext)c)->visual = visual;
1181
1182 /* Initialize the software rasterizer and helper modules.
1183 */
1184 _swrast_CreateContext(c);
1185 _ac_CreateContext(c);
1186 _tnl_CreateContext(c);
1187 _swsetup_CreateContext(c);
1188 /* tnl setup */
1189 tnl = TNL_CONTEXT(c);
1190 tnl->Driver.RunPipeline = _tnl_run_pipeline;
1191 /* swrast setup */
1192 if (((GLvisual *)visual)->rgbMode) dmesa_register_swrast_functions(c);
1193 dmesa_init_pointers(c);
1194 _swsetup_Wakeup(c);
1195 }
1196
1197 #else /* FX */
1198 c = (GLcontext *)0xdeadbeef;
1199 #endif /* FX */
1200
1201 return (DMesaContext)c;
1202 }
1203
1204
1205 void
1206 DMesaDestroyContext (DMesaContext c)
1207 {
1208 #ifndef FX
1209 if (c) {
1210 _swsetup_DestroyContext((GLcontext *)c);
1211 _swrast_DestroyContext((GLcontext *)c);
1212 _tnl_DestroyContext((GLcontext *)c);
1213 _ac_DestroyContext((GLcontext *)c);
1214 _mesa_destroy_context((GLcontext *)c);
1215 }
1216 #endif
1217 }
1218
1219
1220 GLboolean
1221 DMesaMoveBuffer (GLint xpos, GLint ypos)
1222 {
1223 #ifndef FX
1224 GET_CURRENT_CONTEXT(ctx);
1225 DMesaBuffer b = ((DMesaContext)ctx)->buffer;
1226
1227 if (vl_sync_buffer(&b->the_window, xpos, ypos, b->width, b->height) == 0) {
1228 b->xpos = xpos;
1229 b->ypos = ypos;
1230 return GL_TRUE;
1231 }
1232 #endif
1233
1234 return GL_FALSE;
1235 }
1236
1237
1238 GLboolean
1239 DMesaResizeBuffer (GLint width, GLint height)
1240 {
1241 #ifndef FX
1242 GET_CURRENT_CONTEXT(ctx);
1243 DMesaBuffer b = ((DMesaContext)ctx)->buffer;
1244
1245 if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, width, height) == 0) {
1246 b->width = width;
1247 b->height = height;
1248 return GL_TRUE;
1249 }
1250 #endif
1251
1252 return GL_FALSE;
1253 }
1254
1255
1256 /*
1257 * Make the specified context and buffer the current one.
1258 */
1259 GLboolean
1260 DMesaMakeCurrent (DMesaContext c, DMesaBuffer b)
1261 {
1262 #ifndef FX
1263 if ((c != NULL) && (b != NULL)) {
1264 if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, b->width, b->height) != 0) {
1265 return GL_FALSE;
1266 }
1267
1268 c->buffer = b;
1269
1270 _mesa_make_current((GLcontext *)c, (GLframebuffer *)b);
1271 }
1272 else {
1273 /* Detach */
1274 _mesa_make_current(NULL, NULL);
1275 }
1276
1277 #else
1278 fxMesaMakeCurrent((fxMesaContext)b);
1279 #endif
1280
1281 return GL_TRUE;
1282 }
1283
1284
1285 void
1286 DMesaSwapBuffers (DMesaBuffer b)
1287 {
1288 /* copy/swap back buffer to front if applicable */
1289 #ifndef FX
1290 GET_CURRENT_CONTEXT(ctx);
1291 _mesa_notifySwapBuffers(ctx);
1292 vl_flip();
1293 #else
1294 fxMesaSwapBuffers();
1295 #endif
1296 }
1297
1298
1299 void
1300 DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue)
1301 {
1302 #ifndef FX
1303 vl_setCI(ndx, red, green, blue);
1304 #endif
1305 }
1306
1307
1308 DMesaContext
1309 DMesaGetCurrentContext (void)
1310 {
1311 GET_CURRENT_CONTEXT(ctx);
1312
1313 #ifndef FX
1314 #else
1315 if (ctx != NULL) {
1316 ctx = (GLcontext *)0xdeadbeef;
1317 }
1318 #endif
1319
1320 return (DMesaContext)ctx;
1321 }
1322
1323
1324 DMesaBuffer
1325 DMesaGetCurrentBuffer (void)
1326 {
1327 const DMesaContext dmesa = DMesaGetCurrentContext();
1328
1329 if (dmesa == NULL) {
1330 return NULL;
1331 }
1332
1333 #ifndef FX
1334 return dmesa->buffer;
1335 #else
1336 return (DMesaBuffer)fxMesaGetCurrentContext();
1337 #endif
1338 }
1339
1340
1341 DMesaProc
1342 DMesaGetProcAddress (const char *name)
1343 {
1344 DMesaProc p = (DMesaProc)_glapi_get_proc_address(name);
1345
1346 /* TODO: handle DMesa* namespace
1347 if (p == NULL) {
1348 }
1349 */
1350
1351 return p;
1352 }
1353
1354
1355 int
1356 DMesaGetIntegerv (GLenum pname, GLint *params)
1357 {
1358 switch (pname) {
1359 case DMESA_GET_SCREEN_SIZE:
1360 #ifndef FX
1361 vl_get(VL_GET_SCREEN_SIZE, params);
1362 #else
1363 fxGetScreenGeometry(&params[0], &params[1]);
1364 #endif
1365 break;
1366 case DMESA_GET_DRIVER_CAPS:
1367 #ifndef FX
1368 params[0] = DMESA_DRIVER_SWDB_BIT;
1369 #else
1370 params[0] = DMESA_DRIVER_LLWO_BIT;
1371 #endif
1372 break;
1373 case DMESA_GET_VIDEO_MODES:
1374 #ifndef FX
1375 return vl_get(VL_GET_VIDEO_MODES, params);
1376 #else
1377 return -1; /* TODO */
1378 #endif
1379 case DMESA_GET_BUFFER_ADDR: {
1380 #ifndef FX
1381 DMesaContext c = (DMesaContext)DMesaGetCurrentContext();
1382 if (c != NULL) {
1383 DMesaBuffer b = c->buffer;
1384 if (b != NULL) {
1385 params[0] = (GLint)b->the_window;
1386 }
1387 }
1388 break;
1389 #else
1390 return -1;
1391 #endif
1392 }
1393 default:
1394 return -1;
1395 }
1396
1397 return 0;
1398 }
1399
1400
1401 #if SWTC && (((__DJGPP__ << 8) | __DJGPP_MINOR__) >= 0x204)
1402 #include <sys/dxe.h>
1403
1404 extern_asm(___dj_assert);
1405 extern_asm(_free);
1406 extern_asm(_malloc);
1407 extern_asm(_memset);
1408
1409 DXE_EXPORT_TABLE_AUTO (___dxe_eta___dxtn)
1410 DXE_EXPORT_ASM (___dj_assert)
1411 DXE_EXPORT_ASM (_free)
1412 DXE_EXPORT_ASM (_malloc)
1413 DXE_EXPORT_ASM (_memset)
1414 DXE_EXPORT_END
1415 #endif