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
29 * Gareth Hughes <gareth@valinux.com>, 29 Sep - 1 Oct 2000
32 * Gareth Hughes <gareth@valinux.com>
33 * Brian Paul <brianp@valinux.com>
34 * Keith Whitwell <keith@tungstengraphics.com>
38 #include "tdfx_context.h"
39 #include "tdfx_lock.h"
40 #include "tdfx_span.h"
41 #include "tdfx_render.h"
42 #include "swrast/swrast.h"
49 driRenderbuffer *drb = (driRenderbuffer *) rb; \
50 __DRIdrawable *const dPriv = drb->dPriv; \
51 GLuint pitch = drb->backBuffer ? info.strideInBytes \
52 : (drb->pitch * drb->cpp); \
53 const GLuint bottom = dPriv->h - 1; \
54 char *buf = (char *)((char *)info.lfbPtr + \
55 (dPriv->x * drb->cpp) + \
56 (dPriv->y * pitch)); \
61 #define Y_FLIP(_y) (bottom - _y)
64 #define HW_WRITE_LOCK() \
65 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \
67 FLUSH_BATCH( fxMesa ); \
68 UNLOCK_HARDWARE( fxMesa ); \
69 LOCK_HARDWARE( fxMesa ); \
70 info.size = sizeof(GrLfbInfo_t); \
71 if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer, \
72 LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, \
75 #define HW_WRITE_UNLOCK() \
76 fxMesa->Glide.grLfbUnlock( GR_LFB_WRITE_ONLY, fxMesa->DrawBuffer );\
80 #define HW_READ_LOCK() \
81 tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); \
83 FLUSH_BATCH( fxMesa ); \
84 UNLOCK_HARDWARE( fxMesa ); \
85 LOCK_HARDWARE( fxMesa ); \
86 info.size = sizeof(GrLfbInfo_t); \
87 if ( fxMesa->Glide.grLfbLock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer, \
88 LFB_MODE, GR_ORIGIN_UPPER_LEFT, FXFALSE, &info ) ) \
91 #define HW_READ_UNLOCK() \
92 fxMesa->Glide.grLfbUnlock( GR_LFB_READ_ONLY, fxMesa->ReadBuffer );\
96 #define HW_WRITE_CLIPLOOP() \
98 int _nc = fxMesa->numClipRects; \
100 int minx = fxMesa->pClipRects[_nc].x1 - fxMesa->x_offset; \
101 int miny = fxMesa->pClipRects[_nc].y1 - fxMesa->y_offset; \
102 int maxx = fxMesa->pClipRects[_nc].x2 - fxMesa->x_offset; \
103 int maxy = fxMesa->pClipRects[_nc].y2 - fxMesa->y_offset;
105 #define HW_READ_CLIPLOOP() \
107 const __DRIdrawable *dPriv = fxMesa->driDrawable; \
108 drm_clip_rect_t *rect = dPriv->pClipRects; \
109 int _nc = dPriv->numClipRects; \
111 const int minx = rect->x1 - fxMesa->x_offset; \
112 const int miny = rect->y1 - fxMesa->y_offset; \
113 const int maxx = rect->x2 - fxMesa->x_offset; \
114 const int maxy = rect->y2 - fxMesa->y_offset; \
117 #define HW_ENDCLIPLOOP() \
123 #define LFB_MODE GR_LFBWRITEMODE_565
126 /* 16 bit, RGB565 color spanline and pixel functions */ \
128 #undef INIT_MONO_PIXEL
129 #define INIT_MONO_PIXEL(p, color) \
130 p = TDFXPACKCOLOR565( color[0], color[1], color[2] )
133 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
134 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \
135 (((int)g & 0xfc) << 3) | \
136 (((int)b & 0xf8) >> 3))
138 #define WRITE_PIXEL( _x, _y, p ) \
139 *(GLushort *)(buf + _x*2 + _y*pitch) = p
141 #define READ_RGBA( rgba, _x, _y ) \
143 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
144 rgba[0] = (((p >> 11) & 0x1f) * 255) / 31; \
145 rgba[1] = (((p >> 5) & 0x3f) * 255) / 63; \
146 rgba[2] = (((p >> 0) & 0x1f) * 255) / 31; \
150 #define TAG(x) tdfx##x##_RGB565
151 #define BYTESPERPIXEL 2
156 /* 16 bit, BGR565 color spanline and pixel functions */ \
159 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
160 *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)b & 0xf8) << 8) | \
161 (((int)g & 0xfc) << 3) | \
162 (((int)r & 0xf8) >> 3))
164 #define WRITE_PIXEL( _x, _y, p ) \
165 *(GLushort *)(buf + _x*2 + _y*pitch) = p
167 #define READ_RGBA( rgba, _x, _y ) \
169 GLushort p = *(GLushort *)(buf + _x*2 + _y*pitch); \
170 rgba[0] = (p << 3) & 0xf8; \
171 rgba[1] = (p >> 3) & 0xfc; \
172 rgba[2] = (p >> 8) & 0xf8; \
176 #define TAG(x) tdfx##x##_BGR565
177 #define BYTESPERPIXEL 2
184 #define LFB_MODE GR_LFBWRITEMODE_888
187 /* 24 bit, RGB888 color spanline and pixel functions */
188 #undef INIT_MONO_PIXEL
189 #define INIT_MONO_PIXEL(p, color) \
190 p = TDFXPACKCOLOR888( color[0], color[1], color[2] )
192 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
193 *(GLuint *)(buf + _x*3 + _y*pitch) = ((b << 0) | \
197 #define WRITE_PIXEL( _x, _y, p ) \
198 *(GLuint *)(buf + _x*3 + _y*pitch) = p
200 #define READ_RGBA( rgba, _x, _y ) \
202 GLuint p = *(GLuint *)(buf + _x*3 + _y*pitch); \
203 rgba[0] = (p >> 16) & 0xff; \
204 rgba[1] = (p >> 8) & 0xff; \
205 rgba[2] = (p >> 0) & 0xff; \
209 #define TAG(x) tdfx##x##_RGB888
210 #define BYTESPERPIXEL 4
216 #define LFB_MODE GR_LFBWRITEMODE_8888
219 /* 32 bit, ARGB8888 color spanline and pixel functions */
220 #undef INIT_MONO_PIXEL
221 #define INIT_MONO_PIXEL(p, color) \
222 p = TDFXPACKCOLOR8888( color[0], color[1], color[2], color[3] )
224 #define WRITE_RGBA( _x, _y, r, g, b, a ) \
225 *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \
230 #define WRITE_PIXEL( _x, _y, p ) \
231 *(GLuint *)(buf + _x*4 + _y*pitch) = p
233 #define READ_RGBA( rgba, _x, _y ) \
235 GLuint p = *(GLuint *)(buf + _x*4 + _y*pitch); \
236 rgba[0] = (p >> 16) & 0xff; \
237 rgba[1] = (p >> 8) & 0xff; \
238 rgba[2] = (p >> 0) & 0xff; \
239 rgba[3] = (p >> 24) & 0xff; \
242 #define TAG(x) tdfx##x##_ARGB8888
243 #define BYTESPERPIXEL 4
249 /* ================================================================
250 * Old span functions below...
255 * Examine the cliprects to generate an array of flags to indicate
256 * which pixels in a span are visible. Note: (x,y) is a screen
260 generate_vismask(const tdfxContextPtr fxMesa
, GLint x
, GLint y
, GLint n
,
263 GLboolean initialized
= GL_FALSE
;
266 /* Ensure we clear the visual mask */
267 memset(vismask
, 0, n
);
269 /* turn on flags for all visible pixels */
270 for (i
= 0; i
< fxMesa
->numClipRects
; i
++) {
271 const drm_clip_rect_t
*rect
= &fxMesa
->pClipRects
[i
];
273 if (y
>= rect
->y1
&& y
< rect
->y2
) {
274 if (x
>= rect
->x1
&& x
+ n
<= rect
->x2
) {
275 /* common case, whole span inside cliprect */
276 memset(vismask
, 1, n
);
279 if (x
< rect
->x2
&& x
+ n
>= rect
->x1
) {
280 /* some of the span is inside the rect */
283 memset(vismask
, 0, n
);
284 initialized
= GL_TRUE
;
287 start
= rect
->x1
- x
;
290 if (x
+ n
> rect
->x2
)
296 for (j
= start
; j
< end
; j
++)
304 * Examine cliprects and determine if the given screen pixel is visible.
307 visible_pixel(const tdfxContextPtr fxMesa
, int scrX
, int scrY
)
310 for (i
= 0; i
< fxMesa
->numClipRects
; i
++) {
311 const drm_clip_rect_t
*rect
= &fxMesa
->pClipRects
[i
];
312 if (scrX
>= rect
->x1
&&
314 scrY
>= rect
->y1
&& scrY
< rect
->y2
) return GL_TRUE
;
322 * Depth buffer read/write functions.
325 * To read the frame buffer, we need to lock and unlock it. The
326 * four macros {READ,WRITE}_FB_SPAN_{LOCK,UNLOCK}
329 * Note that the lock must be matched with an unlock. These
330 * macros include a spare curly brace, so they must
331 * be syntactically matched.
333 * Note, also, that you can't lock a buffer twice with different
334 * modes. That is to say, you can't lock a buffer in both read
335 * and write modes. The strideInBytes and LFB pointer will be
336 * the same with read and write locks, so you can use either.
337 * o The HW has different state for reads and writes, so
338 * locking it twice may give screwy results.
339 * o The DRM won't let you lock twice. It hangs. This is probably
340 * because of the LOCK_HARDWARE IN THE *_FB_SPAN_LOCK macros,
341 * and could be eliminated with nonlocking lock routines. But
342 * what's the point after all.
344 #define READ_FB_SPAN_LOCK(fxMesa, info, target_buffer) \
345 UNLOCK_HARDWARE(fxMesa); \
346 LOCK_HARDWARE(fxMesa); \
347 (info).size=sizeof(info); \
348 if (fxMesa->Glide.grLfbLock(GR_LFB_READ_ONLY, \
350 GR_LFBWRITEMODE_ANY, \
351 GR_ORIGIN_UPPER_LEFT, \
355 #define READ_FB_SPAN_UNLOCK(fxMesa, target_buffer) \
356 fxMesa->Glide.grLfbUnlock(GR_LFB_READ_ONLY, target_buffer); \
358 fprintf(stderr, "tdfxDriver: Can't get %s (%d) read lock\n", \
359 (target_buffer == GR_BUFFER_BACKBUFFER) \
361 : ((target_buffer == GR_BUFFER_AUXBUFFER) \
363 : "unknown buffer"), \
367 #define WRITE_FB_SPAN_LOCK(fxMesa, info, target_buffer, write_mode) \
368 UNLOCK_HARDWARE(fxMesa); \
369 LOCK_HARDWARE(fxMesa); \
370 info.size=sizeof(info); \
371 if (fxMesa->Glide.grLfbLock(GR_LFB_WRITE_ONLY, \
374 GR_ORIGIN_UPPER_LEFT, \
378 #define WRITE_FB_SPAN_UNLOCK(fxMesa, target_buffer) \
379 fxMesa->Glide.grLfbUnlock(GR_LFB_WRITE_ONLY, target_buffer); \
381 fprintf(stderr, "tdfxDriver: Can't get %s (%d) write lock\n", \
382 (target_buffer == GR_BUFFER_BACKBUFFER) \
384 : ((target_buffer == GR_BUFFER_AUXBUFFER) \
386 : "unknown buffer"), \
391 * Because the Linear Frame Buffer is not necessarily aligned
392 * with the depth buffer, we have to do some fiddling
393 * around to get the right addresses.
395 * Perhaps a picture is in order. The Linear Frame Buffer
398 * |<----------------------info.strideInBytes------------->|
399 * |<-----physicalStrideInBytes------->|
400 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
402 * | Legal Memory | Forbidden Zone |
404 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
406 * You can only reliably read and write legal locations. Reads
407 * and writes from the Forbidden Zone will return undefined values,
408 * and may cause segmentation faults.
410 * Now, the depth buffer may not end up in a location such each
411 * scan line is an LFB line. For example, the depth buffer may
415 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
416 * |0000000000000000000000 | | back
417 * |1111111111111111111111 | | buffer
418 * |2222222222222222222222 | |
419 * |4096b align. padxx00000000000000000| Forbidden Zone | depth
420 * |0000 11111111111111111| | buffer
421 * |1111 22222222222222222| |
423 * +-----------------------------------+xxxxxxxxxxxxxxxxxxx+
424 * where each number is the scan line number. We know it will
425 * be aligned on 128 byte boundaries, at least. Aligning this
426 * on a scanline boundary causes the back and depth buffers to
427 * thrash in the SST1 cache. (Note that the back buffer is always
428 * allocated at the beginning of LFB memory, and so it is always
429 * properly aligned with the LFB stride.)
431 * We call the beginning of the line (which is the rightmost
432 * part of the depth line in the picture above) the *ordinary* part
433 * of the scanline, and the end of the line (which is the
434 * leftmost part, one line below) the *wrapped* part of the scanline.
435 * a.) We need to know what x value to subtract from the screen
436 * x coordinate to index into the wrapped part.
437 * b.) We also need to figure out if we need to read from the ordinary
438 * part scan line, or from the wrapped part of the scan line.
441 * The first wrapped x coordinate is that coordinate such that
442 * depthBufferOffset&(info.strideInBytes) + x*elmentSize {*}
443 * > physicalStrideInBytes
444 * where depthBufferOffset is the LFB distance in bytes
445 * from the back buffer to the depth buffer. The expression
446 * depthBufferOffset&(info.strideInBytes)
447 * is then the offset (in bytes) from the beginining of (any)
448 * depth buffer line to first element in the line.
449 * Simplifying inequation {*} above we see that x is the smallest
451 * x*elementSize > physicalStrideInBytes {**}
452 * - depthBufferOffset&(info.strideInBytes)
453 * Now, we know that both the summands on the right are multiples of
454 * 128, and elementSize <= 4, so if equality holds in {**}, x would
455 * be a multiple of 32. Thus we can set x to
456 * xwrapped = (physicalStrideInBytes
457 * - depthBufferOffset&(info.strideInBytes))/elementSize
461 * Question b is now simple. We read from the wrapped scan line if
462 * x is greater than xwrapped.
464 #define TILE_WIDTH_IN_BYTES 128
465 #define TILE_WIDTH_IN_ZOXELS(bpz) (TILE_WIDTH_IN_BYTES/(bpz))
466 #define TILE_HEIGHT_IN_LINES 32
471 FxU32 LFBStrideInElts
;
477 * We need information about the back buffer. Note that
478 * this function *cannot be called* while the aux buffer
479 * is locked, or the caller will hang.
481 * Only Glide knows the LFB address of the back and depth
482 * offsets. The upper levels of Mesa know the depth offset,
483 * but that is not in LFB space, it is tiled memory space,
484 * and is not useable for us.
487 GetBackBufferInfo(tdfxContextPtr fxMesa
, GrLfbInfo_t
* backBufferInfo
)
489 READ_FB_SPAN_LOCK(fxMesa
, *backBufferInfo
, GR_BUFFER_BACKBUFFER
);
490 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_BACKBUFFER
);
494 GetFbParams(tdfxContextPtr fxMesa
,
496 GrLfbInfo_t
* backBufferInfo
,
497 LFBParameters
* ReadParamsp
, FxU32 elementSize
)
499 FxU32 physicalStrideInBytes
, bufferOffset
;
500 FxU32 strideInBytes
= info
->strideInBytes
;
501 char *lfbPtr
= (char *) (info
->lfbPtr
); /* For arithmetic, use char * */
504 * These two come directly from the info structure.
506 ReadParamsp
->lfbPtr
= (void *) lfbPtr
;
507 ReadParamsp
->LFBStrideInElts
= strideInBytes
/ elementSize
;
509 * Now, calculate the value of firstWrappedX.
511 * The physical stride is the screen width in bytes rounded up to
512 * the next highest multiple of 128 bytes. Note that this fails
513 * when TILE_WIDTH_IN_BYTES is not a power of two.
515 * The buffer Offset is the distance between the beginning of
516 * the LFB space, which is the beginning of the back buffer,
517 * and the buffer we are gathering information about.
518 * We want to make this routine usable for operations on the
519 * back buffer, though we don't actually use it on the back
520 * buffer. Note, then, that if bufferOffset == 0, the firstWrappedX
521 * is in the forbidden zone, and is therefore never reached.
524 * physicalStrideInBytes
525 * < bufferOffset&(info->strideInBytes-1)
526 * the buffer begins in the forbidden zone. We assert for this.
528 bufferOffset
= (FxU32
)(lfbPtr
- (char *) backBufferInfo
->lfbPtr
);
529 physicalStrideInBytes
530 = (fxMesa
->screen_width
* elementSize
+ TILE_WIDTH_IN_BYTES
- 1)
531 & ~(TILE_WIDTH_IN_BYTES
- 1);
532 assert(physicalStrideInBytes
> (bufferOffset
& (strideInBytes
- 1)));
533 ReadParamsp
->firstWrappedX
534 = (physicalStrideInBytes
535 - (bufferOffset
& (strideInBytes
- 1))) / elementSize
;
537 * This is the address of the next physical line.
539 ReadParamsp
->lfbWrapPtr
540 = (void *) ((char *) backBufferInfo
->lfbPtr
541 + (bufferOffset
& ~(strideInBytes
- 1))
542 + (TILE_HEIGHT_IN_LINES
) * strideInBytes
);
546 * These macros fetch data from the frame buffer. The type is
547 * the type of data we want to fetch. It should match the type
548 * whose size was used with GetFbParams to fill in the structure
549 * in *ReadParamsp. We have a macro to read the ordinary
550 * part, a second macro to read the wrapped part, and one which
551 * will do either. When we are reading a span, we will know
552 * when the ordinary part ends, so there's no need to test for
553 * it. However, when reading and writing pixels, we don't
554 * necessarily know. I suppose it's a matter of taste whether
555 * it's better in the macro or in the call.
557 * Recall that x and y are screen coordinates.
559 #define GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \
560 (((type *)((ReadParamsp)->lfbPtr)) \
561 [(y) * ((ReadParamsp)->LFBStrideInElts) \
563 #define GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) \
564 (((type *)((ReadParamsp)->lfbWrapPtr)) \
565 [((y)) * ((ReadParamsp)->LFBStrideInElts) \
566 + ((x) - (ReadParamsp)->firstWrappedX)])
567 #define GET_FB_DATA(ReadParamsp, type, x, y) \
568 (((x) < (ReadParamsp)->firstWrappedX) \
569 ? GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) \
570 : GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y))
571 #define PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value) \
572 (GET_ORDINARY_FB_DATA(ReadParamsp, type, x, y) = (type)(value))
573 #define PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value) \
574 (GET_WRAPPED_FB_DATA(ReadParamsp, type, x, y) = (type)(value))
575 #define PUT_FB_DATA(ReadParamsp, type, x, y, value) \
577 if ((x) < (ReadParamsp)->firstWrappedX) \
578 PUT_ORDINARY_FB_DATA(ReadParamsp, type, x, y, value); \
580 PUT_WRAPPED_FB_DATA(ReadParamsp, type, x, y, value); \
585 tdfxDDWriteDepthSpan(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
586 GLuint n
, GLint x
, GLint y
, const void *values
,
587 const GLubyte mask
[])
589 const GLuint
*depth
= (const GLuint
*) values
;
590 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
591 GLint bottom
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
592 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
593 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
595 GLubyte visMask
[MAX_WIDTH
];
597 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
598 fprintf(stderr
, "tdfxmesa: tdfxDDWriteDepthSpan(...)\n");
601 assert((depth_size
== 16) || (depth_size
== 24) || (depth_size
== 32));
603 * Convert x and y to screen coordinates.
605 x
+= fxMesa
->x_offset
;
610 GrLfbInfo_t backBufferInfo
;
612 switch (depth_size
) {
614 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
616 * Note that the _LOCK macro adds a curly brace,
617 * and the UNLOCK macro removes it.
619 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
,
620 GR_LFBWRITEMODE_ANY
);
621 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
623 LFBParameters ReadParams
;
624 int wrappedPartStart
;
625 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
626 &ReadParams
, sizeof(GLushort
));
627 if (ReadParams
.firstWrappedX
<= x
) {
628 wrappedPartStart
= 0;
630 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
631 wrappedPartStart
= n
;
634 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
636 for (i
= 0; i
< wrappedPartStart
; i
++) {
637 if (mask
[i
] && visMask
[i
]) {
639 PUT_ORDINARY_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
, d16
);
643 if (mask
[i
] && visMask
[i
]) {
645 PUT_WRAPPED_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
, d16
);
649 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
653 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
655 * Note that the _LOCK macro adds a curly brace,
656 * and the UNLOCK macro removes it.
658 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
,
659 GR_LFBWRITEMODE_ANY
);
660 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
662 LFBParameters ReadParams
;
663 int wrappedPartStart
;
664 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
665 &ReadParams
, sizeof(GLuint
));
666 if (ReadParams
.firstWrappedX
<= x
) {
667 wrappedPartStart
= 0;
669 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
670 wrappedPartStart
= n
;
673 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
675 for (i
= 0; i
< wrappedPartStart
; i
++) {
677 if (mask
[i
] && visMask
[i
]) {
678 if (stencil_size
> 0) {
680 GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
683 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
688 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
693 if (mask
[i
] && visMask
[i
]) {
694 if (stencil_size
> 0) {
696 GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
699 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
704 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
708 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
716 GrLfbInfo_t backBufferInfo
;
718 switch (depth_size
) {
720 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
722 * Note that the _LOCK macro adds a curly brace,
723 * and the UNLOCK macro removes it.
725 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
726 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
727 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
729 LFBParameters ReadParams
;
730 GLuint wrappedPartStart
;
731 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
732 &ReadParams
, sizeof(GLushort
));
733 if (ReadParams
.firstWrappedX
<= x
) {
734 wrappedPartStart
= 0;
736 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
737 wrappedPartStart
= n
;
740 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
742 for (i
= 0; i
< wrappedPartStart
; i
++) {
745 PUT_ORDINARY_FB_DATA(&ReadParams
,
754 PUT_WRAPPED_FB_DATA(&ReadParams
,
761 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
765 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
767 * Note that the _LOCK macro adds a curly brace,
768 * and the UNLOCK macro removes it.
770 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
771 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
772 generate_vismask(fxMesa
, x
, y
, n
, visMask
);
774 LFBParameters ReadParams
;
775 GLuint wrappedPartStart
;
777 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
778 &ReadParams
, sizeof(GLuint
));
779 if (ReadParams
.firstWrappedX
<= x
) {
780 wrappedPartStart
= 0;
782 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
783 wrappedPartStart
= n
;
786 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
788 for (i
= 0; i
< wrappedPartStart
; i
++) {
790 if (stencil_size
> 0) {
791 d32
= GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
793 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
798 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
803 if (stencil_size
> 0) {
804 d32
= GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
806 (d32
& 0xFF000000) | (depth
[i
] & 0x00FFFFFF);
811 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
, d32
);
815 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
822 tdfxDDWriteMonoDepthSpan(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
823 GLuint n
, GLint x
, GLint y
, const void *value
,
824 const GLubyte mask
[])
826 GLuint depthVal
= *((GLuint
*) value
);
827 GLuint depths
[MAX_WIDTH
];
829 for (i
= 0; i
< n
; i
++)
830 depths
[i
] = depthVal
;
831 tdfxDDWriteDepthSpan(ctx
, rb
, n
, x
, y
, depths
, mask
);
836 tdfxDDReadDepthSpan(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
837 GLuint n
, GLint x
, GLint y
, void *values
)
839 GLuint
*depth
= (GLuint
*) values
;
840 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
841 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
843 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
846 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
847 fprintf(stderr
, "tdfxmesa: tdfxDDReadDepthSpan(...)\n");
851 * Convert to screen coordinates.
853 x
+= fxMesa
->x_offset
;
855 switch (depth_size
) {
858 LFBParameters ReadParams
;
859 GrLfbInfo_t backBufferInfo
;
860 int wrappedPartStart
;
861 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
863 * Note that the _LOCK macro adds a curly brace,
864 * and the UNLOCK macro removes it.
866 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
867 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
868 &ReadParams
, sizeof(GLushort
));
869 if (ReadParams
.firstWrappedX
<= x
) {
870 wrappedPartStart
= 0;
872 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
873 wrappedPartStart
= n
;
876 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
881 for (i
= 0; i
< wrappedPartStart
; i
++) {
883 GET_ORDINARY_FB_DATA(&ReadParams
, GLushort
, x
+ i
, y
);
886 depth
[i
] = GET_WRAPPED_FB_DATA(&ReadParams
, GLushort
,
889 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
895 LFBParameters ReadParams
;
896 GrLfbInfo_t backBufferInfo
;
897 int wrappedPartStart
;
898 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
899 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
901 * Note that the _LOCK macro adds a curly brace,
902 * and the UNLOCK macro removes it.
904 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
905 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
906 &ReadParams
, sizeof(GLuint
));
907 if (ReadParams
.firstWrappedX
<= x
) {
908 wrappedPartStart
= 0;
910 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
911 wrappedPartStart
= n
;
914 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
919 for (i
= 0; i
< wrappedPartStart
; i
++) {
921 (stencil_size
> 0) ? 0x00FFFFFF : 0xFFFFFFFF;
923 GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
928 (stencil_size
> 0) ? 0x00FFFFFF : 0xFFFFFFFF;
929 depth
[i
] = GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
, x
+ i
, y
);
932 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
940 tdfxDDWriteDepthPixels(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
941 GLuint n
, const GLint x
[], const GLint y
[],
942 const void *values
, const GLubyte mask
[])
944 const GLuint
*depth
= (const GLuint
*) values
;
945 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
946 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
950 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
951 GLuint stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
955 GrLfbInfo_t backBufferInfo
;
957 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
958 fprintf(stderr
, "tdfxmesa: tdfxDDWriteDepthPixels(...)\n");
961 switch (depth_size
) {
963 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
965 * Note that the _LOCK macro adds a curly brace,
966 * and the UNLOCK macro removes it.
968 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
969 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
971 LFBParameters ReadParams
;
972 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
973 &ReadParams
, sizeof(GLushort
));
974 for (i
= 0; i
< n
; i
++) {
975 if ((!mask
|| mask
[i
]) && visible_pixel(fxMesa
, x
[i
], y
[i
])) {
976 xpos
= x
[i
] + fxMesa
->x_offset
;
977 ypos
= bottom
- y
[i
];
979 PUT_FB_DATA(&ReadParams
, GLushort
, xpos
, ypos
, d16
);
983 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
987 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
989 * Note that the _LOCK macro adds a curly brace,
990 * and the UNLOCK macro removes it.
992 WRITE_FB_SPAN_LOCK(fxMesa
, info
,
993 GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
995 LFBParameters ReadParams
;
996 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
997 &ReadParams
, sizeof(GLuint
));
998 for (i
= 0; i
< n
; i
++) {
999 if (!mask
|| mask
[i
]) {
1000 if (visible_pixel(fxMesa
, x
[i
], y
[i
])) {
1001 xpos
= x
[i
] + fxMesa
->x_offset
;
1002 ypos
= bottom
- y
[i
];
1003 if (stencil_size
> 0) {
1005 GET_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
);
1006 d32
= (d32
& 0xFF000000) | (depth
[i
] & 0xFFFFFF);
1011 PUT_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
, d32
);
1016 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1023 tdfxDDReadDepthPixels(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
, GLuint n
,
1024 const GLint x
[], const GLint y
[], void *values
)
1026 GLuint
*depth
= (GLuint
*) values
;
1027 tdfxContextPtr fxMesa
= (tdfxContextPtr
) ctx
->DriverCtx
;
1028 GLint bottom
= fxMesa
->height
+ fxMesa
->y_offset
- 1;
1030 GLuint depth_size
= fxMesa
->glCtx
->Visual
.depthBits
;
1035 GLuint stencil_size
;
1036 GrLfbInfo_t backBufferInfo
;
1038 if (MESA_VERBOSE
& VERBOSE_DRIVER
) {
1039 fprintf(stderr
, "tdfxmesa: tdfxDDReadDepthPixels(...)\n");
1042 assert((depth_size
== 16) || (depth_size
== 24) || (depth_size
== 32));
1043 switch (depth_size
) {
1045 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1047 * Note that the _LOCK macro adds a curly brace,
1048 * and the UNLOCK macro removes it.
1050 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1052 LFBParameters ReadParams
;
1053 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1054 &ReadParams
, sizeof(GLushort
));
1055 for (i
= 0; i
< n
; i
++) {
1057 * Convert to screen coordinates.
1059 xpos
= x
[i
] + fxMesa
->x_offset
;
1060 ypos
= bottom
- y
[i
];
1061 d16
= GET_FB_DATA(&ReadParams
, GLushort
, xpos
, ypos
);
1065 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1069 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1071 * Note that the _LOCK macro adds a curly brace,
1072 * and the UNLOCK macro removes it.
1074 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1075 stencil_size
= fxMesa
->glCtx
->Visual
.stencilBits
;
1077 LFBParameters ReadParams
;
1078 GetFbParams(fxMesa
, &info
, &backBufferInfo
,
1079 &ReadParams
, sizeof(GLuint
));
1080 for (i
= 0; i
< n
; i
++) {
1084 * Convert to screen coordinates.
1086 xpos
= x
[i
] + fxMesa
->x_offset
;
1087 ypos
= bottom
- y
[i
];
1088 d32
= GET_FB_DATA(&ReadParams
, GLuint
, xpos
, ypos
);
1089 if (stencil_size
> 0) {
1095 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1103 * Stencil buffer read/write functions.
1105 #define EXTRACT_S_FROM_ZS(zs) (((zs) >> 24) & 0xFF)
1106 #define EXTRACT_Z_FROM_ZS(zs) ((zs) & 0xffffff)
1107 #define BUILD_ZS(z, s) (((s) << 24) | (z))
1110 write_stencil_span(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
1111 GLuint n
, GLint x
, GLint y
,
1112 const void *values
, const GLubyte mask
[])
1114 const GLubyte
*stencil
= (const GLubyte
*) values
;
1115 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1117 GrLfbInfo_t backBufferInfo
;
1119 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1121 * Note that the _LOCK macro adds a curly brace,
1122 * and the UNLOCK macro removes it.
1124 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1126 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1127 const GLint winX
= fxMesa
->x_offset
;
1128 const GLint scrX
= winX
+ x
;
1129 const GLint scrY
= winY
- y
;
1130 LFBParameters ReadParams
;
1131 GLubyte visMask
[MAX_WIDTH
];
1133 int wrappedPartStart
;
1135 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1137 if (ReadParams
.firstWrappedX
<= x
) {
1138 wrappedPartStart
= 0;
1140 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
1141 wrappedPartStart
= n
;
1144 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
1146 generate_vismask(fxMesa
, scrX
, scrY
, n
, visMask
);
1147 for (i
= 0; i
< wrappedPartStart
; i
++) {
1148 if (visMask
[i
] && (!mask
|| mask
[i
])) {
1149 GLuint z
= GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
1150 scrX
+ i
, scrY
) & 0x00FFFFFF;
1151 z
|= (stencil
[i
] & 0xFF) << 24;
1152 PUT_ORDINARY_FB_DATA(&ReadParams
, GLuint
, scrX
+ i
, scrY
, z
);
1155 for (; i
< n
; i
++) {
1156 if (visMask
[i
] && (!mask
|| mask
[i
])) {
1157 GLuint z
= GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
1158 scrX
+ i
, scrY
) & 0x00FFFFFF;
1159 z
|= (stencil
[i
] & 0xFF) << 24;
1160 PUT_WRAPPED_FB_DATA(&ReadParams
, GLuint
, scrX
+ i
, scrY
, z
);
1164 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1169 write_mono_stencil_span(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
1170 GLuint n
, GLint x
, GLint y
,
1171 const void *value
, const GLubyte mask
[])
1173 GLbyte stencilVal
= *((GLbyte
*) value
);
1174 GLbyte stencils
[MAX_WIDTH
];
1176 for (i
= 0; i
< n
; i
++)
1177 stencils
[i
] = stencilVal
;
1178 write_stencil_span(ctx
, rb
, n
, x
, y
, stencils
, mask
);
1183 read_stencil_span(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
1184 GLuint n
, GLint x
, GLint y
,
1187 GLubyte
*stencil
= (GLubyte
*) values
;
1188 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1190 GrLfbInfo_t backBufferInfo
;
1192 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1194 * Note that the _LOCK macro adds a curly brace,
1195 * and the UNLOCK macro removes it.
1197 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1199 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1200 const GLint winX
= fxMesa
->x_offset
;
1202 LFBParameters ReadParams
;
1203 int wrappedPartStart
;
1206 * Convert to screen coordinates.
1210 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1212 if (ReadParams
.firstWrappedX
<= x
) {
1213 wrappedPartStart
= 0;
1215 else if (n
<= (ReadParams
.firstWrappedX
- x
)) {
1216 wrappedPartStart
= n
;
1219 wrappedPartStart
= (ReadParams
.firstWrappedX
- x
);
1221 for (i
= 0; i
< wrappedPartStart
; i
++) {
1222 stencil
[i
] = (GET_ORDINARY_FB_DATA(&ReadParams
, GLuint
,
1223 x
+ i
, y
) >> 24) & 0xFF;
1225 for (; i
< n
; i
++) {
1226 stencil
[i
] = (GET_WRAPPED_FB_DATA(&ReadParams
, GLuint
,
1227 x
+ i
, y
) >> 24) & 0xFF;
1230 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1235 write_stencil_pixels(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
1236 GLuint n
, const GLint x
[], const GLint y
[],
1237 const void *values
, const GLubyte mask
[])
1239 const GLubyte
*stencil
= (const GLubyte
*) values
;
1240 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1242 GrLfbInfo_t backBufferInfo
;
1244 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1246 * Note that the _LOCK macro adds a curly brace,
1247 * and the UNLOCK macro removes it.
1249 WRITE_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
, GR_LFBWRITEMODE_ANY
);
1251 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1252 const GLint winX
= fxMesa
->x_offset
;
1253 LFBParameters ReadParams
;
1256 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1258 for (i
= 0; i
< n
; i
++) {
1259 const GLint scrX
= winX
+ x
[i
];
1260 const GLint scrY
= winY
- y
[i
];
1261 if ((!mask
|| mask
[i
]) && visible_pixel(fxMesa
, scrX
, scrY
)) {
1263 GET_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
) & 0x00FFFFFF;
1264 z
|= (stencil
[i
] & 0xFF) << 24;
1265 PUT_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
, z
);
1269 WRITE_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1274 read_stencil_pixels(struct gl_context
* ctx
, struct gl_renderbuffer
*rb
,
1275 GLuint n
, const GLint x
[], const GLint y
[],
1278 GLubyte
*stencil
= (GLubyte
*) values
;
1279 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1281 GrLfbInfo_t backBufferInfo
;
1283 GetBackBufferInfo(fxMesa
, &backBufferInfo
);
1285 * Note that the _LOCK macro adds a curly brace,
1286 * and the UNLOCK macro removes it.
1288 READ_FB_SPAN_LOCK(fxMesa
, info
, GR_BUFFER_AUXBUFFER
);
1290 const GLint winY
= fxMesa
->y_offset
+ fxMesa
->height
- 1;
1291 const GLint winX
= fxMesa
->x_offset
;
1293 LFBParameters ReadParams
;
1295 GetFbParams(fxMesa
, &info
, &backBufferInfo
, &ReadParams
,
1297 for (i
= 0; i
< n
; i
++) {
1298 const GLint scrX
= winX
+ x
[i
];
1299 const GLint scrY
= winY
- y
[i
];
1301 (GET_FB_DATA(&ReadParams
, GLuint
, scrX
, scrY
) >> 24) & 0xFF;
1304 READ_FB_SPAN_UNLOCK(fxMesa
, GR_BUFFER_AUXBUFFER
);
1307 #define VISUAL_EQUALS_RGBA(vis, r, g, b, a) \
1308 ((vis.redBits == r) && \
1309 (vis.greenBits == g) && \
1310 (vis.blueBits == b) && \
1311 (vis.alphaBits == a))
1316 /**********************************************************************/
1317 /* Locking for swrast */
1318 /**********************************************************************/
1321 static void tdfxSpanRenderStart( struct gl_context
*ctx
)
1323 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1324 LOCK_HARDWARE(fxMesa
);
1327 static void tdfxSpanRenderFinish( struct gl_context
*ctx
)
1329 tdfxContextPtr fxMesa
= TDFX_CONTEXT(ctx
);
1330 _swrast_flush( ctx
);
1331 UNLOCK_HARDWARE(fxMesa
);
1334 /**********************************************************************/
1335 /* Initialize swrast device driver */
1336 /**********************************************************************/
1338 void tdfxDDInitSpanFuncs( struct gl_context
*ctx
)
1340 struct swrast_device_driver
*swdd
= _swrast_GetDeviceDriverReference( ctx
);
1341 swdd
->SpanRenderStart
= tdfxSpanRenderStart
;
1342 swdd
->SpanRenderFinish
= tdfxSpanRenderFinish
;
1348 * Plug in the Get/Put routines for the given driRenderbuffer.
1351 tdfxSetSpanFunctions(driRenderbuffer
*drb
, const struct gl_config
*vis
)
1353 if (drb
->Base
.InternalFormat
== GL_RGBA
) {
1354 if (vis
->redBits
== 5 && vis
->greenBits
== 6 && vis
->blueBits
== 5) {
1355 tdfxInitPointers_RGB565(&drb
->Base
);
1357 else if (vis
->redBits
== 8 && vis
->greenBits
== 8
1358 && vis
->blueBits
== 8 && vis
->alphaBits
== 0) {
1359 tdfxInitPointers_RGB888(&drb
->Base
);
1361 else if (vis
->redBits
== 8 && vis
->greenBits
== 8
1362 && vis
->blueBits
== 8 && vis
->alphaBits
== 8) {
1363 tdfxInitPointers_ARGB8888(&drb
->Base
);
1366 _mesa_problem(NULL
, "problem in tdfxSetSpanFunctions");
1369 else if (drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT16
||
1370 drb
->Base
.InternalFormat
== GL_DEPTH_COMPONENT24
) {
1371 drb
->Base
.GetRow
= tdfxDDReadDepthSpan
;
1372 drb
->Base
.GetValues
= tdfxDDReadDepthPixels
;
1373 drb
->Base
.PutRow
= tdfxDDWriteDepthSpan
;
1374 drb
->Base
.PutMonoRow
= tdfxDDWriteMonoDepthSpan
;
1375 drb
->Base
.PutValues
= tdfxDDWriteDepthPixels
;
1376 drb
->Base
.PutMonoValues
= NULL
;
1378 else if (drb
->Base
.InternalFormat
== GL_STENCIL_INDEX8_EXT
) {
1379 drb
->Base
.GetRow
= read_stencil_span
;
1380 drb
->Base
.GetValues
= read_stencil_pixels
;
1381 drb
->Base
.PutRow
= write_stencil_span
;
1382 drb
->Base
.PutMonoRow
= write_mono_stencil_span
;
1383 drb
->Base
.PutValues
= write_stencil_pixels
;
1384 drb
->Base
.PutMonoValues
= NULL
;