summaryrefslogtreecommitdiff
path: root/xc/extras/Mesa/src/FX/fxddspan.c
diff options
context:
space:
mode:
Diffstat (limited to 'xc/extras/Mesa/src/FX/fxddspan.c')
-rw-r--r--xc/extras/Mesa/src/FX/fxddspan.c1664
1 files changed, 1423 insertions, 241 deletions
diff --git a/xc/extras/Mesa/src/FX/fxddspan.c b/xc/extras/Mesa/src/FX/fxddspan.c
index c620cc3c6..2c53da8d3 100644
--- a/xc/extras/Mesa/src/FX/fxddspan.c
+++ b/xc/extras/Mesa/src/FX/fxddspan.c
@@ -46,33 +46,193 @@
/* fxdd.c - 3Dfx VooDoo Mesa span and pixel functions */
-#ifdef HAVE_CONFIG_H
-#include "conf.h"
-#endif
+#include "fxdrv.h"
-#if defined(FX)
-#include "fxdrv.h"
-#ifdef _MSC_VER
-#ifdef _WIN32
-#pragma warning( disable : 4090 4022 )
-/* 4101 : "different 'const' qualifier"
- * 4022 : "pointer mistmatch for actual parameter 'n'
+/*
+ * Examine the cliprects to generate an array of flags to indicate
+ * which pixels in a span are visible. Note: (x,y) is a screen
+ * coordinate.
*/
-#endif
-#endif
+static void
+generate_vismask(const fxMesaContext fxMesa, GLint x, GLint y, GLint n,
+ GLubyte vismask[])
+{
+ GLboolean initialized = GL_FALSE;
+ GLint i, j;
+
+ /* turn on flags for all visible pixels */
+ for (i = 0; i < fxMesa->numClipRects; i++) {
+ const XF86DRIClipRectPtr rect = &fxMesa->pClipRects[i];
+
+ if (y >= rect->y1 && y < rect->y2) {
+ if (x >= rect->x1 && x + n <= rect->x2) {
+ /* common case, whole span inside cliprect */
+ MEMSET(vismask, 1, n);
+ return;
+ }
+ if (x < rect->x2 && x + n >= rect->x1) {
+ /* some of the span is inside the rect */
+ GLint start, end;
+ if (!initialized) {
+ MEMSET(vismask, 0, n);
+ initialized = GL_TRUE;
+ }
+ if (x < rect->x1)
+ start = rect->x1 - x;
+ else
+ start = 0;
+ if (x + n > rect->x2)
+ end = rect->x2 - x;
+ else
+ end = n;
+ assert(start >= 0);
+ assert(end <= n);
+ for (j = start; j < end; j++)
+ vismask[j] = 1;
+ }
+ }
+ }
+}
-#if !defined(FXMESA_USE_ARGB)
+/*
+ * Examine cliprects and determine if the given screen pixel is visible.
+ */
+static GLboolean
+visible_pixel(const fxMesaContext fxMesa, int scrX, int scrY)
+{
+ int i;
+ for (i = 0; i < fxMesa->numClipRects; i++) {
+ const XF86DRIClipRectPtr rect = &fxMesa->pClipRects[i];
+ if (scrX >= rect->x1 &&
+ scrX < rect->x2 &&
+ scrY >= rect->y1 &&
+ scrY < rect->y2)
+ return GL_TRUE;
+ }
+ return GL_FALSE;
+}
-#if defined(FX_GLIDE3) && defined(XF86DRI)
+
+typedef enum { FBS_READ, FBS_WRITE } FBS_DIRECTION;
+/*
+ * Read or write a single span from the frame buffer.
+ * Input Parameters:
+ * fxMesa: The context
+ * target_buffer: Which buffer to read from.
+ * xpos, ypos: Starting Coordinates.
+ * xlength: Length of the span.
+ * data_size: Size of data elements: 1, 2, or 4.
+ * buffer: Pointer to the buffer to read
+ * to or write from. This needs
+ * to be turned into a pointer.
+ * direction: Read or Write.
+ */
+static void
+rw_fb_span(fxMesaContext fxMesa,
+ GrBuffer_t target_buffer,
+ FxU32 xpos,
+ FxU32 ypos,
+ FxU32 xlength,
+ FxU32 data_size,
+ void *buffer,
+ FBS_DIRECTION direction)
+{
+ GrLfbInfo_t info;
+ BEGIN_BOARD_LOCK();
+ info.size=sizeof(info);
+
+ if (grLfbLock(direction == FBS_READ ? GR_LFB_READ_ONLY : GR_LFB_WRITE_ONLY,
+ target_buffer,
+ GR_LFBWRITEMODE_ANY,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ const GLint winX = fxMesa->x_offset;
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+#ifdef XF86DRI
+ /* stride in data elements */
+ const GLint srcStride =
+ (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
+ ? (fxMesa->screen_width)
+ : (info.strideInBytes / data_size);
+#else
+ /* stride in data elements */
+ const GLint srcStride = info.strideInBytes / data_size;
+#endif
+ GLushort *data16 = (GLushort *) info.lfbPtr
+ + (winY - ypos) * srcStride
+ + (winX + xpos);
+ GLubyte *target16 = (GLubyte *) buffer;
+ GLubyte *data8 = (GLubyte *) data16;
+ GLubyte *target8 = (GLubyte *) buffer;
+ GLuint *data32 = (GLuint *) data16;
+ GLuint *target32 = (GLuint *) buffer;
+ GLuint i, j;
+
+ for (i = j = 0; i < xlength; i += 1, j += 1) {
+ switch (data_size) {
+ case 1:
+ switch (direction) {
+ case FBS_READ:
+ *target8++ = *data8++;
+ break;
+ case FBS_WRITE:
+ *data8++ = *target8++;
+ break;
+ }
+ break;
+ case 2:
+ switch (direction) {
+ case FBS_READ:
+ *target16++ = *data16++;
+ break;
+ case FBS_WRITE:
+ *data16++ = *target16++;
+ break;
+ }
+ break;
+ case 4:
+ switch (direction) {
+ case FBS_READ:
+ *target32++ = *data32++;
+ break;
+ case FBS_WRITE:
+ *data32++ = *target32++;
+ break;
+ }
+ break;
+ }
+ }
+ grLfbUnlock(direction == FBS_READ ? GR_LFB_READ_ONLY : GR_LFB_WRITE_ONLY,
+ target_buffer);
+ }
+ END_BOARD_LOCK();
+}
+
+static FxBool
+fb_point_is_clipped(fxMesaContext fxMesa,
+ FxU32 dst_x, FxU32 dst_y)
+{
+ int i;
+ for (i=0; i<fxMesa->numClipRects; i++) {
+ if ((dst_x>=fxMesa->pClipRects[i].x1) &&
+ (dst_x<fxMesa->pClipRects[i].x2) &&
+ (dst_y>=fxMesa->pClipRects[i].y1) &&
+ (dst_y<fxMesa->pClipRects[i].y2)) {
+ return GL_FALSE;
+ }
+ }
+ return GL_TRUE;
+}
static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer,
- FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format,
- FxU32 src_width, FxU32 src_height, FxI32 src_stride,
- void *src_data)
+ FxU32 dst_x, FxU32 dst_y, GrLfbSrcFmt_t src_format,
+ FxU32 src_width, FxU32 src_height, FxI32 src_stride,
+ void *src_data)
{
int i, x, w, srcElt;
void *data;
@@ -80,12 +240,12 @@ static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer,
if (src_width==1 && src_height==1) { /* Easy case writing a point */
for (i=0; i<fxMesa->numClipRects; i++) {
if ((dst_x>=fxMesa->pClipRects[i].x1) &&
- (dst_x<fxMesa->pClipRects[i].x2) &&
- (dst_y>=fxMesa->pClipRects[i].y1) &&
- (dst_y<fxMesa->pClipRects[i].y2)) {
- FX_grLfbWriteRegion(dst_buffer, dst_x, dst_y, src_format,
- 1, 1, src_stride, src_data);
- return GL_TRUE;
+ (dst_x<fxMesa->pClipRects[i].x2) &&
+ (dst_y>=fxMesa->pClipRects[i].y1) &&
+ (dst_y<fxMesa->pClipRects[i].y2)) {
+ FX_grLfbWriteRegion(dst_buffer, dst_x, dst_y, src_format,
+ 1, 1, src_stride, src_data);
+ return GL_TRUE;
}
}
} else if (src_height==1) { /* Writing a span */
@@ -97,20 +257,20 @@ static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer,
}
for (i=0; i<fxMesa->numClipRects; i++) {
if (dst_y>=fxMesa->pClipRects[i].y1 && dst_y<fxMesa->pClipRects[i].y2) {
- if (dst_x<fxMesa->pClipRects[i].x1) {
- x=fxMesa->pClipRects[i].x1;
- data=((char*)src_data)+srcElt*(x - dst_x);
- w=src_width-(x-dst_x);
- } else {
- x=dst_x;
- data=src_data;
- w=src_width;
- }
- if (x+w>fxMesa->pClipRects[i].x2) {
- w=fxMesa->pClipRects[i].x2-x;
- }
- FX_grLfbWriteRegion(dst_buffer, x, dst_y, src_format, w, 1,
- src_stride, data);
+ if (dst_x<fxMesa->pClipRects[i].x1) {
+ x=fxMesa->pClipRects[i].x1;
+ data=((char*)src_data)+srcElt*(x - dst_x);
+ w=src_width-(x-dst_x);
+ } else {
+ x=dst_x;
+ data=src_data;
+ w=src_width;
+ }
+ if (x+w>fxMesa->pClipRects[i].x2) {
+ w=fxMesa->pClipRects[i].x2-x;
+ }
+ FX_grLfbWriteRegion(dst_buffer, x, dst_y, src_format, w, 1,
+ src_stride, data);
}
}
} else { /* Punt on the case of arbitrary rectangles */
@@ -119,88 +279,42 @@ static FxBool writeRegionClipped(fxMesaContext fxMesa, GrBuffer_t dst_buffer,
return GL_TRUE;
}
-#else
-
-#define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
- FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
-
-#endif
/* KW: Rearranged the args in the call to grLfbWriteRegion().
*/
-#define LFB_WRITE_SPAN_MESA(dst_buffer, \
- dst_x, \
- dst_y, \
- src_width, \
- src_stride, \
- src_data) \
- writeRegionClipped(fxMesa, dst_buffer, \
- dst_x, \
- dst_y, \
- GR_LFB_SRC_FMT_8888, \
- src_width, \
- 1, \
- src_stride, \
- src_data) \
-
-
-#else /* !defined(FXMESA_USE_RGBA) */
-
-#define writeRegionClipped(fxm,dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data) \
- FX_grLfbWriteRegion(dst_buffer,dst_x,dst_y,src_format,src_width,src_height,src_stride,src_data)
-
-
-#define MESACOLOR_TO_ARGB(c) ( \
- ( ((unsigned int)(c[ACOMP]))<<24 ) | \
- ( ((unsigned int)(c[RCOMP]))<<16 ) | \
- ( ((unsigned int)(c[GCOMP]))<<8 ) | \
- ( (unsigned int)(c[BCOMP])) )
-
-inline void LFB_WRITE_SPAN_MESA(GrBuffer_t dst_buffer,
- FxU32 dst_x,
- FxU32 dst_y,
- FxU32 src_width,
- FxI32 src_stride,
- void *src_data )
-{
- /* Covert to ARGB */
- GLubyte (*rgba)[4] = src_data;
- GLuint argb[MAX_WIDTH];
- int i;
-
- for (i = 0; i < src_width; i++)
- {
- argb[i] = MESACOLOR_TO_ARGB(rgba[i]);
- }
- writeRegionClipped( /*fxMesa,*/ NULL, dst_buffer,
- dst_x,
- dst_y,
- GR_LFB_SRC_FMT_8888,
- src_width,
- 1,
- src_stride,
- (void*)argb);
-}
-
-#endif /* !defined(FXMESA_USE_RGBA) */
+#define LFB_WRITE_SPAN_MESA(dst_buffer, \
+ dst_x, \
+ dst_y, \
+ src_width, \
+ src_stride, \
+ src_data) \
+ writeRegionClipped(fxMesa, dst_buffer, \
+ dst_x, \
+ dst_y, \
+ GR_LFB_SRC_FMT_8888, \
+ src_width, \
+ 1, \
+ src_stride, \
+ src_data) \
+
-/************************************************************************/
-/***** Span functions *****/
-/************************************************************************/
+/*
+ * 16bpp span/pixel functions
+ */
-static void fxDDWriteRGBASpan(const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLubyte rgba[][4], const GLubyte mask[])
+static void
+write_R5G6B5_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte rgba[][4], const GLubyte mask[])
{
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
GLuint i;
GLint bottom=fxMesa->height+fxMesa->y_offset-1;
if (MESA_VERBOSE&VERBOSE_DRIVER) {
- fprintf(stderr,"fxmesa: fxDDWriteRGBASpan(...)\n");
+ fprintf(stderr,"fxmesa: fxDDWriteRGBASpan(...)\n");
}
x+=fxMesa->x_offset;
@@ -213,7 +327,7 @@ static void fxDDWriteRGBASpan(const GLcontext *ctx,
} else {
if (span > 0) {
LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+i-span, bottom-y,
- /* GR_LFB_SRC_FMT_8888,*/ span, /*1,*/ 0, (void *) rgba[i-span] );
+ /* GR_LFB_SRC_FMT_8888,*/ span, /*1,*/ 0, (void *) rgba[i-span] );
span = 0;
}
}
@@ -221,16 +335,16 @@ static void fxDDWriteRGBASpan(const GLcontext *ctx,
if (span > 0)
LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+n-span, bottom-y,
- /* GR_LFB_SRC_FMT_8888, */ span, /*1,*/ 0, (void *) rgba[n-span] );
+ /* GR_LFB_SRC_FMT_8888, */ span, /*1,*/ 0, (void *) rgba[n-span] );
} else
LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x, bottom-y,/* GR_LFB_SRC_FMT_8888,*/
- n,/* 1,*/ 0, (void *) rgba );
+ n,/* 1,*/ 0, (void *) rgba );
}
-static void fxDDWriteRGBSpan(const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLubyte rgb[][3], const GLubyte mask[])
+static void
+write_R5G6B5_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte rgb[][3], const GLubyte mask[])
{
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
GLuint i;
@@ -238,7 +352,7 @@ static void fxDDWriteRGBSpan(const GLcontext *ctx,
GLubyte rgba[MAX_WIDTH][4];
if (MESA_VERBOSE&VERBOSE_DRIVER) {
- fprintf(stderr,"fxmesa: fxDDWriteRGBSpan()\n");
+ fprintf(stderr,"fxmesa: fxDDWriteRGBSpan()\n");
}
x+=fxMesa->x_offset;
@@ -255,7 +369,7 @@ static void fxDDWriteRGBSpan(const GLcontext *ctx,
} else {
if (span > 0) {
LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+i-span, bottom-y,
- /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba );
+ /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba );
span = 0;
}
}
@@ -263,7 +377,7 @@ static void fxDDWriteRGBSpan(const GLcontext *ctx,
if (span > 0)
LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x+n-span, bottom-y,
- /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba );
+ /*GR_LFB_SRC_FMT_8888,*/ span,/* 1,*/ 0, (void *) rgba );
} else {
for (i=0;i<n;i++) {
rgba[i][RCOMP]=rgb[i][0];
@@ -273,14 +387,14 @@ static void fxDDWriteRGBSpan(const GLcontext *ctx,
}
LFB_WRITE_SPAN_MESA( fxMesa->currentFB, x, bottom-y,/* GR_LFB_SRC_FMT_8888,*/
- n,/* 1,*/ 0, (void *) rgba );
+ n,/* 1,*/ 0, (void *) rgba );
}
}
-static void fxDDWriteMonoRGBASpan(const GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLubyte mask[])
+static void
+write_R5G6B5_mono_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte mask[])
{
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
GLuint i;
@@ -288,7 +402,7 @@ static void fxDDWriteMonoRGBASpan(const GLcontext *ctx,
GLuint data[MAX_WIDTH];
if (MESA_VERBOSE&VERBOSE_DRIVER) {
- fprintf(stderr,"fxmesa: fxDDWriteMonoRGBASpan(...)\n");
+ fprintf(stderr,"fxmesa: fxDDWriteMonoRGBASpan(...)\n");
}
x+=fxMesa->x_offset;
@@ -302,8 +416,8 @@ static void fxDDWriteMonoRGBASpan(const GLcontext *ctx,
} else {
if (span > 0) {
writeRegionClipped(fxMesa, fxMesa->currentFB, x+i-span, bottom-y,
- GR_LFB_SRC_FMT_8888, span, 1, 0,
- (void *) data );
+ GR_LFB_SRC_FMT_8888, span, 1, 0,
+ (void *) data );
span = 0;
}
}
@@ -311,59 +425,31 @@ static void fxDDWriteMonoRGBASpan(const GLcontext *ctx,
if (span > 0)
writeRegionClipped(fxMesa, fxMesa->currentFB, x+n-span, bottom-y,
- GR_LFB_SRC_FMT_8888, span, 1, 0,
- (void *) data );
+ GR_LFB_SRC_FMT_8888, span, 1, 0,
+ (void *) data );
} else {
for (i=0;i<n;i++) {
data[i]=(GLuint) fxMesa->color;
}
writeRegionClipped(fxMesa, fxMesa->currentFB, x, bottom-y, GR_LFB_SRC_FMT_8888,
- n, 1, 0, (void *) data );
+ n, 1, 0, (void *) data );
}
}
-#if 0
-static void fxDDReadRGBASpan(const GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLubyte rgba[][4])
-{
- fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
- GLushort data[MAX_WIDTH];
- GLuint i;
- GLint bottom=fxMesa->height+fxMesa->y_offset-1;
-
- printf("read span %d, %d, %d\n", x,y,n);
- if (MESA_VERBOSE&VERBOSE_DRIVER) {
- fprintf(stderr,"fxmesa: fxDDReadRGBASpan(...)\n");
- }
-
- assert(n < MAX_WIDTH);
-
- x+=fxMesa->x_offset;
- FX_grLfbReadRegion( fxMesa->currentFB, x, bottom-y, n, 1, 0, data);
-
- for (i=0;i<n;i++) {
- GLushort pixel = data[i];
- rgba[i][RCOMP] = FX_PixelToR[pixel];
- rgba[i][GCOMP] = FX_PixelToG[pixel];
- rgba[i][BCOMP] = FX_PixelToB[pixel];
- rgba[i][ACOMP] = 255;
- }
-}
-#endif
-
-
/*
* Read a span of 16-bit RGB pixels. Note, we don't worry about cliprects
* since OpenGL says obscured pixels have undefined values.
*/
-static void read_R5G6B5_span(const GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLubyte rgba[][4])
+static void
+read_R5G6B5_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLubyte rgba[][4])
{
- fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
GrLfbInfo_t info;
BEGIN_BOARD_LOCK();
+ info.size=sizeof(info);
if (grLfbLock(GR_LFB_READ_ONLY,
fxMesa->currentFB,
GR_LFBWRITEMODE_ANY,
@@ -374,13 +460,13 @@ static void read_R5G6B5_span(const GLcontext *ctx,
const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
#ifdef XF86DRI
const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
- ? (fxMesa->screen_width) : (info.strideInBytes / 2);
+ ? (fxMesa->screen_width) : (info.strideInBytes / 2);
#else
const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
#endif
const GLushort *data16 = (const GLushort *) info.lfbPtr
- + (winY - y) * srcStride
- + (winX + x);
+ + (winY - y) * srcStride
+ + (winX + x);
const GLuint *data32 = (const GLuint *) data16;
GLuint i, j;
GLuint extraPixel = (n & 1);
@@ -412,91 +498,716 @@ static void read_R5G6B5_span(const GLcontext *ctx,
}
-/************************************************************************/
-/***** Pixel functions *****/
-/************************************************************************/
-
-static void fxDDWriteRGBAPixels(const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- CONST GLubyte rgba[][4], const GLubyte mask[])
+static void
+write_R5G6B5_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ CONST GLubyte rgba[][4], const GLubyte mask[])
{
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
GLuint i;
GLint bottom=fxMesa->height+fxMesa->y_offset-1;
if (MESA_VERBOSE&VERBOSE_DRIVER) {
- fprintf(stderr,"fxmesa: fxDDWriteRGBAPixels(...)\n");
+ fprintf(stderr,"fxmesa: fxDDWriteRGBAPixels(...)\n");
}
for(i=0;i<n;i++)
if(mask[i])
- LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i]+fxMesa->x_offset, bottom-y[i],
- 1, 1, (void *)rgba[i]);
+ LFB_WRITE_SPAN_MESA(fxMesa->currentFB, x[i]+fxMesa->x_offset, bottom-y[i],
+ 1, 1, (void *)rgba[i]);
}
-static void fxDDWriteMonoRGBAPixels(const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLubyte mask[])
+
+static void
+write_R5G6B5_mono_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLubyte mask[])
{
fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
GLuint i;
GLint bottom=fxMesa->height+fxMesa->y_offset-1;
if (MESA_VERBOSE&VERBOSE_DRIVER) {
- fprintf(stderr,"fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
+ fprintf(stderr,"fxmesa: fxDDWriteMonoRGBAPixels(...)\n");
}
for(i=0;i<n;i++)
if(mask[i])
writeRegionClipped(fxMesa, fxMesa->currentFB,x[i]+fxMesa->x_offset,bottom-y[i],
- GR_LFB_SRC_FMT_8888,1,1,0,(void *) &fxMesa->color);
+ GR_LFB_SRC_FMT_8888,1,1,0,(void *) &fxMesa->color);
}
+static void
+read_R5G6B5_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ GLubyte rgba[][4], const GLubyte mask[])
+{
+ fxMesaContext fxMesa=(fxMesaContext)ctx->DriverCtx;
+ GLuint i;
+ GLint bottom=fxMesa->height+fxMesa->y_offset-1;
-static void read_R5G6B5_pixels(const GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLubyte rgba[][4], const GLubyte mask[])
+ if (MESA_VERBOSE&VERBOSE_DRIVER) {
+ fprintf(stderr,"fxmesa: fxDDReadRGBAPixels(...)\n");
+ }
+
+ for(i=0;i<n;i++) {
+ if(mask[i]) {
+ GLushort pixel;
+ FX_grLfbReadRegion(fxMesa->currentFB,x[i],bottom-y[i],1,1,0,&pixel);
+ rgba[i][RCOMP] = FX_PixelToR[pixel];
+ rgba[i][GCOMP] = FX_PixelToG[pixel];
+ rgba[i][BCOMP] = FX_PixelToB[pixel];
+ rgba[i][ACOMP] = 255;
+ }
+ }
+}
+
+
+/*
+ * 24bpp span/pixel functions
+ */
+
+static void
+write_R8G8B8_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte rgb[][3], const GLubyte mask[])
{
- fxMesaContext fxMesa = (fxMesaContext) ctx->DriverCtx;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbWriteMode_t mode;
GrLfbInfo_t info;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
+ mode = GR_LFBWRITEMODE_888;
+ else
+ mode = GR_LFBWRITEMODE_888;
+
BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ mode,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x;
+ const GLint scrY = winY - y;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ /*GLint dstStride = fxMesa->screen_width * 3;*/
+ GLint dstStride = info.strideInBytes / 1;
+ GLubyte *dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 1;
+ GLuint *dst32 = (GLuint *) dst;
+ GLubyte visMask[MAX_WIDTH];
+ GLuint i;
+ generate_vismask(fxMesa, scrX, scrY, n, visMask);
+ for (i = 0; i < n; i++) {
+ if (visMask[i] && (!mask || mask[i])) {
+ dst32[i] = PACK_BGRA32(rgb[i][0], rgb[i][1], rgb[i][2], 255);
+ }
+ }
+ }
+ else {
+ /* back buffer */
+ GLint dstStride = info.strideInBytes;
+ GLubyte *dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ if (mask) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ dst32[i] = PACK_RGBA32(rgb[i][0], rgb[i][1], rgb[i][2], 255);
+ }
+ }
+ }
+ else {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst32[i] = PACK_RGBA32(rgb[i][2], rgb[i][1], rgb[i][0], 255);
+ }
+ }
+ }
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ }
+ END_BOARD_LOCK();
+}
+
+
+
+static void
+write_R8G8B8_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte rgba[][4], const GLubyte mask[])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbWriteMode_t mode;
+ GrLfbInfo_t info;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
+ mode = GR_LFBWRITEMODE_8888;
+ else
+ mode = GR_LFBWRITEMODE_888 /*565*/;
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ mode,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x;
+ const GLint scrY = winY - y;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ /* XXX have to do cliprect clipping! */
+ GLint dstStride = fxMesa->screen_width * 4;
+ GLubyte *dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ GLubyte visMask[MAX_WIDTH];
+ GLuint i;
+ generate_vismask(fxMesa, scrX, scrY, n, visMask);
+ for (i = 0; i < n; i++) {
+ if (visMask[i] && (!mask || mask[i])) {
+ dst32[i] = PACK_BGRA32(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
+ }
+ }
+ }
+ else {
+ /* back buffer */
+ GLint dstStride = info.strideInBytes;
+ GLubyte *dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 4;
+ if (mask) {
+ const GLuint *src32 = (const GLuint *) rgba;
+ GLuint *dst32 = (GLuint *) dst;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ dst32[i] = src32[i];
+ }
+ }
+ }
+ else {
+ /* no mask, write all pixels */
+ MEMCPY(dst, rgba, 4 * n);
+ }
+ }
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ }
+ END_BOARD_LOCK();
+}
+
+
+static void
+write_R8G8B8_mono_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte mask[])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GLubyte rgba[MAX_WIDTH][4];
+ GLuint *data = (GLuint *) rgba;
+ GLuint i;
+
+ /* XXX this is a simple-minded implementation but good enough for now */
+ for (i = 0; i < n; i++) {
+ data[i] = (GLuint) fxMesa->color;
+ }
+ write_R8G8B8_rgba_span(ctx, n, x, y, (const GLubyte (*)[4]) rgba, mask);
+}
+
+
+static void
+read_R8G8B8_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLubyte rgba[][4])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbWriteMode_t mode;
+ GrLfbInfo_t info;
+
+ if (1 || fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ mode = GR_LFBWRITEMODE_8888;
+ }
+ else {
+ mode = GR_LFBWRITEMODE_565; /*888*/ /*565*/;
+ }
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
if (grLfbLock(GR_LFB_READ_ONLY,
fxMesa->currentFB,
- GR_LFBWRITEMODE_ANY,
+ mode, /*GR_LFBWRITEMODE_ANY,*/
GR_ORIGIN_UPPER_LEFT,
FXFALSE,
&info)) {
-#ifdef XF86DRI
- const GLint srcStride = (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
- ? (fxMesa->screen_width) : (info.strideInBytes / 2);
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ GLint srcStride = fxMesa->screen_width * 4;
+ const GLubyte *src = (const GLubyte *) info.lfbPtr
+ + (winY - y) * srcStride + (winX + x) * 4;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][0] = src[i * 4 + 2];
+ rgba[i][1] = src[i * 4 + 1];
+ rgba[i][2] = src[i * 4 + 0];
+ rgba[i][3] = src[i * 4 + 3];
+ }
+ }
+ else {
+ /* back buffer */
+ GLint srcStride = /*info.strideInBytes;*/ 8192 / 2; /* XXX a hack! */
+ const GLubyte *src = (const GLubyte *) info.lfbPtr
+ + (winY - y) * srcStride + (winX + x) * 4;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ rgba[i][0] = src[i * 4 + 2];
+ rgba[i][1] = src[i * 4 + 1];
+ rgba[i][2] = src[i * 4 + 0];
+ rgba[i][3] = src[i * 4 + 3];
+ }
+ }
+ grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
+ }
+ END_BOARD_LOCK();
+}
+
+
+static void
+write_R8G8B8_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ CONST GLubyte rgba[][4], const GLubyte mask[])
+{
+#if 00
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ write_R8G8B8_rgba_span(ctx, 1, x[i], y[i], rgba + i, mask + i);
+ }
+
#else
- const GLint srcStride = info.strideInBytes / 2; /* stride in GLushorts */
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbWriteMode_t mode;
+ GrLfbInfo_t info;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
+ mode = GR_LFBWRITEMODE_8888;
+ else
+ mode = GR_LFBWRITEMODE_888 /*565*/;
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ mode,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x[i];
+ const GLint scrY = winY - y[i];
+ if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) {
+ GLint dstStride = fxMesa->screen_width * 4;
+ GLubyte *dst = (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ *dst32 = PACK_BGRA32(rgba[i][0], rgba[i][1],
+ rgba[i][2], rgba[i][3]);
+ }
+ }
+ }
+ else {
+ /* back buffer */
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x[i];
+ const GLint scrY = winY - y[i];
+ if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) {
+ GLint dstStride = info.strideInBytes;
+ GLubyte *dst = (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ const GLuint *src32 = (const GLuint *) rgba;
+ *dst32 = src32[i];
+ }
+ }
+ }
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ }
+ END_BOARD_LOCK();
#endif
+}
+
+
+static void
+write_R8G8B8_mono_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLubyte mask[])
+{
+}
+
+
+static void
+read_R8G8B8_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ GLubyte rgba[][4], const GLubyte mask[])
+{
+ printf("read_R8G8B8_pixels %d\n", n);
+}
+
+
+
+/*
+ * 32bpp span/pixel functions
+ */
+
+static void
+write_R8G8B8A8_rgb_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte rgb[][3], const GLubyte mask[])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbWriteMode_t mode;
+ GrLfbInfo_t info;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
+ mode = GR_LFBWRITEMODE_8888;
+ else
+ mode = GR_LFBWRITEMODE_888 /*565*/;
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ mode,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x;
+ const GLint scrY = winY - y;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ GLint dstStride = fxMesa->screen_width * 4;
+ GLubyte * dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ GLubyte visMask[MAX_WIDTH];
+ GLuint i;
+ generate_vismask(fxMesa, scrX, scrY, n, visMask);
+ for (i = 0; i < n; i++) {
+ if (visMask[i] && (!mask || mask[i])) {
+ dst32[i] = PACK_BGRA32(rgb[i][0], rgb[i][1], rgb[i][2], 255);
+ }
+ }
+ }
+ else {
+ /* back buffer */
+ GLint dstStride = info.strideInBytes;
+ GLubyte *dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 4;
+ if (mask) {
+ GLuint *dst32 = (GLuint *) dst;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ dst32[i] = PACK_RGBA32(rgb[i][0], rgb[i][1], rgb[i][2], 255);
+ }
+ }
+ }
+ else {
+ GLuint *dst32 = (GLuint *) dst;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ dst32[i] = PACK_RGBA32(rgb[i][0], rgb[i][1], rgb[i][2], 255);
+ }
+ }
+ }
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ }
+ END_BOARD_LOCK();
+}
+
+
+/*
+ *XXX test of grLfbWriteRegion in 32bpp mode. Doesn't seem to work!
+ */
+#if 0
+static void
+write_R8G8B8A8_rgb_span2(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte rgb[][3], const GLubyte mask[])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
+ GLint x2 = fxMesa->x_offset +x;
+ GLint y2 = bottom - y;
+
+ FX_grLfbWriteRegion(fxMesa->currentFB, x2, y2, GR_LFB_SRC_FMT_888,
+ n, 1, 0, rgb);
+}
+#endif
+
+
+static void
+write_R8G8B8A8_rgba_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte rgba[][4], const GLubyte mask[])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbWriteMode_t mode;
+ GrLfbInfo_t info;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
+ mode = GR_LFBWRITEMODE_8888;
+ else
+ mode = GR_LFBWRITEMODE_888 /*565*/;
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ mode,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
- GLuint i;
- for(i=0;i<n;i++) {
- if(mask[i]) {
- const GLushort *data16 = (const GLushort *) info.lfbPtr
- + (winY - y[i]) * srcStride
- + (winX + x[i]);
- const GLushort pixel = *data16;
- rgba[i][RCOMP] = FX_PixelToR[pixel];
- rgba[i][GCOMP] = FX_PixelToG[pixel];
- rgba[i][BCOMP] = FX_PixelToB[pixel];
- rgba[i][ACOMP] = 255;
+ const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x;
+ const GLint scrY = winY - y;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ GLint dstStride = fxMesa->screen_width * 4;
+ GLubyte *dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ GLubyte visMask[MAX_WIDTH];
+ GLuint i;
+ generate_vismask(fxMesa, scrX, scrY, n, visMask);
+ for (i = 0; i < n; i++) {
+ if (visMask[i] && (!mask || mask[i])) {
+ dst32[i] = PACK_BGRA32(rgba[i][0], rgba[i][1], rgba[i][2], rgba[i][3]);
+ }
+ }
+ }
+ else {
+ /* back buffer */
+ GLint dstStride = 8192; /* XXX a hack info.strideInBytes; */
+ GLubyte *dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 4;
+ if (mask) {
+ const GLuint *src32 = (const GLuint *) rgba;
+ GLuint *dst32 = (GLuint *) dst;
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ dst32[i] = src32[i];
+ }
+ }
+ }
+ else {
+ /* no mask, write all pixels */
+ MEMCPY(dst, rgba, 4 * n);
+ }
+ }
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ }
+ else {
+ info.strideInBytes = -1;
+ }
+ END_BOARD_LOCK();
+}
+
+
+static void
+write_R8G8B8A8_mono_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLubyte mask[])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GLubyte rgba[MAX_WIDTH][4];
+ GLuint *data = (GLuint *) rgba;
+ GLuint i;
+
+ /* XXX this is a simple-minded implementation but good enough for now */
+ for (i = 0; i < n; i++) {
+ data[i] = (GLuint) fxMesa->color;
+ }
+ write_R8G8B8A8_rgba_span(ctx, n, x, y, (const GLubyte (*)[4]) rgba, mask);
+}
+
+
+static void
+read_R8G8B8A8_span(const GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLubyte rgba[][4])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbWriteMode_t mode;
+ GrLfbInfo_t info;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ mode = GR_LFBWRITEMODE_8888;
+ }
+ else {
+ mode = GR_LFBWRITEMODE_8888; /*565;*/
+ }
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_READ_ONLY,
+ fxMesa->currentFB,
+ mode,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ GLint srcStride = fxMesa->screen_width;
+ const GLuint *src32 = (const GLuint *) info.lfbPtr
+ + (winY - y) * srcStride + (winX + x);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLuint p = src32[i];
+ rgba[i][0] = (p >> 16) & 0xff;
+ rgba[i][1] = (p >> 8) & 0xff;
+ rgba[i][2] = (p >> 0) & 0xff;
+ rgba[i][3] = (p >> 24) & 0xff;
+ }
+ }
+ else {
+ /* back buffer */
+ GLint srcStride = 1024; /* XXX a hack */
+ const GLuint *src32 = (const GLuint *) info.lfbPtr
+ + (winY - y) * srcStride + (winX + x);
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ GLuint p = src32[i];
+ rgba[i][0] = (p >> 16) & 0xff;
+ rgba[i][1] = (p >> 8) & 0xff;
+ rgba[i][2] = (p >> 0) & 0xff;
+ rgba[i][3] = (p >> 24) & 0xff;
}
}
grLfbUnlock(GR_LFB_READ_ONLY, fxMesa->currentFB);
}
+ else
+ info.strideInBytes = -1;
+ END_BOARD_LOCK();
+}
+
+
+static void
+write_R8G8B8A8_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ CONST GLubyte rgba[][4], const GLubyte mask[])
+{
+#if 00
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ write_R8G8B8A8_rgba_span(ctx, 1, x[i], y[i], rgba + i, mask + i);
+ }
+
+#else
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbWriteMode_t mode;
+ GrLfbInfo_t info;
+
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT)
+ mode = GR_LFBWRITEMODE_8888;
+ else
+ mode = GR_LFBWRITEMODE_888 /*565*/;
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_WRITE_ONLY,
+ fxMesa->currentFB,
+ mode,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ if (fxMesa->glCtx->Color.DrawBuffer == GL_FRONT) {
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x[i];
+ const GLint scrY = winY - y[i];
+ if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) {
+ GLint dstStride = fxMesa->screen_width * 4;
+ GLubyte *dst = (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ *dst32 = PACK_BGRA32(rgba[i][0], rgba[i][1],
+ rgba[i][2], rgba[i][3]);
+ }
+ }
+ }
+ else {
+ /* back buffer */
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x[i];
+ const GLint scrY = winY - y[i];
+ if (mask[i] && visible_pixel(fxMesa, scrX, scrY)) {
+ GLint dstStride = info.strideInBytes;
+ GLubyte *dst = (GLubyte *) info.lfbPtr + scrY * dstStride + scrX * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ const GLuint *src32 = (const GLuint *) rgba;
+ *dst32 = src32[i];
+ }
+ }
+ }
+ grLfbUnlock(GR_LFB_WRITE_ONLY, fxMesa->currentFB);
+ }
END_BOARD_LOCK();
+#endif
+}
+
+
+static void
+write_R8G8B8A8_mono_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ const GLubyte mask[])
+{
+ fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
+ GLuint i;
+ GLuint color = fxMesa->color;
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ write_R8G8B8A8_rgba_span(ctx, 1, x[i], y[i],
+ (const GLubyte (*)[4]) &color, mask + i);
+ }
+ }
+}
+
+
+
+static void
+read_R8G8B8A8_pixels(const GLcontext *ctx,
+ GLuint n, const GLint x[], const GLint y[],
+ GLubyte rgba[][4], const GLubyte mask[])
+{
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ read_R8G8B8A8_span(ctx, 1, x[i], y[i], rgba + i);
+ }
+ }
+ printf("read_R8G8B8A8_pixels %d\n", n);
}
-/************************************************************************/
-/***** Depth functions *****/
-/************************************************************************/
+/*
+ * Depth buffer read/write functions.
+ */
void fxDDWriteDepthSpan(GLcontext *ctx,
GLuint n, GLint x, GLint y, const GLdepth depth[],
@@ -504,9 +1215,11 @@ void fxDDWriteDepthSpan(GLcontext *ctx,
{
fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
+ GLuint depth_size = fxMesa->glVis->DepthBits;
+ GLuint stencil_size = fxMesa->glVis->StencilBits;
if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDWriteDepthSpan(...)\n");
+ fprintf(stderr, "fxmesa: fxDDWriteDepthSpan(...)\n");
}
x += fxMesa->x_offset;
@@ -515,20 +1228,77 @@ void fxDDWriteDepthSpan(GLcontext *ctx,
GLint i;
for (i = 0; i < n; i++) {
if (mask[i]) {
- GLshort d = depth[i];
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
- GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
+ GLshort d16;
+ GLuint d32;
+ switch (depth_size) {
+ case 16:
+ d16 = depth[i];
+ writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x + i, bottom - y,
+ GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d16);
+ break;
+ case 32:
+ if (!fb_point_is_clipped(fxMesa, x+i, bottom-y)) {
+ if (stencil_size > 0) {
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ x + i, bottom - y,
+ 1,
+ sizeof(GLdepth),
+ &d32,
+ FBS_READ);
+ d32 = depth[i] & 0xFF000000;
+ break;
+ } else {
+ d32 = depth[i];
+ }
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ x + i, bottom - y,
+ 1,
+ sizeof(GLdepth),
+ &d32,
+ FBS_WRITE);
+ }
+ }
}
}
- }
- else {
+ } else {
GLushort depth16[MAX_WIDTH];
GLint i;
- for (i = 0; i < n; i++) {
- depth16[i] = depth[i];
+ GLuint d32;
+ switch (depth_size) {
+ case 16:
+ for (i = 0; i < n; i++) {
+ depth16[i] = depth[i];
+ }
+ writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
+ GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth16);
+ break;
+ case 32:
+ for (i = 0; i < n; i++) {
+ if (fb_point_is_clipped(fxMesa, x+i, bottom-y)) {
+ if (stencil_size > 0) {
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ x + i, bottom - y,
+ 1,
+ sizeof(GLdepth),
+ &d32,
+ FBS_READ);
+ d32 = (d32 & 0xFF0000) | (depth[i] & 0x00FFFFFF);
+ } else {
+ d32 = depth[i];
+ }
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ x + i, bottom - y,
+ 1,
+ sizeof(GLdepth),
+ &d32,
+ FBS_WRITE);
+ }
+ }
}
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, x, bottom - y,
- GR_LFB_SRC_FMT_ZA16, n, 1, 0, (void *) depth16);
}
}
@@ -540,15 +1310,34 @@ void fxDDReadDepthSpan(GLcontext *ctx,
GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
GLushort depth16[MAX_WIDTH];
GLuint i;
+ GLuint depth_size = fxMesa->glVis->DepthBits;
+ GLuint stencil_size = fxMesa->glVis->StencilBits;
if (MESA_VERBOSE & VERBOSE_DRIVER) {
- fprintf(stderr, "fxmesa: fxDDReadDepthSpan(...)\n");
+ fprintf(stderr, "fxmesa: fxDDReadDepthSpan(...)\n");
}
x += fxMesa->x_offset;
- FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16);
- for (i = 0; i < n; i++) {
- depth[i] = depth16[i];
+ switch (depth_size) {
+ case 16:
+ FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, x, bottom - y, n, 1, 0, depth16);
+ for (i = 0; i < n; i++) {
+ depth[i] = depth16[i];
+ }
+ break;
+ case 32:
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ x, bottom - y,
+ n,
+ sizeof(GLdepth),
+ depth,
+ FBS_READ);
+ if (stencil_size > 0) {
+ for (i = 0; i < n; i++) {
+ depth[i] &= 0xFFFFFF;
+ }
+ }
}
}
@@ -561,6 +1350,9 @@ void fxDDWriteDepthPixels(GLcontext *ctx,
fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
GLuint i;
+ GLuint d32;
+ GLuint depth_size = fxMesa->glVis->DepthBits;
+ GLuint stencil_size = fxMesa->glVis->StencilBits;
if (MESA_VERBOSE & VERBOSE_DRIVER) {
fprintf(stderr, "fxmesa: fxDDWriteDepthPixels(...)\n");
@@ -570,9 +1362,41 @@ void fxDDWriteDepthPixels(GLcontext *ctx,
if (mask[i]) {
int xpos = x[i] + fxMesa->x_offset;
int ypos = bottom - y[i];
- GLushort d = depth[i];
- writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
- GR_LFB_SRC_FMT_ZA16, 1, 1, 0, (void *) &d);
+ GLushort d16 = depth[i];
+ switch (depth_size) {
+ case 16:
+ writeRegionClipped(fxMesa, GR_BUFFER_AUXBUFFER, xpos, ypos,
+ GR_LFB_SRC_FMT_ZA16, 1, 1, 0,
+ (void *) &d16);
+ break;
+ case 32:
+ if (!fb_point_is_clipped(fxMesa, xpos, ypos)) {
+ if (stencil_size > 0) {
+ /*
+ * Should I sign extend this? I don't
+ * believe so, since GLdepth is unsigned.
+ */
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ sizeof(GLdepth),
+ &d32,
+ FBS_READ);
+ d32 = (d32 &~ 0xFF000000) | (depth[i] & 0x00FFFFFF);
+ } else {
+ d32 = depth[i];
+ }
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ sizeof(GLdepth),
+ &d32,
+ FBS_WRITE);
+ }
+ break;
+ }
}
}
}
@@ -592,51 +1416,409 @@ void fxDDReadDepthPixels(GLcontext *ctx, GLuint n,
for (i = 0; i < n; i++) {
int xpos = x[i] + fxMesa->x_offset;
int ypos = bottom - y[i];
- GLushort d;
- FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d);
- depth[i] = d;
+ GLushort d16;
+ GLuint d32;
+ GLuint depth_size = fxMesa->glVis->DepthBits;
+ GLuint stencil_size = fxMesa->glVis->StencilBits;
+
+ assert((depth_size == 16) || (depth_size == 32));
+ switch (depth_size) {
+ case 16:
+ FX_grLfbReadRegion(GR_BUFFER_AUXBUFFER, xpos, ypos, 1, 1, 0, &d16);
+ depth[i] = d16;
+ break;
+ case 32:
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ depth_size/8,
+ &d32,
+ FBS_READ);
+ /*
+ * Get rid of the stencil bits. Should I sign
+ * extend this? I don't believe so, since GLdepth
+ * is unsigned.
+ */
+ if (stencil_size > 0) {
+ d32 &= 0xFFFFFF;
+ }
+ depth[i] = d32;
+ break;
+ default:
+ assert(0);
+ }
}
}
+/*
+ * Stencil buffer read/write functions.
+ */
+#define DEPTH_VALUE_TO_STENCIL_VALUE(d) (((d) >> 24) & 0xFF)
+#define STENCIL_VALUE_TO_DEPTH_VALUE(s,d) \
+ ((((s) & 0xFF) << 24) | ((d) & 0xFFFFFF))
+#define ASSEMBLE_STENCIL_VALUE(os, ns, mask) \
+ (((os) &~ (mask)) | ((ns) & (mask)))
-/************************************************************************/
+#if 00
+/*
+ * Read a horizontal span of stencil values from the stencil buffer.
+ */
+void
+fxDDReadStencilSpan( GLcontext *ctx,
+ GLuint n,
+ GLint x,
+ GLint y,
+ GLstencil stencil[] )
+{
+ fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
+ GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
+ GLuint i;
+ int xpos = x + fxMesa->x_offset;
+ int ypos = bottom - y;
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDReadStencilSpan(...)\n");
+ }
-void fxSetupDDSpanPointers(GLcontext *ctx)
-{
- ctx->Driver.WriteRGBASpan =fxDDWriteRGBASpan;
- ctx->Driver.WriteRGBSpan =fxDDWriteRGBSpan;
- ctx->Driver.WriteMonoRGBASpan =fxDDWriteMonoRGBASpan;
- ctx->Driver.WriteRGBAPixels =fxDDWriteRGBAPixels;
- ctx->Driver.WriteMonoRGBAPixels =fxDDWriteMonoRGBAPixels;
+ for (i = 0; i < n; i++, ypos += 1) {
+ GLuint d;
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ sizeof(GLdepth),
+ &d,
+ FBS_READ);
+ stencil[i] = DEPTH_VALUE_TO_STENCIL_VALUE(d);
+ }
+}
- ctx->Driver.WriteCI8Span =NULL;
- ctx->Driver.WriteCI32Span =NULL;
- ctx->Driver.WriteMonoCISpan =NULL;
- ctx->Driver.WriteCI32Pixels =NULL;
- ctx->Driver.WriteMonoCIPixels =NULL;
+/*
+ * Write a horizontal span of stencil values into the stencil buffer.
+ * If mask is NULL, write all stencil values.
+ * Else, only write stencil[i] if mask[i] is non-zero.
+ */
+void
+fxDDWriteStencilSpan( GLcontext *ctx,
+ GLuint n,
+ GLint x,
+ GLint y,
+ const GLstencil stencil[],
+ const GLubyte mask[] )
+{
+ fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
+ GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
+ GLuint i;
+ int xpos = x + fxMesa->x_offset;
+ int ypos = bottom - y;
- /* ctx->Driver.ReadRGBASpan =fxDDReadRGBASpan;*/
- ctx->Driver.ReadRGBASpan = read_R5G6B5_span;
- ctx->Driver.ReadRGBAPixels = read_R5G6B5_pixels;
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDWriteStencilSpan(...)\n");
+ }
- ctx->Driver.ReadCI32Span =NULL;
- ctx->Driver.ReadCI32Pixels =NULL;
+ for (i = 0; i < n; i++, ypos += 1) {
+ GLdepth d;
+ GLstencil ns;
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ sizeof(GLdepth),
+ &d,
+ FBS_READ);
+ /*
+ * Find the old stencil value, and strip off the bits
+ * we are going to write.
+ */
+ ns = ASSEMBLE_STENCIL_VALUE(DEPTH_VALUE_TO_STENCIL_VALUE(d),
+ stencil[i],
+ mask[i]);
+ /*
+ * Now, assemble the new StenDepth value, with the old
+ * depth value, the old stencil value in the bits
+ * where mask is 0, and the new stencil value in the bits
+ * where mask is 1.
+ */
+ d = STENCIL_VALUE_TO_DEPTH_VALUE(ns, d);
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ sizeof(GLdepth),
+ &d,
+ FBS_WRITE);
+ }
}
+/* Write an array of stencil values into the stencil buffer.
+ * If mask is NULL, write all stencil values.
+ * Else, only write stencil[i] if mask[i] is non-zero.
+ */
+void
+fxDDReadStencilPixels( GLcontext *ctx,
+ GLuint n,
+ const GLint x[],
+ const GLint y[],
+ GLstencil stencil[])
+{
+ fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
+ GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
+ GLuint i;
-#else
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDReadStencilPixels(...)\n");
+ }
+ for (i = 0; i < n; i++) {
+ int xpos = x[i] + fxMesa->x_offset;
+ int ypos = bottom - y[i];
+ GLuint d;
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ sizeof(GLdepth),
+ &d,
+ FBS_READ);
+ stencil[i] = DEPTH_VALUE_TO_STENCIL_VALUE(d);
+ }
+}
/*
- * Need this to provide at least one external definition.
+ * Read an array of stencil values from the stencil buffer.
*/
+void
+fxDDWriteStencilPixels( GLcontext *ctx,
+ GLuint n,
+ const GLint x[],
+ const GLint y[],
+ const GLstencil stencil[],
+ const GLstencil mask[])
+{
+ fxMesaContext fxMesa = (fxMesaContext)ctx->DriverCtx;
+ GLint bottom = fxMesa->height + fxMesa->y_offset - 1;
+ GLuint i;
+
+ if (MESA_VERBOSE & VERBOSE_DRIVER) {
+ fprintf(stderr, "fxmesa: fxDDWriteStencilPixels(...)\n");
+ }
-int gl_fx_dummy_function_span(void)
+ for (i = 0; i < n; i++) {
+ int xpos = x[i] + fxMesa->x_offset;
+ int ypos = bottom - y[i];
+ GLuint d;
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ sizeof(GLdepth),
+ &d,
+ FBS_READ);
+ d = STENCIL_VALUE_TO_DEPTH_VALUE(stencil[i], d);
+ rw_fb_span(fxMesa,
+ GR_BUFFER_AUXBUFFER,
+ xpos, ypos,
+ 1,
+ sizeof(GLdepth),
+ &d,
+ FBS_WRITE);
+ }
+}
+#endif /* disable fxddStencil* funcs */
+
+
+#define EXTRACT_S_FROM_ZS(zs) (((zs) >> 24) & 0xFF)
+#define EXTRACT_Z_FROM_ZS(zs) ((zs) & 0xffffff)
+#define BUILD_ZS(z, s) (((s) << 24) | (z))
+
+static void write_stencil_span(GLcontext *ctx, GLuint n, GLint x, GLint y,
+ const GLstencil stencil[],
+ const GLubyte mask[] )
{
- return 0;
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbInfo_t info;
+ int s;
+ void *d;
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_WRITE_ONLY,
+ GR_BUFFER_AUXBUFFER,
+ GR_LFBWRITEMODE_Z32,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+ const GLint scrX = winX + x;
+ const GLint scrY = winY - y;
+
+ GLint dstStride = info.strideInBytes;
+ GLubyte *dst = (GLubyte *) info.lfbPtr
+ + (winY - y) * dstStride + (winX + x) * 4;
+ GLuint *dst32 = (GLuint *) dst;
+ GLubyte visMask[MAX_WIDTH];
+ GLuint i;
+ generate_vismask(fxMesa, scrX, scrY, n, visMask);
+ s = dstStride;
+ d = dst32;
+ for (i = 0; i < n; i++) {
+ if (visMask[i] && (!mask || mask[i])) {
+ GLuint zs = dst32[i];
+ GLuint z = EXTRACT_Z_FROM_ZS(zs);
+ zs = BUILD_ZS(z, stencil[i]);
+ dst32[i] = /*zs;*/ stencil[i];
+ }
+ }
+ grLfbUnlock(GR_LFB_WRITE_ONLY, GR_BUFFER_AUXBUFFER);
+ }
+ else {
+ s = -1;
+ d = 0;
+ }
+ END_BOARD_LOCK();
+ /*
+ printf("write stencil span %d %p\n", s, d);
+ printf("info: size=%d lfbPtr=%p stride=%x writeMode=%x origin=%x\n",
+ info.size, info.lfbPtr, info.strideInBytes, info.writeMode, info.origin);
+ */
+}
+
+
+static void
+read_stencil_span(GLcontext *ctx, GLuint n, GLint x, GLint y,
+ GLstencil stencil[])
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+ GrLfbInfo_t info;
+ /*
+ int s;
+ void *d;
+ */
+
+ BEGIN_BOARD_LOCK();
+ info.size = sizeof(info);
+ if (grLfbLock(GR_LFB_READ_ONLY,
+ GR_BUFFER_AUXBUFFER,
+ GR_LFBWRITEMODE_Z32,
+ GR_ORIGIN_UPPER_LEFT,
+ FXFALSE,
+ &info)) {
+ const GLint winY = fxMesa->y_offset + fxMesa->height - 1;
+ const GLint winX = fxMesa->x_offset;
+ GLint srcStride = /*info.strideInBytes;*/ 8192 ; /* XXX a hack! */
+ const GLubyte *src = (const GLubyte *) info.lfbPtr
+ + (winY - y) * srcStride + (winX + x) * 4;
+ const GLuint *src32 = (const GLuint *) src;
+ GLuint i;
+ /*
+ s = srcStride;
+ d = src32;
+ */
+ for (i = 0; i < n; i++) {
+ stencil[i] = EXTRACT_S_FROM_ZS(src32[i]);
+ }
+ grLfbUnlock(GR_LFB_READ_ONLY, GR_BUFFER_AUXBUFFER);
+ }
+ END_BOARD_LOCK();
+ /*
+ printf("read stencil span %d %p\n", s, d);
+ printf("info: size=%d lfbPtr=%p stride=%x writeMode=%x origin=%x\n",
+ info.size, info.lfbPtr, info.strideInBytes, info.writeMode, info.origin);
+ */
+}
+
+
+static void
+write_stencil_pixels( GLcontext *ctx, GLuint n,
+ const GLint x[], const GLint y[],
+ const GLstencil stencil[], const GLubyte mask[])
+{
+ /* XXX optimize this */
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ if (mask[i]) {
+ write_stencil_span(ctx, 1, x[i], y[i], stencil + i, mask + i);
+ }
+ }
+}
+
+
+static void
+read_stencil_pixels(GLcontext *ctx, GLuint n, const GLint x[], const GLint y[],
+ GLstencil stencil[])
+{
+ /* XXX optimize this */
+ GLuint i;
+ for (i = 0; i < n; i++) {
+ read_stencil_span(ctx, 1, x[i], y[i], stencil + i);
+ }
}
-#endif /* FX */
+
+
+void fxSetupDDSpanPointers(GLcontext *ctx)
+{
+ fxMesaContext fxMesa = FX_CONTEXT(ctx);
+
+ if (ctx->Visual->RedBits == 5 &&
+ ctx->Visual->GreenBits == 6 &&
+ ctx->Visual->BlueBits == 5 &&
+ ctx->Visual->AlphaBits == 0) {
+ /* 16bpp mode */
+ ctx->Driver.WriteRGBASpan = write_R5G6B5_rgba_span;
+ ctx->Driver.WriteRGBSpan = write_R5G6B5_rgb_span;
+ ctx->Driver.WriteMonoRGBASpan = write_R5G6B5_mono_span;
+ ctx->Driver.WriteRGBAPixels = write_R5G6B5_pixels;
+ ctx->Driver.WriteMonoRGBAPixels = write_R5G6B5_mono_pixels;
+ ctx->Driver.ReadRGBASpan = read_R5G6B5_span;
+ ctx->Driver.ReadRGBAPixels = read_R5G6B5_pixels;
+ }
+ else if (ctx->Visual->RedBits == 8 &&
+ ctx->Visual->GreenBits == 8 &&
+ ctx->Visual->BlueBits == 8 &&
+ ctx->Visual->AlphaBits == 0) {
+ /* 24bpp mode */
+ ctx->Driver.WriteRGBASpan = write_R8G8B8_rgba_span;
+ ctx->Driver.WriteRGBSpan = write_R8G8B8_rgb_span;
+ ctx->Driver.WriteMonoRGBASpan = write_R8G8B8_mono_span;
+ ctx->Driver.WriteRGBAPixels = write_R8G8B8_pixels;
+ ctx->Driver.WriteMonoRGBAPixels = write_R8G8B8_mono_pixels;
+ ctx->Driver.ReadRGBASpan = read_R8G8B8_span;
+ ctx->Driver.ReadRGBAPixels = read_R8G8B8_pixels;
+ }
+ else if (ctx->Visual->RedBits == 8 &&
+ ctx->Visual->GreenBits == 8 &&
+ ctx->Visual->BlueBits == 8 &&
+ ctx->Visual->AlphaBits == 8) {
+ /* 32bpp mode */
+ ctx->Driver.WriteRGBASpan = write_R8G8B8A8_rgba_span;
+ ctx->Driver.WriteRGBSpan = write_R8G8B8A8_rgb_span;
+ ctx->Driver.WriteMonoRGBASpan = write_R8G8B8A8_mono_span;
+ ctx->Driver.WriteRGBAPixels = write_R8G8B8A8_pixels;
+ ctx->Driver.WriteMonoRGBAPixels = write_R8G8B8A8_mono_pixels;
+ ctx->Driver.ReadRGBASpan = read_R8G8B8A8_span;
+ ctx->Driver.ReadRGBAPixels = read_R8G8B8A8_pixels;
+ }
+ else {
+ abort();
+ }
+
+ if (fxMesa->haveHwStencil) {
+ ctx->Driver.WriteStencilSpan = write_stencil_span;
+ ctx->Driver.ReadStencilSpan = read_stencil_span;
+ ctx->Driver.WriteStencilPixels = write_stencil_pixels;
+ ctx->Driver.ReadStencilPixels = read_stencil_pixels;
+ }
+
+ ctx->Driver.WriteCI8Span = NULL;
+ ctx->Driver.WriteCI32Span = NULL;
+ ctx->Driver.WriteMonoCISpan = NULL;
+ ctx->Driver.WriteCI32Pixels = NULL;
+ ctx->Driver.WriteMonoCIPixels = NULL;
+ ctx->Driver.ReadCI32Span = NULL;
+ ctx->Driver.ReadCI32Pixels = NULL;
+}