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 */
106 /****************************************************************************
108 ***************************************************************************/
109 #define FLIP(y) (dmesa->buffer->height - (y) - 1)
110 #define FLIP2(y) (_b_ - (y))
112 #define DSTRIDE dmesa->buffer->width
114 /****************************************************************************
116 ***************************************************************************/
118 write_rgba_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
119 const GLubyte rgba
[][4], const GLubyte mask
[])
121 const DMesaContext dmesa
= (DMesaContext
)ctx
;
124 offset
= DSTRIDE
* FLIP(y
) + x
;
126 /* draw some pixels */
127 for (i
= 0; i
< n
; i
++, offset
++) {
129 vl_putpixel(offset
, vl_mixrgba(rgba
[i
]));
133 /* draw all pixels */
134 for (i
= 0; i
< n
; i
++, offset
++) {
135 vl_putpixel(offset
, vl_mixrgba(rgba
[i
]));
142 write_rgb_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
143 const GLubyte rgb
[][3], const GLubyte mask
[])
145 const DMesaContext dmesa
= (DMesaContext
)ctx
;
148 offset
= DSTRIDE
* FLIP(y
) + x
;
150 /* draw some pixels */
151 for (i
= 0; i
< n
; i
++, offset
++) {
153 vl_putpixel(offset
, vl_mixrgb(rgb
[i
]));
157 /* draw all pixels */
158 for (i
= 0; i
< n
; i
++, offset
++) {
159 vl_putpixel(offset
, vl_mixrgb(rgb
[i
]));
166 write_mono_rgba_span (const GLcontext
*ctx
,
167 GLuint n
, GLint x
, GLint y
,
168 const GLchan color
[4], const GLubyte mask
[])
170 const DMesaContext dmesa
= (DMesaContext
)ctx
;
171 GLuint i
, offset
, rgba
= vl_mixrgba(color
);
173 offset
= DSTRIDE
* FLIP(y
) + x
;
175 /* draw some pixels */
176 for (i
= 0; i
< n
; i
++, offset
++) {
178 vl_putpixel(offset
, rgba
);
182 /* draw all pixels */
183 for (i
= 0; i
< n
; i
++, offset
++) {
184 vl_putpixel(offset
, rgba
);
191 read_rgba_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
194 const DMesaContext dmesa
= (DMesaContext
)ctx
;
197 offset
= DSTRIDE
* FLIP(y
) + x
;
198 /* read all pixels */
199 for (i
= 0; i
< n
; i
++, offset
++) {
200 vl_getrgba(offset
, rgba
[i
]);
206 write_rgba_pixels (const GLcontext
*ctx
,
207 GLuint n
, const GLint x
[], const GLint y
[],
208 const GLubyte rgba
[][4], const GLubyte mask
[])
210 const DMesaContext dmesa
= (DMesaContext
)ctx
;
211 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
214 /* draw some pixels */
215 for (i
= 0; i
< n
; i
++) {
217 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], vl_mixrgba(rgba
[i
]));
221 /* draw all pixels */
222 for (i
= 0; i
< n
; i
++) {
223 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], vl_mixrgba(rgba
[i
]));
230 write_mono_rgba_pixels (const GLcontext
*ctx
,
231 GLuint n
, const GLint x
[], const GLint y
[],
232 const GLchan color
[4], const GLubyte mask
[])
234 const DMesaContext dmesa
= (DMesaContext
)ctx
;
235 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1, rgba
= vl_mixrgba(color
);
238 /* draw some pixels */
239 for (i
= 0; i
< n
; i
++) {
241 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
);
245 /* draw all pixels */
246 for (i
= 0; i
< n
; i
++) {
247 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
);
254 read_rgba_pixels (const GLcontext
*ctx
,
255 GLuint n
, const GLint x
[], const GLint y
[],
256 GLubyte rgba
[][4], const GLubyte mask
[])
258 const DMesaContext dmesa
= (DMesaContext
)ctx
;
259 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
262 /* read some pixels */
263 for (i
= 0; i
< n
; i
++) {
265 vl_getrgba(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
[i
]);
269 /* read all pixels */
270 for (i
= 0; i
< n
; i
++) {
271 vl_getrgba(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
[i
]);
277 /****************************************************************************
279 ***************************************************************************/
281 write_index_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
282 const GLuint index
[], const GLubyte mask
[])
284 const DMesaContext dmesa
= (DMesaContext
)ctx
;
287 offset
= DSTRIDE
* FLIP(y
) + x
;
289 /* draw some pixels */
290 for (i
= 0; i
< n
; i
++, offset
++) {
292 vl_putpixel(offset
, index
[i
]);
296 /* draw all pixels */
297 for (i
= 0; i
< n
; i
++, offset
++) {
298 vl_putpixel(offset
, index
[i
]);
305 write_index8_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
306 const GLubyte index
[], const GLubyte mask
[])
308 const DMesaContext dmesa
= (DMesaContext
)ctx
;
311 offset
= DSTRIDE
* FLIP(y
) + x
;
313 /* draw some pixels */
314 for (i
= 0; i
< n
; i
++, offset
++) {
316 vl_putpixel(offset
, index
[i
]);
320 /* draw all pixels */
321 for (i
= 0; i
< n
; i
++, offset
++) {
322 vl_putpixel(offset
, index
[i
]);
329 write_mono_index_span (const GLcontext
*ctx
,
330 GLuint n
, GLint x
, GLint y
,
331 GLuint colorIndex
, const GLubyte mask
[])
333 const DMesaContext dmesa
= (DMesaContext
)ctx
;
336 offset
= DSTRIDE
* FLIP(y
) + x
;
338 /* draw some pixels */
339 for (i
= 0; i
< n
; i
++, offset
++) {
341 vl_putpixel(offset
, colorIndex
);
345 /* draw all pixels */
346 for (i
= 0; i
< n
; i
++, offset
++) {
347 vl_putpixel(offset
, colorIndex
);
354 read_index_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
357 const DMesaContext dmesa
= (DMesaContext
)ctx
;
360 offset
= DSTRIDE
* FLIP(y
) + x
;
361 /* read all pixels */
362 for (i
= 0; i
< n
; i
++, offset
++) {
363 index
[i
] = vl_getpixel(offset
);
369 write_index_pixels (const GLcontext
*ctx
,
370 GLuint n
, const GLint x
[], const GLint y
[],
371 const GLuint index
[], const GLubyte mask
[])
373 const DMesaContext dmesa
= (DMesaContext
)ctx
;
374 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
377 /* draw some pixels */
378 for (i
= 0; i
< n
; i
++) {
380 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], index
[i
]);
384 /* draw all pixels */
385 for (i
= 0; i
< n
; i
++) {
386 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], index
[i
]);
393 write_mono_index_pixels (const GLcontext
*ctx
,
394 GLuint n
, const GLint x
[], const GLint y
[],
395 GLuint colorIndex
, const GLubyte mask
[])
397 const DMesaContext dmesa
= (DMesaContext
)ctx
;
398 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
401 /* draw some pixels */
402 for (i
= 0; i
< n
; i
++) {
404 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], colorIndex
);
408 /* draw all pixels */
409 for (i
= 0; i
< n
; i
++) {
410 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], colorIndex
);
417 read_index_pixels (const GLcontext
*ctx
,
418 GLuint n
, const GLint x
[], const GLint y
[],
419 GLuint index
[], const GLubyte mask
[])
421 const DMesaContext dmesa
= (DMesaContext
)ctx
;
422 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
425 /* read some pixels */
426 for (i
= 0; i
< n
; i
++) {
428 index
[i
] = vl_getpixel(FLIP2(y
[i
])*_w_
+ x
[i
]);
432 /* read all pixels */
433 for (i
= 0; i
< n
; i
++) {
434 index
[i
] = vl_getpixel(FLIP2(y
[i
])*_w_
+ x
[i
]);
440 /****************************************************************************
442 ***************************************************************************/
445 /****************************************************************************
446 * Optimized triangle rendering
447 ***************************************************************************/
450 * NON-depth-buffered flat triangle.
452 #define NAME tri_rgb_flat
455 const DMesaContext dmesa = (DMesaContext)ctx;\
456 GLuint _b_ = dmesa->buffer->height - 1; \
457 GLuint _w_ = dmesa->buffer->width; \
458 GLuint rgb = vl_mixrgb(v2->color);
460 #define RENDER_SPAN(span) \
461 GLuint i, offset = FLIP2(span.y)*_w_ + span.x;\
462 for (i = 0; i < span.end; i++, offset++) { \
463 vl_putpixel(offset, rgb); \
466 #include "swrast/s_tritemp.h"
470 * Z-less flat triangle.
472 #define NAME tri_rgb_flat_zless
475 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
478 const DMesaContext dmesa = (DMesaContext)ctx; \
479 GLuint _b_ = dmesa->buffer->height - 1; \
480 GLuint _w_ = dmesa->buffer->width; \
481 GLuint rgb = vl_mixrgb(v2->color);
483 #define RENDER_SPAN(span) \
484 GLuint i, offset = FLIP2(span.y)*_w_ + span.x;\
485 for (i = 0; i < span.end; i++, offset++) { \
486 const DEPTH_TYPE z = FixedToDepth(span.z);\
488 vl_putpixel(offset, rgb); \
491 span.z += span.zStep; \
494 #include "swrast/s_tritemp.h"
498 * NON-depth-buffered iterated triangle.
500 #define NAME tri_rgb_iter
505 const DMesaContext dmesa = (DMesaContext)ctx;\
506 GLuint _b_ = dmesa->buffer->height - 1; \
507 GLuint _w_ = dmesa->buffer->width;
509 #define RENDER_SPAN(span) \
510 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
511 for (i = 0; i < span.end; i++, offset++) { \
512 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue)); \
513 span.red += span.redStep; \
514 span.green += span.greenStep; \
515 span.blue += span.blueStep; \
518 #include "swrast/s_tritemp.h"
522 * Z-less iterated triangle.
524 #define NAME tri_rgb_iter_zless
527 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
531 const DMesaContext dmesa = (DMesaContext)ctx;\
532 GLuint _b_ = dmesa->buffer->height - 1; \
533 GLuint _w_ = dmesa->buffer->width;
535 #define RENDER_SPAN(span) \
536 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
537 for (i = 0; i < span.end; i++, offset++) { \
538 const DEPTH_TYPE z = FixedToDepth(span.z); \
540 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\
543 span.red += span.redStep; \
544 span.green += span.greenStep; \
545 span.blue += span.blueStep; \
546 span.z += span.zStep; \
549 #include "swrast/s_tritemp.h"
553 * Analyze context state to see if we can provide a fast triangle function
554 * Otherwise, return NULL.
556 static swrast_tri_func
557 dmesa_choose_tri_function (GLcontext
*ctx
)
559 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
561 if ((ctx
->RenderMode
!= GL_RENDER
)
562 || (ctx
->Polygon
.SmoothFlag
)
563 || (ctx
->Polygon
.StippleFlag
)
564 || (ctx
->Texture
._EnabledUnits
)
565 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)
566 || (ctx
->Polygon
.CullFlag
&& ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)) {
567 return (swrast_tri_func
)NULL
;
570 if (swrast
->_RasterMask
==DEPTH_BIT
571 && ctx
->Depth
.Func
==GL_LESS
572 && ctx
->Depth
.Mask
==GL_TRUE
573 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
574 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? tri_rgb_iter_zless
: tri_rgb_flat_zless
;
577 if (swrast
->_RasterMask
==0) { /* no depth test */
578 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? tri_rgb_iter
: tri_rgb_flat
;
581 return (swrast_tri_func
)NULL
;
585 /* Override for the swrast triangle-selection function. Try to use one
586 * of our internal triangle functions, otherwise fall back to the
587 * standard swrast functions.
590 dmesa_choose_tri (GLcontext
*ctx
)
592 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
594 if (!(swrast
->Triangle
=dmesa_choose_tri_function(ctx
))) {
595 _swrast_choose_triangle(ctx
);
600 /****************************************************************************
601 * Optimized line rendering
602 ***************************************************************************/
605 * NON-depth-buffered flat line.
607 #define NAME line_rgb_flat
613 const DMesaContext dmesa = (DMesaContext)ctx;\
614 GLuint _b_ = dmesa->buffer->height - 1; \
615 GLuint _w_ = dmesa->buffer->width; \
616 GLuint rgb = vl_mixrgb(vert1->color);
618 #define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb);
620 #include "swrast/s_linetemp.h"
626 #define NAME line_rgb_flat_zless
630 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
634 const DMesaContext dmesa = (DMesaContext)ctx;\
635 GLuint _b_ = dmesa->buffer->height - 1; \
636 GLuint _w_ = dmesa->buffer->width; \
637 GLuint rgb = vl_mixrgb(vert1->color);
642 vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \
645 #include "swrast/s_linetemp.h"
649 * NON-depth-buffered iterated line.
651 #define line_rgb_iter NULL
655 * Z-less iterated line.
657 #define line_rgb_iter_zless NULL
661 * Analyze context state to see if we can provide a fast line function
662 * Otherwise, return NULL.
664 static swrast_line_func
665 dmesa_choose_line_function (GLcontext
*ctx
)
667 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
669 if ((ctx
->RenderMode
!= GL_RENDER
)
670 || (ctx
->Line
.SmoothFlag
)
671 || (ctx
->Texture
._EnabledUnits
)
672 || (ctx
->Line
.StippleFlag
)
673 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)
674 || (ctx
->Line
.Width
!=1.0F
)) {
675 return (swrast_line_func
)NULL
;
678 if (swrast
->_RasterMask
==DEPTH_BIT
679 && ctx
->Depth
.Func
==GL_LESS
680 && ctx
->Depth
.Mask
==GL_TRUE
681 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
682 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? line_rgb_iter_zless
: line_rgb_flat_zless
;
685 if (swrast
->_RasterMask
==0) { /* no depth test */
686 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? line_rgb_iter
: line_rgb_flat
;
689 return (swrast_line_func
)NULL
;
693 /* Override for the swrast line-selection function. Try to use one
694 * of our internal line functions, otherwise fall back to the
695 * standard swrast functions.
698 dmesa_choose_line (GLcontext
*ctx
)
700 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
702 if (!(swrast
->Line
=dmesa_choose_line_function(ctx
))) {
703 _swrast_choose_line(ctx
);
708 /****************************************************************************
709 * Miscellaneous device driver funcs
710 ***************************************************************************/
711 static const struct gl_texture_format
*
712 choose_tex_format (GLcontext
*ctx
, GLint internalFormat
,
713 GLenum format
, GLenum type
)
715 switch (internalFormat
) {
716 case GL_COMPRESSED_RGB_ARB
:
717 return &_mesa_texformat_rgb
;
718 case GL_COMPRESSED_RGBA_ARB
:
719 return &_mesa_texformat_rgba
;
721 return _mesa_choose_tex_format(ctx
, internalFormat
, format
, type
);
727 clear_index (GLcontext
*ctx
, GLuint index
)
729 ((DMesaContext
)ctx
)->ClearIndex
= index
;
734 clear_color (GLcontext
*ctx
, const GLfloat color
[4])
737 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
738 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
739 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
740 CLAMPED_FLOAT_TO_UBYTE(col
[3], color
[3]);
741 ((DMesaContext
)ctx
)->ClearColor
= vl_mixrgba(col
);
746 clear (GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
747 GLint x
, GLint y
, GLint width
, GLint height
)
749 const DMesaContext c
= (DMesaContext
)ctx
;
750 const GLuint
*colorMask
= (GLuint
*)&ctx
->Color
.ColorMask
;
753 * Clear the specified region of the buffers indicated by 'mask'
754 * using the clear color or index as specified by one of the two
756 * If all==GL_TRUE, clear whole buffer, else just clear region defined
757 * by x,y,width,height
760 /* we can't handle color or index masking */
761 if ((*colorMask
== 0xffffffff) && (ctx
->Color
.IndexMask
== 0xffffffff)) {
762 if (mask
& DD_BACK_LEFT_BIT
) {
763 int color
= ((GLvisual
*)(c
->visual
))->rgbMode
? c
->ClearColor
: c
->ClearIndex
;
768 vl_rect(x
, c
->buffer
->height
- y
- height
, width
, height
, color
);
771 mask
&= ~DD_BACK_LEFT_BIT
;
776 _swrast_Clear(ctx
, mask
, all
, x
, y
, width
, height
);
782 * This function is called to specify which buffer to read and write
783 * for software rasterization (swrast) fallbacks. This doesn't necessarily
784 * correspond to glDrawBuffer() or glReadBuffer() calls.
787 set_buffer (GLcontext
*ctx
, GLframebuffer
*colorBuffer
, GLuint bufferBit
)
790 * XXX todo - examine bufferBit and set read/write pointers
792 /* Normally, we would have
793 * ctx->Driver.ReadBuffer == set_read_buffer
794 * ctx->Driver.DrawBuffer == set_draw_buffer
795 * and make sure set_draw_buffer calls _swrast_DrawBuffer,
796 * which in turn will call this routine via dd->SetBuffer.
802 * Return the width and height of the current buffer.
803 * If anything special has to been done when the buffer/window is
804 * resized, do it now.
807 get_buffer_size (GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
809 DMesaBuffer b
= (DMesaBuffer
)buffer
;
817 viewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
819 /* poll for window size change and realloc software Z/stencil/etc if needed */
820 _mesa_ResizeBuffersMESA();
824 static const GLubyte
*
825 get_string (GLcontext
*ctx
, GLenum name
)
829 return (const GLubyte
*)"Mesa DJGPP";
837 finish (GLcontext
*ctx
)
840 * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible
846 flush (GLcontext
*ctx
)
849 * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible
854 /****************************************************************************
856 ***************************************************************************/
857 #define DMESA_NEW_LINE (_NEW_LINE | \
862 _SWRAST_NEW_RASTERMASK)
864 #define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \
869 _SWRAST_NEW_RASTERMASK)
871 /* Extend the software rasterizer with our line and triangle
875 dmesa_register_swrast_functions (GLcontext
*ctx
)
877 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
879 swrast
->choose_line
= dmesa_choose_line
;
880 swrast
->choose_triangle
= dmesa_choose_tri
;
882 swrast
->invalidate_line
|= DMESA_NEW_LINE
;
883 swrast
->invalidate_triangle
|= DMESA_NEW_TRIANGLE
;
888 dmesa_update_state (GLcontext
*ctx
, GLuint new_state
)
890 /* Propagate statechange information to swrast and swrast_setup
891 * modules. The DMesa driver has no internal GL-dependent state.
893 _swrast_InvalidateState( ctx
, new_state
);
894 _ac_InvalidateState( ctx
, new_state
);
895 _tnl_InvalidateState( ctx
, new_state
);
896 _swsetup_InvalidateState( ctx
, new_state
);
900 /* Initialize the device driver function table with the functions
901 * we implement in this driver.
904 dmesa_init_driver_functions (DMesaVisual visual
,
905 struct dd_function_table
*driver
)
907 driver
->UpdateState
= dmesa_update_state
;
908 driver
->GetString
= get_string
;
909 driver
->GetBufferSize
= get_buffer_size
;
910 driver
->Viewport
= viewport
;
911 driver
->Flush
= flush
;
912 driver
->Finish
= finish
;
913 driver
->Clear
= clear
;
914 driver
->ClearColor
= clear_color
;
915 driver
->ClearIndex
= clear_index
;
917 driver
->ChooseTextureFormat
= choose_tex_format
;
922 /* Setup pointers and other driver state that is constant for the life
926 dmesa_init_pointers (GLcontext
*ctx
)
928 struct swrast_device_driver
*dd
= _swrast_GetDeviceDriverReference(ctx
);
930 dd
->SetBuffer
= set_buffer
;
932 /* The span functions should be in `dmesa_update_state', but I'm
933 * pretty sure they will never change during the life of the Visual
936 /* Index span/pixel functions */
937 dd
->WriteCI32Span
= write_index_span
;
938 dd
->WriteCI8Span
= write_index8_span
;
939 dd
->WriteMonoCISpan
= write_mono_index_span
;
940 dd
->WriteCI32Pixels
= write_index_pixels
;
941 dd
->WriteMonoCIPixels
= write_mono_index_pixels
;
942 dd
->ReadCI32Span
= read_index_span
;
943 dd
->ReadCI32Pixels
= read_index_pixels
;
945 /* RGB(A) span/pixel functions */
946 dd
->WriteRGBASpan
= write_rgba_span
;
947 dd
->WriteRGBSpan
= write_rgb_span
;
948 dd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
949 dd
->WriteRGBAPixels
= write_rgba_pixels
;
950 dd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
951 dd
->ReadRGBASpan
= read_rgba_span
;
952 dd
->ReadRGBAPixels
= read_rgba_pixels
;
957 /****************************************************************************
958 * DMesa Public API Functions
959 ***************************************************************************/
962 * The exact arguments to this function will depend on your window system
965 DMesaCreateVisual (GLint width
,
977 GLint redBits
, greenBits
, blueBits
, alphaBits
, indexBits
;
1019 * `alphaBits' is what we can provide
1020 * `alphaSize' is what app requests
1022 * Note that alpha buffering is required only if destination alpha is used
1023 * in alpha blending; alpha blending modes that do not use destination alpha
1024 * can be used w/o alpha buffer.
1026 * We will use whatever ALPHA app requests. Later, in `CreateBuffer' we'll
1027 * instruct Mesa to use its own ALPHA buffer, by passing a non-FALSE value
1028 * for ALPHA to `_mesa_initialize_framebuffer'.
1030 * Basically, 32bit modes provide ALPHA storage, but can we rely on this?
1032 alphaBits
= alphaSize
;
1033 sw_alpha
= (alphaBits
> 0);
1039 if ((colDepth
=vl_video_init(width
, height
, colDepth
, rgbFlag
, refresh
)) <= 0) {
1048 if ((env
= getenv("MESA_FX_INFO")) && (env
[0] == 'r')) {
1049 freopen("MESA.LOG", "w", stderr
);
1052 if (refresh
&& (((env
= getenv("FX_GLIDE_REFRESH")) == NULL
) || !atoi(env
))) {
1053 /* if we are passed non-zero value for refresh, we need to override
1054 * default refresh rate. However, if FX_GLIDE_REFRESH is already set
1055 * to 0, we won't override it, because it has a special meaning for
1056 * DJGPP Glide3x (switch via VESA, using BIOS default refresh).
1059 sprintf(tmp
, "FX_GLIDE_REFRESH=%u", refresh
);
1065 if ((v
=(DMesaVisual
)CALLOC_STRUCT(dmesa_visual
)) != NULL
) {
1066 /* Create core visual */
1067 _mesa_initialize_visual((GLvisual
*)v
,
1070 GL_FALSE
, /* stereo */
1075 indexBits
, /* indexBits */
1078 accumSize
, /* accumRed */
1079 accumSize
, /* accumGreen */
1080 accumSize
, /* accumBlue */
1081 alphaBits
?accumSize
:0, /* accumAlpha */
1082 1); /* numSamples */
1085 v
->sw_alpha
= sw_alpha
;
1086 v
->z_buffer
= (depthSize
> 0) ? 1 : 0;
1095 DMesaDestroyVisual (DMesaVisual v
)
1100 _mesa_destroy_visual((GLvisual
*)v
);
1105 DMesaCreateBuffer (DMesaVisual visual
,
1106 GLint xpos
, GLint ypos
,
1107 GLint width
, GLint height
)
1112 if ((b
=(DMesaBuffer
)CALLOC_STRUCT(dmesa_buffer
)) != NULL
) {
1113 _mesa_initialize_framebuffer((GLframebuffer
*)b
,
1115 visual
->z_buffer
== 1,
1116 ((GLvisual
*)visual
)->stencilBits
> 0,
1117 ((GLvisual
*)visual
)->accumRedBits
> 0,
1128 GLvisual
*v
= (GLvisual
*)visual
;
1129 int i
= 0, fx_attrib
[32];
1131 if (v
->doubleBufferMode
) fx_attrib
[i
++] = FXMESA_DOUBLEBUFFER
;
1132 if (v
->depthBits
> 0) { fx_attrib
[i
++] = FXMESA_DEPTH_SIZE
; fx_attrib
[i
++] = v
->depthBits
; }
1133 if (v
->stencilBits
> 0) { fx_attrib
[i
++] = FXMESA_STENCIL_SIZE
; fx_attrib
[i
++] = v
->stencilBits
; }
1134 if (v
->accumRedBits
> 0) { fx_attrib
[i
++] = FXMESA_ACCUM_SIZE
; fx_attrib
[i
++] = v
->accumRedBits
; }
1135 if (v
->alphaBits
) { fx_attrib
[i
++] = FXMESA_ALPHA_SIZE
; fx_attrib
[i
++] = v
->alphaBits
; }
1136 fx_attrib
[i
++] = FXMESA_COLORDEPTH
;
1137 fx_attrib
[i
++] = v
->redBits
+ v
->greenBits
+ v
->blueBits
;
1138 fx_attrib
[i
] = FXMESA_NONE
;
1140 return (DMesaBuffer
)fxMesaCreateBestContext(-1, width
, height
, fx_attrib
);
1146 DMesaDestroyBuffer (DMesaBuffer b
)
1149 if (b
->the_window
!= NULL
) {
1150 free(b
->the_window
);
1152 _mesa_destroy_framebuffer((GLframebuffer
*)b
);
1154 fxMesaDestroyContext((fxMesaContext
)b
);
1160 DMesaCreateContext (DMesaVisual visual
, DMesaContext share
)
1165 struct dd_function_table functions
;
1167 if ((c
=(GLcontext
*)CALLOC_STRUCT(dmesa_context
)) != NULL
) {
1168 /* Initialize device driver function table */
1169 _mesa_init_driver_functions(&functions
);
1170 /* override with our functions */
1171 dmesa_init_driver_functions(visual
, &functions
);
1173 _mesa_initialize_context(c
,
1179 _mesa_enable_sw_extensions(c
);
1180 _mesa_enable_1_3_extensions(c
);
1181 _mesa_enable_1_4_extensions(c
);
1182 _mesa_enable_1_5_extensions(c
);
1183 _mesa_enable_2_0_extensions(c
);
1186 _mesa_enable_extension(c
, "GL_EXT_texture_compression_s3tc");
1187 _mesa_enable_extension(c
, "GL_S3_s3tc");
1189 _mesa_enable_extension(c
, "GL_3DFX_texture_compression_FXT1");
1192 /* you probably have to do a bunch of other initializations here. */
1193 ((DMesaContext
)c
)->visual
= visual
;
1195 /* Initialize the software rasterizer and helper modules.
1197 _swrast_CreateContext(c
);
1198 _ac_CreateContext(c
);
1199 _tnl_CreateContext(c
);
1200 _swsetup_CreateContext(c
);
1202 tnl
= TNL_CONTEXT(c
);
1203 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1205 if (((GLvisual
*)visual
)->rgbMode
) dmesa_register_swrast_functions(c
);
1206 dmesa_init_pointers(c
);
1211 c
= (GLcontext
*)0xdeadbeef;
1214 return (DMesaContext
)c
;
1219 DMesaDestroyContext (DMesaContext c
)
1223 _swsetup_DestroyContext((GLcontext
*)c
);
1224 _swrast_DestroyContext((GLcontext
*)c
);
1225 _tnl_DestroyContext((GLcontext
*)c
);
1226 _ac_DestroyContext((GLcontext
*)c
);
1227 _mesa_destroy_context((GLcontext
*)c
);
1234 DMesaMoveBuffer (GLint xpos
, GLint ypos
)
1237 GET_CURRENT_CONTEXT(ctx
);
1238 DMesaBuffer b
= ((DMesaContext
)ctx
)->buffer
;
1240 if (vl_sync_buffer(&b
->the_window
, xpos
, ypos
, b
->width
, b
->height
) == 0) {
1252 DMesaResizeBuffer (GLint width
, GLint height
)
1255 GET_CURRENT_CONTEXT(ctx
);
1256 DMesaBuffer b
= ((DMesaContext
)ctx
)->buffer
;
1258 if (vl_sync_buffer(&b
->the_window
, b
->xpos
, b
->ypos
, width
, height
) == 0) {
1270 * Make the specified context and buffer the current one.
1273 DMesaMakeCurrent (DMesaContext c
, DMesaBuffer b
)
1276 if ((c
!= NULL
) && (b
!= NULL
)) {
1277 if (vl_sync_buffer(&b
->the_window
, b
->xpos
, b
->ypos
, b
->width
, b
->height
) != 0) {
1283 _mesa_make_current((GLcontext
*)c
, (GLframebuffer
*)b
);
1287 _mesa_make_current(NULL
, NULL
);
1291 fxMesaMakeCurrent((fxMesaContext
)b
);
1299 DMesaSwapBuffers (DMesaBuffer b
)
1301 /* copy/swap back buffer to front if applicable */
1303 GET_CURRENT_CONTEXT(ctx
);
1304 _mesa_notifySwapBuffers(ctx
);
1307 fxMesaSwapBuffers();
1313 DMesaSetCI (int ndx
, GLfloat red
, GLfloat green
, GLfloat blue
)
1316 vl_setCI(ndx
, red
, green
, blue
);
1322 DMesaGetCurrentContext (void)
1324 GET_CURRENT_CONTEXT(ctx
);
1329 ctx
= (GLcontext
*)0xdeadbeef;
1333 return (DMesaContext
)ctx
;
1338 DMesaGetCurrentBuffer (void)
1340 const DMesaContext dmesa
= DMesaGetCurrentContext();
1342 if (dmesa
== NULL
) {
1347 return dmesa
->buffer
;
1349 return (DMesaBuffer
)fxMesaGetCurrentContext();
1355 DMesaGetProcAddress (const char *name
)
1357 DMesaProc p
= (DMesaProc
)_glapi_get_proc_address(name
);
1359 /* TODO: handle DMesa* namespace
1369 DMesaGetIntegerv (GLenum pname
, GLint
*params
)
1372 case DMESA_GET_SCREEN_SIZE
:
1374 vl_get(VL_GET_SCREEN_SIZE
, params
);
1376 fxGetScreenGeometry(¶ms
[0], ¶ms
[1]);
1379 case DMESA_GET_DRIVER_CAPS
:
1381 params
[0] = DMESA_DRIVER_SWDB_BIT
;
1383 params
[0] = DMESA_DRIVER_LLWO_BIT
;
1386 case DMESA_GET_VIDEO_MODES
:
1388 return vl_get(VL_GET_VIDEO_MODES
, params
);
1390 return -1; /* TODO */
1392 case DMESA_GET_BUFFER_ADDR
: {
1394 DMesaContext c
= (DMesaContext
)DMesaGetCurrentContext();
1396 DMesaBuffer b
= c
->buffer
;
1398 params
[0] = (GLint
)b
->the_window
;
1414 #if SWTC && (((__DJGPP__ << 8) | __DJGPP_MINOR__) >= 0x204)
1415 #include <sys/dxe.h>
1417 extern_asm(___dj_assert
);
1419 extern_asm(_malloc
);
1420 extern_asm(_memset
);
1422 DXE_EXPORT_TABLE_AUTO (___dxe_eta___dxtn
)
1423 DXE_EXPORT_ASM (___dj_assert
)
1424 DXE_EXPORT_ASM (_free
)
1425 DXE_EXPORT_ASM (_malloc
)
1426 DXE_EXPORT_ASM (_memset
)