+++ /dev/null
-/**
- * \file radeon_subset.h
- * \brief Radeon subset driver declarations.
- *
- * \author Keith Whitwell <keith@tungstengraphics.com>
- */
-
-/*
- * 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
+++ /dev/null
-/**
- * \file radeon_subset_bitmap.c
- * \brief Bitmap drawing.
- *
- * \author Keith Whitwell <keith@tungstengraphics.com>
- */
-
-/*
- * 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<width; col++) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address2d(unpack, bitmap, height, width,
- GL_COLOR_INDEX, GL_BITMAP, col, 0 );
-
- /* Msb first */
- GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
- for (row=0; row<height; row++) {
- if (*src & mask) {
- glVertex2f( px-col, h - (py + row) );
- }
- src += mask & 1;
- mask = ((mask << 7) & 0xff) | (mask >> 1);
- }
- /* get ready for next row */
- if (mask != 128)
- src++;
- }
- }
- else {
- for (row=0; row<height; row++) {
- const GLubyte *src = (const GLubyte *)
- _mesa_image_address2d(unpack, bitmap, width, height,
- GL_COLOR_INDEX, GL_BITMAP, row, 0 );
-
- /* Msb first */
- GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
- for (col=0; col<width; col++) {
- if (*src & mask) {
- glVertex2f( px+col, h - (py + row) );
- }
- src += mask & 1;
- mask = ((mask << 7) & 0xff) | (mask >> 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 );
-}
-
+++ /dev/null
-/**
- * \file radeon_subset_readpix.c
- * \brief Pixel reading.
- *
- * \author Keith Whitwell <keith@tungstengraphics.com>
- * \author Brian Paul <brian@tungstengraphics.com>
- */
-
-/*
- * 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; row<readHeight; row++) {
- ReadRGBASpan(ctx, readWidth, srcX, srcY, (GLchan (*)[4]) dest);
- dest += rowLength * 4;
- srcY++;
- }
- }
- else {
- /* can't do this format/type combination */
- assert(0);
- }
-}
+++ /dev/null
-/**
- * \file radeon_subset_select.c
- * \brief Selection.
- */
-
-/*
- * Mesa 3-D graphics library
- * Version: 4.1
- *
- * Copyright (C) 1999-2002 Brian Paul 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
- * the rights to use, copy, modify, merge, publish, distribute, sublicense,
- * 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 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 NONINFRINGEMENT. IN NO EVENT SHALL
- * BRIAN PAUL 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.
- */
-
-/* $Id: radeon_subset_select.c,v 1.2 2003/08/22 20:11:45 brianp Exp $ */
-
-
-#include "glheader.h"
-#include "imports.h"
-#include "context.h"
-/*#include "mmath.h"*/
-#include "mtypes.h"
-#include "enums.h"
-#include "glapi.h"
-#include "feedback.h"
-
-#include "radeon_context.h"
-#include "radeon_subset.h"
-
-/**
- * \brief Vertex.
- */
-typedef struct {
- struct { GLfloat x, y, z, w; } pos; /**< \brief position */
- struct { GLfloat x, y, z, w; } eyePos; /**< \brief position, eye coordinates */
- struct { GLfloat x, y, z, w; } clipPos; /**< \brief clipped coordinates */
- struct { GLfloat x, y, z, w; } winPos; /**< \brief position, windows coordinates */
- struct { GLfloat s, t; } texCoord; /**< \brief texture coordinates */
- struct { GLfloat r, g, b, a; } color; /**< \brief color */
-} vertex;
-
-
-/**
- * \brief Vertex buffer.
- */
-static struct select_vb_t {
- GLuint vCount; /**< \brief vertex count */
- vertex vBuffer[4]; /**< \brief vertex buffer */
- GLboolean lineReset;
- GLboolean partialLineLoop; /**< \brief whether we are in a middle of a line loop */
-} vb;
-
-
-
-
-/**********************************************************************/
-/** \name Vertex Transformation and Clipping */
-/**********************************************************************/
-/*@{*/
-
-/**
- * \brief Transform a point (column vector) by a matrix: Q = M * P.
- *
- * \param Q destination point.
- * \param P source point.
- * \param M transformation matrix.
- */
-#define TRANSFORM_POINT( Q, M, P ) \
- Q.x = M[0] * P.x + M[4] * P.y + M[8] * P.z + M[12] * P.w; \
- Q.y = M[1] * P.x + M[5] * P.y + M[9] * P.z + M[13] * P.w; \
- Q.z = M[2] * P.x + M[6] * P.y + M[10] * P.z + M[14] * P.w; \
- Q.w = M[3] * P.x + M[7] * P.y + M[11] * P.z + M[15] * P.w;
-
-/**
- * \brief Clip coord to window coord mapping.
- *
- * \param Q destination point.
- * \param P source point.
- * \param VP view port.
- */
-#define MAP_POINT( Q, P, VP ) \
- Q.x = (GLfloat) (((P.x / P.w) + 1.0) * VP.Width / 2.0 + VP.X); \
- Q.y = (GLfloat) (((P.y / P.w) + 1.0) * VP.Height / 2.0 + VP.Y); \
- Q.z = (GLfloat) (((P.z / P.w) + 1.0) * (VP.Far - VP.Near) / 2.0 + VP.Near);\
- Q.w = (GLfloat) P.w;
-
-
-/**
- * \brief Linear interpolation: (1 - T) * A + T * B.
- *
- * \param T interpolation factor.
- * \param A first value.
- * \param B second value.
- * \result interpolated value.
- */
-#define INTERPOLATE(T, A, B) ((A) + ((B) - (A)) * (T))
-
-
-
-/**
- * \brief Interpolate vertex position, color, texcoords, etc.
- *
- * \param t interpolation factor.
- * \param v0 first vertex.
- * \param v1 second vertex.
- * \param vOut output vertex.
- *
- * Uses the #INTERPOLATE macro for all the interpolation of all elements.
- */
-static void
-interpolate_vertex(GLfloat t, const vertex *v0, const vertex *v1,
- vertex *vOut)
-{
- vOut->eyePos.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;
-}
+++ /dev/null
-/**
- * \file radeon_subset_tex.c
- * \brief Texturing.
- *
- * \author Gareth Hughes <gareth@valinux.com>
- * \author Brian Paul <brianp@valinux.com>
- */
-
-/*
- * 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 <errno.h>
-#include <stdio.h>
-
-
-/**
- * \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 );
-}
-
-/*@}*/
+++ /dev/null
-/**
- * \file radeon_subset_vtx.c
- * \brief Vertex buffering.
- *
- * \author Keith Whitwell <keith@tungstengraphics.com>
- */
-
-/*
- * 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 );
-}
-
-
-/*@}*/
-
-