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 GLboolean isFront = (ctx->DrawBuffer->_ColorDrawBufferMask[0] \
53 == BUFFER_BIT_FRONT_LEFT); \
54 GLuint pitch = isFront ? (fxMesa->screen_width * BYTESPERPIXEL) \
55 : info.strideInBytes; \
56 GLuint height = fxMesa->height; \
57 char *buf = (char *)((char *)info.lfbPtr + \
58 dPriv->x * fxPriv->cpp + \
64 #define Y_FLIP(_y) (height - _y - 1)
67 #define HW_WRITE_LOCK() \
68 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \
70 FLUSH_BATCH( fxMesa ); \
71 UNLOCK_HARDWARE( fxMesa ); \
72 LOCK_HARDWARE( fxMesa ); \
73 info.size = sizeof(GrLfbInfo_t); \
74 if ( fxMesa->Glide.grLfbLock( GR_LFB_WRITE_ONLY, \
75 fxMesa->DrawBuffer, LFB_MODE, \
76 GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \
79 #define HW_WRITE_UNLOCK() \
80 fxMesa->Glide.grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer );\
84 #define HW_READ_LOCK() \
85 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \
87 FLUSH_BATCH( fxMesa ); \
88 UNLOCK_HARDWARE( fxMesa ); \
89 LOCK_HARDWARE( fxMesa ); \
90 info.size = sizeof(GrLfbInfo_t); \
91 if ( fxMesa->Glide.grLfbLock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer, \
92 LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \
95 #define HW_READ_UNLOCK() \
96 fxMesa->Glide.grLfbUnlock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer );\
100 #define HW_WRITE_CLIPLOOP() \
102 int _nc = fxMesa->numClipRects; \
104 int minx = fxMesa->pClipRects[_nc].x1 - fxMesa->x_offset; \
105 int miny = fxMesa->pClipRects[_nc].y1 - fxMesa->y_offset; \
106 int maxx = fxMesa->pClipRects[_nc].x2 - fxMesa->x_offset; \
107 int maxy = fxMesa->pClipRects[_nc].y2 - fxMesa->y_offset;
109 #define HW_READ_CLIPLOOP() \
111 const __DRIdrawablePrivate *dPriv = fxMesa->driDrawable; \
112 drm_clip_rect_t *rect = dPriv->pClipRects; \
113 int _nc = dPriv->numClipRects; \
115 const int minx = rect->x1 - fxMesa->x_offset; \
116 const int miny = rect->y1 - fxMesa->y_offset; \
117 const int maxx = rect->x2 - fxMesa->x_offset; \
118 const int maxy = rect->y2 - fxMesa->y_offset; \
121 #define HW_ENDCLIPLOOP() \
127 #define LFB_MODE GR_LFBWRITEMODE_565
130 /* 16 bit, RGB565 color spanline and pixel functions */ \
132 #undef INIT_MONO_PIXEL
133 #define INIT_MONO_PIXEL(p, color) \
134 p = TDFXPACKCOLOR565( color[0], color[1], color[2] )
137 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
138 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
139 (((int)g & 0xfc) << 3) | \
140 (((int)b & 0xf8) >> 3))
142 #define WRITE_PIXEL( _x, _y, p ) \
143 *(GLushort *)(buf + _x*2 + _y*pitch) = p
145 #define READ_RGBA( rgba, _x, _y ) \
147 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
148 rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
149 rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
150 rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
154 #define TAG(x) tdfx##x##_RGB565
155 #define BYTESPERPIXEL 2
160 /* 16 bit, BGR565 color spanline and pixel functions */ \
163 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
164 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)b & 0xf8) << 8) | \
165 (((int)g & 0xfc) << 3) | \
166 (((int)r & 0xf8) >> 3))
168 #define WRITE_PIXEL( _x, _y, p ) \
169 *(GLushort *)(buf + _x*2 + _y*pitch) = p
171 #define READ_RGBA( rgba, _x, _y ) \
173 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
174 rgba[0] = (p << 3) & 0xf8; \
175 rgba[1] = (p >> 3) & 0xfc; \
176 rgba[2] = (p >> 8) & 0xf8; \
180 #define TAG(x) tdfx##x##_BGR565
181 #define BYTESPERPIXEL 2
188 #define LFB_MODE GR_LFBWRITEMODE_888
191 /* 24 bit, RGB888 color spanline and pixel functions */
192 #undef INIT_MONO_PIXEL
193 #define INIT_MONO_PIXEL(p, color) \
194 p = TDFXPACKCOLOR888( color[0], color[1], color[2] )
196 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
197 *(GLuint *)(buf + _x*3 + _y*pitch) = ((b << 0) | \
201 #define WRITE_PIXEL( _x, _y, p ) \
202 *(GLuint *)(buf + _x*3 + _y*pitch) = p
204 #define READ_RGBA( rgba, _x, _y ) \
206 GLuint p = *(GLuint *)(buf + _x*3 + _y*pitch); \
207 rgba[0] = (p >> 16) & 0xff; \
208 rgba[1] = (p >> 8) & 0xff; \
209 rgba[2] = (p >> 0) & 0xff; \
213 #define TAG(x) tdfx##x##_RGB888
214 #define BYTESPERPIXEL 4
220 #define LFB_MODE GR_LFBWRITEMODE_8888
223 /* 32 bit, ARGB8888 color spanline and pixel functions */
224 #undef INIT_MONO_PIXEL
225 #define INIT_MONO_PIXEL(p, color) \
226 p = TDFXPACKCOLOR8888( color[0], color[1], color[2], color[3] )
228 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
229 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
234 #define WRITE_PIXEL( _x, _y, p ) \
235 *(GLuint *)(buf + _x*4 + _y*pitch) = p
237 #define READ_RGBA( rgba, _x, _y ) \
239 GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
240 rgba[0] = (p >> 16) & 0xff; \
241 rgba[1] = (p >> 8) & 0xff; \
242 rgba[2] = (p >> 0) & 0xff; \
243 rgba[3] = (p >> 24) & 0xff; \
246 #define TAG(x) tdfx##x##_ARGB8888
247 #define BYTESPERPIXEL 4
253 /* ================================================================
254 * Old span functions below...
259 * Examine the cliprects to generate an array of flags to indicate
260 * which pixels in a span are visible. Note: (x,y) is a screen
264 generate_vismask(const tdfxContextPtr fxMesa
, GLint x
, GLint y
, GLint n
,
267 GLboolean initialized
= GL_FALSE
;
270 /* Ensure we clear the visual mask */
271 MEMSET(vismask
, 0, n
);
273 /* turn on flags for all visible pixels */
274 for (i
= 0; i
< fxMesa
->numClipRects
; i
++) {
275 const drm_clip_rect_t
*rect
= &fxMesa
->pClipRects
[i
];
277 if (y
>= rect
->y1
&& y
< rect
->y2
) {
278 if (x
>= rect
->x1
&& x
+ n
<= rect
->x2
) {
279 /* common case, whole span inside cliprect */
280 MEMSET(vismask
, 1, n
);
283 if (x
< rect
->x2
&& x
+ n
>= rect
->x1
) {
284 /* some of the span is inside the rect */
287 MEMSET(vismask
, 0, n
);
288 initialized
= GL_TRUE
;
291 start
= rect
->x1
- x
;
294 if (x
+ n
> rect
->x2
)
300 for (j
= start
; j
< end
; j
++)
308 * Examine cliprects and determine if the given screen pixel is visible.
311 visible_pixel(const tdfxContextPtr fxMesa
, int scrX
, int scrY
)
314 for (i
= 0; i
< fxMesa
->numClipRects
; i
++) {
315 const drm_clip_rect_t
*rect
= &fxMesa
->pClipRects
[i
];
316 if (scrX
>= rect
->x1
&&
318 scrY
>= rect
->y1
&& scrY
< rect
->y2
) return GL_TRUE
;
326 * Depth buffer read/write functions.
329 * To read the frame buffer, we need to lock and unlock it. The
330 * four macros {READ,WRITE}_FB_SPAN_{LOCK,UNLOCK}
333 * Note that the lock must be matched with an unlock. These
334 * macros include a spare curly brace, so they must
335 * be syntactically matched.
337 * Note, also, that you can't lock a buffer twice with different
338 * modes. That is to say, you can't lock a buffer in both read
339 * and write modes. The strideInBytes and LFB pointer will be
340 * the same with read and write locks, so you can use either.
341 * o The HW has different state for reads and writes, so
342 * locking it twice may give screwy results.
343 * o The DRM won't let you lock twice. It hangs. This is probably
344 * because of the LOCK_HARDWARE IN THE *_FB_SPAN_LOCK macros,
345 * and could be eliminated with nonlocking lock routines. But
346 * what's the point after all.
348 #define READ_FB_SPAN_LOCK(fxMesa, info, target_buffer) \
349 UNLOCK_HARDWARE(fxMesa); \
350 LOCK_HARDWARE(fxMesa); \
351 (info).size=sizeof(info); \
352 if (fxMesa->Glide.grLfbLock(GR_LFB_READ_ONLY, \
354 GR_LFBWRITEMODE_ANY, \
355 GR_ORIGIN_UPPER_LEFT, \
359 #define READ_FB_SPAN_UNLOCK(fxMesa, target_buffer) \
360 fxMesa->Glide.grLfbUnlock(GR_LFB_READ_ONLY, target_buffer); \
362 fprintf(stderr, "tdfxDriver: Can't get %s (%d) read lock\n", \
363 (target_buffer == GR_BUFFER_BACKBUFFER) \
365 : ((target_buffer == GR_BUFFER_AUXBUFFER) \
367 : "unknown buffer"), \
371 #define WRITE_FB_SPAN_LOCK(fxMesa, info, target_buffer, write_mode) \
372 UNLOCK_HARDWARE(fxMesa); \
373 LOCK_HARDWARE(fxMesa); \
374 info.size=sizeof(info); \
375 if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, \
378 GR_ORIGIN_UPPER_LEFT, \
382 #define WRITE_FB_SPAN_UNLOCK(fxMesa, target_buffer) \
383 fxMesa->Glide.grLfbUnlock(GR_LFB_WRITE_ONLY, target_buffer); \
385 fprintf(stderr, "tdfxDriver: Can't get %s (%d) write lock\n", \
386 (target_buffer == GR_BUFFER_BACKBUFFER) \
388 : ((target_buffer == GR_BUFFER_AUXBUFFER) \
390 : "unknown buffer"), \
395 * Because the Linear Frame Buffer is not necessarily aligned
396 * with the depth buffer, we have to do some fiddling
397 * around to get the right addresses.
399 * Perhaps a picture is in order. The Linear Frame Buffer
402 * |<----------------------info.strideInBytes------------->|
403 * |<-----physicalStrideInBytes------->|
404 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
406 * | Legal Memory | Forbidden Zone |
408 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
410 * You can only reliably read and write legal locations. Reads
411 * and writes from the Forbidden Zone will return undefined values,
412 * and may cause segmentation faults.
414 * Now, the depth buffer may not end up in a location such each
415 * scan line is an LFB line. For example, the depth buffer may
419 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
420 * |0000000000000000000000 | | back
421 * |1111111111111111111111 | | buffer
422 * |2222222222222222222222 | |
423 * |4096b align. padxx00000000000000000| Forbidden Zone | depth
424 * |0000 11111111111111111| | buffer
425 * |1111 22222222222222222| |
427 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
428 * where each number is the scan line number. We know it will
429 * be aligned on 128 byte boundaries, at least. Aligning this
430 * on a scanline boundary causes the back and depth buffers to
431 * thrash in the SST1 cache. (Note that the back buffer is always
432 * allocated at the beginning of LFB memory, and so it is always
433 * properly aligned with the LFB stride.)
435 * We call the beginning of the line (which is the rightmost
436 * part of the depth line in the picture above) the *ordinary* part
437 * of the scanline, and the end of the line (which is the
438 * leftmost part, one line below) the *wrapped* part of the scanline.
439 * a.) We need to know what x value to subtract from the screen
440 * x coordinate to index into the wrapped part.
441 * b.) We also need to figure out if we need to read from the ordinary
442 * part scan line, or from the wrapped part of the scan line.
445 * The first wrapped x coordinate is that coordinate such that
446 * depthBufferOffset&(info.strideInBytes) + x*elmentSize {*}
447 * > physicalStrideInBytes
448 * where depthBufferOffset is the LFB distance in bytes
449 * from the back buffer to the depth buffer. The expression
450 * depthBufferOffset&(info.strideInBytes)
451 * is then the offset (in bytes) from the beginining of (any)
452 * depth buffer line to first element in the line.
453 * Simplifying inequation {*} above we see that x is the smallest
455 * x*elementSize > physicalStrideInBytes {**}
456 * - depthBufferOffset&(info.strideInBytes)
457 * Now, we know that both the summands on the right are multiples of
458 * 128, and elementSize <= 4, so if equality holds in {**}, x would
459 * be a multiple of 32. Thus we can set x to
460 * xwrapped = (physicalStrideInBytes
461 * - depthBufferOffset&(info.strideInBytes))/elementSize
465 * Question b is now simple. We read from the wrapped scan line if
466 * x is greater than xwrapped.
468 #define TILE_WIDTH_IN_BYTES 128
469 #define TILE_WIDTH_IN_ZOXELS(bpz) (TILE_WIDTH_IN_BYTES/(bpz))
470 #define TILE_HEIGHT_IN_LINES 32
475 FxU32 LFBStrideInElts
;
481 * We need information about the back buffer. Note that
482 * this function *cannot be called* while the aux buffer
483 * is locked, or the caller will hang.
485 * Only Glide knows the LFB address of the back and depth
486 * offsets. The upper levels of Mesa know the depth offset,
487 * but that is not in LFB space, it is tiled memory space,
488 * and is not useable for us.
491 GetBackBufferInfo(tdfxContextPtr fxMesa
, GrLfbInfo_t
* backBufferInfo
)
493 READ_FB_SPAN_LOCK(fxMesa
, *backBufferInfo
, GR_BUFFER_BACKBUFFER
);
494 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_BACKBUFFER
);
498 GetFbParams(tdfxContextPtr fxMesa
,
500 GrLfbInfo_t
* backBufferInfo
,
501 LFBParameters
* ReadParamsp
, FxU32 elementSize
)
503 FxU32 physicalStrideInBytes
, bufferOffset
;
504 FxU32 strideInBytes
= info
->strideInBytes
;
505 char *lfbPtr
= (char *) (info
->lfbPtr
); /* For arithmetic, use char * */
508 * These two come directly from the info structure.
510 ReadParamsp
->lfbPtr
= (void *) lfbPtr
;
511 ReadParamsp
->LFBStrideInElts
= strideInBytes
/ elementSize
;
513 * Now, calculate the value of firstWrappedX.
515 * The physical stride is the screen width in bytes rounded up to
516 * the next highest multiple of 128 bytes. Note that this fails
517 * when TILE_WIDTH_IN_BYTES is not a power of two.
519 * The buffer Offset is the distance between the beginning of
520 * the LFB space, which is the beginning of the back buffer,
521 * and the buffer we are gathering information about.
522 * We want to make this routine usable for operations on the
523 * back buffer, though we don't actually use it on the back
524 * buffer. Note, then, that if bufferOffset == 0, the firstWrappedX
525 * is in the forbidden zone, and is therefore never reached.
528 * physicalStrideInBytes
529 * < bufferOffset&(info->strideInBytes-1)
530 * the buffer begins in the forbidden zone. We assert for this.
532 bufferOffset
= (FxU32
)(lfbPtr
- (char *) backBufferInfo
->lfbPtr
);
533 physicalStrideInBytes
534 = (fxMesa
->screen_width
* elementSize
+ TILE_WIDTH_IN_BYTES
- 1)
535 & ~(TILE_WIDTH_IN_BYTES
- 1);
536 assert(physicalStrideInBytes
> (bufferOffset
& (strideInBytes
- 1)));
537 ReadParamsp
->firstWrappedX
538 = (physicalStrideInBytes
539 - (bufferOffset
& (strideInBytes
- 1))) / elementSize
;
541 * This is the address of the next physical line.
543 ReadParamsp
->lfbWrapPtr
544 = (void *) ((char *) backBufferInfo
->lfbPtr
545 + (bufferOffset
& ~(strideInBytes
- 1))
546 + (TILE_HEIGHT_IN_LINES
) * strideInBytes
);
550 * These macros fetch data from the frame buffer. The type is
551 * the type of data we want to fetch. It should match the type
552 * whose size was used with GetFbParams to fill in the structure
553 * in *ReadParamsp. We have a macro to read the ordinary
554 * part, a second macro to read the wrapped part, and one which
555 * will do either. When we are reading a span, we will know
556 * when the ordinary part ends, so there's no need to test for
557 * it. However, when reading and writing pixels, we don't
558 * necessarily know. I suppose it's a matter of taste whether
559 * it's better in the macro or in the call.
561 * Recall that x and y are screen coordinates.
563 #define GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \
564 (((type *)((ReadParamsp)->lfbPtr)) \
565 [(y) * ((ReadParamsp)->LFBStrideInElts) \
567 #define GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) \
568 (((type *)((ReadParamsp)->lfbWrapPtr)) \
569 [((y)) * ((ReadParamsp)->LFBStrideInElts) \
570 + ((x) - (ReadParamsp)->firstWrappedX)])
571 #define GET_FB_DATA(ReadParamsp, type, x, y) \
572 (((x) < (ReadParamsp)->firstWrappedX) \
573 ? GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \
574 : GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y))
575 #define PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value) \
576 (GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) = (type)(value))
577 #define PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value) \
578 (GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) = (type)(value))
579 #define PUT_FB_DATA(ReadParamsp, type, x, y, value) \
581 if ((x) < (ReadParamsp)->firstWrappedX) \
582 PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value); \
584 PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value); \
589 tdfxDDWriteDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
590 GLuint n
, GLint x
, GLint y
, const void *values
,
591 const GLubyte mask
[])
593 const GLuint
*depth
= (const GLuint
*) values
;
594 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
595 GLint bottom
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
596 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
597 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
599 GLubyte visMask
[MAX_WIDTH
];
601 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
602 fprintf(stderr
, "tdfxmesa: tdfxDDWriteDepthSpan(...)\n");
605 assert((depth_size
== 16) || (depth_size
== 24) || (depth_size
== 32));
607 * Convert x and y to screen coordinates.
609 x
+= fxMesa
->x_offset
;
614 GrLfbInfo_t backBufferInfo
;
616 switch (depth_size
) {
618 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
620 * Note that the _LOCK macro adds a curly brace,
621 * and the UNLOCK macro removes it.
623 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
,
624 GR_LFBWRITEMODE_ANY
);
625 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
627 LFBParameters ReadParams
;
628 int wrappedPartStart
;
629 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
630 &ReadParams
, sizeof(GLushort
));
631 if (ReadParams
.firstWrappedX
<= x
) {
632 wrappedPartStart
= 0;
634 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
635 wrappedPartStart
= n
;
638 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
640 for (i
= 0; i
< wrappedPartStart
; i
++) {
641 if (mask
[i
] && visMask
[i
]) {
643 PUT_ORDINARY_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
, d16
);
647 if (mask
[i
] && visMask
[i
]) {
649 PUT_WRAPPED_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
, d16
);
653 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
657 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
659 * Note that the _LOCK macro adds a curly brace,
660 * and the UNLOCK macro removes it.
662 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
,
663 GR_LFBWRITEMODE_ANY
);
664 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
666 LFBParameters ReadParams
;
667 int wrappedPartStart
;
668 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
669 &ReadParams
, sizeof(GLuint
));
670 if (ReadParams
.firstWrappedX
<= x
) {
671 wrappedPartStart
= 0;
673 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
674 wrappedPartStart
= n
;
677 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
679 for (i
= 0; i
< wrappedPartStart
; i
++) {
681 if (mask
[i
] && visMask
[i
]) {
682 if (stencil_size
> 0) {
684 GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
687 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
692 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
697 if (mask
[i
] && visMask
[i
]) {
698 if (stencil_size
> 0) {
700 GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
703 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
708 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
712 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
720 GrLfbInfo_t backBufferInfo
;
722 switch (depth_size
) {
724 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
726 * Note that the _LOCK macro adds a curly brace,
727 * and the UNLOCK macro removes it.
729 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
730 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
731 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
733 LFBParameters ReadParams
;
734 GLuint wrappedPartStart
;
735 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
736 &ReadParams
, sizeof(GLushort
));
737 if (ReadParams
.firstWrappedX
<= x
) {
738 wrappedPartStart
= 0;
740 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
741 wrappedPartStart
= n
;
744 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
746 for (i
= 0; i
< wrappedPartStart
; i
++) {
749 PUT_ORDINARY_FB_DATA(&ReadParams
,
758 PUT_WRAPPED_FB_DATA(&ReadParams
,
765 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
769 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
771 * Note that the _LOCK macro adds a curly brace,
772 * and the UNLOCK macro removes it.
774 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
775 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
776 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
778 LFBParameters ReadParams
;
779 GLuint wrappedPartStart
;
781 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
782 &ReadParams
, sizeof(GLuint
));
783 if (ReadParams
.firstWrappedX
<= x
) {
784 wrappedPartStart
= 0;
786 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
787 wrappedPartStart
= n
;
790 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
792 for (i
= 0; i
< wrappedPartStart
; i
++) {
794 if (stencil_size
> 0) {
795 d32
= GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
797 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
802 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
807 if (stencil_size
> 0) {
808 d32
= GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
810 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
815 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
819 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
826 tdfxDDWriteMonoDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
827 GLuint n
, GLint x
, GLint y
, const void *value
,
828 const GLubyte mask
[])
830 GLuint depthVal
= *((GLuint
*) value
);
831 GLuint depths
[MAX_WIDTH
];
833 for (i
= 0; i
< n
; i
++)
834 depths
[i
] = depthVal
;
835 tdfxDDWriteDepthSpan(ctx
, rb
, n
, x
, y
, depths
, mask
);
840 tdfxDDReadDepthSpan(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
841 GLuint n
, GLint x
, GLint y
, void *values
)
843 GLuint
*depth
= (GLuint
*) values
;
844 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
845 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
847 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
850 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
851 fprintf(stderr
, "tdfxmesa: tdfxDDReadDepthSpan(...)\n");
855 * Convert to screen coordinates.
857 x
+= fxMesa
->x_offset
;
859 switch (depth_size
) {
862 LFBParameters ReadParams
;
863 GrLfbInfo_t backBufferInfo
;
864 int wrappedPartStart
;
865 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
867 * Note that the _LOCK macro adds a curly brace,
868 * and the UNLOCK macro removes it.
870 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
871 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
872 &ReadParams
, sizeof(GLushort
));
873 if (ReadParams
.firstWrappedX
<= x
) {
874 wrappedPartStart
= 0;
876 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
877 wrappedPartStart
= n
;
880 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
885 for (i
= 0; i
< wrappedPartStart
; i
++) {
887 GET_ORDINARY_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
);
890 depth
[i
] = GET_WRAPPED_FB_DATA(&ReadParams
, GLushort
,
893 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
899 LFBParameters ReadParams
;
900 GrLfbInfo_t backBufferInfo
;
901 int wrappedPartStart
;
902 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
903 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
905 * Note that the _LOCK macro adds a curly brace,
906 * and the UNLOCK macro removes it.
908 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
909 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
910 &ReadParams
, sizeof(GLuint
));
911 if (ReadParams
.firstWrappedX
<= x
) {
912 wrappedPartStart
= 0;
914 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
915 wrappedPartStart
= n
;
918 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
923 for (i
= 0; i
< wrappedPartStart
; i
++) {
925 (stencil_size
> 0) ? 0x00FFFFFF : 0xFFFFFFFF;
927 GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
932 (stencil_size
> 0) ? 0x00FFFFFF : 0xFFFFFFFF;
933 depth
[i
] = GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
936 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
944 tdfxDDWriteDepthPixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
945 GLuint n
, const GLint x
[], const GLint y
[],
946 const void *values
, const GLubyte mask
[])
948 const GLuint
*depth
= (const GLuint
*) values
;
949 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
950 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
954 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
955 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
959 GrLfbInfo_t backBufferInfo
;
961 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
962 fprintf(stderr
, "tdfxmesa: tdfxDDWriteDepthPixels(...)\n");
965 switch (depth_size
) {
967 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
969 * Note that the _LOCK macro adds a curly brace,
970 * and the UNLOCK macro removes it.
972 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
973 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
975 LFBParameters ReadParams
;
976 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
977 &ReadParams
, sizeof(GLushort
));
978 for (i
= 0; i
< n
; i
++) {
979 if (mask
[i
] && visible_pixel(fxMesa
, x
[i
], y
[i
])) {
980 xpos
= x
[i
] + fxMesa
->x_offset
;
981 ypos
= bottom
- y
[i
];
983 PUT_FB_DATA(&ReadParams
, GLushort
, xpos
, ypos
, d16
);
987 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
991 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
993 * Note that the _LOCK macro adds a curly brace,
994 * and the UNLOCK macro removes it.
996 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
997 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
999 LFBParameters ReadParams
;
1000 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1001 &ReadParams
, sizeof(GLuint
));
1002 for (i
= 0; i
< n
; i
++) {
1004 if (visible_pixel(fxMesa
, x
[i
], y
[i
])) {
1005 xpos
= x
[i
] + fxMesa
->x_offset
;
1006 ypos
= bottom
- y
[i
];
1007 if (stencil_size
> 0) {
1009 GET_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
);
1010 d32
= (d32
& 0xFF000000) | (depth
[i
] & 0xFFFFFF);
1015 PUT_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
, d32
);
1020 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1027 tdfxDDReadDepthPixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
, GLuint n
,
1028 const GLint x
[], const GLint y
[], void *values
)
1030 GLuint
*depth
= (GLuint
*) values
;
1031 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
1032 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
1034 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
1039 GLuint stencil_size
;
1040 GrLfbInfo_t backBufferInfo
;
1042 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
1043 fprintf(stderr
, "tdfxmesa: tdfxDDReadDepthPixels(...)\n");
1046 assert((depth_size
== 16) || (depth_size
== 24) || (depth_size
== 32));
1047 switch (depth_size
) {
1049 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1051 * Note that the _LOCK macro adds a curly brace,
1052 * and the UNLOCK macro removes it.
1054 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1056 LFBParameters ReadParams
;
1057 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1058 &ReadParams
, sizeof(GLushort
));
1059 for (i
= 0; i
< n
; i
++) {
1061 * Convert to screen coordinates.
1063 xpos
= x
[i
] + fxMesa
->x_offset
;
1064 ypos
= bottom
- y
[i
];
1065 d16
= GET_FB_DATA(&ReadParams
, GLushort
, xpos
, ypos
);
1069 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1073 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1075 * Note that the _LOCK macro adds a curly brace,
1076 * and the UNLOCK macro removes it.
1078 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1079 stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
1081 LFBParameters ReadParams
;
1082 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1083 &ReadParams
, sizeof(GLuint
));
1084 for (i
= 0; i
< n
; i
++) {
1088 * Convert to screen coordinates.
1090 xpos
= x
[i
] + fxMesa
->x_offset
;
1091 ypos
= bottom
- y
[i
];
1092 d32
= GET_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
);
1093 if (stencil_size
> 0) {
1099 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1107 * Stencil buffer read/write functions.
1109 #define EXTRACT_S_FROM_ZS(zs) (((zs) >> 24) & 0xFF)
1110 #define EXTRACT_Z_FROM_ZS(zs) ((zs) & 0xffffff)
1111 #define BUILD_ZS(z, s) (((s) << 24) | (z))
1114 write_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1115 GLuint n
, GLint x
, GLint y
,
1116 const void *values
, const GLubyte mask
[])
1118 const GLubyte
*stencil
= (const GLubyte
*) values
;
1119 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1121 GrLfbInfo_t backBufferInfo
;
1123 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1125 * Note that the _LOCK macro adds a curly brace,
1126 * and the UNLOCK macro removes it.
1128 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1130 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1131 const GLint winX
= fxMesa
->x_offset
;
1132 const GLint scrX
= winX
+ x
;
1133 const GLint scrY
= winY
- y
;
1134 LFBParameters ReadParams
;
1135 GLubyte visMask
[MAX_WIDTH
];
1137 int wrappedPartStart
;
1139 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1141 if (ReadParams
.firstWrappedX
<= x
) {
1142 wrappedPartStart
= 0;
1144 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
1145 wrappedPartStart
= n
;
1148 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
1150 generate_vismask(fxMesa
, scrX
, scrY
, n
, visMask
);
1151 for (i
= 0; i
< wrappedPartStart
; i
++) {
1152 if (visMask
[i
] && (!mask
|| mask
[i
])) {
1153 GLuint z
= GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
1154 scrX
+ i
, scrY
) & 0x00FFFFFF;
1155 z
|= (stencil
[i
] & 0xFF) << 24;
1156 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, scrX
+ i
, scrY
, z
);
1159 for (; i
< n
; i
++) {
1160 if (visMask
[i
] && (!mask
|| mask
[i
])) {
1161 GLuint z
= GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
1162 scrX
+ i
, scrY
) & 0x00FFFFFF;
1163 z
|= (stencil
[i
] & 0xFF) << 24;
1164 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, scrX
+ i
, scrY
, z
);
1168 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1173 write_mono_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1174 GLuint n
, GLint x
, GLint y
,
1175 const void *value
, const GLubyte mask
[])
1177 GLbyte stencilVal
= *((GLbyte
*) value
);
1178 GLbyte stencils
[MAX_WIDTH
];
1180 for (i
= 0; i
< n
; i
++)
1181 stencils
[i
] = stencilVal
;
1182 write_stencil_span(ctx
, rb
, n
, x
, y
, stencils
, mask
);
1187 read_stencil_span(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1188 GLuint n
, GLint x
, GLint y
,
1191 GLubyte
*stencil
= (GLubyte
*) values
;
1192 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1194 GrLfbInfo_t backBufferInfo
;
1196 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1198 * Note that the _LOCK macro adds a curly brace,
1199 * and the UNLOCK macro removes it.
1201 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1203 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1204 const GLint winX
= fxMesa
->x_offset
;
1206 LFBParameters ReadParams
;
1207 int wrappedPartStart
;
1210 * Convert to screen coordinates.
1214 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1216 if (ReadParams
.firstWrappedX
<= x
) {
1217 wrappedPartStart
= 0;
1219 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
1220 wrappedPartStart
= n
;
1223 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
1225 for (i
= 0; i
< wrappedPartStart
; i
++) {
1226 stencil
[i
] = (GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
1227 x
+ i
, y
) >> 24) & 0xFF;
1229 for (; i
< n
; i
++) {
1230 stencil
[i
] = (GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
1231 x
+ i
, y
) >> 24) & 0xFF;
1234 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1239 write_stencil_pixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1240 GLuint n
, const GLint x
[], const GLint y
[],
1241 const void *values
, const GLubyte mask
[])
1243 const GLubyte
*stencil
= (const GLubyte
*) values
;
1244 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1246 GrLfbInfo_t backBufferInfo
;
1248 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1250 * Note that the _LOCK macro adds a curly brace,
1251 * and the UNLOCK macro removes it.
1253 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1255 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1256 const GLint winX
= fxMesa
->x_offset
;
1257 LFBParameters ReadParams
;
1260 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1262 for (i
= 0; i
< n
; i
++) {
1263 const GLint scrX
= winX
+ x
[i
];
1264 const GLint scrY
= winY
- y
[i
];
1265 if ((!mask
|| mask
[i
]) && visible_pixel(fxMesa
, scrX
, scrY
)) {
1267 GET_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
) & 0x00FFFFFF;
1268 z
|= (stencil
[i
] & 0xFF) << 24;
1269 PUT_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
, z
);
1273 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1278 read_stencil_pixels(GLcontext
* ctx
, struct gl_renderbuffer
*rb
,
1279 GLuint n
, const GLint x
[], const GLint y
[],
1282 GLubyte
*stencil
= (GLubyte
*) values
;
1283 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1285 GrLfbInfo_t backBufferInfo
;
1287 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1289 * Note that the _LOCK macro adds a curly brace,
1290 * and the UNLOCK macro removes it.
1292 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1294 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1295 const GLint winX
= fxMesa
->x_offset
;
1297 LFBParameters ReadParams
;
1299 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1301 for (i
= 0; i
< n
; i
++) {
1302 const GLint scrX
= winX
+ x
[i
];
1303 const GLint scrY
= winY
- y
[i
];
1305 (GET_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
) >> 24) & 0xFF;
1308 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1311 #define VISUAL_EQUALS_RGBA(vis, r, g, b, a) \
1312 ((vis.redBits == r) && \
1313 (vis.greenBits == g) && \
1314 (vis.blueBits == b) && \
1315 (vis.alphaBits == a))
1320 /**********************************************************************/
1321 /* Locking for swrast */
1322 /**********************************************************************/
1325 static void tdfxSpanRenderStart( GLcontext
*ctx
)
1327 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1328 LOCK_HARDWARE(fxMesa
);
1331 static void tdfxSpanRenderFinish( GLcontext
*ctx
)
1333 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1334 _swrast_flush( ctx
);
1335 UNLOCK_HARDWARE(fxMesa
);
1338 /**********************************************************************/
1339 /* Initialize swrast device driver */
1340 /**********************************************************************/
1342 void tdfxDDInitSpanFuncs( GLcontext
*ctx
)
1344 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1345 swdd
->SpanRenderStart
= tdfxSpanRenderStart
;
1346 swdd
->SpanRenderFinish
= tdfxSpanRenderFinish
;
1352 * Plug in the Get/Put routines for the given driRenderbuffer.
1355 tdfxSetSpanFunctions(driRenderbuffer
*drb
, const GLvisual
*vis
)
1357 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
1358 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
1359 tdfxInitPointers_RGB565(&drb
->Base
);
1361 else if (vis
->redBits
== 8 && vis
->greenBits
== 8
1362 && vis
->blueBits
== 8 && vis
->alphaBits
== 0) {
1363 tdfxInitPointers_RGB888(&drb
->Base
);
1365 else if (vis
->redBits
== 8 && vis
->greenBits
== 8
1366 && vis
->blueBits
== 8 && vis
->alphaBits
== 8) {
1367 tdfxInitPointers_ARGB8888(&drb
->Base
);
1370 _mesa_problem(NULL
, "problem in tdfxSetSpanFunctions");
1373 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
||
1374 drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
1375 drb
->Base
.GetRow
= tdfxDDReadDepthSpan
;
1376 drb
->Base
.GetValues
= tdfxDDReadDepthPixels
;
1377 drb
->Base
.PutRow
= tdfxDDWriteDepthSpan
;
1378 drb
->Base
.PutMonoRow
= tdfxDDWriteMonoDepthSpan
;
1379 drb
->Base
.PutValues
= tdfxDDWriteDepthPixels
;
1380 drb
->Base
.PutMonoValues
= NULL
;
1382 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
1383 drb
->Base
.GetRow
= read_stencil_span
;
1384 drb
->Base
.GetValues
= read_stencil_pixels
;
1385 drb
->Base
.PutRow
= write_stencil_span
;
1386 drb
->Base
.PutMonoRow
= write_mono_stencil_span
;
1387 drb
->Base
.PutValues
= write_stencil_pixels
;
1388 drb
->Base
.PutMonoValues
= NULL
;