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
, struct gl_renderbuffer
*rb
,
282 GLuint n
, GLint x
, GLint y
,
283 const GLuint index
[], const GLubyte mask
[])
285 const DMesaContext dmesa
= (DMesaContext
)ctx
;
288 offset
= DSTRIDE
* FLIP(y
) + x
;
290 /* draw some pixels */
291 for (i
= 0; i
< n
; i
++, offset
++) {
293 vl_putpixel(offset
, index
[i
]);
297 /* draw all pixels */
298 for (i
= 0; i
< n
; i
++, offset
++) {
299 vl_putpixel(offset
, index
[i
]);
306 write_index8_span (const GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
307 GLuint n
, GLint x
, GLint y
,
308 const GLubyte index
[], const GLubyte mask
[])
310 const DMesaContext dmesa
= (DMesaContext
)ctx
;
313 offset
= DSTRIDE
* FLIP(y
) + x
;
315 /* draw some pixels */
316 for (i
= 0; i
< n
; i
++, offset
++) {
318 vl_putpixel(offset
, index
[i
]);
322 /* draw all pixels */
323 for (i
= 0; i
< n
; i
++, offset
++) {
324 vl_putpixel(offset
, index
[i
]);
331 write_mono_index_span (const GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
332 GLuint n
, GLint x
, GLint y
,
333 GLuint colorIndex
, const GLubyte mask
[])
335 const DMesaContext dmesa
= (DMesaContext
)ctx
;
338 offset
= DSTRIDE
* FLIP(y
) + x
;
340 /* draw some pixels */
341 for (i
= 0; i
< n
; i
++, offset
++) {
343 vl_putpixel(offset
, colorIndex
);
347 /* draw all pixels */
348 for (i
= 0; i
< n
; i
++, offset
++) {
349 vl_putpixel(offset
, colorIndex
);
356 read_index_span (const GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
357 GLuint n
, GLint x
, GLint y
, GLuint index
[])
359 const DMesaContext dmesa
= (DMesaContext
)ctx
;
362 offset
= DSTRIDE
* FLIP(y
) + x
;
363 /* read all pixels */
364 for (i
= 0; i
< n
; i
++, offset
++) {
365 index
[i
] = vl_getpixel(offset
);
371 write_index_pixels (const GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
372 GLuint n
, const GLint x
[], const GLint y
[],
373 const GLuint index
[], const GLubyte mask
[])
375 const DMesaContext dmesa
= (DMesaContext
)ctx
;
376 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
379 /* draw some pixels */
380 for (i
= 0; i
< n
; i
++) {
382 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], index
[i
]);
386 /* draw all pixels */
387 for (i
= 0; i
< n
; i
++) {
388 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], index
[i
]);
395 write_mono_index_pixels (const GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
396 GLuint n
, const GLint x
[], const GLint y
[],
397 GLuint colorIndex
, const GLubyte mask
[])
399 const DMesaContext dmesa
= (DMesaContext
)ctx
;
400 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
403 /* draw some pixels */
404 for (i
= 0; i
< n
; i
++) {
406 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], colorIndex
);
410 /* draw all pixels */
411 for (i
= 0; i
< n
; i
++) {
412 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], colorIndex
);
419 read_index_pixels (const GLcontext
*ctx
, struct gl_renderbuffer
*rb
,
420 GLuint n
, const GLint x
[], const GLint y
[],
421 GLuint index
[], const GLubyte mask
[])
423 const DMesaContext dmesa
= (DMesaContext
)ctx
;
424 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->buffer
->height
- 1;
427 /* read some pixels */
428 for (i
= 0; i
< n
; i
++) {
430 index
[i
] = vl_getpixel(FLIP2(y
[i
])*_w_
+ x
[i
]);
434 /* read all pixels */
435 for (i
= 0; i
< n
; i
++) {
436 index
[i
] = vl_getpixel(FLIP2(y
[i
])*_w_
+ x
[i
]);
442 /****************************************************************************
444 ***************************************************************************/
447 /****************************************************************************
448 * Optimized triangle rendering
449 ***************************************************************************/
452 * NON-depth-buffered flat triangle.
454 #define NAME tri_rgb_flat
457 const DMesaContext dmesa = (DMesaContext)ctx;\
458 GLuint _b_ = dmesa->buffer->height - 1; \
459 GLuint _w_ = dmesa->buffer->width; \
460 GLuint rgb = vl_mixrgb(v2->color);
462 #define RENDER_SPAN(span) \
463 GLuint i, offset = FLIP2(span.y)*_w_ + span.x;\
464 for (i = 0; i < span.end; i++, offset++) { \
465 vl_putpixel(offset, rgb); \
468 #include "swrast/s_tritemp.h"
472 * Z-less flat triangle.
474 #define NAME tri_rgb_flat_zless
477 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
480 const DMesaContext dmesa = (DMesaContext)ctx; \
481 GLuint _b_ = dmesa->buffer->height - 1; \
482 GLuint _w_ = dmesa->buffer->width; \
483 GLuint rgb = vl_mixrgb(v2->color);
485 #define RENDER_SPAN(span) \
486 GLuint i, offset = FLIP2(span.y)*_w_ + span.x;\
487 for (i = 0; i < span.end; i++, offset++) { \
488 const DEPTH_TYPE z = FixedToDepth(span.z);\
490 vl_putpixel(offset, rgb); \
493 span.z += span.zStep; \
496 #include "swrast/s_tritemp.h"
500 * NON-depth-buffered iterated triangle.
502 #define NAME tri_rgb_iter
507 const DMesaContext dmesa = (DMesaContext)ctx;\
508 GLuint _b_ = dmesa->buffer->height - 1; \
509 GLuint _w_ = dmesa->buffer->width;
511 #define RENDER_SPAN(span) \
512 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
513 for (i = 0; i < span.end; i++, offset++) { \
514 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue)); \
515 span.red += span.redStep; \
516 span.green += span.greenStep; \
517 span.blue += span.blueStep; \
520 #include "swrast/s_tritemp.h"
524 * Z-less iterated triangle.
526 #define NAME tri_rgb_iter_zless
529 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
533 const DMesaContext dmesa = (DMesaContext)ctx;\
534 GLuint _b_ = dmesa->buffer->height - 1; \
535 GLuint _w_ = dmesa->buffer->width;
537 #define RENDER_SPAN(span) \
538 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
539 for (i = 0; i < span.end; i++, offset++) { \
540 const DEPTH_TYPE z = FixedToDepth(span.z); \
542 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\
545 span.red += span.redStep; \
546 span.green += span.greenStep; \
547 span.blue += span.blueStep; \
548 span.z += span.zStep; \
551 #include "swrast/s_tritemp.h"
555 * Analyze context state to see if we can provide a fast triangle function
556 * Otherwise, return NULL.
558 static swrast_tri_func
559 dmesa_choose_tri_function (GLcontext
*ctx
)
561 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
563 if ((ctx
->RenderMode
!= GL_RENDER
)
564 || (ctx
->Polygon
.SmoothFlag
)
565 || (ctx
->Polygon
.StippleFlag
)
566 || (ctx
->Texture
._EnabledUnits
)
567 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)
568 || (ctx
->Polygon
.CullFlag
&& ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)) {
569 return (swrast_tri_func
)NULL
;
572 if (swrast
->_RasterMask
==DEPTH_BIT
573 && ctx
->Depth
.Func
==GL_LESS
574 && ctx
->Depth
.Mask
==GL_TRUE
575 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
576 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? tri_rgb_iter_zless
: tri_rgb_flat_zless
;
579 if (swrast
->_RasterMask
==0) { /* no depth test */
580 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? tri_rgb_iter
: tri_rgb_flat
;
583 return (swrast_tri_func
)NULL
;
587 /* Override for the swrast triangle-selection function. Try to use one
588 * of our internal triangle functions, otherwise fall back to the
589 * standard swrast functions.
592 dmesa_choose_tri (GLcontext
*ctx
)
594 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
596 if (!(swrast
->Triangle
=dmesa_choose_tri_function(ctx
))) {
597 _swrast_choose_triangle(ctx
);
602 /****************************************************************************
603 * Optimized line rendering
604 ***************************************************************************/
607 * NON-depth-buffered flat line.
609 #define NAME line_rgb_flat
615 const DMesaContext dmesa = (DMesaContext)ctx;\
616 GLuint _b_ = dmesa->buffer->height - 1; \
617 GLuint _w_ = dmesa->buffer->width; \
618 GLuint rgb = vl_mixrgb(vert1->color);
620 #define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb);
622 #include "swrast/s_linetemp.h"
628 #define NAME line_rgb_flat_zless
632 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
636 const DMesaContext dmesa = (DMesaContext)ctx;\
637 GLuint _b_ = dmesa->buffer->height - 1; \
638 GLuint _w_ = dmesa->buffer->width; \
639 GLuint rgb = vl_mixrgb(vert1->color);
644 vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \
647 #include "swrast/s_linetemp.h"
651 * NON-depth-buffered iterated line.
653 #define line_rgb_iter NULL
657 * Z-less iterated line.
659 #define line_rgb_iter_zless NULL
663 * Analyze context state to see if we can provide a fast line function
664 * Otherwise, return NULL.
666 static swrast_line_func
667 dmesa_choose_line_function (GLcontext
*ctx
)
669 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
671 if ((ctx
->RenderMode
!= GL_RENDER
)
672 || (ctx
->Line
.SmoothFlag
)
673 || (ctx
->Texture
._EnabledUnits
)
674 || (ctx
->Line
.StippleFlag
)
675 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)
676 || (ctx
->Line
.Width
!=1.0F
)) {
677 return (swrast_line_func
)NULL
;
680 if (swrast
->_RasterMask
==DEPTH_BIT
681 && ctx
->Depth
.Func
==GL_LESS
682 && ctx
->Depth
.Mask
==GL_TRUE
683 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
684 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? line_rgb_iter_zless
: line_rgb_flat_zless
;
687 if (swrast
->_RasterMask
==0) { /* no depth test */
688 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? line_rgb_iter
: line_rgb_flat
;
691 return (swrast_line_func
)NULL
;
695 /* Override for the swrast line-selection function. Try to use one
696 * of our internal line functions, otherwise fall back to the
697 * standard swrast functions.
700 dmesa_choose_line (GLcontext
*ctx
)
702 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
704 if (!(swrast
->Line
=dmesa_choose_line_function(ctx
))) {
705 _swrast_choose_line(ctx
);
710 /****************************************************************************
711 * Miscellaneous device driver funcs
712 ***************************************************************************/
713 static const struct gl_texture_format
*
714 choose_tex_format (GLcontext
*ctx
, GLint internalFormat
,
715 GLenum format
, GLenum type
)
717 switch (internalFormat
) {
718 case GL_COMPRESSED_RGB_ARB
:
719 return &_mesa_texformat_rgb
;
720 case GL_COMPRESSED_RGBA_ARB
:
721 return &_mesa_texformat_rgba
;
723 return _mesa_choose_tex_format(ctx
, internalFormat
, format
, type
);
729 clear_index (GLcontext
*ctx
, GLuint index
)
731 ((DMesaContext
)ctx
)->ClearIndex
= index
;
736 clear_color (GLcontext
*ctx
, const GLfloat color
[4])
739 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
740 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
741 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
742 CLAMPED_FLOAT_TO_UBYTE(col
[3], color
[3]);
743 ((DMesaContext
)ctx
)->ClearColor
= vl_mixrgba(col
);
748 clear (GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
749 GLint x
, GLint y
, GLint width
, GLint height
)
751 const DMesaContext c
= (DMesaContext
)ctx
;
752 const GLuint
*colorMask
= (GLuint
*)&ctx
->Color
.ColorMask
;
755 * Clear the specified region of the buffers indicated by 'mask'
756 * using the clear color or index as specified by one of the two
758 * If all==GL_TRUE, clear whole buffer, else just clear region defined
759 * by x,y,width,height
762 /* we can't handle color or index masking */
763 if ((*colorMask
== 0xffffffff) && (ctx
->Color
.IndexMask
== 0xffffffff)) {
764 if (mask
& DD_BACK_LEFT_BIT
) {
765 int color
= ((GLvisual
*)(c
->visual
))->rgbMode
? c
->ClearColor
: c
->ClearIndex
;
770 vl_rect(x
, c
->buffer
->height
- y
- height
, width
, height
, color
);
773 mask
&= ~DD_BACK_LEFT_BIT
;
778 _swrast_Clear(ctx
, mask
, all
, x
, y
, width
, height
);
784 * This function is called to specify which buffer to read and write
785 * for software rasterization (swrast) fallbacks. This doesn't necessarily
786 * correspond to glDrawBuffer() or glReadBuffer() calls.
789 set_buffer (GLcontext
*ctx
, GLframebuffer
*colorBuffer
, GLuint bufferBit
)
792 * XXX todo - examine bufferBit and set read/write pointers
794 /* Normally, we would have
795 * ctx->Driver.ReadBuffer == set_read_buffer
796 * ctx->Driver.DrawBuffer == set_draw_buffer
797 * and make sure set_draw_buffer calls _swrast_DrawBuffer,
798 * which in turn will call this routine via dd->SetBuffer.
804 * Return the width and height of the current buffer.
805 * If anything special has to been done when the buffer/window is
806 * resized, do it now.
809 get_buffer_size (GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
811 DMesaBuffer b
= (DMesaBuffer
)buffer
;
819 viewport(GLcontext
*ctx
, GLint x
, GLint y
, GLsizei w
, GLsizei h
)
821 /* poll for window size change and realloc software Z/stencil/etc if needed */
822 _mesa_ResizeBuffersMESA();
826 static const GLubyte
*
827 get_string (GLcontext
*ctx
, GLenum name
)
831 return (const GLubyte
*)"Mesa DJGPP";
839 finish (GLcontext
*ctx
)
842 * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible
848 flush (GLcontext
*ctx
)
851 * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible
856 /****************************************************************************
858 ***************************************************************************/
859 #define DMESA_NEW_LINE (_NEW_LINE | \
864 _SWRAST_NEW_RASTERMASK)
866 #define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \
871 _SWRAST_NEW_RASTERMASK)
873 /* Extend the software rasterizer with our line and triangle
877 dmesa_register_swrast_functions (GLcontext
*ctx
)
879 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
881 swrast
->choose_line
= dmesa_choose_line
;
882 swrast
->choose_triangle
= dmesa_choose_tri
;
884 swrast
->invalidate_line
|= DMESA_NEW_LINE
;
885 swrast
->invalidate_triangle
|= DMESA_NEW_TRIANGLE
;
890 dmesa_update_state (GLcontext
*ctx
, GLuint new_state
)
892 /* Propagate statechange information to swrast and swrast_setup
893 * modules. The DMesa driver has no internal GL-dependent state.
895 _swrast_InvalidateState( ctx
, new_state
);
896 _ac_InvalidateState( ctx
, new_state
);
897 _tnl_InvalidateState( ctx
, new_state
);
898 _swsetup_InvalidateState( ctx
, new_state
);
902 /* Initialize the device driver function table with the functions
903 * we implement in this driver.
906 dmesa_init_driver_functions (DMesaVisual visual
,
907 struct dd_function_table
*driver
)
909 driver
->UpdateState
= dmesa_update_state
;
910 driver
->GetString
= get_string
;
911 driver
->GetBufferSize
= get_buffer_size
;
912 driver
->Viewport
= viewport
;
913 driver
->Flush
= flush
;
914 driver
->Finish
= finish
;
915 driver
->Clear
= clear
;
916 driver
->ClearColor
= clear_color
;
917 driver
->ClearIndex
= clear_index
;
919 driver
->ChooseTextureFormat
= choose_tex_format
;
924 /* Setup pointers and other driver state that is constant for the life
928 dmesa_init_pointers (GLcontext
*ctx
)
930 struct swrast_device_driver
*dd
= _swrast_GetDeviceDriverReference(ctx
);
932 dd
->SetBuffer
= set_buffer
;
934 /* The span functions should be in `dmesa_update_state', but I'm
935 * pretty sure they will never change during the life of the Visual
938 /* Index span/pixel functions */
939 dd
->WriteCI32Span
= write_index_span
;
940 dd
->WriteCI8Span
= write_index8_span
;
941 dd
->WriteMonoCISpan
= write_mono_index_span
;
942 dd
->WriteCI32Pixels
= write_index_pixels
;
943 dd
->WriteMonoCIPixels
= write_mono_index_pixels
;
944 dd
->ReadCI32Span
= read_index_span
;
945 dd
->ReadCI32Pixels
= read_index_pixels
;
947 /* RGB(A) span/pixel functions */
948 dd
->WriteRGBASpan
= write_rgba_span
;
949 dd
->WriteRGBSpan
= write_rgb_span
;
950 dd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
951 dd
->WriteRGBAPixels
= write_rgba_pixels
;
952 dd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
953 dd
->ReadRGBASpan
= read_rgba_span
;
954 dd
->ReadRGBAPixels
= read_rgba_pixels
;
959 /****************************************************************************
960 * DMesa Public API Functions
961 ***************************************************************************/
964 * The exact arguments to this function will depend on your window system
967 DMesaCreateVisual (GLint width
,
979 GLint redBits
, greenBits
, blueBits
, alphaBits
, indexBits
;
1021 * `alphaBits' is what we can provide
1022 * `alphaSize' is what app requests
1024 * Note that alpha buffering is required only if destination alpha is used
1025 * in alpha blending; alpha blending modes that do not use destination alpha
1026 * can be used w/o alpha buffer.
1028 * We will use whatever ALPHA app requests. Later, in `CreateBuffer' we'll
1029 * instruct Mesa to use its own ALPHA buffer, by passing a non-FALSE value
1030 * for ALPHA to `_mesa_initialize_framebuffer'.
1032 * Basically, 32bit modes provide ALPHA storage, but can we rely on this?
1034 alphaBits
= alphaSize
;
1035 sw_alpha
= (alphaBits
> 0);
1041 if ((colDepth
=vl_video_init(width
, height
, colDepth
, rgbFlag
, refresh
)) <= 0) {
1050 if ((env
= getenv("MESA_FX_INFO")) && (env
[0] == 'r')) {
1051 freopen("MESA.LOG", "w", stderr
);
1054 if (refresh
&& (((env
= getenv("FX_GLIDE_REFRESH")) == NULL
) || !atoi(env
))) {
1055 /* if we are passed non-zero value for refresh, we need to override
1056 * default refresh rate. However, if FX_GLIDE_REFRESH is already set
1057 * to 0, we won't override it, because it has a special meaning for
1058 * DJGPP Glide3x (switch via VESA, using BIOS default refresh).
1061 sprintf(tmp
, "FX_GLIDE_REFRESH=%u", refresh
);
1067 if ((v
=(DMesaVisual
)CALLOC_STRUCT(dmesa_visual
)) != NULL
) {
1068 /* Create core visual */
1069 _mesa_initialize_visual((GLvisual
*)v
,
1072 GL_FALSE
, /* stereo */
1077 indexBits
, /* indexBits */
1080 accumSize
, /* accumRed */
1081 accumSize
, /* accumGreen */
1082 accumSize
, /* accumBlue */
1083 alphaBits
?accumSize
:0, /* accumAlpha */
1084 1); /* numSamples */
1087 v
->sw_alpha
= sw_alpha
;
1088 v
->z_buffer
= (depthSize
> 0) ? 1 : 0;
1097 DMesaDestroyVisual (DMesaVisual v
)
1102 _mesa_destroy_visual((GLvisual
*)v
);
1107 DMesaCreateBuffer (DMesaVisual visual
,
1108 GLint xpos
, GLint ypos
,
1109 GLint width
, GLint height
)
1114 if ((b
=(DMesaBuffer
)CALLOC_STRUCT(dmesa_buffer
)) != NULL
) {
1115 _mesa_initialize_framebuffer((GLframebuffer
*)b
,
1117 visual
->z_buffer
== 1,
1118 ((GLvisual
*)visual
)->stencilBits
> 0,
1119 ((GLvisual
*)visual
)->accumRedBits
> 0,
1130 GLvisual
*v
= (GLvisual
*)visual
;
1131 int i
= 0, fx_attrib
[32];
1133 if (v
->doubleBufferMode
) fx_attrib
[i
++] = FXMESA_DOUBLEBUFFER
;
1134 if (v
->depthBits
> 0) { fx_attrib
[i
++] = FXMESA_DEPTH_SIZE
; fx_attrib
[i
++] = v
->depthBits
; }
1135 if (v
->stencilBits
> 0) { fx_attrib
[i
++] = FXMESA_STENCIL_SIZE
; fx_attrib
[i
++] = v
->stencilBits
; }
1136 if (v
->accumRedBits
> 0) { fx_attrib
[i
++] = FXMESA_ACCUM_SIZE
; fx_attrib
[i
++] = v
->accumRedBits
; }
1137 if (v
->alphaBits
) { fx_attrib
[i
++] = FXMESA_ALPHA_SIZE
; fx_attrib
[i
++] = v
->alphaBits
; }
1138 fx_attrib
[i
++] = FXMESA_COLORDEPTH
;
1139 fx_attrib
[i
++] = v
->redBits
+ v
->greenBits
+ v
->blueBits
;
1140 fx_attrib
[i
] = FXMESA_NONE
;
1142 return (DMesaBuffer
)fxMesaCreateBestContext(-1, width
, height
, fx_attrib
);
1148 DMesaDestroyBuffer (DMesaBuffer b
)
1151 if (b
->the_window
!= NULL
) {
1152 free(b
->the_window
);
1154 _mesa_destroy_framebuffer((GLframebuffer
*)b
);
1156 fxMesaDestroyContext((fxMesaContext
)b
);
1162 DMesaCreateContext (DMesaVisual visual
, DMesaContext share
)
1167 struct dd_function_table functions
;
1169 if ((c
=(GLcontext
*)CALLOC_STRUCT(dmesa_context
)) != NULL
) {
1170 /* Initialize device driver function table */
1171 _mesa_init_driver_functions(&functions
);
1172 /* override with our functions */
1173 dmesa_init_driver_functions(visual
, &functions
);
1175 _mesa_initialize_context(c
,
1181 _mesa_enable_sw_extensions(c
);
1182 _mesa_enable_1_3_extensions(c
);
1183 _mesa_enable_1_4_extensions(c
);
1184 _mesa_enable_1_5_extensions(c
);
1185 _mesa_enable_2_0_extensions(c
);
1188 _mesa_enable_extension(c
, "GL_EXT_texture_compression_s3tc");
1189 _mesa_enable_extension(c
, "GL_S3_s3tc");
1191 _mesa_enable_extension(c
, "GL_3DFX_texture_compression_FXT1");
1194 /* you probably have to do a bunch of other initializations here. */
1195 ((DMesaContext
)c
)->visual
= visual
;
1197 /* Initialize the software rasterizer and helper modules.
1199 _swrast_CreateContext(c
);
1200 _ac_CreateContext(c
);
1201 _tnl_CreateContext(c
);
1202 _swsetup_CreateContext(c
);
1204 tnl
= TNL_CONTEXT(c
);
1205 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
1207 if (((GLvisual
*)visual
)->rgbMode
) dmesa_register_swrast_functions(c
);
1208 dmesa_init_pointers(c
);
1213 c
= (GLcontext
*)0xdeadbeef;
1216 return (DMesaContext
)c
;
1221 DMesaDestroyContext (DMesaContext c
)
1225 _swsetup_DestroyContext((GLcontext
*)c
);
1226 _swrast_DestroyContext((GLcontext
*)c
);
1227 _tnl_DestroyContext((GLcontext
*)c
);
1228 _ac_DestroyContext((GLcontext
*)c
);
1229 _mesa_destroy_context((GLcontext
*)c
);
1236 DMesaMoveBuffer (GLint xpos
, GLint ypos
)
1239 GET_CURRENT_CONTEXT(ctx
);
1240 DMesaBuffer b
= ((DMesaContext
)ctx
)->buffer
;
1242 if (vl_sync_buffer(&b
->the_window
, xpos
, ypos
, b
->width
, b
->height
) == 0) {
1254 DMesaResizeBuffer (GLint width
, GLint height
)
1257 GET_CURRENT_CONTEXT(ctx
);
1258 DMesaBuffer b
= ((DMesaContext
)ctx
)->buffer
;
1260 if (vl_sync_buffer(&b
->the_window
, b
->xpos
, b
->ypos
, width
, height
) == 0) {
1272 * Make the specified context and buffer the current one.
1275 DMesaMakeCurrent (DMesaContext c
, DMesaBuffer b
)
1278 if ((c
!= NULL
) && (b
!= NULL
)) {
1279 if (vl_sync_buffer(&b
->the_window
, b
->xpos
, b
->ypos
, b
->width
, b
->height
) != 0) {
1285 _mesa_make_current((GLcontext
*)c
, (GLframebuffer
*)b
);
1289 _mesa_make_current(NULL
, NULL
);
1293 fxMesaMakeCurrent((fxMesaContext
)b
);
1301 DMesaSwapBuffers (DMesaBuffer b
)
1303 /* copy/swap back buffer to front if applicable */
1305 GET_CURRENT_CONTEXT(ctx
);
1306 _mesa_notifySwapBuffers(ctx
);
1309 fxMesaSwapBuffers();
1315 DMesaSetCI (int ndx
, GLfloat red
, GLfloat green
, GLfloat blue
)
1318 vl_setCI(ndx
, red
, green
, blue
);
1324 DMesaGetCurrentContext (void)
1326 GET_CURRENT_CONTEXT(ctx
);
1331 ctx
= (GLcontext
*)0xdeadbeef;
1335 return (DMesaContext
)ctx
;
1340 DMesaGetCurrentBuffer (void)
1342 const DMesaContext dmesa
= DMesaGetCurrentContext();
1344 if (dmesa
== NULL
) {
1349 return dmesa
->buffer
;
1351 return (DMesaBuffer
)fxMesaGetCurrentContext();
1357 DMesaGetProcAddress (const char *name
)
1359 DMesaProc p
= (DMesaProc
)_glapi_get_proc_address(name
);
1361 /* TODO: handle DMesa* namespace
1371 DMesaGetIntegerv (GLenum pname
, GLint
*params
)
1374 case DMESA_GET_SCREEN_SIZE
:
1376 vl_get(VL_GET_SCREEN_SIZE
, params
);
1378 fxGetScreenGeometry(¶ms
[0], ¶ms
[1]);
1381 case DMESA_GET_DRIVER_CAPS
:
1383 params
[0] = DMESA_DRIVER_SWDB_BIT
;
1385 params
[0] = DMESA_DRIVER_LLWO_BIT
;
1388 case DMESA_GET_VIDEO_MODES
:
1390 return vl_get(VL_GET_VIDEO_MODES
, params
);
1392 return -1; /* TODO */
1394 case DMESA_GET_BUFFER_ADDR
: {
1396 DMesaContext c
= (DMesaContext
)DMesaGetCurrentContext();
1398 DMesaBuffer b
= c
->buffer
;
1400 params
[0] = (GLint
)b
->the_window
;
1416 #if SWTC && (((__DJGPP__ << 8) | __DJGPP_MINOR__) >= 0x204)
1417 #include <sys/dxe.h>
1419 extern_asm(___dj_assert
);
1421 extern_asm(_malloc
);
1422 extern_asm(_memset
);
1424 DXE_EXPORT_TABLE_AUTO (___dxe_eta___dxtn
)
1425 DXE_EXPORT_ASM (___dj_assert
)
1426 DXE_EXPORT_ASM (_free
)
1427 DXE_EXPORT_ASM (_malloc
)
1428 DXE_EXPORT_ASM (_memset
)