2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2004 Brian Paul All Rights Reserved.
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:
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
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.
26 * DOS/DJGPP device driver v1.7 for Mesa
28 * Copyright (c) 2003 - Daniel Borca
29 * Email : dborca@users.sourceforge.net
30 * Web : http://www.geocities.com/dborca
38 #include "bufferobj.h"
40 #include "extensions.h"
44 #include "texformat.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"
55 #include "tnl/t_context.h"
56 #include "tnl/t_pipeline.h"
57 #include "drivers/common/driverfuncs.h"
60 #include "GL/fxmesa.h"
66 #define SWTC 0 /* SW texture compression */
70 * In C++ terms, this class derives from the GLvisual class.
71 * Add system-specific fields to it.
75 GLboolean sw_alpha
; /* use Mesa's alpha buffer? */
76 int z_buffer
; /* Z=buffer: 0=no, 1=SW, -1=HW */
80 * In C++ terms, this class derives from the GLframebuffer class.
81 * Add system-specific fields to it.
84 GLframebuffer gl_buffer
; /* The depth, stencil, accum, etc buffers */
85 void *the_window
; /* your window handle, etc */
87 int xpos
, ypos
; /* position */
88 int width
, height
; /* size in pixels */
92 * In C++ terms, this class derives from the GLcontext class.
93 * Add system-specific fields to it.
95 struct dmesa_context
{
96 GLcontext gl_ctx
; /* the core library context */
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.
113 /****************************************************************************
115 ***************************************************************************/
116 #define FLIP(y) (dmesa->buffer->height - (y) - 1)
117 #define FLIP2(y) (_b_ - (y))
119 #define DSTRIDE dmesa->buffer->width
121 /****************************************************************************
123 ***************************************************************************/
125 write_rgba_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
126 const GLubyte rgba
[][4], const GLubyte mask
[])
128 const DMesaContext dmesa
= (DMesaContext
)ctx
;
131 offset
= DSTRIDE
* FLIP(y
) + x
;
133 /* draw some pixels */
134 for (i
= 0; i
< n
; i
++, offset
++) {
136 vl_putpixel(offset
, vl_mixrgba(rgba
[i
]));
140 /* draw all pixels */
141 for (i
= 0; i
< n
; i
++, offset
++) {
142 vl_putpixel(offset
, vl_mixrgba(rgba
[i
]));
149 write_rgb_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
150 const GLubyte rgb
[][3], const GLubyte mask
[])
152 const DMesaContext dmesa
= (DMesaContext
)ctx
;
155 offset
= DSTRIDE
* FLIP(y
) + x
;
157 /* draw some pixels */
158 for (i
= 0; i
< n
; i
++, offset
++) {
160 vl_putpixel(offset
, vl_mixrgb(rgb
[i
]));
164 /* draw all pixels */
165 for (i
= 0; i
< n
; i
++, offset
++) {
166 vl_putpixel(offset
, vl_mixrgb(rgb
[i
]));
173 write_mono_rgba_span (const GLcontext
*ctx
,
174 GLuint n
, GLint x
, GLint y
,
175 const GLchan color
[4], const GLubyte mask
[])
177 const DMesaContext dmesa
= (DMesaContext
)ctx
;
178 GLuint i
, offset
, rgba
= vl_mixrgba(color
);
180 offset
= DSTRIDE
* FLIP(y
) + x
;
182 /* draw some pixels */
183 for (i
= 0; i
< n
; i
++, offset
++) {
185 vl_putpixel(offset
, rgba
);
189 /* draw all pixels */
190 for (i
= 0; i
< n
; i
++, offset
++) {
191 vl_putpixel(offset
, rgba
);
198 read_rgba_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
201 const DMesaContext dmesa
= (DMesaContext
)ctx
;
204 offset
= DSTRIDE
* FLIP(y
) + x
;
205 /* read all pixels */
206 for (i
= 0; i
< n
; i
++, offset
++) {
207 vl_getrgba(offset
, rgba
[i
]);
213 write_rgba_pixels (const GLcontext
*ctx
,
214 GLuint n
, const GLint x
[], const GLint y
[],
215 const GLubyte rgba
[][4], const GLubyte mask
[])
217 const DMesaContext dmesa
= (DMesaContext
)ctx
;
218 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
221 /* draw some pixels */
222 for (i
= 0; i
< n
; i
++) {
224 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], vl_mixrgba(rgba
[i
]));
228 /* draw all pixels */
229 for (i
= 0; i
< n
; i
++) {
230 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], vl_mixrgba(rgba
[i
]));
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
[])
241 const DMesaContext dmesa
= (DMesaContext
)ctx
;
242 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1, rgba
= vl_mixrgba(color
);
245 /* draw some pixels */
246 for (i
= 0; i
< n
; i
++) {
248 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
);
252 /* draw all pixels */
253 for (i
= 0; i
< n
; i
++) {
254 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
);
261 read_rgba_pixels (const GLcontext
*ctx
,
262 GLuint n
, const GLint x
[], const GLint y
[],
263 GLubyte rgba
[][4], const GLubyte mask
[])
265 const DMesaContext dmesa
= (DMesaContext
)ctx
;
266 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
269 /* read some pixels */
270 for (i
= 0; i
< n
; i
++) {
272 vl_getrgba(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
[i
]);
276 /* read all pixels */
277 for (i
= 0; i
< n
; i
++) {
278 vl_getrgba(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
[i
]);
284 /****************************************************************************
286 ***************************************************************************/
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
[])
292 const DMesaContext dmesa
= (DMesaContext
)ctx
;
295 offset
= DSTRIDE
* FLIP(y
) + x
;
297 /* draw some pixels */
298 for (i
= 0; i
< n
; i
++, offset
++) {
300 vl_putpixel(offset
, index
[i
]);
304 /* draw all pixels */
305 for (i
= 0; i
< n
; i
++, offset
++) {
306 vl_putpixel(offset
, index
[i
]);
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
[])
317 const DMesaContext dmesa
= (DMesaContext
)ctx
;
320 offset
= DSTRIDE
* FLIP(y
) + x
;
322 /* draw some pixels */
323 for (i
= 0; i
< n
; i
++, offset
++) {
325 vl_putpixel(offset
, index
[i
]);
329 /* draw all pixels */
330 for (i
= 0; i
< n
; i
++, offset
++) {
331 vl_putpixel(offset
, index
[i
]);
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
[])
342 const DMesaContext dmesa
= (DMesaContext
)ctx
;
345 offset
= DSTRIDE
* FLIP(y
) + x
;
347 /* draw some pixels */
348 for (i
= 0; i
< n
; i
++, offset
++) {
350 vl_putpixel(offset
, colorIndex
);
354 /* draw all pixels */
355 for (i
= 0; i
< n
; i
++, offset
++) {
356 vl_putpixel(offset
, colorIndex
);
363 read_index_span (const GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
364 GLuint n
, GLint x
, GLint y
, GLuint index
[])
366 const DMesaContext dmesa
= (DMesaContext
)ctx
;
369 offset
= DSTRIDE
* FLIP(y
) + x
;
370 /* read all pixels */
371 for (i
= 0; i
< n
; i
++, offset
++) {
372 index
[i
] = vl_getpixel(offset
);
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
[])
382 const DMesaContext dmesa
= (DMesaContext
)ctx
;
383 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
386 /* draw some pixels */
387 for (i
= 0; i
< n
; i
++) {
389 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], index
[i
]);
393 /* draw all pixels */
394 for (i
= 0; i
< n
; i
++) {
395 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], index
[i
]);
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
[])
406 const DMesaContext dmesa
= (DMesaContext
)ctx
;
407 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
410 /* draw some pixels */
411 for (i
= 0; i
< n
; i
++) {
413 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], colorIndex
);
417 /* draw all pixels */
418 for (i
= 0; i
< n
; i
++) {
419 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], colorIndex
);
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
[])
430 const DMesaContext dmesa
= (DMesaContext
)ctx
;
431 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
434 /* read some pixels */
435 for (i
= 0; i
< n
; i
++) {
437 index
[i
] = vl_getpixel(FLIP2(y
[i
])*_w_
+ x
[i
]);
441 /* read all pixels */
442 for (i
= 0; i
< n
; i
++) {
443 index
[i
] = vl_getpixel(FLIP2(y
[i
])*_w_
+ x
[i
]);
449 /****************************************************************************
451 ***************************************************************************/
454 /****************************************************************************
455 * Optimized triangle rendering
456 ***************************************************************************/
459 * NON-depth-buffered flat triangle.
461 #define NAME tri_rgb_flat
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);
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); \
475 #include "swrast/s_tritemp.h"
479 * Z-less flat triangle.
481 #define NAME tri_rgb_flat_zless
484 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
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);
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);\
497 vl_putpixel(offset, rgb); \
500 span.z += span.zStep; \
503 #include "swrast/s_tritemp.h"
507 * NON-depth-buffered iterated triangle.
509 #define NAME tri_rgb_iter
514 const DMesaContext dmesa = (DMesaContext)ctx;\
515 GLuint _b_ = dmesa->buffer->height - 1; \
516 GLuint _w_ = dmesa->buffer->width;
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; \
527 #include "swrast/s_tritemp.h"
531 * Z-less iterated triangle.
533 #define NAME tri_rgb_iter_zless
536 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
540 const DMesaContext dmesa = (DMesaContext)ctx;\
541 GLuint _b_ = dmesa->buffer->height - 1; \
542 GLuint _w_ = dmesa->buffer->width;
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); \
549 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\
552 span.red += span.redStep; \
553 span.green += span.greenStep; \
554 span.blue += span.blueStep; \
555 span.z += span.zStep; \
558 #include "swrast/s_tritemp.h"
562 * Analyze context state to see if we can provide a fast triangle function
563 * Otherwise, return NULL.
565 static swrast_tri_func
566 dmesa_choose_tri_function (GLcontext
*ctx
)
568 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
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
;
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
;
586 if (swrast
->_RasterMask
==0) { /* no depth test */
587 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? tri_rgb_iter
: tri_rgb_flat
;
590 return (swrast_tri_func
)NULL
;
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.
599 dmesa_choose_tri (GLcontext
*ctx
)
601 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
603 if (!(swrast
->Triangle
=dmesa_choose_tri_function(ctx
))) {
604 _swrast_choose_triangle(ctx
);
609 /****************************************************************************
610 * Optimized line rendering
611 ***************************************************************************/
614 * NON-depth-buffered flat line.
616 #define NAME line_rgb_flat
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);
627 #define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb);
629 #include "swrast/s_linetemp.h"
635 #define NAME line_rgb_flat_zless
639 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
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);
651 vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \
654 #include "swrast/s_linetemp.h"
658 * NON-depth-buffered iterated line.
660 #define line_rgb_iter NULL
664 * Z-less iterated line.
666 #define line_rgb_iter_zless NULL
670 * Analyze context state to see if we can provide a fast line function
671 * Otherwise, return NULL.
673 static swrast_line_func
674 dmesa_choose_line_function (GLcontext
*ctx
)
676 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
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
;
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
;
694 if (swrast
->_RasterMask
==0) { /* no depth test */
695 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? line_rgb_iter
: line_rgb_flat
;
698 return (swrast_line_func
)NULL
;
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.
707 dmesa_choose_line (GLcontext
*ctx
)
709 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
711 if (!(swrast
->Line
=dmesa_choose_line_function(ctx
))) {
712 _swrast_choose_line(ctx
);
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
)
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
;
730 return _mesa_choose_tex_format(ctx
, internalFormat
, format
, type
);
736 clear_index (GLcontext
*ctx
, GLuint index
)
738 ((DMesaContext
)ctx
)->ClearIndex
= index
;
743 clear_color (GLcontext
*ctx
, const GLfloat color
[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
);
755 clear (GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
756 GLint x
, GLint y
, GLint width
, GLint height
)
758 const DMesaContext c
= (DMesaContext
)ctx
;
759 const GLuint
*colorMask
= (GLuint
*)&ctx
->Color
.ColorMask
;
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
765 * If all==GL_TRUE, clear whole buffer, else just clear region defined
766 * by x,y,width,height
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
;
777 vl_rect(x
, c
->buffer
->height
- y
- height
, width
, height
, color
);
780 mask
&= ~DD_BACK_LEFT_BIT
;
785 _swrast_Clear(ctx
, mask
, all
, x
, y
, width
, height
);
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.
796 get_buffer_size (GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
798 DMesaBuffer b
= (DMesaBuffer
)buffer
;
806 viewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
808 /* poll for window size change and realloc software Z/stencil/etc if needed */
809 _mesa_ResizeBuffersMESA();
813 static const GLubyte
*
814 get_string (GLcontext
*ctx
, GLenum name
)
818 return (const GLubyte
*)"Mesa DJGPP";
826 finish (GLcontext
*ctx
)
829 * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible
835 flush (GLcontext
*ctx
)
838 * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible
843 /****************************************************************************
845 ***************************************************************************/
846 #define DMESA_NEW_LINE (_NEW_LINE | \
851 _SWRAST_NEW_RASTERMASK)
853 #define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \
858 _SWRAST_NEW_RASTERMASK)
860 /* Extend the software rasterizer with our line and triangle
864 dmesa_register_swrast_functions (GLcontext
*ctx
)
866 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
868 swrast
->choose_line
= dmesa_choose_line
;
869 swrast
->choose_triangle
= dmesa_choose_tri
;
871 swrast
->invalidate_line
|= DMESA_NEW_LINE
;
872 swrast
->invalidate_triangle
|= DMESA_NEW_TRIANGLE
;
877 dmesa_update_state (GLcontext
*ctx
, GLuint new_state
)
879 /* Propagate statechange information to swrast and swrast_setup
880 * modules. The DMesa driver has no internal GL-dependent state.
882 _swrast_InvalidateState( ctx
, new_state
);
883 _ac_InvalidateState( ctx
, new_state
);
884 _tnl_InvalidateState( ctx
, new_state
);
885 _swsetup_InvalidateState( ctx
, new_state
);
889 /* Initialize the device driver function table with the functions
890 * we implement in this driver.
893 dmesa_init_driver_functions (DMesaVisual visual
,
894 struct dd_function_table
*driver
)
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
;
906 driver
->ChooseTextureFormat
= choose_tex_format
;
911 /* Setup pointers and other driver state that is constant for the life
915 dmesa_init_pointers (GLcontext
*ctx
)
917 struct swrast_device_driver
*dd
= _swrast_GetDeviceDriverReference(ctx
);
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
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
;
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
;
944 /****************************************************************************
945 * DMesa Public API Functions
946 ***************************************************************************/
949 * The exact arguments to this function will depend on your window system
952 DMesaCreateVisual (GLint width
,
964 GLint redBits
, greenBits
, blueBits
, alphaBits
, indexBits
;
1006 * `alphaBits' is what we can provide
1007 * `alphaSize' is what app requests
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.
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'.
1017 * Basically, 32bit modes provide ALPHA storage, but can we rely on this?
1019 alphaBits
= alphaSize
;
1020 sw_alpha
= (alphaBits
> 0);
1026 if ((colDepth
=vl_video_init(width
, height
, colDepth
, rgbFlag
, refresh
)) <= 0) {
1035 if ((env
= getenv("MESA_FX_INFO")) && (env
[0] == 'r')) {
1036 freopen("MESA.LOG", "w", stderr
);
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).
1046 sprintf(tmp
, "FX_GLIDE_REFRESH=%u", refresh
);
1052 if ((v
=(DMesaVisual
)CALLOC_STRUCT(dmesa_visual
)) != NULL
) {
1053 /* Create core visual */
1054 _mesa_initialize_visual((GLvisual
*)v
,
1057 GL_FALSE
, /* stereo */
1062 indexBits
, /* indexBits */
1065 accumSize
, /* accumRed */
1066 accumSize
, /* accumGreen */
1067 accumSize
, /* accumBlue */
1068 alphaBits
?accumSize
:0, /* accumAlpha */
1069 1); /* numSamples */
1072 v
->sw_alpha
= sw_alpha
;
1073 v
->z_buffer
= (depthSize
> 0) ? 1 : 0;
1082 DMesaDestroyVisual (DMesaVisual v
)
1087 _mesa_destroy_visual((GLvisual
*)v
);
1092 DMesaCreateBuffer (DMesaVisual visual
,
1093 GLint xpos
, GLint ypos
,
1094 GLint width
, GLint height
)
1099 if ((b
=(DMesaBuffer
)CALLOC_STRUCT(dmesa_buffer
)) != NULL
) {
1100 _mesa_initialize_framebuffer((GLframebuffer
*)b
,
1102 visual
->z_buffer
== 1,
1103 ((GLvisual
*)visual
)->stencilBits
> 0,
1104 ((GLvisual
*)visual
)->accumRedBits
> 0,
1115 GLvisual
*v
= (GLvisual
*)visual
;
1116 int i
= 0, fx_attrib
[32];
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
;
1127 return (DMesaBuffer
)fxMesaCreateBestContext(-1, width
, height
, fx_attrib
);
1133 DMesaDestroyBuffer (DMesaBuffer b
)
1136 if (b
->the_window
!= NULL
) {
1137 free(b
->the_window
);
1139 _mesa_destroy_framebuffer((GLframebuffer
*)b
);
1141 fxMesaDestroyContext((fxMesaContext
)b
);
1147 DMesaCreateContext (DMesaVisual visual
, DMesaContext share
)
1152 struct dd_function_table functions
;
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
);
1160 _mesa_initialize_context(c
,
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
);
1173 _mesa_enable_extension(c
, "GL_EXT_texture_compression_s3tc");
1174 _mesa_enable_extension(c
, "GL_S3_s3tc");
1176 _mesa_enable_extension(c
, "GL_3DFX_texture_compression_FXT1");
1179 /* you probably have to do a bunch of other initializations here. */
1180 ((DMesaContext
)c
)->visual
= visual
;
1182 /* Initialize the software rasterizer and helper modules.
1184 _swrast_CreateContext(c
);
1185 _ac_CreateContext(c
);
1186 _tnl_CreateContext(c
);
1187 _swsetup_CreateContext(c
);
1189 tnl
= TNL_CONTEXT(c
);
1190 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1192 if (((GLvisual
*)visual
)->rgbMode
) dmesa_register_swrast_functions(c
);
1193 dmesa_init_pointers(c
);
1198 c
= (GLcontext
*)0xdeadbeef;
1201 return (DMesaContext
)c
;
1206 DMesaDestroyContext (DMesaContext 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
);
1221 DMesaMoveBuffer (GLint xpos
, GLint ypos
)
1224 GET_CURRENT_CONTEXT(ctx
);
1225 DMesaBuffer b
= ((DMesaContext
)ctx
)->buffer
;
1227 if (vl_sync_buffer(&b
->the_window
, xpos
, ypos
, b
->width
, b
->height
) == 0) {
1239 DMesaResizeBuffer (GLint width
, GLint height
)
1242 GET_CURRENT_CONTEXT(ctx
);
1243 DMesaBuffer b
= ((DMesaContext
)ctx
)->buffer
;
1245 if (vl_sync_buffer(&b
->the_window
, b
->xpos
, b
->ypos
, width
, height
) == 0) {
1257 * Make the specified context and buffer the current one.
1260 DMesaMakeCurrent (DMesaContext c
, DMesaBuffer b
)
1263 if ((c
!= NULL
) && (b
!= NULL
)) {
1264 if (vl_sync_buffer(&b
->the_window
, b
->xpos
, b
->ypos
, b
->width
, b
->height
) != 0) {
1270 _mesa_make_current((GLcontext
*)c
, (GLframebuffer
*)b
);
1274 _mesa_make_current(NULL
, NULL
);
1278 fxMesaMakeCurrent((fxMesaContext
)b
);
1286 DMesaSwapBuffers (DMesaBuffer b
)
1288 /* copy/swap back buffer to front if applicable */
1290 GET_CURRENT_CONTEXT(ctx
);
1291 _mesa_notifySwapBuffers(ctx
);
1294 fxMesaSwapBuffers();
1300 DMesaSetCI (int ndx
, GLfloat red
, GLfloat green
, GLfloat blue
)
1303 vl_setCI(ndx
, red
, green
, blue
);
1309 DMesaGetCurrentContext (void)
1311 GET_CURRENT_CONTEXT(ctx
);
1316 ctx
= (GLcontext
*)0xdeadbeef;
1320 return (DMesaContext
)ctx
;
1325 DMesaGetCurrentBuffer (void)
1327 const DMesaContext dmesa
= DMesaGetCurrentContext();
1329 if (dmesa
== NULL
) {
1334 return dmesa
->buffer
;
1336 return (DMesaBuffer
)fxMesaGetCurrentContext();
1342 DMesaGetProcAddress (const char *name
)
1344 DMesaProc p
= (DMesaProc
)_glapi_get_proc_address(name
);
1346 /* TODO: handle DMesa* namespace
1356 DMesaGetIntegerv (GLenum pname
, GLint
*params
)
1359 case DMESA_GET_SCREEN_SIZE
:
1361 vl_get(VL_GET_SCREEN_SIZE
, params
);
1363 fxGetScreenGeometry(¶ms
[0], ¶ms
[1]);
1366 case DMESA_GET_DRIVER_CAPS
:
1368 params
[0] = DMESA_DRIVER_SWDB_BIT
;
1370 params
[0] = DMESA_DRIVER_LLWO_BIT
;
1373 case DMESA_GET_VIDEO_MODES
:
1375 return vl_get(VL_GET_VIDEO_MODES
, params
);
1377 return -1; /* TODO */
1379 case DMESA_GET_BUFFER_ADDR
: {
1381 DMesaContext c
= (DMesaContext
)DMesaGetCurrentContext();
1383 DMesaBuffer b
= c
->buffer
;
1385 params
[0] = (GLint
)b
->the_window
;
1401 #if SWTC && (((__DJGPP__ << 8) | __DJGPP_MINOR__) >= 0x204)
1402 #include <sys/dxe.h>
1404 extern_asm(___dj_assert
);
1406 extern_asm(_malloc
);
1407 extern_asm(_memset
);
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
)