diff options
Diffstat (limited to 'nx-X11/extras/Mesa_6.4.2/src/mesa/drivers/dos/dmesa.c')
-rw-r--r-- | nx-X11/extras/Mesa_6.4.2/src/mesa/drivers/dos/dmesa.c | 1430 |
1 files changed, 1430 insertions, 0 deletions
diff --git a/nx-X11/extras/Mesa_6.4.2/src/mesa/drivers/dos/dmesa.c b/nx-X11/extras/Mesa_6.4.2/src/mesa/drivers/dos/dmesa.c new file mode 100644 index 000000000..d7c847709 --- /dev/null +++ b/nx-X11/extras/Mesa_6.4.2/src/mesa/drivers/dos/dmesa.c @@ -0,0 +1,1430 @@ +/* + * Mesa 3-D graphics library + * Version: 6.3 + * + * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN + * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +/* + * DOS/DJGPP device driver v1.7 for Mesa + * + * Copyright (c) 2003 - Daniel Borca + * Email : dborca@users.sourceforge.net + * Web : http://www.geocities.com/dborca + */ + + +#include "glheader.h" +#include "context.h" +#include "imports.h" +#ifndef FX +#include "bufferobj.h" +#include "buffers.h" +#include "extensions.h" +#include "macros.h" +#include "matrix.h" +#include "mtypes.h" +#include "texformat.h" +#include "teximage.h" +#include "texstore.h" +#include "array_cache/acache.h" +#include "swrast/s_context.h" +#include "swrast/s_depth.h" +#include "swrast/s_lines.h" +#include "swrast/s_triangle.h" +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" +#include "drivers/common/driverfuncs.h" +#include "video.h" +#else /* FX */ +#include "GL/fxmesa.h" +#endif /* FX */ + +#include "GL/dmesa.h" + + +#define SWTC 0 /* SW texture compression */ + + +/* + * In C++ terms, this class derives from the GLvisual class. + * Add system-specific fields to it. + */ +struct dmesa_visual { + GLvisual gl_visual; + GLboolean sw_alpha; /* use Mesa's alpha buffer? */ + int z_buffer; /* Z=buffer: 0=no, 1=SW, -1=HW */ +}; + +/* + * In C++ terms, this class derives from the GLframebuffer class. + * Add system-specific fields to it. + */ +struct dmesa_buffer { + GLframebuffer gl_buffer; /* The depth, stencil, accum, etc buffers */ + void *the_window; /* your window handle, etc */ + + int xpos, ypos; /* position */ + int width, height; /* size in pixels */ +}; + +/* + * In C++ terms, this class derives from the GLcontext class. + * Add system-specific fields to it. + */ +struct dmesa_context { + GLcontext gl_ctx; /* the core library context */ + DMesaVisual visual; + DMesaBuffer buffer; + GLuint ClearColor; + GLuint ClearIndex; + /* etc... */ +}; + + +#ifndef FX +/**************************************************************************** + * Read/Write pixels + ***************************************************************************/ +#define FLIP(y) (dmesa->buffer->height - (y) - 1) +#define FLIP2(y) (_b_ - (y)) + +#define DSTRIDE dmesa->buffer->width + +/**************************************************************************** + * RGB[A] + ***************************************************************************/ +static void +write_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgba[][4], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++, offset++) { + if (mask[i]) { + vl_putpixel(offset, vl_mixrgba(rgba[i])); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++, offset++) { + vl_putpixel(offset, vl_mixrgba(rgba[i])); + } + } +} + + +static void +write_rgb_span (const GLcontext *ctx, GLuint n, GLint x, GLint y, + const GLubyte rgb[][3], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++, offset++) { + if (mask[i]) { + vl_putpixel(offset, vl_mixrgb(rgb[i])); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++, offset++) { + vl_putpixel(offset, vl_mixrgb(rgb[i])); + } + } +} + + +static void +write_mono_rgba_span (const GLcontext *ctx, + GLuint n, GLint x, GLint y, + const GLchan color[4], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset, rgba = vl_mixrgba(color); + + offset = DSTRIDE * FLIP(y) + x; + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++, offset++) { + if (mask[i]) { + vl_putpixel(offset, rgba); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++, offset++) { + vl_putpixel(offset, rgba); + } + } +} + + +static void +read_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y, + GLubyte rgba[][4]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + /* read all pixels */ + for (i = 0; i < n; i++, offset++) { + vl_getrgba(offset, rgba[i]); + } +} + + +static void +write_rgba_pixels (const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLubyte rgba[][4], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1; + + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++) { + if (mask[i]) { + vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i])); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++) { + vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i])); + } + } +} + + +static void +write_mono_rgba_pixels (const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + const GLchan color[4], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1, rgba = vl_mixrgba(color); + + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++) { + if (mask[i]) { + vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++) { + vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba); + } + } +} + + +static void +read_rgba_pixels (const GLcontext *ctx, + GLuint n, const GLint x[], const GLint y[], + GLubyte rgba[][4], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1; + + if (mask) { + /* read some pixels */ + for (i = 0; i < n; i++) { + if (mask[i]) { + vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]); + } + } + } else { + /* read all pixels */ + for (i = 0; i < n; i++) { + vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]); + } + } +} + + +/**************************************************************************** + * Index + ***************************************************************************/ +static void +write_index_span (const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLuint index[], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++, offset++) { + if (mask[i]) { + vl_putpixel(offset, index[i]); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++, offset++) { + vl_putpixel(offset, index[i]); + } + } +} + + +static void +write_index8_span (const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + const GLubyte index[], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++, offset++) { + if (mask[i]) { + vl_putpixel(offset, index[i]); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++, offset++) { + vl_putpixel(offset, index[i]); + } + } +} + + +static void +write_mono_index_span (const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, + GLuint colorIndex, const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++, offset++) { + if (mask[i]) { + vl_putpixel(offset, colorIndex); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++, offset++) { + vl_putpixel(offset, colorIndex); + } + } +} + + +static void +read_index_span (const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, GLint x, GLint y, GLuint index[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, offset; + + offset = DSTRIDE * FLIP(y) + x; + /* read all pixels */ + for (i = 0; i < n; i++, offset++) { + index[i] = vl_getpixel(offset); + } +} + + +static void +write_index_pixels (const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + const GLuint index[], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1; + + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++) { + if (mask[i]) { + vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++) { + vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]); + } + } +} + + +static void +write_mono_index_pixels (const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + GLuint colorIndex, const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1; + + if (mask) { + /* draw some pixels */ + for (i = 0; i < n; i++) { + if (mask[i]) { + vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex); + } + } + } else { + /* draw all pixels */ + for (i = 0; i < n; i++) { + vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex); + } + } +} + + +static void +read_index_pixels (const GLcontext *ctx, struct gl_renderbuffer *rb, + GLuint n, const GLint x[], const GLint y[], + GLuint index[], const GLubyte mask[]) +{ + const DMesaContext dmesa = (DMesaContext)ctx; + GLuint i, _w_ = DSTRIDE, _b_ = dmesa->buffer->height - 1; + + if (mask) { + /* read some pixels */ + for (i = 0; i < n; i++) { + if (mask[i]) { + index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]); + } + } + } else { + /* read all pixels */ + for (i = 0; i < n; i++) { + index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]); + } + } +} + + +/**************************************************************************** + * Z-buffer + ***************************************************************************/ + + +/**************************************************************************** + * Optimized triangle rendering + ***************************************************************************/ + +/* + * NON-depth-buffered flat triangle. + */ +#define NAME tri_rgb_flat + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx;\ + GLuint _b_ = dmesa->buffer->height - 1; \ + GLuint _w_ = dmesa->buffer->width; \ + GLuint rgb = vl_mixrgb(v2->color); + +#define RENDER_SPAN(span) \ + GLuint i, offset = FLIP2(span.y)*_w_ + span.x;\ + for (i = 0; i < span.end; i++, offset++) { \ + vl_putpixel(offset, rgb); \ + } + +#include "swrast/s_tritemp.h" + + +/* + * Z-less flat triangle. + */ +#define NAME tri_rgb_flat_zless + +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx; \ + GLuint _b_ = dmesa->buffer->height - 1; \ + GLuint _w_ = dmesa->buffer->width; \ + GLuint rgb = vl_mixrgb(v2->color); + +#define RENDER_SPAN(span) \ + GLuint i, offset = FLIP2(span.y)*_w_ + span.x;\ + for (i = 0; i < span.end; i++, offset++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z);\ + if (z < zRow[i]) { \ + vl_putpixel(offset, rgb); \ + zRow[i] = z; \ + } \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + +/* + * NON-depth-buffered iterated triangle. + */ +#define NAME tri_rgb_iter + +#define INTERP_RGB 1 + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx;\ + GLuint _b_ = dmesa->buffer->height - 1; \ + GLuint _w_ = dmesa->buffer->width; + +#define RENDER_SPAN(span) \ + GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \ + for (i = 0; i < span.end; i++, offset++) { \ + vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue)); \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + } + +#include "swrast/s_tritemp.h" + + +/* + * Z-less iterated triangle. + */ +#define NAME tri_rgb_iter_zless + +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define INTERP_RGB 1 + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx;\ + GLuint _b_ = dmesa->buffer->height - 1; \ + GLuint _w_ = dmesa->buffer->width; + +#define RENDER_SPAN(span) \ + GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \ + for (i = 0; i < span.end; i++, offset++) { \ + const DEPTH_TYPE z = FixedToDepth(span.z); \ + if (z < zRow[i]) { \ + vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\ + zRow[i] = z; \ + } \ + span.red += span.redStep; \ + span.green += span.greenStep; \ + span.blue += span.blueStep; \ + span.z += span.zStep; \ + } + +#include "swrast/s_tritemp.h" + + +/* + * Analyze context state to see if we can provide a fast triangle function + * Otherwise, return NULL. + */ +static swrast_tri_func +dmesa_choose_tri_function (GLcontext *ctx) +{ + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if ((ctx->RenderMode != GL_RENDER) + || (ctx->Polygon.SmoothFlag) + || (ctx->Polygon.StippleFlag) + || (ctx->Texture._EnabledUnits) + || (swrast->_RasterMask & MULTI_DRAW_BIT) + || (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)) { + return (swrast_tri_func)NULL; + } + + if (swrast->_RasterMask==DEPTH_BIT + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { + return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter_zless : tri_rgb_flat_zless; + } + + if (swrast->_RasterMask==0) { /* no depth test */ + return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter : tri_rgb_flat; + } + + return (swrast_tri_func)NULL; +} + + +/* Override for the swrast triangle-selection function. Try to use one + * of our internal triangle functions, otherwise fall back to the + * standard swrast functions. + */ +static void +dmesa_choose_tri (GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (!(swrast->Triangle=dmesa_choose_tri_function(ctx))) { + _swrast_choose_triangle(ctx); + } +} + + +/**************************************************************************** + * Optimized line rendering + ***************************************************************************/ + +/* + * NON-depth-buffered flat line. + */ +#define NAME line_rgb_flat + +#define INTERP_XY 1 +#define CLIP_HACK 1 + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx;\ + GLuint _b_ = dmesa->buffer->height - 1; \ + GLuint _w_ = dmesa->buffer->width; \ + GLuint rgb = vl_mixrgb(vert1->color); + +#define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb); + +#include "swrast/s_linetemp.h" + + +/* + * Z-less flat line. + */ +#define NAME line_rgb_flat_zless + +#define INTERP_XY 1 +#define INTERP_Z 1 +#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE +#define CLIP_HACK 1 + +#define SETUP_CODE \ + const DMesaContext dmesa = (DMesaContext)ctx;\ + GLuint _b_ = dmesa->buffer->height - 1; \ + GLuint _w_ = dmesa->buffer->width; \ + GLuint rgb = vl_mixrgb(vert1->color); + +#define PLOT(X,Y) \ + if (Z < *zPtr) { \ + *zPtr = Z; \ + vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \ + } + +#include "swrast/s_linetemp.h" + + +/* + * NON-depth-buffered iterated line. + */ +#define line_rgb_iter NULL + + +/* + * Z-less iterated line. + */ +#define line_rgb_iter_zless NULL + + +/* + * Analyze context state to see if we can provide a fast line function + * Otherwise, return NULL. + */ +static swrast_line_func +dmesa_choose_line_function (GLcontext *ctx) +{ + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if ((ctx->RenderMode != GL_RENDER) + || (ctx->Line.SmoothFlag) + || (ctx->Texture._EnabledUnits) + || (ctx->Line.StippleFlag) + || (swrast->_RasterMask & MULTI_DRAW_BIT) + || (ctx->Line.Width!=1.0F)) { + return (swrast_line_func)NULL; + } + + if (swrast->_RasterMask==DEPTH_BIT + && ctx->Depth.Func==GL_LESS + && ctx->Depth.Mask==GL_TRUE + && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) { + return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter_zless : line_rgb_flat_zless; + } + + if (swrast->_RasterMask==0) { /* no depth test */ + return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter : line_rgb_flat; + } + + return (swrast_line_func)NULL; +} + + +/* Override for the swrast line-selection function. Try to use one + * of our internal line functions, otherwise fall back to the + * standard swrast functions. + */ +static void +dmesa_choose_line (GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + if (!(swrast->Line=dmesa_choose_line_function(ctx))) { + _swrast_choose_line(ctx); + } +} + + +/**************************************************************************** + * Miscellaneous device driver funcs + ***************************************************************************/ +static const struct gl_texture_format * +choose_tex_format (GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type) +{ + switch (internalFormat) { + case GL_COMPRESSED_RGB_ARB: + return &_mesa_texformat_rgb; + case GL_COMPRESSED_RGBA_ARB: + return &_mesa_texformat_rgba; + default: + return _mesa_choose_tex_format(ctx, internalFormat, format, type); + } +} + + +static void +clear_index (GLcontext *ctx, GLuint index) +{ + ((DMesaContext)ctx)->ClearIndex = index; +} + + +static void +clear_color (GLcontext *ctx, const GLfloat color[4]) +{ + GLubyte col[4]; + CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]); + ((DMesaContext)ctx)->ClearColor = vl_mixrgba(col); +} + + +static void +clear (GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height) +{ + const DMesaContext c = (DMesaContext)ctx; + const GLuint *colorMask = (GLuint *)&ctx->Color.ColorMask; + + /* + * Clear the specified region of the buffers indicated by 'mask' + * using the clear color or index as specified by one of the two + * functions above. + * If all==GL_TRUE, clear whole buffer, else just clear region defined + * by x,y,width,height + */ + + /* we can't handle color or index masking */ + if ((*colorMask == 0xffffffff) && (ctx->Color.IndexMask == 0xffffffff)) { + if (mask & DD_BACK_LEFT_BIT) { + int color = ((GLvisual *)(c->visual))->rgbMode ? c->ClearColor : c->ClearIndex; + + if (all) { + vl_clear(color); + } else { + vl_rect(x, c->buffer->height - y - height, width, height, color); + } + + mask &= ~DD_BACK_LEFT_BIT; + } + } + + if (mask) { + _swrast_Clear(ctx, mask, all, x, y, width, height); + } +} + + +/* + * This function is called to specify which buffer to read and write + * for software rasterization (swrast) fallbacks. This doesn't necessarily + * correspond to glDrawBuffer() or glReadBuffer() calls. + */ +static void +set_buffer (GLcontext *ctx, GLframebuffer *colorBuffer, GLuint bufferBit) +{ + /* + * XXX todo - examine bufferBit and set read/write pointers + */ + /* Normally, we would have + * ctx->Driver.ReadBuffer == set_read_buffer + * ctx->Driver.DrawBuffer == set_draw_buffer + * and make sure set_draw_buffer calls _swrast_DrawBuffer, + * which in turn will call this routine via dd->SetBuffer. + */ +} + + +/* + * Return the width and height of the current buffer. + * If anything special has to been done when the buffer/window is + * resized, do it now. + */ +static void +get_buffer_size (GLframebuffer *buffer, GLuint *width, GLuint *height) +{ + DMesaBuffer b = (DMesaBuffer)buffer; + + *width = b->width; + *height = b->height; +} + + +static void +viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h) +{ + /* poll for window size change and realloc software Z/stencil/etc if needed */ + _mesa_ResizeBuffersMESA(); +} + + +static const GLubyte * +get_string (GLcontext *ctx, GLenum name) +{ + switch (name) { + case GL_RENDERER: + return (const GLubyte *)"Mesa DJGPP"; + default: + return NULL; + } +} + + +static void +finish (GLcontext *ctx) +{ + /* + * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible + */ +} + + +static void +flush (GLcontext *ctx) +{ + /* + * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible + */ +} + + +/**************************************************************************** + * State + ***************************************************************************/ +#define DMESA_NEW_LINE (_NEW_LINE | \ + _NEW_TEXTURE | \ + _NEW_LIGHT | \ + _NEW_DEPTH | \ + _NEW_RENDERMODE | \ + _SWRAST_NEW_RASTERMASK) + +#define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \ + _NEW_TEXTURE | \ + _NEW_LIGHT | \ + _NEW_DEPTH | \ + _NEW_RENDERMODE | \ + _SWRAST_NEW_RASTERMASK) + +/* Extend the software rasterizer with our line and triangle + * functions. + */ +static void +dmesa_register_swrast_functions (GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + + swrast->choose_line = dmesa_choose_line; + swrast->choose_triangle = dmesa_choose_tri; + + swrast->invalidate_line |= DMESA_NEW_LINE; + swrast->invalidate_triangle |= DMESA_NEW_TRIANGLE; +} + + +static void +dmesa_update_state (GLcontext *ctx, GLuint new_state) +{ + /* Propagate statechange information to swrast and swrast_setup + * modules. The DMesa driver has no internal GL-dependent state. + */ + _swrast_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); +} + + +/* Initialize the device driver function table with the functions + * we implement in this driver. + */ +static void +dmesa_init_driver_functions (DMesaVisual visual, + struct dd_function_table *driver) +{ + driver->UpdateState = dmesa_update_state; + driver->GetString = get_string; + driver->GetBufferSize = get_buffer_size; + driver->Viewport = viewport; + driver->Flush = flush; + driver->Finish = finish; + driver->Clear = clear; + driver->ClearColor = clear_color; + driver->ClearIndex = clear_index; +#if SWTC + driver->ChooseTextureFormat = choose_tex_format; +#endif +} + + +/* Setup pointers and other driver state that is constant for the life + * of a context. + */ +static void +dmesa_init_pointers (GLcontext *ctx) +{ + struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference(ctx); + + dd->SetBuffer = set_buffer; + + /* The span functions should be in `dmesa_update_state', but I'm + * pretty sure they will never change during the life of the Visual + */ + + /* Index span/pixel functions */ + dd->WriteCI32Span = write_index_span; + dd->WriteCI8Span = write_index8_span; + dd->WriteMonoCISpan = write_mono_index_span; + dd->WriteCI32Pixels = write_index_pixels; + dd->WriteMonoCIPixels = write_mono_index_pixels; + dd->ReadCI32Span = read_index_span; + dd->ReadCI32Pixels = read_index_pixels; + + /* RGB(A) span/pixel functions */ + dd->WriteRGBASpan = write_rgba_span; + dd->WriteRGBSpan = write_rgb_span; + dd->WriteMonoRGBASpan = write_mono_rgba_span; + dd->WriteRGBAPixels = write_rgba_pixels; + dd->WriteMonoRGBAPixels = write_mono_rgba_pixels; + dd->ReadRGBASpan = read_rgba_span; + dd->ReadRGBAPixels = read_rgba_pixels; +} +#endif /* FX */ + + +/**************************************************************************** + * DMesa Public API Functions + ***************************************************************************/ + +/* + * The exact arguments to this function will depend on your window system + */ +DMesaVisual +DMesaCreateVisual (GLint width, + GLint height, + GLint colDepth, + GLint refresh, + GLboolean dbFlag, + GLboolean rgbFlag, + GLint alphaSize, + GLint depthSize, + GLint stencilSize, + GLint accumSize) +{ + DMesaVisual v; + GLint redBits, greenBits, blueBits, alphaBits, indexBits; + GLboolean sw_alpha; + + alphaBits = 0; + + if (!rgbFlag) { + indexBits = 8; + redBits = 0; + greenBits = 0; + blueBits = 0; + } else { + indexBits = 0; + switch (colDepth) { + case 8: + redBits = 8; + greenBits = 8; + blueBits = 8; + break; + case 15: + alphaBits = 1; + redBits = 5; + greenBits = 5; + blueBits = 5; + break; + case 16: + redBits = 5; + greenBits = 6; + blueBits = 5; + break; + case 32: + alphaBits = 8; + case 24: + redBits = 8; + greenBits = 8; + blueBits = 8; + break; + default: + return NULL; + } + } + + /* Okay, + * `alphaBits' is what we can provide + * `alphaSize' is what app requests + * + * Note that alpha buffering is required only if destination alpha is used + * in alpha blending; alpha blending modes that do not use destination alpha + * can be used w/o alpha buffer. + * + * We will use whatever ALPHA app requests. Later, in `CreateBuffer' we'll + * instruct Mesa to use its own ALPHA buffer, by passing a non-FALSE value + * for ALPHA to `_mesa_initialize_framebuffer'. + * + * Basically, 32bit modes provide ALPHA storage, but can we rely on this? + */ + alphaBits = alphaSize; + sw_alpha = (alphaBits > 0); + +#ifndef FX + if (!dbFlag) { + return NULL; + } + if ((colDepth=vl_video_init(width, height, colDepth, rgbFlag, refresh)) <= 0) { + return NULL; + } +#else /* FX */ + if (!rgbFlag) { + return NULL; + } else { + char *env; + + if ((env = getenv("MESA_FX_INFO")) && (env[0] == 'r')) { + freopen("MESA.LOG", "w", stderr); + } + + if (refresh && (((env = getenv("FX_GLIDE_REFRESH")) == NULL) || !atoi(env))) { + /* if we are passed non-zero value for refresh, we need to override + * default refresh rate. However, if FX_GLIDE_REFRESH is already set + * to 0, we won't override it, because it has a special meaning for + * DJGPP Glide3x (switch via VESA, using BIOS default refresh). + */ + char tmp[32]; + sprintf(tmp, "FX_GLIDE_REFRESH=%u", refresh); + putenv(tmp); + } + } +#endif /* FX */ + + if ((v=(DMesaVisual)CALLOC_STRUCT(dmesa_visual)) != NULL) { + /* Create core visual */ + _mesa_initialize_visual((GLvisual *)v, + rgbFlag, /* rgb */ + dbFlag, + GL_FALSE, /* stereo */ + redBits, + greenBits, + blueBits, + alphaBits, + indexBits, /* indexBits */ + depthSize, + stencilSize, + accumSize, /* accumRed */ + accumSize, /* accumGreen */ + accumSize, /* accumBlue */ + alphaBits?accumSize:0, /* accumAlpha */ + 1); /* numSamples */ + +#ifndef FX + v->sw_alpha = sw_alpha; + v->z_buffer = (depthSize > 0) ? 1 : 0; +#endif + } + + return v; +} + + +void +DMesaDestroyVisual (DMesaVisual v) +{ +#ifndef FX + vl_video_exit(); +#endif + _mesa_destroy_visual((GLvisual *)v); +} + + +DMesaBuffer +DMesaCreateBuffer (DMesaVisual visual, + GLint xpos, GLint ypos, + GLint width, GLint height) +{ +#ifndef FX + DMesaBuffer b; + + if ((b=(DMesaBuffer)CALLOC_STRUCT(dmesa_buffer)) != NULL) { + _mesa_initialize_framebuffer((GLframebuffer *)b, + (GLvisual *)visual, + visual->z_buffer == 1, + ((GLvisual *)visual)->stencilBits > 0, + ((GLvisual *)visual)->accumRedBits > 0, + visual->sw_alpha); + b->xpos = xpos; + b->ypos = ypos; + b->width = width; + b->height = height; + } + + return b; +#else /* FX */ + + GLvisual *v = (GLvisual *)visual; + int i = 0, fx_attrib[32]; + + if (v->doubleBufferMode) fx_attrib[i++] = FXMESA_DOUBLEBUFFER; + if (v->depthBits > 0) { fx_attrib[i++] = FXMESA_DEPTH_SIZE; fx_attrib[i++] = v->depthBits; } + if (v->stencilBits > 0) { fx_attrib[i++] = FXMESA_STENCIL_SIZE; fx_attrib[i++] = v->stencilBits; } + if (v->accumRedBits > 0) { fx_attrib[i++] = FXMESA_ACCUM_SIZE; fx_attrib[i++] = v->accumRedBits; } + if (v->alphaBits) { fx_attrib[i++] = FXMESA_ALPHA_SIZE; fx_attrib[i++] = v->alphaBits; } + fx_attrib[i++] = FXMESA_COLORDEPTH; + fx_attrib[i++] = v->redBits + v->greenBits + v->blueBits; + fx_attrib[i] = FXMESA_NONE; + + return (DMesaBuffer)fxMesaCreateBestContext(-1, width, height, fx_attrib); +#endif /* FX */ +} + + +void +DMesaDestroyBuffer (DMesaBuffer b) +{ +#ifndef FX + if (b->the_window != NULL) { + free(b->the_window); + } + _mesa_destroy_framebuffer((GLframebuffer *)b); +#else + fxMesaDestroyContext((fxMesaContext)b); +#endif +} + + +DMesaContext +DMesaCreateContext (DMesaVisual visual, DMesaContext share) +{ + GLcontext *c; +#ifndef FX + TNLcontext *tnl; + struct dd_function_table functions; + + if ((c=(GLcontext *)CALLOC_STRUCT(dmesa_context)) != NULL) { + /* Initialize device driver function table */ + _mesa_init_driver_functions(&functions); + /* override with our functions */ + dmesa_init_driver_functions(visual, &functions); + + _mesa_initialize_context(c, + (GLvisual *)visual, + (GLcontext *)share, + &functions, + (void *)c); + + _mesa_enable_sw_extensions(c); + _mesa_enable_1_3_extensions(c); + _mesa_enable_1_4_extensions(c); + _mesa_enable_1_5_extensions(c); + _mesa_enable_2_0_extensions(c); +#if SWTC + if (c->Mesa_DXTn) { + _mesa_enable_extension(c, "GL_EXT_texture_compression_s3tc"); + _mesa_enable_extension(c, "GL_S3_s3tc"); + } + _mesa_enable_extension(c, "GL_3DFX_texture_compression_FXT1"); +#endif + + /* you probably have to do a bunch of other initializations here. */ + ((DMesaContext)c)->visual = visual; + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext(c); + _ac_CreateContext(c); + _tnl_CreateContext(c); + _swsetup_CreateContext(c); + /* tnl setup */ + tnl = TNL_CONTEXT(c); + tnl->Driver.RunPipeline = _tnl_run_pipeline; + /* swrast setup */ + if (((GLvisual *)visual)->rgbMode) dmesa_register_swrast_functions(c); + dmesa_init_pointers(c); + _swsetup_Wakeup(c); + } + +#else /* FX */ + c = (GLcontext *)0xdeadbeef; +#endif /* FX */ + + return (DMesaContext)c; +} + + +void +DMesaDestroyContext (DMesaContext c) +{ +#ifndef FX + if (c) { + _swsetup_DestroyContext((GLcontext *)c); + _swrast_DestroyContext((GLcontext *)c); + _tnl_DestroyContext((GLcontext *)c); + _ac_DestroyContext((GLcontext *)c); + _mesa_destroy_context((GLcontext *)c); + } +#endif +} + + +GLboolean +DMesaMoveBuffer (GLint xpos, GLint ypos) +{ +#ifndef FX + GET_CURRENT_CONTEXT(ctx); + DMesaBuffer b = ((DMesaContext)ctx)->buffer; + + if (vl_sync_buffer(&b->the_window, xpos, ypos, b->width, b->height) == 0) { + b->xpos = xpos; + b->ypos = ypos; + return GL_TRUE; + } +#endif + + return GL_FALSE; +} + + +GLboolean +DMesaResizeBuffer (GLint width, GLint height) +{ +#ifndef FX + GET_CURRENT_CONTEXT(ctx); + DMesaBuffer b = ((DMesaContext)ctx)->buffer; + + if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, width, height) == 0) { + b->width = width; + b->height = height; + return GL_TRUE; + } +#endif + + return GL_FALSE; +} + + +/* + * Make the specified context and buffer the current one. + */ +GLboolean +DMesaMakeCurrent (DMesaContext c, DMesaBuffer b) +{ +#ifndef FX + if ((c != NULL) && (b != NULL)) { + if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, b->width, b->height) != 0) { + return GL_FALSE; + } + + c->buffer = b; + + _mesa_make_current((GLcontext *)c, (GLframebuffer *)b); + } + else { + /* Detach */ + _mesa_make_current(NULL, NULL); + } + +#else + fxMesaMakeCurrent((fxMesaContext)b); +#endif + + return GL_TRUE; +} + + +void +DMesaSwapBuffers (DMesaBuffer b) +{ + /* copy/swap back buffer to front if applicable */ +#ifndef FX + GET_CURRENT_CONTEXT(ctx); + _mesa_notifySwapBuffers(ctx); + vl_flip(); +#else + fxMesaSwapBuffers(); +#endif +} + + +void +DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue) +{ +#ifndef FX + vl_setCI(ndx, red, green, blue); +#endif +} + + +DMesaContext +DMesaGetCurrentContext (void) +{ + GET_CURRENT_CONTEXT(ctx); + +#ifndef FX +#else + if (ctx != NULL) { + ctx = (GLcontext *)0xdeadbeef; + } +#endif + + return (DMesaContext)ctx; +} + + +DMesaBuffer +DMesaGetCurrentBuffer (void) +{ + const DMesaContext dmesa = DMesaGetCurrentContext(); + + if (dmesa == NULL) { + return NULL; + } + +#ifndef FX + return dmesa->buffer; +#else + return (DMesaBuffer)fxMesaGetCurrentContext(); +#endif +} + + +DMesaProc +DMesaGetProcAddress (const char *name) +{ + DMesaProc p = (DMesaProc)_glapi_get_proc_address(name); + + /* TODO: handle DMesa* namespace + if (p == NULL) { + } + */ + + return p; +} + + +int +DMesaGetIntegerv (GLenum pname, GLint *params) +{ + switch (pname) { + case DMESA_GET_SCREEN_SIZE: + #ifndef FX + vl_get(VL_GET_SCREEN_SIZE, params); + #else + fxGetScreenGeometry(¶ms[0], ¶ms[1]); + #endif + break; + case DMESA_GET_DRIVER_CAPS: + #ifndef FX + params[0] = DMESA_DRIVER_SWDB_BIT; + #else + params[0] = DMESA_DRIVER_LLWO_BIT; + #endif + break; + case DMESA_GET_VIDEO_MODES: + #ifndef FX + return vl_get(VL_GET_VIDEO_MODES, params); + #else + return -1; /* TODO */ + #endif + case DMESA_GET_BUFFER_ADDR: { + #ifndef FX + DMesaContext c = (DMesaContext)DMesaGetCurrentContext(); + if (c != NULL) { + DMesaBuffer b = c->buffer; + if (b != NULL) { + params[0] = (GLint)b->the_window; + } + } + break; + #else + return -1; + #endif + } + default: + return -1; + } + + return 0; +} + + +#if SWTC && (((__DJGPP__ << 8) | __DJGPP_MINOR__) >= 0x204) +#include <sys/dxe.h> + +extern_asm(___dj_assert); +extern_asm(_free); +extern_asm(_malloc); +extern_asm(_memset); + +DXE_EXPORT_TABLE_AUTO (___dxe_eta___dxtn) + DXE_EXPORT_ASM (___dj_assert) + DXE_EXPORT_ASM (_free) + DXE_EXPORT_ASM (_malloc) + DXE_EXPORT_ASM (_memset) +DXE_EXPORT_END +#endif |