2 * Mesa 3-D graphics library
5 * Copyright (C) 1999-2003 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.5 for Mesa
28 * Copyright (c) 2003 - Borca Daniel
29 * Email : dborca@users.sourceforge.net
30 * Web : http://www.geocities.com/dborca
37 #include "bufferobj.h"
38 #include "extensions.h"
42 #include "texformat.h"
46 #include "array_cache/acache.h"
47 #include "swrast/s_context.h"
48 #include "swrast/s_depth.h"
49 #include "swrast/s_lines.h"
50 #include "swrast/s_triangle.h"
51 #include "swrast/swrast.h"
52 #include "swrast_setup/swrast_setup.h"
54 #include "tnl/t_context.h"
55 #include "tnl/t_pipeline.h"
58 #include "GL/fxmesa.h"
66 * In C++ terms, this class derives from the GLvisual class.
67 * Add system-specific fields to it.
71 GLboolean db_flag
; /* double buffered? */
72 GLboolean rgb_flag
; /* RGB mode? */
73 GLboolean sw_alpha
; /* use Mesa's alpha buffer? */
74 GLuint depth
; /* bits per pixel (1, 8, 24, etc) */
75 int zbuffer
; /* Z=buffer: 0=no, 1=SW, -1=HW */
79 * In C++ terms, this class derives from the GLframebuffer class.
80 * Add system-specific fields to it.
83 GLframebuffer gl_buffer
; /* The depth, stencil, accum, etc buffers */
84 void *the_window
; /* your window handle, etc */
86 int xpos
, ypos
; /* position */
87 int width
, height
; /* size in pixels */
91 * In C++ terms, this class derives from the GLcontext class.
92 * Add system-specific fields to it.
94 struct dmesa_context
{
95 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 ***************************************************************************/
117 static void write_rgba_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
118 const GLubyte rgba
[][4], const GLubyte mask
[])
120 const DMesaContext dmesa
= (DMesaContext
)ctx
;
123 offset
= DSTRIDE
* FLIP(y
) + x
;
125 /* draw some pixels */
126 for (i
=0; i
<n
; i
++, offset
++) {
128 vl_putpixel(offset
, vl_mixrgba(rgba
[i
]));
132 /* draw all pixels */
133 for (i
=0; i
<n
; i
++, offset
++) {
134 vl_putpixel(offset
, vl_mixrgba(rgba
[i
]));
141 static void write_rgb_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
142 const GLubyte rgb
[][3], const GLubyte mask
[])
144 const DMesaContext dmesa
= (DMesaContext
)ctx
;
147 offset
= DSTRIDE
* FLIP(y
) + x
;
149 /* draw some pixels */
150 for (i
=0; i
<n
; i
++, offset
++) {
152 vl_putpixel(offset
, vl_mixrgb(rgb
[i
]));
156 /* draw all pixels */
157 for (i
=0; i
<n
; i
++, offset
++) {
158 vl_putpixel(offset
, vl_mixrgb(rgb
[i
]));
165 static void write_mono_rgba_span (const GLcontext
*ctx
,
166 GLuint n
, GLint x
, GLint y
,
167 const GLchan color
[4], const GLubyte mask
[])
169 const DMesaContext dmesa
= (DMesaContext
)ctx
;
170 GLuint i
, offset
, rgba
= vl_mixrgba(color
);
172 offset
= DSTRIDE
* FLIP(y
) + x
;
174 /* draw some pixels */
175 for (i
=0; i
<n
; i
++, offset
++) {
177 vl_putpixel(offset
, rgba
);
181 /* draw all pixels */
182 for (i
=0; i
<n
; i
++, offset
++) {
183 vl_putpixel(offset
, rgba
);
190 static void read_rgba_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
193 const DMesaContext dmesa
= (DMesaContext
)ctx
;
196 offset
= DSTRIDE
* FLIP(y
) + x
;
197 /* read all pixels */
198 for (i
=0; i
<n
; i
++, offset
++) {
199 vl_getrgba(offset
, rgba
[i
]);
205 static void write_rgba_pixels (const GLcontext
*ctx
,
206 GLuint n
, const GLint x
[], const GLint y
[],
207 const GLubyte rgba
[][4], const GLubyte mask
[])
209 const DMesaContext dmesa
= (DMesaContext
)ctx
;
210 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->Buffer
->height
- 1;
213 /* draw some pixels */
214 for (i
=0; i
<n
; i
++) {
216 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], vl_mixrgba(rgba
[i
]));
220 /* draw all pixels */
221 for (i
=0; i
<n
; i
++) {
222 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], vl_mixrgba(rgba
[i
]));
229 static void write_mono_rgba_pixels (const GLcontext
*ctx
,
230 GLuint n
, const GLint x
[], const GLint y
[],
231 const GLchan color
[4], const GLubyte mask
[])
233 const DMesaContext dmesa
= (DMesaContext
)ctx
;
234 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->Buffer
->height
- 1, rgba
= vl_mixrgba(color
);
237 /* draw some pixels */
238 for (i
=0; i
<n
; i
++) {
240 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
);
244 /* draw all pixels */
245 for (i
=0; i
<n
; i
++) {
246 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
);
253 static void read_rgba_pixels (const GLcontext
*ctx
,
254 GLuint n
, const GLint x
[], const GLint y
[],
255 GLubyte rgba
[][4], const GLubyte mask
[])
257 const DMesaContext dmesa
= (DMesaContext
)ctx
;
258 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->Buffer
->height
- 1;
261 /* read some pixels */
262 for (i
=0; i
<n
; i
++) {
264 vl_getrgba(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
[i
]);
268 /* read all pixels */
269 for (i
=0; i
<n
; i
++) {
270 vl_getrgba(FLIP2(y
[i
])*_w_
+ x
[i
], rgba
[i
]);
277 /****************************************************************************
279 ***************************************************************************/
280 static void write_index_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
281 const GLuint index
[], const GLubyte mask
[])
283 const DMesaContext dmesa
= (DMesaContext
)ctx
;
286 offset
= DSTRIDE
* FLIP(y
) + x
;
288 /* draw some pixels */
289 for (i
=0; i
<n
; i
++, offset
++) {
291 vl_putpixel(offset
, index
[i
]);
295 /* draw all pixels */
296 for (i
=0; i
<n
; i
++, offset
++) {
297 vl_putpixel(offset
, index
[i
]);
304 static void write_index8_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
305 const GLubyte index
[], const GLubyte mask
[])
307 const DMesaContext dmesa
= (DMesaContext
)ctx
;
310 offset
= DSTRIDE
* FLIP(y
) + x
;
312 /* draw some pixels */
313 for (i
=0; i
<n
; i
++, offset
++) {
315 vl_putpixel(offset
, index
[i
]);
319 /* draw all pixels */
320 for (i
=0; i
<n
; i
++, offset
++) {
321 vl_putpixel(offset
, index
[i
]);
328 static void write_mono_index_span (const GLcontext
*ctx
,
329 GLuint n
, GLint x
, GLint y
,
330 GLuint colorIndex
, const GLubyte mask
[])
332 const DMesaContext dmesa
= (DMesaContext
)ctx
;
335 offset
= DSTRIDE
* FLIP(y
) + x
;
337 /* draw some pixels */
338 for (i
=0; i
<n
; i
++, offset
++) {
340 vl_putpixel(offset
, colorIndex
);
344 /* draw all pixels */
345 for (i
=0; i
<n
; i
++, offset
++) {
346 vl_putpixel(offset
, colorIndex
);
353 static void read_index_span (const GLcontext
*ctx
, GLuint n
, GLint x
, GLint y
,
356 const DMesaContext dmesa
= (DMesaContext
)ctx
;
359 offset
= DSTRIDE
* FLIP(y
) + x
;
360 /* read all pixels */
361 for (i
=0; i
<n
; i
++, offset
++) {
362 index
[i
] = vl_getpixel(offset
);
368 static void write_index_pixels (const GLcontext
*ctx
,
369 GLuint n
, const GLint x
[], const GLint y
[],
370 const GLuint index
[], const GLubyte mask
[])
372 const DMesaContext dmesa
= (DMesaContext
)ctx
;
373 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->Buffer
->height
- 1;
376 /* draw some pixels */
377 for (i
=0; i
<n
; i
++) {
379 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], index
[i
]);
383 /* draw all pixels */
384 for (i
=0; i
<n
; i
++) {
385 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], index
[i
]);
392 static void write_mono_index_pixels (const GLcontext
*ctx
,
393 GLuint n
, const GLint x
[], const GLint y
[],
394 GLuint colorIndex
, const GLubyte mask
[])
396 const DMesaContext dmesa
= (DMesaContext
)ctx
;
397 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->Buffer
->height
- 1;
400 /* draw some pixels */
401 for (i
=0; i
<n
; i
++) {
403 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], colorIndex
);
407 /* draw all pixels */
408 for (i
=0; i
<n
; i
++) {
409 vl_putpixel(FLIP2(y
[i
])*_w_
+ x
[i
], colorIndex
);
416 static void read_index_pixels (const GLcontext
*ctx
,
417 GLuint n
, const GLint x
[], const GLint y
[],
418 GLuint index
[], const GLubyte mask
[])
420 const DMesaContext dmesa
= (DMesaContext
)ctx
;
421 GLuint i
, _w_
= DSTRIDE
, _b_
= dmesa
->Buffer
->height
- 1;
424 /* read some pixels */
425 for (i
=0; i
<n
; i
++) {
427 index
[i
] = vl_getpixel(FLIP2(y
[i
])*_w_
+ x
[i
]);
431 /* read all pixels */
432 for (i
=0; i
<n
; i
++) {
433 index
[i
] = vl_getpixel(FLIP2(y
[i
])*_w_
+ x
[i
]);
440 /****************************************************************************
442 ***************************************************************************/
446 /****************************************************************************
447 * Optimized triangle rendering
448 ***************************************************************************/
451 * NON-depth-buffered flat triangle.
453 #define NAME tri_rgb_flat
456 const DMesaContext dmesa = (DMesaContext)ctx; \
457 GLuint _b_ = dmesa->Buffer->height - 1; \
458 GLuint _w_ = dmesa->Buffer->width; \
459 GLuint rgb = vl_mixrgb(v2->color);
461 #define RENDER_SPAN(span) \
462 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
463 for (i = 0; i < span.end; i++, offset++) { \
464 vl_putpixel(offset, rgb); \
467 #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"
501 * NON-depth-buffered iterated triangle.
503 #define NAME tri_rgb_iter
508 const DMesaContext dmesa = (DMesaContext)ctx; \
509 GLuint _b_ = dmesa->Buffer->height - 1; \
510 GLuint _w_ = dmesa->Buffer->width;
512 #define RENDER_SPAN(span) \
513 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
514 for (i = 0; i < span.end; i++, offset++) { \
515 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue)); \
516 span.red += span.redStep; \
517 span.green += span.greenStep; \
518 span.blue += span.blueStep; \
521 #include "swrast/s_tritemp.h"
526 * Z-less iterated triangle.
528 #define NAME tri_rgb_iter_zless
531 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
535 const DMesaContext dmesa = (DMesaContext)ctx; \
536 GLuint _b_ = dmesa->Buffer->height - 1; \
537 GLuint _w_ = dmesa->Buffer->width;
539 #define RENDER_SPAN(span) \
540 GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \
541 for (i = 0; i < span.end; i++, offset++) { \
542 const DEPTH_TYPE z = FixedToDepth(span.z); \
544 vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\
547 span.red += span.redStep; \
548 span.green += span.greenStep; \
549 span.blue += span.blueStep; \
550 span.z += span.zStep; \
553 #include "swrast/s_tritemp.h"
558 * Analyze context state to see if we can provide a fast triangle function
559 * Otherwise, return NULL.
561 static swrast_tri_func
dmesa_choose_tri_function (GLcontext
*ctx
)
563 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
565 if ((ctx
->RenderMode
!= GL_RENDER
)
566 || (ctx
->Polygon
.SmoothFlag
)
567 || (ctx
->Polygon
.StippleFlag
)
568 || (ctx
->Texture
._EnabledUnits
)
569 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)
570 || (ctx
->Polygon
.CullFlag
&& ctx
->Polygon
.CullFaceMode
== GL_FRONT_AND_BACK
)) {
571 return (swrast_tri_func
)NULL
;
574 if (swrast
->_RasterMask
==DEPTH_BIT
575 && ctx
->Depth
.Func
==GL_LESS
576 && ctx
->Depth
.Mask
==GL_TRUE
577 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
578 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? tri_rgb_iter_zless
: tri_rgb_flat_zless
;
581 if (swrast
->_RasterMask
==0) { /* no depth test */
582 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? tri_rgb_iter
: tri_rgb_flat
;
585 return (swrast_tri_func
)NULL
;
590 /* Override for the swrast triangle-selection function. Try to use one
591 * of our internal triangle functions, otherwise fall back to the
592 * standard swrast functions.
594 static void dmesa_choose_tri (GLcontext
*ctx
)
596 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
598 if (!(swrast
->Triangle
=dmesa_choose_tri_function(ctx
)))
599 _swrast_choose_triangle(ctx
);
604 /****************************************************************************
605 * Optimized line rendering
606 ***************************************************************************/
609 * NON-depth-buffered flat line.
611 #define NAME line_rgb_flat
617 const DMesaContext dmesa = (DMesaContext)ctx; \
618 GLuint _b_ = dmesa->Buffer->height - 1; \
619 GLuint _w_ = dmesa->Buffer->width; \
620 GLuint rgb = vl_mixrgb(vert1->color);
622 #define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb);
624 #include "swrast/s_linetemp.h"
631 #define NAME line_rgb_flat_zless
635 #define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
639 const DMesaContext dmesa = (DMesaContext)ctx; \
640 GLuint _b_ = dmesa->Buffer->height - 1; \
641 GLuint _w_ = dmesa->Buffer->width; \
642 GLuint rgb = vl_mixrgb(vert1->color);
647 vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \
650 #include "swrast/s_linetemp.h"
655 * NON-depth-buffered iterated line.
657 #define line_rgb_iter NULL
662 * Z-less iterated line.
664 #define line_rgb_iter_zless NULL
669 * Analyze context state to see if we can provide a fast line function
670 * Otherwise, return NULL.
672 static swrast_line_func
dmesa_choose_line_function (GLcontext
*ctx
)
674 const SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
676 if ((ctx
->RenderMode
!= GL_RENDER
)
677 || (ctx
->Line
.SmoothFlag
)
678 || (ctx
->Texture
._EnabledUnits
)
679 || (ctx
->Line
.StippleFlag
)
680 || (swrast
->_RasterMask
& MULTI_DRAW_BIT
)
681 || (ctx
->Line
.Width
!=1.0F
)) {
682 return (swrast_line_func
)NULL
;
685 if (swrast
->_RasterMask
==DEPTH_BIT
686 && ctx
->Depth
.Func
==GL_LESS
687 && ctx
->Depth
.Mask
==GL_TRUE
688 && ctx
->Visual
.depthBits
== DEFAULT_SOFTWARE_DEPTH_BITS
) {
689 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? line_rgb_iter_zless
: line_rgb_flat_zless
;
692 if (swrast
->_RasterMask
==0) { /* no depth test */
693 return (ctx
->Light
.ShadeModel
==GL_SMOOTH
) ? line_rgb_iter
: line_rgb_flat
;
696 return (swrast_line_func
)NULL
;
701 /* Override for the swrast line-selection function. Try to use one
702 * of our internal line functions, otherwise fall back to the
703 * standard swrast functions.
705 static void dmesa_choose_line (GLcontext
*ctx
)
707 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
709 if (!(swrast
->Line
=dmesa_choose_line_function(ctx
)))
710 _swrast_choose_line(ctx
);
715 /****************************************************************************
716 * Miscellaneous device driver funcs
717 ***************************************************************************/
719 static void clear_index (GLcontext
*ctx
, GLuint index
)
721 ((DMesaContext
)ctx
)->ClearIndex
= index
;
724 static void clear_color (GLcontext
*ctx
, const GLfloat color
[4])
727 CLAMPED_FLOAT_TO_UBYTE(col
[0], color
[0]);
728 CLAMPED_FLOAT_TO_UBYTE(col
[1], color
[1]);
729 CLAMPED_FLOAT_TO_UBYTE(col
[2], color
[2]);
730 CLAMPED_FLOAT_TO_UBYTE(col
[3], color
[3]);
731 ((DMesaContext
)ctx
)->ClearColor
= vl_mixrgba(col
);
736 static void clear (GLcontext
*ctx
, GLbitfield mask
, GLboolean all
,
737 GLint x
, GLint y
, GLint width
, GLint height
)
739 const DMesaContext c
= (DMesaContext
)ctx
;
740 const GLuint
*colorMask
= (GLuint
*)&ctx
->Color
.ColorMask
;
743 * Clear the specified region of the buffers indicated by 'mask'
744 * using the clear color or index as specified by one of the two
746 * If all==GL_TRUE, clear whole buffer, else just clear region defined
747 * by x,y,width,height
750 /* we can't handle color or index masking */
751 if ((*colorMask
== 0xffffffff) && (ctx
->Color
.IndexMask
== 0xffffffff)) {
752 if (mask
& DD_BACK_LEFT_BIT
) {
753 int color
= c
->visual
->rgb_flag
? c
->ClearColor
: c
->ClearIndex
;
758 vl_rect(x
, y
, width
, height
, color
);
761 mask
&= ~DD_BACK_LEFT_BIT
;
766 _swrast_Clear(ctx
, mask
, all
, x
, y
, width
, height
);
773 * This function is called to specify which buffer to read and write
774 * for software rasterization (swrast) fallbacks. This doesn't necessarily
775 * correspond to glDrawBuffer() or glReadBuffer() calls.
777 static void set_buffer (GLcontext
*ctx
, GLframebuffer
*colorBuffer
, GLuint bufferBit
)
780 * XXX todo - examine bufferBit and set read/write pointers
782 /* Normally, we would have
783 * ctx->Driver.ReadBuffer == set_read_buffer
784 * ctx->Driver.DrawBuffer == set_draw_buffer
785 * and make sure set_draw_buffer calls _swrast_DrawBuffer,
786 * which in turn will call this routine via dd->SetBuffer.
793 * Return the width and height of the current buffer.
794 * If anything special has to been done when the buffer/window is
795 * resized, do it now.
797 static void get_buffer_size (GLframebuffer
*buffer
, GLuint
*width
, GLuint
*height
)
799 DMesaBuffer b
= (DMesaBuffer
)buffer
;
807 static const GLubyte
* get_string (GLcontext
*ctx
, GLenum name
)
811 return (const GLubyte
*)"Mesa DJGPP"
812 "\0port (c) Borca Daniel dec-2003";
820 static void finish (GLcontext
*ctx
)
823 * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible
829 static void flush (GLcontext
*ctx
)
832 * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible
838 /****************************************************************************
840 ***************************************************************************/
841 #define DMESA_NEW_LINE (_NEW_LINE | \
846 _SWRAST_NEW_RASTERMASK)
848 #define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \
853 _SWRAST_NEW_RASTERMASK)
855 /* Extend the software rasterizer with our line and triangle
858 static void dmesa_register_swrast_functions (GLcontext
*ctx
)
860 SWcontext
*swrast
= SWRAST_CONTEXT(ctx
);
862 swrast
->choose_line
= dmesa_choose_line
;
863 swrast
->choose_triangle
= dmesa_choose_tri
;
865 swrast
->invalidate_line
|= DMESA_NEW_LINE
;
866 swrast
->invalidate_triangle
|= DMESA_NEW_TRIANGLE
;
871 /* Setup pointers and other driver state that is constant for the life
874 static void dmesa_init_pointers (GLcontext
*ctx
)
877 struct swrast_device_driver
*dd
= _swrast_GetDeviceDriverReference(ctx
);
879 ctx
->Driver
.GetString
= get_string
;
880 ctx
->Driver
.GetBufferSize
= get_buffer_size
;
881 ctx
->Driver
.Flush
= flush
;
882 ctx
->Driver
.Finish
= finish
;
884 /* Software rasterizer pixel paths:
886 ctx
->Driver
.Accum
= _swrast_Accum
;
887 ctx
->Driver
.Bitmap
= _swrast_Bitmap
;
888 ctx
->Driver
.Clear
= clear
;
889 ctx
->Driver
.ResizeBuffers
= _swrast_alloc_buffers
;
890 ctx
->Driver
.CopyPixels
= _swrast_CopyPixels
;
891 ctx
->Driver
.DrawPixels
= _swrast_DrawPixels
;
892 ctx
->Driver
.ReadPixels
= _swrast_ReadPixels
;
893 ctx
->Driver
.DrawBuffer
= _swrast_DrawBuffer
;
895 /* Software texture functions:
897 ctx
->Driver
.ChooseTextureFormat
= _mesa_choose_tex_format
;
898 ctx
->Driver
.TexImage1D
= _mesa_store_teximage1d
;
899 ctx
->Driver
.TexImage2D
= _mesa_store_teximage2d
;
900 ctx
->Driver
.TexImage3D
= _mesa_store_teximage3d
;
901 ctx
->Driver
.TexSubImage1D
= _mesa_store_texsubimage1d
;
902 ctx
->Driver
.TexSubImage2D
= _mesa_store_texsubimage2d
;
903 ctx
->Driver
.TexSubImage3D
= _mesa_store_texsubimage3d
;
904 ctx
->Driver
.TestProxyTexImage
= _mesa_test_proxy_teximage
;
906 ctx
->Driver
.CopyTexImage1D
= _swrast_copy_teximage1d
;
907 ctx
->Driver
.CopyTexImage2D
= _swrast_copy_teximage2d
;
908 ctx
->Driver
.CopyTexSubImage1D
= _swrast_copy_texsubimage1d
;
909 ctx
->Driver
.CopyTexSubImage2D
= _swrast_copy_texsubimage2d
;
910 ctx
->Driver
.CopyTexSubImage3D
= _swrast_copy_texsubimage3d
;
912 ctx
->Driver
.CompressedTexImage1D
= _mesa_store_compressed_teximage1d
;
913 ctx
->Driver
.CompressedTexImage2D
= _mesa_store_compressed_teximage2d
;
914 ctx
->Driver
.CompressedTexImage3D
= _mesa_store_compressed_teximage3d
;
915 ctx
->Driver
.CompressedTexSubImage1D
= _mesa_store_compressed_texsubimage1d
;
916 ctx
->Driver
.CompressedTexSubImage2D
= _mesa_store_compressed_texsubimage2d
;
917 ctx
->Driver
.CompressedTexSubImage3D
= _mesa_store_compressed_texsubimage3d
;
919 /* Swrast hooks for imaging extensions:
921 ctx
->Driver
.CopyColorTable
= _swrast_CopyColorTable
;
922 ctx
->Driver
.CopyColorSubTable
= _swrast_CopyColorSubTable
;
923 ctx
->Driver
.CopyConvolutionFilter1D
= _swrast_CopyConvolutionFilter1D
;
924 ctx
->Driver
.CopyConvolutionFilter2D
= _swrast_CopyConvolutionFilter2D
;
926 /* Statechange callbacks:
928 ctx
->Driver
.ClearColor
= clear_color
;
929 ctx
->Driver
.ClearIndex
= clear_index
;
931 /* Initialize the TNL driver interface:
933 tnl
= TNL_CONTEXT(ctx
);
934 tnl
->Driver
.RunPipeline
= _tnl_run_pipeline
;
936 dd
->SetBuffer
= set_buffer
;
938 /* Install swsetup for tnl->Driver.Render.*:
940 _swsetup_Wakeup(ctx
);
942 /* The span functions should be in `dmesa_update_state', but I'm
943 * pretty sure they will never change during the life of the Visual
946 /* Index span/pixel functions */
947 dd
->WriteCI32Span
= write_index_span
;
948 dd
->WriteCI8Span
= write_index8_span
;
949 dd
->WriteMonoCISpan
= write_mono_index_span
;
950 dd
->WriteCI32Pixels
= write_index_pixels
;
951 dd
->WriteMonoCIPixels
= write_mono_index_pixels
;
952 dd
->ReadCI32Span
= read_index_span
;
953 dd
->ReadCI32Pixels
= read_index_pixels
;
955 /* RGB(A) span/pixel functions */
956 dd
->WriteRGBASpan
= write_rgba_span
;
957 dd
->WriteRGBSpan
= write_rgb_span
;
958 dd
->WriteMonoRGBASpan
= write_mono_rgba_span
;
959 dd
->WriteRGBAPixels
= write_rgba_pixels
;
960 dd
->WriteMonoRGBAPixels
= write_mono_rgba_pixels
;
961 dd
->ReadRGBASpan
= read_rgba_span
;
962 dd
->ReadRGBAPixels
= read_rgba_pixels
;
967 static void dmesa_update_state (GLcontext
*ctx
, GLuint new_state
)
969 /* Propagate statechange information to swrast and swrast_setup
970 * modules. The DMesa driver has no internal GL-dependent state.
972 _swrast_InvalidateState( ctx
, new_state
);
973 _ac_InvalidateState( ctx
, new_state
);
974 _tnl_InvalidateState( ctx
, new_state
);
975 _swsetup_InvalidateState( ctx
, new_state
);
981 /****************************************************************************
982 * DMesa Public API Functions
983 ***************************************************************************/
986 * The exact arguments to this function will depend on your window system
988 DMesaVisual
DMesaCreateVisual (GLint width
,
1001 GLint redBits
, greenBits
, blueBits
, alphaBits
, indexBits
;
1047 * `alphaBits' is what we can provide
1048 * `alphaSize' is what app requests
1050 * Note that alpha buffering is required only if destination alpha is used
1051 * in alpha blending; alpha blending modes that do not use destination alpha
1052 * can be used w/o alpha buffer.
1054 * We will use whatever ALPHA app requests. Later, in `CreateBuffer' we'll
1055 * instruct Mesa to use its own ALPHA buffer, by passing a non-FALSE value
1056 * for ALPHA to `_mesa_initialize_framebuffer'.
1058 * Basically, 32bit modes provide ALPHA storage, but can we rely on this?
1060 alphaBits
= alphaSize
;
1061 sw_alpha
= (alphaBits
> 0);
1063 if ((colDepth
=vl_video_init(width
, height
, colDepth
, rgbFlag
, refresh
)) <= 0) {
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 */
1086 v
->depth
= colDepth
;
1087 v
->db_flag
= dbFlag
;
1088 v
->rgb_flag
= rgbFlag
;
1089 v
->sw_alpha
= sw_alpha
;
1091 v
->zbuffer
= (depthSize
> 0) ? 1 : 0;
1099 int i
= 0, fx_attrib
[32];
1105 if (dbFlag
) fx_attrib
[i
++] = FXMESA_DOUBLEBUFFER
;
1106 if (depthSize
> 0) { fx_attrib
[i
++] = FXMESA_DEPTH_SIZE
; fx_attrib
[i
++] = depthSize
; }
1107 if (stencilSize
> 0) { fx_attrib
[i
++] = FXMESA_STENCIL_SIZE
; fx_attrib
[i
++] = stencilSize
; }
1108 if (accumSize
> 0) { fx_attrib
[i
++] = FXMESA_ACCUM_SIZE
; fx_attrib
[i
++] = accumSize
; }
1109 if (alphaSize
) { fx_attrib
[i
++] = FXMESA_ALPHA_SIZE
; fx_attrib
[i
++] = alphaSize
; }
1110 fx_attrib
[i
++] = FXMESA_COLORDEPTH
;
1111 fx_attrib
[i
++] = colDepth
;
1112 fx_attrib
[i
] = FXMESA_NONE
;
1114 if ((env
= getenv("MESA_FX_INFO")) && (env
[0] == 'r')) {
1115 freopen("MESA.LOG", "w", stderr
);
1118 return (DMesaVisual
)fxMesaCreateBestContext(-1, width
, height
, fx_attrib
);
1124 void DMesaDestroyVisual (DMesaVisual v
)
1127 _mesa_destroy_visual((GLvisual
*)v
);
1132 fxMesaDestroyContext((fxMesaContext
)v
);
1138 DMesaBuffer
DMesaCreateBuffer (DMesaVisual visual
,
1139 GLint xpos
, GLint ypos
,
1140 GLint width
, GLint height
)
1145 if ((b
=(DMesaBuffer
)CALLOC_STRUCT(dmesa_buffer
)) != NULL
) {
1146 _mesa_initialize_framebuffer((GLframebuffer
*)b
,
1148 visual
->zbuffer
== 1,
1149 ((GLvisual
*)visual
)->stencilBits
> 0,
1150 ((GLvisual
*)visual
)->accumRedBits
> 0,
1160 return (DMesaBuffer
)visual
;
1166 void DMesaDestroyBuffer (DMesaBuffer b
)
1169 free(b
->the_window
);
1170 _mesa_destroy_framebuffer((GLframebuffer
*)b
);
1176 DMesaContext
DMesaCreateContext (DMesaVisual visual
,
1181 GLboolean direct
= GL_FALSE
;
1183 if ((c
=(DMesaContext
)CALLOC_STRUCT(dmesa_context
)) != NULL
) {
1184 _mesa_initialize_context((GLcontext
*)c
,
1189 _mesa_enable_sw_extensions((GLcontext
*)c
);
1190 _mesa_enable_1_3_extensions((GLcontext
*)c
);
1191 _mesa_enable_1_4_extensions((GLcontext
*)c
);
1192 _mesa_enable_1_5_extensions((GLcontext
*)c
);
1194 /* you probably have to do a bunch of other initializations here. */
1197 ((GLcontext
*)c
)->Driver
.UpdateState
= dmesa_update_state
;
1199 /* Initialize the software rasterizer and helper modules.
1201 _swrast_CreateContext((GLcontext
*)c
);
1202 _ac_CreateContext((GLcontext
*)c
);
1203 _tnl_CreateContext((GLcontext
*)c
);
1204 _swsetup_CreateContext((GLcontext
*)c
);
1205 if (visual
->rgb_flag
) dmesa_register_swrast_functions((GLcontext
*)c
);
1206 dmesa_init_pointers((GLcontext
*)c
);
1212 return (DMesaContext
)visual
;
1218 void DMesaDestroyContext (DMesaContext c
)
1222 _swsetup_DestroyContext((GLcontext
*)c
);
1223 _swrast_DestroyContext((GLcontext
*)c
);
1224 _tnl_DestroyContext((GLcontext
*)c
);
1225 _ac_DestroyContext((GLcontext
*)c
);
1226 _mesa_destroy_context((GLcontext
*)c
);
1233 GLboolean
DMesaMoveBuffer (GLint xpos
, GLint ypos
)
1236 GET_CURRENT_CONTEXT(ctx
);
1237 DMesaBuffer b
= ((DMesaContext
)ctx
)->Buffer
;
1239 if (vl_sync_buffer(&b
->the_window
, xpos
, ypos
, b
->width
, b
->height
) != 0) {
1254 GLboolean
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) {
1276 * Make the specified context and buffer the current one.
1278 GLboolean
DMesaMakeCurrent (DMesaContext c
, DMesaBuffer b
)
1281 if ((c
!= NULL
) && (b
!= NULL
)) {
1282 if (vl_sync_buffer(&b
->the_window
, b
->xpos
, b
->ypos
, b
->width
, b
->height
) != 0) {
1288 _mesa_make_current((GLcontext
*)c
, (GLframebuffer
*)b
);
1289 if (((GLcontext
*)c
)->Viewport
.Width
== 0) {
1290 /* initialize viewport to window size */
1291 _mesa_Viewport(0, 0, b
->width
, b
->height
);
1295 _mesa_make_current(NULL
, NULL
);
1299 fxMesaMakeCurrent((fxMesaContext
)c
);
1307 void DMesaSwapBuffers (DMesaBuffer b
)
1309 /* copy/swap back buffer to front if applicable */
1311 GET_CURRENT_CONTEXT(ctx
);
1312 _mesa_notifySwapBuffers(ctx
);
1315 fxMesaSwapBuffers();
1321 void DMesaSetCI (int ndx
, GLfloat red
, GLfloat green
, GLfloat blue
)
1324 vl_setCI(ndx
, red
, green
, blue
);
1330 void *DMesaGetCurrentContext (void)
1333 GET_CURRENT_CONTEXT(ctx
);
1336 return fxMesaGetCurrentContext();
1342 int DMesaGetIntegerv (GLenum pname
, GLint
*params
)
1345 case DMESA_GET_SCREEN_SIZE
:
1347 vl_get(VL_GET_SCREEN_SIZE
, params
);
1349 fxGetScreenGeometry(¶ms
[0], ¶ms
[1]);
1352 case DMESA_GET_DRIVER_CAPS
:
1354 params
[0] = DMESA_DRIVER_SWDB_BIT
;
1356 params
[0] = DMESA_DRIVER_LLWO_BIT
;
1359 case DMESA_GET_VIDEO_MODES
:
1361 return vl_get(VL_GET_VIDEO_MODES
, params
);
1364 /* `vmode' struct must be sync'ed with `internal.h' (vl_mode)
1365 * `vmode' list must be sync'ed with `fxapi.c'
1366 * `hw >= 6' means Napalm and can do 32bit rendering
1367 * TODO: we should take an envvar for `fxMesaSelectCurrentBoard'
1389 int hw
= fxMesaSelectCurrentBoard(0);
1390 int i
, n
= sizeof(vmode
) / sizeof(vmode
[0]);
1395 for (i
= 0; i
< n
; i
++) {
1396 params
[i
] = (GLint
)(&vmode
[i
]);