-/*\r
- * Mesa 3-D graphics library\r
- * Version: 5.0\r
- * \r
- * Copyright (C) 1999 Brian Paul All Rights Reserved.\r
- * \r
- * Permission is hereby granted, free of charge, to any person obtaining a\r
- * copy of this software and associated documentation files (the "Software"),\r
- * to deal in the Software without restriction, including without limitation\r
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,\r
- * and/or sell copies of the Software, and to permit persons to whom the\r
- * Software is furnished to do so, subject to the following conditions:\r
- * \r
- * The above copyright notice and this permission notice shall be included\r
- * in all copies or substantial portions of the Software.\r
- * \r
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS\r
- * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL\r
- * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN\r
- * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN\r
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
- */\r
-\r
-/*\r
- * DOS/DJGPP device driver v1.3 for Mesa 5.0\r
- *\r
- * Copyright (C) 2002 - Borca Daniel\r
- * Email : dborca@yahoo.com\r
- * Web : http://www.geocities.com/dborca\r
- */\r
-\r
-\r
-#ifndef FX\r
-\r
-#include "glheader.h"\r
-#include "context.h"\r
-#include "GL/dmesa.h"\r
-#include "extensions.h"\r
-#include "macros.h"\r
-#include "matrix.h"\r
-#include "mmath.h"\r
-#include "texformat.h"\r
-#include "texstore.h"\r
-#include "array_cache/acache.h"\r
-#include "swrast/s_context.h"\r
-#include "swrast/s_depth.h"\r
-#include "swrast/s_lines.h"\r
-#include "swrast/s_triangle.h"\r
-#include "swrast/s_trispan.h"\r
-#include "swrast/swrast.h"\r
-#include "swrast_setup/swrast_setup.h"\r
-#include "tnl/tnl.h"\r
-#include "tnl/t_context.h"\r
-#include "tnl/t_pipeline.h"\r
-\r
-#ifndef MATROX\r
-\r
-#include "video.h"\r
-\r
-#else /* MATROX */\r
-\r
-#include "mga/mga.h"\r
-\r
-#endif /* MATROX */\r
-\r
-#else /* FX */\r
-\r
-#include "../FX/fxdrv.h"\r
-#include "GL/dmesa.h"\r
-\r
-#endif /* FX */\r
-\r
-\r
-\r
-/*\r
- * In C++ terms, this class derives from the GLvisual class.\r
- * Add system-specific fields to it.\r
- */\r
-struct dmesa_visual {\r
- GLvisual *gl_visual;\r
- GLboolean db_flag; /* double buffered? */\r
- GLboolean rgb_flag; /* RGB mode? */\r
- GLuint depth; /* bits per pixel (1, 8, 24, etc) */\r
-#ifdef MATROX\r
- int stride_in_pixels;\r
-#endif\r
- int zbuffer; /* Z=buffer: 0=no, 1=SW, -1=HW */\r
-};\r
-\r
-/*\r
- * In C++ terms, this class derives from the GLframebuffer class.\r
- * Add system-specific fields to it.\r
- */\r
-struct dmesa_buffer {\r
- GLframebuffer gl_buffer; /* The depth, stencil, accum, etc buffers */\r
- void *the_window; /* your window handle, etc */\r
-\r
- int xpos, ypos; /* position */\r
- int width, height; /* size in pixels */\r
-};\r
-\r
-/*\r
- * In C++ terms, this class derives from the GLcontext class.\r
- * Add system-specific fields to it.\r
- */\r
-struct dmesa_context {\r
- GLcontext *gl_ctx; /* the core library context */\r
- DMesaVisual visual;\r
- DMesaBuffer Buffer;\r
- GLuint ClearColor;\r
- GLuint ClearIndex;\r
- /* etc... */\r
-};\r
-\r
-\r
-\r
-#ifndef FX\r
-/****************************************************************************\r
- * Read/Write pixels\r
- ***************************************************************************/\r
-#define FLIP(y) (dmesa->Buffer->height - (y) - 1)\r
-#define FLIP2(y) (_b_ - (y))\r
-\r
-\r
-#ifndef MATROX\r
-#define DSTRIDE dmesa->Buffer->width\r
-#else\r
-#define DSTRIDE dmesa->visual->stride_in_pixels\r
-#define vl_putpixel mga_putpixel\r
-#define vl_mixrgba mga_mixrgb\r
-#define vl_mixrgb mga_mixrgb\r
-#define vl_getrgba mga_getrgba\r
-#define vl_setz mga_setz\r
-#define vl_getz mga_getz\r
-#endif\r
-\r
-/****************************************************************************\r
- * RGB[A]\r
- ***************************************************************************/\r
-static void write_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
- const GLubyte rgba[][4], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
-#ifndef MATROX\r
- offset = DSTRIDE * FLIP(y) + x;\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- if (mask[i]) {\r
- vl_putpixel(offset, vl_mixrgba(rgba[i]));\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- vl_putpixel(offset, vl_mixrgba(rgba[i]));\r
- }\r
- }\r
-#else /* MATROX */\r
- y = FLIP(y);\r
- if (mask) {\r
- /* draw some pixels */\r
- offset = 0;\r
- for (i = 0; i < n; i++) {\r
- if (mask[i]) {\r
- ++offset;\r
- } else {\r
- if (offset != 0) {\r
- mga_draw_span_rgb_tx32(x + i - offset, y, offset, (const unsigned long *)(&rgba[i-offset]));\r
- offset = 0;\r
- }\r
- }\r
- }\r
- if (offset != 0) {\r
- mga_draw_span_rgb_tx32(x + n - offset, y, offset, (const unsigned long *)(&rgba[n-offset]));\r
- }\r
- } else {\r
- /* draw all pixels */\r
- mga_draw_span_rgb_tx32(x, y, n, (const unsigned long *)rgba);\r
- }\r
-#endif /* MATROX */\r
-}\r
-\r
-\r
-\r
-static void write_rgb_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
- const GLubyte rgb[][3], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- if (mask[i]) {\r
- vl_putpixel(offset, vl_mixrgb(rgb[i]));\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- vl_putpixel(offset, vl_mixrgb(rgb[i]));\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void write_mono_rgba_span (const GLcontext *ctx,\r
- GLuint n, GLint x, GLint y,\r
- const GLchan color[4], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset, rgba = vl_mixrgba(color);\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- if (mask[i]) {\r
- vl_putpixel(offset, rgba);\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- vl_putpixel(offset, rgba);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void read_rgba_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
- GLubyte rgba[][4])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- /* read all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- vl_getrgba(offset, rgba[i]);\r
- }\r
-}\r
-\r
-\r
-\r
-static void write_rgba_pixels (const GLcontext *ctx,\r
- GLuint n, const GLint x[], const GLint y[],\r
- const GLubyte rgba[][4], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;\r
-\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++) {\r
- if (mask[i]) {\r
- vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i]));\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++) {\r
- vl_putpixel(FLIP2(y[i])*_w_ + x[i], vl_mixrgba(rgba[i]));\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void write_mono_rgba_pixels (const GLcontext *ctx,\r
- GLuint n, const GLint x[], const GLint y[],\r
- const GLchan color[4], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1, rgba = vl_mixrgba(color);\r
-\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++) {\r
- if (mask[i]) {\r
- vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba);\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++) {\r
- vl_putpixel(FLIP2(y[i])*_w_ + x[i], rgba);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void read_rgba_pixels (const GLcontext *ctx,\r
- GLuint n, const GLint x[], const GLint y[],\r
- GLubyte rgba[][4], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;\r
-\r
- if (mask) {\r
- /* read some pixels */\r
- for (i=0; i<n; i++) {\r
- if (mask[i]) {\r
- vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]);\r
- }\r
- }\r
- } else {\r
- /* read all pixels */\r
- for (i=0; i<n; i++) {\r
- vl_getrgba(FLIP2(y[i])*_w_ + x[i], rgba[i]);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-/****************************************************************************\r
- * Index\r
- ***************************************************************************/\r
-#ifndef MATROX\r
-static void write_index_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
- const GLuint index[], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- if (mask[i]) {\r
- vl_putpixel(offset, index[i]);\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- vl_putpixel(offset, index[i]);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void write_index8_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
- const GLubyte index[], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- if (mask[i]) {\r
- vl_putpixel(offset, index[i]);\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- vl_putpixel(offset, index[i]);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void write_mono_index_span (const GLcontext *ctx,\r
- GLuint n, GLint x, GLint y,\r
- GLuint colorIndex, const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- if (mask[i]) {\r
- vl_putpixel(offset, colorIndex);\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- vl_putpixel(offset, colorIndex);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void read_index_span (const GLcontext *ctx, GLuint n, GLint x, GLint y,\r
- GLuint index[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- /* read all pixels */\r
- for (i=0; i<n; i++, offset++) {\r
- index[i] = vl_getpixel(offset);\r
- }\r
-}\r
-\r
-\r
-\r
-static void write_index_pixels (const GLcontext *ctx,\r
- GLuint n, const GLint x[], const GLint y[],\r
- const GLuint index[], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;\r
-\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++) {\r
- if (mask[i]) {\r
- vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]);\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++) {\r
- vl_putpixel(FLIP2(y[i])*_w_ + x[i], index[i]);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void write_mono_index_pixels (const GLcontext *ctx,\r
- GLuint n, const GLint x[], const GLint y[],\r
- GLuint colorIndex, const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;\r
-\r
- if (mask) {\r
- /* draw some pixels */\r
- for (i=0; i<n; i++) {\r
- if (mask[i]) {\r
- vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex);\r
- }\r
- }\r
- } else {\r
- /* draw all pixels */\r
- for (i=0; i<n; i++) {\r
- vl_putpixel(FLIP2(y[i])*_w_ + x[i], colorIndex);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void read_index_pixels (const GLcontext *ctx,\r
- GLuint n, const GLint x[], const GLint y[],\r
- GLuint index[], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;\r
-\r
- if (mask) {\r
- /* read some pixels */\r
- for (i=0; i<n; i++) {\r
- if (mask[i]) {\r
- index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]);\r
- }\r
- }\r
- } else {\r
- /* read all pixels */\r
- for (i=0; i<n; i++) {\r
- index[i] = vl_getpixel(FLIP2(y[i])*_w_ + x[i]);\r
- }\r
- }\r
-}\r
-#endif /* !MATROX */\r
-\r
-\r
-\r
-/****************************************************************************\r
- * Z-buffer\r
- ***************************************************************************/\r
-#ifdef MATROX\r
-static void write_depth_span (GLcontext *ctx, GLuint n, GLint x, GLint y,\r
- const GLdepth depth[], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- if (mask) {\r
- /* draw some values */\r
- for (i=0; i<n; i++, offset++) {\r
- if (mask[i]) {\r
- vl_setz(offset, depth[i]);\r
- }\r
- }\r
- } else {\r
- /* draw all values */\r
- for (i=0; i<n; i++, offset++) {\r
- vl_setz(offset, depth[i]);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void read_depth_span (GLcontext *ctx, GLuint n, GLint x, GLint y,\r
- GLdepth depth[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, offset;\r
-\r
- offset = DSTRIDE * FLIP(y) + x;\r
- /* read all values */\r
- for (i=0; i<n; i++, offset++) {\r
- depth[i] = vl_getz(offset);\r
- }\r
-}\r
-\r
-\r
-\r
-static void write_depth_pixels (GLcontext *ctx, GLuint n,\r
- const GLint x[], const GLint y[],\r
- const GLdepth depth[], const GLubyte mask[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;\r
-\r
- if (mask) {\r
- /* draw some values */\r
- for (i=0; i<n; i++) {\r
- if (mask[i]) {\r
- vl_setz(FLIP2(y[i])*_w_ + x[i], depth[i]);\r
- }\r
- }\r
- } else {\r
- /* draw all values */\r
- for (i=0; i<n; i++) {\r
- vl_setz(FLIP2(y[i])*_w_ + x[i], depth[i]);\r
- }\r
- }\r
-}\r
-\r
-\r
-\r
-static void read_depth_pixels (GLcontext *ctx, GLuint n,\r
- const GLint x[], const GLint y[],\r
- GLdepth depth[])\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint i, _w_ = DSTRIDE, _b_ = dmesa->Buffer->height - 1;\r
-\r
- /* read all values */\r
- for (i=0; i<n; i++) {\r
- depth[i] = vl_getz(FLIP2(y[i])*_w_ + x[i]);\r
- }\r
-}\r
-#endif /* MATROX */\r
-\r
-\r
-\r
-/****************************************************************************\r
- * Optimized triangle rendering\r
- ***************************************************************************/\r
-\r
-/*\r
- * NON-depth-buffered flat triangle.\r
- */\r
-static void tri_rgb_flat (GLcontext *ctx,\r
- const SWvertex *v0,\r
- const SWvertex *v1,\r
- const SWvertex *v2)\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint _b_ = dmesa->Buffer->height - 1;\r
-#ifndef MATROX\r
- GLuint _w_ = dmesa->Buffer->width;\r
-\r
-#define SETUP_CODE GLuint rgb = vl_mixrgb(v2->color);\r
-\r
-#define RENDER_SPAN(span) \\r
- GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \\r
- for (i = 0; i < span.end; i++, offset++) { \\r
- vl_putpixel(offset, rgb); \\r
- }\r
-\r
-#include "swrast/s_tritemp.h"\r
-#else /* MATROX */\r
- MGAvertex m0, m1, m2;\r
- m0.win[0] = v0->win[0];\r
- m0.win[1] = FLIP2(v0->win[1]);\r
- m1.win[0] = v1->win[0];\r
- m1.win[1] = FLIP2(v1->win[1]);\r
- m2.win[0] = v2->win[0];\r
- m2.win[1] = FLIP2(v2->win[1]);\r
- *(unsigned long *)m2.color = *(unsigned long *)v2->color;\r
- mga_draw_tri_rgb_flat((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);\r
-#endif /* MATROX */\r
-}\r
-\r
-\r
-\r
-/*\r
- * Z-less flat triangle.\r
- */\r
-static void tri_rgb_flat_zless (GLcontext *ctx,\r
- const SWvertex *v0,\r
- const SWvertex *v1,\r
- const SWvertex *v2)\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint _b_ = dmesa->Buffer->height - 1;\r
-#ifndef MATROX\r
- GLuint _w_ = dmesa->Buffer->width;\r
-\r
-#define INTERP_Z 1\r
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE\r
-#define SETUP_CODE GLuint rgb = vl_mixrgb(v2->color);\r
-\r
-#define RENDER_SPAN(span) \\r
- GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \\r
- for (i = 0; i < span.end; i++, offset++) { \\r
- const DEPTH_TYPE z = FixedToDepth(span.z); \\r
- if (z < zRow[i]) { \\r
- vl_putpixel(offset, rgb); \\r
- zRow[i] = z; \\r
- } \\r
- span.z += span.zStep; \\r
- }\r
-\r
-#include "swrast/s_tritemp.h"\r
-#else /* MATROX */\r
- MGAvertex m0, m1, m2;\r
- m0.win[0] = v0->win[0];\r
- m0.win[1] = FLIP2(v0->win[1]);\r
- m0.win[2] = v0->win[2];\r
- m1.win[0] = v1->win[0];\r
- m1.win[1] = FLIP2(v1->win[1]);\r
- m1.win[2] = v1->win[2];\r
- m2.win[0] = v2->win[0];\r
- m2.win[1] = FLIP2(v2->win[1]);\r
- m2.win[2] = v2->win[2];\r
- *(unsigned long *)m2.color = *(unsigned long *)v2->color;\r
- mga_draw_tri_rgb_flat_zless((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);\r
-#endif /* MATROX */\r
-}\r
-\r
-\r
-\r
-/*\r
- * NON-depth-buffered iterated triangle.\r
- */\r
-static void tri_rgb_iter (GLcontext *ctx,\r
- const SWvertex *v0,\r
- const SWvertex *v1,\r
- const SWvertex *v2)\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint _b_ = dmesa->Buffer->height - 1;\r
-#ifndef MATROX\r
- GLuint _w_ = dmesa->Buffer->width;\r
-\r
-#define INTERP_RGB 1\r
-#define RENDER_SPAN(span) \\r
- GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \\r
- for (i = 0; i < span.end; i++, offset++) { \\r
- vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue)); \\r
- span.red += span.redStep; \\r
- span.green += span.greenStep; \\r
- span.blue += span.blueStep; \\r
- }\r
-\r
-#include "swrast/s_tritemp.h"\r
-#else /* MATROX */\r
- MGAvertex m0, m1, m2;\r
- m0.win[0] = v0->win[0];\r
- m0.win[1] = FLIP2(v0->win[1]);\r
- m1.win[0] = v1->win[0];\r
- m1.win[1] = FLIP2(v1->win[1]);\r
- m2.win[0] = v2->win[0];\r
- m2.win[1] = FLIP2(v2->win[1]);\r
- *(unsigned long *)m0.color = *(unsigned long *)v0->color;\r
- *(unsigned long *)m1.color = *(unsigned long *)v1->color;\r
- *(unsigned long *)m2.color = *(unsigned long *)v2->color;\r
- mga_draw_tri_rgb_iter((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);\r
-#endif /* MATROX */\r
-}\r
-\r
-\r
-\r
-/*\r
- * Z-less iterated triangle.\r
- */\r
-static void tri_rgb_iter_zless (GLcontext *ctx,\r
- const SWvertex *v0,\r
- const SWvertex *v1,\r
- const SWvertex *v2)\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint _b_ = dmesa->Buffer->height - 1;\r
-#ifndef MATROX\r
- GLuint _w_ = dmesa->Buffer->width;\r
-\r
-#define INTERP_Z 1\r
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE\r
-#define INTERP_RGB 1\r
-\r
-#define RENDER_SPAN(span) \\r
- GLuint i, offset = FLIP2(span.y)*_w_ + span.x; \\r
- for (i = 0; i < span.end; i++, offset++) { \\r
- const DEPTH_TYPE z = FixedToDepth(span.z); \\r
- if (z < zRow[i]) { \\r
- vl_putpixel(offset, vl_mixfix(span.red, span.green, span.blue));\\r
- zRow[i] = z; \\r
- } \\r
- span.red += span.redStep; \\r
- span.green += span.greenStep; \\r
- span.blue += span.blueStep; \\r
- span.z += span.zStep; \\r
- }\r
-\r
-#include "swrast/s_tritemp.h"\r
-#else /* MATROX */\r
- MGAvertex m0, m1, m2;\r
- m0.win[0] = v0->win[0];\r
- m0.win[1] = FLIP2(v0->win[1]);\r
- m0.win[2] = v0->win[2];\r
- m1.win[0] = v1->win[0];\r
- m1.win[1] = FLIP2(v1->win[1]);\r
- m1.win[2] = v1->win[2];\r
- m2.win[0] = v2->win[0];\r
- m2.win[1] = FLIP2(v2->win[1]);\r
- m2.win[2] = v2->win[2];\r
- *(unsigned long *)m0.color = *(unsigned long *)v0->color;\r
- *(unsigned long *)m1.color = *(unsigned long *)v1->color;\r
- *(unsigned long *)m2.color = *(unsigned long *)v2->color;\r
- mga_draw_tri_rgb_iter_zless((int)SWRAST_CONTEXT(ctx)->_backface_sign, &m0, &m1, &m2);\r
-#endif /* MATROX */\r
-}\r
-\r
-\r
-\r
-/*\r
- * Analyze context state to see if we can provide a fast triangle function\r
- * Otherwise, return NULL.\r
- */\r
-static swrast_tri_func dmesa_choose_tri_function (GLcontext *ctx)\r
-{\r
- const SWcontext *swrast = SWRAST_CONTEXT(ctx);\r
-\r
- if ((ctx->RenderMode != GL_RENDER)\r
- || (ctx->Polygon.SmoothFlag)\r
- || (ctx->Polygon.StippleFlag)\r
- || (ctx->Texture._EnabledUnits)\r
- || (swrast->_RasterMask & MULTI_DRAW_BIT)\r
- || (ctx->Polygon.CullFlag && ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK)) {\r
- return (swrast_tri_func)NULL;\r
- }\r
-\r
- if (swrast->_RasterMask==DEPTH_BIT\r
- && ctx->Depth.Func==GL_LESS\r
- && ctx->Depth.Mask==GL_TRUE\r
- && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {\r
- return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter_zless : tri_rgb_flat_zless;\r
- }\r
-\r
- if (swrast->_RasterMask==0) { /* no depth test */\r
- return (ctx->Light.ShadeModel==GL_SMOOTH) ? tri_rgb_iter : tri_rgb_flat;\r
- }\r
-\r
- return (swrast_tri_func)NULL;\r
-}\r
-\r
-\r
-\r
-/* Override for the swrast triangle-selection function. Try to use one\r
- * of our internal triangle functions, otherwise fall back to the\r
- * standard swrast functions.\r
- */\r
-static void dmesa_choose_tri (GLcontext *ctx)\r
-{\r
- SWcontext *swrast = SWRAST_CONTEXT(ctx);\r
-\r
- if (!(swrast->Triangle=dmesa_choose_tri_function(ctx)))\r
- _swrast_choose_triangle(ctx);\r
-}\r
-\r
-\r
-\r
-/****************************************************************************\r
- * Optimized line rendering\r
- ***************************************************************************/\r
-\r
-#ifdef MATROX\r
-static __inline void matrox_line_clip_hack (GLcontext *ctx, int _b_, MGAvertex *m0, const SWvertex *vert0, MGAvertex *m1, const SWvertex *vert1)\r
-{\r
- int x0 = vert0->win[0];\r
- int y0 = vert0->win[1];\r
- int x1 = vert1->win[0];\r
- int y1 = vert1->win[1];\r
- /* s_linetemp.h { */\r
- GLint w = ctx->DrawBuffer->Width;\r
- GLint h = ctx->DrawBuffer->Height;\r
- if ((x0==w) | (x1==w)) {\r
- if ((x0==w) & (x1==w))\r
- return;\r
- x0 -= x0==w;\r
- x1 -= x1==w;\r
- }\r
- if ((y0==h) | (y1==h)) {\r
- if ((y0==h) & (y1==h))\r
- return;\r
- y0 -= y0==h;\r
- y1 -= y1==h;\r
- }\r
- /* } s_linetemp.h */\r
- m0->win[0] = x0;\r
- m0->win[1] = FLIP2(y0);\r
- m1->win[0] = x1;\r
- m1->win[1] = FLIP2(y1);\r
-}\r
-#endif\r
-\r
-/*\r
- * NON-depth-buffered flat line.\r
- */\r
-static void line_rgb_flat (GLcontext *ctx,\r
- const SWvertex *vert0,\r
- const SWvertex *vert1)\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint _b_ = dmesa->Buffer->height - 1;\r
-#ifndef MATROX\r
- GLuint _w_ = dmesa->Buffer->width;\r
- GLuint rgb = vl_mixrgb(vert1->color);\r
-\r
-#define INTERP_XY 1\r
-#define CLIP_HACK 1\r
-#define PLOT(X,Y) vl_putpixel(FLIP2(Y) * _w_ + X, rgb);\r
-\r
-#include "swrast/s_linetemp.h"\r
-#else\r
- MGAvertex m0, m1;\r
- matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);\r
- *(unsigned long *)m1.color = *(unsigned long *)vert1->color;\r
- mga_draw_line_rgb_flat(&m0, &m1);\r
-#endif\r
-}\r
-\r
-\r
-\r
-/*\r
- * Z-less flat line.\r
- */\r
-static void line_rgb_flat_zless (GLcontext *ctx,\r
- const SWvertex *vert0,\r
- const SWvertex *vert1)\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint _b_ = dmesa->Buffer->height - 1;\r
-#ifndef MATROX\r
- GLuint _w_ = dmesa->Buffer->width;\r
- GLuint rgb = vl_mixrgb(vert1->color);\r
-\r
-#define INTERP_XY 1\r
-#define INTERP_Z 1\r
-#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE\r
-#define CLIP_HACK 1\r
-#define PLOT(X,Y) \\r
- if (Z < *zPtr) { \\r
- *zPtr = Z; \\r
- vl_putpixel(FLIP2(Y) * _w_ + X, rgb); \\r
- }\r
-\r
-#include "swrast/s_linetemp.h"\r
-#else\r
- MGAvertex m0, m1;\r
- matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);\r
- m0.win[2] = vert0->win[2];\r
- m1.win[2] = vert1->win[2];\r
- *(unsigned long *)m1.color = *(unsigned long *)vert1->color;\r
- mga_draw_line_rgb_flat_zless(&m0, &m1);\r
-#endif\r
-}\r
-\r
-\r
-\r
-#ifndef MATROX\r
-#define line_rgb_iter NULL\r
-#define line_rgb_iter_zless NULL\r
-#else /* MATROX */\r
-/*\r
- * NON-depth-buffered iterated line.\r
- */\r
-static void line_rgb_iter (GLcontext *ctx,\r
- const SWvertex *vert0,\r
- const SWvertex *vert1)\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint _b_ = dmesa->Buffer->height - 1;\r
- MGAvertex m0, m1;\r
- matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);\r
- *(unsigned long *)m0.color = *(unsigned long *)vert0->color;\r
- *(unsigned long *)m1.color = *(unsigned long *)vert1->color;\r
- mga_draw_line_rgb_iter(&m0, &m1);\r
-}\r
-\r
-\r
-\r
-/*\r
- * Z-less iterated line.\r
- */\r
-static void line_rgb_iter_zless (GLcontext *ctx,\r
- const SWvertex *vert0,\r
- const SWvertex *vert1)\r
-{\r
- const DMesaContext dmesa = (DMesaContext)ctx->DriverCtx;\r
- GLuint _b_ = dmesa->Buffer->height - 1;\r
- MGAvertex m0, m1;\r
- matrox_line_clip_hack(ctx, _b_, &m0, vert0, &m1, vert1);\r
- m0.win[2] = vert0->win[2];\r
- m1.win[2] = vert1->win[2];\r
- *(unsigned long *)m0.color = *(unsigned long *)vert0->color;\r
- *(unsigned long *)m1.color = *(unsigned long *)vert1->color;\r
- mga_draw_line_rgb_iter_zless(&m0, &m1);\r
-}\r
-#endif /* MATROX */\r
-\r
-\r
-\r
-/*\r
- * Analyze context state to see if we can provide a fast line function\r
- * Otherwise, return NULL.\r
- */\r
-static swrast_line_func dmesa_choose_line_function (GLcontext *ctx)\r
-{\r
- const SWcontext *swrast = SWRAST_CONTEXT(ctx);\r
-\r
- if ((ctx->RenderMode != GL_RENDER)\r
- || (ctx->Line.SmoothFlag)\r
- || (ctx->Texture._EnabledUnits)\r
- || (ctx->Line.StippleFlag)\r
- || (swrast->_RasterMask & MULTI_DRAW_BIT)\r
- || (ctx->Line.Width!=1.0F)) {\r
- return (swrast_line_func)NULL;\r
- }\r
-\r
- if (swrast->_RasterMask==DEPTH_BIT\r
- && ctx->Depth.Func==GL_LESS\r
- && ctx->Depth.Mask==GL_TRUE\r
- && ctx->Visual.depthBits == DEFAULT_SOFTWARE_DEPTH_BITS) {\r
- return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter_zless : line_rgb_flat_zless;\r
- }\r
-\r
- if (swrast->_RasterMask==0) { /* no depth test */\r
- return (ctx->Light.ShadeModel==GL_SMOOTH) ? line_rgb_iter : line_rgb_flat;\r
- }\r
-\r
- return (swrast_line_func)NULL;\r
-}\r
-\r
-\r
-\r
-/* Override for the swrast line-selection function. Try to use one\r
- * of our internal line functions, otherwise fall back to the\r
- * standard swrast functions.\r
- */\r
-static void dmesa_choose_line (GLcontext *ctx)\r
-{\r
- SWcontext *swrast = SWRAST_CONTEXT(ctx);\r
-\r
- if (!(swrast->Line=dmesa_choose_line_function(ctx)))\r
- _swrast_choose_line(ctx);\r
-}\r
-\r
-\r
-\r
-/****************************************************************************\r
- * Miscellaneous device driver funcs\r
- ***************************************************************************/\r
-\r
-static void clear_index (GLcontext *ctx, GLuint index)\r
-{\r
- ((DMesaContext)ctx->DriverCtx)->ClearIndex = index;\r
-}\r
-\r
-static void clear_color (GLcontext *ctx, const GLfloat color[4])\r
-{\r
- GLubyte col[4];\r
- CLAMPED_FLOAT_TO_UBYTE(col[0], color[0]);\r
- CLAMPED_FLOAT_TO_UBYTE(col[1], color[1]);\r
- CLAMPED_FLOAT_TO_UBYTE(col[2], color[2]);\r
- CLAMPED_FLOAT_TO_UBYTE(col[3], color[3]);\r
- ((DMesaContext)ctx->DriverCtx)->ClearColor = vl_mixrgba(col);\r
-}\r
-\r
-\r
-\r
-static void clear (GLcontext *ctx, GLbitfield mask, GLboolean all,\r
- GLint x, GLint y, GLint width, GLint height)\r
-{\r
- const DMesaContext c = (DMesaContext)ctx->DriverCtx;\r
- const GLuint *colorMask = (GLuint *)&ctx->Color.ColorMask;\r
-\r
-/*\r
- * Clear the specified region of the buffers indicated by 'mask'\r
- * using the clear color or index as specified by one of the two\r
- * functions above.\r
- * If all==GL_TRUE, clear whole buffer, else just clear region defined\r
- * by x,y,width,height\r
- */\r
-\r
- /* we can't handle color or index masking */\r
- if ((*colorMask == 0xffffffff) && (ctx->Color.IndexMask == 0xffffffff)) {\r
-#ifndef MATROX\r
- if (mask & DD_BACK_LEFT_BIT) {\r
- int color = c->visual->rgb_flag ? c->ClearColor : c->ClearIndex;\r
-\r
- if (all) {\r
- vl_clear(color);\r
- } else {\r
- vl_rect(x, y, width, height, color);\r
- }\r
-\r
- mask &= ~DD_BACK_LEFT_BIT;\r
- }\r
-#else /* MATROX */\r
- unsigned short z = -1;\r
- int color = c->ClearColor;\r
- if (mask & DD_DEPTH_BIT) {\r
- z = ctx->Depth.Clear * 0xffff;\r
- }\r
- if (all) {\r
- mga_clear(mask & DD_FRONT_LEFT_BIT,\r
- mask & DD_BACK_LEFT_BIT,\r
- mask & DD_DEPTH_BIT,\r
- 0, 0, c->Buffer->width, c->Buffer->height,\r
- color, z);\r
- } else {\r
- mga_clear(mask & DD_FRONT_LEFT_BIT,\r
- mask & DD_BACK_LEFT_BIT,\r
- mask & DD_DEPTH_BIT,\r
- x, y, width, height,\r
- color, z);\r
- }\r
- mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT);\r
-#endif /* MATROX */\r
- }\r
-\r
- if (mask) {\r
- _swrast_Clear(ctx, mask, all, x, y, width, height);\r
- }\r
-}\r
-\r
-\r
-\r
-static void set_buffer (GLcontext *ctx, GLframebuffer *colorBuffer, GLuint bufferBit)\r
-{\r
- /*\r
- * XXX todo - examine bufferBit and set read/write pointers\r
- */\r
-}\r
-\r
-\r
-\r
-/*\r
- * Return the width and height of the current buffer.\r
- * If anything special has to been done when the buffer/window is\r
- * resized, do it now.\r
- */\r
-static void get_buffer_size (GLframebuffer *buffer, GLuint *width, GLuint *height)\r
-{\r
- DMesaBuffer b = (DMesaBuffer)buffer;\r
-\r
- *width = b->width;\r
- *height = b->height;\r
-}\r
-\r
-\r
-\r
-static const GLubyte* get_string (GLcontext *ctx, GLenum name)\r
-{\r
- switch (name) {\r
- case GL_RENDERER:\r
- return (const GLubyte *)"Mesa DJGPP"\r
- #ifdef FX\r
- " (FX)"\r
- #endif\r
- #ifdef MATROX\r
- " (MGA)"\r
- #endif\r
- "\0port (c) Borca Daniel feb-2003";\r
- default:\r
- return NULL;\r
- }\r
-}\r
-\r
-\r
-\r
-static void finish (GLcontext *ctx)\r
-{\r
- /*\r
- * XXX todo - OPTIONAL FUNCTION: implements glFinish if possible\r
- */\r
-}\r
-\r
-\r
-\r
-static void flush (GLcontext *ctx)\r
-{\r
- /*\r
- * XXX todo - OPTIONAL FUNCTION: implements glFlush if possible\r
- */\r
-}\r
-\r
-\r
-\r
-/****************************************************************************\r
- * State\r
- ***************************************************************************/\r
-#define DMESA_NEW_LINE (_NEW_LINE | \\r
- _NEW_TEXTURE | \\r
- _NEW_LIGHT | \\r
- _NEW_DEPTH | \\r
- _NEW_RENDERMODE | \\r
- _SWRAST_NEW_RASTERMASK)\r
-\r
-#define DMESA_NEW_TRIANGLE (_NEW_POLYGON | \\r
- _NEW_TEXTURE | \\r
- _NEW_LIGHT | \\r
- _NEW_DEPTH | \\r
- _NEW_RENDERMODE | \\r
- _SWRAST_NEW_RASTERMASK)\r
-\r
-/* Extend the software rasterizer with our line and triangle\r
- * functions.\r
- */\r
-static void dmesa_register_swrast_functions (GLcontext *ctx)\r
-{\r
- SWcontext *swrast = SWRAST_CONTEXT(ctx);\r
-\r
- swrast->choose_line = dmesa_choose_line;\r
- swrast->choose_triangle = dmesa_choose_tri;\r
-\r
- swrast->invalidate_line |= DMESA_NEW_LINE;\r
- swrast->invalidate_triangle |= DMESA_NEW_TRIANGLE;\r
-}\r
-\r
-\r
-\r
-/* Setup pointers and other driver state that is constant for the life\r
- * of a context.\r
- */\r
-static void dmesa_init_pointers (GLcontext *ctx)\r
-{\r
- TNLcontext *tnl;\r
- struct swrast_device_driver *dd = _swrast_GetDeviceDriverReference(ctx);\r
-\r
- ctx->Driver.GetString = get_string;\r
- ctx->Driver.GetBufferSize = get_buffer_size;\r
- ctx->Driver.Flush = flush;\r
- ctx->Driver.Finish = finish;\r
- \r
- /* Software rasterizer pixel paths:\r
- */\r
- ctx->Driver.Accum = _swrast_Accum;\r
- ctx->Driver.Bitmap = _swrast_Bitmap;\r
- ctx->Driver.Clear = clear;\r
- ctx->Driver.ResizeBuffers = _swrast_alloc_buffers;\r
- ctx->Driver.CopyPixels = _swrast_CopyPixels;\r
- ctx->Driver.DrawPixels = _swrast_DrawPixels;\r
- ctx->Driver.ReadPixels = _swrast_ReadPixels;\r
- ctx->Driver.DrawBuffer = _swrast_DrawBuffer;\r
-\r
- /* Software texture functions:\r
- */\r
- ctx->Driver.ChooseTextureFormat = _mesa_choose_tex_format;\r
- ctx->Driver.TexImage1D = _mesa_store_teximage1d;\r
- ctx->Driver.TexImage2D = _mesa_store_teximage2d;\r
- ctx->Driver.TexImage3D = _mesa_store_teximage3d;\r
- ctx->Driver.TexSubImage1D = _mesa_store_texsubimage1d;\r
- ctx->Driver.TexSubImage2D = _mesa_store_texsubimage2d;\r
- ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d;\r
- ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage;\r
-\r
- ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d;\r
- ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d;\r
- ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d;\r
- ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d;\r
- ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d;\r
-\r
- ctx->Driver.CompressedTexImage1D = _mesa_store_compressed_teximage1d;\r
- ctx->Driver.CompressedTexImage2D = _mesa_store_compressed_teximage2d;\r
- ctx->Driver.CompressedTexImage3D = _mesa_store_compressed_teximage3d;\r
- ctx->Driver.CompressedTexSubImage1D = _mesa_store_compressed_texsubimage1d;\r
- ctx->Driver.CompressedTexSubImage2D = _mesa_store_compressed_texsubimage2d;\r
- ctx->Driver.CompressedTexSubImage3D = _mesa_store_compressed_texsubimage3d;\r
-\r
- /* Swrast hooks for imaging extensions:\r
- */\r
- ctx->Driver.CopyColorTable = _swrast_CopyColorTable;\r
- ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable;\r
- ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D;\r
- ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D;\r
-\r
- /* Statechange callbacks:\r
- */\r
- ctx->Driver.ClearColor = clear_color;\r
- ctx->Driver.ClearIndex = clear_index;\r
-\r
- /* Initialize the TNL driver interface:\r
- */\r
- tnl = TNL_CONTEXT(ctx);\r
- tnl->Driver.RunPipeline = _tnl_run_pipeline;\r
-\r
- dd->SetBuffer = set_buffer;\r
- \r
- /* Install swsetup for tnl->Driver.Render.*:\r
- */\r
- _swsetup_Wakeup(ctx);\r
-\r
- /* The span functions should be in `dmesa_update_state', but I'm\r
- * pretty sure they will never change during the life of the Visual\r
- */\r
-#ifdef MATROX\r
- if (((DMesaContext)ctx->DriverCtx)->visual->zbuffer == -1) {\r
- /* Depth span/pixel functions */\r
- dd->WriteDepthSpan = write_depth_span;\r
- dd->WriteDepthPixels = write_depth_pixels;\r
- dd->ReadDepthSpan = read_depth_span;\r
- dd->ReadDepthPixels = read_depth_pixels;\r
- }\r
-#endif\r
-\r
-#ifndef MATROX\r
- /* Index span/pixel functions */\r
- dd->WriteCI32Span = write_index_span;\r
- dd->WriteCI8Span = write_index8_span;\r
- dd->WriteMonoCISpan = write_mono_index_span;\r
- dd->WriteCI32Pixels = write_index_pixels;\r
- dd->WriteMonoCIPixels = write_mono_index_pixels;\r
- dd->ReadCI32Span = read_index_span;\r
- dd->ReadCI32Pixels = read_index_pixels;\r
-#endif\r
-\r
- /* RGB(A) span/pixel functions */\r
- dd->WriteRGBASpan = write_rgba_span;\r
- dd->WriteRGBSpan = write_rgb_span;\r
- dd->WriteMonoRGBASpan = write_mono_rgba_span;\r
- dd->WriteRGBAPixels = write_rgba_pixels;\r
- dd->WriteMonoRGBAPixels = write_mono_rgba_pixels;\r
- dd->ReadRGBASpan = read_rgba_span;\r
- dd->ReadRGBAPixels = read_rgba_pixels;\r
-}\r
-\r
-\r
-\r
-static void dmesa_update_state (GLcontext *ctx, GLuint new_state)\r
-{\r
- /* Propogate statechange information to swrast and swrast_setup\r
- * modules. The DMesa driver has no internal GL-dependent state.\r
- */\r
- _swrast_InvalidateState( ctx, new_state );\r
- _ac_InvalidateState( ctx, new_state );\r
- _tnl_InvalidateState( ctx, new_state );\r
- _swsetup_InvalidateState( ctx, new_state );\r
-}\r
-#endif /* FX */\r
-\r
-\r
-\r
-/****************************************************************************\r
- * DMesa Public API Functions\r
- ***************************************************************************/\r
-\r
-/*\r
- * The exact arguments to this function will depend on your window system\r
- */\r
-DMesaVisual DMesaCreateVisual (GLint width,\r
- GLint height,\r
- GLint colDepth,\r
- GLint refresh,\r
- GLboolean dbFlag,\r
- GLboolean rgbFlag,\r
- GLboolean alphaFlag,\r
- GLint depthSize,\r
- GLint stencilSize,\r
- GLint accumSize)\r
-{\r
-#ifndef FX\r
- DMesaVisual v;\r
- GLint redBits, greenBits, blueBits, alphaBits, indexBits;\r
-\r
-#ifndef MATROX\r
- if (!dbFlag) {\r
- return NULL;\r
- }\r
-#else\r
- if (!rgbFlag) {\r
- return NULL;\r
- }\r
-#endif\r
-\r
- alphaBits = 0;\r
-\r
- if (!rgbFlag) {\r
- indexBits = 8;\r
- redBits = 0;\r
- greenBits = 0;\r
- blueBits = 0;\r
- } else {\r
- indexBits = 0;\r
- switch (colDepth) {\r
- case 8:\r
- redBits = 8;\r
- greenBits = 8;\r
- blueBits = 8;\r
- break;\r
- case 15:\r
- redBits = 5;\r
- greenBits = 5;\r
- blueBits = 5;\r
- break;\r
- case 16:\r
- redBits = 5;\r
- greenBits = 6;\r
- blueBits = 5;\r
- break;\r
- case 32:\r
- alphaBits = 8;\r
- case 24:\r
- redBits = 8;\r
- greenBits = 8;\r
- blueBits = 8;\r
- break;\r
- default:\r
- return NULL;\r
- }\r
- }\r
-\r
-#ifndef MATROX\r
- if ((colDepth=vl_video_init(width, height, colDepth, rgbFlag, refresh)) <= 0) {\r
- return NULL;\r
- }\r
-#else\r
- if (mga_open(width, height, colDepth, dbFlag ? 2 : 1, depthSize == 16, refresh) < 0) {\r
- return NULL;\r
- }\r
-#endif\r
-\r
- if (alphaFlag && (alphaBits==0)) {\r
- alphaBits = 8;\r
- }\r
-\r
- if ((v=(DMesaVisual)calloc(1, sizeof(struct dmesa_visual))) != NULL) {\r
- /* Create core visual */\r
- v->gl_visual = _mesa_create_visual(rgbFlag, /* rgb */\r
- dbFlag,\r
- GL_FALSE, /* stereo */\r
- redBits,\r
- greenBits,\r
- blueBits,\r
- alphaBits,\r
- indexBits, /* indexBits */\r
- depthSize,\r
- stencilSize,\r
- accumSize, /* accumRed */\r
- accumSize, /* accumGreen */\r
- accumSize, /* accumBlue */\r
- alphaFlag?accumSize:0, /* accumAlpha */\r
- 1); /* numSamples */\r
-\r
- v->depth = colDepth;\r
- v->db_flag = dbFlag;\r
- v->rgb_flag = rgbFlag;\r
-\r
- v->zbuffer = (depthSize > 0) ? 1 : 0;\r
-#ifdef MATROX\r
- mga_get(MGA_GET_HPIXELS, &v->stride_in_pixels);\r
- if (depthSize == 16) {\r
- v->zbuffer = -1;\r
- }\r
-#endif\r
- }\r
-\r
- return v;\r
-\r
-#else /* FX */\r
-\r
- int i = 0, fx_attrib[32];\r
-\r
- if (!rgbFlag) {\r
- return NULL;\r
- }\r
-\r
- if (dbFlag) fx_attrib[i++] = FXMESA_DOUBLEBUFFER;\r
- if (depthSize > 0) { fx_attrib[i++] = FXMESA_DEPTH_SIZE; fx_attrib[i++] = depthSize; }\r
- if (stencilSize > 0) { fx_attrib[i++] = FXMESA_STENCIL_SIZE; fx_attrib[i++] = stencilSize; }\r
- if (accumSize > 0) { fx_attrib[i++] = FXMESA_ACCUM_SIZE; fx_attrib[i++] = accumSize; }\r
- if (alphaFlag) { fx_attrib[i++] = FXMESA_ALPHA_SIZE; fx_attrib[i++] = 1; }\r
- fx_attrib[i] = FXMESA_NONE;\r
-\r
- return (DMesaVisual)fxMesaCreateBestContext(-1, width, height, fx_attrib);\r
-#endif /* FX */\r
-}\r
-\r
-\r
-\r
-void DMesaDestroyVisual (DMesaVisual v)\r
-{\r
-#ifndef FX\r
- _mesa_destroy_visual(v->gl_visual);\r
- free(v);\r
-\r
-#ifndef MATROX\r
- vl_video_exit();\r
-#else\r
- mga_close(1, 1);\r
-#endif\r
-\r
-#else\r
- fxMesaDestroyContext((fxMesaContext)v);\r
-#endif\r
-}\r
-\r
-\r
-\r
-DMesaBuffer DMesaCreateBuffer (DMesaVisual visual,\r
- GLint xpos, GLint ypos,\r
- GLint width, GLint height)\r
-{\r
-#ifndef FX\r
- DMesaBuffer b;\r
-\r
- if ((b=(DMesaBuffer)calloc(1, sizeof(struct dmesa_buffer))) != NULL) {\r
-\r
- _mesa_initialize_framebuffer(&b->gl_buffer,\r
- visual->gl_visual,\r
- visual->zbuffer == 1,\r
- visual->gl_visual->stencilBits > 0,\r
- visual->gl_visual->accumRedBits > 0,\r
- visual->gl_visual->alphaBits > 0);\r
- b->xpos = xpos;\r
- b->ypos = ypos;\r
- b->width = width;\r
- b->height = height;\r
- }\r
-\r
- return b;\r
-#else\r
- return (DMesaBuffer)visual;\r
-#endif\r
-}\r
-\r
-\r
-\r
-void DMesaDestroyBuffer (DMesaBuffer b)\r
-{\r
-#ifndef FX\r
-#ifndef MATROX\r
- free(b->the_window);\r
-#endif\r
- _mesa_free_framebuffer_data(&b->gl_buffer);\r
- free(b);\r
-#endif\r
-}\r
-\r
-\r
-\r
-DMesaContext DMesaCreateContext (DMesaVisual visual,\r
- DMesaContext share)\r
-{\r
-#ifndef FX\r
- DMesaContext c;\r
- GLboolean direct = GL_FALSE;\r
-\r
- if ((c=(DMesaContext)calloc(1, sizeof(struct dmesa_context))) != NULL) {\r
- c->gl_ctx = _mesa_create_context(visual->gl_visual,\r
- share ? share->gl_ctx : NULL,\r
- (void *)c, direct);\r
-\r
- _mesa_enable_sw_extensions(c->gl_ctx);\r
- _mesa_enable_1_3_extensions(c->gl_ctx);\r
- _mesa_enable_1_4_extensions(c->gl_ctx);\r
-\r
- /* you probably have to do a bunch of other initializations here. */\r
- c->visual = visual;\r
-\r
- c->gl_ctx->Driver.UpdateState = dmesa_update_state;\r
-\r
- /* Initialize the software rasterizer and helper modules.\r
- */\r
- _swrast_CreateContext(c->gl_ctx);\r
- _ac_CreateContext(c->gl_ctx);\r
- _tnl_CreateContext(c->gl_ctx);\r
- _swsetup_CreateContext(c->gl_ctx);\r
- if (visual->rgb_flag) dmesa_register_swrast_functions(c->gl_ctx);\r
- dmesa_init_pointers(c->gl_ctx);\r
- }\r
-\r
- return c;\r
-\r
-#else /* FX */\r
- return (DMesaContext)visual;\r
-#endif /* FX */\r
-}\r
-\r
-\r
-\r
-void DMesaDestroyContext (DMesaContext c)\r
-{\r
-#ifndef FX\r
- if (c->gl_ctx) {\r
- _swsetup_DestroyContext(c->gl_ctx);\r
- _swrast_DestroyContext(c->gl_ctx);\r
- _tnl_DestroyContext(c->gl_ctx);\r
- _ac_DestroyContext(c->gl_ctx);\r
- _mesa_destroy_context(c->gl_ctx);\r
- }\r
- free(c);\r
-#endif\r
-}\r
-\r
-\r
-\r
-GLboolean DMesaMoveBuffer (GLint xpos, GLint ypos)\r
-{\r
-#if !defined(FX) && !defined(MATROX)\r
- GET_CURRENT_CONTEXT(ctx);\r
- DMesaBuffer b = ((DMesaContext)ctx->DriverCtx)->Buffer;\r
-\r
- if (vl_sync_buffer(&b->the_window, xpos, ypos, b->width, b->height) != 0) {\r
- return GL_FALSE;\r
- } else {\r
- b->xpos = xpos;\r
- b->ypos = ypos;\r
- return GL_TRUE;\r
- }\r
-\r
-#else\r
- return GL_FALSE;\r
-#endif\r
-}\r
-\r
-\r
-\r
-GLboolean DMesaResizeBuffer (GLint width, GLint height)\r
-{\r
-#if !defined(FX) && !defined(MATROX)\r
- GET_CURRENT_CONTEXT(ctx);\r
- DMesaBuffer b = ((DMesaContext)ctx->DriverCtx)->Buffer;\r
-\r
- if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, width, height) != 0) {\r
- return GL_FALSE;\r
- } else {\r
- b->width = width;\r
- b->height = height;\r
- return GL_TRUE;\r
- }\r
-\r
-#else\r
- return GL_FALSE;\r
-#endif\r
-}\r
-\r
-\r
-\r
-/*\r
- * Make the specified context and buffer the current one.\r
- */\r
-GLboolean DMesaMakeCurrent (DMesaContext c, DMesaBuffer b)\r
-{\r
-#ifndef FX\r
- if ((c != NULL) && (b != NULL)) {\r
-#ifndef MATROX\r
- if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, b->width, b->height) != 0) {\r
- return GL_FALSE;\r
- }\r
-#endif\r
-\r
- c->Buffer = b;\r
-\r
- _mesa_make_current(c->gl_ctx, &b->gl_buffer);\r
- if (c->gl_ctx->Viewport.Width == 0) {\r
- /* initialize viewport to window size */\r
- _mesa_Viewport(0, 0, b->width, b->height);\r
- }\r
- } else {\r
- /* Detach */\r
- _mesa_make_current(NULL, NULL);\r
- }\r
-\r
-#else\r
- fxMesaMakeCurrent((fxMesaContext)c);\r
-#endif\r
-\r
- return GL_TRUE;\r
-}\r
-\r
-\r
-\r
-void DMesaSwapBuffers (DMesaBuffer b)\r
-{\r
- /* copy/swap back buffer to front if applicable */\r
-#ifndef FX\r
- GET_CURRENT_CONTEXT(ctx);\r
- _mesa_notifySwapBuffers(ctx);\r
-#ifndef MATROX\r
- vl_flip();\r
-#else\r
- if (((DMesaContext)ctx->DriverCtx)->visual->db_flag) {\r
- mga_swapbuffers(1);\r
- }\r
-#endif\r
-#else\r
- fxMesaSwapBuffers();\r
-#endif\r
-}\r
-\r
-\r
-\r
-void DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue)\r
-{\r
-#if !defined(FX) && !defined(MATROX)\r
- vl_setCI(ndx, red, green, blue);\r
-#endif\r
-}\r
-\r
-\r
-\r
-DMesaContext DMesaGetCurrentContext (void)\r
-{\r
-#ifndef FX\r
- GET_CURRENT_CONTEXT(ctx);\r
- return (ctx == NULL) ? NULL : (DMesaContext)ctx->DriverCtx;\r
-#else\r
- return (DMesaContext)fxMesaGetCurrentContext();\r
-#endif\r
-}\r
-\r
-\r
-\r
-int DMesaGetIntegerv (GLenum pname, GLint *params)\r
-{\r
-#ifndef FX\r
- GET_CURRENT_CONTEXT(ctx);\r
- const DMesaContext c = (ctx == NULL) ? NULL : (DMesaContext)ctx->DriverCtx;\r
-#else\r
- const fxMesaContext c = fxMesaGetCurrentContext();\r
-#endif\r
-\r
- if (c == NULL) {\r
- return -1;\r
- }\r
-\r
- switch (pname) {\r
- case DMESA_GET_SCREEN_SIZE:\r
- #ifndef FX\r
- #ifndef MATROX\r
- vl_get(VL_GET_SCREEN_SIZE, params);\r
- #else\r
- mga_get(MGA_GET_SCREEN_SIZE, params);\r
- #endif\r
- #else\r
- params[0] = c->screen_width;\r
- params[1] = c->screen_height;\r
- #endif\r
- break;\r
- case DMESA_GET_DRIVER_CAPS:\r
- #ifndef FX\r
- #ifndef MATROX\r
- params[0] = DMESA_DRIVER_SWDB_BIT;\r
- #else\r
- params[0] = 0;\r
- #endif\r
- #else\r
- params[0] = DMESA_DRIVER_LLWO_BIT;\r
- #endif\r
- break;\r
- default:\r
- return -1;\r
- }\r
-\r
- return 0;\r
-}\r
+/*
+ * 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 for Mesa
+ *
+ * Author: Daniel Borca
+ * Email : dborca@users.sourceforge.net
+ * Web : http://www.geocities.com/dborca
+ */
+
+
+#include "context.h"
+#include "imports.h"
+#include "mtypes.h"
+
+#include "video.h"
+
+#include "GL/osmesa.h"
+#include "GL/dmesa.h"
+
+
+/*
+ * This has nothing to do with Mesa Visual structure.
+ * We keep this one around for backwards compatibility,
+ * and to store video mode data for DMesaCreateContext.
+ */
+struct dmesa_visual {
+ GLenum format; /* OSMesa framebuffer format */
+ GLint depthBits;
+ GLint stencilBits;
+ GLint accumBits;
+};
+
+/*
+ * This has nothing to do with Mesa Buffer structure.
+ * We keep this one around for backwards compatibility,
+ * and to store various data.
+ */
+struct dmesa_buffer {
+ int xpos, ypos; /* position */
+ int width, height; /* size in pixels */
+ GLenum type;
+ void *the_window; /* your window handle, etc */
+};
+
+/*
+ * This has nothing to do with Mesa Context structure.
+ * We keep this one around for backwards compatibility,
+ * and to store real off-screen context.
+ */
+struct dmesa_context {
+ OSMesaContext osmesa;
+ DMesaBuffer buffer;
+};
+
+
+static DMesaContext ctx;
+
+
+/****************************************************************************
+ * 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 visual;
+ GLenum format;
+ int fbbits;
+
+ if (dbFlag) {
+ return NULL;
+ }
+
+ if (!rgbFlag) {
+ format = OSMESA_COLOR_INDEX;
+ fbbits = 8;
+ } else if (alphaSize) {
+ format = OSMESA_BGRA;
+ fbbits = 32;
+ } else if (colDepth == 15 || colDepth == 16) {
+ format = OSMESA_RGB_565;
+ fbbits = 16;
+ } else {
+ format = OSMESA_BGR;
+ fbbits = 24;
+ }
+
+ if ((visual = (DMesaVisual)CALLOC_STRUCT(dmesa_visual)) == NULL) {
+ return NULL;
+ }
+
+ if (vl_video_init(width, height, colDepth, rgbFlag, refresh, fbbits) <= 0) {
+ FREE(visual);
+ return NULL;
+ }
+
+ visual->format = format;
+ visual->depthBits = depthSize;
+ visual->stencilBits = stencilSize;
+ visual->accumBits = accumSize;
+ return visual;
+}
+
+
+void
+DMesaDestroyVisual (DMesaVisual visual)
+{
+ vl_video_exit();
+ FREE(visual);
+}
+
+
+DMesaBuffer
+DMesaCreateBuffer (DMesaVisual visual,
+ GLint xpos, GLint ypos,
+ GLint width, GLint height)
+{
+ DMesaBuffer buffer;
+ GLenum type;
+ int bytesPerPixel;
+
+ switch (visual->format) {
+ case OSMESA_COLOR_INDEX:
+ bytesPerPixel = 1;
+ type = CHAN_TYPE;
+ break;
+ case OSMESA_RGB_565:
+ bytesPerPixel = 2;
+ type = GL_UNSIGNED_SHORT_5_6_5;
+ break;
+ case OSMESA_BGR:
+ bytesPerPixel = 3;
+ type = CHAN_TYPE;
+ break;
+ default:
+ bytesPerPixel = 4;
+ type = CHAN_TYPE;
+ }
+
+ if ((buffer = (DMesaBuffer)CALLOC_STRUCT(dmesa_buffer)) != NULL) {
+ buffer->xpos = xpos;
+ buffer->ypos = ypos;
+ buffer->width = width;
+ buffer->height = height;
+ buffer->type = type;
+ buffer->the_window = MALLOC(width * height * bytesPerPixel + 1);
+ if (buffer->the_window == NULL) {
+ FREE(buffer);
+ buffer = NULL;
+ }
+ }
+
+ return buffer;
+}
+
+
+void
+DMesaDestroyBuffer (DMesaBuffer buffer)
+{
+ FREE(buffer->the_window);
+ FREE(buffer);
+}
+
+
+DMesaContext
+DMesaCreateContext (DMesaVisual visual, DMesaContext share)
+{
+ DMesaContext dmesa;
+ if ((dmesa = (DMesaContext)CALLOC_STRUCT(dmesa_context)) != NULL) {
+ dmesa->osmesa = OSMesaCreateContextExt(
+ visual->format,
+ visual->depthBits,
+ visual->stencilBits,
+ visual->accumBits,
+ (share != NULL) ? share->osmesa : NULL);
+ if (dmesa->osmesa == NULL) {
+ FREE(dmesa);
+ dmesa = NULL;
+ }
+ }
+ return dmesa;
+}
+
+
+void
+DMesaDestroyContext (DMesaContext dmesa)
+{
+ OSMesaDestroyContext(dmesa->osmesa);
+ FREE(dmesa);
+}
+
+
+GLboolean
+DMesaMoveBuffer (GLint xpos, GLint ypos)
+{
+ const DMesaContext dmesa = DMesaGetCurrentContext();
+ DMesaBuffer b = dmesa->buffer;
+
+ if (vl_sync_buffer(&b->the_window, xpos, ypos, b->width, b->height) == 0) {
+ b->xpos = xpos;
+ b->ypos = ypos;
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+
+GLboolean
+DMesaResizeBuffer (GLint width, GLint height)
+{
+ const DMesaContext dmesa = DMesaGetCurrentContext();
+ DMesaBuffer b = dmesa->buffer;
+
+ if (vl_sync_buffer(&b->the_window, b->xpos, b->ypos, width, height) == 0) {
+ b->width = width;
+ b->height = height;
+ return GL_TRUE;
+ }
+
+ return GL_FALSE;
+}
+
+
+GLboolean
+DMesaMakeCurrent (DMesaContext dmesa, DMesaBuffer buffer)
+{
+ if (dmesa == NULL || buffer == NULL) {
+ ctx = NULL;
+ return GL_TRUE;
+ }
+ if (OSMesaMakeCurrent(dmesa->osmesa, buffer->the_window,
+ buffer->type,
+ buffer->width, buffer->height) &&
+ vl_sync_buffer(&buffer->the_window, buffer->xpos, buffer->ypos, buffer->width, buffer->height) == 0) {
+ OSMesaPixelStore(OSMESA_Y_UP, GL_FALSE);
+ dmesa->buffer = buffer;
+ ctx = dmesa;
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
+
+
+void
+DMesaSwapBuffers (DMesaBuffer buffer)
+{
+ /* copy/swap back buffer to front if applicable */
+ GET_CURRENT_CONTEXT(ctx);
+ _mesa_notifySwapBuffers(ctx);
+ vl_flip();
+ (void)buffer;
+}
+
+
+void
+DMesaSetCI (int ndx, GLfloat red, GLfloat green, GLfloat blue)
+{
+ vl_setCI(ndx, red, green, blue);
+}
+
+
+DMesaContext
+DMesaGetCurrentContext (void)
+{
+ return ctx;
+}
+
+
+DMesaBuffer
+DMesaGetCurrentBuffer (void)
+{
+ const DMesaContext dmesa = DMesaGetCurrentContext();
+
+ if (dmesa != NULL) {
+ return dmesa->buffer;
+ }
+
+ return NULL;
+}
+
+
+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:
+ vl_get(VL_GET_SCREEN_SIZE, params);
+ break;
+ case DMESA_GET_DRIVER_CAPS:
+ params[0] = 0;
+ break;
+ case DMESA_GET_VIDEO_MODES:
+ return vl_get(VL_GET_VIDEO_MODES, params);
+ case DMESA_GET_BUFFER_ADDR: {
+ const DMesaContext dmesa = DMesaGetCurrentContext();
+ if (dmesa != NULL) {
+ DMesaBuffer b = dmesa->buffer;
+ if (b != NULL) {
+ params[0] = (GLint)b->the_window;
+ }
+ }
+ break;
+ }
+ default:
+ return -1;
+ }
+
+ return 0;
+}