Remove all the radeon_subset files. They were completely unused. Keith
Whitwell says, "[T]he radeon subset code can probably be archived now." This "fixes" bug #1623.
This commit is contained in:
parent
a657c1aee8
commit
db382c5b1d
|
@ -1,75 +0,0 @@
|
|||
/**
|
||||
* \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
|
|
@ -1,197 +0,0 @@
|
|||
/**
|
||||
* \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 );
|
||||
}
|
||||
|
|
@ -1,246 +0,0 @@
|
|||
/**
|
||||
* \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);
|
||||
}
|
||||
}
|
|
@ -1,998 +0,0 @@
|
|||
/**
|
||||
* \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;
|
||||
}
|
File diff suppressed because it is too large
Load Diff
|
@ -1,989 +0,0 @@
|
|||
/**
|
||||
* \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 );
|
||||
}
|
||||
|
||||
|
||||
/*@}*/
|
||||
|
||||
|
Loading…
Reference in New Issue