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 driRenderbuffer *drb = (driRenderbuffer *) rb; \
51 __DRIdrawablePrivate *const dPriv = drb->dPriv; \
52 GLuint pitch = drb->backBuffer ? info.strideInBytes \
53 : (drb->pitch * drb->cpp); \
54 const GLuint bottom = dPriv->h - 1; \
55 char *buf = (char *)((char *)info.lfbPtr + \
56 (dPriv->x * drb->cpp) + \
57 (dPriv->y * pitch)); \
62 #define Y_FLIP(_y) (bottom - _y)
65 #define HW_WRITE_LOCK() \
66 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \
68 FLUSH_BATCH( fxMesa ); \
69 UNLOCK_HARDWARE( fxMesa ); \
70 LOCK_HARDWARE( fxMesa ); \
71 info.size = sizeof(GrLfbInfo_t); \
72 if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer, \
73 LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, \
76 #define HW_WRITE_UNLOCK() \
77 fxMesa->Glide.grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer );\
81 #define HW_READ_LOCK() \
82 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \
84 FLUSH_BATCH( fxMesa ); \
85 UNLOCK_HARDWARE( fxMesa ); \
86 LOCK_HARDWARE( fxMesa ); \
87 info.size = sizeof(GrLfbInfo_t); \
88 if ( fxMesa->Glide.grLfbLock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer, \
89 LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \
92 #define HW_READ_UNLOCK() \
93 fxMesa->Glide.grLfbUnlock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer );\
97 #define HW_WRITE_CLIPLOOP() \
99 int _nc = fxMesa->numClipRects; \
101 int minx = fxMesa->pClipRects[_nc].x1 - fxMesa->x_offset; \
102 int miny = fxMesa->pClipRects[_nc].y1 - fxMesa->y_offset; \
103 int maxx = fxMesa->pClipRects[_nc].x2 - fxMesa->x_offset; \
104 int maxy = fxMesa->pClipRects[_nc].y2 - fxMesa->y_offset;
106 #define HW_READ_CLIPLOOP() \
108 const __DRIdrawablePrivate *dPriv = fxMesa->driDrawable; \
109 drm_clip_rect_t *rect = dPriv->pClipRects; \
110 int _nc = dPriv->numClipRects; \
112 const int minx = rect->x1 - fxMesa->x_offset; \
113 const int miny = rect->y1 - fxMesa->y_offset; \
114 const int maxx = rect->x2 - fxMesa->x_offset; \
115 const int maxy = rect->y2 - fxMesa->y_offset; \
118 #define HW_ENDCLIPLOOP() \
124 #define LFB_MODE GR_LFBWRITEMODE_565
127 /* 16 bit, RGB565 color spanline and pixel functions */ \
129 #undef INIT_MONO_PIXEL
130 #define INIT_MONO_PIXEL(p, color) \
131 p = TDFXPACKCOLOR565( color[0], color[1], color[2] )
134 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
135 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
136 (((int)g & 0xfc) << 3) | \
137 (((int)b & 0xf8) >> 3))
139 #define WRITE_PIXEL( _x, _y, p ) \
140 *(GLushort *)(buf + _x*2 + _y*pitch) = p
142 #define READ_RGBA( rgba, _x, _y ) \
144 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
145 rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
146 rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
147 rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
151 #define TAG(x) tdfx##x##_RGB565
152 #define BYTESPERPIXEL 2
157 /* 16 bit, BGR565 color spanline and pixel functions */ \
160 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
161 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)b & 0xf8) << 8) | \
162 (((int)g & 0xfc) << 3) | \
163 (((int)r & 0xf8) >> 3))
165 #define WRITE_PIXEL( _x, _y, p ) \
166 *(GLushort *)(buf + _x*2 + _y*pitch) = p
168 #define READ_RGBA( rgba, _x, _y ) \
170 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
171 rgba[0] = (p << 3) & 0xf8; \
172 rgba[1] = (p >> 3) & 0xfc; \
173 rgba[2] = (p >> 8) & 0xf8; \
177 #define TAG(x) tdfx##x##_BGR565
178 #define BYTESPERPIXEL 2
185 #define LFB_MODE GR_LFBWRITEMODE_888
188 /* 24 bit, RGB888 color spanline and pixel functions */
189 #undef INIT_MONO_PIXEL
190 #define INIT_MONO_PIXEL(p, color) \
191 p = TDFXPACKCOLOR888( color[0], color[1], color[2] )
193 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
194 *(GLuint *)(buf + _x*3 + _y*pitch) = ((b << 0) | \
198 #define WRITE_PIXEL( _x, _y, p ) \
199 *(GLuint *)(buf + _x*3 + _y*pitch) = p
201 #define READ_RGBA( rgba, _x, _y ) \
203 GLuint p = *(GLuint *)(buf + _x*3 + _y*pitch); \
204 rgba[0] = (p >> 16) & 0xff; \
205 rgba[1] = (p >> 8) & 0xff; \
206 rgba[2] = (p >> 0) & 0xff; \
210 #define TAG(x) tdfx##x##_RGB888
211 #define BYTESPERPIXEL 4
217 #define LFB_MODE GR_LFBWRITEMODE_8888
220 /* 32 bit, ARGB8888 color spanline and pixel functions */
221 #undef INIT_MONO_PIXEL
222 #define INIT_MONO_PIXEL(p, color) \
223 p = TDFXPACKCOLOR8888( color[0], color[1], color[2], color[3] )
225 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
226 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
231 #define WRITE_PIXEL( _x, _y, p ) \
232 *(GLuint *)(buf + _x*4 + _y*pitch) = p
234 #define READ_RGBA( rgba, _x, _y ) \
236 GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
237 rgba[0] = (p >> 16) & 0xff; \
238 rgba[1] = (p >> 8) & 0xff; \
239 rgba[2] = (p >> 0) & 0xff; \
240 rgba[3] = (p >> 24) & 0xff; \
243 #define TAG(x) tdfx##x##_ARGB8888
244 #define BYTESPERPIXEL 4
250 /* ================================================================
251 * Old span functions below...
256 * Examine the cliprects to generate an array of flags to indicate
257 * which pixels in a span are visible. Note: (x,y) is a screen
261 generate_vismask(const tdfxContextPtr fxMesa
, GLint x
, GLint y
, GLint n
,
264 GLboolean initialized
= GL_FALSE
;
267 /* Ensure we clear the visual mask */
268 MEMSET(vismask
, 0, n
);
270 /* turn on flags for all visible pixels */
271 for (i
= 0; i
< fxMesa
->numClipRects
; i
++) {
272 const drm_clip_rect_t
*rect
= &fxMesa
->pClipRects
[i
];
274 if (y
>= rect
->y1
&& y
< rect
->y2
) {
275 if (x
>= rect
->x1
&& x
+ n
<= rect
->x2
) {
276 /* common case, whole span inside cliprect */
277 MEMSET(vismask
, 1, n
);
280 if (x
< rect
->x2
&& x
+ n
>= rect
->x1
) {
281 /* some of the span is inside the rect */
284 MEMSET(vismask
, 0, n
);
285 initialized
= GL_TRUE
;
288 start
= rect
->x1
- x
;
291 if (x
+ n
> rect
->x2
)
297 for (j
= start
; j
< end
; j
++)
305 * Examine cliprects and determine if the given screen pixel is visible.
308 visible_pixel(const tdfxContextPtr fxMesa
, int scrX
, int scrY
)
311 for (i
= 0; i
< fxMesa
->numClipRects
; i
++) {
312 const drm_clip_rect_t
*rect
= &fxMesa
->pClipRects
[i
];
313 if (scrX
>= rect
->x1
&&
315 scrY
>= rect
->y1
&& scrY
< rect
->y2
) return GL_TRUE
;
323 * Depth buffer read/write functions.
326 * To read the frame buffer, we need to lock and unlock it. The
327 * four macros {READ,WRITE}_FB_SPAN_{LOCK,UNLOCK}
330 * Note that the lock must be matched with an unlock. These
331 * macros include a spare curly brace, so they must
332 * be syntactically matched.
334 * Note, also, that you can't lock a buffer twice with different
335 * modes. That is to say, you can't lock a buffer in both read
336 * and write modes. The strideInBytes and LFB pointer will be
337 * the same with read and write locks, so you can use either.
338 * o The HW has different state for reads and writes, so
339 * locking it twice may give screwy results.
340 * o The DRM won't let you lock twice. It hangs. This is probably
341 * because of the LOCK_HARDWARE IN THE *_FB_SPAN_LOCK macros,
342 * and could be eliminated with nonlocking lock routines. But
343 * what's the point after all.
345 #define READ_FB_SPAN_LOCK(fxMesa, info, target_buffer) \
346 UNLOCK_HARDWARE(fxMesa); \
347 LOCK_HARDWARE(fxMesa); \
348 (info).size=sizeof(info); \
349 if (fxMesa->Glide.grLfbLock(GR_LFB_READ_ONLY, \
351 GR_LFBWRITEMODE_ANY, \
352 GR_ORIGIN_UPPER_LEFT, \
356 #define READ_FB_SPAN_UNLOCK(fxMesa, target_buffer) \
357 fxMesa->Glide.grLfbUnlock(GR_LFB_READ_ONLY, target_buffer); \
359 fprintf(stderr, "tdfxDriver: Can't get %s (%d) read lock\n", \
360 (target_buffer == GR_BUFFER_BACKBUFFER) \
362 : ((target_buffer == GR_BUFFER_AUXBUFFER) \
364 : "unknown buffer"), \
368 #define WRITE_FB_SPAN_LOCK(fxMesa, info, target_buffer, write_mode) \
369 UNLOCK_HARDWARE(fxMesa); \
370 LOCK_HARDWARE(fxMesa); \
371 info.size=sizeof(info); \
372 if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, \
375 GR_ORIGIN_UPPER_LEFT, \
379 #define WRITE_FB_SPAN_UNLOCK(fxMesa, target_buffer) \
380 fxMesa->Glide.grLfbUnlock(GR_LFB_WRITE_ONLY, target_buffer); \
382 fprintf(stderr, "tdfxDriver: Can't get %s (%d) write lock\n", \
383 (target_buffer == GR_BUFFER_BACKBUFFER) \
385 : ((target_buffer == GR_BUFFER_AUXBUFFER) \
387 : "unknown buffer"), \
392 * Because the Linear Frame Buffer is not necessarily aligned
393 * with the depth buffer, we have to do some fiddling
394 * around to get the right addresses.
396 * Perhaps a picture is in order. The Linear Frame Buffer
399 * |<----------------------info.strideInBytes------------->|
400 * |<-----physicalStrideInBytes------->|
401 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
403 * | Legal Memory | Forbidden Zone |
405 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
407 * You can only reliably read and write legal locations. Reads
408 * and writes from the Forbidden Zone will return undefined values,
409 * and may cause segmentation faults.
411 * Now, the depth buffer may not end up in a location such each
412 * scan line is an LFB line. For example, the depth buffer may
416 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
417 * |0000000000000000000000 | | back
418 * |1111111111111111111111 | | buffer
419 * |2222222222222222222222 | |
420 * |4096b align. padxx00000000000000000| Forbidden Zone | depth
421 * |0000 11111111111111111| | buffer
422 * |1111 22222222222222222| |
424 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
425 * where each number is the scan line number. We know it will
426 * be aligned on 128 byte boundaries, at least. Aligning this
427 * on a scanline boundary causes the back and depth buffers to
428 * thrash in the SST1 cache. (Note that the back buffer is always
429 * allocated at the beginning of LFB memory, and so it is always
430 * properly aligned with the LFB stride.)
432 * We call the beginning of the line (which is the rightmost
433 * part of the depth line in the picture above) the *ordinary* part
434 * of the scanline, and the end of the line (which is the
435 * leftmost part, one line below) the *wrapped* part of the scanline.
436 * a.) We need to know what x value to subtract from the screen
437 * x coordinate to index into the wrapped part.
438 * b.) We also need to figure out if we need to read from the ordinary
439 * part scan line, or from the wrapped part of the scan line.
442 * The first wrapped x coordinate is that coordinate such that
443 * depthBufferOffset&(info.strideInBytes) + x*elmentSize {*}
444 * > physicalStrideInBytes
445 * where depthBufferOffset is the LFB distance in bytes
446 * from the back buffer to the depth buffer. The expression
447 * depthBufferOffset&(info.strideInBytes)
448 * is then the offset (in bytes) from the beginining of (any)
449 * depth buffer line to first element in the line.
450 * Simplifying inequation {*} above we see that x is the smallest
452 * x*elementSize > physicalStrideInBytes {**}
453 * - depthBufferOffset&(info.strideInBytes)
454 * Now, we know that both the summands on the right are multiples of
455 * 128, and elementSize <= 4, so if equality holds in {**}, x would
456 * be a multiple of 32. Thus we can set x to
457 * xwrapped = (physicalStrideInBytes
458 * - depthBufferOffset&(info.strideInBytes))/elementSize
462 * Question b is now simple. We read from the wrapped scan line if
463 * x is greater than xwrapped.
465 #define TILE_WIDTH_IN_BYTES 128
466 #define TILE_WIDTH_IN_ZOXELS(bpz) (TILE_WIDTH_IN_BYTES/(bpz))
467 #define TILE_HEIGHT_IN_LINES 32
472 FxU32 LFBStrideInElts
;
478 * We need information about the back buffer. Note that
479 * this function *cannot be called* while the aux buffer
480 * is locked, or the caller will hang.
482 * Only Glide knows the LFB address of the back and depth
483 * offsets. The upper levels of Mesa know the depth offset,
484 * but that is not in LFB space, it is tiled memory space,
485 * and is not useable for us.
488 GetBackBufferInfo(tdfxContextPtr fxMesa
, GrLfbInfo_t
* backBufferInfo
)
490 READ_FB_SPAN_LOCK(fxMesa
, *backBufferInfo
, GR_BUFFER_BACKBUFFER
);
491 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_BACKBUFFER
);
495 GetFbParams(tdfxContextPtr fxMesa
,
497 GrLfbInfo_t
* backBufferInfo
,
498 LFBParameters
* ReadParamsp
, FxU32 elementSize
)
500 FxU32 physicalStrideInBytes
, bufferOffset
;
501 FxU32 strideInBytes
= info
->strideInBytes
;
502 char *lfbPtr
= (char *) (info
->lfbPtr
); /* For arithmetic, use char * */
505 * These two come directly from the info structure.
507 ReadParamsp
->lfbPtr
= (void *) lfbPtr
;
508 ReadParamsp
->LFBStrideInElts
= strideInBytes
/ elementSize
;
510 * Now, calculate the value of firstWrappedX.
512 * The physical stride is the screen width in bytes rounded up to
513 * the next highest multiple of 128 bytes. Note that this fails
514 * when TILE_WIDTH_IN_BYTES is not a power of two.
516 * The buffer Offset is the distance between the beginning of
517 * the LFB space, which is the beginning of the back buffer,
518 * and the buffer we are gathering information about.
519 * We want to make this routine usable for operations on the
520 * back buffer, though we don't actually use it on the back
521 * buffer. Note, then, that if bufferOffset == 0, the firstWrappedX
522 * is in the forbidden zone, and is therefore never reached.
525 * physicalStrideInBytes
526 * < bufferOffset&(info->strideInBytes-1)
527 * the buffer begins in the forbidden zone. We assert for this.
529 bufferOffset
= (FxU32
)(lfbPtr
- (char *) backBufferInfo
->lfbPtr
);
530 physicalStrideInBytes
531 = (fxMesa
->screen_width
* elementSize
+ TILE_WIDTH_IN_BYTES
- 1)
532 & ~(TILE_WIDTH_IN_BYTES
- 1);
533 assert(physicalStrideInBytes
> (bufferOffset
& (strideInBytes
- 1)));
534 ReadParamsp
->firstWrappedX
535 = (physicalStrideInBytes
536 - (bufferOffset
& (strideInBytes
- 1))) / elementSize
;
538 * This is the address of the next physical line.
540 ReadParamsp
->lfbWrapPtr
541 = (void *) ((char *) backBufferInfo
->lfbPtr
542 + (bufferOffset
& ~(strideInBytes
- 1))
543 + (TILE_HEIGHT_IN_LINES
) * strideInBytes
);
547 * These macros fetch data from the frame buffer. The type is
548 * the type of data we want to fetch. It should match the type
549 * whose size was used with GetFbParams to fill in the structure
550 * in *ReadParamsp. We have a macro to read the ordinary
551 * part, a second macro to read the wrapped part, and one which
552 * will do either. When we are reading a span, we will know
553 * when the ordinary part ends, so there's no need to test for
554 * it. However, when reading and writing pixels, we don't
555 * necessarily know. I suppose it's a matter of taste whether
556 * it's better in the macro or in the call.
558 * Recall that x and y are screen coordinates.
560 #define GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \
561 (((type *)((ReadParamsp)->lfbPtr)) \
562 [(y) * ((ReadParamsp)->LFBStrideInElts) \
564 #define GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) \
565 (((type *)((ReadParamsp)->lfbWrapPtr)) \
566 [((y)) * ((ReadParamsp)->LFBStrideInElts) \
567 + ((x) - (ReadParamsp)->firstWrappedX)])
568 #define GET_FB_DATA(ReadParamsp, type, x, y) \
569 (((x) < (ReadParamsp)->firstWrappedX) \
570 ? GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \
571 : GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y))
572 #define PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value) \
573 (GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) = (type)(value))
574 #define PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value) \
575 (GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) = (type)(value))
576 #define PUT_FB_DATA(ReadParamsp, type, x, y, value) \
578 if ((x) < (ReadParamsp)->firstWrappedX) \
579 PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value); \
581 PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value); \
586 tdfxDDWriteDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
587 GLuint n
, GLint x
, GLint y
, const void *values
,
588 const GLubyte mask
[])
590 const GLuint
*depth
= (const GLuint
*) values
;
591 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
592 GLint bottom
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
593 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
594 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
596 GLubyte visMask
[MAX_WIDTH
];
598 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
599 fprintf(stderr
, "tdfxmesa: tdfxDDWriteDepthSpan(...)\n");
602 assert((depth_size
== 16) || (depth_size
== 24) || (depth_size
== 32));
604 * Convert x and y to screen coordinates.
606 x
+= fxMesa
->x_offset
;
611 GrLfbInfo_t backBufferInfo
;
613 switch (depth_size
) {
615 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
617 * Note that the _LOCK macro adds a curly brace,
618 * and the UNLOCK macro removes it.
620 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
,
621 GR_LFBWRITEMODE_ANY
);
622 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
624 LFBParameters ReadParams
;
625 int wrappedPartStart
;
626 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
627 &ReadParams
, sizeof(GLushort
));
628 if (ReadParams
.firstWrappedX
<= x
) {
629 wrappedPartStart
= 0;
631 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
632 wrappedPartStart
= n
;
635 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
637 for (i
= 0; i
< wrappedPartStart
; i
++) {
638 if (mask
[i
] && visMask
[i
]) {
640 PUT_ORDINARY_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
, d16
);
644 if (mask
[i
] && visMask
[i
]) {
646 PUT_WRAPPED_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
, d16
);
650 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
654 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
656 * Note that the _LOCK macro adds a curly brace,
657 * and the UNLOCK macro removes it.
659 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
,
660 GR_LFBWRITEMODE_ANY
);
661 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
663 LFBParameters ReadParams
;
664 int wrappedPartStart
;
665 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
666 &ReadParams
, sizeof(GLuint
));
667 if (ReadParams
.firstWrappedX
<= x
) {
668 wrappedPartStart
= 0;
670 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
671 wrappedPartStart
= n
;
674 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
676 for (i
= 0; i
< wrappedPartStart
; i
++) {
678 if (mask
[i
] && visMask
[i
]) {
679 if (stencil_size
> 0) {
681 GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
684 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
689 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
694 if (mask
[i
] && visMask
[i
]) {
695 if (stencil_size
> 0) {
697 GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
700 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
705 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
709 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
717 GrLfbInfo_t backBufferInfo
;
719 switch (depth_size
) {
721 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
723 * Note that the _LOCK macro adds a curly brace,
724 * and the UNLOCK macro removes it.
726 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
727 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
728 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
730 LFBParameters ReadParams
;
731 GLuint wrappedPartStart
;
732 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
733 &ReadParams
, sizeof(GLushort
));
734 if (ReadParams
.firstWrappedX
<= x
) {
735 wrappedPartStart
= 0;
737 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
738 wrappedPartStart
= n
;
741 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
743 for (i
= 0; i
< wrappedPartStart
; i
++) {
746 PUT_ORDINARY_FB_DATA(&ReadParams
,
755 PUT_WRAPPED_FB_DATA(&ReadParams
,
762 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
766 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
768 * Note that the _LOCK macro adds a curly brace,
769 * and the UNLOCK macro removes it.
771 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
772 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
773 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
775 LFBParameters ReadParams
;
776 GLuint wrappedPartStart
;
778 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
779 &ReadParams
, sizeof(GLuint
));
780 if (ReadParams
.firstWrappedX
<= x
) {
781 wrappedPartStart
= 0;
783 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
784 wrappedPartStart
= n
;
787 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
789 for (i
= 0; i
< wrappedPartStart
; i
++) {
791 if (stencil_size
> 0) {
792 d32
= GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
794 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
799 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
804 if (stencil_size
> 0) {
805 d32
= GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
807 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
812 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
816 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
823 tdfxDDWriteMonoDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
824 GLuint n
, GLint x
, GLint y
, const void *value
,
825 const GLubyte mask
[])
827 GLuint depthVal
= *((GLuint
*) value
);
828 GLuint depths
[MAX_WIDTH
];
830 for (i
= 0; i
< n
; i
++)
831 depths
[i
] = depthVal
;
832 tdfxDDWriteDepthSpan(ctx
, rb
, n
, x
, y
, depths
, mask
);
837 tdfxDDReadDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
838 GLuint n
, GLint x
, GLint y
, void *values
)
840 GLuint
*depth
= (GLuint
*) values
;
841 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
842 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
844 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
847 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
848 fprintf(stderr
, "tdfxmesa: tdfxDDReadDepthSpan(...)\n");
852 * Convert to screen coordinates.
854 x
+= fxMesa
->x_offset
;
856 switch (depth_size
) {
859 LFBParameters ReadParams
;
860 GrLfbInfo_t backBufferInfo
;
861 int wrappedPartStart
;
862 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
864 * Note that the _LOCK macro adds a curly brace,
865 * and the UNLOCK macro removes it.
867 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
868 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
869 &ReadParams
, sizeof(GLushort
));
870 if (ReadParams
.firstWrappedX
<= x
) {
871 wrappedPartStart
= 0;
873 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
874 wrappedPartStart
= n
;
877 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
882 for (i
= 0; i
< wrappedPartStart
; i
++) {
884 GET_ORDINARY_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
);
887 depth
[i
] = GET_WRAPPED_FB_DATA(&ReadParams
, GLushort
,
890 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
896 LFBParameters ReadParams
;
897 GrLfbInfo_t backBufferInfo
;
898 int wrappedPartStart
;
899 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
900 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
902 * Note that the _LOCK macro adds a curly brace,
903 * and the UNLOCK macro removes it.
905 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
906 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
907 &ReadParams
, sizeof(GLuint
));
908 if (ReadParams
.firstWrappedX
<= x
) {
909 wrappedPartStart
= 0;
911 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
912 wrappedPartStart
= n
;
915 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
920 for (i
= 0; i
< wrappedPartStart
; i
++) {
922 (stencil_size
> 0) ? 0x00FFFFFF : 0xFFFFFFFF;
924 GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
929 (stencil_size
> 0) ? 0x00FFFFFF : 0xFFFFFFFF;
930 depth
[i
] = GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
933 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
941 tdfxDDWriteDepthPixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
942 GLuint n
, const GLint x
[], const GLint y
[],
943 const void *values
, const GLubyte mask
[])
945 const GLuint
*depth
= (const GLuint
*) values
;
946 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
947 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
951 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
952 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
956 GrLfbInfo_t backBufferInfo
;
958 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
959 fprintf(stderr
, "tdfxmesa: tdfxDDWriteDepthPixels(...)\n");
962 switch (depth_size
) {
964 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
966 * Note that the _LOCK macro adds a curly brace,
967 * and the UNLOCK macro removes it.
969 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
970 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
972 LFBParameters ReadParams
;
973 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
974 &ReadParams
, sizeof(GLushort
));
975 for (i
= 0; i
< n
; i
++) {
976 if ((!mask
|| mask
[i
]) && visible_pixel(fxMesa
, x
[i
], y
[i
])) {
977 xpos
= x
[i
] + fxMesa
->x_offset
;
978 ypos
= bottom
- y
[i
];
980 PUT_FB_DATA(&ReadParams
, GLushort
, xpos
, ypos
, d16
);
984 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
988 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
990 * Note that the _LOCK macro adds a curly brace,
991 * and the UNLOCK macro removes it.
993 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
994 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
996 LFBParameters ReadParams
;
997 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
998 &ReadParams
, sizeof(GLuint
));
999 for (i
= 0; i
< n
; i
++) {
1000 if (!mask
|| mask
[i
]) {
1001 if (visible_pixel(fxMesa
, x
[i
], y
[i
])) {
1002 xpos
= x
[i
] + fxMesa
->x_offset
;
1003 ypos
= bottom
- y
[i
];
1004 if (stencil_size
> 0) {
1006 GET_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
);
1007 d32
= (d32
& 0xFF000000) | (depth
[i
] & 0xFFFFFF);
1012 PUT_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
, d32
);
1017 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1024 tdfxDDReadDepthPixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
, GLuint n
,
1025 const GLint x
[], const GLint y
[], void *values
)
1027 GLuint
*depth
= (GLuint
*) values
;
1028 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
1029 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
1031 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
1036 GLuint stencil_size
;
1037 GrLfbInfo_t backBufferInfo
;
1039 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
1040 fprintf(stderr
, "tdfxmesa: tdfxDDReadDepthPixels(...)\n");
1043 assert((depth_size
== 16) || (depth_size
== 24) || (depth_size
== 32));
1044 switch (depth_size
) {
1046 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1048 * Note that the _LOCK macro adds a curly brace,
1049 * and the UNLOCK macro removes it.
1051 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1053 LFBParameters ReadParams
;
1054 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1055 &ReadParams
, sizeof(GLushort
));
1056 for (i
= 0; i
< n
; i
++) {
1058 * Convert to screen coordinates.
1060 xpos
= x
[i
] + fxMesa
->x_offset
;
1061 ypos
= bottom
- y
[i
];
1062 d16
= GET_FB_DATA(&ReadParams
, GLushort
, xpos
, ypos
);
1066 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1070 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1072 * Note that the _LOCK macro adds a curly brace,
1073 * and the UNLOCK macro removes it.
1075 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1076 stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
1078 LFBParameters ReadParams
;
1079 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1080 &ReadParams
, sizeof(GLuint
));
1081 for (i
= 0; i
< n
; i
++) {
1085 * Convert to screen coordinates.
1087 xpos
= x
[i
] + fxMesa
->x_offset
;
1088 ypos
= bottom
- y
[i
];
1089 d32
= GET_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
);
1090 if (stencil_size
> 0) {
1096 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1104 * Stencil buffer read/write functions.
1106 #define EXTRACT_S_FROM_ZS(zs) (((zs) >> 24) & 0xFF)
1107 #define EXTRACT_Z_FROM_ZS(zs) ((zs) & 0xffffff)
1108 #define BUILD_ZS(z, s) (((s) << 24) | (z))
1111 write_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1112 GLuint n
, GLint x
, GLint y
,
1113 const void *values
, const GLubyte mask
[])
1115 const GLubyte
*stencil
= (const GLubyte
*) values
;
1116 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1118 GrLfbInfo_t backBufferInfo
;
1120 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1122 * Note that the _LOCK macro adds a curly brace,
1123 * and the UNLOCK macro removes it.
1125 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1127 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1128 const GLint winX
= fxMesa
->x_offset
;
1129 const GLint scrX
= winX
+ x
;
1130 const GLint scrY
= winY
- y
;
1131 LFBParameters ReadParams
;
1132 GLubyte visMask
[MAX_WIDTH
];
1134 int wrappedPartStart
;
1136 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1138 if (ReadParams
.firstWrappedX
<= x
) {
1139 wrappedPartStart
= 0;
1141 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
1142 wrappedPartStart
= n
;
1145 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
1147 generate_vismask(fxMesa
, scrX
, scrY
, n
, visMask
);
1148 for (i
= 0; i
< wrappedPartStart
; i
++) {
1149 if (visMask
[i
] && (!mask
|| mask
[i
])) {
1150 GLuint z
= GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
1151 scrX
+ i
, scrY
) & 0x00FFFFFF;
1152 z
|= (stencil
[i
] & 0xFF) << 24;
1153 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, scrX
+ i
, scrY
, z
);
1156 for (; i
< n
; i
++) {
1157 if (visMask
[i
] && (!mask
|| mask
[i
])) {
1158 GLuint z
= GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
1159 scrX
+ i
, scrY
) & 0x00FFFFFF;
1160 z
|= (stencil
[i
] & 0xFF) << 24;
1161 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, scrX
+ i
, scrY
, z
);
1165 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1170 write_mono_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1171 GLuint n
, GLint x
, GLint y
,
1172 const void *value
, const GLubyte mask
[])
1174 GLbyte stencilVal
= *((GLbyte
*) value
);
1175 GLbyte stencils
[MAX_WIDTH
];
1177 for (i
= 0; i
< n
; i
++)
1178 stencils
[i
] = stencilVal
;
1179 write_stencil_span(ctx
, rb
, n
, x
, y
, stencils
, mask
);
1184 read_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1185 GLuint n
, GLint x
, GLint y
,
1188 GLubyte
*stencil
= (GLubyte
*) values
;
1189 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1191 GrLfbInfo_t backBufferInfo
;
1193 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1195 * Note that the _LOCK macro adds a curly brace,
1196 * and the UNLOCK macro removes it.
1198 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1200 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1201 const GLint winX
= fxMesa
->x_offset
;
1203 LFBParameters ReadParams
;
1204 int wrappedPartStart
;
1207 * Convert to screen coordinates.
1211 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1213 if (ReadParams
.firstWrappedX
<= x
) {
1214 wrappedPartStart
= 0;
1216 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
1217 wrappedPartStart
= n
;
1220 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
1222 for (i
= 0; i
< wrappedPartStart
; i
++) {
1223 stencil
[i
] = (GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
1224 x
+ i
, y
) >> 24) & 0xFF;
1226 for (; i
< n
; i
++) {
1227 stencil
[i
] = (GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
1228 x
+ i
, y
) >> 24) & 0xFF;
1231 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1236 write_stencil_pixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1237 GLuint n
, const GLint x
[], const GLint y
[],
1238 const void *values
, const GLubyte mask
[])
1240 const GLubyte
*stencil
= (const GLubyte
*) values
;
1241 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1243 GrLfbInfo_t backBufferInfo
;
1245 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1247 * Note that the _LOCK macro adds a curly brace,
1248 * and the UNLOCK macro removes it.
1250 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1252 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1253 const GLint winX
= fxMesa
->x_offset
;
1254 LFBParameters ReadParams
;
1257 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1259 for (i
= 0; i
< n
; i
++) {
1260 const GLint scrX
= winX
+ x
[i
];
1261 const GLint scrY
= winY
- y
[i
];
1262 if ((!mask
|| mask
[i
]) && visible_pixel(fxMesa
, scrX
, scrY
)) {
1264 GET_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
) & 0x00FFFFFF;
1265 z
|= (stencil
[i
] & 0xFF) << 24;
1266 PUT_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
, z
);
1270 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1275 read_stencil_pixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1276 GLuint n
, const GLint x
[], const GLint y
[],
1279 GLubyte
*stencil
= (GLubyte
*) values
;
1280 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1282 GrLfbInfo_t backBufferInfo
;
1284 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1286 * Note that the _LOCK macro adds a curly brace,
1287 * and the UNLOCK macro removes it.
1289 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1291 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1292 const GLint winX
= fxMesa
->x_offset
;
1294 LFBParameters ReadParams
;
1296 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1298 for (i
= 0; i
< n
; i
++) {
1299 const GLint scrX
= winX
+ x
[i
];
1300 const GLint scrY
= winY
- y
[i
];
1302 (GET_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
) >> 24) & 0xFF;
1305 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1308 #define VISUAL_EQUALS_RGBA(vis, r, g, b, a) \
1309 ((vis.redBits == r) && \
1310 (vis.greenBits == g) && \
1311 (vis.blueBits == b) && \
1312 (vis.alphaBits == a))
1317 /**********************************************************************/
1318 /* Locking for swrast */
1319 /**********************************************************************/
1322 static void tdfxSpanRenderStart( GLcontext
*ctx
)
1324 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1325 LOCK_HARDWARE(fxMesa
);
1328 static void tdfxSpanRenderFinish( GLcontext
*ctx
)
1330 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1331 _swrast_flush( ctx
);
1332 UNLOCK_HARDWARE(fxMesa
);
1335 /**********************************************************************/
1336 /* Initialize swrast device driver */
1337 /**********************************************************************/
1339 void tdfxDDInitSpanFuncs( GLcontext
*ctx
)
1341 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1342 swdd
->SpanRenderStart
= tdfxSpanRenderStart
;
1343 swdd
->SpanRenderFinish
= tdfxSpanRenderFinish
;
1349 * Plug in the Get/Put routines for the given driRenderbuffer.
1352 tdfxSetSpanFunctions(driRenderbuffer
*drb
, const GLvisual
*vis
)
1354 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
1355 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
1356 tdfxInitPointers_RGB565(&drb
->Base
);
1358 else if (vis
->redBits
== 8 && vis
->greenBits
== 8
1359 && vis
->blueBits
== 8 && vis
->alphaBits
== 0) {
1360 tdfxInitPointers_RGB888(&drb
->Base
);
1362 else if (vis
->redBits
== 8 && vis
->greenBits
== 8
1363 && vis
->blueBits
== 8 && vis
->alphaBits
== 8) {
1364 tdfxInitPointers_ARGB8888(&drb
->Base
);
1367 _mesa_problem(NULL
, "problem in tdfxSetSpanFunctions");
1370 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
||
1371 drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
1372 drb
->Base
.GetRow
= tdfxDDReadDepthSpan
;
1373 drb
->Base
.GetValues
= tdfxDDReadDepthPixels
;
1374 drb
->Base
.PutRow
= tdfxDDWriteDepthSpan
;
1375 drb
->Base
.PutMonoRow
= tdfxDDWriteMonoDepthSpan
;
1376 drb
->Base
.PutValues
= tdfxDDWriteDepthPixels
;
1377 drb
->Base
.PutMonoValues
= NULL
;
1379 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
1380 drb
->Base
.GetRow
= read_stencil_span
;
1381 drb
->Base
.GetValues
= read_stencil_pixels
;
1382 drb
->Base
.PutRow
= write_stencil_span
;
1383 drb
->Base
.PutMonoRow
= write_mono_stencil_span
;
1384 drb
->Base
.PutValues
= write_stencil_pixels
;
1385 drb
->Base
.PutMonoValues
= NULL
;