1 /* -*- mode: c; c-basic-offset: 3 -*-
3 * Copyright 2000 VA Linux Systems Inc., Fremont, California.
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
23 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26 /* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_span.c,v 1.7 2002/10/30 12:52:00 alanh Exp $ */
30 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
33 * Gareth Hughes <gareth@valinux.com>
34 * Brian Paul <brianp@valinux.com>
35 * Keith Whitwell <keith@tungstengraphics.com>
39 #include "tdfx_context.h"
40 #include "tdfx_lock.h"
41 #include "tdfx_span.h"
42 #include "tdfx_render.h"
43 #include "swrast/swrast.h"
50 __DRIdrawablePrivate *dPriv = fxMesa->driDrawable; \
51 tdfxScreenPrivate *fxPriv = fxMesa->fxScreen; \
52 GLuint pitch = (fxMesa->glCtx->Color.DrawBuffer[0] == GL_FRONT) \
53 ? (fxMesa->screen_width * BYTESPERPIXEL) : \
54 (info.strideInBytes); \
55 GLuint height = fxMesa->height; \
56 char *buf = (char *)((char *)info.lfbPtr + \
57 dPriv->x * fxPriv->cpp + \
63 #define CLIPPIXEL( _x, _y ) ( _x >= minx && _x < maxx && \
64 _y >= miny && _y < maxy )
66 #define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \
67 if ( _y < miny || _y >= maxy ) { \
72 if ( _x1 < minx ) _i += (minx-_x1), n1 -= (minx-_x1), _x1 = minx; \
73 if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \
76 #define Y_FLIP(_y) (height - _y - 1)
79 #define HW_WRITE_LOCK() \
80 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \
82 FLUSH_BATCH( fxMesa ); \
83 UNLOCK_HARDWARE( fxMesa ); \
84 LOCK_HARDWARE( fxMesa ); \
85 info.size = sizeof(GrLfbInfo_t); \
86 if ( fxMesa->Glide.grLfbLock( GR_LFB_WRITE_ONLY, \
87 fxMesa->DrawBuffer, LFB_MODE, \
88 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \
91 #define HW_WRITE_UNLOCK() \
92 fxMesa->Glide.grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer );\
96 #define HW_READ_LOCK() \
97 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \
99 FLUSH_BATCH( fxMesa ); \
100 UNLOCK_HARDWARE( fxMesa ); \
101 LOCK_HARDWARE( fxMesa ); \
102 info.size = sizeof(GrLfbInfo_t); \
103 if ( fxMesa->Glide.grLfbLock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer, \
104 LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \
107 #define HW_READ_UNLOCK() \
108 fxMesa->Glide.grLfbUnlock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer );\
112 #define HW_WRITE_CLIPLOOP() \
114 int _nc = fxMesa->numClipRects; \
116 int minx = fxMesa->pClipRects[_nc].x1 - fxMesa->x_offset; \
117 int miny = fxMesa->pClipRects[_nc].y1 - fxMesa->y_offset; \
118 int maxx = fxMesa->pClipRects[_nc].x2 - fxMesa->x_offset; \
119 int maxy = fxMesa->pClipRects[_nc].y2 - fxMesa->y_offset;
121 #define HW_READ_CLIPLOOP() \
123 const __DRIdrawablePrivate *dPriv = fxMesa->driDrawable; \
124 drm_clip_rect_t *rect = dPriv->pClipRects; \
125 int _nc = dPriv->numClipRects; \
127 const int minx = rect->x1 - fxMesa->x_offset; \
128 const int miny = rect->y1 - fxMesa->y_offset; \
129 const int maxx = rect->x2 - fxMesa->x_offset; \
130 const int maxy = rect->y2 - fxMesa->y_offset; \
133 #define HW_ENDCLIPLOOP() \
139 #define LFB_MODE GR_LFBWRITEMODE_565
142 /* 16 bit, RGB565 color spanline and pixel functions */ \
144 #undef INIT_MONO_PIXEL
145 #define INIT_MONO_PIXEL(p, color) \
146 p = TDFXPACKCOLOR565( color[0], color[1], color[2] )
149 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
150 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
151 (((int)g & 0xfc) << 3) | \
152 (((int)b & 0xf8) >> 3))
154 #define WRITE_PIXEL( _x, _y, p ) \
155 *(GLushort *)(buf + _x*2 + _y*pitch) = p
157 #define READ_RGBA( rgba, _x, _y ) \
159 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
160 rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
161 rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
162 rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
166 #define TAG(x) tdfx##x##_RGB565
167 #define BYTESPERPIXEL 2
172 /* 16 bit, BGR565 color spanline and pixel functions */ \
175 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
176 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)b & 0xf8) << 8) | \
177 (((int)g & 0xfc) << 3) | \
178 (((int)r & 0xf8) >> 3))
180 #define WRITE_PIXEL( _x, _y, p ) \
181 *(GLushort *)(buf + _x*2 + _y*pitch) = p
183 #define READ_RGBA( rgba, _x, _y ) \
185 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
186 rgba[0] = (p << 3) & 0xf8; \
187 rgba[1] = (p >> 3) & 0xfc; \
188 rgba[2] = (p >> 8) & 0xf8; \
192 #define TAG(x) tdfx##x##_BGR565
193 #define BYTESPERPIXEL 2
200 #define LFB_MODE GR_LFBWRITEMODE_888
203 /* 24 bit, RGB888 color spanline and pixel functions */
204 #undef INIT_MONO_PIXEL
205 #define INIT_MONO_PIXEL(p, color) \
206 p = TDFXPACKCOLOR888( color[0], color[1], color[2] )
208 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
209 *(GLuint *)(buf + _x*3 + _y*pitch) = ((b << 0) | \
213 #define WRITE_PIXEL( _x, _y, p ) \
214 *(GLuint *)(buf + _x*3 + _y*pitch) = p
216 #define READ_RGBA( rgba, _x, _y ) \
218 GLuint p = *(GLuint *)(buf + _x*3 + _y*pitch); \
219 rgba[0] = (p >> 16) & 0xff; \
220 rgba[1] = (p >> 8) & 0xff; \
221 rgba[2] = (p >> 0) & 0xff; \
225 #define TAG(x) tdfx##x##_RGB888
226 #define BYTESPERPIXEL 4
232 #define LFB_MODE GR_LFBWRITEMODE_8888
235 /* 32 bit, ARGB8888 color spanline and pixel functions */
236 #undef INIT_MONO_PIXEL
237 #define INIT_MONO_PIXEL(p, color) \
238 p = TDFXPACKCOLOR8888( color[0], color[1], color[2], color[3] )
240 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
241 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
246 #define WRITE_PIXEL( _x, _y, p ) \
247 *(GLuint *)(buf + _x*4 + _y*pitch) = p
249 #define READ_RGBA( rgba, _x, _y ) \
251 GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
252 rgba[0] = (p >> 16) & 0xff; \
253 rgba[1] = (p >> 8) & 0xff; \
254 rgba[2] = (p >> 0) & 0xff; \
255 rgba[3] = (p >> 24) & 0xff; \
258 #define TAG(x) tdfx##x##_ARGB8888
259 #define BYTESPERPIXEL 4
265 /* ================================================================
266 * Old span functions below...
271 * Examine the cliprects to generate an array of flags to indicate
272 * which pixels in a span are visible. Note: (x,y) is a screen
276 generate_vismask(const tdfxContextPtr fxMesa
, GLint x
, GLint y
, GLint n
,
279 GLboolean initialized
= GL_FALSE
;
282 /* Ensure we clear the visual mask */
283 MEMSET(vismask
, 0, n
);
285 /* turn on flags for all visible pixels */
286 for (i
= 0; i
< fxMesa
->numClipRects
; i
++) {
287 const drm_clip_rect_t
*rect
= &fxMesa
->pClipRects
[i
];
289 if (y
>= rect
->y1
&& y
< rect
->y2
) {
290 if (x
>= rect
->x1
&& x
+ n
<= rect
->x2
) {
291 /* common case, whole span inside cliprect */
292 MEMSET(vismask
, 1, n
);
295 if (x
< rect
->x2
&& x
+ n
>= rect
->x1
) {
296 /* some of the span is inside the rect */
299 MEMSET(vismask
, 0, n
);
300 initialized
= GL_TRUE
;
303 start
= rect
->x1
- x
;
306 if (x
+ n
> rect
->x2
)
312 for (j
= start
; j
< end
; j
++)
320 * Examine cliprects and determine if the given screen pixel is visible.
323 visible_pixel(const tdfxContextPtr fxMesa
, int scrX
, int scrY
)
326 for (i
= 0; i
< fxMesa
->numClipRects
; i
++) {
327 const drm_clip_rect_t
*rect
= &fxMesa
->pClipRects
[i
];
328 if (scrX
>= rect
->x1
&&
330 scrY
>= rect
->y1
&& scrY
< rect
->y2
) return GL_TRUE
;
338 * Depth buffer read/write functions.
341 * To read the frame buffer, we need to lock and unlock it. The
342 * four macros {READ,WRITE}_FB_SPAN_{LOCK,UNLOCK}
345 * Note that the lock must be matched with an unlock. These
346 * macros include a spare curly brace, so they must
347 * be syntactically matched.
349 * Note, also, that you can't lock a buffer twice with different
350 * modes. That is to say, you can't lock a buffer in both read
351 * and write modes. The strideInBytes and LFB pointer will be
352 * the same with read and write locks, so you can use either.
353 * o The HW has different state for reads and writes, so
354 * locking it twice may give screwy results.
355 * o The DRM won't let you lock twice. It hangs. This is probably
356 * because of the LOCK_HARDWARE IN THE *_FB_SPAN_LOCK macros,
357 * and could be eliminated with nonlocking lock routines. But
358 * what's the point after all.
360 #define READ_FB_SPAN_LOCK(fxMesa, info, target_buffer) \
361 UNLOCK_HARDWARE(fxMesa); \
362 LOCK_HARDWARE(fxMesa); \
363 (info).size=sizeof(info); \
364 if (fxMesa->Glide.grLfbLock(GR_LFB_READ_ONLY, \
366 GR_LFBWRITEMODE_ANY, \
367 GR_ORIGIN_UPPER_LEFT, \
371 #define READ_FB_SPAN_UNLOCK(fxMesa, target_buffer) \
372 fxMesa->Glide.grLfbUnlock(GR_LFB_READ_ONLY, target_buffer); \
374 fprintf(stderr, "tdfxDriver: Can't get %s (%d) read lock\n", \
375 (target_buffer == GR_BUFFER_BACKBUFFER) \
377 : ((target_buffer == GR_BUFFER_AUXBUFFER) \
379 : "unknown buffer"), \
383 #define WRITE_FB_SPAN_LOCK(fxMesa, info, target_buffer, write_mode) \
384 UNLOCK_HARDWARE(fxMesa); \
385 LOCK_HARDWARE(fxMesa); \
386 info.size=sizeof(info); \
387 if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, \
390 GR_ORIGIN_UPPER_LEFT, \
394 #define WRITE_FB_SPAN_UNLOCK(fxMesa, target_buffer) \
395 fxMesa->Glide.grLfbUnlock(GR_LFB_WRITE_ONLY, target_buffer); \
397 fprintf(stderr, "tdfxDriver: Can't get %s (%d) write lock\n", \
398 (target_buffer == GR_BUFFER_BACKBUFFER) \
400 : ((target_buffer == GR_BUFFER_AUXBUFFER) \
402 : "unknown buffer"), \
407 * Because the Linear Frame Buffer is not necessarily aligned
408 * with the depth buffer, we have to do some fiddling
409 * around to get the right addresses.
411 * Perhaps a picture is in order. The Linear Frame Buffer
414 * |<----------------------info.strideInBytes------------->|
415 * |<-----physicalStrideInBytes------->|
416 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
418 * | Legal Memory | Forbidden Zone |
420 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
422 * You can only reliably read and write legal locations. Reads
423 * and writes from the Forbidden Zone will return undefined values,
424 * and may cause segmentation faults.
426 * Now, the depth buffer may not end up in a location such each
427 * scan line is an LFB line. For example, the depth buffer may
431 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
432 * |0000000000000000000000 | | back
433 * |1111111111111111111111 | | buffer
434 * |2222222222222222222222 | |
435 * |4096b align. padxx00000000000000000| Forbidden Zone | depth
436 * |0000 11111111111111111| | buffer
437 * |1111 22222222222222222| |
439 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
440 * where each number is the scan line number. We know it will
441 * be aligned on 128 byte boundaries, at least. Aligning this
442 * on a scanline boundary causes the back and depth buffers to
443 * thrash in the SST1 cache. (Note that the back buffer is always
444 * allocated at the beginning of LFB memory, and so it is always
445 * properly aligned with the LFB stride.)
447 * We call the beginning of the line (which is the rightmost
448 * part of the depth line in the picture above) the *ordinary* part
449 * of the scanline, and the end of the line (which is the
450 * leftmost part, one line below) the *wrapped* part of the scanline.
451 * a.) We need to know what x value to subtract from the screen
452 * x coordinate to index into the wrapped part.
453 * b.) We also need to figure out if we need to read from the ordinary
454 * part scan line, or from the wrapped part of the scan line.
457 * The first wrapped x coordinate is that coordinate such that
458 * depthBufferOffset&(info.strideInBytes) + x*elmentSize {*}
459 * > physicalStrideInBytes
460 * where depthBufferOffset is the LFB distance in bytes
461 * from the back buffer to the depth buffer. The expression
462 * depthBufferOffset&(info.strideInBytes)
463 * is then the offset (in bytes) from the beginining of (any)
464 * depth buffer line to first element in the line.
465 * Simplifying inequation {*} above we see that x is the smallest
467 * x*elementSize > physicalStrideInBytes {**}
468 * - depthBufferOffset&(info.strideInBytes)
469 * Now, we know that both the summands on the right are multiples of
470 * 128, and elementSize <= 4, so if equality holds in {**}, x would
471 * be a multiple of 32. Thus we can set x to
472 * xwrapped = (physicalStrideInBytes
473 * - depthBufferOffset&(info.strideInBytes))/elementSize
477 * Question b is now simple. We read from the wrapped scan line if
478 * x is greater than xwrapped.
480 #define TILE_WIDTH_IN_BYTES 128
481 #define TILE_WIDTH_IN_ZOXELS(bpz) (TILE_WIDTH_IN_BYTES/(bpz))
482 #define TILE_HEIGHT_IN_LINES 32
487 FxU32 LFBStrideInElts
;
493 * We need information about the back buffer. Note that
494 * this function *cannot be called* while the aux buffer
495 * is locked, or the caller will hang.
497 * Only Glide knows the LFB address of the back and depth
498 * offsets. The upper levels of Mesa know the depth offset,
499 * but that is not in LFB space, it is tiled memory space,
500 * and is not useable for us.
503 GetBackBufferInfo(tdfxContextPtr fxMesa
, GrLfbInfo_t
* backBufferInfo
)
505 READ_FB_SPAN_LOCK(fxMesa
, *backBufferInfo
, GR_BUFFER_BACKBUFFER
);
506 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_BACKBUFFER
);
510 GetFbParams(tdfxContextPtr fxMesa
,
512 GrLfbInfo_t
* backBufferInfo
,
513 LFBParameters
* ReadParamsp
, FxU32 elementSize
)
515 FxU32 physicalStrideInBytes
, bufferOffset
;
516 FxU32 strideInBytes
= info
->strideInBytes
;
517 char *lfbPtr
= (char *) (info
->lfbPtr
); /* For arithmetic, use char * */
520 * These two come directly from the info structure.
522 ReadParamsp
->lfbPtr
= (void *) lfbPtr
;
523 ReadParamsp
->LFBStrideInElts
= strideInBytes
/ elementSize
;
525 * Now, calculate the value of firstWrappedX.
527 * The physical stride is the screen width in bytes rounded up to
528 * the next highest multiple of 128 bytes. Note that this fails
529 * when TILE_WIDTH_IN_BYTES is not a power of two.
531 * The buffer Offset is the distance between the beginning of
532 * the LFB space, which is the beginning of the back buffer,
533 * and the buffer we are gathering information about.
534 * We want to make this routine usable for operations on the
535 * back buffer, though we don't actually use it on the back
536 * buffer. Note, then, that if bufferOffset == 0, the firstWrappedX
537 * is in the forbidden zone, and is therefore never reached.
540 * physicalStrideInBytes
541 * < bufferOffset&(info->strideInBytes-1)
542 * the buffer begins in the forbidden zone. We assert for this.
544 bufferOffset
= (FxU32
)(lfbPtr
- (char *) backBufferInfo
->lfbPtr
);
545 physicalStrideInBytes
546 = (fxMesa
->screen_width
* elementSize
+ TILE_WIDTH_IN_BYTES
- 1)
547 & ~(TILE_WIDTH_IN_BYTES
- 1);
548 assert(physicalStrideInBytes
> (bufferOffset
& (strideInBytes
- 1)));
549 ReadParamsp
->firstWrappedX
550 = (physicalStrideInBytes
551 - (bufferOffset
& (strideInBytes
- 1))) / elementSize
;
553 * This is the address of the next physical line.
555 ReadParamsp
->lfbWrapPtr
556 = (void *) ((char *) backBufferInfo
->lfbPtr
557 + (bufferOffset
& ~(strideInBytes
- 1))
558 + (TILE_HEIGHT_IN_LINES
) * strideInBytes
);
562 * These macros fetch data from the frame buffer. The type is
563 * the type of data we want to fetch. It should match the type
564 * whose size was used with GetFbParams to fill in the structure
565 * in *ReadParamsp. We have a macro to read the ordinary
566 * part, a second macro to read the wrapped part, and one which
567 * will do either. When we are reading a span, we will know
568 * when the ordinary part ends, so there's no need to test for
569 * it. However, when reading and writing pixels, we don't
570 * necessarily know. I suppose it's a matter of taste whether
571 * it's better in the macro or in the call.
573 * Recall that x and y are screen coordinates.
575 #define GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \
576 (((type *)((ReadParamsp)->lfbPtr)) \
577 [(y) * ((ReadParamsp)->LFBStrideInElts) \
579 #define GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) \
580 (((type *)((ReadParamsp)->lfbWrapPtr)) \
581 [((y)) * ((ReadParamsp)->LFBStrideInElts) \
582 + ((x) - (ReadParamsp)->firstWrappedX)])
583 #define GET_FB_DATA(ReadParamsp, type, x, y) \
584 (((x) < (ReadParamsp)->firstWrappedX) \
585 ? GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \
586 : GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y))
587 #define PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value) \
588 (GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) = (type)(value))
589 #define PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value) \
590 (GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) = (type)(value))
591 #define PUT_FB_DATA(ReadParamsp, type, x, y, value) \
593 if ((x) < (ReadParamsp)->firstWrappedX) \
594 PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value); \
596 PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value); \
601 tdfxDDWriteDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
602 GLuint n
, GLint x
, GLint y
, const void *values
,
603 const GLubyte mask
[])
605 const GLuint
*depth
= (const GLuint
*) values
;
606 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
607 GLint bottom
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
608 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
609 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
611 GLubyte visMask
[MAX_WIDTH
];
613 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
614 fprintf(stderr
, "tdfxmesa: tdfxDDWriteDepthSpan(...)\n");
617 assert((depth_size
== 16) || (depth_size
== 24) || (depth_size
== 32));
619 * Convert x and y to screen coordinates.
621 x
+= fxMesa
->x_offset
;
626 GrLfbInfo_t backBufferInfo
;
628 switch (depth_size
) {
630 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
632 * Note that the _LOCK macro adds a curly brace,
633 * and the UNLOCK macro removes it.
635 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
,
636 GR_LFBWRITEMODE_ANY
);
637 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
639 LFBParameters ReadParams
;
640 int wrappedPartStart
;
641 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
642 &ReadParams
, sizeof(GLushort
));
643 if (ReadParams
.firstWrappedX
<= x
) {
644 wrappedPartStart
= 0;
646 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
647 wrappedPartStart
= n
;
650 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
652 for (i
= 0; i
< wrappedPartStart
; i
++) {
653 if (mask
[i
] && visMask
[i
]) {
655 PUT_ORDINARY_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
, d16
);
659 if (mask
[i
] && visMask
[i
]) {
661 PUT_WRAPPED_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
, d16
);
665 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
669 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
671 * Note that the _LOCK macro adds a curly brace,
672 * and the UNLOCK macro removes it.
674 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
,
675 GR_LFBWRITEMODE_ANY
);
676 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
678 LFBParameters ReadParams
;
679 int wrappedPartStart
;
680 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
681 &ReadParams
, sizeof(GLuint
));
682 if (ReadParams
.firstWrappedX
<= x
) {
683 wrappedPartStart
= 0;
685 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
686 wrappedPartStart
= n
;
689 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
691 for (i
= 0; i
< wrappedPartStart
; i
++) {
693 if (mask
[i
] && visMask
[i
]) {
694 if (stencil_size
> 0) {
696 GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
699 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
704 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
709 if (mask
[i
] && visMask
[i
]) {
710 if (stencil_size
> 0) {
712 GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
715 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
720 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
724 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
732 GrLfbInfo_t backBufferInfo
;
734 switch (depth_size
) {
736 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
738 * Note that the _LOCK macro adds a curly brace,
739 * and the UNLOCK macro removes it.
741 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
742 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
743 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
745 LFBParameters ReadParams
;
746 GLuint wrappedPartStart
;
747 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
748 &ReadParams
, sizeof(GLushort
));
749 if (ReadParams
.firstWrappedX
<= x
) {
750 wrappedPartStart
= 0;
752 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
753 wrappedPartStart
= n
;
756 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
758 for (i
= 0; i
< wrappedPartStart
; i
++) {
761 PUT_ORDINARY_FB_DATA(&ReadParams
,
770 PUT_WRAPPED_FB_DATA(&ReadParams
,
777 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
781 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
783 * Note that the _LOCK macro adds a curly brace,
784 * and the UNLOCK macro removes it.
786 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
787 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
788 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
790 LFBParameters ReadParams
;
791 GLuint wrappedPartStart
;
793 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
794 &ReadParams
, sizeof(GLuint
));
795 if (ReadParams
.firstWrappedX
<= x
) {
796 wrappedPartStart
= 0;
798 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
799 wrappedPartStart
= n
;
802 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
804 for (i
= 0; i
< wrappedPartStart
; i
++) {
806 if (stencil_size
> 0) {
807 d32
= GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
809 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
814 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
819 if (stencil_size
> 0) {
820 d32
= GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
822 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
827 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
831 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
838 tdfxDDWriteMonoDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
839 GLuint n
, GLint x
, GLint y
, const void *value
,
840 const GLubyte mask
[])
842 GLuint depthVal
= *((GLuint
*) value
);
843 GLuint depths
[MAX_WIDTH
];
845 for (i
= 0; i
< n
; i
++)
846 depths
[i
] = depthVal
;
847 tdfxDDWriteDepthSpan(ctx
, rb
, n
, x
, y
, depths
, mask
);
852 tdfxDDReadDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
853 GLuint n
, GLint x
, GLint y
, void *values
)
855 GLuint
*depth
= (GLuint
*) values
;
856 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
857 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
859 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
862 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
863 fprintf(stderr
, "tdfxmesa: tdfxDDReadDepthSpan(...)\n");
867 * Convert to screen coordinates.
869 x
+= fxMesa
->x_offset
;
871 switch (depth_size
) {
874 LFBParameters ReadParams
;
875 GrLfbInfo_t backBufferInfo
;
876 int wrappedPartStart
;
877 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
879 * Note that the _LOCK macro adds a curly brace,
880 * and the UNLOCK macro removes it.
882 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
883 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
884 &ReadParams
, sizeof(GLushort
));
885 if (ReadParams
.firstWrappedX
<= x
) {
886 wrappedPartStart
= 0;
888 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
889 wrappedPartStart
= n
;
892 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
897 for (i
= 0; i
< wrappedPartStart
; i
++) {
899 GET_ORDINARY_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
);
902 depth
[i
] = GET_WRAPPED_FB_DATA(&ReadParams
, GLushort
,
905 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
911 LFBParameters ReadParams
;
912 GrLfbInfo_t backBufferInfo
;
913 int wrappedPartStart
;
914 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
915 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
917 * Note that the _LOCK macro adds a curly brace,
918 * and the UNLOCK macro removes it.
920 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
921 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
922 &ReadParams
, sizeof(GLuint
));
923 if (ReadParams
.firstWrappedX
<= x
) {
924 wrappedPartStart
= 0;
926 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
927 wrappedPartStart
= n
;
930 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
935 for (i
= 0; i
< wrappedPartStart
; i
++) {
937 (stencil_size
> 0) ? 0x00FFFFFF : 0xFFFFFFFF;
939 GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
944 (stencil_size
> 0) ? 0x00FFFFFF : 0xFFFFFFFF;
945 depth
[i
] = GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
948 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
956 tdfxDDWriteDepthPixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
957 GLuint n
, const GLint x
[], const GLint y
[],
958 const void *values
, const GLubyte mask
[])
960 const GLuint
*depth
= (const GLuint
*) values
;
961 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
962 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
966 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
967 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
971 GrLfbInfo_t backBufferInfo
;
973 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
974 fprintf(stderr
, "tdfxmesa: tdfxDDWriteDepthPixels(...)\n");
977 switch (depth_size
) {
979 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
981 * Note that the _LOCK macro adds a curly brace,
982 * and the UNLOCK macro removes it.
984 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
985 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
987 LFBParameters ReadParams
;
988 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
989 &ReadParams
, sizeof(GLushort
));
990 for (i
= 0; i
< n
; i
++) {
991 if (mask
[i
] && visible_pixel(fxMesa
, x
[i
], y
[i
])) {
992 xpos
= x
[i
] + fxMesa
->x_offset
;
993 ypos
= bottom
- y
[i
];
995 PUT_FB_DATA(&ReadParams
, GLushort
, xpos
, ypos
, d16
);
999 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1003 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1005 * Note that the _LOCK macro adds a curly brace,
1006 * and the UNLOCK macro removes it.
1008 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
1009 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1011 LFBParameters ReadParams
;
1012 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1013 &ReadParams
, sizeof(GLuint
));
1014 for (i
= 0; i
< n
; i
++) {
1016 if (visible_pixel(fxMesa
, x
[i
], y
[i
])) {
1017 xpos
= x
[i
] + fxMesa
->x_offset
;
1018 ypos
= bottom
- y
[i
];
1019 if (stencil_size
> 0) {
1021 GET_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
);
1022 d32
= (d32
& 0xFF000000) | (depth
[i
] & 0xFFFFFF);
1027 PUT_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
, d32
);
1032 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1039 tdfxDDReadDepthPixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
, GLuint n
,
1040 const GLint x
[], const GLint y
[], void *values
)
1042 GLuint
*depth
= (GLuint
*) values
;
1043 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
1044 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
1046 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
1051 GLuint stencil_size
;
1052 GrLfbInfo_t backBufferInfo
;
1054 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
1055 fprintf(stderr
, "tdfxmesa: tdfxDDReadDepthPixels(...)\n");
1058 assert((depth_size
== 16) || (depth_size
== 24) || (depth_size
== 32));
1059 switch (depth_size
) {
1061 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1063 * Note that the _LOCK macro adds a curly brace,
1064 * and the UNLOCK macro removes it.
1066 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1068 LFBParameters ReadParams
;
1069 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1070 &ReadParams
, sizeof(GLushort
));
1071 for (i
= 0; i
< n
; i
++) {
1073 * Convert to screen coordinates.
1075 xpos
= x
[i
] + fxMesa
->x_offset
;
1076 ypos
= bottom
- y
[i
];
1077 d16
= GET_FB_DATA(&ReadParams
, GLushort
, xpos
, ypos
);
1081 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1085 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1087 * Note that the _LOCK macro adds a curly brace,
1088 * and the UNLOCK macro removes it.
1090 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1091 stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
1093 LFBParameters ReadParams
;
1094 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1095 &ReadParams
, sizeof(GLuint
));
1096 for (i
= 0; i
< n
; i
++) {
1100 * Convert to screen coordinates.
1102 xpos
= x
[i
] + fxMesa
->x_offset
;
1103 ypos
= bottom
- y
[i
];
1104 d32
= GET_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
);
1105 if (stencil_size
> 0) {
1111 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1119 * Stencil buffer read/write functions.
1121 #define EXTRACT_S_FROM_ZS(zs) (((zs) >> 24) & 0xFF)
1122 #define EXTRACT_Z_FROM_ZS(zs) ((zs) & 0xffffff)
1123 #define BUILD_ZS(z, s) (((s) << 24) | (z))
1126 write_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1127 GLuint n
, GLint x
, GLint y
,
1128 const void *values
, const GLubyte mask
[])
1130 const GLubyte
*stencil
= (const GLubyte
*) values
;
1131 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1133 GrLfbInfo_t backBufferInfo
;
1135 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1137 * Note that the _LOCK macro adds a curly brace,
1138 * and the UNLOCK macro removes it.
1140 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1142 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1143 const GLint winX
= fxMesa
->x_offset
;
1144 const GLint scrX
= winX
+ x
;
1145 const GLint scrY
= winY
- y
;
1146 LFBParameters ReadParams
;
1147 GLubyte visMask
[MAX_WIDTH
];
1149 int wrappedPartStart
;
1151 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1153 if (ReadParams
.firstWrappedX
<= x
) {
1154 wrappedPartStart
= 0;
1156 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
1157 wrappedPartStart
= n
;
1160 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
1162 generate_vismask(fxMesa
, scrX
, scrY
, n
, visMask
);
1163 for (i
= 0; i
< wrappedPartStart
; i
++) {
1164 if (visMask
[i
] && (!mask
|| mask
[i
])) {
1165 GLuint z
= GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
1166 scrX
+ i
, scrY
) & 0x00FFFFFF;
1167 z
|= (stencil
[i
] & 0xFF) << 24;
1168 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, scrX
+ i
, scrY
, z
);
1171 for (; i
< n
; i
++) {
1172 if (visMask
[i
] && (!mask
|| mask
[i
])) {
1173 GLuint z
= GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
1174 scrX
+ i
, scrY
) & 0x00FFFFFF;
1175 z
|= (stencil
[i
] & 0xFF) << 24;
1176 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, scrX
+ i
, scrY
, z
);
1180 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1185 write_mono_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1186 GLuint n
, GLint x
, GLint y
,
1187 const void *value
, const GLubyte mask
[])
1189 GLbyte stencilVal
= *((GLbyte
*) value
);
1190 GLbyte stencils
[MAX_WIDTH
];
1192 for (i
= 0; i
< n
; i
++)
1193 stencils
[i
] = stencilVal
;
1194 write_stencil_span(ctx
, rb
, n
, x
, y
, stencils
, mask
);
1199 read_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1200 GLuint n
, GLint x
, GLint y
,
1203 GLubyte
*stencil
= (GLubyte
*) values
;
1204 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1206 GrLfbInfo_t backBufferInfo
;
1208 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1210 * Note that the _LOCK macro adds a curly brace,
1211 * and the UNLOCK macro removes it.
1213 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1215 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1216 const GLint winX
= fxMesa
->x_offset
;
1218 LFBParameters ReadParams
;
1219 int wrappedPartStart
;
1222 * Convert to screen coordinates.
1226 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1228 if (ReadParams
.firstWrappedX
<= x
) {
1229 wrappedPartStart
= 0;
1231 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
1232 wrappedPartStart
= n
;
1235 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
1237 for (i
= 0; i
< wrappedPartStart
; i
++) {
1238 stencil
[i
] = (GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
1239 x
+ i
, y
) >> 24) & 0xFF;
1241 for (; i
< n
; i
++) {
1242 stencil
[i
] = (GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
1243 x
+ i
, y
) >> 24) & 0xFF;
1246 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1251 write_stencil_pixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1252 GLuint n
, const GLint x
[], const GLint y
[],
1253 const void *values
, const GLubyte mask
[])
1255 const GLubyte
*stencil
= (const GLubyte
*) values
;
1256 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1258 GrLfbInfo_t backBufferInfo
;
1260 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1262 * Note that the _LOCK macro adds a curly brace,
1263 * and the UNLOCK macro removes it.
1265 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1267 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1268 const GLint winX
= fxMesa
->x_offset
;
1269 LFBParameters ReadParams
;
1272 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1274 for (i
= 0; i
< n
; i
++) {
1275 const GLint scrX
= winX
+ x
[i
];
1276 const GLint scrY
= winY
- y
[i
];
1277 if ((!mask
|| mask
[i
]) && visible_pixel(fxMesa
, scrX
, scrY
)) {
1279 GET_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
) & 0x00FFFFFF;
1280 z
|= (stencil
[i
] & 0xFF) << 24;
1281 PUT_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
, z
);
1285 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1290 read_stencil_pixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1291 GLuint n
, const GLint x
[], const GLint y
[],
1294 GLubyte
*stencil
= (GLubyte
*) values
;
1295 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1297 GrLfbInfo_t backBufferInfo
;
1299 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1301 * Note that the _LOCK macro adds a curly brace,
1302 * and the UNLOCK macro removes it.
1304 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1306 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1307 const GLint winX
= fxMesa
->x_offset
;
1309 LFBParameters ReadParams
;
1311 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1313 for (i
= 0; i
< n
; i
++) {
1314 const GLint scrX
= winX
+ x
[i
];
1315 const GLint scrY
= winY
- y
[i
];
1317 (GET_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
) >> 24) & 0xFF;
1320 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1323 #define VISUAL_EQUALS_RGBA(vis, r, g, b, a) \
1324 ((vis.redBits == r) && \
1325 (vis.greenBits == g) && \
1326 (vis.blueBits == b) && \
1327 (vis.alphaBits == a))
1332 /**********************************************************************/
1333 /* Locking for swrast */
1334 /**********************************************************************/
1337 static void tdfxSpanRenderStart( GLcontext
*ctx
)
1339 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1340 LOCK_HARDWARE(fxMesa
);
1343 static void tdfxSpanRenderFinish( GLcontext
*ctx
)
1345 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1346 _swrast_flush( ctx
);
1347 UNLOCK_HARDWARE(fxMesa
);
1350 /* Set the buffer used for reading */
1351 static void tdfxDDSetBuffer( GLcontext
*ctx
,
1352 GLframebuffer
*buffer
, GLuint bufferBit
)
1354 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1357 switch ( bufferBit
) {
1358 case BUFFER_BIT_FRONT_LEFT
:
1359 fxMesa
->DrawBuffer
= fxMesa
->ReadBuffer
= GR_BUFFER_FRONTBUFFER
;
1361 case BUFFER_BIT_BACK_LEFT
:
1362 fxMesa
->DrawBuffer
= fxMesa
->ReadBuffer
= GR_BUFFER_BACKBUFFER
;
1369 /**********************************************************************/
1370 /* Initialize swrast device driver */
1371 /**********************************************************************/
1373 void tdfxDDInitSpanFuncs( GLcontext
*ctx
)
1375 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1376 swdd
->SetBuffer
= tdfxDDSetBuffer
;
1377 swdd
->SpanRenderStart
= tdfxSpanRenderStart
;
1378 swdd
->SpanRenderFinish
= tdfxSpanRenderFinish
;
1384 * Plug in the Get/Put routines for the given driRenderbuffer.
1387 tdfxSetSpanFunctions(driRenderbuffer
*drb
, const GLvisual
*vis
)
1389 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
1390 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
1391 drb
->Base
.GetRow
= tdfxReadRGBASpan_RGB565
;
1392 drb
->Base
.GetValues
= tdfxReadRGBAPixels_RGB565
;
1393 drb
->Base
.PutRow
= tdfxWriteRGBASpan_RGB565
;
1394 drb
->Base
.PutRowRGB
= tdfxWriteRGBSpan_RGB565
;
1395 drb
->Base
.PutMonoRow
= tdfxWriteMonoRGBASpan_RGB565
;
1396 drb
->Base
.PutValues
= tdfxWriteRGBAPixels_RGB565
;
1397 drb
->Base
.PutMonoValues
= tdfxWriteMonoRGBAPixels_RGB565
;
1399 else if (vis
->redBits
== 8 && vis
->greenBits
== 8
1400 && vis
->blueBits
== 8 && vis
->alphaBits
== 0) {
1401 drb
->Base
.GetRow
= tdfxReadRGBASpan_RGB888
;
1402 drb
->Base
.GetValues
= tdfxReadRGBAPixels_RGB888
;
1403 drb
->Base
.PutRow
= tdfxWriteRGBASpan_RGB888
;
1404 drb
->Base
.PutRowRGB
= tdfxWriteRGBSpan_RGB888
;
1405 drb
->Base
.PutMonoRow
= tdfxWriteMonoRGBASpan_RGB888
;
1406 drb
->Base
.PutValues
= tdfxWriteRGBAPixels_RGB888
;
1407 drb
->Base
.PutMonoValues
= tdfxWriteMonoRGBAPixels_RGB888
;
1409 else if (vis
->redBits
== 8 && vis
->greenBits
== 8
1410 && vis
->blueBits
== 8 && vis
->alphaBits
== 8) {
1411 drb
->Base
.GetRow
= tdfxReadRGBASpan_ARGB8888
;
1412 drb
->Base
.GetValues
= tdfxReadRGBAPixels_ARGB8888
;
1413 drb
->Base
.PutRow
= tdfxWriteRGBASpan_ARGB8888
;
1414 drb
->Base
.PutRowRGB
= tdfxWriteRGBSpan_ARGB8888
;
1415 drb
->Base
.PutMonoRow
= tdfxWriteMonoRGBASpan_ARGB8888
;
1416 drb
->Base
.PutValues
= tdfxWriteRGBAPixels_ARGB8888
;
1417 drb
->Base
.PutMonoValues
= tdfxWriteMonoRGBAPixels_ARGB8888
;
1420 _mesa_problem(NULL
, "problem in tdfxSetSpanFunctions");
1423 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
||
1424 drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
1425 drb
->Base
.GetRow
= tdfxDDReadDepthSpan
;
1426 drb
->Base
.GetValues
= tdfxDDReadDepthPixels
;
1427 drb
->Base
.PutRow
= tdfxDDWriteDepthSpan
;
1428 drb
->Base
.PutMonoRow
= tdfxDDWriteMonoDepthSpan
;
1429 drb
->Base
.PutValues
= tdfxDDWriteDepthPixels
;
1430 drb
->Base
.PutMonoValues
= NULL
;
1432 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
1433 drb
->Base
.GetRow
= read_stencil_span
;
1434 drb
->Base
.GetValues
= read_stencil_pixels
;
1435 drb
->Base
.PutRow
= write_stencil_span
;
1436 drb
->Base
.PutMonoRow
= write_mono_stencil_span
;
1437 drb
->Base
.PutValues
= write_stencil_pixels
;
1438 drb
->Base
.PutMonoValues
= NULL
;