From: Ian Romanick Date: Fri, 8 Apr 2005 23:54:20 +0000 (+0000) Subject: Remove all the radeon_subset files. They were completely unused. Keith X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=db382c5b1d3357cc9add8a55306ce702a5df0e5e;p=mesa.git Remove all the radeon_subset files. They were completely unused. Keith Whitwell says, "[T]he radeon subset code can probably be archived now." This "fixes" bug #1623. --- diff --git a/src/mesa/drivers/dri/radeon/radeon_subset.h b/src/mesa/drivers/dri/radeon/radeon_subset.h deleted file mode 100644 index 1b6e7bd432c..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_subset.h +++ /dev/null @@ -1,75 +0,0 @@ -/** - * \file radeon_subset.h - * \brief Radeon subset driver declarations. - * - * \author Keith Whitwell - */ - -/* - * Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - * Tungsten Grahpics Inc., Austin, Texas. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * ATI, TUNGSTEN GRAHPICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* $XFree86$ */ - -#ifndef __RADEON_SUBSET_H__ -#define __RADEON_SUBSET_H__ - -extern void radeonPointsBitmap( GLsizei width, GLsizei height, - GLfloat xorig, GLfloat yorig, - GLfloat xmove, GLfloat ymove, - const GLubyte *bitmap ); - -extern void radeonReadPixels( GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels ); - -extern void radeon_select_Install( GLcontext *ctx ); - -extern void radeonInitSelect( GLcontext *ctx ); - -extern void radeonVtxfmtDestroy( GLcontext *ctx ); - -extern void radeonVtxfmtMakeCurrent( GLcontext *ctx ); - -extern void radeonVtxfmtUnbindContext( GLcontext *ctx ); - -extern void radeonVtxfmtInit( GLcontext *ctx ); - -extern void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); - -extern void radeonVtxfmtInvalidate( GLcontext *ctx ); - -extern void radeonSubsetVtxEnableTCL( radeonContextPtr rmesa, GLboolean flag ); - -extern void radeonUpdateTextureState( GLcontext *ctx ); - -extern void radeonInitTextureFuncs( GLcontext *ctx ); - -extern void radeonAgeTextures( radeonContextPtr rmesa, int heap ); - -extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ); - -#endif diff --git a/src/mesa/drivers/dri/radeon/radeon_subset_bitmap.c b/src/mesa/drivers/dri/radeon/radeon_subset_bitmap.c deleted file mode 100644 index 3ac20bd7b71..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_subset_bitmap.c +++ /dev/null @@ -1,197 +0,0 @@ -/** - * \file radeon_subset_bitmap.c - * \brief Bitmap drawing. - * - * \author Keith Whitwell - */ - -/* - * Copyright 2003 ATI Technologies Inc., Ontario, Canada, and - * Tungsten Graphics Inc., Cedar Park, Texas. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/* $XFree86$ */ - -#include "glheader.h" -#include "mtypes.h" -#include "colormac.h" -#include "context.h" -#include "enums.h" -#include "imports.h" -#include "image.h" -/*#include "mmath.h"*/ -#include "macros.h" -#include "state.h" - -#include "radeon_context.h" -#include "radeon_ioctl.h" -#include "radeon_state.h" -#include "radeon_subset.h" - -/** - * \brief Cope with depth operations by drawing individual pixels as points - * - * \param xorig x coordinate of the bitmap corner. - * \param yorig y coordinate of the bitmap corner. - * \param xmove increment to the final x coordinate. - * \param ymove increment to the final y coordinate. - * \param width bitmap width. - * \param height bitmap height. - * \param bitmap bitmap pointer. - * - * Clips the bitmap coordinates and adjusts for windows coordinates. Draws the - * bitmap with glPoints(), turning off TCL and hardware viewport transformation - * to emit raw pixel coordinates. Finally fires any outstanding vertices and - * restores TCL, viewport, texture and color states. - */ -void -radeonPointsBitmap( GLsizei width, GLsizei height, - GLfloat xorig, GLfloat yorig, - GLfloat xmove, GLfloat ymove, - const GLubyte *bitmap ) -{ - GET_CURRENT_CONTEXT(ctx); - GLsizei bmwidth = width, bmheight = height; - GLint px, py; - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat saved_color[4], saved_tex0[2]; - GLint row, col; - GLuint orig_se_cntl; - GLuint w, h; - const struct gl_pixelstore_attrib *unpack = &ctx->Unpack; - - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - if (width < 0 || height < 0) { - _mesa_error( ctx, GL_INVALID_VALUE, "glBitmap(width or height < 0)" ); - return; - } - - if (!ctx->Current.RasterPosValid) - return; - - if (ctx->NewState) - _mesa_update_state(ctx); - - - if (ctx->_RotateMode) { - width = bmheight; height = bmwidth; - - px = IFLOOR(ctx->Current.RasterPos[0] + yorig); - py = IFLOOR(ctx->Current.RasterPos[1] + xorig); - - ctx->Current.RasterPos[0] += ymove; - ctx->Current.RasterPos[1] += xmove; - } - else { - px = IFLOOR(ctx->Current.RasterPos[0] - xorig); - py = IFLOOR(ctx->Current.RasterPos[1] - yorig); - - ctx->Current.RasterPos[0] += xmove; - ctx->Current.RasterPos[1] += ymove; - } - - - - /* Turn off tcl and the hw viewport transformation so that we can - * emit raw pixel coordinates: - */ - radeonSubsetVtxEnableTCL( rmesa, GL_FALSE ); - RADEON_STATECHANGE( rmesa, set ); - orig_se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL]; - rmesa->hw.set.cmd[SET_SE_CNTL] &= ~(RADEON_VPORT_XY_XFORM_ENABLE | - RADEON_VPORT_Z_XFORM_ENABLE); - - - /* Adjust for window coordinates, flip y values: - */ - h = rmesa->dri.drawable->h + rmesa->dri.drawable->y - 1; - w = rmesa->dri.drawable->w; - px += rmesa->dri.drawable->x; - - /* Save current color, texcoord to restore later: - */ - COPY_4V( saved_color, ctx->Current.Attrib[VERT_ATTRIB_COLOR0] ); - COPY_2V( saved_tex0, ctx->Current.Attrib[VERT_ATTRIB_TEX0] ); - - /* Just use the GL entrypoints to talk to radeon_subset_vtx.c: - */ - glBegin( GL_POINTS ); - glColor4fv( ctx->Current.RasterColor ); - glTexCoord2fv( ctx->Current.RasterTexCoords[0] ); - - - if (ctx->_RotateMode) { - for (col=0; col> (unpack->SkipPixels & 0x7); - for (row=0; row> 1); - } - /* get ready for next row */ - if (mask != 128) - src++; - } - } - else { - for (row=0; row> (unpack->SkipPixels & 0x7); - for (col=0; col> 1); - } - /* get ready for next row */ - if (mask != 128) - src++; - } - } - - glEnd(); - glColor4fv( saved_color ); - glTexCoord2fv( saved_tex0 ); - - /* Fire outstanding vertices, restore state - */ - RADEON_STATECHANGE( rmesa, set ); - rmesa->hw.set.cmd[SET_SE_CNTL] = orig_se_cntl; - radeonSubsetVtxEnableTCL( rmesa, GL_TRUE ); -} - diff --git a/src/mesa/drivers/dri/radeon/radeon_subset_readpix.c b/src/mesa/drivers/dri/radeon/radeon_subset_readpix.c deleted file mode 100644 index f72d3b84728..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_subset_readpix.c +++ /dev/null @@ -1,246 +0,0 @@ -/** - * \file radeon_subset_readpix.c - * \brief Pixel reading. - * - * \author Keith Whitwell - * \author Brian Paul - */ - -/* - * Copyright 2003 ATI Technologies Inc., Ontario, Canada, and - * Tungsten Graphics Inc., Cedar Park, Texas. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* $XFree86$ */ - -#include "glheader.h" -#include "mtypes.h" -#include "colormac.h" -#include "context.h" -#include "enums.h" -#include "imports.h" -/*#include "mmath.h" */ -#include "macros.h" -#include "state.h" - -#include "radeon_context.h" -#include "radeon_ioctl.h" -#include "radeon_state.h" -#include "radeon_subset.h" - -/** - * \brief Read pixel in RGBA format on a Radeon 16bpp frame buffer. - * - * \param rgba destination pointer. - * \param ptr pointer to the pixel in the frame buffer. - */ -#define READ_RGBA_16( rgba, ptr ) \ -do { \ - GLushort p = *(GLushort *)ptr; \ - rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \ - rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \ - rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \ - rgba[3] = 0xff; \ -} while (0) - -/** - * \brief Read pixel in RGBA format on a Radeon 32bpp frame buffer. - * - * \param rgba destination pointer. - * \param ptr pointer to the pixel in the frame buffer. - */ -#define READ_RGBA_32( rgba, ptr ) \ -do { \ - GLuint p = *(GLuint *)ptr; \ - rgba[0] = (p >> 16) & 0xff; \ - rgba[1] = (p >> 8) & 0xff; \ - rgba[2] = (p >> 0) & 0xff; \ - rgba[3] = (p >> 24) & 0xff; \ -} while (0) - -/** - * \brief Read a span in RGBA format. - * - * \param ctx GL context. - * \param n number of pixels in the span. - * \param x x position of the span start. - * \param y y position of the span. - * \param rgba destination buffer. - * - * Calculates the pointer to the span start in the frame buffer and uses either - * #READ_RGBA_16 or #READ_RGBA_32 macros to copy the values. - */ -static void ReadRGBASpan( const GLcontext *ctx, - GLuint n, GLint x, GLint y, - GLubyte rgba[][4]) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonScreenPtr radeonScreen = rmesa->radeonScreen; - __DRIdrawablePrivate *dPriv = rmesa->dri.drawable; - GLuint cpp = radeonScreen->cpp; - GLuint pitch = radeonScreen->frontPitch * cpp; - GLint i; - - if (ctx->_RotateMode) { - char *ptr = (char *)(rmesa->dri.screen->pFB + - rmesa->state.pixel.readOffset + - ((dPriv->x + (dPriv->w - y - 1)) * cpp) + - ((dPriv->y + (dPriv->h - x - 1)) * pitch)); - - if (cpp == 4) - for (i = 0; i < n; i++, ptr -= pitch) - READ_RGBA_32( rgba[i], ptr ); - else - for (i = 0; i < n; i++, ptr -= pitch) - READ_RGBA_16( rgba[i], ptr ); - } - else { - char *ptr = (char *)(rmesa->dri.screen->pFB + - rmesa->state.pixel.readOffset + - ((dPriv->x + x) * cpp) + - ((dPriv->y + (dPriv->h - y - 1)) * pitch)); - - if (cpp == 4) - for (i = 0; i < n; i++, ptr += cpp) - READ_RGBA_32( rgba[i], ptr ); - else - for (i = 0; i < n; i++, ptr += cpp) - READ_RGBA_16( rgba[i], ptr ); - } -} - - -/** - * \brief Optimized glReadPixels(). - * - * To be used with particular pixel formats GL_UNSIGNED_BYTE and GL_RGBA, when pixel - * scaling, biasing and mapping are disabled. - * - * \param x x start position of the reading rectangle. - * \param y y start position of the reading rectangle. - * \param width width of the reading rectangle. - * \param height height of the reading rectangle. - * \param format pixel format. Must be GL_RGBA. - * \param type pixel type. Must be GL_UNSIGNED_BYTE. - * \param pixels pixel data. - * - * After asserting the above conditions, compensates for clipping and calls - * ReadRGBASpan() to read each row. - */ -void radeonReadPixels( GLint x, GLint y, - GLsizei width, GLsizei height, - GLenum format, GLenum type, - GLvoid *pixels ) -{ - GET_CURRENT_CONTEXT(ctx); - GLint srcX = x; - GLint srcY = y; - GLint readWidth = width; /* actual width read */ - GLint readHeight = height; /* actual height read */ - const struct gl_pixelstore_attrib *packing = &ctx->Pack; - GLint skipRows = packing->SkipRows; - GLint skipPixels = packing->SkipPixels; - GLint rowLength; - ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx); - - { - GLint tmp, tmps; - tmp = x; x = y; y = tmp; - tmps = width; width = height; height = tmps; - } - - if (width < 0 || height < 0) { - _mesa_error( ctx, GL_INVALID_VALUE, - "glReadPixels(width=%d height=%d)", width, height ); - return; - } - - if (!pixels) { - _mesa_error( ctx, GL_INVALID_VALUE, "glReadPixels(pixels)" ); - return; - } - - if (ctx->NewState) - _mesa_update_state(ctx); - - - /* can't do scale, bias, mapping, etc */ - assert(!ctx->_ImageTransferState); - - /* can't do fancy pixel packing */ - assert (packing->Alignment == 1 && - !packing->SwapBytes && - !packing->LsbFirst); - - - if (packing->RowLength > 0) - rowLength = packing->RowLength; - else - rowLength = width; - - /* horizontal clipping */ - if (srcX < 0) { - skipPixels -= srcX; - readWidth += srcX; - srcX = 0; - } - if (srcX + readWidth > (GLint) ctx->ReadBuffer->Width) - readWidth -= (srcX + readWidth - (GLint) ctx->ReadBuffer->Width); - if (readWidth <= 0) - return; - - /* vertical clipping */ - if (srcY < 0) { - skipRows -= srcY; - readHeight += srcY; - srcY = 0; - } - if (srcY + readHeight > (GLint) ctx->ReadBuffer->Height) - readHeight -= (srcY + readHeight - (GLint) ctx->ReadBuffer->Height); - if (readHeight <= 0) - return; - - /* - * Ready to read! - * The window region at (destX, destY) of size (readWidth, readHeight) - * will be read back. - * We'll write pixel data to buffer pointed to by "pixels" but we'll - * skip "skipRows" rows and skip "skipPixels" pixels/row. - */ - if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) { - GLchan *dest = (GLchan *) pixels - + (skipRows * rowLength + skipPixels) * 4; - GLint row; - - for (row=0; roweyePos.x = INTERPOLATE(t, v0->eyePos.x, v1->eyePos.x); - vOut->eyePos.y = INTERPOLATE(t, v0->eyePos.y, v1->eyePos.y); - vOut->eyePos.z = INTERPOLATE(t, v0->eyePos.z, v1->eyePos.z); - vOut->eyePos.w = INTERPOLATE(t, v0->eyePos.w, v1->eyePos.w); - - vOut->clipPos.x = INTERPOLATE(t, v0->clipPos.x, v1->clipPos.x); - vOut->clipPos.y = INTERPOLATE(t, v0->clipPos.y, v1->clipPos.y); - vOut->clipPos.z = INTERPOLATE(t, v0->clipPos.z, v1->clipPos.z); - vOut->clipPos.w = INTERPOLATE(t, v0->clipPos.w, v1->clipPos.w); - - vOut->color.r = INTERPOLATE(t, v0->color.r, v1->color.r); - vOut->color.g = INTERPOLATE(t, v0->color.g, v1->color.g); - vOut->color.b = INTERPOLATE(t, v0->color.b, v1->color.b); - vOut->color.a = INTERPOLATE(t, v0->color.a, v1->color.a); - - vOut->texCoord.s = INTERPOLATE(t, v0->texCoord.s, v1->texCoord.s); - vOut->texCoord.t = INTERPOLATE(t, v0->texCoord.t, v1->texCoord.t); -} - - - - -/* - * Clip bit codes - */ -#define CLIP_LEFT 1 -#define CLIP_RIGHT 2 -#define CLIP_BOTTOM 4 -#define CLIP_TOP 8 -#define CLIP_NEAR 16 -#define CLIP_FAR 32 - - -/** - * \brief Apply view volume clip testing to a point. - * - * \param v point to test. - * \return zero if visible, or the clip code mask, i.e., binary OR of a - * combination of the #CLIP_LEFT, #CLIP_RIGHT, #CLIP_BOTTOM, #CLIP_TOP, #CLIP_NEAR, - * #CLIP_FAR clip bit codes. - */ -static GLuint -clip_point(const vertex *v) -{ - GLuint mask = 0; - if (v->clipPos.x > v->clipPos.w) mask |= CLIP_RIGHT; - if (v->clipPos.x < -v->clipPos.w) mask |= CLIP_LEFT; - if (v->clipPos.y > v->clipPos.w) mask |= CLIP_TOP; - if (v->clipPos.y < -v->clipPos.w) mask |= CLIP_BOTTOM; - if (v->clipPos.z > v->clipPos.w) mask |= CLIP_FAR; - if (v->clipPos.z < -v->clipPos.w) mask |= CLIP_NEAR; - return mask; -} - - -/** - * \def GENERAL_CLIP - * \brief Clipping utility macro. - * - * We use 6 instances of this code in each of the clip_line() and - * clip_polygon() to clip against the 6 planes. For each plane, we define the - * #OUTSIDE and #COMPUTE_INTERSECTION macros appropriately. - */ - - -/** - * \brief Apply clipping to a line segment. - * - * \param v0in input start vertex - * \param v1in input end vertesx - * \param v0new output start vertex - * \param v1new output end vertex - * - * \return GL_TRUE if the line segment is visible, or GL_FALSE if it is totally - * clipped. - * - * \sa #GENERAL_CLIP. - */ -static GLboolean -clip_line(const vertex *v0in, const vertex *v1in, - vertex *v0new, vertex *v1new) -{ - vertex v0, v1, vNew; - GLfloat dx, dy, dz, dw, t; - GLuint code0, code1; - - code0 = clip_point(v0in); - code1 = clip_point(v1in); - if (code0 & code1) - return GL_FALSE; /* totally clipped */ - - *v0new = *v0in; - *v1new = *v1in; - if (code0 == 0 && code1 == 0) - return GL_TRUE; /* no clipping needed */ - - v0 = *v0in; - v1 = *v1in; - - -#define GENERAL_CLIP \ - if (OUTSIDE(v0)) { \ - if (OUTSIDE(v1)) { \ - /* both verts are outside ==> return 0 */ \ - return 0; \ - } \ - else { \ - /* v0 is outside, v1 is inside ==> clip */ \ - COMPUTE_INTERSECTION( v1, v0, vNew ) \ - interpolate_vertex(t, &v1, &v0, &vNew); \ - v0 = vNew; \ - } \ - } \ - else { \ - if (OUTSIDE(v1)) { \ - /* v0 is inside, v1 is outside ==> clip */ \ - COMPUTE_INTERSECTION( v0, v1, vNew ) \ - interpolate_vertex(t, &v0, &v1, &vNew); \ - v1 = vNew; \ - } \ - /* else both verts are inside ==> do nothing */ \ - } - - /* Clip against +X side */ -#define OUTSIDE(V) (V.clipPos.x > V.clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dx = OUT.clipPos.x - IN.clipPos.x; \ - dw = OUT.clipPos.w - IN.clipPos.w; \ - t = (IN.clipPos.x - IN.clipPos.w) / (dw-dx); - GENERAL_CLIP -#undef OUTSIDE -#undef COMPUTE_INTERSECTION - - /* Clip against -X side */ -#define OUTSIDE(V) (V.clipPos.x < -(V.clipPos.w)) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dx = OUT.clipPos.x - IN.clipPos.x; \ - dw = OUT.clipPos.w - IN.clipPos.w; \ - t = -(IN.clipPos.x + IN.clipPos.w) / (dw+dx); - GENERAL_CLIP -#undef OUTSIDE -#undef COMPUTE_INTERSECTION - - /* Clip against +Y side */ -#define OUTSIDE(V) (V.clipPos.y > V.clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dy = OUT.clipPos.y - IN.clipPos.y; \ - dw = OUT.clipPos.w - IN.clipPos.w; \ - t = (IN.clipPos.y - IN.clipPos.w) / (dw-dy); - GENERAL_CLIP -#undef OUTSIDE -#undef COMPUTE_INTERSECTION - - /* Clip against -Y side */ -#define OUTSIDE(V) (V.clipPos.y < -(V.clipPos.w)) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dy = OUT.clipPos.y - IN.clipPos.y; \ - dw = OUT.clipPos.w - IN.clipPos.w; \ - t = -(IN.clipPos.y + IN.clipPos.w) / (dw+dy); - GENERAL_CLIP -#undef OUTSIDE -#undef COMPUTE_INTERSECTION - - /* Clip against +Z side */ -#define OUTSIDE(V) (V.clipPos.z > V.clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dz = OUT.clipPos.z - IN.clipPos.z; \ - dw = OUT.clipPos.w - IN.clipPos.w; \ - t = (IN.clipPos.z - IN.clipPos.w) / (dw-dz); - GENERAL_CLIP -#undef OUTSIDE -#undef COMPUTE_INTERSECTION - - /* Clip against -Z side */ -#define OUTSIDE(V) (V.clipPos.z < -(V.clipPos.w)) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dz = OUT.clipPos.z - IN.clipPos.z; \ - dw = OUT.clipPos.w - IN.clipPos.w; \ - t = -(IN.clipPos.z + IN.clipPos.w) / (dw+dz); - GENERAL_CLIP -#undef OUTSIDE -#undef COMPUTE_INTERSECTION - -#undef GENERAL_CLIP - - *v0new = v0; - *v1new = v1; - return GL_TRUE; -} - - - -/** - * \brief Apply clipping to a polygon. - * - * \param vIn array of input vertices. - * \param inCount number of input vertices - * \param vOut array of output vertices. - * - * \return number of vertices in \p vOut. - * - * \sa #GENERAL_CLIP. - */ -static GLuint -clip_polygon(const vertex *vIn, unsigned int inCount, vertex *vOut) -{ - vertex inlist[20], outlist[20]; - GLfloat dx, dy, dz, dw, t; - GLuint incount, outcount, previ, curri, result; - const vertex *currVert, *prevVert; - vertex *newVert; - - -#define GENERAL_CLIP(INCOUNT, INLIST, OUTCOUNT, OUTLIST) \ - if (INCOUNT < 3) \ - return GL_FALSE; \ - previ = INCOUNT - 1; /* let previous = last vertex */ \ - prevVert = INLIST + previ; \ - OUTCOUNT = 0; \ - for (curri = 0; curri < INCOUNT; curri++) { \ - currVert = INLIST + curri; \ - if (INSIDE(currVert)) { \ - if (INSIDE(prevVert)) { \ - /* both verts are inside ==> copy current to outlist */ \ - OUTLIST[OUTCOUNT] = *currVert; \ - OUTCOUNT++; \ - } \ - else { \ - newVert = OUTLIST + OUTCOUNT; \ - /* current is inside and previous is outside ==> clip */ \ - COMPUTE_INTERSECTION( currVert, prevVert, newVert ) \ - OUTCOUNT++; \ - /* Output current */ \ - OUTLIST[OUTCOUNT] = *currVert; \ - OUTCOUNT++; \ - } \ - } \ - else { \ - if (INSIDE(prevVert)) { \ - newVert = OUTLIST + OUTCOUNT; \ - /* current is outside and previous is inside ==> clip */ \ - COMPUTE_INTERSECTION( prevVert, currVert, newVert ); \ - OUTLIST[OUTCOUNT] = *newVert; \ - OUTCOUNT++; \ - } \ - /* else both verts are outside ==> do nothing */ \ - } \ - /* let previous = current */ \ - previ = curri; \ - prevVert = currVert; \ - } - -/* - * Clip against +X - */ -#define INSIDE(V) (V->clipPos.x <= V->clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dx = OUT->clipPos.x - IN->clipPos.x; \ - dw = OUT->clipPos.w - IN->clipPos.w; \ - t = (IN->clipPos.x - IN->clipPos.w) / (dw - dx); \ - interpolate_vertex(t, IN, OUT, NEW ); - - GENERAL_CLIP(inCount, vIn, outcount, outlist) - -#undef INSIDE -#undef COMPUTE_INTERSECTION - -/* - * Clip against -X - */ -#define INSIDE(V) (V->clipPos.x >= -V->clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dx = OUT->clipPos.x - IN->clipPos.x; \ - dw = OUT->clipPos.w - IN->clipPos.w; \ - t = -(IN->clipPos.x + IN->clipPos.w) / (dw + dx); \ - interpolate_vertex(t, IN, OUT, NEW ); - - GENERAL_CLIP(outcount, outlist, incount, inlist) - -#undef INSIDE -#undef COMPUTE_INTERSECTION - -/* - * Clip against +Y - */ -#define INSIDE(V) (V->clipPos.y <= V->clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dy = OUT->clipPos.y - IN->clipPos.y; \ - dw = OUT->clipPos.w - IN->clipPos.w; \ - t = (IN->clipPos.y - IN->clipPos.w) / (dw - dy); \ - interpolate_vertex(t, IN, OUT, NEW ); - - GENERAL_CLIP(incount, inlist, outcount, outlist) - -#undef INSIDE -#undef COMPUTE_INTERSECTION - -/* - * Clip against -Y - */ -#define INSIDE(V) (V->clipPos.y >= -V->clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dy = OUT->clipPos.y - IN->clipPos.y; \ - dw = OUT->clipPos.w - IN->clipPos.w; \ - t = -(IN->clipPos.y + IN->clipPos.w) / (dw + dy); \ - interpolate_vertex(t, IN, OUT, NEW ); - - GENERAL_CLIP(outcount, outlist, incount, inlist) - -#undef INSIDE -#undef COMPUTE_INTERSECTION - -/* - * Clip against +Z - */ -#define INSIDE(V) (V->clipPos.z <= V->clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dz = OUT->clipPos.z - IN->clipPos.z; \ - dw = OUT->clipPos.w - IN->clipPos.w; \ - t = (IN->clipPos.z - IN->clipPos.w) / (dw - dz); \ - interpolate_vertex(t, IN, OUT, NEW ); - - GENERAL_CLIP(incount, inlist, outcount, outlist) - -#undef INSIDE -#undef COMPUTE_INTERSECTION - -/* - * Clip against -Z - */ -#define INSIDE(V) (V->clipPos.z >= -V->clipPos.w) -#define COMPUTE_INTERSECTION( IN, OUT, NEW ) \ - dz = OUT->clipPos.z - IN->clipPos.z; \ - dw = OUT->clipPos.w - IN->clipPos.w; \ - t = -(IN->clipPos.z + IN->clipPos.w) / (dw + dz); \ - interpolate_vertex(t, IN, OUT, NEW ); - - GENERAL_CLIP(outcount, outlist, result, vOut) - -#undef INSIDE -#undef COMPUTE_INTERSECTION - -#undef GENERAL_CLIP - - return result; -} - -/*@}*/ - - - -/**********************************************************************/ -/** \name Selection */ -/**********************************************************************/ -/*@{*/ - -/** - * \brief Select point. - * - * \param v vertex. - * - * If the clipped point is visible then maps the vertex into window coordinates - * and calls _mesa_update_hitflag(). - */ -static void -select_point(const vertex *v) -{ - GET_CURRENT_CONTEXT(ctx); - if (clip_point(v) == 0) - { - vertex c = *v; - MAP_POINT(c.winPos, c.clipPos, ctx->Viewport); - _mesa_update_hitflag(ctx, c.winPos.z); - } -} - -/** - * \brief Select line. - * - * \param v0 first vertex. - * \param v1 second vertex. - * - * If the clipped line is visible then maps the vertices into window coordinates - * and calls _mesa_update_hitflag(). - */ -static void -select_line(const vertex *v0, const vertex *v1) -{ - GET_CURRENT_CONTEXT(ctx); - vertex c0, c1; - if (clip_line(v0, v1, &c0, &c1)) - { - MAP_POINT(c0.winPos, c0.clipPos, ctx->Viewport); - MAP_POINT(c1.winPos, c1.clipPos, ctx->Viewport); - _mesa_update_hitflag(ctx, c0.winPos.z); - _mesa_update_hitflag(ctx, c1.winPos.z); - } -} - -/** - * \brief Select line. - * - * \param v0 first vertex. - * \param v1 second vertex. - * \param v2 third vertex. - * - * If the clipped polygon is visible then maps the vertices into window - * coordinates and calls _mesa_update_hitflag(). - */ -static void -select_triangle(const vertex *v0, - const vertex *v1, - const vertex *v2) -{ - GET_CURRENT_CONTEXT(ctx); - vertex vlist[3], vclipped[8]; - GLuint i, n; - - vlist[0] = *v0; - vlist[1] = *v1; - vlist[2] = *v2; - n = clip_polygon(vlist, 3, vclipped); - for (i = 0; i < n; i++) { - MAP_POINT(vclipped[i].winPos, vclipped[i].clipPos, ctx->Viewport); - _mesa_update_hitflag(ctx, vclipped[i].winPos.z); - } -} - -/** - * \brief Set current vertex coordinates. - * - * \param x x vertex coordinate. - * \param y y vertex coordinate. - * \param z z vertex coordinate. - * \param w homogeneous coordinate. - * - * Stores the vertex and current attributes in ::vb, transforms it into eye space and then clip space. - * - * If a sufficient number of vertices is stored calls one of select_point(), - * select_line() or select_triangle(), according to the current primitive. - */ -static void -radeon_select_Vertex4f(GLfloat x, GLfloat y, GLfloat z, GLfloat w) -{ - GET_CURRENT_CONTEXT(ctx); - struct gl_polygon_attrib *p = &(ctx->Polygon); - vertex *v = vb.vBuffer + vb.vCount; - - /* store the vertex */ - v->pos.x = x; - v->pos.y = y; - v->pos.z = z; - v->pos.w = w; - v->color.r = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - v->color.g = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - v->color.b = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - v->color.a = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - v->texCoord.s = ctx->Current.Attrib[VERT_ATTRIB_TEX0][0]; - v->texCoord.t = ctx->Current.Attrib[VERT_ATTRIB_TEX0][1]; - - /* transform to eye space, then clip space */ - TRANSFORM_POINT(v->eyePos, ctx->ModelviewMatrixStack.Top->m, v->pos); - TRANSFORM_POINT(v->clipPos, ctx->ProjectionMatrixStack.Top->m, v->eyePos); - - switch (ctx->Driver.CurrentExecPrimitive) { - case GL_POINTS: - assert(vb.vCount == 0); - select_point(v); - break; - case GL_LINES: - if (vb.vCount == 0) - { - vb.vCount = 1; - } - else - { - assert(vb.vCount == 1); - select_line(vb.vBuffer + 0, vb.vBuffer + 1); - vb.vCount = 0; - } - break; - case GL_LINE_STRIP: - if (vb.vCount == 0) - { - vb.vCount = 1; - } - else - { - assert(vb.vCount == 1); - select_line(vb.vBuffer + 0, vb.vBuffer + 1); - vb.vBuffer[0] = vb.vBuffer[1]; - /* leave vb.vCount at 1 */ - } - break; - case GL_LINE_LOOP: - if (vb.vCount == 0) - { - vb.vCount = 1; - vb.partialLineLoop = GL_FALSE; - } - else if (vb.vCount == 1) - { - select_line(vb.vBuffer + 0, vb.vBuffer + 1); - vb.partialLineLoop = GL_TRUE; - vb.vCount = 2; - } - else - { - assert(vb.vCount == 2); - vb.partialLineLoop = GL_FALSE; - select_line(vb.vBuffer + 1, vb.vBuffer + 2); - vb.vBuffer[1] = vb.vBuffer[2]; - /* leave vb.vCount at 2 */ - } - break; - case GL_TRIANGLES: - if (vb.vCount == 0 || vb.vCount == 1) - { - vb.vCount++; - } - else - { - assert(vb.vCount == 2); - select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2); - vb.vCount = 0; - } - break; - case GL_TRIANGLE_STRIP: - if (vb.vCount == 0 || vb.vCount == 1) - { - vb.vCount++; - } - else if (vb.vCount == 2) - { - select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2); - vb.vCount = 3; - } - else - { - assert(vb.vCount == 3); - select_triangle(vb.vBuffer + 1, vb.vBuffer + 3, vb.vBuffer + 2); - vb.vBuffer[0] = vb.vBuffer[2]; - vb.vBuffer[1] = vb.vBuffer[3]; - vb.vCount = 2; - } - break; - case GL_TRIANGLE_FAN: - if (vb.vCount == 0 || vb.vCount == 1) - { - vb.vCount++; - } - else - { - assert(vb.vCount == 2); - select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2); - vb.vBuffer[1] = vb.vBuffer[2]; - /* leave vb.vCount = 2 */ - } - break; - case GL_QUADS: - if (vb.vCount < 3) - { - vb.vCount++; - } - else - { - assert(vb.vCount == 3); - select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2); - select_triangle(vb.vBuffer + 0, vb.vBuffer + 2, vb.vBuffer + 3); - vb.vCount = 0; - } - break; - case GL_QUAD_STRIP: - if (vb.vCount < 3) - { - vb.vCount++; - } - else - { - assert(vb.vCount == 3); - select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2); - select_triangle(vb.vBuffer + 1, vb.vBuffer + 3, vb.vBuffer + 2); - vb.vBuffer[0] = vb.vBuffer[2]; - vb.vBuffer[1] = vb.vBuffer[3]; - vb.vCount = 2; - } - break; - case GL_POLYGON: - switch (p->FrontMode) { - case GL_POINT: - assert(vb.vCount == 0); - select_point(v); - break; - case GL_LINE: - if (vb.vCount == 0) - { - vb.vCount = 1; - vb.partialLineLoop = GL_FALSE; - } - else if (vb.vCount == 1) - { - select_line(vb.vBuffer + 0, vb.vBuffer + 1); - vb.partialLineLoop = GL_TRUE; - vb.vCount = 2; - } - else - { - assert(vb.vCount == 2); - vb.partialLineLoop = GL_FALSE; - select_line(vb.vBuffer + 1, vb.vBuffer + 2); - vb.vBuffer[1] = vb.vBuffer[2]; - /* leave vb.vCount at 2 */ - } - break; - case GL_FILL: - /* draw as a tri-fan */ - if (vb.vCount == 0 || vb.vCount == 1) - { - vb.vCount++; - } - else - { - assert(vb.vCount == 2); - select_triangle(vb.vBuffer + 0, vb.vBuffer + 1, vb.vBuffer + 2); - vb.vBuffer[1] = vb.vBuffer[2]; - /* leave vb.vCount = 2 */ - } - break; - default: - ; /* impossible */ - } - break; - default: - ; /* outside begin/end -- no action required */ - } -} - -/** - * \brief Calls radeon_select_Vertex4f(). - */ -static void radeon_select_Vertex2f(GLfloat x, GLfloat y) -{ - radeon_select_Vertex4f(x, y, 0.0, 1.0); -} - -/** - * \brief Calls radeon_select_Vertex4f(). - */ -static void radeon_select_Vertex2fv(const GLfloat * v) -{ - radeon_select_Vertex4f(v[0], v[1], 0.0, 1.0); -} - -/** - * \brief Calls radeon_select_Vertex4f(). - */ -static void radeon_select_Vertex3f(GLfloat x, GLfloat y, GLfloat z) -{ - radeon_select_Vertex4f(x, y, z, 1.0); -} - -/** - * \brief Calls radeon_select_Vertex4f(). - */ -static void radeon_select_Vertex3fv(const GLfloat * v) -{ - radeon_select_Vertex4f(v[0], v[1], v[2], 1.0); -} - - -/** - * \brief Set current vertex color. - * - * \param r red color component. - * \param g gree color component. - * \param b blue color component. - * \param a alpha color component. - * - * Updates the GL context's current vertex color. - */ -static void radeon_select_Color4f( GLfloat r, GLfloat g, - GLfloat b, GLfloat a ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = a; -} - -/** - * \brief Calls radeon_select_Color4f(). - */ -static void radeon_select_Color4fv( const GLfloat *v ) -{ - radeon_select_Color4f( v[0], v[1], v[2], v[3] ); -} - -/** - * \brief Calls radeon_select_Color4f(). - */ -static void radeon_select_Color3f( GLfloat r, GLfloat g, GLfloat b ) -{ - radeon_select_Color4f( r, g, b, 1.0 ); -} - -/** - * \brief Calls radeon_select_Color4f(). - */ -static void radeon_select_Color3fv( const GLfloat *v ) -{ - radeon_select_Color4f( v[0], v[1], v[2], 1.0 ); -} - -/** - * \brief Set current vertex texture coordinates. - * - * \param s texture coordinate. - * \param t texture coordinate. - * - * Updates the GL context's current vertex texture coordinates. - */ -static __inline__ void radeon_select_TexCoord2f( GLfloat s, GLfloat t ) -{ - GET_CURRENT_CONTEXT(ctx); - GLfloat *dest = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - dest[0] = s; - dest[1] = t; -} - -/** - * \brief Calls radeon_select_TexCoord2f(). - */ -static void radeon_select_TexCoord2fv( const GLfloat *v ) -{ - radeon_select_TexCoord2f( v[0], v[1] ); -} - - -/** - * \brief Process glBegin(). - * - * \param mode primitive. - */ -static void radeon_select_Begin(GLenum mode) -{ - GET_CURRENT_CONTEXT(ctx); - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - ctx->Driver.CurrentExecPrimitive = mode; - - vb.vCount = 0; - vb.lineReset = GL_TRUE; - vb.partialLineLoop = GL_FALSE; -} - -/** - * \brief Process glEnd(). - */ -static void radeon_select_End(void) -{ - GET_CURRENT_CONTEXT(ctx); - - if ( (ctx->Driver.CurrentExecPrimitive == GL_LINE_LOOP || - (ctx->Driver.CurrentExecPrimitive == GL_POLYGON && - ctx->Polygon.FrontMode == GL_LINE)) - && vb.vCount == 2 ) - { - /* draw the last line segment */ - if (vb.partialLineLoop) - select_line(vb.vBuffer + 1, vb.vBuffer + 0); - else - select_line(vb.vBuffer + 2, vb.vBuffer + 0); - } - - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; -} - - -/** - * \brief Flush vertices. - * - * \param ctx GL context. - * \param flags not used. - * - * Nothing much to do here, besides marking the vertices as flushed, as we - * don't buffer anything. - */ -static void radeonSelectFlushVertices( GLcontext *ctx, GLuint flags ) -{ - ctx->Driver.NeedFlush = 0; -} - -/** - * \brief Install the select callbacks. - * - * \param ctx GL context. - * - * Installs the glBegin()/glEnd() associated select callbacks into the glapi - * table. - */ -void radeon_select_Install( GLcontext *ctx ) -{ - struct _glapi_table *exec = ctx->Exec; - - exec->Color3f = radeon_select_Color3f; - exec->Color3fv = radeon_select_Color3fv; - exec->Color4f = radeon_select_Color4f; - exec->Color4fv = radeon_select_Color4fv; - exec->TexCoord2f = radeon_select_TexCoord2f; - exec->TexCoord2fv = radeon_select_TexCoord2fv; - exec->Vertex2f = radeon_select_Vertex2f; - exec->Vertex2fv = radeon_select_Vertex2fv; - exec->Vertex3f = radeon_select_Vertex3f; - exec->Vertex3fv = radeon_select_Vertex3fv; - exec->Begin = radeon_select_Begin; - exec->End = radeon_select_End; - - ctx->Driver.FlushVertices = radeonSelectFlushVertices; -} -/*@}*/ - - - -/** - * \brief Set rasterization mode. - * - * \param ctx GL context. - * \param mode rasterization mode. Supports GL_RENDER or - * - * If mode is GL_RENDER, calls either radeonVtxfmtInit() or - * radeon_noop_Install depending on whether the application has focus - * (i.e., a fullscreen-cliprect) or not. If mode is GL_SELECT, calls - * radeon_select_Install(). - */ -static void radeonRenderMode( GLcontext *ctx, GLenum mode ) -{ - switch (mode) { - case GL_RENDER: - radeonVtxfmtInit( ctx ); - break; - case GL_SELECT: - radeon_select_Install( ctx ); - break; - default: - break; - } -} - -/** - * \brief Setup the GL context driver callbacks. - * - * \param ctx GL context. - * - * \sa Called by radeonCreateContext(). - */ -void radeonInitSelect( GLcontext *ctx ) -{ - ctx->Driver.RenderMode = radeonRenderMode; -} diff --git a/src/mesa/drivers/dri/radeon/radeon_subset_tex.c b/src/mesa/drivers/dri/radeon/radeon_subset_tex.c deleted file mode 100644 index 1e3c1afce2f..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_subset_tex.c +++ /dev/null @@ -1,1017 +0,0 @@ -/** - * \file radeon_subset_tex.c - * \brief Texturing. - * - * \author Gareth Hughes - * \author Brian Paul - */ - -/* - * Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - * VA Linux Systems Inc., Fremont, California. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.6 2002/09/16 18:05:20 eich Exp $ */ - -#include "glheader.h" -#include "imports.h" -#include "colormac.h" -#include "context.h" -#include "enums.h" -#include "image.h" -#include "simple_list.h" -#include "texformat.h" -#include "texstore.h" - -#include "radeon_context.h" -#include "radeon_state.h" -#include "radeon_ioctl.h" -#include "radeon_subset.h" - -#include -#include - - -/** - * \brief Destroy hardware state associated with a texture. - * - * \param rmesa Radeon context. - * \param t Radeon texture object to be destroyed. - * - * Frees the memory associated with the texture and if the texture is bound to - * a texture unit cleans the associated hardware state. - */ -void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) -{ - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - if ( t->tObj ) - t->tObj->DriverData = NULL; - - if ( rmesa ) { - if ( t == rmesa->state.texture.unit[0].texobj ) { - rmesa->state.texture.unit[0].texobj = NULL; - rmesa->hw.tex[0].dirty = GL_FALSE; - } - } - - remove_from_list( t ); - FREE( t ); -} - - -/** - * \brief Keep track of swapped out texture objects. - * - * \param rmesa Radeon context. - * \param t Radeon texture object. - * - * Frees the memory associated with the texture, marks all mipmap images in - * the texture as dirty and add it to the radeon_texture::swapped list. - */ -static void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) -{ - if ( t->memBlock ) { - mmFreeMem( t->memBlock ); - t->memBlock = NULL; - } - - t->dirty_images = ~0; - move_to_tail( &rmesa->texture.swapped, t ); -} - - -/** - * Texture space has been invalidated. - * - * \param rmesa Radeon context. - * \param heap texture heap number. - * - * Swaps out every texture in the specified heap. - */ -void radeonAgeTextures( radeonContextPtr rmesa, int heap ) -{ - radeonTexObjPtr t, tmp; - - foreach_s ( t, tmp, &rmesa->texture.objects[heap] ) - radeonSwapOutTexObj( rmesa, t ); -} - - -/***************************************************************/ -/** \name Texture image conversions - */ -/*@{*/ - -/** - * \brief Upload texture image. - * - * \param rmesa Radeon context. - * \param t Radeon texture object. - * \param level level of the image to take the sub-image. - * \param x sub-image abscissa. - * \param y sub-image ordinate. - * \param width sub-image width. - * \param height sub-image height. - * - * Fills in a drmRadeonTexture and drmRadeonTexImage structures and uploads the - * texture via the DRM_RADEON_TEXTURE ioctl, aborting in case of failure. - */ -static void radeonUploadSubImage( radeonContextPtr rmesa, - radeonTexObjPtr t, GLint level, - GLint x, GLint y, GLint width, GLint height ) -{ - struct gl_texture_image *texImage; - GLint ret; - drmRadeonTexture tex; - drmRadeonTexImage tmp; - - level += t->firstLevel; - texImage = t->tObj->Image[0][level]; - - if ( !texImage || !texImage->Data ) - return; - - t->image[level].data = texImage->Data; - - tex.offset = t->bufAddr; - tex.pitch = (t->image[0].width * texImage->TexFormat->TexelBytes) / 64; - tex.format = t->pp_txformat & RADEON_TXFORMAT_FORMAT_MASK; - tex.width = texImage->Width; - tex.height = texImage->Height; - tex.image = &tmp; - - memcpy( &tmp, &t->image[level], sizeof(drmRadeonTexImage) ); - - do { - ret = drmCommandWriteRead( rmesa->dri.fd, DRM_RADEON_TEXTURE, - &tex, sizeof(drmRadeonTexture) ); - } while ( ret && errno == EAGAIN ); - - if ( ret ) { - UNLOCK_HARDWARE( rmesa ); - fprintf( stderr, "DRM_RADEON_TEXTURE: return = %d\n", ret ); - exit( 1 ); - } -} - -/** - * \brief Upload texture images. - * - * This might require removing our own and/or other client's texture objects to - * make room for these images. - * - * \param rmesa Radeon context. - * \param tObj texture object to upload. - * - * Sets the matching hardware texture format. Calculates which mipmap levels to - * send, depending of the base image size, GL_TEXTURE_MIN_LOD, - * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL and the - * Radeon offset rules. Kicks out textures until the requested texture fits, - * sets the texture hardware state and, while holding the hardware lock, - * uploads any images that are new. - */ -static void radeonSetTexImages( radeonContextPtr rmesa, - struct gl_texture_object *tObj ) -{ - radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; - const struct gl_texture_image *baseImage = tObj->Image[0][tObj->BaseLevel]; - GLint totalSize; - GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0; - GLint x, y, width, height; - GLint i; - GLint firstLevel, lastLevel, numLevels; - GLint log2Width, log2Height; - GLuint txformat = 0; - - /* This code cannot be reached once we have lost focus - */ - assert(rmesa->radeonScreen->buffers); - - /* Set the hardware texture format - */ - switch (baseImage->TexFormat->MesaFormat) { - case MESA_FORMAT_I8: - txformat = RADEON_TXFORMAT_I8; - texelsPerDword = 4; - blitPitch = 64; - break; - case MESA_FORMAT_RGBA8888: - txformat = RADEON_TXFORMAT_RGBA8888 | RADEON_TXFORMAT_ALPHA_IN_MAP; - texelsPerDword = 1; - blitPitch = 16; - break; - case MESA_FORMAT_RGB565: - txformat = RADEON_TXFORMAT_RGB565; - texelsPerDword = 2; - blitPitch = 32; - break; - default: - _mesa_problem(NULL, "unexpected texture format in radeonTexImage2D"); - return; - } - - t->pp_txformat &= ~(RADEON_TXFORMAT_FORMAT_MASK | - RADEON_TXFORMAT_ALPHA_IN_MAP); - t->pp_txformat |= txformat; - - - /* Select the larger of the two widths for our global texture image - * coordinate space. As the Radeon has very strict offset rules, we - * can't upload mipmaps directly and have to reference their location - * from the aligned start of the whole image. - */ - blitWidth = MAX2( baseImage->Width, blitPitch ); - - /* Calculate mipmap offsets and dimensions. - */ - totalSize = 0; - x = 0; - y = 0; - - /* Compute which mipmap levels we really want to send to the hardware. - * This depends on the base image size, GL_TEXTURE_MIN_LOD, - * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. - * Yes, this looks overly complicated, but it's all needed. - */ - firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); - firstLevel = MAX2(firstLevel, tObj->BaseLevel); - lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); - lastLevel = MAX2(lastLevel, tObj->BaseLevel); - lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); - lastLevel = MIN2(lastLevel, tObj->MaxLevel); - lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ - - /* save these values */ - t->firstLevel = firstLevel; - t->lastLevel = lastLevel; - - numLevels = lastLevel - firstLevel + 1; - - log2Width = tObj->Image[0][firstLevel]->WidthLog2; - log2Height = tObj->Image[0][firstLevel]->HeightLog2; - - for ( i = 0 ; i < numLevels ; i++ ) { - const struct gl_texture_image *texImage = tObj->Image[0][i + firstLevel]; - if ( !texImage ) - break; - - width = texImage->Width; - height = texImage->Height; - - /* Texture images have a minimum pitch of 32 bytes (half of the - * 64-byte minimum pitch for blits). For images that have a - * width smaller than this, we must pad each texture image - * scanline out to this amount. - */ - if ( width < blitPitch / 2 ) { - width = blitPitch / 2; - } - - totalSize += width * height * baseImage->TexFormat->TexelBytes; - ASSERT( (totalSize & 31) == 0 ); - - while ( width < blitWidth && height > 1 ) { - width *= 2; - height /= 2; - } - - ASSERT(i < RADEON_MAX_TEXTURE_LEVELS); - t->image[i].x = x; - t->image[i].y = y; - t->image[i].width = width; - t->image[i].height = height; - - /* While blits must have a pitch of at least 64 bytes, mipmaps - * must be aligned on a 32-byte boundary (just like each texture - * image scanline). - */ - if ( width >= blitWidth ) { - y += height; - } else { - x += width; - if ( x >= blitWidth ) { - x = 0; - y++; - } - } - } - - /* Align the total size of texture memory block. - */ - t->totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; - - /* Hardware state: - */ - t->pp_txfilter &= ~RADEON_MAX_MIP_LEVEL_MASK; - t->pp_txfilter |= (numLevels - 1) << RADEON_MAX_MIP_LEVEL_SHIFT; - - t->pp_txformat &= ~(RADEON_TXFORMAT_WIDTH_MASK | - RADEON_TXFORMAT_HEIGHT_MASK); - t->pp_txformat |= ((log2Width << RADEON_TXFORMAT_WIDTH_SHIFT) | - (log2Height << RADEON_TXFORMAT_HEIGHT_SHIFT)); - t->dirty_state = TEX_ALL; - - /* Update the local texture LRU. - */ - move_to_head( &rmesa->texture.objects[0], t ); - - LOCK_HARDWARE( rmesa ); - - /* Kick out textures until the requested texture fits */ - while ( !t->memBlock ) { - t->memBlock = mmAllocMem( rmesa->texture.heap[0], t->totalSize, 12, 0); - - if (!t->memBlock) - radeonSwapOutTexObj( rmesa, rmesa->texture.objects[0].prev ); - - } - - /* Set the base offset of the texture image */ - t->bufAddr = rmesa->radeonScreen->texOffset[0] + t->memBlock->ofs; - t->pp_txoffset = t->bufAddr; - - /* Upload any images that are new - */ - for ( i = 0 ; i < numLevels ; i++ ) { - if ( t->dirty_images & (1 << i) ) { - radeonUploadSubImage( rmesa, t, i, 0, 0, - t->image[i].width, t->image[i].height ); - } - } - - rmesa->texture.age[0] = ++rmesa->sarea->texAge[0]; - UNLOCK_HARDWARE( rmesa ); - t->dirty_images = 0; -} - -/*@}*/ - - -/******************************************************************/ -/** \name Texture combine functions - */ -/*@{*/ - -enum { - RADEON_DISABLE = 0, /**< \brief disabled */ - RADEON_REPLACE = 1, /**< \brief replace function */ - RADEON_MODULATE = 2, /**< \brief modulate function */ - RADEON_DECAL = 3, /**< \brief decal function */ - RADEON_BLEND = 4, /**< \brief blend function */ - RADEON_MAX_COMBFUNC = 5 /**< \brief max number of combine functions */ -} ; - - -/** - * \brief Color combine function hardware state table. - */ -static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] = -{ - /* Unit 0: - */ - { - /* Disable combiner stage - */ - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_CURRENT_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_REPLACE = 0x00802800 - */ - (RADEON_COLOR_ARG_A_ZERO | - RADEON_COLOR_ARG_B_ZERO | - RADEON_COLOR_ARG_C_T0_COLOR | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_MODULATE = 0x00800142 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_T0_COLOR | - RADEON_COLOR_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_DECAL = 0x008c2d42 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_T0_COLOR | - RADEON_COLOR_ARG_C_T0_ALPHA | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_BLEND = 0x008c2902 - */ - (RADEON_COLOR_ARG_A_CURRENT_COLOR | - RADEON_COLOR_ARG_B_TFACTOR_COLOR | - RADEON_COLOR_ARG_C_T0_COLOR | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - }, - -}; - -/** - * \brief Alpha combine function hardware state table. - */ -static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] = -{ - /* Unit 0: - */ - { - /* Disable combiner stage - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_REPLACE = 0x00800500 - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_T0_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_MODULATE = 0x00800051 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_T0_ALPHA | - RADEON_ALPHA_ARG_C_ZERO | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_DECAL = 0x00800100 - */ - (RADEON_ALPHA_ARG_A_ZERO | - RADEON_ALPHA_ARG_B_ZERO | - RADEON_ALPHA_ARG_C_CURRENT_ALPHA | - RADEON_BLEND_CTL_ADD | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - /* GL_BLEND = 0x00800051 - */ - (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | - RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | - RADEON_ALPHA_ARG_C_T0_ALPHA | - RADEON_BLEND_CTL_BLEND | - RADEON_SCALE_1X | - RADEON_CLAMP_TX), - - }, - -}; - -/*@}*/ - - -/******************************************************************/ -/** \name Texture unit state management - */ -/*@{*/ - -/** - * \brief Update the texture environment. - * - * \param ctx GL context - * \param unit texture unit to update. - * - * Sets the state of the RADEON_TEX_PP_TXCBLEND and RADEON_TEX_PP_TXABLEND - * registers using the ::radeon_color_combine and ::radeon_alpha_combine tables, - * and informs of the state change. - */ -static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - const struct gl_texture_object *tObj = texUnit->_Current; - const GLenum format = tObj->Image[0][tObj->BaseLevel]->Format; - GLuint color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - GLuint alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - - - /* Set the texture environment state. Isn't this nice and clean? - * The Radeon will automagically set the texture alpha to 0xff when - * the texture format does not include an alpha component. This - * reduces the amount of special-casing we have to do, alpha-only - * textures being a notable exception. - */ - switch ( texUnit->EnvMode ) { - case GL_REPLACE: - switch ( format ) { - case GL_RGBA: - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_REPLACE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; - break; - case GL_RGB: - color_combine = radeon_color_combine[unit][RADEON_REPLACE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - default: - break; - } - break; - - case GL_MODULATE: - switch ( format ) { - case GL_RGBA: - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_MODULATE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_RGB: - color_combine = radeon_color_combine[unit][RADEON_MODULATE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - default: - break; - } - break; - - case GL_DECAL: - switch ( format ) { - case GL_RGBA: - case GL_RGB: - color_combine = radeon_color_combine[unit][RADEON_DECAL]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_DISABLE]; - alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; - break; - default: - break; - } - break; - - case GL_BLEND: - switch ( format ) { - case GL_RGBA: - case GL_RGB: - color_combine = radeon_color_combine[unit][RADEON_BLEND]; - alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; - break; - case GL_INTENSITY: - color_combine = radeon_color_combine[unit][RADEON_BLEND]; - alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND]; - break; - default: - break; - } - break; - - default: - break; - } - - if ( rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] != color_combine || - rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] != alpha_combine ) { - RADEON_STATECHANGE( rmesa, tex[unit] ); - rmesa->hw.tex[unit].cmd[TEX_PP_TXCBLEND] = color_combine; - rmesa->hw.tex[unit].cmd[TEX_PP_TXABLEND] = alpha_combine; - } -} - - -#define TEXOBJ_TXFILTER_MASK (RADEON_MAX_MIP_LEVEL_MASK | \ - RADEON_MIN_FILTER_MASK | \ - RADEON_MAG_FILTER_MASK | \ - RADEON_MAX_ANISO_MASK | \ - RADEON_CLAMP_S_MASK | \ - RADEON_CLAMP_T_MASK) - -#define TEXOBJ_TXFORMAT_MASK (RADEON_TXFORMAT_WIDTH_MASK | \ - RADEON_TXFORMAT_HEIGHT_MASK | \ - RADEON_TXFORMAT_FORMAT_MASK | \ - RADEON_TXFORMAT_ALPHA_IN_MAP) - - - -void radeonUpdateTextureState( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[0]; - - if ( texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) { - struct gl_texture_object *tObj = texUnit->_Current; - radeonTexObjPtr t = (radeonTexObjPtr) tObj->DriverData; - - /* Upload teximages (not pipelined) - */ - if ( t->dirty_images ) { - RADEON_FIREVERTICES( rmesa ); - radeonSetTexImages( rmesa, tObj ); - } - - /* Update state if this is a different texture object to last - * time. - */ - if ( rmesa->state.texture.unit[0].texobj != t ) { - rmesa->state.texture.unit[0].texobj = t; - t->dirty_state |= 1<<0; - move_to_head( &rmesa->texture.objects[0], t ); - } - - if (t->dirty_state) { - GLuint *cmd = RADEON_DB_STATE( tex[0] ); - - cmd[TEX_PP_TXFILTER] &= ~TEXOBJ_TXFILTER_MASK; - cmd[TEX_PP_TXFORMAT] &= ~TEXOBJ_TXFORMAT_MASK; - cmd[TEX_PP_TXFILTER] |= t->pp_txfilter & TEXOBJ_TXFILTER_MASK; - cmd[TEX_PP_TXFORMAT] |= t->pp_txformat & TEXOBJ_TXFORMAT_MASK; - cmd[TEX_PP_TXOFFSET] = t->pp_txoffset; - cmd[TEX_PP_BORDER_COLOR] = t->pp_border_color; - - RADEON_DB_STATECHANGE( rmesa, &rmesa->hw.tex[0] ); - t->dirty_state = 0; - } - - /* Newly enabled? - */ - if (!(rmesa->hw.ctx.cmd[CTX_PP_CNTL] & RADEON_TEX_0_ENABLE)) { - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_PP_CNTL] |= (RADEON_TEX_0_ENABLE | - RADEON_TEX_BLEND_0_ENABLE); - - RADEON_STATECHANGE( rmesa, tcl ); - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] |= RADEON_TCL_VTX_ST0; - } - - radeonUpdateTextureEnv( ctx, 0 ); - } - else if (rmesa->hw.ctx.cmd[CTX_PP_CNTL] & (RADEON_TEX_0_ENABLE<<0)) { - /* Texture unit disabled */ - rmesa->state.texture.unit[0].texobj = 0; - RADEON_STATECHANGE( rmesa, ctx ); - rmesa->hw.ctx.cmd[CTX_PP_CNTL] &= - ~((RADEON_TEX_0_ENABLE | RADEON_TEX_BLEND_0_ENABLE) << 0); - - RADEON_STATECHANGE( rmesa, tcl ); - rmesa->hw.tcl.cmd[TCL_OUTPUT_VTXFMT] &= ~(RADEON_TCL_VTX_ST0 | - RADEON_TCL_VTX_Q0); - } -} - - - -/** - * \brief Choose texture format. - * - * \param ctx GL context. - * \param internalFormat texture internal format. - * \param format pixel format. Not used. - * \param type pixel data type. Not used. - * - * \return pointer to chosen texture format. - * - * Returns a pointer to one of the Mesa texture formats which is supported by - * Radeon and matches the internal format. - */ -static const struct gl_texture_format * -radeonChooseTextureFormat( GLcontext *ctx, GLint internalFormat, - GLenum format, GLenum type ) -{ - switch ( internalFormat ) { - case GL_RGBA: - case GL_RGBA8: - return &_mesa_texformat_rgba8888; - - case GL_RGB: - case GL_RGB5: - return &_mesa_texformat_rgb565; - - case GL_INTENSITY: - case GL_INTENSITY8: - return &_mesa_texformat_i8; - - default: - _mesa_problem(ctx, "unexpected texture format in radeonChoosTexFormat"); - return NULL; - } -} - -/** - * \brief Allocate a Radeon texture object. - * - * \param texObj texture object. - * - * \return pointer to the device specific texture object on success, or NULL on failure. - * - * Allocates and initializes a radeon_tex_obj structure to connect it to the - * driver private data pointer in \p texObj. - */ -static radeonTexObjPtr radeonAllocTexObj( struct gl_texture_object *texObj ) -{ - radeonTexObjPtr t; - - t = CALLOC_STRUCT( radeon_tex_obj ); - if (!t) - return NULL; - - t->tObj = texObj; - texObj->DriverData = t; - make_empty_list( t ); - t->dirty_images = ~0; - return t; -} - - -/** - * \brief Load a texture image. - * - * \param ctx GL context. - * \param texObj texture object - * \param target target texture. - * \param level level of detail number. - * \param internalFormat internal format. - * \param width texture image width. - * \param height texture image height. - * \param border border width. - * \param format pixel format. - * \param type pixel data type. - * \param pixels image data. - * \param packing passed to _mesa_store_teximage2d() unchanged. - * \param texImage passed to _mesa_store_teximage2d() unchanged. - * - * If there is a device specific texture object associated with the given - * texture object then swaps that texture out. Calls _mesa_store_teximage2d() - * with all other parameters unchanged. - */ -static void radeonTexImage2D( GLcontext *ctx, GLenum target, GLint level, - GLint internalFormat, - GLint width, GLint height, GLint border, - GLenum format, GLenum type, const GLvoid *pixels, - const struct gl_pixelstore_attrib *packing, - struct gl_texture_object *texObj, - struct gl_texture_image *texImage ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr)texObj->DriverData; - - if ( t ) - radeonSwapOutTexObj( rmesa, t ); - - /* Note, this will call radeonChooseTextureFormat */ - _mesa_store_teximage2d(ctx, target, level, internalFormat, - width, height, border, format, type, pixels, - &ctx->Unpack, texObj, texImage); -} - -/** - * \brief Set texture environment parameters. - * - * \param ctx GL context. - * \param target texture environment. - * \param pname texture parameter. Accepted value is GL_TEXTURE_ENV_COLOR. - * \param param parameter value. - * - * Updates the current unit's RADEON_TEX_PP_TFACTOR register and informs of the - * state change. - */ -static void radeonTexEnv( GLcontext *ctx, GLenum target, - GLenum pname, const GLfloat *param ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint unit = ctx->Texture.CurrentUnit; - struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; - - switch ( pname ) { - case GL_TEXTURE_ENV_COLOR: { - GLubyte c[4]; - GLuint envColor; - UNCLAMPED_FLOAT_TO_RGBA_CHAN( c, texUnit->EnvColor ); - envColor = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); - if ( rmesa->hw.tex[unit].cmd[TEX_PP_TFACTOR] != envColor ) { - RADEON_STATECHANGE( rmesa, tex[unit] ); - rmesa->hw.tex[unit].cmd[TEX_PP_TFACTOR] = envColor; - } - break; - } - - default: - return; - } -} - -/** - * \brief Set texture parameter. - * - * \param ctx GL context. - * \param target target texture. - * \param texObj texture object. - * \param pname texture parameter. - * \param params parameter value. - * - * Allocates the device specific texture object data if it doesn't exist - * already. - * - * Updates the texture object radeon_tex_obj::pp_txfilter register and marks - * the texture state (radeon_tex_obj::dirty_state) as dirty. - */ -static void radeonTexParameter( GLcontext *ctx, GLenum target, - struct gl_texture_object *texObj, - GLenum pname, const GLfloat *params ) -{ - radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; - - if (!t) - t = radeonAllocTexObj( texObj ); - - switch ( pname ) { - case GL_TEXTURE_MIN_FILTER: - t->pp_txfilter &= ~RADEON_MIN_FILTER_MASK; - switch ( texObj->MinFilter ) { - case GL_NEAREST: - t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST; - break; - case GL_LINEAR: - t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR; - break; - case GL_NEAREST_MIPMAP_NEAREST: - t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - t->pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - t->pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR; - break; - } - break; - - case GL_TEXTURE_MAG_FILTER: - t->pp_txfilter &= ~RADEON_MAG_FILTER_MASK; - switch ( texObj->MagFilter ) { - case GL_NEAREST: - t->pp_txfilter |= RADEON_MAG_FILTER_NEAREST; - break; - case GL_LINEAR: - t->pp_txfilter |= RADEON_MAG_FILTER_LINEAR; - break; - } - break; - - case GL_TEXTURE_WRAP_S: - t->pp_txfilter &= ~RADEON_CLAMP_S_MASK; - switch ( texObj->WrapS ) { - case GL_REPEAT: - t->pp_txfilter |= RADEON_CLAMP_S_WRAP; - break; - case GL_CLAMP_TO_EDGE: - t->pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; - break; - } - break; - - case GL_TEXTURE_WRAP_T: - t->pp_txfilter &= ~RADEON_CLAMP_T_MASK; - switch ( texObj->WrapT ) { - case GL_REPEAT: - t->pp_txfilter |= RADEON_CLAMP_T_WRAP; - break; - case GL_CLAMP_TO_EDGE: - t->pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; - break; - } - break; - - default: - return; - } - - /* Mark this texobj as dirty (one bit per tex unit) - */ - t->dirty_state = TEX_ALL; -} - -/** - * \brief Bind texture. - * - * \param ctx GL context. - * \param target not used. - * \param texObj texture object. - * - * Allocates the device specific texture data if it doesn't exist already. - */ -static void radeonBindTexture( GLcontext *ctx, GLenum target, - struct gl_texture_object *texObj ) -{ - if ( !texObj->DriverData ) - radeonAllocTexObj( texObj ); -} - -/** - * \brief Delete texture. - * - * \param ctx GL context. - * \param texObj texture object. - * - * Fires any outstanding vertices and destroy the device specific texture - * object. - */ -static void radeonDeleteTexture( GLcontext *ctx, - struct gl_texture_object *texObj ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - radeonTexObjPtr t = (radeonTexObjPtr) texObj->DriverData; - - if ( t ) { - if ( rmesa ) - RADEON_FIREVERTICES( rmesa ); - radeonDestroyTexObj( rmesa, t ); - } -} - -/** - * \brief Initialize context texture object data. - * - * \param ctx GL context. - * - * Called by radeonInitTextureFuncs() to setup the context initial texture - * objects. - */ -static void radeonInitTextureObjects( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct gl_texture_object *texObj; - GLuint tmp = ctx->Texture.CurrentUnit; - - ctx->Texture.CurrentUnit = 0; - - texObj = ctx->Texture.Unit[0].Current2D; - radeonBindTexture( ctx, GL_TEXTURE_2D, texObj ); - move_to_tail( &rmesa->texture.swapped, - (radeonTexObjPtr)texObj->DriverData ); - - - ctx->Texture.CurrentUnit = tmp; -} - -/** - * \brief Setup the GL context driver callbacks. - * - * \param ctx GL context. - * - * \sa Called by radeonCreateContext(). - */ -void radeonInitTextureFuncs( GLcontext *ctx ) -{ - ctx->Driver.ChooseTextureFormat = radeonChooseTextureFormat; - ctx->Driver.TexImage2D = radeonTexImage2D; - - ctx->Driver.BindTexture = radeonBindTexture; - ctx->Driver.CreateTexture = NULL; /* FIXME: Is this used??? */ - ctx->Driver.DeleteTexture = radeonDeleteTexture; - ctx->Driver.PrioritizeTexture = NULL; - ctx->Driver.ActiveTexture = NULL; - ctx->Driver.UpdateTexturePalette = NULL; - - ctx->Driver.TexEnv = radeonTexEnv; - ctx->Driver.TexParameter = radeonTexParameter; - - radeonInitTextureObjects( ctx ); -} - -/*@}*/ diff --git a/src/mesa/drivers/dri/radeon/radeon_subset_vtx.c b/src/mesa/drivers/dri/radeon/radeon_subset_vtx.c deleted file mode 100644 index aa6ec73d5b2..00000000000 --- a/src/mesa/drivers/dri/radeon/radeon_subset_vtx.c +++ /dev/null @@ -1,989 +0,0 @@ -/** - * \file radeon_subset_vtx.c - * \brief Vertex buffering. - * - * \author Keith Whitwell - */ - -/* - * Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and - * Tungsten Graphics Inc., Cedar Park, Texas. - * - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * on the rights to use, copy, modify, merge, publish, distribute, sub - * license, and/or sell copies of the Software, and to permit persons to whom - * the Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice (including the next - * paragraph) shall be included in all copies or substantial portions of the - * Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL - * ATI, TUNGSTEN GRAPHICS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE - * USE OR OTHER DEALINGS IN THE SOFTWARE. - * - */ - -/* $XFree86$ */ - -#include "glheader.h" -#include "imports.h" -#include "api_noop.h" -#include "context.h" -/*#include "mmath.h" */ -#include "mtypes.h" -#include "enums.h" -#include "glapi.h" -#include "colormac.h" -#include "state.h" - -#include "radeon_context.h" -#include "radeon_state.h" -#include "radeon_ioctl.h" -#include "radeon_subset.h" - -/** - * \brief Union for vertex data. - */ -union vertex_dword { - float f; /**< \brief floating point value */ - int i; /**< \brief integer point value */ -}; - - -/** - * \brief Maximum number of dwords per vertex. - * - * Defined as 10 to hold: \code xyzw rgba st \endcode - */ -#define MAX_VERTEX_DWORDS 10 - - -/** - * \brief Global vertex buffer data. - */ -static struct vb_t { - /** - * \brief Notification mechanism. - * - * These are treated as a stack to allow us to do things like build quads in - * temporary storage and then emit them as triangles. - */ - struct { - GLint vertspace; /**< \brief free vertices count */ - GLint initial_vertspace; /**< \brief total vertices count */ - GLint *dmaptr; /**< \brief */ - void (*notify)( void ); /**< \brief notification callback */ - } stack[2]; - - /** - * \brief Storage for current vertex. - */ - union vertex_dword vertex[MAX_VERTEX_DWORDS]; - - /** - * \brief Temporary storage for quads, etc. - */ - union vertex_dword vertex_store[MAX_VERTEX_DWORDS * 4]; - - /** - * \name Color/texture - * - * Pointers to either vertex or ctx->Current.Attrib, depending on whether - * color/texture participates in the current vertex. - */ - /*@{*/ - GLfloat *floatcolorptr; /**< \brief color */ - GLfloat *texcoordptr; /**< \brief texture */ - /*@}*/ - - /** - * \brief Pointer to the GL context. - */ - GLcontext *context; - - /** - * \brief Active primitive. - * - * \note May differ from ctx->Driver.CurrentExecPrimitive. - */ - /*@{*/ - GLenum prim; /**< \brief primitive */ - GLuint vertex_format; /**< \brief vertex format */ - GLint vertex_size; /**< \brief vertex size */ - GLboolean recheck; /**< \brief set if it's needed to validate this information */ - /*@}*/ -} vb; - - -static void radeonFlushVertices( GLcontext *, GLuint ); - - -/** - * \brief Primitive information table. - */ -static struct prims_t { - int start, /**< \brief vertex count for the starting primitive */ - incr, /**< \brief vertex increment for a further primitive */ - hwprim; /**< \brief hardware primitive */ -} prims[10] = { - { 1, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_POINT }, - { 2, 2, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE }, - { 2, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP }, - { 2, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP }, - { 3, 3, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST }, - { 3, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP }, - { 3, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN }, - { 4, 4, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST }, - { 4, 2, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP }, - { 3, 1, RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN }, -}; - - -/** - * \brief Finish the primitive in the vertex buffer. - * - * \param rmesa Radeon context. - * - * Truncates any redundant vertices off the end of the buffer, emit the - * remaining vertices and advances the current DMA region. - */ -static void finish_prim( radeonContextPtr rmesa ) -{ - GLuint prim_end = vb.stack[0].initial_vertspace - vb.stack[0].vertspace; - - /* Too few vertices? (eg: 2 vertices for a triangles prim?) - */ - if (prim_end < prims[vb.prim].start) - return; - - /* Drop redundant vertices off end of primitive. (eg: 5 vertices - * for triangles prim?) - */ - prim_end -= (prim_end - prims[vb.prim].start) % prims[vb.prim].incr; - - radeonEmitVertexAOS( rmesa, vb.vertex_size, GET_START(&rmesa->dma.current) ); - - radeonEmitVbufPrim( rmesa, vb.vertex_format, - prims[vb.prim].hwprim | rmesa->tcl.tcl_flag, - prim_end ); - - rmesa->dma.current.ptr = - rmesa->dma.current.start += prim_end * vb.vertex_size * 4; -} - - -/** - * \brief Copy a vertex from the current DMA region - * - * \param rmesa Radeon context. - * \param n vertex index relative to the current DMA region. - * \param dst destination pointer. - * - * Used internally by copy_dma_verts(). - */ -static void copy_vertex( radeonContextPtr rmesa, GLuint n, GLfloat *dst ) -{ - GLuint i; - GLfloat *src = (GLfloat *)(rmesa->dma.current.address + - rmesa->dma.current.ptr + - n * vb.vertex_size * 4); - - for (i = 0 ; i < vb.vertex_size; i++) - dst[i] = src[i]; -} - - -/** - * \brief Copy last vertices from the current DMA buffer to resume in a new buffer. - * - * \param rmesa Radeon context. - * \param tmp destination buffer. - * - * Takes from the current DMA buffer the last vertices necessary to resume in a - * new buffer, according to the current primitive. Uses internally - * copy_vertex() for the vertex copying. - * - */ -static GLuint copy_dma_verts( radeonContextPtr rmesa, - GLfloat (*tmp)[MAX_VERTEX_DWORDS] ) -{ - GLuint ovf, i; - GLuint nr = vb.stack[0].initial_vertspace - vb.stack[0].vertspace; - - switch( vb.prim ) - { - case GL_POINTS: - return 0; - case GL_LINES: - ovf = nr&1; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_LINE_STRIP: - if (nr == 0) - return 0; - copy_vertex( rmesa, nr-1, tmp[0] ); - return 1; - case GL_LINE_LOOP: - case GL_TRIANGLE_FAN: - case GL_POLYGON: - if (nr == 0) - return 0; - else if (nr == 1) { - copy_vertex( rmesa, 0, tmp[0] ); - return 1; - } else { - copy_vertex( rmesa, 0, tmp[0] ); - copy_vertex( rmesa, nr-1, tmp[1] ); - return 2; - } - case GL_TRIANGLES: - ovf = nr % 3; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_QUADS: - ovf = nr % 4; - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - case GL_TRIANGLE_STRIP: - case GL_QUAD_STRIP: - ovf = MIN2(nr, 2); - for (i = 0 ; i < ovf ; i++) - copy_vertex( rmesa, nr-ovf+i, tmp[i] ); - return i; - default: - return 0; - } -} - -static void notify_wrap_buffer( void ); - -/** - * \brief Resets the vertex buffer notification mechanism. - * - * Fills in vb_t::stack with the values from the current DMA region in - * radeon_dma::current and sets the notification callback to - * notify_wrap_buffer(). - */ -static void reset_notify( void ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( vb.context ); - - vb.stack[0].dmaptr = (int *)(rmesa->dma.current.address + - rmesa->dma.current.ptr); - vb.stack[0].vertspace = ((rmesa->dma.current.end - rmesa->dma.current.ptr) / - (vb.vertex_size * 4)); - vb.stack[0].vertspace &= ~1; /* even numbers only -- avoid tristrip parity */ - vb.stack[0].initial_vertspace = vb.stack[0].vertspace; - vb.stack[0].notify = notify_wrap_buffer; -} - -/** - * \brief Full buffer notification callback. - * - * Makes a copy of the necessary vertices of the current buffer via - * copy_dma_verts(), gets and resets new buffer via radeon and re-emits the - * saved vertices. - */ -static void notify_wrap_buffer( void ) -{ - GLcontext *ctx = vb.context; - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLfloat tmp[3][MAX_VERTEX_DWORDS]; - GLuint i, nrverts = 0; - - /* Copy vertices out of dma: - */ - nrverts = copy_dma_verts( rmesa, tmp ); - finish_prim( rmesa ); - - /* Get new buffer - */ - radeonRefillCurrentDmaRegion( rmesa ); - - /* Reset vertspace[0], dmaptr - */ - reset_notify(); - - /* Reemit saved vertices - */ - for (i = 0 ; i < nrverts; i++) { - memcpy( vb.stack[0].dmaptr, tmp[i], vb.vertex_size * 4 ); - vb.stack[0].dmaptr += vb.vertex_size; - vb.stack[0].vertspace--; - } -} - - -static void notify_noop( void ) -{ - vb.stack[0].dmaptr = (int *)vb.vertex; - vb.stack[0].notify = notify_noop; - vb.stack[0].vertspace = 1; -} - -/** - * \brief Pop the notification mechanism stack. - * - * Simply copy the second stack array element into the first. - * - * \sa vb_t::stack and push_notify(). - */ -static void pop_notify( void ) -{ - vb.stack[0] = vb.stack[1]; -} - -/** - * \brief Push the notification mechanism stack. - * - * \param notify new notify callback for the stack head. - * \param space space available for vertices in \p store. - * \param store buffer where to store the vertices. - * - * Copy the second stack array element into the first and makes the stack head - * use the given resources. - * - * \sa vb_t::stack and pop_notify(). - */ -static void push_notify( void (*notify)( void ), int space, - union vertex_dword *store ) -{ - vb.stack[1] = vb.stack[0]; - vb.stack[0].notify = notify; - vb.stack[0].initial_vertspace = space; - vb.stack[0].vertspace = space; - vb.stack[0].dmaptr = (int *)store; -} - - -/** - * \brief Emit a stored vertex (in vb_t::vertex_store) to DMA. - * - * \param v vertex index. - * - * Adds the vertex into the current vertex buffer and calls the notification - * callback vb_t::notify(). - */ -static void emit_vertex( int v ) -{ - int i, *tmp = (int *)vb.vertex_store + v * vb.vertex_size; - - for (i = 0 ; i < vb.vertex_size ; i++) - *vb.stack[0].dmaptr++ = *tmp++; - - if (--vb.stack[0].vertspace == 0) - vb.stack[0].notify(); -} - - -/** - * \brief Emit a quad (in vb_t::vertex_store) to DMA as two triangles. - * - * \param v0 first vertex index. - * \param v1 second vertex index. - * \param v2 third vertex index. - * \param v3 fourth vertex index. - * - * Calls emit_vertex() to emit the triangles' vertices. - */ -static void emit_quad( int v0, int v1, int v2, int v3 ) -{ - emit_vertex( v0 ); emit_vertex( v1 ); emit_vertex( v3 ); - emit_vertex( v1 ); emit_vertex( v2 ); emit_vertex( v3 ); -} - -/** - * \brief Every fourth vertex in a quad primitive, this is called to emit it. - * - * Pops the notification stack, calls emit_quad() and pushes the notification - * stack again, with itself and the vb_t::vertex_store to process another four - * vertices. - */ -static void notify_quad( void ) -{ - pop_notify(); - emit_quad( 0, 1, 2, 3 ); - push_notify( notify_quad, 4, vb.vertex_store ); -} - -static void notify_qstrip1( void ); - -/** - * \brief After the 4th vertex, emit either a quad or a flipped quad each two - * vertices. - * - * Pops the notification stack, calls emit_quad() with the flipped vertices and - * pushes the notification stack again, with notify_qstrip1() and the - * vb_t::vertex_store to process another two vertices. - * - * \sa notify_qstrip1(). - */ -static void notify_qstrip0( void ) -{ - pop_notify(); - emit_quad( 0, 1, 3, 2 ); - push_notify( notify_qstrip1, 2, vb.vertex_store ); -} - -/** - * \brief After the 4th vertex, emit either a quad or a flipped quad each two - * vertices. - * - * Pops the notification stack, calls emit_quad() with the straight vertices - * and pushes the notification stack again, with notify_qstrip0() and the - * vb_t::vertex_store to process another two vertices. - * - * \sa notify_qstrip0(). - */ -static void notify_qstrip1( void ) -{ - pop_notify(); - emit_quad( 2, 3, 1, 0 ); - push_notify( notify_qstrip0, 2, vb.vertex_store + 2*vb.vertex_size ); -} - -/** - * \brief Emit the saved vertex (but hang on to it for later). - * - * Continue processing this primitive as a linestrip. - * - * Pops the notification stack and calls emit_quad with the first vertex. - */ -static void notify_lineloop0( void ) -{ - pop_notify(); - emit_vertex(0); -} - -/** - * \brief Invalidate the current vertex format. - * - * \param ctx GL context. - * - * Sets the vb_t::recheck flag. - */ -void radeonVtxfmtInvalidate( GLcontext *ctx ) -{ - vb.recheck = GL_TRUE; -} - - -/** - * \brief Validate the vertex format from the context. - * - * \param ctx GL context. - * - * Signals a new primitive and determines the appropriate vertex format and - * size. Points vb_t::floatcolorptr and vb_t::texcoordptr to the current vertex - * and sets them to the current color and texture attributes. - * - * Clears the vb_t::recheck flag on exit. - */ -static void radeonVtxfmtValidate( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); - GLuint ind = (RADEON_CP_VC_FRMT_Z | - RADEON_CP_VC_FRMT_FPCOLOR | - RADEON_CP_VC_FRMT_FPALPHA); - - if (ctx->Driver.NeedFlush) - ctx->Driver.FlushVertices( ctx, ctx->Driver.NeedFlush ); - - if (ctx->Texture.Unit[0]._ReallyEnabled) - ind |= RADEON_CP_VC_FRMT_ST0; - - RADEON_NEWPRIM(rmesa); - vb.vertex_format = ind; - vb.vertex_size = 3; - - /* Would prefer to use ubyte floats in the vertex: - */ - vb.floatcolorptr = &vb.vertex[vb.vertex_size].f; - vb.vertex_size += 4; - vb.floatcolorptr[0] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0]; - vb.floatcolorptr[1] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1]; - vb.floatcolorptr[2] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2]; - vb.floatcolorptr[3] = ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3]; - - if (ind & RADEON_CP_VC_FRMT_ST0) { - vb.texcoordptr = &vb.vertex[vb.vertex_size].f; - vb.vertex_size += 2; - vb.texcoordptr[0] = ctx->Current.Attrib[VERT_ATTRIB_TEX0][0]; - vb.texcoordptr[1] = ctx->Current.Attrib[VERT_ATTRIB_TEX0][1]; - } - else - vb.texcoordptr = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - - vb.recheck = GL_FALSE; - ctx->Driver.NeedFlush = FLUSH_UPDATE_CURRENT; -} - - -#define RESET_STIPPLE() do { \ - RADEON_STATECHANGE( rmesa, lin ); \ - radeonEmitState( rmesa ); \ -} while (0) - -#define AUTO_STIPPLE( mode ) do { \ - RADEON_STATECHANGE( rmesa, lin ); \ - if (mode) \ - rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] |= \ - RADEON_LINE_PATTERN_AUTO_RESET; \ - else \ - rmesa->hw.lin.cmd[LIN_RE_LINE_PATTERN] &= \ - ~RADEON_LINE_PATTERN_AUTO_RESET; \ - radeonEmitState( rmesa ); \ -} while (0) - - -/** - * \brief Process glBegin(). - * - * \param mode primitive. - */ -static void radeon_Begin( GLenum mode ) -{ - GLcontext *ctx = vb.context; - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - GLuint se_cntl; - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - if (ctx->NewState) - _mesa_update_state( ctx ); - - if (rmesa->NewGLState) - radeonValidateState( ctx ); - - if (vb.recheck) - radeonVtxfmtValidate( ctx ); - - /* Do we need to grab a new DMA region for the vertices? - */ - if (rmesa->dma.current.ptr + 12*vb.vertex_size*4 > rmesa->dma.current.end) { - RADEON_NEWPRIM( rmesa ); - radeonRefillCurrentDmaRegion( rmesa ); - } - - reset_notify(); - vb.prim = ctx->Driver.CurrentExecPrimitive = mode; - se_cntl = rmesa->hw.set.cmd[SET_SE_CNTL] | RADEON_FLAT_SHADE_VTX_LAST; - - if (ctx->Line.StippleFlag && - (mode == GL_LINES || - mode == GL_LINE_LOOP || - mode == GL_LINE_STRIP)) - RESET_STIPPLE(); - - switch( mode ) { - case GL_LINES: - if (ctx->Line.StippleFlag) - AUTO_STIPPLE( GL_TRUE ); - break; - case GL_LINE_LOOP: - vb.prim = GL_LINE_STRIP; - push_notify( notify_lineloop0, 1, vb.vertex_store ); - break; - case GL_QUADS: - vb.prim = GL_TRIANGLES; - push_notify( notify_quad, 4, vb.vertex_store ); - break; - case GL_QUAD_STRIP: - if (ctx->_TriangleCaps & DD_FLATSHADE) { - vb.prim = GL_TRIANGLES; - push_notify( notify_qstrip0, 4, vb.vertex_store ); - } - break; - case GL_POLYGON: - if (ctx->_TriangleCaps & DD_FLATSHADE) - se_cntl &= ~RADEON_FLAT_SHADE_VTX_LAST; - break; - default: - break; - } - - if (se_cntl != rmesa->hw.set.cmd[SET_SE_CNTL]) { - RADEON_STATECHANGE( rmesa, set ); - rmesa->hw.set.cmd[SET_SE_CNTL] = se_cntl; - } -} - - -/** - * \brief Process glEnd(). - * - */ -static void radeon_End( void ) -{ - GLcontext *ctx = vb.context; - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - - if (ctx->Driver.CurrentExecPrimitive == GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glEnd" ); - return; - } - - /* Need to finish a line loop? - */ - if (ctx->Driver.CurrentExecPrimitive == GL_LINE_LOOP) - emit_vertex( 0 ); - - /* Need to pop off quads/quadstrip/etc notification? - */ - if (vb.stack[0].notify != notify_wrap_buffer) - pop_notify(); - - finish_prim( rmesa ); - - if (ctx->Driver.CurrentExecPrimitive == GL_LINES && ctx->Line.StippleFlag) - AUTO_STIPPLE( GL_FALSE ); - - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - notify_noop(); -} - - - -/** - * \brief Flush vertices. - * - * \param ctx GL context. - * \param flags flags. - * - * If FLUSH_UPDATE_CURRENT is et in \p flags then the current vertex attributes - * in the GL context is updated from vb_t::floatcolorptr and vb_t::texcoordptr. - */ -static void radeonFlushVertices( GLcontext *ctx, GLuint flags ) -{ - if (flags & FLUSH_UPDATE_CURRENT) { - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][0] = vb.floatcolorptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][1] = vb.floatcolorptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][2] = vb.floatcolorptr[2]; - ctx->Current.Attrib[VERT_ATTRIB_COLOR0][3] = vb.floatcolorptr[3]; - - if (vb.vertex_format & RADEON_CP_VC_FRMT_ST0) { - ctx->Current.Attrib[VERT_ATTRIB_TEX0][0] = vb.texcoordptr[0]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0][1] = vb.texcoordptr[1]; - ctx->Current.Attrib[VERT_ATTRIB_TEX0][2] = 0.0F; - ctx->Current.Attrib[VERT_ATTRIB_TEX0][3] = 1.0F; - } - } - - ctx->Driver.NeedFlush &= ~FLUSH_STORED_VERTICES; -} - - -/** - * \brief Set current vertex coordinates. - * - * \param x x vertex coordinate. - * \param y y vertex coordinate. - * \param z z vertex coordinate. - * - * Set the current vertex coordinates. If run out of space in this buffer call - * the notification callback. - */ -static __inline__ void radeon_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) -{ - int i; - - *vb.stack[0].dmaptr++ = *(int *)&x; - *vb.stack[0].dmaptr++ = *(int *)&y; - *vb.stack[0].dmaptr++ = *(int *)&z; - - for (i = 3; i < vb.vertex_size; i++) - *vb.stack[0].dmaptr++ = vb.vertex[i].i; - - if (--vb.stack[0].vertspace == 0) - vb.stack[0].notify(); -} - -/** - * \brief Set current vertex color. - * - * \param r red color component. - * \param g gree color component. - * \param b blue color component. - * \param a alpha color component. - * - * Sets the current vertex color via vb_t::floatcolorptr. - */ -static __inline__ void radeon_Color4f( GLfloat r, GLfloat g, - GLfloat b, GLfloat a ) -{ - GLfloat *dest = vb.floatcolorptr; - dest[0] = r; - dest[1] = g; - dest[2] = b; - dest[3] = a; -} - -/** - * \brief Set current vertex texture coordinates. - * - * \param s texture coordinate. - * \param t texture coordinate. - * - * Sets the current vertex color via vb_t::texcoordptr. - */ -static __inline__ void radeon_TexCoord2f( GLfloat s, GLfloat t ) -{ - GLfloat *dest = vb.texcoordptr; - dest[0] = s; - dest[1] = t; -} - -/** - * Calls radeon_Vertex3f(), which is expanded inline by the compiler to be - * efficient. - */ -static void radeon_Vertex3fv( const GLfloat *v ) -{ - radeon_Vertex3f( v[0], v[1], v[2] ); -} - -/** - * Calls radeon_Vertex3f(), which is expanded inline by the compiler to be - * efficient. - */ -static void radeon_Vertex2f( GLfloat x, GLfloat y ) -{ - radeon_Vertex3f( x, y, 0 ); -} - -/** - * Calls radeon_Vertex3f(), which is expanded inline by the compiler to be - * efficient. - */ -static void radeon_Vertex2fv( const GLfloat *v ) -{ - radeon_Vertex3f( v[0], v[1], 0 ); -} - -/** - * Calls radeon_Vertex3f(), which is expanded inline by the compiler to be - * efficient. - */ -static void radeon_Color4fv( const GLfloat *v ) -{ - radeon_Color4f( v[0], v[1], v[2], v[3] ); -} - -/** - * Calls radeon_Color4f(), which is expanded inline by the compiler to be - * efficient. - */ -static void radeon_Color3f( GLfloat r, GLfloat g, GLfloat b ) -{ - radeon_Color4f( r, g, b, 1.0 ); -} - -/** - * Calls radeon_Color4f(), which is expanded inline by the compiler to be - * efficient. - */ -static void radeon_Color3fv( const GLfloat *v ) -{ - radeon_Color4f( v[0], v[1], v[2], 1.0 ); -} - -/** - * Calls radeon_TexCoord2f(), which is expanded inline by the compiler to be - * efficient. - */ -static void radeon_TexCoord2fv( const GLfloat *v ) -{ - radeon_TexCoord2f( v[0], v[1] ); -} - - -/** - * No-op. - */ -void radeonVtxfmtUnbindContext( GLcontext *ctx ) -{ -} - -/** - * No-op. - */ -void radeonVtxfmtMakeCurrent( GLcontext *ctx ) -{ -} - -/** - * No-op. - */ -void radeonVtxfmtDestroy( GLcontext *ctx ) -{ -} - -/** - * \brief Software rendering fallback. - * - * \param ctx GL context. - * \param bit fallback bitmask. - * \param mode enable or disable. - * - * Does nothing except display a warning message if \p mode is set. - */ -void radeonFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) -{ - if (mode) - fprintf(stderr, "Warning: hit nonexistant fallback path!\n"); -} - -/** - * \brief Software TCL fallback. - * - * \param ctx GL context. - * \param bit fallback bitmask. - * \param mode enable or disable. - * - * Does nothing except display a warning message if \p mode is set. - */ -void radeonTclFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) -{ - if (mode) - fprintf(stderr, "Warning: hit nonexistant fallback path!\n"); -} - -/** - * \brief Called by radeonPointsBitmap() to disable TCL. - * - * \param rmesa Radeon context. - * \param flag whether to enable or disable TCL. - * - * Updates radeon_tcl_info::tcl_flag. - */ -void radeonSubsetVtxEnableTCL( radeonContextPtr rmesa, GLboolean flag ) -{ - rmesa->tcl.tcl_flag = flag ? RADEON_CP_VC_CNTL_TCL_ENABLE : 0; -} - - - -/**********************************************************************/ -/** \name Noop mode for operation without focus */ -/**********************************************************************/ -/*@{*/ - - -/** - * \brief Process glBegin(). - * - * \param mode primitive. - */ -static void radeon_noop_Begin(GLenum mode) -{ - GET_CURRENT_CONTEXT(ctx); - - if (mode > GL_POLYGON) { - _mesa_error( ctx, GL_INVALID_ENUM, "glBegin" ); - return; - } - - if (ctx->Driver.CurrentExecPrimitive != GL_POLYGON+1) { - _mesa_error( ctx, GL_INVALID_OPERATION, "glBegin" ); - return; - } - - ctx->Driver.CurrentExecPrimitive = mode; -} - -/** - * \brief Process glEnd(). - */ -static void radeon_noop_End(void) -{ - GET_CURRENT_CONTEXT(ctx); - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; -} - - -/** - * \brief Install the noop callbacks. - * - * \param ctx GL context. - * - * Installs the noop callbacks into the glapi table. These functions - * will not attempt to emit any DMA vertices, but will keep internal - * GL state updated. Borrows heavily from the select code. - */ -static void radeon_noop_Install( GLcontext *ctx ) -{ - ctx->Exec->Begin = radeon_noop_Begin; - ctx->Exec->End = radeon_noop_End; - - vb.texcoordptr = ctx->Current.Attrib[VERT_ATTRIB_TEX0]; - vb.floatcolorptr = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - - notify_noop(); -} - - -/** - * \brief Setup the GL context callbacks. - * - * \param ctx GL context. - * - * Setups the GL context callbacks and links _glapi_table entries related to - * the glBegin()/glEnd() pairs to the functions in this module. - * - * Called by radeonCreateContext() and radeonRenderMode(). - */ -void radeonVtxfmtInit( GLcontext *ctx ) -{ - radeonContextPtr rmesa = RADEON_CONTEXT(ctx); - struct _glapi_table *exec = ctx->Exec; - - exec->Color3f = radeon_Color3f; - exec->Color3fv = radeon_Color3fv; - exec->Color4f = radeon_Color4f; - exec->Color4fv = radeon_Color4fv; - exec->TexCoord2f = radeon_TexCoord2f; - exec->TexCoord2fv = radeon_TexCoord2fv; - exec->Vertex2f = radeon_Vertex2f; - exec->Vertex2fv = radeon_Vertex2fv; - exec->Vertex3f = radeon_Vertex3f; - exec->Vertex3fv = radeon_Vertex3fv; - exec->Begin = radeon_Begin; - exec->End = radeon_End; - - vb.context = ctx; - - ctx->Driver.FlushVertices = radeonFlushVertices; - ctx->Driver.CurrentExecPrimitive = GL_POLYGON+1; - - if (rmesa->radeonScreen->buffers) { - radeonVtxfmtValidate( ctx ); - notify_noop(); - } - else - radeon_noop_Install( ctx ); -} - - -/*@}*/ - -