1 | /* -*- mode: C; tab-width:8; c-basic-offset:2 -*- */
|
---|
2 |
|
---|
3 | /*
|
---|
4 | * Mesa 3-D graphics library
|
---|
5 | * Version: 3.3
|
---|
6 | *
|
---|
7 | * Copyright (C) 1999 Brian Paul All Rights Reserved.
|
---|
8 | *
|
---|
9 | * Permission is hereby granted, free of charge, to any person obtaining a
|
---|
10 | * copy of this software and associated documentation files (the "Software"),
|
---|
11 | * to deal in the Software without restriction, including without limitation
|
---|
12 | * the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
---|
13 | * and/or sell copies of the Software, and to permit persons to whom the
|
---|
14 | * Software is furnished to do so, subject to the following conditions:
|
---|
15 | *
|
---|
16 | * The above copyright notice and this permission notice shall be included
|
---|
17 | * in all copies or substantial portions of the Software.
|
---|
18 | *
|
---|
19 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
---|
20 | * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
---|
21 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
---|
22 | * BRIAN PAUL BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
|
---|
23 | * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
---|
24 | * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
---|
25 | *
|
---|
26 | *
|
---|
27 | * Original Mesa / 3Dfx device driver (C) 1999 David Bucciarelli, by the
|
---|
28 | * terms stated above.
|
---|
29 | *
|
---|
30 | * Thank you for your contribution, David!
|
---|
31 | *
|
---|
32 | * Please make note of the above copyright/license statement. If you
|
---|
33 | * contributed code or bug fixes to this code under the previous (GNU
|
---|
34 | * Library) license and object to the new license, your code will be
|
---|
35 | * removed at your request. Please see the Mesa docs/COPYRIGHT file
|
---|
36 | * for more information.
|
---|
37 | *
|
---|
38 | * Additional Mesa/3Dfx driver developers:
|
---|
39 | * Daryll Strauss <daryll@precisioninsight.com>
|
---|
40 | * Keith Whitwell <keith@precisioninsight.com>
|
---|
41 | *
|
---|
42 | * See fxapi.h for more revision/author details.
|
---|
43 | */
|
---|
44 |
|
---|
45 |
|
---|
46 | /* fxdd.c - 3Dfx VooDoo Mesa device driver functions */
|
---|
47 |
|
---|
48 |
|
---|
49 | #ifdef HAVE_CONFIG_H
|
---|
50 | #include "conf.h"
|
---|
51 | #endif
|
---|
52 |
|
---|
53 | #if defined(FX)
|
---|
54 |
|
---|
55 | #include "image.h"
|
---|
56 | #include "types.h"
|
---|
57 | #include "fxdrv.h"
|
---|
58 | #include "enums.h"
|
---|
59 | #include "extensions.h"
|
---|
60 | #include "pb.h"
|
---|
61 |
|
---|
62 | /* These lookup table are used to extract RGB values in [0,255] from
|
---|
63 | * 16-bit pixel values.
|
---|
64 | */
|
---|
65 | GLubyte FX_PixelToR[0x10000];
|
---|
66 | GLubyte FX_PixelToG[0x10000];
|
---|
67 | GLubyte FX_PixelToB[0x10000];
|
---|
68 |
|
---|
69 |
|
---|
70 | /*
|
---|
71 | * Initialize the FX_PixelTo{RGB} arrays.
|
---|
72 | * Input: bgrOrder - if TRUE, pixels are in BGR order, else RGB order.
|
---|
73 | */
|
---|
74 | void fxInitPixelTables(fxMesaContext fxMesa, GLboolean bgrOrder)
|
---|
75 | {
|
---|
76 | GLuint pixel;
|
---|
77 |
|
---|
78 | fxMesa->bgrOrder=bgrOrder;
|
---|
79 | for (pixel = 0; pixel <= 0xffff; pixel++) {
|
---|
80 | GLuint r, g, b;
|
---|
81 | if (bgrOrder) {
|
---|
82 | r = (pixel & 0x001F) << 3;
|
---|
83 | g = (pixel & 0x07E0) >> 3;
|
---|
84 | b = (pixel & 0xF800) >> 8;
|
---|
85 | }
|
---|
86 | else {
|
---|
87 | r = (pixel & 0xF800) >> 8;
|
---|
88 | g = (pixel & 0x07E0) >> 3;
|
---|
89 | b = (pixel & 0x001F) << 3;
|
---|
90 | }
|
---|
91 | r = r * 255 / 0xF8; /* fill in low-order bits */
|
---|
92 | g = g * 255 / 0xFC;
|
---|
93 | b = b * 255 / 0xF8;
|
---|
94 | FX_PixelToR[pixel] = r;
|
---|
95 | FX_PixelToG[pixel] = g;
|
---|
96 | FX_PixelToB[pixel] = b;
|
---|
97 | }
|
---|
98 | }
|
---|
99 |
|
---|
100 |
|
---|
101 | /**********************************************************************/
|
---|
102 | /***** Miscellaneous functions *****/
|
---|
103 | /**********************************************************************/
|
---|
104 |
|
---|
105 | /* Enalbe/Disable dithering */
|
---|
106 | static void fxDDDither(GLcontext *ctx, GLboolean enable)
|
---|
107 | {
|
---|
108 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
109 | fprintf(stderr,"fxmesa: fxDDDither()\n");
|
---|
110 | }
|
---|
111 |
|
---|
112 | if (enable) {
|
---|
113 | FX_grDitherMode(GR_DITHER_4x4);
|
---|
114 | } else {
|
---|
115 | FX_grDitherMode(GR_DITHER_DISABLE);
|
---|
116 | }
|
---|
117 | }
|
---|
118 |
|
---|
119 |
|
---|
120 | /* Return buffer size information */
|
---|
121 | static void fxDDBufferSize(GLcontext *ctx, GLuint *width, GLuint *height)
|
---|
122 | {
|
---|
123 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
124 |
|
---|
125 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
126 | fprintf(stderr,"fxmesa: fxDDBufferSize(...) Start\n");
|
---|
127 | }
|
---|
128 |
|
---|
129 | *width=fxMesa->width;
|
---|
130 | *height=fxMesa->height;
|
---|
131 |
|
---|
132 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
133 | fprintf(stderr,"fxmesa: fxDDBufferSize(...) End\n");
|
---|
134 | }
|
---|
135 | }
|
---|
136 |
|
---|
137 |
|
---|
138 | /* Set current drawing color */
|
---|
139 | static void fxDDSetColor(GLcontext *ctx, GLubyte red, GLubyte green,
|
---|
140 | GLubyte blue, GLubyte alpha )
|
---|
141 | {
|
---|
142 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
143 | GLubyte col[4];
|
---|
144 | ASSIGN_4V( col, red, green, blue, alpha );
|
---|
145 |
|
---|
146 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
147 | fprintf(stderr,"fxmesa: fxDDSetColor(%d,%d,%d,%d)\n",red,green,blue,alpha);
|
---|
148 | }
|
---|
149 |
|
---|
150 | fxMesa->color=FXCOLOR4(col);
|
---|
151 | }
|
---|
152 |
|
---|
153 |
|
---|
154 | /* Implements glClearColor() */
|
---|
155 | static void fxDDClearColor(GLcontext *ctx, GLubyte red, GLubyte green,
|
---|
156 | GLubyte blue, GLubyte alpha )
|
---|
157 | {
|
---|
158 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
159 | GLubyte col[4];
|
---|
160 |
|
---|
161 |
|
---|
162 |
|
---|
163 | ASSIGN_4V( col, red, green, blue, 255 );
|
---|
164 |
|
---|
165 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
166 | fprintf(stderr,"fxmesa: fxDDClearColor(%d,%d,%d,%d)\n",red,green,blue,alpha);
|
---|
167 | }
|
---|
168 |
|
---|
169 | fxMesa->clearC=FXCOLOR4( col );
|
---|
170 | fxMesa->clearA=alpha;
|
---|
171 | }
|
---|
172 |
|
---|
173 | /* Clear the color and/or depth buffers */
|
---|
174 | static GLbitfield fxDDClear(GLcontext *ctx, GLbitfield mask, GLboolean all,
|
---|
175 | GLint x, GLint y, GLint width, GLint height )
|
---|
176 | {
|
---|
177 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
178 | const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
|
---|
179 | const FxU16 clearD = (FxU16) (ctx->Depth.Clear * 0xffff);
|
---|
180 | GLbitfield softwareMask = mask & (DD_STENCIL_BIT | DD_ACCUM_BIT);
|
---|
181 |
|
---|
182 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
183 | fprintf(stderr,"fxmesa: fxDDClear(%d,%d,%d,%d)\n",x,y,width,height);
|
---|
184 | }
|
---|
185 |
|
---|
186 | if (colorMask != 0xffffffff) {
|
---|
187 | /* do color buffer clears in software */
|
---|
188 | softwareMask |= (mask & (DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT));
|
---|
189 | mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT);
|
---|
190 | }
|
---|
191 |
|
---|
192 | /*
|
---|
193 | * This could probably be done fancier but doing each possible case
|
---|
194 | * explicitly is less error prone.
|
---|
195 | */
|
---|
196 | switch (mask) {
|
---|
197 | case DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
|
---|
198 | /* back buffer & depth */
|
---|
199 | FX_grDepthMask(FXTRUE);
|
---|
200 | FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
|
---|
201 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
202 | if (!ctx->Depth.Mask) {
|
---|
203 | FX_grDepthMask(FXFALSE);
|
---|
204 | }
|
---|
205 | break;
|
---|
206 | case DD_FRONT_LEFT_BIT | DD_DEPTH_BIT:
|
---|
207 | /* XXX it appears that the depth buffer isn't cleared when
|
---|
208 | * glRenderBuffer(GR_BUFFER_FRONTBUFFER) is set.
|
---|
209 | * This is a work-around/
|
---|
210 | */
|
---|
211 | /* clear depth */
|
---|
212 | FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
|
---|
213 | FX_grColorMask(FXFALSE,FXFALSE);
|
---|
214 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
215 | /* clear front */
|
---|
216 | FX_grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
|
---|
217 | FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
|
---|
218 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
219 | break;
|
---|
220 | case DD_BACK_LEFT_BIT:
|
---|
221 | /* back buffer only */
|
---|
222 | FX_grDepthMask(FXFALSE);
|
---|
223 | FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
|
---|
224 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
225 | if (!ctx->Depth.Mask) {
|
---|
226 | FX_grDepthMask(FXFALSE);
|
---|
227 | }
|
---|
228 | break;
|
---|
229 | case DD_FRONT_LEFT_BIT:
|
---|
230 | /* front buffer only */
|
---|
231 | FX_grDepthMask(FXFALSE);
|
---|
232 | FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
|
---|
233 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
234 | if (!ctx->Depth.Mask) {
|
---|
235 | FX_grDepthMask(FXFALSE);
|
---|
236 | }
|
---|
237 | break;
|
---|
238 | case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT:
|
---|
239 | /* front and back */
|
---|
240 | FX_grDepthMask(FXFALSE);
|
---|
241 | FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
|
---|
242 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
243 | FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
|
---|
244 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
245 | if (!ctx->Depth.Mask) {
|
---|
246 | FX_grDepthMask(FXFALSE);
|
---|
247 | }
|
---|
248 | break;
|
---|
249 | case DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT | DD_DEPTH_BIT:
|
---|
250 | /* clear front */
|
---|
251 | FX_grDepthMask(FXFALSE);
|
---|
252 | FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
|
---|
253 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
254 | /* clear back and depth */
|
---|
255 | FX_grDepthMask(FXTRUE);
|
---|
256 | FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
|
---|
257 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA, clearD);
|
---|
258 | if (!ctx->Depth.Mask) {
|
---|
259 | FX_grDepthMask(FXFALSE);
|
---|
260 | }
|
---|
261 | break;
|
---|
262 | case DD_DEPTH_BIT:
|
---|
263 | /* just the depth buffer */
|
---|
264 | FX_grColorMask(FXFALSE,FXFALSE);
|
---|
265 | FX_grBufferClear(fxMesa->clearC, fxMesa->clearA,
|
---|
266 | (FxU16)(ctx->Depth.Clear*0xffff));
|
---|
267 | FX_grColorMask(FXTRUE, ctx->Color.ColorMask[ACOMP] && fxMesa->haveAlphaBuffer);
|
---|
268 | break;
|
---|
269 | default:
|
---|
270 | /* error */
|
---|
271 | ;
|
---|
272 | }
|
---|
273 |
|
---|
274 | return softwareMask;
|
---|
275 | }
|
---|
276 |
|
---|
277 |
|
---|
278 | /* Set the buffer used for reading */
|
---|
279 | static GLboolean fxDDSetDrawBuffer(GLcontext *ctx, GLenum mode )
|
---|
280 | {
|
---|
281 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
282 |
|
---|
283 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
284 | fprintf(stderr,"fxmesa: fxDDSetBuffer(%x)\n",mode);
|
---|
285 | }
|
---|
286 |
|
---|
287 | if (mode == GL_FRONT_LEFT) {
|
---|
288 | fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
|
---|
289 | FX_grRenderBuffer(fxMesa->currentFB);
|
---|
290 | return GL_TRUE;
|
---|
291 | }
|
---|
292 | else if (mode == GL_BACK_LEFT) {
|
---|
293 | fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
|
---|
294 | FX_grRenderBuffer(fxMesa->currentFB);
|
---|
295 | return GL_TRUE;
|
---|
296 | }
|
---|
297 | else {
|
---|
298 | return GL_FALSE;
|
---|
299 | }
|
---|
300 | }
|
---|
301 |
|
---|
302 | /* Set the buffer used for reading */
|
---|
303 | static void fxDDSetReadBuffer(GLcontext *ctx, GLframebuffer *buffer,
|
---|
304 | GLenum mode )
|
---|
305 | {
|
---|
306 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
307 | (void) buffer;
|
---|
308 |
|
---|
309 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
310 | fprintf(stderr,"fxmesa: fxDDSetBuffer(%x)\n", (int) mode);
|
---|
311 | }
|
---|
312 |
|
---|
313 | if (mode == GL_FRONT_LEFT) {
|
---|
314 | fxMesa->currentFB = GR_BUFFER_FRONTBUFFER;
|
---|
315 | FX_grRenderBuffer(fxMesa->currentFB);
|
---|
316 | }
|
---|
317 | else if (mode == GL_BACK_LEFT) {
|
---|
318 | fxMesa->currentFB = GR_BUFFER_BACKBUFFER;
|
---|
319 | FX_grRenderBuffer(fxMesa->currentFB);
|
---|
320 | }
|
---|
321 | }
|
---|
322 |
|
---|
323 |
|
---|
324 |
|
---|
325 | #ifdef XF86DRI
|
---|
326 | /* test if window coord (px,py) is visible */
|
---|
327 | static GLboolean inClipRects(fxMesaContext fxMesa, int px, int py)
|
---|
328 | {
|
---|
329 | int i;
|
---|
330 | for (i=0; i<fxMesa->numClipRects; i++) {
|
---|
331 | if ((px>=fxMesa->pClipRects[i].x1) &&
|
---|
332 | (px<fxMesa->pClipRects[i].x2) &&
|
---|
333 | (py>=fxMesa->pClipRects[i].y1) &&
|
---|
334 | (py<fxMesa->pClipRects[i].y2)) return GL_TRUE;
|
---|
335 | }
|
---|
336 | return GL_FALSE;
|
---|
337 | }
|
---|
338 | #endif
|
---|
339 |
|
---|
340 |
|
---|
341 | static GLboolean fxDDDrawBitMap(GLcontext *ctx, GLint px, GLint py,
|
---|
342 | GLsizei width, GLsizei height,
|
---|
343 | const struct gl_pixelstore_attrib *unpack,
|
---|
344 | const GLubyte *bitmap)
|
---|
345 | {
|
---|
346 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
347 | GrLfbInfo_t info;
|
---|
348 | FxU16 color;
|
---|
349 | const struct gl_pixelstore_attrib *finalUnpack;
|
---|
350 | struct gl_pixelstore_attrib scissoredUnpack;
|
---|
351 |
|
---|
352 | /* check if there's any raster operations enabled which we can't handle */
|
---|
353 | if (ctx->RasterMask & (ALPHATEST_BIT |
|
---|
354 | BLEND_BIT |
|
---|
355 | DEPTH_BIT |
|
---|
356 | FOG_BIT |
|
---|
357 | LOGIC_OP_BIT |
|
---|
358 | SCISSOR_BIT |
|
---|
359 | STENCIL_BIT |
|
---|
360 | MASKING_BIT |
|
---|
361 | ALPHABUF_BIT |
|
---|
362 | MULTI_DRAW_BIT))
|
---|
363 | return GL_FALSE;
|
---|
364 |
|
---|
365 | if (ctx->Scissor.Enabled) {
|
---|
366 | /* This is a bit tricky, but by carefully adjusting the px, py,
|
---|
367 | * width, height, skipPixels and skipRows values we can do
|
---|
368 | * scissoring without special code in the rendering loop.
|
---|
369 | */
|
---|
370 |
|
---|
371 | /* we'll construct a new pixelstore struct */
|
---|
372 | finalUnpack = &scissoredUnpack;
|
---|
373 | scissoredUnpack = *unpack;
|
---|
374 | if (scissoredUnpack.RowLength == 0)
|
---|
375 | scissoredUnpack.RowLength = width;
|
---|
376 |
|
---|
377 | /* clip left */
|
---|
378 | if (px < ctx->Scissor.X) {
|
---|
379 | scissoredUnpack.SkipPixels += (ctx->Scissor.X - px);
|
---|
380 | width -= (ctx->Scissor.X - px);
|
---|
381 | px = ctx->Scissor.X;
|
---|
382 | }
|
---|
383 | /* clip right */
|
---|
384 | if (px + width >= ctx->Scissor.X + ctx->Scissor.Width) {
|
---|
385 | width -= (px + width - (ctx->Scissor.X + ctx->Scissor.Width));
|
---|
386 | }
|
---|
387 | /* clip bottom */
|
---|
388 | if (py < ctx->Scissor.Y) {
|
---|
389 | scissoredUnpack.SkipRows += (ctx->Scissor.Y - py);
|
---|
390 | height -= (ctx->Scissor.Y - py);
|
---|
391 | py = ctx->Scissor.Y;
|
---|
392 | }
|
---|
393 | /* clip top */
|
---|
394 | if (py + height >= ctx->Scissor.Y + ctx->Scissor.Height) {
|
---|
395 | height -= (py + height - (ctx->Scissor.Y + ctx->Scissor.Height));
|
---|
396 | }
|
---|
397 |
|
---|
398 | if (width <= 0 || height <= 0)
|
---|
399 | return GL_TRUE; /* totally scissored away */
|
---|
400 | }
|
---|
401 | else {
|
---|
402 | finalUnpack = unpack;
|
---|
403 | }
|
---|
404 |
|
---|
405 | /* compute pixel value */
|
---|
406 | {
|
---|
407 | GLint r = (GLint) (ctx->Current.RasterColor[0] * 255.0f);
|
---|
408 | GLint g = (GLint) (ctx->Current.RasterColor[1] * 255.0f);
|
---|
409 | GLint b = (GLint) (ctx->Current.RasterColor[2] * 255.0f);
|
---|
410 | /*GLint a = (GLint)(ctx->Current.RasterColor[3]*255.0f);*/
|
---|
411 | if (fxMesa->bgrOrder)
|
---|
412 | color = (FxU16)
|
---|
413 | ( ((FxU16)0xf8 & b) << (11-3)) |
|
---|
414 | ( ((FxU16)0xfc & g) << (5-3+1)) |
|
---|
415 | ( ((FxU16)0xf8 & r) >> 3);
|
---|
416 | else
|
---|
417 | color = (FxU16)
|
---|
418 | ( ((FxU16)0xf8 & r) << (11-3)) |
|
---|
419 | ( ((FxU16)0xfc & g) << (5-3+1)) |
|
---|
420 | ( ((FxU16)0xf8 & b) >> 3);
|
---|
421 | }
|
---|
422 |
|
---|
423 | info.size = sizeof(info);
|
---|
424 | if (!FX_grLfbLock(GR_LFB_WRITE_ONLY,
|
---|
425 | fxMesa->currentFB,
|
---|
426 | GR_LFBWRITEMODE_565,
|
---|
427 | GR_ORIGIN_UPPER_LEFT,
|
---|
428 | FXFALSE,
|
---|
429 | &info)) {
|
---|
430 | #ifndef FX_SILENT
|
---|
431 | fprintf(stderr,"fx Driver: error locking the linear frame buffer\n");
|
---|
432 | #endif
|
---|
433 | return GL_TRUE;
|
---|
434 | }
|
---|
435 |
|
---|
436 | #ifdef XF86DRI
|
---|
437 | #define INSIDE(c, x, y) inClipRects((c), (x), (y))
|
---|
438 | #else
|
---|
439 | #define INSIDE(c, x, y) (1)
|
---|
440 | #endif
|
---|
441 |
|
---|
442 | {
|
---|
443 | const GLint winX = fxMesa->x_offset;
|
---|
444 | const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
|
---|
445 | /* The dest stride depends on the hardware and whether we're drawing
|
---|
446 | * to the front or back buffer. This compile-time test seems to do
|
---|
447 | * the job for now.
|
---|
448 | */
|
---|
449 | #ifdef XF86DRI
|
---|
450 | const GLint dstStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
|
---|
451 | ? (fxMesa->screen_width) : (info.strideInBytes / 2);
|
---|
452 | #else
|
---|
453 | const GLint dstStride = info.strideInBytes / 2; /* stride in GLushorts */
|
---|
454 | #endif
|
---|
455 | GLint row;
|
---|
456 | /* compute dest address of bottom-left pixel in bitmap */
|
---|
457 | GLushort *dst = (GLushort *) info.lfbPtr
|
---|
458 | + (winY - py) * dstStride
|
---|
459 | + (winX + px);
|
---|
460 |
|
---|
461 | for (row = 0; row < height; row++) {
|
---|
462 | const GLubyte *src = (const GLubyte *) _mesa_image_address( finalUnpack,
|
---|
463 | bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
|
---|
464 | if (finalUnpack->LsbFirst) {
|
---|
465 | /* least significan bit first */
|
---|
466 | GLubyte mask = 1U << (finalUnpack->SkipPixels & 0x7);
|
---|
467 | GLint col;
|
---|
468 | for (col=0; col<width; col++) {
|
---|
469 | if (*src & mask) {
|
---|
470 | if (INSIDE(fxMesa, winX + px + col, winY - py - row))
|
---|
471 | dst[col] = color;
|
---|
472 | }
|
---|
473 | if (mask == 128U) {
|
---|
474 | src++;
|
---|
475 | mask = 1U;
|
---|
476 | }
|
---|
477 | else {
|
---|
478 | mask = mask << 1;
|
---|
479 | }
|
---|
480 | }
|
---|
481 | if (mask != 1)
|
---|
482 | src++;
|
---|
483 | }
|
---|
484 | else {
|
---|
485 | /* most significan bit first */
|
---|
486 | GLubyte mask = 128U >> (finalUnpack->SkipPixels & 0x7);
|
---|
487 | GLint col;
|
---|
488 | for (col=0; col<width; col++) {
|
---|
489 | if (*src & mask) {
|
---|
490 | if (INSIDE(fxMesa, winX + px + col, winY - py - row))
|
---|
491 | dst[col] = color;
|
---|
492 | }
|
---|
493 | if (mask == 1U) {
|
---|
494 | src++;
|
---|
495 | mask = 128U;
|
---|
496 | }
|
---|
497 | else {
|
---|
498 | mask = mask >> 1;
|
---|
499 | }
|
---|
500 | }
|
---|
501 | if (mask != 128)
|
---|
502 | src++;
|
---|
503 | }
|
---|
504 | dst -= dstStride;
|
---|
505 | }
|
---|
506 | }
|
---|
507 |
|
---|
508 | #undef INSIDE
|
---|
509 |
|
---|
510 | FX_grLfbUnlock(GR_LFB_WRITE_ONLY,fxMesa->currentFB);
|
---|
511 | return GL_TRUE;
|
---|
512 | }
|
---|
513 |
|
---|
514 | static void fxDDFinish(GLcontext *ctx)
|
---|
515 | {
|
---|
516 | FX_grFlush();
|
---|
517 | }
|
---|
518 |
|
---|
519 |
|
---|
520 | static GLint fxDDGetParameteri(const GLcontext *ctx, GLint param)
|
---|
521 | {
|
---|
522 | switch(param) {
|
---|
523 | case DD_HAVE_HARDWARE_FOG:
|
---|
524 | return 1;
|
---|
525 | default:
|
---|
526 | fprintf(stderr,"fx Driver: internal error in fxDDGetParameteri(): %x\n",param);
|
---|
527 | fxCloseHardware();
|
---|
528 | EXIT(-1);
|
---|
529 | return 0;
|
---|
530 | }
|
---|
531 | }
|
---|
532 |
|
---|
533 |
|
---|
534 | void fxDDSetNearFar(GLcontext *ctx, GLfloat n, GLfloat f)
|
---|
535 | {
|
---|
536 | FX_CONTEXT(ctx)->new_state |= FX_NEW_FOG;
|
---|
537 | ctx->Driver.RenderStart = fxSetupFXUnits;
|
---|
538 | }
|
---|
539 |
|
---|
540 | /* KW: Put the word Mesa in the render string because quakeworld
|
---|
541 | * checks for this rather than doing a glGet(GL_MAX_TEXTURE_SIZE).
|
---|
542 | * Why?
|
---|
543 | */
|
---|
544 | static const GLubyte *fxDDGetString(GLcontext *ctx, GLenum name)
|
---|
545 | {
|
---|
546 | #if defined(GLX_DIRECT_RENDERING)
|
---|
547 | /* Building for DRI driver */
|
---|
548 | switch (name) {
|
---|
549 | case GL_RENDERER:
|
---|
550 | {
|
---|
551 | static char buffer[100];
|
---|
552 | char hardware[100];
|
---|
553 | strcpy(hardware, grGetString(GR_HARDWARE));
|
---|
554 | if (strcmp(hardware, "Voodoo3 (tm)") == 0)
|
---|
555 | strcpy(hardware, "Voodoo3");
|
---|
556 | else if (strcmp(hardware, "Voodoo Banshee (tm)") == 0)
|
---|
557 | strcpy(hardware, "VoodooBanshee");
|
---|
558 | else {
|
---|
559 | /* unexpected result: replace spaces with hyphens */
|
---|
560 | int i;
|
---|
561 | for (i = 0; hardware[i]; i++) {
|
---|
562 | if (hardware[i] == ' ' || hardware[i] == '\t')
|
---|
563 | hardware[i] = '-';
|
---|
564 | }
|
---|
565 | }
|
---|
566 | /* now make the GL_RENDERER string */
|
---|
567 | sprintf(buffer, "Mesa DRI %s 20000322", hardware);
|
---|
568 | return buffer;
|
---|
569 | }
|
---|
570 | case GL_VENDOR:
|
---|
571 | return "Precision Insight, Inc.";
|
---|
572 | default:
|
---|
573 | return NULL;
|
---|
574 | }
|
---|
575 |
|
---|
576 | #else
|
---|
577 |
|
---|
578 | /* Building for Voodoo1/2 stand-alone Mesa */
|
---|
579 | switch (name) {
|
---|
580 | case GL_RENDERER:
|
---|
581 | {
|
---|
582 | static char buf[80];
|
---|
583 |
|
---|
584 | if (glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_VOODOO) {
|
---|
585 | GrVoodooConfig_t *vc =
|
---|
586 | &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.VoodooConfig;
|
---|
587 |
|
---|
588 | sprintf(buf,
|
---|
589 | "Mesa Glide v0.30 Voodoo_Graphics %d "
|
---|
590 | "CARD/%d FB/%d TM/%d TMU/%s",
|
---|
591 | glbCurrentBoard,
|
---|
592 | (vc->sliDetect ? (vc->fbRam*2) : vc->fbRam),
|
---|
593 | (vc->tmuConfig[GR_TMU0].tmuRam +
|
---|
594 | ((vc->nTexelfx>1) ? vc->tmuConfig[GR_TMU1].tmuRam : 0)),
|
---|
595 | vc->nTexelfx,
|
---|
596 | (vc->sliDetect ? "SLI" : "NOSLI"));
|
---|
597 | }
|
---|
598 | else if (glbHWConfig.SSTs[glbCurrentBoard].type==GR_SSTTYPE_SST96) {
|
---|
599 | GrSst96Config_t *sc =
|
---|
600 | &glbHWConfig.SSTs[glbCurrentBoard].sstBoard.SST96Config;
|
---|
601 |
|
---|
602 | sprintf(buf,
|
---|
603 | "Glide v0.30 Voodoo_Rush %d "
|
---|
604 | "CARD/%d FB/%d TM/%d TMU/NOSLI",
|
---|
605 | glbCurrentBoard,
|
---|
606 | sc->fbRam,
|
---|
607 | sc->tmuConfig.tmuRam,
|
---|
608 | sc->nTexelfx);
|
---|
609 | }
|
---|
610 | else {
|
---|
611 | strcpy(buf, "Glide v0.30 UNKNOWN");
|
---|
612 | }
|
---|
613 | return (GLubyte *) buf;
|
---|
614 | }
|
---|
615 | default:
|
---|
616 | return NULL;
|
---|
617 | }
|
---|
618 | #endif
|
---|
619 | }
|
---|
620 |
|
---|
621 |
|
---|
622 | int fxDDInitFxMesaContext( fxMesaContext fxMesa )
|
---|
623 | {
|
---|
624 |
|
---|
625 | FX_setupGrVertexLayout();
|
---|
626 |
|
---|
627 | if (getenv("FX_EMULATE_SINGLE_TMU"))
|
---|
628 | fxMesa->haveTwoTMUs = GL_FALSE;
|
---|
629 |
|
---|
630 | fxMesa->emulateTwoTMUs = fxMesa->haveTwoTMUs;
|
---|
631 |
|
---|
632 | if (!getenv("FX_DONT_FAKE_MULTITEX"))
|
---|
633 | fxMesa->emulateTwoTMUs = GL_TRUE;
|
---|
634 |
|
---|
635 | if(getenv("FX_GLIDE_SWAPINTERVAL"))
|
---|
636 | fxMesa->swapInterval=atoi(getenv("FX_GLIDE_SWAPINTERVAL"));
|
---|
637 | else
|
---|
638 | fxMesa->swapInterval=1;
|
---|
639 |
|
---|
640 | if(getenv("MESA_FX_SWAP_PENDING"))
|
---|
641 | fxMesa->maxPendingSwapBuffers=atoi(getenv("MESA_FX_SWAP_PENDING"));
|
---|
642 | else
|
---|
643 | fxMesa->maxPendingSwapBuffers=2;
|
---|
644 |
|
---|
645 | if(getenv("MESA_FX_INFO"))
|
---|
646 | fxMesa->verbose=GL_TRUE;
|
---|
647 | else
|
---|
648 | fxMesa->verbose=GL_FALSE;
|
---|
649 |
|
---|
650 | fxMesa->color=0xffffffff;
|
---|
651 | fxMesa->clearC=0;
|
---|
652 | fxMesa->clearA=0;
|
---|
653 |
|
---|
654 | fxMesa->stats.swapBuffer=0;
|
---|
655 | fxMesa->stats.reqTexUpload=0;
|
---|
656 | fxMesa->stats.texUpload=0;
|
---|
657 | fxMesa->stats.memTexUpload=0;
|
---|
658 |
|
---|
659 | fxMesa->tmuSrc=FX_TMU_NONE;
|
---|
660 | fxMesa->lastUnitsMode=FX_UM_NONE;
|
---|
661 | fxTMInit(fxMesa);
|
---|
662 |
|
---|
663 | /* FX units setup */
|
---|
664 |
|
---|
665 | fxMesa->unitsState.alphaTestEnabled=GL_FALSE;
|
---|
666 | fxMesa->unitsState.alphaTestFunc=GR_CMP_ALWAYS;
|
---|
667 | fxMesa->unitsState.alphaTestRefValue=0;
|
---|
668 |
|
---|
669 | fxMesa->unitsState.blendEnabled=GL_FALSE;
|
---|
670 | fxMesa->unitsState.blendSrcFuncRGB=GR_BLEND_ONE;
|
---|
671 | fxMesa->unitsState.blendDstFuncRGB=GR_BLEND_ZERO;
|
---|
672 | fxMesa->unitsState.blendSrcFuncAlpha=GR_BLEND_ONE;
|
---|
673 | fxMesa->unitsState.blendDstFuncAlpha=GR_BLEND_ZERO;
|
---|
674 |
|
---|
675 | fxMesa->unitsState.depthTestEnabled =GL_FALSE;
|
---|
676 | fxMesa->unitsState.depthMask =GL_TRUE;
|
---|
677 | fxMesa->unitsState.depthTestFunc =GR_CMP_LESS;
|
---|
678 |
|
---|
679 | FX_grColorMask(FXTRUE, fxMesa->haveAlphaBuffer ? FXTRUE : FXFALSE);
|
---|
680 | if(fxMesa->haveDoubleBuffer) {
|
---|
681 | fxMesa->currentFB=GR_BUFFER_BACKBUFFER;
|
---|
682 | FX_grRenderBuffer(GR_BUFFER_BACKBUFFER);
|
---|
683 | } else {
|
---|
684 | fxMesa->currentFB=GR_BUFFER_FRONTBUFFER;
|
---|
685 | FX_grRenderBuffer(GR_BUFFER_FRONTBUFFER);
|
---|
686 | }
|
---|
687 |
|
---|
688 | fxMesa->state = NULL;
|
---|
689 | fxMesa->fogTable = NULL;
|
---|
690 |
|
---|
691 | fxMesa->state = malloc(FX_grGetInteger(FX_GLIDE_STATE_SIZE));
|
---|
692 | fxMesa->fogTable = (GrFog_t*)malloc(FX_grGetInteger(FX_FOG_TABLE_ENTRIES)*sizeof(GrFog_t));
|
---|
693 |
|
---|
694 | if (!fxMesa->state || !fxMesa->fogTable) {
|
---|
695 | if (fxMesa->state) free(fxMesa->state);
|
---|
696 | if (fxMesa->fogTable) free(fxMesa->fogTable);
|
---|
697 | return 0;
|
---|
698 | }
|
---|
699 |
|
---|
700 | if(fxMesa->haveZBuffer)
|
---|
701 | FX_grDepthBufferMode(GR_DEPTHBUFFER_ZBUFFER);
|
---|
702 |
|
---|
703 | #if (!FXMESA_USE_ARGB)
|
---|
704 | FX_grLfbWriteColorFormat(GR_COLORFORMAT_ABGR); /* Not every Glide has this */
|
---|
705 | #endif
|
---|
706 |
|
---|
707 | fxMesa->textureAlign=FX_grGetInteger(FX_TEXTURE_ALIGN);
|
---|
708 | fxMesa->glCtx->Const.MaxTextureLevels=9;
|
---|
709 | fxMesa->glCtx->Const.MaxTextureSize=256;
|
---|
710 | fxMesa->glCtx->Const.MaxTextureUnits=fxMesa->emulateTwoTMUs ? 2 : 1;
|
---|
711 | fxMesa->glCtx->NewState|=NEW_DRVSTATE1;
|
---|
712 | fxMesa->new_state = NEW_ALL;
|
---|
713 |
|
---|
714 | fxDDSetupInit();
|
---|
715 | fxDDCvaInit();
|
---|
716 | fxDDClipInit();
|
---|
717 | fxDDTrifuncInit();
|
---|
718 | fxDDFastPathInit();
|
---|
719 |
|
---|
720 | fxSetupDDPointers(fxMesa->glCtx);
|
---|
721 | fxDDRenderInit(fxMesa->glCtx);
|
---|
722 | fxDDInitExtensions(fxMesa->glCtx);
|
---|
723 |
|
---|
724 | fxDDSetNearFar(fxMesa->glCtx,1.0,100.0);
|
---|
725 |
|
---|
726 | FX_grGlideGetState((GrState*)fxMesa->state);
|
---|
727 |
|
---|
728 | /* XXX Fix me: callback not registered when main VB is created.
|
---|
729 | */
|
---|
730 | if (fxMesa->glCtx->VB)
|
---|
731 | fxDDRegisterVB( fxMesa->glCtx->VB );
|
---|
732 |
|
---|
733 | /* XXX Fix me too: need to have the 'struct dd' prepared prior to
|
---|
734 | * creating the context... The below is broken if you try to insert
|
---|
735 | * new stages.
|
---|
736 | */
|
---|
737 | if (fxMesa->glCtx->NrPipelineStages)
|
---|
738 | fxMesa->glCtx->NrPipelineStages = fxDDRegisterPipelineStages(
|
---|
739 | fxMesa->glCtx->PipelineStage,
|
---|
740 | fxMesa->glCtx->PipelineStage,
|
---|
741 | fxMesa->glCtx->NrPipelineStages);
|
---|
742 |
|
---|
743 | /* Run the config file */
|
---|
744 | gl_context_initialize( fxMesa->glCtx );
|
---|
745 |
|
---|
746 | return 1;
|
---|
747 | }
|
---|
748 |
|
---|
749 |
|
---|
750 |
|
---|
751 |
|
---|
752 |
|
---|
753 | void fxDDInitExtensions( GLcontext *ctx )
|
---|
754 | {
|
---|
755 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
756 |
|
---|
757 | gl_extensions_disable(ctx, "GL_EXT_blend_logic_op");
|
---|
758 | gl_extensions_disable(ctx, "GL_EXT_blend_minmax");
|
---|
759 | gl_extensions_disable(ctx, "GL_EXT_blend_subtract");
|
---|
760 | gl_extensions_disable(ctx, "GL_EXT_blend_color");
|
---|
761 | gl_extensions_disable(ctx, "GL_EXT_paletted_texture");
|
---|
762 |
|
---|
763 | gl_extensions_add(ctx, DEFAULT_ON, "3DFX_set_global_palette", 0);
|
---|
764 |
|
---|
765 | if (!fxMesa->haveTwoTMUs)
|
---|
766 | gl_extensions_disable(ctx, "GL_EXT_texture_env_add");
|
---|
767 |
|
---|
768 | if (!fxMesa->emulateTwoTMUs)
|
---|
769 | gl_extensions_disable(ctx, "GL_ARB_multitexture");
|
---|
770 |
|
---|
771 |
|
---|
772 | /* Example of hooking in an extension function.
|
---|
773 | * For DRI-based drivers, also see __driRegisterExtensions in the
|
---|
774 | * tdfx_xmesa.c file.
|
---|
775 | */
|
---|
776 | #if 0
|
---|
777 | {
|
---|
778 | void **dispatchTable = (void **) ctx->Exec;
|
---|
779 | const int _gloffset_FooBarEXT = 555; /* just an example number! */
|
---|
780 | const int tabSize = _glapi_get_dispatch_table_size();
|
---|
781 | assert(_gloffset_FooBarEXT < tabSize);
|
---|
782 | dispatchTable[_gloffset_FooBarEXT] = (void *) fxFooBarEXT;
|
---|
783 | /* XXX You would also need to hook into the display list dispatch
|
---|
784 | * table. Really, the implementation of extensions might as well
|
---|
785 | * be in the core of Mesa since core Mesa and the device driver
|
---|
786 | * is one big shared lib.
|
---|
787 | */
|
---|
788 | }
|
---|
789 | #endif
|
---|
790 | }
|
---|
791 |
|
---|
792 | /*
|
---|
793 | This driver may need to move the drawing operations to a different sub
|
---|
794 | window. This modifies the viewport command to add our X,Y offset to all
|
---|
795 | drawn objects that go through the viewport transformation.
|
---|
796 | */
|
---|
797 |
|
---|
798 | /************************************************************************/
|
---|
799 | /************************************************************************/
|
---|
800 | /************************************************************************/
|
---|
801 |
|
---|
802 | /* Check if the hardware supports the current context
|
---|
803 | *
|
---|
804 | * Performs similar work to fxDDChooseRenderState() - should be merged.
|
---|
805 | */
|
---|
806 | static GLboolean fxIsInHardware(GLcontext *ctx)
|
---|
807 | {
|
---|
808 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
809 |
|
---|
810 | if (!ctx->Hint.AllowDrawMem)
|
---|
811 | return GL_TRUE; /* you'll take it and like it */
|
---|
812 |
|
---|
813 | if((ctx->RasterMask & STENCIL_BIT) ||
|
---|
814 | ((ctx->Color.BlendEnabled) && (ctx->Color.BlendEquation!=GL_FUNC_ADD_EXT)) ||
|
---|
815 | ((ctx->Color.ColorLogicOpEnabled) && (ctx->Color.LogicOp!=GL_COPY)) ||
|
---|
816 | (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR) ||
|
---|
817 | (!((ctx->Color.ColorMask[RCOMP]==ctx->Color.ColorMask[GCOMP]) &&
|
---|
818 | (ctx->Color.ColorMask[GCOMP]==ctx->Color.ColorMask[BCOMP]) &&
|
---|
819 | (ctx->Color.ColorMask[ACOMP]==ctx->Color.ColorMask[ACOMP])))
|
---|
820 | )
|
---|
821 | {
|
---|
822 | return GL_FALSE;
|
---|
823 | }
|
---|
824 | /* Unsupported texture/multitexture cases */
|
---|
825 |
|
---|
826 | if(fxMesa->emulateTwoTMUs) {
|
---|
827 | if((ctx->Enabled & (TEXTURE0_3D | TEXTURE1_3D)) ||
|
---|
828 | /* Not very well written ... */
|
---|
829 | ((ctx->Enabled & (TEXTURE0_1D | TEXTURE1_1D)) &&
|
---|
830 | ((ctx->Enabled & (TEXTURE0_2D | TEXTURE1_2D))!=(TEXTURE0_2D | TEXTURE1_2D)))
|
---|
831 | ) {
|
---|
832 | return GL_FALSE;
|
---|
833 | }
|
---|
834 |
|
---|
835 | if((ctx->Texture.ReallyEnabled & TEXTURE0_2D) &&
|
---|
836 | (ctx->Texture.Unit[0].EnvMode==GL_BLEND)) {
|
---|
837 | return GL_FALSE;
|
---|
838 | }
|
---|
839 |
|
---|
840 | if((ctx->Texture.ReallyEnabled & TEXTURE1_2D) &&
|
---|
841 | (ctx->Texture.Unit[1].EnvMode==GL_BLEND)) {
|
---|
842 | return GL_FALSE;
|
---|
843 | }
|
---|
844 |
|
---|
845 |
|
---|
846 | if (MESA_VERBOSE & (VERBOSE_DRIVER|VERBOSE_TEXTURE))
|
---|
847 | fprintf(stderr, "fxMesa: fxIsInHardware, envmode is %s/%s\n",
|
---|
848 | gl_lookup_enum_by_nr(ctx->Texture.Unit[0].EnvMode),
|
---|
849 | gl_lookup_enum_by_nr(ctx->Texture.Unit[1].EnvMode));
|
---|
850 |
|
---|
851 | /* KW: This was wrong (I think) and I changed it... which doesn't mean
|
---|
852 | * it is now correct...
|
---|
853 | */
|
---|
854 | if((ctx->Enabled & (TEXTURE0_1D | TEXTURE0_2D | TEXTURE0_3D)) &&
|
---|
855 | (ctx->Enabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D)))
|
---|
856 | {
|
---|
857 | /* Can't use multipass to blend a multitextured triangle - fall
|
---|
858 | * back to software.
|
---|
859 | */
|
---|
860 | if (!fxMesa->haveTwoTMUs && ctx->Color.BlendEnabled) {
|
---|
861 | return GL_FALSE;
|
---|
862 | }
|
---|
863 |
|
---|
864 | if ((ctx->Texture.Unit[0].EnvMode!=ctx->Texture.Unit[1].EnvMode) &&
|
---|
865 | (ctx->Texture.Unit[0].EnvMode!=GL_MODULATE) &&
|
---|
866 | (ctx->Texture.Unit[0].EnvMode!=GL_REPLACE)) /* q2, seems ok... */
|
---|
867 | {
|
---|
868 | if (MESA_VERBOSE&VERBOSE_DRIVER)
|
---|
869 | fprintf(stderr, "fxMesa: unsupported multitex env mode\n");
|
---|
870 | return GL_FALSE;
|
---|
871 | }
|
---|
872 | }
|
---|
873 | } else {
|
---|
874 | if((ctx->Enabled & (TEXTURE1_1D | TEXTURE1_2D | TEXTURE1_3D)) ||
|
---|
875 | /* Not very well written ... */
|
---|
876 | ((ctx->Enabled & TEXTURE0_1D) &&
|
---|
877 | (!(ctx->Enabled & TEXTURE0_2D)))
|
---|
878 | ) {
|
---|
879 | return GL_FALSE;
|
---|
880 | }
|
---|
881 |
|
---|
882 |
|
---|
883 | if((ctx->Texture.ReallyEnabled & TEXTURE0_2D) &&
|
---|
884 | (ctx->Texture.Unit[0].EnvMode==GL_BLEND)) {
|
---|
885 | return GL_FALSE;
|
---|
886 | }
|
---|
887 | }
|
---|
888 |
|
---|
889 | return GL_TRUE;
|
---|
890 | }
|
---|
891 |
|
---|
892 |
|
---|
893 |
|
---|
894 | #define INTERESTED (~(NEW_MODELVIEW|NEW_PROJECTION|NEW_PROJECTION|NEW_TEXTURE_MATRIX|NEW_USER_CLIP|NEW_CLIENT_STATE|NEW_TEXTURE_ENABLE))
|
---|
895 |
|
---|
896 | static void fxDDUpdateDDPointers(GLcontext *ctx)
|
---|
897 | {
|
---|
898 | fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
|
---|
899 | GLuint new_state = ctx->NewState;
|
---|
900 |
|
---|
901 | if (MESA_VERBOSE&(VERBOSE_DRIVER|VERBOSE_STATE))
|
---|
902 | fprintf(stderr,"fxmesa: fxDDUpdateDDPointers(...)\n");
|
---|
903 |
|
---|
904 | if (new_state & (NEW_RASTER_OPS|NEW_TEXTURING))
|
---|
905 | fxMesa->is_in_hardware = fxIsInHardware(ctx);
|
---|
906 |
|
---|
907 | if (fxMesa->is_in_hardware) {
|
---|
908 | if (fxMesa->new_state)
|
---|
909 | fxSetupFXUnits(ctx);
|
---|
910 |
|
---|
911 | if(new_state & INTERESTED) {
|
---|
912 | fxDDChooseRenderState( ctx );
|
---|
913 | fxMesa->RenderVBTables=fxDDChooseRenderVBTables(ctx);
|
---|
914 | fxMesa->RenderVBClippedTab=fxMesa->RenderVBTables[0];
|
---|
915 | fxMesa->RenderVBCulledTab=fxMesa->RenderVBTables[1];
|
---|
916 | fxMesa->RenderVBRawTab=fxMesa->RenderVBTables[2];
|
---|
917 |
|
---|
918 | ctx->Driver.RasterSetup=fxDDChooseSetupFunction(ctx);
|
---|
919 | }
|
---|
920 |
|
---|
921 | ctx->Driver.PointsFunc=fxMesa->PointsFunc;
|
---|
922 | ctx->Driver.LineFunc=fxMesa->LineFunc;
|
---|
923 | ctx->Driver.TriangleFunc=fxMesa->TriangleFunc;
|
---|
924 | ctx->Driver.QuadFunc=fxMesa->QuadFunc;
|
---|
925 | } else {
|
---|
926 | fxMesa->render_index = FX_FALLBACK;
|
---|
927 | }
|
---|
928 | }
|
---|
929 |
|
---|
930 | static void fxDDReducedPrimitiveChange(GLcontext *ctx, GLenum prim)
|
---|
931 | {
|
---|
932 | if (ctx->Polygon.CullFlag) {
|
---|
933 | if (ctx->PB->primitive != GL_POLYGON) { /* Lines or Points */
|
---|
934 | FX_grCullMode(GR_CULL_DISABLE);
|
---|
935 | FX_CONTEXT(ctx)->cullMode=GR_CULL_DISABLE;
|
---|
936 | }
|
---|
937 | }
|
---|
938 | }
|
---|
939 |
|
---|
940 | void fxSetupDDPointers(GLcontext *ctx)
|
---|
941 | {
|
---|
942 | if (MESA_VERBOSE&VERBOSE_DRIVER) {
|
---|
943 | fprintf(stderr,"fxmesa: fxSetupDDPointers()\n");
|
---|
944 | }
|
---|
945 |
|
---|
946 | ctx->Driver.UpdateState=fxDDUpdateDDPointers;
|
---|
947 |
|
---|
948 | ctx->Driver.WriteDepthSpan=fxDDWriteDepthSpan;
|
---|
949 | ctx->Driver.WriteDepthPixels=fxDDWriteDepthPixels;
|
---|
950 | ctx->Driver.ReadDepthSpan=fxDDReadDepthSpan;
|
---|
951 | ctx->Driver.ReadDepthPixels=fxDDReadDepthPixels;
|
---|
952 |
|
---|
953 | ctx->Driver.GetString=fxDDGetString;
|
---|
954 |
|
---|
955 | ctx->Driver.Dither=fxDDDither;
|
---|
956 |
|
---|
957 | ctx->Driver.NearFar=fxDDSetNearFar;
|
---|
958 |
|
---|
959 | ctx->Driver.GetParameteri=fxDDGetParameteri;
|
---|
960 |
|
---|
961 | ctx->Driver.ClearIndex=NULL;
|
---|
962 | ctx->Driver.ClearColor=fxDDClearColor;
|
---|
963 | ctx->Driver.Clear=fxDDClear;
|
---|
964 |
|
---|
965 | ctx->Driver.Index=NULL;
|
---|
966 | ctx->Driver.Color=fxDDSetColor;
|
---|
967 |
|
---|
968 | ctx->Driver.SetDrawBuffer=fxDDSetDrawBuffer;
|
---|
969 | ctx->Driver.SetReadBuffer=fxDDSetReadBuffer;
|
---|
970 | ctx->Driver.GetBufferSize=fxDDBufferSize;
|
---|
971 |
|
---|
972 | ctx->Driver.Bitmap=fxDDDrawBitMap;
|
---|
973 | ctx->Driver.DrawPixels=NULL;
|
---|
974 |
|
---|
975 | ctx->Driver.Finish=fxDDFinish;
|
---|
976 | ctx->Driver.Flush=NULL;
|
---|
977 |
|
---|
978 | ctx->Driver.RenderStart=NULL;
|
---|
979 | ctx->Driver.RenderFinish=NULL;
|
---|
980 |
|
---|
981 | ctx->Driver.TexEnv=fxDDTexEnv;
|
---|
982 | ctx->Driver.TexImage=fxDDTexImg;
|
---|
983 | ctx->Driver.TexSubImage=fxDDTexSubImg;
|
---|
984 | ctx->Driver.TexParameter=fxDDTexParam;
|
---|
985 | ctx->Driver.BindTexture=fxDDTexBind;
|
---|
986 | ctx->Driver.DeleteTexture=fxDDTexDel;
|
---|
987 | ctx->Driver.UpdateTexturePalette=fxDDTexPalette;
|
---|
988 |
|
---|
989 | ctx->Driver.RectFunc=NULL;
|
---|
990 |
|
---|
991 | ctx->Driver.AlphaFunc=fxDDAlphaFunc;
|
---|
992 | ctx->Driver.BlendFunc=fxDDBlendFunc;
|
---|
993 | ctx->Driver.DepthFunc=fxDDDepthFunc;
|
---|
994 | ctx->Driver.DepthMask=fxDDDepthMask;
|
---|
995 | ctx->Driver.ColorMask=fxDDColorMask;
|
---|
996 | ctx->Driver.Fogfv=fxDDFogfv;
|
---|
997 | ctx->Driver.Scissor=fxDDScissor;
|
---|
998 | ctx->Driver.FrontFace=fxDDFrontFace;
|
---|
999 | ctx->Driver.CullFace=fxDDCullFace;
|
---|
1000 | ctx->Driver.ShadeModel=fxDDShadeModel;
|
---|
1001 | ctx->Driver.Enable=fxDDEnable;
|
---|
1002 | ctx->Driver.ReducedPrimitiveChange=fxDDReducedPrimitiveChange;
|
---|
1003 |
|
---|
1004 | ctx->Driver.RegisterVB=fxDDRegisterVB;
|
---|
1005 | ctx->Driver.UnregisterVB=fxDDUnregisterVB;
|
---|
1006 |
|
---|
1007 | ctx->Driver.RegisterPipelineStages = fxDDRegisterPipelineStages;
|
---|
1008 |
|
---|
1009 | ctx->Driver.OptimizeImmediatePipeline = 0; /* nothing done yet */
|
---|
1010 | ctx->Driver.OptimizePrecalcPipeline = 0;
|
---|
1011 |
|
---|
1012 | /* if (getenv("MESA_USE_FAST") || getenv("FX_USE_FAST")) */
|
---|
1013 | /* ctx->Driver.OptimizePrecalcPipeline = fxDDOptimizePrecalcPipeline; */
|
---|
1014 |
|
---|
1015 | if (!getenv("FX_NO_FAST"))
|
---|
1016 | ctx->Driver.BuildPrecalcPipeline = fxDDBuildPrecalcPipeline;
|
---|
1017 |
|
---|
1018 | ctx->Driver.TriangleCaps = DD_TRI_CULL|DD_TRI_OFFSET|DD_TRI_LIGHT_TWOSIDE;
|
---|
1019 |
|
---|
1020 | fxSetupDDSpanPointers(ctx);
|
---|
1021 |
|
---|
1022 | FX_CONTEXT(ctx)->render_index = 1; /* force an update */
|
---|
1023 | fxDDUpdateDDPointers(ctx);
|
---|
1024 | }
|
---|
1025 |
|
---|
1026 |
|
---|
1027 | #else
|
---|
1028 |
|
---|
1029 |
|
---|
1030 | /*
|
---|
1031 | * Need this to provide at least one external definition.
|
---|
1032 | */
|
---|
1033 |
|
---|
1034 | int gl_fx_dummy_function_dd(void)
|
---|
1035 | {
|
---|
1036 | return 0;
|
---|
1037 | }
|
---|
1038 |
|
---|
1039 | #endif /* FX */
|
---|
1040 |
|
---|