Subversion Repositories shark

Compare Revisions

Ignore whitespace Rev 56 → Rev 57

/shark/trunk/ports/mesa/src/swrast/s_points.c
0,0 → 1,278
/* $Id: s_points.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "context.h"
#include "macros.h"
#include "mmath.h"
#include "texstate.h"
#include "s_context.h"
#include "s_feedback.h"
#include "s_points.h"
#include "s_span.h"
 
 
 
#define RGBA 0x1
#define INDEX 0x2
#define SMOOTH 0x4
#define TEXTURE 0x8
#define SPECULAR 0x10
#define LARGE 0x20
#define ATTENUATE 0x40
#define SPRITE 0x80
 
 
/*
* CI points with size == 1.0
*/
#define FLAGS (INDEX)
#define NAME size1_ci_point
#include "s_pointtemp.h"
 
 
/*
* General CI points.
*/
#define FLAGS (INDEX | LARGE)
#define NAME general_ci_point
#include "s_pointtemp.h"
 
 
/*
* Antialiased CI points.
*/
#define FLAGS (INDEX | SMOOTH)
#define NAME antialiased_ci_point
#include "s_pointtemp.h"
 
 
/*
* Distance attenuated, general CI points.
*/
#define FLAGS (INDEX | ATTENUATE)
#define NAME atten_general_ci_point
#include "s_pointtemp.h"
 
 
/*
* RGBA points with size == 1.0
*/
#define FLAGS (RGBA)
#define NAME size1_rgba_point
#include "s_pointtemp.h"
 
 
/*
* General RGBA points.
*/
#define FLAGS (RGBA | LARGE)
#define NAME general_rgba_point
#include "s_pointtemp.h"
 
 
/*
* Antialiased RGBA points.
*/
#define FLAGS (RGBA | SMOOTH)
#define NAME antialiased_rgba_point
#include "s_pointtemp.h"
 
 
/*
* Textured RGBA points.
*/
#define FLAGS (RGBA | LARGE | TEXTURE | SPECULAR)
#define NAME textured_rgba_point
#include "s_pointtemp.h"
 
 
/*
* Antialiased points with texture mapping.
*/
#define FLAGS (RGBA | SMOOTH | TEXTURE | SPECULAR)
#define NAME antialiased_tex_rgba_point
#include "s_pointtemp.h"
 
 
/*
* Distance attenuated, general RGBA points.
*/
#define FLAGS (RGBA | ATTENUATE)
#define NAME atten_general_rgba_point
#include "s_pointtemp.h"
 
 
/*
* Distance attenuated, textured RGBA points.
*/
#define FLAGS (RGBA | ATTENUATE | TEXTURE | SPECULAR)
#define NAME atten_textured_rgba_point
#include "s_pointtemp.h"
 
 
/*
* Distance attenuated, antialiased points with or without texture mapping.
*/
#define FLAGS (RGBA | ATTENUATE | TEXTURE | SMOOTH)
#define NAME atten_antialiased_rgba_point
#include "s_pointtemp.h"
 
 
/*
* Sprite (textured point)
*/
#define FLAGS (RGBA | SPRITE)
#define NAME sprite_point
#include "s_pointtemp.h"
 
 
#define FLAGS (RGBA | ATTENUATE | SPRITE)
#define NAME atten_sprite_point
#include "s_pointtemp.h"
 
 
 
void _swrast_add_spec_terms_point( GLcontext *ctx,
const SWvertex *v0 )
{
SWvertex *ncv0 = (SWvertex *)v0;
GLchan c[1][4];
COPY_CHAN4( c[0], ncv0->color );
ACC_3V( ncv0->color, ncv0->specular );
SWRAST_CONTEXT(ctx)->SpecPoint( ctx, ncv0 );
COPY_CHAN4( ncv0->color, c[0] );
}
 
 
 
/* record the current point function name */
#ifdef DEBUG
 
static const char *pntFuncName = NULL;
 
#define USE(pntFunc) \
do { \
pntFuncName = #pntFunc; \
/*printf("%s\n", pntFuncName);*/ \
swrast->Point = pntFunc; \
} while (0)
 
#else
 
#define USE(pntFunc) swrast->Point = pntFunc
 
#endif
 
 
/*
* Examine the current context to determine which point drawing function
* should be used.
*/
void
_swrast_choose_point( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLboolean rgbMode = ctx->Visual.rgbMode;
 
if (ctx->RenderMode==GL_RENDER) {
if (ctx->Point.PointSprite) {
/* GL_NV_point_sprite */
/* XXX this might not be good enough */
if (ctx->Point._Attenuated)
USE(atten_sprite_point);
else
USE(sprite_point);
}
else if (ctx->Point.SmoothFlag) {
/* Smooth points */
if (rgbMode) {
if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
USE(atten_antialiased_rgba_point);
}
else if (ctx->Texture._EnabledUnits) {
USE(antialiased_tex_rgba_point);
}
else {
USE(antialiased_rgba_point);
}
}
else {
USE(antialiased_ci_point);
}
}
else if (ctx->Point._Attenuated || ctx->VertexProgram.PointSizeEnabled) {
if (rgbMode) {
if (ctx->Texture._EnabledUnits) {
if (ctx->Point.SmoothFlag) {
USE(atten_antialiased_rgba_point);
}
else {
USE(atten_textured_rgba_point);
}
}
else {
USE(atten_general_rgba_point);
}
}
else {
/* ci, atten */
USE(atten_general_ci_point);
}
}
else if (ctx->Texture._EnabledUnits && rgbMode) {
/* textured */
USE(textured_rgba_point);
}
else if (ctx->Point.Size != 1.0) {
/* large points */
if (rgbMode) {
USE(general_rgba_point);
}
else {
USE(general_ci_point);
}
}
else {
/* single pixel points */
if (rgbMode) {
USE(size1_rgba_point);
}
else {
USE(size1_ci_point);
}
}
}
else if (ctx->RenderMode==GL_FEEDBACK) {
USE(_mesa_feedback_point);
}
else {
/* GL_SELECT mode */
USE(_mesa_select_point);
}
}
/shark/trunk/ports/mesa/src/swrast/s_texstore.c
0,0 → 1,429
/* $Id: s_texstore.c,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* 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.
*/
 
/*
* Authors:
* Brian Paul
*/
 
 
/*
* The functions in this file are mostly related to software texture fallbacks.
* This includes texture image transfer/packing and texel fetching.
* Hardware drivers will likely override most of this.
*/
 
 
 
#include "colormac.h"
#include "context.h"
#include "convolve.h"
#include "image.h"
#include "imports.h"
#include "macros.h"
#include "texformat.h"
#include "teximage.h"
#include "texstore.h"
 
#include "s_context.h"
#include "s_depth.h"
#include "s_span.h"
 
/*
* Read an RGBA image from the frame buffer.
* This is used by glCopyTex[Sub]Image[12]D().
* Input: ctx - the context
* x, y - lower left corner
* width, height - size of region to read
* Return: pointer to block of GL_RGBA, GLchan data.
*/
static GLchan *
read_color_image( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint stride, i;
GLchan *image, *dst;
 
image = (GLchan *) MALLOC(width * height * 4 * sizeof(GLchan));
if (!image)
return NULL;
 
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
 
RENDER_START(swrast,ctx);
 
dst = image;
stride = width * 4;
for (i = 0; i < height; i++) {
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i,
(GLchan (*)[4]) dst );
dst += stride;
}
 
RENDER_FINISH(swrast,ctx);
 
/* Read from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
 
return image;
}
 
 
/*
* As above, but read data from depth buffer.
*/
static GLfloat *
read_depth_image( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLfloat *image, *dst;
GLint i;
 
image = (GLfloat *) MALLOC(width * height * sizeof(GLfloat));
if (!image)
return NULL;
 
RENDER_START(swrast,ctx);
 
dst = image;
for (i = 0; i < height; i++) {
_mesa_read_depth_span_float(ctx, width, x, y + i, dst);
dst += width;
}
 
RENDER_FINISH(swrast,ctx);
 
return image;
}
 
 
 
static GLboolean
is_depth_format(GLenum format)
{
switch (format) {
case GL_DEPTH_COMPONENT:
case GL_DEPTH_COMPONENT16_SGIX:
case GL_DEPTH_COMPONENT24_SGIX:
case GL_DEPTH_COMPONENT32_SGIX:
return GL_TRUE;
default:
return GL_FALSE;
}
}
 
 
/*
* Fallback for Driver.CopyTexImage1D().
*/
void
_swrast_copy_teximage1d( GLcontext *ctx, GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLint border )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
 
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
ASSERT(texObj);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
ASSERT(texImage);
 
ASSERT(ctx->Driver.TexImage1D);
 
if (is_depth_format(internalFormat)) {
/* read depth image from framebuffer */
GLfloat *image = read_depth_image(ctx, x, y, width, 1);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
return;
}
 
/* call glTexImage1D to redefine the texture */
(*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
width, border,
GL_DEPTH_COMPONENT, GL_FLOAT, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
else {
/* read RGBA image from framebuffer */
GLchan *image = read_color_image(ctx, x, y, width, 1);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage1D");
return;
}
 
/* call glTexImage1D to redefine the texture */
(*ctx->Driver.TexImage1D)(ctx, target, level, internalFormat,
width, border,
GL_RGBA, CHAN_TYPE, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
 
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
_mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
 
 
/*
* Fallback for Driver.CopyTexImage2D().
*/
void
_swrast_copy_teximage2d( GLcontext *ctx, GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
 
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
ASSERT(texObj);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
ASSERT(texImage);
 
ASSERT(ctx->Driver.TexImage2D);
 
if (is_depth_format(internalFormat)) {
/* read depth image from framebuffer */
GLfloat *image = read_depth_image(ctx, x, y, width, height);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
return;
}
 
/* call glTexImage2D to redefine the texture */
(*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
width, height, border,
GL_DEPTH_COMPONENT, GL_FLOAT, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
else {
/* read RGBA image from framebuffer */
GLchan *image = read_color_image(ctx, x, y, width, height);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexImage2D");
return;
}
 
/* call glTexImage2D to redefine the texture */
(*ctx->Driver.TexImage2D)(ctx, target, level, internalFormat,
width, height, border,
GL_RGBA, CHAN_TYPE, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
 
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
_mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
 
 
/*
* Fallback for Driver.CopyTexSubImage1D().
*/
void
_swrast_copy_texsubimage1d( GLcontext *ctx, GLenum target, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
 
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
ASSERT(texObj);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
ASSERT(texImage);
 
ASSERT(ctx->Driver.TexImage1D);
 
if (texImage->Format == GL_DEPTH_COMPONENT) {
/* read depth image from framebuffer */
GLfloat *image = read_depth_image(ctx, x, y, width, 1);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D");
return;
}
 
/* call glTexSubImage1D to redefine the texture */
(*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
GL_DEPTH_COMPONENT, GL_FLOAT, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
else {
/* read RGBA image from framebuffer */
GLchan *image = read_color_image(ctx, x, y, width, 1);
if (!image) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage1D" );
return;
}
 
/* now call glTexSubImage1D to do the real work */
(*ctx->Driver.TexSubImage1D)(ctx, target, level, xoffset, width,
GL_RGBA, CHAN_TYPE, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
 
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
_mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
 
 
/*
* Fallback for Driver.CopyTexSubImage2D().
*/
void
_swrast_copy_texsubimage2d( GLcontext *ctx,
GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
 
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
ASSERT(texObj);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
ASSERT(texImage);
 
ASSERT(ctx->Driver.TexImage2D);
 
if (texImage->Format == GL_DEPTH_COMPONENT) {
/* read depth image from framebuffer */
GLfloat *image = read_depth_image(ctx, x, y, width, height);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D");
return;
}
 
/* call glTexImage1D to redefine the texture */
(*ctx->Driver.TexSubImage2D)(ctx, target, level,
xoffset, yoffset, width, height,
GL_DEPTH_COMPONENT, GL_FLOAT, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
else {
/* read RGBA image from framebuffer */
GLchan *image = read_color_image(ctx, x, y, width, height);
if (!image) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage2D" );
return;
}
 
/* now call glTexSubImage2D to do the real work */
(*ctx->Driver.TexSubImage2D)(ctx, target, level,
xoffset, yoffset, width, height,
GL_RGBA, CHAN_TYPE, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
 
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
_mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
 
 
/*
* Fallback for Driver.CopyTexSubImage3D().
*/
void
_swrast_copy_texsubimage3d( GLcontext *ctx,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height )
{
struct gl_texture_unit *texUnit;
struct gl_texture_object *texObj;
struct gl_texture_image *texImage;
 
texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit];
texObj = _mesa_select_tex_object(ctx, texUnit, target);
ASSERT(texObj);
texImage = _mesa_select_tex_image(ctx, texUnit, target, level);
ASSERT(texImage);
 
ASSERT(ctx->Driver.TexImage3D);
 
if (texImage->Format == GL_DEPTH_COMPONENT) {
/* read depth image from framebuffer */
GLfloat *image = read_depth_image(ctx, x, y, width, height);
if (!image) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D");
return;
}
 
/* call glTexImage1D to redefine the texture */
(*ctx->Driver.TexSubImage3D)(ctx, target, level,
xoffset, yoffset, zoffset, width, height, 1,
GL_DEPTH_COMPONENT, GL_FLOAT, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
else {
/* read RGBA image from framebuffer */
GLchan *image = read_color_image(ctx, x, y, width, height);
if (!image) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyTexSubImage3D" );
return;
}
 
/* now call glTexSubImage3D to do the real work */
(*ctx->Driver.TexSubImage3D)(ctx, target, level,
xoffset, yoffset, zoffset, width, height, 1,
GL_RGBA, CHAN_TYPE, image,
&_mesa_native_packing, texObj, texImage);
FREE(image);
}
 
/* GL_SGIS_generate_mipmap */
if (level == texObj->BaseLevel && texObj->GenerateMipmap) {
_mesa_generate_mipmap(ctx, target, texUnit, texObj);
}
}
/shark/trunk/ports/mesa/src/swrast/s_drawpix.c
0,0 → 1,957
/* $Id: s_drawpix.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "context.h"
#include "convolve.h"
#include "image.h"
#include "macros.h"
#include "imports.h"
#include "mmath.h"
#include "pixel.h"
 
#include "s_context.h"
#include "s_drawpix.h"
#include "s_pixeltex.h"
#include "s_span.h"
#include "s_stencil.h"
#include "s_texture.h"
#include "s_zoom.h"
 
 
 
/*
* Given the dest position, size and skipPixels and skipRows values
* for a glDrawPixels command, perform clipping of the image bounds
* so the result lies withing the context's buffer bounds.
* Return: GL_TRUE if image is ready for drawing
* GL_FALSE if image was completely clipped away (draw nothing)
*/
GLboolean
_mesa_clip_pixelrect(const GLcontext *ctx,
GLint *destX, GLint *destY,
GLsizei *width, GLsizei *height,
GLint *skipPixels, GLint *skipRows)
{
const GLframebuffer *buffer = ctx->DrawBuffer;
 
/* left clipping */
if (*destX < buffer->_Xmin) {
*skipPixels += (buffer->_Xmin - *destX);
*width -= (buffer->_Xmin - *destX);
*destX = buffer->_Xmin;
}
/* right clipping */
if (*destX + *width > buffer->_Xmax)
*width -= (*destX + *width - buffer->_Xmax);
 
if (*width <= 0)
return GL_FALSE;
 
/* bottom clipping */
if (*destY < buffer->_Ymin) {
*skipRows += (buffer->_Ymin - *destY);
*height -= (buffer->_Ymin - *destY);
*destY = buffer->_Ymin;
}
/* top clipping */
if (*destY + *height > buffer->_Ymax)
*height -= (*destY + *height - buffer->_Ymax);
 
if (*height <= 0)
return GL_TRUE;
 
return GL_TRUE;
}
 
 
 
/*
* Try to do a fast and simple RGB(a) glDrawPixels.
* Return: GL_TRUE if success, GL_FALSE if slow path must be used instead
*/
static GLboolean
fast_draw_pixels(GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type, const GLvoid *pixels)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
struct sw_span span;
 
INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
 
if (!ctx->Current.RasterPosValid) {
return GL_TRUE; /* no-op */
}
 
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
 
if ((SWRAST_CONTEXT(ctx)->_RasterMask & ~CLIP_BIT) == 0
&& ctx->Texture._EnabledUnits == 0
&& unpack->Alignment == 1
&& !unpack->SwapBytes
&& !unpack->LsbFirst) {
 
GLint destX = x;
GLint destY = y;
GLint drawWidth = width; /* actual width drawn */
GLint drawHeight = height; /* actual height drawn */
GLint skipPixels = unpack->SkipPixels;
GLint skipRows = unpack->SkipRows;
GLint rowLength;
GLdepth zSpan[MAX_WIDTH]; /* only used when zooming */
GLint zoomY0 = 0;
 
if (unpack->RowLength > 0)
rowLength = unpack->RowLength;
else
rowLength = width;
 
/* If we're not using pixel zoom then do all clipping calculations
* now. Otherwise, we'll let the _mesa_write_zoomed_*_span() functions
* handle the clipping.
*/
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
/* horizontal clipping */
if (destX < ctx->DrawBuffer->_Xmin) {
skipPixels += (ctx->DrawBuffer->_Xmin - destX);
drawWidth -= (ctx->DrawBuffer->_Xmin - destX);
destX = ctx->DrawBuffer->_Xmin;
}
if (destX + drawWidth > ctx->DrawBuffer->_Xmax)
drawWidth -= (destX + drawWidth - ctx->DrawBuffer->_Xmax);
if (drawWidth <= 0)
return GL_TRUE;
 
/* vertical clipping */
if (destY < ctx->DrawBuffer->_Ymin) {
skipRows += (ctx->DrawBuffer->_Ymin - destY);
drawHeight -= (ctx->DrawBuffer->_Ymin - destY);
destY = ctx->DrawBuffer->_Ymin;
}
if (destY + drawHeight > ctx->DrawBuffer->_Ymax)
drawHeight -= (destY + drawHeight - ctx->DrawBuffer->_Ymax);
if (drawHeight <= 0)
return GL_TRUE;
}
else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
/* upside-down image */
/* horizontal clipping */
if (destX < ctx->DrawBuffer->_Xmin) {
skipPixels += (ctx->DrawBuffer->_Xmin - destX);
drawWidth -= (ctx->DrawBuffer->_Xmin - destX);
destX = ctx->DrawBuffer->_Xmin;
}
if (destX + drawWidth > ctx->DrawBuffer->_Xmax)
drawWidth -= (destX + drawWidth - ctx->DrawBuffer->_Xmax);
if (drawWidth <= 0)
return GL_TRUE;
 
/* vertical clipping */
if (destY > ctx->DrawBuffer->_Ymax) {
skipRows += (destY - ctx->DrawBuffer->_Ymax);
drawHeight -= (destY - ctx->DrawBuffer->_Ymax);
destY = ctx->DrawBuffer->_Ymax;
}
if (destY - drawHeight < ctx->DrawBuffer->_Ymin)
drawHeight -= (ctx->DrawBuffer->_Ymin - (destY - drawHeight));
if (drawHeight <= 0)
return GL_TRUE;
}
else {
/* setup array of fragment Z value to pass to zoom function */
GLdepth z = (GLdepth) (ctx->Current.RasterPos[2] * ctx->DepthMaxF);
GLint i;
ASSERT(drawWidth < MAX_WIDTH);
for (i=0; i<drawWidth; i++)
zSpan[i] = z;
 
/* save Y value of first row */
zoomY0 = IROUND(ctx->Current.RasterPos[1]);
}
 
 
/*
* Ready to draw!
* The window region at (destX, destY) of size (drawWidth, drawHeight)
* will be written to.
* We'll take pixel data from buffer pointed to by "pixels" but we'll
* skip "skipRows" rows and skip "skipPixels" pixels/row.
*/
 
if (format == GL_RGBA && type == CHAN_TYPE
&& ctx->_ImageTransferState==0) {
if (ctx->Visual.rgbMode) {
GLchan *src = (GLchan *) pixels
+ (skipRows * rowLength + skipPixels) * 4;
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
/* no zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[4]) src, NULL);
src += rowLength * 4;
destY++;
}
}
else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
/* upside-down */
GLint row;
for (row=0; row<drawHeight; row++) {
destY--;
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[4]) src, NULL);
src += rowLength * 4;
}
}
else {
/* with zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) src, zoomY0);
src += rowLength * 4;
destY++;
}
}
}
return GL_TRUE;
}
else if (format == GL_RGB && type == CHAN_TYPE
&& ctx->_ImageTransferState == 0) {
if (ctx->Visual.rgbMode) {
GLchan *src = (GLchan *) pixels
+ (skipRows * rowLength + skipPixels) * 3;
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
GLint row;
for (row=0; row<drawHeight; row++) {
(*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[3]) src, NULL);
src += rowLength * 3;
destY++;
}
}
else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
/* upside-down */
GLint row;
for (row=0; row<drawHeight; row++) {
destY--;
(*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[3]) src, NULL);
src += rowLength * 3;
}
}
else {
/* with zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgb_span(ctx, &span,
(CONST GLchan (*)[3]) src, zoomY0);
src += rowLength * 3;
destY++;
}
}
}
return GL_TRUE;
}
else if (format == GL_LUMINANCE && type == CHAN_TYPE
&& ctx->_ImageTransferState==0) {
if (ctx->Visual.rgbMode) {
GLchan *src = (GLchan *) pixels
+ (skipRows * rowLength + skipPixels);
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
/* no zooming */
GLint row;
ASSERT(drawWidth < MAX_WIDTH);
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
span.array->rgb[i][0] = src[i];
span.array->rgb[i][1] = src[i];
span.array->rgb[i][2] = src[i];
}
(*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[3]) span.array->rgb, NULL);
src += rowLength;
destY++;
}
}
else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
/* upside-down */
GLint row;
ASSERT(drawWidth < MAX_WIDTH);
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
span.array->rgb[i][0] = src[i];
span.array->rgb[i][1] = src[i];
span.array->rgb[i][2] = src[i];
}
destY--;
(*swrast->Driver.WriteRGBSpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[3]) span.array->rgb, NULL);
src += rowLength;
}
}
else {
/* with zooming */
GLint row;
ASSERT(drawWidth < MAX_WIDTH);
for (row=0; row<drawHeight; row++) {
GLint i;
for (i=0;i<drawWidth;i++) {
span.array->rgb[i][0] = src[i];
span.array->rgb[i][1] = src[i];
span.array->rgb[i][2] = src[i];
}
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgb_span(ctx, &span,
(CONST GLchan (*)[3]) span.array->rgb, zoomY0);
src += rowLength;
destY++;
}
}
}
return GL_TRUE;
}
else if (format == GL_LUMINANCE_ALPHA && type == CHAN_TYPE
&& ctx->_ImageTransferState == 0) {
if (ctx->Visual.rgbMode) {
GLchan *src = (GLchan *) pixels
+ (skipRows * rowLength + skipPixels)*2;
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
/* no zooming */
GLint row;
ASSERT(drawWidth < MAX_WIDTH);
for (row=0; row<drawHeight; row++) {
GLint i;
GLchan *ptr = src;
for (i=0;i<drawWidth;i++) {
span.array->rgba[i][0] = *ptr;
span.array->rgba[i][1] = *ptr;
span.array->rgba[i][2] = *ptr++;
span.array->rgba[i][3] = *ptr++;
}
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[4]) span.array->rgba, NULL);
src += rowLength*2;
destY++;
}
}
else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
/* upside-down */
GLint row;
ASSERT(drawWidth < MAX_WIDTH);
for (row=0; row<drawHeight; row++) {
GLint i;
GLchan *ptr = src;
for (i=0;i<drawWidth;i++) {
span.array->rgba[i][0] = *ptr;
span.array->rgba[i][1] = *ptr;
span.array->rgba[i][2] = *ptr++;
span.array->rgba[i][3] = *ptr++;
}
destY--;
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[4]) span.array->rgba, NULL);
src += rowLength*2;
}
}
else {
/* with zooming */
GLint row;
ASSERT(drawWidth < MAX_WIDTH);
for (row=0; row<drawHeight; row++) {
GLchan *ptr = src;
GLint i;
for (i=0;i<drawWidth;i++) {
span.array->rgba[i][0] = *ptr;
span.array->rgba[i][1] = *ptr;
span.array->rgba[i][2] = *ptr++;
span.array->rgba[i][3] = *ptr++;
}
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.array->rgba, zoomY0);
src += rowLength*2;
destY++;
}
}
}
return GL_TRUE;
}
else if (format==GL_COLOR_INDEX && type==GL_UNSIGNED_BYTE) {
GLubyte *src = (GLubyte *) pixels + skipRows * rowLength + skipPixels;
if (ctx->Visual.rgbMode) {
/* convert CI data to RGBA */
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
/* no zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(const GLchan (*)[4]) span.array->rgba, NULL);
src += rowLength;
destY++;
}
return GL_TRUE;
}
else if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==-1.0F) {
/* upside-down */
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
destY--;
(*swrast->Driver.WriteRGBASpan)(ctx, drawWidth, destX, destY,
(CONST GLchan (*)[4]) span.array->rgba, NULL);
src += rowLength;
}
return GL_TRUE;
}
else {
/* with zooming */
GLint row;
for (row=0; row<drawHeight; row++) {
ASSERT(drawWidth < MAX_WIDTH);
_mesa_map_ci8_to_rgba(ctx, drawWidth, src, span.array->rgba);
span.x = destX;
span.y = destY;
span.end = drawWidth;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.array->rgba, zoomY0);
src += rowLength;
destY++;
}
return GL_TRUE;
}
}
else if (ctx->_ImageTransferState==0) {
/* write CI data to CI frame buffer */
GLint row;
if (ctx->Pixel.ZoomX==1.0F && ctx->Pixel.ZoomY==1.0F) {
/* no zooming */
for (row=0; row<drawHeight; row++) {
(*swrast->Driver.WriteCI8Span)(ctx, drawWidth, destX, destY,
src, NULL);
src += rowLength;
destY++;
}
return GL_TRUE;
}
else {
/* with zooming */
return GL_FALSE;
}
}
}
else {
/* can't handle this pixel format and/or data type here */
return GL_FALSE;
}
}
 
/* can't do a simple draw, have to use slow path */
return GL_FALSE;
}
 
 
 
/*
* Do glDrawPixels of index pixels.
*/
static void
draw_index_pixels( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type, const GLvoid *pixels )
{
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
const GLint desty = y;
GLint row, drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
struct sw_span span;
 
INIT_SPAN(span, GL_BITMAP, drawWidth, 0, SPAN_INDEX);
 
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
 
/*
* General solution
*/
for (row = 0; row < height; row++, y++) {
const GLvoid *source = _mesa_image_address(&ctx->Unpack,
pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
_mesa_unpack_index_span(ctx, drawWidth, GL_UNSIGNED_INT,
span.array->index,
type, source, &ctx->Unpack,
ctx->_ImageTransferState);
span.x = x;
span.y = y;
span.end = drawWidth;
if (zoom)
_mesa_write_zoomed_index_span(ctx, &span, desty);
else
_mesa_write_index_span(ctx, &span);
}
}
 
 
 
/*
* Do glDrawPixels of stencil image. The image datatype may either
* be GLubyte or GLbitmap.
*/
static void
draw_stencil_pixels( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type, const GLvoid *pixels )
{
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
const GLint desty = y;
GLint row, drawWidth;
 
if (type != GL_BYTE &&
type != GL_UNSIGNED_BYTE &&
type != GL_SHORT &&
type != GL_UNSIGNED_SHORT &&
type != GL_INT &&
type != GL_UNSIGNED_INT &&
type != GL_FLOAT &&
type != GL_BITMAP) {
_mesa_error( ctx, GL_INVALID_ENUM, "glDrawPixels(stencil type)");
return;
}
 
if (ctx->Visual.stencilBits == 0) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glDrawPixels(no stencil buffer)");
return;
}
 
drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
 
for (row = 0; row < height; row++, y++) {
GLstencil values[MAX_WIDTH];
GLenum destType = (sizeof(GLstencil) == sizeof(GLubyte))
? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT;
const GLvoid *source = _mesa_image_address(&ctx->Unpack,
pixels, width, height, GL_COLOR_INDEX, type, 0, row, 0);
_mesa_unpack_index_span(ctx, drawWidth, destType, values,
type, source, &ctx->Unpack,
ctx->_ImageTransferState);
if (ctx->_ImageTransferState & IMAGE_SHIFT_OFFSET_BIT) {
_mesa_shift_and_offset_stencil( ctx, drawWidth, values );
}
if (ctx->Pixel.MapStencilFlag) {
_mesa_map_stencil( ctx, drawWidth, values );
}
 
if (zoom) {
_mesa_write_zoomed_stencil_span( ctx, (GLuint) drawWidth, x, y,
values, desty );
}
else {
_mesa_write_stencil_span( ctx, (GLuint) drawWidth, x, y, values );
}
}
}
 
 
/*
* Do a glDrawPixels of depth values.
*/
static void
draw_depth_pixels( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type, const GLvoid *pixels )
{
const GLboolean bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
const GLint desty = y;
GLint drawWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
struct sw_span span;
 
INIT_SPAN(span, GL_BITMAP, drawWidth, 0, SPAN_Z);
 
if (type != GL_BYTE
&& type != GL_UNSIGNED_BYTE
&& type != GL_SHORT
&& type != GL_UNSIGNED_SHORT
&& type != GL_INT
&& type != GL_UNSIGNED_INT
&& type != GL_FLOAT) {
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawPixels(type)");
return;
}
 
_mesa_span_default_color(ctx, &span);
 
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
if (ctx->Texture._EnabledUnits)
_mesa_span_default_texcoords(ctx, &span);
 
if (type==GL_UNSIGNED_SHORT && ctx->Visual.depthBits == 16
&& !bias_or_scale && !zoom && ctx->Visual.rgbMode) {
/* Special case: directly write 16-bit depth values */
GLint row;
span.x = x;
span.y = y;
span.end = drawWidth;
for (row = 0; row < height; row++, span.y++) {
const GLushort *zptr = (const GLushort *)
_mesa_image_address(&ctx->Unpack, pixels, width, height,
GL_DEPTH_COMPONENT, type, 0, row, 0);
GLint i;
for (i = 0; i < drawWidth; i++)
span.array->z[i] = zptr[i];
_mesa_write_rgba_span(ctx, &span);
}
}
else if (type==GL_UNSIGNED_INT && ctx->Visual.depthBits == 32
&& !bias_or_scale && !zoom && ctx->Visual.rgbMode) {
/* Special case: directly write 32-bit depth values */
GLint row;
span.x = x;
span.y = y;
span.end = drawWidth;
for (row = 0; row < height; row++, span.y++) {
const GLuint *zptr = (const GLuint *)
_mesa_image_address(&ctx->Unpack, pixels, width, height,
GL_DEPTH_COMPONENT, type, 0, row, 0);
MEMCPY(span.array->z, zptr, drawWidth * sizeof(GLdepth));
_mesa_write_rgba_span(ctx, &span);
}
}
else {
/* General case */
GLint row;
span.x = x;
span.y = y;
span.end = drawWidth;
for (row = 0; row < height; row++, span.y++) {
GLfloat fspan[MAX_WIDTH];
const GLvoid *src = _mesa_image_address(&ctx->Unpack,
pixels, width, height, GL_DEPTH_COMPONENT, type, 0, row, 0);
_mesa_unpack_depth_span( ctx, drawWidth, fspan, type, src,
&ctx->Unpack );
/* clamp depth values to [0,1] and convert from floats to integers */
{
const GLfloat zs = ctx->DepthMaxF;
GLint i;
for (i = 0; i < drawWidth; i++) {
span.array->z[i] = (GLdepth) (fspan[i] * zs + 0.5F);
}
}
if (ctx->Visual.rgbMode) {
if (zoom) {
_mesa_write_zoomed_rgba_span(ctx, &span,
(const GLchan (*)[4]) span.array->rgba, desty);
}
else
_mesa_write_rgba_span(ctx, &span);
}
else {
if (zoom)
_mesa_write_zoomed_index_span(ctx, &span, desty);
else
_mesa_write_index_span(ctx, &span);
}
}
}
}
 
 
/*
* Do glDrawPixels of RGBA pixels.
*/
static void
draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type, const GLvoid *pixels )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const struct gl_pixelstore_attrib *unpack = &ctx->Unpack;
const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0;
const GLint desty = y;
GLboolean quickDraw;
GLfloat *convImage = NULL;
GLuint transferOps = ctx->_ImageTransferState;
struct sw_span span;
 
INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
 
if (!_mesa_is_legal_format_and_type(format, type)) {
_mesa_error(ctx, GL_INVALID_ENUM, "glDrawPixels(format or type)");
return;
}
 
/* Try an optimized glDrawPixels first */
if (fast_draw_pixels(ctx, x, y, width, height, format, type, pixels))
return;
 
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
if (ctx->Texture._EnabledUnits)
_mesa_span_default_texcoords(ctx, &span);
 
if (SWRAST_CONTEXT(ctx)->_RasterMask == 0 && !zoom && x >= 0 && y >= 0
&& x + width <= (GLint) ctx->DrawBuffer->Width
&& y + height <= (GLint) ctx->DrawBuffer->Height) {
quickDraw = GL_TRUE;
}
else {
quickDraw = GL_FALSE;
}
 
if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
/* Convolution has to be handled specially. We'll create an
* intermediate image, applying all pixel transfer operations
* up to convolution. Then we'll convolve the image. Then
* we'll proceed with the rest of the transfer operations and
* rasterize the image.
*/
GLint row;
GLfloat *dest, *tmpImage;
 
tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
if (!tmpImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
return;
}
convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
if (!convImage) {
FREE(tmpImage);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glDrawPixels");
return;
}
 
/* Unpack the image and apply transfer ops up to convolution */
dest = tmpImage;
for (row = 0; row < height; row++) {
const GLvoid *source = _mesa_image_address(unpack,
pixels, width, height, format, type, 0, row, 0);
_mesa_unpack_float_color_span(ctx, width, GL_RGBA, (GLfloat *) dest,
format, type, source, unpack,
transferOps & IMAGE_PRE_CONVOLUTION_BITS,
GL_FALSE);
dest += width * 4;
}
 
/* do convolution */
if (ctx->Pixel.Convolution2DEnabled) {
_mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage);
}
else {
ASSERT(ctx->Pixel.Separable2DEnabled);
_mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage);
}
FREE(tmpImage);
 
/* continue transfer ops and draw the convolved image */
unpack = &_mesa_native_packing;
pixels = convImage;
format = GL_RGBA;
type = GL_FLOAT;
transferOps &= IMAGE_POST_CONVOLUTION_BITS;
}
 
/*
* General solution
*/
{
GLint row;
if (width > MAX_WIDTH)
width = MAX_WIDTH;
 
for (row = 0; row < height; row++, y++) {
const GLvoid *source = _mesa_image_address(unpack,
pixels, width, height, format, type, 0, row, 0);
 
_mesa_unpack_chan_color_span(ctx, width, GL_RGBA,
(GLchan *) span.array->rgba,
format, type, source, unpack,
transferOps);
 
if ((ctx->Pixel.MinMaxEnabled && ctx->MinMax.Sink) ||
(ctx->Pixel.HistogramEnabled && ctx->Histogram.Sink))
continue;
 
if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) {
span.end = width;
_swrast_pixel_texture(ctx, &span);
}
 
if (quickDraw) {
(*swrast->Driver.WriteRGBASpan)(ctx, width, x, y,
(CONST GLchan (*)[4]) span.array->rgba, NULL);
}
else if (zoom) {
span.x = x;
span.y = y;
span.end = width;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.array->rgba, desty);
}
else {
span.x = x;
span.y = y;
span.end = width;
_mesa_write_rgba_span(ctx, &span);
}
}
}
 
if (convImage) {
FREE(convImage);
}
}
 
 
 
/*
* Execute glDrawPixels
*/
void
_swrast_DrawPixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
(void) unpack;
 
if (swrast->NewState)
_swrast_validate_derived( ctx );
 
RENDER_START(swrast,ctx);
 
switch (format) {
case GL_STENCIL_INDEX:
draw_stencil_pixels( ctx, x, y, width, height, type, pixels );
break;
case GL_DEPTH_COMPONENT:
draw_depth_pixels( ctx, x, y, width, height, type, pixels );
break;
case GL_COLOR_INDEX:
if (ctx->Visual.rgbMode)
draw_rgba_pixels(ctx, x,y, width, height, format, type, pixels);
else
draw_index_pixels(ctx, x, y, width, height, type, pixels);
break;
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_RGB:
case GL_BGR:
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
draw_rgba_pixels(ctx, x, y, width, height, format, type, pixels);
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glDrawPixels(format)" );
}
 
RENDER_FINISH(swrast,ctx);
}
 
 
 
#if 0 /* experimental */
/*
* Execute glDrawDepthPixelsMESA().
*/
void
_swrast_DrawDepthPixelsMESA( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum colorFormat, GLenum colorType,
const GLvoid *colors,
GLenum depthType, const GLvoid *depths,
const struct gl_pixelstore_attrib *unpack )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
(void) unpack;
 
if (swrast->NewState)
_swrast_validate_derived( ctx );
 
RENDER_START(swrast,ctx);
 
switch (colorFormat) {
case GL_COLOR_INDEX:
if (ctx->Visual.rgbMode)
draw_rgba_pixels(ctx, x,y, width, height, colorFormat, colorType, colors);
else
draw_index_pixels(ctx, x, y, width, height, colorType, colors);
break;
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_RGB:
case GL_BGR:
case GL_RGBA:
case GL_BGRA:
case GL_ABGR_EXT:
draw_rgba_pixels(ctx, x, y, width, height, colorFormat, colorType, colors);
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM,
"glDrawDepthPixelsMESA(colorFormat)" );
}
 
RENDER_FINISH(swrast,ctx);
}
#endif
/shark/trunk/ports/mesa/src/swrast/s_points.h
0,0 → 1,40
/* $Id: s_points.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef S_POINTS_H
#define S_POINTS_H
 
#include "mtypes.h"
 
extern void
_swrast_choose_point( GLcontext *ctx );
 
extern void
_swrast_add_spec_terms_point( GLcontext *ctx,
const SWvertex *v0 );
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_linetemp.h
0,0 → 1,626
/* $Id: s_linetemp.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 5.0
*
* 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.
*/
 
 
/*
* Line Rasterizer Template
*
* This file is #include'd to generate custom line rasterizers.
*
* The following macros may be defined to indicate what auxillary information
* must be interplated along the line:
* INTERP_Z - if defined, interpolate Z values
* INTERP_FOG - if defined, interpolate FOG values
* INTERP_RGB - if defined, interpolate RGB values
* INTERP_SPEC - if defined, interpolate specular RGB values
* INTERP_ALPHA - if defined, interpolate Alpha values
* INTERP_INDEX - if defined, interpolate color index values
* INTERP_TEX - if defined, interpolate unit 0 texcoords
* INTERP_MULTITEX - if defined, interpolate multi-texcoords
*
* When one can directly address pixels in the color buffer the following
* macros can be defined and used to directly compute pixel addresses during
* rasterization (see pixelPtr):
* PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint)
* BYTES_PER_ROW - number of bytes per row in the color buffer
* PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where
* Y==0 at bottom of screen and increases upward.
*
* Similarly, for direct depth buffer access, this type is used for depth
* buffer addressing:
* DEPTH_TYPE - either GLushort or GLuint
*
* Optionally, one may provide one-time setup code
* SETUP_CODE - code which is to be executed once per line
*
* To actually "plot" each pixel the PLOT macro must be defined...
* PLOT(X,Y) - code to plot a pixel. Example:
* if (Z < *zPtr) {
* *zPtr = Z;
* color = pack_rgb( FixedToInt(r0), FixedToInt(g0),
* FixedToInt(b0) );
* put_pixel( X, Y, color );
* }
*
* This code was designed for the origin to be in the lower-left corner.
*
*/
 
 
/*void line( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 )*/
{
GLint x0 = (GLint) vert0->win[0];
GLint x1 = (GLint) vert1->win[0];
GLint y0 = (GLint) vert0->win[1];
GLint y1 = (GLint) vert1->win[1];
GLint dx, dy;
#ifdef INTERP_XY
GLint xstep, ystep;
#endif
#ifdef INTERP_Z
GLint z0, z1, dz;
const GLint depthBits = ctx->Visual.depthBits;
const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
# define FixedToDepth(F) ((F) >> fixedToDepthShift)
# ifdef DEPTH_TYPE
GLint zPtrXstep, zPtrYstep;
DEPTH_TYPE *zPtr;
# endif
#endif
#ifdef INTERP_FOG
GLfloat fog0 = vert0->fog;
GLfloat dfog = vert1->fog - fog0;
#endif
#ifdef INTERP_RGB
GLfixed r0 = ChanToFixed(vert0->color[0]);
GLfixed dr = ChanToFixed(vert1->color[0]) - r0;
GLfixed g0 = ChanToFixed(vert0->color[1]);
GLfixed dg = ChanToFixed(vert1->color[1]) - g0;
GLfixed b0 = ChanToFixed(vert0->color[2]);
GLfixed db = ChanToFixed(vert1->color[2]) - b0;
#endif
#ifdef INTERP_SPEC
GLfixed sr0 = ChanToFixed(vert0->specular[0]);
GLfixed dsr = ChanToFixed(vert1->specular[0]) - sr0;
GLfixed sg0 = ChanToFixed(vert0->specular[1]);
GLfixed dsg = ChanToFixed(vert1->specular[1]) - sg0;
GLfixed sb0 = ChanToFixed(vert0->specular[2]);
GLfixed dsb = ChanToFixed(vert1->specular[2]) - sb0;
#endif
#ifdef INTERP_ALPHA
GLfixed a0 = ChanToFixed(vert0->color[3]);
GLfixed da = ChanToFixed(vert1->color[3]) - a0;
#endif
#ifdef INTERP_INDEX
GLint i0 = vert0->index << 8;
GLint di = (GLint) (vert1->index << 8) - i0;
#endif
#ifdef INTERP_TEX
const GLfloat invw0 = vert0->win[3];
const GLfloat invw1 = vert1->win[3];
GLfloat tex[4];
GLfloat dtex[4];
GLfloat fragTexcoord[4];
#endif
#ifdef INTERP_MULTITEX
const GLfloat invw0 = vert0->win[3];
const GLfloat invw1 = vert1->win[3];
GLfloat tex[MAX_TEXTURE_UNITS][4];
GLfloat dtex[MAX_TEXTURE_UNITS][4];
GLfloat fragTexcoord[MAX_TEXTURE_UNITS][4];
#endif
#ifdef PIXEL_ADDRESS
PIXEL_TYPE *pixelPtr;
GLint pixelXstep, pixelYstep;
#endif
#ifdef INTERP_TEX
{
tex[0] = invw0 * vert0->texcoord[0][0];
dtex[0] = invw1 * vert1->texcoord[0][0] - tex[0];
tex[1] = invw0 * vert0->texcoord[0][1];
dtex[1] = invw1 * vert1->texcoord[0][1] - tex[1];
tex[2] = invw0 * vert0->texcoord[0][2];
dtex[2] = invw1 * vert1->texcoord[0][2] - tex[2];
tex[3] = invw0 * vert0->texcoord[0][3];
dtex[3] = invw1 * vert1->texcoord[0][3] - tex[3];
}
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
tex[u][0] = invw0 * vert0->texcoord[u][0];
dtex[u][0] = invw1 * vert1->texcoord[u][0] - tex[u][0];
tex[u][1] = invw0 * vert0->texcoord[u][1];
dtex[u][1] = invw1 * vert1->texcoord[u][1] - tex[u][1];
tex[u][2] = invw0 * vert0->texcoord[u][2];
dtex[u][2] = invw1 * vert1->texcoord[u][2] - tex[u][2];
tex[u][3] = invw0 * vert0->texcoord[u][3];
dtex[u][3] = invw1 * vert1->texcoord[u][3] - tex[u][3];
}
}
}
#endif
 
/* Cull primitives with malformed coordinates.
*/
{
float tmp = vert0->win[0] + vert0->win[1] + vert1->win[0] + vert1->win[1];
if (IS_INF_OR_NAN(tmp))
return;
}
 
/*
printf("%s():\n", __FUNCTION__);
printf(" (%f, %f, %f) -> (%f, %f, %f)\n",
vert0->win[0], vert0->win[1], vert0->win[2],
vert1->win[0], vert1->win[1], vert1->win[2]);
printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
vert0->color[0], vert0->color[1], vert0->color[2],
vert1->color[0], vert1->color[1], vert1->color[2]);
printf(" (%d, %d, %d) -> (%d, %d, %d)\n",
vert0->specular[0], vert0->specular[1], vert0->specular[2],
vert1->specular[0], vert1->specular[1], vert1->specular[2]);
*/
 
/*
* Despite being clipped to the view volume, the line's window coordinates
* may just lie outside the window bounds. That is, if the legal window
* coordinates are [0,W-1][0,H-1], it's possible for x==W and/or y==H.
* This quick and dirty code nudges the endpoints inside the window if
* necessary.
*/
#ifdef CLIP_HACK
{
GLint w = ctx->DrawBuffer->Width;
GLint h = ctx->DrawBuffer->Height;
if ((x0==w) | (x1==w)) {
if ((x0==w) & (x1==w))
return;
x0 -= x0==w;
x1 -= x1==w;
}
if ((y0==h) | (y1==h)) {
if ((y0==h) & (y1==h))
return;
y0 -= y0==h;
y1 -= y1==h;
}
}
#endif
dx = x1 - x0;
dy = y1 - y0;
if (dx==0 && dy==0) {
return;
}
 
/*
* Setup
*/
#ifdef SETUP_CODE
SETUP_CODE
#endif
 
#ifdef INTERP_Z
# ifdef DEPTH_TYPE
zPtr = (DEPTH_TYPE *) _mesa_zbuffer_address(ctx, x0, y0);
# endif
if (depthBits <= 16) {
z0 = FloatToFixed(vert0->win[2]) + FIXED_HALF;
z1 = FloatToFixed(vert1->win[2]) + FIXED_HALF;
}
else {
z0 = (int) vert0->win[2];
z1 = (int) vert1->win[2];
}
#endif
#ifdef PIXEL_ADDRESS
pixelPtr = (PIXEL_TYPE *) PIXEL_ADDRESS(x0,y0);
#endif
 
if (dx<0) {
dx = -dx; /* make positive */
#ifdef INTERP_XY
xstep = -1;
#endif
#if defined(INTERP_Z) && defined(DEPTH_TYPE)
zPtrXstep = -((GLint)sizeof(DEPTH_TYPE));
#endif
#ifdef PIXEL_ADDRESS
pixelXstep = -((GLint)sizeof(PIXEL_TYPE));
#endif
}
else {
#ifdef INTERP_XY
xstep = 1;
#endif
#if defined(INTERP_Z) && defined(DEPTH_TYPE)
zPtrXstep = ((GLint)sizeof(DEPTH_TYPE));
#endif
#ifdef PIXEL_ADDRESS
pixelXstep = ((GLint)sizeof(PIXEL_TYPE));
#endif
}
 
if (dy<0) {
dy = -dy; /* make positive */
#ifdef INTERP_XY
ystep = -1;
#endif
#if defined(INTERP_Z) && defined(DEPTH_TYPE)
zPtrYstep = -((GLint) (ctx->DrawBuffer->Width * sizeof(DEPTH_TYPE)));
#endif
#ifdef PIXEL_ADDRESS
pixelYstep = BYTES_PER_ROW;
#endif
}
else {
#ifdef INTERP_XY
ystep = 1;
#endif
#if defined(INTERP_Z) && defined(DEPTH_TYPE)
zPtrYstep = (GLint) (ctx->DrawBuffer->Width * sizeof(DEPTH_TYPE));
#endif
#ifdef PIXEL_ADDRESS
pixelYstep = -(BYTES_PER_ROW);
#endif
}
 
/*
* Draw
*/
 
if (dx>dy) {
/*** X-major line ***/
GLint i;
GLint errorInc = dy+dy;
GLint error = errorInc-dx;
GLint errorDec = error-dx;
#ifdef SET_XMAJOR
xMajor = GL_TRUE;
#endif
#ifdef INTERP_Z
dz = (z1-z0) / dx;
#endif
#ifdef INTERP_FOG
dfog /= dx;
#endif
#ifdef INTERP_RGB
dr /= dx; /* convert from whole line delta to per-pixel delta */
dg /= dx;
db /= dx;
#endif
#ifdef INTERP_SPEC
dsr /= dx; /* convert from whole line delta to per-pixel delta */
dsg /= dx;
dsb /= dx;
#endif
#ifdef INTERP_ALPHA
da /= dx;
#endif
#ifdef INTERP_INDEX
di /= dx;
#endif
#ifdef INTERP_TEX
{
const GLfloat invDx = 1.0F / (GLfloat) dx;
dtex[0] *= invDx;
dtex[1] *= invDx;
dtex[2] *= invDx;
dtex[3] *= invDx;
}
#endif
#ifdef INTERP_MULTITEX
{
const GLfloat invDx = 1.0F / (GLfloat) dx;
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
dtex[u][0] *= invDx;
dtex[u][1] *= invDx;
dtex[u][2] *= invDx;
dtex[u][3] *= invDx;
}
}
}
#endif
 
for (i=0;i<dx;i++) {
#ifdef INTERP_Z
GLdepth Z = FixedToDepth(z0);
#endif
#ifdef INTERP_INDEX
GLint I = i0 >> 8;
#endif
#ifdef INTERP_TEX
{
const GLfloat invQ = tex[3] ? (1.0F / tex[3]) : 1.0F;
fragTexcoord[0] = tex[0] * invQ;
fragTexcoord[1] = tex[1] * invQ;
fragTexcoord[2] = tex[2] * invQ;
fragTexcoord[3] = tex[3];
}
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
const GLfloat invQ = 1.0F / tex[u][3];
fragTexcoord[u][0] = tex[u][0] * invQ;
fragTexcoord[u][1] = tex[u][1] * invQ;
fragTexcoord[u][2] = tex[u][2] * invQ;
fragTexcoord[u][3] = tex[u][3];
}
}
}
#endif
 
PLOT( x0, y0 );
 
#ifdef INTERP_XY
x0 += xstep;
#endif
#ifdef INTERP_Z
# ifdef DEPTH_TYPE
zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep);
# endif
z0 += dz;
#endif
#ifdef INTERP_FOG
fog0 += dfog;
#endif
#ifdef INTERP_RGB
r0 += dr;
g0 += dg;
b0 += db;
#endif
#ifdef INTERP_SPEC
sr0 += dsr;
sg0 += dsg;
sb0 += dsb;
#endif
#ifdef INTERP_ALPHA
a0 += da;
#endif
#ifdef INTERP_INDEX
i0 += di;
#endif
#ifdef INTERP_TEX
tex[0] += dtex[0];
tex[1] += dtex[1];
tex[2] += dtex[2];
tex[3] += dtex[3];
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
tex[u][0] += dtex[u][0];
tex[u][1] += dtex[u][1];
tex[u][2] += dtex[u][2];
tex[u][3] += dtex[u][3];
}
}
}
#endif
 
#ifdef PIXEL_ADDRESS
pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
#endif
if (error<0) {
error += errorInc;
}
else {
error += errorDec;
#ifdef INTERP_XY
y0 += ystep;
#endif
#if defined(INTERP_Z) && defined(DEPTH_TYPE)
zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep);
#endif
#ifdef PIXEL_ADDRESS
pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
#endif
}
}
}
else {
/*** Y-major line ***/
GLint i;
GLint errorInc = dx+dx;
GLint error = errorInc-dy;
GLint errorDec = error-dy;
#ifdef INTERP_Z
dz = (z1-z0) / dy;
#endif
#ifdef INTERP_FOG
dfog /= dy;
#endif
#ifdef INTERP_RGB
dr /= dy; /* convert from whole line delta to per-pixel delta */
dg /= dy;
db /= dy;
#endif
#ifdef INTERP_SPEC
dsr /= dy; /* convert from whole line delta to per-pixel delta */
dsg /= dy;
dsb /= dy;
#endif
#ifdef INTERP_ALPHA
da /= dy;
#endif
#ifdef INTERP_INDEX
di /= dy;
#endif
#ifdef INTERP_TEX
{
const GLfloat invDy = 1.0F / (GLfloat) dy;
dtex[0] *= invDy;
dtex[1] *= invDy;
dtex[2] *= invDy;
dtex[3] *= invDy;
}
#endif
#ifdef INTERP_MULTITEX
{
const GLfloat invDy = 1.0F / (GLfloat) dy;
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
dtex[u][0] *= invDy;
dtex[u][1] *= invDy;
dtex[u][2] *= invDy;
dtex[u][3] *= invDy;
}
}
}
#endif
 
for (i=0;i<dy;i++) {
#ifdef INTERP_Z
GLdepth Z = FixedToDepth(z0);
#endif
#ifdef INTERP_INDEX
GLint I = i0 >> 8;
#endif
#ifdef INTERP_TEX
{
const GLfloat invQ = tex[3] ? (1.0F / tex[3]) : 1.0F;
fragTexcoord[0] = tex[0] * invQ;
fragTexcoord[1] = tex[1] * invQ;
fragTexcoord[2] = tex[2] * invQ;
fragTexcoord[3] = tex[3];
}
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
const GLfloat invQ = 1.0F / tex[u][3];
fragTexcoord[u][0] = tex[u][0] * invQ;
fragTexcoord[u][1] = tex[u][1] * invQ;
fragTexcoord[u][2] = tex[u][2] * invQ;
fragTexcoord[u][3] = tex[u][3];
}
}
}
#endif
 
PLOT( x0, y0 );
 
#ifdef INTERP_XY
y0 += ystep;
#endif
#ifdef INTERP_Z
# ifdef DEPTH_TYPE
zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrYstep);
# endif
z0 += dz;
#endif
#ifdef INTERP_FOG
fog0 += dfog;
#endif
#ifdef INTERP_RGB
r0 += dr;
g0 += dg;
b0 += db;
#endif
#ifdef INTERP_SPEC
sr0 += dsr;
sg0 += dsg;
sb0 += dsb;
#endif
#ifdef INTERP_ALPHA
a0 += da;
#endif
#ifdef INTERP_INDEX
i0 += di;
#endif
#ifdef INTERP_TEX
tex[0] += dtex[0];
tex[1] += dtex[1];
tex[2] += dtex[2];
tex[3] += dtex[3];
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
tex[u][0] += dtex[u][0];
tex[u][1] += dtex[u][1];
tex[u][2] += dtex[u][2];
tex[u][3] += dtex[u][3];
}
}
}
#endif
#ifdef PIXEL_ADDRESS
pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelYstep);
#endif
if (error<0) {
error += errorInc;
}
else {
error += errorDec;
#ifdef INTERP_XY
x0 += xstep;
#endif
#if defined(INTERP_Z) && defined(DEPTH_TYPE)
zPtr = (DEPTH_TYPE *) ((GLubyte*) zPtr + zPtrXstep);
#endif
#ifdef PIXEL_ADDRESS
pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep);
#endif
}
}
}
 
}
 
 
#undef INTERP_XY
#undef INTERP_Z
#undef INTERP_FOG
#undef INTERP_RGB
#undef INTERP_SPEC
#undef INTERP_ALPHA
#undef INTERP_TEX
#undef INTERP_MULTITEX
#undef INTERP_INDEX
#undef PIXEL_ADDRESS
#undef PIXEL_TYPE
#undef DEPTH_TYPE
#undef BYTES_PER_ROW
#undef SETUP_CODE
#undef PLOT
#undef CLIP_HACK
#undef FixedToDepth
#undef SET_XMAJOR
/shark/trunk/ports/mesa/src/swrast/s_drawpix.h
0,0 → 1,42
/* $Id: s_drawpix.h,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef S_DRAWPIXELS_H
#define S_DRAWPIXELS_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern GLboolean
_mesa_clip_pixelrect(const GLcontext *ctx,
GLint *destX, GLint *destY,
GLsizei *width, GLsizei *height,
GLint *skipPixels, GLint *skipRows);
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_blend.c
0,0 → 1,807
/* $Id: s_blend.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
 
#include "glheader.h"
#include "context.h"
#include "colormac.h"
#include "macros.h"
 
#include "s_alphabuf.h"
#include "s_blend.h"
#include "s_context.h"
#include "s_span.h"
 
 
#if defined(USE_MMX_ASM)
#include "X86/mmx.h"
#include "X86/common_x86_asm.h"
#define _BLENDAPI _ASMAPI
#else
#define _BLENDAPI
#endif
 
 
/*
* Special case for glBlendFunc(GL_ZERO, GL_ONE)
*/
static void _BLENDAPI
blend_noop( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
GLuint i;
ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
ASSERT(ctx->Color.BlendSrcRGB==GL_ZERO);
ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
(void) ctx;
 
for (i = 0; i < n; i++) {
if (mask[i]) {
COPY_CHAN4( rgba[i], dest[i] );
}
}
}
 
 
/*
* Special case for glBlendFunc(GL_ONE, GL_ZERO)
*/
static void _BLENDAPI
blend_replace( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
ASSERT(ctx->Color.BlendDstRGB==GL_ZERO);
(void) ctx;
(void) n;
(void) mask;
(void) rgba;
(void) dest;
}
 
 
/*
* Common transparency blending mode.
*/
static void _BLENDAPI
blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
GLuint i;
ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
ASSERT(ctx->Color.BlendSrcRGB==GL_SRC_ALPHA);
ASSERT(ctx->Color.BlendDstRGB==GL_ONE_MINUS_SRC_ALPHA);
(void) ctx;
 
for (i=0;i<n;i++) {
if (mask[i]) {
const GLchan t = rgba[i][ACOMP]; /* t in [0, CHAN_MAX] */
if (t == 0) {
/* 0% alpha */
rgba[i][RCOMP] = dest[i][RCOMP];
rgba[i][GCOMP] = dest[i][GCOMP];
rgba[i][BCOMP] = dest[i][BCOMP];
rgba[i][ACOMP] = dest[i][ACOMP];
}
else if (t == CHAN_MAX) {
/* 100% alpha, no-op */
}
else {
#if 0
/* This is pretty close, but Glean complains */
const GLint s = CHAN_MAX - t;
const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s + 1) >> 8;
const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s + 1) >> 8;
const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s + 1) >> 8;
const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s + 1) >> 8;
#elif 0
/* This is slower but satisfies Glean */
const GLint s = CHAN_MAX - t;
const GLint r = (rgba[i][RCOMP] * t + dest[i][RCOMP] * s) / 255;
const GLint g = (rgba[i][GCOMP] * t + dest[i][GCOMP] * s) / 255;
const GLint b = (rgba[i][BCOMP] * t + dest[i][BCOMP] * s) / 255;
const GLint a = (rgba[i][ACOMP] * t + dest[i][ACOMP] * s) / 255;
#else
#if CHAN_BITS == 8
/* This satisfies Glean and should be reasonably fast */
/* Contributed by Nathan Hand */
#if 0
#define DIV255(X) (((X) << 8) + (X) + 256) >> 16
#else
GLint temp;
#define DIV255(X) (temp = (X), ((temp << 8) + temp + 256) >> 16)
#endif
const GLint r = DIV255((rgba[i][RCOMP] - dest[i][RCOMP]) * t) + dest[i][RCOMP];
const GLint g = DIV255((rgba[i][GCOMP] - dest[i][GCOMP]) * t) + dest[i][GCOMP];
const GLint b = DIV255((rgba[i][BCOMP] - dest[i][BCOMP]) * t) + dest[i][BCOMP];
const GLint a = DIV255((rgba[i][ACOMP] - dest[i][ACOMP]) * t) + dest[i][ACOMP];
 
#undef DIV255
#elif CHAN_BITS == 16
const GLfloat tt = (GLfloat) t / CHAN_MAXF;
const GLint r = (GLint) ((rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP]);
const GLint g = (GLint) ((rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP]);
const GLint b = (GLint) ((rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP]);
const GLint a = (GLint) ((rgba[i][ACOMP] - dest[i][ACOMP]) * tt + dest[i][ACOMP]);
#else /* CHAN_BITS == 32 */
const GLfloat tt = (GLfloat) t / CHAN_MAXF;
const GLfloat r = (rgba[i][RCOMP] - dest[i][RCOMP]) * tt + dest[i][RCOMP];
const GLfloat g = (rgba[i][GCOMP] - dest[i][GCOMP]) * tt + dest[i][GCOMP];
const GLfloat b = (rgba[i][BCOMP] - dest[i][BCOMP]) * tt + dest[i][BCOMP];
const GLfloat a = CLAMP( rgba[i][ACOMP], 0.0F, CHAN_MAXF ) * t +
CLAMP( dest[i][ACOMP], 0.0F, CHAN_MAXF ) * (1.0F - t);
#endif
#endif
ASSERT(r <= CHAN_MAX);
ASSERT(g <= CHAN_MAX);
ASSERT(b <= CHAN_MAX);
ASSERT(a <= CHAN_MAX);
rgba[i][RCOMP] = (GLchan) r;
rgba[i][GCOMP] = (GLchan) g;
rgba[i][BCOMP] = (GLchan) b;
rgba[i][ACOMP] = (GLchan) a;
}
}
}
}
 
 
 
/*
* Add src and dest.
*/
static void _BLENDAPI
blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
GLuint i;
ASSERT(ctx->Color.BlendEquation==GL_FUNC_ADD_EXT);
ASSERT(ctx->Color.BlendSrcRGB==GL_ONE);
ASSERT(ctx->Color.BlendDstRGB==GL_ONE);
(void) ctx;
 
for (i=0;i<n;i++) {
if (mask[i]) {
#if CHAN_TYPE == GL_FLOAT
/* don't RGB clamp to max */
GLfloat a = CLAMP(rgba[i][ACOMP], 0.0F, CHAN_MAXF) + dest[i][ACOMP];
rgba[i][RCOMP] += dest[i][RCOMP];
rgba[i][GCOMP] += dest[i][GCOMP];
rgba[i][BCOMP] += dest[i][BCOMP];
rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAXF );
#else
GLint r = rgba[i][RCOMP] + dest[i][RCOMP];
GLint g = rgba[i][GCOMP] + dest[i][GCOMP];
GLint b = rgba[i][BCOMP] + dest[i][BCOMP];
GLint a = rgba[i][ACOMP] + dest[i][ACOMP];
rgba[i][RCOMP] = (GLchan) MIN2( r, CHAN_MAX );
rgba[i][GCOMP] = (GLchan) MIN2( g, CHAN_MAX );
rgba[i][BCOMP] = (GLchan) MIN2( b, CHAN_MAX );
rgba[i][ACOMP] = (GLchan) MIN2( a, CHAN_MAX );
#endif
}
}
}
 
 
 
/*
* Blend min function (for GL_EXT_blend_minmax)
*/
static void _BLENDAPI
blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
GLuint i;
ASSERT(ctx->Color.BlendEquation==GL_MIN_EXT);
(void) ctx;
 
for (i=0;i<n;i++) {
if (mask[i]) {
rgba[i][RCOMP] = (GLchan) MIN2( rgba[i][RCOMP], dest[i][RCOMP] );
rgba[i][GCOMP] = (GLchan) MIN2( rgba[i][GCOMP], dest[i][GCOMP] );
rgba[i][BCOMP] = (GLchan) MIN2( rgba[i][BCOMP], dest[i][BCOMP] );
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (GLchan) MIN2(CLAMP(rgba[i][ACOMP], 0.0F, CHAN_MAXF),
dest[i][ACOMP]);
#else
rgba[i][ACOMP] = (GLchan) MIN2( rgba[i][ACOMP], dest[i][ACOMP] );
#endif
}
}
}
 
 
 
/*
* Blend max function (for GL_EXT_blend_minmax)
*/
static void _BLENDAPI
blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
GLuint i;
ASSERT(ctx->Color.BlendEquation==GL_MAX_EXT);
(void) ctx;
 
for (i=0;i<n;i++) {
if (mask[i]) {
rgba[i][RCOMP] = (GLchan) MAX2( rgba[i][RCOMP], dest[i][RCOMP] );
rgba[i][GCOMP] = (GLchan) MAX2( rgba[i][GCOMP], dest[i][GCOMP] );
rgba[i][BCOMP] = (GLchan) MAX2( rgba[i][BCOMP], dest[i][BCOMP] );
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (GLchan) MAX2(CLAMP(rgba[i][ACOMP], 0.0F, CHAN_MAXF),
dest[i][ACOMP]);
#else
rgba[i][ACOMP] = (GLchan) MAX2( rgba[i][ACOMP], dest[i][ACOMP] );
#endif
}
}
}
 
 
 
/*
* Modulate: result = src * dest
*/
static void _BLENDAPI
blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
GLuint i;
(void) ctx;
 
for (i=0;i<n;i++) {
if (mask[i]) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = rgba[i][RCOMP] * dest[i][RCOMP];
rgba[i][GCOMP] = rgba[i][GCOMP] * dest[i][GCOMP];
rgba[i][BCOMP] = rgba[i][BCOMP] * dest[i][BCOMP];
rgba[i][ACOMP] = rgba[i][ACOMP] * dest[i][ACOMP];
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
GLint r = (rgba[i][RCOMP] * dest[i][RCOMP] + 65535) >> 16;
GLint g = (rgba[i][GCOMP] * dest[i][GCOMP] + 65535) >> 16;
GLint b = (rgba[i][BCOMP] * dest[i][BCOMP] + 65535) >> 16;
GLint a = (rgba[i][ACOMP] * dest[i][ACOMP] + 65535) >> 16;
rgba[i][RCOMP] = (GLchan) r;
rgba[i][GCOMP] = (GLchan) g;
rgba[i][BCOMP] = (GLchan) b;
rgba[i][ACOMP] = (GLchan) a;
#else
GLint r = (rgba[i][RCOMP] * dest[i][RCOMP] + 255) >> 8;
GLint g = (rgba[i][GCOMP] * dest[i][GCOMP] + 255) >> 8;
GLint b = (rgba[i][BCOMP] * dest[i][BCOMP] + 255) >> 8;
GLint a = (rgba[i][ACOMP] * dest[i][ACOMP] + 255) >> 8;
rgba[i][RCOMP] = (GLchan) r;
rgba[i][GCOMP] = (GLchan) g;
rgba[i][BCOMP] = (GLchan) b;
rgba[i][ACOMP] = (GLchan) a;
#endif
}
}
}
 
 
 
/*
* General case blend pixels.
* Input: n - number of pixels
* mask - the usual write mask
* In/Out: rgba - the incoming and modified pixels
* Input: dest - the pixels from the dest color buffer
*/
static void _BLENDAPI
blend_general( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan rgba[][4], CONST GLchan dest[][4] )
{
const GLfloat rscale = 1.0F / CHAN_MAXF;
const GLfloat gscale = 1.0F / CHAN_MAXF;
const GLfloat bscale = 1.0F / CHAN_MAXF;
const GLfloat ascale = 1.0F / CHAN_MAXF;
GLuint i;
 
for (i=0;i<n;i++) {
if (mask[i]) {
#if CHAN_TYPE == GL_FLOAT
GLfloat Rs, Gs, Bs, As; /* Source colors */
GLfloat Rd, Gd, Bd, Ad; /* Dest colors */
#else
GLint Rs, Gs, Bs, As; /* Source colors */
GLint Rd, Gd, Bd, Ad; /* Dest colors */
#endif
GLfloat sR, sG, sB, sA; /* Source scaling */
GLfloat dR, dG, dB, dA; /* Dest scaling */
GLfloat r, g, b, a; /* result color */
 
/* Incoming/source Color */
Rs = rgba[i][RCOMP];
Gs = rgba[i][GCOMP];
Bs = rgba[i][BCOMP];
As = rgba[i][ACOMP];
#if CHAN_TYPE == GL_FLOAT
/* clamp */
Rs = MIN2(Rs, CHAN_MAXF);
Gs = MIN2(Gs, CHAN_MAXF);
Bs = MIN2(Bs, CHAN_MAXF);
As = MIN2(As, CHAN_MAXF);
#endif
 
/* Frame buffer/dest color */
Rd = dest[i][RCOMP];
Gd = dest[i][GCOMP];
Bd = dest[i][BCOMP];
Ad = dest[i][ACOMP];
#if CHAN_TYPE == GL_FLOAT
/* clamp */
Rd = MIN2(Rd, CHAN_MAXF);
Gd = MIN2(Gd, CHAN_MAXF);
Bd = MIN2(Bd, CHAN_MAXF);
Ad = MIN2(Ad, CHAN_MAXF);
#endif
 
/* Source RGB factor */
switch (ctx->Color.BlendSrcRGB) {
case GL_ZERO:
sR = sG = sB = 0.0F;
break;
case GL_ONE:
sR = sG = sB = 1.0F;
break;
case GL_DST_COLOR:
sR = (GLfloat) Rd * rscale;
sG = (GLfloat) Gd * gscale;
sB = (GLfloat) Bd * bscale;
break;
case GL_ONE_MINUS_DST_COLOR:
sR = 1.0F - (GLfloat) Rd * rscale;
sG = 1.0F - (GLfloat) Gd * gscale;
sB = 1.0F - (GLfloat) Bd * bscale;
break;
case GL_SRC_ALPHA:
sR = sG = sB = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_ALPHA:
sR = sG = sB = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
sR = sG = sB = (GLfloat) Ad * ascale;
break;
case GL_ONE_MINUS_DST_ALPHA:
sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
break;
case GL_SRC_ALPHA_SATURATE:
if (As < CHAN_MAX - Ad) {
sR = sG = sB = (GLfloat) As * ascale;
}
else {
sR = sG = sB = 1.0F - (GLfloat) Ad * ascale;
}
break;
case GL_CONSTANT_COLOR:
sR = ctx->Color.BlendColor[0];
sG = ctx->Color.BlendColor[1];
sB = ctx->Color.BlendColor[2];
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
sR = 1.0F - ctx->Color.BlendColor[0];
sG = 1.0F - ctx->Color.BlendColor[1];
sB = 1.0F - ctx->Color.BlendColor[2];
break;
case GL_CONSTANT_ALPHA:
sR = sG = sB = ctx->Color.BlendColor[3];
break;
case GL_ONE_MINUS_CONSTANT_ALPHA:
sR = sG = sB = 1.0F - ctx->Color.BlendColor[3];
break;
case GL_SRC_COLOR: /* GL_NV_blend_square */
sR = (GLfloat) Rs * rscale;
sG = (GLfloat) Gs * gscale;
sB = (GLfloat) Bs * bscale;
break;
case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
sR = 1.0F - (GLfloat) Rs * rscale;
sG = 1.0F - (GLfloat) Gs * gscale;
sB = 1.0F - (GLfloat) Bs * bscale;
break;
default:
/* this should never happen */
_mesa_problem(ctx, "Bad blend source RGB factor in do_blend");
return;
}
 
/* Source Alpha factor */
switch (ctx->Color.BlendSrcA) {
case GL_ZERO:
sA = 0.0F;
break;
case GL_ONE:
sA = 1.0F;
break;
case GL_DST_COLOR:
sA = (GLfloat) Ad * ascale;
break;
case GL_ONE_MINUS_DST_COLOR:
sA = 1.0F - (GLfloat) Ad * ascale;
break;
case GL_SRC_ALPHA:
sA = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_ALPHA:
sA = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
sA =(GLfloat) Ad * ascale;
break;
case GL_ONE_MINUS_DST_ALPHA:
sA = 1.0F - (GLfloat) Ad * ascale;
break;
case GL_SRC_ALPHA_SATURATE:
sA = 1.0;
break;
case GL_CONSTANT_COLOR:
sA = ctx->Color.BlendColor[3];
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
sA = 1.0F - ctx->Color.BlendColor[3];
break;
case GL_CONSTANT_ALPHA:
sA = ctx->Color.BlendColor[3];
break;
case GL_ONE_MINUS_CONSTANT_ALPHA:
sA = 1.0F - ctx->Color.BlendColor[3];
break;
case GL_SRC_COLOR: /* GL_NV_blend_square */
sA = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_COLOR: /* GL_NV_blend_square */
sA = 1.0F - (GLfloat) As * ascale;
break;
default:
/* this should never happen */
sA = 0.0F;
_mesa_problem(ctx, "Bad blend source A factor in do_blend");
}
 
/* Dest RGB factor */
switch (ctx->Color.BlendDstRGB) {
case GL_ZERO:
dR = dG = dB = 0.0F;
break;
case GL_ONE:
dR = dG = dB = 1.0F;
break;
case GL_SRC_COLOR:
dR = (GLfloat) Rs * rscale;
dG = (GLfloat) Gs * gscale;
dB = (GLfloat) Bs * bscale;
break;
case GL_ONE_MINUS_SRC_COLOR:
dR = 1.0F - (GLfloat) Rs * rscale;
dG = 1.0F - (GLfloat) Gs * gscale;
dB = 1.0F - (GLfloat) Bs * bscale;
break;
case GL_SRC_ALPHA:
dR = dG = dB = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_ALPHA:
dR = dG = dB = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
dR = dG = dB = (GLfloat) Ad * ascale;
break;
case GL_ONE_MINUS_DST_ALPHA:
dR = dG = dB = 1.0F - (GLfloat) Ad * ascale;
break;
case GL_CONSTANT_COLOR:
dR = ctx->Color.BlendColor[0];
dG = ctx->Color.BlendColor[1];
dB = ctx->Color.BlendColor[2];
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
dR = 1.0F - ctx->Color.BlendColor[0];
dG = 1.0F - ctx->Color.BlendColor[1];
dB = 1.0F - ctx->Color.BlendColor[2];
break;
case GL_CONSTANT_ALPHA:
dR = dG = dB = ctx->Color.BlendColor[3];
break;
case GL_ONE_MINUS_CONSTANT_ALPHA:
dR = dG = dB = 1.0F - ctx->Color.BlendColor[3];
break;
case GL_DST_COLOR: /* GL_NV_blend_square */
dR = (GLfloat) Rd * rscale;
dG = (GLfloat) Gd * gscale;
dB = (GLfloat) Bd * bscale;
break;
case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
dR = 1.0F - (GLfloat) Rd * rscale;
dG = 1.0F - (GLfloat) Gd * gscale;
dB = 1.0F - (GLfloat) Bd * bscale;
break;
default:
/* this should never happen */
dR = dG = dB = 0.0F;
_mesa_problem(ctx, "Bad blend dest RGB factor in do_blend");
}
 
/* Dest Alpha factor */
switch (ctx->Color.BlendDstA) {
case GL_ZERO:
dA = 0.0F;
break;
case GL_ONE:
dA = 1.0F;
break;
case GL_SRC_COLOR:
dA = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_COLOR:
dA = 1.0F - (GLfloat) As * ascale;
break;
case GL_SRC_ALPHA:
dA = (GLfloat) As * ascale;
break;
case GL_ONE_MINUS_SRC_ALPHA:
dA = 1.0F - (GLfloat) As * ascale;
break;
case GL_DST_ALPHA:
dA = (GLfloat) Ad * ascale;
break;
case GL_ONE_MINUS_DST_ALPHA:
dA = 1.0F - (GLfloat) Ad * ascale;
break;
case GL_CONSTANT_COLOR:
dA = ctx->Color.BlendColor[3];
break;
case GL_ONE_MINUS_CONSTANT_COLOR:
dA = 1.0F - ctx->Color.BlendColor[3];
break;
case GL_CONSTANT_ALPHA:
dA = ctx->Color.BlendColor[3];
break;
case GL_ONE_MINUS_CONSTANT_ALPHA:
dA = 1.0F - ctx->Color.BlendColor[3];
break;
case GL_DST_COLOR: /* GL_NV_blend_square */
dA = (GLfloat) Ad * ascale;
break;
case GL_ONE_MINUS_DST_COLOR: /* GL_NV_blend_square */
dA = 1.0F - (GLfloat) Ad * ascale;
break;
default:
/* this should never happen */
dA = 0.0F;
_mesa_problem(ctx, "Bad blend dest A factor in do_blend");
return;
}
 
/* Due to round-off problems we have to clamp against zero. */
/* Optimization: we don't have to do this for all src & dst factors */
if (dA < 0.0F) dA = 0.0F;
if (dR < 0.0F) dR = 0.0F;
if (dG < 0.0F) dG = 0.0F;
if (dB < 0.0F) dB = 0.0F;
if (sA < 0.0F) sA = 0.0F;
if (sR < 0.0F) sR = 0.0F;
if (sG < 0.0F) sG = 0.0F;
if (sB < 0.0F) sB = 0.0F;
 
ASSERT( sR <= 1.0 );
ASSERT( sG <= 1.0 );
ASSERT( sB <= 1.0 );
ASSERT( sA <= 1.0 );
ASSERT( dR <= 1.0 );
ASSERT( dG <= 1.0 );
ASSERT( dB <= 1.0 );
ASSERT( dA <= 1.0 );
 
/* compute blended color */
#if CHAN_TYPE == GL_FLOAT
if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
r = Rs * sR + Rd * dR;
g = Gs * sG + Gd * dG;
b = Bs * sB + Bd * dB;
a = As * sA + Ad * dA;
}
else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
r = Rs * sR - Rd * dR;
g = Gs * sG - Gd * dG;
b = Bs * sB - Bd * dB;
a = As * sA - Ad * dA;
}
else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
r = Rd * dR - Rs * sR;
g = Gd * dG - Gs * sG;
b = Bd * dB - Bs * sB;
a = Ad * dA - As * sA;
}
else {
/* should never get here */
r = g = b = a = 0.0F; /* silence uninitialized var warning */
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
}
 
/* final clamping */
rgba[i][RCOMP] = MAX2( r, 0.0F );
rgba[i][GCOMP] = MAX2( g, 0.0F );
rgba[i][BCOMP] = MAX2( b, 0.0F );
rgba[i][ACOMP] = CLAMP( a, 0.0F, CHAN_MAXF );
#else
if (ctx->Color.BlendEquation==GL_FUNC_ADD_EXT) {
r = Rs * sR + Rd * dR + 0.5F;
g = Gs * sG + Gd * dG + 0.5F;
b = Bs * sB + Bd * dB + 0.5F;
a = As * sA + Ad * dA + 0.5F;
}
else if (ctx->Color.BlendEquation==GL_FUNC_SUBTRACT_EXT) {
r = Rs * sR - Rd * dR + 0.5F;
g = Gs * sG - Gd * dG + 0.5F;
b = Bs * sB - Bd * dB + 0.5F;
a = As * sA - Ad * dA + 0.5F;
}
else if (ctx->Color.BlendEquation==GL_FUNC_REVERSE_SUBTRACT_EXT) {
r = Rd * dR - Rs * sR + 0.5F;
g = Gd * dG - Gs * sG + 0.5F;
b = Bd * dB - Bs * sB + 0.5F;
a = Ad * dA - As * sA + 0.5F;
}
else {
/* should never get here */
r = g = b = a = 0.0F; /* silence uninitialized var warning */
_mesa_problem(ctx, "unexpected BlendEquation in blend_general()");
}
 
/* final clamping */
rgba[i][RCOMP] = (GLchan) (GLint) CLAMP( r, 0.0F, CHAN_MAXF );
rgba[i][GCOMP] = (GLchan) (GLint) CLAMP( g, 0.0F, CHAN_MAXF );
rgba[i][BCOMP] = (GLchan) (GLint) CLAMP( b, 0.0F, CHAN_MAXF );
rgba[i][ACOMP] = (GLchan) (GLint) CLAMP( a, 0.0F, CHAN_MAXF );
#endif
}
}
}
 
 
 
 
 
/*
* Analyze current blending parameters to pick fastest blending function.
* Result: the ctx->Color.BlendFunc pointer is updated.
*/
void _swrast_choose_blend_func( GLcontext *ctx )
{
const GLenum eq = ctx->Color.BlendEquation;
const GLenum srcRGB = ctx->Color.BlendSrcRGB;
const GLenum dstRGB = ctx->Color.BlendDstRGB;
const GLenum srcA = ctx->Color.BlendSrcA;
const GLenum dstA = ctx->Color.BlendDstA;
 
if (srcRGB != srcA || dstRGB != dstA) {
SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
}
else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_SRC_ALPHA
&& dstRGB==GL_ONE_MINUS_SRC_ALPHA) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_transparency;
}
else
#endif
SWRAST_CONTEXT(ctx)->BlendFunc = blend_transparency;
}
else if (eq==GL_FUNC_ADD_EXT && srcRGB==GL_ONE && dstRGB==GL_ONE) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_add;
}
else
#endif
SWRAST_CONTEXT(ctx)->BlendFunc = blend_add;
}
else if (((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_REVERSE_SUBTRACT_EXT)
&& (srcRGB==GL_ZERO && dstRGB==GL_SRC_COLOR))
||
((eq==GL_FUNC_ADD_EXT || eq==GL_FUNC_SUBTRACT_EXT)
&& (srcRGB==GL_DST_COLOR && dstRGB==GL_ZERO))) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_modulate;
}
else
#endif
SWRAST_CONTEXT(ctx)->BlendFunc = blend_modulate;
}
else if (eq==GL_MIN_EXT) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_min;
}
else
#endif
SWRAST_CONTEXT(ctx)->BlendFunc = blend_min;
}
else if (eq==GL_MAX_EXT) {
#if defined(USE_MMX_ASM)
if ( cpu_has_mmx ) {
SWRAST_CONTEXT(ctx)->BlendFunc = _mesa_mmx_blend_max;
}
else
#endif
SWRAST_CONTEXT(ctx)->BlendFunc = blend_max;
}
else if (eq==GL_FUNC_ADD_EXT && srcRGB == GL_ZERO && dstRGB == GL_ONE) {
SWRAST_CONTEXT(ctx)->BlendFunc = blend_noop;
}
else if (eq==GL_FUNC_ADD_EXT && srcRGB == GL_ONE && dstRGB == GL_ZERO) {
SWRAST_CONTEXT(ctx)->BlendFunc = blend_replace;
}
else {
SWRAST_CONTEXT(ctx)->BlendFunc = blend_general;
}
}
 
 
 
/*
* Apply the blending operator to a span of pixels.
* We can handle horizontal runs of pixels (spans) or arrays of x/y
* pixel coordinates.
*/
void
_mesa_blend_span( GLcontext *ctx, const struct sw_span *span,
GLchan rgba[][4] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan framebuffer[MAX_WIDTH][4];
 
ASSERT(span->end <= MAX_WIDTH);
ASSERT(span->arrayMask & SPAN_RGBA);
ASSERT(!ctx->Color.ColorLogicOpEnabled);
 
/* Read span of current frame buffer pixels */
if (span->arrayMask & SPAN_XY) {
/* array of x/y pixel coords */
(*swrast->Driver.ReadRGBAPixels)( ctx, span->end,
span->array->x, span->array->y,
framebuffer, span->array->mask );
if (swrast->_RasterMask & ALPHABUF_BIT) {
_mesa_read_alpha_pixels( ctx, span->end,
span->array->x, span->array->y,
framebuffer, span->array->mask );
}
}
else {
/* horizontal run of pixels */
_mesa_read_rgba_span( ctx, ctx->DrawBuffer, span->end,
span->x, span->y, framebuffer );
}
 
SWRAST_CONTEXT(ctx)->BlendFunc( ctx, span->end, span->array->mask, rgba,
(const GLchan (*)[4]) framebuffer );
}
/shark/trunk/ports/mesa/src/swrast/s_alpha.c
0,0 → 1,226
/* $Id: s_alpha.c,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*/
 
/**
* \file swrast/s_alpha.c
* \brief Functions to apply alpha test.
*/
 
#include "glheader.h"
#include "context.h"
#include "colormac.h"
#include "macros.h"
#include "mmath.h"
 
#include "s_alpha.h"
#include "s_context.h"
 
 
/**
* \fn GLint _mesa_alpha_test( const GLcontext *ctx, struct sw_span *span )
* \brief Apply the alpha test to a span of pixels.
* \return
* - "0" = all pixels in the span failed the alpha test.
* - "1" = one or more pixels passed the alpha test.
*/
GLint
_mesa_alpha_test( const GLcontext *ctx, struct sw_span *span )
{
const GLchan (*rgba)[4] = (const GLchan (*)[4]) span->array->rgba;
GLchan ref;
const GLuint n = span->end;
GLubyte *mask = span->array->mask;
GLuint i;
 
CLAMPED_FLOAT_TO_CHAN(ref, ctx->Color.AlphaRef);
 
if (span->arrayMask & SPAN_RGBA) {
/* Use the array values */
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] < ref);
break;
case GL_LEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] <= ref);
break;
case GL_GEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] >= ref);
break;
case GL_GREATER:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] > ref);
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] != ref);
break;
case GL_EQUAL:
for (i = 0; i < n; i++)
mask[i] &= (rgba[i][ACOMP] == ref);
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in _mesa_alpha_test" );
return 0;
}
}
else {
/* Use the interpolation values */
#if CHAN_TYPE == GL_FLOAT
const GLfloat alphaStep = span->alphaStep;
GLfloat alpha = span->alpha;
ASSERT(span->interpMask & SPAN_RGBA);
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++) {
mask[i] &= (alpha < ref);
alpha += alphaStep;
}
break;
case GL_LEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha <= ref);
alpha += alphaStep;
}
break;
case GL_GEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha >= ref);
alpha += alphaStep;
}
break;
case GL_GREATER:
for (i = 0; i < n; i++) {
mask[i] &= (alpha > ref);
alpha += alphaStep;
}
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha != ref);
alpha += alphaStep;
}
break;
case GL_EQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (alpha == ref);
alpha += alphaStep;
}
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
return 0;
}
#else
/* 8 or 16-bit channel interpolation */
const GLfixed alphaStep = span->alphaStep;
GLfixed alpha = span->alpha;
ASSERT(span->interpMask & SPAN_RGBA);
switch (ctx->Color.AlphaFunc) {
case GL_LESS:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) < ref);
alpha += alphaStep;
}
break;
case GL_LEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) <= ref);
alpha += alphaStep;
}
break;
case GL_GEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) >= ref);
alpha += alphaStep;
}
break;
case GL_GREATER:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) > ref);
alpha += alphaStep;
}
break;
case GL_NOTEQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) != ref);
alpha += alphaStep;
}
break;
case GL_EQUAL:
for (i = 0; i < n; i++) {
mask[i] &= (FixedToChan(alpha) == ref);
alpha += alphaStep;
}
break;
case GL_ALWAYS:
/* do nothing */
return 1;
case GL_NEVER:
/* caller should check for zero! */
span->writeAll = GL_FALSE;
return 0;
default:
_mesa_problem( ctx, "Invalid alpha test in gl_alpha_test" );
return 0;
}
#endif /* CHAN_TYPE */
}
 
#if 0
/* XXXX This causes conformance failures!!!! */
while ((span->start <= span->end) &&
(mask[span->start] == 0))
span->start ++;
 
while ((span->end >= span->start) &&
(mask[span->end] == 0))
span->end --;
#endif
 
span->writeAll = GL_FALSE;
 
if (span->start >= span->end)
return 0;
else
return 1;
}
/shark/trunk/ports/mesa/src/swrast/s_trispan.h
0,0 → 1,32
/* $Id: s_trispan.h,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef S_TRISPAN_H
#define S_TRISPAN_H
 
 
#endif /* S_TRISPAN_H */
/shark/trunk/ports/mesa/src/swrast/s_accum.c
0,0 → 1,529
/* $Id: s_accum.c,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "mmath.h"
#include "imports.h"
 
#include "s_accum.h"
#include "s_alphabuf.h"
#include "s_context.h"
#include "s_masking.h"
#include "s_span.h"
 
 
/*
* Accumulation buffer notes
*
* Normally, accumulation buffer values are GLshorts with values in
* [-32767, 32767] which represent floating point colors in [-1, 1],
* as suggested by the OpenGL specification.
*
* We optimize for the common case used for full-scene antialiasing:
* // start with accum buffer cleared to zero
* glAccum(GL_LOAD, w); // or GL_ACCUM the first image
* glAccum(GL_ACCUM, w);
* ...
* glAccum(GL_ACCUM, w);
* glAccum(GL_RETURN, 1.0);
* That is, we start with an empty accumulation buffer and accumulate
* n images, each with weight w = 1/n.
* In this scenario, we can simply store unscaled integer values in
* the accum buffer instead of scaled integers. We'll also keep track
* of the w value so when we do GL_RETURN we simply divide the accumulated
* values by n (=1/w).
* This lets us avoid _many_ int->float->int conversions.
*/
 
 
#if CHAN_BITS == 8 && ACCUM_BITS < 32
#define USE_OPTIMIZED_ACCUM /* enable the optimization */
#endif
 
 
void
_mesa_alloc_accum_buffer( GLframebuffer *buffer )
{
GET_CURRENT_CONTEXT(ctx);
GLint n;
 
if (buffer->Accum) {
MESA_PBUFFER_FREE( buffer->Accum );
buffer->Accum = NULL;
}
 
/* allocate accumulation buffer if not already present */
n = buffer->Width * buffer->Height * 4 * sizeof(GLaccum);
buffer->Accum = (GLaccum *) MESA_PBUFFER_ALLOC( n );
if (!buffer->Accum) {
/* unable to setup accumulation buffer */
_mesa_error( NULL, GL_OUT_OF_MEMORY, "glAccum" );
}
 
if (ctx) {
SWcontext *swrast = SWRAST_CONTEXT(ctx);
/* XXX these fields should probably be in the GLframebuffer */
#ifdef USE_OPTIMIZED_ACCUM
swrast->_IntegerAccumMode = GL_TRUE;
#else
swrast->_IntegerAccumMode = GL_FALSE;
#endif
swrast->_IntegerAccumScaler = 0.0;
}
}
 
 
/*
* This is called when we fall out of optimized/unscaled accum buffer mode.
* That is, we convert each unscaled accum buffer value into a scaled value
* representing the range[-1, 1].
*/
static void rescale_accum( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height * 4;
const GLfloat s = swrast->_IntegerAccumScaler * (32767.0F / CHAN_MAXF);
GLaccum *accum = ctx->DrawBuffer->Accum;
GLuint i;
 
assert(swrast->_IntegerAccumMode);
assert(accum);
 
for (i = 0; i < n; i++) {
accum[i] = (GLaccum) (accum[i] * s);
}
 
swrast->_IntegerAccumMode = GL_FALSE;
}
 
 
 
 
 
 
/*
* Clear the accumulation Buffer.
*/
void
_mesa_clear_accum_buffer( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint buffersize;
GLfloat acc_scale;
 
if (ctx->Visual.accumRedBits==0) {
/* No accumulation buffer! */
return;
}
 
if (sizeof(GLaccum)==1) {
acc_scale = 127.0;
}
else if (sizeof(GLaccum)==2) {
acc_scale = 32767.0;
}
else {
acc_scale = 1.0F;
}
 
/* number of pixels */
buffersize = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
 
if (!ctx->DrawBuffer->Accum) {
/* try to alloc accumulation buffer */
ctx->DrawBuffer->Accum = (GLaccum *)
MALLOC( buffersize * 4 * sizeof(GLaccum) );
}
 
if (ctx->DrawBuffer->Accum) {
if (ctx->Scissor.Enabled) {
/* Limit clear to scissor box */
const GLaccum r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale);
const GLaccum g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale);
const GLaccum b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale);
const GLaccum a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale);
GLint i, j;
GLint width, height;
GLaccum *row;
/* size of region to clear */
width = 4 * (ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin);
height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
/* ptr to first element to clear */
row = ctx->DrawBuffer->Accum
+ 4 * (ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width
+ ctx->DrawBuffer->_Xmin);
for (j=0;j<height;j++) {
for (i=0;i<width;i+=4) {
row[i+0] = r;
row[i+1] = g;
row[i+2] = b;
row[i+3] = a;
}
row += 4 * ctx->DrawBuffer->Width;
}
}
else {
/* clear whole buffer */
if (ctx->Accum.ClearColor[0]==0.0 &&
ctx->Accum.ClearColor[1]==0.0 &&
ctx->Accum.ClearColor[2]==0.0 &&
ctx->Accum.ClearColor[3]==0.0) {
/* Black */
_mesa_bzero( ctx->DrawBuffer->Accum,
buffersize * 4 * sizeof(GLaccum) );
}
else {
/* Not black */
const GLaccum r = (GLaccum) (ctx->Accum.ClearColor[0] * acc_scale);
const GLaccum g = (GLaccum) (ctx->Accum.ClearColor[1] * acc_scale);
const GLaccum b = (GLaccum) (ctx->Accum.ClearColor[2] * acc_scale);
const GLaccum a = (GLaccum) (ctx->Accum.ClearColor[3] * acc_scale);
GLaccum *acc = ctx->DrawBuffer->Accum;
GLuint i;
for (i=0;i<buffersize;i++) {
*acc++ = r;
*acc++ = g;
*acc++ = b;
*acc++ = a;
}
}
}
 
/* update optimized accum state vars */
if (ctx->Accum.ClearColor[0] == 0.0 && ctx->Accum.ClearColor[1] == 0.0 &&
ctx->Accum.ClearColor[2] == 0.0 && ctx->Accum.ClearColor[3] == 0.0) {
#ifdef USE_OPTIMIZED_ACCUM
swrast->_IntegerAccumMode = GL_TRUE;
#else
swrast->_IntegerAccumMode = GL_FALSE;
#endif
swrast->_IntegerAccumScaler = 0.0; /* denotes empty accum buffer */
}
else {
swrast->_IntegerAccumMode = GL_FALSE;
}
}
}
 
 
void
_swrast_Accum( GLcontext *ctx, GLenum op, GLfloat value,
GLint xpos, GLint ypos,
GLint width, GLint height )
 
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint width4;
GLfloat acc_scale;
GLchan rgba[MAX_WIDTH][4];
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
 
 
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
 
if (!ctx->DrawBuffer->Accum) {
_mesa_warning(ctx,
"Calling glAccum() without an accumulation "
"buffer (low memory?)");
return;
}
 
if (sizeof(GLaccum)==1) {
acc_scale = 127.0;
}
else if (sizeof(GLaccum)==2) {
acc_scale = 32767.0;
}
else {
acc_scale = 1.0F;
}
 
width4 = 4 * width;
 
switch (op) {
case GL_ADD:
if (value != 0.0F) {
const GLaccum val = (GLaccum) (value * acc_scale);
GLint j;
/* Leave optimized accum buffer mode */
if (swrast->_IntegerAccumMode)
rescale_accum(ctx);
for (j = 0; j < height; j++) {
GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + 4*xpos;
GLuint i;
for (i = 0; i < width4; i++) {
acc[i] += val;
}
ypos++;
}
}
break;
 
case GL_MULT:
if (value != 1.0F) {
GLint j;
/* Leave optimized accum buffer mode */
if (swrast->_IntegerAccumMode)
rescale_accum(ctx);
for (j = 0; j < height; j++) {
GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + 4 * xpos;
GLuint i;
for (i = 0; i < width4; i++) {
acc[i] = (GLaccum) ( (GLfloat) acc[i] * value );
}
ypos++;
}
}
break;
 
case GL_ACCUM:
if (value == 0.0F)
return;
 
_swrast_use_read_buffer(ctx);
 
/* May have to leave optimized accum buffer mode */
if (swrast->_IntegerAccumScaler == 0.0 && value > 0.0 && value <= 1.0)
swrast->_IntegerAccumScaler = value;
if (swrast->_IntegerAccumMode && value != swrast->_IntegerAccumScaler)
rescale_accum(ctx);
 
RENDER_START(swrast,ctx);
 
if (swrast->_IntegerAccumMode) {
/* simply add integer color values into accum buffer */
GLint j;
GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
assert(swrast->_IntegerAccumScaler > 0.0);
assert(swrast->_IntegerAccumScaler <= 1.0);
for (j = 0; j < height; j++) {
 
GLint i, i4;
_mesa_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
for (i = i4 = 0; i < width; i++, i4+=4) {
acc[i4+0] += rgba[i][RCOMP];
acc[i4+1] += rgba[i][GCOMP];
acc[i4+2] += rgba[i][BCOMP];
acc[i4+3] += rgba[i][ACOMP];
}
acc += width4;
ypos++;
}
}
else {
/* scaled integer (or float) accum buffer */
const GLfloat rscale = value * acc_scale / CHAN_MAXF;
const GLfloat gscale = value * acc_scale / CHAN_MAXF;
const GLfloat bscale = value * acc_scale / CHAN_MAXF;
const GLfloat ascale = value * acc_scale / CHAN_MAXF;
GLint j;
for (j=0;j<height;j++) {
GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
GLint i;
_mesa_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
for (i=0;i<width;i++) {
acc[0] += (GLaccum) ( (GLfloat) rgba[i][RCOMP] * rscale );
acc[1] += (GLaccum) ( (GLfloat) rgba[i][GCOMP] * gscale );
acc[2] += (GLaccum) ( (GLfloat) rgba[i][BCOMP] * bscale );
acc[3] += (GLaccum) ( (GLfloat) rgba[i][ACOMP] * ascale );
acc += 4;
}
ypos++;
}
}
/* restore read buffer = draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
 
RENDER_FINISH(swrast,ctx);
break;
 
case GL_LOAD:
_swrast_use_read_buffer(ctx);
 
/* This is a change to go into optimized accum buffer mode */
if (value > 0.0 && value <= 1.0) {
#ifdef USE_OPTIMIZED_ACCUM
swrast->_IntegerAccumMode = GL_TRUE;
#else
swrast->_IntegerAccumMode = GL_FALSE;
#endif
swrast->_IntegerAccumScaler = value;
}
else {
swrast->_IntegerAccumMode = GL_FALSE;
swrast->_IntegerAccumScaler = 0.0;
}
 
RENDER_START(swrast,ctx);
if (swrast->_IntegerAccumMode) {
/* just copy values into accum buffer */
GLint j;
GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
assert(swrast->_IntegerAccumScaler > 0.0);
assert(swrast->_IntegerAccumScaler <= 1.0);
for (j = 0; j < height; j++) {
GLint i, i4;
_mesa_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
for (i = i4 = 0; i < width; i++, i4 += 4) {
acc[i4+0] = rgba[i][RCOMP];
acc[i4+1] = rgba[i][GCOMP];
acc[i4+2] = rgba[i][BCOMP];
acc[i4+3] = rgba[i][ACOMP];
}
acc += width4;
ypos++;
}
}
else {
/* scaled integer (or float) accum buffer */
const GLfloat rscale = value * acc_scale / CHAN_MAXF;
const GLfloat gscale = value * acc_scale / CHAN_MAXF;
const GLfloat bscale = value * acc_scale / CHAN_MAXF;
const GLfloat ascale = value * acc_scale / CHAN_MAXF;
#if 0
const GLfloat d = 3.0 / acc_scale; /* XXX what's this? */
#endif
GLint i, j;
for (j = 0; j < height; j++) {
GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos * 4;
_mesa_read_rgba_span(ctx, ctx->DrawBuffer, width, xpos, ypos, rgba);
for (i=0;i<width;i++) {
#if 0
*acc++ = (GLaccum) ((GLfloat) rgba[i][RCOMP] * rscale + d);
*acc++ = (GLaccum) ((GLfloat) rgba[i][GCOMP] * gscale + d);
*acc++ = (GLaccum) ((GLfloat) rgba[i][BCOMP] * bscale + d);
*acc++ = (GLaccum) ((GLfloat) rgba[i][ACOMP] * ascale + d);
#else
*acc++ = (GLaccum) ((GLfloat) rgba[i][RCOMP] * rscale);
*acc++ = (GLaccum) ((GLfloat) rgba[i][GCOMP] * gscale);
*acc++ = (GLaccum) ((GLfloat) rgba[i][BCOMP] * bscale);
*acc++ = (GLaccum) ((GLfloat) rgba[i][ACOMP] * ascale);
#endif
}
ypos++;
}
}
 
/* restore read buffer = draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
 
RENDER_FINISH(swrast,ctx);
break;
 
case GL_RETURN:
/* May have to leave optimized accum buffer mode */
if (swrast->_IntegerAccumMode && value != 1.0)
rescale_accum(ctx);
 
RENDER_START(swrast,ctx);
#ifdef USE_OPTIMIZED_ACCUM
if (swrast->_IntegerAccumMode && swrast->_IntegerAccumScaler > 0) {
/* build lookup table to avoid many floating point multiplies */
static GLchan multTable[32768];
static GLfloat prevMult = 0.0;
const GLfloat mult = swrast->_IntegerAccumScaler;
const GLint max = MIN2((GLint) (256 / mult), 32767);
GLint j;
if (mult != prevMult) {
for (j = 0; j < max; j++)
multTable[j] = IROUND((GLfloat) j * mult);
prevMult = mult;
}
 
assert(swrast->_IntegerAccumScaler > 0.0);
assert(swrast->_IntegerAccumScaler <= 1.0);
for (j = 0; j < height; j++) {
const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4;
GLint i, i4;
for (i = i4 = 0; i < width; i++, i4 += 4) {
ASSERT(acc[i4+0] < max);
ASSERT(acc[i4+1] < max);
ASSERT(acc[i4+2] < max);
ASSERT(acc[i4+3] < max);
rgba[i][RCOMP] = multTable[acc[i4+0]];
rgba[i][GCOMP] = multTable[acc[i4+1]];
rgba[i][BCOMP] = multTable[acc[i4+2]];
rgba[i][ACOMP] = multTable[acc[i4+3]];
}
if (colorMask != 0xffffffff) {
_mesa_mask_rgba_array( ctx, width, xpos, ypos, rgba );
}
(*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
(const GLchan (*)[4])rgba, NULL );
if (ctx->DrawBuffer->UseSoftwareAlphaBuffers
&& ctx->Color.ColorMask[ACOMP]) {
_mesa_write_alpha_span(ctx, width, xpos, ypos,
(CONST GLchan (*)[4]) rgba, NULL);
}
ypos++;
}
}
else
#endif /* USE_OPTIMIZED_ACCUM */
{
/* scaled integer (or float) accum buffer */
const GLfloat rscale = value / acc_scale * CHAN_MAXF;
const GLfloat gscale = value / acc_scale * CHAN_MAXF;
const GLfloat bscale = value / acc_scale * CHAN_MAXF;
const GLfloat ascale = value / acc_scale * CHAN_MAXF;
GLint i, j;
for (j=0;j<height;j++) {
const GLaccum *acc = ctx->DrawBuffer->Accum + ypos * width4 + xpos*4;
for (i=0;i<width;i++) {
GLint r = IROUND( (GLfloat) (acc[0]) * rscale );
GLint g = IROUND( (GLfloat) (acc[1]) * gscale );
GLint b = IROUND( (GLfloat) (acc[2]) * bscale );
GLint a = IROUND( (GLfloat) (acc[3]) * ascale );
acc += 4;
rgba[i][RCOMP] = CLAMP( r, 0, CHAN_MAX );
rgba[i][GCOMP] = CLAMP( g, 0, CHAN_MAX );
rgba[i][BCOMP] = CLAMP( b, 0, CHAN_MAX );
rgba[i][ACOMP] = CLAMP( a, 0, CHAN_MAX );
}
if (colorMask != 0xffffffff) {
_mesa_mask_rgba_array( ctx, width, xpos, ypos, rgba );
}
(*swrast->Driver.WriteRGBASpan)( ctx, width, xpos, ypos,
(const GLchan (*)[4])rgba, NULL );
if (ctx->DrawBuffer->UseSoftwareAlphaBuffers
&& ctx->Color.ColorMask[ACOMP]) {
_mesa_write_alpha_span(ctx, width, xpos, ypos,
(CONST GLchan (*)[4]) rgba, NULL);
}
ypos++;
}
}
RENDER_FINISH(swrast,ctx);
break;
 
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glAccum" );
}
}
/shark/trunk/ports/mesa/src/swrast/s_blend.h
0,0 → 1,46
/* $Id: s_blend.h,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_BLEND_H
#define S_BLEND_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
 
extern void
_mesa_blend_span( GLcontext *ctx, const struct sw_span *span,
GLchan rgba[][4] );
 
 
extern void
_swrast_choose_blend_func( GLcontext *ctx );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_aaline.c
0,0 → 1,537
/* $Id: s_aaline.c,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "swrast/s_aaline.h"
#include "swrast/s_context.h"
#include "swrast/s_span.h"
#include "swrast/swrast.h"
#include "mtypes.h"
#include "mmath.h"
 
 
#define SUB_PIXEL 4
 
 
/*
* Info about the AA line we're rendering
*/
struct LineInfo
{
GLfloat x0, y0; /* start */
GLfloat x1, y1; /* end */
GLfloat dx, dy; /* direction vector */
GLfloat len; /* length */
GLfloat halfWidth; /* half of line width */
GLfloat xAdj, yAdj; /* X and Y adjustment for quad corners around line */
/* for coverage computation */
GLfloat qx0, qy0; /* quad vertices */
GLfloat qx1, qy1;
GLfloat qx2, qy2;
GLfloat qx3, qy3;
GLfloat ex0, ey0; /* quad edge vectors */
GLfloat ex1, ey1;
GLfloat ex2, ey2;
GLfloat ex3, ey3;
 
/* DO_Z */
GLfloat zPlane[4];
/* DO_FOG */
GLfloat fPlane[4];
/* DO_RGBA */
GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
/* DO_INDEX */
GLfloat iPlane[4];
/* DO_SPEC */
GLfloat srPlane[4], sgPlane[4], sbPlane[4];
/* DO_TEX or DO_MULTITEX */
GLfloat sPlane[MAX_TEXTURE_UNITS][4];
GLfloat tPlane[MAX_TEXTURE_UNITS][4];
GLfloat uPlane[MAX_TEXTURE_UNITS][4];
GLfloat vPlane[MAX_TEXTURE_UNITS][4];
GLfloat lambda[MAX_TEXTURE_UNITS];
GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
 
struct sw_span span;
};
 
 
 
/*
* Compute the equation of a plane used to interpolate line fragment data
* such as color, Z, texture coords, etc.
* Input: (x0, y0) and (x1,y1) are the endpoints of the line.
* z0, and z1 are the end point values to interpolate.
* Output: plane - the plane equation.
*
* Note: we don't really have enough parameters to specify a plane.
* We take the endpoints of the line and compute a plane such that
* the cross product of the line vector and the plane normal is
* parallel to the projection plane.
*/
static void
compute_plane(GLfloat x0, GLfloat y0, GLfloat x1, GLfloat y1,
GLfloat z0, GLfloat z1, GLfloat plane[4])
{
#if 0
/* original */
const GLfloat px = x1 - x0;
const GLfloat py = y1 - y0;
const GLfloat pz = z1 - z0;
const GLfloat qx = -py;
const GLfloat qy = px;
const GLfloat qz = 0;
const GLfloat a = py * qz - pz * qy;
const GLfloat b = pz * qx - px * qz;
const GLfloat c = px * qy - py * qx;
const GLfloat d = -(a * x0 + b * y0 + c * z0);
plane[0] = a;
plane[1] = b;
plane[2] = c;
plane[3] = d;
#else
/* simplified */
const GLfloat px = x1 - x0;
const GLfloat py = y1 - y0;
const GLfloat pz = z0 - z1;
const GLfloat a = pz * px;
const GLfloat b = pz * py;
const GLfloat c = px * px + py * py;
const GLfloat d = -(a * x0 + b * y0 + c * z0);
if (a == 0.0 && b == 0.0 && c == 0.0 && d == 0.0) {
plane[0] = 0.0;
plane[1] = 0.0;
plane[2] = 1.0;
plane[3] = 0.0;
}
else {
plane[0] = a;
plane[1] = b;
plane[2] = c;
plane[3] = d;
}
#endif
}
 
 
static INLINE void
constant_plane(GLfloat value, GLfloat plane[4])
{
plane[0] = 0.0;
plane[1] = 0.0;
plane[2] = -1.0;
plane[3] = value;
}
 
 
static INLINE GLfloat
solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
{
const GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
return z;
}
 
#define SOLVE_PLANE(X, Y, PLANE) \
((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2])
 
 
/*
* Return 1 / solve_plane().
*/
static INLINE GLfloat
solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
{
const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y;
if (denom == 0.0)
return 0.0;
else
return -plane[2] / denom;
}
 
 
/*
* Solve plane and return clamped GLchan value.
*/
static INLINE GLchan
solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
{
GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2] + 0.5F;
if (z < 0.0F)
return 0;
else if (z > CHAN_MAXF)
return (GLchan) CHAN_MAXF;
return (GLchan) (GLint) z;
}
 
 
/*
* Compute mipmap level of detail.
*/
static INLINE GLfloat
compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
GLfloat invQ, GLfloat width, GLfloat height)
{
GLfloat dudx = sPlane[0] / sPlane[2] * invQ * width;
GLfloat dudy = sPlane[1] / sPlane[2] * invQ * width;
GLfloat dvdx = tPlane[0] / tPlane[2] * invQ * height;
GLfloat dvdy = tPlane[1] / tPlane[2] * invQ * height;
GLfloat r1 = dudx * dudx + dudy * dudy;
GLfloat r2 = dvdx * dvdx + dvdy * dvdy;
GLfloat rho2 = r1 + r2;
/* return log base 2 of rho */
if (rho2 == 0.0F)
return 0.0;
else
return (GLfloat) (log(rho2) * 1.442695 * 0.5);/* 1.442695 = 1/log(2) */
}
 
 
 
 
/*
* Fill in the samples[] array with the (x,y) subpixel positions of
* xSamples * ySamples sample positions.
* Note that the four corner samples are put into the first four
* positions of the array. This allows us to optimize for the common
* case of all samples being inside the polygon.
*/
static void
make_sample_table(GLint xSamples, GLint ySamples, GLfloat samples[][2])
{
const GLfloat dx = 1.0F / (GLfloat) xSamples;
const GLfloat dy = 1.0F / (GLfloat) ySamples;
GLint x, y;
GLint i;
 
i = 4;
for (x = 0; x < xSamples; x++) {
for (y = 0; y < ySamples; y++) {
GLint j;
if (x == 0 && y == 0) {
/* lower left */
j = 0;
}
else if (x == xSamples - 1 && y == 0) {
/* lower right */
j = 1;
}
else if (x == 0 && y == ySamples - 1) {
/* upper left */
j = 2;
}
else if (x == xSamples - 1 && y == ySamples - 1) {
/* upper right */
j = 3;
}
else {
j = i++;
}
samples[j][0] = x * dx + 0.5F * dx;
samples[j][1] = y * dy + 0.5F * dy;
}
}
}
 
 
 
/*
* Compute how much of the given pixel's area is inside the rectangle
* defined by vertices v0, v1, v2, v3.
* Vertices MUST be specified in counter-clockwise order.
* Return: coverage in [0, 1].
*/
static GLfloat
compute_coveragef(const struct LineInfo *info,
GLint winx, GLint winy)
{
static GLfloat samples[SUB_PIXEL * SUB_PIXEL][2];
static GLboolean haveSamples = GL_FALSE;
const GLfloat x = (GLfloat) winx;
const GLfloat y = (GLfloat) winy;
GLint stop = 4, i;
GLfloat insideCount = SUB_PIXEL * SUB_PIXEL;
 
if (!haveSamples) {
make_sample_table(SUB_PIXEL, SUB_PIXEL, samples);
haveSamples = GL_TRUE;
}
 
#if 0 /*DEBUG*/
{
const GLfloat area = dx0 * dy1 - dx1 * dy0;
assert(area >= 0.0);
}
#endif
 
for (i = 0; i < stop; i++) {
const GLfloat sx = x + samples[i][0];
const GLfloat sy = y + samples[i][1];
const GLfloat fx0 = sx - info->qx0;
const GLfloat fy0 = sy - info->qy0;
const GLfloat fx1 = sx - info->qx1;
const GLfloat fy1 = sy - info->qy1;
const GLfloat fx2 = sx - info->qx2;
const GLfloat fy2 = sy - info->qy2;
const GLfloat fx3 = sx - info->qx3;
const GLfloat fy3 = sy - info->qy3;
/* cross product determines if sample is inside or outside each edge */
GLfloat cross0 = (info->ex0 * fy0 - info->ey0 * fx0);
GLfloat cross1 = (info->ex1 * fy1 - info->ey1 * fx1);
GLfloat cross2 = (info->ex2 * fy2 - info->ey2 * fx2);
GLfloat cross3 = (info->ex3 * fy3 - info->ey3 * fx3);
/* Check if the sample is exactly on an edge. If so, let cross be a
* positive or negative value depending on the direction of the edge.
*/
if (cross0 == 0.0F)
cross0 = info->ex0 + info->ey0;
if (cross1 == 0.0F)
cross1 = info->ex1 + info->ey1;
if (cross2 == 0.0F)
cross2 = info->ex2 + info->ey2;
if (cross3 == 0.0F)
cross3 = info->ex3 + info->ey3;
if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F || cross3 < 0.0F) {
/* point is outside quadrilateral */
insideCount -= 1.0F;
stop = SUB_PIXEL * SUB_PIXEL;
}
}
if (stop == 4)
return 1.0F;
else
return insideCount * (1.0F / (SUB_PIXEL * SUB_PIXEL));
}
 
 
 
typedef void (*plot_func)(GLcontext *ctx, struct LineInfo *line,
int ix, int iy);
 
 
/*
* Draw an AA line segment (called many times per line when stippling)
*/
static void
segment(GLcontext *ctx,
struct LineInfo *line,
plot_func plot,
GLfloat t0, GLfloat t1)
{
const GLfloat absDx = (line->dx < 0.0F) ? -line->dx : line->dx;
const GLfloat absDy = (line->dy < 0.0F) ? -line->dy : line->dy;
/* compute the actual segment's endpoints */
const GLfloat x0 = line->x0 + t0 * line->dx;
const GLfloat y0 = line->y0 + t0 * line->dy;
const GLfloat x1 = line->x0 + t1 * line->dx;
const GLfloat y1 = line->y0 + t1 * line->dy;
 
/* compute vertices of the line-aligned quadrilateral */
line->qx0 = x0 - line->yAdj;
line->qy0 = y0 + line->xAdj;
line->qx1 = x0 + line->yAdj;
line->qy1 = y0 - line->xAdj;
line->qx2 = x1 + line->yAdj;
line->qy2 = y1 - line->xAdj;
line->qx3 = x1 - line->yAdj;
line->qy3 = y1 + line->xAdj;
/* compute the quad's edge vectors (for coverage calc) */
line->ex0 = line->qx1 - line->qx0;
line->ey0 = line->qy1 - line->qy0;
line->ex1 = line->qx2 - line->qx1;
line->ey1 = line->qy2 - line->qy1;
line->ex2 = line->qx3 - line->qx2;
line->ey2 = line->qy3 - line->qy2;
line->ex3 = line->qx0 - line->qx3;
line->ey3 = line->qy0 - line->qy3;
 
if (absDx > absDy) {
/* X-major line */
GLfloat dydx = line->dy / line->dx;
GLfloat xLeft, xRight, yBot, yTop;
GLint ix, ixRight;
if (x0 < x1) {
xLeft = x0 - line->halfWidth;
xRight = x1 + line->halfWidth;
if (line->dy >= 0.0) {
yBot = y0 - 3.0F * line->halfWidth;
yTop = y0 + line->halfWidth;
}
else {
yBot = y0 - line->halfWidth;
yTop = y0 + 3.0F * line->halfWidth;
}
}
else {
xLeft = x1 - line->halfWidth;
xRight = x0 + line->halfWidth;
if (line->dy <= 0.0) {
yBot = y1 - 3.0F * line->halfWidth;
yTop = y1 + line->halfWidth;
}
else {
yBot = y1 - line->halfWidth;
yTop = y1 + 3.0F * line->halfWidth;
}
}
 
/* scan along the line, left-to-right */
ixRight = (GLint) (xRight + 1.0F);
 
/*printf("avg span height: %g\n", yTop - yBot);*/
for (ix = (GLint) xLeft; ix < ixRight; ix++) {
const GLint iyBot = (GLint) yBot;
const GLint iyTop = (GLint) (yTop + 1.0F);
GLint iy;
/* scan across the line, bottom-to-top */
for (iy = iyBot; iy < iyTop; iy++) {
(*plot)(ctx, line, ix, iy);
}
yBot += dydx;
yTop += dydx;
}
}
else {
/* Y-major line */
GLfloat dxdy = line->dx / line->dy;
GLfloat yBot, yTop, xLeft, xRight;
GLint iy, iyTop;
if (y0 < y1) {
yBot = y0 - line->halfWidth;
yTop = y1 + line->halfWidth;
if (line->dx >= 0.0) {
xLeft = x0 - 3.0F * line->halfWidth;
xRight = x0 + line->halfWidth;
}
else {
xLeft = x0 - line->halfWidth;
xRight = x0 + 3.0F * line->halfWidth;
}
}
else {
yBot = y1 - line->halfWidth;
yTop = y0 + line->halfWidth;
if (line->dx <= 0.0) {
xLeft = x1 - 3.0F * line->halfWidth;
xRight = x1 + line->halfWidth;
}
else {
xLeft = x1 - line->halfWidth;
xRight = x1 + 3.0F * line->halfWidth;
}
}
 
/* scan along the line, bottom-to-top */
iyTop = (GLint) (yTop + 1.0F);
 
/*printf("avg span width: %g\n", xRight - xLeft);*/
for (iy = (GLint) yBot; iy < iyTop; iy++) {
const GLint ixLeft = (GLint) xLeft;
const GLint ixRight = (GLint) (xRight + 1.0F);
GLint ix;
/* scan across the line, left-to-right */
for (ix = ixLeft; ix < ixRight; ix++) {
(*plot)(ctx, line, ix, iy);
}
xLeft += dxdy;
xRight += dxdy;
}
}
}
 
 
#define NAME(x) aa_ci_##x
#define DO_Z
#define DO_FOG
#define DO_INDEX
#include "s_aalinetemp.h"
 
 
#define NAME(x) aa_rgba_##x
#define DO_Z
#define DO_FOG
#define DO_RGBA
#include "s_aalinetemp.h"
 
 
#define NAME(x) aa_tex_rgba_##x
#define DO_Z
#define DO_FOG
#define DO_RGBA
#define DO_TEX
#include "s_aalinetemp.h"
 
 
#define NAME(x) aa_multitex_rgba_##x
#define DO_Z
#define DO_FOG
#define DO_RGBA
#define DO_MULTITEX
#include "s_aalinetemp.h"
 
 
#define NAME(x) aa_multitex_spec_##x
#define DO_Z
#define DO_FOG
#define DO_RGBA
#define DO_MULTITEX
#define DO_SPEC
#include "s_aalinetemp.h"
 
 
 
void
_swrast_choose_aa_line_function(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
ASSERT(ctx->Line.SmoothFlag);
 
if (ctx->Visual.rgbMode) {
/* RGBA */
if (ctx->Texture._EnabledUnits != 0) {
if (ctx->Texture._EnabledUnits > 1) {
/* Multitextured! */
if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR ||
ctx->Fog.ColorSumEnabled)
swrast->Line = aa_multitex_spec_line;
else
swrast->Line = aa_multitex_rgba_line;
}
else {
swrast->Line = aa_tex_rgba_line;
}
}
else {
swrast->Line = aa_rgba_line;
}
}
else {
/* Color Index */
swrast->Line = aa_ci_line;
}
}
/shark/trunk/ports/mesa/src/swrast/s_alpha.h
0,0 → 1,40
/* $Id: s_alpha.h,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_ALPHA_H
#define S_ALPHA_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern GLint
_mesa_alpha_test( const GLcontext *ctx, struct sw_span *span );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_aatritemp.h
0,0 → 1,554
/* $Id: s_aatritemp.h,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*/
 
 
/*
* Antialiased Triangle Rasterizer Template
*
* This file is #include'd to generate custom AA triangle rasterizers.
* NOTE: this code hasn't been optimized yet. That'll come after it
* works correctly.
*
* The following macros may be defined to indicate what auxillary information
* must be copmuted across the triangle:
* DO_Z - if defined, compute Z values
* DO_RGBA - if defined, compute RGBA values
* DO_INDEX - if defined, compute color index values
* DO_SPEC - if defined, compute specular RGB values
* DO_TEX - if defined, compute unit 0 STRQ texcoords
* DO_MULTITEX - if defined, compute all unit's STRQ texcoords
*/
 
/*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/
{
const GLfloat *p0 = v0->win;
const GLfloat *p1 = v1->win;
const GLfloat *p2 = v2->win;
const SWvertex *vMin, *vMid, *vMax;
GLint iyMin, iyMax;
GLfloat yMin, yMax;
GLboolean ltor;
GLfloat majDx, majDy; /* major (i.e. long) edge dx and dy */
struct sw_span span;
#ifdef DO_Z
GLfloat zPlane[4];
#endif
#ifdef DO_FOG
GLfloat fogPlane[4];
#else
GLfloat *fog = NULL;
#endif
#ifdef DO_RGBA
GLfloat rPlane[4], gPlane[4], bPlane[4], aPlane[4];
#endif
#ifdef DO_INDEX
GLfloat iPlane[4];
#endif
#ifdef DO_SPEC
GLfloat srPlane[4], sgPlane[4], sbPlane[4];
#endif
#ifdef DO_TEX
GLfloat sPlane[4], tPlane[4], uPlane[4], vPlane[4];
GLfloat texWidth, texHeight;
#elif defined(DO_MULTITEX)
GLfloat sPlane[MAX_TEXTURE_UNITS][4]; /* texture S */
GLfloat tPlane[MAX_TEXTURE_UNITS][4]; /* texture T */
GLfloat uPlane[MAX_TEXTURE_UNITS][4]; /* texture R */
GLfloat vPlane[MAX_TEXTURE_UNITS][4]; /* texture Q */
GLfloat texWidth[MAX_TEXTURE_UNITS], texHeight[MAX_TEXTURE_UNITS];
#endif
GLfloat bf = SWRAST_CONTEXT(ctx)->_backface_sign;
INIT_SPAN(span, GL_POLYGON, 0, 0, SPAN_COVERAGE);
 
/* determine bottom to top order of vertices */
{
GLfloat y0 = v0->win[1];
GLfloat y1 = v1->win[1];
GLfloat y2 = v2->win[1];
if (y0 <= y1) {
if (y1 <= y2) {
vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */
}
else if (y2 <= y0) {
vMin = v2; vMid = v0; vMax = v1; /* y2<=y0<=y1 */
}
else {
vMin = v0; vMid = v2; vMax = v1; bf = -bf; /* y0<=y2<=y1 */
}
}
else {
if (y0 <= y2) {
vMin = v1; vMid = v0; vMax = v2; bf = -bf; /* y1<=y0<=y2 */
}
else if (y2 <= y1) {
vMin = v2; vMid = v1; vMax = v0; bf = -bf; /* y2<=y1<=y0 */
}
else {
vMin = v1; vMid = v2; vMax = v0; /* y1<=y2<=y0 */
}
}
}
 
majDx = vMax->win[0] - vMin->win[0];
majDy = vMax->win[1] - vMin->win[1];
 
{
const GLfloat botDx = vMid->win[0] - vMin->win[0];
const GLfloat botDy = vMid->win[1] - vMin->win[1];
const GLfloat area = majDx * botDy - botDx * majDy;
ltor = (GLboolean) (area < 0.0F);
/* Do backface culling */
if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area))
return;
}
 
#ifndef DO_OCCLUSION_TEST
ctx->OcclusionResult = GL_TRUE;
#endif
 
/* Plane equation setup:
* We evaluate plane equations at window (x,y) coordinates in order
* to compute color, Z, fog, texcoords, etc. This isn't terribly
* efficient but it's easy and reliable.
*/
#ifdef DO_Z
compute_plane(p0, p1, p2, p0[2], p1[2], p2[2], zPlane);
span.arrayMask |= SPAN_Z;
#endif
#ifdef DO_FOG
compute_plane(p0, p1, p2, v0->fog, v1->fog, v2->fog, fogPlane);
span.arrayMask |= SPAN_FOG;
#endif
#ifdef DO_RGBA
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(p0, p1, p2, v0->color[0], v1->color[0], v2->color[0], rPlane);
compute_plane(p0, p1, p2, v0->color[1], v1->color[1], v2->color[1], gPlane);
compute_plane(p0, p1, p2, v0->color[2], v1->color[2], v2->color[2], bPlane);
compute_plane(p0, p1, p2, v0->color[3], v1->color[3], v2->color[3], aPlane);
}
else {
constant_plane(v2->color[RCOMP], rPlane);
constant_plane(v2->color[GCOMP], gPlane);
constant_plane(v2->color[BCOMP], bPlane);
constant_plane(v2->color[ACOMP], aPlane);
}
span.arrayMask |= SPAN_RGBA;
#endif
#ifdef DO_INDEX
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(p0, p1, p2, (GLfloat) v0->index,
(GLfloat) v1->index, (GLfloat) v2->index, iPlane);
}
else {
constant_plane((GLfloat) v2->index, iPlane);
}
span.arrayMask |= SPAN_INDEX;
#endif
#ifdef DO_SPEC
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(p0, p1, p2, v0->specular[0], v1->specular[0], v2->specular[0],srPlane);
compute_plane(p0, p1, p2, v0->specular[1], v1->specular[1], v2->specular[1],sgPlane);
compute_plane(p0, p1, p2, v0->specular[2], v1->specular[2], v2->specular[2],sbPlane);
}
else {
constant_plane(v2->specular[RCOMP], srPlane);
constant_plane(v2->specular[GCOMP], sgPlane);
constant_plane(v2->specular[BCOMP], sbPlane);
}
span.arrayMask |= SPAN_SPEC;
#endif
#ifdef DO_TEX
{
const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
const GLfloat invW0 = v0->win[3];
const GLfloat invW1 = v1->win[3];
const GLfloat invW2 = v2->win[3];
const GLfloat s0 = v0->texcoord[0][0] * invW0;
const GLfloat s1 = v1->texcoord[0][0] * invW1;
const GLfloat s2 = v2->texcoord[0][0] * invW2;
const GLfloat t0 = v0->texcoord[0][1] * invW0;
const GLfloat t1 = v1->texcoord[0][1] * invW1;
const GLfloat t2 = v2->texcoord[0][1] * invW2;
const GLfloat r0 = v0->texcoord[0][2] * invW0;
const GLfloat r1 = v1->texcoord[0][2] * invW1;
const GLfloat r2 = v2->texcoord[0][2] * invW2;
const GLfloat q0 = v0->texcoord[0][3] * invW0;
const GLfloat q1 = v1->texcoord[0][3] * invW1;
const GLfloat q2 = v2->texcoord[0][3] * invW2;
compute_plane(p0, p1, p2, s0, s1, s2, sPlane);
compute_plane(p0, p1, p2, t0, t1, t2, tPlane);
compute_plane(p0, p1, p2, r0, r1, r2, uPlane);
compute_plane(p0, p1, p2, q0, q1, q2, vPlane);
texWidth = (GLfloat) texImage->Width;
texHeight = (GLfloat) texImage->Height;
}
span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
#elif defined(DO_MULTITEX)
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
const GLfloat invW0 = v0->win[3];
const GLfloat invW1 = v1->win[3];
const GLfloat invW2 = v2->win[3];
const GLfloat s0 = v0->texcoord[u][0] * invW0;
const GLfloat s1 = v1->texcoord[u][0] * invW1;
const GLfloat s2 = v2->texcoord[u][0] * invW2;
const GLfloat t0 = v0->texcoord[u][1] * invW0;
const GLfloat t1 = v1->texcoord[u][1] * invW1;
const GLfloat t2 = v2->texcoord[u][1] * invW2;
const GLfloat r0 = v0->texcoord[u][2] * invW0;
const GLfloat r1 = v1->texcoord[u][2] * invW1;
const GLfloat r2 = v2->texcoord[u][2] * invW2;
const GLfloat q0 = v0->texcoord[u][3] * invW0;
const GLfloat q1 = v1->texcoord[u][3] * invW1;
const GLfloat q2 = v2->texcoord[u][3] * invW2;
compute_plane(p0, p1, p2, s0, s1, s2, sPlane[u]);
compute_plane(p0, p1, p2, t0, t1, t2, tPlane[u]);
compute_plane(p0, p1, p2, r0, r1, r2, uPlane[u]);
compute_plane(p0, p1, p2, q0, q1, q2, vPlane[u]);
texWidth[u] = (GLfloat) texImage->Width;
texHeight[u] = (GLfloat) texImage->Height;
}
}
}
span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
#endif
 
/* Begin bottom-to-top scan over the triangle.
* The long edge will either be on the left or right side of the
* triangle. We always scan from the long edge toward the shorter
* edges, stopping when we find that coverage = 0. If the long edge
* is on the left we scan left-to-right. Else, we scan right-to-left.
*/
yMin = vMin->win[1];
yMax = vMax->win[1];
iyMin = (GLint) yMin;
iyMax = (GLint) yMax + 1;
 
if (ltor) {
/* scan left to right */
const GLfloat *pMin = vMin->win;
const GLfloat *pMid = vMid->win;
const GLfloat *pMax = vMax->win;
const GLfloat dxdy = majDx / majDy;
const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F;
GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
GLint iy;
for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
GLint ix, startX = (GLint) (x - xAdj);
GLuint count;
GLfloat coverage = 0.0F;
 
/* skip over fragments with zero coverage */
while (startX < MAX_WIDTH) {
coverage = compute_coveragef(pMin, pMid, pMax, startX, iy);
if (coverage > 0.0F)
break;
startX++;
}
 
/* enter interior of triangle */
ix = startX;
count = 0;
while (coverage > 0.0F) {
/* (cx,cy) = center of fragment */
const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
struct span_arrays *array = span.array;
#ifdef DO_INDEX
array->coverage[count] = (GLfloat) compute_coveragei(pMin, pMid, pMax, ix, iy);
#else
array->coverage[count] = coverage;
#endif
#ifdef DO_Z
array->z[count] = (GLdepth) solve_plane(cx, cy, zPlane);
#endif
#ifdef DO_FOG
array->fog[count] = solve_plane(cx, cy, fogPlane);
#endif
#ifdef DO_RGBA
array->rgba[count][RCOMP] = solve_plane_chan(cx, cy, rPlane);
array->rgba[count][GCOMP] = solve_plane_chan(cx, cy, gPlane);
array->rgba[count][BCOMP] = solve_plane_chan(cx, cy, bPlane);
array->rgba[count][ACOMP] = solve_plane_chan(cx, cy, aPlane);
#endif
#ifdef DO_INDEX
array->index[count] = (GLint) solve_plane(cx, cy, iPlane);
#endif
#ifdef DO_SPEC
array->spec[count][RCOMP] = solve_plane_chan(cx, cy, srPlane);
array->spec[count][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
array->spec[count][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
#endif
#ifdef DO_TEX
{
const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
array->texcoords[0][count][0] = solve_plane(cx, cy, sPlane) * invQ;
array->texcoords[0][count][1] = solve_plane(cx, cy, tPlane) * invQ;
array->texcoords[0][count][2] = solve_plane(cx, cy, uPlane) * invQ;
array->lambda[0][count] = compute_lambda(sPlane, tPlane, vPlane,
cx, cy, invQ,
texWidth, texHeight);
}
#elif defined(DO_MULTITEX)
{
GLuint unit;
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
array->texcoords[unit][count][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
array->texcoords[unit][count][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
array->texcoords[unit][count][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
array->lambda[unit][count] = compute_lambda(sPlane[unit],
tPlane[unit], vPlane[unit], cx, cy, invQ,
texWidth[unit], texHeight[unit]);
}
}
}
#endif
ix++;
count++;
coverage = compute_coveragef(pMin, pMid, pMax, ix, iy);
}
if (ix <= startX)
continue;
span.x = startX;
span.y = iy;
span.end = (GLuint) ix - (GLuint) startX;
ASSERT(span.interpMask == 0);
#if defined(DO_MULTITEX) || defined(DO_TEX)
_mesa_write_texture_span(ctx, &span);
#elif defined(DO_RGBA)
_mesa_write_rgba_span(ctx, &span);
#elif defined(DO_INDEX)
_mesa_write_index_span(ctx, &span);
#endif
}
}
else {
/* scan right to left */
const GLfloat *pMin = vMin->win;
const GLfloat *pMid = vMid->win;
const GLfloat *pMax = vMax->win;
const GLfloat dxdy = majDx / majDy;
const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F;
GLfloat x = pMin[0] - (yMin - iyMin) * dxdy;
GLint iy;
for (iy = iyMin; iy < iyMax; iy++, x += dxdy) {
GLint ix, left, startX = (GLint) (x + xAdj);
GLuint count, n;
GLfloat coverage = 0.0F;
/* make sure we're not past the window edge */
if (startX >= ctx->DrawBuffer->_Xmax) {
startX = ctx->DrawBuffer->_Xmax - 1;
}
 
/* skip fragments with zero coverage */
while (startX >= 0) {
coverage = compute_coveragef(pMin, pMax, pMid, startX, iy);
if (coverage > 0.0F)
break;
startX--;
}
/* enter interior of triangle */
ix = startX;
count = 0;
while (coverage > 0.0F) {
/* (cx,cy) = center of fragment */
const GLfloat cx = ix + 0.5F, cy = iy + 0.5F;
struct span_arrays *array = span.array;
#ifdef DO_INDEX
array->coverage[ix] = (GLfloat) compute_coveragei(pMin, pMax, pMid, ix, iy);
#else
array->coverage[ix] = coverage;
#endif
#ifdef DO_Z
array->z[ix] = (GLdepth) solve_plane(cx, cy, zPlane);
#endif
#ifdef DO_FOG
array->fog[ix] = solve_plane(cx, cy, fogPlane);
#endif
#ifdef DO_RGBA
array->rgba[ix][RCOMP] = solve_plane_chan(cx, cy, rPlane);
array->rgba[ix][GCOMP] = solve_plane_chan(cx, cy, gPlane);
array->rgba[ix][BCOMP] = solve_plane_chan(cx, cy, bPlane);
array->rgba[ix][ACOMP] = solve_plane_chan(cx, cy, aPlane);
#endif
#ifdef DO_INDEX
array->index[ix] = (GLint) solve_plane(cx, cy, iPlane);
#endif
#ifdef DO_SPEC
array->spec[ix][RCOMP] = solve_plane_chan(cx, cy, srPlane);
array->spec[ix][GCOMP] = solve_plane_chan(cx, cy, sgPlane);
array->spec[ix][BCOMP] = solve_plane_chan(cx, cy, sbPlane);
#endif
#ifdef DO_TEX
{
const GLfloat invQ = solve_plane_recip(cx, cy, vPlane);
array->texcoords[0][ix][0] = solve_plane(cx, cy, sPlane) * invQ;
array->texcoords[0][ix][1] = solve_plane(cx, cy, tPlane) * invQ;
array->texcoords[0][ix][2] = solve_plane(cx, cy, uPlane) * invQ;
array->lambda[0][ix] = compute_lambda(sPlane, tPlane, vPlane,
cx, cy, invQ, texWidth, texHeight);
}
#elif defined(DO_MULTITEX)
{
GLuint unit;
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
GLfloat invQ = solve_plane_recip(cx, cy, vPlane[unit]);
array->texcoords[unit][ix][0] = solve_plane(cx, cy, sPlane[unit]) * invQ;
array->texcoords[unit][ix][1] = solve_plane(cx, cy, tPlane[unit]) * invQ;
array->texcoords[unit][ix][2] = solve_plane(cx, cy, uPlane[unit]) * invQ;
array->lambda[unit][ix] = compute_lambda(sPlane[unit],
tPlane[unit],
vPlane[unit],
cx, cy, invQ,
texWidth[unit],
texHeight[unit]);
}
}
}
#endif
ix--;
count++;
coverage = compute_coveragef(pMin, pMax, pMid, ix, iy);
}
if (startX <= ix)
continue;
 
n = (GLuint) startX - (GLuint) ix;
 
left = ix + 1;
 
/* shift all values to the left */
/* XXX this is temporary */
{
struct span_arrays *array = span.array;
GLint j;
for (j = 0; j < (GLint) n; j++) {
#ifdef DO_RGBA
COPY_4V(array->rgba[j], array->rgba[j + left]);
#endif
#ifdef DO_SPEC
COPY_4V(array->spec[j], array->spec[j + left]);
#endif
#ifdef DO_INDEX
array->index[j] = array->index[j + left];
#endif
#ifdef DO_Z
array->z[j] = array->z[j + left];
#endif
#ifdef DO_FOG
array->fog[j] = array->fog[j + left];
#endif
#ifdef DO_TEX
COPY_4V(array->texcoords[0][j], array->texcoords[0][j + left]);
#endif
#if defined(DO_MULTITEX) || defined(DO_TEX)
array->lambda[0][j] = array->lambda[0][j + left];
#endif
array->coverage[j] = array->coverage[j + left];
}
}
#ifdef DO_MULTITEX
/* shift texcoords */
{
struct span_arrays *array = span.array;
GLuint unit;
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
GLint j;
for (j = 0; j < (GLint) n; j++) {
array->texcoords[unit][j][0] = array->texcoords[unit][j + left][0];
array->texcoords[unit][j][1] = array->texcoords[unit][j + left][1];
array->texcoords[unit][j][2] = array->texcoords[unit][j + left][2];
array->lambda[unit][j] = array->lambda[unit][j + left];
}
}
}
}
#endif
 
span.x = left;
span.y = iy;
span.end = n;
ASSERT(span.interpMask == 0);
#if defined(DO_MULTITEX) || defined(DO_TEX)
_mesa_write_texture_span(ctx, &span);
#elif defined(DO_RGBA)
_mesa_write_rgba_span(ctx, &span);
#elif defined(DO_INDEX)
_mesa_write_index_span(ctx, &span);
#endif
}
}
}
 
 
#ifdef DO_Z
#undef DO_Z
#endif
 
#ifdef DO_FOG
#undef DO_FOG
#endif
 
#ifdef DO_RGBA
#undef DO_RGBA
#endif
 
#ifdef DO_INDEX
#undef DO_INDEX
#endif
 
#ifdef DO_SPEC
#undef DO_SPEC
#endif
 
#ifdef DO_TEX
#undef DO_TEX
#endif
 
#ifdef DO_MULTITEX
#undef DO_MULTITEX
#endif
 
#ifdef DO_OCCLUSION_TEST
#undef DO_OCCLUSION_TEST
#endif
/shark/trunk/ports/mesa/src/swrast/s_buffers.c
0,0 → 1,305
/* $Id: s_buffers.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "macros.h"
#include "imports.h"
 
#include "s_accum.h"
#include "s_alphabuf.h"
#include "s_context.h"
#include "s_depth.h"
#include "s_masking.h"
#include "s_stencil.h"
 
 
 
 
/*
* Clear the color buffer when glColorMask or glIndexMask is in effect.
*/
static void
clear_color_buffer_with_masking( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint x = ctx->DrawBuffer->_Xmin;
const GLint y = ctx->DrawBuffer->_Ymin;
const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
 
if (ctx->Visual.rgbMode) {
/* RGBA mode */
GLchan clearColor[4];
GLint i;
CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
for (i = 0; i < height; i++) {
GLchan rgba[MAX_WIDTH][4];
GLint j;
for (j = 0; j < width; j++) {
COPY_CHAN4(rgba[j], clearColor);
}
_mesa_mask_rgba_array( ctx, width, x, y + i, rgba );
(*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
(CONST GLchan (*)[4]) rgba, NULL );
}
}
else {
/* Color index mode */
GLuint span[MAX_WIDTH];
GLubyte mask[MAX_WIDTH];
GLint i, j;
MEMSET( mask, 1, width );
for (i=0;i<height;i++) {
for (j=0;j<width;j++) {
span[j] = ctx->Color.ClearIndex;
}
_mesa_mask_index_array( ctx, width, x, y + i, span );
(*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, mask );
}
}
}
 
 
 
/*
* Clear a color buffer without index/channel masking.
*/
static void
clear_color_buffer(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint x = ctx->DrawBuffer->_Xmin;
const GLint y = ctx->DrawBuffer->_Ymin;
const GLint height = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
 
if (ctx->Visual.rgbMode) {
/* RGBA mode */
GLchan clearColor[4];
GLchan span[MAX_WIDTH][4];
GLint i;
 
CLAMPED_FLOAT_TO_CHAN(clearColor[RCOMP], ctx->Color.ClearColor[0]);
CLAMPED_FLOAT_TO_CHAN(clearColor[GCOMP], ctx->Color.ClearColor[1]);
CLAMPED_FLOAT_TO_CHAN(clearColor[BCOMP], ctx->Color.ClearColor[2]);
CLAMPED_FLOAT_TO_CHAN(clearColor[ACOMP], ctx->Color.ClearColor[3]);
 
ASSERT(*((GLuint *) &ctx->Color.ColorMask) == 0xffffffff);
 
for (i = 0; i < width; i++) {
COPY_CHAN4(span[i], clearColor);
}
for (i = 0; i < height; i++) {
(*swrast->Driver.WriteRGBASpan)( ctx, width, x, y + i,
(CONST GLchan (*)[4]) span, NULL );
}
}
else {
/* Color index mode */
ASSERT((ctx->Color.IndexMask & ((1 << ctx->Visual.indexBits) - 1))
== (GLuint) ((1 << ctx->Visual.indexBits) - 1));
if (ctx->Visual.indexBits == 8) {
/* 8-bit clear */
GLubyte span[MAX_WIDTH];
GLint i;
MEMSET(span, ctx->Color.ClearIndex, width);
for (i = 0; i < height; i++) {
(*swrast->Driver.WriteCI8Span)( ctx, width, x, y + i, span, NULL );
}
}
else {
/* non 8-bit clear */
GLuint span[MAX_WIDTH];
GLint i;
for (i = 0; i < width; i++) {
span[i] = ctx->Color.ClearIndex;
}
for (i = 0; i < height; i++) {
(*swrast->Driver.WriteCI32Span)( ctx, width, x, y + i, span, NULL );
}
}
}
}
 
 
 
/*
* Clear the front/back/left/right color buffers.
* This function is usually only called if we need to clear the
* buffers with masking.
*/
static void
clear_color_buffers(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
GLuint bufferBit;
 
/* loop over four possible dest color buffers */
for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
if (bufferBit & ctx->Color._DrawDestMask) {
(*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
 
if (colorMask != 0xffffffff) {
clear_color_buffer_with_masking(ctx);
}
else {
clear_color_buffer(ctx);
}
}
}
 
/* restore default read/draw buffer */
_swrast_use_draw_buffer(ctx);
}
 
 
 
void
_swrast_Clear( GLcontext *ctx, GLbitfield mask,
GLboolean all,
GLint x, GLint y, GLint width, GLint height )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
#ifdef DEBUG
{
GLbitfield legalBits = DD_FRONT_LEFT_BIT |
DD_FRONT_RIGHT_BIT |
DD_BACK_LEFT_BIT |
DD_BACK_RIGHT_BIT |
DD_DEPTH_BIT |
DD_STENCIL_BIT |
DD_ACCUM_BIT;
assert((mask & (~legalBits)) == 0);
}
#endif
 
RENDER_START(swrast,ctx);
 
/* do software clearing here */
if (mask) {
if (mask & ctx->Color._DrawDestMask) clear_color_buffers(ctx);
if (mask & GL_DEPTH_BUFFER_BIT) _mesa_clear_depth_buffer(ctx);
if (mask & GL_ACCUM_BUFFER_BIT) _mesa_clear_accum_buffer(ctx);
if (mask & GL_STENCIL_BUFFER_BIT) _mesa_clear_stencil_buffer(ctx);
}
 
/* clear software-based alpha buffer(s) */
if ( (mask & GL_COLOR_BUFFER_BIT)
&& ctx->DrawBuffer->UseSoftwareAlphaBuffers
&& ctx->Color.ColorMask[ACOMP]) {
_mesa_clear_alpha_buffers( ctx );
}
 
RENDER_FINISH(swrast,ctx);
}
 
 
void
_swrast_alloc_buffers( GLframebuffer *buffer )
{
/* Reallocate other buffers if needed. */
if (buffer->UseSoftwareDepthBuffer) {
_mesa_alloc_depth_buffer( buffer );
}
if (buffer->UseSoftwareStencilBuffer) {
_mesa_alloc_stencil_buffer( buffer );
}
if (buffer->UseSoftwareAccumBuffer) {
_mesa_alloc_accum_buffer( buffer );
}
if (buffer->UseSoftwareAlphaBuffers) {
_mesa_alloc_alpha_buffers( buffer );
}
}
 
 
/*
* Fallback for ctx->Driver.DrawBuffer()
*/
void
_swrast_DrawBuffer( GLcontext *ctx, GLenum mode )
{
_swrast_use_draw_buffer(ctx);
}
 
 
/*
* Setup things so that we read/write spans from the user-designated
* read buffer (set via glReadPixels). We usually just have to call
* this for glReadPixels, glCopyPixels, etc.
*/
void
_swrast_use_read_buffer( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
/* Do this so the software-emulated alpha plane span functions work! */
swrast->CurrentBuffer = ctx->Pixel._ReadSrcMask;
/* Tell the device driver where to read/write spans */
(*swrast->Driver.SetBuffer)( ctx, ctx->ReadBuffer, swrast->CurrentBuffer );
}
 
 
/*
* Setup things so that we read/write spans from the default draw buffer.
* This is the usual mode that Mesa's software rasterizer operates in.
*/
void
_swrast_use_draw_buffer( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
/* The user can specify rendering to zero, one, two, or four color
* buffers simultaneously with glDrawBuffer()!
* We don't expect the span/point/line/triangle functions to deal with
* that mess so we'll iterate over the multiple buffers as needed.
* But usually we only render to one color buffer at a time.
* We set ctx->Color._DriverDrawBuffer to that buffer and tell the
* device driver to use that buffer.
* Look in s_span.c's multi_write_rgba_span() function to see how
* we loop over multiple color buffers when needed.
*/
 
if (ctx->Color._DrawDestMask & FRONT_LEFT_BIT)
swrast->CurrentBuffer = FRONT_LEFT_BIT;
else if (ctx->Color._DrawDestMask & BACK_LEFT_BIT)
swrast->CurrentBuffer = BACK_LEFT_BIT;
else if (ctx->Color._DrawDestMask & FRONT_RIGHT_BIT)
swrast->CurrentBuffer = FRONT_RIGHT_BIT;
else if (ctx->Color._DrawDestMask & BACK_RIGHT_BIT)
swrast->CurrentBuffer = BACK_RIGHT_BIT;
else
/* glDrawBuffer(GL_NONE) */
swrast->CurrentBuffer = FRONT_LEFT_BIT; /* we always have this buffer */
 
(*swrast->Driver.SetBuffer)( ctx, ctx->DrawBuffer, swrast->CurrentBuffer );
}
/shark/trunk/ports/mesa/src/swrast/s_logic.c
0,0 → 1,498
/* $Id: s_logic.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "context.h"
#include "imports.h"
#include "macros.h"
 
#include "s_alphabuf.h"
#include "s_context.h"
#include "s_logic.h"
#include "s_span.h"
 
 
 
/*
* Apply logic op to array of CI pixels.
*/
static void
index_logicop( GLcontext *ctx, GLuint n, GLuint index[], const GLuint dest[],
const GLubyte mask[] )
{
GLuint i;
switch (ctx->Color.LogicOp) {
case GL_CLEAR:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = 0;
}
}
break;
case GL_SET:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = ~0;
}
}
break;
case GL_COPY:
/* do nothing */
break;
case GL_COPY_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = ~index[i];
}
}
break;
case GL_NOOP:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = dest[i];
}
}
break;
case GL_INVERT:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = ~dest[i];
}
}
break;
case GL_AND:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] &= dest[i];
}
}
break;
case GL_NAND:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = ~(index[i] & dest[i]);
}
}
break;
case GL_OR:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] |= dest[i];
}
}
break;
case GL_NOR:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = ~(index[i] | dest[i]);
}
}
break;
case GL_XOR:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] ^= dest[i];
}
}
break;
case GL_EQUIV:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = ~(index[i] ^ dest[i]);
}
}
break;
case GL_AND_REVERSE:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = index[i] & ~dest[i];
}
}
break;
case GL_AND_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = ~index[i] & dest[i];
}
}
break;
case GL_OR_REVERSE:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = index[i] | ~dest[i];
}
}
break;
case GL_OR_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
index[i] = ~index[i] | dest[i];
}
}
break;
default:
_mesa_problem(ctx, "bad mode in index_logic()");
}
}
 
 
 
/*
* Apply the current logic operator to a span of CI pixels. This is only
* used if the device driver can't do logic ops.
*/
void
_mesa_logicop_ci_span( GLcontext *ctx, const struct sw_span *span,
GLuint index[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint dest[MAX_WIDTH];
 
ASSERT(span->end < MAX_WIDTH);
 
/* Read dest values from frame buffer */
if (span->arrayMask & SPAN_XY) {
(*swrast->Driver.ReadCI32Pixels)( ctx, span->end,
span->array->x, span->array->y,
dest, span->array->mask );
}
else {
(*swrast->Driver.ReadCI32Span)( ctx, span->end, span->x, span->y, dest );
}
 
index_logicop( ctx, span->end, index, dest, span->array->mask );
}
 
 
 
/*
* Apply logic operator to rgba pixels.
* Input: ctx - the context
* n - number of pixels
* mask - pixel mask array
* In/Out: src - incoming pixels which will be modified
* Input: dest - frame buffer values
*
* Note: Since the R, G, B, and A channels are all treated the same we
* process them as 4-byte GLuints instead of four GLubytes.
*/
static void
rgba_logicop_ui( const GLcontext *ctx, GLuint n, const GLubyte mask[],
GLuint src[], const GLuint dest[] )
{
GLuint i;
switch (ctx->Color.LogicOp) {
case GL_CLEAR:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = 0;
}
}
break;
case GL_SET:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~0;
}
}
break;
case GL_COPY:
/* do nothing */
break;
case GL_COPY_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~src[i];
}
}
break;
case GL_NOOP:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = dest[i];
}
}
break;
case GL_INVERT:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~dest[i];
}
}
break;
case GL_AND:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] &= dest[i];
}
}
break;
case GL_NAND:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~(src[i] & dest[i]);
}
}
break;
case GL_OR:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i]|= dest[i];
}
}
break;
case GL_NOR:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~(src[i] | dest[i]);
}
}
break;
case GL_XOR:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] ^= dest[i];
}
}
break;
case GL_EQUIV:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~(src[i] ^ dest[i]);
}
}
break;
case GL_AND_REVERSE:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = src[i] & ~dest[i];
}
}
break;
case GL_AND_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~src[i] & dest[i];
}
}
break;
case GL_OR_REVERSE:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = src[i] | ~dest[i];
}
}
break;
case GL_OR_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~src[i] | dest[i];
}
}
break;
default:
/* should never happen */
_mesa_problem(ctx, "Bad function in rgba_logicop");
}
}
 
 
/*
* As above, but operate on GLchan values
* Note: need to pass n = numPixels * 4.
*/
static void
rgba_logicop_chan( const GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan srcPtr[], const GLchan destPtr[] )
{
#if CHAN_TYPE == GL_FLOAT
GLuint *src = (GLuint *) srcPtr;
const GLuint *dest = (const GLuint *) destPtr;
GLuint i;
ASSERT(sizeof(GLfloat) == sizeof(GLuint));
#else
GLchan *src = srcPtr;
const GLchan *dest = destPtr;
GLuint i;
#endif
 
switch (ctx->Color.LogicOp) {
case GL_CLEAR:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = 0;
}
}
break;
case GL_SET:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~0;
}
}
break;
case GL_COPY:
/* do nothing */
break;
case GL_COPY_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~src[i];
}
}
break;
case GL_NOOP:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = dest[i];
}
}
break;
case GL_INVERT:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~dest[i];
}
}
break;
case GL_AND:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] &= dest[i];
}
}
break;
case GL_NAND:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~(src[i] & dest[i]);
}
}
break;
case GL_OR:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i]|= dest[i];
}
}
break;
case GL_NOR:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~(src[i] | dest[i]);
}
}
break;
case GL_XOR:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] ^= dest[i];
}
}
break;
case GL_EQUIV:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~(src[i] ^ dest[i]);
}
}
break;
case GL_AND_REVERSE:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = src[i] & ~dest[i];
}
}
break;
case GL_AND_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~src[i] & dest[i];
}
}
break;
case GL_OR_REVERSE:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = src[i] | ~dest[i];
}
}
break;
case GL_OR_INVERTED:
for (i=0;i<n;i++) {
if (mask[i]) {
src[i] = ~src[i] | dest[i];
}
}
break;
default:
/* should never happen */
_mesa_problem(ctx, "Bad function in rgba_logicop");
}
}
 
 
 
/*
* Apply the current logic operator to a span of RGBA pixels.
* We can handle horizontal runs of pixels (spans) or arrays of x/y
* pixel coordinates.
*/
void
_mesa_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span,
GLchan rgba[][4] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan dest[MAX_WIDTH][4];
 
ASSERT(span->end < MAX_WIDTH);
ASSERT(span->arrayMask & SPAN_RGBA);
 
if (span->arrayMask & SPAN_XY) {
(*swrast->Driver.ReadRGBAPixels)(ctx, span->end,
span->array->x, span->array->y,
dest, span->array->mask);
if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
_mesa_read_alpha_pixels(ctx, span->end,
span->array->x, span->array->y,
dest, span->array->mask);
}
}
else {
_mesa_read_rgba_span(ctx, ctx->DrawBuffer, span->end,
span->x, span->y, dest);
}
 
if (sizeof(GLchan) * 4 == sizeof(GLuint)) {
rgba_logicop_ui(ctx, span->end, span->array->mask,
(GLuint *) rgba, (const GLuint *) dest);
}
else {
rgba_logicop_chan(ctx, 4 * span->end, span->array->mask,
(GLchan *) rgba, (const GLchan *) dest);
}
}
/shark/trunk/ports/mesa/src/swrast/s_accum.h
0,0 → 1,44
/* $Id: s_accum.h,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 4.0.2
*
* 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.
*/
 
 
#ifndef S_ACCUM_H
#define S_ACCUM_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void
_mesa_alloc_accum_buffer( GLframebuffer *buffer );
 
 
extern void
_mesa_clear_accum_buffer( GLcontext *ctx );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_aaline.h
0,0 → 1,40
/* $Id: s_aaline.h,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef S_AALINE_H
#define S_AALINE_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void
_swrast_choose_aa_line_function(GLcontext *ctx);
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_stencil.c
0,0 → 1,1327
/* $Id: s_stencil.c,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "imports.h"
 
#include "s_context.h"
#include "s_depth.h"
#include "s_stencil.h"
 
 
 
/* Stencil Logic:
 
IF stencil test fails THEN
Apply fail-op to stencil value
Don't write the pixel (RGBA,Z)
ELSE
IF doing depth test && depth test fails THEN
Apply zfail-op to stencil value
Write RGBA and Z to appropriate buffers
ELSE
Apply zpass-op to stencil value
ENDIF
 
*/
 
 
/*
* Return the address of a stencil buffer value given the window coords:
*/
#define STENCIL_ADDRESS(X,Y) \
(ctx->DrawBuffer->Stencil + ctx->DrawBuffer->Width * (Y) + (X))
 
 
 
/**
* Apply the given stencil operator to the array of stencil values.
* Don't touch stencil[i] if mask[i] is zero.
* Input: n - size of stencil array
* oper - the stencil buffer operator
* face - 0 or 1 for front or back face operation
* stencil - array of stencil values
* mask - array [n] of flag: 1=apply operator, 0=don't apply operator
* Output: stencil - modified values
*/
static void
apply_stencil_op( const GLcontext *ctx, GLenum oper, GLuint face,
GLuint n, GLstencil stencil[], const GLubyte mask[] )
{
const GLstencil ref = ctx->Stencil.Ref[face];
const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
const GLstencil invmask = (GLstencil) (~wrtmask);
GLuint i;
 
switch (oper) {
case GL_KEEP:
/* do nothing */
break;
case GL_ZERO:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
stencil[i] = 0;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
stencil[i] = (GLstencil) (stencil[i] & invmask);
}
}
}
break;
case GL_REPLACE:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
stencil[i] = ref;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil s = stencil[i];
stencil[i] = (GLstencil) ((invmask & s ) | (wrtmask & ref));
}
}
}
break;
case GL_INCR:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil s = stencil[i];
if (s < STENCIL_MAX) {
stencil[i] = (GLstencil) (s+1);
}
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
/* VERIFY logic of adding 1 to a write-masked value */
GLstencil s = stencil[i];
if (s < STENCIL_MAX) {
stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s+1)));
}
}
}
}
break;
case GL_DECR:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil s = stencil[i];
if (s>0) {
stencil[i] = (GLstencil) (s-1);
}
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
/* VERIFY logic of subtracting 1 to a write-masked value */
GLstencil s = stencil[i];
if (s>0) {
stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1)));
}
}
}
}
break;
case GL_INCR_WRAP_EXT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
stencil[i]++;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil s = stencil[i];
stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s+1)));
}
}
}
break;
case GL_DECR_WRAP_EXT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
stencil[i]--;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil s = stencil[i];
stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & (s-1)));
}
}
}
break;
case GL_INVERT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil s = stencil[i];
stencil[i] = (GLstencil) ~s;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil s = stencil[i];
stencil[i] = (GLstencil) ((invmask & s) | (wrtmask & ~s));
}
}
}
break;
default:
_mesa_problem(ctx, "Bad stencil op in apply_stencil_op");
}
}
 
 
 
 
/**
* Apply stencil test to an array of stencil values (before depth buffering).
* Input: face - 0 or 1 for front or back-face polygons
* n - number of pixels in the array
* stencil - array of [n] stencil values
* mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel
* Output: mask - pixels which fail the stencil test will have their
* mask flag set to 0.
* stencil - updated stencil values (where the test passed)
* Return: GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
*/
static GLboolean
do_stencil_test( GLcontext *ctx, GLuint face, GLuint n, GLstencil stencil[],
GLubyte mask[] )
{
GLubyte fail[MAX_WIDTH];
GLboolean allfail = GL_FALSE;
GLuint i;
GLstencil r, s;
const GLuint valueMask = ctx->Stencil.ValueMask[face];
 
ASSERT(n <= MAX_WIDTH);
 
/*
* Perform stencil test. The results of this operation are stored
* in the fail[] array:
* IF fail[i] is non-zero THEN
* the stencil fail operator is to be applied
* ELSE
* the stencil fail operator is not to be applied
* ENDIF
*/
switch (ctx->Stencil.Function[face]) {
case GL_NEVER:
/* never pass; always fail */
for (i=0;i<n;i++) {
if (mask[i]) {
mask[i] = 0;
fail[i] = 1;
}
else {
fail[i] = 0;
}
}
allfail = GL_TRUE;
break;
case GL_LESS:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
if (r < s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_LEQUAL:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
if (r <= s) {
/* pass */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_GREATER:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
if (r > s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_GEQUAL:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
if (r >= s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_EQUAL:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
if (r == s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_NOTEQUAL:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
s = (GLstencil) (stencil[i] & valueMask);
if (r != s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_ALWAYS:
/* always pass */
for (i=0;i<n;i++) {
fail[i] = 0;
}
break;
default:
_mesa_problem(ctx, "Bad stencil func in gl_stencil_span");
return 0;
}
 
if (ctx->Stencil.FailFunc[face] != GL_KEEP) {
apply_stencil_op( ctx, ctx->Stencil.FailFunc[face], face, n, stencil, fail );
}
 
return !allfail;
}
 
 
 
/**
* Apply stencil and depth testing to the span of pixels.
* Both software and hardware stencil buffers are acceptable.
* Input: n - number of pixels in the span
* x, y - location of leftmost pixel in span
* z - array [n] of z values
* mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
* Output: mask - array [n] of flags (1=stencil and depth test passed)
* Return: GL_FALSE - all fragments failed the testing
* GL_TRUE - one or more fragments passed the testing
*
*/
static GLboolean
stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span, GLuint face)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLstencil stencilRow[MAX_WIDTH];
GLstencil *stencil;
const GLuint n = span->end;
const GLint x = span->x;
const GLint y = span->y;
GLubyte *mask = span->array->mask;
 
ASSERT((span->arrayMask & SPAN_XY) == 0);
ASSERT(ctx->Stencil.Enabled);
ASSERT(n <= MAX_WIDTH);
#ifdef DEBUG
if (ctx->Depth.Test) {
ASSERT(span->arrayMask & SPAN_Z);
}
#endif
/* Get initial stencil values */
if (swrast->Driver.WriteStencilSpan) {
/* Get stencil values from the hardware stencil buffer */
ASSERT(swrast->Driver.ReadStencilSpan);
(*swrast->Driver.ReadStencilSpan)(ctx, n, x, y, stencilRow);
stencil = stencilRow;
}
else {
/* Get pointer into software stencil buffer */
stencil = STENCIL_ADDRESS(x, y);
}
/*
* Apply the stencil test to the fragments.
* failMask[i] is 1 if the stencil test failed.
*/
if (do_stencil_test( ctx, face, n, stencil, mask ) == GL_FALSE) {
/* all fragments failed the stencil test, we're done. */
span->writeAll = GL_FALSE;
return GL_FALSE;
}
 
/*
* Some fragments passed the stencil test, apply depth test to them
* and apply Zpass and Zfail stencil ops.
*/
if (ctx->Depth.Test == GL_FALSE) {
/*
* No depth buffer, just apply zpass stencil function to active pixels.
*/
apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face, n, stencil, mask );
}
else {
/*
* Perform depth buffering, then apply zpass or zfail stencil function.
*/
GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
GLuint i;
 
/* save the current mask bits */
MEMCPY(oldmask, mask, n * sizeof(GLubyte));
 
/* apply the depth test */
_mesa_depth_test_span(ctx, span);
 
/* Set the stencil pass/fail flags according to result of depth testing.
* if oldmask[i] == 0 then
* Don't touch the stencil value
* else if oldmask[i] and newmask[i] then
* Depth test passed
* else
* assert(oldmask[i] && !newmask[i])
* Depth test failed
* endif
*/
for (i=0;i<n;i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);
passmask[i] = oldmask[i] & mask[i];
failmask[i] = oldmask[i] & (mask[i] ^ 1);
}
 
/* apply the pass and fail operations */
if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
apply_stencil_op( ctx, ctx->Stencil.ZFailFunc[face], face,
n, stencil, failmask );
}
if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
apply_stencil_op( ctx, ctx->Stencil.ZPassFunc[face], face,
n, stencil, passmask );
}
}
 
/*
* Write updated stencil values back into hardware stencil buffer.
*/
if (swrast->Driver.WriteStencilSpan) {
ASSERT(stencil == stencilRow);
(swrast->Driver.WriteStencilSpan)(ctx, n, x, y, stencil, mask );
}
span->writeAll = GL_FALSE;
return GL_TRUE; /* one or more fragments passed both tests */
}
 
 
 
 
/**
* Apply the given stencil operator for each pixel in the array whose
* mask flag is set.
* \note This is for software stencil buffers only.
* Input: n - number of pixels in the span
* x, y - array of [n] pixels
* operator - the stencil buffer operator
* mask - array [n] of flag: 1=apply operator, 0=don't apply operator
*/
static void
apply_stencil_op_to_pixels( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLenum oper, GLuint face, const GLubyte mask[] )
{
const GLstencil ref = ctx->Stencil.Ref[face];
const GLstencil wrtmask = ctx->Stencil.WriteMask[face];
const GLstencil invmask = (GLstencil) (~wrtmask);
GLuint i;
 
ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan); /* software stencil buffer only! */
 
switch (oper) {
case GL_KEEP:
/* do nothing */
break;
case GL_ZERO:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = 0;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) (invmask & *sptr);
}
}
}
break;
case GL_REPLACE:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = ref;
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) ((invmask & *sptr ) | (wrtmask & ref));
}
}
}
break;
case GL_INCR:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr < STENCIL_MAX) {
*sptr = (GLstencil) (*sptr + 1);
}
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr < STENCIL_MAX) {
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
}
}
}
}
break;
case GL_DECR:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr>0) {
*sptr = (GLstencil) (*sptr - 1);
}
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
if (*sptr>0) {
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
}
}
}
}
break;
case GL_INCR_WRAP_EXT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) (*sptr + 1);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr+1)));
}
}
}
break;
case GL_DECR_WRAP_EXT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) (*sptr - 1);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & (*sptr-1)));
}
}
}
break;
case GL_INVERT:
if (invmask==0) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) (~*sptr);
}
}
}
else {
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS( x[i], y[i] );
*sptr = (GLstencil) ((invmask & *sptr) | (wrtmask & ~*sptr));
}
}
}
break;
default:
_mesa_problem(ctx, "Bad stencilop in apply_stencil_op_to_pixels");
}
}
 
 
 
/**
* Apply stencil test to an array of pixels before depth buffering.
*
* \note Used for software stencil buffer only.
* Input: n - number of pixels in the span
* x, y - array of [n] pixels to stencil
* mask - array [n] of flag: 0=skip the pixel, 1=stencil the pixel
* Output: mask - pixels which fail the stencil test will have their
* mask flag set to 0.
* \return GL_FALSE = all pixels failed, GL_TRUE = zero or more pixels passed.
*/
static GLboolean
stencil_test_pixels( GLcontext *ctx, GLuint face, GLuint n,
const GLint x[], const GLint y[], GLubyte mask[] )
{
GLubyte fail[MAX_WIDTH];
GLstencil r, s;
GLuint i;
GLboolean allfail = GL_FALSE;
const GLuint valueMask = ctx->Stencil.ValueMask[face];
 
/* software stencil buffer only! */
ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer);
ASSERT(!SWRAST_CONTEXT(ctx)->Driver.ReadStencilSpan);
ASSERT(!SWRAST_CONTEXT(ctx)->Driver.WriteStencilSpan);
 
/*
* Perform stencil test. The results of this operation are stored
* in the fail[] array:
* IF fail[i] is non-zero THEN
* the stencil fail operator is to be applied
* ELSE
* the stencil fail operator is not to be applied
* ENDIF
*/
 
switch (ctx->Stencil.Function[face]) {
case GL_NEVER:
/* always fail */
for (i=0;i<n;i++) {
if (mask[i]) {
mask[i] = 0;
fail[i] = 1;
}
else {
fail[i] = 0;
}
}
allfail = GL_TRUE;
break;
case GL_LESS:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
s = (GLstencil) (*sptr & valueMask);
if (r < s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_LEQUAL:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
s = (GLstencil) (*sptr & valueMask);
if (r <= s) {
/* pass */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_GREATER:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
s = (GLstencil) (*sptr & valueMask);
if (r > s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_GEQUAL:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
s = (GLstencil) (*sptr & valueMask);
if (r >= s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_EQUAL:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
s = (GLstencil) (*sptr & valueMask);
if (r == s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_NOTEQUAL:
r = (GLstencil) (ctx->Stencil.Ref[face] & valueMask);
for (i=0;i<n;i++) {
if (mask[i]) {
GLstencil *sptr = STENCIL_ADDRESS(x[i],y[i]);
s = (GLstencil) (*sptr & valueMask);
if (r != s) {
/* passed */
fail[i] = 0;
}
else {
fail[i] = 1;
mask[i] = 0;
}
}
else {
fail[i] = 0;
}
}
break;
case GL_ALWAYS:
/* always pass */
for (i=0;i<n;i++) {
fail[i] = 0;
}
break;
default:
_mesa_problem(ctx, "Bad stencil func in gl_stencil_pixels");
return 0;
}
 
if (ctx->Stencil.FailFunc[face] != GL_KEEP) {
apply_stencil_op_to_pixels( ctx, n, x, y, ctx->Stencil.FailFunc[face],
face, fail );
}
 
return !allfail;
}
 
 
 
 
/**
* Apply stencil and depth testing to an array of pixels.
* This is used both for software and hardware stencil buffers.
*
* The comments in this function are a bit sparse but the code is
* almost identical to stencil_and_ztest_span(), which is well
* commented.
*
* Input: n - number of pixels in the array
* x, y - array of [n] pixel positions
* z - array [n] of z values
* mask - array [n] of flags (1=test this pixel, 0=skip the pixel)
* Output: mask - array [n] of flags (1=stencil and depth test passed)
* Return: GL_FALSE - all fragments failed the testing
* GL_TRUE - one or more fragments passed the testing
*/
static GLboolean
stencil_and_ztest_pixels( GLcontext *ctx, struct sw_span *span, GLuint face )
{
const GLuint n = span->end;
const GLint *x = span->array->x;
const GLint *y = span->array->y;
GLubyte *mask = span->array->mask;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
ASSERT(span->arrayMask & SPAN_XY);
ASSERT(ctx->Stencil.Enabled);
ASSERT(n <= MAX_WIDTH);
 
if (swrast->Driver.WriteStencilPixels) {
/*** Hardware stencil buffer ***/
GLstencil stencil[MAX_WIDTH];
GLubyte origMask[MAX_WIDTH];
 
ASSERT(!ctx->DrawBuffer->UseSoftwareStencilBuffer);
ASSERT(swrast->Driver.ReadStencilPixels);
(*swrast->Driver.ReadStencilPixels)(ctx, n, x, y, stencil);
 
MEMCPY(origMask, mask, n * sizeof(GLubyte));
 
(void) do_stencil_test(ctx, face, n, stencil, mask);
 
if (ctx->Depth.Test == GL_FALSE) {
apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
n, stencil, mask);
}
else {
_mesa_depth_test_span(ctx, span);
 
if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
GLubyte failmask[MAX_WIDTH];
GLuint i;
for (i = 0; i < n; i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);
failmask[i] = origMask[i] & (mask[i] ^ 1);
}
apply_stencil_op(ctx, ctx->Stencil.ZFailFunc[face], face,
n, stencil, failmask);
}
if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
GLubyte passmask[MAX_WIDTH];
GLuint i;
for (i = 0; i < n; i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);
passmask[i] = origMask[i] & mask[i];
}
apply_stencil_op(ctx, ctx->Stencil.ZPassFunc[face], face,
n, stencil, passmask);
}
}
 
/* Write updated stencil values into hardware stencil buffer */
(swrast->Driver.WriteStencilPixels)(ctx, n, x, y, stencil, origMask);
 
return GL_TRUE;
}
else {
/*** Software stencil buffer ***/
 
ASSERT(ctx->DrawBuffer->UseSoftwareStencilBuffer);
 
if (stencil_test_pixels(ctx, face, n, x, y, mask) == GL_FALSE) {
/* all fragments failed the stencil test, we're done. */
return GL_FALSE;
}
 
if (ctx->Depth.Test==GL_FALSE) {
apply_stencil_op_to_pixels(ctx, n, x, y,
ctx->Stencil.ZPassFunc[face], face, mask);
}
else {
GLubyte passmask[MAX_WIDTH], failmask[MAX_WIDTH], oldmask[MAX_WIDTH];
GLuint i;
 
MEMCPY(oldmask, mask, n * sizeof(GLubyte));
 
_mesa_depth_test_span(ctx, span);
 
for (i=0;i<n;i++) {
ASSERT(mask[i] == 0 || mask[i] == 1);
passmask[i] = oldmask[i] & mask[i];
failmask[i] = oldmask[i] & (mask[i] ^ 1);
}
 
if (ctx->Stencil.ZFailFunc[face] != GL_KEEP) {
apply_stencil_op_to_pixels(ctx, n, x, y,
ctx->Stencil.ZFailFunc[face],
face, failmask);
}
if (ctx->Stencil.ZPassFunc[face] != GL_KEEP) {
apply_stencil_op_to_pixels(ctx, n, x, y,
ctx->Stencil.ZPassFunc[face],
face, passmask);
}
}
 
return GL_TRUE; /* one or more fragments passed both tests */
}
}
 
 
/**
* /return GL_TRUE = one or more fragments passed,
* GL_FALSE = all fragments failed.
*/
GLboolean
_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span)
{
/* span->facing can only be non-zero if using two-sided stencil */
ASSERT(ctx->Stencil.TestTwoSide || span->facing == 0);
if (span->arrayMask & SPAN_XY)
return stencil_and_ztest_pixels(ctx, span, span->facing);
else
return stencil_and_ztest_span(ctx, span, span->facing);
}
 
 
/**
* Return a span of stencil values from the stencil buffer.
* Used for glRead/CopyPixels
* Input: n - how many pixels
* x,y - location of first pixel
* Output: stencil - the array of stencil values
*/
void
_mesa_read_stencil_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLstencil stencil[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint bufWidth = (GLint) ctx->DrawBuffer->Width;
const GLint bufHeight = (GLint) ctx->DrawBuffer->Height;
 
if (y < 0 || y >= bufHeight || x + n <= 0 || x >= bufWidth) {
/* span is completely outside framebuffer */
return; /* undefined values OK */
}
 
if (x < 0) {
GLint dx = -x;
x = 0;
n -= dx;
stencil += dx;
}
if (x + n > bufWidth) {
GLint dx = x + n - bufWidth;
n -= dx;
}
if (n <= 0) {
return;
}
 
 
ASSERT(n >= 0);
if (swrast->Driver.ReadStencilSpan) {
(*swrast->Driver.ReadStencilSpan)( ctx, (GLuint) n, x, y, stencil );
}
else if (ctx->DrawBuffer->Stencil) {
const GLstencil *s = STENCIL_ADDRESS( x, y );
#if STENCIL_BITS == 8
MEMCPY( stencil, s, n * sizeof(GLstencil) );
#else
GLuint i;
for (i=0;i<n;i++)
stencil[i] = s[i];
#endif
}
}
 
 
 
/**
* Write a span of stencil values to the stencil buffer.
* Used for glDraw/CopyPixels
* Input: n - how many pixels
* x, y - location of first pixel
* stencil - the array of stencil values
*/
void
_mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
const GLstencil stencil[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLstencil *ssrc = stencil;
const GLint bufWidth = (GLint) ctx->DrawBuffer->Width;
const GLint bufHeight = (GLint) ctx->DrawBuffer->Height;
 
if (y < 0 || y >= bufHeight || x + n <= 0 || x >= bufWidth) {
/* span is completely outside framebuffer */
return; /* undefined values OK */
}
 
if (x < 0) {
GLint dx = -x;
x = 0;
n -= dx;
ssrc += dx;
}
if (x + n > bufWidth) {
GLint dx = x + n - bufWidth;
n -= dx;
}
if (n <= 0) {
return;
}
 
if (swrast->Driver.WriteStencilSpan) {
(*swrast->Driver.WriteStencilSpan)( ctx, n, x, y, ssrc, NULL );
}
else if (ctx->DrawBuffer->Stencil) {
GLstencil *s = STENCIL_ADDRESS( x, y );
#if STENCIL_BITS == 8
MEMCPY( s, ssrc, n * sizeof(GLstencil) );
#else
GLuint i;
for (i=0;i<n;i++)
s[i] = ssrc[i];
#endif
}
}
 
 
 
/**
* Allocate a new stencil buffer. If there's an old one it will be
* deallocated first. The new stencil buffer will be uninitialized.
*/
void
_mesa_alloc_stencil_buffer( GLframebuffer *buffer )
{
/* deallocate current stencil buffer if present */
if (buffer->Stencil) {
MESA_PBUFFER_FREE(buffer->Stencil);
buffer->Stencil = NULL;
}
 
/* allocate new stencil buffer */
buffer->Stencil = (GLstencil *)
MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height * sizeof(GLstencil));
if (!buffer->Stencil) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY, "_mesa_alloc_stencil_buffer" );
}
}
 
 
 
/**
* Clear the software (malloc'd) stencil buffer.
*/
static void
clear_software_stencil_buffer( GLcontext *ctx )
{
if (ctx->Visual.stencilBits==0 || !ctx->DrawBuffer->Stencil) {
/* no stencil buffer */
return;
}
 
if (ctx->Scissor.Enabled) {
/* clear scissor region only */
const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) {
/* must apply mask to the clear */
GLint y;
for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) {
const GLstencil mask = ctx->Stencil.WriteMask[0];
const GLstencil invMask = ~mask;
const GLstencil clearVal = (ctx->Stencil.Clear & mask);
GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y );
GLint i;
for (i = 0; i < width; i++) {
stencil[i] = (stencil[i] & invMask) | clearVal;
}
}
}
else {
/* no masking */
GLint y;
for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) {
GLstencil *stencil = STENCIL_ADDRESS( ctx->DrawBuffer->_Xmin, y );
#if STENCIL_BITS==8
MEMSET( stencil, ctx->Stencil.Clear, width * sizeof(GLstencil) );
#else
GLint i;
for (i = 0; i < width; i++)
stencil[x] = ctx->Stencil.Clear;
#endif
}
}
}
else {
/* clear whole stencil buffer */
if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) {
/* must apply mask to the clear */
const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
GLstencil *stencil = ctx->DrawBuffer->Stencil;
const GLstencil mask = ctx->Stencil.WriteMask[0];
const GLstencil invMask = ~mask;
const GLstencil clearVal = (ctx->Stencil.Clear & mask);
GLuint i;
for (i = 0; i < n; i++) {
stencil[i] = (stencil[i] & invMask) | clearVal;
}
}
else {
/* clear whole buffer without masking */
const GLuint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
GLstencil *stencil = ctx->DrawBuffer->Stencil;
 
#if STENCIL_BITS==8
MEMSET(stencil, ctx->Stencil.Clear, n * sizeof(GLstencil) );
#else
GLuint i;
for (i = 0; i < n; i++) {
stencil[i] = ctx->Stencil.Clear;
}
#endif
}
}
}
 
 
 
/**
* Clear the hardware (in graphics card) stencil buffer.
* This is done with the Driver.WriteStencilSpan() and Driver.ReadStencilSpan()
* functions.
* Actually, if there is a hardware stencil buffer it really should have
* been cleared in Driver.Clear()! However, if the hardware does not
* support scissored clears or masked clears (i.e. glStencilMask) then
* we have to use the span-based functions.
*/
static void
clear_hardware_stencil_buffer( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
ASSERT(swrast->Driver.WriteStencilSpan);
ASSERT(swrast->Driver.ReadStencilSpan);
 
if (ctx->Scissor.Enabled) {
/* clear scissor region only */
const GLint x = ctx->DrawBuffer->_Xmin;
const GLint width = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) {
/* must apply mask to the clear */
GLint y;
for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) {
const GLstencil mask = ctx->Stencil.WriteMask[0];
const GLstencil invMask = ~mask;
const GLstencil clearVal = (ctx->Stencil.Clear & mask);
GLstencil stencil[MAX_WIDTH];
GLint i;
(*swrast->Driver.ReadStencilSpan)(ctx, width, x, y, stencil);
for (i = 0; i < width; i++) {
stencil[i] = (stencil[i] & invMask) | clearVal;
}
(*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL);
}
}
else {
/* no masking */
GLstencil stencil[MAX_WIDTH];
GLint y, i;
for (i = 0; i < width; i++) {
stencil[i] = ctx->Stencil.Clear;
}
for (y = ctx->DrawBuffer->_Ymin; y < ctx->DrawBuffer->_Ymax; y++) {
(*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL);
}
}
}
else {
/* clear whole stencil buffer */
if (ctx->Stencil.WriteMask[0] != STENCIL_MAX) {
/* must apply mask to the clear */
const GLstencil mask = ctx->Stencil.WriteMask[0];
const GLstencil invMask = ~mask;
const GLstencil clearVal = (ctx->Stencil.Clear & mask);
const GLint width = ctx->DrawBuffer->Width;
const GLint height = ctx->DrawBuffer->Height;
const GLint x = ctx->DrawBuffer->_Xmin;
GLint y;
for (y = 0; y < height; y++) {
GLstencil stencil[MAX_WIDTH];
GLint i;
(*swrast->Driver.ReadStencilSpan)(ctx, width, x, y, stencil);
for (i = 0; i < width; i++) {
stencil[i] = (stencil[i] & invMask) | clearVal;
}
(*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL);
}
}
else {
/* clear whole buffer without masking */
const GLint width = ctx->DrawBuffer->Width;
const GLint height = ctx->DrawBuffer->Height;
const GLint x = ctx->DrawBuffer->_Xmin;
GLstencil stencil[MAX_WIDTH];
GLint y, i;
for (i = 0; i < width; i++) {
stencil[i] = ctx->Stencil.Clear;
}
for (y = 0; y < height; y++) {
(*swrast->Driver.WriteStencilSpan)(ctx, width, x, y, stencil, NULL);
}
}
}
}
 
 
 
/**
* Clear the stencil buffer (hardware or software).
*/
void
_mesa_clear_stencil_buffer( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
if (swrast->Driver.WriteStencilSpan) {
ASSERT(swrast->Driver.ReadStencilSpan);
clear_hardware_stencil_buffer(ctx);
}
else {
clear_software_stencil_buffer(ctx);
}
}
/shark/trunk/ports/mesa/src/swrast/s_pixeltex.c
0,0 → 1,118
/* $Id: s_pixeltex.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
/*
* This file implements both the GL_SGIX_pixel_texture and
* GL_SIGS_pixel_texture extensions. Luckily, they pretty much
* overlap in functionality so we use the same state variables
* and execution code for both.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "imports.h"
 
#include "s_context.h"
#include "s_pixeltex.h"
#include "s_texture.h"
 
 
/*
* Convert RGBA values into strq texture coordinates.
*/
static void
pixeltexgen(GLcontext *ctx, GLuint n, const GLchan rgba[][4],
GLfloat texcoord[][4])
{
if (ctx->Pixel.FragmentRgbSource == GL_CURRENT_RASTER_COLOR) {
GLuint i;
for (i = 0; i < n; i++) {
texcoord[i][0] = ctx->Current.RasterColor[RCOMP];
texcoord[i][1] = ctx->Current.RasterColor[GCOMP];
texcoord[i][2] = ctx->Current.RasterColor[BCOMP];
}
}
else {
GLuint i;
ASSERT(ctx->Pixel.FragmentRgbSource == GL_PIXEL_GROUP_COLOR_SGIS);
for (i = 0; i < n; i++) {
texcoord[i][0] = CHAN_TO_FLOAT(rgba[i][RCOMP]);
texcoord[i][1] = CHAN_TO_FLOAT(rgba[i][GCOMP]);
texcoord[i][2] = CHAN_TO_FLOAT(rgba[i][BCOMP]);
}
}
 
if (ctx->Pixel.FragmentAlphaSource == GL_CURRENT_RASTER_COLOR) {
GLuint i;
for (i = 0; i < n; i++) {
texcoord[i][3] = ctx->Current.RasterColor[ACOMP];
}
}
else {
GLuint i;
ASSERT(ctx->Pixel.FragmentAlphaSource == GL_PIXEL_GROUP_COLOR_SGIS);
for (i = 0; i < n; i++) {
texcoord[i][3] = CHAN_TO_FLOAT(rgba[i][ACOMP]);
}
}
}
 
 
 
/*
* Used by glDraw/CopyPixels: the incoming image colors are treated
* as texture coordinates. Use those coords to texture the image.
* This is for GL_SGIS_pixel_texture / GL_SGIX_pixel_texture.
*/
void
_swrast_pixel_texture(GLcontext *ctx, struct sw_span *span)
{
GLuint unit;
 
ASSERT(!(span->arrayMask & SPAN_TEXTURE));
span->arrayMask |= SPAN_TEXTURE;
 
/* convert colors into texture coordinates */
pixeltexgen( ctx, span->end,
(const GLchan (*)[4]) span->array->rgba,
span->array->texcoords[0] );
 
/* copy the new texture units for all enabled units */
for (unit = 1; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
MEMCPY( span->array->texcoords[unit], span->array->texcoords[0],
span->end * 4 * sizeof(GLfloat) );
}
}
 
/* apply texture mapping */
_swrast_texture_span( ctx, span );
 
/* this is a work-around to be fixed by initializing again span */
span->arrayMask &= ~SPAN_TEXTURE;
}
/shark/trunk/ports/mesa/src/swrast/s_logic.h
0,0 → 1,46
/* $Id: s_logic.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_LOGIC_H
#define S_LOGIC_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void
_mesa_logicop_ci_span( GLcontext *ctx, const struct sw_span *span,
GLuint index[] );
 
 
extern void
_mesa_logicop_rgba_span( GLcontext *ctx, const struct sw_span *span,
GLchan rgba[][4] );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_stencil.h
0,0 → 1,60
/* $Id: s_stencil.h,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_STENCIL_H
#define S_STENCIL_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
 
extern GLboolean
_mesa_stencil_and_ztest_span(GLcontext *ctx, struct sw_span *span);
 
 
 
extern void
_mesa_read_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
GLstencil stencil[] );
 
 
extern void
_mesa_write_stencil_span( GLcontext *ctx, GLint n, GLint x, GLint y,
const GLstencil stencil[] );
 
 
extern void
_mesa_alloc_stencil_buffer( GLframebuffer *buffer );
 
 
extern void
_mesa_clear_stencil_buffer( GLcontext *ctx );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_aatriangle.c
0,0 → 1,480
/* $Id: s_aatriangle.c,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*/
 
 
/*
* Antialiased Triangle rasterizers
*/
 
 
#include "glheader.h"
#include "macros.h"
#include "imports.h"
#include "mmath.h"
#include "s_aatriangle.h"
#include "s_context.h"
#include "s_span.h"
 
 
/*
* Compute coefficients of a plane using the X,Y coords of the v0, v1, v2
* vertices and the given Z values.
* A point (x,y,z) lies on plane iff a*x+b*y+c*z+d = 0.
*/
static INLINE void
compute_plane(const GLfloat v0[], const GLfloat v1[], const GLfloat v2[],
GLfloat z0, GLfloat z1, GLfloat z2, GLfloat plane[4])
{
const GLfloat px = v1[0] - v0[0];
const GLfloat py = v1[1] - v0[1];
const GLfloat pz = z1 - z0;
 
const GLfloat qx = v2[0] - v0[0];
const GLfloat qy = v2[1] - v0[1];
const GLfloat qz = z2 - z0;
 
/* Crossproduct "(a,b,c):= dv1 x dv2" is orthogonal to plane. */
const GLfloat a = py * qz - pz * qy;
const GLfloat b = pz * qx - px * qz;
const GLfloat c = px * qy - py * qx;
/* Point on the plane = "r*(a,b,c) + w", with fixed "r" depending
on the distance of plane from origin and arbitrary "w" parallel
to the plane. */
/* The scalar product "(r*(a,b,c)+w)*(a,b,c)" is "r*(a^2+b^2+c^2)",
which is equal to "-d" below. */
const GLfloat d = -(a * v0[0] + b * v0[1] + c * z0);
 
plane[0] = a;
plane[1] = b;
plane[2] = c;
plane[3] = d;
}
 
 
/*
* Compute coefficients of a plane with a constant Z value.
*/
static INLINE void
constant_plane(GLfloat value, GLfloat plane[4])
{
plane[0] = 0.0;
plane[1] = 0.0;
plane[2] = -1.0;
plane[3] = value;
}
 
#define CONSTANT_PLANE(VALUE, PLANE) \
do { \
PLANE[0] = 0.0F; \
PLANE[1] = 0.0F; \
PLANE[2] = -1.0F; \
PLANE[3] = VALUE; \
} while (0)
 
 
 
/*
* Solve plane equation for Z at (X,Y).
*/
static INLINE GLfloat
solve_plane(GLfloat x, GLfloat y, const GLfloat plane[4])
{
ASSERT(plane[2] != 0.0F);
return (plane[3] + plane[0] * x + plane[1] * y) / -plane[2];
}
 
 
#define SOLVE_PLANE(X, Y, PLANE) \
((PLANE[3] + PLANE[0] * (X) + PLANE[1] * (Y)) / -PLANE[2])
 
 
/*
* Return 1 / solve_plane().
*/
static INLINE GLfloat
solve_plane_recip(GLfloat x, GLfloat y, const GLfloat plane[4])
{
const GLfloat denom = plane[3] + plane[0] * x + plane[1] * y;
if (denom == 0.0F)
return 0.0F;
else
return -plane[2] / denom;
}
 
 
/*
* Solve plane and return clamped GLchan value.
*/
static INLINE GLchan
solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4])
{
GLfloat z = (plane[3] + plane[0] * x + plane[1] * y) / -plane[2] + 0.5F;
if (z < 0.0F)
return 0;
else if (z > CHAN_MAXF)
return (GLchan) CHAN_MAXF;
return (GLchan) (GLint) z;
}
 
 
 
/*
* Compute how much (area) of the given pixel is inside the triangle.
* Vertices MUST be specified in counter-clockwise order.
* Return: coverage in [0, 1].
*/
static GLfloat
compute_coveragef(const GLfloat v0[3], const GLfloat v1[3],
const GLfloat v2[3], GLint winx, GLint winy)
{
/* Given a position [0,3]x[0,3] return the sub-pixel sample position.
* Contributed by Ray Tice.
*
* Jitter sample positions -
* - average should be .5 in x & y for each column
* - each of the 16 rows and columns should be used once
* - the rectangle formed by the first four points
* should contain the other points
* - the distrubition should be fairly even in any given direction
*
* The pattern drawn below isn't optimal, but it's better than a regular
* grid. In the drawing, the center of each subpixel is surrounded by
* four dots. The "x" marks the jittered position relative to the
* subpixel center.
*/
#define POS(a, b) (0.5+a*4+b)/16
static const GLfloat samples[16][2] = {
/* start with the four corners */
{ POS(0, 2), POS(0, 0) },
{ POS(3, 3), POS(0, 2) },
{ POS(0, 0), POS(3, 1) },
{ POS(3, 1), POS(3, 3) },
/* continue with interior samples */
{ POS(1, 1), POS(0, 1) },
{ POS(2, 0), POS(0, 3) },
{ POS(0, 3), POS(1, 3) },
{ POS(1, 2), POS(1, 0) },
{ POS(2, 3), POS(1, 2) },
{ POS(3, 2), POS(1, 1) },
{ POS(0, 1), POS(2, 2) },
{ POS(1, 0), POS(2, 1) },
{ POS(2, 1), POS(2, 3) },
{ POS(3, 0), POS(2, 0) },
{ POS(1, 3), POS(3, 0) },
{ POS(2, 2), POS(3, 2) }
};
 
const GLfloat x = (GLfloat) winx;
const GLfloat y = (GLfloat) winy;
const GLfloat dx0 = v1[0] - v0[0];
const GLfloat dy0 = v1[1] - v0[1];
const GLfloat dx1 = v2[0] - v1[0];
const GLfloat dy1 = v2[1] - v1[1];
const GLfloat dx2 = v0[0] - v2[0];
const GLfloat dy2 = v0[1] - v2[1];
GLint stop = 4, i;
GLfloat insideCount = 16.0F;
 
#ifdef DEBUG
{
const GLfloat area = dx0 * dy1 - dx1 * dy0;
ASSERT(area >= 0.0);
}
#endif
 
for (i = 0; i < stop; i++) {
const GLfloat sx = x + samples[i][0];
const GLfloat sy = y + samples[i][1];
const GLfloat fx0 = sx - v0[0];
const GLfloat fy0 = sy - v0[1];
const GLfloat fx1 = sx - v1[0];
const GLfloat fy1 = sy - v1[1];
const GLfloat fx2 = sx - v2[0];
const GLfloat fy2 = sy - v2[1];
/* cross product determines if sample is inside or outside each edge */
GLfloat cross0 = (dx0 * fy0 - dy0 * fx0);
GLfloat cross1 = (dx1 * fy1 - dy1 * fx1);
GLfloat cross2 = (dx2 * fy2 - dy2 * fx2);
/* Check if the sample is exactly on an edge. If so, let cross be a
* positive or negative value depending on the direction of the edge.
*/
if (cross0 == 0.0F)
cross0 = dx0 + dy0;
if (cross1 == 0.0F)
cross1 = dx1 + dy1;
if (cross2 == 0.0F)
cross2 = dx2 + dy2;
if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) {
/* point is outside triangle */
insideCount -= 1.0F;
stop = 16;
}
}
if (stop == 4)
return 1.0F;
else
return insideCount * (1.0F / 16.0F);
}
 
 
 
/*
* Compute how much (area) of the given pixel is inside the triangle.
* Vertices MUST be specified in counter-clockwise order.
* Return: coverage in [0, 15].
*/
static GLint
compute_coveragei(const GLfloat v0[3], const GLfloat v1[3],
const GLfloat v2[3], GLint winx, GLint winy)
{
/* NOTE: 15 samples instead of 16. */
static const GLfloat samples[15][2] = {
/* start with the four corners */
{ POS(0, 2), POS(0, 0) },
{ POS(3, 3), POS(0, 2) },
{ POS(0, 0), POS(3, 1) },
{ POS(3, 1), POS(3, 3) },
/* continue with interior samples */
{ POS(1, 1), POS(0, 1) },
{ POS(2, 0), POS(0, 3) },
{ POS(0, 3), POS(1, 3) },
{ POS(1, 2), POS(1, 0) },
{ POS(2, 3), POS(1, 2) },
{ POS(3, 2), POS(1, 1) },
{ POS(0, 1), POS(2, 2) },
{ POS(1, 0), POS(2, 1) },
{ POS(2, 1), POS(2, 3) },
{ POS(3, 0), POS(2, 0) },
{ POS(1, 3), POS(3, 0) }
};
const GLfloat x = (GLfloat) winx;
const GLfloat y = (GLfloat) winy;
const GLfloat dx0 = v1[0] - v0[0];
const GLfloat dy0 = v1[1] - v0[1];
const GLfloat dx1 = v2[0] - v1[0];
const GLfloat dy1 = v2[1] - v1[1];
const GLfloat dx2 = v0[0] - v2[0];
const GLfloat dy2 = v0[1] - v2[1];
GLint stop = 4, i;
GLint insideCount = 15;
 
#ifdef DEBUG
{
const GLfloat area = dx0 * dy1 - dx1 * dy0;
ASSERT(area >= 0.0);
}
#endif
 
for (i = 0; i < stop; i++) {
const GLfloat sx = x + samples[i][0];
const GLfloat sy = y + samples[i][1];
const GLfloat fx0 = sx - v0[0];
const GLfloat fy0 = sy - v0[1];
const GLfloat fx1 = sx - v1[0];
const GLfloat fy1 = sy - v1[1];
const GLfloat fx2 = sx - v2[0];
const GLfloat fy2 = sy - v2[1];
/* cross product determines if sample is inside or outside each edge */
GLfloat cross0 = (dx0 * fy0 - dy0 * fx0);
GLfloat cross1 = (dx1 * fy1 - dy1 * fx1);
GLfloat cross2 = (dx2 * fy2 - dy2 * fx2);
/* Check if the sample is exactly on an edge. If so, let cross be a
* positive or negative value depending on the direction of the edge.
*/
if (cross0 == 0.0F)
cross0 = dx0 + dy0;
if (cross1 == 0.0F)
cross1 = dx1 + dy1;
if (cross2 == 0.0F)
cross2 = dx2 + dy2;
if (cross0 < 0.0F || cross1 < 0.0F || cross2 < 0.0F) {
/* point is outside triangle */
insideCount--;
stop = 15;
}
}
if (stop == 4)
return 15;
else
return insideCount;
}
 
 
 
static void
rgba_aa_tri(GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
#define DO_Z
#define DO_FOG
#define DO_RGBA
#include "s_aatritemp.h"
}
 
 
static void
index_aa_tri(GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
#define DO_Z
#define DO_FOG
#define DO_INDEX
#include "s_aatritemp.h"
}
 
 
/*
* Compute mipmap level of detail.
* XXX we should really include the R coordinate in this computation
* in order to do 3-D texture mipmapping.
*/
static INLINE GLfloat
compute_lambda(const GLfloat sPlane[4], const GLfloat tPlane[4],
const GLfloat qPlane[4], GLfloat cx, GLfloat cy,
GLfloat invQ, GLfloat texWidth, GLfloat texHeight)
{
const GLfloat s = solve_plane(cx, cy, sPlane);
const GLfloat t = solve_plane(cx, cy, tPlane);
const GLfloat invQ_x1 = solve_plane_recip(cx+1.0F, cy, qPlane);
const GLfloat invQ_y1 = solve_plane_recip(cx, cy+1.0F, qPlane);
const GLfloat s_x1 = s - sPlane[0] / sPlane[2];
const GLfloat s_y1 = s - sPlane[1] / sPlane[2];
const GLfloat t_x1 = t - tPlane[0] / tPlane[2];
const GLfloat t_y1 = t - tPlane[1] / tPlane[2];
GLfloat dsdx = s_x1 * invQ_x1 - s * invQ;
GLfloat dsdy = s_y1 * invQ_y1 - s * invQ;
GLfloat dtdx = t_x1 * invQ_x1 - t * invQ;
GLfloat dtdy = t_y1 * invQ_y1 - t * invQ;
GLfloat maxU, maxV, rho, lambda;
dsdx = FABSF(dsdx);
dsdy = FABSF(dsdy);
dtdx = FABSF(dtdx);
dtdy = FABSF(dtdy);
maxU = MAX2(dsdx, dsdy) * texWidth;
maxV = MAX2(dtdx, dtdy) * texHeight;
rho = MAX2(maxU, maxV);
lambda = LOG2(rho);
return lambda;
}
 
 
static void
tex_aa_tri(GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
#define DO_Z
#define DO_FOG
#define DO_RGBA
#define DO_TEX
#include "s_aatritemp.h"
}
 
 
static void
spec_tex_aa_tri(GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
#define DO_Z
#define DO_FOG
#define DO_RGBA
#define DO_TEX
#define DO_SPEC
#include "s_aatritemp.h"
}
 
 
static void
multitex_aa_tri(GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
#define DO_Z
#define DO_FOG
#define DO_RGBA
#define DO_MULTITEX
#include "s_aatritemp.h"
}
 
static void
spec_multitex_aa_tri(GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
#define DO_Z
#define DO_FOG
#define DO_RGBA
#define DO_MULTITEX
#define DO_SPEC
#include "s_aatritemp.h"
}
 
 
/*
* Examine GL state and set swrast->Triangle to an
* appropriate antialiased triangle rasterizer function.
*/
void
_mesa_set_aa_triangle_function(GLcontext *ctx)
{
ASSERT(ctx->Polygon.SmoothFlag);
 
if (ctx->Texture._EnabledUnits != 0) {
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) {
if (ctx->Texture._EnabledUnits > 1) {
SWRAST_CONTEXT(ctx)->Triangle = spec_multitex_aa_tri;
}
else {
SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri;
}
}
else {
if (ctx->Texture._EnabledUnits > 1) {
SWRAST_CONTEXT(ctx)->Triangle = multitex_aa_tri;
}
else {
SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri;
}
}
}
else if (ctx->Visual.rgbMode) {
SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri;
}
else {
SWRAST_CONTEXT(ctx)->Triangle = index_aa_tri;
}
 
ASSERT(SWRAST_CONTEXT(ctx)->Triangle);
}
/shark/trunk/ports/mesa/src/swrast/s_pixeltex.h
0,0 → 1,39
/* $Id: s_pixeltex.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_PIXELTEX_H
#define S_PIXELTEX_H
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void
_swrast_pixel_texture(GLcontext *ctx, struct sw_span *span);
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_lines.c
0,0 → 1,884
/* $Id: s_lines.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 5.0
*
* 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.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "macros.h"
#include "mmath.h"
#include "s_aaline.h"
#include "s_context.h"
#include "s_depth.h"
#include "s_feedback.h"
#include "s_lines.h"
#include "s_span.h"
 
 
/*
* Init the mask[] array to implement a line stipple.
*/
static void
compute_stipple_mask( GLcontext *ctx, GLuint len, GLubyte mask[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint i;
 
for (i = 0; i < len; i++) {
GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
if ((1 << bit) & ctx->Line.StipplePattern) {
mask[i] = GL_TRUE;
}
else {
mask[i] = GL_FALSE;
}
swrast->StippleCounter++;
}
}
 
 
/*
* To draw a wide line we can simply redraw the span N times, side by side.
*/
static void
draw_wide_line( GLcontext *ctx, struct sw_span *span, GLboolean xMajor )
{
GLint width, start;
 
ASSERT(span->end < MAX_WIDTH);
 
width = (GLint) CLAMP( ctx->Line.Width, MIN_LINE_WIDTH, MAX_LINE_WIDTH );
 
if (width & 1)
start = width / 2;
else
start = width / 2 - 1;
 
if (xMajor) {
GLint *y = span->array->y;
GLuint i;
GLint w;
for (w = 0; w < width; w++) {
if (w == 0) {
for (i = 0; i < span->end; i++)
y[i] -= start;
}
else {
for (i = 0; i < span->end; i++)
y[i]++;
}
if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
_mesa_write_texture_span(ctx, span);
else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
_mesa_write_rgba_span(ctx, span);
else
_mesa_write_index_span(ctx, span);
}
}
else {
GLint *x = span->array->x;
GLuint i;
GLint w;
for (w = 0; w < width; w++) {
if (w == 0) {
for (i = 0; i < span->end; i++)
x[i] -= start;
}
else {
for (i = 0; i < span->end; i++)
x[i]++;
}
if ((span->interpMask | span->arrayMask) & SPAN_TEXTURE)
_mesa_write_texture_span(ctx, span);
else if ((span->interpMask | span->arrayMask) & SPAN_RGBA)
_mesa_write_rgba_span(ctx, span);
else
_mesa_write_index_span(ctx, span);
}
}
}
 
 
 
/**********************************************************************/
/***** Rasterization *****/
/**********************************************************************/
 
 
/* Flat, color index line */
static void flat_ci_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLint *x, *y;
struct sw_span span;
 
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
ASSERT(!ctx->Line.StippleFlag);
ASSERT(ctx->Line.Width == 1.0F);
 
INIT_SPAN(span, GL_LINE, 0, SPAN_INDEX, SPAN_XY);
span.index = IntToFixed(vert1->index);
span.indexStep = 0;
x = span.array->x;
y = span.array->y;
 
#define INTERP_XY 1
#define PLOT(X,Y) \
{ \
x[span.end] = X; \
y[span.end] = Y; \
span.end++; \
}
 
#include "s_linetemp.h"
 
_mesa_write_index_span(ctx, &span);
}
 
 
/* Flat-shaded, RGBA line */
static void flat_rgba_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
struct sw_span span;
GLint *x, *y;
 
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
ASSERT(!ctx->Line.StippleFlag);
ASSERT(ctx->Line.Width == 1.0F);
 
INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA, SPAN_XY);
span.red = ChanToFixed(vert1->color[0]);
span.green = ChanToFixed(vert1->color[1]);
span.blue = ChanToFixed(vert1->color[2]);
span.alpha = ChanToFixed(vert1->color[3]);
span.redStep = 0;
span.greenStep = 0;
span.blueStep = 0;
span.alphaStep = 0;
x = span.array->x;
y = span.array->y;
 
#define INTERP_XY 1
#define PLOT(X,Y) \
{ \
x[span.end] = X; \
y[span.end] = Y; \
span.end++; \
}
 
#include "s_linetemp.h"
 
_mesa_write_rgba_span(ctx, &span);
}
 
 
/* Smooth shaded, color index line */
static void smooth_ci_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
struct sw_span span;
GLint *x, *y;
GLuint *index;
 
ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
ASSERT(!ctx->Line.StippleFlag);
ASSERT(ctx->Line.Width == 1.0F);
 
INIT_SPAN(span, GL_LINE, 0, 0, SPAN_XY | SPAN_INDEX);
x = span.array->x;
y = span.array->y;
index = span.array->index;
 
#define INTERP_XY 1
#define INTERP_INDEX 1
#define PLOT(X,Y) \
{ \
x[span.end] = X; \
y[span.end] = Y; \
index[span.end] = I; \
span.end++; \
}
 
#include "s_linetemp.h"
 
_mesa_write_index_span(ctx, &span);
}
 
 
/* Smooth-shaded, RGBA line */
static void smooth_rgba_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
struct sw_span span;
GLint *x, *y;
GLchan (*rgba)[4];
 
ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
ASSERT(!ctx->Line.StippleFlag);
ASSERT(ctx->Line.Width == 1.0F);
 
INIT_SPAN(span, GL_LINE, 0, 0, SPAN_XY | SPAN_RGBA);
x = span.array->x;
y = span.array->y;
rgba = span.array->rgba;
 
#define INTERP_XY 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define PLOT(X,Y) \
{ \
x[span.end] = X; \
y[span.end] = Y; \
rgba[span.end][RCOMP] = FixedToInt(r0); \
rgba[span.end][GCOMP] = FixedToInt(g0); \
rgba[span.end][BCOMP] = FixedToInt(b0); \
rgba[span.end][ACOMP] = FixedToInt(a0); \
span.end++; \
}
 
#include "s_linetemp.h"
 
_mesa_write_rgba_span(ctx, &span);
}
 
 
/* Smooth shaded, color index, any width, maybe stippled */
static void general_smooth_ci_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLboolean xMajor = GL_FALSE;
struct sw_span span;
GLint *x, *y;
GLdepth *z;
GLfloat *fog;
GLuint *index;
 
ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
 
INIT_SPAN(span, GL_LINE, 0, 0,
SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_INDEX);
x = span.array->x;
y = span.array->y;
z = span.array->z;
fog = span.array->fog;
index = span.array->index;
 
#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_INDEX 1
#define PLOT(X,Y) \
{ \
x[span.end] = X; \
y[span.end] = Y; \
z[span.end] = Z; \
fog[span.end] = fog0; \
index[span.end] = I; \
span.end++; \
}
#include "s_linetemp.h"
 
if (ctx->Line.StippleFlag) {
span.arrayMask |= SPAN_MASK;
compute_stipple_mask(ctx, span.end, span.array->mask);
}
 
if (ctx->Line.Width > 1.0) {
draw_wide_line(ctx, &span, xMajor);
}
else {
_mesa_write_index_span(ctx, &span);
}
}
 
 
/* Flat shaded, color index, any width, maybe stippled */
static void general_flat_ci_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLboolean xMajor = GL_FALSE;
struct sw_span span;
GLint *x, *y;
GLdepth *z;
GLfloat *fog;
 
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
 
INIT_SPAN(span, GL_LINE, 0, SPAN_INDEX,
SPAN_XY | SPAN_Z | SPAN_FOG);
span.index = IntToFixed(vert1->index);
span.indexStep = 0;
x = span.array->x;
y = span.array->y;
z = span.array->z;
fog = span.array->fog;
 
#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define PLOT(X,Y) \
{ \
x[span.end] = X; \
y[span.end] = Y; \
z[span.end] = Z; \
fog[span.end] = fog0; \
span.end++; \
}
#include "s_linetemp.h"
 
if (ctx->Line.StippleFlag) {
span.arrayMask |= SPAN_MASK;
compute_stipple_mask(ctx, span.end, span.array->mask);
}
 
if (ctx->Line.Width > 1.0) {
draw_wide_line(ctx, &span, xMajor);
}
else {
_mesa_write_index_span(ctx, &span);
}
}
 
 
 
static void general_smooth_rgba_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLboolean xMajor = GL_FALSE;
struct sw_span span;
GLint *x, *y;
GLdepth *z;
GLchan (*rgba)[4];
GLfloat *fog;
 
ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
 
INIT_SPAN(span, GL_LINE, 0, 0,
SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA);
x = span.array->x;
y = span.array->y;
z = span.array->z;
rgba = span.array->rgba;
fog = span.array->fog;
 
#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define PLOT(X,Y) \
{ \
x[span.end] = X; \
y[span.end] = Y; \
z[span.end] = Z; \
rgba[span.end][RCOMP] = FixedToInt(r0); \
rgba[span.end][GCOMP] = FixedToInt(g0); \
rgba[span.end][BCOMP] = FixedToInt(b0); \
rgba[span.end][ACOMP] = FixedToInt(a0); \
fog[span.end] = fog0; \
span.end++; \
}
#include "s_linetemp.h"
 
if (ctx->Line.StippleFlag) {
span.arrayMask |= SPAN_MASK;
compute_stipple_mask(ctx, span.end, span.array->mask);
}
 
if (ctx->Line.Width > 1.0) {
draw_wide_line(ctx, &span, xMajor);
}
else {
_mesa_write_rgba_span(ctx, &span);
}
}
 
 
static void general_flat_rgba_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLboolean xMajor = GL_FALSE;
struct sw_span span;
GLint *x, *y;
GLdepth *z;
GLfloat *fog;
 
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
 
INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA,
SPAN_XY | SPAN_Z | SPAN_FOG);
span.red = ChanToFixed(vert1->color[0]);
span.green = ChanToFixed(vert1->color[1]);
span.blue = ChanToFixed(vert1->color[2]);
span.alpha = ChanToFixed(vert1->color[3]);
span.redStep = 0;
span.greenStep = 0;
span.blueStep = 0;
span.alphaStep = 0;
x = span.array->x;
y = span.array->y;
z = span.array->z;
fog = span.array->fog;
 
#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define PLOT(X,Y) \
{ \
x[span.end] = X; \
y[span.end] = Y; \
z[span.end] = Z; \
fog[span.end] = fog0; \
span.end++; \
}
#include "s_linetemp.h"
 
if (ctx->Line.StippleFlag) {
span.arrayMask |= SPAN_MASK;
compute_stipple_mask(ctx, span.end, span.array->mask);
}
 
if (ctx->Line.Width > 1.0) {
draw_wide_line(ctx, &span, xMajor);
}
else {
_mesa_write_rgba_span(ctx, &span);
}
}
 
 
/* Flat-shaded, textured, any width, maybe stippled */
static void flat_textured_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLboolean xMajor = GL_FALSE;
struct sw_span span;
 
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
 
INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA | SPAN_SPEC,
SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
span.red = ChanToFixed(vert1->color[0]);
span.green = ChanToFixed(vert1->color[1]);
span.blue = ChanToFixed(vert1->color[2]);
span.alpha = ChanToFixed(vert1->color[3]);
span.redStep = 0;
span.greenStep = 0;
span.blueStep = 0;
span.alphaStep = 0;
span.specRed = ChanToFixed(vert1->specular[0]);
span.specGreen = ChanToFixed(vert1->specular[1]);
span.specBlue = ChanToFixed(vert1->specular[2]);
span.specRedStep = 0;
span.specGreenStep = 0;
span.specBlueStep = 0;
 
#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_TEX 1
#define PLOT(X,Y) \
{ \
span.array->x[span.end] = X; \
span.array->y[span.end] = Y; \
span.array->z[span.end] = Z; \
span.array->fog[span.end] = fog0; \
span.array->texcoords[0][span.end][0] = fragTexcoord[0]; \
span.array->texcoords[0][span.end][1] = fragTexcoord[1]; \
span.array->texcoords[0][span.end][2] = fragTexcoord[2]; \
span.array->lambda[0][span.end] = 0.0; \
span.end++; \
}
#include "s_linetemp.h"
 
if (ctx->Line.StippleFlag) {
span.arrayMask |= SPAN_MASK;
compute_stipple_mask(ctx, span.end, span.array->mask);
}
 
if (ctx->Line.Width > 1.0) {
draw_wide_line(ctx, &span, xMajor);
}
else {
_mesa_write_texture_span(ctx, &span);
}
}
 
 
 
/* Smooth-shaded, textured, any width, maybe stippled */
static void smooth_textured_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLboolean xMajor = GL_FALSE;
struct sw_span span;
 
ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
 
INIT_SPAN(span, GL_LINE, 0, 0,
SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_TEXTURE | SPAN_LAMBDA);
 
#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1
#define PLOT(X,Y) \
{ \
span.array->x[span.end] = X; \
span.array->y[span.end] = Y; \
span.array->z[span.end] = Z; \
span.array->fog[span.end] = fog0; \
span.array->rgba[span.end][RCOMP] = FixedToInt(r0); \
span.array->rgba[span.end][GCOMP] = FixedToInt(g0); \
span.array->rgba[span.end][BCOMP] = FixedToInt(b0); \
span.array->rgba[span.end][ACOMP] = FixedToInt(a0); \
span.array->texcoords[0][span.end][0] = fragTexcoord[0]; \
span.array->texcoords[0][span.end][1] = fragTexcoord[1]; \
span.array->texcoords[0][span.end][2] = fragTexcoord[2]; \
span.array->lambda[0][span.end] = 0.0; \
span.end++; \
}
#include "s_linetemp.h"
 
if (ctx->Line.StippleFlag) {
span.arrayMask |= SPAN_MASK;
compute_stipple_mask(ctx, span.end, span.array->mask);
}
 
if (ctx->Line.Width > 1.0) {
draw_wide_line(ctx, &span, xMajor);
}
else {
_mesa_write_texture_span(ctx, &span);
}
}
 
 
/* Smooth-shaded, multitextured, any width, maybe stippled, separate specular
* color interpolation.
*/
static void smooth_multitextured_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLboolean xMajor = GL_FALSE;
struct sw_span span;
GLuint u;
 
ASSERT(ctx->Light.ShadeModel == GL_SMOOTH);
 
INIT_SPAN(span, GL_LINE, 0, 0,
SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_RGBA | SPAN_SPEC | SPAN_TEXTURE | SPAN_LAMBDA);
 
#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_RGB 1
#define INTERP_SPEC 1
#define INTERP_ALPHA 1
#define INTERP_MULTITEX 1
#define PLOT(X,Y) \
{ \
span.array->x[span.end] = X; \
span.array->y[span.end] = Y; \
span.array->z[span.end] = Z; \
span.array->fog[span.end] = fog0; \
span.array->rgba[span.end][RCOMP] = FixedToInt(r0); \
span.array->rgba[span.end][GCOMP] = FixedToInt(g0); \
span.array->rgba[span.end][BCOMP] = FixedToInt(b0); \
span.array->rgba[span.end][ACOMP] = FixedToInt(a0); \
span.array->spec[span.end][RCOMP] = FixedToInt(sr0); \
span.array->spec[span.end][GCOMP] = FixedToInt(sg0); \
span.array->spec[span.end][BCOMP] = FixedToInt(sb0); \
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
if (ctx->Texture.Unit[u]._ReallyEnabled) { \
span.array->texcoords[u][span.end][0] = fragTexcoord[u][0]; \
span.array->texcoords[u][span.end][1] = fragTexcoord[u][1]; \
span.array->texcoords[u][span.end][2] = fragTexcoord[u][2]; \
span.array->lambda[u][span.end] = 0.0; \
} \
} \
span.end++; \
}
#include "s_linetemp.h"
 
if (ctx->Line.StippleFlag) {
span.arrayMask |= SPAN_MASK;
compute_stipple_mask(ctx, span.end, span.array->mask);
}
 
if (ctx->Line.Width > 1.0) {
draw_wide_line(ctx, &span, xMajor);
}
else {
_mesa_write_texture_span(ctx, &span);
}
}
 
 
/* Flat-shaded, multitextured, any width, maybe stippled, separate specular
* color interpolation.
*/
static void flat_multitextured_line( GLcontext *ctx,
const SWvertex *vert0,
const SWvertex *vert1 )
{
GLboolean xMajor = GL_FALSE;
struct sw_span span;
GLuint u;
 
ASSERT(ctx->Light.ShadeModel == GL_FLAT);
 
INIT_SPAN(span, GL_LINE, 0, SPAN_RGBA | SPAN_SPEC,
SPAN_XY | SPAN_Z | SPAN_FOG | SPAN_TEXTURE | SPAN_LAMBDA);
span.red = ChanToFixed(vert1->color[0]);
span.green = ChanToFixed(vert1->color[1]);
span.blue = ChanToFixed(vert1->color[2]);
span.alpha = ChanToFixed(vert1->color[3]);
span.redStep = 0;
span.greenStep = 0;
span.blueStep = 0;
span.alphaStep = 0;
span.specRed = ChanToFixed(vert1->specular[0]);
span.specGreen = ChanToFixed(vert1->specular[1]);
span.specBlue = ChanToFixed(vert1->specular[2]);
span.specRedStep = 0;
span.specGreenStep = 0;
span.specBlueStep = 0;
 
#define SET_XMAJOR 1
#define INTERP_XY 1
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_MULTITEX 1
#define PLOT(X,Y) \
{ \
span.array->x[span.end] = X; \
span.array->y[span.end] = Y; \
span.array->z[span.end] = Z; \
span.array->fog[span.end] = fog0; \
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { \
if (ctx->Texture.Unit[u]._ReallyEnabled) { \
span.array->texcoords[u][span.end][0] = fragTexcoord[u][0]; \
span.array->texcoords[u][span.end][1] = fragTexcoord[u][1]; \
span.array->texcoords[u][span.end][2] = fragTexcoord[u][2]; \
span.array->lambda[u][span.end] = 0.0; \
} \
} \
span.end++; \
}
#include "s_linetemp.h"
 
if (ctx->Line.StippleFlag) {
span.arrayMask |= SPAN_MASK;
compute_stipple_mask(ctx, span.end, span.array->mask);
}
 
if (ctx->Line.Width > 1.0) {
draw_wide_line(ctx, &span, xMajor);
}
else {
_mesa_write_texture_span(ctx, &span);
}
}
 
 
void _swrast_add_spec_terms_line( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1 )
{
SWvertex *ncv0 = (SWvertex *)v0;
SWvertex *ncv1 = (SWvertex *)v1;
GLchan c[2][4];
COPY_CHAN4( c[0], ncv0->color );
COPY_CHAN4( c[1], ncv1->color );
ACC_3V( ncv0->color, ncv0->specular );
ACC_3V( ncv1->color, ncv1->specular );
SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 );
COPY_CHAN4( ncv0->color, c[0] );
COPY_CHAN4( ncv1->color, c[1] );
}
 
 
#ifdef DEBUG
extern void
_mesa_print_line_function(GLcontext *ctx); /* silence compiler warning */
void
_mesa_print_line_function(GLcontext *ctx)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
_mesa_printf("Line Func == ");
if (swrast->Line == flat_ci_line)
_mesa_printf("flat_ci_line\n");
else if (swrast->Line == flat_rgba_line)
_mesa_printf("flat_rgba_line\n");
else if (swrast->Line == smooth_ci_line)
_mesa_printf("smooth_ci_line\n");
else if (swrast->Line == smooth_rgba_line)
_mesa_printf("smooth_rgba_line\n");
else if (swrast->Line == general_smooth_ci_line)
_mesa_printf("general_smooth_ci_line\n");
else if (swrast->Line == general_flat_ci_line)
_mesa_printf("general_flat_ci_line\n");
else if (swrast->Line == general_smooth_rgba_line)
_mesa_printf("general_smooth_rgba_line\n");
else if (swrast->Line == general_flat_rgba_line)
_mesa_printf("general_flat_rgba_line\n");
else if (swrast->Line == flat_textured_line)
_mesa_printf("flat_textured_line\n");
else if (swrast->Line == smooth_textured_line)
_mesa_printf("smooth_textured_line\n");
else if (swrast->Line == smooth_multitextured_line)
_mesa_printf("smooth_multitextured_line\n");
else if (swrast->Line == flat_multitextured_line)
_mesa_printf("flat_multitextured_line\n");
else
_mesa_printf("Driver func %p\n", (void *) swrast->Line);
}
#endif
 
 
 
#ifdef DEBUG
 
/* record the current line function name */
static const char *lineFuncName = NULL;
 
#define USE(lineFunc) \
do { \
lineFuncName = #lineFunc; \
/*_mesa_printf("%s\n", lineFuncName);*/ \
swrast->Line = lineFunc; \
} while (0)
 
#else
 
#define USE(lineFunc) swrast->Line = lineFunc
 
#endif
 
 
 
/*
* Determine which line drawing function to use given the current
* rendering context.
*
* Please update the summary flag _SWRAST_NEW_LINE if you add or remove
* tests to this code.
*/
void
_swrast_choose_line( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLboolean rgbmode = ctx->Visual.rgbMode;
 
if (ctx->RenderMode == GL_RENDER) {
if (ctx->Line.SmoothFlag) {
/* antialiased lines */
_swrast_choose_aa_line_function(ctx);
ASSERT(swrast->Triangle);
}
else if (ctx->Texture._EnabledUnits) {
if (ctx->Texture._EnabledUnits > 1 ||
(ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)) {
/* multi-texture and/or separate specular color */
if (ctx->Light.ShadeModel == GL_SMOOTH)
USE(smooth_multitextured_line);
else
USE(flat_multitextured_line);
}
else {
if (ctx->Light.ShadeModel == GL_SMOOTH) {
USE(smooth_textured_line);
}
else {
USE(flat_textured_line);
}
}
}
else {
if (ctx->Light.ShadeModel == GL_SMOOTH) {
if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
|| ctx->Line.StippleFlag) {
if (rgbmode)
USE(general_smooth_rgba_line);
else
USE(general_smooth_ci_line);
}
else {
if (rgbmode)
USE(smooth_rgba_line);
else
USE(smooth_ci_line);
}
}
else {
if (ctx->Depth.Test || ctx->Fog.Enabled || ctx->Line.Width != 1.0
|| ctx->Line.StippleFlag) {
if (rgbmode)
USE(general_flat_rgba_line);
else
USE(general_flat_ci_line);
}
else {
if (rgbmode)
USE(flat_rgba_line);
else
USE(flat_ci_line);
}
}
}
}
else if (ctx->RenderMode == GL_FEEDBACK) {
USE(_mesa_feedback_line);
}
else {
ASSERT(ctx->RenderMode == GL_SELECT);
USE(_mesa_select_line);
}
 
/*_mesa_print_line_function(ctx);*/
}
/shark/trunk/ports/mesa/src/swrast/s_fog.c
0,0 → 1,315
/* $Id: s_fog.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "context.h"
#include "macros.h"
#include "mmath.h"
 
#include "s_context.h"
#include "s_fog.h"
#include "s_span.h"
 
 
 
 
/**
* Used to convert current raster distance to a fog factor in [0,1].
*/
GLfloat
_mesa_z_to_fogfactor(GLcontext *ctx, GLfloat z)
{
GLfloat d, f;
 
switch (ctx->Fog.Mode) {
case GL_LINEAR:
if (ctx->Fog.Start == ctx->Fog.End)
d = 1.0F;
else
d = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
f = (ctx->Fog.End - z) * d;
return CLAMP(f, 0.0F, 1.0F);
case GL_EXP:
d = ctx->Fog.Density;
f = (GLfloat) exp(-d * z);
return f;
case GL_EXP2:
d = ctx->Fog.Density;
f = (GLfloat) exp(-(d * d * z * z));
return f;
default:
_mesa_problem(ctx, "Bad fog mode in _mesa_z_to_fogfactor");
return 0.0;
}
}
 
 
 
/**
* Calculate fog factors (in [0,1]) from window z values
* Input: n - number of pixels
* z - array of integer depth values
* red, green, blue, alpha - pixel colors
* Output: red, green, blue, alpha - fogged pixel colors
*
* Use lookup table & interpolation?
*/
static void
compute_fog_factors_from_z( const GLcontext *ctx,
GLuint n,
const GLdepth z[],
GLfloat fogFact[] )
{
const GLfloat *proj = ctx->ProjectionMatrixStack.Top->m;
const GLboolean ortho = (proj[15] != 0.0F);
const GLfloat p10 = proj[10];
const GLfloat p14 = proj[14];
const GLfloat tz = ctx->Viewport._WindowMap.m[MAT_TZ];
GLfloat szInv;
GLuint i;
 
if (ctx->Viewport._WindowMap.m[MAT_SZ] == 0.0)
szInv = 1.0F;
else
szInv = 1.0F / ctx->Viewport._WindowMap.m[MAT_SZ];
 
/*
* Note: to compute eyeZ from the ndcZ we have to solve the following:
*
* p[10] * eyeZ + p[14] * eyeW
* ndcZ = ---------------------------
* p[11] * eyeZ + p[15] * eyeW
*
* Thus:
*
* p[14] * eyeW - p[15] * eyeW * ndcZ
* eyeZ = ----------------------------------
* p[11] * ndcZ - p[10]
*
* If we note:
* a) if using an orthographic projection, p[11] = 0 and p[15] = 1.
* b) if using a perspective projection, p[11] = -1 and p[15] = 0.
* c) we assume eyeW = 1 (not always true- glVertex4)
*
* Then we can simplify the calculation of eyeZ quite a bit. We do
* separate calculations for the orthographic and perspective cases below.
* Note that we drop a negative sign or two since they don't matter.
*/
 
switch (ctx->Fog.Mode) {
case GL_LINEAR:
{
GLfloat fogEnd = ctx->Fog.End;
GLfloat fogScale;
if (ctx->Fog.Start == ctx->Fog.End)
fogScale = 1.0;
else
fogScale = 1.0F / (ctx->Fog.End - ctx->Fog.Start);
if (ortho) {
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = (ndcz - p14) / p10;
GLfloat f;
if (eyez < 0.0)
eyez = -eyez;
f = (fogEnd - eyez) * fogScale;
fogFact[i] = CLAMP(f, 0.0F, 1.0F);
}
}
else {
/* perspective */
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = p14 / (ndcz + p10);
GLfloat f;
if (eyez < 0.0)
eyez = -eyez;
f = (fogEnd - eyez) * fogScale;
fogFact[i] = CLAMP(f, 0.0F, 1.0F);
}
}
}
break;
case GL_EXP:
if (ortho) {
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = (ndcz - p14) / p10;
if (eyez < 0.0)
eyez = -eyez;
fogFact[i] = (GLfloat) exp( -ctx->Fog.Density * eyez );
}
}
else {
/* perspective */
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = p14 / (ndcz + p10);
if (eyez < 0.0)
eyez = -eyez;
fogFact[i] = (GLfloat) exp( -ctx->Fog.Density * eyez );
}
}
break;
case GL_EXP2:
{
GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density;
if (ortho) {
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = (ndcz - p14) / p10;
GLfloat tmp = negDensitySquared * eyez * eyez;
#if defined(__alpha__) || defined(__alpha)
/* XXX this underflow check may be needed for other systems*/
if (tmp < FLT_MIN_10_EXP)
tmp = FLT_MIN_10_EXP;
#endif
fogFact[i] = (GLfloat) exp( tmp );
}
}
else {
/* perspective */
for (i=0;i<n;i++) {
GLfloat ndcz = ((GLfloat) z[i] - tz) * szInv;
GLfloat eyez = p14 / (ndcz + p10);
GLfloat tmp = negDensitySquared * eyez * eyez;
#if defined(__alpha__) || defined(__alpha)
/* XXX this underflow check may be needed for other systems*/
if (tmp < FLT_MIN_10_EXP)
tmp = FLT_MIN_10_EXP;
#endif
fogFact[i] = (GLfloat) exp( tmp );
}
}
}
break;
default:
_mesa_problem(ctx, "Bad fog mode in compute_fog_factors_from_z");
return;
}
}
 
 
 
/**
* Apply fog to a span of RGBA pixels.
* The fog factors are either in the span->array->fog or stored as base/step.
* These are fog _factors_, not fog coords. Fog coords were converted to
* fog factors per vertex.
*/
void
_mesa_fog_rgba_span( const GLcontext *ctx, struct sw_span *span )
{
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint n = span->end;
GLchan (*rgba)[4] = (GLchan (*)[4]) span->array->rgba;
GLchan rFog, gFog, bFog;
 
ASSERT(ctx->Fog.Enabled);
ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
ASSERT(span->arrayMask & SPAN_RGBA);
 
UNCLAMPED_FLOAT_TO_CHAN(rFog, ctx->Fog.Color[RCOMP]);
UNCLAMPED_FLOAT_TO_CHAN(gFog, ctx->Fog.Color[GCOMP]);
UNCLAMPED_FLOAT_TO_CHAN(bFog, ctx->Fog.Color[BCOMP]);
 
if (swrast->_PreferPixelFog) {
/* compute fog factor from each fragment's Z value */
if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
_mesa_span_interpolate_z(ctx, span);
compute_fog_factors_from_z(ctx, n, span->array->z, span->array->fog);
span->arrayMask |= SPAN_FOG;
}
 
if (span->arrayMask & SPAN_FOG) {
/* use fog array in span */
GLuint i;
for (i = 0; i < n; i++) {
const GLfloat fog = span->array->fog[i];
const GLfloat oneMinusFog = 1.0F - fog;
rgba[i][RCOMP] = (GLchan) (fog * rgba[i][RCOMP] + oneMinusFog * rFog);
rgba[i][GCOMP] = (GLchan) (fog * rgba[i][GCOMP] + oneMinusFog * gFog);
rgba[i][BCOMP] = (GLchan) (fog * rgba[i][BCOMP] + oneMinusFog * bFog);
}
}
else {
/* interpolate fog factors */
GLfloat fog = span->fog, dFog = span->fogStep;
GLuint i;
for (i = 0; i < n; i++) {
const GLfloat oneMinusFog = 1.0F - fog;
rgba[i][RCOMP] = (GLchan) (fog * rgba[i][RCOMP] + oneMinusFog * rFog);
rgba[i][GCOMP] = (GLchan) (fog * rgba[i][GCOMP] + oneMinusFog * gFog);
rgba[i][BCOMP] = (GLchan) (fog * rgba[i][BCOMP] + oneMinusFog * bFog);
fog += dFog;
}
}
}
 
 
/**
* As above, but color index mode.
*/
void
_mesa_fog_ci_span( const GLcontext *ctx, struct sw_span *span )
{
const SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint n = span->end;
GLuint *index = span->array->index;
 
ASSERT(ctx->Fog.Enabled);
ASSERT(span->arrayMask & SPAN_INDEX);
ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
 
if (swrast->_PreferPixelFog) {
/* compute fog factor from each fragment's Z value */
if ((span->interpMask & SPAN_Z) && (span->arrayMask & SPAN_Z) == 0)
_mesa_span_interpolate_z(ctx, span);
compute_fog_factors_from_z(ctx, n, span->array->z, span->array->fog);
span->arrayMask |= SPAN_FOG;
}
 
if (span->arrayMask & SPAN_FOG) {
const GLuint idx = (GLuint) ctx->Fog.Index;
GLuint i;
for (i = 0; i < n; i++) {
const GLfloat f = CLAMP(span->array->fog[i], 0.0F, 1.0F);
index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * idx);
}
}
else {
GLfloat fog = span->fog, dFog = span->fogStep;
const GLuint idx = (GLuint) ctx->Fog.Index;
GLuint i;
for (i = 0; i < n; i++) {
const GLfloat f = CLAMP(fog, 0.0F, 1.0F);
index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * idx);
fog += dFog;
}
}
}
/shark/trunk/ports/mesa/src/swrast/s_imaging.c
0,0 → 1,156
/* $Id: s_imaging.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
/* KW: Moved these here to remove knowledge of swrast from core mesa.
* Should probably pull the entire software implementation of these
* extensions into either swrast or a sister module.
*/
 
#include "s_context.h"
#include "s_span.h"
 
void
_swrast_CopyColorTable( GLcontext *ctx,
GLenum target, GLenum internalformat,
GLint x, GLint y, GLsizei width)
{
GLchan data[MAX_WIDTH][4];
 
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
 
if (width > MAX_WIDTH)
width = MAX_WIDTH;
 
/* read the data from framebuffer */
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, data );
 
/* Restore reading from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
 
glColorTable(target, internalformat, width, GL_RGBA, CHAN_TYPE, data);
}
 
void
_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
GLint x, GLint y, GLsizei width)
{
GLchan data[MAX_WIDTH][4];
 
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
 
if (width > MAX_WIDTH)
width = MAX_WIDTH;
 
/* read the data from framebuffer */
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y, data );
 
/* Restore reading from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
 
glColorSubTable(target, start, width, GL_RGBA, CHAN_TYPE, data);
}
 
 
void
_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan rgba[MAX_CONVOLUTION_WIDTH][4];
 
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
 
RENDER_START( swrast, ctx );
 
/* read the data from framebuffer */
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y,
(GLchan (*)[4]) rgba );
RENDER_FINISH( swrast, ctx );
 
/* Restore reading from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
 
/* store as convolution filter */
glConvolutionFilter1D(target, internalFormat, width,
GL_RGBA, CHAN_TYPE, rgba);
}
 
 
void
_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
struct gl_pixelstore_attrib packSave;
GLchan rgba[MAX_CONVOLUTION_HEIGHT][MAX_CONVOLUTION_WIDTH][4];
GLint i;
 
/* Select buffer to read from */
_swrast_use_read_buffer(ctx);
 
RENDER_START(swrast,ctx);
/* read pixels from framebuffer */
for (i = 0; i < height; i++) {
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, x, y + i,
(GLchan (*)[4]) rgba[i] );
}
 
RENDER_FINISH(swrast,ctx);
 
/* Restore reading from draw buffer (the default) */
_swrast_use_draw_buffer(ctx);
 
/*
* HACK: save & restore context state so we can store this as a
* convolution filter via the GL api. Doesn't call any callbacks
* hanging off ctx->Unpack statechanges.
*/
 
packSave = ctx->Unpack; /* save pixel packing params */
 
ctx->Unpack.Alignment = 1;
ctx->Unpack.RowLength = MAX_CONVOLUTION_WIDTH;
ctx->Unpack.SkipPixels = 0;
ctx->Unpack.SkipRows = 0;
ctx->Unpack.ImageHeight = 0;
ctx->Unpack.SkipImages = 0;
ctx->Unpack.SwapBytes = GL_FALSE;
ctx->Unpack.LsbFirst = GL_FALSE;
ctx->NewState |= _NEW_PACKUNPACK;
 
glConvolutionFilter2D(target, internalFormat, width, height,
GL_RGBA, CHAN_TYPE, rgba);
 
ctx->Unpack = packSave; /* restore pixel packing params */
ctx->NewState |= _NEW_PACKUNPACK;
}
/shark/trunk/ports/mesa/src/swrast/s_bitmap.c
0,0 → 1,255
/* $Id: s_bitmap.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
/**
* \file swrast/s_bitmap.c
* \brief glBitmap rendering.
* \author Brian Paul
*/
 
#include "glheader.h"
#include "image.h"
#include "macros.h"
#include "mmath.h"
#include "pixel.h"
 
#include "s_context.h"
#include "s_span.h"
 
 
 
/*
* Render a bitmap.
*/
void
_swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint row, col;
GLuint count = 0;
struct sw_span span;
 
ASSERT(ctx->RenderMode == GL_RENDER);
ASSERT(bitmap);
 
RENDER_START(swrast,ctx);
 
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
 
INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_XY);
 
if (ctx->Visual.rgbMode) {
span.interpMask |= SPAN_RGBA;
span.red = FloatToFixed(ctx->Current.RasterColor[0] * CHAN_MAXF);
span.green = FloatToFixed(ctx->Current.RasterColor[1] * CHAN_MAXF);
span.blue = FloatToFixed(ctx->Current.RasterColor[2] * CHAN_MAXF);
span.alpha = FloatToFixed(ctx->Current.RasterColor[3] * CHAN_MAXF);
span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
}
else {
span.interpMask |= SPAN_INDEX;
span.index = ChanToFixed(ctx->Current.RasterIndex);
span.indexStep = 0;
}
 
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
 
for (row = 0; row < height; row++, span.y++) {
const GLubyte *src = (const GLubyte *) _mesa_image_address( unpack,
bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
 
if (unpack->LsbFirst) {
/* Lsb first */
GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
for (col = 0; col < width; col++) {
if (*src & mask) {
span.array->x[count] = px + col;
span.array->y[count] = py + row;
count++;
}
if (mask == 128U) {
src++;
mask = 1U;
}
else {
mask = mask << 1;
}
}
 
/* get ready for next row */
if (mask != 1)
src++;
}
else {
/* Msb first */
GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
for (col = 0; col < width; col++) {
if (*src & mask) {
span.array->x[count] = px + col;
span.array->y[count] = py + row;
count++;
}
if (mask == 1U) {
src++;
mask = 128U;
}
else {
mask = mask >> 1;
}
}
 
/* get ready for next row */
if (mask != 128)
src++;
}
 
if (count + width >= MAX_WIDTH || row + 1 == height) {
/* flush the span */
span.end = count;
if (ctx->Visual.rgbMode)
_mesa_write_rgba_span(ctx, &span);
else
_mesa_write_index_span(ctx, &span);
span.end = 0;
count = 0;
}
}
 
RENDER_FINISH(swrast,ctx);
}
 
 
#if 0
/*
* XXX this is another way to implement Bitmap. Use horizontal runs of
* fragments, initializing the mask array to indicate which fragmens to
* draw or skip.
*/
void
_swrast_Bitmap( GLcontext *ctx, GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint row, col;
struct sw_span span;
 
ASSERT(ctx->RenderMode == GL_RENDER);
ASSERT(bitmap);
 
RENDER_START(swrast,ctx);
 
if (SWRAST_CONTEXT(ctx)->NewState)
_swrast_validate_derived( ctx );
 
INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_MASK);
 
/*span.arrayMask |= SPAN_MASK;*/ /* we'll init span.mask[] */
span.x = px;
span.y = py;
/*span.end = width;*/
if (ctx->Visual.rgbMode) {
span.interpMask |= SPAN_RGBA;
span.red = FloatToFixed(ctx->Current.RasterColor[0] * CHAN_MAXF);
span.green = FloatToFixed(ctx->Current.RasterColor[1] * CHAN_MAXF);
span.blue = FloatToFixed(ctx->Current.RasterColor[2] * CHAN_MAXF);
span.alpha = FloatToFixed(ctx->Current.RasterColor[3] * CHAN_MAXF);
span.redStep = span.greenStep = span.blueStep = span.alphaStep = 0;
}
else {
span.interpMask |= SPAN_INDEX;
span.index = ChanToFixed(ctx->Current.RasterIndex);
span.indexStep = 0;
}
 
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
 
for (row=0; row<height; row++, span.y++) {
const GLubyte *src = (const GLubyte *) _mesa_image_address( unpack,
bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, 0, row, 0 );
 
if (unpack->LsbFirst) {
/* Lsb first */
GLubyte mask = 1U << (unpack->SkipPixels & 0x7);
for (col=0; col<width; col++) {
span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
if (mask == 128U) {
src++;
mask = 1U;
}
else {
mask = mask << 1;
}
}
 
if (ctx->Visual.rgbMode)
_mesa_write_rgba_span(ctx, &span);
else
_mesa_write_index_span(ctx, &span);
 
/* get ready for next row */
if (mask != 1)
src++;
}
else {
/* Msb first */
GLubyte mask = 128U >> (unpack->SkipPixels & 0x7);
for (col=0; col<width; col++) {
span.array->mask[col] = (*src & mask) ? GL_TRUE : GL_FALSE;
if (mask == 1U) {
src++;
mask = 128U;
}
else {
mask = mask >> 1;
}
}
 
if (ctx->Visual.rgbMode)
_mesa_write_rgba_span(ctx, &span);
else
_mesa_write_index_span(ctx, &span);
 
/* get ready for next row */
if (mask != 128)
src++;
}
}
 
RENDER_FINISH(swrast,ctx);
}
#endif
/shark/trunk/ports/mesa/src/swrast/s_aatriangle.h
0,0 → 1,40
/* $Id: s_aatriangle.h,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef S_AATRIANGLE_H
#define S_AATRIANGLE_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void
_mesa_set_aa_triangle_function(GLcontext *ctx);
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_lines.h
0,0 → 1,42
/* $Id: s_lines.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef S_LINES_H
#define S_LINES_H
 
#include "mtypes.h"
 
void
_swrast_choose_line( GLcontext *ctx );
 
void
_swrast_add_spec_terms_line( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1 );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_fog.h
0,0 → 1,46
/* $Id: s_fog.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_FOG_H
#define S_FOG_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern GLfloat
_mesa_z_to_fogfactor(GLcontext *ctx, GLfloat z);
 
extern void
_mesa_fog_rgba_span( const GLcontext *ctx, struct sw_span *span );
 
extern void
_mesa_fog_ci_span( const GLcontext *ctx, struct sw_span *span );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_alphabuf.c
0,0 → 1,335
/* $Id: s_alphabuf.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
/*
* Software alpha planes. Many frame buffers don't have alpha bits so
* we simulate them in software.
*/
 
 
#include "glheader.h"
#include "context.h"
#include "imports.h"
 
#include "s_context.h"
#include "s_alphabuf.h"
 
 
/*
* Allocate a new front and back alpha buffer.
*/
void
_mesa_alloc_alpha_buffers( GLframebuffer *buffer )
{
const GLint bytes = buffer->Width * buffer->Height * sizeof(GLchan);
 
ASSERT(buffer->UseSoftwareAlphaBuffers);
 
if (buffer->FrontLeftAlpha) {
MESA_PBUFFER_FREE( buffer->FrontLeftAlpha );
}
buffer->FrontLeftAlpha = MESA_PBUFFER_ALLOC( bytes );
if (!buffer->FrontLeftAlpha) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY,
"Couldn't allocate front-left alpha buffer" );
}
 
if (buffer->Visual.doubleBufferMode) {
if (buffer->BackLeftAlpha) {
MESA_PBUFFER_FREE( buffer->BackLeftAlpha );
}
buffer->BackLeftAlpha = MESA_PBUFFER_ALLOC( bytes );
if (!buffer->BackLeftAlpha) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY,
"Couldn't allocate back-left alpha buffer" );
}
}
 
if (buffer->Visual.stereoMode) {
if (buffer->FrontRightAlpha) {
MESA_PBUFFER_FREE( buffer->FrontRightAlpha );
}
buffer->FrontRightAlpha = MESA_PBUFFER_ALLOC( bytes );
if (!buffer->FrontRightAlpha) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY,
"Couldn't allocate front-right alpha buffer" );
}
 
if (buffer->Visual.doubleBufferMode) {
if (buffer->BackRightAlpha) {
MESA_PBUFFER_FREE( buffer->BackRightAlpha );
}
buffer->BackRightAlpha = MESA_PBUFFER_ALLOC( bytes );
if (!buffer->BackRightAlpha) {
/* out of memory */
_mesa_error( NULL, GL_OUT_OF_MEMORY,
"Couldn't allocate back-right alpha buffer" );
}
}
}
}
 
 
/*
* Clear all the alpha buffers
*/
void
_mesa_clear_alpha_buffers( GLcontext *ctx )
{
const GLchan aclear = (GLchan) ctx->Color.ClearColor[3];
GLuint bufferBit;
 
ASSERT(ctx->DrawBuffer->UseSoftwareAlphaBuffers);
ASSERT(ctx->Color.ColorMask[ACOMP]);
 
/* loop over four possible alpha buffers */
for (bufferBit = 1; bufferBit <= 8; bufferBit = bufferBit << 1) {
if (bufferBit & ctx->Color._DrawDestMask) {
GLchan *buffer;
if (bufferBit == FRONT_LEFT_BIT) {
buffer = (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
}
else if (bufferBit == FRONT_RIGHT_BIT) {
buffer = (GLchan *) ctx->DrawBuffer->FrontRightAlpha;
}
else if (bufferBit == BACK_LEFT_BIT) {
buffer = (GLchan *) ctx->DrawBuffer->BackLeftAlpha;
}
else {
buffer = (GLchan *) ctx->DrawBuffer->BackRightAlpha;
}
 
if (ctx->Scissor.Enabled) {
/* clear scissor region */
GLint j;
GLint rowLen = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
GLint width = ctx->DrawBuffer->Width;
GLchan *aptr = buffer
+ ctx->DrawBuffer->_Ymin * ctx->DrawBuffer->Width
+ ctx->DrawBuffer->_Xmin;
for (j = 0; j < rows; j++) {
#if CHAN_BITS == 8
MEMSET( aptr, aclear, rowLen );
#elif CHAN_BITS == 16
MEMSET16( aptr, aclear, rowLen );
#else
GLint i;
for (i = 0; i < rowLen; i++) {
aptr[i] = aclear;
}
#endif
aptr += width;
}
}
else {
/* clear whole buffer */
GLuint pixels = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
#if CHAN_BITS == 8
MEMSET(buffer, aclear, pixels);
#elif CHAN_BITS == 16
MEMSET16(buffer, aclear, pixels);
#else
GLuint i;
for (i = 0; i < pixels; i++) {
buffer[i] = aclear;
}
#endif
}
}
}
}
 
 
 
static INLINE
GLchan *get_alpha_buffer( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
switch (swrast->CurrentBuffer) {
case FRONT_LEFT_BIT:
return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
break;
case BACK_LEFT_BIT:
return (GLchan *) ctx->DrawBuffer->BackLeftAlpha;
break;
case FRONT_RIGHT_BIT:
return (GLchan *) ctx->DrawBuffer->FrontRightAlpha;
break;
case BACK_RIGHT_BIT:
return (GLchan *) ctx->DrawBuffer->BackRightAlpha;
break;
default:
_mesa_problem(ctx, "Bad CurrentBuffer in get_alpha_buffer()");
return (GLchan *) ctx->DrawBuffer->FrontLeftAlpha;
}
}
 
 
void
_mesa_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
CONST GLchan rgba[][4], const GLubyte mask[] )
{
GLchan *buffer, *aptr;
GLuint i;
 
buffer = get_alpha_buffer(ctx);
aptr = buffer + y * ctx->DrawBuffer->Width + x;
 
if (mask) {
for (i=0;i<n;i++) {
if (mask[i]) {
*aptr = rgba[i][ACOMP];
}
aptr++;
}
}
else {
for (i=0;i<n;i++) {
*aptr++ = rgba[i][ACOMP];
}
}
}
 
 
void
_mesa_write_mono_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
GLchan alpha, const GLubyte mask[] )
{
GLchan *buffer, *aptr;
GLuint i;
 
buffer = get_alpha_buffer(ctx);
aptr = buffer + y * ctx->DrawBuffer->Width + x;
 
if (mask) {
for (i=0;i<n;i++) {
if (mask[i]) {
*aptr = alpha;
}
aptr++;
}
}
else {
for (i=0;i<n;i++) {
*aptr++ = alpha;
}
}
}
 
 
void
_mesa_write_alpha_pixels( GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
CONST GLchan rgba[][4], const GLubyte mask[] )
{
GLchan *buffer;
GLuint i;
 
buffer = get_alpha_buffer(ctx);
 
if (mask) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
*aptr = rgba[i][ACOMP];
}
}
}
else {
for (i=0;i<n;i++) {
GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
*aptr = rgba[i][ACOMP];
}
}
}
 
 
void
_mesa_write_mono_alpha_pixels( GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLchan alpha, const GLubyte mask[] )
{
GLchan *buffer;
GLuint i;
 
buffer = get_alpha_buffer(ctx);
 
if (mask) {
for (i=0;i<n;i++) {
if (mask[i]) {
GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
*aptr = alpha;
}
}
}
else {
for (i=0;i<n;i++) {
GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
*aptr = alpha;
}
}
}
 
 
 
void
_mesa_read_alpha_span( GLcontext *ctx,
GLuint n, GLint x, GLint y, GLchan rgba[][4] )
{
const GLchan *buffer, *aptr;
GLuint i;
 
buffer = get_alpha_buffer(ctx);
aptr = buffer + y * ctx->DrawBuffer->Width + x;
 
for (i = 0; i < n; i++)
rgba[i][ACOMP] = *aptr++;
}
 
 
void
_mesa_read_alpha_pixels( GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLchan rgba[][4], const GLubyte mask[] )
{
const GLchan *buffer;
GLuint i;
 
buffer = get_alpha_buffer(ctx);
 
for (i = 0; i < n; i++) {
if (mask[i]) {
const GLchan *aptr = buffer + y[i] * ctx->DrawBuffer->Width + x[i];
rgba[i][ACOMP] = *aptr;
}
}
}
/shark/trunk/ports/mesa/src/swrast/s_zoom.c
0,0 → 1,346
/* $Id: s_zoom.c,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* 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.
*/
 
#include "glheader.h"
#include "macros.h"
#include "imports.h"
#include "colormac.h"
 
#include "s_context.h"
#include "s_span.h"
#include "s_stencil.h"
#include "s_zoom.h"
 
 
/*
* Helper function called from _mesa_write_zoomed_rgba/rgb/index_span().
*/
static void
zoom_span( GLcontext *ctx, const struct sw_span *span,
const GLvoid *src, GLint y0, GLenum format )
{
GLint r0, r1, row;
GLint c0, c1, skipCol;
GLint i, j;
const GLuint maxWidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
GLchan rgbaSave[MAX_WIDTH][4];
GLuint indexSave[MAX_WIDTH];
const GLchan (*rgba)[4] = (const GLchan (*)[4]) src;
const GLchan (*rgb)[3] = (const GLchan (*)[3]) src;
const GLuint *indexes = (const GLuint *) src;
struct sw_span zoomed;
struct span_arrays zoomed_arrays; /* this is big! */
 
/* no pixel arrays! */
ASSERT((span->arrayMask & SPAN_XY) == 0);
ASSERT(span->primitive == GL_BITMAP);
 
INIT_SPAN(zoomed, GL_BITMAP, 0, 0, 0);
zoomed.array = &zoomed_arrays;
 
if (format == GL_RGBA || format == GL_RGB) {
zoomed.z = span->z;
zoomed.zStep = span->z;
zoomed.fog = span->fog;
zoomed.fogStep = span->fogStep;
zoomed.interpMask = span->interpMask & ~SPAN_RGBA;
zoomed.arrayMask |= SPAN_RGBA;
}
else if (format == GL_COLOR_INDEX) {
zoomed.z = span->z;
zoomed.zStep = span->z;
zoomed.fog = span->fog;
zoomed.fogStep = span->fogStep;
zoomed.interpMask = span->interpMask & ~SPAN_INDEX;
zoomed.arrayMask |= SPAN_INDEX;
}
 
/*
* Compute which columns to draw: [c0, c1)
*/
c0 = (GLint) span->x;
c1 = (GLint) (span->x + span->end * ctx->Pixel.ZoomX);
if (c0 == c1) {
return;
}
else if (c1 < c0) {
/* swap */
GLint ctmp = c1;
c1 = c0;
c0 = ctmp;
}
if (c0 < 0) {
zoomed.x = 0;
zoomed.start = 0;
zoomed.end = c1;
skipCol = -c0;
}
else {
zoomed.x = c0;
zoomed.start = 0;
zoomed.end = c1 - c0;
skipCol = 0;
}
if (zoomed.end > maxWidth)
zoomed.end = maxWidth;
 
/*
* Compute which rows to draw: [r0, r1)
*/
row = span->y - y0;
r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
if (r0 == r1) {
return;
}
else if (r1 < r0) {
/* swap */
GLint rtmp = r1;
r1 = r0;
r0 = rtmp;
}
 
ASSERT(r0 < r1);
ASSERT(c0 < c1);
 
/*
* Trivial clip rejection testing.
*/
if (r1 < 0) /* below window */
return;
if (r0 >= (GLint) ctx->DrawBuffer->Height) /* above window */
return;
if (c1 < 0) /* left of window */
return;
if (c0 >= (GLint) ctx->DrawBuffer->Width) /* right of window */
return;
 
/* zoom the span horizontally */
if (format == GL_RGBA) {
if (ctx->Pixel.ZoomX == -1.0F) {
/* common case */
for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
i = span->end - (j + skipCol) - 1;
COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
}
}
else {
/* general solution */
const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
i = (GLint) ((j + skipCol) * xscale);
if (i < 0)
i = span->end + i - 1;
COPY_CHAN4(zoomed.array->rgba[j], rgba[i]);
}
}
}
else if (format == GL_RGB) {
if (ctx->Pixel.ZoomX == -1.0F) {
/* common case */
for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
i = span->end - (j + skipCol) - 1;
zoomed.array->rgba[j][0] = rgb[i][0];
zoomed.array->rgba[j][1] = rgb[i][1];
zoomed.array->rgba[j][2] = rgb[i][2];
zoomed.array->rgba[j][3] = CHAN_MAX;
}
}
else {
/* general solution */
const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
i = (GLint) ((j + skipCol) * xscale);
if (i < 0)
i = span->end + i - 1;
zoomed.array->rgba[j][0] = rgb[i][0];
zoomed.array->rgba[j][1] = rgb[i][1];
zoomed.array->rgba[j][2] = rgb[i][2];
zoomed.array->rgba[j][3] = CHAN_MAX;
}
}
}
else if (format == GL_COLOR_INDEX) {
if (ctx->Pixel.ZoomX == -1.0F) {
/* common case */
for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
i = span->end - (j + skipCol) - 1;
zoomed.array->index[j] = indexes[i];
}
}
else {
/* general solution */
const GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j = (GLint) zoomed.start; j < (GLint) zoomed.end; j++) {
i = (GLint) ((j + skipCol) * xscale);
if (i < 0)
i = span->end + i - 1;
zoomed.array->index[j] = indexes[i];
}
}
}
 
/* write the span in rows [r0, r1) */
if (format == GL_RGBA || format == GL_RGB) {
/* Writing the span may modify the colors, so make a backup now if we're
* going to call _mesa_write_zoomed_span() more than once.
*/
if (r1 - r0 > 1) {
MEMCPY(rgbaSave, zoomed.array->rgba, zoomed.end * 4 * sizeof(GLchan));
}
for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
_mesa_write_rgba_span(ctx, &zoomed);
if (r1 - r0 > 1) {
/* restore the colors */
MEMCPY(zoomed.array->rgba, rgbaSave, zoomed.end*4 * sizeof(GLchan));
}
}
}
else if (format == GL_COLOR_INDEX) {
if (r1 - r0 > 1) {
MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint));
}
for (zoomed.y = r0; zoomed.y < r1; zoomed.y++) {
_mesa_write_index_span(ctx, &zoomed);
if (r1 - r0 > 1) {
/* restore the colors */
MEMCPY(zoomed.array->index, indexSave, zoomed.end * sizeof(GLuint));
}
}
}
}
 
 
void
_mesa_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgba[][4], GLint y0 )
{
zoom_span(ctx, span, (const GLvoid *) rgba, y0, GL_RGBA);
}
 
 
void
_mesa_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgb[][3], GLint y0 )
{
zoom_span(ctx, span, (const GLvoid *) rgb, y0, GL_RGB);
}
 
 
void
_mesa_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
GLint y0 )
{
zoom_span(ctx, span, (const GLvoid *) span->array->index, y0, GL_COLOR_INDEX);
}
 
 
/*
* As above, but write stencil values.
*/
void
_mesa_write_zoomed_stencil_span( GLcontext *ctx,
GLuint n, GLint x, GLint y,
const GLstencil stencil[], GLint y0 )
{
GLint m;
GLint r0, r1, row, r;
GLint i, j, skipcol;
GLstencil zstencil[MAX_WIDTH]; /* zoomed stencil values */
GLint maxwidth = MIN2( ctx->DrawBuffer->Width, MAX_WIDTH );
 
/* compute width of output row */
m = (GLint) ABSF( n * ctx->Pixel.ZoomX );
if (m==0) {
return;
}
if (ctx->Pixel.ZoomX<0.0) {
/* adjust x coordinate for left/right mirroring */
x = x - m;
}
 
/* compute which rows to draw */
row = y-y0;
r0 = y0 + (GLint) (row * ctx->Pixel.ZoomY);
r1 = y0 + (GLint) ((row+1) * ctx->Pixel.ZoomY);
if (r0==r1) {
return;
}
else if (r1<r0) {
GLint rtmp = r1;
r1 = r0;
r0 = rtmp;
}
 
/* return early if r0...r1 is above or below window */
if (r0<0 && r1<0) {
/* below window */
return;
}
if (r0 >= (GLint) ctx->DrawBuffer->Height &&
r1 >= (GLint) ctx->DrawBuffer->Height) {
/* above window */
return;
}
 
/* check if left edge is outside window */
skipcol = 0;
if (x<0) {
skipcol = -x;
m += x;
}
/* make sure span isn't too long or short */
if (m>maxwidth) {
m = maxwidth;
}
else if (m<=0) {
return;
}
 
ASSERT( m <= MAX_WIDTH );
 
/* zoom the span horizontally */
if (ctx->Pixel.ZoomX==-1.0F) {
/* n==m */
for (j=0;j<m;j++) {
i = n - (j+skipcol) - 1;
zstencil[j] = stencil[i];
}
}
else {
GLfloat xscale = 1.0F / ctx->Pixel.ZoomX;
for (j=0;j<m;j++) {
i = (GLint) ((j+skipcol) * xscale);
if (i<0) i = n + i - 1;
zstencil[j] = stencil[i];
}
}
 
/* write the span */
for (r=r0; r<r1; r++) {
_mesa_write_stencil_span( ctx, m, x+skipcol, r, zstencil );
}
}
/shark/trunk/ports/mesa/src/swrast/s_aalinetemp.h
0,0 → 1,315
/* $Id: s_aalinetemp.h,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*/
 
 
/*
* Antialiased line template.
*/
 
 
/*
* Function to render each fragment in the AA line.
*/
static void
NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy)
{
const GLfloat fx = (GLfloat) ix;
const GLfloat fy = (GLfloat) iy;
const GLfloat coverage = compute_coveragef(line, ix, iy);
const GLuint i = line->span.end;
 
if (coverage == 0.0)
return;
 
line->span.end++;
line->span.array->coverage[i] = coverage;
line->span.array->x[i] = ix;
line->span.array->y[i] = iy;
 
/*
* Compute Z, color, texture coords, fog for the fragment by
* solving the plane equations at (ix,iy).
*/
#ifdef DO_Z
line->span.array->z[i] = (GLdepth) solve_plane(fx, fy, line->zPlane);
#endif
#ifdef DO_FOG
line->span.array->fog[i] = solve_plane(fx, fy, line->fPlane);
#endif
#ifdef DO_RGBA
line->span.array->rgba[i][RCOMP] = solve_plane_chan(fx, fy, line->rPlane);
line->span.array->rgba[i][GCOMP] = solve_plane_chan(fx, fy, line->gPlane);
line->span.array->rgba[i][BCOMP] = solve_plane_chan(fx, fy, line->bPlane);
line->span.array->rgba[i][ACOMP] = solve_plane_chan(fx, fy, line->aPlane);
#endif
#ifdef DO_INDEX
line->span.array->index[i] = (GLint) solve_plane(fx, fy, line->iPlane);
#endif
#ifdef DO_SPEC
line->span.array->spec[i][RCOMP] = solve_plane_chan(fx, fy, line->srPlane);
line->span.array->spec[i][GCOMP] = solve_plane_chan(fx, fy, line->sgPlane);
line->span.array->spec[i][BCOMP] = solve_plane_chan(fx, fy, line->sbPlane);
#endif
#ifdef DO_TEX
{
const GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[0]);
line->span.array->texcoords[0][i][0] = solve_plane(fx, fy, line->sPlane[0]) * invQ;
line->span.array->texcoords[0][i][1] = solve_plane(fx, fy, line->tPlane[0]) * invQ;
line->span.array->texcoords[0][i][2] = solve_plane(fx, fy, line->uPlane[0]) * invQ;
line->span.array->lambda[0][i] = compute_lambda(line->sPlane[0], line->tPlane[0], invQ,
line->texWidth[0], line->texHeight[0]);
}
#elif defined(DO_MULTITEX)
{
GLuint unit;
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
const GLfloat invQ = solve_plane_recip(fx, fy, line->vPlane[unit]);
line->span.array->texcoords[unit][i][0] = solve_plane(fx, fy, line->sPlane[unit]) * invQ;
line->span.array->texcoords[unit][i][1] = solve_plane(fx, fy, line->tPlane[unit]) * invQ;
line->span.array->texcoords[unit][i][2] = solve_plane(fx, fy, line->uPlane[unit]) * invQ;
line->span.array->lambda[unit][i] = compute_lambda(line->sPlane[unit],
line->tPlane[unit], invQ,
line->texWidth[unit], line->texHeight[unit]);
}
}
}
#endif
 
if (line->span.end == MAX_WIDTH) {
#if defined(DO_TEX) || defined(DO_MULTITEX)
_mesa_write_texture_span(ctx, &(line->span));
#elif defined(DO_RGBA)
_mesa_write_rgba_span(ctx, &(line->span));
#else
_mesa_write_index_span(ctx, &(line->span));
#endif
line->span.end = 0; /* reset counter */
}
}
 
 
 
/*
* Line setup
*/
static void
NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLfloat tStart, tEnd; /* segment start, end along line length */
GLboolean inSegment;
GLint iLen, i;
 
/* Init the LineInfo struct */
struct LineInfo line;
line.x0 = v0->win[0];
line.y0 = v0->win[1];
line.x1 = v1->win[0];
line.y1 = v1->win[1];
line.dx = line.x1 - line.x0;
line.dy = line.y1 - line.y0;
line.len = (GLfloat) sqrt(line.dx * line.dx + line.dy * line.dy);
line.halfWidth = 0.5F * ctx->Line.Width;
 
if (line.len == 0.0 || IS_INF_OR_NAN(line.len))
return;
 
INIT_SPAN(line.span, GL_LINE, 0, 0, SPAN_XY | SPAN_COVERAGE);
 
line.xAdj = line.dx / line.len * line.halfWidth;
line.yAdj = line.dy / line.len * line.halfWidth;
 
#ifdef DO_Z
line.span.arrayMask |= SPAN_Z;
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->win[2], v1->win[2], line.zPlane);
#endif
#ifdef DO_FOG
line.span.arrayMask |= SPAN_FOG;
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->fog, v1->fog, line.fPlane);
#endif
#ifdef DO_RGBA
line.span.arrayMask |= SPAN_RGBA;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->color[RCOMP], v1->color[RCOMP], line.rPlane);
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->color[GCOMP], v1->color[GCOMP], line.gPlane);
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->color[BCOMP], v1->color[BCOMP], line.bPlane);
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->color[ACOMP], v1->color[ACOMP], line.aPlane);
}
else {
constant_plane(v1->color[RCOMP], line.rPlane);
constant_plane(v1->color[GCOMP], line.gPlane);
constant_plane(v1->color[BCOMP], line.bPlane);
constant_plane(v1->color[ACOMP], line.aPlane);
}
#endif
#ifdef DO_SPEC
line.span.arrayMask |= SPAN_SPEC;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->specular[RCOMP], v1->specular[RCOMP], line.srPlane);
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->specular[GCOMP], v1->specular[GCOMP], line.sgPlane);
compute_plane(line.x0, line.y0, line.x1, line.y1,
v0->specular[BCOMP], v1->specular[BCOMP], line.sbPlane);
}
else {
constant_plane(v1->specular[RCOMP], line.srPlane);
constant_plane(v1->specular[GCOMP], line.sgPlane);
constant_plane(v1->specular[BCOMP], line.sbPlane);
}
#endif
#ifdef DO_INDEX
line.span.arrayMask |= SPAN_INDEX;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
compute_plane(line.x0, line.y0, line.x1, line.y1,
(GLfloat) v0->index, (GLfloat) v1->index, line.iPlane);
}
else {
constant_plane((GLfloat) v1->index, line.iPlane);
}
#endif
#ifdef DO_TEX
{
const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
const GLfloat invW0 = v0->win[3];
const GLfloat invW1 = v1->win[3];
const GLfloat s0 = v0->texcoord[0][0] * invW0;
const GLfloat s1 = v1->texcoord[0][0] * invW1;
const GLfloat t0 = v0->texcoord[0][1] * invW0;
const GLfloat t1 = v1->texcoord[0][1] * invW0;
const GLfloat r0 = v0->texcoord[0][2] * invW0;
const GLfloat r1 = v1->texcoord[0][2] * invW0;
const GLfloat q0 = v0->texcoord[0][3] * invW0;
const GLfloat q1 = v1->texcoord[0][3] * invW0;
line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[0]);
compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[0]);
compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[0]);
compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[0]);
line.texWidth[0] = (GLfloat) texImage->Width;
line.texHeight[0] = (GLfloat) texImage->Height;
}
#elif defined(DO_MULTITEX)
{
GLuint u;
line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA);
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current;
const struct gl_texture_image *texImage = obj->Image[obj->BaseLevel];
const GLfloat invW0 = v0->win[3];
const GLfloat invW1 = v1->win[3];
const GLfloat s0 = v0->texcoord[u][0] * invW0;
const GLfloat s1 = v1->texcoord[u][0] * invW1;
const GLfloat t0 = v0->texcoord[u][1] * invW0;
const GLfloat t1 = v1->texcoord[u][1] * invW0;
const GLfloat r0 = v0->texcoord[u][2] * invW0;
const GLfloat r1 = v1->texcoord[u][2] * invW0;
const GLfloat q0 = v0->texcoord[u][3] * invW0;
const GLfloat q1 = v1->texcoord[u][3] * invW0;
compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[u]);
compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[u]);
compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[u]);
compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[u]);
line.texWidth[u] = (GLfloat) texImage->Width;
line.texHeight[u] = (GLfloat) texImage->Height;
}
}
}
#endif
 
tStart = tEnd = 0.0;
inSegment = GL_FALSE;
iLen = (GLint) line.len;
 
if (ctx->Line.StippleFlag) {
for (i = 0; i < iLen; i++) {
const GLuint bit = (swrast->StippleCounter / ctx->Line.StippleFactor) & 0xf;
if ((1 << bit) & ctx->Line.StipplePattern) {
/* stipple bit is on */
const GLfloat t = (GLfloat) i / (GLfloat) line.len;
if (!inSegment) {
/* start new segment */
inSegment = GL_TRUE;
tStart = t;
}
else {
/* still in the segment, extend it */
tEnd = t;
}
}
else {
/* stipple bit is off */
if (inSegment && (tEnd > tStart)) {
/* draw the segment */
segment(ctx, &line, NAME(plot), tStart, tEnd);
inSegment = GL_FALSE;
}
else {
/* still between segments, do nothing */
}
}
swrast->StippleCounter++;
}
 
if (inSegment) {
/* draw the final segment of the line */
segment(ctx, &line, NAME(plot), tStart, 1.0F);
}
}
else {
/* non-stippled */
segment(ctx, &line, NAME(plot), 0.0, 1.0);
}
 
#if defined(DO_TEX) || defined(DO_MULTITEX)
_mesa_write_texture_span(ctx, &(line.span));
#elif defined(DO_RGBA)
_mesa_write_rgba_span(ctx, &(line.span));
#else
_mesa_write_index_span(ctx, &(line.span));
#endif
}
 
 
 
 
#undef DO_Z
#undef DO_FOG
#undef DO_RGBA
#undef DO_INDEX
#undef DO_SPEC
#undef DO_TEX
#undef DO_MULTITEX
#undef NAME
/shark/trunk/ports/mesa/src/swrast/s_context.c
0,0 → 1,660
/* $Id: s_context.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
 
#include "glheader.h"
#include "context.h"
#include "mtypes.h"
#include "imports.h"
 
#include "swrast.h"
#include "s_blend.h"
#include "s_context.h"
#include "s_lines.h"
#include "s_points.h"
#include "s_span.h"
#include "s_triangle.h"
#include "s_texture.h"
 
 
/*
* Recompute the value of swrast->_RasterMask, etc. according to
* the current context.
*/
static void
_swrast_update_rasterflags( GLcontext *ctx )
{
GLuint RasterMask = 0;
 
if (ctx->Color.AlphaEnabled) RasterMask |= ALPHATEST_BIT;
if (ctx->Color.BlendEnabled) RasterMask |= BLEND_BIT;
if (ctx->Depth.Test) RasterMask |= DEPTH_BIT;
if (ctx->Fog.Enabled) RasterMask |= FOG_BIT;
if (ctx->Scissor.Enabled) RasterMask |= CLIP_BIT;
if (ctx->Stencil.Enabled) RasterMask |= STENCIL_BIT;
if (ctx->Visual.rgbMode) {
const GLuint colorMask = *((GLuint *) &ctx->Color.ColorMask);
if (colorMask != 0xffffffff) RasterMask |= MASKING_BIT;
if (ctx->Color.ColorLogicOpEnabled) RasterMask |= LOGIC_OP_BIT;
if (ctx->Texture._EnabledUnits) RasterMask |= TEXTURE_BIT;
}
else {
if (ctx->Color.IndexMask != 0xffffffff) RasterMask |= MASKING_BIT;
if (ctx->Color.IndexLogicOpEnabled) RasterMask |= LOGIC_OP_BIT;
}
 
if (ctx->DrawBuffer->UseSoftwareAlphaBuffers
&& ctx->Color.ColorMask[ACOMP]
&& ctx->Color.DrawBuffer != GL_NONE)
RasterMask |= ALPHABUF_BIT;
 
if ( ctx->Viewport.X < 0
|| ctx->Viewport.X + ctx->Viewport.Width > (GLint) ctx->DrawBuffer->Width
|| ctx->Viewport.Y < 0
|| ctx->Viewport.Y + ctx->Viewport.Height > (GLint) ctx->DrawBuffer->Height) {
RasterMask |= CLIP_BIT;
}
 
if (ctx->Depth.OcclusionTest)
RasterMask |= OCCLUSION_BIT;
 
 
/* If we're not drawing to exactly one color buffer set the
* MULTI_DRAW_BIT flag. Also set it if we're drawing to no
* buffers or the RGBA or CI mask disables all writes.
*/
if (ctx->Color._DrawDestMask != FRONT_LEFT_BIT &&
ctx->Color._DrawDestMask != BACK_LEFT_BIT &&
ctx->Color._DrawDestMask != FRONT_RIGHT_BIT &&
ctx->Color._DrawDestMask != BACK_RIGHT_BIT) {
/* more than one color buffer designated for writing (or zero buffers) */
RasterMask |= MULTI_DRAW_BIT;
}
else if (ctx->Visual.rgbMode && *((GLuint *) ctx->Color.ColorMask) == 0) {
RasterMask |= MULTI_DRAW_BIT; /* all RGBA channels disabled */
}
else if (!ctx->Visual.rgbMode && ctx->Color.IndexMask==0) {
RasterMask |= MULTI_DRAW_BIT; /* all color index bits disabled */
}
 
SWRAST_CONTEXT(ctx)->_RasterMask = RasterMask;
}
 
 
static void
_swrast_update_polygon( GLcontext *ctx )
{
GLfloat backface_sign = 1;
 
if (ctx->Polygon.CullFlag) {
backface_sign = 1;
switch(ctx->Polygon.CullFaceMode) {
case GL_BACK:
if(ctx->Polygon.FrontFace==GL_CCW)
backface_sign = -1;
break;
case GL_FRONT:
if(ctx->Polygon.FrontFace!=GL_CCW)
backface_sign = -1;
break;
default:
case GL_FRONT_AND_BACK:
backface_sign = 0;
break;
}
}
else {
backface_sign = 0;
}
 
SWRAST_CONTEXT(ctx)->_backface_sign = backface_sign;
}
 
 
static void
_swrast_update_hint( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
swrast->_PreferPixelFog = (!swrast->AllowVertexFog ||
(ctx->Hint.Fog == GL_NICEST &&
swrast->AllowPixelFog));
}
 
 
/*
* Update the swrast->_AnyTextureCombine flag.
*/
static void
_swrast_update_texture_env( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint i;
swrast->_AnyTextureCombine = GL_FALSE;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
if (ctx->Texture.Unit[i].EnvMode == GL_COMBINE_EXT ||
ctx->Texture.Unit[i].EnvMode == GL_COMBINE4_NV) {
swrast->_AnyTextureCombine = GL_TRUE;
return;
}
}
}
 
 
#define _SWRAST_NEW_DERIVED (_SWRAST_NEW_RASTERMASK | \
_NEW_TEXTURE | \
_NEW_HINT | \
_NEW_POLYGON )
 
/* State referenced by _swrast_choose_triangle, _swrast_choose_line.
*/
#define _SWRAST_NEW_TRIANGLE (_SWRAST_NEW_DERIVED | \
_NEW_RENDERMODE| \
_NEW_POLYGON| \
_NEW_DEPTH| \
_NEW_STENCIL| \
_NEW_COLOR| \
_NEW_TEXTURE| \
_SWRAST_NEW_RASTERMASK| \
_NEW_LIGHT| \
_NEW_FOG | \
_DD_NEW_SEPARATE_SPECULAR)
 
#define _SWRAST_NEW_LINE (_SWRAST_NEW_DERIVED | \
_NEW_RENDERMODE| \
_NEW_LINE| \
_NEW_TEXTURE| \
_NEW_LIGHT| \
_NEW_FOG| \
_NEW_DEPTH | \
_DD_NEW_SEPARATE_SPECULAR)
 
#define _SWRAST_NEW_POINT (_SWRAST_NEW_DERIVED | \
_NEW_RENDERMODE | \
_NEW_POINT | \
_NEW_TEXTURE | \
_NEW_LIGHT | \
_NEW_FOG | \
_DD_NEW_SEPARATE_SPECULAR)
 
#define _SWRAST_NEW_TEXTURE_SAMPLE_FUNC _NEW_TEXTURE
 
#define _SWRAST_NEW_TEXTURE_ENV_MODE _NEW_TEXTURE
 
#define _SWRAST_NEW_BLEND_FUNC _NEW_COLOR
 
 
 
/* Stub for swrast->Triangle to select a true triangle function
* after a state change.
*/
static void
_swrast_validate_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
_swrast_validate_derived( ctx );
swrast->choose_triangle( ctx );
 
if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) &&
ctx->Texture._EnabledUnits == 0) {
swrast->SpecTriangle = swrast->Triangle;
swrast->Triangle = _swrast_add_spec_terms_triangle;
}
 
swrast->Triangle( ctx, v0, v1, v2 );
}
 
static void
_swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
_swrast_validate_derived( ctx );
swrast->choose_line( ctx );
 
if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) &&
ctx->Texture._EnabledUnits == 0) {
swrast->SpecLine = swrast->Line;
swrast->Line = _swrast_add_spec_terms_line;
}
 
 
swrast->Line( ctx, v0, v1 );
}
 
static void
_swrast_validate_point( GLcontext *ctx, const SWvertex *v0 )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
_swrast_validate_derived( ctx );
swrast->choose_point( ctx );
 
if ((ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) &&
ctx->Texture._EnabledUnits == 0) {
swrast->SpecPoint = swrast->Point;
swrast->Point = _swrast_add_spec_terms_point;
}
 
swrast->Point( ctx, v0 );
}
 
static void
_swrast_validate_blend_func( GLcontext *ctx, GLuint n,
const GLubyte mask[],
GLchan src[][4],
CONST GLchan dst[][4] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
_swrast_validate_derived( ctx );
_swrast_choose_blend_func( ctx );
 
swrast->BlendFunc( ctx, n, mask, src, dst );
}
 
 
static void
_swrast_validate_texture_sample( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
_swrast_validate_derived( ctx );
_swrast_choose_texture_sample_func( ctx, texUnit, tObj );
 
swrast->TextureSample[texUnit]( ctx, texUnit, tObj, n, texcoords,
lambda, rgba );
}
 
 
static void
_swrast_sleep( GLcontext *ctx, GLuint new_state )
{
}
 
 
static void
_swrast_invalidate_state( GLcontext *ctx, GLuint new_state )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint i;
 
swrast->NewState |= new_state;
 
/* After 10 statechanges without any swrast functions being called,
* put the module to sleep.
*/
if (++swrast->StateChanges > 10) {
swrast->InvalidateState = _swrast_sleep;
swrast->NewState = ~0;
new_state = ~0;
}
 
if (new_state & swrast->invalidate_triangle)
swrast->Triangle = _swrast_validate_triangle;
 
if (new_state & swrast->invalidate_line)
swrast->Line = _swrast_validate_line;
 
if (new_state & swrast->invalidate_point)
swrast->Point = _swrast_validate_point;
 
if (new_state & _SWRAST_NEW_BLEND_FUNC)
swrast->BlendFunc = _swrast_validate_blend_func;
 
if (new_state & _SWRAST_NEW_TEXTURE_SAMPLE_FUNC)
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
swrast->TextureSample[i] = _swrast_validate_texture_sample;
 
if (ctx->Visual.rgbMode) {
ASSERT(swrast->Driver.WriteRGBASpan);
ASSERT(swrast->Driver.WriteRGBSpan);
ASSERT(swrast->Driver.WriteMonoRGBASpan);
ASSERT(swrast->Driver.WriteRGBAPixels);
ASSERT(swrast->Driver.WriteMonoRGBAPixels);
ASSERT(swrast->Driver.ReadRGBASpan);
ASSERT(swrast->Driver.ReadRGBAPixels);
}
else {
ASSERT(swrast->Driver.WriteCI32Span);
ASSERT(swrast->Driver.WriteCI8Span);
ASSERT(swrast->Driver.WriteMonoCISpan);
ASSERT(swrast->Driver.WriteCI32Pixels);
ASSERT(swrast->Driver.WriteMonoCIPixels);
ASSERT(swrast->Driver.ReadCI32Span);
ASSERT(swrast->Driver.ReadCI32Pixels);
}
}
 
 
void
_swrast_validate_derived( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
if (swrast->NewState) {
if (swrast->NewState & _SWRAST_NEW_RASTERMASK)
_swrast_update_rasterflags( ctx );
 
if (swrast->NewState & _NEW_POLYGON)
_swrast_update_polygon( ctx );
 
if (swrast->NewState & _NEW_HINT)
_swrast_update_hint( ctx );
 
if (swrast->NewState & _SWRAST_NEW_TEXTURE_ENV_MODE)
_swrast_update_texture_env( ctx );
 
swrast->NewState = 0;
swrast->StateChanges = 0;
swrast->InvalidateState = _swrast_invalidate_state;
}
}
 
#define SWRAST_DEBUG 0
 
/* Public entrypoints: See also s_accum.c, s_bitmap.c, etc.
*/
void
_swrast_Quad( GLcontext *ctx,
const SWvertex *v0, const SWvertex *v1,
const SWvertex *v2, const SWvertex *v3 )
{
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_Quad\n");
_swrast_print_vertex( ctx, v0 );
_swrast_print_vertex( ctx, v1 );
_swrast_print_vertex( ctx, v2 );
_swrast_print_vertex( ctx, v3 );
}
SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v3 );
SWRAST_CONTEXT(ctx)->Triangle( ctx, v1, v2, v3 );
}
 
void
_swrast_Triangle( GLcontext *ctx, const SWvertex *v0,
const SWvertex *v1, const SWvertex *v2 )
{
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_Triangle\n");
_swrast_print_vertex( ctx, v0 );
_swrast_print_vertex( ctx, v1 );
_swrast_print_vertex( ctx, v2 );
}
SWRAST_CONTEXT(ctx)->Triangle( ctx, v0, v1, v2 );
}
 
void
_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_Line\n");
_swrast_print_vertex( ctx, v0 );
_swrast_print_vertex( ctx, v1 );
}
SWRAST_CONTEXT(ctx)->Line( ctx, v0, v1 );
}
 
void
_swrast_Point( GLcontext *ctx, const SWvertex *v0 )
{
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_Point\n");
_swrast_print_vertex( ctx, v0 );
}
SWRAST_CONTEXT(ctx)->Point( ctx, v0 );
}
 
void
_swrast_InvalidateState( GLcontext *ctx, GLuint new_state )
{
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_InvalidateState\n");
}
SWRAST_CONTEXT(ctx)->InvalidateState( ctx, new_state );
}
 
void
_swrast_ResetLineStipple( GLcontext *ctx )
{
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_ResetLineStipple\n");
}
SWRAST_CONTEXT(ctx)->StippleCounter = 0;
}
 
void
_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value )
{
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_allow_vertex_fog %d\n", value);
}
SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
SWRAST_CONTEXT(ctx)->AllowVertexFog = value;
}
 
void
_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value )
{
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_allow_pixel_fog %d\n", value);
}
SWRAST_CONTEXT(ctx)->InvalidateState( ctx, _NEW_HINT );
SWRAST_CONTEXT(ctx)->AllowPixelFog = value;
}
 
 
GLboolean
_swrast_CreateContext( GLcontext *ctx )
{
GLuint i;
SWcontext *swrast = (SWcontext *)CALLOC(sizeof(SWcontext));
 
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_CreateContext\n");
}
 
if (!swrast)
return GL_FALSE;
 
swrast->NewState = ~0;
 
swrast->choose_point = _swrast_choose_point;
swrast->choose_line = _swrast_choose_line;
swrast->choose_triangle = _swrast_choose_triangle;
 
swrast->invalidate_point = _SWRAST_NEW_POINT;
swrast->invalidate_line = _SWRAST_NEW_LINE;
swrast->invalidate_triangle = _SWRAST_NEW_TRIANGLE;
 
swrast->Point = _swrast_validate_point;
swrast->Line = _swrast_validate_line;
swrast->Triangle = _swrast_validate_triangle;
swrast->InvalidateState = _swrast_sleep;
swrast->BlendFunc = _swrast_validate_blend_func;
 
swrast->AllowVertexFog = GL_TRUE;
swrast->AllowPixelFog = GL_TRUE;
 
if (ctx->Visual.doubleBufferMode)
swrast->CurrentBuffer = BACK_LEFT_BIT;
else
swrast->CurrentBuffer = FRONT_LEFT_BIT;
 
/* Optimized Accum buffer */
swrast->_IntegerAccumMode = GL_TRUE;
swrast->_IntegerAccumScaler = 0.0;
 
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++)
swrast->TextureSample[i] = _swrast_validate_texture_sample;
 
swrast->SpanArrays = MALLOC_STRUCT(span_arrays);
if (!swrast->SpanArrays) {
FREE(swrast);
return GL_FALSE;
}
 
/* init point span buffer */
swrast->PointSpan.primitive = GL_POINT;
swrast->PointSpan.start = 0;
swrast->PointSpan.end = 0;
swrast->PointSpan.facing = 0;
swrast->PointSpan.array = swrast->SpanArrays;
 
assert(ctx->Const.MaxTextureUnits > 0);
assert(ctx->Const.MaxTextureUnits <= MAX_TEXTURE_UNITS);
 
swrast->TexelBuffer = (GLchan *) MALLOC(ctx->Const.MaxTextureUnits *
MAX_WIDTH * 4 * sizeof(GLchan));
if (!swrast->TexelBuffer) {
FREE(swrast->SpanArrays);
FREE(swrast);
return GL_FALSE;
}
 
ctx->swrast_context = swrast;
 
return GL_TRUE;
}
 
void
_swrast_DestroyContext( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
if (SWRAST_DEBUG) {
_mesa_debug(ctx, "_swrast_DestroyContext\n");
}
 
FREE( swrast->SpanArrays );
FREE( swrast->TexelBuffer );
FREE( swrast );
 
ctx->swrast_context = 0;
}
 
 
struct swrast_device_driver *
_swrast_GetDeviceDriverReference( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
return &swrast->Driver;
}
 
void
_swrast_flush( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
/* flush any pending fragments from rendering points */
if (swrast->PointSpan.end > 0) {
if (ctx->Visual.rgbMode) {
if (ctx->Texture._EnabledUnits)
_mesa_write_texture_span(ctx, &(swrast->PointSpan));
else
_mesa_write_rgba_span(ctx, &(swrast->PointSpan));
}
else {
_mesa_write_index_span(ctx, &(swrast->PointSpan));
}
swrast->PointSpan.end = 0;
}
}
 
void
_swrast_render_primitive( GLcontext *ctx, GLenum prim )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
if (swrast->Primitive == GL_POINTS && prim != GL_POINTS) {
_swrast_flush(ctx);
}
swrast->Primitive = prim;
}
 
 
void
_swrast_render_start( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
if (swrast->Driver.SpanRenderStart)
swrast->Driver.SpanRenderStart( ctx );
swrast->PointSpan.end = 0;
}
void
_swrast_render_finish( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
if (swrast->Driver.SpanRenderFinish)
swrast->Driver.SpanRenderFinish( ctx );
 
_swrast_flush(ctx);
}
 
 
#define SWRAST_DEBUG_VERTICES 0
 
void
_swrast_print_vertex( GLcontext *ctx, const SWvertex *v )
{
GLuint i;
 
if (SWRAST_DEBUG_VERTICES) {
_mesa_debug(ctx, "win %f %f %f %f\n",
v->win[0], v->win[1], v->win[2], v->win[3]);
 
for (i = 0 ; i < ctx->Const.MaxTextureUnits ; i++)
if (ctx->Texture.Unit[i]._ReallyEnabled)
_mesa_debug(ctx, "texcoord[%d] %f %f %f %f\n", i,
v->texcoord[i][0], v->texcoord[i][1],
v->texcoord[i][2], v->texcoord[i][3]);
 
#if CHAN_TYPE == GL_FLOAT
_mesa_debug(ctx, "color %f %f %f %f\n",
v->color[0], v->color[1], v->color[2], v->color[3]);
_mesa_debug(ctx, "spec %f %f %f %f\n",
v->specular[0], v->specular[1],
v->specular[2], v->specular[3]);
#else
_mesa_debug(ctx, "color %d %d %d %d\n",
v->color[0], v->color[1], v->color[2], v->color[3]);
_mesa_debug(ctx, "spec %d %d %d %d\n",
v->specular[0], v->specular[1],
v->specular[2], v->specular[3]);
#endif
_mesa_debug(ctx, "fog %f\n", v->fog);
_mesa_debug(ctx, "index %d\n", v->index);
_mesa_debug(ctx, "pointsize %f\n", v->pointSize);
_mesa_debug(ctx, "\n");
}
}
/shark/trunk/ports/mesa/src/swrast/s_pointtemp.h
0,0 → 1,373
/* $Id: s_pointtemp.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 5.0
*
* 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.
*/
 
 
/*
* Point rendering template code.
*
* Set FLAGS = bitwise-OR of the following tokens:
*
* RGBA = do rgba instead of color index
* SMOOTH = do antialiasing
* TEXTURE = do texture coords
* SPECULAR = do separate specular color
* LARGE = do points with diameter > 1 pixel
* ATTENUATE = compute point size attenuation
* SPRITE = GL_NV_point_sprite
*
* Notes: LARGE and ATTENUATE are exclusive of each other.
* TEXTURE requires RGBA
* SPECULAR requires TEXTURE
*/
 
 
/*
* NOTES on antialiased point rasterization:
*
* Let d = distance of fragment center from vertex.
* if d < rmin2 then
* fragment has 100% coverage
* else if d > rmax2 then
* fragment has 0% coverage
* else
* fragment has % coverage = (d - rmin2) / (rmax2 - rmin2)
*/
 
 
 
static void
NAME ( GLcontext *ctx, const SWvertex *vert )
{
#if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
GLfloat size;
#endif
#if FLAGS & ATTENUATE
GLfloat alphaAtten;
#endif
#if FLAGS & RGBA
const GLchan red = vert->color[0];
const GLchan green = vert->color[1];
const GLchan blue = vert->color[2];
const GLchan alpha = vert->color[3];
#endif
#if FLAGS & SPECULAR
const GLchan specRed = vert->specular[0];
const GLchan specGreen = vert->specular[1];
const GLchan specBlue = vert->specular[2];
#endif
#if FLAGS & INDEX
const GLuint colorIndex = vert->index;
#endif
#if FLAGS & TEXTURE
GLfloat texcoord[MAX_TEXTURE_UNITS][4];
GLuint u;
#endif
SWcontext *swrast = SWRAST_CONTEXT(ctx);
struct sw_span *span = &(swrast->PointSpan);
 
/* Cull primitives with malformed coordinates.
*/
{
float tmp = vert->win[0] + vert->win[1];
if (IS_INF_OR_NAN(tmp))
return;
}
 
/*
* Span init
*/
span->interpMask = SPAN_FOG;
span->arrayMask = SPAN_XY | SPAN_Z;
span->fog = vert->fog;
span->fogStep = 0.0;
#if FLAGS & RGBA
span->arrayMask |= SPAN_RGBA;
#endif
#if FLAGS & SPECULAR
span->arrayMask |= SPAN_SPEC;
#endif
#if FLAGS & INDEX
span->arrayMask |= SPAN_INDEX;
#endif
#if FLAGS & TEXTURE
span->arrayMask |= SPAN_TEXTURE;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
const GLfloat q = vert->texcoord[u][3];
const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q);
texcoord[u][0] = vert->texcoord[u][0] * invQ;
texcoord[u][1] = vert->texcoord[u][1] * invQ;
texcoord[u][2] = vert->texcoord[u][2] * invQ;
texcoord[u][3] = q;
}
}
#endif
#if FLAGS & SMOOTH
span->arrayMask |= SPAN_COVERAGE;
#endif
#if FLAGS & SPRITE
span->arrayMask |= SPAN_TEXTURE;
#endif
 
#if FLAGS & ATTENUATE
if (vert->pointSize >= ctx->Point.Threshold) {
size = MIN2(vert->pointSize, ctx->Point.MaxSize);
alphaAtten = 1.0F;
}
else {
GLfloat dsize = vert->pointSize / ctx->Point.Threshold;
size = MAX2(ctx->Point.Threshold, ctx->Point.MinSize);
alphaAtten = dsize * dsize;
}
#elif FLAGS & (LARGE | SMOOTH | SPRITE)
size = ctx->Point._Size;
#endif
 
#if FLAGS & (ATTENUATE | LARGE | SMOOTH | SPRITE)
/*
* Multi-pixel points
*/
{{
GLint x, y;
const GLfloat radius = 0.5F * size;
const GLint z = (GLint) (vert->win[2] + 0.5F);
GLuint count;
#if FLAGS & SMOOTH
const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */
const GLfloat rmax = radius + 0.7071F;
const GLfloat rmin2 = MAX2(0.0F, rmin * rmin);
const GLfloat rmax2 = rmax * rmax;
const GLfloat cscale = 1.0F / (rmax2 - rmin2);
const GLint xmin = (GLint) (vert->win[0] - radius);
const GLint xmax = (GLint) (vert->win[0] + radius);
const GLint ymin = (GLint) (vert->win[1] - radius);
const GLint ymax = (GLint) (vert->win[1] + radius);
#else
/* non-smooth */
GLint xmin, xmax, ymin, ymax;
GLint iSize = (GLint) (size + 0.5F);
GLint iRadius;
iSize = MAX2(1, iSize);
iRadius = iSize / 2;
if (iSize & 1) {
/* odd size */
xmin = (GLint) (vert->win[0] - iRadius);
xmax = (GLint) (vert->win[0] + iRadius);
ymin = (GLint) (vert->win[1] - iRadius);
ymax = (GLint) (vert->win[1] + iRadius);
}
else {
/* even size */
xmin = (GLint) vert->win[0] - iRadius + 1;
xmax = xmin + iSize - 1;
ymin = (GLint) vert->win[1] - iRadius + 1;
ymax = ymin + iSize - 1;
}
#endif /*SMOOTH*/
 
/* check if we need to flush */
if (span->end + (xmax-xmin+1) * (ymax-ymin+1) >= MAX_WIDTH ||
(swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
#if FLAGS & (TEXTURE | SPRITE)
if (ctx->Texture._EnabledUnits)
_mesa_write_texture_span(ctx, span);
else
_mesa_write_rgba_span(ctx, span);
#elif FLAGS & RGBA
_mesa_write_rgba_span(ctx, span);
#else
_mesa_write_index_span(ctx, span);
#endif
span->end = 0;
}
 
/*
* OK, generate fragments
*/
count = span->end;
(void) radius;
for (y = ymin; y <= ymax; y++) {
for (x = xmin; x <= xmax; x++) {
#if FLAGS & (SPRITE | TEXTURE)
GLuint u;
#endif
 
#if FLAGS & RGBA
span->array->rgba[count][RCOMP] = red;
span->array->rgba[count][GCOMP] = green;
span->array->rgba[count][BCOMP] = blue;
span->array->rgba[count][ACOMP] = alpha;
#endif
#if FLAGS & SPECULAR
span->array->spec[count][RCOMP] = specRed;
span->array->spec[count][GCOMP] = specGreen;
span->array->spec[count][BCOMP] = specBlue;
#endif
#if FLAGS & INDEX
span->array->index[count] = colorIndex;
#endif
#if FLAGS & TEXTURE
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
COPY_4V(span->array->texcoords[u][count], texcoord[u]);
}
}
#endif
 
#if FLAGS & SMOOTH
/* compute coverage */
{
const GLfloat dx = x - vert->win[0] + 0.5F;
const GLfloat dy = y - vert->win[1] + 0.5F;
const GLfloat dist2 = dx * dx + dy * dy;
if (dist2 < rmax2) {
if (dist2 >= rmin2) {
/* compute partial coverage */
span->array->coverage[count] = 1.0F - (dist2 - rmin2) * cscale;
#if FLAGS & INDEX
/* coverage in [0,15] */
span->array->coverage[count] *= 15.0;
#endif
}
else {
/* full coverage */
span->array->coverage[count] = 1.0F;
}
 
span->array->x[count] = x;
span->array->y[count] = y;
span->array->z[count] = z;
 
#if (FLAGS & ATTENUATE) && (FLAGS & RGBA)
span->array->rgba[count][ACOMP] = (GLchan) (alpha * alphaAtten);
#elif FLAGS & RGBA
span->array->rgba[count][ACOMP] = alpha;
#endif /*ATTENUATE*/
count++;
} /*if*/
}
 
#else /*SMOOTH*/
 
/* not smooth (square points) */
span->array->x[count] = x;
span->array->y[count] = y;
span->array->z[count] = z;
 
#if FLAGS & SPRITE
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
if (ctx->Point.CoordReplace[u]) {
GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size;
GLfloat t = 0.5F - (y + 0.5F - vert->win[1]) / size;
span->array->texcoords[u][count][0] = s;
span->array->texcoords[u][count][1] = t;
span->array->texcoords[u][count][3] = 1.0F;
if (ctx->Point.SpriteRMode == GL_ZERO)
span->array->texcoords[u][count][2] = 0.0F;
else if (ctx->Point.SpriteRMode == GL_S)
span->array->texcoords[u][count][2] = vert->texcoord[u][0];
else /* GL_R */
span->array->texcoords[u][count][2] = vert->texcoord[u][2];
}
else {
COPY_4V(span->array->texcoords[u][count], vert->texcoord[u]);
}
}
}
#endif /*SPRITE*/
 
count++; /* square point */
 
#endif /*SMOOTH*/
 
} /*for x*/
} /*for y*/
span->end = count;
}}
 
#else /* LARGE | ATTENUATE | SMOOTH | SPRITE */
 
/*
* Single-pixel points
*/
{{
GLuint count;
 
/* check if we need to flush */
if (span->end >= MAX_WIDTH ||
(swrast->_RasterMask & (BLEND_BIT | LOGIC_OP_BIT | MASKING_BIT))) {
#if FLAGS & (TEXTURE | SPRITE)
if (ctx->Texture._EnabledUnits)
_mesa_write_texture_span(ctx, span);
else
_mesa_write_rgba_span(ctx, span);
#elif FLAGS & RGBA
_mesa_write_rgba_span(ctx, span);
#else
_mesa_write_index_span(ctx, span);
#endif
span->end = 0;
}
 
count = span->end;
 
#if FLAGS & RGBA
span->array->rgba[count][RCOMP] = red;
span->array->rgba[count][GCOMP] = green;
span->array->rgba[count][BCOMP] = blue;
span->array->rgba[count][ACOMP] = alpha;
#endif
#if FLAGS & SPECULAR
span->array->spec[count][RCOMP] = specRed;
span->array->spec[count][GCOMP] = specGreen;
span->array->spec[count][BCOMP] = specBlue;
#endif
#if FLAGS & INDEX
span->array->index[count] = colorIndex;
#endif
#if FLAGS & TEXTURE
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
COPY_4V(span->array->texcoords[u][count], texcoord[u]);
}
}
#endif
 
span->array->x[count] = (GLint) vert->win[0];
span->array->y[count] = (GLint) vert->win[1];
span->array->z[count] = (GLint) (vert->win[2] + 0.5F);
span->end = count + 1;
}}
 
#endif /* LARGE || ATTENUATE || SMOOTH */
 
ASSERT(span->end <= MAX_WIDTH);
}
 
 
#undef FLAGS
#undef NAME
/shark/trunk/ports/mesa/src/swrast/s_feedback.c
0,0 → 1,167
/* $Id: s_feedback.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
#include "glheader.h"
#include "colormac.h"
#include "context.h"
#include "enums.h"
#include "feedback.h"
#include "macros.h"
#include "mmath.h"
 
#include "s_context.h"
#include "s_feedback.h"
#include "s_triangle.h"
 
 
#define FB_3D 0x01
#define FB_4D 0x02
#define FB_INDEX 0x04
#define FB_COLOR 0x08
#define FB_TEXTURE 0X10
 
 
 
 
static void feedback_vertex( GLcontext *ctx,
const SWvertex *v, const SWvertex *pv )
{
const GLuint texUnit = 0; /* See section 5.3 of 1.2.1 spec */
GLfloat win[4];
GLfloat color[4];
GLfloat tc[4];
GLuint index;
 
win[0] = v->win[0];
win[1] = v->win[1];
win[2] = v->win[2] / ctx->DepthMaxF;
win[3] = 1.0F / v->win[3];
 
color[0] = CHAN_TO_FLOAT(pv->color[0]);
color[1] = CHAN_TO_FLOAT(pv->color[1]);
color[2] = CHAN_TO_FLOAT(pv->color[2]);
color[3] = CHAN_TO_FLOAT(pv->color[3]);
 
if (v->texcoord[texUnit][3] != 1.0 &&
v->texcoord[texUnit][3] != 0.0) {
GLfloat invq = 1.0F / v->texcoord[texUnit][3];
tc[0] = v->texcoord[texUnit][0] * invq;
tc[1] = v->texcoord[texUnit][1] * invq;
tc[2] = v->texcoord[texUnit][2] * invq;
tc[3] = v->texcoord[texUnit][3];
}
else {
COPY_4V(tc, v->texcoord[texUnit]);
}
 
index = v->index;
 
_mesa_feedback_vertex( ctx, win, color, index, tc );
}
 
 
/*
* Put triangle in feedback buffer.
*/
void _mesa_feedback_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
if (_mesa_cull_triangle( ctx, v0, v1, v2 )) {
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POLYGON_TOKEN );
FEEDBACK_TOKEN( ctx, (GLfloat) 3 ); /* three vertices */
 
if (ctx->Light.ShadeModel == GL_SMOOTH) {
feedback_vertex( ctx, v0, v0 );
feedback_vertex( ctx, v1, v1 );
feedback_vertex( ctx, v2, v2 );
} else {
feedback_vertex( ctx, v0, v2 );
feedback_vertex( ctx, v1, v2 );
feedback_vertex( ctx, v2, v2 );
}
}
}
 
 
void _mesa_feedback_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
GLenum token = GL_LINE_TOKEN;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
if (swrast->StippleCounter==0)
token = GL_LINE_RESET_TOKEN;
 
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) token );
 
if (ctx->Light.ShadeModel == GL_SMOOTH) {
feedback_vertex( ctx, v0, v0 );
feedback_vertex( ctx, v1, v1 );
} else {
feedback_vertex( ctx, v0, v1 );
feedback_vertex( ctx, v1, v1 );
}
 
swrast->StippleCounter++;
}
 
 
void _mesa_feedback_point( GLcontext *ctx, const SWvertex *v )
{
FEEDBACK_TOKEN( ctx, (GLfloat) (GLint) GL_POINT_TOKEN );
feedback_vertex( ctx, v, v );
}
 
 
void _mesa_select_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2)
{
if (_mesa_cull_triangle( ctx, v0, v1, v2 )) {
const GLfloat zs = 1.0F / ctx->DepthMaxF;
 
_mesa_update_hitflag( ctx, v0->win[2] * zs );
_mesa_update_hitflag( ctx, v1->win[2] * zs );
_mesa_update_hitflag( ctx, v2->win[2] * zs );
}
}
 
 
void _mesa_select_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 )
{
const GLfloat zs = 1.0F / ctx->DepthMaxF;
_mesa_update_hitflag( ctx, v0->win[2] * zs );
_mesa_update_hitflag( ctx, v1->win[2] * zs );
}
 
 
void _mesa_select_point( GLcontext *ctx, const SWvertex *v )
{
const GLfloat zs = 1.0F / ctx->DepthMaxF;
_mesa_update_hitflag( ctx, v->win[2] * zs );
}
/shark/trunk/ports/mesa/src/swrast/s_alphabuf.h
0,0 → 1,81
/* $Id: s_alphabuf.h,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 4.0.2
*
* 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.
*/
 
 
#ifndef S_ALPHABUF_H
#define S_ALPHABUF_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void
_mesa_alloc_alpha_buffers( GLframebuffer *buffer );
 
 
extern void
_mesa_clear_alpha_buffers( GLcontext *ctx );
 
 
extern void
_mesa_write_alpha_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
CONST GLchan rgba[][4], const GLubyte mask[] );
 
 
extern void
_mesa_write_mono_alpha_span( GLcontext *ctx,
GLuint n, GLint x, GLint y,
GLchan alpha, const GLubyte mask[] );
 
 
 
extern void
_mesa_write_alpha_pixels( GLcontext* ctx,
GLuint n, const GLint x[], const GLint y[],
CONST GLchan rgba[][4],
const GLubyte mask[] );
 
 
extern void
_mesa_write_mono_alpha_pixels( GLcontext* ctx,
GLuint n, const GLint x[],
const GLint y[], GLchan alpha,
const GLubyte mask[] );
 
 
extern void
_mesa_read_alpha_span( GLcontext* ctx,
GLuint n, GLint x, GLint y, GLchan rgba[][4] );
 
 
extern void
_mesa_read_alpha_pixels( GLcontext* ctx,
GLuint n, const GLint x[], const GLint y[],
GLchan rgba[][4], const GLubyte mask[] );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_zoom.h
0,0 → 1,49
/* $Id: s_zoom.h,v 1.1 2003-02-28 11:49:44 pj Exp $ */
 
/*
* 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.
*/
 
#ifndef S_ZOOM_H
#define S_ZOOM_H
 
#include "mtypes.h"
#include "swrast.h"
 
extern void
_mesa_write_zoomed_rgba_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgb[][4], GLint y0 );
 
extern void
_mesa_write_zoomed_rgb_span( GLcontext *ctx, const struct sw_span *span,
CONST GLchan rgb[][3], GLint y0 );
 
extern void
_mesa_write_zoomed_index_span( GLcontext *ctx, const struct sw_span *span,
GLint y0 );
 
extern void
_mesa_write_zoomed_stencil_span( GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLstencil stencil[], GLint y0 );
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_tritemp.h
0,0 → 1,1406
/* $Id: s_tritemp.h,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
/* $XFree86: xc/extras/Mesa/src/swrast/s_tritemp.h,v 1.2 2002/02/27 21:07:54 tsi Exp $ */
 
/*
* Triangle Rasterizer Template
*
* This file is #include'd to generate custom triangle rasterizers.
*
* The following macros may be defined to indicate what auxillary information
* must be interplated across the triangle:
* INTERP_Z - if defined, interpolate Z values
* INTERP_FOG - if defined, interpolate fog values
* INTERP_RGB - if defined, interpolate RGB values
* INTERP_ALPHA - if defined, interpolate Alpha values (req's INTERP_RGB)
* INTERP_SPEC - if defined, interpolate specular RGB values
* INTERP_INDEX - if defined, interpolate color index values
* INTERP_INT_TEX - if defined, interpolate integer ST texcoords
* (fast, simple 2-D texture mapping)
* INTERP_TEX - if defined, interpolate set 0 float STRQ texcoords
* NOTE: OpenGL STRQ = Mesa STUV (R was taken for red)
* INTERP_MULTITEX - if defined, interpolate N units of STRQ texcoords
* INTERP_FLOAT_RGBA - if defined, interpolate RGBA with floating point
* INTERP_FLOAT_SPEC - if defined, interpolate specular with floating point
*
* When one can directly address pixels in the color buffer the following
* macros can be defined and used to compute pixel addresses during
* rasterization (see pRow):
* PIXEL_TYPE - the datatype of a pixel (GLubyte, GLushort, GLuint)
* BYTES_PER_ROW - number of bytes per row in the color buffer
* PIXEL_ADDRESS(X,Y) - returns the address of pixel at (X,Y) where
* Y==0 at bottom of screen and increases upward.
*
* Similarly, for direct depth buffer access, this type is used for depth
* buffer addressing:
* DEPTH_TYPE - either GLushort or GLuint
*
* Optionally, one may provide one-time setup code per triangle:
* SETUP_CODE - code which is to be executed once per triangle
* CLEANUP_CODE - code to execute at end of triangle
*
* The following macro MUST be defined:
* RENDER_SPAN(span) - code to write a span of pixels.
*
* This code was designed for the origin to be in the lower-left corner.
*
* Inspired by triangle rasterizer code written by Allen Akin. Thanks Allen!
*/
 
 
/*
* This is a bit of a hack, but it's a centralized place to enable floating-
* point color interpolation when GLchan is actually floating point.
*/
#if CHAN_TYPE == GL_FLOAT
 
#if defined(INTERP_RGB)
#undef INTERP_RGB
#undef INTERP_ALPHA
#define INTERP_FLOAT_RGBA
#endif
 
#if defined(INTERP_SPEC)
#undef INTERP_SPEC
#define INTERP_FLOAT_SPEC
#endif
 
#endif
 
 
/*void triangle( GLcontext *ctx, SWvertex *v0, SWvertex *v1, SWvertex *v2 )*/
{
typedef struct {
const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */
GLfloat dx; /* X(v1) - X(v0) */
GLfloat dy; /* Y(v1) - Y(v0) */
GLfixed fdxdy; /* dx/dy in fixed-point */
GLfixed fsx; /* first sample point x coord */
GLfixed fsy;
GLfloat adjy; /* adjust from v[0]->fy to fsy, scaled */
GLint lines; /* number of lines to be sampled on this edge */
GLfixed fx0; /* fixed pt X of lower endpoint */
} EdgeT;
 
#ifdef INTERP_Z
const GLint depthBits = ctx->Visual.depthBits;
const GLint fixedToDepthShift = depthBits <= 16 ? FIXED_SHIFT : 0;
const GLfloat maxDepth = ctx->DepthMaxF;
#define FixedToDepth(F) ((F) >> fixedToDepthShift)
#endif
EdgeT eMaj, eTop, eBot;
GLfloat oneOverArea;
const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */
float bf = SWRAST_CONTEXT(ctx)->_backface_sign;
const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */
GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy;
 
struct sw_span span;
 
INIT_SPAN(span, GL_POLYGON, 0, 0, 0);
 
#ifdef INTERP_Z
(void) fixedToDepthShift;
#endif
 
/*
printf("%s()\n", __FUNCTION__);
printf(" %g, %g, %g\n", v0->win[0], v0->win[1], v0->win[2]);
printf(" %g, %g, %g\n", v1->win[0], v1->win[1], v1->win[2]);
printf(" %g, %g, %g\n", v2->win[0], v2->win[1], v2->win[2]);
*/
 
/* Compute fixed point x,y coords w/ half-pixel offsets and snapping.
* And find the order of the 3 vertices along the Y axis.
*/
{
const GLfixed fy0 = FloatToFixed(v0->win[1] - 0.5F) & snapMask;
const GLfixed fy1 = FloatToFixed(v1->win[1] - 0.5F) & snapMask;
const GLfixed fy2 = FloatToFixed(v2->win[1] - 0.5F) & snapMask;
 
if (fy0 <= fy1) {
if (fy1 <= fy2) {
/* y0 <= y1 <= y2 */
vMin = v0; vMid = v1; vMax = v2;
vMin_fy = fy0; vMid_fy = fy1; vMax_fy = fy2;
}
else if (fy2 <= fy0) {
/* y2 <= y0 <= y1 */
vMin = v2; vMid = v0; vMax = v1;
vMin_fy = fy2; vMid_fy = fy0; vMax_fy = fy1;
}
else {
/* y0 <= y2 <= y1 */
vMin = v0; vMid = v2; vMax = v1;
vMin_fy = fy0; vMid_fy = fy2; vMax_fy = fy1;
bf = -bf;
}
}
else {
if (fy0 <= fy2) {
/* y1 <= y0 <= y2 */
vMin = v1; vMid = v0; vMax = v2;
vMin_fy = fy1; vMid_fy = fy0; vMax_fy = fy2;
bf = -bf;
}
else if (fy2 <= fy1) {
/* y2 <= y1 <= y0 */
vMin = v2; vMid = v1; vMax = v0;
vMin_fy = fy2; vMid_fy = fy1; vMax_fy = fy0;
bf = -bf;
}
else {
/* y1 <= y2 <= y0 */
vMin = v1; vMid = v2; vMax = v0;
vMin_fy = fy1; vMid_fy = fy2; vMax_fy = fy0;
}
}
 
/* fixed point X coords */
vMin_fx = FloatToFixed(vMin->win[0] + 0.5F) & snapMask;
vMid_fx = FloatToFixed(vMid->win[0] + 0.5F) & snapMask;
vMax_fx = FloatToFixed(vMax->win[0] + 0.5F) & snapMask;
}
 
/* vertex/edge relationship */
eMaj.v0 = vMin; eMaj.v1 = vMax; /*TODO: .v1's not needed */
eTop.v0 = vMid; eTop.v1 = vMax;
eBot.v0 = vMin; eBot.v1 = vMid;
 
/* compute deltas for each edge: vertex[upper] - vertex[lower] */
eMaj.dx = FixedToFloat(vMax_fx - vMin_fx);
eMaj.dy = FixedToFloat(vMax_fy - vMin_fy);
eTop.dx = FixedToFloat(vMax_fx - vMid_fx);
eTop.dy = FixedToFloat(vMax_fy - vMid_fy);
eBot.dx = FixedToFloat(vMid_fx - vMin_fx);
eBot.dy = FixedToFloat(vMid_fy - vMin_fy);
 
/* compute area, oneOverArea and perform backface culling */
{
const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy;
 
/* Do backface culling */
if (area * bf < 0.0)
return;
 
if (IS_INF_OR_NAN(area) || area == 0.0F)
return;
 
oneOverArea = 1.0F / area;
}
 
#ifndef DO_OCCLUSION_TEST
ctx->OcclusionResult = GL_TRUE;
#endif
span.facing = ctx->_Facing; /* for 2-sided stencil test */
 
/* Edge setup. For a triangle strip these could be reused... */
{
eMaj.fsy = FixedCeil(vMin_fy);
eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy));
if (eMaj.lines > 0) {
GLfloat dxdy = eMaj.dx / eMaj.dy;
eMaj.fdxdy = SignedFloatToFixed(dxdy);
eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */
eMaj.fx0 = vMin_fx;
eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * dxdy);
}
else {
return; /*CULLED*/
}
 
eTop.fsy = FixedCeil(vMid_fy);
eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy));
if (eTop.lines > 0) {
GLfloat dxdy = eTop.dx / eTop.dy;
eTop.fdxdy = SignedFloatToFixed(dxdy);
eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */
eTop.fx0 = vMid_fx;
eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * dxdy);
}
 
eBot.fsy = FixedCeil(vMin_fy);
eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy));
if (eBot.lines > 0) {
GLfloat dxdy = eBot.dx / eBot.dy;
eBot.fdxdy = SignedFloatToFixed(dxdy);
eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */
eBot.fx0 = vMin_fx;
eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * dxdy);
}
}
 
/*
* Conceptually, we view a triangle as two subtriangles
* separated by a perfectly horizontal line. The edge that is
* intersected by this line is one with maximal absolute dy; we
* call it a ``major'' edge. The other two edges are the
* ``top'' edge (for the upper subtriangle) and the ``bottom''
* edge (for the lower subtriangle). If either of these two
* edges is horizontal or very close to horizontal, the
* corresponding subtriangle might cover zero sample points;
* we take care to handle such cases, for performance as well
* as correctness.
*
* By stepping rasterization parameters along the major edge,
* we can avoid recomputing them at the discontinuity where
* the top and bottom edges meet. However, this forces us to
* be able to scan both left-to-right and right-to-left.
* Also, we must determine whether the major edge is at the
* left or right side of the triangle. We do this by
* computing the magnitude of the cross-product of the major
* and top edges. Since this magnitude depends on the sine of
* the angle between the two edges, its sign tells us whether
* we turn to the left or to the right when travelling along
* the major edge to the top edge, and from this we infer
* whether the major edge is on the left or the right.
*
* Serendipitously, this cross-product magnitude is also a
* value we need to compute the iteration parameter
* derivatives for the triangle, and it can be used to perform
* backface culling because its sign tells us whether the
* triangle is clockwise or counterclockwise. In this code we
* refer to it as ``area'' because it's also proportional to
* the pixel area of the triangle.
*/
 
{
GLint scan_from_left_to_right; /* true if scanning left-to-right */
#ifdef INTERP_Z
GLfloat dzdx, dzdy;
#endif
#ifdef INTERP_FOG
GLfloat dfogdy;
#endif
#if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
GLfloat drdx, drdy;
GLfloat dgdx, dgdy;
GLfloat dbdx, dbdy;
#endif
#if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
GLfloat dadx, dady;
#endif
#if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
GLfloat dsrdx, dsrdy;
GLfloat dsgdx, dsgdy;
GLfloat dsbdx, dsbdy;
#endif
#ifdef INTERP_INDEX
GLfloat didx, didy;
#endif
#ifdef INTERP_INT_TEX
GLfloat dsdx, dsdy;
GLfloat dtdx, dtdy;
#endif
#ifdef INTERP_TEX
GLfloat dsdx, dsdy;
GLfloat dtdx, dtdy;
GLfloat dudx, dudy;
GLfloat dvdx, dvdy;
#endif
#ifdef INTERP_MULTITEX
GLfloat dsdx[MAX_TEXTURE_UNITS], dsdy[MAX_TEXTURE_UNITS];
GLfloat dtdx[MAX_TEXTURE_UNITS], dtdy[MAX_TEXTURE_UNITS];
GLfloat dudx[MAX_TEXTURE_UNITS], dudy[MAX_TEXTURE_UNITS];
GLfloat dvdx[MAX_TEXTURE_UNITS], dvdy[MAX_TEXTURE_UNITS];
#endif
 
/*
* Execute user-supplied setup code
*/
#ifdef SETUP_CODE
SETUP_CODE
#endif
 
scan_from_left_to_right = (oneOverArea < 0.0F);
 
 
/* compute d?/dx and d?/dy derivatives */
#ifdef INTERP_Z
span.interpMask |= SPAN_Z;
{
GLfloat eMaj_dz, eBot_dz;
eMaj_dz = vMax->win[2] - vMin->win[2];
eBot_dz = vMid->win[2] - vMin->win[2];
dzdx = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz);
if (dzdx > maxDepth || dzdx < -maxDepth) {
/* probably a sliver triangle */
dzdx = 0.0;
dzdy = 0.0;
}
else {
dzdy = oneOverArea * (eMaj.dx * eBot_dz - eMaj_dz * eBot.dx);
}
if (depthBits <= 16)
span.zStep = SignedFloatToFixed(dzdx);
else
span.zStep = (GLint) dzdx;
}
#endif
#ifdef INTERP_FOG
span.interpMask |= SPAN_FOG;
{
const GLfloat eMaj_dfog = vMax->fog - vMin->fog;
const GLfloat eBot_dfog = vMid->fog - vMin->fog;
span.fogStep = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog);
dfogdy = oneOverArea * (eMaj.dx * eBot_dfog - eMaj_dfog * eBot.dx);
}
#endif
#ifdef INTERP_RGB
span.interpMask |= SPAN_RGBA;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dr, eBot_dr;
GLfloat eMaj_dg, eBot_dg;
GLfloat eMaj_db, eBot_db;
# ifdef INTERP_ALPHA
GLfloat eMaj_da, eBot_da;
# endif
eMaj_dr = (GLfloat) ((GLint) vMax->color[RCOMP] -
(GLint) vMin->color[RCOMP]);
eBot_dr = (GLfloat) ((GLint) vMid->color[RCOMP] -
(GLint) vMin->color[RCOMP]);
drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
span.redStep = SignedFloatToFixed(drdx);
drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
eMaj_dg = (GLfloat) ((GLint) vMax->color[GCOMP] -
(GLint) vMin->color[GCOMP]);
eBot_dg = (GLfloat) ((GLint) vMid->color[GCOMP] -
(GLint) vMin->color[GCOMP]);
dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
span.greenStep = SignedFloatToFixed(dgdx);
dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
eMaj_db = (GLfloat) ((GLint) vMax->color[BCOMP] -
(GLint) vMin->color[BCOMP]);
eBot_db = (GLfloat) ((GLint) vMid->color[BCOMP] -
(GLint) vMin->color[BCOMP]);
dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
span.blueStep = SignedFloatToFixed(dbdx);
dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
# ifdef INTERP_ALPHA
eMaj_da = (GLfloat) ((GLint) vMax->color[ACOMP] -
(GLint) vMin->color[ACOMP]);
eBot_da = (GLfloat) ((GLint) vMid->color[ACOMP] -
(GLint) vMin->color[ACOMP]);
dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
span.alphaStep = SignedFloatToFixed(dadx);
dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
# endif
}
else {
ASSERT (ctx->Light.ShadeModel == GL_FLAT);
span.interpMask |= SPAN_FLAT;
drdx = drdy = 0.0F;
dgdx = dgdy = 0.0F;
dbdx = dbdy = 0.0F;
span.redStep = 0;
span.greenStep = 0;
span.blueStep = 0;
# ifdef INTERP_ALPHA
dadx = dady = 0.0F;
span.alphaStep = 0;
# endif
}
#endif
#ifdef INTERP_FLOAT_RGBA
span.interpMask |= SPAN_RGBA;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dr, eBot_dr;
GLfloat eMaj_dg, eBot_dg;
GLfloat eMaj_db, eBot_db;
GLfloat eMaj_da, eBot_da;
eMaj_dr = vMax->color[RCOMP] - vMin->color[RCOMP];
eBot_dr = vMid->color[RCOMP] - vMin->color[RCOMP];
drdx = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr);
span.redStep = drdx;
drdy = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx);
eMaj_dg = vMax->color[GCOMP] - vMin->color[GCOMP];
eBot_dg = vMid->color[GCOMP] - vMin->color[GCOMP];
dgdx = oneOverArea * (eMaj_dg * eBot.dy - eMaj.dy * eBot_dg);
span.greenStep = dgdx;
dgdy = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx);
eMaj_db = vMax->color[BCOMP] - vMin->color[BCOMP];
eBot_db = vMid->color[BCOMP] - vMin->color[BCOMP];
dbdx = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db);
span.blueStep = dbdx;
dbdy = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx);
eMaj_da = vMax->color[ACOMP] - vMin->color[ACOMP];
eBot_da = vMid->color[ACOMP] - vMin->color[ACOMP];
dadx = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da);
span.alphaStep = dadx;
dady = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx);
}
else {
drdx = drdy = span.redStep = 0.0F;
dgdx = dgdy = span.greenStep = 0.0F;
dbdx = dbdy = span.blueStep = 0.0F;
dadx = dady = span.alphaStep = 0.0F;
}
#endif
#ifdef INTERP_SPEC
span.interpMask |= SPAN_SPEC;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dsr, eBot_dsr;
GLfloat eMaj_dsg, eBot_dsg;
GLfloat eMaj_dsb, eBot_dsb;
eMaj_dsr = (GLfloat) ((GLint) vMax->specular[RCOMP] -
(GLint) vMin->specular[RCOMP]);
eBot_dsr = (GLfloat) ((GLint) vMid->specular[RCOMP] -
(GLint) vMin->specular[RCOMP]);
dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
span.specRedStep = SignedFloatToFixed(dsrdx);
dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
eMaj_dsg = (GLfloat) ((GLint) vMax->specular[GCOMP] -
(GLint) vMin->specular[GCOMP]);
eBot_dsg = (GLfloat) ((GLint) vMid->specular[GCOMP] -
(GLint) vMin->specular[GCOMP]);
dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
span.specGreenStep = SignedFloatToFixed(dsgdx);
dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
eMaj_dsb = (GLfloat) ((GLint) vMax->specular[BCOMP] -
(GLint) vMin->specular[BCOMP]);
eBot_dsb = (GLfloat) ((GLint) vMid->specular[BCOMP] -
(GLint) vMin->specular[BCOMP]);
dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
span.specBlueStep = SignedFloatToFixed(dsbdx);
dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
}
else {
dsrdx = dsrdy = 0.0F;
dsgdx = dsgdy = 0.0F;
dsbdx = dsbdy = 0.0F;
span.specRedStep = 0;
span.specGreenStep = 0;
span.specBlueStep = 0;
}
#endif
#ifdef INTERP_FLOAT_SPEC
span.interpMask |= SPAN_SPEC;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_dsr, eBot_dsr;
GLfloat eMaj_dsg, eBot_dsg;
GLfloat eMaj_dsb, eBot_dsb;
eMaj_dsr = vMax->specular[RCOMP] - vMin->specular[RCOMP];
eBot_dsr = vMid->specular[RCOMP] - vMin->specular[RCOMP];
dsrdx = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr);
span.specRedStep = dsrdx;
dsrdy = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx);
eMaj_dsg = vMax->specular[GCOMP] - vMin->specular[GCOMP];
eBot_dsg = vMid->specular[GCOMP] - vMin->specular[GCOMP];
dsgdx = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg);
span.specGreenStep = dsgdx;
dsgdy = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx);
eMaj_dsb = vMax->specular[BCOMP] - vMin->specular[BCOMP];
eBot_dsb = vMid->specular[BCOMP] - vMin->specular[BCOMP];
dsbdx = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb);
span.specBlueStep = dsbdx;
dsbdy = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx);
}
else {
dsrdx = dsrdy = span.specRedStep = 0;
dsgdx = dsgdy = span.specGreenStep = 0;
dsbdx = dsbdy = span.specBlueStep = 0;
}
#endif
#ifdef INTERP_INDEX
span.interpMask |= SPAN_INDEX;
if (ctx->Light.ShadeModel == GL_SMOOTH) {
GLfloat eMaj_di, eBot_di;
eMaj_di = (GLfloat) ((GLint) vMax->index - (GLint) vMin->index);
eBot_di = (GLfloat) ((GLint) vMid->index - (GLint) vMin->index);
didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di);
span.indexStep = SignedFloatToFixed(didx);
didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx);
}
else {
span.interpMask |= SPAN_FLAT;
didx = didy = 0.0F;
span.indexStep = 0;
}
#endif
#ifdef INTERP_INT_TEX
span.interpMask |= SPAN_INT_TEXTURE;
{
GLfloat eMaj_ds, eBot_ds;
eMaj_ds = (vMax->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
eBot_ds = (vMid->texcoord[0][0] - vMin->texcoord[0][0]) * S_SCALE;
dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
span.intTexStep[0] = SignedFloatToFixed(dsdx);
dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
}
{
GLfloat eMaj_dt, eBot_dt;
eMaj_dt = (vMax->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
eBot_dt = (vMid->texcoord[0][1] - vMin->texcoord[0][1]) * T_SCALE;
dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
span.intTexStep[1] = SignedFloatToFixed(dtdx);
dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
}
 
#endif
#ifdef INTERP_TEX
span.interpMask |= SPAN_TEXTURE;
{
GLfloat wMax = vMax->win[3];
GLfloat wMin = vMin->win[3];
GLfloat wMid = vMid->win[3];
GLfloat eMaj_ds, eBot_ds;
GLfloat eMaj_dt, eBot_dt;
GLfloat eMaj_du, eBot_du;
GLfloat eMaj_dv, eBot_dv;
 
eMaj_ds = vMax->texcoord[0][0] * wMax - vMin->texcoord[0][0] * wMin;
eBot_ds = vMid->texcoord[0][0] * wMid - vMin->texcoord[0][0] * wMin;
dsdx = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
dsdy = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
span.texStepX[0][0] = dsdx;
span.texStepY[0][0] = dsdy;
 
eMaj_dt = vMax->texcoord[0][1] * wMax - vMin->texcoord[0][1] * wMin;
eBot_dt = vMid->texcoord[0][1] * wMid - vMin->texcoord[0][1] * wMin;
dtdx = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
dtdy = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
span.texStepX[0][1] = dtdx;
span.texStepY[0][1] = dtdy;
 
eMaj_du = vMax->texcoord[0][2] * wMax - vMin->texcoord[0][2] * wMin;
eBot_du = vMid->texcoord[0][2] * wMid - vMin->texcoord[0][2] * wMin;
dudx = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
dudy = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
span.texStepX[0][2] = dudx;
span.texStepY[0][2] = dudy;
 
eMaj_dv = vMax->texcoord[0][3] * wMax - vMin->texcoord[0][3] * wMin;
eBot_dv = vMid->texcoord[0][3] * wMid - vMin->texcoord[0][3] * wMin;
dvdx = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
dvdy = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
span.texStepX[0][3] = dvdx;
span.texStepY[0][3] = dvdy;
}
#endif
#ifdef INTERP_MULTITEX
span.interpMask |= SPAN_TEXTURE;
{
GLfloat wMax = vMax->win[3];
GLfloat wMin = vMin->win[3];
GLfloat wMid = vMid->win[3];
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
GLfloat eMaj_ds, eBot_ds;
GLfloat eMaj_dt, eBot_dt;
GLfloat eMaj_du, eBot_du;
GLfloat eMaj_dv, eBot_dv;
eMaj_ds = vMax->texcoord[u][0] * wMax
- vMin->texcoord[u][0] * wMin;
eBot_ds = vMid->texcoord[u][0] * wMid
- vMin->texcoord[u][0] * wMin;
dsdx[u] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds);
dsdy[u] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx);
span.texStepX[u][0] = dsdx[u];
span.texStepY[u][0] = dsdy[u];
 
eMaj_dt = vMax->texcoord[u][1] * wMax
- vMin->texcoord[u][1] * wMin;
eBot_dt = vMid->texcoord[u][1] * wMid
- vMin->texcoord[u][1] * wMin;
dtdx[u] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt);
dtdy[u] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx);
span.texStepX[u][1] = dtdx[u];
span.texStepY[u][1] = dtdy[u];
 
eMaj_du = vMax->texcoord[u][2] * wMax
- vMin->texcoord[u][2] * wMin;
eBot_du = vMid->texcoord[u][2] * wMid
- vMin->texcoord[u][2] * wMin;
dudx[u] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du);
dudy[u] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx);
span.texStepX[u][2] = dudx[u];
span.texStepY[u][2] = dudy[u];
 
eMaj_dv = vMax->texcoord[u][3] * wMax
- vMin->texcoord[u][3] * wMin;
eBot_dv = vMid->texcoord[u][3] * wMid
- vMin->texcoord[u][3] * wMin;
dvdx[u] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv);
dvdy[u] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx);
span.texStepX[u][3] = dvdx[u];
span.texStepY[u][3] = dvdy[u];
}
}
}
#endif
 
/*
* We always sample at pixel centers. However, we avoid
* explicit half-pixel offsets in this code by incorporating
* the proper offset in each of x and y during the
* transformation to window coordinates.
*
* We also apply the usual rasterization rules to prevent
* cracks and overlaps. A pixel is considered inside a
* subtriangle if it meets all of four conditions: it is on or
* to the right of the left edge, strictly to the left of the
* right edge, on or below the top edge, and strictly above
* the bottom edge. (Some edges may be degenerate.)
*
* The following discussion assumes left-to-right scanning
* (that is, the major edge is on the left); the right-to-left
* case is a straightforward variation.
*
* We start by finding the half-integral y coordinate that is
* at or below the top of the triangle. This gives us the
* first scan line that could possibly contain pixels that are
* inside the triangle.
*
* Next we creep down the major edge until we reach that y,
* and compute the corresponding x coordinate on the edge.
* Then we find the half-integral x that lies on or just
* inside the edge. This is the first pixel that might lie in
* the interior of the triangle. (We won't know for sure
* until we check the other edges.)
*
* As we rasterize the triangle, we'll step down the major
* edge. For each step in y, we'll move an integer number
* of steps in x. There are two possible x step sizes, which
* we'll call the ``inner'' step (guaranteed to land on the
* edge or inside it) and the ``outer'' step (guaranteed to
* land on the edge or outside it). The inner and outer steps
* differ by one. During rasterization we maintain an error
* term that indicates our distance from the true edge, and
* select either the inner step or the outer step, whichever
* gets us to the first pixel that falls inside the triangle.
*
* All parameters (z, red, etc.) as well as the buffer
* addresses for color and z have inner and outer step values,
* so that we can increment them appropriately. This method
* eliminates the need to adjust parameters by creeping a
* sub-pixel amount into the triangle at each scanline.
*/
 
{
int subTriangle;
GLfixed fx;
GLfixed fxLeftEdge = 0, fxRightEdge = 0;
GLfixed fdxLeftEdge = 0, fdxRightEdge = 0;
GLfixed fdxOuter;
int idxOuter;
float dxOuter;
GLfixed fError = 0, fdError = 0;
float adjx, adjy;
GLfixed fy;
#ifdef PIXEL_ADDRESS
PIXEL_TYPE *pRow = NULL;
int dPRowOuter = 0, dPRowInner; /* offset in bytes */
#endif
#ifdef INTERP_Z
# ifdef DEPTH_TYPE
DEPTH_TYPE *zRow = NULL;
int dZRowOuter = 0, dZRowInner; /* offset in bytes */
# endif
GLfixed fz = 0, fdzOuter = 0, fdzInner;
#endif
#ifdef INTERP_FOG
GLfloat fogLeft = 0, dfogOuter = 0, dfogInner;
#endif
#ifdef INTERP_RGB
GLfixed fr = 0, fdrOuter = 0, fdrInner;
GLfixed fg = 0, fdgOuter = 0, fdgInner;
GLfixed fb = 0, fdbOuter = 0, fdbInner;
#endif
#ifdef INTERP_ALPHA
GLfixed fa = 0, fdaOuter = 0, fdaInner;
#endif
#ifdef INTERP_FLOAT_RGBA
GLfloat fr, fdrOuter, fdrInner;
GLfloat fg, fdgOuter, fdgInner;
GLfloat fb, fdbOuter, fdbInner;
GLfloat fa, fdaOuter, fdaInner;
#endif
#ifdef INTERP_SPEC
GLfixed fsr=0, fdsrOuter=0, fdsrInner;
GLfixed fsg=0, fdsgOuter=0, fdsgInner;
GLfixed fsb=0, fdsbOuter=0, fdsbInner;
#endif
#ifdef INTERP_FLOAT_SPEC
GLfloat fsr=0, fdsrOuter=0, fdsrInner;
GLfloat fsg=0, fdsgOuter=0, fdsgInner;
GLfloat fsb=0, fdsbOuter=0, fdsbInner;
#endif
#ifdef INTERP_INDEX
GLfixed fi=0, fdiOuter=0, fdiInner;
#endif
#ifdef INTERP_INT_TEX
GLfixed fs=0, fdsOuter=0, fdsInner;
GLfixed ft=0, fdtOuter=0, fdtInner;
#endif
#ifdef INTERP_TEX
GLfloat sLeft=0, dsOuter=0, dsInner;
GLfloat tLeft=0, dtOuter=0, dtInner;
GLfloat uLeft=0, duOuter=0, duInner;
GLfloat vLeft=0, dvOuter=0, dvInner;
#endif
#ifdef INTERP_MULTITEX
GLfloat sLeft[MAX_TEXTURE_UNITS];
GLfloat tLeft[MAX_TEXTURE_UNITS];
GLfloat uLeft[MAX_TEXTURE_UNITS];
GLfloat vLeft[MAX_TEXTURE_UNITS];
GLfloat dsOuter[MAX_TEXTURE_UNITS], dsInner[MAX_TEXTURE_UNITS];
GLfloat dtOuter[MAX_TEXTURE_UNITS], dtInner[MAX_TEXTURE_UNITS];
GLfloat duOuter[MAX_TEXTURE_UNITS], duInner[MAX_TEXTURE_UNITS];
GLfloat dvOuter[MAX_TEXTURE_UNITS], dvInner[MAX_TEXTURE_UNITS];
#endif
 
for (subTriangle=0; subTriangle<=1; subTriangle++) {
EdgeT *eLeft, *eRight;
int setupLeft, setupRight;
int lines;
 
if (subTriangle==0) {
/* bottom half */
if (scan_from_left_to_right) {
eLeft = &eMaj;
eRight = &eBot;
lines = eRight->lines;
setupLeft = 1;
setupRight = 1;
}
else {
eLeft = &eBot;
eRight = &eMaj;
lines = eLeft->lines;
setupLeft = 1;
setupRight = 1;
}
}
else {
/* top half */
if (scan_from_left_to_right) {
eLeft = &eMaj;
eRight = &eTop;
lines = eRight->lines;
setupLeft = 0;
setupRight = 1;
}
else {
eLeft = &eTop;
eRight = &eMaj;
lines = eLeft->lines;
setupLeft = 1;
setupRight = 0;
}
if (lines == 0)
return;
}
 
if (setupLeft && eLeft->lines > 0) {
const SWvertex *vLower;
GLfixed fsx = eLeft->fsx;
fx = FixedCeil(fsx);
fError = fx - fsx - FIXED_ONE;
fxLeftEdge = fsx - FIXED_EPSILON;
fdxLeftEdge = eLeft->fdxdy;
fdxOuter = FixedFloor(fdxLeftEdge - FIXED_EPSILON);
fdError = fdxOuter - fdxLeftEdge + FIXED_ONE;
idxOuter = FixedToInt(fdxOuter);
dxOuter = (float) idxOuter;
(void) dxOuter;
 
fy = eLeft->fsy;
span.y = FixedToInt(fy);
 
adjx = (float)(fx - eLeft->fx0); /* SCALED! */
adjy = eLeft->adjy; /* SCALED! */
(void) adjx; /* silence compiler warnings */
(void) adjy; /* silence compiler warnings */
 
vLower = eLeft->v0;
(void) vLower; /* silence compiler warnings */
 
#ifdef PIXEL_ADDRESS
{
pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(FixedToInt(fxLeftEdge), span.y);
dPRowOuter = -((int)BYTES_PER_ROW) + idxOuter * sizeof(PIXEL_TYPE);
/* negative because Y=0 at bottom and increases upward */
}
#endif
/*
* Now we need the set of parameter (z, color, etc.) values at
* the point (fx, fy). This gives us properly-sampled parameter
* values that we can step from pixel to pixel. Furthermore,
* although we might have intermediate results that overflow
* the normal parameter range when we step temporarily outside
* the triangle, we shouldn't overflow or underflow for any
* pixel that's actually inside the triangle.
*/
 
#ifdef INTERP_Z
{
GLfloat z0 = vLower->win[2];
if (depthBits <= 16) {
/* interpolate fixed-pt values */
GLfloat tmp = (z0 * FIXED_SCALE +
dzdx * adjx + dzdy * adjy) + FIXED_HALF;
if (tmp < MAX_GLUINT / 2)
fz = (GLfixed) tmp;
else
fz = MAX_GLUINT / 2;
fdzOuter = SignedFloatToFixed(dzdy + dxOuter * dzdx);
}
else {
/* interpolate depth values exactly */
fz = (GLint) (z0 + dzdx * FixedToFloat(adjx)
+ dzdy * FixedToFloat(adjy));
fdzOuter = (GLint) (dzdy + dxOuter * dzdx);
}
# ifdef DEPTH_TYPE
zRow = (DEPTH_TYPE *)
_mesa_zbuffer_address(ctx, FixedToInt(fxLeftEdge), span.y);
dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE);
# endif
}
#endif
#ifdef INTERP_FOG
fogLeft = vLower->fog + (span.fogStep * adjx + dfogdy * adjy)
* (1.0F/FIXED_SCALE);
dfogOuter = dfogdy + dxOuter * span.fogStep;
#endif
#ifdef INTERP_RGB
if (ctx->Light.ShadeModel == GL_SMOOTH) {
fr = (GLfixed) (ChanToFixed(vLower->color[RCOMP])
+ drdx * adjx + drdy * adjy) + FIXED_HALF;
fdrOuter = SignedFloatToFixed(drdy + dxOuter * drdx);
fg = (GLfixed) (ChanToFixed(vLower->color[GCOMP])
+ dgdx * adjx + dgdy * adjy) + FIXED_HALF;
fdgOuter = SignedFloatToFixed(dgdy + dxOuter * dgdx);
fb = (GLfixed) (ChanToFixed(vLower->color[BCOMP])
+ dbdx * adjx + dbdy * adjy) + FIXED_HALF;
fdbOuter = SignedFloatToFixed(dbdy + dxOuter * dbdx);
# ifdef INTERP_ALPHA
fa = (GLfixed) (ChanToFixed(vLower->color[ACOMP])
+ dadx * adjx + dady * adjy) + FIXED_HALF;
fdaOuter = SignedFloatToFixed(dady + dxOuter * dadx);
# endif
}
else {
ASSERT (ctx->Light.ShadeModel == GL_FLAT);
fr = ChanToFixed(v2->color[RCOMP]);
fg = ChanToFixed(v2->color[GCOMP]);
fb = ChanToFixed(v2->color[BCOMP]);
fdrOuter = fdgOuter = fdbOuter = 0;
# ifdef INTERP_ALPHA
fa = ChanToFixed(v2->color[ACOMP]);
fdaOuter = 0;
# endif
}
#endif
#ifdef INTERP_FLOAT_RGBA
if (ctx->Light.ShadeModel == GL_SMOOTH) {
fr = vLower->color[RCOMP]
+ (drdx * adjx + drdy * adjy) * (1.0F / FIXED_SCALE);
fdrOuter = drdy + dxOuter * drdx;
fg = vLower->color[GCOMP]
+ (dgdx * adjx + dgdy * adjy) * (1.0F / FIXED_SCALE);
fdgOuter = dgdy + dxOuter * dgdx;
fb = vLower->color[BCOMP]
+ (dbdx * adjx + dbdy * adjy) * (1.0F / FIXED_SCALE);
fdbOuter = dbdy + dxOuter * dbdx;
fa = vLower->color[ACOMP]
+ (dadx * adjx + dady * adjy) * (1.0F / FIXED_SCALE);
fdaOuter = dady + dxOuter * dadx;
}
else {
fr = v2->color[RCOMP];
fg = v2->color[GCOMP];
fb = v2->color[BCOMP];
fa = v2->color[ACOMP];
fdrOuter = fdgOuter = fdbOuter = fdaOuter = 0.0F;
}
#endif
#ifdef INTERP_SPEC
if (ctx->Light.ShadeModel == GL_SMOOTH) {
fsr = (GLfixed) (ChanToFixed(vLower->specular[RCOMP])
+ dsrdx * adjx + dsrdy * adjy) + FIXED_HALF;
fdsrOuter = SignedFloatToFixed(dsrdy + dxOuter * dsrdx);
fsg = (GLfixed) (ChanToFixed(vLower->specular[GCOMP])
+ dsgdx * adjx + dsgdy * adjy) + FIXED_HALF;
fdsgOuter = SignedFloatToFixed(dsgdy + dxOuter * dsgdx);
fsb = (GLfixed) (ChanToFixed(vLower->specular[BCOMP])
+ dsbdx * adjx + dsbdy * adjy) + FIXED_HALF;
fdsbOuter = SignedFloatToFixed(dsbdy + dxOuter * dsbdx);
}
else {
fsr = ChanToFixed(v2->specular[RCOMP]);
fsg = ChanToFixed(v2->specular[GCOMP]);
fsb = ChanToFixed(v2->specular[BCOMP]);
fdsrOuter = fdsgOuter = fdsbOuter = 0;
}
#endif
#ifdef INTERP_FLOAT_SPEC
if (ctx->Light.ShadeModel == GL_SMOOTH) {
fsr = vLower->specular[RCOMP]
+ (dsrdx * adjx + dsrdy * adjy) * (1.0F / FIXED_SCALE);
fdsrOuter = dsrdy + dxOuter * dsrdx;
fsg = vLower->specular[GCOMP]
+ (dsgdx * adjx + dsgdy * adjy) * (1.0F / FIXED_SCALE);
fdsgOuter = dsgdy + dxOuter * dsgdx;
fsb = vLower->specular[BCOMP]
+ (dsbdx * adjx + dsbdy * adjy) * (1.0F / FIXED_SCALE);
fdsbOuter = dsbdy + dxOuter * dsbdx;
}
else {
fsr = v2->specular[RCOMP];
fsg = v2->specular[GCOMP];
fsb = v2->specular[BCOMP];
fdsrOuter = fdsgOuter = fdsbOuter = 0.0F;
}
#endif
#ifdef INTERP_INDEX
if (ctx->Light.ShadeModel == GL_SMOOTH) {
fi = (GLfixed)(vLower->index * FIXED_SCALE
+ didx * adjx + didy * adjy) + FIXED_HALF;
fdiOuter = SignedFloatToFixed(didy + dxOuter * didx);
}
else {
fi = (GLfixed) (v2->index * FIXED_SCALE);
fdiOuter = 0;
}
#endif
#ifdef INTERP_INT_TEX
{
GLfloat s0, t0;
s0 = vLower->texcoord[0][0] * S_SCALE;
fs = (GLfixed)(s0 * FIXED_SCALE + dsdx * adjx
+ dsdy * adjy) + FIXED_HALF;
fdsOuter = SignedFloatToFixed(dsdy + dxOuter * dsdx);
 
t0 = vLower->texcoord[0][1] * T_SCALE;
ft = (GLfixed)(t0 * FIXED_SCALE + dtdx * adjx
+ dtdy * adjy) + FIXED_HALF;
fdtOuter = SignedFloatToFixed(dtdy + dxOuter * dtdx);
}
#endif
#ifdef INTERP_TEX
{
GLfloat invW = vLower->win[3];
GLfloat s0, t0, u0, v0;
s0 = vLower->texcoord[0][0] * invW;
sLeft = s0 + (span.texStepX[0][0] * adjx + dsdy * adjy)
* (1.0F/FIXED_SCALE);
dsOuter = dsdy + dxOuter * span.texStepX[0][0];
t0 = vLower->texcoord[0][1] * invW;
tLeft = t0 + (span.texStepX[0][1] * adjx + dtdy * adjy)
* (1.0F/FIXED_SCALE);
dtOuter = dtdy + dxOuter * span.texStepX[0][1];
u0 = vLower->texcoord[0][2] * invW;
uLeft = u0 + (span.texStepX[0][2] * adjx + dudy * adjy)
* (1.0F/FIXED_SCALE);
duOuter = dudy + dxOuter * span.texStepX[0][2];
v0 = vLower->texcoord[0][3] * invW;
vLeft = v0 + (span.texStepX[0][3] * adjx + dvdy * adjy)
* (1.0F/FIXED_SCALE);
dvOuter = dvdy + dxOuter * span.texStepX[0][3];
}
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
GLfloat invW = vLower->win[3];
GLfloat s0, t0, u0, v0;
s0 = vLower->texcoord[u][0] * invW;
sLeft[u] = s0 + (span.texStepX[u][0] * adjx + dsdy[u]
* adjy) * (1.0F/FIXED_SCALE);
dsOuter[u] = dsdy[u] + dxOuter * span.texStepX[u][0];
t0 = vLower->texcoord[u][1] * invW;
tLeft[u] = t0 + (span.texStepX[u][1] * adjx + dtdy[u]
* adjy) * (1.0F/FIXED_SCALE);
dtOuter[u] = dtdy[u] + dxOuter * span.texStepX[u][1];
u0 = vLower->texcoord[u][2] * invW;
uLeft[u] = u0 + (span.texStepX[u][2] * adjx + dudy[u]
* adjy) * (1.0F/FIXED_SCALE);
duOuter[u] = dudy[u] + dxOuter * span.texStepX[u][2];
v0 = vLower->texcoord[u][3] * invW;
vLeft[u] = v0 + (span.texStepX[u][3] * adjx + dvdy[u]
* adjy) * (1.0F/FIXED_SCALE);
dvOuter[u] = dvdy[u] + dxOuter * span.texStepX[u][3];
}
}
}
#endif
 
} /*if setupLeft*/
 
 
if (setupRight && eRight->lines>0) {
fxRightEdge = eRight->fsx - FIXED_EPSILON;
fdxRightEdge = eRight->fdxdy;
}
 
if (lines==0) {
continue;
}
 
 
/* Rasterize setup */
#ifdef PIXEL_ADDRESS
dPRowInner = dPRowOuter + sizeof(PIXEL_TYPE);
#endif
#ifdef INTERP_Z
# ifdef DEPTH_TYPE
dZRowInner = dZRowOuter + sizeof(DEPTH_TYPE);
# endif
fdzInner = fdzOuter + span.zStep;
#endif
#ifdef INTERP_FOG
dfogInner = dfogOuter + span.fogStep;
#endif
#if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
fdrInner = fdrOuter + span.redStep;
fdgInner = fdgOuter + span.greenStep;
fdbInner = fdbOuter + span.blueStep;
#endif
#if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
fdaInner = fdaOuter + span.alphaStep;
#endif
#if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
fdsrInner = fdsrOuter + span.specRedStep;
fdsgInner = fdsgOuter + span.specGreenStep;
fdsbInner = fdsbOuter + span.specBlueStep;
#endif
#ifdef INTERP_INDEX
fdiInner = fdiOuter + span.indexStep;
#endif
#ifdef INTERP_INT_TEX
fdsInner = fdsOuter + span.intTexStep[0];
fdtInner = fdtOuter + span.intTexStep[1];
#endif
#ifdef INTERP_TEX
dsInner = dsOuter + span.texStepX[0][0];
dtInner = dtOuter + span.texStepX[0][1];
duInner = duOuter + span.texStepX[0][2];
dvInner = dvOuter + span.texStepX[0][3];
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
dsInner[u] = dsOuter[u] + span.texStepX[u][0];
dtInner[u] = dtOuter[u] + span.texStepX[u][1];
duInner[u] = duOuter[u] + span.texStepX[u][2];
dvInner[u] = dvOuter[u] + span.texStepX[u][3];
}
}
}
#endif
 
while (lines > 0) {
/* initialize the span interpolants to the leftmost value */
/* ff = fixed-pt fragment */
const GLint right = FixedToInt(fxRightEdge);
 
span.x = FixedToInt(fxLeftEdge);
 
if (right <= span.x)
span.end = 0;
else
span.end = right - span.x;
 
#ifdef INTERP_Z
span.z = fz;
#endif
#ifdef INTERP_FOG
span.fog = fogLeft;
#endif
#if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
span.red = fr;
span.green = fg;
span.blue = fb;
#endif
#if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
span.alpha = fa;
#endif
#if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
span.specRed = fsr;
span.specGreen = fsg;
span.specBlue = fsb;
#endif
#ifdef INTERP_INDEX
span.index = fi;
#endif
#ifdef INTERP_INT_TEX
span.intTex[0] = fs;
span.intTex[1] = ft;
#endif
 
#ifdef INTERP_TEX
span.tex[0][0] = sLeft;
span.tex[0][1] = tLeft;
span.tex[0][2] = uLeft;
span.tex[0][3] = vLeft;
#endif
 
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
span.tex[u][0] = sLeft[u];
span.tex[u][1] = tLeft[u];
span.tex[u][2] = uLeft[u];
span.tex[u][3] = vLeft[u];
}
}
}
#endif
 
#ifdef INTERP_RGB
{
/* need this to accomodate round-off errors */
const GLint len = right - span.x - 1;
GLfixed ffrend = span.red + len * span.redStep;
GLfixed ffgend = span.green + len * span.greenStep;
GLfixed ffbend = span.blue + len * span.blueStep;
if (ffrend < 0) {
span.red -= ffrend;
if (span.red < 0)
span.red = 0;
}
if (ffgend < 0) {
span.green -= ffgend;
if (span.green < 0)
span.green = 0;
}
if (ffbend < 0) {
span.blue -= ffbend;
if (span.blue < 0)
span.blue = 0;
}
}
#endif
#ifdef INTERP_ALPHA
{
const GLint len = right - span.x - 1;
GLfixed ffaend = span.alpha + len * span.alphaStep;
if (ffaend < 0) {
span.alpha -= ffaend;
if (span.alpha < 0)
span.alpha = 0;
}
}
#endif
#ifdef INTERP_SPEC
{
/* need this to accomodate round-off errors */
const GLint len = right - span.x - 1;
GLfixed ffsrend = span.specRed + len * span.specRedStep;
GLfixed ffsgend = span.specGreen + len * span.specGreenStep;
GLfixed ffsbend = span.specBlue + len * span.specBlueStep;
if (ffsrend < 0) {
span.specRed -= ffsrend;
if (span.specRed < 0)
span.specRed = 0;
}
if (ffsgend < 0) {
span.specGreen -= ffsgend;
if (span.specGreen < 0)
span.specGreen = 0;
}
if (ffsbend < 0) {
span.specBlue -= ffsbend;
if (span.specBlue < 0)
span.specBlue = 0;
}
}
#endif
#ifdef INTERP_INDEX
if (span.index < 0) span.index = 0;
#endif
 
/* This is where we actually generate fragments */
if (span.end > 0) {
RENDER_SPAN( span );
}
 
/*
* Advance to the next scan line. Compute the
* new edge coordinates, and adjust the
* pixel-center x coordinate so that it stays
* on or inside the major edge.
*/
(span.y)++;
lines--;
 
fxLeftEdge += fdxLeftEdge;
fxRightEdge += fdxRightEdge;
 
 
fError += fdError;
if (fError >= 0) {
fError -= FIXED_ONE;
#ifdef PIXEL_ADDRESS
pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter);
#endif
#ifdef INTERP_Z
# ifdef DEPTH_TYPE
zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowOuter);
# endif
fz += fdzOuter;
#endif
#ifdef INTERP_FOG
fogLeft += dfogOuter;
#endif
#if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
fr += fdrOuter;
fg += fdgOuter;
fb += fdbOuter;
#endif
#if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
fa += fdaOuter;
#endif
#if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
fsr += fdsrOuter;
fsg += fdsgOuter;
fsb += fdsbOuter;
#endif
#ifdef INTERP_INDEX
fi += fdiOuter;
#endif
#ifdef INTERP_INT_TEX
fs += fdsOuter;
ft += fdtOuter;
#endif
#ifdef INTERP_TEX
sLeft += dsOuter;
tLeft += dtOuter;
uLeft += duOuter;
vLeft += dvOuter;
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
sLeft[u] += dsOuter[u];
tLeft[u] += dtOuter[u];
uLeft[u] += duOuter[u];
vLeft[u] += dvOuter[u];
}
}
}
#endif
}
else {
#ifdef PIXEL_ADDRESS
pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowInner);
#endif
#ifdef INTERP_Z
# ifdef DEPTH_TYPE
zRow = (DEPTH_TYPE *) ((GLubyte *) zRow + dZRowInner);
# endif
fz += fdzInner;
#endif
#ifdef INTERP_FOG
fogLeft += dfogInner;
#endif
#if defined(INTERP_RGB) || defined(INTERP_FLOAT_RGBA)
fr += fdrInner;
fg += fdgInner;
fb += fdbInner;
#endif
#if defined(INTERP_ALPHA) || defined(INTERP_FLOAT_RGBA)
fa += fdaInner;
#endif
#if defined(INTERP_SPEC) || defined(INTERP_FLOAT_SPEC)
fsr += fdsrInner;
fsg += fdsgInner;
fsb += fdsbInner;
#endif
#ifdef INTERP_INDEX
fi += fdiInner;
#endif
#ifdef INTERP_INT_TEX
fs += fdsInner;
ft += fdtInner;
#endif
#ifdef INTERP_TEX
sLeft += dsInner;
tLeft += dtInner;
uLeft += duInner;
vLeft += dvInner;
#endif
#ifdef INTERP_MULTITEX
{
GLuint u;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
sLeft[u] += dsInner[u];
tLeft[u] += dtInner[u];
uLeft[u] += duInner[u];
vLeft[u] += dvInner[u];
}
}
}
#endif
}
} /*while lines>0*/
 
} /* for subTriangle */
 
}
#ifdef CLEANUP_CODE
CLEANUP_CODE
#endif
}
}
 
#undef SETUP_CODE
#undef CLEANUP_CODE
#undef RENDER_SPAN
 
#undef PIXEL_TYPE
#undef BYTES_PER_ROW
#undef PIXEL_ADDRESS
 
#undef INTERP_Z
#undef INTERP_FOG
#undef INTERP_RGB
#undef INTERP_ALPHA
#undef INTERP_SPEC
#undef INTERP_INDEX
#undef INTERP_INT_TEX
#undef INTERP_TEX
#undef INTERP_MULTITEX
#undef INTERP_FLOAT_RGBA
#undef INTERP_FLOAT_SPEC
 
#undef S_SCALE
#undef T_SCALE
 
#undef FixedToDepth
 
#undef DO_OCCLUSION_TEST
/shark/trunk/ports/mesa/src/swrast/s_context.h
0,0 → 1,236
/* $Id: s_context.h,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
 
/**
* \file swrast/s_context.h
* \brief fill in description
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
 
#ifndef S_CONTEXT_H
#define S_CONTEXT_H
 
#include "mtypes.h"
#include "swrast.h"
 
/*
* For texture sampling:
*/
typedef void (*TextureSampleFunc)( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] );
 
 
 
/*
* Blending function
*/
#ifdef USE_MMX_ASM
typedef void (_ASMAPIP blend_func)( GLcontext *ctx, GLuint n,
const GLubyte mask[],
GLchan src[][4], CONST GLchan dst[][4] );
#else
typedef void (*blend_func)( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLchan src[][4], CONST GLchan dst[][4] );
#endif
 
typedef void (*swrast_point_func)( GLcontext *ctx, const SWvertex *);
 
typedef void (*swrast_line_func)( GLcontext *ctx,
const SWvertex *, const SWvertex *);
 
typedef void (*swrast_tri_func)( GLcontext *ctx, const SWvertex *,
const SWvertex *, const SWvertex *);
 
 
/** \defgroup Bitmasks
* Bitmasks to indicate which rasterization options are enabled
* (RasterMask)
*/
/*@{*/
#define ALPHATEST_BIT 0x001 /**< Alpha-test pixels */
#define BLEND_BIT 0x002 /**< Blend pixels */
#define DEPTH_BIT 0x004 /**< Depth-test pixels */
#define FOG_BIT 0x008 /**< Fog pixels */
#define LOGIC_OP_BIT 0x010 /**< Apply logic op in software */
#define CLIP_BIT 0x020 /**< Scissor or window clip pixels */
#define STENCIL_BIT 0x040 /**< Stencil pixels */
#define MASKING_BIT 0x080 /**< Do glColorMask or glIndexMask */
#define ALPHABUF_BIT 0x100 /**< Using software alpha buffer */
#define MULTI_DRAW_BIT 0x400 /**< Write to more than one color- */
/**< buffer or no buffers. */
#define OCCLUSION_BIT 0x800 /**< GL_HP_occlusion_test enabled */
#define TEXTURE_BIT 0x1000 /**< Texturing really enabled */
/*@}*/
 
#define _SWRAST_NEW_RASTERMASK (_NEW_BUFFERS| \
_NEW_SCISSOR| \
_NEW_COLOR| \
_NEW_DEPTH| \
_NEW_FOG| \
_NEW_STENCIL| \
_NEW_TEXTURE| \
_NEW_VIEWPORT| \
_NEW_DEPTH)
 
 
/**
* \struct SWcontext
* \brief SWContext?
*/
typedef struct
{
/** Driver interface:
*/
struct swrast_device_driver Driver;
 
/** Configuration mechanisms to make software rasterizer match
* characteristics of the hardware rasterizer (if present):
*/
GLboolean AllowVertexFog;
GLboolean AllowPixelFog;
 
/** Derived values, invalidated on statechanges, updated from
* _swrast_validate_derived():
*/
GLuint _RasterMask;
GLfloat _MinMagThresh[MAX_TEXTURE_UNITS];
GLfloat _backface_sign;
GLboolean _PreferPixelFog;
GLboolean _AnyTextureCombine;
 
/* Accum buffer temporaries.
*/
GLboolean _IntegerAccumMode; /**< Storing unscaled integers? */
GLfloat _IntegerAccumScaler; /**< Implicit scale factor */
 
 
/* Working values:
*/
GLuint StippleCounter; /**< Line stipple counter */
GLuint NewState;
GLuint StateChanges;
GLenum Primitive; /* current primitive being drawn (ala glBegin) */
GLuint CurrentBuffer; /* exactly one of FRONT_LEFT_BIT, BACK_LEFT_BIT, etc*/
 
/** Mechanism to allow driver (like X11) to register further
* software rasterization routines.
*/
/*@{*/
void (*choose_point)( GLcontext * );
void (*choose_line)( GLcontext * );
void (*choose_triangle)( GLcontext * );
 
GLuint invalidate_point;
GLuint invalidate_line;
GLuint invalidate_triangle;
/*@}*/
 
/** Function pointers for dispatch behind public entrypoints. */
/*@{*/
void (*InvalidateState)( GLcontext *ctx, GLuint new_state );
 
swrast_point_func Point;
swrast_line_func Line;
swrast_tri_func Triangle;
/*@}*/
 
/**
* Placeholders for when separate specular (or secondary color) is
* enabled but texturing is not.
*/
/*@{*/
swrast_point_func SpecPoint;
swrast_line_func SpecLine;
swrast_tri_func SpecTriangle;
/*@}*/
 
/**
* Typically, we'll allocate a sw_span structure as a local variable
* and set its 'array' pointer to point to this object. The reason is
* this object is big and causes problems when allocated on the stack
* on some systems.
*/
struct span_arrays *SpanArrays;
 
/**
* Used to buffer N GL_POINTS, instead of rendering one by one.
*/
struct sw_span PointSpan;
 
/** Internal hooks, kept uptodate by the same mechanism as above.
*/
blend_func BlendFunc;
TextureSampleFunc TextureSample[MAX_TEXTURE_UNITS];
 
/** Buffer for saving the sampled texture colors.
* Needed for GL_ARB_texture_env_crossbar implementation.
*/
GLchan *TexelBuffer;
 
} SWcontext;
 
 
extern void
_swrast_validate_derived( GLcontext *ctx );
 
 
#define SWRAST_CONTEXT(ctx) ((SWcontext *)ctx->swrast_context)
 
#define RENDER_START(SWctx, GLctx) \
do { \
if ((SWctx)->Driver.SpanRenderStart) { \
(*(SWctx)->Driver.SpanRenderStart)(GLctx); \
} \
} while (0)
 
#define RENDER_FINISH(SWctx, GLctx) \
do { \
if ((SWctx)->Driver.SpanRenderFinish) { \
(*(SWctx)->Driver.SpanRenderFinish)(GLctx); \
} \
} while (0)
 
 
 
/*
* XXX these macros are just bandages for now in order to make
* CHAN_BITS==32 compile cleanly.
* These should probably go elsewhere at some point.
*/
#if CHAN_TYPE == GL_FLOAT
#define ChanToFixed(X) (X)
#define FixedToChan(X) (X)
#else
#define ChanToFixed(X) IntToFixed(X)
#define FixedToChan(X) FixedToInt(X)
#endif
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_masking.c
0,0 → 1,192
/* $Id: s_masking.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
/*
* Implement the effect of glColorMask and glIndexMask in software.
*/
 
 
#include "glheader.h"
#include "enums.h"
#include "macros.h"
 
#include "s_alphabuf.h"
#include "s_context.h"
#include "s_masking.h"
#include "s_span.h"
 
 
 
void
_mesa_mask_rgba_span( GLcontext *ctx, const struct sw_span *span,
GLchan rgba[][4] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan dest[MAX_WIDTH][4];
#if CHAN_BITS == 8
GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
GLuint dstMask = ~srcMask;
GLuint *rgba32 = (GLuint *) rgba;
GLuint *dest32 = (GLuint *) dest;
#else
const GLboolean rMask = ctx->Color.ColorMask[RCOMP];
const GLboolean gMask = ctx->Color.ColorMask[GCOMP];
const GLboolean bMask = ctx->Color.ColorMask[BCOMP];
const GLboolean aMask = ctx->Color.ColorMask[ACOMP];
#endif
const GLuint n = span->end;
GLuint i;
 
ASSERT(n < MAX_WIDTH);
ASSERT(span->arrayMask & SPAN_RGBA);
 
if (span->arrayMask & SPAN_XY) {
(*swrast->Driver.ReadRGBAPixels)(ctx, n, span->array->x, span->array->y,
dest, span->array->mask);
if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
_mesa_read_alpha_pixels(ctx, n, span->array->x, span->array->y,
dest, span->array->mask);
}
}
else {
_mesa_read_rgba_span(ctx, ctx->DrawBuffer, n, span->x, span->y, dest);
}
 
#if CHAN_BITS == 8
for (i = 0; i < n; i++) {
rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
}
#else
for (i = 0; i < n; i++) {
if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP];
if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP];
if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP];
if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP];
}
#endif
}
 
 
 
 
/*
* Apply glColorMask to a span of RGBA pixels.
*/
void
_mesa_mask_rgba_array( GLcontext *ctx,
GLuint n, GLint x, GLint y, GLchan rgba[][4] )
{
GLchan dest[MAX_WIDTH][4];
GLuint i;
 
#if CHAN_BITS == 8
 
GLuint srcMask = *((GLuint*)ctx->Color.ColorMask);
GLuint dstMask = ~srcMask;
GLuint *rgba32 = (GLuint *) rgba;
GLuint *dest32 = (GLuint *) dest;
 
_mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
for (i = 0; i < n; i++) {
rgba32[i] = (rgba32[i] & srcMask) | (dest32[i] & dstMask);
}
 
#else
 
const GLint rMask = ctx->Color.ColorMask[RCOMP];
const GLint gMask = ctx->Color.ColorMask[GCOMP];
const GLint bMask = ctx->Color.ColorMask[BCOMP];
const GLint aMask = ctx->Color.ColorMask[ACOMP];
 
_mesa_read_rgba_span( ctx, ctx->DrawBuffer, n, x, y, dest );
for (i = 0; i < n; i++) {
if (!rMask) rgba[i][RCOMP] = dest[i][RCOMP];
if (!gMask) rgba[i][GCOMP] = dest[i][GCOMP];
if (!bMask) rgba[i][BCOMP] = dest[i][BCOMP];
if (!aMask) rgba[i][ACOMP] = dest[i][ACOMP];
}
 
#endif
}
 
 
 
void
_mesa_mask_index_span( GLcontext *ctx, const struct sw_span *span,
GLuint index[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint msrc = ctx->Color.IndexMask;
const GLuint mdest = ~msrc;
GLuint fbindexes[MAX_WIDTH];
GLuint i;
 
ASSERT(span->arrayMask & SPAN_INDEX);
ASSERT(span->end < MAX_WIDTH);
 
if (span->arrayMask & SPAN_XY) {
 
(*swrast->Driver.ReadCI32Pixels)(ctx, span->end, span->array->x,
span->array->y, fbindexes,
span->array->mask);
 
for (i = 0; i < span->end; i++) {
index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
}
}
else {
_mesa_read_index_span(ctx, ctx->DrawBuffer, span->end, span->x, span->y,
fbindexes );
 
for (i = 0; i < span->end; i++) {
index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
}
}
}
 
 
 
/*
* Apply glIndexMask to a span of CI pixels.
*/
void
_mesa_mask_index_array( GLcontext *ctx,
GLuint n, GLint x, GLint y, GLuint index[] )
{
GLuint i;
GLuint fbindexes[MAX_WIDTH];
GLuint msrc, mdest;
 
_mesa_read_index_span( ctx, ctx->DrawBuffer, n, x, y, fbindexes );
 
msrc = ctx->Color.IndexMask;
mdest = ~msrc;
 
for (i=0;i<n;i++) {
index[i] = (index[i] & msrc) | (fbindexes[i] & mdest);
}
}
/shark/trunk/ports/mesa/src/swrast/s_feedback.h
0,0 → 1,52
/* $Id: s_feedback.h,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef S_FEEDBACK_H
#define S_FEEDBACK_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void _mesa_feedback_point( GLcontext *ctx, const SWvertex *v );
 
extern void _mesa_feedback_line( GLcontext *ctx,
const SWvertex *v1, const SWvertex *v2 );
 
extern void _mesa_feedback_triangle( GLcontext *ctx, const SWvertex *v0,
const SWvertex *v1, const SWvertex *v2 );
 
extern void _mesa_select_point( GLcontext *ctx, const SWvertex *v );
 
extern void _mesa_select_line( GLcontext *ctx,
const SWvertex *v1, const SWvertex *v2 );
 
extern void _mesa_select_triangle( GLcontext *ctx, const SWvertex *v0,
const SWvertex *v1, const SWvertex *v2 );
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_copypix.c
0,0 → 1,816
/* $Id: s_copypix.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 5.0
*
* 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.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "context.h"
#include "convolve.h"
#include "feedback.h"
#include "macros.h"
#include "imports.h"
#include "mmath.h"
#include "pixel.h"
 
#include "s_context.h"
#include "s_depth.h"
#include "s_histogram.h"
#include "s_pixeltex.h"
#include "s_span.h"
#include "s_stencil.h"
#include "s_texture.h"
#include "s_zoom.h"
 
 
 
/*
* Determine if there's overlap in an image copy.
* This test also compensates for the fact that copies are done from
* bottom to top and overlaps can sometimes be handled correctly
* without making a temporary image copy.
*/
static GLboolean
regions_overlap(GLint srcx, GLint srcy,
GLint dstx, GLint dsty,
GLint width, GLint height,
GLfloat zoomX, GLfloat zoomY)
{
if (zoomX == 1.0 && zoomY == 1.0) {
/* no zoom */
if (srcx >= dstx + width || (srcx + width <= dstx)) {
return GL_FALSE;
}
else if (srcy < dsty) { /* this is OK */
return GL_FALSE;
}
else if (srcy > dsty + height) {
return GL_FALSE;
}
else {
return GL_TRUE;
}
}
else {
/* add one pixel of slop when zooming, just to be safe */
if ((srcx > dstx + (width * zoomX) + 1) || (srcx + width + 1 < dstx)) {
return GL_FALSE;
}
else if ((srcy < dsty) && (srcy + height < dsty + (height * zoomY))) {
return GL_FALSE;
}
else if ((srcy > dsty) && (srcy + height > dsty + (height * zoomY))) {
return GL_FALSE;
}
else {
return GL_TRUE;
}
}
}
 
 
 
/*
* RGBA copypixels with convolution.
*/
static void
copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height, GLint destx, GLint desty)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLboolean quick_draw;
GLint row;
GLboolean changeBuffer;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
const GLuint transferOps = ctx->_ImageTransferState;
GLfloat *dest, *tmpImage, *convImage;
struct sw_span span;
 
INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
 
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
 
 
if (SWRAST_CONTEXT(ctx)->_RasterMask == 0
&& !zoom
&& destx >= 0
&& destx + width <= (GLint) ctx->DrawBuffer->Width) {
quick_draw = GL_TRUE;
}
else {
quick_draw = GL_FALSE;
}
 
/* If read and draw buffer are different we must do buffer switching */
changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer
|| ctx->DrawBuffer != ctx->ReadBuffer;
 
 
/* allocate space for GLfloat image */
tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
if (!tmpImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
return;
}
convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
if (!convImage) {
FREE(tmpImage);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glCopyPixels");
return;
}
 
dest = tmpImage;
 
if (changeBuffer) {
/* choose the read buffer */
_swrast_use_read_buffer(ctx);
}
 
/* read source image */
dest = tmpImage;
for (row = 0; row < height; row++) {
GLchan rgba[MAX_WIDTH][4];
GLint i;
_mesa_read_rgba_span(ctx, ctx->ReadBuffer, width, srcx, srcy + row, rgba);
/* convert GLchan to GLfloat */
for (i = 0; i < width; i++) {
*dest++ = (GLfloat) rgba[i][RCOMP] * (1.0F / CHAN_MAXF);
*dest++ = (GLfloat) rgba[i][GCOMP] * (1.0F / CHAN_MAXF);
*dest++ = (GLfloat) rgba[i][BCOMP] * (1.0F / CHAN_MAXF);
*dest++ = (GLfloat) rgba[i][ACOMP] * (1.0F / CHAN_MAXF);
}
}
 
if (changeBuffer) {
/* restore default src/dst buffer */
_swrast_use_draw_buffer(ctx);
}
 
/* do image transfer ops up until convolution */
for (row = 0; row < height; row++) {
GLfloat (*rgba)[4] = (GLfloat (*)[4]) (tmpImage + row * width * 4);
 
/* scale & bias */
if (transferOps & IMAGE_SCALE_BIAS_BIT) {
_mesa_scale_and_bias_rgba(ctx, width, rgba,
ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
}
/* color map lookup */
if (transferOps & IMAGE_MAP_COLOR_BIT) {
_mesa_map_rgba(ctx, width, rgba);
}
/* GL_COLOR_TABLE lookup */
if (transferOps & IMAGE_COLOR_TABLE_BIT) {
_mesa_lookup_rgba(&ctx->ColorTable, width, rgba);
}
}
 
/* do convolution */
if (ctx->Pixel.Convolution2DEnabled) {
_mesa_convolve_2d_image(ctx, &width, &height, tmpImage, convImage);
}
else {
ASSERT(ctx->Pixel.Separable2DEnabled);
_mesa_convolve_sep_image(ctx, &width, &height, tmpImage, convImage);
}
FREE(tmpImage);
 
/* do remaining image transfer ops */
for (row = 0; row < height; row++) {
GLfloat (*rgba)[4] = (GLfloat (*)[4]) (convImage + row * width * 4);
 
/* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
_mesa_lookup_rgba(&ctx->PostConvolutionColorTable, width, rgba);
}
/* color matrix */
if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
_mesa_transform_rgba(ctx, width, rgba);
}
/* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
_mesa_lookup_rgba(&ctx->PostColorMatrixColorTable, width, rgba);
}
/* update histogram count */
if (transferOps & IMAGE_HISTOGRAM_BIT) {
_mesa_update_histogram(ctx, width, (CONST GLfloat (*)[4]) rgba);
}
/* update min/max */
if (transferOps & IMAGE_MIN_MAX_BIT) {
_mesa_update_minmax(ctx, width, (CONST GLfloat (*)[4]) rgba);
}
}
 
for (row = 0; row < height; row++) {
const GLfloat *src = convImage + row * width * 4;
GLint i, dy;
 
/* clamp to [0,1] and convert float back to chan */
for (i = 0; i < width; i++) {
GLint r = (GLint) (src[i * 4 + RCOMP] * CHAN_MAXF);
GLint g = (GLint) (src[i * 4 + GCOMP] * CHAN_MAXF);
GLint b = (GLint) (src[i * 4 + BCOMP] * CHAN_MAXF);
GLint a = (GLint) (src[i * 4 + ACOMP] * CHAN_MAXF);
span.array->rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
span.array->rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
span.array->rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
span.array->rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
}
 
if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) {
span.end = width;
_swrast_pixel_texture(ctx, &span);
}
 
/* write row to framebuffer */
 
dy = desty + row;
if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) {
(*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy,
(const GLchan (*)[4])span.array->rgba, NULL );
}
else if (zoom) {
span.x = destx;
span.y = dy;
span.end = width;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4])span.array->rgba,
desty);
}
else {
span.x = destx;
span.y = dy;
span.end = width;
_mesa_write_rgba_span(ctx, &span);
}
}
 
FREE(convImage);
}
 
 
/*
* RGBA copypixels
*/
static void
copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height, GLint destx, GLint desty)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan *tmpImage,*p;
GLboolean quick_draw;
GLint sy, dy, stepy, j;
GLboolean changeBuffer;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
GLint overlapping;
const GLuint transferOps = ctx->_ImageTransferState;
struct sw_span span;
 
INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA);
 
if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
copy_conv_rgba_pixels(ctx, srcx, srcy, width, height, destx, desty);
return;
}
 
/* Determine if copy should be done bottom-to-top or top-to-bottom */
if (srcy < desty) {
/* top-down max-to-min */
sy = srcy + height - 1;
dy = desty + height - 1;
stepy = -1;
}
else {
/* bottom-up min-to-max */
sy = srcy;
dy = desty;
stepy = 1;
}
 
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
 
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
 
if (SWRAST_CONTEXT(ctx)->_RasterMask == 0
&& !zoom
&& destx >= 0
&& destx + width <= (GLint) ctx->DrawBuffer->Width) {
quick_draw = GL_TRUE;
}
else {
quick_draw = GL_FALSE;
}
 
/* If read and draw buffer are different we must do buffer switching */
changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer
|| ctx->DrawBuffer != ctx->ReadBuffer;
 
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLchan *) MALLOC(width * height * sizeof(GLchan) * 4);
if (!tmpImage) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
return;
}
/* setup source */
if (changeBuffer)
_swrast_use_read_buffer(ctx);
/* read the source image */
p = tmpImage;
for (j = 0; j < height; j++, ssy += stepy) {
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, ssy,
(GLchan (*)[4]) p );
p += width * 4;
}
p = tmpImage;
/* restore dest */
if (changeBuffer) {
_swrast_use_draw_buffer(ctx);
changeBuffer = GL_FALSE;
}
}
else {
tmpImage = NULL; /* silence compiler warnings */
p = NULL;
}
 
for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
/* Get source pixels */
if (overlapping) {
/* get from buffered image */
MEMCPY(span.array->rgba, p, width * sizeof(GLchan) * 4);
p += width * 4;
}
else {
/* get from framebuffer */
if (changeBuffer)
_swrast_use_read_buffer(ctx);
_mesa_read_rgba_span( ctx, ctx->ReadBuffer, width, srcx, sy,
span.array->rgba );
if (changeBuffer)
_swrast_use_draw_buffer(ctx);
}
 
if (transferOps) {
const GLfloat scale = (1.0F / CHAN_MAXF);
GLint k;
DEFMARRAY(GLfloat, rgbaFloat, MAX_WIDTH, 4); /* mac 32k limitation */
CHECKARRAY(rgbaFloat, return);
 
/* convert chan to float */
for (k = 0; k < width; k++) {
rgbaFloat[k][RCOMP] = (GLfloat) span.array->rgba[k][RCOMP] * scale;
rgbaFloat[k][GCOMP] = (GLfloat) span.array->rgba[k][GCOMP] * scale;
rgbaFloat[k][BCOMP] = (GLfloat) span.array->rgba[k][BCOMP] * scale;
rgbaFloat[k][ACOMP] = (GLfloat) span.array->rgba[k][ACOMP] * scale;
}
/* scale & bias */
if (transferOps & IMAGE_SCALE_BIAS_BIT) {
_mesa_scale_and_bias_rgba(ctx, width, rgbaFloat,
ctx->Pixel.RedScale, ctx->Pixel.GreenScale,
ctx->Pixel.BlueScale, ctx->Pixel.AlphaScale,
ctx->Pixel.RedBias, ctx->Pixel.GreenBias,
ctx->Pixel.BlueBias, ctx->Pixel.AlphaBias);
}
/* color map lookup */
if (transferOps & IMAGE_MAP_COLOR_BIT) {
_mesa_map_rgba(ctx, width, rgbaFloat);
}
/* GL_COLOR_TABLE lookup */
if (transferOps & IMAGE_COLOR_TABLE_BIT) {
_mesa_lookup_rgba(&ctx->ColorTable, width, rgbaFloat);
}
/* convolution */
if (transferOps & IMAGE_CONVOLUTION_BIT) {
_mesa_problem(ctx, "Convolution should not be enabled in copy_rgba_pixels()");
return;
}
/* GL_POST_CONVOLUTION_RED/GREEN/BLUE/ALPHA_SCALE/BIAS */
if (transferOps & IMAGE_POST_CONVOLUTION_SCALE_BIAS) {
_mesa_scale_and_bias_rgba(ctx, width, rgbaFloat,
ctx->Pixel.PostConvolutionScale[RCOMP],
ctx->Pixel.PostConvolutionScale[GCOMP],
ctx->Pixel.PostConvolutionScale[BCOMP],
ctx->Pixel.PostConvolutionScale[ACOMP],
ctx->Pixel.PostConvolutionBias[RCOMP],
ctx->Pixel.PostConvolutionBias[GCOMP],
ctx->Pixel.PostConvolutionBias[BCOMP],
ctx->Pixel.PostConvolutionBias[ACOMP]);
}
/* GL_POST_CONVOLUTION_COLOR_TABLE lookup */
if (transferOps & IMAGE_POST_CONVOLUTION_COLOR_TABLE_BIT) {
_mesa_lookup_rgba(&ctx->PostConvolutionColorTable, width, rgbaFloat);
}
/* color matrix */
if (transferOps & IMAGE_COLOR_MATRIX_BIT) {
_mesa_transform_rgba(ctx, width, rgbaFloat);
}
/* GL_POST_COLOR_MATRIX_COLOR_TABLE lookup */
if (transferOps & IMAGE_POST_COLOR_MATRIX_COLOR_TABLE_BIT) {
_mesa_lookup_rgba(&ctx->PostColorMatrixColorTable, width, rgbaFloat);
}
/* update histogram count */
if (transferOps & IMAGE_HISTOGRAM_BIT) {
_mesa_update_histogram(ctx, width, (CONST GLfloat (*)[4]) rgbaFloat);
}
/* update min/max */
if (transferOps & IMAGE_MIN_MAX_BIT) {
_mesa_update_minmax(ctx, width, (CONST GLfloat (*)[4]) rgbaFloat);
}
/* clamp to [0,1] and convert float back to chan */
for (k = 0; k < width; k++) {
GLint r = (GLint) (rgbaFloat[k][RCOMP] * CHAN_MAXF);
GLint g = (GLint) (rgbaFloat[k][GCOMP] * CHAN_MAXF);
GLint b = (GLint) (rgbaFloat[k][BCOMP] * CHAN_MAXF);
GLint a = (GLint) (rgbaFloat[k][ACOMP] * CHAN_MAXF);
span.array->rgba[k][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
span.array->rgba[k][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
span.array->rgba[k][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
span.array->rgba[k][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
}
UNDEFARRAY(rgbaFloat); /* mac 32k limitation */
}
 
if (ctx->Pixel.PixelTextureEnabled && ctx->Texture._EnabledUnits) {
span.end = width;
_swrast_pixel_texture(ctx, &span);
}
 
if (quick_draw && dy >= 0 && dy < (GLint) ctx->DrawBuffer->Height) {
(*swrast->Driver.WriteRGBASpan)( ctx, width, destx, dy,
(const GLchan (*)[4])span.array->rgba, NULL );
}
else if (zoom) {
span.x = destx;
span.y = dy;
span.end = width;
_mesa_write_zoomed_rgba_span(ctx, &span,
(CONST GLchan (*)[4]) span.array->rgba,
desty);
}
else {
span.x = destx;
span.y = dy;
span.end = width;
_mesa_write_rgba_span(ctx, &span);
}
}
 
if (overlapping)
FREE(tmpImage);
}
 
 
static void copy_ci_pixels( GLcontext *ctx,
GLint srcx, GLint srcy, GLint width, GLint height,
GLint destx, GLint desty )
{
GLuint *tmpImage,*p;
GLint sy, dy, stepy;
GLint j;
GLboolean changeBuffer;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset;
GLint overlapping;
struct sw_span span;
 
INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX);
 
/* Determine if copy should be bottom-to-top or top-to-bottom */
if (srcy<desty) {
/* top-down max-to-min */
sy = srcy + height - 1;
dy = desty + height - 1;
stepy = -1;
}
else {
/* bottom-up min-to-max */
sy = srcy;
dy = desty;
stepy = 1;
}
 
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
 
if (ctx->Depth.Test)
_mesa_span_default_z(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
 
/* If read and draw buffer are different we must do buffer switching */
changeBuffer = ctx->Pixel.ReadBuffer != ctx->Color.DrawBuffer
|| ctx->DrawBuffer != ctx->ReadBuffer;
 
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLuint *) MALLOC(width * height * sizeof(GLuint));
if (!tmpImage) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
return;
}
/* setup source */
if (changeBuffer)
_swrast_use_read_buffer(ctx);
/* read the image */
p = tmpImage;
for (j = 0; j < height; j++, ssy += stepy) {
_mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, ssy, p );
p += width;
}
p = tmpImage;
/* restore to draw buffer */
if (changeBuffer) {
_swrast_use_draw_buffer(ctx);
changeBuffer = GL_FALSE;
}
}
else {
tmpImage = NULL; /* silence compiler warning */
p = NULL;
}
 
for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
if (overlapping) {
MEMCPY(span.array->index, p, width * sizeof(GLuint));
p += width;
}
else {
if (changeBuffer)
_swrast_use_read_buffer(ctx);
_mesa_read_index_span( ctx, ctx->ReadBuffer, width, srcx, sy,
span.array->index );
if (changeBuffer)
_swrast_use_draw_buffer(ctx);
}
 
if (shift_or_offset) {
_mesa_shift_and_offset_ci( ctx, width, span.array->index );
}
if (ctx->Pixel.MapColorFlag) {
_mesa_map_ci( ctx, width, span.array->index );
}
 
span.x = destx;
span.y = dy;
span.end = width;
if (zoom)
_mesa_write_zoomed_index_span(ctx, &span, desty);
else
_mesa_write_index_span(ctx, &span);
}
 
if (overlapping)
FREE(tmpImage);
}
 
 
 
/*
* TODO: Optimize!!!!
*/
static void copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height,
GLint destx, GLint desty )
{
GLfloat depth[MAX_WIDTH];
GLfloat *p, *tmpImage;
GLint sy, dy, stepy;
GLint i, j;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
GLint overlapping;
struct sw_span span;
 
INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z);
 
if (!ctx->Visual.depthBits) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
return;
}
 
/* Determine if copy should be bottom-to-top or top-to-bottom */
if (srcy<desty) {
/* top-down max-to-min */
sy = srcy + height - 1;
dy = desty + height - 1;
stepy = -1;
}
else {
/* bottom-up min-to-max */
sy = srcy;
dy = desty;
stepy = 1;
}
 
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
 
_mesa_span_default_color(ctx, &span);
if (ctx->Fog.Enabled)
_mesa_span_default_fog(ctx, &span);
 
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLfloat *) MALLOC(width * height * sizeof(GLfloat));
if (!tmpImage) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
return;
}
p = tmpImage;
for (j = 0; j < height; j++, ssy += stepy) {
_mesa_read_depth_span_float(ctx, width, srcx, ssy, p);
p += width;
}
p = tmpImage;
}
else {
tmpImage = NULL; /* silence compiler warning */
p = NULL;
}
 
for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
if (overlapping) {
MEMCPY(depth, p, width * sizeof(GLfloat));
p += width;
}
else {
_mesa_read_depth_span_float(ctx, width, srcx, sy, depth);
}
 
for (i = 0; i < width; i++) {
GLfloat d = depth[i] * ctx->Pixel.DepthScale + ctx->Pixel.DepthBias;
span.array->z[i] = (GLdepth) (CLAMP(d, 0.0F, 1.0F) * ctx->DepthMax);
}
 
span.x = destx;
span.y = dy;
span.end = width;
if (ctx->Visual.rgbMode) {
if (zoom)
_mesa_write_zoomed_rgba_span( ctx, &span,
(const GLchan (*)[4])span.array->rgba,
desty );
else
_mesa_write_rgba_span(ctx, &span);
}
else {
if (zoom)
_mesa_write_zoomed_index_span( ctx, &span, desty );
else
_mesa_write_index_span(ctx, &span);
}
}
 
if (overlapping)
FREE(tmpImage);
}
 
 
 
static void copy_stencil_pixels( GLcontext *ctx, GLint srcx, GLint srcy,
GLint width, GLint height,
GLint destx, GLint desty )
{
GLint sy, dy, stepy;
GLint j;
GLstencil *p, *tmpImage;
const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F;
const GLboolean shift_or_offset = ctx->Pixel.IndexShift || ctx->Pixel.IndexOffset;
GLint overlapping;
 
if (!ctx->Visual.stencilBits) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glCopyPixels" );
return;
}
 
/* Determine if copy should be bottom-to-top or top-to-bottom */
if (srcy < desty) {
/* top-down max-to-min */
sy = srcy + height - 1;
dy = desty + height - 1;
stepy = -1;
}
else {
/* bottom-up min-to-max */
sy = srcy;
dy = desty;
stepy = 1;
}
 
overlapping = regions_overlap(srcx, srcy, destx, desty, width, height,
ctx->Pixel.ZoomX, ctx->Pixel.ZoomY);
 
if (overlapping) {
GLint ssy = sy;
tmpImage = (GLstencil *) MALLOC(width * height * sizeof(GLstencil));
if (!tmpImage) {
_mesa_error( ctx, GL_OUT_OF_MEMORY, "glCopyPixels" );
return;
}
p = tmpImage;
for (j = 0; j < height; j++, ssy += stepy) {
_mesa_read_stencil_span( ctx, width, srcx, ssy, p );
p += width;
}
p = tmpImage;
}
else {
tmpImage = NULL; /* silence compiler warning */
p = NULL;
}
 
for (j = 0; j < height; j++, sy += stepy, dy += stepy) {
GLstencil stencil[MAX_WIDTH];
 
if (overlapping) {
MEMCPY(stencil, p, width * sizeof(GLstencil));
p += width;
}
else {
_mesa_read_stencil_span( ctx, width, srcx, sy, stencil );
}
 
if (shift_or_offset) {
_mesa_shift_and_offset_stencil( ctx, width, stencil );
}
if (ctx->Pixel.MapStencilFlag) {
_mesa_map_stencil( ctx, width, stencil );
}
 
if (zoom) {
_mesa_write_zoomed_stencil_span( ctx, width, destx, dy, stencil, desty );
}
else {
_mesa_write_stencil_span( ctx, width, destx, dy, stencil );
}
}
 
if (overlapping)
FREE(tmpImage);
}
 
 
 
 
void
_swrast_CopyPixels( GLcontext *ctx,
GLint srcx, GLint srcy, GLsizei width, GLsizei height,
GLint destx, GLint desty,
GLenum type )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
RENDER_START(swrast,ctx);
if (swrast->NewState)
_swrast_validate_derived( ctx );
 
if (type == GL_COLOR && ctx->Visual.rgbMode) {
copy_rgba_pixels( ctx, srcx, srcy, width, height, destx, desty );
}
else if (type == GL_COLOR && !ctx->Visual.rgbMode) {
copy_ci_pixels( ctx, srcx, srcy, width, height, destx, desty );
}
else if (type == GL_DEPTH) {
copy_depth_pixels( ctx, srcx, srcy, width, height, destx, desty );
}
else if (type == GL_STENCIL) {
copy_stencil_pixels( ctx, srcx, srcy, width, height, destx, desty );
}
else {
_mesa_error( ctx, GL_INVALID_ENUM, "glCopyPixels" );
}
 
RENDER_FINISH(swrast,ctx);
}
/shark/trunk/ports/mesa/src/swrast/s_readpix.c
0,0 → 1,526
/* $Id: s_readpix.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "convolve.h"
#include "context.h"
#include "feedback.h"
#include "image.h"
#include "macros.h"
#include "imports.h"
#include "pixel.h"
 
#include "s_alphabuf.h"
#include "s_context.h"
#include "s_depth.h"
#include "s_span.h"
#include "s_stencil.h"
 
 
 
/*
* Read a block of color index pixels.
*/
static void
read_index_pixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type, GLvoid *pixels,
const struct gl_pixelstore_attrib *packing )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint i, readWidth;
 
/* error checking */
if (ctx->Visual.rgbMode) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
return;
}
 
_swrast_use_read_buffer(ctx);
 
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
 
/* process image row by row */
for (i = 0; i < height; i++) {
GLuint index[MAX_WIDTH];
GLvoid *dest;
 
(*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y + i, index);
 
dest = _mesa_image_address(packing, pixels, width, height,
GL_COLOR_INDEX, type, 0, i, 0);
 
_mesa_pack_index_span(ctx, readWidth, type, dest, index,
&ctx->Pack, ctx->_ImageTransferState);
}
 
_swrast_use_draw_buffer(ctx);
}
 
 
 
static void
read_depth_pixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type, GLvoid *pixels,
const struct gl_pixelstore_attrib *packing )
{
GLint readWidth;
GLboolean bias_or_scale;
 
/* Error checking */
if (ctx->Visual.depthBits <= 0) {
/* No depth buffer */
_mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
return;
}
 
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
 
if (type != GL_BYTE &&
type != GL_UNSIGNED_BYTE &&
type != GL_SHORT &&
type != GL_UNSIGNED_SHORT &&
type != GL_INT &&
type != GL_UNSIGNED_INT &&
type != GL_FLOAT) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels(depth type)");
return;
}
 
bias_or_scale = ctx->Pixel.DepthBias!=0.0 || ctx->Pixel.DepthScale!=1.0;
 
if (type==GL_UNSIGNED_SHORT && ctx->Visual.depthBits == 16
&& !bias_or_scale && !packing->SwapBytes) {
/* Special case: directly read 16-bit unsigned depth values. */
GLint j;
for (j=0;j<height;j++,y++) {
GLdepth depth[MAX_WIDTH];
GLushort *dst = (GLushort*) _mesa_image_address( packing, pixels,
width, height, GL_DEPTH_COMPONENT, type, 0, j, 0 );
GLint i;
_mesa_read_depth_span(ctx, width, x, y, depth);
for (i = 0; i < width; i++)
dst[i] = depth[i];
}
}
else if (type==GL_UNSIGNED_INT && ctx->Visual.depthBits == 32
&& !bias_or_scale && !packing->SwapBytes) {
/* Special case: directly read 32-bit unsigned depth values. */
GLint j;
for (j=0;j<height;j++,y++) {
GLdepth *dst = (GLdepth *) _mesa_image_address( packing, pixels,
width, height, GL_DEPTH_COMPONENT, type, 0, j, 0 );
_mesa_read_depth_span(ctx, width, x, y, dst);
}
}
else {
/* General case (slower) */
GLint j;
for (j=0;j<height;j++,y++) {
GLfloat depth[MAX_WIDTH];
GLvoid *dest;
 
_mesa_read_depth_span_float(ctx, readWidth, x, y, depth);
 
dest = _mesa_image_address(packing, pixels, width, height,
GL_DEPTH_COMPONENT, type, 0, j, 0);
 
_mesa_pack_depth_span(ctx, readWidth, (GLdepth *) dest, type,
depth, &ctx->Pack);
}
}
}
 
 
 
static void
read_stencil_pixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum type, GLvoid *pixels,
const struct gl_pixelstore_attrib *packing )
{
GLint j, readWidth;
 
if (type != GL_BYTE &&
type != GL_UNSIGNED_BYTE &&
type != GL_SHORT &&
type != GL_UNSIGNED_SHORT &&
type != GL_INT &&
type != GL_UNSIGNED_INT &&
type != GL_FLOAT &&
type != GL_BITMAP) {
_mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels(stencil type)");
return;
}
 
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
 
if (ctx->Visual.stencilBits <= 0) {
/* No stencil buffer */
_mesa_error( ctx, GL_INVALID_OPERATION, "glReadPixels" );
return;
}
 
/* process image row by row */
for (j=0;j<height;j++,y++) {
GLvoid *dest;
GLstencil stencil[MAX_WIDTH];
 
_mesa_read_stencil_span(ctx, readWidth, x, y, stencil);
 
dest = _mesa_image_address(packing, pixels, width, height,
GL_STENCIL_INDEX, type, 0, j, 0);
 
_mesa_pack_stencil_span(ctx, readWidth, type, dest, stencil, &ctx->Pack);
}
}
 
 
 
/*
* Optimized glReadPixels for particular pixel formats:
* GL_UNSIGNED_BYTE, GL_RGBA
* when pixel scaling, biasing and mapping are disabled.
*/
static GLboolean
read_fast_rgba_pixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
GLvoid *pixels,
const struct gl_pixelstore_attrib *packing )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
/* can't do scale, bias, mapping, etc */
if (ctx->_ImageTransferState)
return GL_FALSE;
 
/* can't do fancy pixel packing */
if (packing->Alignment != 1 || packing->SwapBytes || packing->LsbFirst)
return GL_FALSE;
 
{
GLint srcX = x;
GLint srcY = y;
GLint readWidth = width; /* actual width read */
GLint readHeight = height; /* actual height read */
GLint skipPixels = packing->SkipPixels;
GLint skipRows = packing->SkipRows;
GLint rowLength;
 
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 GL_TRUE;
 
/* 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 GL_TRUE;
 
/*
* 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 CHAN_BITS == 8
if (format == GL_RGBA && type == GL_UNSIGNED_BYTE) {
#elif CHAN_BITS == 16
if (format == GL_RGBA && type == GL_UNSIGNED_SHORT) {
#else
if (0) {
#endif
GLchan *dest = (GLchan *) pixels
+ (skipRows * rowLength + skipPixels) * 4;
GLint row;
 
if (packing->Invert) {
/* start at top and go down */
dest += (readHeight - 1) * rowLength * 4;
rowLength = -rowLength;
}
 
for (row=0; row<readHeight; row++) {
(*swrast->Driver.ReadRGBASpan)(ctx, readWidth, srcX, srcY,
(GLchan (*)[4]) dest);
if (ctx->DrawBuffer->UseSoftwareAlphaBuffers) {
_mesa_read_alpha_span(ctx, readWidth, srcX, srcY,
(GLchan (*)[4]) dest);
}
dest += rowLength * 4;
srcY++;
}
return GL_TRUE;
}
else {
/* can't do this format/type combination */
return GL_FALSE;
}
}
}
 
 
 
/*
* Read R, G, B, A, RGB, L, or LA pixels.
*/
static void
read_rgba_pixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type, GLvoid *pixels,
const struct gl_pixelstore_attrib *packing )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLint readWidth;
 
_swrast_use_read_buffer(ctx);
 
/* Try optimized path first */
if (read_fast_rgba_pixels( ctx, x, y, width, height,
format, type, pixels, packing )) {
 
_swrast_use_draw_buffer(ctx);
return; /* done! */
}
 
readWidth = (width > MAX_WIDTH) ? MAX_WIDTH : width;
 
/* do error checking on pixel type, format was already checked by caller */
switch (type) {
case GL_UNSIGNED_BYTE:
case GL_BYTE:
case GL_UNSIGNED_SHORT:
case GL_SHORT:
case GL_UNSIGNED_INT:
case GL_INT:
case GL_FLOAT:
case GL_UNSIGNED_BYTE_3_3_2:
case GL_UNSIGNED_BYTE_2_3_3_REV:
case GL_UNSIGNED_SHORT_5_6_5:
case GL_UNSIGNED_SHORT_5_6_5_REV:
case GL_UNSIGNED_SHORT_4_4_4_4:
case GL_UNSIGNED_SHORT_4_4_4_4_REV:
case GL_UNSIGNED_SHORT_5_5_5_1:
case GL_UNSIGNED_SHORT_1_5_5_5_REV:
case GL_UNSIGNED_INT_8_8_8_8:
case GL_UNSIGNED_INT_8_8_8_8_REV:
case GL_UNSIGNED_INT_10_10_10_2:
case GL_UNSIGNED_INT_2_10_10_10_REV:
/* valid pixel type */
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glReadPixels(type)" );
return;
}
 
if (!_mesa_is_legal_format_and_type(format, type) ||
format == GL_INTENSITY) {
_mesa_error(ctx, GL_INVALID_OPERATION, "glReadPixels(format or type)");
return;
}
 
if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) {
const GLuint transferOps = ctx->_ImageTransferState;
GLfloat *dest, *src, *tmpImage, *convImage;
GLint row;
 
tmpImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
if (!tmpImage) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return;
}
convImage = (GLfloat *) MALLOC(width * height * 4 * sizeof(GLfloat));
if (!convImage) {
FREE(tmpImage);
_mesa_error(ctx, GL_OUT_OF_MEMORY, "glReadPixels");
return;
}
 
/* read full RGBA, FLOAT image */
dest = tmpImage;
for (row = 0; row < height; row++, y++) {
GLchan rgba[MAX_WIDTH][4];
if (ctx->Visual.rgbMode) {
_mesa_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba);
}
else {
GLuint index[MAX_WIDTH];
(*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y, index);
if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset !=0 ) {
_mesa_map_ci(ctx, readWidth, index);
}
_mesa_map_ci_to_rgba_chan(ctx, readWidth, index, rgba);
}
_mesa_pack_rgba_span(ctx, readWidth, (const GLchan (*)[4]) rgba,
GL_RGBA, GL_FLOAT, dest, &_mesa_native_packing,
transferOps & IMAGE_PRE_CONVOLUTION_BITS);
dest += width * 4;
}
 
/* do convolution */
if (ctx->Pixel.Convolution2DEnabled) {
_mesa_convolve_2d_image(ctx, &readWidth, &height, tmpImage, convImage);
}
else {
ASSERT(ctx->Pixel.Separable2DEnabled);
_mesa_convolve_sep_image(ctx, &readWidth, &height, tmpImage, convImage);
}
FREE(tmpImage);
 
/* finish transfer ops and pack the resulting image */
src = convImage;
for (row = 0; row < height; row++) {
GLvoid *dest;
dest = _mesa_image_address(packing, pixels, readWidth, height,
format, type, 0, row, 0);
_mesa_pack_float_rgba_span(ctx, readWidth,
(const GLfloat (*)[4]) src,
format, type, dest, packing,
transferOps & IMAGE_POST_CONVOLUTION_BITS);
src += readWidth * 4;
}
}
else {
/* no convolution */
GLint row;
for (row = 0; row < height; row++, y++) {
GLchan rgba[MAX_WIDTH][4];
GLvoid *dst;
if (ctx->Visual.rgbMode) {
_mesa_read_rgba_span(ctx, ctx->ReadBuffer, readWidth, x, y, rgba);
}
else {
GLuint index[MAX_WIDTH];
(*swrast->Driver.ReadCI32Span)(ctx, readWidth, x, y, index);
if (ctx->Pixel.IndexShift != 0 || ctx->Pixel.IndexOffset != 0) {
_mesa_map_ci(ctx, readWidth, index);
}
_mesa_map_ci_to_rgba_chan(ctx, readWidth, index, rgba);
}
dst = _mesa_image_address(packing, pixels, width, height,
format, type, 0, row, 0);
if (ctx->Visual.redBits < CHAN_BITS ||
ctx->Visual.greenBits < CHAN_BITS ||
ctx->Visual.blueBits < CHAN_BITS) {
/* Requantize the color values into floating point and go from
* there. This fixes conformance failures with 16-bit color
* buffers, for example.
*/
DEFMARRAY(GLfloat, rgbaf, MAX_WIDTH, 4); /* mac 32k limitation */
CHECKARRAY(rgbaf, return); /* mac 32k limitation */
_mesa_chan_to_float_span(ctx, readWidth,
(CONST GLchan (*)[4]) rgba, rgbaf);
_mesa_pack_float_rgba_span(ctx, readWidth,
(CONST GLfloat (*)[4]) rgbaf,
format, type, dst, packing,
ctx->_ImageTransferState);
UNDEFARRAY(rgbaf); /* mac 32k limitation */
}
else {
/* GLubytes are fine */
_mesa_pack_rgba_span(ctx, readWidth, (CONST GLchan (*)[4]) rgba,
format, type, dst, packing,
ctx->_ImageTransferState);
}
}
}
 
_swrast_use_draw_buffer(ctx);
}
 
 
 
void
_swrast_ReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *pack,
GLvoid *pixels )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
(void) pack;
 
if (swrast->NewState)
_swrast_validate_derived( ctx );
 
RENDER_START(swrast,ctx);
 
switch (format) {
case GL_COLOR_INDEX:
read_index_pixels(ctx, x, y, width, height, type, pixels, &ctx->Pack);
break;
case GL_STENCIL_INDEX:
read_stencil_pixels(ctx, x,y, width,height, type, pixels, &ctx->Pack);
break;
case GL_DEPTH_COMPONENT:
read_depth_pixels(ctx, x, y, width, height, type, pixels, &ctx->Pack);
break;
case GL_RED:
case GL_GREEN:
case GL_BLUE:
case GL_ALPHA:
case GL_RGB:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_RGBA:
case GL_BGR:
case GL_BGRA:
case GL_ABGR_EXT:
read_rgba_pixels(ctx, x, y, width, height,
format, type, pixels, &ctx->Pack);
break;
default:
_mesa_error( ctx, GL_INVALID_ENUM, "glReadPixels(format)" );
}
 
RENDER_FINISH(swrast,ctx);
}
/shark/trunk/ports/mesa/src/swrast/s_histogram.c
0,0 → 1,97
/* $Id: s_histogram.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#include "glheader.h"
#include "colormac.h"
#include "image.h"
#include "mmath.h"
 
#include "s_context.h"
#include "s_histogram.h"
#include "s_span.h"
 
 
 
/*
* Update the min/max values from an array of fragment colors.
*/
void
_mesa_update_minmax(GLcontext *ctx, GLuint n, const GLfloat rgba[][4])
{
GLuint i;
for (i = 0; i < n; i++) {
/* update mins */
if (rgba[i][RCOMP] < ctx->MinMax.Min[RCOMP])
ctx->MinMax.Min[RCOMP] = rgba[i][RCOMP];
if (rgba[i][GCOMP] < ctx->MinMax.Min[GCOMP])
ctx->MinMax.Min[GCOMP] = rgba[i][GCOMP];
if (rgba[i][BCOMP] < ctx->MinMax.Min[BCOMP])
ctx->MinMax.Min[BCOMP] = rgba[i][BCOMP];
if (rgba[i][ACOMP] < ctx->MinMax.Min[ACOMP])
ctx->MinMax.Min[ACOMP] = rgba[i][ACOMP];
 
/* update maxs */
if (rgba[i][RCOMP] > ctx->MinMax.Max[RCOMP])
ctx->MinMax.Max[RCOMP] = rgba[i][RCOMP];
if (rgba[i][GCOMP] > ctx->MinMax.Max[GCOMP])
ctx->MinMax.Max[GCOMP] = rgba[i][GCOMP];
if (rgba[i][BCOMP] > ctx->MinMax.Max[BCOMP])
ctx->MinMax.Max[BCOMP] = rgba[i][BCOMP];
if (rgba[i][ACOMP] > ctx->MinMax.Max[ACOMP])
ctx->MinMax.Max[ACOMP] = rgba[i][ACOMP];
}
}
 
 
/*
* Update the histogram values from an array of fragment colors.
*/
void
_mesa_update_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4])
{
const GLint max = ctx->Histogram.Width - 1;
GLfloat w = (GLfloat) max;
GLuint i;
 
if (ctx->Histogram.Width == 0)
return;
 
for (i = 0; i < n; i++) {
GLint ri = IROUND(rgba[i][RCOMP] * w);
GLint gi = IROUND(rgba[i][GCOMP] * w);
GLint bi = IROUND(rgba[i][BCOMP] * w);
GLint ai = IROUND(rgba[i][ACOMP] * w);
ri = CLAMP(ri, 0, max);
gi = CLAMP(gi, 0, max);
bi = CLAMP(bi, 0, max);
ai = CLAMP(ai, 0, max);
ctx->Histogram.Count[ri][RCOMP]++;
ctx->Histogram.Count[gi][GCOMP]++;
ctx->Histogram.Count[bi][BCOMP]++;
ctx->Histogram.Count[ai][ACOMP]++;
}
}
/shark/trunk/ports/mesa/src/swrast/s_masking.h
0,0 → 1,62
/* $Id: s_masking.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_MASKING_H
#define S_MASKING_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
/*
* Implement glColorMask for a span of RGBA pixels.
*/
extern void
_mesa_mask_rgba_span( GLcontext *ctx, const struct sw_span *span,
GLchan rgba[][4] );
 
 
extern void
_mesa_mask_rgba_array( GLcontext *ctx, GLuint n, GLint x, GLint y,
GLchan rgba[][4] );
 
 
/*
* Implement glIndexMask for a span of CI pixels.
*/
extern void
_mesa_mask_index_span( GLcontext *ctx, const struct sw_span *span,
GLuint index[] );
 
 
extern void
_mesa_mask_index_array( GLcontext *ctx,
GLuint n, GLint x, GLint y, GLuint index[] );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_texture.c
0,0 → 1,3743
/* $Id: s_texture.c,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 5.0
*
* 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.
*/
 
 
#include "glheader.h"
#include "context.h"
#include "colormac.h"
#include "macros.h"
#include "mmath.h"
#include "imports.h"
#include "texformat.h"
#include "teximage.h"
 
#include "s_context.h"
#include "s_texture.h"
 
 
/*
* These values are used in the fixed-point arithmetic used
* for linear filtering.
*/
#define WEIGHT_SCALE 65536.0F
#define WEIGHT_SHIFT 16
 
 
/*
* Used to compute texel locations for linear sampling.
* Input:
* wrapMode = GL_REPEAT, GL_CLAMP, GL_CLAMP_TO_EDGE, GL_CLAMP_TO_BORDER_ARB
* S = texcoord in [0,1]
* SIZE = width (or height or depth) of texture
* Output:
* U = texcoord in [0, width]
* I0, I1 = two nearest texel indexes
*/
#define COMPUTE_LINEAR_TEXEL_LOCATIONS(wrapMode, S, U, SIZE, I0, I1) \
{ \
if (wrapMode == GL_REPEAT) { \
U = S * SIZE - 0.5F; \
I0 = IFLOOR(U) & (SIZE - 1); \
I1 = (I0 + 1) & (SIZE - 1); \
} \
else if (wrapMode == GL_CLAMP_TO_EDGE) { \
if (S <= 0.0F) \
U = 0.0F; \
else if (S >= 1.0F) \
U = (GLfloat) SIZE; \
else \
U = S * SIZE; \
U -= 0.5F; \
I0 = IFLOOR(U); \
I1 = I0 + 1; \
if (I0 < 0) \
I0 = 0; \
if (I1 >= (GLint) SIZE) \
I1 = SIZE - 1; \
} \
else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) { \
const GLfloat min = -1.0F / (2.0F * SIZE); \
const GLfloat max = 1.0F - min; \
if (S <= min) \
U = min * SIZE; \
else if (S >= max) \
U = max * SIZE; \
else \
U = S * SIZE; \
U -= 0.5F; \
I0 = IFLOOR(U); \
I1 = I0 + 1; \
} \
else if (wrapMode == GL_MIRRORED_REPEAT_ARB) { \
const GLint flr = IFLOOR(S); \
if (flr & 1) \
U = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \
else \
U = S - (GLfloat) flr; /* flr is even */ \
U = (U * SIZE) - 0.5F; \
I0 = IFLOOR(U); \
I1 = I0 + 1; \
if (I0 < 0) \
I0 = 0; \
if (I1 >= (GLint) SIZE) \
I1 = SIZE - 1; \
} \
else if (wrapMode == GL_MIRROR_CLAMP_ATI) { \
U = (GLfloat) fabs(S); \
if (U >= 1.0F) \
U = (GLfloat) SIZE; \
else \
U *= SIZE; \
U -= 0.5F; \
I0 = IFLOOR(U); \
I1 = I0 + 1; \
} \
else if (wrapMode == GL_MIRROR_CLAMP_TO_EDGE_ATI) { \
U = (GLfloat) fabs(S); \
if (U >= 1.0F) \
U = (GLfloat) SIZE; \
else \
U *= SIZE; \
U -= 0.5F; \
I0 = IFLOOR(U); \
I1 = I0 + 1; \
if (I0 < 0) \
I0 = 0; \
if (I1 >= (GLint) SIZE) \
I1 = SIZE - 1; \
} \
else { \
ASSERT(wrapMode == GL_CLAMP); \
if (S <= 0.0F) \
U = 0.0F; \
else if (S >= 1.0F) \
U = (GLfloat) SIZE; \
else \
U = S * SIZE; \
U -= 0.5F; \
I0 = IFLOOR(U); \
I1 = I0 + 1; \
} \
}
 
 
/*
* Used to compute texel location for nearest sampling.
*/
#define COMPUTE_NEAREST_TEXEL_LOCATION(wrapMode, S, SIZE, I) \
{ \
if (wrapMode == GL_REPEAT) { \
/* s limited to [0,1) */ \
/* i limited to [0,size-1] */ \
I = IFLOOR(S * SIZE); \
I &= (SIZE - 1); \
} \
else if (wrapMode == GL_CLAMP_TO_EDGE) { \
/* s limited to [min,max] */ \
/* i limited to [0, size-1] */ \
const GLfloat min = 1.0F / (2.0F * SIZE); \
const GLfloat max = 1.0F - min; \
if (S < min) \
I = 0; \
else if (S > max) \
I = SIZE - 1; \
else \
I = IFLOOR(S * SIZE); \
} \
else if (wrapMode == GL_CLAMP_TO_BORDER_ARB) { \
/* s limited to [min,max] */ \
/* i limited to [-1, size] */ \
const GLfloat min = -1.0F / (2.0F * SIZE); \
const GLfloat max = 1.0F - min; \
if (S <= min) \
I = -1; \
else if (S >= max) \
I = SIZE; \
else \
I = IFLOOR(S * SIZE); \
} \
else if (wrapMode == GL_MIRRORED_REPEAT_ARB) { \
const GLfloat min = 1.0F / (2.0F * SIZE); \
const GLfloat max = 1.0F - min; \
const GLint flr = IFLOOR(S); \
GLfloat u; \
if (flr & 1) \
u = 1.0F - (S - (GLfloat) flr); /* flr is odd */ \
else \
u = S - (GLfloat) flr; /* flr is even */ \
if (u < min) \
I = 0; \
else if (u > max) \
I = SIZE - 1; \
else \
I = IFLOOR(u * SIZE); \
} \
else if (wrapMode == GL_MIRROR_CLAMP_ATI) { \
/* s limited to [0,1] */ \
/* i limited to [0,size-1] */ \
const GLfloat u = (GLfloat) fabs(S); \
if (u <= 0.0F) \
I = 0; \
else if (u >= 1.0F) \
I = SIZE - 1; \
else \
I = IFLOOR(u * SIZE); \
} \
else if (wrapMode == GL_MIRROR_CLAMP_TO_EDGE_ATI) { \
/* s limited to [min,max] */ \
/* i limited to [0, size-1] */ \
const GLfloat min = 1.0F / (2.0F * SIZE); \
const GLfloat max = 1.0F - min; \
const GLfloat u = (GLfloat) fabs(S); \
if (u < min) \
I = 0; \
else if (u > max) \
I = SIZE - 1; \
else \
I = IFLOOR(u * SIZE); \
} \
else { \
ASSERT(wrapMode == GL_CLAMP); \
/* s limited to [0,1] */ \
/* i limited to [0,size-1] */ \
if (S <= 0.0F) \
I = 0; \
else if (S >= 1.0F) \
I = SIZE - 1; \
else \
I = IFLOOR(S * SIZE); \
} \
}
 
 
#define COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(S, U, SIZE, I0, I1) \
{ \
U = S * SIZE - 0.5F; \
I0 = IFLOOR(U) & (SIZE - 1); \
I1 = (I0 + 1) & (SIZE - 1); \
}
 
 
/*
* Compute linear mipmap levels for given lambda.
*/
#define COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda, level) \
{ \
if (lambda < 0.0F) \
level = tObj->BaseLevel; \
else if (lambda > tObj->_MaxLambda) \
level = (GLint) (tObj->BaseLevel + tObj->_MaxLambda); \
else \
level = (GLint) (tObj->BaseLevel + lambda); \
}
 
 
/*
* Compute nearest mipmap level for given lambda.
*/
#define COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda, level) \
{ \
GLfloat l; \
if (lambda <= 0.5F) \
l = 0.0F; \
else if (lambda > tObj->_MaxLambda + 0.4999F) \
l = tObj->_MaxLambda + 0.4999F; \
else \
l = lambda; \
level = (GLint) (tObj->BaseLevel + l + 0.5F); \
if (level > tObj->_MaxLevel) \
level = tObj->_MaxLevel; \
}
 
 
 
/*
* Note, the FRAC macro has to work perfectly. Otherwise you'll sometimes
* see 1-pixel bands of improperly weighted linear-sampled texels. The
* tests/texwrap.c demo is a good test.
* Also note, FRAC(x) doesn't truly return the fractional part of x for x < 0.
* Instead, if x < 0 then FRAC(x) = 1 - true_frac(x).
*/
#define FRAC(f) ((f) - IFLOOR(f))
 
 
 
/*
* Bitflags for texture border color sampling.
*/
#define I0BIT 1
#define I1BIT 2
#define J0BIT 4
#define J1BIT 8
#define K0BIT 16
#define K1BIT 32
 
 
 
/*
* Get texture palette entry.
*/
static void
palette_sample(const GLcontext *ctx,
const struct gl_texture_object *tObj,
GLint index, GLchan rgba[4] )
{
const GLchan *palette;
GLenum format;
 
if (ctx->Texture.SharedPalette) {
ASSERT(!ctx->Texture.Palette.FloatTable);
palette = (const GLchan *) ctx->Texture.Palette.Table;
format = ctx->Texture.Palette.Format;
}
else {
ASSERT(!tObj->Palette.FloatTable);
palette = (const GLchan *) tObj->Palette.Table;
format = tObj->Palette.Format;
}
 
switch (format) {
case GL_ALPHA:
rgba[ACOMP] = palette[index];
return;
case GL_LUMINANCE:
case GL_INTENSITY:
rgba[RCOMP] = palette[index];
return;
case GL_LUMINANCE_ALPHA:
rgba[RCOMP] = palette[(index << 1) + 0];
rgba[ACOMP] = palette[(index << 1) + 1];
return;
case GL_RGB:
rgba[RCOMP] = palette[index * 3 + 0];
rgba[GCOMP] = palette[index * 3 + 1];
rgba[BCOMP] = palette[index * 3 + 2];
return;
case GL_RGBA:
rgba[RCOMP] = palette[(index << 2) + 0];
rgba[GCOMP] = palette[(index << 2) + 1];
rgba[BCOMP] = palette[(index << 2) + 2];
rgba[ACOMP] = palette[(index << 2) + 3];
return;
default:
_mesa_problem(ctx, "Bad palette format in palette_sample");
}
}
 
 
/*
* The lambda[] array values are always monotonic. Either the whole span
* will be minified, magnified, or split between the two. This function
* determines the subranges in [0, n-1] that are to be minified or magnified.
*/
static INLINE void
compute_min_mag_ranges( GLfloat minMagThresh, GLuint n, const GLfloat lambda[],
GLuint *minStart, GLuint *minEnd,
GLuint *magStart, GLuint *magEnd )
{
ASSERT(lambda != NULL);
#if 0
/* Verify that lambda[] is monotonous.
* We can't really use this because the inaccuracy in the LOG2 function
* causes this test to fail, yet the resulting texturing is correct.
*/
if (n > 1) {
GLuint i;
printf("lambda delta = %g\n", lambda[0] - lambda[n-1]);
if (lambda[0] >= lambda[n-1]) { /* decreasing */
for (i = 0; i < n - 1; i++) {
ASSERT((GLint) (lambda[i] * 10) >= (GLint) (lambda[i+1] * 10));
}
}
else { /* increasing */
for (i = 0; i < n - 1; i++) {
ASSERT((GLint) (lambda[i] * 10) <= (GLint) (lambda[i+1] * 10));
}
}
}
#endif /* DEBUG */
 
/* since lambda is monotonous-array use this check first */
if (lambda[0] <= minMagThresh && lambda[n-1] <= minMagThresh) {
/* magnification for whole span */
*magStart = 0;
*magEnd = n;
*minStart = *minEnd = 0;
}
else if (lambda[0] > minMagThresh && lambda[n-1] > minMagThresh) {
/* minification for whole span */
*minStart = 0;
*minEnd = n;
*magStart = *magEnd = 0;
}
else {
/* a mix of minification and magnification */
GLuint i;
if (lambda[0] > minMagThresh) {
/* start with minification */
for (i = 1; i < n; i++) {
if (lambda[i] <= minMagThresh)
break;
}
*minStart = 0;
*minEnd = i;
*magStart = i;
*magEnd = n;
}
else {
/* start with magnification */
for (i = 1; i < n; i++) {
if (lambda[i] > minMagThresh)
break;
}
*magStart = 0;
*magEnd = i;
*minStart = i;
*minEnd = n;
}
}
 
#if 0
/* Verify the min/mag Start/End values
* We don't use this either (see above)
*/
{
GLint i;
for (i = 0; i < n; i++) {
if (lambda[i] > minMagThresh) {
/* minification */
ASSERT(i >= *minStart);
ASSERT(i < *minEnd);
}
else {
/* magnification */
ASSERT(i >= *magStart);
ASSERT(i < *magEnd);
}
}
}
#endif
}
 
 
/**********************************************************************/
/* 1-D Texture Sampling Functions */
/**********************************************************************/
 
/*
* Return the texture sample for coordinate (s) using GL_NEAREST filter.
*/
static void
sample_1d_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
const GLfloat texcoord[4], GLchan rgba[4])
{
const GLint width = img->Width2; /* without border, power of two */
GLint i;
 
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);
 
/* skip over the border, if any */
i += img->Border;
 
if (i < 0 || i >= (GLint) img->Width) {
/* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
COPY_CHAN4(rgba, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i, 0, 0, (GLvoid *) rgba);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, rgba[0], rgba);
}
}
}
 
 
 
/*
* Return the texture sample for coordinate (s) using GL_LINEAR filter.
*/
static void
sample_1d_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
const GLfloat texcoord[4], GLchan rgba[4])
{
const GLint width = img->Width2;
GLint i0, i1;
GLfloat u;
GLuint useBorderColor;
 
COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);
 
useBorderColor = 0;
if (img->Border) {
i0 += img->Border;
i1 += img->Border;
}
else {
if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
}
 
{
const GLfloat a = FRAC(u);
 
#if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT
const GLfloat w0 = (1.0F-a);
const GLfloat w1 = a ;
#else /* CHAN_BITS == 8 */
/* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
const GLint w0 = IROUND_POS((1.0F - a) * WEIGHT_SCALE);
const GLint w1 = IROUND_POS( a * WEIGHT_SCALE);
#endif
GLchan t0[4], t1[4]; /* texels */
 
if (useBorderColor & I0BIT) {
COPY_CHAN4(t0, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, 0, 0, (GLvoid *) t0);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t0[0], t0);
}
}
if (useBorderColor & I1BIT) {
COPY_CHAN4(t1, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, 0, 0, (GLvoid *) t1);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t1[0], t1);
}
}
 
#if CHAN_TYPE == GL_FLOAT
rgba[0] = w0 * t0[0] + w1 * t1[0];
rgba[1] = w0 * t0[1] + w1 * t1[1];
rgba[2] = w0 * t0[2] + w1 * t1[2];
rgba[3] = w0 * t0[3] + w1 * t1[3];
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
rgba[0] = (GLchan) (w0 * t0[0] + w1 * t1[0] + 0.5);
rgba[1] = (GLchan) (w0 * t0[1] + w1 * t1[1] + 0.5);
rgba[2] = (GLchan) (w0 * t0[2] + w1 * t1[2] + 0.5);
rgba[3] = (GLchan) (w0 * t0[3] + w1 * t1[3] + 0.5);
#else /* CHAN_BITS == 8 */
rgba[0] = (GLchan) ((w0 * t0[0] + w1 * t1[0]) >> WEIGHT_SHIFT);
rgba[1] = (GLchan) ((w0 * t0[1] + w1 * t1[1]) >> WEIGHT_SHIFT);
rgba[2] = (GLchan) ((w0 * t0[2] + w1 * t1[2]) >> WEIGHT_SHIFT);
rgba[3] = (GLchan) ((w0 * t0[3] + w1 * t1[3]) >> WEIGHT_SHIFT);
#endif
 
}
}
 
 
static void
sample_1d_nearest_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
sample_1d_nearest(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
}
}
 
 
static void
sample_1d_linear_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
sample_1d_linear(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
}
}
 
 
 
/*
* This is really just needed in order to prevent warnings with some compilers.
*/
#if CHAN_TYPE == GL_FLOAT
#define CHAN_CAST
#else
#define CHAN_CAST (GLchan) (GLint)
#endif
 
 
static void
sample_1d_nearest_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
if (level >= tObj->_MaxLevel) {
sample_1d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
texcoord[i], rgba[i]);
}
else {
GLchan t0[4], t1[4];
const GLfloat f = FRAC(lambda[i]);
sample_1d_nearest(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
sample_1d_nearest(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
 
static void
sample_1d_linear_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
if (level >= tObj->_MaxLevel) {
sample_1d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel],
texcoord[i], rgba[i]);
}
else {
GLchan t0[4], t1[4];
const GLfloat f = FRAC(lambda[i]);
sample_1d_linear(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
sample_1d_linear(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
 
static void
sample_nearest_1d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
sample_1d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
 
 
 
static void
sample_linear_1d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
sample_1d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
 
 
/*
* Given an (s) texture coordinate and lambda (level of detail) value,
* return a texture sample.
*
*/
static void
sample_lambda_1d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint minStart, minEnd; /* texels with minification */
GLuint magStart, magEnd; /* texels with magnification */
GLuint i;
 
ASSERT(lambda != NULL);
compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
n, lambda, &minStart, &minEnd, &magStart, &magEnd);
 
if (minStart < minEnd) {
/* do the minified texels */
const GLuint m = minEnd - minStart;
switch (tObj->MinFilter) {
case GL_NEAREST:
for (i = minStart; i < minEnd; i++)
sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
texcoords[i], rgba[i]);
break;
case GL_LINEAR:
for (i = minStart; i < minEnd; i++)
sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
texcoords[i], rgba[i]);
break;
case GL_NEAREST_MIPMAP_NEAREST:
sample_1d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR_MIPMAP_NEAREST:
sample_1d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_NEAREST_MIPMAP_LINEAR:
sample_1d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR_MIPMAP_LINEAR:
sample_1d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
default:
_mesa_problem(ctx, "Bad min filter in sample_1d_texture");
return;
}
}
 
if (magStart < magEnd) {
/* do the magnified texels */
switch (tObj->MagFilter) {
case GL_NEAREST:
for (i = magStart; i < magEnd; i++)
sample_1d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
texcoords[i], rgba[i]);
break;
case GL_LINEAR:
for (i = magStart; i < magEnd; i++)
sample_1d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
texcoords[i], rgba[i]);
break;
default:
_mesa_problem(ctx, "Bad mag filter in sample_1d_texture");
return;
}
}
}
 
 
/**********************************************************************/
/* 2-D Texture Sampling Functions */
/**********************************************************************/
 
 
/*
* Return the texture sample for coordinate (s,t) using GL_NEAREST filter.
*/
static INLINE void
sample_2d_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
const GLfloat texcoord[4],
GLchan rgba[])
{
const GLint width = img->Width2; /* without border, power of two */
const GLint height = img->Height2; /* without border, power of two */
GLint i, j;
 
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j);
 
/* skip over the border, if any */
i += img->Border;
j += img->Border;
 
if (i < 0 || i >= (GLint) img->Width || j < 0 || j >= (GLint) img->Height) {
/* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
COPY_CHAN4(rgba, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i, j, 0, (GLvoid *) rgba);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, rgba[0], rgba);
}
}
}
 
 
 
/*
* Return the texture sample for coordinate (s,t) using GL_LINEAR filter.
* New sampling code contributed by Lynn Quam <quam@ai.sri.com>.
*/
static INLINE void
sample_2d_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
const GLfloat texcoord[4],
GLchan rgba[])
{
const GLint width = img->Width2;
const GLint height = img->Height2;
GLint i0, j0, i1, j1;
GLuint useBorderColor;
GLfloat u, v;
 
COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);
COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1);
 
useBorderColor = 0;
if (img->Border) {
i0 += img->Border;
i1 += img->Border;
j0 += img->Border;
j1 += img->Border;
}
else {
if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
}
 
{
const GLfloat a = FRAC(u);
const GLfloat b = FRAC(v);
 
#if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT
const GLfloat w00 = (1.0F-a) * (1.0F-b);
const GLfloat w10 = a * (1.0F-b);
const GLfloat w01 = (1.0F-a) * b ;
const GLfloat w11 = a * b ;
#else /* CHAN_BITS == 8 */
/* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
const GLint w00 = IROUND_POS((1.0F-a) * (1.0F-b) * WEIGHT_SCALE);
const GLint w10 = IROUND_POS( a * (1.0F-b) * WEIGHT_SCALE);
const GLint w01 = IROUND_POS((1.0F-a) * b * WEIGHT_SCALE);
const GLint w11 = IROUND_POS( a * b * WEIGHT_SCALE);
#endif
GLchan t00[4];
GLchan t10[4];
GLchan t01[4];
GLchan t11[4];
 
if (useBorderColor & (I0BIT | J0BIT)) {
COPY_CHAN4(t00, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j0, 0, (GLvoid *) t00);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t00[0], t00);
}
}
if (useBorderColor & (I1BIT | J0BIT)) {
COPY_CHAN4(t10, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j0, 0, (GLvoid *) t10);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t10[0], t10);
}
}
if (useBorderColor & (I0BIT | J1BIT)) {
COPY_CHAN4(t01, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j1, 0, (GLvoid *) t01);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t01[0], t01);
}
}
if (useBorderColor & (I1BIT | J1BIT)) {
COPY_CHAN4(t11, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j1, 0, (GLvoid *) t11);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t11[0], t11);
}
}
#if CHAN_TYPE == GL_FLOAT
rgba[0] = w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0];
rgba[1] = w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1];
rgba[2] = w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2];
rgba[3] = w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3];
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
rgba[0] = (GLchan) (w00 * t00[0] + w10 * t10[0] +
w01 * t01[0] + w11 * t11[0] + 0.5);
rgba[1] = (GLchan) (w00 * t00[1] + w10 * t10[1] +
w01 * t01[1] + w11 * t11[1] + 0.5);
rgba[2] = (GLchan) (w00 * t00[2] + w10 * t10[2] +
w01 * t01[2] + w11 * t11[2] + 0.5);
rgba[3] = (GLchan) (w00 * t00[3] + w10 * t10[3] +
w01 * t01[3] + w11 * t11[3] + 0.5);
#else /* CHAN_BITS == 8 */
rgba[0] = (GLchan) ((w00 * t00[0] + w10 * t10[0] +
w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT);
rgba[1] = (GLchan) ((w00 * t00[1] + w10 * t10[1] +
w01 * t01[1] + w11 * t11[1]) >> WEIGHT_SHIFT);
rgba[2] = (GLchan) ((w00 * t00[2] + w10 * t10[2] +
w01 * t01[2] + w11 * t11[2]) >> WEIGHT_SHIFT);
rgba[3] = (GLchan) ((w00 * t00[3] + w10 * t10[3] +
w01 * t01[3] + w11 * t11[3]) >> WEIGHT_SHIFT);
#endif
 
}
 
}
 
 
/*
* As above, but we know WRAP_S == REPEAT and WRAP_T == REPEAT
* and we're not using a paletted texture.
*/
static INLINE void
sample_2d_linear_repeat(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
const GLfloat texcoord[4],
GLchan rgba[])
{
const GLint width = img->Width2;
const GLint height = img->Height2;
GLint i0, j0, i1, j1;
GLfloat u, v;
 
ASSERT(tObj->WrapS == GL_REPEAT);
ASSERT(tObj->WrapT == GL_REPEAT);
ASSERT(img->Border == 0);
ASSERT(img->Format != GL_COLOR_INDEX);
 
COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[0], u, width, i0, i1);
COMPUTE_LINEAR_REPEAT_TEXEL_LOCATION(texcoord[1], v, height, j0, j1);
 
{
const GLfloat a = FRAC(u);
const GLfloat b = FRAC(v);
 
#if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT
const GLfloat w00 = (1.0F-a) * (1.0F-b);
const GLfloat w10 = a * (1.0F-b);
const GLfloat w01 = (1.0F-a) * b ;
const GLfloat w11 = a * b ;
#else /* CHAN_BITS == 8 */
/* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
const GLint w00 = IROUND_POS((1.0F-a) * (1.0F-b) * WEIGHT_SCALE);
const GLint w10 = IROUND_POS( a * (1.0F-b) * WEIGHT_SCALE);
const GLint w01 = IROUND_POS((1.0F-a) * b * WEIGHT_SCALE);
const GLint w11 = IROUND_POS( a * b * WEIGHT_SCALE);
#endif
GLchan t00[4];
GLchan t10[4];
GLchan t01[4];
GLchan t11[4];
 
(*img->FetchTexel)(img, i0, j0, 0, (GLvoid *) t00);
(*img->FetchTexel)(img, i1, j0, 0, (GLvoid *) t10);
(*img->FetchTexel)(img, i0, j1, 0, (GLvoid *) t01);
(*img->FetchTexel)(img, i1, j1, 0, (GLvoid *) t11);
 
#if CHAN_TYPE == GL_FLOAT
rgba[0] = w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0];
rgba[1] = w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1];
rgba[2] = w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2];
rgba[3] = w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3];
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
rgba[0] = (GLchan) (w00 * t00[0] + w10 * t10[0] +
w01 * t01[0] + w11 * t11[0] + 0.5);
rgba[1] = (GLchan) (w00 * t00[1] + w10 * t10[1] +
w01 * t01[1] + w11 * t11[1] + 0.5);
rgba[2] = (GLchan) (w00 * t00[2] + w10 * t10[2] +
w01 * t01[2] + w11 * t11[2] + 0.5);
rgba[3] = (GLchan) (w00 * t00[3] + w10 * t10[3] +
w01 * t01[3] + w11 * t11[3] + 0.5);
#else /* CHAN_BITS == 8 */
rgba[0] = (GLchan) ((w00 * t00[0] + w10 * t10[0] +
w01 * t01[0] + w11 * t11[0]) >> WEIGHT_SHIFT);
rgba[1] = (GLchan) ((w00 * t00[1] + w10 * t10[1] +
w01 * t01[1] + w11 * t11[1]) >> WEIGHT_SHIFT);
rgba[2] = (GLchan) ((w00 * t00[2] + w10 * t10[2] +
w01 * t01[2] + w11 * t11[2]) >> WEIGHT_SHIFT);
rgba[3] = (GLchan) ((w00 * t00[3] + w10 * t10[3] +
w01 * t01[3] + w11 * t11[3]) >> WEIGHT_SHIFT);
#endif
 
}
 
}
 
 
 
static void
sample_2d_nearest_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
sample_2d_nearest(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
}
}
 
 
 
static void
sample_2d_linear_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
sample_2d_linear(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
}
}
 
 
 
static void
sample_2d_nearest_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
if (level >= tObj->_MaxLevel) {
sample_2d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
texcoord[i], rgba[i]);
}
else {
GLchan t0[4], t1[4]; /* texels */
const GLfloat f = FRAC(lambda[i]);
sample_2d_nearest(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
sample_2d_nearest(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
 
/* Trilinear filtering */
static void
sample_2d_linear_mipmap_linear( GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
if (level >= tObj->_MaxLevel) {
sample_2d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel],
texcoord[i], rgba[i]);
}
else {
GLchan t0[4], t1[4]; /* texels */
const GLfloat f = FRAC(lambda[i]);
sample_2d_linear(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
sample_2d_linear(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
static void
sample_2d_linear_mipmap_linear_repeat( GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
ASSERT(lambda != NULL);
ASSERT(tObj->WrapS == GL_REPEAT);
ASSERT(tObj->WrapT == GL_REPEAT);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
if (level >= tObj->_MaxLevel) {
sample_2d_linear_repeat(ctx, tObj, tObj->Image[tObj->_MaxLevel],
texcoord[i], rgba[i]);
}
else {
GLchan t0[4], t1[4]; /* texels */
const GLfloat f = FRAC(lambda[i]);
sample_2d_linear_repeat(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
sample_2d_linear_repeat(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
static void
sample_nearest_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
sample_2d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
 
 
 
static void
sample_linear_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
sample_2d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
 
 
/*
* Optimized 2-D texture sampling:
* S and T wrap mode == GL_REPEAT
* GL_NEAREST min/mag filter
* No border,
* RowStride == Width,
* Format = GL_RGB
*/
static void
opt_sample_rgb_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
const GLfloat width = (GLfloat) img->Width;
const GLfloat height = (GLfloat) img->Height;
const GLint colMask = img->Width - 1;
const GLint rowMask = img->Height - 1;
const GLint shift = img->WidthLog2;
GLuint k;
(void) lambda;
ASSERT(tObj->WrapS==GL_REPEAT);
ASSERT(tObj->WrapT==GL_REPEAT);
ASSERT(img->Border==0);
ASSERT(img->Format==GL_RGB);
 
for (k=0; k<n; k++) {
GLint i = IFLOOR(texcoords[k][0] * width) & colMask;
GLint j = IFLOOR(texcoords[k][1] * height) & rowMask;
GLint pos = (j << shift) | i;
GLchan *texel = ((GLchan *) img->Data) + 3*pos;
rgba[k][RCOMP] = texel[0];
rgba[k][GCOMP] = texel[1];
rgba[k][BCOMP] = texel[2];
}
}
 
 
/*
* Optimized 2-D texture sampling:
* S and T wrap mode == GL_REPEAT
* GL_NEAREST min/mag filter
* No border
* RowStride == Width,
* Format = GL_RGBA
*/
static void
opt_sample_rgba_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
const struct gl_texture_image *img = tObj->Image[tObj->BaseLevel];
const GLfloat width = (GLfloat) img->Width;
const GLfloat height = (GLfloat) img->Height;
const GLint colMask = img->Width - 1;
const GLint rowMask = img->Height - 1;
const GLint shift = img->WidthLog2;
GLuint i;
(void) lambda;
ASSERT(tObj->WrapS==GL_REPEAT);
ASSERT(tObj->WrapT==GL_REPEAT);
ASSERT(img->Border==0);
ASSERT(img->Format==GL_RGBA);
 
for (i = 0; i < n; i++) {
const GLint col = IFLOOR(texcoords[i][0] * width) & colMask;
const GLint row = IFLOOR(texcoords[i][1] * height) & rowMask;
const GLint pos = (row << shift) | col;
const GLchan *texel = ((GLchan *) img->Data) + (pos << 2); /* pos*4 */
COPY_CHAN4(rgba[i], texel);
}
}
 
 
/*
* Given an array of texture coordinate and lambda (level of detail)
* values, return an array of texture sample.
*/
static void
sample_lambda_2d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
const struct gl_texture_image *tImg = tObj->Image[tObj->BaseLevel];
GLuint minStart, minEnd; /* texels with minification */
GLuint magStart, magEnd; /* texels with magnification */
 
const GLboolean repeatNoBorder = (tObj->WrapS == GL_REPEAT)
&& (tObj->WrapT == GL_REPEAT)
&& (tImg->Border == 0 && (tImg->Width == tImg->RowStride))
&& (tImg->Format != GL_COLOR_INDEX);
 
ASSERT(lambda != NULL);
compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
n, lambda, &minStart, &minEnd, &magStart, &magEnd);
 
if (minStart < minEnd) {
/* do the minified texels */
const GLuint m = minEnd - minStart;
switch (tObj->MinFilter) {
case GL_NEAREST:
if (repeatNoBorder) {
switch (tImg->Format) {
case GL_RGB:
opt_sample_rgb_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart);
break;
case GL_RGBA:
opt_sample_rgba_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart);
break;
default:
sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart );
}
}
else {
sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart);
}
break;
case GL_LINEAR:
sample_linear_2d(ctx, texUnit, tObj, m, texcoords + minStart,
NULL, rgba + minStart);
break;
case GL_NEAREST_MIPMAP_NEAREST:
sample_2d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR_MIPMAP_NEAREST:
sample_2d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_NEAREST_MIPMAP_LINEAR:
sample_2d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR_MIPMAP_LINEAR:
if (repeatNoBorder)
sample_2d_linear_mipmap_linear_repeat(ctx, tObj, m,
texcoords + minStart, lambda + minStart, rgba + minStart);
else
sample_2d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
default:
_mesa_problem(ctx, "Bad min filter in sample_2d_texture");
return;
}
}
 
if (magStart < magEnd) {
/* do the magnified texels */
const GLuint m = magEnd - magStart;
 
switch (tObj->MagFilter) {
case GL_NEAREST:
if (repeatNoBorder) {
switch (tImg->Format) {
case GL_RGB:
opt_sample_rgb_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart);
break;
case GL_RGBA:
opt_sample_rgba_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart);
break;
default:
sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart );
}
}
else {
sample_nearest_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart);
}
break;
case GL_LINEAR:
sample_linear_2d(ctx, texUnit, tObj, m, texcoords + magStart,
NULL, rgba + magStart);
break;
default:
_mesa_problem(ctx, "Bad mag filter in sample_lambda_2d");
}
}
}
 
 
 
/**********************************************************************/
/* 3-D Texture Sampling Functions */
/**********************************************************************/
 
/*
* Return the texture sample for coordinate (s,t,r) using GL_NEAREST filter.
*/
static void
sample_3d_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
const GLfloat texcoord[4],
GLchan rgba[4])
{
const GLint width = img->Width2; /* without border, power of two */
const GLint height = img->Height2; /* without border, power of two */
const GLint depth = img->Depth2; /* without border, power of two */
GLint i, j, k;
 
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoord[0], width, i);
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoord[1], height, j);
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapR, texcoord[2], depth, k);
 
if (i < 0 || i >= (GLint) img->Width ||
j < 0 || j >= (GLint) img->Height ||
k < 0 || k >= (GLint) img->Depth) {
/* Need this test for GL_CLAMP_TO_BORDER_ARB mode */
COPY_CHAN4(rgba, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i, j, k, (GLvoid *) rgba);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, rgba[0], rgba);
}
}
}
 
 
 
/*
* Return the texture sample for coordinate (s,t,r) using GL_LINEAR filter.
*/
static void
sample_3d_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
const struct gl_texture_image *img,
const GLfloat texcoord[4],
GLchan rgba[4])
{
const GLint width = img->Width2;
const GLint height = img->Height2;
const GLint depth = img->Depth2;
GLint i0, j0, k0, i1, j1, k1;
GLuint useBorderColor;
GLfloat u, v, w;
 
COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoord[0], u, width, i0, i1);
COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoord[1], v, height, j0, j1);
COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapR, texcoord[2], w, depth, k0, k1);
 
useBorderColor = 0;
if (img->Border) {
i0 += img->Border;
i1 += img->Border;
j0 += img->Border;
j1 += img->Border;
k0 += img->Border;
k1 += img->Border;
}
else {
/* check if sampling texture border color */
if (i0 < 0 || i0 >= width) useBorderColor |= I0BIT;
if (i1 < 0 || i1 >= width) useBorderColor |= I1BIT;
if (j0 < 0 || j0 >= height) useBorderColor |= J0BIT;
if (j1 < 0 || j1 >= height) useBorderColor |= J1BIT;
if (k0 < 0 || k0 >= depth) useBorderColor |= K0BIT;
if (k1 < 0 || k1 >= depth) useBorderColor |= K1BIT;
}
 
{
const GLfloat a = FRAC(u);
const GLfloat b = FRAC(v);
const GLfloat c = FRAC(w);
 
#if CHAN_TYPE == GL_FLOAT || CHAN_TYPE == GL_UNSIGNED_SHORT
/* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
GLfloat w000 = (1.0F-a) * (1.0F-b) * (1.0F-c);
GLfloat w100 = a * (1.0F-b) * (1.0F-c);
GLfloat w010 = (1.0F-a) * b * (1.0F-c);
GLfloat w110 = a * b * (1.0F-c);
GLfloat w001 = (1.0F-a) * (1.0F-b) * c ;
GLfloat w101 = a * (1.0F-b) * c ;
GLfloat w011 = (1.0F-a) * b * c ;
GLfloat w111 = a * b * c ;
#else /* CHAN_BITS == 8 */
/* compute sample weights in fixed point in [0,WEIGHT_SCALE] */
GLint w000 = IROUND_POS((1.0F-a) * (1.0F-b) * (1.0F-c) * WEIGHT_SCALE);
GLint w100 = IROUND_POS( a * (1.0F-b) * (1.0F-c) * WEIGHT_SCALE);
GLint w010 = IROUND_POS((1.0F-a) * b * (1.0F-c) * WEIGHT_SCALE);
GLint w110 = IROUND_POS( a * b * (1.0F-c) * WEIGHT_SCALE);
GLint w001 = IROUND_POS((1.0F-a) * (1.0F-b) * c * WEIGHT_SCALE);
GLint w101 = IROUND_POS( a * (1.0F-b) * c * WEIGHT_SCALE);
GLint w011 = IROUND_POS((1.0F-a) * b * c * WEIGHT_SCALE);
GLint w111 = IROUND_POS( a * b * c * WEIGHT_SCALE);
#endif
 
GLchan t000[4], t010[4], t001[4], t011[4];
GLchan t100[4], t110[4], t101[4], t111[4];
 
if (useBorderColor & (I0BIT | J0BIT | K0BIT)) {
COPY_CHAN4(t000, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j0, k0, (GLvoid *) t000);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t000[0], t000);
}
}
if (useBorderColor & (I1BIT | J0BIT | K0BIT)) {
COPY_CHAN4(t100, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j0, k0, (GLvoid *) t100);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t100[0], t100);
}
}
if (useBorderColor & (I0BIT | J1BIT | K0BIT)) {
COPY_CHAN4(t010, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j1, k0, (GLvoid *) t010);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t010[0], t010);
}
}
if (useBorderColor & (I1BIT | J1BIT | K0BIT)) {
COPY_CHAN4(t110, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j1, k0, (GLvoid *) t110);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t110[0], t110);
}
}
 
if (useBorderColor & (I0BIT | J0BIT | K1BIT)) {
COPY_CHAN4(t001, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j0, k1, (GLvoid *) t001);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t001[0], t001);
}
}
if (useBorderColor & (I1BIT | J0BIT | K1BIT)) {
COPY_CHAN4(t101, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j0, k1, (GLvoid *) t101);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t101[0], t101);
}
}
if (useBorderColor & (I0BIT | J1BIT | K1BIT)) {
COPY_CHAN4(t011, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i0, j1, k1, (GLvoid *) t011);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t011[0], t011);
}
}
if (useBorderColor & (I1BIT | J1BIT | K1BIT)) {
COPY_CHAN4(t111, tObj->_BorderChan);
}
else {
(*img->FetchTexel)(img, i1, j1, k1, (GLvoid *) t111);
if (img->Format == GL_COLOR_INDEX) {
palette_sample(ctx, tObj, t111[0], t111);
}
}
 
#if CHAN_TYPE == GL_FLOAT
rgba[0] = w000*t000[0] + w010*t010[0] + w001*t001[0] + w011*t011[0] +
w100*t100[0] + w110*t110[0] + w101*t101[0] + w111*t111[0];
rgba[1] = w000*t000[1] + w010*t010[1] + w001*t001[1] + w011*t011[1] +
w100*t100[1] + w110*t110[1] + w101*t101[1] + w111*t111[1];
rgba[2] = w000*t000[2] + w010*t010[2] + w001*t001[2] + w011*t011[2] +
w100*t100[2] + w110*t110[2] + w101*t101[2] + w111*t111[2];
rgba[3] = w000*t000[3] + w010*t010[3] + w001*t001[3] + w011*t011[3] +
w100*t100[3] + w110*t110[3] + w101*t101[3] + w111*t111[3];
#elif CHAN_TYPE == GL_UNSIGNED_SHORT
rgba[0] = (GLchan) (w000*t000[0] + w010*t010[0] +
w001*t001[0] + w011*t011[0] +
w100*t100[0] + w110*t110[0] +
w101*t101[0] + w111*t111[0] + 0.5);
rgba[1] = (GLchan) (w000*t000[1] + w010*t010[1] +
w001*t001[1] + w011*t011[1] +
w100*t100[1] + w110*t110[1] +
w101*t101[1] + w111*t111[1] + 0.5);
rgba[2] = (GLchan) (w000*t000[2] + w010*t010[2] +
w001*t001[2] + w011*t011[2] +
w100*t100[2] + w110*t110[2] +
w101*t101[2] + w111*t111[2] + 0.5);
rgba[3] = (GLchan) (w000*t000[3] + w010*t010[3] +
w001*t001[3] + w011*t011[3] +
w100*t100[3] + w110*t110[3] +
w101*t101[3] + w111*t111[3] + 0.5);
#else /* CHAN_BITS == 8 */
rgba[0] = (GLchan) (
(w000*t000[0] + w010*t010[0] + w001*t001[0] + w011*t011[0] +
w100*t100[0] + w110*t110[0] + w101*t101[0] + w111*t111[0] )
>> WEIGHT_SHIFT);
rgba[1] = (GLchan) (
(w000*t000[1] + w010*t010[1] + w001*t001[1] + w011*t011[1] +
w100*t100[1] + w110*t110[1] + w101*t101[1] + w111*t111[1] )
>> WEIGHT_SHIFT);
rgba[2] = (GLchan) (
(w000*t000[2] + w010*t010[2] + w001*t001[2] + w011*t011[2] +
w100*t100[2] + w110*t110[2] + w101*t101[2] + w111*t111[2] )
>> WEIGHT_SHIFT);
rgba[3] = (GLchan) (
(w000*t000[3] + w010*t010[3] + w001*t001[3] + w011*t011[3] +
w100*t100[3] + w110*t110[3] + w101*t101[3] + w111*t111[3] )
>> WEIGHT_SHIFT);
#endif
 
}
}
 
 
 
static void
sample_3d_nearest_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
sample_3d_nearest(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
}
}
 
 
static void
sample_3d_linear_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
sample_3d_linear(ctx, tObj, tObj->Image[level], texcoord[i], rgba[i]);
}
}
 
 
static void
sample_3d_nearest_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
if (level >= tObj->_MaxLevel) {
sample_3d_nearest(ctx, tObj, tObj->Image[tObj->_MaxLevel],
texcoord[i], rgba[i]);
}
else {
GLchan t0[4], t1[4]; /* texels */
const GLfloat f = FRAC(lambda[i]);
sample_3d_nearest(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
sample_3d_nearest(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
static void
sample_3d_linear_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
if (level >= tObj->_MaxLevel) {
sample_3d_linear(ctx, tObj, tObj->Image[tObj->_MaxLevel],
texcoord[i], rgba[i]);
}
else {
GLchan t0[4], t1[4]; /* texels */
const GLfloat f = FRAC(lambda[i]);
sample_3d_linear(ctx, tObj, tObj->Image[level ], texcoord[i], t0);
sample_3d_linear(ctx, tObj, tObj->Image[level+1], texcoord[i], t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
static void
sample_nearest_3d(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
sample_3d_nearest(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
 
 
 
static void
sample_linear_3d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4] )
{
GLuint i;
struct gl_texture_image *image = tObj->Image[tObj->BaseLevel];
(void) lambda;
for (i=0;i<n;i++) {
sample_3d_linear(ctx, tObj, image, texcoords[i], rgba[i]);
}
}
 
 
/*
* Given an (s,t,r) texture coordinate and lambda (level of detail) value,
* return a texture sample.
*/
static void
sample_lambda_3d( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4] )
{
GLuint minStart, minEnd; /* texels with minification */
GLuint magStart, magEnd; /* texels with magnification */
GLuint i;
 
ASSERT(lambda != NULL);
compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
n, lambda, &minStart, &minEnd, &magStart, &magEnd);
 
if (minStart < minEnd) {
/* do the minified texels */
GLuint m = minEnd - minStart;
switch (tObj->MinFilter) {
case GL_NEAREST:
for (i = minStart; i < minEnd; i++)
sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
texcoords[i], rgba[i]);
break;
case GL_LINEAR:
for (i = minStart; i < minEnd; i++)
sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
texcoords[i], rgba[i]);
break;
case GL_NEAREST_MIPMAP_NEAREST:
sample_3d_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR_MIPMAP_NEAREST:
sample_3d_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_NEAREST_MIPMAP_LINEAR:
sample_3d_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR_MIPMAP_LINEAR:
sample_3d_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
default:
_mesa_problem(ctx, "Bad min filter in sample_3d_texture");
return;
}
}
 
if (magStart < magEnd) {
/* do the magnified texels */
switch (tObj->MagFilter) {
case GL_NEAREST:
for (i = magStart; i < magEnd; i++)
sample_3d_nearest(ctx, tObj, tObj->Image[tObj->BaseLevel],
texcoords[i], rgba[i]);
break;
case GL_LINEAR:
for (i = magStart; i < magEnd; i++)
sample_3d_linear(ctx, tObj, tObj->Image[tObj->BaseLevel],
texcoords[i], rgba[i]);
break;
default:
_mesa_problem(ctx, "Bad mag filter in sample_3d_texture");
return;
}
}
}
 
 
/**********************************************************************/
/* Texture Cube Map Sampling Functions */
/**********************************************************************/
 
/*
* Choose one of six sides of a texture cube map given the texture
* coord (rx,ry,rz). Return pointer to corresponding array of texture
* images.
*/
static const struct gl_texture_image **
choose_cube_face(const struct gl_texture_object *texObj,
const GLfloat texcoord[4], GLfloat newCoord[4])
{
/*
major axis
direction target sc tc ma
---------- ------------------------------- --- --- ---
+rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx
-rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx
+ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry
-ry TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT +rx -rz ry
+rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz
-rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz
*/
const GLfloat rx = texcoord[0];
const GLfloat ry = texcoord[1];
const GLfloat rz = texcoord[2];
const struct gl_texture_image **imgArray;
const GLfloat arx = ABSF(rx), ary = ABSF(ry), arz = ABSF(rz);
GLfloat sc, tc, ma;
 
if (arx > ary && arx > arz) {
if (rx >= 0.0F) {
imgArray = (const struct gl_texture_image **) texObj->Image;
sc = -rz;
tc = -ry;
ma = arx;
}
else {
imgArray = (const struct gl_texture_image **) texObj->NegX;
sc = rz;
tc = -ry;
ma = arx;
}
}
else if (ary > arx && ary > arz) {
if (ry >= 0.0F) {
imgArray = (const struct gl_texture_image **) texObj->PosY;
sc = rx;
tc = rz;
ma = ary;
}
else {
imgArray = (const struct gl_texture_image **) texObj->NegY;
sc = rx;
tc = -rz;
ma = ary;
}
}
else {
if (rz > 0.0F) {
imgArray = (const struct gl_texture_image **) texObj->PosZ;
sc = rx;
tc = -ry;
ma = arz;
}
else {
imgArray = (const struct gl_texture_image **) texObj->NegZ;
sc = -rx;
tc = -ry;
ma = arz;
}
}
 
newCoord[0] = ( sc / ma + 1.0F ) * 0.5F;
newCoord[1] = ( tc / ma + 1.0F ) * 0.5F;
return imgArray;
}
 
 
static void
sample_nearest_cube(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
GLuint i;
(void) lambda;
for (i = 0; i < n; i++) {
const struct gl_texture_image **images;
GLfloat newCoord[4];
images = choose_cube_face(tObj, texcoords[i], newCoord);
sample_2d_nearest(ctx, tObj, images[tObj->BaseLevel],
newCoord, rgba[i]);
}
}
 
 
static void
sample_linear_cube(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
(void) lambda;
for (i = 0; i < n; i++) {
const struct gl_texture_image **images;
GLfloat newCoord[4];
images = choose_cube_face(tObj, texcoords[i], newCoord);
sample_2d_linear(ctx, tObj, images[tObj->BaseLevel],
newCoord, rgba[i]);
}
}
 
 
static void
sample_cube_nearest_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
const struct gl_texture_image **images;
GLfloat newCoord[4];
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
images = choose_cube_face(tObj, texcoord[i], newCoord);
sample_2d_nearest(ctx, tObj, images[level], newCoord, rgba[i]);
}
}
 
 
static void
sample_cube_linear_mipmap_nearest(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
const struct gl_texture_image **images;
GLfloat newCoord[4];
GLint level;
COMPUTE_NEAREST_MIPMAP_LEVEL(tObj, lambda[i], level);
images = choose_cube_face(tObj, texcoord[i], newCoord);
sample_2d_linear(ctx, tObj, images[level], newCoord, rgba[i]);
}
}
 
 
static void
sample_cube_nearest_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
const struct gl_texture_image **images;
GLfloat newCoord[4];
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
images = choose_cube_face(tObj, texcoord[i], newCoord);
if (level >= tObj->_MaxLevel) {
sample_2d_nearest(ctx, tObj, images[tObj->_MaxLevel],
newCoord, rgba[i]);
}
else {
GLchan t0[4], t1[4]; /* texels */
const GLfloat f = FRAC(lambda[i]);
sample_2d_nearest(ctx, tObj, images[level ], newCoord, t0);
sample_2d_nearest(ctx, tObj, images[level+1], newCoord, t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
static void
sample_cube_linear_mipmap_linear(GLcontext *ctx,
const struct gl_texture_object *tObj,
GLuint n, GLfloat texcoord[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
GLuint i;
ASSERT(lambda != NULL);
for (i = 0; i < n; i++) {
const struct gl_texture_image **images;
GLfloat newCoord[4];
GLint level;
COMPUTE_LINEAR_MIPMAP_LEVEL(tObj, lambda[i], level);
images = choose_cube_face(tObj, texcoord[i], newCoord);
if (level >= tObj->_MaxLevel) {
sample_2d_linear(ctx, tObj, images[tObj->_MaxLevel],
newCoord, rgba[i]);
}
else {
GLchan t0[4], t1[4];
const GLfloat f = FRAC(lambda[i]);
sample_2d_linear(ctx, tObj, images[level ], newCoord, t0);
sample_2d_linear(ctx, tObj, images[level+1], newCoord, t1);
rgba[i][RCOMP] = CHAN_CAST ((1.0F-f) * t0[RCOMP] + f * t1[RCOMP]);
rgba[i][GCOMP] = CHAN_CAST ((1.0F-f) * t0[GCOMP] + f * t1[GCOMP]);
rgba[i][BCOMP] = CHAN_CAST ((1.0F-f) * t0[BCOMP] + f * t1[BCOMP]);
rgba[i][ACOMP] = CHAN_CAST ((1.0F-f) * t0[ACOMP] + f * t1[ACOMP]);
}
}
}
 
 
static void
sample_lambda_cube( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
GLuint minStart, minEnd; /* texels with minification */
GLuint magStart, magEnd; /* texels with magnification */
 
ASSERT(lambda != NULL);
compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
n, lambda, &minStart, &minEnd, &magStart, &magEnd);
 
if (minStart < minEnd) {
/* do the minified texels */
const GLuint m = minEnd - minStart;
switch (tObj->MinFilter) {
case GL_NEAREST:
sample_nearest_cube(ctx, texUnit, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR:
sample_linear_cube(ctx, texUnit, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_NEAREST_MIPMAP_NEAREST:
sample_cube_nearest_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR_MIPMAP_NEAREST:
sample_cube_linear_mipmap_nearest(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_NEAREST_MIPMAP_LINEAR:
sample_cube_nearest_mipmap_linear(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
case GL_LINEAR_MIPMAP_LINEAR:
sample_cube_linear_mipmap_linear(ctx, tObj, m, texcoords + minStart,
lambda + minStart, rgba + minStart);
break;
default:
_mesa_problem(ctx, "Bad min filter in sample_lambda_cube");
}
}
 
if (magStart < magEnd) {
/* do the magnified texels */
const GLuint m = magEnd - magStart;
switch (tObj->MagFilter) {
case GL_NEAREST:
sample_nearest_cube(ctx, texUnit, tObj, m, texcoords + magStart,
lambda + magStart, rgba + magStart);
break;
case GL_LINEAR:
sample_linear_cube(ctx, texUnit, tObj, m, texcoords + magStart,
lambda + magStart, rgba + magStart);
break;
default:
_mesa_problem(ctx, "Bad mag filter in sample_lambda_cube");
}
}
}
 
 
/**********************************************************************/
/* Texture Rectangle Sampling Functions */
/**********************************************************************/
 
static void
sample_nearest_rect(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
const struct gl_texture_image *img = tObj->Image[0];
const GLfloat width = (GLfloat) img->Width;
const GLfloat height = (GLfloat) img->Height;
const GLint width_minus_1 = img->Width - 1;
const GLint height_minus_1 = img->Height - 1;
GLuint i;
 
(void) texUnit;
(void) lambda;
 
ASSERT(tObj->WrapS == GL_CLAMP ||
tObj->WrapS == GL_CLAMP_TO_EDGE ||
tObj->WrapS == GL_CLAMP_TO_BORDER_ARB);
ASSERT(tObj->WrapT == GL_CLAMP ||
tObj->WrapT == GL_CLAMP_TO_EDGE ||
tObj->WrapT == GL_CLAMP_TO_BORDER_ARB);
ASSERT(img->Format != GL_COLOR_INDEX);
 
/* XXX move Wrap mode tests outside of loops for common cases */
for (i = 0; i < n; i++) {
GLint row, col;
/* NOTE: we DO NOT use [0, 1] texture coordinates! */
if (tObj->WrapS == GL_CLAMP) {
col = IFLOOR( CLAMP(texcoords[i][0], 0.0F, width) );
}
else if (tObj->WrapS == GL_CLAMP_TO_EDGE) {
col = IFLOOR( CLAMP(texcoords[i][0], 0.5F, width - 0.5F) );
}
else {
col = IFLOOR( CLAMP(texcoords[i][0], -0.5F, width + 0.5F) );
}
if (tObj->WrapT == GL_CLAMP) {
row = IFLOOR( CLAMP(texcoords[i][1], 0.0F, height) );
}
else if (tObj->WrapT == GL_CLAMP_TO_EDGE) {
row = IFLOOR( CLAMP(texcoords[i][1], 0.5F, height - 0.5F) );
}
else {
row = IFLOOR( CLAMP(texcoords[i][1], -0.5F, height + 0.5F) );
}
 
col = CLAMP(col, 0, width_minus_1);
row = CLAMP(row, 0, height_minus_1);
 
(*img->FetchTexel)(img, col, row, 0, (GLvoid *) rgba[i]);
}
}
 
 
static void
sample_linear_rect(GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4],
const GLfloat lambda[], GLchan rgba[][4])
{
const struct gl_texture_image *img = tObj->Image[0];
const GLfloat width = (GLfloat) img->Width;
const GLfloat height = (GLfloat) img->Height;
const GLint width_minus_1 = img->Width - 1;
const GLint height_minus_1 = img->Height - 1;
GLuint i;
 
(void) texUnit;
(void) lambda;
 
ASSERT(tObj->WrapS == GL_CLAMP ||
tObj->WrapS == GL_CLAMP_TO_EDGE ||
tObj->WrapS == GL_CLAMP_TO_BORDER_ARB);
ASSERT(tObj->WrapT == GL_CLAMP ||
tObj->WrapT == GL_CLAMP_TO_EDGE ||
tObj->WrapT == GL_CLAMP_TO_BORDER_ARB);
ASSERT(img->Format != GL_COLOR_INDEX);
 
/* XXX lots of opportunity for optimization in this loop */
for (i = 0; i < n; i++) {
GLfloat frow, fcol;
GLint row0, col0, row1, col1;
GLchan t00[4], t01[4], t10[4], t11[4];
GLfloat a, b, w00, w01, w10, w11;
 
/* NOTE: we DO NOT use [0, 1] texture coordinates! */
if (tObj->WrapS == GL_CLAMP) {
fcol = CLAMP(texcoords[i][0], 0.0F, width);
}
else if (tObj->WrapS == GL_CLAMP_TO_EDGE) {
fcol = CLAMP(texcoords[i][0], 0.5F, width - 0.5F);
}
else {
fcol = CLAMP(texcoords[i][0], -0.5F, width + 0.5F);
}
if (tObj->WrapT == GL_CLAMP) {
frow = CLAMP(texcoords[i][1], 0.0F, height);
}
else if (tObj->WrapT == GL_CLAMP_TO_EDGE) {
frow = CLAMP(texcoords[i][1], 0.5F, height - 0.5F);
}
else {
frow = CLAMP(texcoords[i][1], -0.5F, height + 0.5F);
}
 
/* compute integer rows/columns */
col0 = IFLOOR(fcol);
col1 = col0 + 1;
col0 = CLAMP(col0, 0, width_minus_1);
col1 = CLAMP(col1, 0, width_minus_1);
row0 = IFLOOR(frow);
row1 = row0 + 1;
row0 = CLAMP(row0, 0, height_minus_1);
row1 = CLAMP(row1, 0, height_minus_1);
 
/* get four texel samples */
(*img->FetchTexel)(img, col0, row0, 0, (GLvoid *) t00);
(*img->FetchTexel)(img, col1, row0, 0, (GLvoid *) t10);
(*img->FetchTexel)(img, col0, row1, 0, (GLvoid *) t01);
(*img->FetchTexel)(img, col1, row1, 0, (GLvoid *) t11);
 
/* compute sample weights */
a = FRAC(fcol);
b = FRAC(frow);
w00 = (1.0F-a) * (1.0F-b);
w10 = a * (1.0F-b);
w01 = (1.0F-a) * b ;
w11 = a * b ;
 
/* compute weighted average of samples */
rgba[i][0] =
(GLchan) (w00 * t00[0] + w10 * t10[0] + w01 * t01[0] + w11 * t11[0]);
rgba[i][1] =
(GLchan) (w00 * t00[1] + w10 * t10[1] + w01 * t01[1] + w11 * t11[1]);
rgba[i][2] =
(GLchan) (w00 * t00[2] + w10 * t10[2] + w01 * t01[2] + w11 * t11[2]);
rgba[i][3] =
(GLchan) (w00 * t00[3] + w10 * t10[3] + w01 * t01[3] + w11 * t11[3]);
}
}
 
 
static void
sample_lambda_rect( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
GLuint minStart, minEnd, magStart, magEnd;
 
/* We only need lambda to decide between minification and magnification.
* There is no mipmapping with rectangular textures.
*/
compute_min_mag_ranges(SWRAST_CONTEXT(ctx)->_MinMagThresh[texUnit],
n, lambda, &minStart, &minEnd, &magStart, &magEnd);
 
if (minStart < minEnd) {
if (tObj->MinFilter == GL_NEAREST) {
sample_nearest_rect( ctx, texUnit, tObj, minEnd - minStart,
texcoords + minStart, NULL, rgba + minStart);
}
else {
sample_linear_rect( ctx, texUnit, tObj, minEnd - minStart,
texcoords + minStart, NULL, rgba + minStart);
}
}
if (magStart < magEnd) {
if (tObj->MagFilter == GL_NEAREST) {
sample_nearest_rect( ctx, texUnit, tObj, magEnd - magStart,
texcoords + magStart, NULL, rgba + magStart);
}
else {
sample_linear_rect( ctx, texUnit, tObj, magEnd - magStart,
texcoords + magStart, NULL, rgba + magStart);
}
}
}
 
 
 
/*
* Sample a shadow/depth texture.
*/
static void
sample_depth_texture( GLcontext *ctx, GLuint unit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan texel[][4] )
{
const GLint baseLevel = tObj->BaseLevel;
const struct gl_texture_image *texImage = tObj->Image[baseLevel];
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
GLchan ambient;
GLenum function;
GLchan result;
 
(void) unit;
 
ASSERT(tObj->Image[tObj->BaseLevel]->Format == GL_DEPTH_COMPONENT);
ASSERT(tObj->Target == GL_TEXTURE_1D ||
tObj->Target == GL_TEXTURE_2D ||
tObj->Target == GL_TEXTURE_RECTANGLE_NV);
 
UNCLAMPED_FLOAT_TO_CHAN(ambient, tObj->ShadowAmbient);
 
/* XXXX if tObj->MinFilter != tObj->MagFilter, we're ignoring lambda */
 
/* XXX this could be precomputed and saved in the texture object */
if (tObj->CompareFlag) {
/* GL_SGIX_shadow */
if (tObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
function = GL_LEQUAL;
}
else {
ASSERT(tObj->CompareOperator == GL_TEXTURE_GEQUAL_R_SGIX);
function = GL_GEQUAL;
}
}
else if (tObj->CompareMode == GL_COMPARE_R_TO_TEXTURE_ARB) {
/* GL_ARB_shadow */
function = tObj->CompareFunc;
}
else {
function = GL_NONE; /* pass depth through as grayscale */
}
 
if (tObj->MagFilter == GL_NEAREST) {
GLuint i;
for (i = 0; i < n; i++) {
GLfloat depthSample;
GLint col, row;
/* XXX fix for texture rectangle! */
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapS, texcoords[i][0], width, col);
COMPUTE_NEAREST_TEXEL_LOCATION(tObj->WrapT, texcoords[i][1], height, row);
depthSample = *((const GLfloat *) texImage->Data + row * width + col);
 
switch (function) {
case GL_LEQUAL:
result = (texcoords[i][2] <= depthSample) ? CHAN_MAX : ambient;
break;
case GL_GEQUAL:
result = (texcoords[i][2] >= depthSample) ? CHAN_MAX : ambient;
break;
case GL_LESS:
result = (texcoords[i][2] < depthSample) ? CHAN_MAX : ambient;
break;
case GL_GREATER:
result = (texcoords[i][2] > depthSample) ? CHAN_MAX : ambient;
break;
case GL_EQUAL:
result = (texcoords[i][2] == depthSample) ? CHAN_MAX : ambient;
break;
case GL_NOTEQUAL:
result = (texcoords[i][2] != depthSample) ? CHAN_MAX : ambient;
break;
case GL_ALWAYS:
result = CHAN_MAX;
break;
case GL_NEVER:
result = ambient;
break;
case GL_NONE:
CLAMPED_FLOAT_TO_CHAN(result, depthSample);
break;
default:
_mesa_problem(ctx, "Bad compare func in sample_depth_texture");
return;
}
 
switch (tObj->DepthMode) {
case GL_LUMINANCE:
texel[i][RCOMP] = result;
texel[i][GCOMP] = result;
texel[i][BCOMP] = result;
texel[i][ACOMP] = CHAN_MAX;
break;
case GL_INTENSITY:
texel[i][RCOMP] = result;
texel[i][GCOMP] = result;
texel[i][BCOMP] = result;
texel[i][ACOMP] = result;
break;
case GL_ALPHA:
texel[i][RCOMP] = 0;
texel[i][GCOMP] = 0;
texel[i][BCOMP] = 0;
texel[i][ACOMP] = result;
break;
default:
_mesa_problem(ctx, "Bad depth texture mode");
}
}
}
else {
GLuint i;
ASSERT(tObj->MagFilter == GL_LINEAR);
for (i = 0; i < n; i++) {
GLfloat depth00, depth01, depth10, depth11;
GLint i0, i1, j0, j1;
GLfloat u, v;
GLuint useBorderTexel;
 
/* XXX fix for texture rectangle! */
COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapS, texcoords[i][0], u, width, i0, i1);
COMPUTE_LINEAR_TEXEL_LOCATIONS(tObj->WrapT, texcoords[i][1], v, height,j0, j1);
 
useBorderTexel = 0;
if (texImage->Border) {
i0 += texImage->Border;
i1 += texImage->Border;
j0 += texImage->Border;
j1 += texImage->Border;
}
else {
if (i0 < 0 || i0 >= (GLint) width) useBorderTexel |= I0BIT;
if (i1 < 0 || i1 >= (GLint) width) useBorderTexel |= I1BIT;
if (j0 < 0 || j0 >= (GLint) height) useBorderTexel |= J0BIT;
if (j1 < 0 || j1 >= (GLint) height) useBorderTexel |= J1BIT;
}
 
/* get four depth samples from the texture */
if (useBorderTexel & (I0BIT | J0BIT)) {
depth00 = 1.0;
}
else {
depth00 = *((const GLfloat *) texImage->Data + j0 * width + i0);
}
if (useBorderTexel & (I1BIT | J0BIT)) {
depth10 = 1.0;
}
else {
depth10 = *((const GLfloat *) texImage->Data + j0 * width + i1);
}
if (useBorderTexel & (I0BIT | J1BIT)) {
depth01 = 1.0;
}
else {
depth01 = *((const GLfloat *) texImage->Data + j1 * width + i0);
}
if (useBorderTexel & (I1BIT | J1BIT)) {
depth11 = 1.0;
}
else {
depth11 = *((const GLfloat *) texImage->Data + j1 * width + i1);
}
 
if (0) {
/* compute a single weighted depth sample and do one comparison */
const GLfloat a = FRAC(u + 1.0F);
const GLfloat b = FRAC(v + 1.0F);
const GLfloat w00 = (1.0F - a) * (1.0F - b);
const GLfloat w10 = ( a) * (1.0F - b);
const GLfloat w01 = (1.0F - a) * ( b);
const GLfloat w11 = ( a) * ( b);
const GLfloat depthSample = w00 * depth00 + w10 * depth10
+ w01 * depth01 + w11 * depth11;
if ((depthSample <= texcoords[i][2] && function == GL_LEQUAL) ||
(depthSample >= texcoords[i][2] && function == GL_GEQUAL)) {
result = ambient;
}
else {
result = CHAN_MAX;
}
}
else {
/* Do four depth/R comparisons and compute a weighted result.
* If this touches on somebody's I.P., I'll remove this code
* upon request.
*/
const GLfloat d = (CHAN_MAXF - (GLfloat) ambient) * 0.25F;
GLfloat luminance = CHAN_MAXF;
 
switch (function) {
case GL_LEQUAL:
if (depth00 <= texcoords[i][2]) luminance -= d;
if (depth01 <= texcoords[i][2]) luminance -= d;
if (depth10 <= texcoords[i][2]) luminance -= d;
if (depth11 <= texcoords[i][2]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_GEQUAL:
if (depth00 >= texcoords[i][2]) luminance -= d;
if (depth01 >= texcoords[i][2]) luminance -= d;
if (depth10 >= texcoords[i][2]) luminance -= d;
if (depth11 >= texcoords[i][2]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_LESS:
if (depth00 < texcoords[i][2]) luminance -= d;
if (depth01 < texcoords[i][2]) luminance -= d;
if (depth10 < texcoords[i][2]) luminance -= d;
if (depth11 < texcoords[i][2]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_GREATER:
if (depth00 > texcoords[i][2]) luminance -= d;
if (depth01 > texcoords[i][2]) luminance -= d;
if (depth10 > texcoords[i][2]) luminance -= d;
if (depth11 > texcoords[i][2]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_EQUAL:
if (depth00 == texcoords[i][2]) luminance -= d;
if (depth01 == texcoords[i][2]) luminance -= d;
if (depth10 == texcoords[i][2]) luminance -= d;
if (depth11 == texcoords[i][2]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_NOTEQUAL:
if (depth00 != texcoords[i][2]) luminance -= d;
if (depth01 != texcoords[i][2]) luminance -= d;
if (depth10 != texcoords[i][2]) luminance -= d;
if (depth11 != texcoords[i][2]) luminance -= d;
result = (GLchan) luminance;
break;
case GL_ALWAYS:
result = 0;
break;
case GL_NEVER:
result = CHAN_MAX;
break;
case GL_NONE:
/* ordinary bilinear filtering */
{
const GLfloat a = FRAC(u + 1.0F);
const GLfloat b = FRAC(v + 1.0F);
const GLfloat w00 = (1.0F - a) * (1.0F - b);
const GLfloat w10 = ( a) * (1.0F - b);
const GLfloat w01 = (1.0F - a) * ( b);
const GLfloat w11 = ( a) * ( b);
const GLfloat depthSample = w00 * depth00 + w10 * depth10
+ w01 * depth01 + w11 * depth11;
CLAMPED_FLOAT_TO_CHAN(result, depthSample);
}
break;
default:
_mesa_problem(ctx, "Bad compare func in sample_depth_texture");
return;
}
}
 
switch (tObj->DepthMode) {
case GL_LUMINANCE:
texel[i][RCOMP] = result;
texel[i][GCOMP] = result;
texel[i][BCOMP] = result;
texel[i][ACOMP] = CHAN_MAX;
break;
case GL_INTENSITY:
texel[i][RCOMP] = result;
texel[i][GCOMP] = result;
texel[i][BCOMP] = result;
texel[i][ACOMP] = result;
break;
case GL_ALPHA:
texel[i][RCOMP] = 0;
texel[i][GCOMP] = 0;
texel[i][BCOMP] = 0;
texel[i][ACOMP] = result;
break;
default:
_mesa_problem(ctx, "Bad depth texture mode");
}
} /* for */
} /* if filter */
}
 
 
#if 0
/*
* Experimental depth texture sampling function.
*/
static void
sample_depth_texture2(const GLcontext *ctx,
const struct gl_texture_unit *texUnit,
GLuint n, GLfloat texcoords[][4],
GLchan texel[][4])
{
const struct gl_texture_object *texObj = texUnit->_Current;
const GLint baseLevel = texObj->BaseLevel;
const struct gl_texture_image *texImage = texObj->Image[baseLevel];
const GLuint width = texImage->Width;
const GLuint height = texImage->Height;
GLchan ambient;
GLboolean lequal, gequal;
 
if (texObj->Target != GL_TEXTURE_2D) {
_mesa_problem(ctx, "only 2-D depth textures supported at this time");
return;
}
 
if (texObj->MinFilter != texObj->MagFilter) {
_mesa_problem(ctx, "mipmapped depth textures not supported at this time");
return;
}
 
/* XXX the GL_SGIX_shadow extension spec doesn't say what to do if
* GL_TEXTURE_COMPARE_SGIX == GL_TRUE but the current texture object
* isn't a depth texture.
*/
if (texImage->Format != GL_DEPTH_COMPONENT) {
_mesa_problem(ctx,"GL_TEXTURE_COMPARE_SGIX enabled with non-depth texture");
return;
}
 
UNCLAMPED_FLOAT_TO_CHAN(ambient, tObj->ShadowAmbient);
 
if (texObj->CompareOperator == GL_TEXTURE_LEQUAL_R_SGIX) {
lequal = GL_TRUE;
gequal = GL_FALSE;
}
else {
lequal = GL_FALSE;
gequal = GL_TRUE;
}
 
{
GLuint i;
for (i = 0; i < n; i++) {
const GLint K = 3;
GLint col, row, ii, jj, imin, imax, jmin, jmax, samples, count;
GLfloat w;
GLchan lum;
COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapS, texcoords[i][0],
width, col);
COMPUTE_NEAREST_TEXEL_LOCATION(texObj->WrapT, texcoords[i][1],
height, row);
 
imin = col - K;
imax = col + K;
jmin = row - K;
jmax = row + K;
 
if (imin < 0) imin = 0;
if (imax >= width) imax = width - 1;
if (jmin < 0) jmin = 0;
if (jmax >= height) jmax = height - 1;
 
samples = (imax - imin + 1) * (jmax - jmin + 1);
count = 0;
for (jj = jmin; jj <= jmax; jj++) {
for (ii = imin; ii <= imax; ii++) {
GLfloat depthSample = *((const GLfloat *) texImage->Data
+ jj * width + ii);
if ((depthSample <= r[i] && lequal) ||
(depthSample >= r[i] && gequal)) {
count++;
}
}
}
 
w = (GLfloat) count / (GLfloat) samples;
w = CHAN_MAXF - w * (CHAN_MAXF - (GLfloat) ambient);
lum = (GLint) w;
 
texel[i][RCOMP] = lum;
texel[i][GCOMP] = lum;
texel[i][BCOMP] = lum;
texel[i][ACOMP] = CHAN_MAX;
}
}
}
#endif
 
 
/**
* We use this function when a texture object is in an "incomplete" state.
*/
static void
null_sample_func( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *tObj, GLuint n,
GLfloat texcoords[][4], const GLfloat lambda[],
GLchan rgba[][4])
{
}
 
 
 
/**
* Setup the texture sampling function for this texture object.
*/
void
_swrast_choose_texture_sample_func( GLcontext *ctx, GLuint texUnit,
const struct gl_texture_object *t )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
if (!t->Complete) {
swrast->TextureSample[texUnit] = null_sample_func;
}
else {
const GLboolean needLambda = (GLboolean) (t->MinFilter != t->MagFilter);
const GLenum format = t->Image[t->BaseLevel]->Format;
 
if (needLambda) {
/* Compute min/mag filter threshold */
if (t->MagFilter == GL_LINEAR
&& (t->MinFilter == GL_NEAREST_MIPMAP_NEAREST ||
t->MinFilter == GL_NEAREST_MIPMAP_LINEAR)) {
swrast->_MinMagThresh[texUnit] = 0.5F;
}
else {
swrast->_MinMagThresh[texUnit] = 0.0F;
}
}
 
switch (t->Target) {
case GL_TEXTURE_1D:
if (format == GL_DEPTH_COMPONENT) {
swrast->TextureSample[texUnit] = sample_depth_texture;
}
else if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_1d;
}
else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_1d;
}
else {
ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_1d;
}
break;
case GL_TEXTURE_2D:
if (format == GL_DEPTH_COMPONENT) {
swrast->TextureSample[texUnit] = sample_depth_texture;
}
else if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_2d;
}
else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_2d;
}
else {
GLint baseLevel = t->BaseLevel;
ASSERT(t->MinFilter == GL_NEAREST);
if (t->WrapS == GL_REPEAT &&
t->WrapT == GL_REPEAT &&
t->Image[baseLevel]->Border == 0 &&
t->Image[baseLevel]->TexFormat->MesaFormat == MESA_FORMAT_RGB) {
swrast->TextureSample[texUnit] = opt_sample_rgb_2d;
}
else if (t->WrapS == GL_REPEAT &&
t->WrapT == GL_REPEAT &&
t->Image[baseLevel]->Border == 0 &&
t->Image[baseLevel]->TexFormat->MesaFormat == MESA_FORMAT_RGBA) {
swrast->TextureSample[texUnit] = opt_sample_rgba_2d;
}
else
swrast->TextureSample[texUnit] = sample_nearest_2d;
}
break;
case GL_TEXTURE_3D:
if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_3d;
}
else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_3d;
}
else {
ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_3d;
}
break;
case GL_TEXTURE_CUBE_MAP_ARB:
if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_cube;
}
else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_cube;
}
else {
ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_cube;
}
break;
case GL_TEXTURE_RECTANGLE_NV:
if (needLambda) {
swrast->TextureSample[texUnit] = sample_lambda_rect;
}
else if (t->MinFilter == GL_LINEAR) {
swrast->TextureSample[texUnit] = sample_linear_rect;
}
else {
ASSERT(t->MinFilter == GL_NEAREST);
swrast->TextureSample[texUnit] = sample_nearest_rect;
}
break;
default:
_mesa_problem(ctx, "invalid target in _swrast_choose_texture_sample_func");
}
}
}
 
 
#define PROD(A,B) ( (GLuint)(A) * ((GLuint)(B)+1) )
#define S_PROD(A,B) ( (GLint)(A) * ((GLint)(B)+1) )
 
 
/**
* Do texture application for GL_ARB/EXT_texture_env_combine.
* Input:
* ctx - rendering context
* textureUnit - the texture unit to apply
* n - number of fragments to process (span width)
* primary_rgba - incoming fragment color array
* texelBuffer - pointer to texel colors for all texture units
* Input/Output:
* rgba - incoming colors, which get modified here
*/
static INLINE void
texture_combine( const GLcontext *ctx, GLuint unit, GLuint n,
CONST GLchan (*primary_rgba)[4],
CONST GLchan *texelBuffer,
GLchan (*rgba)[4] )
{
const struct gl_texture_unit *textureUnit = &(ctx->Texture.Unit[unit]);
const GLchan (*argRGB [3])[4];
const GLchan (*argA [3])[4];
const GLuint RGBshift = textureUnit->CombineScaleShiftRGB;
const GLuint Ashift = textureUnit->CombineScaleShiftA;
#if CHAN_TYPE == GL_FLOAT
const GLchan RGBmult = (GLfloat) (1 << RGBshift);
const GLchan Amult = (GLfloat) (1 << Ashift);
#else
const GLint half = (CHAN_MAX + 1) / 2;
#endif
GLuint i, j;
 
/* GLchan ccolor[3][4]; */
DEFMNARRAY(GLchan, ccolor, 3, 3 * MAX_WIDTH, 4); /* mac 32k limitation */
CHECKARRAY(ccolor, return); /* mac 32k limitation */
 
ASSERT(ctx->Extensions.EXT_texture_env_combine ||
ctx->Extensions.ARB_texture_env_combine);
ASSERT(SWRAST_CONTEXT(ctx)->_AnyTextureCombine);
 
 
/*
printf("modeRGB 0x%x modeA 0x%x srcRGB1 0x%x srcA1 0x%x srcRGB2 0x%x srcA2 0x%x\n",
textureUnit->CombineModeRGB,
textureUnit->CombineModeA,
textureUnit->CombineSourceRGB[0],
textureUnit->CombineSourceA[0],
textureUnit->CombineSourceRGB[1],
textureUnit->CombineSourceA[1]);
*/
 
/*
* Do operand setup for up to 3 operands. Loop over the terms.
*/
for (j = 0; j < 3; j++) {
const GLenum srcA = textureUnit->CombineSourceA[j];
const GLenum srcRGB = textureUnit->CombineSourceRGB[j];
 
switch (srcA) {
case GL_TEXTURE:
argA[j] = (const GLchan (*)[4])
(texelBuffer + unit * (n * 4 * sizeof(GLchan)));
break;
case GL_PRIMARY_COLOR_EXT:
argA[j] = primary_rgba;
break;
case GL_PREVIOUS_EXT:
argA[j] = (const GLchan (*)[4]) rgba;
break;
case GL_CONSTANT_EXT:
{
GLchan alpha, (*c)[4] = ccolor[j];
UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
for (i = 0; i < n; i++)
c[i][ACOMP] = alpha;
argA[j] = (const GLchan (*)[4]) ccolor[j];
}
break;
default:
/* ARB_texture_env_crossbar source */
{
const GLuint srcUnit = srcA - GL_TEXTURE0_ARB;
ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
return;
argA[j] = (const GLchan (*)[4])
(texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
}
}
 
switch (srcRGB) {
case GL_TEXTURE:
argRGB[j] = (const GLchan (*)[4])
(texelBuffer + unit * (n * 4 * sizeof(GLchan)));
break;
case GL_PRIMARY_COLOR_EXT:
argRGB[j] = primary_rgba;
break;
case GL_PREVIOUS_EXT:
argRGB[j] = (const GLchan (*)[4]) rgba;
break;
case GL_CONSTANT_EXT:
{
GLchan (*c)[4] = ccolor[j];
GLchan red, green, blue, alpha;
UNCLAMPED_FLOAT_TO_CHAN(red, textureUnit->EnvColor[0]);
UNCLAMPED_FLOAT_TO_CHAN(green, textureUnit->EnvColor[1]);
UNCLAMPED_FLOAT_TO_CHAN(blue, textureUnit->EnvColor[2]);
UNCLAMPED_FLOAT_TO_CHAN(alpha, textureUnit->EnvColor[3]);
for (i = 0; i < n; i++) {
c[i][RCOMP] = red;
c[i][GCOMP] = green;
c[i][BCOMP] = blue;
c[i][ACOMP] = alpha;
}
argRGB[j] = (const GLchan (*)[4]) ccolor[j];
}
break;
default:
/* ARB_texture_env_crossbar source */
{
const GLuint srcUnit = srcRGB - GL_TEXTURE0_ARB;
ASSERT(srcUnit < ctx->Const.MaxTextureUnits);
if (!ctx->Texture.Unit[srcUnit]._ReallyEnabled)
return;
argRGB[j] = (const GLchan (*)[4])
(texelBuffer + srcUnit * (n * 4 * sizeof(GLchan)));
}
}
 
if (textureUnit->CombineOperandRGB[j] != GL_SRC_COLOR) {
const GLchan (*src)[4] = argRGB[j];
GLchan (*dst)[4] = ccolor[j];
 
/* point to new arg[j] storage */
argRGB[j] = (const GLchan (*)[4]) ccolor[j];
 
if (textureUnit->CombineOperandRGB[j] == GL_ONE_MINUS_SRC_COLOR) {
for (i = 0; i < n; i++) {
dst[i][RCOMP] = CHAN_MAX - src[i][RCOMP];
dst[i][GCOMP] = CHAN_MAX - src[i][GCOMP];
dst[i][BCOMP] = CHAN_MAX - src[i][BCOMP];
}
}
else if (textureUnit->CombineOperandRGB[j] == GL_SRC_ALPHA) {
for (i = 0; i < n; i++) {
dst[i][RCOMP] = src[i][ACOMP];
dst[i][GCOMP] = src[i][ACOMP];
dst[i][BCOMP] = src[i][ACOMP];
}
}
else {
ASSERT(textureUnit->CombineOperandRGB[j] ==GL_ONE_MINUS_SRC_ALPHA);
for (i = 0; i < n; i++) {
dst[i][RCOMP] = CHAN_MAX - src[i][ACOMP];
dst[i][GCOMP] = CHAN_MAX - src[i][ACOMP];
dst[i][BCOMP] = CHAN_MAX - src[i][ACOMP];
}
}
}
 
if (textureUnit->CombineOperandA[j] == GL_ONE_MINUS_SRC_ALPHA) {
const GLchan (*src)[4] = argA[j];
GLchan (*dst)[4] = ccolor[j];
argA[j] = (const GLchan (*)[4]) ccolor[j];
for (i = 0; i < n; i++) {
dst[i][ACOMP] = CHAN_MAX - src[i][ACOMP];
}
}
 
if (textureUnit->CombineModeRGB == GL_REPLACE &&
textureUnit->CombineModeA == GL_REPLACE) {
break; /* done, we need only arg0 */
}
 
if (j == 1 &&
textureUnit->CombineModeRGB != GL_INTERPOLATE_EXT &&
textureUnit->CombineModeA != GL_INTERPOLATE_EXT) {
break; /* arg0 and arg1 are done. we don't need arg2. */
}
}
 
/*
* Do the texture combine.
*/
switch (textureUnit->CombineModeRGB) {
case GL_REPLACE:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
if (RGBshift) {
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = arg0[i][RCOMP] * RGBmult;
rgba[i][GCOMP] = arg0[i][GCOMP] * RGBmult;
rgba[i][BCOMP] = arg0[i][BCOMP] * RGBmult;
#else
GLuint r = (GLuint) arg0[i][RCOMP] << RGBshift;
GLuint g = (GLuint) arg0[i][GCOMP] << RGBshift;
GLuint b = (GLuint) arg0[i][BCOMP] << RGBshift;
rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
#endif
}
}
else {
for (i = 0; i < n; i++) {
rgba[i][RCOMP] = arg0[i][RCOMP];
rgba[i][GCOMP] = arg0[i][GCOMP];
rgba[i][BCOMP] = arg0[i][BCOMP];
}
}
}
break;
case GL_MODULATE:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
#if CHAN_TYPE != GL_FLOAT
const GLint shift = CHAN_BITS - RGBshift;
#endif
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = arg0[i][RCOMP] * arg1[i][RCOMP] * RGBmult;
rgba[i][GCOMP] = arg0[i][GCOMP] * arg1[i][GCOMP] * RGBmult;
rgba[i][BCOMP] = arg0[i][BCOMP] * arg1[i][BCOMP] * RGBmult;
#else
GLuint r = PROD(arg0[i][RCOMP], arg1[i][RCOMP]) >> shift;
GLuint g = PROD(arg0[i][GCOMP], arg1[i][GCOMP]) >> shift;
GLuint b = PROD(arg0[i][BCOMP], arg1[i][BCOMP]) >> shift;
rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
#endif
}
}
break;
case GL_ADD:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP]) * RGBmult;
rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP]) * RGBmult;
rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP]) * RGBmult;
#else
GLint r = ((GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP]) << RGBshift;
GLint g = ((GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP]) << RGBshift;
GLint b = ((GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP]) << RGBshift;
rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
#endif
}
}
break;
case GL_ADD_SIGNED_EXT:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = (arg0[i][RCOMP] + arg1[i][RCOMP] - 0.5) * RGBmult;
rgba[i][GCOMP] = (arg0[i][GCOMP] + arg1[i][GCOMP] - 0.5) * RGBmult;
rgba[i][BCOMP] = (arg0[i][BCOMP] + arg1[i][BCOMP] - 0.5) * RGBmult;
#else
GLint r = (GLint) arg0[i][RCOMP] + (GLint) arg1[i][RCOMP] -half;
GLint g = (GLint) arg0[i][GCOMP] + (GLint) arg1[i][GCOMP] -half;
GLint b = (GLint) arg0[i][BCOMP] + (GLint) arg1[i][BCOMP] -half;
r = (r < 0) ? 0 : r << RGBshift;
g = (g < 0) ? 0 : g << RGBshift;
b = (b < 0) ? 0 : b << RGBshift;
rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
#endif
}
}
break;
case GL_INTERPOLATE_EXT:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argRGB[2];
#if CHAN_TYPE != GL_FLOAT
const GLint shift = CHAN_BITS - RGBshift;
#endif
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = (arg0[i][RCOMP] * arg2[i][RCOMP] +
arg1[i][RCOMP] * (CHAN_MAXF - arg2[i][RCOMP])) * RGBmult;
rgba[i][GCOMP] = (arg0[i][GCOMP] * arg2[i][GCOMP] +
arg1[i][GCOMP] * (CHAN_MAXF - arg2[i][GCOMP])) * RGBmult;
rgba[i][BCOMP] = (arg0[i][BCOMP] * arg2[i][BCOMP] +
arg1[i][BCOMP] * (CHAN_MAXF - arg2[i][BCOMP])) * RGBmult;
#else
GLuint r = (PROD(arg0[i][RCOMP], arg2[i][RCOMP])
+ PROD(arg1[i][RCOMP], CHAN_MAX - arg2[i][RCOMP]))
>> shift;
GLuint g = (PROD(arg0[i][GCOMP], arg2[i][GCOMP])
+ PROD(arg1[i][GCOMP], CHAN_MAX - arg2[i][GCOMP]))
>> shift;
GLuint b = (PROD(arg0[i][BCOMP], arg2[i][BCOMP])
+ PROD(arg1[i][BCOMP], CHAN_MAX - arg2[i][BCOMP]))
>> shift;
rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
#endif
}
}
break;
case GL_SUBTRACT_ARB:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][RCOMP] = (arg0[i][RCOMP] - arg1[i][RCOMP]) * RGBmult;
rgba[i][GCOMP] = (arg0[i][GCOMP] - arg1[i][GCOMP]) * RGBmult;
rgba[i][BCOMP] = (arg0[i][BCOMP] - arg1[i][BCOMP]) * RGBmult;
#else
GLint r = ((GLint) arg0[i][RCOMP] - (GLint) arg1[i][RCOMP]) << RGBshift;
GLint g = ((GLint) arg0[i][GCOMP] - (GLint) arg1[i][GCOMP]) << RGBshift;
GLint b = ((GLint) arg0[i][BCOMP] - (GLint) arg1[i][BCOMP]) << RGBshift;
rgba[i][RCOMP] = (GLchan) CLAMP(r, 0, CHAN_MAX);
rgba[i][GCOMP] = (GLchan) CLAMP(g, 0, CHAN_MAX);
rgba[i][BCOMP] = (GLchan) CLAMP(b, 0, CHAN_MAX);
#endif
}
}
break;
case GL_DOT3_RGB_EXT:
case GL_DOT3_RGBA_EXT:
{
/* Do not scale the result by 1 2 or 4 */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) +
(arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) +
(arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F))
* 4.0F;
dot = CLAMP(dot, 0.0F, CHAN_MAXF);
#else
GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half,
(GLint)arg1[i][RCOMP] - half) +
S_PROD((GLint)arg0[i][GCOMP] - half,
(GLint)arg1[i][GCOMP] - half) +
S_PROD((GLint)arg0[i][BCOMP] - half,
(GLint)arg1[i][BCOMP] - half)) >> 6;
dot = CLAMP(dot, 0, CHAN_MAX);
#endif
rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot;
}
}
break;
case GL_DOT3_RGB_ARB:
case GL_DOT3_RGBA_ARB:
{
/* DO scale the result by 1 2 or 4 */
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argRGB[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argRGB[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
GLchan dot = ((arg0[i][RCOMP]-0.5F) * (arg1[i][RCOMP]-0.5F) +
(arg0[i][GCOMP]-0.5F) * (arg1[i][GCOMP]-0.5F) +
(arg0[i][BCOMP]-0.5F) * (arg1[i][BCOMP]-0.5F))
* 4.0F * RGBmult;
dot = CLAMP(dot, 0.0, CHAN_MAXF);
#else
GLint dot = (S_PROD((GLint)arg0[i][RCOMP] - half,
(GLint)arg1[i][RCOMP] - half) +
S_PROD((GLint)arg0[i][GCOMP] - half,
(GLint)arg1[i][GCOMP] - half) +
S_PROD((GLint)arg0[i][BCOMP] - half,
(GLint)arg1[i][BCOMP] - half)) >> 6;
dot <<= RGBshift;
dot = CLAMP(dot, 0, CHAN_MAX);
#endif
rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = (GLchan) dot;
}
}
break;
default:
_mesa_problem(ctx, "invalid combine mode");
}
 
switch (textureUnit->CombineModeA) {
case GL_REPLACE:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
if (Ashift) {
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
GLchan a = arg0[i][ACOMP] * Amult;
#else
GLuint a = (GLuint) arg0[i][ACOMP] << Ashift;
#endif
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
}
}
else {
for (i = 0; i < n; i++) {
rgba[i][ACOMP] = arg0[i][ACOMP];
}
}
}
break;
case GL_MODULATE:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
#if CHAN_TYPE != GL_FLOAT
const GLint shift = CHAN_BITS - Ashift;
#endif
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = arg0[i][ACOMP] * arg1[i][ACOMP] * Amult;
#else
GLuint a = (PROD(arg0[i][ACOMP], arg1[i][ACOMP]) >> shift);
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
#endif
}
}
break;
case GL_ADD:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP]) * Amult;
#else
GLint a = ((GLint) arg0[i][ACOMP] + arg1[i][ACOMP]) << Ashift;
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
#endif
}
}
break;
case GL_ADD_SIGNED_EXT:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (arg0[i][ACOMP] + arg1[i][ACOMP] - 0.5F) * Amult;
#else
GLint a = (GLint) arg0[i][ACOMP] + (GLint) arg1[i][ACOMP] -half;
a = (a < 0) ? 0 : a << Ashift;
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
#endif
}
}
break;
case GL_INTERPOLATE_EXT:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
const GLchan (*arg2)[4] = (const GLchan (*)[4]) argA[2];
#if CHAN_TYPE != GL_FLOAT
const GLint shift = CHAN_BITS - Ashift;
#endif
for (i=0; i<n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (arg0[i][ACOMP] * arg2[i][ACOMP] +
arg1[i][ACOMP] * (CHAN_MAXF - arg2[i][ACOMP]))
* Amult;
#else
GLuint a = (PROD(arg0[i][ACOMP], arg2[i][ACOMP])
+ PROD(arg1[i][ACOMP], CHAN_MAX - arg2[i][ACOMP]))
>> shift;
rgba[i][ACOMP] = (GLchan) MIN2(a, CHAN_MAX);
#endif
}
}
break;
case GL_SUBTRACT_ARB:
{
const GLchan (*arg0)[4] = (const GLchan (*)[4]) argA[0];
const GLchan (*arg1)[4] = (const GLchan (*)[4]) argA[1];
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
rgba[i][ACOMP] = (arg0[i][ACOMP] - arg1[i][ACOMP]) * Amult;
#else
GLint a = ((GLint) arg0[i][ACOMP] - (GLint) arg1[i][ACOMP]) << Ashift;
rgba[i][ACOMP] = (GLchan) CLAMP(a, 0, CHAN_MAX);
#endif
}
}
break;
 
default:
_mesa_problem(ctx, "invalid combine mode");
}
 
/* Fix the alpha component for GL_DOT3_RGBA_EXT/ARB combining.
* This is kind of a kludge. It would have been better if the spec
* were written such that the GL_COMBINE_ALPHA value could be set to
* GL_DOT3.
*/
if (textureUnit->CombineModeRGB == GL_DOT3_RGBA_EXT ||
textureUnit->CombineModeRGB == GL_DOT3_RGBA_ARB) {
for (i = 0; i < n; i++) {
rgba[i][ACOMP] = rgba[i][RCOMP];
}
}
UNDEFARRAY(ccolor); /* mac 32k limitation */
}
#undef PROD
 
 
/**
* Implement NVIDIA's GL_NV_texture_env_combine4 extension when
* texUnit->EnvMode == GL_COMBINE4_NV.
*/
static INLINE void
texture_combine4( const GLcontext *ctx, GLuint unit, GLuint n,
CONST GLchan (*primary_rgba)[4],
CONST GLchan *texelBuffer,
GLchan (*rgba)[4] )
{
}
 
 
 
/**
* Apply a conventional OpenGL texture env mode (REPLACE, ADD, BLEND,
* MODULATE, or DECAL) to an array of fragments.
* Input: textureUnit - pointer to texture unit to apply
* format - base internal texture format
* n - number of fragments
* primary_rgba - primary colors (may alias rgba for single texture)
* texels - array of texel colors
* InOut: rgba - incoming fragment colors modified by texel colors
* according to the texture environment mode.
*/
static void
texture_apply( const GLcontext *ctx,
const struct gl_texture_unit *texUnit,
GLuint n,
CONST GLchan primary_rgba[][4], CONST GLchan texel[][4],
GLchan rgba[][4] )
{
GLint baseLevel;
GLuint i;
GLint Rc, Gc, Bc, Ac;
GLenum format;
 
ASSERT(texUnit);
ASSERT(texUnit->_Current);
 
baseLevel = texUnit->_Current->BaseLevel;
ASSERT(texUnit->_Current->Image[baseLevel]);
 
format = texUnit->_Current->Image[baseLevel]->Format;
 
if (format == GL_COLOR_INDEX || format == GL_DEPTH_COMPONENT
|| format == GL_YCBCR_MESA) {
format = GL_RGBA; /* a bit of a hack */
}
 
switch (texUnit->EnvMode) {
case GL_REPLACE:
switch (format) {
case GL_ALPHA:
for (i=0;i<n;i++) {
/* Cv = Cf */
/* Av = At */
rgba[i][ACOMP] = texel[i][ACOMP];
}
break;
case GL_LUMINANCE:
for (i=0;i<n;i++) {
/* Cv = Lt */
GLchan Lt = texel[i][RCOMP];
rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
/* Av = Af */
}
break;
case GL_LUMINANCE_ALPHA:
for (i=0;i<n;i++) {
GLchan Lt = texel[i][RCOMP];
/* Cv = Lt */
rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = Lt;
/* Av = At */
rgba[i][ACOMP] = texel[i][ACOMP];
}
break;
case GL_INTENSITY:
for (i=0;i<n;i++) {
/* Cv = It */
GLchan It = texel[i][RCOMP];
rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = It;
/* Av = It */
rgba[i][ACOMP] = It;
}
break;
case GL_RGB:
for (i=0;i<n;i++) {
/* Cv = Ct */
rgba[i][RCOMP] = texel[i][RCOMP];
rgba[i][GCOMP] = texel[i][GCOMP];
rgba[i][BCOMP] = texel[i][BCOMP];
/* Av = Af */
}
break;
case GL_RGBA:
for (i=0;i<n;i++) {
/* Cv = Ct */
rgba[i][RCOMP] = texel[i][RCOMP];
rgba[i][GCOMP] = texel[i][GCOMP];
rgba[i][BCOMP] = texel[i][BCOMP];
/* Av = At */
rgba[i][ACOMP] = texel[i][ACOMP];
}
break;
default:
_mesa_problem(ctx, "Bad format (GL_REPLACE) in texture_apply");
return;
}
break;
 
case GL_MODULATE:
switch (format) {
case GL_ALPHA:
for (i=0;i<n;i++) {
/* Cv = Cf */
/* Av = AfAt */
rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
}
break;
case GL_LUMINANCE:
for (i=0;i<n;i++) {
/* Cv = LtCf */
GLchan Lt = texel[i][RCOMP];
rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt );
rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt );
rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt );
/* Av = Af */
}
break;
case GL_LUMINANCE_ALPHA:
for (i=0;i<n;i++) {
/* Cv = CfLt */
GLchan Lt = texel[i][RCOMP];
rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], Lt );
rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], Lt );
rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], Lt );
/* Av = AfAt */
rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
}
break;
case GL_INTENSITY:
for (i=0;i<n;i++) {
/* Cv = CfIt */
GLchan It = texel[i][RCOMP];
rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], It );
rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], It );
rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], It );
/* Av = AfIt */
rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], It );
}
break;
case GL_RGB:
for (i=0;i<n;i++) {
/* Cv = CfCt */
rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] );
rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] );
rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] );
/* Av = Af */
}
break;
case GL_RGBA:
for (i=0;i<n;i++) {
/* Cv = CfCt */
rgba[i][RCOMP] = CHAN_PRODUCT( rgba[i][RCOMP], texel[i][RCOMP] );
rgba[i][GCOMP] = CHAN_PRODUCT( rgba[i][GCOMP], texel[i][GCOMP] );
rgba[i][BCOMP] = CHAN_PRODUCT( rgba[i][BCOMP], texel[i][BCOMP] );
/* Av = AfAt */
rgba[i][ACOMP] = CHAN_PRODUCT( rgba[i][ACOMP], texel[i][ACOMP] );
}
break;
default:
_mesa_problem(ctx, "Bad format (GL_MODULATE) in texture_apply");
return;
}
break;
 
case GL_DECAL:
switch (format) {
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_INTENSITY:
/* undefined */
break;
case GL_RGB:
for (i=0;i<n;i++) {
/* Cv = Ct */
rgba[i][RCOMP] = texel[i][RCOMP];
rgba[i][GCOMP] = texel[i][GCOMP];
rgba[i][BCOMP] = texel[i][BCOMP];
/* Av = Af */
}
break;
case GL_RGBA:
for (i=0;i<n;i++) {
/* Cv = Cf(1-At) + CtAt */
GLint t = texel[i][ACOMP], s = CHAN_MAX - t;
rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(texel[i][RCOMP],t);
rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(texel[i][GCOMP],t);
rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(texel[i][BCOMP],t);
/* Av = Af */
}
break;
default:
_mesa_problem(ctx, "Bad format (GL_DECAL) in texture_apply");
return;
}
break;
 
case GL_BLEND:
Rc = (GLint) (texUnit->EnvColor[0] * CHAN_MAXF);
Gc = (GLint) (texUnit->EnvColor[1] * CHAN_MAXF);
Bc = (GLint) (texUnit->EnvColor[2] * CHAN_MAXF);
Ac = (GLint) (texUnit->EnvColor[3] * CHAN_MAXF);
switch (format) {
case GL_ALPHA:
for (i=0;i<n;i++) {
/* Cv = Cf */
/* Av = AfAt */
rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
}
break;
case GL_LUMINANCE:
for (i=0;i<n;i++) {
/* Cv = Cf(1-Lt) + CcLt */
GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt;
rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt);
rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt);
rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt);
/* Av = Af */
}
break;
case GL_LUMINANCE_ALPHA:
for (i=0;i<n;i++) {
/* Cv = Cf(1-Lt) + CcLt */
GLchan Lt = texel[i][RCOMP], s = CHAN_MAX - Lt;
rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, Lt);
rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, Lt);
rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, Lt);
/* Av = AfAt */
rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]);
}
break;
case GL_INTENSITY:
for (i=0;i<n;i++) {
/* Cv = Cf(1-It) + CcLt */
GLchan It = texel[i][RCOMP], s = CHAN_MAX - It;
rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], s) + CHAN_PRODUCT(Rc, It);
rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], s) + CHAN_PRODUCT(Gc, It);
rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], s) + CHAN_PRODUCT(Bc, It);
/* Av = Af(1-It) + Ac*It */
rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], s) + CHAN_PRODUCT(Ac, It);
}
break;
case GL_RGB:
for (i=0;i<n;i++) {
/* Cv = Cf(1-Ct) + CcCt */
rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]);
rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]);
rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]);
/* Av = Af */
}
break;
case GL_RGBA:
for (i=0;i<n;i++) {
/* Cv = Cf(1-Ct) + CcCt */
rgba[i][RCOMP] = CHAN_PRODUCT(rgba[i][RCOMP], (CHAN_MAX-texel[i][RCOMP])) + CHAN_PRODUCT(Rc,texel[i][RCOMP]);
rgba[i][GCOMP] = CHAN_PRODUCT(rgba[i][GCOMP], (CHAN_MAX-texel[i][GCOMP])) + CHAN_PRODUCT(Gc,texel[i][GCOMP]);
rgba[i][BCOMP] = CHAN_PRODUCT(rgba[i][BCOMP], (CHAN_MAX-texel[i][BCOMP])) + CHAN_PRODUCT(Bc,texel[i][BCOMP]);
/* Av = AfAt */
rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP],texel[i][ACOMP]);
}
break;
default:
_mesa_problem(ctx, "Bad format (GL_BLEND) in texture_apply");
return;
}
break;
 
/* XXX don't clamp results if GLchan is float??? */
 
case GL_ADD: /* GL_EXT_texture_add_env */
switch (format) {
case GL_ALPHA:
for (i=0;i<n;i++) {
/* Rv = Rf */
/* Gv = Gf */
/* Bv = Bf */
rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
}
break;
case GL_LUMINANCE:
for (i=0;i<n;i++) {
GLuint Lt = texel[i][RCOMP];
GLuint r = rgba[i][RCOMP] + Lt;
GLuint g = rgba[i][GCOMP] + Lt;
GLuint b = rgba[i][BCOMP] + Lt;
rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
/* Av = Af */
}
break;
case GL_LUMINANCE_ALPHA:
for (i=0;i<n;i++) {
GLuint Lt = texel[i][RCOMP];
GLuint r = rgba[i][RCOMP] + Lt;
GLuint g = rgba[i][GCOMP] + Lt;
GLuint b = rgba[i][BCOMP] + Lt;
rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
}
break;
case GL_INTENSITY:
for (i=0;i<n;i++) {
GLchan It = texel[i][RCOMP];
GLuint r = rgba[i][RCOMP] + It;
GLuint g = rgba[i][GCOMP] + It;
GLuint b = rgba[i][BCOMP] + It;
GLuint a = rgba[i][ACOMP] + It;
rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
rgba[i][ACOMP] = MIN2(a, CHAN_MAX);
}
break;
case GL_RGB:
for (i=0;i<n;i++) {
GLuint r = rgba[i][RCOMP] + texel[i][RCOMP];
GLuint g = rgba[i][GCOMP] + texel[i][GCOMP];
GLuint b = rgba[i][BCOMP] + texel[i][BCOMP];
rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
/* Av = Af */
}
break;
case GL_RGBA:
for (i=0;i<n;i++) {
GLuint r = rgba[i][RCOMP] + texel[i][RCOMP];
GLuint g = rgba[i][GCOMP] + texel[i][GCOMP];
GLuint b = rgba[i][BCOMP] + texel[i][BCOMP];
rgba[i][RCOMP] = MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = MIN2(b, CHAN_MAX);
rgba[i][ACOMP] = CHAN_PRODUCT(rgba[i][ACOMP], texel[i][ACOMP]);
}
break;
default:
_mesa_problem(ctx, "Bad format (GL_ADD) in texture_apply");
return;
}
break;
 
default:
_mesa_problem(ctx, "Bad env mode in texture_apply");
return;
}
}
 
 
 
/**
* Apply texture mapping to a span of fragments.
*/
void
_swrast_texture_span( GLcontext *ctx, struct sw_span *span )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLchan primary_rgba[MAX_WIDTH][4];
GLuint unit;
 
ASSERT(span->end < MAX_WIDTH);
ASSERT(span->arrayMask & SPAN_TEXTURE);
 
/*
* Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR)
*/
if (swrast->_AnyTextureCombine)
MEMCPY(primary_rgba, span->array->rgba, 4 * span->end * sizeof(GLchan));
 
/*
* Must do all texture sampling before combining in order to
* accomodate GL_ARB_texture_env_crossbar.
*/
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
const struct gl_texture_object *curObj = texUnit->_Current;
GLfloat *lambda = span->array->lambda[unit];
GLchan (*texels)[4] = (GLchan (*)[4])
(swrast->TexelBuffer + unit * (span->end * 4 * sizeof(GLchan)));
 
/* adjust texture lod (lambda) */
if (span->arrayMask | SPAN_LAMBDA) {
if (texUnit->LodBias != 0.0F) {
/* apply LOD bias, but don't clamp yet */
GLuint i;
for (i = 0; i < span->end; i++) {
lambda[i] += texUnit->LodBias;
}
}
 
if (curObj->MinLod != -1000.0 || curObj->MaxLod != 1000.0) {
/* apply LOD clamping to lambda */
const GLfloat min = curObj->MinLod;
const GLfloat max = curObj->MaxLod;
GLuint i;
for (i = 0; i < span->end; i++) {
GLfloat l = lambda[i];
lambda[i] = CLAMP(l, min, max);
}
}
}
 
/* Sample the texture (span->end fragments) */
swrast->TextureSample[unit]( ctx, unit, texUnit->_Current,
span->end, span->array->texcoords[unit],
lambda, texels );
}
}
 
/*
* OK, now apply the texture (aka texture combine/blend).
* We modify the span->color.rgba values.
*/
for (unit = 0; unit < ctx->Const.MaxTextureUnits; unit++) {
if (ctx->Texture.Unit[unit]._ReallyEnabled) {
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
if (texUnit->EnvMode == GL_COMBINE_EXT) {
/* GL_ARB/EXT_texture_env_combine */
texture_combine( ctx, unit, span->end,
(CONST GLchan (*)[4]) primary_rgba,
swrast->TexelBuffer,
span->array->rgba );
}
else if (texUnit->EnvMode == GL_COMBINE4_NV) {
/* GL_NV_texture_env_combine4 */
texture_combine4( ctx, unit, span->end,
(CONST GLchan (*)[4]) primary_rgba,
swrast->TexelBuffer,
span->array->rgba );
}
else {
/* conventional texture blend */
const GLchan (*texels)[4] = (const GLchan (*)[4])
(swrast->TexelBuffer + unit *
(span->end * 4 * sizeof(GLchan)));
texture_apply( ctx, texUnit, span->end,
(CONST GLchan (*)[4]) primary_rgba, texels,
span->array->rgba );
}
}
}
}
/shark/trunk/ports/mesa/src/swrast/s_span.c
0,0 → 1,1409
/* $Id: s_span.c,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 5.0
*
* 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.
*/
 
 
/**
* \file swrast/s_span.c
* \brief Span processing functions used by all rasterization functions.
* This is where all the per-fragment tests are performed
* \author Brian Paul
*/
 
#include "glheader.h"
#include "colormac.h"
#include "context.h"
#include "macros.h"
#include "mmath.h"
#include "imports.h"
 
#include "s_alpha.h"
#include "s_alphabuf.h"
#include "s_blend.h"
#include "s_context.h"
#include "s_depth.h"
#include "s_fog.h"
#include "s_logic.h"
#include "s_masking.h"
#include "s_span.h"
#include "s_stencil.h"
#include "s_texture.h"
 
 
/**
* Init span's Z interpolation values to the RasterPos Z.
* Used during setup for glDraw/CopyPixels.
*/
void
_mesa_span_default_z( GLcontext *ctx, struct sw_span *span )
{
if (ctx->Visual.depthBits <= 16)
span->z = FloatToFixed(ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F);
else
span->z = (GLint) (ctx->Current.RasterPos[2] * ctx->DepthMax + 0.5F);
span->zStep = 0;
span->interpMask |= SPAN_Z;
}
 
 
/**
* Init span's fog interpolation values to the RasterPos fog.
* Used during setup for glDraw/CopyPixels.
*/
void
_mesa_span_default_fog( GLcontext *ctx, struct sw_span *span )
{
span->fog = _mesa_z_to_fogfactor(ctx, ctx->Current.RasterDistance);
span->fogStep = 0;
span->interpMask |= SPAN_FOG;
}
 
 
/**
* Init span's color or index interpolation values to the RasterPos color.
* Used during setup for glDraw/CopyPixels.
*/
void
_mesa_span_default_color( GLcontext *ctx, struct sw_span *span )
{
if (ctx->Visual.rgbMode) {
GLchan r, g, b, a;
UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]);
UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterColor[1]);
UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterColor[2]);
UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterColor[3]);
#if CHAN_TYPE == GL_FLOAT
span->red = r;
span->green = g;
span->blue = b;
span->alpha = a;
#else
span->red = IntToFixed(r);
span->green = IntToFixed(g);
span->blue = IntToFixed(b);
span->alpha = IntToFixed(a);
#endif
span->redStep = 0;
span->greenStep = 0;
span->blueStep = 0;
span->alphaStep = 0;
span->interpMask |= SPAN_RGBA;
}
else {
span->index = IntToFixed(ctx->Current.RasterIndex);
span->indexStep = 0;
span->interpMask |= SPAN_INDEX;
}
}
 
 
/**
* Init span's texcoord interpolation values to the RasterPos texcoords.
* Used during setup for glDraw/CopyPixels.
*/
void
_mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span )
{
GLuint i;
for (i = 0; i < ctx->Const.MaxTextureUnits; i++) {
COPY_4V(span->tex[i], ctx->Current.RasterTexCoords[i]);
ASSIGN_4V(span->texStepX[i], 0.0F, 0.0F, 0.0F, 0.0F);
ASSIGN_4V(span->texStepY[i], 0.0F, 0.0F, 0.0F, 0.0F);
}
span->interpMask |= SPAN_TEXTURE;
}
 
 
/* Fill in the span.color.rgba array from the interpolation values */
static void
interpolate_colors(GLcontext *ctx, struct sw_span *span)
{
GLfixed r = span->red;
GLfixed g = span->green;
GLfixed b = span->blue;
GLfixed a = span->alpha;
const GLint dr = span->redStep;
const GLint dg = span->greenStep;
const GLint db = span->blueStep;
const GLint da = span->alphaStep;
const GLuint n = span->end;
GLchan (*rgba)[4] = span->array->rgba;
GLuint i;
 
ASSERT((span->interpMask & SPAN_RGBA) &&
!(span->arrayMask & SPAN_RGBA));
 
if (span->interpMask & SPAN_FLAT) {
/* constant color */
GLchan color[4];
color[RCOMP] = FixedToChan(r);
color[GCOMP] = FixedToChan(g);
color[BCOMP] = FixedToChan(b);
color[ACOMP] = FixedToChan(a);
for (i = 0; i < n; i++) {
COPY_CHAN4(span->array->rgba[i], color);
}
}
else {
/* interpolate */
for (i = 0; i < n; i++) {
rgba[i][RCOMP] = FixedToChan(r);
rgba[i][GCOMP] = FixedToChan(g);
rgba[i][BCOMP] = FixedToChan(b);
rgba[i][ACOMP] = FixedToChan(a);
r += dr;
g += dg;
b += db;
a += da;
}
}
span->arrayMask |= SPAN_RGBA;
}
 
 
/* Fill in the span.color.index array from the interpolation values */
static void
interpolate_indexes(GLcontext *ctx, struct sw_span *span)
{
GLfixed index = span->index;
const GLint indexStep = span->indexStep;
const GLuint n = span->end;
GLuint *indexes = span->array->index;
GLuint i;
ASSERT((span->interpMask & SPAN_INDEX) &&
!(span->arrayMask & SPAN_INDEX));
 
if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) {
/* constant color */
index = FixedToInt(index);
for (i = 0; i < n; i++) {
indexes[i] = index;
}
}
else {
/* interpolate */
for (i = 0; i < n; i++) {
indexes[i] = FixedToInt(index);
index += indexStep;
}
}
span->arrayMask |= SPAN_INDEX;
}
 
 
/* Fill in the span.->array->spec array from the interpolation values */
static void
interpolate_specular(GLcontext *ctx, struct sw_span *span)
{
if (span->interpMask & SPAN_FLAT) {
/* constant color */
const GLchan r = FixedToChan(span->specRed);
const GLchan g = FixedToChan(span->specGreen);
const GLchan b = FixedToChan(span->specBlue);
GLuint i;
for (i = 0; i < span->end; i++) {
span->array->spec[i][RCOMP] = r;
span->array->spec[i][GCOMP] = g;
span->array->spec[i][BCOMP] = b;
}
}
else {
/* interpolate */
#if CHAN_TYPE == GL_FLOAT
GLfloat r = span->specRed;
GLfloat g = span->specGreen;
GLfloat b = span->specBlue;
#else
GLfixed r = span->specRed;
GLfixed g = span->specGreen;
GLfixed b = span->specBlue;
#endif
GLuint i;
for (i = 0; i < span->end; i++) {
span->array->spec[i][RCOMP] = FixedToChan(r);
span->array->spec[i][GCOMP] = FixedToChan(g);
span->array->spec[i][BCOMP] = FixedToChan(b);
r += span->specRedStep;
g += span->specGreenStep;
b += span->specBlueStep;
}
}
span->arrayMask |= SPAN_SPEC;
}
 
 
/* Fill in the span.zArray array from the interpolation values */
void
_mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span )
{
const GLuint n = span->end;
GLuint i;
 
ASSERT((span->interpMask & SPAN_Z) &&
!(span->arrayMask & SPAN_Z));
 
if (ctx->Visual.depthBits <= 16) {
GLfixed zval = span->z;
GLdepth *z = span->array->z;
for (i = 0; i < n; i++) {
z[i] = FixedToInt(zval);
zval += span->zStep;
}
}
else {
/* Deep Z buffer, no fixed->int shift */
GLfixed zval = span->z;
GLdepth *z = span->array->z;
for (i = 0; i < n; i++) {
z[i] = zval;
zval += span->zStep;
}
}
span->arrayMask |= SPAN_Z;
}
 
 
/*
* This the ideal solution, as given in the OpenGL spec.
*/
#if 0
static GLfloat
compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
{
GLfloat dudx = texW * ((s + dsdx) / (q + dqdx) - s * invQ);
GLfloat dvdx = texH * ((t + dtdx) / (q + dqdx) - t * invQ);
GLfloat dudy = texW * ((s + dsdy) / (q + dqdy) - s * invQ);
GLfloat dvdy = texH * ((t + dtdy) / (q + dqdy) - t * invQ);
GLfloat x = sqrt(dudx * dudx + dvdx * dvdx);
GLfloat y = sqrt(dudy * dudy + dvdy * dvdy);
GLfloat rho = MAX2(x, y);
GLfloat lambda = LOG2(rho);
return lambda;
}
#endif
 
 
/*
* This is a faster approximation
*/
static GLfloat
compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy,
GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH,
GLfloat s, GLfloat t, GLfloat q, GLfloat invQ)
{
GLfloat dsdx2 = (s + dsdx) / (q + dqdx) - s * invQ;
GLfloat dtdx2 = (t + dtdx) / (q + dqdx) - t * invQ;
GLfloat dsdy2 = (s + dsdy) / (q + dqdy) - s * invQ;
GLfloat dtdy2 = (t + dtdy) / (q + dqdy) - t * invQ;
GLfloat maxU, maxV, rho, lambda;
dsdx2 = FABSF(dsdx2);
dsdy2 = FABSF(dsdy2);
dtdx2 = FABSF(dtdx2);
dtdy2 = FABSF(dtdy2);
maxU = MAX2(dsdx2, dsdy2) * texW;
maxV = MAX2(dtdx2, dtdy2) * texH;
rho = MAX2(maxU, maxV);
lambda = LOG2(rho);
return lambda;
}
 
/*
* Fill in the span.texcoords array from the interpolation values.
* XXX We could optimize here for the case when dq = 0. That would
* usually be the case when using an orthographic projection.
*/
static void
interpolate_texcoords(GLcontext *ctx, struct sw_span *span)
{
ASSERT(span->interpMask & SPAN_TEXTURE);
ASSERT(!(span->arrayMask & SPAN_TEXTURE));
 
if (ctx->Texture._EnabledUnits > 1) {
/* multitexture */
GLuint u;
span->arrayMask |= SPAN_TEXTURE;
for (u = 0; u < ctx->Const.MaxTextureUnits; u++) {
if (ctx->Texture.Unit[u]._ReallyEnabled) {
const struct gl_texture_object *obj =ctx->Texture.Unit[u]._Current;
const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
GLboolean needLambda = (obj->MinFilter != obj->MagFilter);
if (needLambda) {
GLfloat (*texcoord)[4] = span->array->texcoords[u];
GLfloat *lambda = span->array->lambda[u];
const GLfloat texW = (GLfloat) img->WidthScale;
const GLfloat texH = (GLfloat) img->HeightScale;
const GLfloat dsdx = span->texStepX[u][0];
const GLfloat dsdy = span->texStepY[u][0];
const GLfloat dtdx = span->texStepX[u][1];
const GLfloat dtdy = span->texStepY[u][1];
const GLfloat drdx = span->texStepX[u][2];
const GLfloat dqdx = span->texStepX[u][3];
const GLfloat dqdy = span->texStepY[u][3];
GLfloat s = span->tex[u][0];
GLfloat t = span->tex[u][1];
GLfloat r = span->tex[u][2];
GLfloat q = span->tex[u][3];
GLuint i;
for (i = 0; i < span->end; i++) {
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
texcoord[i][0] = s * invQ;
texcoord[i][1] = t * invQ;
texcoord[i][2] = r * invQ;
lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy,
dqdx, dqdy, texW, texH,
s, t, q, invQ);
s += dsdx;
t += dtdx;
r += drdx;
q += dqdx;
}
span->arrayMask |= SPAN_LAMBDA;
}
else {
GLfloat (*texcoord)[4] = span->array->texcoords[u];
GLfloat *lambda = span->array->lambda[u];
const GLfloat dsdx = span->texStepX[u][0];
const GLfloat dtdx = span->texStepX[u][1];
const GLfloat drdx = span->texStepX[u][2];
const GLfloat dqdx = span->texStepX[u][3];
GLfloat s = span->tex[u][0];
GLfloat t = span->tex[u][1];
GLfloat r = span->tex[u][2];
GLfloat q = span->tex[u][3];
GLuint i;
if (dqdx == 0.0) {
/* Ortho projection or polygon's parallel to window X axis */
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
for (i = 0; i < span->end; i++) {
texcoord[i][0] = s * invQ;
texcoord[i][1] = t * invQ;
texcoord[i][2] = r * invQ;
lambda[i] = 0.0;
s += dsdx;
t += dtdx;
r += drdx;
}
}
else {
for (i = 0; i < span->end; i++) {
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
texcoord[i][0] = s * invQ;
texcoord[i][1] = t * invQ;
texcoord[i][2] = r * invQ;
lambda[i] = 0.0;
s += dsdx;
t += dtdx;
r += drdx;
q += dqdx;
}
}
} /* lambda */
} /* if */
} /* for */
}
else {
/* single texture */
const struct gl_texture_object *obj = ctx->Texture.Unit[0]._Current;
const struct gl_texture_image *img = obj->Image[obj->BaseLevel];
GLboolean needLambda = (obj->MinFilter != obj->MagFilter);
span->arrayMask |= SPAN_TEXTURE;
if (needLambda) {
/* just texture unit 0, with lambda */
GLfloat (*texcoord)[4] = span->array->texcoords[0];
GLfloat *lambda = span->array->lambda[0];
const GLfloat texW = (GLfloat) img->WidthScale;
const GLfloat texH = (GLfloat) img->HeightScale;
const GLfloat dsdx = span->texStepX[0][0];
const GLfloat dsdy = span->texStepY[0][0];
const GLfloat dtdx = span->texStepX[0][1];
const GLfloat dtdy = span->texStepY[0][1];
const GLfloat drdx = span->texStepX[0][2];
const GLfloat dqdx = span->texStepX[0][3];
const GLfloat dqdy = span->texStepY[0][3];
GLfloat s = span->tex[0][0];
GLfloat t = span->tex[0][1];
GLfloat r = span->tex[0][2];
GLfloat q = span->tex[0][3];
GLuint i;
for (i = 0; i < span->end; i++) {
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
lambda[i] = compute_lambda(dsdx, dsdy, dtdx, dtdy,
dqdx, dqdy, texW, texH,
s, t, q, invQ);
texcoord[i][0] = s * invQ;
texcoord[i][1] = t * invQ;
texcoord[i][2] = r * invQ;
s += dsdx;
t += dtdx;
r += drdx;
q += dqdx;
}
span->arrayMask |= SPAN_LAMBDA;
}
else {
/* just texture 0, without lambda */
GLfloat (*texcoord)[4] = span->array->texcoords[0];
const GLfloat dsdx = span->texStepX[0][0];
const GLfloat dtdx = span->texStepX[0][1];
const GLfloat drdx = span->texStepX[0][2];
const GLfloat dqdx = span->texStepX[0][3];
GLfloat s = span->tex[0][0];
GLfloat t = span->tex[0][1];
GLfloat r = span->tex[0][2];
GLfloat q = span->tex[0][3];
GLuint i;
if (dqdx == 0.0) {
/* Ortho projection or polygon's parallel to window X axis */
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
for (i = 0; i < span->end; i++) {
texcoord[i][0] = s * invQ;
texcoord[i][1] = t * invQ;
texcoord[i][2] = r * invQ;
s += dsdx;
t += dtdx;
r += drdx;
}
}
else {
for (i = 0; i < span->end; i++) {
const GLfloat invQ = (q == 0.0F) ? 1.0F : (1.0F / q);
texcoord[i][0] = s * invQ;
texcoord[i][1] = t * invQ;
texcoord[i][2] = r * invQ;
s += dsdx;
t += dtdx;
r += drdx;
q += dqdx;
}
}
}
}
}
 
 
/**
* Apply the current polygon stipple pattern to a span of pixels.
*/
static void
stipple_polygon_span( GLcontext *ctx, struct sw_span *span )
{
const GLuint highbit = 0x80000000;
const GLuint stipple = ctx->PolygonStipple[span->y % 32];
GLubyte *mask = span->array->mask;
GLuint i, m;
 
ASSERT(ctx->Polygon.StippleFlag);
ASSERT((span->arrayMask & SPAN_XY) == 0);
 
m = highbit >> (GLuint) (span->x % 32);
 
for (i = 0; i < span->end; i++) {
if ((m & stipple) == 0) {
mask[i] = 0;
}
m = m >> 1;
if (m == 0) {
m = highbit;
}
}
span->writeAll = GL_FALSE;
}
 
 
/**
* Clip a pixel span to the current buffer/window boundaries:
* DrawBuffer->_Xmin, _Xmax, _Ymin, _Ymax. This will accomplish
* window clipping and scissoring.
* Return: GL_TRUE some pixels still visible
* GL_FALSE nothing visible
*/
static GLuint
clip_span( GLcontext *ctx, struct sw_span *span )
{
const GLint xmin = ctx->DrawBuffer->_Xmin;
const GLint xmax = ctx->DrawBuffer->_Xmax;
const GLint ymin = ctx->DrawBuffer->_Ymin;
const GLint ymax = ctx->DrawBuffer->_Ymax;
 
if (span->arrayMask & SPAN_XY) {
/* arrays of x/y pixel coords */
const GLint *x = span->array->x;
const GLint *y = span->array->y;
const GLint n = span->end;
GLubyte *mask = span->array->mask;
GLint i;
if (span->arrayMask & SPAN_MASK) {
/* note: using & intead of && to reduce branches */
for (i = 0; i < n; i++) {
mask[i] &= (x[i] >= xmin) & (x[i] < xmax)
& (y[i] >= ymin) & (y[i] < ymax);
}
}
else {
/* note: using & intead of && to reduce branches */
for (i = 0; i < n; i++) {
mask[i] = (x[i] >= xmin) & (x[i] < xmax)
& (y[i] >= ymin) & (y[i] < ymax);
}
}
return GL_TRUE; /* some pixels visible */
}
else {
/* horizontal span of pixels */
const GLint x = span->x;
const GLint y = span->y;
const GLint n = span->end;
 
/* Trivial rejection tests */
if (y < ymin || y >= ymax || x + n <= xmin || x >= xmax) {
span->end = 0;
return GL_FALSE; /* all pixels clipped */
}
 
/* Clip to the left */
if (x < xmin) {
ASSERT(x + n > xmin);
span->writeAll = GL_FALSE;
_mesa_bzero(span->array->mask, (xmin - x) * sizeof(GLubyte));
}
 
/* Clip to right */
if (x + n > xmax) {
ASSERT(x < xmax);
span->end = xmax - x;
}
 
return GL_TRUE; /* some pixels visible */
}
}
 
 
 
/**
* Draw to more than one color buffer (or none).
*/
static void
multi_write_index_span( GLcontext *ctx, struct sw_span *span )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
GLuint bufferBit;
 
/* loop over four possible dest color buffers */
for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) {
if (bufferBit & ctx->Color._DrawDestMask) {
GLuint indexTmp[MAX_WIDTH];
ASSERT(span->end < MAX_WIDTH);
 
/* Set the current read/draw buffer */
swrast->CurrentBuffer = bufferBit;
(*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
 
/* make copy of incoming indexes */
MEMCPY( indexTmp, span->array->index, span->end * sizeof(GLuint) );
 
if (ctx->Color.IndexLogicOpEnabled) {
_mesa_logicop_ci_span(ctx, span, indexTmp);
}
 
if (ctx->Color.IndexMask != 0xffffffff) {
_mesa_mask_index_span(ctx, span, indexTmp);
}
 
if (span->arrayMask & SPAN_XY) {
/* array of pixel coords */
(*swrast->Driver.WriteCI32Pixels)(ctx, span->end,
span->array->x, span->array->y,
indexTmp, span->array->mask);
}
else {
/* horizontal run of pixels */
(*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
indexTmp, span->array->mask);
}
}
}
 
/* restore default dest buffer */
_swrast_use_draw_buffer(ctx);
}
 
 
/**
* Draw to more than one RGBA color buffer (or none).
* All fragment operations, up to (but not) blending/logicop should
* have been done first.
*/
static void
multi_write_rgba_span( GLcontext *ctx, struct sw_span *span )
{
const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
GLuint bufferBit;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
ASSERT(colorMask != 0x0);
 
if (ctx->Color.DrawBuffer == GL_NONE)
return;
 
/* loop over four possible dest color buffers */
for (bufferBit = 1; bufferBit <= 8; bufferBit <<= 1) {
if (bufferBit & ctx->Color._DrawDestMask) {
GLchan rgbaTmp[MAX_WIDTH][4];
ASSERT(span->end < MAX_WIDTH);
 
/* Set the current read/draw buffer */
swrast->CurrentBuffer = bufferBit;
(*swrast->Driver.SetBuffer)(ctx, ctx->DrawBuffer, bufferBit);
 
/* make copy of incoming colors */
MEMCPY( rgbaTmp, span->array->rgba, 4 * span->end * sizeof(GLchan) );
 
if (ctx->Color.ColorLogicOpEnabled) {
_mesa_logicop_rgba_span(ctx, span, rgbaTmp);
}
else if (ctx->Color.BlendEnabled) {
_mesa_blend_span(ctx, span, rgbaTmp);
}
 
if (colorMask != 0xffffffff) {
_mesa_mask_rgba_span(ctx, span, rgbaTmp);
}
 
if (span->arrayMask & SPAN_XY) {
/* array of pixel coords */
(*swrast->Driver.WriteRGBAPixels)(ctx, span->end,
span->array->x, span->array->y,
(const GLchan (*)[4]) rgbaTmp,
span->array->mask);
if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
_mesa_write_alpha_pixels(ctx, span->end,
span->array->x, span->array->y,
(const GLchan (*)[4]) rgbaTmp,
span->array->mask);
}
}
else {
/* horizontal run of pixels */
(*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) rgbaTmp,
span->array->mask);
if (swrast->_RasterMask & ALPHABUF_BIT) {
_mesa_write_alpha_span(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) rgbaTmp,
span->array->mask);
}
}
}
}
 
/* restore default dest buffer */
_swrast_use_draw_buffer(ctx);
}
 
 
 
/**
* This function may modify any of the array values in the span.
* span->interpMask and span->arrayMask may be changed but will be restored
* to their original values before returning.
*/
void
_mesa_write_index_span( GLcontext *ctx, struct sw_span *span)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint origInterpMask = span->interpMask;
const GLuint origArrayMask = span->arrayMask;
 
ASSERT(span->end <= MAX_WIDTH);
ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
span->primitive == GL_POLYGON || span->primitive == GL_BITMAP);
ASSERT((span->interpMask | span->arrayMask) & SPAN_INDEX);
ASSERT((span->interpMask & span->arrayMask) == 0);
 
if (span->arrayMask & SPAN_MASK) {
/* mask was initialized by caller, probably glBitmap */
span->writeAll = GL_FALSE;
}
else {
MEMSET(span->array->mask, 1, span->end);
span->writeAll = GL_TRUE;
}
 
/* Clipping */
if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
if (!clip_span(ctx, span)) {
return;
}
}
 
#ifdef DEBUG
if (span->arrayMask & SPAN_XY) {
GLuint i;
for (i = 0; i < span->end; i++) {
if (span->array->mask[i]) {
assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
}
}
}
#endif
 
/* Polygon Stippling */
if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
stipple_polygon_span(ctx, span);
}
 
/* Depth test and stencil */
if (ctx->Depth.Test || ctx->Stencil.Enabled) {
if (span->interpMask & SPAN_Z)
_mesa_span_interpolate_z(ctx, span);
 
if (ctx->Stencil.Enabled) {
if (!_mesa_stencil_and_ztest_span(ctx, span)) {
span->arrayMask = origArrayMask;
return;
}
}
else {
ASSERT(ctx->Depth.Test);
if (!_mesa_depth_test_span(ctx, span)) {
span->arrayMask = origArrayMask;
return;
}
}
}
 
/* if we get here, something passed the depth test */
ctx->OcclusionResult = GL_TRUE;
 
/* we have to wait until after occlusion to do this test */
if (ctx->Color.DrawBuffer == GL_NONE || ctx->Color.IndexMask == 0) {
/* write no pixels */
span->arrayMask = origArrayMask;
return;
}
 
/* Interpolate the color indexes if needed */
if (span->interpMask & SPAN_INDEX) {
interpolate_indexes(ctx, span);
/* clear the bit - this allows the WriteMonoCISpan optimization below */
span->interpMask &= ~SPAN_INDEX;
}
 
/* Fog */
if (ctx->Fog.Enabled) {
_mesa_fog_ci_span(ctx, span);
}
 
/* Antialias coverage application */
if (span->arrayMask & SPAN_COVERAGE) {
GLuint i;
GLuint *index = span->array->index;
GLfloat *coverage = span->array->coverage;
for (i = 0; i < span->end; i++) {
ASSERT(coverage[i] < 16);
index[i] = (index[i] & ~0xf) | ((GLuint) coverage[i]);
}
}
 
if (swrast->_RasterMask & MULTI_DRAW_BIT) {
/* draw to zero or two or more buffers */
multi_write_index_span(ctx, span);
}
else {
/* normal situation: draw to exactly one buffer */
if (ctx->Color.IndexLogicOpEnabled) {
_mesa_logicop_ci_span(ctx, span, span->array->index);
}
 
if (ctx->Color.IndexMask != 0xffffffff) {
_mesa_mask_index_span(ctx, span, span->array->index);
}
 
/* write pixels */
if (span->arrayMask & SPAN_XY) {
/* array of pixel coords */
if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
/* all pixels have same color index */
(*swrast->Driver.WriteMonoCIPixels)(ctx, span->end,
span->array->x, span->array->y,
FixedToInt(span->index),
span->array->mask);
}
else {
(*swrast->Driver.WriteCI32Pixels)(ctx, span->end, span->array->x,
span->array->y, span->array->index,
span->array->mask );
}
}
else {
/* horizontal run of pixels */
if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) {
/* all pixels have same color index */
(*swrast->Driver.WriteMonoCISpan)(ctx, span->end, span->x, span->y,
FixedToInt(span->index),
span->array->mask);
}
else {
(*swrast->Driver.WriteCI32Span)(ctx, span->end, span->x, span->y,
span->array->index,
span->array->mask);
}
}
}
 
span->interpMask = origInterpMask;
span->arrayMask = origArrayMask;
}
 
 
/**
* This function may modify any of the array values in the span.
* span->interpMask and span->arrayMask may be changed but will be restored
* to their original values before returning.
*/
void
_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span)
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
const GLuint origInterpMask = span->interpMask;
const GLuint origArrayMask = span->arrayMask;
GLboolean monoColor;
 
ASSERT(span->end <= MAX_WIDTH);
ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
span->primitive == GL_POLYGON || span->primitive == GL_BITMAP);
ASSERT((span->interpMask & span->arrayMask) == 0);
ASSERT((span->interpMask | span->arrayMask) & SPAN_RGBA);
#ifdef DEBUG
if (ctx->Fog.Enabled)
ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG);
if (ctx->Depth.Test)
ASSERT((span->interpMask | span->arrayMask) & SPAN_Z);
#endif
 
if (span->arrayMask & SPAN_MASK) {
/* mask was initialized by caller, probably glBitmap */
span->writeAll = GL_FALSE;
}
else {
MEMSET(span->array->mask, 1, span->end);
span->writeAll = GL_TRUE;
}
 
/* Determine if we have mono-chromatic colors */
monoColor = (span->interpMask & SPAN_RGBA) &&
span->redStep == 0 && span->greenStep == 0 &&
span->blueStep == 0 && span->alphaStep == 0;
 
/* Clipping */
if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
if (!clip_span(ctx, span)) {
return;
}
}
 
#ifdef DEBUG
if (span->arrayMask & SPAN_XY) {
GLuint i;
for (i = 0; i < span->end; i++) {
if (span->array->mask[i]) {
assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
}
}
}
#endif
 
/* Polygon Stippling */
if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
stipple_polygon_span(ctx, span);
}
 
/* Do the alpha test */
if (ctx->Color.AlphaEnabled) {
if (!_mesa_alpha_test(ctx, span)) {
span->interpMask = origInterpMask;
span->arrayMask = origArrayMask;
return;
}
}
 
/* Stencil and Z testing */
if (ctx->Stencil.Enabled || ctx->Depth.Test) {
if (span->interpMask & SPAN_Z)
_mesa_span_interpolate_z(ctx, span);
 
if (ctx->Stencil.Enabled) {
if (!_mesa_stencil_and_ztest_span(ctx, span)) {
span->interpMask = origInterpMask;
span->arrayMask = origArrayMask;
return;
}
}
else {
ASSERT(ctx->Depth.Test);
ASSERT(span->arrayMask & SPAN_Z);
/* regular depth testing */
if (!_mesa_depth_test_span(ctx, span)) {
span->interpMask = origInterpMask;
span->arrayMask = origArrayMask;
return;
}
}
}
 
/* if we get here, something passed the depth test */
ctx->OcclusionResult = GL_TRUE;
 
/* can't abort span-writing until after occlusion testing */
if (colorMask == 0x0) {
span->interpMask = origInterpMask;
span->arrayMask = origArrayMask;
return;
}
 
/* Now we may need to interpolate the colors */
if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0) {
interpolate_colors(ctx, span);
/* clear the bit - this allows the WriteMonoCISpan optimization below */
span->interpMask &= ~SPAN_RGBA;
}
 
/* Fog */
if (ctx->Fog.Enabled) {
_mesa_fog_rgba_span(ctx, span);
monoColor = GL_FALSE;
}
 
/* Antialias coverage application */
if (span->arrayMask & SPAN_COVERAGE) {
GLchan (*rgba)[4] = span->array->rgba;
GLfloat *coverage = span->array->coverage;
GLuint i;
for (i = 0; i < span->end; i++) {
rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
}
monoColor = GL_FALSE;
}
 
if (swrast->_RasterMask & MULTI_DRAW_BIT) {
multi_write_rgba_span(ctx, span);
}
else {
/* normal: write to exactly one buffer */
if (ctx->Color.ColorLogicOpEnabled) {
_mesa_logicop_rgba_span(ctx, span, span->array->rgba);
monoColor = GL_FALSE;
}
else if (ctx->Color.BlendEnabled) {
_mesa_blend_span(ctx, span, span->array->rgba);
monoColor = GL_FALSE;
}
 
/* Color component masking */
if (colorMask != 0xffffffff) {
_mesa_mask_rgba_span(ctx, span, span->array->rgba);
monoColor = GL_FALSE;
}
 
/* write pixels */
if (span->arrayMask & SPAN_XY) {
/* array of pixel coords */
/* XXX test for mono color */
(*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x,
span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask);
if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
_mesa_write_alpha_pixels(ctx, span->end,
span->array->x, span->array->y,
(const GLchan (*)[4]) span->array->rgba,
span->array->mask);
}
}
else {
/* horizontal run of pixels */
if (monoColor) {
/* all pixels have same color */
GLchan color[4];
color[RCOMP] = FixedToChan(span->red);
color[GCOMP] = FixedToChan(span->green);
color[BCOMP] = FixedToChan(span->blue);
color[ACOMP] = FixedToChan(span->alpha);
(*swrast->Driver.WriteMonoRGBASpan)(ctx, span->end, span->x,
span->y, color, span->array->mask);
/* XXX software alpha buffer writes! */
}
else {
/* each pixel is a different color */
(*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) span->array->rgba,
span->writeAll ? ((const GLubyte *) NULL) : span->array->mask);
if (swrast->_RasterMask & ALPHABUF_BIT) {
_mesa_write_alpha_span(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) span->array->rgba,
span->writeAll ? ((const GLubyte *) NULL) : span->array->mask);
}
}
}
}
 
span->interpMask = origInterpMask;
span->arrayMask = origArrayMask;
}
 
 
/**
* Add specular color to base color. This is used only when
* GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR.
*/
static void
add_colors(GLuint n, GLchan rgba[][4], GLchan specular[][4] )
{
GLuint i;
for (i = 0; i < n; i++) {
#if CHAN_TYPE == GL_FLOAT
/* no clamping */
rgba[i][RCOMP] += specular[i][RCOMP];
rgba[i][GCOMP] += specular[i][GCOMP];
rgba[i][BCOMP] += specular[i][BCOMP];
#else
GLint r = rgba[i][RCOMP] + specular[i][RCOMP];
GLint g = rgba[i][GCOMP] + specular[i][GCOMP];
GLint b = rgba[i][BCOMP] + specular[i][BCOMP];
rgba[i][RCOMP] = (GLchan) MIN2(r, CHAN_MAX);
rgba[i][GCOMP] = (GLchan) MIN2(g, CHAN_MAX);
rgba[i][BCOMP] = (GLchan) MIN2(b, CHAN_MAX);
#endif
}
}
 
 
/**
* This function may modify any of the array values in the span.
* span->interpMask and span->arrayMask may be changed but will be restored
* to their original values before returning.
*/
void
_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span)
{
const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask);
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint origArrayMask = span->arrayMask;
 
ASSERT(span->primitive == GL_POINT || span->primitive == GL_LINE ||
span->primitive == GL_POLYGON || span->primitive == GL_BITMAP);
ASSERT(span->end <= MAX_WIDTH);
ASSERT((span->interpMask & span->arrayMask) == 0);
ASSERT(ctx->Texture._EnabledUnits);
 
/*
printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, span->interpMask, span->arrayMask);
*/
 
if (span->arrayMask & SPAN_MASK) {
/* mask was initialized by caller, probably glBitmap */
span->writeAll = GL_FALSE;
}
else {
MEMSET(span->array->mask, 1, span->end);
span->writeAll = GL_TRUE;
}
 
/* Clipping */
if ((swrast->_RasterMask & CLIP_BIT) || (span->primitive != GL_POLYGON)) {
if (!clip_span(ctx, span)) {
return;
}
}
 
#ifdef DEBUG
if (span->arrayMask & SPAN_XY) {
GLuint i;
for (i = 0; i < span->end; i++) {
if (span->array->mask[i]) {
assert(span->array->x[i] >= ctx->DrawBuffer->_Xmin);
assert(span->array->x[i] < ctx->DrawBuffer->_Xmax);
assert(span->array->y[i] >= ctx->DrawBuffer->_Ymin);
assert(span->array->y[i] < ctx->DrawBuffer->_Ymax);
}
}
}
#endif
 
/* Polygon Stippling */
if (ctx->Polygon.StippleFlag && span->primitive == GL_POLYGON) {
stipple_polygon_span(ctx, span);
}
 
/* Need texture coordinates now */
if ((span->interpMask & SPAN_TEXTURE)
&& (span->arrayMask & SPAN_TEXTURE) == 0)
interpolate_texcoords(ctx, span);
 
/* Texture with alpha test */
if (ctx->Color.AlphaEnabled) {
 
/* Now we need the rgba array, fill it in if needed */
if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
interpolate_colors(ctx, span);
 
/* Texturing without alpha is done after depth-testing which
* gives a potential speed-up.
*/
_swrast_texture_span( ctx, span );
 
/* Do the alpha test */
if (!_mesa_alpha_test(ctx, span)) {
span->arrayMask = origArrayMask;
return;
}
}
 
/* Stencil and Z testing */
if (ctx->Stencil.Enabled || ctx->Depth.Test) {
if (span->interpMask & SPAN_Z)
_mesa_span_interpolate_z(ctx, span);
 
if (ctx->Stencil.Enabled) {
if (!_mesa_stencil_and_ztest_span(ctx, span)) {
span->arrayMask = origArrayMask;
return;
}
}
else {
ASSERT(ctx->Depth.Test);
ASSERT(span->arrayMask & SPAN_Z);
/* regular depth testing */
if (!_mesa_depth_test_span(ctx, span)) {
span->arrayMask = origArrayMask;
return;
}
}
}
 
/* if we get here, some fragments passed the depth test */
ctx->OcclusionResult = GL_TRUE;
 
/* We had to wait until now to check for glColorMask(F,F,F,F) because of
* the occlusion test.
*/
if (colorMask == 0x0) {
span->arrayMask = origArrayMask;
return;
}
 
/* Texture without alpha test */
if (!ctx->Color.AlphaEnabled) {
 
/* Now we need the rgba array, fill it in if needed */
if ((span->interpMask & SPAN_RGBA) && (span->arrayMask & SPAN_RGBA) == 0)
interpolate_colors(ctx, span);
 
_swrast_texture_span( ctx, span );
}
 
ASSERT(span->arrayMask & SPAN_RGBA);
 
/* Add base and specular colors */
if (ctx->Fog.ColorSumEnabled ||
(ctx->Light.Enabled &&
ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) {
if (span->interpMask & SPAN_SPEC) {
interpolate_specular(ctx, span);
}
ASSERT(span->arrayMask & SPAN_SPEC);
add_colors( span->end, span->array->rgba, span->array->spec );
}
 
/* Fog */
if (ctx->Fog.Enabled) {
_mesa_fog_rgba_span(ctx, span);
}
 
/* Antialias coverage application */
if (span->arrayMask & SPAN_COVERAGE) {
GLchan (*rgba)[4] = span->array->rgba;
GLfloat *coverage = span->array->coverage;
GLuint i;
for (i = 0; i < span->end; i++) {
rgba[i][ACOMP] = (GLchan) (rgba[i][ACOMP] * coverage[i]);
}
}
 
if (swrast->_RasterMask & MULTI_DRAW_BIT) {
multi_write_rgba_span(ctx, span);
}
else {
/* normal: write to exactly one buffer */
if (ctx->Color.ColorLogicOpEnabled) {
_mesa_logicop_rgba_span(ctx, span, span->array->rgba);
}
else if (ctx->Color.BlendEnabled) {
_mesa_blend_span(ctx, span, span->array->rgba);
}
 
if (colorMask != 0xffffffff) {
_mesa_mask_rgba_span(ctx, span, span->array->rgba);
}
 
if (span->arrayMask & SPAN_XY) {
/* array of pixel coords */
(*swrast->Driver.WriteRGBAPixels)(ctx, span->end, span->array->x,
span->array->y, (const GLchan (*)[4]) span->array->rgba, span->array->mask);
if (SWRAST_CONTEXT(ctx)->_RasterMask & ALPHABUF_BIT) {
_mesa_write_alpha_pixels(ctx, span->end,
span->array->x, span->array->y,
(const GLchan (*)[4]) span->array->rgba,
span->array->mask);
}
}
else {
/* horizontal run of pixels */
(*swrast->Driver.WriteRGBASpan)(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) span->array->rgba,
span->writeAll ? NULL : span->array->mask);
if (swrast->_RasterMask & ALPHABUF_BIT) {
_mesa_write_alpha_span(ctx, span->end, span->x, span->y,
(const GLchan (*)[4]) span->array->rgba,
span->writeAll ? NULL : span->array->mask);
}
}
}
 
span->arrayMask = origArrayMask;
}
 
 
 
/**
* Read RGBA pixels from frame buffer. Clipping will be done to prevent
* reading ouside the buffer's boundaries.
*/
void
_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
GLuint n, GLint x, GLint y, GLchan rgba[][4] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint bufWidth = (GLint) buffer->Width;
const GLint bufHeight = (GLint) buffer->Height;
 
if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
/* completely above, below, or right */
/* XXX maybe leave undefined? */
_mesa_bzero(rgba, 4 * n * sizeof(GLchan));
}
else {
GLint skip, length;
if (x < 0) {
/* left edge clippping */
skip = -x;
length = (GLint) n - skip;
if (length < 0) {
/* completely left of window */
return;
}
if (length > bufWidth) {
length = bufWidth;
}
}
else if ((GLint) (x + n) > bufWidth) {
/* right edge clipping */
skip = 0;
length = bufWidth - x;
if (length < 0) {
/* completely to right of window */
return;
}
}
else {
/* no clipping */
skip = 0;
length = (GLint) n;
}
 
(*swrast->Driver.ReadRGBASpan)( ctx, length, x + skip, y, rgba + skip );
if (buffer->UseSoftwareAlphaBuffers) {
_mesa_read_alpha_span(ctx, length, x + skip, y, rgba + skip);
}
}
}
 
 
/**
* Read CI pixels from frame buffer. Clipping will be done to prevent
* reading ouside the buffer's boundaries.
*/
void
_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer,
GLuint n, GLint x, GLint y, GLuint indx[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLint bufWidth = (GLint) buffer->Width;
const GLint bufHeight = (GLint) buffer->Height;
 
if (y < 0 || y >= bufHeight || x + (GLint) n < 0 || x >= bufWidth) {
/* completely above, below, or right */
_mesa_bzero(indx, n * sizeof(GLuint));
}
else {
GLint skip, length;
if (x < 0) {
/* left edge clippping */
skip = -x;
length = (GLint) n - skip;
if (length < 0) {
/* completely left of window */
return;
}
if (length > bufWidth) {
length = bufWidth;
}
}
else if ((GLint) (x + n) > bufWidth) {
/* right edge clipping */
skip = 0;
length = bufWidth - x;
if (length < 0) {
/* completely to right of window */
return;
}
}
else {
/* no clipping */
skip = 0;
length = (GLint) n;
}
 
(*swrast->Driver.ReadCI32Span)( ctx, length, skip + x, y, indx + skip );
}
}
/shark/trunk/ports/mesa/src/swrast/s_histogram.h
0,0 → 1,41
/* $Id: s_histogram.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef S_HISTOGRAM_H
#define S_HISTOGRAM_H
 
#include "mtypes.h"
#include "swrast.h"
 
extern void
_mesa_update_minmax(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]);
 
extern void
_mesa_update_histogram(GLcontext *ctx, GLuint n, const GLfloat rgba[][4]);
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_depth.c
0,0 → 1,1682
/* $Id: s_depth.c,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "imports.h"
 
#include "s_depth.h"
#include "s_context.h"
 
 
/**
* Return address of depth buffer value for given window coord.
*/
GLvoid *
_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y)
{
if (ctx->Visual.depthBits <= 16)
return (GLushort *) ctx->DrawBuffer->DepthBuffer
+ ctx->DrawBuffer->Width * y + x;
else
return (GLuint *) ctx->DrawBuffer->DepthBuffer
+ ctx->DrawBuffer->Width * y + x;
}
 
 
#define Z_ADDRESS16( CTX, X, Y ) \
( ((GLushort *) (CTX)->DrawBuffer->DepthBuffer) \
+ (CTX)->DrawBuffer->Width * (Y) + (X) )
 
#define Z_ADDRESS32( CTX, X, Y ) \
( ((GLuint *) (CTX)->DrawBuffer->DepthBuffer) \
+ (CTX)->DrawBuffer->Width * (Y) + (X) )
 
 
 
/**********************************************************************/
/***** Depth Testing Functions *****/
/**********************************************************************/
 
 
/*
* Do depth test for an array of fragments. This is used both for
* software and hardware Z buffers.
* Input: zbuffer - array of z values in the zbuffer
* z - array of fragment z values
* Return: number of fragments which pass the test.
*/
static GLuint
depth_test_span16( GLcontext *ctx, GLuint n,
GLushort zbuffer[], const GLdepth z[], GLubyte mask[] )
{
GLuint passed = 0;
 
/* switch cases ordered from most frequent to less frequent */
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
/* pass */
zbuffer[i] = z[i];
passed++;
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
zbuffer[i] = z[i];
passed++;
}
}
}
else {
/* Don't update Z buffer or mask */
passed = n;
}
break;
case GL_NEVER:
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in depth_test_span16");
}
 
return passed;
}
 
 
static GLuint
depth_test_span32( GLcontext *ctx, GLuint n,
GLuint zbuffer[], const GLdepth z[], GLubyte mask[] )
{
GLuint passed = 0;
 
/* switch cases ordered from most frequent to less frequent */
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
/* pass */
zbuffer[i] = z[i];
passed++;
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
zbuffer[i] = z[i];
passed++;
}
else {
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
/* pass */
passed++;
}
else {
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0;i<n;i++) {
if (mask[i]) {
zbuffer[i] = z[i];
passed++;
}
}
}
else {
/* Don't update Z buffer or mask */
passed = n;
}
break;
case GL_NEVER:
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in depth_test_span32");
}
 
return passed;
}
 
 
 
/*
* Apply depth test to span of fragments. Hardware or software z buffer.
*/
static GLuint
depth_test_span( GLcontext *ctx, struct sw_span *span)
{
const GLint x = span->x;
const GLint y = span->y;
const GLuint n = span->end;
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
ASSERT((span->arrayMask & SPAN_XY) == 0);
ASSERT(span->arrayMask & SPAN_Z);
if (swrast->Driver.ReadDepthSpan) {
/* hardware-based depth buffer */
GLdepth zbuffer[MAX_WIDTH];
GLuint passed;
(*swrast->Driver.ReadDepthSpan)(ctx, n, x, y, zbuffer);
passed = depth_test_span32(ctx, n, zbuffer, span->array->z,
span->array->mask);
ASSERT(swrast->Driver.WriteDepthSpan);
(*swrast->Driver.WriteDepthSpan)(ctx, n, x, y, zbuffer,
span->array->mask);
if (passed < n)
span->writeAll = GL_FALSE;
return passed;
}
else {
GLuint passed;
/* software depth buffer */
if (ctx->Visual.depthBits <= 16) {
GLushort *zptr = (GLushort *) Z_ADDRESS16(ctx, x, y);
passed = depth_test_span16(ctx, n, zptr, span->array->z, span->array->mask);
}
else {
GLuint *zptr = (GLuint *) Z_ADDRESS32(ctx, x, y);
passed = depth_test_span32(ctx, n, zptr, span->array->z, span->array->mask);
}
#if 1
if (passed < span->end) {
span->writeAll = GL_FALSE;
}
#else
/* this causes a glDrawPixels(GL_DEPTH_COMPONENT) conformance failure */
if (passed < span->end) {
span->writeAll = GL_FALSE;
if (passed == 0) {
span->end = 0;
return 0;
}
while (span->end > 0 && span->mask[span->end - 1] == 0)
span->end --;
}
#endif
return passed;
}
}
 
 
 
 
/*
* Do depth testing for an array of fragments using software Z buffer.
*/
static void
software_depth_test_pixels16( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
const GLdepth z[], GLubyte mask[] )
{
/* switch cases ordered from most frequent to less frequent */
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] < *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] < *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] > *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] > *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] != *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] != *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] == *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
if (z[i] == *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLushort *zptr = Z_ADDRESS16(ctx,x[i],y[i]);
*zptr = z[i];
}
}
}
else {
/* Don't update Z buffer or mask */
}
break;
case GL_NEVER:
/* depth test never passes */
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
}
}
 
 
 
/*
* Do depth testing for an array of fragments using software Z buffer.
*/
static void
software_depth_test_pixels32( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
const GLdepth z[], GLubyte mask[] )
{
/* switch cases ordered from most frequent to less frequent */
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] < *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] < *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] <= *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] >= *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] > *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] > *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] != *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] != *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] == *zptr) {
/* pass */
*zptr = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
if (z[i] == *zptr) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
GLuint *zptr = Z_ADDRESS32(ctx,x[i],y[i]);
*zptr = z[i];
}
}
}
else {
/* Don't update Z buffer or mask */
}
break;
case GL_NEVER:
/* depth test never passes */
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in software_depth_test_pixels");
}
}
 
 
 
/*
* Do depth testing for an array of pixels using hardware Z buffer.
* Input/output: zbuffer - array of depth values from Z buffer
* Input: z - array of fragment z values.
*/
static void
hardware_depth_test_pixels( GLcontext *ctx, GLuint n, GLdepth zbuffer[],
const GLdepth z[], GLubyte mask[] )
{
/* switch cases ordered from most frequent to less frequent */
switch (ctx->Depth.Func) {
case GL_LESS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
/* pass */
zbuffer[i] = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] < zbuffer[i]) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_LEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
/* pass */
zbuffer[i] = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] <= zbuffer[i]) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_GEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
/* pass */
zbuffer[i] = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] >= zbuffer[i]) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_GREATER:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
/* pass */
zbuffer[i] = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] > zbuffer[i]) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_NOTEQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
/* pass */
zbuffer[i] = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] != zbuffer[i]) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_EQUAL:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
/* pass */
zbuffer[i] = z[i];
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
else {
/* Don't update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
if (z[i] == zbuffer[i]) {
/* pass */
}
else {
/* fail */
mask[i] = 0;
}
}
}
}
break;
case GL_ALWAYS:
if (ctx->Depth.Mask) {
/* Update Z buffer */
GLuint i;
for (i=0; i<n; i++) {
if (mask[i]) {
zbuffer[i] = z[i];
}
}
}
else {
/* Don't update Z buffer or mask */
}
break;
case GL_NEVER:
/* depth test never passes */
_mesa_bzero(mask, n * sizeof(GLubyte));
break;
default:
_mesa_problem(ctx, "Bad depth func in hardware_depth_test_pixels");
}
}
 
 
 
static GLuint
depth_test_pixels( GLcontext *ctx, struct sw_span *span )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLuint n = span->end;
const GLint *x = span->array->x;
const GLint *y = span->array->y;
const GLdepth *z = span->array->z;
GLubyte *mask = span->array->mask;
 
if (swrast->Driver.ReadDepthPixels) {
/* read depth values from hardware Z buffer */
GLdepth zbuffer[MAX_WIDTH];
(*swrast->Driver.ReadDepthPixels)(ctx, n, x, y, zbuffer);
 
hardware_depth_test_pixels( ctx, n, zbuffer, z, mask );
 
/* update hardware Z buffer with new values */
assert(swrast->Driver.WriteDepthPixels);
(*swrast->Driver.WriteDepthPixels)(ctx, n, x, y, zbuffer, mask );
}
else {
/* software depth testing */
if (ctx->Visual.depthBits <= 16)
software_depth_test_pixels16(ctx, n, x, y, z, mask);
else
software_depth_test_pixels32(ctx, n, x, y, z, mask);
}
return n; /* not really correct, but OK */
}
 
 
/**
* Apply depth (Z) buffer testing to the span.
* \return approx number of pixels that passed (only zero is reliable)
*/
GLuint
_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span)
{
if (span->arrayMask & SPAN_XY)
return depth_test_pixels(ctx, span);
else
return depth_test_span(ctx, span);
}
 
 
 
/**********************************************************************/
/***** Read Depth Buffer *****/
/**********************************************************************/
 
 
/**
* Read a span of depth values from the depth buffer.
* This function does clipping before calling the device driver function.
*/
void
_mesa_read_depth_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLdepth depth[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
 
if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
/* span is completely outside framebuffer */
GLint i;
for (i = 0; i < n; i++)
depth[i] = 0;
return;
}
 
if (x < 0) {
GLint dx = -x;
GLint i;
for (i = 0; i < dx; i++)
depth[i] = 0;
x = 0;
n -= dx;
depth += dx;
}
if (x + n > (GLint) ctx->DrawBuffer->Width) {
GLint dx = x + n - (GLint) ctx->DrawBuffer->Width;
GLint i;
for (i = 0; i < dx; i++)
depth[n - i - 1] = 0;
n -= dx;
}
if (n <= 0) {
return;
}
 
if (ctx->DrawBuffer->DepthBuffer) {
/* read from software depth buffer */
if (ctx->Visual.depthBits <= 16) {
const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
GLint i;
for (i = 0; i < n; i++) {
depth[i] = zptr[i];
}
}
else {
const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
GLint i;
for (i = 0; i < n; i++) {
depth[i] = zptr[i];
}
}
}
else if (swrast->Driver.ReadDepthSpan) {
/* read from hardware depth buffer */
(*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, depth );
}
else {
/* no depth buffer */
_mesa_bzero(depth, n * sizeof(GLfloat));
}
 
}
 
 
 
 
/**
* Return a span of depth values from the depth buffer as floats in [0,1].
* This is used for both hardware and software depth buffers.
* Input: n - how many pixels
* x,y - location of first pixel
* Output: depth - the array of depth values
*/
void
_mesa_read_depth_span_float( GLcontext *ctx,
GLint n, GLint x, GLint y, GLfloat depth[] )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLfloat scale = 1.0F / ctx->DepthMaxF;
 
if (y < 0 || y >= (GLint) ctx->DrawBuffer->Height ||
x + (GLint) n <= 0 || x >= (GLint) ctx->DrawBuffer->Width) {
/* span is completely outside framebuffer */
GLint i;
for (i = 0; i < n; i++)
depth[i] = 0.0F;
return;
}
 
if (x < 0) {
GLint dx = -x;
GLint i;
for (i = 0; i < dx; i++)
depth[i] = 0.0F;
n -= dx;
x = 0;
}
if (x + n > (GLint) ctx->DrawBuffer->Width) {
GLint dx = x + n - (GLint) ctx->DrawBuffer->Width;
GLint i;
for (i = 0; i < dx; i++)
depth[n - i - 1] = 0.0F;
n -= dx;
}
if (n <= 0) {
return;
}
 
if (ctx->DrawBuffer->DepthBuffer) {
/* read from software depth buffer */
if (ctx->Visual.depthBits <= 16) {
const GLushort *zptr = Z_ADDRESS16( ctx, x, y );
GLint i;
for (i = 0; i < n; i++) {
depth[i] = (GLfloat) zptr[i] * scale;
}
}
else {
const GLuint *zptr = Z_ADDRESS32( ctx, x, y );
GLint i;
for (i = 0; i < n; i++) {
depth[i] = (GLfloat) zptr[i] * scale;
}
}
}
else if (swrast->Driver.ReadDepthSpan) {
/* read from hardware depth buffer */
GLdepth d[MAX_WIDTH];
GLint i;
assert(n <= MAX_WIDTH);
(*swrast->Driver.ReadDepthSpan)( ctx, n, x, y, d );
for (i = 0; i < n; i++) {
depth[i] = d[i] * scale;
}
}
else {
/* no depth buffer */
_mesa_bzero(depth, n * sizeof(GLfloat));
}
}
 
 
 
/**********************************************************************/
/***** Allocate and Clear Depth Buffer *****/
/**********************************************************************/
 
 
 
/**
* Allocate a new depth buffer. If there's already a depth buffer allocated
* it will be free()'d. The new depth buffer will be uniniitalized.
* This function is only called through Driver.alloc_depth_buffer.
*/
void
_mesa_alloc_depth_buffer( GLframebuffer *buffer )
{
GLint bytesPerValue;
 
ASSERT(buffer->UseSoftwareDepthBuffer);
 
/* deallocate current depth buffer if present */
if (buffer->DepthBuffer) {
MESA_PBUFFER_FREE(buffer->DepthBuffer);
buffer->DepthBuffer = NULL;
}
 
/* allocate new depth buffer, but don't initialize it */
if (buffer->Visual.depthBits <= 16)
bytesPerValue = sizeof(GLushort);
else
bytesPerValue = sizeof(GLuint);
 
buffer->DepthBuffer = MESA_PBUFFER_ALLOC(buffer->Width * buffer->Height
* bytesPerValue);
 
if (!buffer->DepthBuffer) {
/* out of memory */
GET_CURRENT_CONTEXT(ctx);
if (ctx) {
ctx->Depth.Test = GL_FALSE;
ctx->NewState |= _NEW_DEPTH;
_mesa_error(ctx, GL_OUT_OF_MEMORY, "Couldn't allocate depth buffer");
}
}
}
 
 
/**
* Clear the depth buffer. If the depth buffer doesn't exist yet we'll
* allocate it now.
* This function is only called through Driver.clear_depth_buffer.
*/
void
_mesa_clear_depth_buffer( GLcontext *ctx )
{
if (ctx->Visual.depthBits == 0
|| !ctx->DrawBuffer->DepthBuffer
|| !ctx->Depth.Mask) {
/* no depth buffer, or writing to it is disabled */
return;
}
 
/* The loops in this function have been written so the IRIX 5.3
* C compiler can unroll them. Hopefully other compilers can too!
*/
 
if (ctx->Scissor.Enabled) {
/* only clear scissor region */
if (ctx->Visual.depthBits <= 16) {
const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax);
const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
const GLint rowStride = ctx->DrawBuffer->Width;
GLushort *dRow = (GLushort *) ctx->DrawBuffer->DepthBuffer
+ ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin;
GLint i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
dRow[j] = clearValue;
}
dRow += rowStride;
}
}
else {
const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax);
const GLint rows = ctx->DrawBuffer->_Ymax - ctx->DrawBuffer->_Ymin;
const GLint cols = ctx->DrawBuffer->_Xmax - ctx->DrawBuffer->_Xmin;
const GLint rowStride = ctx->DrawBuffer->Width;
GLuint *dRow = (GLuint *) ctx->DrawBuffer->DepthBuffer
+ ctx->DrawBuffer->_Ymin * rowStride + ctx->DrawBuffer->_Xmin;
GLint i, j;
for (i = 0; i < rows; i++) {
for (j = 0; j < cols; j++) {
dRow[j] = clearValue;
}
dRow += rowStride;
}
}
}
else {
/* clear whole buffer */
if (ctx->Visual.depthBits <= 16) {
const GLushort clearValue = (GLushort) (ctx->Depth.Clear * ctx->DepthMax);
if ((clearValue & 0xff) == (clearValue >> 8)) {
if (clearValue == 0) {
_mesa_bzero(ctx->DrawBuffer->DepthBuffer,
2*ctx->DrawBuffer->Width*ctx->DrawBuffer->Height);
}
else {
/* lower and upper bytes of clear_value are same, use MEMSET */
MEMSET( ctx->DrawBuffer->DepthBuffer, clearValue & 0xff,
2 * ctx->DrawBuffer->Width * ctx->DrawBuffer->Height);
}
}
else {
GLushort *d = (GLushort *) ctx->DrawBuffer->DepthBuffer;
GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
while (n >= 16) {
d[0] = clearValue; d[1] = clearValue;
d[2] = clearValue; d[3] = clearValue;
d[4] = clearValue; d[5] = clearValue;
d[6] = clearValue; d[7] = clearValue;
d[8] = clearValue; d[9] = clearValue;
d[10] = clearValue; d[11] = clearValue;
d[12] = clearValue; d[13] = clearValue;
d[14] = clearValue; d[15] = clearValue;
d += 16;
n -= 16;
}
while (n > 0) {
*d++ = clearValue;
n--;
}
}
}
else {
/* >16 bit depth buffer */
const GLuint clearValue = (GLuint) (ctx->Depth.Clear * ctx->DepthMax);
if (clearValue == 0) {
_mesa_bzero(ctx->DrawBuffer->DepthBuffer,
ctx->DrawBuffer->Width*ctx->DrawBuffer->Height*sizeof(GLuint));
}
else {
GLint n = ctx->DrawBuffer->Width * ctx->DrawBuffer->Height;
GLuint *d = (GLuint *) ctx->DrawBuffer->DepthBuffer;
while (n >= 16) {
d[0] = clearValue; d[1] = clearValue;
d[2] = clearValue; d[3] = clearValue;
d[4] = clearValue; d[5] = clearValue;
d[6] = clearValue; d[7] = clearValue;
d[8] = clearValue; d[9] = clearValue;
d[10] = clearValue; d[11] = clearValue;
d[12] = clearValue; d[13] = clearValue;
d[14] = clearValue; d[15] = clearValue;
d += 16;
n -= 16;
}
while (n > 0) {
*d++ = clearValue;
n--;
}
}
}
}
}
/shark/trunk/ports/mesa/src/swrast/s_triangle.c
0,0 → 1,1224
/* $Id: s_triangle.c,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 5.0
*
* 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.
*/
 
 
/*
* When the device driver doesn't implement triangle rasterization it
* can hook in _swrast_Triangle, which eventually calls one of these
* functions to draw triangles.
*/
 
#include "glheader.h"
#include "context.h"
#include "colormac.h"
#include "imports.h"
#include "macros.h"
#include "mmath.h"
#include "texformat.h"
#include "teximage.h"
#include "texstate.h"
 
#include "s_aatriangle.h"
#include "s_context.h"
#include "s_depth.h"
#include "s_feedback.h"
#include "s_span.h"
#include "s_triangle.h"
 
 
/*
* Just used for feedback mode.
*/
GLboolean _mesa_cull_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
GLfloat ex = v1->win[0] - v0->win[0];
GLfloat ey = v1->win[1] - v0->win[1];
GLfloat fx = v2->win[0] - v0->win[0];
GLfloat fy = v2->win[1] - v0->win[1];
GLfloat c = ex*fy-ey*fx;
 
if (c * SWRAST_CONTEXT(ctx)->_backface_sign > 0)
return 0;
 
return 1;
}
 
 
 
/*
* Render a flat-shaded color index triangle.
*/
static void flat_ci_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
#define INTERP_Z 1
#define INTERP_FOG 1
 
#define SETUP_CODE \
span.interpMask |= SPAN_INDEX; \
span.index = IntToFixed(v2->index); \
span.indexStep = 0;
 
#define RENDER_SPAN( span ) _mesa_write_index_span(ctx, &span);
 
#include "s_tritemp.h"
}
 
 
 
/*
* Render a smooth-shaded color index triangle.
*/
static void smooth_ci_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
#define INTERP_Z 1
#define INTERP_FOG 1
#define INTERP_INDEX 1
 
#define RENDER_SPAN( span ) _mesa_write_index_span(ctx, &span);
 
#include "s_tritemp.h"
}
 
 
 
/*
* Render a flat-shaded RGBA triangle.
*/
static void flat_rgba_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
#define INTERP_Z 1
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 
#define SETUP_CODE \
ASSERT(ctx->Texture._EnabledUnits == 0); \
ASSERT(ctx->Light.ShadeModel==GL_FLAT); \
span.interpMask |= SPAN_RGBA; \
span.red = ChanToFixed(v2->color[0]); \
span.green = ChanToFixed(v2->color[1]); \
span.blue = ChanToFixed(v2->color[2]); \
span.alpha = ChanToFixed(v2->color[3]); \
span.redStep = 0; \
span.greenStep = 0; \
span.blueStep = 0; \
span.alphaStep = 0;
 
#define RENDER_SPAN( span ) _mesa_write_rgba_span(ctx, &span);
 
#include "s_tritemp.h"
}
 
 
 
/*
* Render a smooth-shaded RGBA triangle.
*/
static void smooth_rgba_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
 
#define INTERP_Z 1
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_ALPHA 1
 
#define SETUP_CODE \
{ \
/* texturing must be off */ \
ASSERT(ctx->Texture._EnabledUnits == 0); \
ASSERT(ctx->Light.ShadeModel==GL_SMOOTH); \
}
 
#define RENDER_SPAN( span ) _mesa_write_rgba_span(ctx, &span);
 
#include "s_tritemp.h"
 
}
 
 
/*
* Render an RGB, GL_DECAL, textured triangle.
* Interpolate S,T only w/out mipmapping or perspective correction.
*
* No fog.
*/
static void simple_textured_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
#define INTERP_INT_TEX 1
#define S_SCALE twidth
#define T_SCALE theight
 
#define SETUP_CODE \
SWcontext *swrast = SWRAST_CONTEXT(ctx); \
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
const GLint b = obj->BaseLevel; \
const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
const GLfloat theight = (GLfloat) obj->Image[b]->Height; \
const GLint twidth_log2 = obj->Image[b]->WidthLog2; \
const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \
const GLint smask = obj->Image[b]->Width - 1; \
const GLint tmask = obj->Image[b]->Height - 1; \
if (!texture) { \
/* this shouldn't happen */ \
return; \
}
 
#define RENDER_SPAN( span ) \
GLuint i; \
span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \
span.intTex[1] -= FIXED_HALF; \
for (i = 0; i < span.end; i++) { \
GLint s = FixedToInt(span.intTex[0]) & smask; \
GLint t = FixedToInt(span.intTex[1]) & tmask; \
GLint pos = (t << twidth_log2) + s; \
pos = pos + pos + pos; /* multiply by 3 */ \
span.array->rgb[i][RCOMP] = texture[pos]; \
span.array->rgb[i][GCOMP] = texture[pos+1]; \
span.array->rgb[i][BCOMP] = texture[pos+2]; \
span.intTex[0] += span.intTexStep[0]; \
span.intTex[1] += span.intTexStep[1]; \
} \
(*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, \
(CONST GLchan (*)[3]) span.array->rgb,\
NULL );
 
#include "s_tritemp.h"
}
 
 
/*
* Render an RGB, GL_DECAL, textured triangle.
* Interpolate S,T, GL_LESS depth test, w/out mipmapping or
* perspective correction.
*
* No fog.
*/
static void simple_z_textured_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
#define INTERP_Z 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_INT_TEX 1
#define S_SCALE twidth
#define T_SCALE theight
 
#define SETUP_CODE \
SWcontext *swrast = SWRAST_CONTEXT(ctx); \
struct gl_texture_object *obj = ctx->Texture.Unit[0].Current2D; \
const GLint b = obj->BaseLevel; \
const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
const GLfloat theight = (GLfloat) obj->Image[b]->Height; \
const GLint twidth_log2 = obj->Image[b]->WidthLog2; \
const GLchan *texture = (const GLchan *) obj->Image[b]->Data; \
const GLint smask = obj->Image[b]->Width - 1; \
const GLint tmask = obj->Image[b]->Height - 1; \
if (!texture) { \
/* this shouldn't happen */ \
return; \
}
 
#define RENDER_SPAN( span ) \
GLuint i; \
span.intTex[0] -= FIXED_HALF; /* off-by-one error? */ \
span.intTex[1] -= FIXED_HALF; \
for (i = 0; i < span.end; i++) { \
const GLdepth z = FixedToDepth(span.z); \
if (z < zRow[i]) { \
GLint s = FixedToInt(span.intTex[0]) & smask; \
GLint t = FixedToInt(span.intTex[1]) & tmask; \
GLint pos = (t << twidth_log2) + s; \
pos = pos + pos + pos; /* multiply by 3 */ \
span.array->rgb[i][RCOMP] = texture[pos]; \
span.array->rgb[i][GCOMP] = texture[pos+1]; \
span.array->rgb[i][BCOMP] = texture[pos+2]; \
zRow[i] = z; \
span.array->mask[i] = 1; \
} \
else { \
span.array->mask[i] = 0; \
} \
span.intTex[0] += span.intTexStep[0]; \
span.intTex[1] += span.intTexStep[1]; \
span.z += span.zStep; \
} \
(*swrast->Driver.WriteRGBSpan)(ctx, span.end, span.x, span.y, \
(CONST GLchan (*)[3]) span.array->rgb,\
span.array->mask );
 
#include "s_tritemp.h"
}
 
 
#if CHAN_TYPE != GL_FLOAT
 
struct affine_info
{
GLenum filter;
GLenum format;
GLenum envmode;
GLint smask, tmask;
GLint twidth_log2;
const GLchan *texture;
GLfixed er, eg, eb, ea;
GLint tbytesline, tsize;
};
 
 
/* This function can handle GL_NEAREST or GL_LINEAR sampling of 2D RGB or RGBA
* textures with GL_REPLACE, GL_MODULATE, GL_BLEND, GL_DECAL or GL_ADD
* texture env modes.
*/
static INLINE void
affine_span(GLcontext *ctx, struct sw_span *span,
struct affine_info *info)
{
GLchan sample[4]; /* the filtered texture sample */
 
/* Instead of defining a function for each mode, a test is done
* between the outer and inner loops. This is to reduce code size
* and complexity. Observe that an optimizing compiler kills
* unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
*/
 
#define NEAREST_RGB \
sample[RCOMP] = tex00[RCOMP]; \
sample[GCOMP] = tex00[GCOMP]; \
sample[BCOMP] = tex00[BCOMP]; \
sample[ACOMP] = CHAN_MAX
 
#define LINEAR_RGB \
sample[RCOMP] = (ti * (si * tex00[0] + sf * tex01[0]) + \
tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT; \
sample[GCOMP] = (ti * (si * tex00[1] + sf * tex01[1]) + \
tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT; \
sample[BCOMP] = (ti * (si * tex00[2] + sf * tex01[2]) + \
tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT; \
sample[ACOMP] = CHAN_MAX
 
#define NEAREST_RGBA COPY_CHAN4(sample, tex00)
 
#define LINEAR_RGBA \
sample[RCOMP] = (ti * (si * tex00[0] + sf * tex01[0]) + \
tf * (si * tex10[0] + sf * tex11[0])) >> 2 * FIXED_SHIFT;\
sample[GCOMP] = (ti * (si * tex00[1] + sf * tex01[1]) + \
tf * (si * tex10[1] + sf * tex11[1])) >> 2 * FIXED_SHIFT;\
sample[BCOMP] = (ti * (si * tex00[2] + sf * tex01[2]) + \
tf * (si * tex10[2] + sf * tex11[2])) >> 2 * FIXED_SHIFT;\
sample[ACOMP] = (ti * (si * tex00[3] + sf * tex01[3]) + \
tf * (si * tex10[3] + sf * tex11[3])) >> 2 * FIXED_SHIFT
 
#define MODULATE \
dest[RCOMP] = span->red * (sample[RCOMP] + 1u) >> (FIXED_SHIFT + 8); \
dest[GCOMP] = span->green * (sample[GCOMP] + 1u) >> (FIXED_SHIFT + 8); \
dest[BCOMP] = span->blue * (sample[BCOMP] + 1u) >> (FIXED_SHIFT + 8); \
dest[ACOMP] = span->alpha * (sample[ACOMP] + 1u) >> (FIXED_SHIFT + 8)
 
#define DECAL \
dest[RCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->red + \
((sample[ACOMP] + 1) * sample[RCOMP] << FIXED_SHIFT)) \
>> (FIXED_SHIFT + 8); \
dest[GCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->green + \
((sample[ACOMP] + 1) * sample[GCOMP] << FIXED_SHIFT)) \
>> (FIXED_SHIFT + 8); \
dest[BCOMP] = ((CHAN_MAX - sample[ACOMP]) * span->blue + \
((sample[ACOMP] + 1) * sample[BCOMP] << FIXED_SHIFT)) \
>> (FIXED_SHIFT + 8); \
dest[ACOMP] = FixedToInt(span->alpha)
 
#define BLEND \
dest[RCOMP] = ((CHAN_MAX - sample[RCOMP]) * span->red \
+ (sample[RCOMP] + 1) * info->er) >> (FIXED_SHIFT + 8); \
dest[GCOMP] = ((CHAN_MAX - sample[GCOMP]) * span->green \
+ (sample[GCOMP] + 1) * info->eg) >> (FIXED_SHIFT + 8); \
dest[BCOMP] = ((CHAN_MAX - sample[BCOMP]) * span->blue \
+ (sample[BCOMP] + 1) * info->eb) >> (FIXED_SHIFT + 8); \
dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8)
 
#define REPLACE COPY_CHAN4(dest, sample)
 
#define ADD \
{ \
GLint rSum = FixedToInt(span->red) + (GLint) sample[RCOMP]; \
GLint gSum = FixedToInt(span->green) + (GLint) sample[GCOMP]; \
GLint bSum = FixedToInt(span->blue) + (GLint) sample[BCOMP]; \
dest[RCOMP] = MIN2(rSum, CHAN_MAX); \
dest[GCOMP] = MIN2(gSum, CHAN_MAX); \
dest[BCOMP] = MIN2(bSum, CHAN_MAX); \
dest[ACOMP] = span->alpha * (sample[ACOMP] + 1) >> (FIXED_SHIFT + 8); \
}
 
/* shortcuts */
 
#define NEAREST_RGB_REPLACE \
NEAREST_RGB; \
dest[0] = sample[0]; \
dest[1] = sample[1]; \
dest[2] = sample[2]; \
dest[3] = FixedToInt(span->alpha);
 
#define NEAREST_RGBA_REPLACE COPY_CHAN4(dest, tex00)
 
#define SPAN_NEAREST(DO_TEX,COMP) \
for (i = 0; i < span->end; i++) { \
/* Isn't it necessary to use FixedFloor below?? */ \
GLint s = FixedToInt(span->intTex[0]) & info->smask; \
GLint t = FixedToInt(span->intTex[1]) & info->tmask; \
GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
DO_TEX; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
span->alpha += span->alphaStep; \
span->intTex[0] += span->intTexStep[0]; \
span->intTex[1] += span->intTexStep[1]; \
dest += 4; \
}
 
#define SPAN_LINEAR(DO_TEX,COMP) \
for (i = 0; i < span->end; i++) { \
/* Isn't it necessary to use FixedFloor below?? */ \
GLint s = FixedToInt(span->intTex[0]) & info->smask; \
GLint t = FixedToInt(span->intTex[1]) & info->tmask; \
GLfixed sf = span->intTex[0] & FIXED_FRAC_MASK; \
GLfixed tf = span->intTex[1] & FIXED_FRAC_MASK; \
GLfixed si = FIXED_FRAC_MASK - sf; \
GLfixed ti = FIXED_FRAC_MASK - tf; \
GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
const GLchan *tex10 = tex00 + info->tbytesline; \
const GLchan *tex01 = tex00 + COMP; \
const GLchan *tex11 = tex10 + COMP; \
(void) ti; \
(void) si; \
if (t == info->tmask) { \
tex10 -= info->tsize; \
tex11 -= info->tsize; \
} \
if (s == info->smask) { \
tex01 -= info->tbytesline; \
tex11 -= info->tbytesline; \
} \
DO_TEX; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
span->alpha += span->alphaStep; \
span->intTex[0] += span->intTexStep[0]; \
span->intTex[1] += span->intTexStep[1]; \
dest += 4; \
}
 
 
GLuint i;
GLchan *dest = span->array->rgba[0];
 
span->intTex[0] -= FIXED_HALF;
span->intTex[1] -= FIXED_HALF;
switch (info->filter) {
case GL_NEAREST:
switch (info->format) {
case GL_RGB:
switch (info->envmode) {
case GL_MODULATE:
SPAN_NEAREST(NEAREST_RGB;MODULATE,3);
break;
case GL_DECAL:
case GL_REPLACE:
SPAN_NEAREST(NEAREST_RGB_REPLACE,3);
break;
case GL_BLEND:
SPAN_NEAREST(NEAREST_RGB;BLEND,3);
break;
case GL_ADD:
SPAN_NEAREST(NEAREST_RGB;ADD,3);
break;
default:
_mesa_problem(ctx, "bad tex env mode in SPAN_LINEAR");
return;
}
break;
case GL_RGBA:
switch(info->envmode) {
case GL_MODULATE:
SPAN_NEAREST(NEAREST_RGBA;MODULATE,4);
break;
case GL_DECAL:
SPAN_NEAREST(NEAREST_RGBA;DECAL,4);
break;
case GL_BLEND:
SPAN_NEAREST(NEAREST_RGBA;BLEND,4);
break;
case GL_ADD:
SPAN_NEAREST(NEAREST_RGBA;ADD,4);
break;
case GL_REPLACE:
SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
break;
default:
_mesa_problem(ctx, "bad tex env mode (2) in SPAN_LINEAR");
return;
}
break;
}
break;
 
case GL_LINEAR:
span->intTex[0] -= FIXED_HALF;
span->intTex[1] -= FIXED_HALF;
switch (info->format) {
case GL_RGB:
switch (info->envmode) {
case GL_MODULATE:
SPAN_LINEAR(LINEAR_RGB;MODULATE,3);
break;
case GL_DECAL:
case GL_REPLACE:
SPAN_LINEAR(LINEAR_RGB;REPLACE,3);
break;
case GL_BLEND:
SPAN_LINEAR(LINEAR_RGB;BLEND,3);
break;
case GL_ADD:
SPAN_LINEAR(LINEAR_RGB;ADD,3);
break;
default:
_mesa_problem(ctx, "bad tex env mode (3) in SPAN_LINEAR");
return;
}
break;
case GL_RGBA:
switch (info->envmode) {
case GL_MODULATE:
SPAN_LINEAR(LINEAR_RGBA;MODULATE,4);
break;
case GL_DECAL:
SPAN_LINEAR(LINEAR_RGBA;DECAL,4);
break;
case GL_BLEND:
SPAN_LINEAR(LINEAR_RGBA;BLEND,4);
break;
case GL_ADD:
SPAN_LINEAR(LINEAR_RGBA;ADD,4);
break;
case GL_REPLACE:
SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
break;
default:
_mesa_problem(ctx, "bad tex env mode (4) in SPAN_LINEAR");
return;
}
break;
}
break;
}
span->interpMask &= ~SPAN_RGBA;
ASSERT(span->arrayMask & SPAN_RGBA);
_mesa_write_rgba_span(ctx, span);
 
#undef SPAN_NEAREST
#undef SPAN_LINEAR
}
 
 
 
/*
* Render an RGB/RGBA textured triangle without perspective correction.
*/
static void affine_textured_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
#define INTERP_Z 1
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_INT_TEX 1
#define S_SCALE twidth
#define T_SCALE theight
 
#define SETUP_CODE \
struct affine_info info; \
struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
struct gl_texture_object *obj = unit->Current2D; \
const GLint b = obj->BaseLevel; \
const GLfloat twidth = (GLfloat) obj->Image[b]->Width; \
const GLfloat theight = (GLfloat) obj->Image[b]->Height; \
info.texture = (const GLchan *) obj->Image[b]->Data; \
info.twidth_log2 = obj->Image[b]->WidthLog2; \
info.smask = obj->Image[b]->Width - 1; \
info.tmask = obj->Image[b]->Height - 1; \
info.format = obj->Image[b]->Format; \
info.filter = obj->MinFilter; \
info.envmode = unit->EnvMode; \
span.arrayMask |= SPAN_RGBA; \
\
if (info.envmode == GL_BLEND) { \
/* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \
info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \
info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \
info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \
info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \
} \
if (!info.texture) { \
/* this shouldn't happen */ \
return; \
} \
\
switch (info.format) { \
case GL_ALPHA: \
case GL_LUMINANCE: \
case GL_INTENSITY: \
info.tbytesline = obj->Image[b]->Width; \
break; \
case GL_LUMINANCE_ALPHA: \
info.tbytesline = obj->Image[b]->Width * 2; \
break; \
case GL_RGB: \
info.tbytesline = obj->Image[b]->Width * 3; \
break; \
case GL_RGBA: \
info.tbytesline = obj->Image[b]->Width * 4; \
break; \
default: \
_mesa_problem(NULL, "Bad texture format in affine_texture_triangle");\
return; \
} \
info.tsize = obj->Image[b]->Height * info.tbytesline;
 
#define RENDER_SPAN( span ) affine_span(ctx, &span, &info);
 
#include "s_tritemp.h"
 
}
 
 
 
struct persp_info
{
GLenum filter;
GLenum format;
GLenum envmode;
GLint smask, tmask;
GLint twidth_log2;
const GLchan *texture;
GLfixed er, eg, eb, ea; /* texture env color */
GLint tbytesline, tsize;
};
 
 
static INLINE void
fast_persp_span(GLcontext *ctx, struct sw_span *span,
struct persp_info *info)
{
GLchan sample[4]; /* the filtered texture sample */
 
/* Instead of defining a function for each mode, a test is done
* between the outer and inner loops. This is to reduce code size
* and complexity. Observe that an optimizing compiler kills
* unused variables (for instance tf,sf,ti,si in case of GL_NEAREST).
*/
#define SPAN_NEAREST(DO_TEX,COMP) \
for (i = 0; i < span->end; i++) { \
GLdouble invQ = tex_coord[2] ? \
(1.0 / tex_coord[2]) : 1.0; \
GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \
GLint s = IFLOOR(s_tmp) & info->smask; \
GLint t = IFLOOR(t_tmp) & info->tmask; \
GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
DO_TEX; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
span->alpha += span->alphaStep; \
tex_coord[0] += tex_step[0]; \
tex_coord[1] += tex_step[1]; \
tex_coord[2] += tex_step[2]; \
dest += 4; \
}
 
#define SPAN_LINEAR(DO_TEX,COMP) \
for (i = 0; i < span->end; i++) { \
GLdouble invQ = tex_coord[2] ? \
(1.0 / tex_coord[2]) : 1.0; \
GLfloat s_tmp = (GLfloat) (tex_coord[0] * invQ); \
GLfloat t_tmp = (GLfloat) (tex_coord[1] * invQ); \
GLfixed s_fix = FloatToFixed(s_tmp) - FIXED_HALF; \
GLfixed t_fix = FloatToFixed(t_tmp) - FIXED_HALF; \
GLint s = FixedToInt(FixedFloor(s_fix)) & info->smask; \
GLint t = FixedToInt(FixedFloor(t_fix)) & info->tmask; \
GLfixed sf = s_fix & FIXED_FRAC_MASK; \
GLfixed tf = t_fix & FIXED_FRAC_MASK; \
GLfixed si = FIXED_FRAC_MASK - sf; \
GLfixed ti = FIXED_FRAC_MASK - tf; \
GLint pos = (t << info->twidth_log2) + s; \
const GLchan *tex00 = info->texture + COMP * pos; \
const GLchan *tex10 = tex00 + info->tbytesline; \
const GLchan *tex01 = tex00 + COMP; \
const GLchan *tex11 = tex10 + COMP; \
(void) ti; \
(void) si; \
if (t == info->tmask) { \
tex10 -= info->tsize; \
tex11 -= info->tsize; \
} \
if (s == info->smask) { \
tex01 -= info->tbytesline; \
tex11 -= info->tbytesline; \
} \
DO_TEX; \
span->red += span->redStep; \
span->green += span->greenStep; \
span->blue += span->blueStep; \
span->alpha += span->alphaStep; \
tex_coord[0] += tex_step[0]; \
tex_coord[1] += tex_step[1]; \
tex_coord[2] += tex_step[2]; \
dest += 4; \
}
 
GLuint i;
GLfloat tex_coord[3], tex_step[3];
GLchan *dest = span->array->rgba[0];
 
tex_coord[0] = span->tex[0][0] * (info->smask + 1);
tex_step[0] = span->texStepX[0][0] * (info->smask + 1);
tex_coord[1] = span->tex[0][1] * (info->tmask + 1);
tex_step[1] = span->texStepX[0][1] * (info->tmask + 1);
/* span->tex[0][2] only if 3D-texturing, here only 2D */
tex_coord[2] = span->tex[0][3];
tex_step[2] = span->texStepX[0][3];
 
switch (info->filter) {
case GL_NEAREST:
switch (info->format) {
case GL_RGB:
switch (info->envmode) {
case GL_MODULATE:
SPAN_NEAREST(NEAREST_RGB;MODULATE,3);
break;
case GL_DECAL:
case GL_REPLACE:
SPAN_NEAREST(NEAREST_RGB_REPLACE,3);
break;
case GL_BLEND:
SPAN_NEAREST(NEAREST_RGB;BLEND,3);
break;
case GL_ADD:
SPAN_NEAREST(NEAREST_RGB;ADD,3);
break;
default:
_mesa_problem(ctx, "bad tex env mode (5) in SPAN_LINEAR");
return;
}
break;
case GL_RGBA:
switch(info->envmode) {
case GL_MODULATE:
SPAN_NEAREST(NEAREST_RGBA;MODULATE,4);
break;
case GL_DECAL:
SPAN_NEAREST(NEAREST_RGBA;DECAL,4);
break;
case GL_BLEND:
SPAN_NEAREST(NEAREST_RGBA;BLEND,4);
break;
case GL_ADD:
SPAN_NEAREST(NEAREST_RGBA;ADD,4);
break;
case GL_REPLACE:
SPAN_NEAREST(NEAREST_RGBA_REPLACE,4);
break;
default:
_mesa_problem(ctx, "bad tex env mode (6) in SPAN_LINEAR");
return;
}
break;
}
break;
 
case GL_LINEAR:
switch (info->format) {
case GL_RGB:
switch (info->envmode) {
case GL_MODULATE:
SPAN_LINEAR(LINEAR_RGB;MODULATE,3);
break;
case GL_DECAL:
case GL_REPLACE:
SPAN_LINEAR(LINEAR_RGB;REPLACE,3);
break;
case GL_BLEND:
SPAN_LINEAR(LINEAR_RGB;BLEND,3);
break;
case GL_ADD:
SPAN_LINEAR(LINEAR_RGB;ADD,3);
break;
default:
_mesa_problem(ctx, "bad tex env mode (7) in SPAN_LINEAR");
return;
}
break;
case GL_RGBA:
switch (info->envmode) {
case GL_MODULATE:
SPAN_LINEAR(LINEAR_RGBA;MODULATE,4);
break;
case GL_DECAL:
SPAN_LINEAR(LINEAR_RGBA;DECAL,4);
break;
case GL_BLEND:
SPAN_LINEAR(LINEAR_RGBA;BLEND,4);
break;
case GL_ADD:
SPAN_LINEAR(LINEAR_RGBA;ADD,4);
break;
case GL_REPLACE:
SPAN_LINEAR(LINEAR_RGBA;REPLACE,4);
break;
default:
_mesa_problem(ctx, "bad tex env mode (8) in SPAN_LINEAR");
return;
}
break;
}
break;
}
ASSERT(span->arrayMask & SPAN_RGBA);
_mesa_write_rgba_span(ctx, span);
 
#undef SPAN_NEAREST
#undef SPAN_LINEAR
}
 
 
/*
* Render an perspective corrected RGB/RGBA textured triangle.
* The Q (aka V in Mesa) coordinate must be zero such that the divide
* by interpolated Q/W comes out right.
*
*/
static void persp_textured_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
#define INTERP_Z 1
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1
 
#define SETUP_CODE \
struct persp_info info; \
const struct gl_texture_unit *unit = ctx->Texture.Unit+0; \
const struct gl_texture_object *obj = unit->Current2D; \
const GLint b = obj->BaseLevel; \
info.texture = (const GLchan *) obj->Image[b]->Data; \
info.twidth_log2 = obj->Image[b]->WidthLog2; \
info.smask = obj->Image[b]->Width - 1; \
info.tmask = obj->Image[b]->Height - 1; \
info.format = obj->Image[b]->Format; \
info.filter = obj->MinFilter; \
info.envmode = unit->EnvMode; \
\
if (info.envmode == GL_BLEND) { \
/* potential off-by-one error here? (1.0f -> 2048 -> 0) */ \
info.er = FloatToFixed(unit->EnvColor[RCOMP] * CHAN_MAXF); \
info.eg = FloatToFixed(unit->EnvColor[GCOMP] * CHAN_MAXF); \
info.eb = FloatToFixed(unit->EnvColor[BCOMP] * CHAN_MAXF); \
info.ea = FloatToFixed(unit->EnvColor[ACOMP] * CHAN_MAXF); \
} \
if (!info.texture) { \
/* this shouldn't happen */ \
return; \
} \
\
switch (info.format) { \
case GL_ALPHA: \
case GL_LUMINANCE: \
case GL_INTENSITY: \
info.tbytesline = obj->Image[b]->Width; \
break; \
case GL_LUMINANCE_ALPHA: \
info.tbytesline = obj->Image[b]->Width * 2; \
break; \
case GL_RGB: \
info.tbytesline = obj->Image[b]->Width * 3; \
break; \
case GL_RGBA: \
info.tbytesline = obj->Image[b]->Width * 4; \
break; \
default: \
_mesa_problem(NULL, "Bad texture format in persp_textured_triangle");\
return; \
} \
info.tsize = obj->Image[b]->Height * info.tbytesline;
 
#define RENDER_SPAN( span ) \
span.interpMask &= ~SPAN_RGBA; \
span.arrayMask |= SPAN_RGBA; \
fast_persp_span(ctx, &span, &info);
 
#include "s_tritemp.h"
 
}
 
 
#endif /* CHAN_BITS != GL_FLOAT */
 
 
 
/*
* Render a smooth-shaded, textured, RGBA triangle.
* Interpolate S,T,R with perspective correction, w/out mipmapping.
*/
static void general_textured_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
#define INTERP_Z 1
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_SPEC 1
#define INTERP_ALPHA 1
#define INTERP_TEX 1
 
#define RENDER_SPAN( span ) _mesa_write_texture_span(ctx, &span);
 
#include "s_tritemp.h"
}
 
 
 
/*
* This is the big one!
* Interpolate Z, RGB, Alpha, specular, fog, and N sets of texture coordinates.
* Yup, it's slow.
*/
static void
multitextured_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
 
#define INTERP_Z 1
#define INTERP_FOG 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
#define INTERP_RGB 1
#define INTERP_ALPHA 1
#define INTERP_SPEC 1
#define INTERP_MULTITEX 1
 
#define RENDER_SPAN( span ) _mesa_write_texture_span(ctx, &span);
 
#include "s_tritemp.h"
 
}
 
 
static void occlusion_zless_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
if (ctx->OcclusionResult) {
return;
}
 
#define DO_OCCLUSION_TEST
#define INTERP_Z 1
#define DEPTH_TYPE DEFAULT_SOFTWARE_DEPTH_TYPE
 
#define RENDER_SPAN( span ) \
GLuint i; \
for (i = 0; i < span.end; i++) { \
GLdepth z = FixedToDepth(span.z); \
if (z < zRow[i]) { \
ctx->OcclusionResult = GL_TRUE; \
return; \
} \
span.z += span.zStep; \
}
 
#include "s_tritemp.h"
}
 
static void nodraw_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
(void) (ctx && v0 && v1 && v2);
}
 
 
/*
* This is used when separate specular color is enabled, but not
* texturing. We add the specular color to the primary color,
* draw the triangle, then restore the original primary color.
* Inefficient, but seldom needed.
*/
void _swrast_add_spec_terms_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 )
{
SWvertex *ncv0 = (SWvertex *)v0; /* drop const qualifier */
SWvertex *ncv1 = (SWvertex *)v1;
SWvertex *ncv2 = (SWvertex *)v2;
#if CHAN_TYPE == GL_FLOAT
GLfloat rSum, gSum, bSum;
#else
GLint rSum, gSum, bSum;
#endif
GLchan c[3][4];
/* save original colors */
COPY_CHAN4( c[0], ncv0->color );
COPY_CHAN4( c[1], ncv1->color );
COPY_CHAN4( c[2], ncv2->color );
/* sum v0 */
rSum = ncv0->color[0] + ncv0->specular[0];
gSum = ncv0->color[1] + ncv0->specular[1];
bSum = ncv0->color[2] + ncv0->specular[2];
ncv0->color[0] = MIN2(rSum, CHAN_MAX);
ncv0->color[1] = MIN2(gSum, CHAN_MAX);
ncv0->color[2] = MIN2(bSum, CHAN_MAX);
/* sum v1 */
rSum = ncv1->color[0] + ncv1->specular[0];
gSum = ncv1->color[1] + ncv1->specular[1];
bSum = ncv1->color[2] + ncv1->specular[2];
ncv1->color[0] = MIN2(rSum, CHAN_MAX);
ncv1->color[1] = MIN2(gSum, CHAN_MAX);
ncv1->color[2] = MIN2(bSum, CHAN_MAX);
/* sum v2 */
rSum = ncv2->color[0] + ncv2->specular[0];
gSum = ncv2->color[1] + ncv2->specular[1];
bSum = ncv2->color[2] + ncv2->specular[2];
ncv2->color[0] = MIN2(rSum, CHAN_MAX);
ncv2->color[1] = MIN2(gSum, CHAN_MAX);
ncv2->color[2] = MIN2(bSum, CHAN_MAX);
/* draw */
SWRAST_CONTEXT(ctx)->SpecTriangle( ctx, ncv0, ncv1, ncv2 );
/* restore original colors */
COPY_CHAN4( ncv0->color, c[0] );
COPY_CHAN4( ncv1->color, c[1] );
COPY_CHAN4( ncv2->color, c[2] );
}
 
 
 
#ifdef DEBUG
 
/* record the current triangle function name */
const char *_mesa_triFuncName = NULL;
 
#define USE(triFunc) \
do { \
_mesa_triFuncName = #triFunc; \
/*printf("%s\n", _mesa_triFuncName);*/ \
swrast->Triangle = triFunc; \
} while (0)
 
#else
 
#define USE(triFunc) swrast->Triangle = triFunc;
 
#endif
 
 
 
 
/*
* Determine which triangle rendering function to use given the current
* rendering context.
*
* Please update the summary flag _SWRAST_NEW_TRIANGLE if you add or
* remove tests to this code.
*/
void
_swrast_choose_triangle( GLcontext *ctx )
{
SWcontext *swrast = SWRAST_CONTEXT(ctx);
const GLboolean rgbmode = ctx->Visual.rgbMode;
 
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode == GL_FRONT_AND_BACK) {
USE(nodraw_triangle);
return;
}
 
if (ctx->RenderMode==GL_RENDER) {
 
if (ctx->Polygon.SmoothFlag) {
_mesa_set_aa_triangle_function(ctx);
ASSERT(swrast->Triangle);
return;
}
 
if (ctx->Depth.OcclusionTest &&
ctx->Depth.Test &&
ctx->Depth.Mask == GL_FALSE &&
ctx->Depth.Func == GL_LESS &&
!ctx->Stencil.Enabled) {
if ((rgbmode &&
ctx->Color.ColorMask[0] == 0 &&
ctx->Color.ColorMask[1] == 0 &&
ctx->Color.ColorMask[2] == 0 &&
ctx->Color.ColorMask[3] == 0)
||
(!rgbmode && ctx->Color.IndexMask == 0)) {
USE(occlusion_zless_triangle);
return;
}
}
 
if (ctx->Texture._EnabledUnits) {
/* Ugh, we do a _lot_ of tests to pick the best textured tri func */
const struct gl_texture_object *texObj2D;
const struct gl_texture_image *texImg;
GLenum minFilter, magFilter, envMode;
GLint format;
texObj2D = ctx->Texture.Unit[0].Current2D;
texImg = texObj2D ? texObj2D->Image[texObj2D->BaseLevel] : NULL;
format = texImg ? texImg->TexFormat->MesaFormat : -1;
minFilter = texObj2D ? texObj2D->MinFilter : (GLenum) 0;
magFilter = texObj2D ? texObj2D->MagFilter : (GLenum) 0;
envMode = ctx->Texture.Unit[0].EnvMode;
 
/* First see if we can used an optimized 2-D texture function */
if (ctx->Texture._EnabledUnits == 1
&& ctx->Texture.Unit[0]._ReallyEnabled == TEXTURE_2D_BIT
&& texObj2D->WrapS==GL_REPEAT
&& texObj2D->WrapT==GL_REPEAT
&& texImg->Border==0
&& texImg->Width == texImg->RowStride
&& (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA)
&& minFilter == magFilter
&& ctx->Light.Model.ColorControl == GL_SINGLE_COLOR
&& ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) {
if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) {
if (minFilter == GL_NEAREST
&& format == MESA_FORMAT_RGB
&& (envMode == GL_REPLACE || envMode == GL_DECAL)
&& ((swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)
&& ctx->Depth.Func == GL_LESS
&& ctx->Depth.Mask == GL_TRUE)
|| swrast->_RasterMask == TEXTURE_BIT)
&& ctx->Polygon.StippleFlag == GL_FALSE) {
if (swrast->_RasterMask == (DEPTH_BIT | TEXTURE_BIT)) {
USE(simple_z_textured_triangle);
}
else {
USE(simple_textured_triangle);
}
}
else {
#if (CHAN_BITS == 16 || CHAN_BITS == 32)
USE(general_textured_triangle);
#else
USE(affine_textured_triangle);
#endif
}
}
else {
#if (CHAN_BITS == 16 || CHAN_BITS == 32)
USE(general_textured_triangle);
#else
USE(persp_textured_triangle);
#endif
}
}
else {
/* general case textured triangles */
if (ctx->Texture._EnabledUnits > 1) {
USE(multitextured_triangle);
}
else {
USE(general_textured_triangle);
}
}
}
else {
ASSERT(!ctx->Texture._EnabledUnits);
if (ctx->Light.ShadeModel==GL_SMOOTH) {
/* smooth shaded, no texturing, stippled or some raster ops */
if (rgbmode) {
USE(smooth_rgba_triangle);
}
else {
USE(smooth_ci_triangle);
}
}
else {
/* flat shaded, no texturing, stippled or some raster ops */
if (rgbmode) {
USE(flat_rgba_triangle);
}
else {
USE(flat_ci_triangle);
}
}
}
}
else if (ctx->RenderMode==GL_FEEDBACK) {
USE(_mesa_feedback_triangle);
}
else {
/* GL_SELECT mode */
USE(_mesa_select_triangle);
}
}
/shark/trunk/ports/mesa/src/swrast/s_texture.h
0,0 → 1,45
/* $Id: s_texture.h,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_TEXTURE_H
#define S_TEXTURE_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void
_swrast_choose_texture_sample_func( GLcontext *ctx,
GLuint texUnit,
const struct gl_texture_object *tObj );
 
 
extern void
_swrast_texture_span( GLcontext *ctx, struct sw_span *span );
 
#endif
/shark/trunk/ports/mesa/src/swrast/swrast.h
0,0 → 1,602
/* $Id: swrast.h,v 1.1 2003-02-28 11:49:44 pj Exp $ */
 
/*
* 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.
*
*/
 
/**
* \file swrast/swrast.h
* \brief Defines basic structures for sw_rasterizer.
* \author Keith Whitwell <keith@tungstengraphics.com>
*/
 
#ifndef SWRAST_H
#define SWRAST_H
 
#include "mtypes.h"
 
/**
* \struct SWvertex
* \brief Data-structure to handle vertices in the software rasterizer.
*
* The software rasterizer now uses this format for vertices. Thus a
* 'RasterSetup' stage or other translation is required between the
* tnl module and the swrast rasterization functions. This serves to
* isolate the swrast module from the internals of the tnl module, and
* improve its usefulness as a fallback mechanism for hardware
* drivers.
*
* Full software drivers:
* - Register the rastersetup and triangle functions from
* utils/software_helper.
* - On statechange, update the rasterization pointers in that module.
*
* Rasterization hardware drivers:
* - Keep native rastersetup.
* - Implement native twoside,offset and unfilled triangle setup.
* - Implement a translator from native vertices to swrast vertices.
* - On partial fallback (mix of accelerated and unaccelerated
* prims), call a pass-through function which translates native
* vertices to SWvertices and calls the appropriate swrast function.
* - On total fallback (vertex format insufficient for state or all
* primitives unaccelerated), hook in swrast_setup instead.
*/
typedef struct {
/** win[0], win[1] are the screen-coords of SWvertex. win[2] is the
* z-coord. what is win[3]? */
GLfloat win[4];
GLfloat texcoord[MAX_TEXTURE_UNITS][4];
GLchan color[4];
GLchan specular[4];
GLfloat fog;
GLuint index;
GLfloat pointSize;
} SWvertex;
 
 
/**
* \struct sw_span
* \brief Contains data for either a horizontal line or a set of
* pixels that are passed through a pipeline of functions before being
* drawn.
*
* The sw_span structure describes the colors, Z, fogcoord, texcoords,
* etc for either a horizontal run or a set of independent pixels. We
* can either specify a base/step to indicate interpolated values, or
* fill in arrays of values. The interpMask and arrayMask bitfields
* indicate which are active.
*
* With this structure it's easy to hand-off span rasterization to
* subroutines instead of doing it all inline in the triangle functions
* like we used to do.
* It also cleans up the local variable namespace a great deal.
*
* It would be interesting to experiment with multiprocessor rasterization
* with this structure. The triangle rasterizer could simply emit a
* stream of these structures which would be consumed by one or more
* span-processing threads which could run in parallel.
*/
 
 
/**
* \defgroup SpanFlags SPAN_XXX-flags
* Bitmasks to indicate which span_arrays need to be computed
* (sw_span::interpMask) or have already been filled
* (sw_span::arrayMask)
*/
/*@{*/
#define SPAN_RGBA 0x001
#define SPAN_SPEC 0x002
#define SPAN_INDEX 0x004
#define SPAN_Z 0x008
#define SPAN_FOG 0x010
#define SPAN_TEXTURE 0x020
#define SPAN_INT_TEXTURE 0x040
#define SPAN_LAMBDA 0x080
#define SPAN_COVERAGE 0x100
#define SPAN_FLAT 0x200 /**< flat shading? */
/** sw_span::arrayMask only - for span_arrays::x, span_arrays::y */
#define SPAN_XY 0x400
#define SPAN_MASK 0x800 /**< sw_span::arrayMask only */
/*@}*/
 
 
/**
* \struct span_arrays
* \brief Arrays of fragment values.
*
* These will either be computed from the x/xStep values above or
* filled in by glDraw/CopyPixels, etc.
*/
struct span_arrays {
GLchan rgb[MAX_WIDTH][3];
GLchan rgba[MAX_WIDTH][4];
GLuint index[MAX_WIDTH];
GLchan spec[MAX_WIDTH][4]; /* specular color */
GLint x[MAX_WIDTH]; /**< X/Y used for point/line rendering only */
GLint y[MAX_WIDTH]; /**< X/Y used for point/line rendering only */
GLdepth z[MAX_WIDTH];
GLfloat fog[MAX_WIDTH];
GLfloat texcoords[MAX_TEXTURE_UNITS][MAX_WIDTH][4];
GLfloat lambda[MAX_TEXTURE_UNITS][MAX_WIDTH];
GLfloat coverage[MAX_WIDTH];
 
/** This mask indicates if fragment is alive or culled */
GLubyte mask[MAX_WIDTH];
};
 
 
struct sw_span {
GLint x, y;
 
/** Only need to process pixels between start <= i < end */
/** At this time, start is always zero. */
GLuint start, end;
 
/** This flag indicates that mask[] array is effectively filled with ones */
GLboolean writeAll;
 
/** either GL_POLYGON, GL_LINE, GL_POLYGON, GL_BITMAP */
GLenum primitive;
 
/** 0 = front-facing span, 1 = back-facing span (for two-sided stencil) */
GLuint facing;
 
/**
* This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
* which of the x/xStep variables are relevant.
*/
GLuint interpMask;
 
#if CHAN_TYPE == GL_FLOAT
GLfloat red, redStep;
GLfloat green, greenStep;
GLfloat blue, blueStep;
GLfloat alpha, alphaStep;
GLfloat specRed, specRedStep;
GLfloat specGreen, specGreenStep;
GLfloat specBlue, specBlueStep;
#else /* CHAN_TYPE == GL_UNSIGNED_BYTE or GL_UNSIGNED SHORT */
GLfixed red, redStep;
GLfixed green, greenStep;
GLfixed blue, blueStep;
GLfixed alpha, alphaStep;
GLfixed specRed, specRedStep;
GLfixed specGreen, specGreenStep;
GLfixed specBlue, specBlueStep;
#endif
GLfixed index, indexStep;
GLfixed z, zStep;
GLfloat fog, fogStep;
GLfloat tex[MAX_TEXTURE_UNITS][4];
GLfloat texStepX[MAX_TEXTURE_UNITS][4];
GLfloat texStepY[MAX_TEXTURE_UNITS][4];
GLfixed intTex[2], intTexStep[2];
 
/**
* This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates
* which of the fragment arrays in the span_arrays struct are relevant.
*/
GLuint arrayMask;
 
/**
* We store the arrays of fragment values in a separate struct so
* that we can allocate sw_span structs on the stack without using
* a lot of memory. The span_arrays struct is about 400KB while the
* sw_span struct is only about 512 bytes.
*/
struct span_arrays *array;
};
 
 
#define INIT_SPAN(S, PRIMITIVE, END, INTERP_MASK, ARRAY_MASK) \
do { \
(S).primitive = (PRIMITIVE); \
(S).interpMask = (INTERP_MASK); \
(S).arrayMask = (ARRAY_MASK); \
(S).start = 0; \
(S).end = (END); \
(S).facing = 0; \
(S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \
} while (0)
 
 
 
struct swrast_device_driver;
 
 
/* These are the public-access functions exported from swrast.
*/
extern void
_swrast_alloc_buffers( GLframebuffer *buffer );
 
extern void
_swrast_use_read_buffer( GLcontext *ctx );
 
extern void
_swrast_use_draw_buffer( GLcontext *ctx );
 
extern GLboolean
_swrast_CreateContext( GLcontext *ctx );
 
extern void
_swrast_DestroyContext( GLcontext *ctx );
 
/* Get a (non-const) reference to the device driver struct for swrast.
*/
extern struct swrast_device_driver *
_swrast_GetDeviceDriverReference( GLcontext *ctx );
 
extern void
_swrast_Bitmap( GLcontext *ctx,
GLint px, GLint py,
GLsizei width, GLsizei height,
const struct gl_pixelstore_attrib *unpack,
const GLubyte *bitmap );
 
extern void
_swrast_CopyPixels( GLcontext *ctx,
GLint srcx, GLint srcy,
GLint destx, GLint desty,
GLsizei width, GLsizei height,
GLenum type );
 
extern void
_swrast_DrawPixels( GLcontext *ctx,
GLint x, GLint y,
GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
const GLvoid *pixels );
 
extern void
_swrast_ReadPixels( GLcontext *ctx,
GLint x, GLint y, GLsizei width, GLsizei height,
GLenum format, GLenum type,
const struct gl_pixelstore_attrib *unpack,
GLvoid *pixels );
 
extern void
_swrast_Clear( GLcontext *ctx, GLbitfield mask, GLboolean all,
GLint x, GLint y, GLint width, GLint height );
 
extern void
_swrast_Accum( GLcontext *ctx, GLenum op,
GLfloat value, GLint xpos, GLint ypos,
GLint width, GLint height );
 
 
extern void
_swrast_DrawBuffer( GLcontext *ctx, GLenum mode );
 
 
/* Reset the stipple counter
*/
extern void
_swrast_ResetLineStipple( GLcontext *ctx );
 
/* These will always render the correct point/line/triangle for the
* current state.
*
* For flatshaded primitives, the provoking vertex is the final one.
*/
extern void
_swrast_Point( GLcontext *ctx, const SWvertex *v );
 
extern void
_swrast_Line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 );
 
extern void
_swrast_Triangle( GLcontext *ctx, const SWvertex *v0,
const SWvertex *v1, const SWvertex *v2 );
 
extern void
_swrast_Quad( GLcontext *ctx,
const SWvertex *v0, const SWvertex *v1,
const SWvertex *v2, const SWvertex *v3);
 
extern void
_swrast_flush( GLcontext *ctx );
 
extern void
_swrast_render_primitive( GLcontext *ctx, GLenum mode );
 
extern void
_swrast_render_start( GLcontext *ctx );
 
extern void
_swrast_render_finish( GLcontext *ctx );
 
/* Tell the software rasterizer about core state changes.
*/
extern void
_swrast_InvalidateState( GLcontext *ctx, GLuint new_state );
 
/* Configure software rasterizer to match hardware rasterizer characteristics:
*/
extern void
_swrast_allow_vertex_fog( GLcontext *ctx, GLboolean value );
 
extern void
_swrast_allow_pixel_fog( GLcontext *ctx, GLboolean value );
 
/* Debug:
*/
extern void
_swrast_print_vertex( GLcontext *ctx, const SWvertex *v );
 
 
/*
* Imaging fallbacks (a better solution should be found, perhaps
* moving all the imaging fallback code to a new module)
*/
extern void
_swrast_CopyConvolutionFilter2D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width,
GLsizei height);
extern void
_swrast_CopyConvolutionFilter1D(GLcontext *ctx, GLenum target,
GLenum internalFormat,
GLint x, GLint y, GLsizei width);
extern void
_swrast_CopyColorSubTable( GLcontext *ctx,GLenum target, GLsizei start,
GLint x, GLint y, GLsizei width);
extern void
_swrast_CopyColorTable( GLcontext *ctx,
GLenum target, GLenum internalformat,
GLint x, GLint y, GLsizei width);
 
 
/*
* Texture fallbacks, Brian Paul. Could also live in a new module
* with the rest of the texture store fallbacks?
*/
extern void
_swrast_copy_teximage1d(GLcontext *ctx, GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLint border);
 
extern void
_swrast_copy_teximage2d(GLcontext *ctx, GLenum target, GLint level,
GLenum internalFormat,
GLint x, GLint y, GLsizei width, GLsizei height,
GLint border);
 
 
extern void
_swrast_copy_texsubimage1d(GLcontext *ctx, GLenum target, GLint level,
GLint xoffset, GLint x, GLint y, GLsizei width);
 
extern void
_swrast_copy_texsubimage2d(GLcontext *ctx,
GLenum target, GLint level,
GLint xoffset, GLint yoffset,
GLint x, GLint y, GLsizei width, GLsizei height);
 
extern void
_swrast_copy_texsubimage3d(GLcontext *ctx,
GLenum target, GLint level,
GLint xoffset, GLint yoffset, GLint zoffset,
GLint x, GLint y, GLsizei width, GLsizei height);
 
 
 
/* The driver interface for the software rasterizer.
* Unless otherwise noted, all functions are mandatory.
*/
struct swrast_device_driver {
 
void (*SetBuffer)( GLcontext *ctx, GLframebuffer *buffer, GLuint bufferBit);
/*
* Specifies the current buffer for span/pixel writing/reading.
* buffer indicates which window to write to / read from. Normally,
* this'll be the buffer currently bound to the context, but it doesn't
* have to be!
* bufferBit indicates which color buffer, one of:
* FRONT_LEFT_BIT - this buffer always exists
* BACK_LEFT_BIT - when double buffering
* FRONT_RIGHT_BIT - when using stereo
* BACK_RIGHT_BIT - when using stereo and double buffering
* AUXn_BIT - if aux buffers are implemented
*/
 
 
/***
*** Functions for synchronizing access to the framebuffer:
***/
 
void (*SpanRenderStart)(GLcontext *ctx);
void (*SpanRenderFinish)(GLcontext *ctx);
/* OPTIONAL.
*
* Called before and after all rendering operations, including DrawPixels,
* ReadPixels, Bitmap, span functions, and CopyTexImage, etc commands.
* These are a suitable place for grabbing/releasing hardware locks.
*
* NOTE: The swrast triangle/line/point routines *DO NOT* call
* these functions. Locking in that case must be organized by the
* driver by other mechanisms.
*/
 
/***
*** Functions for writing pixels to the frame buffer:
***/
 
void (*WriteRGBASpan)( const GLcontext *ctx,
GLuint n, GLint x, GLint y,
CONST GLchan rgba[][4], const GLubyte mask[] );
void (*WriteRGBSpan)( const GLcontext *ctx,
GLuint n, GLint x, GLint y,
CONST GLchan rgb[][3], const GLubyte mask[] );
/* Write a horizontal run of RGBA or RGB pixels.
* If mask is NULL, draw all pixels.
* If mask is not null, only draw pixel [i] when mask [i] is true.
*/
 
void (*WriteMonoRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLchan color[4], const GLubyte mask[] );
/* Write a horizontal run of RGBA pixels all with the same color.
*/
 
void (*WriteRGBAPixels)( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
CONST GLchan rgba[][4], const GLubyte mask[] );
/* Write array of RGBA pixels at random locations.
*/
 
void (*WriteMonoRGBAPixels)( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
const GLchan color[4], const GLubyte mask[] );
/* Write an array of mono-RGBA pixels at random locations.
*/
 
void (*WriteCI32Span)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLuint index[], const GLubyte mask[] );
void (*WriteCI8Span)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLubyte index[], const GLubyte mask[] );
/* Write a horizontal run of CI pixels. One function is for 32bpp
* indexes and the other for 8bpp pixels (the common case). You mus
* implement both for color index mode.
*/
 
void (*WriteMonoCISpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
GLuint colorIndex, const GLubyte mask[] );
/* Write a horizontal run of color index pixels using the color index
* last specified by the Index() function.
*/
 
void (*WriteCI32Pixels)( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
const GLuint index[], const GLubyte mask[] );
/*
* Write a random array of CI pixels.
*/
 
void (*WriteMonoCIPixels)( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLuint colorIndex, const GLubyte mask[] );
/* Write a random array of color index pixels using the color index
* last specified by the Index() function.
*/
 
 
/***
*** Functions to read pixels from frame buffer:
***/
 
void (*ReadCI32Span)( const GLcontext *ctx,
GLuint n, GLint x, GLint y, GLuint index[] );
/* Read a horizontal run of color index pixels.
*/
 
void (*ReadRGBASpan)( const GLcontext *ctx, GLuint n, GLint x, GLint y,
GLchan rgba[][4] );
/* Read a horizontal run of RGBA pixels.
*/
 
void (*ReadCI32Pixels)( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLuint indx[], const GLubyte mask[] );
/* Read a random array of CI pixels.
*/
 
void (*ReadRGBAPixels)( const GLcontext *ctx,
GLuint n, const GLint x[], const GLint y[],
GLchan rgba[][4], const GLubyte mask[] );
/* Read a random array of RGBA pixels.
*/
 
 
 
/***
*** For supporting hardware Z buffers:
*** Either ALL or NONE of these functions must be implemented!
*** NOTE that Each depth value is a 32-bit GLuint. If the depth
*** buffer is less than 32 bits deep then the extra upperbits are zero.
***/
 
void (*WriteDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLdepth depth[], const GLubyte mask[] );
/* Write a horizontal span of values into the depth buffer. Only write
* depth[i] value if mask[i] is nonzero.
*/
 
void (*ReadDepthSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
GLdepth depth[] );
/* Read a horizontal span of values from the depth buffer.
*/
 
 
void (*WriteDepthPixels)( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
const GLdepth depth[], const GLubyte mask[] );
/* Write an array of randomly positioned depth values into the
* depth buffer. Only write depth[i] value if mask[i] is nonzero.
*/
 
void (*ReadDepthPixels)( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
GLdepth depth[] );
/* Read an array of randomly positioned depth values from the depth buffer.
*/
 
 
 
/***
*** For supporting hardware stencil buffers:
*** Either ALL or NONE of these functions must be implemented!
***/
 
void (*WriteStencilSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
const GLstencil stencil[], const GLubyte mask[] );
/* Write a horizontal span of stencil values into the stencil buffer.
* If mask is NULL, write all stencil values.
* Else, only write stencil[i] if mask[i] is non-zero.
*/
 
void (*ReadStencilSpan)( GLcontext *ctx, GLuint n, GLint x, GLint y,
GLstencil stencil[] );
/* Read a horizontal span of stencil values from the stencil buffer.
*/
 
void (*WriteStencilPixels)( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
const GLstencil stencil[],
const GLubyte mask[] );
/* Write an array of stencil values into the stencil buffer.
* If mask is NULL, write all stencil values.
* Else, only write stencil[i] if mask[i] is non-zero.
*/
 
void (*ReadStencilPixels)( GLcontext *ctx, GLuint n,
const GLint x[], const GLint y[],
GLstencil stencil[] );
/* Read an array of stencil values from the stencil buffer.
*/
};
 
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_span.h
0,0 → 1,71
/* $Id: s_span.h,v 1.1 2003-02-28 11:49:42 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_SPAN_H
#define S_SPAN_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern void
_mesa_span_default_z( GLcontext *ctx, struct sw_span *span );
 
extern void
_mesa_span_interpolate_z( const GLcontext *ctx, struct sw_span *span );
 
extern void
_mesa_span_default_fog( GLcontext *ctx, struct sw_span *span );
 
extern void
_mesa_span_default_color( GLcontext *ctx, struct sw_span *span );
 
extern void
_mesa_span_default_texcoords( GLcontext *ctx, struct sw_span *span );
 
extern void
_mesa_write_index_span( GLcontext *ctx, struct sw_span *span);
 
 
extern void
_mesa_write_rgba_span( GLcontext *ctx, struct sw_span *span);
 
 
extern void
_mesa_write_texture_span( GLcontext *ctx, struct sw_span *span);
 
 
extern void
_mesa_read_rgba_span( GLcontext *ctx, GLframebuffer *buffer,
GLuint n, GLint x, GLint y, GLchan rgba[][4] );
 
extern void
_mesa_read_index_span( GLcontext *ctx, GLframebuffer *buffer,
GLuint n, GLint x, GLint y, GLuint indx[] );
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_depth.h
0,0 → 1,64
/* $Id: s_depth.h,v 1.1 2003-02-28 11:49:41 pj Exp $ */
 
/*
* 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.
*/
 
 
#ifndef S_DEPTH_H
#define S_DEPTH_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
extern GLvoid *
_mesa_zbuffer_address(GLcontext *ctx, GLint x, GLint y);
 
 
 
extern GLuint
_mesa_depth_test_span( GLcontext *ctx, struct sw_span *span);
 
 
 
extern void
_mesa_read_depth_span( GLcontext *ctx,
GLint n, GLint x, GLint y, GLdepth depth[] );
 
 
extern void
_mesa_read_depth_span_float( GLcontext *ctx, GLint n, GLint x, GLint y,
GLfloat depth[] );
 
 
extern void
_mesa_alloc_depth_buffer( GLframebuffer *buffer );
 
 
extern void
_mesa_clear_depth_buffer( GLcontext *ctx );
 
 
#endif
/shark/trunk/ports/mesa/src/swrast/s_triangle.h
0,0 → 1,55
/* $Id: s_triangle.h,v 1.1 2003-02-28 11:49:43 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
 
 
 
#ifndef S_TRIANGLES_H
#define S_TRIANGLES_H
 
 
#include "mtypes.h"
#include "swrast.h"
 
 
GLboolean _mesa_cull_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2);
 
 
void
_swrast_choose_triangle( GLcontext *ctx );
 
void
_swrast_add_spec_terms_triangle( GLcontext *ctx,
const SWvertex *v0,
const SWvertex *v1,
const SWvertex *v2 );
 
 
#endif
/shark/trunk/ports/mesa/src/array_cache/ac_context.c
0,0 → 1,315
/* $Id: ac_context.c,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
 
#include "glheader.h"
#include "macros.h"
#include "imports.h"
#include "mmath.h"
#include "mtypes.h"
 
#include "array_cache/ac_context.h"
 
 
/*
* Initialize the array fallbacks. That is, by default the fallback arrays
* point into the current vertex attribute values in ctx->Current.Attrib[]
*/
static void _ac_fallbacks_init( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *cl;
GLuint i;
 
cl = &ac->Fallback.Normal;
cl->Size = 3;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (void *) ctx->Current.Attrib[VERT_ATTRIB_NORMAL];
cl->Enabled = 1;
cl->Flags = CA_CLIENT_DATA; /* hack */
 
cl = &ac->Fallback.Color;
cl->Size = 4;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (void *) ctx->Current.Attrib[VERT_ATTRIB_COLOR0];
cl->Enabled = 1;
cl->Flags = CA_CLIENT_DATA; /* hack */
 
cl = &ac->Fallback.SecondaryColor;
cl->Size = 3;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (void *) ctx->Current.Attrib[VERT_ATTRIB_COLOR1];
cl->Enabled = 1;
cl->Flags = CA_CLIENT_DATA; /* hack */
 
cl = &ac->Fallback.FogCoord;
cl->Size = 1;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (void *) &ctx->Current.Attrib[VERT_ATTRIB_FOG];
cl->Enabled = 1;
cl->Flags = CA_CLIENT_DATA; /* hack */
 
cl = &ac->Fallback.Index;
cl->Size = 1;
cl->Type = GL_UNSIGNED_INT;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (void *) &ctx->Current.Index;
cl->Enabled = 1;
cl->Flags = CA_CLIENT_DATA; /* hack */
 
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
cl = &ac->Fallback.TexCoord[i];
cl->Size = 4;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (void *) ctx->Current.Attrib[VERT_ATTRIB_TEX0 + i];
cl->Enabled = 1;
cl->Flags = CA_CLIENT_DATA; /* hack */
}
 
cl = &ac->Fallback.EdgeFlag;
cl->Size = 1;
cl->Type = GL_UNSIGNED_BYTE;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (void *) &ctx->Current.EdgeFlag;
cl->Enabled = 1;
cl->Flags = CA_CLIENT_DATA; /* hack */
 
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
cl = &ac->Fallback.Attrib[i];
cl->Size = 4;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 0;
cl->Ptr = (void *) ctx->Current.Attrib[i];
cl->Enabled = 1;
cl->Flags = CA_CLIENT_DATA; /* hack */
}
}
 
 
/*
* Initialize the array cache pointers, types, strides, etc.
*/
static void _ac_cache_init( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *cl;
GLuint size = ctx->Const.MaxArrayLockSize + MAX_CLIPPED_VERTICES;
GLuint i;
 
cl = &ac->Cache.Vertex;
cl->Size = 4;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 4 * sizeof(GLfloat);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
 
cl = &ac->Cache.Normal;
cl->Size = 3;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 3 * sizeof(GLfloat);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
 
cl = &ac->Cache.Color;
cl->Size = 4;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 4 * sizeof(GLfloat);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
 
cl = &ac->Cache.SecondaryColor;
cl->Size = 3;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 4 * sizeof(GLfloat);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
 
cl = &ac->Cache.FogCoord;
cl->Size = 1;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = sizeof(GLfloat);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
 
cl = &ac->Cache.Index;
cl->Size = 1;
cl->Type = GL_UNSIGNED_INT;
cl->Stride = 0;
cl->StrideB = sizeof(GLuint);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
 
for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
cl = &ac->Cache.TexCoord[i];
cl->Size = 4;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 4 * sizeof(GLfloat);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
}
 
cl = &ac->Cache.EdgeFlag;
cl->Size = 1;
cl->Type = GL_UNSIGNED_BYTE;
cl->Stride = 0;
cl->StrideB = sizeof(GLubyte);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
 
for (i = 0 ; i < VERT_ATTRIB_MAX; i++) {
cl = &ac->Cache.Attrib[i];
cl->Size = 4;
cl->Type = GL_FLOAT;
cl->Stride = 0;
cl->StrideB = 4 * sizeof(GLfloat);
cl->Ptr = MALLOC( cl->StrideB * size );
cl->Enabled = 1;
cl->Flags = 0;
}
}
 
 
/* This storage used to hold translated client data if type or stride
* need to be fixed.
*/
static void _ac_elts_init( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
GLuint size = 1000;
 
ac->Elts = (GLuint *)MALLOC( sizeof(GLuint) * size );
ac->elt_size = size;
}
 
static void _ac_raw_init( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
GLuint i;
 
ac->Raw.Color = ac->Fallback.Color;
ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag;
ac->Raw.FogCoord = ac->Fallback.FogCoord;
ac->Raw.Index = ac->Fallback.Index;
ac->Raw.Normal = ac->Fallback.Normal;
ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor;
ac->Raw.Vertex = ctx->Array.Vertex;
 
ac->IsCached.Color = GL_FALSE;
ac->IsCached.EdgeFlag = GL_FALSE;
ac->IsCached.FogCoord = GL_FALSE;
ac->IsCached.Index = GL_FALSE;
ac->IsCached.Normal = GL_FALSE;
ac->IsCached.SecondaryColor = GL_FALSE;
ac->IsCached.Vertex = GL_FALSE;
 
for (i = 0 ; i < MAX_TEXTURE_UNITS ; i++) {
ac->Raw.TexCoord[i] = ac->Fallback.TexCoord[i];
ac->IsCached.TexCoord[i] = GL_FALSE;
}
 
for (i = 0 ; i < VERT_ATTRIB_MAX ; i++) {
ac->Raw.Attrib[i] = ac->Fallback.Attrib[i];
ac->IsCached.Attrib[i] = GL_FALSE;
}
}
 
GLboolean _ac_CreateContext( GLcontext *ctx )
{
ctx->acache_context = CALLOC(sizeof(ACcontext));
if (ctx->acache_context) {
_ac_cache_init( ctx );
_ac_fallbacks_init( ctx );
_ac_raw_init( ctx );
_ac_elts_init( ctx );
return GL_TRUE;
}
return GL_FALSE;
}
 
void _ac_DestroyContext( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
GLint i;
 
if (ac->Cache.Vertex.Ptr) FREE( ac->Cache.Vertex.Ptr );
if (ac->Cache.Normal.Ptr) FREE( ac->Cache.Normal.Ptr );
if (ac->Cache.Color.Ptr) FREE( ac->Cache.Color.Ptr );
if (ac->Cache.SecondaryColor.Ptr) FREE( ac->Cache.SecondaryColor.Ptr );
if (ac->Cache.EdgeFlag.Ptr) FREE( ac->Cache.EdgeFlag.Ptr );
if (ac->Cache.Index.Ptr) FREE( ac->Cache.Index.Ptr );
if (ac->Cache.FogCoord.Ptr) FREE( ac->Cache.FogCoord.Ptr );
 
for (i = 0; i < MAX_TEXTURE_UNITS; i++) {
if (ac->Cache.TexCoord[i].Ptr)
FREE( ac->Cache.TexCoord[i].Ptr );
}
 
for (i = 0; i < VERT_ATTRIB_MAX; i++) {
if (ac->Cache.Attrib[i].Ptr)
FREE( ac->Cache.Attrib[i].Ptr );
}
 
if (ac->Elts) FREE( ac->Elts );
 
/* Free the context structure itself */
FREE(ac);
ctx->acache_context = NULL;
}
 
void _ac_InvalidateState( GLcontext *ctx, GLuint new_state )
{
AC_CONTEXT(ctx)->NewState |= new_state;
AC_CONTEXT(ctx)->NewArrayState |= ctx->Array.NewState;
}
/shark/trunk/ports/mesa/src/array_cache/acache.h
0,0 → 1,133
/* $Id: acache.h,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
 
#ifndef _ARRAYCACHE_H
#define _ARRAYCACHE_H
 
#include "mtypes.h"
 
 
extern GLboolean
_ac_CreateContext( GLcontext *ctx );
 
extern void
_ac_DestroyContext( GLcontext *ctx );
 
extern void
_ac_InvalidateState( GLcontext *ctx, GLuint new_state );
 
extern struct gl_client_array *
_ac_import_vertex( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwritable,
GLboolean *writable );
 
extern struct gl_client_array *
_ac_import_normal( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLboolean reqwritable,
GLboolean *writable );
 
extern struct gl_client_array *
_ac_import_color( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwritable,
GLboolean *writable );
 
extern struct gl_client_array *
_ac_import_index( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLboolean reqwritable,
GLboolean *writable );
 
extern struct gl_client_array *
_ac_import_secondarycolor( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwritable,
GLboolean *writable );
 
extern struct gl_client_array *
_ac_import_fogcoord( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLboolean reqwritable,
GLboolean *writable );
 
extern struct gl_client_array *
_ac_import_edgeflag( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLboolean reqwritable,
GLboolean *writable );
 
extern struct gl_client_array *
_ac_import_texcoord( GLcontext *ctx,
GLuint unit,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwritable,
GLboolean *writable );
 
extern struct gl_client_array *
_ac_import_attrib( GLcontext *ctx,
GLuint index,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwritable,
GLboolean *writable );
 
 
/* Clients must call this function to validate state and set bounds
* before importing any data:
*/
extern void
_ac_import_range( GLcontext *ctx, GLuint start, GLuint count );
 
 
/* Additional convenience function:
*/
extern CONST void *
_ac_import_elements( GLcontext *ctx,
GLenum new_type,
GLuint count,
GLenum old_type,
CONST void *indices );
 
 
#endif
/shark/trunk/ports/mesa/src/array_cache/ac_context.h
0,0 → 1,100
/* $Id: ac_context.h,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
 
#ifndef _AC_CONTEXT_H
#define _AC_CONTEXT_H
 
#include "glheader.h"
#include "mtypes.h"
 
#include "array_cache/acache.h"
 
/* These are used to make the ctx->Current values look like
* arrays (with zero StrideB).
*/
struct ac_arrays {
struct gl_client_array Vertex;
struct gl_client_array Normal;
struct gl_client_array Color;
struct gl_client_array SecondaryColor;
struct gl_client_array FogCoord;
struct gl_client_array Index;
struct gl_client_array TexCoord[MAX_TEXTURE_UNITS];
struct gl_client_array EdgeFlag;
struct gl_client_array Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */
};
 
struct ac_array_pointers {
struct gl_client_array *Vertex;
struct gl_client_array *Normal;
struct gl_client_array *Color;
struct gl_client_array *SecondaryColor;
struct gl_client_array *FogCoord;
struct gl_client_array *Index;
struct gl_client_array *TexCoord[MAX_TEXTURE_UNITS];
struct gl_client_array *EdgeFlag;
struct gl_client_array *Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */
};
 
struct ac_array_flags {
GLboolean Vertex;
GLboolean Normal;
GLboolean Color;
GLboolean SecondaryColor;
GLboolean FogCoord;
GLboolean Index;
GLboolean TexCoord[MAX_TEXTURE_UNITS];
GLboolean EdgeFlag;
GLboolean Attrib[VERT_ATTRIB_MAX]; /* GL_NV_vertex_program */
};
 
 
typedef struct {
GLuint NewState; /* not needed? */
GLuint NewArrayState;
 
/* Facility for importing and caching array data:
*/
struct ac_arrays Fallback;
struct ac_arrays Cache;
struct ac_arrays Raw;
struct ac_array_flags IsCached;
GLuint start;
GLuint count;
 
/* Facility for importing element lists:
*/
GLuint *Elts;
GLuint elt_size;
 
} ACcontext;
 
#define AC_CONTEXT(ctx) ((ACcontext *)ctx->acache_context)
 
#endif
/shark/trunk/ports/mesa/src/array_cache/ac_import.c
0,0 → 1,929
/* $Id: ac_import.c,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* 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.
*
* Authors:
* Keith Whitwell <keith@tungstengraphics.com>
*/
 
#include "glheader.h"
#include "macros.h"
#include "imports.h"
#include "mmath.h"
#include "mtypes.h"
 
#include "math/m_translate.h"
#include "array_cache/ac_context.h"
#include "math/m_translate.h"
 
#define STRIDE_ARRAY( array, offset ) \
do { \
char *tmp = (char *) (array).Ptr; \
tmp += (offset) * (array).StrideB; \
(array).Ptr = tmp; \
} while (0)
 
/* Set the array pointer back to its source when the cached data is
* invalidated:
*/
 
static void reset_texcoord( GLcontext *ctx, GLuint unit )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (ctx->Array._Enabled & _NEW_ARRAY_TEXCOORD(unit)) {
ac->Raw.TexCoord[unit] = ctx->Array.TexCoord[unit];
STRIDE_ARRAY(ac->Raw.TexCoord[unit], ac->start);
}
else {
ac->Raw.TexCoord[unit] = ac->Fallback.TexCoord[unit];
 
if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][3] != 1.0)
ac->Raw.TexCoord[unit].Size = 4;
else if (ctx->Current.Attrib[VERT_ATTRIB_TEX0 + unit][2] != 0.0)
ac->Raw.TexCoord[unit].Size = 3;
else
ac->Raw.TexCoord[unit].Size = 2;
}
 
ac->IsCached.TexCoord[unit] = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_TEXCOORD(unit);
}
 
static void reset_vertex( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
ASSERT(ctx->Array.Vertex.Enabled
|| (ctx->VertexProgram.Enabled && ctx->Array.VertexAttrib[0].Enabled));
ac->Raw.Vertex = ctx->Array.Vertex;
STRIDE_ARRAY(ac->Raw.Vertex, ac->start);
ac->IsCached.Vertex = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_VERTEX;
}
 
 
static void reset_normal( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (ctx->Array._Enabled & _NEW_ARRAY_NORMAL) {
ac->Raw.Normal = ctx->Array.Normal;
STRIDE_ARRAY(ac->Raw.Normal, ac->start);
}
else {
ac->Raw.Normal = ac->Fallback.Normal;
}
 
ac->IsCached.Normal = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_NORMAL;
}
 
 
static void reset_color( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
 
if (ctx->Array._Enabled & _NEW_ARRAY_COLOR0) {
ac->Raw.Color = ctx->Array.Color;
STRIDE_ARRAY(ac->Raw.Color, ac->start);
}
else
ac->Raw.Color = ac->Fallback.Color;
 
ac->IsCached.Color = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_COLOR0;
}
 
 
static void reset_secondarycolor( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (ctx->Array._Enabled & _NEW_ARRAY_COLOR1) {
ac->Raw.SecondaryColor = ctx->Array.SecondaryColor;
STRIDE_ARRAY(ac->Raw.SecondaryColor, ac->start);
}
else
ac->Raw.SecondaryColor = ac->Fallback.SecondaryColor;
 
ac->IsCached.SecondaryColor = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_COLOR1;
}
 
 
static void reset_index( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (ctx->Array._Enabled & _NEW_ARRAY_INDEX) {
ac->Raw.Index = ctx->Array.Index;
STRIDE_ARRAY(ac->Raw.Index, ac->start);
}
else
ac->Raw.Index = ac->Fallback.Index;
 
ac->IsCached.Index = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_INDEX;
}
 
 
static void reset_fogcoord( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (ctx->Array._Enabled & _NEW_ARRAY_FOGCOORD) {
ac->Raw.FogCoord = ctx->Array.FogCoord;
STRIDE_ARRAY(ac->Raw.FogCoord, ac->start);
}
else
ac->Raw.FogCoord = ac->Fallback.FogCoord;
 
ac->IsCached.FogCoord = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_FOGCOORD;
}
 
 
static void reset_edgeflag( GLcontext *ctx )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (ctx->Array._Enabled & _NEW_ARRAY_EDGEFLAG) {
ac->Raw.EdgeFlag = ctx->Array.EdgeFlag;
STRIDE_ARRAY(ac->Raw.EdgeFlag, ac->start);
}
else
ac->Raw.EdgeFlag = ac->Fallback.EdgeFlag;
 
ac->IsCached.EdgeFlag = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_EDGEFLAG;
}
 
 
static void reset_attrib( GLcontext *ctx, GLuint index )
{
ACcontext *ac = AC_CONTEXT(ctx);
GLboolean fallback = GL_FALSE;
 
/*
* The 16 NV vertex attribute arrays have top priority. If one of those
* is not enabled, look if a corresponding conventional array is enabled.
* If nothing else, use the fallback (ctx->Current.Attrib) values.
*/
if (ctx->Array._Enabled & _NEW_ARRAY_ATTRIB(index)) {
ac->Raw.Attrib[index] = ctx->Array.VertexAttrib[index];
STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start);
}
else if (ctx->Array._Enabled & (1 << index)) {
/* use conventional vertex array if possible */
if (index == VERT_ATTRIB_POS) {
ac->Raw.Attrib[index] = ctx->Array.Vertex;
}
else if (index == VERT_ATTRIB_NORMAL) {
ac->Raw.Attrib[index] = ctx->Array.Normal;
}
else if (index == VERT_ATTRIB_COLOR0) {
ac->Raw.Attrib[index] = ctx->Array.Color;
}
else if (index == VERT_ATTRIB_COLOR1) {
ac->Raw.Attrib[index] = ctx->Array.SecondaryColor;
}
else if (index == VERT_ATTRIB_FOG) {
ac->Raw.Attrib[index] = ctx->Array.FogCoord;
}
else if (index >= VERT_ATTRIB_TEX0 && index <= VERT_ATTRIB_TEX7) {
GLuint unit = index - VERT_ATTRIB_TEX0;
ASSERT(unit < MAX_TEXTURE_UNITS);
ac->Raw.Attrib[index] = ctx->Array.TexCoord[unit];
}
else {
/* missing conventional array (vertex weight, for example) */
fallback = GL_TRUE;
}
if (!fallback)
STRIDE_ARRAY(ac->Raw.Attrib[index], ac->start);
}
else {
fallback = GL_TRUE;
}
 
if (fallback) {
/* fallback to ctx->Current.Attrib values */
ac->Raw.Attrib[index] = ac->Fallback.Attrib[index];
 
if (ctx->Current.Attrib[index][3] != 1.0)
ac->Raw.Attrib[index].Size = 4;
else if (ctx->Current.Attrib[index][2] != 0.0)
ac->Raw.Attrib[index].Size = 3;
else
ac->Raw.Attrib[index].Size = 2;
}
 
ac->IsCached.Attrib[index] = GL_FALSE;
ac->NewArrayState &= ~_NEW_ARRAY_ATTRIB(index);
}
 
 
/*
* Generic import function for color data
*/
static void import( GLcontext *ctx,
GLenum type,
struct gl_client_array *to,
struct gl_client_array *from )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (type == 0)
type = from->Type;
 
switch (type) {
case GL_FLOAT:
_math_trans_4f( (GLfloat (*)[4]) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
from->Size,
0,
ac->count - ac->start);
 
to->StrideB = 4 * sizeof(GLfloat);
to->Type = GL_FLOAT;
break;
case GL_UNSIGNED_BYTE:
_math_trans_4ub( (GLubyte (*)[4]) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
from->Size,
0,
ac->count - ac->start);
 
to->StrideB = 4 * sizeof(GLubyte);
to->Type = GL_UNSIGNED_BYTE;
break;
 
case GL_UNSIGNED_SHORT:
_math_trans_4us( (GLushort (*)[4]) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
from->Size,
0,
ac->count - ac->start);
 
to->StrideB = 4 * sizeof(GLushort);
to->Type = GL_UNSIGNED_SHORT;
break;
default:
ASSERT(0);
break;
}
}
 
 
 
/*
* Functions to import array ranges with specified types and strides.
* For example, if the vertex data is GLshort[2] and we want GLfloat[3]
* we'll use an import function to do the data conversion.
*/
 
static void import_texcoord( GLcontext *ctx, GLuint unit,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.TexCoord[unit];
struct gl_client_array *to = &ac->Cache.TexCoord[unit];
 
ASSERT(unit < ctx->Const.MaxTextureUnits);
 
/* Limited choices at this stage:
*/
ASSERT(type == GL_FLOAT);
ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
 
_math_trans_4f( (GLfloat (*)[4]) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
from->Size,
0,
ac->count - ac->start);
 
to->Size = from->Size;
to->StrideB = 4 * sizeof(GLfloat);
to->Type = GL_FLOAT;
ac->IsCached.TexCoord[unit] = GL_TRUE;
}
 
static void import_vertex( GLcontext *ctx,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.Vertex;
struct gl_client_array *to = &ac->Cache.Vertex;
 
/* Limited choices at this stage:
*/
ASSERT(type == GL_FLOAT);
ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
 
_math_trans_4f( (GLfloat (*)[4]) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
from->Size,
0,
ac->count - ac->start);
 
to->Size = from->Size;
to->StrideB = 4 * sizeof(GLfloat);
to->Type = GL_FLOAT;
ac->IsCached.Vertex = GL_TRUE;
}
 
static void import_normal( GLcontext *ctx,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.Normal;
struct gl_client_array *to = &ac->Cache.Normal;
 
/* Limited choices at this stage:
*/
ASSERT(type == GL_FLOAT);
ASSERT(stride == 3*sizeof(GLfloat) || stride == 0);
 
_math_trans_3f( (GLfloat (*)[3]) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
0,
ac->count - ac->start);
 
to->StrideB = 3 * sizeof(GLfloat);
to->Type = GL_FLOAT;
ac->IsCached.Normal = GL_TRUE;
}
 
static void import_color( GLcontext *ctx,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.Color;
struct gl_client_array *to = &ac->Cache.Color;
 
import( ctx, type, to, from );
ac->IsCached.Color = GL_TRUE;
}
 
static void import_index( GLcontext *ctx,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.Index;
struct gl_client_array *to = &ac->Cache.Index;
 
/* Limited choices at this stage:
*/
ASSERT(type == GL_UNSIGNED_INT);
ASSERT(stride == sizeof(GLuint) || stride == 0);
 
_math_trans_1ui( (GLuint *) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
0,
ac->count - ac->start);
 
to->StrideB = sizeof(GLuint);
to->Type = GL_UNSIGNED_INT;
ac->IsCached.Index = GL_TRUE;
}
 
static void import_secondarycolor( GLcontext *ctx,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.SecondaryColor;
struct gl_client_array *to = &ac->Cache.SecondaryColor;
 
import( ctx, type, to, from );
 
ac->IsCached.SecondaryColor = GL_TRUE;
}
 
static void import_fogcoord( GLcontext *ctx,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.FogCoord;
struct gl_client_array *to = &ac->Cache.FogCoord;
 
/* Limited choices at this stage:
*/
ASSERT(type == GL_FLOAT);
ASSERT(stride == sizeof(GLfloat) || stride == 0);
 
_math_trans_1f( (GLfloat *) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
0,
ac->count - ac->start);
 
to->StrideB = sizeof(GLfloat);
to->Type = GL_FLOAT;
ac->IsCached.FogCoord = GL_TRUE;
}
 
static void import_edgeflag( GLcontext *ctx,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.EdgeFlag;
struct gl_client_array *to = &ac->Cache.EdgeFlag;
 
/* Limited choices at this stage:
*/
ASSERT(type == GL_UNSIGNED_BYTE);
ASSERT(stride == sizeof(GLubyte) || stride == 0);
 
_math_trans_1ub( (GLubyte *) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
0,
ac->count - ac->start);
 
to->StrideB = sizeof(GLubyte);
to->Type = GL_UNSIGNED_BYTE;
ac->IsCached.EdgeFlag = GL_TRUE;
}
 
static void import_attrib( GLcontext *ctx, GLuint index,
GLenum type, GLuint stride )
{
ACcontext *ac = AC_CONTEXT(ctx);
struct gl_client_array *from = &ac->Raw.Attrib[index];
struct gl_client_array *to = &ac->Cache.Attrib[index];
 
ASSERT(index < VERT_ATTRIB_MAX);
 
/* Limited choices at this stage:
*/
ASSERT(type == GL_FLOAT);
ASSERT(stride == 4*sizeof(GLfloat) || stride == 0);
ASSERT(ac->count - ac->start < ctx->Const.MaxArrayLockSize);
 
_math_trans_4f( (GLfloat (*)[4]) to->Ptr,
from->Ptr,
from->StrideB,
from->Type,
from->Size,
0,
ac->count - ac->start);
 
to->Size = from->Size;
to->StrideB = 4 * sizeof(GLfloat);
to->Type = GL_FLOAT;
ac->IsCached.Attrib[index] = GL_TRUE;
}
 
 
 
/*
* Externals to request arrays with specific properties:
*/
 
 
struct gl_client_array *_ac_import_texcoord( GLcontext *ctx,
GLuint unit,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
ASSERT(unit < ctx->Const.MaxTextureUnits);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_TEXCOORD(unit))
reset_texcoord( ctx, unit );
 
/* Is the request impossible?
*/
if (reqsize != 0 && ac->Raw.TexCoord[unit].Size > (GLint) reqsize)
return 0;
 
/* Do we need to pull in a copy of the client data:
*/
if (ac->Raw.TexCoord[unit].Type != type ||
(reqstride != 0 && ac->Raw.TexCoord[unit].StrideB != (GLint)reqstride) ||
reqwriteable)
{
if (!ac->IsCached.TexCoord[unit])
import_texcoord(ctx, unit, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.TexCoord[unit];
}
else {
*writeable = GL_FALSE;
return &ac->Raw.TexCoord[unit];
}
}
 
struct gl_client_array *_ac_import_vertex( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_VERTEX)
reset_vertex( ctx );
 
/* Is the request impossible?
*/
if (reqsize != 0 && ac->Raw.Vertex.Size > (GLint) reqsize)
return 0;
 
/* Do we need to pull in a copy of the client data:
*/
if (ac->Raw.Vertex.Type != type ||
(reqstride != 0 && ac->Raw.Vertex.StrideB != (GLint) reqstride) ||
reqwriteable)
{
if (!ac->IsCached.Vertex)
import_vertex(ctx, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.Vertex;
}
else {
*writeable = GL_FALSE;
return &ac->Raw.Vertex;
}
}
 
struct gl_client_array *_ac_import_normal( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_NORMAL)
reset_normal( ctx );
 
/* Do we need to pull in a copy of the client data:
*/
if (ac->Raw.Normal.Type != type ||
(reqstride != 0 && ac->Raw.Normal.StrideB != (GLint) reqstride) ||
reqwriteable)
{
if (!ac->IsCached.Normal)
import_normal(ctx, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.Normal;
}
else {
*writeable = GL_FALSE;
return &ac->Raw.Normal;
}
}
 
struct gl_client_array *_ac_import_color( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_COLOR0)
reset_color( ctx );
 
/* Is the request impossible?
*/
if (reqsize != 0 && ac->Raw.Color.Size > (GLint) reqsize) {
return 0;
}
 
/* Do we need to pull in a copy of the client data:
*/
if ((type != 0 && ac->Raw.Color.Type != type) ||
(reqstride != 0 && ac->Raw.Color.StrideB != (GLint) reqstride) ||
reqwriteable)
{
if (!ac->IsCached.Color)
import_color(ctx, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.Color;
}
else {
*writeable = GL_FALSE;
return &ac->Raw.Color;
}
}
 
struct gl_client_array *_ac_import_index( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_INDEX)
reset_index( ctx );
 
 
/* Do we need to pull in a copy of the client data:
*/
if (ac->Raw.Index.Type != type ||
(reqstride != 0 && ac->Raw.Index.StrideB != (GLint) reqstride) ||
reqwriteable)
{
if (!ac->IsCached.Index)
import_index(ctx, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.Index;
}
else {
*writeable = GL_FALSE;
return &ac->Raw.Index;
}
}
 
struct gl_client_array *_ac_import_secondarycolor( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_COLOR1)
reset_secondarycolor( ctx );
 
/* Is the request impossible?
*/
if (reqsize != 0 && ac->Raw.SecondaryColor.Size > (GLint) reqsize)
return 0;
 
/* Do we need to pull in a copy of the client data:
*/
if ((type != 0 && ac->Raw.SecondaryColor.Type != type) ||
(reqstride != 0 && ac->Raw.SecondaryColor.StrideB != (GLint)reqstride) ||
reqwriteable)
{
if (!ac->IsCached.SecondaryColor)
import_secondarycolor(ctx, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.SecondaryColor;
}
else {
*writeable = GL_FALSE;
return &ac->Raw.SecondaryColor;
}
}
 
struct gl_client_array *_ac_import_fogcoord( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_FOGCOORD)
reset_fogcoord( ctx );
 
/* Do we need to pull in a copy of the client data:
*/
if (ac->Raw.FogCoord.Type != type ||
(reqstride != 0 && ac->Raw.FogCoord.StrideB != (GLint) reqstride) ||
reqwriteable)
{
if (!ac->IsCached.FogCoord)
import_fogcoord(ctx, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.FogCoord;
}
else {
*writeable = GL_FALSE;
return &ac->Raw.FogCoord;
}
}
 
struct gl_client_array *_ac_import_edgeflag( GLcontext *ctx,
GLenum type,
GLuint reqstride,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_EDGEFLAG)
reset_edgeflag( ctx );
 
/* Do we need to pull in a copy of the client data:
*/
if (ac->Raw.EdgeFlag.Type != type ||
(reqstride != 0 && ac->Raw.EdgeFlag.StrideB != (GLint) reqstride) ||
reqwriteable)
{
if (!ac->IsCached.EdgeFlag)
import_edgeflag(ctx, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.EdgeFlag;
}
else {
*writeable = GL_FALSE;
return &ac->Raw.EdgeFlag;
}
}
 
/* GL_NV_vertex_program */
struct gl_client_array *_ac_import_attrib( GLcontext *ctx,
GLuint index,
GLenum type,
GLuint reqstride,
GLuint reqsize,
GLboolean reqwriteable,
GLboolean *writeable )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
ASSERT(index < VERT_ATTRIB_MAX);
 
/* Can we keep the existing version?
*/
if (ac->NewArrayState & _NEW_ARRAY_ATTRIB(index)) {
reset_attrib( ctx, index );
}
else if (ac->NewArrayState & (1 << index)) {
/* Also need to check conventional attributes */
reset_attrib( ctx, index );
}
 
/* Is the request impossible?
*/
if (reqsize != 0 && ac->Raw.Attrib[index].Size > (GLint) reqsize)
return NULL;
 
/* Do we need to pull in a copy of the client data:
*/
if (ac->Raw.Attrib[index].Type != type ||
(reqstride != 0 && ac->Raw.Attrib[index].StrideB != (GLint)reqstride) ||
reqwriteable)
{
if (!ac->IsCached.Attrib[index])
import_attrib(ctx, index, type, reqstride );
*writeable = GL_TRUE;
return &ac->Cache.Attrib[index];
}
else {
*writeable = GL_FALSE;
return &ac->Raw.Attrib[index];
}
}
 
 
/* Clients must call this function to validate state and set bounds
* before importing any data:
*/
void _ac_import_range( GLcontext *ctx, GLuint start, GLuint count )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (!ctx->Array.LockCount) {
/* Not locked, discard cached data. Changes to lock
* status are caught via. _ac_invalidate_state().
*/
ac->NewArrayState = _NEW_ARRAY_ALL;
ac->start = start;
ac->count = count;
}
else {
/* Locked, discard data for any disabled arrays. Require that
* the whole locked range always be dealt with, otherwise hard to
* maintain cached data in the face of clipping.
*/
ac->NewArrayState |= ~ctx->Array._Enabled;
ac->start = ctx->Array.LockFirst;
ac->count = ctx->Array.LockCount;
ASSERT(ac->start == start); /* hmm? */
ASSERT(ac->count == count);
}
}
 
 
 
/* Additional convienence function for importing the element list
* for glDrawElements() and glDrawRangeElements().
*/
CONST void *
_ac_import_elements( GLcontext *ctx,
GLenum new_type,
GLuint count,
GLenum old_type,
CONST void *indices )
{
ACcontext *ac = AC_CONTEXT(ctx);
 
if (old_type == new_type)
return indices;
 
if (ac->elt_size < count * sizeof(GLuint)) {
if (ac->Elts) FREE(ac->Elts);
while (ac->elt_size < count * sizeof(GLuint))
ac->elt_size *= 2;
ac->Elts = (GLuint *) MALLOC(ac->elt_size);
}
 
switch (new_type) {
case GL_UNSIGNED_BYTE:
ASSERT(0);
return 0;
case GL_UNSIGNED_SHORT:
ASSERT(0);
return 0;
case GL_UNSIGNED_INT: {
GLuint *out = (GLuint *)ac->Elts;
GLuint i;
 
switch (old_type) {
case GL_UNSIGNED_BYTE: {
CONST GLubyte *in = (CONST GLubyte *)indices;
for (i = 0 ; i < count ; i++)
out[i] = in[i];
break;
}
case GL_UNSIGNED_SHORT: {
CONST GLushort *in = (CONST GLushort *)indices;
for (i = 0 ; i < count ; i++)
out[i] = in[i];
break;
}
default:
ASSERT(0);
}
 
return (CONST void *)out;
}
default:
ASSERT(0);
break;
}
 
return 0;
}
/shark/trunk/ports/mesa/src/X86/sse.h
0,0 → 1,39
/* $Id: sse.h,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* PentiumIII-SIMD (SSE) optimizations contributed by
* Andre Werthmann <wertmann@cs.uni-potsdam.de>
*/
 
#ifndef __SSE_H__
#define __SSE_H__
 
#include "math/m_xform.h"
 
void _mesa_init_sse_transform_asm( void );
 
#endif
/shark/trunk/ports/mesa/src/X86/common_x86_features.h
0,0 → 1,80
/* $Id: common_x86_features.h,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* x86 CPUID feature information. The raw data is returned by
* _mesa_identify_x86_cpu_features() and interpreted with the cpu_has_*
* helper macros.
*
* Gareth Hughes
*/
 
#ifndef __COMMON_X86_FEATURES_H__
#define __COMMON_X86_FEATURES_H__
 
/* Capabilities of CPUs
*/
#define X86_FEATURE_FPU 0x00000001
#define X86_FEATURE_VME 0x00000002
#define X86_FEATURE_DE 0x00000004
#define X86_FEATURE_PSE 0x00000008
#define X86_FEATURE_TSC 0x00000010
#define X86_FEATURE_MSR 0x00000020
#define X86_FEATURE_PAE 0x00000040
#define X86_FEATURE_MCE 0x00000080
#define X86_FEATURE_CX8 0x00000100
#define X86_FEATURE_APIC 0x00000200
#define X86_FEATURE_10 0x00000400
#define X86_FEATURE_SEP 0x00000800
#define X86_FEATURE_MTRR 0x00001000
#define X86_FEATURE_PGE 0x00002000
#define X86_FEATURE_MCA 0x00004000
#define X86_FEATURE_CMOV 0x00008000
#define X86_FEATURE_PAT 0x00010000
#define X86_FEATURE_PSE36 0x00020000
#define X86_FEATURE_18 0x00040000
#define X86_FEATURE_19 0x00080000
#define X86_FEATURE_20 0x00100000
#define X86_FEATURE_21 0x00200000
#define X86_FEATURE_MMXEXT 0x00400000
#define X86_FEATURE_MMX 0x00800000
#define X86_FEATURE_FXSR 0x01000000
#define X86_FEATURE_XMM 0x02000000
#define X86_FEATURE_XMM2 0x04000000
#define X86_FEATURE_27 0x08000000
#define X86_FEATURE_28 0x10000000
#define X86_FEATURE_29 0x20000000
#define X86_FEATURE_3DNOWEXT 0x40000000
#define X86_FEATURE_3DNOW 0x80000000
 
#define cpu_has_mmx (_mesa_x86_cpu_features & X86_FEATURE_MMX)
#define cpu_has_mmxext (_mesa_x86_cpu_features & X86_FEATURE_MMXEXT)
#define cpu_has_xmm (_mesa_x86_cpu_features & X86_FEATURE_XMM)
#define cpu_has_xmm2 (_mesa_x86_cpu_features & X86_FEATURE_XMM2)
#define cpu_has_3dnow (_mesa_x86_cpu_features & X86_FEATURE_3DNOW)
#define cpu_has_3dnowext (_mesa_x86_cpu_features & X86_FEATURE_3DNOWEXT)
 
#endif
/shark/trunk/ports/mesa/src/X86/common_x86_asm.h
0,0 → 1,64
/* $Id: common_x86_asm.h,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* Check CPU capabilities & initialize optimized funtions for this particular
* processor.
*
* Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
* Changed by Andre Werthmann <wertmann@cs.uni-potsdam.de> for using the
* new Katmai functions
*
* Reimplemented by Gareth Hughes in a more
* future-proof manner, based on code in the Linux kernel.
*/
 
#ifndef __COMMON_X86_ASM_H__
#define __COMMON_X86_ASM_H__
 
/* Do not reference mtypes.h from this file.
*/
#include "common_x86_features.h"
 
#ifdef HAVE_CONFIG_H
#include "conf.h"
#endif
 
#ifdef USE_X86_ASM
#include "x86.h"
#ifdef USE_3DNOW_ASM
#include "3dnow.h"
#endif
#ifdef USE_SSE_ASM
#include "sse.h"
#endif
#endif
 
extern int _mesa_x86_cpu_features;
 
extern void _mesa_init_all_x86_transform_asm( void );
 
#endif
/shark/trunk/ports/mesa/src/X86/x86_xform2.s
0,0 → 1,563
/* $Id: x86_xform2.s,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* NOTE: Avoid using spaces in between '(' ')' and arguments, especially
* with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces
* in there will break the build on some platforms.
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define FP_ONE 1065353216
#define FP_ZERO 0
 
#define SRC0 REGOFF(0, ESI)
#define SRC1 REGOFF(4, ESI)
#define SRC2 REGOFF(8, ESI)
#define SRC3 REGOFF(12, ESI)
#define DST0 REGOFF(0, EDI)
#define DST1 REGOFF(4, EDI)
#define DST2 REGOFF(8, EDI)
#define DST3 REGOFF(12, EDI)
#define MAT0 REGOFF(0, EDX)
#define MAT1 REGOFF(4, EDX)
#define MAT2 REGOFF(8, EDX)
#define MAT3 REGOFF(12, EDX)
#define MAT4 REGOFF(16, EDX)
#define MAT5 REGOFF(20, EDX)
#define MAT6 REGOFF(24, EDX)
#define MAT7 REGOFF(28, EDX)
#define MAT8 REGOFF(32, EDX)
#define MAT9 REGOFF(36, EDX)
#define MAT10 REGOFF(40, EDX)
#define MAT11 REGOFF(44, EDX)
#define MAT12 REGOFF(48, EDX)
#define MAT13 REGOFF(52, EDX)
#define MAT14 REGOFF(56, EDX)
#define MAT15 REGOFF(60, EDX)
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points2_general )
GLNAME( _mesa_x86_transform_points2_general ):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p2_gr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p2_gr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
FLD_S( SRC0 ) /* F6 F5 F4 */
FMUL_S( MAT2 )
FLD_S( SRC0 ) /* F7 F6 F5 F4 */
FMUL_S( MAT3 )
 
FLD_S( SRC1 ) /* F0 F7 F6 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT5 )
FLD_S( SRC1 ) /* F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT6 )
FLD_S( SRC1 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT7 )
 
FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */
FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */
 
FXCH( ST(3) ) /* F4 F6 F5 F7 */
FADD_S( MAT12 )
FXCH( ST(2) ) /* F5 F6 F4 F7 */
FADD_S( MAT13 )
FXCH( ST(1) ) /* F6 F5 F4 F7 */
FADD_S( MAT14 )
FXCH( ST(3) ) /* F7 F5 F4 F6 */
FADD_S( MAT15 )
 
FXCH( ST(2) ) /* F4 F5 F7 F6 */
FSTP_S( DST0 ) /* F5 F7 F6 */
FSTP_S( DST1 ) /* F7 F6 */
FXCH( ST(1) ) /* F6 F7 */
FSTP_S( DST2 ) /* F7 */
FSTP_S( DST3 ) /* */
 
LLBL(x86_p2_gr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p2_gr_loop) )
 
LLBL(x86_p2_gr_done):
 
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points2_perspective )
GLNAME( _mesa_x86_transform_points2_perspective ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p2_pr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
MOV_L( MAT14, EBX )
 
ALIGNTEXT16
LLBL(x86_p2_pr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F1 F4 */
FMUL_S( MAT5 )
 
FXCH( ST(1) ) /* F4 F1 */
FSTP_S( DST0 ) /* F1 */
FSTP_S( DST1 ) /* */
MOV_L( EBX, DST2 )
MOV_L( CONST(FP_ZERO), DST3 )
 
LLBL(x86_p2_pr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p2_pr_loop) )
 
LLBL(x86_p2_pr_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points2_3d )
GLNAME( _mesa_x86_transform_points2_3d ):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p2_3dr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p2_3dr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
FLD_S( SRC0 ) /* F6 F5 F4 */
FMUL_S( MAT2 )
 
FLD_S( SRC1 ) /* F0 F6 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F6 F5 F4 */
FMUL_S( MAT5 )
FLD_S( SRC1 ) /* F2 F1 F0 F6 F5 F4 */
FMUL_S( MAT6 )
 
FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
FXCH( ST(2) ) /* F4 F5 F6 */
FADD_S( MAT12 )
FXCH( ST(1) ) /* F5 F4 F6 */
FADD_S( MAT13 )
FXCH( ST(2) ) /* F6 F4 F5 */
FADD_S( MAT14 )
 
FXCH( ST(1) ) /* F4 F6 F5 */
FSTP_S( DST0 ) /* F6 F5 */
FXCH( ST(1) ) /* F5 F6 */
FSTP_S( DST1 ) /* F6 */
FSTP_S( DST2 ) /* */
 
LLBL(x86_p2_3dr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p2_3dr_loop) )
 
LLBL(x86_p2_3dr_done):
 
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points2_3d_no_rot )
GLNAME( _mesa_x86_transform_points2_3d_no_rot ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p2_3dnrr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
MOV_L( MAT14, EBX )
 
ALIGNTEXT16
LLBL(x86_p2_3dnrr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F1 F4 */
FMUL_S( MAT5 )
 
FXCH( ST(1) ) /* F4 F1 */
FADD_S( MAT12 )
FLD_S( MAT13 ) /* F5 F4 F1 */
FXCH( ST(2) ) /* F1 F4 F5 */
FADDP( ST0, ST(2) ) /* F4 F5 */
 
FSTP_S( DST0 ) /* F5 */
FSTP_S( DST1 ) /* */
MOV_L( EBX, DST2 )
 
LLBL(x86_p2_3dnrr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p2_3dnrr_loop) )
 
LLBL(x86_p2_3dnrr_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points2_2d )
GLNAME( _mesa_x86_transform_points2_2d ):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p2_2dr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p2_2dr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
 
FLD_S( SRC1 ) /* F0 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F5 F4 */
FMUL_S( MAT5 )
 
FXCH( ST(1) ) /* F0 F1 F5 F4 */
FADDP( ST0, ST(3) ) /* F1 F5 F4 */
FADDP( ST0, ST(1) ) /* F5 F4 */
 
FXCH( ST(1) ) /* F4 F5 */
FADD_S( MAT12 )
FXCH( ST(1) ) /* F5 F4 */
FADD_S( MAT13 )
 
FXCH( ST(1) ) /* F4 F5 */
FSTP_S( DST0 ) /* F5 */
FSTP_S( DST1 ) /* */
 
LLBL(x86_p2_2dr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p2_2dr_loop) )
 
LLBL(x86_p2_2dr_done):
 
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT4
GLOBL GLNAME( _mesa_x86_transform_points2_2d_no_rot )
GLNAME( _mesa_x86_transform_points2_2d_no_rot ):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p2_2dnrr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p2_2dnrr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F1 F4 */
FMUL_S( MAT5 )
 
FXCH( ST(1) ) /* F4 F1 */
FADD_S( MAT12 )
FLD_S( MAT13 ) /* F5 F4 F1 */
FXCH( ST(2) ) /* F1 F4 F5 */
FADDP( ST0, ST(2) ) /* F4 F5 */
 
FSTP_S( DST0 ) /* F5 */
FSTP_S( DST1 ) /* */
 
LLBL(x86_p2_2dnrr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p2_2dnrr_loop) )
 
LLBL(x86_p2_2dnrr_done):
 
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points2_identity )
GLNAME( _mesa_x86_transform_points2_identity ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p2_ir_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
CMP_L( ESI, EDI )
JE( LLBL(x86_p2_ir_done) )
 
ALIGNTEXT16
LLBL(x86_p2_ir_loop):
 
MOV_L( SRC0, EBX )
MOV_L( SRC1, EDX )
 
MOV_L( EBX, DST0 )
MOV_L( EDX, DST1 )
 
LLBL(x86_p2_ir_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p2_ir_loop) )
 
LLBL(x86_p2_ir_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
/shark/trunk/ports/mesa/src/X86/x86_xform3.s
0,0 → 1,633
/* $Id: x86_xform3.s,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* NOTE: Avoid using spaces in between '(' ')' and arguments, especially
* with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces
* in there will break the build on some platforms.
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define FP_ONE 1065353216
#define FP_ZERO 0
 
#define SRC0 REGOFF(0, ESI)
#define SRC1 REGOFF(4, ESI)
#define SRC2 REGOFF(8, ESI)
#define SRC3 REGOFF(12, ESI)
#define DST0 REGOFF(0, EDI)
#define DST1 REGOFF(4, EDI)
#define DST2 REGOFF(8, EDI)
#define DST3 REGOFF(12, EDI)
#define MAT0 REGOFF(0, EDX)
#define MAT1 REGOFF(4, EDX)
#define MAT2 REGOFF(8, EDX)
#define MAT3 REGOFF(12, EDX)
#define MAT4 REGOFF(16, EDX)
#define MAT5 REGOFF(20, EDX)
#define MAT6 REGOFF(24, EDX)
#define MAT7 REGOFF(28, EDX)
#define MAT8 REGOFF(32, EDX)
#define MAT9 REGOFF(36, EDX)
#define MAT10 REGOFF(40, EDX)
#define MAT11 REGOFF(44, EDX)
#define MAT12 REGOFF(48, EDX)
#define MAT13 REGOFF(52, EDX)
#define MAT14 REGOFF(56, EDX)
#define MAT15 REGOFF(60, EDX)
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points3_general )
GLNAME( _mesa_x86_transform_points3_general ):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p3_gr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p3_gr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
FLD_S( SRC0 ) /* F6 F5 F4 */
FMUL_S( MAT2 )
FLD_S( SRC0 ) /* F7 F6 F5 F4 */
FMUL_S( MAT3 )
 
FLD_S( SRC1 ) /* F0 F7 F6 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT5 )
FLD_S( SRC1 ) /* F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT6 )
FLD_S( SRC1 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT7 )
 
FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */
FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */
 
FLD_S( SRC2 ) /* F0 F7 F6 F5 F4 */
FMUL_S( MAT8 )
FLD_S( SRC2 ) /* F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT9 )
FLD_S( SRC2 ) /* F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT10 )
FLD_S( SRC2 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT11 )
 
FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */
FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */
 
FXCH( ST(3) ) /* F4 F6 F5 F7 */
FADD_S( MAT12 )
FXCH( ST(2) ) /* F5 F6 F4 F7 */
FADD_S( MAT13 )
FXCH( ST(1) ) /* F6 F5 F4 F7 */
FADD_S( MAT14 )
FXCH( ST(3) ) /* F7 F5 F4 F6 */
FADD_S( MAT15 )
 
FXCH( ST(2) ) /* F4 F5 F7 F6 */
FSTP_S( DST0 ) /* F5 F7 F6 */
FSTP_S( DST1 ) /* F7 F6 */
FXCH( ST(1) ) /* F6 F7 */
FSTP_S( DST2 ) /* F7 */
FSTP_S( DST3 ) /* */
 
LLBL(x86_p3_gr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p3_gr_loop) )
 
LLBL(x86_p3_gr_done):
 
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points3_perspective )
GLNAME( _mesa_x86_transform_points3_perspective ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p3_pr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p3_pr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F5 F4 */
FMUL_S( MAT5 )
 
FLD_S( SRC2 ) /* F0 F5 F4 */
FMUL_S( MAT8 )
FLD_S( SRC2 ) /* F1 F0 F5 F4 */
FMUL_S( MAT9 )
FLD_S( SRC2 ) /* F2 F1 F0 F5 F4 */
FMUL_S( MAT10 )
 
FXCH( ST(2) ) /* F0 F1 F2 F5 F4 */
FADDP( ST0, ST(4) ) /* F1 F2 F5 F4 */
FADDP( ST0, ST(2) ) /* F2 F5 F4 */
FLD_S( MAT14 ) /* F6 F2 F5 F4 */
FXCH( ST(1) ) /* F2 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
MOV_L( SRC2, EBX )
XOR_L( CONST(-2147483648), EBX )/* change sign */
 
FXCH( ST(2) ) /* F4 F5 F6 */
FSTP_S( DST0 ) /* F5 F6 */
FSTP_S( DST1 ) /* F6 */
FSTP_S( DST2 ) /* */
MOV_L( EBX, DST3 )
 
LLBL(x86_p3_pr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p3_pr_loop) )
 
LLBL(x86_p3_pr_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points3_3d )
GLNAME( _mesa_x86_transform_points3_3d ):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p3_3dr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p3_3dr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
FLD_S( SRC0 ) /* F6 F5 F4 */
FMUL_S( MAT2 )
 
FLD_S( SRC1 ) /* F0 F6 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F6 F5 F4 */
FMUL_S( MAT5 )
FLD_S( SRC1 ) /* F2 F1 F0 F6 F5 F4 */
FMUL_S( MAT6 )
 
FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
FLD_S( SRC2 ) /* F0 F6 F5 F4 */
FMUL_S( MAT8 )
FLD_S( SRC2 ) /* F1 F0 F6 F5 F4 */
FMUL_S( MAT9 )
FLD_S( SRC2 ) /* F2 F1 F0 F6 F5 F4 */
FMUL_S( MAT10 )
 
FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
FXCH( ST(2) ) /* F4 F5 F6 */
FADD_S( MAT12 )
FXCH( ST(1) ) /* F5 F4 F6 */
FADD_S( MAT13 )
FXCH( ST(2) ) /* F6 F4 F5 */
FADD_S( MAT14 )
 
FXCH( ST(1) ) /* F4 F6 F5 */
FSTP_S( DST0 ) /* F6 F5 */
FXCH( ST(1) ) /* F5 F6 */
FSTP_S( DST1 ) /* F6 */
FSTP_S( DST2 ) /* */
 
LLBL(x86_p3_3dr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p3_3dr_loop) )
 
LLBL(x86_p3_3dr_done):
 
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points3_3d_no_rot )
GLNAME( _mesa_x86_transform_points3_3d_no_rot ):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p3_3dnrr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p3_3dnrr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F1 F4 */
FMUL_S( MAT5 )
 
FLD_S( SRC2 ) /* F2 F1 F4 */
FMUL_S( MAT10 )
 
FXCH( ST(2) ) /* F4 F1 F2 */
FADD_S( MAT12 )
FLD_S( MAT13 ) /* F5 F4 F1 F2 */
FXCH( ST(2) ) /* F1 F4 F5 F2 */
FADDP( ST0, ST(2) ) /* F4 F5 F2 */
FLD_S( MAT14 ) /* F6 F4 F5 F2 */
FXCH( ST(3) ) /* F2 F4 F5 F6 */
FADDP( ST0, ST(3) ) /* F4 F5 F6 */
 
FSTP_S( DST0 ) /* F5 F6 */
FSTP_S( DST1 ) /* F6 */
FSTP_S( DST2 ) /* */
 
LLBL(x86_p3_3dnrr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p3_3dnrr_loop) )
 
LLBL(x86_p3_3dnrr_done):
 
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points3_2d )
GLNAME( _mesa_x86_transform_points3_2d ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p3_2dr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p3_2dr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
 
FLD_S( SRC1 ) /* F0 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F5 F4 */
FMUL_S( MAT5 )
 
FXCH( ST(1) ) /* F0 F1 F5 F4 */
FADDP( ST0, ST(3) ) /* F1 F5 F4 */
FADDP( ST0, ST(1) ) /* F5 F4 */
 
FXCH( ST(1) ) /* F4 F5 */
FADD_S( MAT12 )
FXCH( ST(1) ) /* F5 F4 */
FADD_S( MAT13 )
 
MOV_L( SRC2, EBX )
 
FXCH( ST(1) ) /* F4 F5 */
FSTP_S( DST0 ) /* F5 */
FSTP_S( DST1 ) /* */
MOV_L( EBX, DST2 )
 
LLBL(x86_p3_2dr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p3_2dr_loop) )
 
LLBL(x86_p3_2dr_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points3_2d_no_rot )
GLNAME( _mesa_x86_transform_points3_2d_no_rot ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p3_2dnrr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p3_2dnrr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F1 F4 */
FMUL_S( MAT5 )
 
FXCH( ST(1) ) /* F4 F1 */
FADD_S( MAT12 )
FLD_S( MAT13 ) /* F5 F4 F1 */
 
FXCH( ST(2) ) /* F1 F4 F5 */
FADDP( ST0, ST(2) ) /* F4 F5 */
 
MOV_L( SRC2, EBX )
 
FSTP_S( DST0 ) /* F5 */
FSTP_S( DST1 ) /* */
MOV_L( EBX, DST2 )
 
LLBL(x86_p3_2dnrr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p3_2dnrr_loop) )
 
LLBL(x86_p3_2dnrr_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points3_identity )
GLNAME(_mesa_x86_transform_points3_identity ):
 
#define FRAME_OFFSET 16
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
PUSH_L( EBP )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p3_ir_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
CMP_L( ESI, EDI )
JE( LLBL(x86_p3_ir_done) )
 
ALIGNTEXT16
LLBL(x86_p3_ir_loop):
 
#if 1
MOV_L( SRC0, EBX )
MOV_L( SRC1, EBP )
MOV_L( SRC2, EDX )
 
MOV_L( EBX, DST0 )
MOV_L( EBP, DST1 )
MOV_L( EDX, DST2 )
#else
FLD_S( SRC0 )
FLD_S( SRC1 )
FLD_S( SRC2 )
 
FSTP_S( DST2 )
FSTP_S( DST1 )
FSTP_S( DST0 )
#endif
 
LLBL(x86_p3_ir_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p3_ir_loop) )
 
LLBL(x86_p3_ir_done):
 
POP_L( EBP )
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
/shark/trunk/ports/mesa/src/X86/x86_xform4.s
0,0 → 1,666
/* $Id: x86_xform4.s,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* NOTE: Avoid using spaces in between '(' ')' and arguments, especially
* with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces
* in there will break the build on some platforms.
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define FP_ONE 1065353216
#define FP_ZERO 0
 
#define SRC0 REGOFF(0, ESI)
#define SRC1 REGOFF(4, ESI)
#define SRC2 REGOFF(8, ESI)
#define SRC3 REGOFF(12, ESI)
#define DST0 REGOFF(0, EDI)
#define DST1 REGOFF(4, EDI)
#define DST2 REGOFF(8, EDI)
#define DST3 REGOFF(12, EDI)
#define MAT0 REGOFF(0, EDX)
#define MAT1 REGOFF(4, EDX)
#define MAT2 REGOFF(8, EDX)
#define MAT3 REGOFF(12, EDX)
#define MAT4 REGOFF(16, EDX)
#define MAT5 REGOFF(20, EDX)
#define MAT6 REGOFF(24, EDX)
#define MAT7 REGOFF(28, EDX)
#define MAT8 REGOFF(32, EDX)
#define MAT9 REGOFF(36, EDX)
#define MAT10 REGOFF(40, EDX)
#define MAT11 REGOFF(44, EDX)
#define MAT12 REGOFF(48, EDX)
#define MAT13 REGOFF(52, EDX)
#define MAT14 REGOFF(56, EDX)
#define MAT15 REGOFF(60, EDX)
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points4_general )
GLNAME( _mesa_x86_transform_points4_general ):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p4_gr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p4_gr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
FLD_S( SRC0 ) /* F6 F5 F4 */
FMUL_S( MAT2 )
FLD_S( SRC0 ) /* F7 F6 F5 F4 */
FMUL_S( MAT3 )
 
FLD_S( SRC1 ) /* F0 F7 F6 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT5 )
FLD_S( SRC1 ) /* F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT6 )
FLD_S( SRC1 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT7 )
 
FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */
FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */
 
FLD_S( SRC2 ) /* F0 F7 F6 F5 F4 */
FMUL_S( MAT8 )
FLD_S( SRC2 ) /* F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT9 )
FLD_S( SRC2 ) /* F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT10 )
FLD_S( SRC2 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT11 )
 
FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */
FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */
 
FLD_S( SRC3 ) /* F0 F7 F6 F5 F4 */
FMUL_S( MAT12 )
FLD_S( SRC3 ) /* F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT13 )
FLD_S( SRC3 ) /* F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT14 )
FLD_S( SRC3 ) /* F3 F2 F1 F0 F7 F6 F5 F4 */
FMUL_S( MAT15 )
 
FXCH( ST(3) ) /* F0 F2 F1 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(7) ) /* F2 F1 F3 F7 F6 F5 F4 */
FXCH( ST(1) ) /* F1 F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F2 F3 F7 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F3 F7 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F7 F6 F5 F4 */
 
FXCH( ST(3) ) /* F4 F6 F5 F7 */
FSTP_S( DST0 ) /* F6 F5 F7 */
FXCH( ST(1) ) /* F5 F6 F7 */
FSTP_S( DST1 ) /* F6 F7 */
FSTP_S( DST2 ) /* F7 */
FSTP_S( DST3 ) /* */
 
LLBL(x86_p4_gr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p4_gr_loop) )
 
LLBL(x86_p4_gr_done):
 
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points4_perspective )
GLNAME( _mesa_x86_transform_points4_perspective ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p4_pr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p4_pr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F5 F4 */
FMUL_S( MAT5 )
 
FLD_S( SRC2 ) /* F0 F5 F4 */
FMUL_S( MAT8 )
FLD_S( SRC2 ) /* F1 F0 F5 F4 */
FMUL_S( MAT9 )
FLD_S( SRC2 ) /* F6 F1 F0 F5 F4 */
FMUL_S( MAT10 )
 
FXCH( ST(2) ) /* F0 F1 F6 F5 F4 */
FADDP( ST0, ST(4) ) /* F1 F6 F5 F4 */
FADDP( ST0, ST(2) ) /* F6 F5 F4 */
 
FLD_S( SRC3 ) /* F2 F6 F5 F4 */
FMUL_S( MAT14 )
 
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
MOV_L( SRC2, EBX )
XOR_L( CONST(-2147483648), EBX )/* change sign */
 
FXCH( ST(2) ) /* F4 F5 F6 */
FSTP_S( DST0 ) /* F5 F6 */
FSTP_S( DST1 ) /* F6 */
FSTP_S( DST2 ) /* */
MOV_L( EBX, DST3 )
 
LLBL(x86_p4_pr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p4_pr_loop) )
 
LLBL(x86_p4_pr_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points4_3d )
GLNAME( _mesa_x86_transform_points4_3d ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p4_3dr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p4_3dr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
FLD_S( SRC0 ) /* F6 F5 F4 */
FMUL_S( MAT2 )
 
FLD_S( SRC1 ) /* F0 F6 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F6 F5 F4 */
FMUL_S( MAT5 )
FLD_S( SRC1 ) /* F2 F1 F0 F6 F5 F4 */
FMUL_S( MAT6 )
 
FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
FLD_S( SRC2 ) /* F0 F6 F5 F4 */
FMUL_S( MAT8 )
FLD_S( SRC2 ) /* F1 F0 F6 F5 F4 */
FMUL_S( MAT9 )
FLD_S( SRC2 ) /* F2 F1 F0 F6 F5 F4 */
FMUL_S( MAT10 )
 
FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
FLD_S( SRC3 ) /* F0 F6 F5 F4 */
FMUL_S( MAT12 )
FLD_S( SRC3 ) /* F1 F0 F6 F5 F4 */
FMUL_S( MAT13 )
FLD_S( SRC3 ) /* F2 F1 F0 F6 F5 F4 */
FMUL_S( MAT14 )
 
FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
MOV_L( SRC3, EBX )
 
FXCH( ST(2) ) /* F4 F5 F6 */
FSTP_S( DST0 ) /* F5 F6 */
FSTP_S( DST1 ) /* F6 */
FSTP_S( DST2 ) /* */
MOV_L( EBX, DST3 )
 
LLBL(x86_p4_3dr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p4_3dr_loop) )
 
LLBL(x86_p4_3dr_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_x86_transform_points4_3d_no_rot)
GLNAME(_mesa_x86_transform_points4_3d_no_rot):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p4_3dnrr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p4_3dnrr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F5 F4 */
FMUL_S( MAT5 )
 
FLD_S( SRC2 ) /* F6 F5 F4 */
FMUL_S( MAT10 )
 
FLD_S( SRC3 ) /* F0 F6 F5 F4 */
FMUL_S( MAT12 )
FLD_S( SRC3 ) /* F1 F0 F6 F5 F4 */
FMUL_S( MAT13 )
FLD_S( SRC3 ) /* F2 F1 F0 F6 F5 F4 */
FMUL_S( MAT14 )
 
FXCH( ST(2) ) /* F0 F1 F2 F6 F5 F4 */
FADDP( ST0, ST(5) ) /* F1 F2 F6 F5 F4 */
FADDP( ST0, ST(3) ) /* F2 F6 F5 F4 */
FADDP( ST0, ST(1) ) /* F6 F5 F4 */
 
MOV_L( SRC3, EBX )
 
FXCH( ST(2) ) /* F4 F5 F6 */
FSTP_S( DST0 ) /* F5 F6 */
FSTP_S( DST1 ) /* F6 */
FSTP_S( DST2 ) /* */
MOV_L( EBX, DST3 )
 
LLBL(x86_p4_3dnrr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p4_3dnrr_loop) )
 
LLBL(x86_p4_3dnrr_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points4_2d )
GLNAME( _mesa_x86_transform_points4_2d ):
 
#define FRAME_OFFSET 16
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
PUSH_L( EBP )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p4_2dr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p4_2dr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
FLD_S( SRC0 ) /* F5 F4 */
FMUL_S( MAT1 )
 
FLD_S( SRC1 ) /* F0 F5 F4 */
FMUL_S( MAT4 )
FLD_S( SRC1 ) /* F1 F0 F5 F4 */
FMUL_S( MAT5 )
 
FXCH( ST(1) ) /* F0 F1 F5 F4 */
FADDP( ST0, ST(3) ) /* F1 F5 F4 */
FADDP( ST0, ST(1) ) /* F5 F4 */
 
FLD_S( SRC3 ) /* F0 F5 F4 */
FMUL_S( MAT12 )
FLD_S( SRC3 ) /* F1 F0 F5 F4 */
FMUL_S( MAT13 )
 
FXCH( ST(1) ) /* F0 F1 F5 F4 */
FADDP( ST0, ST(3) ) /* F1 F5 F4 */
FADDP( ST0, ST(1) ) /* F5 F4 */
 
MOV_L( SRC2, EBX )
MOV_L( SRC3, EBP )
 
FXCH( ST(1) ) /* F4 F5 */
FSTP_S( DST0 ) /* F5 */
FSTP_S( DST1 ) /* */
MOV_L( EBX, DST2 )
MOV_L( EBP, DST3 )
 
LLBL(x86_p4_2dr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p4_2dr_loop) )
 
LLBL(x86_p4_2dr_done):
 
POP_L( EBP )
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points4_2d_no_rot )
GLNAME( _mesa_x86_transform_points4_2d_no_rot ):
 
#define FRAME_OFFSET 16
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
PUSH_L( EBP )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p4_2dnrr_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
ALIGNTEXT16
LLBL(x86_p4_2dnrr_loop):
 
FLD_S( SRC0 ) /* F4 */
FMUL_S( MAT0 )
 
FLD_S( SRC1 ) /* F5 F4 */
FMUL_S( MAT5 )
 
FLD_S( SRC3 ) /* F0 F5 F4 */
FMUL_S( MAT12 )
FLD_S( SRC3 ) /* F1 F0 F5 F4 */
FMUL_S( MAT13 )
 
FXCH( ST(1) ) /* F0 F1 F5 F4 */
FADDP( ST0, ST(3) ) /* F1 F5 F4 */
FADDP( ST0, ST(1) ) /* F5 F4 */
 
MOV_L( SRC2, EBX )
MOV_L( SRC3, EBP )
 
FXCH( ST(1) ) /* F4 F5 */
FSTP_S( DST0 ) /* F5 */
FSTP_S( DST1 ) /* */
MOV_L( EBX, DST2 )
MOV_L( EBP, DST3 )
 
LLBL(x86_p4_2dnrr_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p4_2dnrr_loop) )
 
LLBL(x86_p4_2dnrr_done):
 
POP_L( EBP )
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_transform_points4_identity )
GLNAME( _mesa_x86_transform_points4_identity ):
 
#define FRAME_OFFSET 12
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBX )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX )
JZ( LLBL(x86_p4_ir_done) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
 
SHL_L( CONST(4), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDI, ECX )
 
CMP_L( ESI, EDI )
JE( LLBL(x86_p4_ir_done) )
 
ALIGNTEXT16
LLBL(x86_p4_ir_loop):
 
MOV_L( SRC0, EBX )
MOV_L( SRC1, EDX )
 
MOV_L( EBX, DST0 )
MOV_L( EDX, DST1 )
 
MOV_L( SRC2, EBX )
MOV_L( SRC3, EDX )
 
MOV_L( EBX, DST2 )
MOV_L( EDX, DST3 )
 
LLBL(x86_p4_ir_skip):
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(x86_p4_ir_loop) )
 
LLBL(x86_p4_ir_done):
 
POP_L( EBX )
POP_L( EDI )
POP_L( ESI )
RET
/shark/trunk/ports/mesa/src/X86/mmx.h
0,0 → 1,51
/* $Id: mmx.h,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
 
#ifndef ASM_MMX_H
#define ASM_MMX_H
 
extern void _ASMAPI
_mesa_mmx_blend_transparency( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLubyte rgba[][4], const GLubyte dest[][4] );
 
extern void _ASMAPI
_mesa_mmx_blend_add( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLubyte rgba[][4], const GLubyte dest[][4] );
 
extern void _ASMAPI
_mesa_mmx_blend_min( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLubyte rgba[][4], const GLubyte dest[][4] );
 
extern void _ASMAPI
_mesa_mmx_blend_max( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLubyte rgba[][4], const GLubyte dest[][4] );
 
extern void _ASMAPI
_mesa_mmx_blend_modulate( GLcontext *ctx, GLuint n, const GLubyte mask[],
GLubyte rgba[][4], const GLubyte dest[][4] );
 
#endif
/shark/trunk/ports/mesa/src/X86/3dnow_xform1.s
0,0 → 1,423
/* $Id: 3dnow_xform1.s,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define FRAME_OFFSET 4
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points1_general )
GLNAME( _mesa_3dnow_transform_points1_general ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(4, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPGR_3 ) )
 
MOVQ ( REGIND(ECX), MM0 ) /* m01 | m00 */
MOVQ ( REGOFF(8, ECX), MM1 ) /* m03 | m02 */
 
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
MOVQ ( REGOFF(56, ECX), MM3 ) /* m33 | m32 */
 
ALIGNTEXT16
LLBL( G3TPGR_2 ):
 
MOVD ( REGIND(EAX), MM4 ) /* | x0 */
PUNPCKLDQ ( MM4, MM4 ) /* x0 | x0 */
 
MOVQ ( MM4, MM5 ) /* x0 | x0 */
PFMUL ( MM0, MM4 ) /* x0*m01 | x0*m00 */
 
PFMUL ( MM1, MM5 ) /* x0*m03 | x0*m02 */
PFADD ( MM2, MM4 ) /* x0*m01+m31 | x0*m00+m30 */
 
PFADD ( MM3, MM5 ) /* x0*m03+m33 | x0*m02+m32 */
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
 
MOVQ ( MM5, REGOFF(8, EDX) ) /* write r3, r2 */
ADD_L ( EDI, EAX ) /* next vertex */
 
ADD_L ( CONST(16), EDX ) /* next r */
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TPGR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPGR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points1_identity )
GLNAME( _mesa_3dnow_transform_points1_identity ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(1), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_1), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(4, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPIR_4) )
 
ALIGNTEXT16
LLBL( G3TPIR_3 ):
 
MOVD ( REGIND(EAX), MM0 ) /* | x0 */
ADD_L ( EDI, EAX ) /* next vertex */
 
MOVD ( MM0, REGIND(EDX) ) /* | r0 */
ADD_L ( CONST(16), EDX ) /* next r */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPIR_3 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPIR_4 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points1_3d_no_rot )
GLNAME( _mesa_3dnow_transform_points1_3d_no_rot ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(4, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP3NRR_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
 
MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */
 
ALIGNTEXT16
LLBL( G3TP3NRR_2 ):
 
MOVD ( REGIND(EAX), MM4 ) /* | x0 */
PFMUL ( MM0, MM4 ) /* | x0*m00 */
 
PFADD ( MM2, MM4 ) /* m31 | x0*m00+m30 */
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
 
MOVD ( MM3, REGOFF(8, EDX) ) /* write r2 */
ADD_L ( EDI, EAX ) /* next vertex */
 
ADD_L ( CONST(16), EDX ) /* next r */
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TP3NRR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP3NRR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points1_perspective )
GLNAME( _mesa_3dnow_transform_points1_perspective ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(4, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPPR_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */
 
ALIGNTEXT16
LLBL( G3TPPR_2 ):
 
MOVD ( REGIND(EAX), MM4 ) /* 0 | x0 */
PFMUL ( MM0, MM4 ) /* 0 | x0*m00 */
 
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
MOVQ ( MM3, REGOFF(8, EDX) ) /* write r2 (=m32), r3 (=0) */
 
ADD_L ( EDI, EAX ) /* next vertex */
ADD_L ( CONST(16), EDX ) /* next r */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPPR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPPR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points1_2d )
GLNAME( _mesa_3dnow_transform_points1_2d ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(4, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP2R_3 ) )
 
MOVQ ( REGIND(ECX), MM0 ) /* m01 | m00 */
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
 
ALIGNTEXT16
LLBL( G3TP2R_2 ):
 
MOVD ( REGIND(EAX), MM4 ) /* | x0 */
PUNPCKLDQ ( MM4, MM4 ) /* x0 | x0 */
 
PFMUL ( MM0, MM4 ) /* x0*m01 | x0*m00 */
PFADD ( MM2, MM4 ) /* x0*m01+m31 | x0*m00+m30 */
 
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
ADD_L ( EDI, EAX ) /* next vertex */
 
ADD_L ( CONST(16), EDX ) /* next r */
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TP2R_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP2R_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points1_2d_no_rot )
GLNAME( _mesa_3dnow_transform_points1_2d_no_rot ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(4, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP2NRR_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
 
ALIGNTEXT16
LLBL( G3TP2NRR_2 ):
 
MOVD ( REGIND(EAX), MM4 ) /* | x0 */
ADD_L ( EDI, EAX ) /* next vertex */
 
PFMUL ( MM0, MM4 ) /* | x0*m00 */
PFADD ( MM2, MM4 ) /* m31 | x0*m00+m30 */
 
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
ADD_L ( CONST(16), EDX ) /* next r */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TP2NRR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP2NRR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points1_3d )
GLNAME( _mesa_3dnow_transform_points1_3d ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(4, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP3R_3 ) )
 
MOVQ ( REGIND(ECX), MM0 ) /* m01 | m00 */
MOVD ( REGOFF(8, ECX), MM1 ) /* | m02 */
 
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */
 
ALIGNTEXT16
LLBL( G3TP3R_2 ):
 
MOVD ( REGIND(EAX), MM4 ) /* | x0 */
PUNPCKLDQ ( MM4, MM4 ) /* x0 | x0 */
 
MOVQ ( MM4, MM5 ) /* | x0 */
PFMUL ( MM0, MM4 ) /* x0*m01 | x0*m00 */
 
PFMUL ( MM1, MM5 ) /* | x0*m02 */
PFADD ( MM2, MM4 ) /* x0*m01+m31 | x0*m00+m30 */
 
PFADD ( MM3, MM5 ) /* | x0*m02+m32 */
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
 
MOVD ( MM5, REGOFF(8, EDX) ) /* write r2 */
ADD_L ( EDI, EAX ) /* next vertex */
 
ADD_L ( CONST(16), EDX ) /* next r */
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TP3R_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP3R_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
/shark/trunk/ports/mesa/src/X86/3dnow_xform2.s
0,0 → 1,464
/* $Id: 3dnow_xform2.s,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define FRAME_OFFSET 4
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points2_general )
GLNAME( _mesa_3dnow_transform_points2_general ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPGR_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(16, ECX), MM0 ) /* m10 | m00 */
 
MOVD ( REGOFF(4, ECX), MM1 ) /* | m01 */
PUNPCKLDQ ( REGOFF(20, ECX), MM1 ) /* m11 | m01 */
 
MOVD ( REGOFF(8, ECX), MM2 ) /* | m02 */
PUNPCKLDQ ( REGOFF(24, ECX), MM2 ) /* m12 | m02 */
 
MOVD ( REGOFF(12, ECX), MM3 ) /* | m03 */
PUNPCKLDQ ( REGOFF(28, ECX), MM3 ) /* m13 | m03 */
 
MOVQ ( REGOFF(48, ECX), MM4 ) /* m31 | m30 */
MOVQ ( REGOFF(56, ECX), MM5 ) /* m33 | m32 */
 
ALIGNTEXT16
LLBL( G3TPGR_2 ):
 
MOVQ ( REGIND(EAX), MM6 ) /* x1 | x0 */
MOVQ ( MM6, MM7 ) /* x1 | x0 */
 
PFMUL ( MM0, MM6 ) /* x1*m10 | x0*m00 */
PFMUL ( MM1, MM7 ) /* x1*m11 | x0*m01 */
 
PFACC ( MM7, MM6 ) /* x0*m01+x1*m11 | x0*x00+x1*m10 */
PFADD ( MM4, MM6 ) /* x0*...*m11+m31 | x0*...*m10+m30 */
 
MOVQ ( MM6, REGIND(EDX) ) /* write r1, r0 */
MOVQ ( REGIND(EAX), MM6 ) /* x1 | x0 */
 
MOVQ ( MM6, MM7 ) /* x1 | x0 */
PFMUL ( MM2, MM6 ) /* x1*m12 | x0*m02 */
 
PFMUL ( MM3, MM7 ) /* x1*m13 | x0*m03 */
ADD_L ( EDI, EAX ) /* next vertex */
 
PFACC ( MM7, MM6 ) /* x0*m03+x1*m13 | x0*x02+x1*m12 */
PFADD ( MM5, MM6 ) /* x0*...*m13+m33 | x0*...*m12+m32 */
 
MOVQ ( MM6, REGOFF(8, EDX) ) /* write r3, r2 */
ADD_L ( CONST(16), EDX ) /* next r */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPGR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPGR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points2_perspective )
GLNAME( _mesa_3dnow_transform_points2_perspective ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPPR_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */
 
ALIGNTEXT16
LLBL( G3TPPR_2 ):
 
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
 
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
MOVQ ( MM3, REGOFF(8, EDX) ) /* write r2 (=m32), r3 (=0) */
 
ADD_L ( EDI, EAX ) /* next vertex */
ADD_L ( CONST(16), EDX ) /* next r */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPPR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPPR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points2_3d )
GLNAME( _mesa_3dnow_transform_points2_3d ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3 ), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP3R_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(16, ECX), MM0 ) /* m10 | m00 */
 
MOVD ( REGOFF(4, ECX), MM1 ) /* | m01 */
PUNPCKLDQ ( REGOFF(20, ECX), MM1 ) /* m11 | m01 */
 
MOVD ( REGOFF(8, ECX), MM2 ) /* | m02 */
PUNPCKLDQ ( REGOFF(24, ECX), MM2 ) /* m12 | m02 */
 
MOVQ ( REGOFF(48, ECX), MM4 ) /* m31 | m30 */
MOVD ( REGOFF(56, ECX), MM5 ) /* | m32 */
 
ALIGNTEXT16
LLBL( G3TP3R_2 ):
 
MOVQ ( REGIND(EAX), MM6 ) /* x1 | x0 */
MOVQ ( MM6, MM7 ) /* x1 | x0 */
 
PFMUL ( MM0, MM6 ) /* x1*m10 | x0*m00 */
PFMUL ( MM1, MM7 ) /* x1*m11 | x0*m01 */
 
PFACC ( MM7, MM6 ) /* x0*m01+x1*m11 | x0*x00+x1*m10 */
PFADD ( MM4, MM6 ) /* x0*...*m11+m31 | x0*...*m10+m30 */
 
MOVQ ( MM6, REGIND(EDX) ) /* write r1, r0 */
MOVQ ( REGIND(EAX), MM6 ) /* x1 | x0 */
 
MOVQ ( MM6, MM7 ) /* x1 | x0 */
PFMUL ( MM2, MM6 ) /* x1*m12 | x0*m02 */
 
PFACC ( MM7, MM6 ) /* ***trash*** | x0*x02+x1*m12 */
PFADD ( MM5, MM6 ) /* ***trash*** | x0*...*m12+m32 */
 
MOVD ( MM6, REGOFF(8, EDX) ) /* write r2 */
ADD_L ( EDI, EAX ) /* next vertex */
 
ADD_L ( CONST(16), EDX ) /* next r */
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TP3R_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP3R_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points2_3d_no_rot )
GLNAME( _mesa_3dnow_transform_points2_3d_no_rot ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3 ), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP3NRR_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */
 
ALIGNTEXT16
LLBL( G3TP3NRR_2 ):
 
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
 
PFADD ( MM2, MM4 ) /* x1*m11+m31 | x0*m00+m30 */
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
 
MOVD ( MM3, REGOFF(8, EDX) ) /* write r2 */
ADD_L ( EDI, EAX ) /* next vertex */
 
ADD_L ( CONST(16), EDX ) /* next r */
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TP3NRR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP3NRR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points2_2d )
GLNAME( _mesa_3dnow_transform_points2_2d ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP2R_3 ) )
 
MOVQ ( REGIND(ECX), MM0 ) /* m01 | m00 */
MOVQ ( REGOFF(16, ECX), MM1 ) /* m11 | m10 */
 
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
 
ALIGNTEXT16
LLBL( G3TP2R_2 ):
 
MOVD ( REGIND(EAX), MM4 ) /* | x0 */
MOVD ( REGOFF(4, EAX), MM5 ) /* | x1 */
 
PUNPCKLDQ ( MM4, MM4 ) /* x0 | x0 */
ADD_L ( EDI, EAX ) /* next vertex */
 
PFMUL ( MM0, MM4 ) /* x0*m01 | x0*m00 */
PUNPCKLDQ ( MM5, MM5 ) /* x1 | x1 */
 
PFMUL ( MM1, MM5 ) /* x1*m11 | x1*m10 */
PFADD ( MM2, MM4 ) /* x...x1*m11+31 | x0*..*m10+m30 */
 
PFADD ( MM5, MM4 ) /* x0*m01+x1*m11 | x0*m00+x1*m10 */
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
 
ADD_L ( CONST(16), EDX ) /* next r */
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TP2R_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP2R_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points2_2d_no_rot )
GLNAME( _mesa_3dnow_transform_points2_2d_no_rot ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP2NRR_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
 
ALIGNTEXT16
LLBL( G3TP2NRR_2 ):
 
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
ADD_L ( EDI, EAX ) /* next vertex */
 
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
PFADD ( MM2, MM4 ) /* m31 | x0*m00+m30 */
 
MOVQ ( MM4, REGIND(EDX) ) /* write r1, r0 */
ADD_L ( CONST(16), EDX ) /* next r */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TP2NRR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP2NRR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points2_identity )
GLNAME( _mesa_3dnow_transform_points2_identity ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(2), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPIR_3 ) )
 
ALIGNTEXT16
LLBL( G3TPIR_3 ):
 
MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */
ADD_L ( EDI, EAX ) /* next vertex */
 
MOVQ ( MM0, REGIND(EDX) ) /* r1 | r0 */
ADD_L ( CONST(16), EDX ) /* next r */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPIR_3 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPIR_4 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
/shark/trunk/ports/mesa/src/X86/3dnow_xform3.s
0,0 → 1,548
/* $Id: 3dnow_xform3.s,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define FRAME_OFFSET 4
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points3_general )
GLNAME( _mesa_3dnow_transform_points3_general ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPGR_2 ) )
 
PREFETCHW ( REGIND(EDX) )
 
ALIGNTEXT16
LLBL( G3TPGR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF(8, EAX), MM2 ) /* | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
 
MOVQ ( MM0, MM1 ) /* x1 | x0 */
PUNPCKLDQ ( MM2, MM2 ) /* x2 | x2 */
 
PUNPCKLDQ ( MM0, MM0 ) /* x0 | x0 */
MOVQ ( MM2, MM5 ) /* x2 | x2 */
 
PUNPCKHDQ ( MM1, MM1 ) /* x1 | x1 */
PFMUL ( REGOFF(32, ECX), MM2 ) /* x2*m9 | x2*m8 */
 
MOVQ ( MM0, MM3 ) /* x0 | x0 */
PFMUL ( REGOFF(40, ECX), MM5 ) /* x2*m11 | x2*m10 */
 
MOVQ ( MM1, MM4 ) /* x1 | x1 */
PFMUL ( REGIND(ECX), MM0 ) /* x0*m1 | x0*m0 */
 
PFADD ( REGOFF(48, ECX), MM2 ) /* x2*m9+m13 | x2*m8+m12 */
PFMUL ( REGOFF(16, ECX), MM1 ) /* x1*m5 | x1*m4 */
 
PFADD ( REGOFF(56, ECX), MM5 ) /* x2*m11+m15 | x2*m10+m14 */
PFADD ( MM0, MM1 ) /* x0*m1+x1*m5 | x0*m0+x1*m4 */
 
PFMUL ( REGOFF(8, ECX), MM3 ) /* x0*m3 | x0*m2 */
PFADD ( MM1, MM2 ) /* r1 | r0 */
 
PFMUL ( REGOFF(24, ECX), MM4 ) /* x1*m7 | x1*m6 */
ADD_L ( CONST(16), EDX ) /* next output vertex */
 
PFADD ( MM3, MM4 ) /* x0*m3+x1*m7 | x0*m2+x1*m6 */
MOVQ ( MM2, REGOFF(-16, EDX) ) /* write r0, r1 */
 
PFADD ( MM4, MM5 ) /* r3 | r2 */
MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPGR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPGR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points3_perspective )
GLNAME( _mesa_3dnow_transform_points3_perspective ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPPR_2 ) )
 
PREFETCH ( REGIND(EAX) )
PREFETCHW ( REGIND(EDX) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVQ ( REGOFF(32, ECX), MM1 ) /* m21 | m20 */
MOVD ( REGOFF(40, ECX), MM2 ) /* | m22 */
 
MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */
 
ALIGNTEXT16
LLBL( G3TPPR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVD ( REGOFF(8, EAX), MM5 ) /* | x2 */
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
 
PXOR ( MM7, MM7 ) /* 0 | 0 */
MOVQ ( MM5, MM6 ) /* | x2 */
 
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
PFSUB ( MM5, MM7 ) /* | -x2 */
 
PFMUL ( MM2, MM6 ) /* | x2*m22 */
PUNPCKLDQ ( MM5, MM5 ) /* x2 | x2 */
 
ADD_L ( CONST(16), EDX ) /* next r */
PFMUL ( MM1, MM5 ) /* x2*m21 | x2*m20 */
 
PFADD ( MM3, MM6 ) /* | x2*m22+m32 */
PFADD ( MM4, MM5 ) /* x1*m11+x2*m21 | x0*m00+x2*m20 */
 
MOVQ ( MM5, REGOFF(-16, EDX) ) /* write r0, r1 */
MOVD ( MM6, REGOFF(-8, EDX) ) /* write r2 */
 
MOVD ( MM7, REGOFF(-4, EDX) ) /* write r3 */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPPR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPPR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points3_3d )
GLNAME( _mesa_3dnow_transform_points3_3d ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP3R_2 ) )
 
PREFETCH ( REGIND(EAX) )
PREFETCH ( REGIND(EDX) )
 
MOVD ( REGOFF(8, ECX), MM7 ) /* | m2 */
PUNPCKLDQ ( REGOFF(24, ECX), MM7 ) /* m6 | m2 */
 
 
ALIGNTEXT16
LLBL( G3TP3R_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF(8, EAX), MM1 ) /* | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
 
MOVQ ( MM0, MM2 ) /* x1 | x0 */
ADD_L ( CONST(16), EDX ) /* next r */
 
PUNPCKLDQ ( MM2, MM2 ) /* x0 | x0 */
MOVQ ( MM0, MM3 ) /* x1 | x0 */
 
PFMUL ( REGIND(ECX), MM2 ) /* x0*m1 | x0*m0 */
PUNPCKHDQ ( MM3, MM3 ) /* x1 | x1 */
 
MOVQ ( MM1, MM4 ) /* | x2 */
PFMUL ( REGOFF(16, ECX), MM3 ) /* x1*m5 | x1*m4 */
 
PUNPCKLDQ ( MM4, MM4 ) /* x2 | x2 */
PFADD ( MM2, MM3 ) /* x0*m1+x1*m5 | x0*m0+x1*m4 */
 
PFMUL ( REGOFF(32, ECX), MM4 ) /* x2*m9 | x2*m8 */
PFADD ( REGOFF(48, ECX), MM3 ) /* x0*m1+...+m11 | x0*m0+x1*m4+m12 */
 
PFMUL ( MM7, MM0 ) /* x1*m6 | x0*m2 */
PFADD ( MM4, MM3 ) /* r1 | r0 */
 
PFMUL ( REGOFF(40, ECX), MM1 ) /* | x2*m10 */
PUNPCKLDQ ( REGOFF(56, ECX), MM1 ) /* m14 | x2*m10 */
 
PFACC ( MM0, MM1 )
 
MOVQ ( MM3, REGOFF(-16, EDX) ) /* write r0, r1 */
PFACC ( MM1, MM1 ) /* | r2 */
 
MOVD ( MM1, REGOFF(-8, EDX) ) /* write r2 */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TP3R_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP3R_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points3_3d_no_rot )
GLNAME( _mesa_3dnow_transform_points3_3d_no_rot ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP3NRR_2 ) )
 
PREFETCH ( REGIND(EAX) )
PREFETCHW ( REGIND(EDX) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVD ( REGOFF(40, ECX), MM2 ) /* | m22 */
PUNPCKLDQ ( MM2, MM2 ) /* m22 | m22 */
 
MOVQ ( REGOFF(48, ECX), MM1 ) /* m31 | m30 */
MOVD ( REGOFF(56, ECX), MM3 ) /* | m32 */
 
PUNPCKLDQ ( MM3, MM3 ) /* m32 | m32 */
 
 
ALIGNTEXT16
LLBL( G3TP3NRR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
MOVD ( REGOFF(8, EAX), MM5 ) /* | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCHW ( REGIND(EAX) )
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
 
PFADD ( MM1, MM4 ) /* x1*m11+m31 | x0*m00+m30 */
PFMUL ( MM2, MM5 ) /* | x2*m22 */
 
PFADD ( MM3, MM5 ) /* | x2*m22+m32 */
MOVQ ( MM4, REGIND(EDX) ) /* write r0, r1 */
 
ADD_L ( CONST(16), EDX ) /* next r */
DEC_L ( ESI ) /* decrement vertex counter */
 
MOVD ( MM5, REGOFF(-8, EDX) ) /* write r2 */
JNZ ( LLBL( G3TP3NRR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP3NRR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points3_2d )
GLNAME( _mesa_3dnow_transform_points3_2d ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP2R_3) )
 
PREFETCH ( REGIND(EAX) )
PREFETCHW ( REGIND(EDX) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(16, ECX), MM0 ) /* m10 | m00 */
 
MOVD ( REGOFF(4, ECX), MM1 ) /* | m01 */
PUNPCKLDQ ( REGOFF(20, ECX), MM1 ) /* m11 | m01 */
 
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
 
ALIGNTEXT16
LLBL( G3TP2R_2 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM3 ) /* x1 | x0 */
MOVD ( REGOFF(8, EAX), MM5 ) /* | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
 
MOVQ ( MM3, MM4 ) /* x1 | x0 */
PFMUL ( MM0, MM3 ) /* x1*m10 | x0*m00 */
 
ADD_L ( CONST(16), EDX ) /* next r */
PFMUL ( MM1, MM4 ) /* x1*m11 | x0*m01 */
 
PFACC ( MM4, MM3 ) /* x0*m00+x1*m10 | x0*m01+x1*m11 */
MOVD ( MM5, REGOFF(-8, EDX) ) /* write r2 (=x2) */
 
PFADD ( MM2, MM3 ) /* x0*...*m10+m30 | x0*...*m11+m31 */
MOVQ ( MM3, REGOFF(-16, EDX) ) /* write r0, r1 */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TP2R_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP2R_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points3_2d_no_rot )
GLNAME( _mesa_3dnow_transform_points3_2d_no_rot ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP2NRR_2 ) )
 
PREFETCH ( REGIND(EAX) )
PREFETCHW ( REGIND(EDX) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVQ ( REGOFF(48, ECX), MM1 ) /* m31 | m30 */
 
 
ALIGNTEXT16
LLBL( G3TP2NRR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
MOVD ( REGOFF(8, EAX), MM5 ) /* | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
 
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
ADD_L ( CONST(16), EDX ) /* next r */
 
PFADD ( MM1, MM4 ) /* x1*m11+m31 | x0*m00+m30 */
 
MOVQ ( MM4, REGOFF(-16, EDX) ) /* write r0, r1 */
MOVD ( MM5, REGOFF(-8, EDX) ) /* write r2 (=x2) */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TP2NRR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP2NRR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points3_identity )
GLNAME( _mesa_3dnow_transform_points3_identity ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(3), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPIR_2 ) )
 
PREFETCHW ( REGIND(EDX) )
 
ALIGNTEXT16
LLBL( G3TPIR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) )
 
MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF(8, EAX), MM1 ) /* | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
ADD_L ( CONST(16), EDX ) /* next r */
 
DEC_L ( ESI ) /* decrement vertex counter */
MOVQ ( MM0, REGOFF(-16, EDX) ) /* r1 | r0 */
 
MOVD ( MM1, REGOFF(-8, EDX) ) /* | r2 */
JNZ ( LLBL( G3TPIR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPIR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
/shark/trunk/ports/mesa/src/X86/clip_args.h
0,0 → 1,60
/* $Id: clip_args.h,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* Clip test function interface for assembly code. Simply define
* FRAME_OFFSET to the number of bytes pushed onto the stack before
* using the ARG_* argument macros.
*
* Gareth Hughes
*/
 
#ifndef __CLIP_ARGS_H__
#define __CLIP_ARGS_H__
 
/*
* Offsets for clip_func arguments
*
* typedef GLvector4f *(*clip_func)( GLvector4f *clip_vec,
* GLvector4f *proj_vec,
* GLubyte clipMask[],
* GLubyte *orMask,
* GLubyte *andMask );
*/
 
#define OFFSET_SOURCE 4
#define OFFSET_DEST 8
#define OFFSET_CLIP 12
#define OFFSET_OR 16
#define OFFSET_AND 20
 
#define ARG_SOURCE REGOFF(FRAME_OFFSET+OFFSET_SOURCE, ESP)
#define ARG_DEST REGOFF(FRAME_OFFSET+OFFSET_DEST, ESP)
#define ARG_CLIP REGOFF(FRAME_OFFSET+OFFSET_CLIP, ESP)
#define ARG_OR REGOFF(FRAME_OFFSET+OFFSET_OR, ESP)
#define ARG_AND REGOFF(FRAME_OFFSET+OFFSET_AND, ESP)
 
#endif
/shark/trunk/ports/mesa/src/X86/3dnow_xform4.s
0,0 → 1,557
/* $Id: 3dnow_xform4.s,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define FRAME_OFFSET 4
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points4_general )
GLNAME( _mesa_3dnow_transform_points4_general ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPGR_2 ) )
 
PREFETCHW ( REGIND(EDX) )
 
ALIGNTEXT16
LLBL( G3TPGR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */
MOVQ ( REGOFF(8, EAX), MM4 ) /* x3 | x2 */
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
MOVQ ( MM0, MM2 ) /* x1 | x0 */
MOVQ ( MM4, MM6 ) /* x3 | x2 */
 
PUNPCKLDQ ( MM0, MM0 ) /* x0 | x0 */
PUNPCKHDQ ( MM2, MM2 ) /* x1 | x1 */
 
MOVQ ( MM0, MM1 ) /* x0 | x0 */
ADD_L ( CONST(16), EDX ) /* next r */
 
PFMUL ( REGIND(ECX), MM0 ) /* x0*m1 | x0*m0 */
MOVQ ( MM2, MM3 ) /* x1 | x1 */
 
PFMUL ( REGOFF(8, ECX), MM1 ) /* x0*m3 | x0*m2 */
PUNPCKLDQ ( MM4, MM4 ) /* x2 | x2 */
 
PFMUL ( REGOFF(16, ECX), MM2 ) /* x1*m5 | x1*m4 */
MOVQ ( MM4, MM5 ) /* x2 | x2 */
 
PFMUL ( REGOFF(24, ECX), MM3 ) /* x1*m7 | x1*m6 */
PUNPCKHDQ ( MM6, MM6 ) /* x3 | x3 */
 
PFMUL ( REGOFF(32, ECX), MM4 ) /* x2*m9 | x2*m8 */
MOVQ ( MM6, MM7 ) /* x3 | x3 */
 
PFMUL ( REGOFF(40, ECX), MM5 ) /* x2*m11 | x2*m10 */
PFADD ( MM0, MM2 )
 
PFMUL ( REGOFF(48, ECX), MM6 ) /* x3*m13 | x3*m12 */
PFADD ( MM1, MM3 )
 
PFMUL ( REGOFF(56, ECX), MM7 ) /* x3*m15 | x3*m14 */
PFADD ( MM4, MM6 )
 
PFADD ( MM5, MM7 )
PFADD ( MM2, MM6 )
 
PFADD ( MM3, MM7 )
MOVQ ( MM6, REGOFF(-16, EDX) )
 
MOVQ ( MM7, REGOFF(-8, EDX) )
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPGR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPGR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points4_perspective )
GLNAME( _mesa_3dnow_transform_points4_perspective ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPPR_2 ) )
 
PREFETCH ( REGIND(EAX) )
PREFETCHW ( REGIND(EDX) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVD ( REGOFF(40, ECX), MM1 ) /* | m22 */
PUNPCKLDQ ( REGOFF(56, ECX), MM1 ) /* m32 | m22 */
 
MOVQ ( REGOFF(32, ECX), MM2 ) /* m21 | m20 */
PXOR ( MM7, MM7 ) /* 0 | 0 */
 
ALIGNTEXT16
LLBL( G3TPPR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
MOVQ ( REGOFF(8, EAX), MM5 ) /* x3 | x2 */
MOVD ( REGOFF(8, EAX), MM3 ) /* | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGOFF(32, EAX) ) /* hopefully stride is zero */
 
MOVQ ( MM5, MM6 ) /* x3 | x2 */
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
 
PUNPCKLDQ ( MM5, MM5 ) /* x2 | x2 */
ADD_L ( CONST(16), EDX ) /* next r */
 
PFMUL ( MM2, MM5 ) /* x2*m21 | x2*m20 */
PFSUBR ( MM7, MM3 ) /* | -x2 */
 
PFMUL ( MM1, MM6 ) /* x3*m32 | x2*m22 */
PFADD ( MM4, MM5 ) /* x1*m11+x2*m21 | x0*m00+x2*m20 */
 
PFACC ( MM3, MM6 ) /* -x2 | x2*m22+x3*m32 */
MOVQ ( MM5, REGOFF(-16, EDX) ) /* write r0, r1 */
 
MOVQ ( MM6, REGOFF(-8, EDX) ) /* write r2, r3 */
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TPPR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPPR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points4_3d )
GLNAME( _mesa_3dnow_transform_points4_3d ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP3R_2 ) )
 
MOVD ( REGOFF(8, ECX), MM6 ) /* | m2 */
PUNPCKLDQ ( REGOFF(24, ECX), MM6 ) /* m6 | m2 */
 
MOVD ( REGOFF(40, ECX), MM7 ) /* | m10 */
PUNPCKLDQ ( REGOFF(56, ECX), MM7 ) /* m14 | m10 */
 
ALIGNTEXT16
LLBL( G3TP3R_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
PREFETCH ( REGOFF(32, EAX) ) /* hopefully array is tightly packed */
 
MOVQ ( REGIND(EAX), MM2 ) /* x1 | x0 */
MOVQ ( REGOFF(8, EAX), MM3 ) /* x3 | x2 */
 
MOVQ ( MM2, MM0 ) /* x1 | x0 */
MOVQ ( MM3, MM4 ) /* x3 | x2 */
 
MOVQ ( MM0, MM1 ) /* x1 | x0 */
MOVQ ( MM4, MM5 ) /* x3 | x2 */
 
PUNPCKLDQ ( MM0, MM0 ) /* x0 | x0 */
PUNPCKHDQ ( MM1, MM1 ) /* x1 | x1 */
 
PFMUL ( REGIND(ECX), MM0 ) /* x0*m1 | x0*m0 */
PUNPCKLDQ ( MM3, MM3 ) /* x2 | x2 */
 
PFMUL ( REGOFF(16, ECX), MM1 ) /* x1*m5 | x1*m4 */
PUNPCKHDQ ( MM4, MM4 ) /* x3 | x3 */
 
PFMUL ( MM6, MM2 ) /* x1*m6 | x0*m2 */
PFADD ( MM0, MM1 ) /* x0*m1+x1*m5 | x0*m0+x1*m4 */
 
PFMUL ( REGOFF(32, ECX), MM3 ) /* x2*m9 | x2*m8 */
ADD_L ( CONST(16), EDX ) /* next r */
 
PFMUL ( REGOFF(48, ECX), MM4 ) /* x3*m13 | x3*m12 */
PFADD ( MM1, MM3 ) /* x0*m1+..+x2*m9 | x0*m0+...+x2*m8 */
 
PFMUL ( MM7, MM5 ) /* x3*m14 | x2*m10 */
PFADD ( MM3, MM4 ) /* r1 | r0 */
 
PFACC ( MM2, MM5 ) /* x0*m2+x1*m6 | x2*m10+x3*m14 */
MOVD ( REGOFF(12, EAX), MM0 ) /* | x3 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PFACC ( MM0, MM5 ) /* r3 | r2 */
 
MOVQ ( MM4, REGOFF(-16, EDX) ) /* write r0, r1 */
MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TP3R_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP3R_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points4_3d_no_rot )
GLNAME( _mesa_3dnow_transform_points4_3d_no_rot ):
 
PUSH_L ( ESI )
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP3NRR_2 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVD ( REGOFF(40, ECX), MM2 ) /* | m22 */
PUNPCKLDQ ( REGOFF(56, ECX), MM2 ) /* m32 | m22 */
 
MOVQ ( REGOFF(48, ECX), MM1 ) /* m31 | m30 */
 
ALIGNTEXT16
LLBL( G3TP3NRR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
MOVQ ( REGOFF(8, EAX), MM5 ) /* x3 | x2 */
MOVD ( REGOFF(12, EAX), MM7 ) /* | x3 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGOFF(32, EAX) ) /* hopefully stride is zero */
 
MOVQ ( MM5, MM6 ) /* x3 | x2 */
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
 
PUNPCKHDQ ( MM6, MM6 ) /* x3 | x3 */
PFMUL ( MM2, MM5 ) /* x3*m32 | x2*m22 */
 
PFMUL ( MM1, MM6 ) /* x3*m31 | x3*m30 */
PFACC ( MM7, MM5 ) /* x3 | x2*m22+x3*m32 */
 
PFADD ( MM6, MM4 ) /* x1*m11+x3*m31 | x0*m00+x3*m30 */
ADD_L ( CONST(16), EDX ) /* next r */
 
MOVQ ( MM4, REGOFF(-16, EDX) ) /* write r0, r1 */
MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TP3NRR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP3NRR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points4_2d )
GLNAME( _mesa_3dnow_transform_points4_2d ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP2R_2 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(16, ECX), MM0 ) /* m10 | m00 */
 
MOVD ( REGOFF(4, ECX), MM1 ) /* | m01 */
PUNPCKLDQ ( REGOFF(20, ECX), MM1 ) /* m11 | m01 */
 
MOVQ ( REGOFF(48, ECX), MM2 ) /* m31 | m30 */
 
ALIGNTEXT16
LLBL( G3TP2R_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM3 ) /* x1 | x0 */
MOVQ ( REGOFF(8, EAX), MM5 ) /* x3 | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
 
MOVQ ( MM3, MM4 ) /* x1 | x0 */
MOVQ ( MM5, MM6 ) /* x3 | x2 */
 
PFMUL ( MM1, MM4 ) /* x1*m11 | x0*m01 */
PUNPCKHDQ ( MM6, MM6 ) /* x3 | x3 */
 
PFMUL ( MM0, MM3 ) /* x1*m10 | x0*m00 */
ADD_L ( CONST(16), EDX ) /* next r */
 
PFACC ( MM4, MM3 ) /* x0*m01+x1*m11 | x0*m00+x1*m10 */
PFMUL ( MM2, MM6 ) /* x3*m31 | x3*m30 */
 
PFADD ( MM6, MM3 ) /* r1 | r0 */
MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */
 
MOVQ ( MM3, REGOFF(-16, EDX) ) /* write r0, r1 */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TP2R_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP2R_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points4_2d_no_rot )
GLNAME( _mesa_3dnow_transform_points4_2d_no_rot ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TP2NRR_3 ) )
 
MOVD ( REGIND(ECX), MM0 ) /* | m00 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m11 | m00 */
 
MOVQ ( REGOFF(48, ECX), MM1 ) /* m31 | m30 */
 
ALIGNTEXT16
LLBL( G3TP2NRR_2 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
 
MOVQ ( REGIND(EAX), MM4 ) /* x1 | x0 */
MOVQ ( REGOFF(8, EAX), MM5 ) /* x3 | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
 
PFMUL ( MM0, MM4 ) /* x1*m11 | x0*m00 */
MOVQ ( MM5, MM6 ) /* x3 | x2 */
 
ADD_L ( CONST(16), EDX ) /* next r */
PUNPCKHDQ ( MM6, MM6 ) /* x3 | x3 */
 
PFMUL ( MM1, MM6 ) /* x3*m31 | x3*m30 */
PFADD ( MM4, MM6 ) /* x1*m11+x3*m31 | x0*m00+x3*m30 */
 
MOVQ ( MM6, REGOFF(-16, EDX) ) /* write r0, r1 */
MOVQ ( MM5, REGOFF(-8, EDX) ) /* write r2, r3 */
 
DEC_L ( ESI ) /* decrement vertex counter */
 
JNZ ( LLBL( G3TP2NRR_2 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TP2NRR_3 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_3dnow_transform_points4_identity )
GLNAME( _mesa_3dnow_transform_points4_identity ):
 
PUSH_L ( ESI )
 
MOV_L ( ARG_DEST, ECX )
MOV_L ( ARG_MATRIX, ESI )
MOV_L ( ARG_SOURCE, EAX )
MOV_L ( CONST(4), REGOFF(V4F_SIZE, ECX) )
OR_B ( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, ECX) )
MOV_L ( REGOFF(V4F_COUNT, EAX), EDX )
MOV_L ( EDX, REGOFF(V4F_COUNT, ECX) )
 
PUSH_L ( EDI )
 
MOV_L ( REGOFF(V4F_START, ECX), EDX )
MOV_L ( ESI, ECX )
MOV_L ( REGOFF(V4F_COUNT, EAX), ESI )
MOV_L ( REGOFF(V4F_STRIDE, EAX), EDI )
MOV_L ( REGOFF(V4F_START, EAX), EAX )
 
TEST_L ( ESI, ESI )
JZ ( LLBL( G3TPIR_2 ) )
 
ALIGNTEXT16
LLBL( G3TPIR_1 ):
 
PREFETCHW ( REGOFF(32, EDX) ) /* prefetch 2 vertices ahead */
MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */
MOVQ ( REGOFF(8, EAX), MM1 ) /* x3 | x2 */
 
ADD_L ( EDI, EAX ) /* next vertex */
PREFETCH ( REGIND(EAX) )
 
ADD_L ( CONST(16), EDX ) /* next r */
MOVQ ( MM0, REGOFF(-16, EDX) ) /* r1 | r0 */
 
MOVQ ( MM1, REGOFF(-8, EDX) ) /* r3 | r2 */
 
DEC_L ( ESI ) /* decrement vertex counter */
JNZ ( LLBL( G3TPIR_1 ) ) /* cnt > 0 ? -> process next vertex */
 
LLBL( G3TPIR_2 ):
 
FEMMS
POP_L ( EDI )
POP_L ( ESI )
RET
/shark/trunk/ports/mesa/src/X86/gen_matypes.c
0,0 → 1,292
/* $Id: gen_matypes.c,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* 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.
*
* Authors:
* Gareth Hughes
*/
 
/*
* This generates an asm version of mtypes.h (called matypes.h), so that
* Mesa's x86 assembly code can access the internal structures easily.
* This will be particularly useful when developing new x86 asm code for
* Mesa, including lighting, clipping, texture image conversion etc.
*/
 
#include "glheader.h"
#include "mtypes.h"
#include "tnl/t_context.h"
 
 
#undef offsetof
#define offsetof( type, member ) ((size_t) &((type *)0)->member)
 
 
#define OFFSET_HEADER( x ) \
do { \
printf( "\n" ); \
printf( "\n" ); \
printf( "/* =====================================================" \
"========\n" ); \
printf( " * Offsets for %s\n", x ); \
printf( " */\n" ); \
printf( "\n" ); \
} while (0)
 
#define DEFINE_HEADER( x ) \
do { \
printf( "\n" ); \
printf( "/*\n" ); \
printf( " * Flags for %s\n", x ); \
printf( " */\n" ); \
printf( "\n" ); \
} while (0)
 
#if defined(__BEOS__)
#define OFFSET( s, t, m ) \
printf( "#define %s\t%ld\n", s, offsetof( t, m ) );
#else
#define OFFSET( s, t, m ) \
printf( "#define %s\t%d\n", s, offsetof( t, m ) );
#endif
 
#if defined(__BEOS__)
#define SIZEOF( s, t ) \
printf( "#define %s\t%ld\n", s, sizeof(t) );
#else
#define SIZEOF( s, t ) \
printf( "#define %s\t%d\n", s, sizeof(t) );
#endif
 
#define DEFINE( s, d ) \
printf( "#define %s\t0x%x\n", s, d );
 
 
 
int main( int argc, char **argv )
{
printf( "/*\n" );
printf( " * This file is automatically generated from the Mesa internal type\n" );
printf( " * definitions. Do not edit directly.\n" );
printf( " */\n" );
printf( "\n" );
printf( "#ifndef __ASM_TYPES_H__\n" );
printf( "#define __ASM_TYPES_H__\n" );
printf( "\n" );
printf( "#include \"assyntax.h\"\n" );
 
 
/* GLcontext offsets:
*/
OFFSET_HEADER( "GLcontext" );
 
OFFSET( "CTX_DRIVER_CTX ", GLcontext, DriverCtx );
printf( "\n" );
OFFSET( "CTX_LIGHT_ENABLED ", GLcontext, Light.Enabled );
OFFSET( "CTX_LIGHT_SHADE_MODEL ", GLcontext, Light.ShadeModel );
OFFSET( "CTX_LIGHT_COLOR_MAT_FACE ", GLcontext, Light.ColorMaterialFace );
OFFSET( "CTX_LIGHT_COLOR_MAT_MODE ", GLcontext, Light.ColorMaterialMode );
OFFSET( "CTX_LIGHT_COLOR_MAT_MASK ", GLcontext, Light.ColorMaterialBitmask );
OFFSET( "CTX_LIGHT_COLOR_MAT_ENABLED ", GLcontext, Light.ColorMaterialEnabled );
OFFSET( "CTX_LIGHT_ENABLED_LIST ", GLcontext, Light.EnabledList );
OFFSET( "CTX_LIGHT_NEED_VERTS ", GLcontext, Light._NeedVertices );
OFFSET( "CTX_LIGHT_FLAGS ", GLcontext, Light._Flags );
OFFSET( "CTX_LIGHT_BASE_COLOR ", GLcontext, Light._BaseColor );
 
 
/* struct vertex_buffer offsets:
*/
OFFSET_HEADER( "struct vertex_buffer" );
 
OFFSET( "VB_SIZE ", struct vertex_buffer, Size );
OFFSET( "VB_COUNT ", struct vertex_buffer, Count );
printf( "\n" );
OFFSET( "VB_FIRST_CLIPPED ", struct vertex_buffer, FirstClipped );
OFFSET( "VB_FIRST_PRIMITIVE ", struct vertex_buffer, FirstPrimitive );
printf( "\n" );
OFFSET( "VB_ELTS ", struct vertex_buffer, Elts );
OFFSET( "VB_OBJ_PTR ", struct vertex_buffer, ObjPtr );
OFFSET( "VB_EYE_PTR ", struct vertex_buffer, EyePtr );
OFFSET( "VB_CLIP_PTR ", struct vertex_buffer, ClipPtr );
OFFSET( "VB_PROJ_CLIP_PTR ", struct vertex_buffer, NdcPtr );
OFFSET( "VB_CLIP_OR_MASK ", struct vertex_buffer, ClipOrMask );
OFFSET( "VB_CLIP_MASK ", struct vertex_buffer, ClipMask );
OFFSET( "VB_NORMAL_PTR ", struct vertex_buffer, NormalPtr );
OFFSET( "VB_EDGE_FLAG ", struct vertex_buffer, EdgeFlag );
OFFSET( "VB_TEX0_COORD_PTR ", struct vertex_buffer, TexCoordPtr[0] );
OFFSET( "VB_TEX1_COORD_PTR ", struct vertex_buffer, TexCoordPtr[1] );
OFFSET( "VB_TEX2_COORD_PTR ", struct vertex_buffer, TexCoordPtr[2] );
OFFSET( "VB_TEX3_COORD_PTR ", struct vertex_buffer, TexCoordPtr[3] );
OFFSET( "VB_INDEX_PTR ", struct vertex_buffer, IndexPtr );
OFFSET( "VB_COLOR_PTR ", struct vertex_buffer, ColorPtr );
OFFSET( "VB_SECONDARY_COLOR_PTR ", struct vertex_buffer, SecondaryColorPtr );
OFFSET( "VB_FOG_COORD_PTR ", struct vertex_buffer, FogCoordPtr );
OFFSET( "VB_POINT_SIZE_PTR ", struct vertex_buffer, PointSizePtr );
OFFSET( "VB_MATERIAL ", struct vertex_buffer, Material );
OFFSET( "VB_MATERIAL_MASK ", struct vertex_buffer, MaterialMask );
OFFSET( "VB_FLAG ", struct vertex_buffer, Flag );
OFFSET( "VB_PRIMITIVE ", struct vertex_buffer, Primitive );
OFFSET( "VB_PRIMITIVE_LENGTH ", struct vertex_buffer, PrimitiveLength );
printf( "\n" );
OFFSET( "VB_IMPORTABLE_DATA ", struct vertex_buffer, importable_data );
printf( "\n" );
OFFSET( "VB_LAST_CLIPPED ", struct vertex_buffer, LastClipped );
 
DEFINE_HEADER( "struct vertex_buffer" );
 
/* XXX use new labels here someday after vertex proram is done */
DEFINE( "VERT_BIT_OBJ ", VERT_BIT_POS );
DEFINE( "VERT_BIT_NORM ", VERT_BIT_NORMAL );
DEFINE( "VERT_BIT_RGBA ", VERT_BIT_COLOR0 );
DEFINE( "VERT_BIT_SPEC_RGB ", VERT_BIT_COLOR1 );
DEFINE( "VERT_BIT_FOG_COORD ", VERT_BIT_FOG );
DEFINE( "VERT_BIT_INDEX ", VERT_BIT_INDEX );
DEFINE( "VERT_BIT_EDGE ", VERT_BIT_EDGEFLAG );
DEFINE( "VERT_BIT_TEX0 ", VERT_BIT_TEX0 );
DEFINE( "VERT_BIT_TEX1 ", VERT_BIT_TEX1 );
DEFINE( "VERT_BIT_TEX2 ", VERT_BIT_TEX2 );
DEFINE( "VERT_BIT_TEX3 ", VERT_BIT_TEX3 );
DEFINE( "VERT_BIT_EVAL_C1 ", VERT_BIT_EVAL_C1 );
DEFINE( "VERT_BIT_EVAL_C2 ", VERT_BIT_EVAL_C2 );
DEFINE( "VERT_BIT_EVAL_P1 ", VERT_BIT_EVAL_P1 );
DEFINE( "VERT_BIT_EVAL_P2 ", VERT_BIT_EVAL_P2 );
DEFINE( "VERT_BIT_OBJ_3 ", VERT_BIT_OBJ_3 );
DEFINE( "VERT_BIT_OBJ_4 ", VERT_BIT_OBJ_4 );
DEFINE( "VERT_BIT_MATERIAL ", VERT_BIT_MATERIAL );
DEFINE( "VERT_BIT_ELT ", VERT_BIT_ELT );
DEFINE( "VERT_BIT_BEGIN ", VERT_BIT_BEGIN );
DEFINE( "VERT_BIT_END ", VERT_BIT_END );
DEFINE( "VERT_BIT_END_VB ", VERT_BIT_END_VB );
DEFINE( "VERT_BIT_POINT_SIZE ", VERT_BIT_POINT_SIZE );
DEFINE( "VERT_BIT_EYE ", VERT_BIT_EYE );
DEFINE( "VERT_BIT_CLIP ", VERT_BIT_CLIP );
printf( "\n" );
DEFINE( "VERT_BIT_OBJ_23 ", VERT_BIT_OBJ_3 );
DEFINE( "VERT_BIT_OBJ_234 ", VERT_BIT_OBJ_4 );
 
 
/* GLvector3f offsets:
*/
OFFSET_HEADER( "GLvector3f" );
 
OFFSET( "V3F_DATA ", GLvector3f, data );
OFFSET( "V3F_START ", GLvector3f, start );
OFFSET( "V3F_COUNT ", GLvector3f, count );
OFFSET( "V3F_STRIDE ", GLvector3f, stride );
OFFSET( "V3F_FLAGS ", GLvector3f, flags );
 
 
/* GLvector4f offsets:
*/
OFFSET_HEADER( "GLvector4f" );
 
OFFSET( "V4F_DATA ", GLvector4f, data );
OFFSET( "V4F_START ", GLvector4f, start );
OFFSET( "V4F_COUNT ", GLvector4f, count );
OFFSET( "V4F_STRIDE ", GLvector4f, stride );
OFFSET( "V4F_SIZE ", GLvector4f, size );
OFFSET( "V4F_FLAGS ", GLvector4f, flags );
 
DEFINE_HEADER( "GLvector4f" );
 
DEFINE( "VEC_MALLOC ", VEC_MALLOC );
DEFINE( "VEC_NOT_WRITEABLE ", VEC_NOT_WRITEABLE );
DEFINE( "VEC_BAD_STRIDE ", VEC_BAD_STRIDE );
printf( "\n" );
DEFINE( "VEC_SIZE_1 ", VEC_SIZE_1 );
DEFINE( "VEC_SIZE_2 ", VEC_SIZE_2 );
DEFINE( "VEC_SIZE_3 ", VEC_SIZE_3 );
DEFINE( "VEC_SIZE_4 ", VEC_SIZE_4 );
 
 
/* GLmatrix offsets:
*/
OFFSET_HEADER( "GLmatrix" );
 
OFFSET( "MATRIX_DATA ", GLmatrix, m );
OFFSET( "MATRIX_INV ", GLmatrix, inv );
OFFSET( "MATRIX_FLAGS ", GLmatrix, flags );
OFFSET( "MATRIX_TYPE ", GLmatrix, type );
 
 
/* struct gl_light offsets:
*/
OFFSET_HEADER( "struct gl_light" );
 
OFFSET( "LIGHT_NEXT ", struct gl_light, next );
OFFSET( "LIGHT_PREV ", struct gl_light, prev );
printf( "\n" );
OFFSET( "LIGHT_AMBIENT ", struct gl_light, Ambient );
OFFSET( "LIGHT_DIFFUSE ", struct gl_light, Diffuse );
OFFSET( "LIGHT_SPECULAR ", struct gl_light, Specular );
OFFSET( "LIGHT_EYE_POSITION ", struct gl_light, EyePosition );
OFFSET( "LIGHT_EYE_DIRECTION ", struct gl_light, EyeDirection );
OFFSET( "LIGHT_SPOT_EXPONENT ", struct gl_light, SpotExponent );
OFFSET( "LIGHT_SPOT_CUTOFF ", struct gl_light, SpotCutoff );
OFFSET( "LIGHT_COS_CUTOFF ", struct gl_light, _CosCutoff );
OFFSET( "LIGHT_CONST_ATTEN ", struct gl_light, ConstantAttenuation );
OFFSET( "LIGHT_LINEAR_ATTEN ", struct gl_light, LinearAttenuation );
OFFSET( "LIGHT_QUADRATIC_ATTEN ", struct gl_light, QuadraticAttenuation );
OFFSET( "LIGHT_ENABLED ", struct gl_light, Enabled );
printf( "\n" );
OFFSET( "LIGHT_FLAGS ", struct gl_light, _Flags );
printf( "\n" );
OFFSET( "LIGHT_POSITION ", struct gl_light, _Position );
OFFSET( "LIGHT_VP_INF_NORM ", struct gl_light, _VP_inf_norm );
OFFSET( "LIGHT_H_INF_NORM ", struct gl_light, _h_inf_norm );
OFFSET( "LIGHT_NORM_DIRECTION ", struct gl_light, _NormDirection );
OFFSET( "LIGHT_VP_INF_SPOT_ATTEN ", struct gl_light, _VP_inf_spot_attenuation );
printf( "\n" );
OFFSET( "LIGHT_SPOT_EXP_TABLE ", struct gl_light, _SpotExpTable );
OFFSET( "LIGHT_MAT_AMBIENT ", struct gl_light, _MatAmbient );
OFFSET( "LIGHT_MAT_DIFFUSE ", struct gl_light, _MatDiffuse );
OFFSET( "LIGHT_MAT_SPECULAR ", struct gl_light, _MatSpecular );
printf( "\n" );
SIZEOF( "SIZEOF_GL_LIGHT ", struct gl_light );
 
DEFINE_HEADER( "struct gl_light" );
 
DEFINE( "LIGHT_SPOT ", LIGHT_SPOT );
DEFINE( "LIGHT_LOCAL_VIEWER ", LIGHT_LOCAL_VIEWER );
DEFINE( "LIGHT_POSITIONAL ", LIGHT_POSITIONAL );
printf( "\n" );
DEFINE( "LIGHT_NEED_VERTICES ", LIGHT_NEED_VERTICES );
 
 
/* struct gl_lightmodel offsets:
*/
OFFSET_HEADER( "struct gl_lightmodel" );
 
OFFSET( "LIGHT_MODEL_AMBIENT ", struct gl_lightmodel, Ambient );
OFFSET( "LIGHT_MODEL_LOCAL_VIEWER ", struct gl_lightmodel, LocalViewer );
OFFSET( "LIGHT_MODEL_TWO_SIDE ", struct gl_lightmodel, TwoSide );
OFFSET( "LIGHT_MODEL_COLOR_CONTROL ", struct gl_lightmodel, ColorControl );
 
 
printf( "\n" );
printf( "\n" );
printf( "#endif /* __ASM_TYPES_H__ */\n" );
 
return 0;
}
/shark/trunk/ports/mesa/src/X86/xform_args.h
0,0 → 1,52
/* $Id: xform_args.h,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* Transform function interface for assembly code. Simply define
* FRAME_OFFSET to the number of bytes pushed onto the stack before
* using the ARG_* argument macros.
*
* Gareth Hughes
*/
 
#ifndef __XFORM_ARGS_H__
#define __XFORM_ARGS_H__
 
/* Offsets for transform_func arguments
*
* typedef void (*transform_func)( GLvector4f *to_vec,
* const GLfloat m[16],
* const GLvector4f *from_vec );
*/
#define OFFSET_DEST 4
#define OFFSET_MATRIX 8
#define OFFSET_SOURCE 12
 
#define ARG_DEST REGOFF(FRAME_OFFSET+OFFSET_DEST, ESP)
#define ARG_MATRIX REGOFF(FRAME_OFFSET+OFFSET_MATRIX, ESP)
#define ARG_SOURCE REGOFF(FRAME_OFFSET+OFFSET_SOURCE, ESP)
 
#endif
/shark/trunk/ports/mesa/src/X86/common_x86_asm.s
0,0 → 1,239
/* $Id: common_x86_asm.s,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 4.0.3
*
* 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.
*/
 
/*
* Check extended CPU capabilities. Now justs returns the raw CPUID
* feature information, allowing the higher level code to interpret the
* results.
*
* Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
*
* Cleaned up and simplified by Gareth Hughes <gareth@valinux.com>
*/
 
/*
* NOTE: Avoid using spaces in between '(' ')' and arguments, especially
* with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces
* in there will break the build on some platforms.
*/
 
#include "matypes.h"
#include "common_x86_features.h"
 
 
/* Intel vendor string
*/
#define GENU 0x756e6547 /* "Genu" */
#define INEI 0x49656e69 /* "ineI" */
#define NTEL 0x6c65746e /* "ntel" */
 
/* AMD vendor string
*/
#define AUTH 0x68747541 /* "Auth" */
#define ENTI 0x69746e65 /* "enti" */
#define CAMD 0x444d4163 /* "cAMD" */
 
 
SEG_DATA
 
/* We might want to print out some useful messages.
*/
GLNAME( found_intel ): STRING( "Genuine Intel processor found\n\0" )
GLNAME( found_amd ): STRING( "Authentic AMD processor found\n\0" )
 
 
SEG_TEXT
 
ALIGNTEXT4
GLOBL GLNAME( _mesa_identify_x86_cpu_features )
GLNAME( _mesa_identify_x86_cpu_features ):
 
PUSH_L ( EBX )
PUSH_L ( ESI )
 
/* Test for the CPUID command. If the ID Flag bit in EFLAGS
* (bit 21) is writable, the CPUID command is present.
*/
PUSHF_L
POP_L ( EAX )
MOV_L ( EAX, ECX )
XOR_L ( CONST(0x00200000), EAX )
PUSH_L ( EAX )
POPF_L
PUSHF_L
POP_L ( EAX )
 
/* Verify the ID Flag bit has been written.
*/
CMP_L ( ECX, EAX )
JZ ( LLBL (cpuid_done) )
 
/* Get the CPU vendor info.
*/
XOR_L ( EAX, EAX )
CPUID
 
/* Test for Intel processors. We must look for the
* "GenuineIntel" string in EBX, ECX and EDX.
*/
CMP_L ( CONST(GENU), EBX )
JNE ( LLBL(cpuid_amd) )
CMP_L ( CONST(INEI), EDX )
JNE ( LLBL(cpuid_amd) )
CMP_L ( CONST(NTEL), ECX )
JNE ( LLBL(cpuid_amd) )
 
/* We have an Intel processor, so we can get the feature
* information with an CPUID input value of 1.
*/
MOV_L ( CONST(0x1), EAX )
CPUID
MOV_L ( EDX, EAX )
 
/* Mask out highest bit, which is used by AMD for 3dnow
* Newer Intel have this bit set, but do not support 3dnow
*/
AND_L ( CONST(0X7FFFFFFF), EAX)
JMP ( LLBL(cpuid_done) )
 
LLBL(cpuid_amd):
 
/* Test for AMD processors. We must look for the
* "AuthenticAMD" string in EBX, ECX and EDX.
*/
CMP_L ( CONST(AUTH), EBX )
JNE ( LLBL(cpuid_other) )
CMP_L ( CONST(ENTI), EDX )
JNE ( LLBL(cpuid_other) )
CMP_L ( CONST(CAMD), ECX )
JNE ( LLBL(cpuid_other) )
 
/* We have an AMD processor, so we can get the feature
* information after we verify that the extended functions are
* supported.
*/
/* The features we need are almost all in the extended set. The
* exception is SSE enable, which is in the standard set (0x1).
*/
MOV_L ( CONST(0x1), EAX )
CPUID
TEST_L ( EAX, EAX )
JZ ( LLBL (cpuid_failed) )
MOV_L ( EDX, ESI )
 
MOV_L ( CONST(0x80000000), EAX )
CPUID
TEST_L ( EAX, EAX )
JZ ( LLBL (cpuid_failed) )
 
MOV_L ( CONST(0x80000001), EAX )
CPUID
MOV_L ( EDX, EAX )
AND_L ( CONST(0x02000000), ESI ) /* OR in the SSE bit */
OR_L ( ESI, EAX )
JMP ( LLBL (cpuid_done) )
 
LLBL(cpuid_other):
 
/* Test for other processors here when required.
*/
 
LLBL(cpuid_failed):
 
/* If we can't determine the feature information, we must
* return zero to indicate that no platform-specific
* optimizations can be used.
*/
MOV_L ( CONST(0), EAX )
 
LLBL (cpuid_done):
 
POP_L ( ESI )
POP_L ( EBX )
RET
 
 
#ifdef USE_SSE_ASM
/* Execute an SSE instruction to see if the operating system correctly
* supports SSE. A signal handler for SIGILL should have been set
* before calling this function, otherwise this could kill the client
* application.
*/
ALIGNTEXT4
GLOBL GLNAME( _mesa_test_os_sse_support )
GLNAME( _mesa_test_os_sse_support ):
 
XORPS ( XMM0, XMM0 )
 
RET
 
 
/* Perform an SSE divide-by-zero to see if the operating system
* correctly supports unmasked SIMD FPU exceptions. Signal handlers for
* SIGILL and SIGFPE should have been set before calling this function,
* otherwise this could kill the client application.
*/
ALIGNTEXT4
GLOBL GLNAME( _mesa_test_os_sse_exception_support )
GLNAME( _mesa_test_os_sse_exception_support ):
 
PUSH_L ( EBP )
MOV_L ( ESP, EBP )
SUB_L ( CONST( 8 ), ESP )
 
/* Save the original MXCSR register value.
*/
STMXCSR ( REGOFF( -4, EBP ) )
 
/* Unmask the divide-by-zero exception and perform one.
*/
STMXCSR ( REGOFF( -8, EBP ) )
AND_L ( CONST( 0xfffffdff ), REGOFF( -8, EBP ) )
LDMXCSR ( REGOFF( -8, EBP ) )
 
XORPS ( XMM0, XMM0 )
 
PUSH_L ( CONST( 0x3f800000 ) )
PUSH_L ( CONST( 0x3f800000 ) )
PUSH_L ( CONST( 0x3f800000 ) )
PUSH_L ( CONST( 0x3f800000 ) )
 
MOVUPS ( REGIND( ESP ), XMM1 )
 
ADD_L ( CONST( 32 ), ESP )
 
DIVPS ( XMM0, XMM1 )
 
/* Restore the original MXCSR register value.
*/
LDMXCSR ( REGOFF( -4, EBP ) )
 
LEAVE
RET
 
#endif
/shark/trunk/ports/mesa/src/X86/glapi_x86.s
0,0 → 1,4861
/* DO NOT EDIT - This file generated automatically with glx86asm.py script */
#include "assyntax.h"
#include "../glapioffsets.h"
 
#ifndef __WIN32__
 
#if defined(USE_MGL_NAMESPACE)
#define GL_PREFIX(n) GLNAME(CONCAT(mgl,n))
#else
#define GL_PREFIX(n) GLNAME(CONCAT(gl,n))
#endif
 
#define GL_OFFSET(x) CODEPTR(REGOFF(4 * x, EAX))
 
#if defined(GNU_ASSEMBLER) && !defined(DJGPP)
#define GLOBL_FN(x) GLOBL x ; .type x,@function
#else
#define GLOBL_FN(x) GLOBL x
#endif
 
 
EXTERN GLNAME(_glapi_Dispatch)
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(NewList))
GL_PREFIX(NewList):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_NewList))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EndList))
GL_PREFIX(EndList):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EndList))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CallList))
GL_PREFIX(CallList):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CallList))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CallLists))
GL_PREFIX(CallLists):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CallLists))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DeleteLists))
GL_PREFIX(DeleteLists):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DeleteLists))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GenLists))
GL_PREFIX(GenLists):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GenLists))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ListBase))
GL_PREFIX(ListBase):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ListBase))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Begin))
GL_PREFIX(Begin):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Begin))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Bitmap))
GL_PREFIX(Bitmap):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Bitmap))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3b))
GL_PREFIX(Color3b):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3b))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3bv))
GL_PREFIX(Color3bv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3bv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3d))
GL_PREFIX(Color3d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3dv))
GL_PREFIX(Color3dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3f))
GL_PREFIX(Color3f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3fv))
GL_PREFIX(Color3fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3i))
GL_PREFIX(Color3i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3iv))
GL_PREFIX(Color3iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3s))
GL_PREFIX(Color3s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3sv))
GL_PREFIX(Color3sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3ub))
GL_PREFIX(Color3ub):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3ub))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3ubv))
GL_PREFIX(Color3ubv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3ubv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3ui))
GL_PREFIX(Color3ui):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3ui))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3uiv))
GL_PREFIX(Color3uiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3uiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3us))
GL_PREFIX(Color3us):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3us))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color3usv))
GL_PREFIX(Color3usv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color3usv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4b))
GL_PREFIX(Color4b):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4b))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4bv))
GL_PREFIX(Color4bv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4bv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4d))
GL_PREFIX(Color4d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4dv))
GL_PREFIX(Color4dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4f))
GL_PREFIX(Color4f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4fv))
GL_PREFIX(Color4fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4i))
GL_PREFIX(Color4i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4iv))
GL_PREFIX(Color4iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4s))
GL_PREFIX(Color4s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4sv))
GL_PREFIX(Color4sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4ub))
GL_PREFIX(Color4ub):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4ub))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4ubv))
GL_PREFIX(Color4ubv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4ubv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4ui))
GL_PREFIX(Color4ui):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4ui))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4uiv))
GL_PREFIX(Color4uiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4uiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4us))
GL_PREFIX(Color4us):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4us))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Color4usv))
GL_PREFIX(Color4usv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Color4usv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EdgeFlag))
GL_PREFIX(EdgeFlag):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EdgeFlag))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EdgeFlagv))
GL_PREFIX(EdgeFlagv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EdgeFlagv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(End))
GL_PREFIX(End):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_End))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexd))
GL_PREFIX(Indexd):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexd))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexdv))
GL_PREFIX(Indexdv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexdv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexf))
GL_PREFIX(Indexf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexfv))
GL_PREFIX(Indexfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexi))
GL_PREFIX(Indexi):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexi))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexiv))
GL_PREFIX(Indexiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexs))
GL_PREFIX(Indexs):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexs))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexsv))
GL_PREFIX(Indexsv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexsv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3b))
GL_PREFIX(Normal3b):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3b))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3bv))
GL_PREFIX(Normal3bv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3bv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3d))
GL_PREFIX(Normal3d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3dv))
GL_PREFIX(Normal3dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3f))
GL_PREFIX(Normal3f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3fv))
GL_PREFIX(Normal3fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3i))
GL_PREFIX(Normal3i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3iv))
GL_PREFIX(Normal3iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3s))
GL_PREFIX(Normal3s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Normal3sv))
GL_PREFIX(Normal3sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Normal3sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos2d))
GL_PREFIX(RasterPos2d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos2d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos2dv))
GL_PREFIX(RasterPos2dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos2dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos2f))
GL_PREFIX(RasterPos2f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos2f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos2fv))
GL_PREFIX(RasterPos2fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos2fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos2i))
GL_PREFIX(RasterPos2i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos2i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos2iv))
GL_PREFIX(RasterPos2iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos2iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos2s))
GL_PREFIX(RasterPos2s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos2s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos2sv))
GL_PREFIX(RasterPos2sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos2sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos3d))
GL_PREFIX(RasterPos3d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos3d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos3dv))
GL_PREFIX(RasterPos3dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos3dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos3f))
GL_PREFIX(RasterPos3f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos3f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos3fv))
GL_PREFIX(RasterPos3fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos3fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos3i))
GL_PREFIX(RasterPos3i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos3i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos3iv))
GL_PREFIX(RasterPos3iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos3iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos3s))
GL_PREFIX(RasterPos3s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos3s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos3sv))
GL_PREFIX(RasterPos3sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos3sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos4d))
GL_PREFIX(RasterPos4d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos4d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos4dv))
GL_PREFIX(RasterPos4dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos4dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos4f))
GL_PREFIX(RasterPos4f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos4f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos4fv))
GL_PREFIX(RasterPos4fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos4fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos4i))
GL_PREFIX(RasterPos4i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos4i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos4iv))
GL_PREFIX(RasterPos4iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos4iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos4s))
GL_PREFIX(RasterPos4s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos4s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RasterPos4sv))
GL_PREFIX(RasterPos4sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RasterPos4sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rectd))
GL_PREFIX(Rectd):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rectd))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rectdv))
GL_PREFIX(Rectdv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rectdv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rectf))
GL_PREFIX(Rectf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rectf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rectfv))
GL_PREFIX(Rectfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rectfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Recti))
GL_PREFIX(Recti):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Recti))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rectiv))
GL_PREFIX(Rectiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rectiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rects))
GL_PREFIX(Rects):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rects))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rectsv))
GL_PREFIX(Rectsv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rectsv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord1d))
GL_PREFIX(TexCoord1d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord1d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord1dv))
GL_PREFIX(TexCoord1dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord1dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord1f))
GL_PREFIX(TexCoord1f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord1f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord1fv))
GL_PREFIX(TexCoord1fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord1fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord1i))
GL_PREFIX(TexCoord1i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord1i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord1iv))
GL_PREFIX(TexCoord1iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord1iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord1s))
GL_PREFIX(TexCoord1s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord1s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord1sv))
GL_PREFIX(TexCoord1sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord1sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord2d))
GL_PREFIX(TexCoord2d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord2d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord2dv))
GL_PREFIX(TexCoord2dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord2dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord2f))
GL_PREFIX(TexCoord2f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord2f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord2fv))
GL_PREFIX(TexCoord2fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord2fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord2i))
GL_PREFIX(TexCoord2i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord2i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord2iv))
GL_PREFIX(TexCoord2iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord2iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord2s))
GL_PREFIX(TexCoord2s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord2s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord2sv))
GL_PREFIX(TexCoord2sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord2sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord3d))
GL_PREFIX(TexCoord3d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord3d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord3dv))
GL_PREFIX(TexCoord3dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord3dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord3f))
GL_PREFIX(TexCoord3f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord3f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord3fv))
GL_PREFIX(TexCoord3fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord3fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord3i))
GL_PREFIX(TexCoord3i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord3i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord3iv))
GL_PREFIX(TexCoord3iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord3iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord3s))
GL_PREFIX(TexCoord3s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord3s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord3sv))
GL_PREFIX(TexCoord3sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord3sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord4d))
GL_PREFIX(TexCoord4d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord4d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord4dv))
GL_PREFIX(TexCoord4dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord4dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord4f))
GL_PREFIX(TexCoord4f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord4f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord4fv))
GL_PREFIX(TexCoord4fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord4fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord4i))
GL_PREFIX(TexCoord4i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord4i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord4iv))
GL_PREFIX(TexCoord4iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord4iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord4s))
GL_PREFIX(TexCoord4s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord4s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoord4sv))
GL_PREFIX(TexCoord4sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoord4sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex2d))
GL_PREFIX(Vertex2d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex2d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex2dv))
GL_PREFIX(Vertex2dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex2dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex2f))
GL_PREFIX(Vertex2f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex2f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex2fv))
GL_PREFIX(Vertex2fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex2fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex2i))
GL_PREFIX(Vertex2i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex2i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex2iv))
GL_PREFIX(Vertex2iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex2iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex2s))
GL_PREFIX(Vertex2s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex2s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex2sv))
GL_PREFIX(Vertex2sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex2sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex3d))
GL_PREFIX(Vertex3d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex3d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex3dv))
GL_PREFIX(Vertex3dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex3dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex3f))
GL_PREFIX(Vertex3f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex3f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex3fv))
GL_PREFIX(Vertex3fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex3fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex3i))
GL_PREFIX(Vertex3i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex3i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex3iv))
GL_PREFIX(Vertex3iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex3iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex3s))
GL_PREFIX(Vertex3s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex3s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex3sv))
GL_PREFIX(Vertex3sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex3sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex4d))
GL_PREFIX(Vertex4d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex4d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex4dv))
GL_PREFIX(Vertex4dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex4dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex4f))
GL_PREFIX(Vertex4f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex4f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex4fv))
GL_PREFIX(Vertex4fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex4fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex4i))
GL_PREFIX(Vertex4i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex4i))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex4iv))
GL_PREFIX(Vertex4iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex4iv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex4s))
GL_PREFIX(Vertex4s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex4s))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Vertex4sv))
GL_PREFIX(Vertex4sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Vertex4sv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ClipPlane))
GL_PREFIX(ClipPlane):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ClipPlane))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorMaterial))
GL_PREFIX(ColorMaterial):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorMaterial))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CullFace))
GL_PREFIX(CullFace):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CullFace))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Fogf))
GL_PREFIX(Fogf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Fogf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Fogfv))
GL_PREFIX(Fogfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Fogfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Fogi))
GL_PREFIX(Fogi):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Fogi))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Fogiv))
GL_PREFIX(Fogiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Fogiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FrontFace))
GL_PREFIX(FrontFace):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FrontFace))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Hint))
GL_PREFIX(Hint):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Hint))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Lightf))
GL_PREFIX(Lightf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Lightf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Lightfv))
GL_PREFIX(Lightfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Lightfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Lighti))
GL_PREFIX(Lighti):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Lighti))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Lightiv))
GL_PREFIX(Lightiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Lightiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LightModelf))
GL_PREFIX(LightModelf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LightModelf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LightModelfv))
GL_PREFIX(LightModelfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LightModelfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LightModeli))
GL_PREFIX(LightModeli):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LightModeli))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LightModeliv))
GL_PREFIX(LightModeliv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LightModeliv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LineStipple))
GL_PREFIX(LineStipple):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LineStipple))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LineWidth))
GL_PREFIX(LineWidth):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LineWidth))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Materialf))
GL_PREFIX(Materialf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Materialf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Materialfv))
GL_PREFIX(Materialfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Materialfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Materiali))
GL_PREFIX(Materiali):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Materiali))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Materialiv))
GL_PREFIX(Materialiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Materialiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointSize))
GL_PREFIX(PointSize):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointSize))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PolygonMode))
GL_PREFIX(PolygonMode):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PolygonMode))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PolygonStipple))
GL_PREFIX(PolygonStipple):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PolygonStipple))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Scissor))
GL_PREFIX(Scissor):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Scissor))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ShadeModel))
GL_PREFIX(ShadeModel):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ShadeModel))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexParameterf))
GL_PREFIX(TexParameterf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexParameterf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexParameterfv))
GL_PREFIX(TexParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexParameteri))
GL_PREFIX(TexParameteri):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexParameteri))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexParameteriv))
GL_PREFIX(TexParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexImage1D))
GL_PREFIX(TexImage1D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexImage1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexImage2D))
GL_PREFIX(TexImage2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexImage2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexEnvf))
GL_PREFIX(TexEnvf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexEnvf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexEnvfv))
GL_PREFIX(TexEnvfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexEnvfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexEnvi))
GL_PREFIX(TexEnvi):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexEnvi))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexEnviv))
GL_PREFIX(TexEnviv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexEnviv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexGend))
GL_PREFIX(TexGend):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexGend))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexGendv))
GL_PREFIX(TexGendv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexGendv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexGenf))
GL_PREFIX(TexGenf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexGenf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexGenfv))
GL_PREFIX(TexGenfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexGenfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexGeni))
GL_PREFIX(TexGeni):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexGeni))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexGeniv))
GL_PREFIX(TexGeniv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexGeniv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FeedbackBuffer))
GL_PREFIX(FeedbackBuffer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FeedbackBuffer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SelectBuffer))
GL_PREFIX(SelectBuffer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SelectBuffer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RenderMode))
GL_PREFIX(RenderMode):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RenderMode))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(InitNames))
GL_PREFIX(InitNames):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_InitNames))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadName))
GL_PREFIX(LoadName):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadName))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PassThrough))
GL_PREFIX(PassThrough):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PassThrough))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PopName))
GL_PREFIX(PopName):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PopName))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PushName))
GL_PREFIX(PushName):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PushName))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DrawBuffer))
GL_PREFIX(DrawBuffer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DrawBuffer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Clear))
GL_PREFIX(Clear):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Clear))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ClearAccum))
GL_PREFIX(ClearAccum):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ClearAccum))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ClearIndex))
GL_PREFIX(ClearIndex):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ClearIndex))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ClearColor))
GL_PREFIX(ClearColor):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ClearColor))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ClearStencil))
GL_PREFIX(ClearStencil):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ClearStencil))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ClearDepth))
GL_PREFIX(ClearDepth):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ClearDepth))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(StencilMask))
GL_PREFIX(StencilMask):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_StencilMask))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorMask))
GL_PREFIX(ColorMask):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorMask))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DepthMask))
GL_PREFIX(DepthMask):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DepthMask))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IndexMask))
GL_PREFIX(IndexMask):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IndexMask))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Accum))
GL_PREFIX(Accum):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Accum))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Disable))
GL_PREFIX(Disable):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Disable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Enable))
GL_PREFIX(Enable):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Enable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Finish))
GL_PREFIX(Finish):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Finish))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Flush))
GL_PREFIX(Flush):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Flush))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PopAttrib))
GL_PREFIX(PopAttrib):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PopAttrib))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PushAttrib))
GL_PREFIX(PushAttrib):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PushAttrib))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Map1d))
GL_PREFIX(Map1d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Map1d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Map1f))
GL_PREFIX(Map1f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Map1f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Map2d))
GL_PREFIX(Map2d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Map2d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Map2f))
GL_PREFIX(Map2f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Map2f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MapGrid1d))
GL_PREFIX(MapGrid1d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MapGrid1d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MapGrid1f))
GL_PREFIX(MapGrid1f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MapGrid1f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MapGrid2d))
GL_PREFIX(MapGrid2d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MapGrid2d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MapGrid2f))
GL_PREFIX(MapGrid2f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MapGrid2f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalCoord1d))
GL_PREFIX(EvalCoord1d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalCoord1d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalCoord1dv))
GL_PREFIX(EvalCoord1dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalCoord1dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalCoord1f))
GL_PREFIX(EvalCoord1f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalCoord1f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalCoord1fv))
GL_PREFIX(EvalCoord1fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalCoord1fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalCoord2d))
GL_PREFIX(EvalCoord2d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalCoord2d))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalCoord2dv))
GL_PREFIX(EvalCoord2dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalCoord2dv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalCoord2f))
GL_PREFIX(EvalCoord2f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalCoord2f))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalCoord2fv))
GL_PREFIX(EvalCoord2fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalCoord2fv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalMesh1))
GL_PREFIX(EvalMesh1):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalMesh1))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalPoint1))
GL_PREFIX(EvalPoint1):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalPoint1))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalMesh2))
GL_PREFIX(EvalMesh2):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalMesh2))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EvalPoint2))
GL_PREFIX(EvalPoint2):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EvalPoint2))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(AlphaFunc))
GL_PREFIX(AlphaFunc):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_AlphaFunc))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BlendFunc))
GL_PREFIX(BlendFunc):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BlendFunc))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LogicOp))
GL_PREFIX(LogicOp):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LogicOp))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(StencilFunc))
GL_PREFIX(StencilFunc):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_StencilFunc))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(StencilOp))
GL_PREFIX(StencilOp):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_StencilOp))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DepthFunc))
GL_PREFIX(DepthFunc):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DepthFunc))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelZoom))
GL_PREFIX(PixelZoom):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelZoom))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelTransferf))
GL_PREFIX(PixelTransferf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelTransferf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelTransferi))
GL_PREFIX(PixelTransferi):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelTransferi))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelStoref))
GL_PREFIX(PixelStoref):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelStoref))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelStorei))
GL_PREFIX(PixelStorei):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelStorei))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelMapfv))
GL_PREFIX(PixelMapfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelMapfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelMapuiv))
GL_PREFIX(PixelMapuiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelMapuiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelMapusv))
GL_PREFIX(PixelMapusv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelMapusv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ReadBuffer))
GL_PREFIX(ReadBuffer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ReadBuffer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyPixels))
GL_PREFIX(CopyPixels):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyPixels))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ReadPixels))
GL_PREFIX(ReadPixels):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ReadPixels))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DrawPixels))
GL_PREFIX(DrawPixels):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DrawPixels))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetBooleanv))
GL_PREFIX(GetBooleanv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetBooleanv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetClipPlane))
GL_PREFIX(GetClipPlane):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetClipPlane))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetDoublev))
GL_PREFIX(GetDoublev):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetDoublev))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetError))
GL_PREFIX(GetError):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetError))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetFloatv))
GL_PREFIX(GetFloatv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetFloatv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetIntegerv))
GL_PREFIX(GetIntegerv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetIntegerv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetLightfv))
GL_PREFIX(GetLightfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetLightfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetLightiv))
GL_PREFIX(GetLightiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetLightiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMapdv))
GL_PREFIX(GetMapdv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMapdv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMapfv))
GL_PREFIX(GetMapfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMapfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMapiv))
GL_PREFIX(GetMapiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMapiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMaterialfv))
GL_PREFIX(GetMaterialfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMaterialfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMaterialiv))
GL_PREFIX(GetMaterialiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMaterialiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetPixelMapfv))
GL_PREFIX(GetPixelMapfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetPixelMapfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetPixelMapuiv))
GL_PREFIX(GetPixelMapuiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetPixelMapuiv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetPixelMapusv))
GL_PREFIX(GetPixelMapusv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetPixelMapusv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetPolygonStipple))
GL_PREFIX(GetPolygonStipple):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetPolygonStipple))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetString))
GL_PREFIX(GetString):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetString))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexEnvfv))
GL_PREFIX(GetTexEnvfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexEnvfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexEnviv))
GL_PREFIX(GetTexEnviv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexEnviv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexGendv))
GL_PREFIX(GetTexGendv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexGendv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexGenfv))
GL_PREFIX(GetTexGenfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexGenfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexGeniv))
GL_PREFIX(GetTexGeniv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexGeniv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexImage))
GL_PREFIX(GetTexImage):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexImage))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexParameterfv))
GL_PREFIX(GetTexParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexParameteriv))
GL_PREFIX(GetTexParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexLevelParameterfv))
GL_PREFIX(GetTexLevelParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexLevelParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexLevelParameteriv))
GL_PREFIX(GetTexLevelParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexLevelParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IsEnabled))
GL_PREFIX(IsEnabled):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IsEnabled))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IsList))
GL_PREFIX(IsList):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IsList))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DepthRange))
GL_PREFIX(DepthRange):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DepthRange))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Frustum))
GL_PREFIX(Frustum):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Frustum))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadIdentity))
GL_PREFIX(LoadIdentity):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadIdentity))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadMatrixf))
GL_PREFIX(LoadMatrixf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadMatrixf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadMatrixd))
GL_PREFIX(LoadMatrixd):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadMatrixd))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MatrixMode))
GL_PREFIX(MatrixMode):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MatrixMode))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultMatrixf))
GL_PREFIX(MultMatrixf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultMatrixf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultMatrixd))
GL_PREFIX(MultMatrixd):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultMatrixd))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Ortho))
GL_PREFIX(Ortho):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Ortho))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PopMatrix))
GL_PREFIX(PopMatrix):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PopMatrix))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PushMatrix))
GL_PREFIX(PushMatrix):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PushMatrix))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rotated))
GL_PREFIX(Rotated):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rotated))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Rotatef))
GL_PREFIX(Rotatef):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Rotatef))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Scaled))
GL_PREFIX(Scaled):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Scaled))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Scalef))
GL_PREFIX(Scalef):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Scalef))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Translated))
GL_PREFIX(Translated):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Translated))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Translatef))
GL_PREFIX(Translatef):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Translatef))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Viewport))
GL_PREFIX(Viewport):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Viewport))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ArrayElement))
GL_PREFIX(ArrayElement):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ArrayElement))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorPointer))
GL_PREFIX(ColorPointer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorPointer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DisableClientState))
GL_PREFIX(DisableClientState):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DisableClientState))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DrawArrays))
GL_PREFIX(DrawArrays):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DrawArrays))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DrawElements))
GL_PREFIX(DrawElements):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DrawElements))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EdgeFlagPointer))
GL_PREFIX(EdgeFlagPointer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EdgeFlagPointer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EnableClientState))
GL_PREFIX(EnableClientState):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EnableClientState))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetPointerv))
GL_PREFIX(GetPointerv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetPointerv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IndexPointer))
GL_PREFIX(IndexPointer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IndexPointer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(InterleavedArrays))
GL_PREFIX(InterleavedArrays):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_InterleavedArrays))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(NormalPointer))
GL_PREFIX(NormalPointer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_NormalPointer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoordPointer))
GL_PREFIX(TexCoordPointer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoordPointer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexPointer))
GL_PREFIX(VertexPointer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexPointer))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PolygonOffset))
GL_PREFIX(PolygonOffset):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PolygonOffset))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexImage1D))
GL_PREFIX(CopyTexImage1D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexImage1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexImage2D))
GL_PREFIX(CopyTexImage2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexImage2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexSubImage1D))
GL_PREFIX(CopyTexSubImage1D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexSubImage1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexSubImage2D))
GL_PREFIX(CopyTexSubImage2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexSubImage2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexSubImage1D))
GL_PREFIX(TexSubImage1D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexSubImage1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexSubImage2D))
GL_PREFIX(TexSubImage2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexSubImage2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(AreTexturesResident))
GL_PREFIX(AreTexturesResident):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_AreTexturesResident))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BindTexture))
GL_PREFIX(BindTexture):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BindTexture))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DeleteTextures))
GL_PREFIX(DeleteTextures):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DeleteTextures))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GenTextures))
GL_PREFIX(GenTextures):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GenTextures))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IsTexture))
GL_PREFIX(IsTexture):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IsTexture))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PrioritizeTextures))
GL_PREFIX(PrioritizeTextures):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PrioritizeTextures))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexub))
GL_PREFIX(Indexub):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexub))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Indexubv))
GL_PREFIX(Indexubv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Indexubv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PopClientAttrib))
GL_PREFIX(PopClientAttrib):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PopClientAttrib))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PushClientAttrib))
GL_PREFIX(PushClientAttrib):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PushClientAttrib))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BlendColor))
GL_PREFIX(BlendColor):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BlendColor))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BlendEquation))
GL_PREFIX(BlendEquation):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BlendEquation))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DrawRangeElements))
GL_PREFIX(DrawRangeElements):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DrawRangeElements))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorTable))
GL_PREFIX(ColorTable):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorTableParameterfv))
GL_PREFIX(ColorTableParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorTableParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorTableParameteriv))
GL_PREFIX(ColorTableParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorTableParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyColorTable))
GL_PREFIX(CopyColorTable):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyColorTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTable))
GL_PREFIX(GetColorTable):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTableParameterfv))
GL_PREFIX(GetColorTableParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTableParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTableParameteriv))
GL_PREFIX(GetColorTableParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTableParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorSubTable))
GL_PREFIX(ColorSubTable):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorSubTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyColorSubTable))
GL_PREFIX(CopyColorSubTable):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyColorSubTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionFilter1D))
GL_PREFIX(ConvolutionFilter1D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionFilter1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionFilter2D))
GL_PREFIX(ConvolutionFilter2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionFilter2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionParameterf))
GL_PREFIX(ConvolutionParameterf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionParameterf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionParameterfv))
GL_PREFIX(ConvolutionParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionParameteri))
GL_PREFIX(ConvolutionParameteri):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionParameteri))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionParameteriv))
GL_PREFIX(ConvolutionParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyConvolutionFilter1D))
GL_PREFIX(CopyConvolutionFilter1D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyConvolutionFilter1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyConvolutionFilter2D))
GL_PREFIX(CopyConvolutionFilter2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyConvolutionFilter2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetConvolutionFilter))
GL_PREFIX(GetConvolutionFilter):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetConvolutionFilter))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetConvolutionParameterfv))
GL_PREFIX(GetConvolutionParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetConvolutionParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetConvolutionParameteriv))
GL_PREFIX(GetConvolutionParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetConvolutionParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetSeparableFilter))
GL_PREFIX(GetSeparableFilter):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetSeparableFilter))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SeparableFilter2D))
GL_PREFIX(SeparableFilter2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SeparableFilter2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetHistogram))
GL_PREFIX(GetHistogram):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetHistogram))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetHistogramParameterfv))
GL_PREFIX(GetHistogramParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetHistogramParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetHistogramParameteriv))
GL_PREFIX(GetHistogramParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetHistogramParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMinmax))
GL_PREFIX(GetMinmax):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMinmax))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMinmaxParameterfv))
GL_PREFIX(GetMinmaxParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMinmaxParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMinmaxParameteriv))
GL_PREFIX(GetMinmaxParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMinmaxParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Histogram))
GL_PREFIX(Histogram):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Histogram))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(Minmax))
GL_PREFIX(Minmax):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Minmax))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ResetHistogram))
GL_PREFIX(ResetHistogram):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ResetHistogram))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ResetMinmax))
GL_PREFIX(ResetMinmax):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ResetMinmax))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexImage3D))
GL_PREFIX(TexImage3D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexImage3D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexSubImage3D))
GL_PREFIX(TexSubImage3D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexSubImage3D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexSubImage3D))
GL_PREFIX(CopyTexSubImage3D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexSubImage3D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ActiveTextureARB))
GL_PREFIX(ActiveTextureARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ActiveTextureARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ClientActiveTextureARB))
GL_PREFIX(ClientActiveTextureARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ClientActiveTextureARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1dARB))
GL_PREFIX(MultiTexCoord1dARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1dARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1dvARB))
GL_PREFIX(MultiTexCoord1dvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1dvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1fARB))
GL_PREFIX(MultiTexCoord1fARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1fARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1fvARB))
GL_PREFIX(MultiTexCoord1fvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1fvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1iARB))
GL_PREFIX(MultiTexCoord1iARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1iARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1ivARB))
GL_PREFIX(MultiTexCoord1ivARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1ivARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1sARB))
GL_PREFIX(MultiTexCoord1sARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1sARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1svARB))
GL_PREFIX(MultiTexCoord1svARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1svARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2dARB))
GL_PREFIX(MultiTexCoord2dARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2dARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2dvARB))
GL_PREFIX(MultiTexCoord2dvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2dvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2fARB))
GL_PREFIX(MultiTexCoord2fARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2fARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2fvARB))
GL_PREFIX(MultiTexCoord2fvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2fvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2iARB))
GL_PREFIX(MultiTexCoord2iARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2iARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2ivARB))
GL_PREFIX(MultiTexCoord2ivARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2ivARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2sARB))
GL_PREFIX(MultiTexCoord2sARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2sARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2svARB))
GL_PREFIX(MultiTexCoord2svARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2svARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3dARB))
GL_PREFIX(MultiTexCoord3dARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3dARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3dvARB))
GL_PREFIX(MultiTexCoord3dvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3dvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3fARB))
GL_PREFIX(MultiTexCoord3fARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3fARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3fvARB))
GL_PREFIX(MultiTexCoord3fvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3fvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3iARB))
GL_PREFIX(MultiTexCoord3iARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3iARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3ivARB))
GL_PREFIX(MultiTexCoord3ivARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3ivARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3sARB))
GL_PREFIX(MultiTexCoord3sARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3sARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3svARB))
GL_PREFIX(MultiTexCoord3svARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3svARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4dARB))
GL_PREFIX(MultiTexCoord4dARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4dARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4dvARB))
GL_PREFIX(MultiTexCoord4dvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4dvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4fARB))
GL_PREFIX(MultiTexCoord4fARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4fARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4fvARB))
GL_PREFIX(MultiTexCoord4fvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4fvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4iARB))
GL_PREFIX(MultiTexCoord4iARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4iARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4ivARB))
GL_PREFIX(MultiTexCoord4ivARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4ivARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4sARB))
GL_PREFIX(MultiTexCoord4sARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4sARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4svARB))
GL_PREFIX(MultiTexCoord4svARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4svARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadTransposeMatrixfARB))
GL_PREFIX(LoadTransposeMatrixfARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadTransposeMatrixfARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadTransposeMatrixdARB))
GL_PREFIX(LoadTransposeMatrixdARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadTransposeMatrixdARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultTransposeMatrixfARB))
GL_PREFIX(MultTransposeMatrixfARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultTransposeMatrixfARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultTransposeMatrixdARB))
GL_PREFIX(MultTransposeMatrixdARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultTransposeMatrixdARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SampleCoverageARB))
GL_PREFIX(SampleCoverageARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SampleCoverageARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(__unused413))
GL_PREFIX(__unused413):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset___unused413))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexImage3DARB))
GL_PREFIX(CompressedTexImage3DARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexImage3DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexImage2DARB))
GL_PREFIX(CompressedTexImage2DARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexImage2DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexImage1DARB))
GL_PREFIX(CompressedTexImage1DARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexImage1DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexSubImage3DARB))
GL_PREFIX(CompressedTexSubImage3DARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexSubImage3DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexSubImage2DARB))
GL_PREFIX(CompressedTexSubImage2DARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexSubImage2DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexSubImage1DARB))
GL_PREFIX(CompressedTexSubImage1DARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexSubImage1DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetCompressedTexImageARB))
GL_PREFIX(GetCompressedTexImageARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetCompressedTexImageARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ActiveTexture))
GL_PREFIX(ActiveTexture):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ActiveTextureARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ClientActiveTexture))
GL_PREFIX(ClientActiveTexture):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ClientActiveTextureARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1d))
GL_PREFIX(MultiTexCoord1d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1dARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1dv))
GL_PREFIX(MultiTexCoord1dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1dvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1f))
GL_PREFIX(MultiTexCoord1f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1fARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1fv))
GL_PREFIX(MultiTexCoord1fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1fvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1i))
GL_PREFIX(MultiTexCoord1i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1iARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1iv))
GL_PREFIX(MultiTexCoord1iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1ivARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1s))
GL_PREFIX(MultiTexCoord1s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1sARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord1sv))
GL_PREFIX(MultiTexCoord1sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord1svARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2d))
GL_PREFIX(MultiTexCoord2d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2dARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2dv))
GL_PREFIX(MultiTexCoord2dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2dvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2f))
GL_PREFIX(MultiTexCoord2f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2fARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2fv))
GL_PREFIX(MultiTexCoord2fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2fvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2i))
GL_PREFIX(MultiTexCoord2i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2iARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2iv))
GL_PREFIX(MultiTexCoord2iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2ivARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2s))
GL_PREFIX(MultiTexCoord2s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2sARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord2sv))
GL_PREFIX(MultiTexCoord2sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord2svARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3d))
GL_PREFIX(MultiTexCoord3d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3dARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3dv))
GL_PREFIX(MultiTexCoord3dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3dvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3f))
GL_PREFIX(MultiTexCoord3f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3fARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3fv))
GL_PREFIX(MultiTexCoord3fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3fvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3i))
GL_PREFIX(MultiTexCoord3i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3iARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3iv))
GL_PREFIX(MultiTexCoord3iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3ivARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3s))
GL_PREFIX(MultiTexCoord3s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3sARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord3sv))
GL_PREFIX(MultiTexCoord3sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord3svARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4d))
GL_PREFIX(MultiTexCoord4d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4dARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4dv))
GL_PREFIX(MultiTexCoord4dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4dvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4f))
GL_PREFIX(MultiTexCoord4f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4fARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4fv))
GL_PREFIX(MultiTexCoord4fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4fvARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4i))
GL_PREFIX(MultiTexCoord4i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4iARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4iv))
GL_PREFIX(MultiTexCoord4iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4ivARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4s))
GL_PREFIX(MultiTexCoord4s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4sARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiTexCoord4sv))
GL_PREFIX(MultiTexCoord4sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiTexCoord4svARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadTransposeMatrixf))
GL_PREFIX(LoadTransposeMatrixf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadTransposeMatrixfARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadTransposeMatrixd))
GL_PREFIX(LoadTransposeMatrixd):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadTransposeMatrixdARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultTransposeMatrixf))
GL_PREFIX(MultTransposeMatrixf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultTransposeMatrixfARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultTransposeMatrixd))
GL_PREFIX(MultTransposeMatrixd):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultTransposeMatrixdARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SampleCoverage))
GL_PREFIX(SampleCoverage):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SampleCoverageARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexImage3D))
GL_PREFIX(CompressedTexImage3D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexImage3DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexImage2D))
GL_PREFIX(CompressedTexImage2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexImage2DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexImage1D))
GL_PREFIX(CompressedTexImage1D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexImage1DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexSubImage3D))
GL_PREFIX(CompressedTexSubImage3D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexSubImage3DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexSubImage2D))
GL_PREFIX(CompressedTexSubImage2D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexSubImage2DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CompressedTexSubImage1D))
GL_PREFIX(CompressedTexSubImage1D):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CompressedTexSubImage1DARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetCompressedTexImage))
GL_PREFIX(GetCompressedTexImage):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetCompressedTexImageARB))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BlendColorEXT))
GL_PREFIX(BlendColorEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BlendColor))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PolygonOffsetEXT))
GL_PREFIX(PolygonOffsetEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PolygonOffsetEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexImage3DEXT))
GL_PREFIX(TexImage3DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexImage3D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexSubImage3DEXT))
GL_PREFIX(TexSubImage3DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexSubImage3D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTexFilterFuncSGIS))
GL_PREFIX(GetTexFilterFuncSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTexFilterFuncSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexFilterFuncSGIS))
GL_PREFIX(TexFilterFuncSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexFilterFuncSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexSubImage1DEXT))
GL_PREFIX(TexSubImage1DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexSubImage1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexSubImage2DEXT))
GL_PREFIX(TexSubImage2DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexSubImage2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexImage1DEXT))
GL_PREFIX(CopyTexImage1DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexImage1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexImage2DEXT))
GL_PREFIX(CopyTexImage2DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexImage2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexSubImage1DEXT))
GL_PREFIX(CopyTexSubImage1DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexSubImage1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexSubImage2DEXT))
GL_PREFIX(CopyTexSubImage2DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexSubImage2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyTexSubImage3DEXT))
GL_PREFIX(CopyTexSubImage3DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyTexSubImage3D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetHistogramEXT))
GL_PREFIX(GetHistogramEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetHistogramEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetHistogramParameterfvEXT))
GL_PREFIX(GetHistogramParameterfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetHistogramParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetHistogramParameterivEXT))
GL_PREFIX(GetHistogramParameterivEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetHistogramParameterivEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMinmaxEXT))
GL_PREFIX(GetMinmaxEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMinmaxEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMinmaxParameterfvEXT))
GL_PREFIX(GetMinmaxParameterfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMinmaxParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetMinmaxParameterivEXT))
GL_PREFIX(GetMinmaxParameterivEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetMinmaxParameterivEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(HistogramEXT))
GL_PREFIX(HistogramEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Histogram))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MinmaxEXT))
GL_PREFIX(MinmaxEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_Minmax))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ResetHistogramEXT))
GL_PREFIX(ResetHistogramEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ResetHistogram))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ResetMinmaxEXT))
GL_PREFIX(ResetMinmaxEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ResetMinmax))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionFilter1DEXT))
GL_PREFIX(ConvolutionFilter1DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionFilter1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionFilter2DEXT))
GL_PREFIX(ConvolutionFilter2DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionFilter2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionParameterfEXT))
GL_PREFIX(ConvolutionParameterfEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionParameterf))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionParameterfvEXT))
GL_PREFIX(ConvolutionParameterfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionParameteriEXT))
GL_PREFIX(ConvolutionParameteriEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionParameteri))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ConvolutionParameterivEXT))
GL_PREFIX(ConvolutionParameterivEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ConvolutionParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyConvolutionFilter1DEXT))
GL_PREFIX(CopyConvolutionFilter1DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyConvolutionFilter1D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyConvolutionFilter2DEXT))
GL_PREFIX(CopyConvolutionFilter2DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyConvolutionFilter2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetConvolutionFilterEXT))
GL_PREFIX(GetConvolutionFilterEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetConvolutionFilterEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetConvolutionParameterfvEXT))
GL_PREFIX(GetConvolutionParameterfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetConvolutionParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetConvolutionParameterivEXT))
GL_PREFIX(GetConvolutionParameterivEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetConvolutionParameterivEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetSeparableFilterEXT))
GL_PREFIX(GetSeparableFilterEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetSeparableFilterEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SeparableFilter2DEXT))
GL_PREFIX(SeparableFilter2DEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SeparableFilter2D))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorTableSGI))
GL_PREFIX(ColorTableSGI):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorTableParameterfvSGI))
GL_PREFIX(ColorTableParameterfvSGI):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorTableParameterfv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorTableParameterivSGI))
GL_PREFIX(ColorTableParameterivSGI):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorTableParameteriv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyColorTableSGI))
GL_PREFIX(CopyColorTableSGI):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyColorTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTableSGI))
GL_PREFIX(GetColorTableSGI):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTableSGI))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTableParameterfvSGI))
GL_PREFIX(GetColorTableParameterfvSGI):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTableParameterfvSGI))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTableParameterivSGI))
GL_PREFIX(GetColorTableParameterivSGI):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTableParameterivSGI))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelTexGenSGIX))
GL_PREFIX(PixelTexGenSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelTexGenSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelTexGenParameteriSGIS))
GL_PREFIX(PixelTexGenParameteriSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelTexGenParameteriSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelTexGenParameterivSGIS))
GL_PREFIX(PixelTexGenParameterivSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelTexGenParameterivSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelTexGenParameterfSGIS))
GL_PREFIX(PixelTexGenParameterfSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelTexGenParameterfSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PixelTexGenParameterfvSGIS))
GL_PREFIX(PixelTexGenParameterfvSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PixelTexGenParameterfvSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetPixelTexGenParameterivSGIS))
GL_PREFIX(GetPixelTexGenParameterivSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetPixelTexGenParameterivSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetPixelTexGenParameterfvSGIS))
GL_PREFIX(GetPixelTexGenParameterfvSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetPixelTexGenParameterfvSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexImage4DSGIS))
GL_PREFIX(TexImage4DSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexImage4DSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexSubImage4DSGIS))
GL_PREFIX(TexSubImage4DSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexSubImage4DSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(AreTexturesResidentEXT))
GL_PREFIX(AreTexturesResidentEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_AreTexturesResidentEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BindTextureEXT))
GL_PREFIX(BindTextureEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BindTexture))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DeleteTexturesEXT))
GL_PREFIX(DeleteTexturesEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DeleteTextures))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GenTexturesEXT))
GL_PREFIX(GenTexturesEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GenTexturesEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IsTextureEXT))
GL_PREFIX(IsTextureEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IsTextureEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PrioritizeTexturesEXT))
GL_PREFIX(PrioritizeTexturesEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PrioritizeTextures))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DetailTexFuncSGIS))
GL_PREFIX(DetailTexFuncSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DetailTexFuncSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetDetailTexFuncSGIS))
GL_PREFIX(GetDetailTexFuncSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetDetailTexFuncSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SharpenTexFuncSGIS))
GL_PREFIX(SharpenTexFuncSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SharpenTexFuncSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetSharpenTexFuncSGIS))
GL_PREFIX(GetSharpenTexFuncSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetSharpenTexFuncSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SampleMaskSGIS))
GL_PREFIX(SampleMaskSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SampleMaskSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SamplePatternSGIS))
GL_PREFIX(SamplePatternSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SamplePatternSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ArrayElementEXT))
GL_PREFIX(ArrayElementEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ArrayElement))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorPointerEXT))
GL_PREFIX(ColorPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DrawArraysEXT))
GL_PREFIX(DrawArraysEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DrawArrays))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(EdgeFlagPointerEXT))
GL_PREFIX(EdgeFlagPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_EdgeFlagPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetPointervEXT))
GL_PREFIX(GetPointervEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetPointerv))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IndexPointerEXT))
GL_PREFIX(IndexPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IndexPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(NormalPointerEXT))
GL_PREFIX(NormalPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_NormalPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TexCoordPointerEXT))
GL_PREFIX(TexCoordPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TexCoordPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexPointerEXT))
GL_PREFIX(VertexPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BlendEquationEXT))
GL_PREFIX(BlendEquationEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BlendEquation))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SpriteParameterfSGIX))
GL_PREFIX(SpriteParameterfSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SpriteParameterfSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SpriteParameterfvSGIX))
GL_PREFIX(SpriteParameterfvSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SpriteParameterfvSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SpriteParameteriSGIX))
GL_PREFIX(SpriteParameteriSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SpriteParameteriSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SpriteParameterivSGIX))
GL_PREFIX(SpriteParameterivSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SpriteParameterivSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterfEXT))
GL_PREFIX(PointParameterfEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterfEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterfvEXT))
GL_PREFIX(PointParameterfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterfARB))
GL_PREFIX(PointParameterfARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterfEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterfvARB))
GL_PREFIX(PointParameterfvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterfSGIS))
GL_PREFIX(PointParameterfSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterfEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterfvSGIS))
GL_PREFIX(PointParameterfvSGIS):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetInstrumentsSGIX))
GL_PREFIX(GetInstrumentsSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetInstrumentsSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(InstrumentsBufferSGIX))
GL_PREFIX(InstrumentsBufferSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_InstrumentsBufferSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PollInstrumentsSGIX))
GL_PREFIX(PollInstrumentsSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PollInstrumentsSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ReadInstrumentsSGIX))
GL_PREFIX(ReadInstrumentsSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ReadInstrumentsSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(StartInstrumentsSGIX))
GL_PREFIX(StartInstrumentsSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_StartInstrumentsSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(StopInstrumentsSGIX))
GL_PREFIX(StopInstrumentsSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_StopInstrumentsSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FrameZoomSGIX))
GL_PREFIX(FrameZoomSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FrameZoomSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TagSampleBufferSGIX))
GL_PREFIX(TagSampleBufferSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TagSampleBufferSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ReferencePlaneSGIX))
GL_PREFIX(ReferencePlaneSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ReferencePlaneSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FlushRasterSGIX))
GL_PREFIX(FlushRasterSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FlushRasterSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorSubTableEXT))
GL_PREFIX(ColorSubTableEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorSubTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CopyColorSubTableEXT))
GL_PREFIX(CopyColorSubTableEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CopyColorSubTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(HintPGI))
GL_PREFIX(HintPGI):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_HintPGI))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ColorTableEXT))
GL_PREFIX(ColorTableEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ColorTable))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTableEXT))
GL_PREFIX(GetColorTableEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTableEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTableParameterivEXT))
GL_PREFIX(GetColorTableParameterivEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTableParameterivEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetColorTableParameterfvEXT))
GL_PREFIX(GetColorTableParameterfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetColorTableParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetListParameterfvSGIX))
GL_PREFIX(GetListParameterfvSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetListParameterfvSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetListParameterivSGIX))
GL_PREFIX(GetListParameterivSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetListParameterivSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ListParameterfSGIX))
GL_PREFIX(ListParameterfSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ListParameterfSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ListParameterfvSGIX))
GL_PREFIX(ListParameterfvSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ListParameterfvSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ListParameteriSGIX))
GL_PREFIX(ListParameteriSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ListParameteriSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ListParameterivSGIX))
GL_PREFIX(ListParameterivSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ListParameterivSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IndexMaterialEXT))
GL_PREFIX(IndexMaterialEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IndexMaterialEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IndexFuncEXT))
GL_PREFIX(IndexFuncEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IndexFuncEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LockArraysEXT))
GL_PREFIX(LockArraysEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LockArraysEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(UnlockArraysEXT))
GL_PREFIX(UnlockArraysEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_UnlockArraysEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CullParameterdvEXT))
GL_PREFIX(CullParameterdvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CullParameterdvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CullParameterfvEXT))
GL_PREFIX(CullParameterfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CullParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentColorMaterialSGIX))
GL_PREFIX(FragmentColorMaterialSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentColorMaterialSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentLightfSGIX))
GL_PREFIX(FragmentLightfSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentLightfSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentLightfvSGIX))
GL_PREFIX(FragmentLightfvSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentLightfvSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentLightiSGIX))
GL_PREFIX(FragmentLightiSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentLightiSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentLightivSGIX))
GL_PREFIX(FragmentLightivSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentLightivSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentLightModelfSGIX))
GL_PREFIX(FragmentLightModelfSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentLightModelfSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentLightModelfvSGIX))
GL_PREFIX(FragmentLightModelfvSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentLightModelfvSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentLightModeliSGIX))
GL_PREFIX(FragmentLightModeliSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentLightModeliSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentLightModelivSGIX))
GL_PREFIX(FragmentLightModelivSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentLightModelivSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentMaterialfSGIX))
GL_PREFIX(FragmentMaterialfSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentMaterialfSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentMaterialfvSGIX))
GL_PREFIX(FragmentMaterialfvSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentMaterialfvSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentMaterialiSGIX))
GL_PREFIX(FragmentMaterialiSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentMaterialiSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FragmentMaterialivSGIX))
GL_PREFIX(FragmentMaterialivSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FragmentMaterialivSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetFragmentLightfvSGIX))
GL_PREFIX(GetFragmentLightfvSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetFragmentLightfvSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetFragmentLightivSGIX))
GL_PREFIX(GetFragmentLightivSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetFragmentLightivSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetFragmentMaterialfvSGIX))
GL_PREFIX(GetFragmentMaterialfvSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetFragmentMaterialfvSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetFragmentMaterialivSGIX))
GL_PREFIX(GetFragmentMaterialivSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetFragmentMaterialivSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LightEnviSGIX))
GL_PREFIX(LightEnviSGIX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LightEnviSGIX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DrawRangeElementsEXT))
GL_PREFIX(DrawRangeElementsEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DrawRangeElements))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3bEXT))
GL_PREFIX(SecondaryColor3bEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3bEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3bvEXT))
GL_PREFIX(SecondaryColor3bvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3bvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3dEXT))
GL_PREFIX(SecondaryColor3dEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3dEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3dvEXT))
GL_PREFIX(SecondaryColor3dvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3dvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3fEXT))
GL_PREFIX(SecondaryColor3fEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3fEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3fvEXT))
GL_PREFIX(SecondaryColor3fvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3fvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3iEXT))
GL_PREFIX(SecondaryColor3iEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3iEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3ivEXT))
GL_PREFIX(SecondaryColor3ivEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3ivEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3sEXT))
GL_PREFIX(SecondaryColor3sEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3sEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3svEXT))
GL_PREFIX(SecondaryColor3svEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3svEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3ubEXT))
GL_PREFIX(SecondaryColor3ubEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3ubEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3ubvEXT))
GL_PREFIX(SecondaryColor3ubvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3ubvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3uiEXT))
GL_PREFIX(SecondaryColor3uiEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3uiEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3uivEXT))
GL_PREFIX(SecondaryColor3uivEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3uivEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3usEXT))
GL_PREFIX(SecondaryColor3usEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3usEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3usvEXT))
GL_PREFIX(SecondaryColor3usvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3usvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColorPointerEXT))
GL_PREFIX(SecondaryColorPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColorPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiDrawArraysEXT))
GL_PREFIX(MultiDrawArraysEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiDrawArraysEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiDrawElementsEXT))
GL_PREFIX(MultiDrawElementsEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiDrawElementsEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoordfEXT))
GL_PREFIX(FogCoordfEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoordfEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoordfvEXT))
GL_PREFIX(FogCoordfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoordfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoorddEXT))
GL_PREFIX(FogCoorddEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoorddEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoorddvEXT))
GL_PREFIX(FogCoorddvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoorddvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoordPointerEXT))
GL_PREFIX(FogCoordPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoordPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BlendFuncSeparateEXT))
GL_PREFIX(BlendFuncSeparateEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BlendFuncSeparateEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BlendFuncSeparateINGR))
GL_PREFIX(BlendFuncSeparateINGR):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BlendFuncSeparateEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexWeightfEXT))
GL_PREFIX(VertexWeightfEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexWeightfEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexWeightfvEXT))
GL_PREFIX(VertexWeightfvEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexWeightfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexWeightPointerEXT))
GL_PREFIX(VertexWeightPointerEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexWeightPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FlushVertexArrayRangeNV))
GL_PREFIX(FlushVertexArrayRangeNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FlushVertexArrayRangeNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexArrayRangeNV))
GL_PREFIX(VertexArrayRangeNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexArrayRangeNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CombinerParameterfvNV))
GL_PREFIX(CombinerParameterfvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CombinerParameterfvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CombinerParameterfNV))
GL_PREFIX(CombinerParameterfNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CombinerParameterfNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CombinerParameterivNV))
GL_PREFIX(CombinerParameterivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CombinerParameterivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CombinerParameteriNV))
GL_PREFIX(CombinerParameteriNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CombinerParameteriNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CombinerInputNV))
GL_PREFIX(CombinerInputNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CombinerInputNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(CombinerOutputNV))
GL_PREFIX(CombinerOutputNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_CombinerOutputNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FinalCombinerInputNV))
GL_PREFIX(FinalCombinerInputNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FinalCombinerInputNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetCombinerInputParameterfvNV))
GL_PREFIX(GetCombinerInputParameterfvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetCombinerInputParameterfvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetCombinerInputParameterivNV))
GL_PREFIX(GetCombinerInputParameterivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetCombinerInputParameterivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetCombinerOutputParameterfvNV))
GL_PREFIX(GetCombinerOutputParameterfvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetCombinerOutputParameterfvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetCombinerOutputParameterivNV))
GL_PREFIX(GetCombinerOutputParameterivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetCombinerOutputParameterivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetFinalCombinerInputParameterfvNV))
GL_PREFIX(GetFinalCombinerInputParameterfvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetFinalCombinerInputParameterfvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetFinalCombinerInputParameterivNV))
GL_PREFIX(GetFinalCombinerInputParameterivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetFinalCombinerInputParameterivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ResizeBuffersMESA))
GL_PREFIX(ResizeBuffersMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ResizeBuffersMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2dMESA))
GL_PREFIX(WindowPos2dMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2dMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2dvMESA))
GL_PREFIX(WindowPos2dvMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2dvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2fMESA))
GL_PREFIX(WindowPos2fMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2fMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2fvMESA))
GL_PREFIX(WindowPos2fvMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2fvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2iMESA))
GL_PREFIX(WindowPos2iMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2iMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2ivMESA))
GL_PREFIX(WindowPos2ivMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2ivMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2sMESA))
GL_PREFIX(WindowPos2sMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2sMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2svMESA))
GL_PREFIX(WindowPos2svMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2svMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3dMESA))
GL_PREFIX(WindowPos3dMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3dMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3dvMESA))
GL_PREFIX(WindowPos3dvMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3dvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3fMESA))
GL_PREFIX(WindowPos3fMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3fMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3fvMESA))
GL_PREFIX(WindowPos3fvMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3fvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3iMESA))
GL_PREFIX(WindowPos3iMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3iMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3ivMESA))
GL_PREFIX(WindowPos3ivMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3ivMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3sMESA))
GL_PREFIX(WindowPos3sMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3sMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3svMESA))
GL_PREFIX(WindowPos3svMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3svMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos4dMESA))
GL_PREFIX(WindowPos4dMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos4dMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos4dvMESA))
GL_PREFIX(WindowPos4dvMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos4dvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos4fMESA))
GL_PREFIX(WindowPos4fMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos4fMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos4fvMESA))
GL_PREFIX(WindowPos4fvMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos4fvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos4iMESA))
GL_PREFIX(WindowPos4iMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos4iMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos4ivMESA))
GL_PREFIX(WindowPos4ivMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos4ivMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos4sMESA))
GL_PREFIX(WindowPos4sMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos4sMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos4svMESA))
GL_PREFIX(WindowPos4svMESA):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos4svMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TbufferMask3DFX))
GL_PREFIX(TbufferMask3DFX):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TbufferMask3DFX))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SampleMaskEXT))
GL_PREFIX(SampleMaskEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SampleMaskSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SamplePatternEXT))
GL_PREFIX(SamplePatternEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SamplePatternSGIS))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DeleteFencesNV))
GL_PREFIX(DeleteFencesNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DeleteFencesNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GenFencesNV))
GL_PREFIX(GenFencesNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GenFencesNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IsFenceNV))
GL_PREFIX(IsFenceNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IsFenceNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TestFenceNV))
GL_PREFIX(TestFenceNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TestFenceNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetFenceivNV))
GL_PREFIX(GetFenceivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetFenceivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FinishFenceNV))
GL_PREFIX(FinishFenceNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FinishFenceNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SetFenceNV))
GL_PREFIX(SetFenceNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SetFenceNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2dARB))
GL_PREFIX(WindowPos2dARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2dMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2fARB))
GL_PREFIX(WindowPos2fARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2fMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2iARB))
GL_PREFIX(WindowPos2iARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2iMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2sARB))
GL_PREFIX(WindowPos2sARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2sMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2dvARB))
GL_PREFIX(WindowPos2dvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2dvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2fvARB))
GL_PREFIX(WindowPos2fvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2fvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2ivARB))
GL_PREFIX(WindowPos2ivARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2ivMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2svARB))
GL_PREFIX(WindowPos2svARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2svMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3dARB))
GL_PREFIX(WindowPos3dARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3dMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3fARB))
GL_PREFIX(WindowPos3fARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3fMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3iARB))
GL_PREFIX(WindowPos3iARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3iMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3sARB))
GL_PREFIX(WindowPos3sARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3sMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3dvARB))
GL_PREFIX(WindowPos3dvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3dvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3fvARB))
GL_PREFIX(WindowPos3fvARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3fvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3ivARB))
GL_PREFIX(WindowPos3ivARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3ivMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3svARB))
GL_PREFIX(WindowPos3svARB):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3svMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(AreProgramsResidentNV))
GL_PREFIX(AreProgramsResidentNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_AreProgramsResidentNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BindProgramNV))
GL_PREFIX(BindProgramNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BindProgramNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(DeleteProgramsNV))
GL_PREFIX(DeleteProgramsNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_DeleteProgramsNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ExecuteProgramNV))
GL_PREFIX(ExecuteProgramNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ExecuteProgramNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GenProgramsNV))
GL_PREFIX(GenProgramsNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GenProgramsNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetProgramParameterdvNV))
GL_PREFIX(GetProgramParameterdvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetProgramParameterdvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetProgramParameterfvNV))
GL_PREFIX(GetProgramParameterfvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetProgramParameterfvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetProgramivNV))
GL_PREFIX(GetProgramivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetProgramivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetProgramStringNV))
GL_PREFIX(GetProgramStringNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetProgramStringNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetTrackMatrixivNV))
GL_PREFIX(GetTrackMatrixivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetTrackMatrixivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetVertexAttribdvNV))
GL_PREFIX(GetVertexAttribdvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetVertexAttribdvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetVertexAttribfvNV))
GL_PREFIX(GetVertexAttribfvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetVertexAttribfvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetVertexAttribivNV))
GL_PREFIX(GetVertexAttribivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetVertexAttribivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(GetVertexAttribPointervNV))
GL_PREFIX(GetVertexAttribPointervNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_GetVertexAttribPointervNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(IsProgramNV))
GL_PREFIX(IsProgramNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_IsProgramNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(LoadProgramNV))
GL_PREFIX(LoadProgramNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_LoadProgramNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ProgramParameter4dNV))
GL_PREFIX(ProgramParameter4dNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ProgramParameter4dNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ProgramParameter4dvNV))
GL_PREFIX(ProgramParameter4dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ProgramParameter4dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ProgramParameter4fNV))
GL_PREFIX(ProgramParameter4fNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ProgramParameter4fNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ProgramParameter4fvNV))
GL_PREFIX(ProgramParameter4fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ProgramParameter4fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ProgramParameters4dvNV))
GL_PREFIX(ProgramParameters4dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ProgramParameters4dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ProgramParameters4fvNV))
GL_PREFIX(ProgramParameters4fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ProgramParameters4fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(RequestResidentProgramsNV))
GL_PREFIX(RequestResidentProgramsNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_RequestResidentProgramsNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(TrackMatrixNV))
GL_PREFIX(TrackMatrixNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_TrackMatrixNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribPointerNV))
GL_PREFIX(VertexAttribPointerNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribPointerNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib1dNV))
GL_PREFIX(VertexAttrib1dNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib1dNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib1dvNV))
GL_PREFIX(VertexAttrib1dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib1dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib1fNV))
GL_PREFIX(VertexAttrib1fNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib1fNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib1fvNV))
GL_PREFIX(VertexAttrib1fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib1fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib1sNV))
GL_PREFIX(VertexAttrib1sNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib1sNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib1svNV))
GL_PREFIX(VertexAttrib1svNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib1svNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib2dNV))
GL_PREFIX(VertexAttrib2dNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib2dNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib2dvNV))
GL_PREFIX(VertexAttrib2dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib2dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib2fNV))
GL_PREFIX(VertexAttrib2fNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib2fNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib2fvNV))
GL_PREFIX(VertexAttrib2fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib2fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib2sNV))
GL_PREFIX(VertexAttrib2sNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib2sNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib2svNV))
GL_PREFIX(VertexAttrib2svNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib2svNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib3dNV))
GL_PREFIX(VertexAttrib3dNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib3dNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib3dvNV))
GL_PREFIX(VertexAttrib3dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib3dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib3fNV))
GL_PREFIX(VertexAttrib3fNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib3fNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib3fvNV))
GL_PREFIX(VertexAttrib3fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib3fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib3sNV))
GL_PREFIX(VertexAttrib3sNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib3sNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib3svNV))
GL_PREFIX(VertexAttrib3svNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib3svNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib4dNV))
GL_PREFIX(VertexAttrib4dNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib4dNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib4dvNV))
GL_PREFIX(VertexAttrib4dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib4dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib4fNV))
GL_PREFIX(VertexAttrib4fNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib4fNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib4fvNV))
GL_PREFIX(VertexAttrib4fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib4fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib4sNV))
GL_PREFIX(VertexAttrib4sNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib4sNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib4svNV))
GL_PREFIX(VertexAttrib4svNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib4svNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib4ubNV))
GL_PREFIX(VertexAttrib4ubNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib4ubNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttrib4ubvNV))
GL_PREFIX(VertexAttrib4ubvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttrib4ubvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs1dvNV))
GL_PREFIX(VertexAttribs1dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs1dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs1fvNV))
GL_PREFIX(VertexAttribs1fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs1fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs1svNV))
GL_PREFIX(VertexAttribs1svNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs1svNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs2dvNV))
GL_PREFIX(VertexAttribs2dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs2dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs2fvNV))
GL_PREFIX(VertexAttribs2fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs2fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs2svNV))
GL_PREFIX(VertexAttribs2svNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs2svNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs3dvNV))
GL_PREFIX(VertexAttribs3dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs3dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs3fvNV))
GL_PREFIX(VertexAttribs3fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs3fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs3svNV))
GL_PREFIX(VertexAttribs3svNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs3svNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs4dvNV))
GL_PREFIX(VertexAttribs4dvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs4dvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs4fvNV))
GL_PREFIX(VertexAttribs4fvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs4fvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs4svNV))
GL_PREFIX(VertexAttribs4svNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs4svNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(VertexAttribs4ubvNV))
GL_PREFIX(VertexAttribs4ubvNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_VertexAttribs4ubvNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameteriNV))
GL_PREFIX(PointParameteriNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameteriNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterivNV))
GL_PREFIX(PointParameterivNV):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(BlendFuncSeparate))
GL_PREFIX(BlendFuncSeparate):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_BlendFuncSeparateEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoordf))
GL_PREFIX(FogCoordf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoordfEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoordfv))
GL_PREFIX(FogCoordfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoordfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoordd))
GL_PREFIX(FogCoordd):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoorddEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoorddv))
GL_PREFIX(FogCoorddv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoorddvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(FogCoordPointer))
GL_PREFIX(FogCoordPointer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_FogCoordPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiDrawArrays))
GL_PREFIX(MultiDrawArrays):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiDrawArraysEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(MultiDrawElements))
GL_PREFIX(MultiDrawElements):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_MultiDrawElementsEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterf))
GL_PREFIX(PointParameterf):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterfEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameterfv))
GL_PREFIX(PointParameterfv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterfvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameteri))
GL_PREFIX(PointParameteri):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameteriNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(PointParameteriv))
GL_PREFIX(PointParameteriv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_PointParameterivNV))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3b))
GL_PREFIX(SecondaryColor3b):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3bEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3bv))
GL_PREFIX(SecondaryColor3bv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3bvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3d))
GL_PREFIX(SecondaryColor3d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3dEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3dv))
GL_PREFIX(SecondaryColor3dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3dvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3f))
GL_PREFIX(SecondaryColor3f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3fEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3fv))
GL_PREFIX(SecondaryColor3fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3fvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3i))
GL_PREFIX(SecondaryColor3i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3iEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3iv))
GL_PREFIX(SecondaryColor3iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3ivEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3s))
GL_PREFIX(SecondaryColor3s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3sEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3sv))
GL_PREFIX(SecondaryColor3sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3svEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3ub))
GL_PREFIX(SecondaryColor3ub):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3ubEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3ubv))
GL_PREFIX(SecondaryColor3ubv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3ubvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3ui))
GL_PREFIX(SecondaryColor3ui):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3uiEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3uiv))
GL_PREFIX(SecondaryColor3uiv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3uivEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3us))
GL_PREFIX(SecondaryColor3us):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3usEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColor3usv))
GL_PREFIX(SecondaryColor3usv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColor3usvEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(SecondaryColorPointer))
GL_PREFIX(SecondaryColorPointer):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_SecondaryColorPointerEXT))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2d))
GL_PREFIX(WindowPos2d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2dMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2dv))
GL_PREFIX(WindowPos2dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2dvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2f))
GL_PREFIX(WindowPos2f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2fMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2fv))
GL_PREFIX(WindowPos2fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2fvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2i))
GL_PREFIX(WindowPos2i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2iMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2iv))
GL_PREFIX(WindowPos2iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2ivMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2s))
GL_PREFIX(WindowPos2s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2sMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos2sv))
GL_PREFIX(WindowPos2sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos2svMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3d))
GL_PREFIX(WindowPos3d):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3dMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3dv))
GL_PREFIX(WindowPos3dv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3dvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3f))
GL_PREFIX(WindowPos3f):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3fMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3fv))
GL_PREFIX(WindowPos3fv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3fvMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3i))
GL_PREFIX(WindowPos3i):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3iMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3iv))
GL_PREFIX(WindowPos3iv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3ivMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3s))
GL_PREFIX(WindowPos3s):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3sMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(WindowPos3sv))
GL_PREFIX(WindowPos3sv):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_WindowPos3svMESA))
 
ALIGNTEXT16
GLOBL_FN(GL_PREFIX(ActiveStencilFaceEXT))
GL_PREFIX(ActiveStencilFaceEXT):
MOV_L(CONTENT(GLNAME(_glapi_Dispatch)), EAX)
JMP(GL_OFFSET(_gloffset_ActiveStencilFaceEXT))
 
 
#endif /* __WIN32__ */
/shark/trunk/ports/mesa/src/X86/3dnow_normal.s
0,0 → 1,836
/* $Id: 3dnow_normal.s,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* 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.
*/
 
/*
* 3Dnow assembly code by Holger Waechtler
*/
 
#include "matypes.h"
#include "norm_args.h"
 
SEG_TEXT
 
#define M(i) REGOFF(i * 4, ECX)
#define STRIDE REGOFF(12, ESI)
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_3dnow_transform_normalize_normals)
GLNAME(_mesa_3dnow_transform_normalize_normals):
 
#define FRAME_OFFSET 12
 
PUSH_L ( EDI )
PUSH_L ( ESI )
PUSH_L ( EBP )
 
MOV_L ( ARG_LENGTHS, EDI )
MOV_L ( ARG_IN, ESI )
MOV_L ( ARG_DEST, EAX )
MOV_L ( REGOFF(V3F_COUNT, ESI), EBP ) /* dest->count = in->count */
MOV_L ( EBP, REGOFF(V3F_COUNT, EAX) )
MOV_L ( REGOFF(V3F_START, ESI), EDX ) /* in->start */
MOV_L ( REGOFF(V3F_START, EAX), EAX ) /* dest->start */
MOV_L ( ARG_MAT, ECX )
MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */
 
CMP_L ( CONST(0), EBP ) /* count > 0 ?? */
JE ( LLBL (G3TN_end) )
 
MOV_L ( REGOFF (V3F_COUNT, ESI), EBP )
FEMMS
 
PUSH_L ( EBP )
PUSH_L ( EAX )
PUSH_L ( EDX ) /* save counter & pointer for */
/* the normalize pass */
#undef FRAME_OFFSET
#define FRAME_OFFSET 24
 
MOVQ ( M(0), MM3 ) /* m1 | m0 */
MOVQ ( M(4), MM4 ) /* m5 | m4 */
 
MOVD ( M(2), MM5 ) /* | m2 */
PUNPCKLDQ ( M(6), MM5 ) /* m6 | m2 */
 
MOVQ ( M(8), MM6 ) /* m9 | m8 */
MOVQ ( M(10), MM7 ) /* | m10 */
 
CMP_L ( CONST(0), EDI ) /* lengths == 0 ? */
JNE ( LLBL (G3TN_scale_end ) )
 
MOVD ( ARG_SCALE, MM0 ) /* | scale */
PUNPCKLDQ ( MM0, MM0 ) /* scale | scale */
 
PFMUL ( MM0, MM3 ) /* scale * m1 | scale * m0 */
PFMUL ( MM0, MM4 ) /* scale * m5 | scale * m4 */
PFMUL ( MM0, MM5 ) /* scale * m6 | scale * m2 */
PFMUL ( MM0, MM6 ) /* scale * m9 | scale * m8 */
PFMUL ( MM0, MM7 ) /* | scale * m10 */
 
ALIGNTEXT32
LLBL (G3TN_scale_end):
LLBL (G3TN_transform):
MOVQ ( REGIND (EDX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF (8, EDX), MM2 ) /* | x2 */
 
MOVQ ( MM0, MM1 ) /* x1 | x0 */
PUNPCKLDQ ( MM2, MM2 ) /* x2 | x2 */
 
PFMUL ( MM3, MM0 ) /* x1*m1 | x0*m0 */
ADD_L ( CONST(16), EAX ) /* next r */
 
PREFETCHW ( REGIND(EAX) )
 
PFMUL ( MM4, MM1 ) /* x1*m5 | x0*m4 */
PFACC ( MM1, MM0 ) /* x0*m4+x1*m5 | x0*m0+x1*m1 */
 
PFMUL ( MM5, MM2 ) /* x2*m6 | x2*m2 */
PFADD ( MM2, MM0 ) /* x0*m4+x1*m5+x2*m6| x0*m0+...+x2**/
 
MOVQ ( REGIND (EDX), MM1 ) /* x1 | x0 */
MOVQ ( MM0, REGOFF(-16, EAX) ) /* write r0, r1 */
 
PFMUL ( MM6, MM1 ) /* x1*m9 | x0*m8 */
MOVD ( REGOFF (8, EDX), MM2 ) /* | x2 */
 
PFMUL ( MM7, MM2 ) /* | x2*m10 */
PFACC ( MM1, MM1 ) /* *not used* | x0*m8+x1*m9 */
 
PFADD ( MM2, MM1 ) /* *not used* | x0*m8+x1*m9+x2*m*/
ADD_L ( STRIDE, EDX ) /* next normal */
 
PREFETCH ( REGIND(EDX) )
 
MOVD ( MM1, REGOFF(-8, EAX) ) /* write r2 */
DEC_L ( EBP ) /* decrement normal counter */
JA ( LLBL (G3TN_transform) )
 
 
POP_L ( EDX ) /* end of transform --- */
POP_L ( EAX ) /* now normalizing ... */
POP_L ( EBP )
 
CMP_L ( CONST(0), EDI ) /* lengths == 0 ? */
JE ( LLBL (G3TN_norm ) ) /* calculate lengths */
 
 
ALIGNTEXT32
LLBL (G3TN_norm_w_lengths):
 
PREFETCHW ( REGOFF(12,EAX) )
 
MOVQ ( REGIND(EAX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF(8, EAX), MM1 ) /* | x2 */
 
MOVD ( REGIND (EDI), MM3 ) /* | length (x) */
PFMUL ( MM3, MM1 ) /* | x2 (normalize*/
 
PUNPCKLDQ ( MM3, MM3 ) /* length (x) | length (x) */
PFMUL ( MM3, MM0 ) /* x1 (normalized) | x0 (normalize*/
 
ADD_L ( STRIDE, EDX ) /* next normal */
ADD_L ( CONST(4), EDI ) /* next length */
 
PREFETCH ( REGIND(EDI) )
 
MOVQ ( MM0, REGIND(EAX) ) /* write new x0, x1 */
MOVD ( MM1, REGOFF(8, EAX) ) /* write new x2 */
 
ADD_L ( CONST(16), EAX ) /* next r */
DEC_L ( EBP ) /* decrement normal counter */
 
JA ( LLBL (G3TN_norm_w_lengths) )
JMP ( LLBL (G3TN_exit_3dnow) )
 
ALIGNTEXT32
LLBL (G3TN_norm):
 
PREFETCHW ( REGIND(EAX) )
 
MOVQ ( MM0, MM3 ) /* x1 | x0 */
MOVQ ( MM1, MM4 ) /* | x2 */
 
PFMUL ( MM0, MM3 ) /* x1*x1 | x0*x0 */
ADD_L ( CONST(16), EAX ) /* next r */
 
PFMUL ( MM1, MM4 ) /* | x2*x2 */
PFADD ( MM4, MM3 ) /* | x0*x0+x2*x2 */
 
PFACC ( MM3, MM3 ) /* **not used** | x0*x0+x1*x1+x2**/
PFRSQRT ( MM3, MM5 ) /* 1/sqrt (x0*x0+x1*x1+x2*x2) */
 
MOVQ ( MM5, MM4 )
PUNPCKLDQ ( MM3, MM3 )
 
DEC_L ( EBP ) /* decrement normal counter */
PFMUL ( MM5, MM5 )
 
PFRSQIT1 ( MM3, MM5 )
PFRCPIT2 ( MM4, MM5 )
 
PFMUL ( MM5, MM0 ) /* x1 (normalized) | x0 (normalize*/
 
MOVQ ( MM0, REGOFF(-16, EAX) ) /* write new x0, x1 */
PFMUL ( MM5, MM1 ) /* | x2 (normalize*/
 
MOVD ( MM1, REGOFF(-8, EAX) ) /* write new x2 */
MOVQ ( REGIND (EAX), MM0 ) /* x1 | x0 */
 
MOVD ( REGOFF(8, EAX), MM1 ) /* | x2 */
JA ( LLBL (G3TN_norm) )
 
LLBL (G3TN_exit_3dnow):
FEMMS
 
LLBL (G3TN_end):
POP_L ( EBP )
POP_L ( ESI )
POP_L ( EDI )
RET
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_3dnow_transform_normalize_normals_no_rot)
GLNAME(_mesa_3dnow_transform_normalize_normals_no_rot):
 
#undef FRAME_OFFSET
#define FRAME_OFFSET 12
 
PUSH_L ( EDI )
PUSH_L ( ESI )
PUSH_L ( EBP )
 
MOV_L ( ARG_LENGTHS, EDI )
MOV_L ( ARG_IN, ESI )
MOV_L ( ARG_DEST, EAX )
MOV_L ( REGOFF(V3F_COUNT, ESI), EBP ) /* dest->count = in->count */
MOV_L ( EBP, REGOFF(V3F_COUNT, EAX) )
MOV_L ( ARG_MAT, ECX )
MOV_L ( REGOFF(V3F_START, EAX), EAX ) /* dest->start */
MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */
MOV_L ( REGOFF(V3F_START, ESI), EDX ) /* in->start */
 
CMP_L ( CONST(0), EBP ) /* count > 0 ?? */
JE ( LLBL (G3TNNR_end) )
 
FEMMS
 
MOVD ( M(0), MM0 ) /* | m0 */
PUNPCKLDQ ( M(5), MM0 ) /* m5 | m0 */
 
MOVD ( M(10), MM2 ) /* | m10 */
PUNPCKLDQ ( MM2, MM2 ) /* m10 | m10 */
 
CMP_L ( CONST(0), EDI ) /* lengths == 0 ? */
JNE ( LLBL (G3TNNR_scale_end ) )
 
MOVD ( ARG_SCALE, MM7 ) /* | scale */
PUNPCKLDQ ( MM7, MM7 ) /* scale | scale */
 
PFMUL ( MM7, MM0 ) /* scale * m5 | scale * m0 */
PFMUL ( MM7, MM2 ) /* scale * m10 | scale * m10 */
 
ALIGNTEXT32
LLBL (G3TNNR_scale_end):
CMP_L ( CONST(0), EDI ) /* lengths == 0 ? */
JE ( LLBL (G3TNNR_norm) ) /* need to calculate lengths */
 
MOVD ( REGIND(EDI), MM3 ) /* | length (x) */
 
 
ALIGNTEXT32
LLBL (G3TNNR_norm_w_lengths): /* use precalculated lengths */
 
PREFETCHW ( REGIND(EAX) )
 
MOVQ ( REGIND(EDX), MM6 ) /* x1 | x0 */
MOVD ( REGOFF(8, EDX), MM7 ) /* | x2 */
 
PFMUL ( MM0, MM6 ) /* x1*m5 | x0*m0 */
ADD_L ( STRIDE, EDX ) /* next normal */
 
PREFETCH ( REGIND(EDX) )
 
PFMUL ( MM2, MM7 ) /* | x2*m10 */
ADD_L ( CONST(16), EAX ) /* next r */
 
PFMUL ( MM3, MM7 ) /* | x2 (normalized) */
PUNPCKLDQ ( MM3, MM3 ) /* length (x) | length (x) */
 
ADD_L ( CONST(4), EDI ) /* next length */
PFMUL ( MM3, MM6 ) /* x1 (normalized) | x0 (normalized) */
 
DEC_L ( EBP ) /* decrement normal counter */
MOVQ ( MM6, REGOFF(-16, EAX) ) /* write r0, r1 */
 
MOVD ( MM7, REGOFF(-8, EAX) ) /* write r2 */
MOVD ( REGIND(EDI), MM3 ) /* | length (x) */
 
JA ( LLBL (G3TNNR_norm_w_lengths) )
JMP ( LLBL (G3TNNR_exit_3dnow) )
 
ALIGNTEXT32
LLBL (G3TNNR_norm): /* need to calculate lengths */
 
PREFETCHW ( REGIND(EAX) )
 
MOVQ ( REGIND(EDX), MM6 ) /* x1 | x0 */
MOVD ( REGOFF(8, EDX), MM7 ) /* | x2 */
 
PFMUL ( MM0, MM6 ) /* x1*m5 | x0*m0 */
ADD_L ( CONST(16), EAX ) /* next r */
 
PFMUL ( MM2, MM7 ) /* | x2*m10 */
MOVQ ( MM6, MM3 ) /* x1 (transformed)| x0 (transformed) */
 
MOVQ ( MM7, MM4 ) /* | x2 (transformed) */
PFMUL ( MM6, MM3 ) /* x1*x1 | x0*x0 */
 
 
PFMUL ( MM7, MM4 ) /* | x2*x2 */
PFACC ( MM3, MM3 ) /* **not used** | x0*x0+x1*x1 */
 
PFADD ( MM4, MM3 ) /* | x0*x0+x1*x1+x2*x2*/
ADD_L ( STRIDE, EDX ) /* next normal */
 
PREFETCH ( REGIND(EDX) )
 
PFRSQRT ( MM3, MM5 ) /* 1/sqrt (x0*x0+x1*x1+x2*x2) */
MOVQ ( MM5, MM4 )
 
PUNPCKLDQ ( MM3, MM3 )
PFMUL ( MM5, MM5 )
 
PFRSQIT1 ( MM3, MM5 )
DEC_L ( EBP ) /* decrement normal counter */
 
PFRCPIT2 ( MM4, MM5 )
PFMUL ( MM5, MM6 ) /* x1 (normalized) | x0 (normalized) */
 
MOVQ ( MM6, REGOFF(-16, EAX) ) /* write r0, r1 */
PFMUL ( MM5, MM7 ) /* | x2 (normalized) */
 
MOVD ( MM7, REGOFF(-8, EAX) ) /* write r2 */
JA ( LLBL (G3TNNR_norm) )
 
 
LLBL (G3TNNR_exit_3dnow):
FEMMS
 
LLBL (G3TNNR_end):
POP_L ( EBP )
POP_L ( ESI )
POP_L ( EDI )
RET
 
 
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_3dnow_transform_rescale_normals_no_rot)
GLNAME(_mesa_3dnow_transform_rescale_normals_no_rot):
 
#undef FRAME_OFFSET
#define FRAME_OFFSET 12
 
PUSH_L ( EDI )
PUSH_L ( ESI )
PUSH_L ( EBP )
 
MOV_L ( ARG_IN, EAX )
MOV_L ( ARG_DEST, EDX )
MOV_L ( REGOFF(V3F_COUNT, EAX), EBP ) /* dest->count = in->count */
MOV_L ( EBP, REGOFF(V3F_COUNT, EDX) )
MOV_L ( ARG_IN, ESI )
MOV_L ( ARG_MAT, ECX )
MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */
MOV_L ( REGOFF(V3F_START, EDX), EAX ) /* dest->start */
MOV_L ( REGOFF(V3F_START, ESI), EDX ) /* in->start */
 
CMP_L ( CONST(0), EBP )
JE ( LLBL (G3TRNR_end) )
 
FEMMS
 
MOVD ( ARG_SCALE, MM6 ) /* | scale */
PUNPCKLDQ ( MM6, MM6 ) /* scale | scale */
 
MOVD ( REGIND(ECX), MM0 ) /* | m0 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m5 | m0 */
 
PFMUL ( MM6, MM0 ) /* scale*m5 | scale*m0 */
MOVD ( REGOFF(40, ECX), MM2 ) /* | m10 */
 
PFMUL ( MM6, MM2 ) /* | scale*m10 */
 
ALIGNTEXT32
LLBL (G3TRNR_rescale):
 
PREFETCHW ( REGIND(EAX) )
MOVQ ( REGIND(EDX), MM4 ) /* x1 | x0 */
MOVD ( REGOFF(8, EDX), MM5 ) /* | x2 */
PFMUL ( MM0, MM4 ) /* x1*m5 | x0*m0 */
ADD_L ( STRIDE, EDX ) /* next normal */
 
PREFETCH ( REGIND(EDX) )
 
PFMUL ( MM2, MM5 ) /* | x2*m10 */
ADD_L ( CONST(16), EAX ) /* next r */
 
DEC_L ( EBP ) /* decrement normal counter */
MOVQ ( MM4, REGOFF(-16, EAX) ) /* write r0, r1 */
 
MOVD ( MM5, REGOFF(-8, EAX) ) /* write r2 */
JA ( LLBL (G3TRNR_rescale) ) /* cnt > 0 ? -> process next normal */
 
FEMMS
 
LLBL (G3TRNR_end):
POP_L ( EBP )
POP_L ( ESI )
POP_L ( EDI )
RET
 
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_3dnow_transform_rescale_normals)
GLNAME(_mesa_3dnow_transform_rescale_normals):
 
#undef FRAME_OFFSET
#define FRAME_OFFSET 8
 
PUSH_L ( EDI )
PUSH_L ( ESI )
 
MOV_L ( ARG_IN, ESI )
MOV_L ( ARG_DEST, EAX )
MOV_L ( ARG_MAT, ECX )
MOV_L ( REGOFF(V3F_COUNT, ESI), EDI ) /* dest->count = in->count */
MOV_L ( EDI, REGOFF(V3F_COUNT, EAX) )
MOV_L ( REGOFF(V3F_START, EAX), EAX ) /* dest->start */
MOV_L ( REGOFF(V3F_START, ESI), EDX ) /* in->start */
MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */
 
CMP_L ( CONST(0), EDI )
JE ( LLBL (G3TR_end) )
 
FEMMS
 
MOVQ ( REGIND(ECX), MM3 ) /* m1 | m0 */
 
MOVQ ( REGOFF(16,ECX), MM4 ) /* m5 | m4 */
MOVD ( ARG_SCALE, MM0 ) /* scale */
 
MOVD ( REGOFF(8,ECX), MM5 ) /* | m2 */
PUNPCKLDQ ( MM0, MM0 ) /* scale | scale */
 
PUNPCKLDQ ( REGOFF(24, ECX), MM5 )
PFMUL ( MM0, MM3 ) /* scale*m1 | scale*m0 */
 
MOVQ ( REGOFF(32, ECX), MM6 ) /* m9 | m8*/
PFMUL ( MM0, MM4 ) /* scale*m5 | scale*m4 */
 
MOVD ( REGOFF(40, ECX), MM7 ) /* | m10 */
PFMUL ( MM0, MM5 ) /* scale*m6 | scale*m2 */
 
PFMUL ( MM0, MM6 ) /* scale*m9 | scale*m8 */
 
PFMUL ( MM0, MM7 ) /* | scale*m10 */
 
ALIGNTEXT32
LLBL (G3TR_rescale):
 
PREFETCHW ( REGIND(EAX) )
 
MOVQ ( REGIND(EDX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF(8, EDX), MM2 ) /* | x2 */
 
MOVQ ( MM0, MM1 ) /* x1 | x0 */
PUNPCKLDQ ( MM2, MM2 ) /* x2 | x2 */
 
PFMUL ( MM3, MM0 ) /* x1*m1 | x0*m0 */
ADD_L ( CONST(16), EAX ) /* next r */
 
PFMUL ( MM4, MM1 ) /* x1*m5 | x0*m4 */
PFACC ( MM1, MM0 ) /* x0*m4+x1*m5 | x0*m0+x1*m1 */
 
MOVQ ( REGIND(EDX), MM1 ) /* x1 | x0 */
 
PFMUL ( MM5, MM2 ) /* x2*m6 | x2*m2 */
PFADD ( MM2, MM0 ) /* x0*m4...+x2*m6| x0*m0+x1*m1+x2*m2 */
 
MOVD ( REGOFF(8, EDX), MM2 ) /* | x2 */
ADD_L ( STRIDE, EDX ) /* next normal */
 
PREFETCH ( REGIND(EDX) )
 
MOVQ ( MM0, REGOFF(-16, EAX) ) /* write r0, r1 */
PFMUL ( MM6, MM1 ) /* x1*m9 | x0*m8 */
 
PFMUL ( MM7, MM2 ) /* | x2*m10 */
PFACC ( MM1, MM1 ) /* *not used* | x0*m8+x1*m9 */
 
PFADD ( MM2, MM1 ) /* *not used* | x0*m8+x1*m9+x2*m10 */
MOVD ( MM1, REGOFF(-8, EAX) ) /* write r2 */
 
DEC_L ( EDI ) /* decrement normal counter */
JA ( LLBL (G3TR_rescale) )
 
FEMMS
 
LLBL (G3TR_end):
POP_L ( ESI )
POP_L ( EDI )
RET
 
 
 
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_3dnow_transform_normals_no_rot)
GLNAME(_mesa_3dnow_transform_normals_no_rot):
 
#undef FRAME_OFFSET
#define FRAME_OFFSET 8
 
PUSH_L ( EDI )
PUSH_L ( ESI )
 
MOV_L ( ARG_IN, ESI )
MOV_L ( ARG_DEST, EAX )
MOV_L ( ARG_MAT, ECX )
MOV_L ( REGOFF(V3F_COUNT, ESI), EDI ) /* dest->count = in->count */
MOV_L ( EDI, REGOFF(V3F_COUNT, EAX) )
MOV_L ( REGOFF(V3F_START, EAX), EAX ) /* dest->start */
MOV_L ( REGOFF(V3F_START, ESI), EDX ) /* in->start */
MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */
 
CMP_L ( CONST(0), EDI )
JE ( LLBL (G3TNR_end) )
 
FEMMS
 
MOVD ( REGIND(ECX), MM0 ) /* | m0 */
PUNPCKLDQ ( REGOFF(20, ECX), MM0 ) /* m5 | m0 */
 
MOVD ( REGOFF(40, ECX), MM2 ) /* | m10 */
PUNPCKLDQ ( MM2, MM2 ) /* m10 | m10 */
 
ALIGNTEXT32
LLBL (G3TNR_transform):
 
PREFETCHW ( REGIND(EAX) )
 
MOVQ ( REGIND(EDX), MM4 ) /* x1 | x0 */
MOVD ( REGOFF(8, EDX), MM5 ) /* | x2 */
 
PFMUL ( MM0, MM4 ) /* x1*m5 | x0*m0 */
ADD_L ( STRIDE, EDX) /* next normal */
 
PREFETCH ( REGIND(EDX) )
 
PFMUL ( MM2, MM5 ) /* | x2*m10 */
ADD_L ( CONST(16), EAX ) /* next r */
 
DEC_L ( EDI ) /* decrement normal counter */
MOVQ ( MM4, REGOFF(-16, EAX) ) /* write r0, r1 */
 
MOVD ( MM5, REGOFF(-8, EAX) ) /* write r2 */
JA ( LLBL (G3TNR_transform) )
 
FEMMS
 
LLBL (G3TNR_end):
POP_L ( ESI )
POP_L ( EDI )
RET
 
 
 
 
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_3dnow_transform_normals)
GLNAME(_mesa_3dnow_transform_normals):
 
#undef FRAME_OFFSET
#define FRAME_OFFSET 8
 
PUSH_L ( EDI )
PUSH_L ( ESI )
 
MOV_L ( ARG_IN, ESI )
MOV_L ( ARG_DEST, EAX )
MOV_L ( ARG_MAT, ECX )
MOV_L ( REGOFF(V3F_COUNT, ESI), EDI ) /* dest->count = in->count */
MOV_L ( EDI, REGOFF(V3F_COUNT, EAX) )
MOV_L ( REGOFF(V3F_START, EAX), EAX ) /* dest->start */
MOV_L ( REGOFF(V3F_START, ESI), EDX ) /* in->start */
MOV_L ( REGOFF(MATRIX_INV, ECX), ECX ) /* mat->inv */
 
CMP_L ( CONST(0), EDI ) /* count > 0 ?? */
JE ( LLBL (G3T_end) )
 
FEMMS
 
MOVQ ( REGIND(ECX), MM3 ) /* m1 | m0 */
MOVQ ( REGOFF(16, ECX), MM4 ) /* m5 | m4 */
 
MOVD ( REGOFF(8, ECX), MM5 ) /* | m2 */
PUNPCKLDQ ( REGOFF(24, ECX), MM5 ) /* m6 | m2 */
 
MOVQ ( REGOFF(32, ECX), MM6 ) /* m9 | m8 */
MOVD ( REGOFF(40, ECX), MM7 ) /* | m10 */
 
ALIGNTEXT32
LLBL (G3T_transform):
 
PREFETCHW ( REGIND(EAX) )
 
MOVQ ( REGIND(EDX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF(8, EDX), MM2 ) /* | x2 */
 
MOVQ ( MM0, MM1 ) /* x1 | x0 */
PUNPCKLDQ ( MM2, MM2 ) /* x2 | x2 */
 
PFMUL ( MM3, MM0 ) /* x1*m1 | x0*m0 */
ADD_L ( CONST(16), EAX ) /* next r */
 
PFMUL ( MM4, MM1 ) /* x1*m5 | x0*m4 */
PFACC ( MM1, MM0 ) /* x0*m4+x1*m5 | x0*m0+x1*m1 */
 
PFMUL ( MM5, MM2 ) /* x2*m6 | x2*m2 */
PFADD ( MM2, MM0 ) /* x0*m4...+x2*m6| x0*m0+x1*m1+x2*m2 */
 
MOVQ ( REGIND(EDX), MM1 ) /* x1 | x0 */
MOVQ ( MM0, REGOFF(-16, EAX) ) /* write r0, r1 */
 
PFMUL ( MM6, MM1 ) /* x1*m9 | x0*m8 */
MOVD ( REGOFF(8, EDX), MM2 ) /* | x2 */
 
PFMUL ( MM7, MM2 ) /* | x2*m10 */
ADD_L ( STRIDE, EDX ) /* next normal */
 
PREFETCH ( REGIND(EDX) )
 
PFACC ( MM1, MM1 ) /* *not used* | x0*m8+x1*m9 */
PFADD ( MM2, MM1 ) /* *not used* | x0*m8+x1*m9+x2*m10 */
 
MOVD ( MM1, REGOFF(-8, EAX) ) /* write r2 */
DEC_L ( EDI ) /* decrement normal counter */
 
JA ( LLBL (G3T_transform) )
 
FEMMS
 
LLBL (G3T_end):
POP_L ( ESI )
POP_L ( EDI )
RET
 
 
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_3dnow_normalize_normals)
GLNAME(_mesa_3dnow_normalize_normals):
 
#undef FRAME_OFFSET
#define FRAME_OFFSET 12
 
PUSH_L ( EDI )
PUSH_L ( ESI )
PUSH_L ( EBP )
 
MOV_L ( ARG_IN, ESI )
MOV_L ( ARG_DEST, EAX )
MOV_L ( REGOFF(V3F_COUNT, ESI), EBP ) /* dest->count = in->count */
MOV_L ( EBP, REGOFF(V3F_COUNT, EAX) )
MOV_L ( REGOFF(V3F_START, EAX), EAX ) /* dest->start */
MOV_L ( REGOFF(V3F_START, ESI), ECX ) /* in->start */
MOV_L ( ARG_LENGTHS, EDX )
 
CMP_L ( CONST(0), EBP ) /* count > 0 ?? */
JE ( LLBL (G3N_end) )
 
FEMMS
 
CMP_L ( CONST(0), EDX ) /* lengths == 0 ? */
JE ( LLBL (G3N_norm2) ) /* calculate lengths */
 
ALIGNTEXT32
LLBL (G3N_norm1): /* use precalculated lengths */
 
PREFETCH ( REGIND(EAX) )
 
MOVQ ( REGIND(ECX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF(8, ECX), MM1 ) /* | x2 */
 
MOVD ( REGIND(EDX), MM3 ) /* | length (x) */
PFMUL ( MM3, MM1 ) /* | x2 (normalized) */
 
PUNPCKLDQ ( MM3, MM3 ) /* length (x) | length (x) */
ADD_L ( STRIDE, ECX ) /* next normal */
 
PREFETCH ( REGIND(ECX) )
 
PFMUL ( MM3, MM0 ) /* x1 (normalized) | x0 (normalized) */
MOVQ ( MM0, REGIND(EAX) ) /* write new x0, x1 */
 
MOVD ( MM1, REGOFF(8, EAX) ) /* write new x2 */
ADD_L ( CONST(16), EAX ) /* next r */
 
ADD_L ( CONST(4), EDX ) /* next length */
DEC_L ( EBP ) /* decrement normal counter */
 
JA ( LLBL (G3N_norm1) )
 
JMP ( LLBL (G3N_end1) )
 
ALIGNTEXT32
LLBL (G3N_norm2): /* need to calculate lengths */
 
PREFETCHW ( REGIND(EAX) )
 
MOVQ ( MM0, MM3 ) /* x1 | x0 */
ADD_L ( STRIDE, ECX ) /* next normal */
 
PREFETCH ( REGIND(ECX) )
 
MOVQ ( REGIND(ECX), MM0 ) /* x1 | x0 */
MOVD ( REGOFF(8, ECX), MM1 ) /* | x2 */
 
PFMUL ( MM0, MM3 ) /* x1*x1 | x0*x0 */
MOVQ ( MM1, MM4 ) /* | x2 */
 
ADD_L ( CONST(16), EAX ) /* next r */
PFMUL ( MM1, MM4 ) /* | x2*x2 */
 
PFADD ( MM4, MM3 ) /* | x0*x0+x2*x2 */
PFACC ( MM3, MM3 ) /* x0*x0+...+x2*x2 | x0*x0+x1*x1+x2*x2*/
 
PFRSQRT ( MM3, MM5 ) /* 1/sqrt (x0*x0+x1*x1+x2*x2) */
MOVQ ( MM5, MM4 )
 
PUNPCKLDQ ( MM3, MM3 )
PFMUL ( MM5, MM5 )
 
PFRSQIT1 ( MM3, MM5 )
DEC_L ( EBP ) /* decrement normal counter */
 
PFRCPIT2 ( MM4, MM5 )
 
PFMUL ( MM5, MM0 ) /* x1 (normalized) | x0 (normalized) */
MOVQ ( MM0, REGOFF(-16, EAX) ) /* write new x0, x1 */
 
PFMUL ( MM5, MM1 ) /* | x2 (normalized) */
MOVD ( MM1, REGOFF(-8, EAX) ) /* write new x2 */
 
JA ( LLBL (G3N_norm2) )
 
LLBL (G3N_end1):
FEMMS
 
LLBL (G3N_end):
POP_L ( EBP )
POP_L ( ESI )
POP_L ( EDI )
RET
 
 
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_3dnow_rescale_normals)
GLNAME(_mesa_3dnow_rescale_normals):
 
#undef FRAME_OFFSET
#define FRAME_OFFSET 8
PUSH_L ( EDI )
PUSH_L ( ESI )
 
MOV_L ( ARG_IN, ESI )
MOV_L ( ARG_DEST, EAX )
MOV_L ( REGOFF(V3F_COUNT, ESI), EDX ) /* dest->count = in->count */
MOV_L ( EDX, REGOFF(V3F_COUNT, EAX) )
MOV_L ( REGOFF(V3F_START, EAX), EAX ) /* dest->start */
MOV_L ( REGOFF(V3F_START, ESI), ECX ) /* in->start */
 
CMP_L ( CONST(0), EDX )
JE ( LLBL (G3R_end) )
 
FEMMS
 
MOVD ( ARG_SCALE, MM0 ) /* scale */
PUNPCKLDQ ( MM0, MM0 )
 
ALIGNTEXT32
LLBL (G3R_rescale):
 
PREFETCHW ( REGIND(EAX) )
 
MOVQ ( REGIND(ECX), MM1 ) /* x1 | x0 */
MOVD ( REGOFF(8, ECX), MM2 ) /* | x2 */
 
PFMUL ( MM0, MM1 ) /* x1*scale | x0*scale */
ADD_L ( STRIDE, ECX ) /* next normal */
 
PREFETCH ( REGIND(ECX) )
 
PFMUL ( MM0, MM2 ) /* | x2*scale */
ADD_L ( CONST(16), EAX ) /* next r */
 
MOVQ ( MM1, REGOFF(-16, EAX) ) /* write r0, r1 */
MOVD ( MM2, REGOFF(-8, EAX) ) /* write r2 */
 
DEC_L ( EDX ) /* decrement normal counter */
JA ( LLBL (G3R_rescale) )
 
FEMMS
 
LLBL (G3R_end):
POP_L ( ESI )
POP_L ( EDI )
RET
/shark/trunk/ports/mesa/src/X86/mmx_blend.s
0,0 → 1,358
/*
* Written by José Fonseca <j_r_fonseca@yahoo.co.uk>
*/
 
#include "matypes.h"
 
 
/* integer multiplication - alpha plus one
*
* makes the following approximation to the division (Sree)
*
* rgb*a/255 ~= (rgb*(a+1)) >> 256
*
* which is the fastest method that satisfies the following OpenGL criteria
*
* 0*0 = 0 and 255*255 = 255
*
* note that MX1 is a register with 0xffffffffffffffff constant which can be easily obtained making
*
* PCMPEQW ( MX1, MX1 )
*/
#define GMB_MULT_AP1( MP1, MA1, MP2, MA2, MX1 ) \
PSUBW ( MX1, MA1 ) /* a1 + 1 | a1 + 1 | a1 + 1 | a1 + 1 */ ;\
PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\
;\
TWO(PSUBW ( MX1, MA2 )) /* a2 + 1 | a2 + 1 | a2 + 1 | a2 + 1 */ ;\
TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\
;\
PSRLW ( CONST(8), MA1 ) /* t1 >> 8 ~= t1/255 */ ;\
TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 ~= t2/255 */
 
 
/* integer multiplication - geometric series
*
* takes the geometric series approximation to the division
*
* t/255 = (t >> 8) + (t >> 16) + (t >> 24) ..
*
* in this case just the first two terms to fit in 16bit arithmetic
*
* t/255 ~= (t + (t >> 8)) >> 8
*
* note that just by itself it doesn't satisfies the OpenGL criteria, as 255*255 = 254,
* so the special case a = 255 must be accounted or roundoff must be used
*/
#define GMB_MULT_GS( MP1, MA1, MP2, MA2 ) \
PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\
TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\
;\
MOVQ ( MA1, MP1 ) ;\
PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\
;\
TWO(MOVQ ( MA2, MP2 )) ;\
TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\
;\
PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\
PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\
;\
TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\
TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */
 
 
/* integer multiplication - geometric series plus rounding
*
* when using a geometric series division instead of truncating the result
* use roundoff in the approximation (Jim Blinn)
*
* t = rgb*a + 0x80
*
* achieving the exact results
*
* note that M80 is register with the 0x0080008000800080 constant
*/
#define GMB_MULT_GSR( MP1, MA1, MP2, MA2, M80 ) \
PMULLW ( MP1, MA1 ) /* t1 = p1*a1 */ ;\
PADDW ( M80, MA1 ) /* t1 += 0x80 */ ;\
;\
TWO(PMULLW ( MP2, MA2 )) /* t2 = p2*a2 */ ;\
TWO(PADDW ( M80, MA2 )) /* t2 += 0x80 */ ;\
;\
MOVQ ( MA1, MP1 ) ;\
PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\
;\
TWO(MOVQ ( MA2, MP2 )) ;\
TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\
;\
PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\
PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\
;\
TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\
TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */
 
 
/* linear interpolation - geometric series
*/
#define GMB_LERP_GS( MP1, MQ1, MA1, MP2, MQ2, MA2) \
PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\
PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\
PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\
;\
TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\
TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\
TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\
;\
MOVQ ( MA1, MP1 ) ;\
PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\
;\
TWO(MOVQ ( MA2, MP2 )) ;\
TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\
;\
PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\
TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\
;\
PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\
TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\
;\
PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\
TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */
 
 
/* linear interpolation - geometric series with roundoff
*
* this is a generalization of Blinn's formula to signed arithmetic
*
* note that M80 is a register with the 0x0080008000800080 constant
*/
#define GMB_LERP_GSR( MP1, MQ1, MA1, MP2, MQ2, MA2, M80) \
PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\
PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\
PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\
;\
TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\
TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\
TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\
;\
PSRLW ( CONST(15), MP1 ) /* q1 > p1 ? 1 : 0 */ ;\
TWO(PSRLW ( CONST(15), MP2 )) /* q2 > q2 ? 1 : 0 */ ;\
;\
PSLLW ( CONST(8), MP1 ) /* q1 > p1 ? 0x100 : 0 */ ;\
TWO(PSLLW ( CONST(8), MP2 )) /* q2 > q2 ? 0x100 : 0 */ ;\
;\
PSUBW ( MP1, MA1 ) /* t1 -=? 0x100 */ ;\
TWO(PSUBW ( MP2, MA2 )) /* t2 -=? 0x100 */ ;\
;\
PADDW ( M80, MA1 ) /* t1 += 0x80 */ ;\
TWO(PADDW ( M80, MA2 )) /* t2 += 0x80 */ ;\
;\
MOVQ ( MA1, MP1 ) ;\
PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\
;\
TWO(MOVQ ( MA2, MP2 )) ;\
TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\
;\
PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\
TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\
;\
PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\
TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\
;\
PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\
TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */
 
 
/* linear interpolation - geometric series with correction
*
* instead of the roundoff this adds a small correction to satisfy the OpenGL criteria
*
* t/255 ~= (t + (t >> 8) + (t >> 15)) >> 8
*
* note that although is faster than rounding off it doesn't give always the exact results
*/
#define GMB_LERP_GSC( MP1, MQ1, MA1, MP2, MQ2, MA2) \
PSUBW ( MQ1, MP1 ) /* pa1 - qa1 | pb1 - qb1 | pg1 - qg1 | pr1 - qr1 */ ;\
PSLLW ( CONST(8), MQ1 ) /* q1 << 8 */ ;\
PMULLW ( MP1, MA1 ) /* t1 = (q1 - p1)*pa1 */ ;\
;\
TWO(PSUBW ( MQ2, MP2 )) /* pa2 - qa2 | pb2 - qb2 | pg2 - qg2 | pr2 - qr2 */ ;\
TWO(PSLLW ( CONST(8), MQ2 )) /* q2 << 8 */ ;\
TWO(PMULLW ( MP2, MA2 )) /* t2 = (q2 - p2)*pa2 */ ;\
;\
MOVQ ( MA1, MP1 ) ;\
PSRLW ( CONST(8), MA1 ) /* t1 >> 8 */ ;\
;\
TWO(MOVQ ( MA2, MP2 )) ;\
TWO(PSRLW ( CONST(8), MA2 )) /* t2 >> 8 */ ;\
;\
PADDW ( MA1, MP1 ) /* t1 + (t1 >> 8) ~= (t1/255) << 8 */ ;\
PSRLW ( CONST(7), MA1 ) /* t1 >> 15 */ ;\
;\
TWO(PADDW ( MA2, MP2 )) /* t2 + (t2 >> 8) ~= (t2/255) << 8 */ ;\
TWO(PSRLW ( CONST(7), MA2 )) /* t2 >> 15 */ ;\
;\
PADDW ( MP1, MA1 ) /* t1 + (t1 >> 8) + (t1 >>15) ~= (t1/255) << 8 */ ;\
TWO(PADDW ( MP2, MA2 )) /* t2 + (t2 >> 8) + (t2 >>15) ~= (t2/255) << 8 */ ;\
;\
PADDW ( MQ1, MA1 ) /* (t1/255 + q1) << 8 */ ;\
TWO(PADDW ( MQ2, MA2 )) /* (t2/255 + q2) << 8 */ ;\
;\
PSRLW ( CONST(8), MA1 ) /* sa1 | sb1 | sg1 | sr1 */ ;\
TWO(PSRLW ( CONST(8), MA2 )) /* sa2 | sb2 | sg2 | sr2 */
 
 
/* common blending setup code
*
* note that M00 is a register with 0x0000000000000000 constant which can be easily obtained making
*
* PXOR ( M00, M00 )
*/
#define GMB_LOAD(rgba, dest, MPP, MQQ) \
ONE(MOVD ( REGIND(rgba), MPP )) /* | | | | qa1 | qb1 | qg1 | qr1 */ ;\
ONE(MOVD ( REGIND(dest), MQQ )) /* | | | | pa1 | pb1 | pg1 | pr1 */ ;\
;\
TWO(MOVQ ( REGIND(rgba), MPP )) /* qa2 | qb2 | qg2 | qr2 | qa1 | qb1 | qg1 | qr1 */ ;\
TWO(MOVQ ( REGIND(dest), MQQ )) /* pa2 | pb2 | pg2 | pr2 | pa1 | pb1 | pg1 | pr1 */
 
#define GMB_UNPACK(MP1, MQ1, MP2, MQ2, M00) \
TWO(MOVQ ( MP1, MP2 )) ;\
TWO(MOVQ ( MQ1, MQ2 )) ;\
;\
PUNPCKLBW ( M00, MQ1 ) /* qa1 | qb1 | qg1 | qr1 */ ;\
TWO(PUNPCKHBW ( M00, MQ2 )) /* qa2 | qb2 | qg2 | qr2 */ ;\
PUNPCKLBW ( M00, MP1 ) /* pa1 | pb1 | pg1 | pr1 */ ;\
TWO(PUNPCKHBW ( M00, MP2 )) /* pa2 | pb2 | pg2 | pr2 */
 
#define GMB_ALPHA(MP1, MA1, MP2, MA2) \
MOVQ ( MP1, MA1 ) ;\
TWO(MOVQ ( MP2, MA2 )) ;\
;\
PUNPCKHWD ( MA1, MA1 ) /* pa1 | pa1 | | */ ;\
TWO(PUNPCKHWD ( MA2, MA2 )) /* pa2 | pa2 | | */ ;\
PUNPCKHDQ ( MA1, MA1 ) /* pa1 | pa1 | pa1 | pa1 */ ;\
TWO(PUNPCKHDQ ( MA2, MA2 )) /* pa2 | pa2 | pa2 | pa2 */
 
#define GMB_PACK( MS1, MS2 ) \
PACKUSWB ( MS2, MS1 ) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ ;\
 
#define GMB_STORE(rgba, MSS ) \
ONE(MOVD ( MSS, REGIND(rgba) )) /* | | | | sa1 | sb1 | sg1 | sr1 */ ;\
TWO(MOVQ ( MSS, REGIND(rgba) )) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */
 
 
SEG_DATA
 
ALIGNDATA8
const_0080:
D_LONG 0x00800080, 0x00800080
 
const_80:
D_LONG 0x80808080, 0x80808080
 
SEG_TEXT
 
 
/* Blend transparency function
*/
 
#define TAG(x) x##_transparency
 
#define INIT \
PXOR ( MM0, MM0 ) /* 0x0000 | 0x0000 | 0x0000 | 0x0000 */
 
#define MAIN( rgba, dest ) \
GMB_LOAD( rgba, dest, MM1, MM2 ) ;\
GMB_UNPACK( MM1, MM2, MM4, MM5, MM0 ) ;\
GMB_ALPHA( MM1, MM3, MM4, MM6 ) ;\
GMB_LERP_GSC( MM1, MM2, MM3, MM4, MM5, MM6 ) ;\
GMB_PACK( MM3, MM6 ) ;\
GMB_STORE( rgba, MM3 )
 
#include "mmx_blendtmp.h"
 
 
/* Blend add function
*
* FIXME: Add some loop unrolling here...
*/
 
#define TAG(x) x##_add
 
#define INIT
 
#define MAIN( rgba, dest ) \
ONE(MOVD ( REGIND(rgba), MM1 )) /* | | | | qa1 | qb1 | qg1 | qr1 */ ;\
ONE(MOVD ( REGIND(dest), MM2 )) /* | | | | pa1 | pb1 | pg1 | pr1 */ ;\
ONE(PADDUSB ( MM2, MM1 )) ;\
ONE(MOVD ( MM1, REGIND(rgba) )) /* | | | | sa1 | sb1 | sg1 | sr1 */ ;\
;\
TWO(MOVQ ( REGIND(rgba), MM1 )) /* qa2 | qb2 | qg2 | qr2 | qa1 | qb1 | qg1 | qr1 */ ;\
TWO(PADDUSB ( REGIND(dest), MM1 )) /* sa2 | sb2 | sg2 | sr2 | sa1 | sb1 | sg1 | sr1 */ ;\
TWO(MOVQ ( MM1, REGIND(rgba) ))
 
#include "mmx_blendtmp.h"
 
 
/* Blend min function
*/
 
#define TAG(x) x##_min
 
#define INIT \
MOVQ ( CONTENT(const_80), MM7 ) /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/
 
#define MAIN( rgba, dest ) \
GMB_LOAD( rgba, dest, MM1, MM2 ) ;\
MOVQ ( MM1, MM3 ) ;\
MOVQ ( MM2, MM4 ) ;\
PXOR ( MM7, MM3 ) /* unsigned -> signed */ ;\
PXOR ( MM7, MM4 ) /* unsigned -> signed */ ;\
PCMPGTB ( MM3, MM4 ) /* q > p ? 0xff : 0x00 */ ;\
PAND ( MM4, MM1 ) /* q > p ? p : 0 */ ;\
PANDN ( MM2, MM4 ) /* q > p ? 0 : q */ ;\
POR ( MM1, MM4 ) /* q > p ? p : q */ ;\
GMB_STORE( rgba, MM4 )
 
#include "mmx_blendtmp.h"
 
 
/* Blend max function
*/
 
#define TAG(x) x##_max
 
#define INIT \
MOVQ ( CONTENT(const_80), MM7 ) /* 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80| 0x80*/
 
#define MAIN( rgba, dest ) \
GMB_LOAD( rgba, dest, MM1, MM2 ) ;\
MOVQ ( MM1, MM3 ) ;\
MOVQ ( MM2, MM4 ) ;\
PXOR ( MM7, MM3 ) /* unsigned -> signed */ ;\
PXOR ( MM7, MM4 ) /* unsigned -> signed */ ;\
PCMPGTB ( MM3, MM4 ) /* q > p ? 0xff : 0x00 */ ;\
PAND ( MM4, MM2 ) /* q > p ? q : 0 */ ;\
PANDN ( MM1, MM4 ) /* q > p ? 0 : p */ ;\
POR ( MM2, MM4 ) /* q > p ? p : q */ ;\
GMB_STORE( rgba, MM4 )
 
#include "mmx_blendtmp.h"
 
 
/* Blend modulate function
*/
 
#define TAG(x) x##_modulate
 
#define INIT \
PXOR ( MM0, MM0 ) /* 0x0000 | 0x0000 | 0x0000 | 0x0000 */ ;\
MOVQ ( CONTENT(const_0080), MM7 ) /* 0x0080 | 0x0080 | 0x0080 | 0x0080 */
 
#define MAIN( rgba, dest ) \
GMB_LOAD( rgba, dest, MM1, MM2 ) ;\
GMB_UNPACK( MM1, MM2, MM4, MM5, MM0 ) ;\
GMB_MULT_GSR( MM1, MM2, MM4, MM5, MM7 ) ;\
GMB_PACK( MM2, MM5 ) ;\
GMB_STORE( rgba, MM2 )
 
#include "mmx_blendtmp.h"
 
/shark/trunk/ports/mesa/src/X86/3dnow.c
0,0 → 1,89
/* $Id: 3dnow.c,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* 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.
*/
 
/*
* 3DNow! optimizations contributed by
* Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
*/
 
#include "glheader.h"
#include "context.h"
#include "math/m_xform.h"
#include "tnl/t_context.h"
 
#include "3dnow.h"
#include "common_x86_macros.h"
 
#ifdef DEBUG
#include "math/m_debug.h"
#endif
 
 
#ifdef USE_3DNOW_ASM
DECLARE_XFORM_GROUP( 3dnow, 2 )
DECLARE_XFORM_GROUP( 3dnow, 3 )
DECLARE_XFORM_GROUP( 3dnow, 4 )
 
DECLARE_NORM_GROUP( 3dnow )
 
 
extern void _ASMAPI
_mesa_v16_3dnow_general_xform( GLfloat *first_vert,
const GLfloat *m,
const GLfloat *src,
GLuint src_stride,
GLuint count );
 
extern void _ASMAPI
_mesa_3dnow_project_vertices( GLfloat *first,
GLfloat *last,
const GLfloat *m,
GLuint stride );
 
extern void _ASMAPI
_mesa_3dnow_project_clipped_vertices( GLfloat *first,
GLfloat *last,
const GLfloat *m,
GLuint stride,
const GLubyte *clipmask );
#endif
 
 
void _mesa_init_3dnow_transform_asm( void )
{
#ifdef USE_3DNOW_ASM
ASSIGN_XFORM_GROUP( 3dnow, 2 );
ASSIGN_XFORM_GROUP( 3dnow, 3 );
ASSIGN_XFORM_GROUP( 3dnow, 4 );
 
ASSIGN_NORM_GROUP( 3dnow );
 
#ifdef DEBUG
_math_test_all_transform_functions( "3DNow!" );
_math_test_all_normal_transform_functions( "3DNow!" );
#endif
#endif
}
/shark/trunk/ports/mesa/src/X86/norm_args.h
0,0 → 1,58
/* $Id: norm_args.h,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* Normal transform function interface for assembly code. Simply define
* FRAME_OFFSET to the number of bytes pushed onto the stack before
* using the ARG_* argument macros.
*
* Gareth Hughes
*/
 
#ifndef __NORM_ARGS_H__
#define __NORM_ARGS_H__
 
/* Offsets for normal_func arguments
*
* typedef void (*normal_func)( CONST GLmatrix *mat,
* GLfloat scale,
* CONST GLvector3f *in,
* CONST GLfloat lengths[],
* GLvector3f *dest );
*/
#define OFFSET_MAT 4
#define OFFSET_SCALE 8
#define OFFSET_IN 12
#define OFFSET_LENGTHS 16
#define OFFSET_DEST 20
 
#define ARG_MAT REGOFF(FRAME_OFFSET+OFFSET_MAT, ESP)
#define ARG_SCALE REGOFF(FRAME_OFFSET+OFFSET_SCALE, ESP)
#define ARG_IN REGOFF(FRAME_OFFSET+OFFSET_IN, ESP)
#define ARG_LENGTHS REGOFF(FRAME_OFFSET+OFFSET_LENGTHS, ESP)
#define ARG_DEST REGOFF(FRAME_OFFSET+OFFSET_DEST, ESP)
 
#endif
/shark/trunk/ports/mesa/src/X86/common_x86.c
0,0 → 1,65
/* $Id: common_x86.c,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 5.0
*
* 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.
*/
 
/*
* Check CPU capabilities & initialize optimized funtions for this particular
* processor.
*
* Written by Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
* Changed by Andre Werthmann <wertmann@cs.uni-potsdam.de> for using the
* new Katmai functions.
*/
 
#include <stdlib.h>
#include <stdio.h>
#if defined(USE_SSE_ASM) && defined(__linux__)
#include <signal.h>
#endif
#if defined(USE_SSE_ASM) && defined(__FreeBSD__)
#include <sys/types.h>
#include <sys/sysctl.h>
#endif
 
#include "context.h"
#include "common_x86_asm.h"
#include "imports.h"
 
 
int _mesa_x86_cpu_features = 1;
 
void _mesa_init_all_x86_transform_asm( void )
{
_mesa_x86_cpu_features = 1;
 
if ( _mesa_x86_cpu_features ) {
_mesa_init_x86_transform_asm();
}
 
_mesa_x86_cpu_features &= ~(X86_FEATURE_XMM);
 
}
 
/shark/trunk/ports/mesa/src/X86/3dnow.h
0,0 → 1,39
/* $Id: 3dnow.h,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* 3DNow! optimizations contributed by
* Holger Waechtler <holger@akaflieg.extern.tu-berlin.de>
*/
 
#ifndef __3DNOW_H__
#define __3DNOW_H__
 
#include "math/m_xform.h"
 
void _mesa_init_3dnow_transform_asm( void );
 
#endif
/shark/trunk/ports/mesa/src/X86/sse_xform1.s
0,0 → 1,433
/* $Id: sse_xform1.s,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/** TODO:
* - insert PREFETCH instructions to avoid cache-misses !
* - some more optimizations are possible...
* - for 40-50% more performance in the SSE-functions, the
* data (trans-matrix, src_vert, dst_vert) needs to be 16byte aligned !
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define S(i) REGOFF(i * 4, ESI)
#define D(i) REGOFF(i * 4, EDI)
#define M(i) REGOFF(i * 4, EDX)
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points1_general)
GLNAME( _mesa_sse_transform_points1_general ):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
CMP_L( CONST(0), ECX ) /* count == 0 ? */
JE( LLBL(K_GTP1GR_finish) ) /* yes -> nothing to do. */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
 
ALIGNTEXT32
MOVAPS( M(0), XMM0 ) /* m3 | m2 | m1 | m0 */
MOVAPS( M(12), XMM1 ) /* m15 | m14 | m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP1GR_top):
MOVSS( S(0), XMM2 ) /* ox */
SHUFPS( CONST(0x0), XMM2, XMM2 ) /* ox | ox | ox | ox */
MULPS( XMM0, XMM2 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */
ADDPS( XMM1, XMM2 ) /* + | + | + | + */
MOVUPS( XMM2, D(0) )
 
LLBL(K_GTP1GR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP1GR_top) )
 
LLBL(K_GTP1GR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points1_identity)
GLNAME( _mesa_sse_transform_points1_identity ):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP1IR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_1), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(1), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
CMP_L( ESI, EDI )
JE( LLBL(K_GTP1IR_finish) )
 
 
ALIGNTEXT32
LLBL(K_GTP1IR_top):
MOV_L( S(0), EDX )
MOV_L( EDX, D(0) )
 
LLBL(K_GTP1IR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP1IR_top) )
 
LLBL(K_GTP1IR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points1_3d_no_rot)
GLNAME(_mesa_sse_transform_points1_3d_no_rot):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP13DNRR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
 
ALIGNTEXT32
MOVSS( M(0), XMM0 ) /* m0 */
MOVSS( M(12), XMM1 ) /* m12 */
MOVSS( M(13), XMM2 ) /* m13 */
MOVSS( M(14), XMM3 ) /* m14 */
 
ALIGNTEXT32
LLBL(K_GTP13DNRR_top):
MOVSS( S(0), XMM4 ) /* ox */
MULSS( XMM0, XMM4 ) /* ox*m0 */
ADDSS( XMM1, XMM4 ) /* ox*m0+m12 */
MOVSS( XMM4, D(0) )
 
MOVSS( XMM2, D(1) )
MOVSS( XMM3, D(2) )
 
LLBL(K_GTP13DNRR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP13DNRR_top) )
 
LLBL(K_GTP13DNRR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points1_perspective)
GLNAME(_mesa_sse_transform_points1_perspective):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP13PR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
 
ALIGNTEXT32
XORPS( XMM0, XMM0 ) /* 0 | 0 | 0 | 0 */
MOVSS( M(0), XMM1 ) /* m0 */
MOVSS( M(14), XMM2 ) /* m14 */
 
ALIGNTEXT32
LLBL(K_GTP13PR_top):
MOVSS( S(0), XMM3 ) /* ox */
MULSS( XMM1, XMM3 ) /* ox*m0 */
MOVSS( XMM3, D(0) ) /* ox*m0->D(0) */
MOVSS( XMM2, D(2) ) /* m14->D(2) */
 
MOVSS( XMM0, D(1) )
MOVSS( XMM0, D(3) )
 
LLBL(K_GTP13PR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP13PR_top) )
 
LLBL(K_GTP13PR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points1_2d)
GLNAME(_mesa_sse_transform_points1_2d):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP13P2DR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVLPS( M(0), XMM0 ) /* m1 | m0 */
MOVLPS( M(12), XMM1 ) /* m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP13P2DR_top):
MOVSS( S(0), XMM2 ) /* ox */
SHUFPS( CONST(0x0), XMM2, XMM2 ) /* ox | ox | ox | ox */
MULPS( XMM0, XMM2 ) /* - | - | ox*m1 | ox*m0 */
ADDPS( XMM1, XMM2 ) /* - | - | ox*m1+m13 | ox*m0+m12 */
MOVLPS( XMM2, D(0) )
 
LLBL(K_GTP13P2DR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP13P2DR_top) )
 
LLBL(K_GTP13P2DR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points1_2d_no_rot)
GLNAME(_mesa_sse_transform_points1_2d_no_rot):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP13P2DNRR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVSS( M(0), XMM0 ) /* m0 */
MOVSS( M(12), XMM1 ) /* m12 */
MOVSS( M(13), XMM2 ) /* m13 */
 
ALIGNTEXT32
LLBL(K_GTP13P2DNRR_top):
MOVSS( S(0), XMM3 ) /* ox */
MULSS( XMM0, XMM3 ) /* ox*m0 */
ADDSS( XMM1, XMM3 ) /* ox*m0+m12 */
MOVSS( XMM3, D(0) )
MOVSS( XMM2, D(1) )
 
LLBL(K_GTP13P2DNRR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP13P2DNRR_top) )
 
LLBL(K_GTP13P2DNRR_finish):
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points1_3d)
GLNAME(_mesa_sse_transform_points1_3d):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP13P3DR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
 
ALIGNTEXT32
MOVAPS( M(0), XMM0 ) /* m3 | m2 | m1 | m0 */
MOVAPS( M(12), XMM1 ) /* m15 | m14 | m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP13P3DR_top):
MOVSS( S(0), XMM2 ) /* ox */
SHUFPS( CONST(0x0), XMM2, XMM2 ) /* ox | ox | ox | ox */
MULPS( XMM0, XMM2 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */
ADDPS( XMM1, XMM2 ) /* +m15 | +m14 | +m13 | +m12 */
MOVLPS( XMM2, D(0) ) /* - | - | ->D(1)| ->D(0)*/
UNPCKHPS( XMM2, XMM2 ) /* ox*m3+m15 | ox*m3+m15 | ox*m2+m14 | ox*m2+m14 */
MOVSS( XMM2, D(2) )
 
LLBL(K_GTP13P3DR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP13P3DR_top) )
 
LLBL(K_GTP13P3DR_finish):
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
/shark/trunk/ports/mesa/src/X86/common_x86_macros.h
0,0 → 1,107
/* $Id: common_x86_macros.h,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*
* Authors:
* Gareth Hughes
*/
 
#ifndef __COMMON_X86_MACROS_H__
#define __COMMON_X86_MACROS_H__
 
 
/* =============================================================
* Transformation function declarations:
*/
 
#define XFORM_ARGS GLvector4f *to_vec, \
const GLfloat m[16], \
const GLvector4f *from_vec
 
#define DECLARE_XFORM_GROUP( pfx, sz ) \
extern void _ASMAPI _mesa_##pfx##_transform_points##sz##_general( XFORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_points##sz##_identity( XFORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_points##sz##_3d_no_rot( XFORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_points##sz##_perspective( XFORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_points##sz##_2d( XFORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_points##sz##_2d_no_rot( XFORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_points##sz##_3d( XFORM_ARGS );
 
#define ASSIGN_XFORM_GROUP( pfx, sz ) \
_mesa_transform_tab[sz][MATRIX_GENERAL] = \
_mesa_##pfx##_transform_points##sz##_general; \
_mesa_transform_tab[sz][MATRIX_IDENTITY] = \
_mesa_##pfx##_transform_points##sz##_identity; \
_mesa_transform_tab[sz][MATRIX_3D_NO_ROT] = \
_mesa_##pfx##_transform_points##sz##_3d_no_rot; \
_mesa_transform_tab[sz][MATRIX_PERSPECTIVE] = \
_mesa_##pfx##_transform_points##sz##_perspective; \
_mesa_transform_tab[sz][MATRIX_2D] = \
_mesa_##pfx##_transform_points##sz##_2d; \
_mesa_transform_tab[sz][MATRIX_2D_NO_ROT] = \
_mesa_##pfx##_transform_points##sz##_2d_no_rot; \
_mesa_transform_tab[sz][MATRIX_3D] = \
_mesa_##pfx##_transform_points##sz##_3d;
 
 
/* =============================================================
* Normal transformation function declarations:
*/
 
#define NORM_ARGS const GLmatrix *mat, \
GLfloat scale, \
const GLvector4f *in, \
const GLfloat *lengths, \
GLvector4f *dest
 
#define DECLARE_NORM_GROUP( pfx ) \
extern void _ASMAPI _mesa_##pfx##_rescale_normals( NORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_normalize_normals( NORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_normals( NORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_normals_no_rot( NORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_rescale_normals( NORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_rescale_normals_no_rot( NORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_normalize_normals( NORM_ARGS ); \
extern void _ASMAPI _mesa_##pfx##_transform_normalize_normals_no_rot( NORM_ARGS );
 
#define ASSIGN_NORM_GROUP( pfx ) \
_mesa_normal_tab[NORM_RESCALE] = \
_mesa_##pfx##_rescale_normals; \
_mesa_normal_tab[NORM_NORMALIZE] = \
_mesa_##pfx##_normalize_normals; \
_mesa_normal_tab[NORM_TRANSFORM] = \
_mesa_##pfx##_transform_normals; \
_mesa_normal_tab[NORM_TRANSFORM_NO_ROT] = \
_mesa_##pfx##_transform_normals_no_rot; \
_mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] = \
_mesa_##pfx##_transform_rescale_normals; \
_mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] = \
_mesa_##pfx##_transform_rescale_normals_no_rot; \
_mesa_normal_tab[NORM_TRANSFORM | NORM_NORMALIZE] = \
_mesa_##pfx##_transform_normalize_normals; \
_mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_NORMALIZE] = \
_mesa_##pfx##_transform_normalize_normals_no_rot;
 
 
#endif
/shark/trunk/ports/mesa/src/X86/sse_xform2.s
0,0 → 1,452
/* $Id: sse_xform2.s,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/** TODO:
* - insert PREFETCH instructions to avoid cache-misses !
* - some more optimizations are possible...
* - for 40-50% more performance in the SSE-functions, the
* data (trans-matrix, src_vert, dst_vert) needs to be 16byte aligned !
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define S(i) REGOFF(i * 4, ESI)
#define D(i) REGOFF(i * 4, EDI)
#define M(i) REGOFF(i * 4, EDX)
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points2_general)
GLNAME( _mesa_sse_transform_points2_general ):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX )
JZ( LLBL(K_GTP2GR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVAPS( M(0), XMM0 ) /* m3 | m2 | m1 | m0 */
MOVAPS( M(4), XMM1 ) /* m7 | m6 | m5 | m4 */
MOVAPS( M(12), XMM2 ) /* m15 | m14 | m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP2GR_top):
MOVSS( S(0), XMM3 ) /* ox */
SHUFPS( CONST(0x0), XMM3, XMM3 ) /* ox | ox | ox | ox */
MULPS( XMM0, XMM3 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */
MOVSS( S(1), XMM4 ) /* oy */
SHUFPS( CONST(0x0), XMM4, XMM4 ) /* oy | oy | oy | oy */
MULPS( XMM1, XMM4 ) /* oy*m7 | oy*m6 | oy*m5 | oy*m4 */
 
ADDPS( XMM4, XMM3 )
ADDPS( XMM2, XMM3 )
MOVAPS( XMM3, D(0) )
 
LLBL(K_GTP2GR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP2GR_top) )
 
LLBL(K_GTP2GR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points2_identity)
GLNAME( _mesa_sse_transform_points2_identity ):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP2IR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
CMP_L( ESI, EDI )
JE( LLBL(K_GTP2IR_finish) )
 
 
ALIGNTEXT32
LLBL(K_GTP2IR_top):
MOV_L ( S(0), EDX )
MOV_L ( EDX, D(0) )
MOV_L ( S(1), EDX )
MOV_L ( EDX, D(1) )
 
LLBL(K_GTP2IR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP2IR_top) )
 
LLBL(K_GTP2IR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points2_3d_no_rot)
GLNAME(_mesa_sse_transform_points2_3d_no_rot):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP23DNRR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
 
ALIGNTEXT32
MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */
MOVSS ( M(5), XMM2 ) /* - | - | - | m5 */
UNPCKLPS ( XMM2, XMM1 ) /* - | - | m5 | m0 */
MOVLPS ( M(12), XMM2 ) /* - | - | m13 | m12 */
MOVSS ( M(14), XMM3 ) /* - | - | - | m14 */
 
ALIGNTEXT32
LLBL(K_GTP23DNRR_top):
MOVLPS ( S(0), XMM0 ) /* - | - | oy | ox */
MULPS ( XMM1, XMM0 ) /* - | - | oy*m5 | ox*m0 */
ADDPS ( XMM2, XMM0 ) /* - | - | +m13 | +m12 */
MOVLPS ( XMM0, D(0) ) /* -> D(1) | -> D(0) */
 
MOVSS ( XMM3, D(2) ) /* -> D(2) */
 
LLBL(K_GTP23DNRR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP23DNRR_top) )
 
LLBL(K_GTP23DNRR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points2_perspective)
GLNAME(_mesa_sse_transform_points2_perspective):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP23PR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */
MOVSS ( M(5), XMM2 ) /* - | - | - | m5 */
UNPCKLPS ( XMM2, XMM1 ) /* - | - | m5 | m0 */
MOVSS ( M(14), XMM3 ) /* m14 */
XORPS ( XMM0, XMM0 ) /* 0 | 0 | 0 | 0 */
 
ALIGNTEXT32
LLBL(K_GTP23PR_top):
MOVLPS( S(0), XMM4 ) /* oy | ox */
MULPS( XMM1, XMM4 ) /* oy*m5 | ox*m0 */
MOVLPS( XMM4, D(0) ) /* ->D(1) | ->D(0) */
MOVSS( XMM3, D(2) ) /* ->D(2) */
MOVSS( XMM0, D(3) ) /* ->D(3) */
 
LLBL(K_GTP23PR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP23PR_top) )
 
LLBL(K_GTP23PR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points2_2d)
GLNAME(_mesa_sse_transform_points2_2d):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP23P2DR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVLPS( M(0), XMM0 ) /* m1 | m0 */
MOVLPS( M(4), XMM1 ) /* m5 | m4 */
MOVLPS( M(12), XMM2 ) /* m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP23P2DR_top):
MOVSS( S(0), XMM3 ) /* ox */
SHUFPS( CONST(0x0), XMM3, XMM3 ) /* ox | ox */
MULPS( XMM0, XMM3 ) /* ox*m1 | ox*m0 */
 
MOVSS( S(1), XMM4 ) /* oy */
SHUFPS( CONST(0x0), XMM4, XMM4 ) /* oy | oy */
MULPS( XMM1, XMM4 ) /* oy*m5 | oy*m4 */
 
ADDPS( XMM4, XMM3 )
ADDPS( XMM2, XMM3 )
MOVLPS( XMM3, D(0) ) /* ->D(1) | ->D(0) */
 
LLBL(K_GTP23P2DR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP23P2DR_top) )
 
LLBL(K_GTP23P2DR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points2_2d_no_rot)
GLNAME(_mesa_sse_transform_points2_2d_no_rot):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP23P2DNRR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_2), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(2), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVSS ( M(0), XMM1 ) /* m0 */
MOVSS ( M(5), XMM2 ) /* m5 */
UNPCKLPS ( XMM2, XMM1 ) /* m5 | m0 */
MOVLPS ( M(12), XMM2 ) /* m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP23P2DNRR_top):
MOVLPS( S(0), XMM0 ) /* oy | ox */
MULPS( XMM1, XMM0 ) /* oy*m5 | ox*m0 */
ADDPS( XMM2, XMM0 ) /* +m13 | +m12 */
MOVLPS( XMM0, D(0) ) /* ->D(1) | ->D(0) */
 
LLBL(K_GTP23P2DNRR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP23P2DNRR_top) )
 
LLBL(K_GTP23P2DNRR_finish):
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points2_3d)
GLNAME(_mesa_sse_transform_points2_3d):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP23P3DR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVAPS( M(0), XMM0 ) /* m2 | m1 | m0 */
MOVAPS( M(4), XMM1 ) /* m6 | m5 | m4 */
MOVAPS( M(12), XMM2 ) /* m14 | m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP23P3DR_top):
MOVSS( S(0), XMM3 ) /* ox */
SHUFPS( CONST(0x0), XMM3, XMM3 ) /* ox | ox | ox */
MULPS( XMM0, XMM3 ) /* ox*m2 | ox*m1 | ox*m0 */
 
MOVSS( S(1), XMM4 ) /* oy */
SHUFPS( CONST(0x0), XMM4, XMM4 ) /* oy | oy | oy */
MULPS( XMM1, XMM4 ) /* oy*m6 | oy*m5 | oy*m4 */
 
ADDPS( XMM4, XMM3 )
ADDPS( XMM2, XMM3 )
 
MOVLPS( XMM3, D(0) ) /* ->D(1) | ->D(0) */
UNPCKHPS( XMM3, XMM3 )
MOVSS( XMM3, D(2) ) /* ->D(2) */
 
LLBL(K_GTP23P3DR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP23P3DR_top) )
 
LLBL(K_GTP23P3DR_finish):
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
/shark/trunk/ports/mesa/src/X86/sse_xform3.s
0,0 → 1,498
/* $Id: sse_xform3.s,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/** TODO:
* - insert PREFETCH instructions to avoid cache-misses !
* - some more optimizations are possible...
* - for 40-50% more performance in the SSE-functions, the
* data (trans-matrix, src_vert, dst_vert) needs to be 16byte aligned !
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define S(i) REGOFF(i * 4, ESI)
#define D(i) REGOFF(i * 4, EDI)
#define M(i) REGOFF(i * 4, EDX)
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points3_general)
GLNAME( _mesa_sse_transform_points3_general ):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
CMP_L ( CONST(0), ECX ) /* count == 0 ? */
JE ( LLBL(K_GTPGR_finish) ) /* yes -> nothing to do. */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
 
ALIGNTEXT32
MOVAPS ( REGOFF(0, EDX), XMM0 ) /* m0 | m1 | m2 | m3 */
MOVAPS ( REGOFF(16, EDX), XMM1 ) /* m4 | m5 | m6 | m7 */
MOVAPS ( REGOFF(32, EDX), XMM2 ) /* m8 | m9 | m10 | m11 */
MOVAPS ( REGOFF(48, EDX), XMM3 ) /* m12 | m13 | m14 | m15 */
 
 
ALIGNTEXT32
LLBL(K_GTPGR_top):
MOVSS ( REGOFF(0, ESI), XMM4 ) /* | | | ox */
SHUFPS ( CONST(0x0), XMM4, XMM4 ) /* ox | ox | ox | ox */
MOVSS ( REGOFF(4, ESI), XMM5 ) /* | | | oy */
SHUFPS ( CONST(0x0), XMM5, XMM5 ) /* oy | oy | oy | oy */
MOVSS ( REGOFF(8, ESI), XMM6 ) /* | | | oz */
SHUFPS ( CONST(0x0), XMM6, XMM6 ) /* oz | oz | oz | oz */
 
MULPS ( XMM0, XMM4 ) /* m3*ox | m2*ox | m1*ox | m0*ox */
MULPS ( XMM1, XMM5 ) /* m7*oy | m6*oy | m5*oy | m4*oy */
MULPS ( XMM2, XMM6 ) /* m11*oz | m10*oz | m9*oz | m8*oz */
 
ADDPS ( XMM5, XMM4 )
ADDPS ( XMM6, XMM4 )
ADDPS ( XMM3, XMM4 )
 
MOVAPS ( XMM4, REGOFF(0, EDI) )
 
LLBL(K_GTPGR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTPGR_top) )
 
LLBL(K_GTPGR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points3_identity)
GLNAME( _mesa_sse_transform_points3_identity ):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTPIR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
CMP_L( ESI, EDI )
JE( LLBL(K_GTPIR_finish) )
 
 
ALIGNTEXT32
LLBL(K_GTPIR_top):
MOVLPS ( S(0), XMM0 )
MOVLPS ( XMM0, D(0) )
MOVSS ( S(2), XMM0 )
MOVSS ( XMM0, D(2) )
 
LLBL(K_GTPIR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTPIR_top) )
 
LLBL(K_GTPIR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points3_3d_no_rot)
GLNAME(_mesa_sse_transform_points3_3d_no_rot):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP3DNRR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
 
ALIGNTEXT32
MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */
MOVSS ( M(5), XMM2 ) /* - | - | - | m5 */
UNPCKLPS ( XMM2, XMM1 ) /* - | - | m5 | m0 */
MOVLPS ( M(12), XMM2 ) /* - | - | m13 | m12 */
MOVSS ( M(10), XMM3 ) /* - | - | - | m10 */
MOVSS ( M(14), XMM4 ) /* - | - | - | m14 */
 
ALIGNTEXT32
LLBL(K_GTP3DNRR_top):
 
MOVLPS ( S(0), XMM0 ) /* - | - | s1 | s0 */
MULPS ( XMM1, XMM0 ) /* - | - | s1*m5 | s0*m0 */
ADDPS ( XMM2, XMM0 ) /* - | - | +m13 | +m12 */
MOVLPS ( XMM0, D(0) ) /* -> D(1) | -> D(0) */
 
MOVSS ( S(2), XMM0 ) /* sz */
MULSS ( XMM3, XMM0 ) /* sz*m10 */
ADDSS ( XMM4, XMM0 ) /* +m14 */
MOVSS ( XMM0, D(2) ) /* -> D(2) */
 
LLBL(K_GTP3DNRR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP3DNRR_top) )
 
LLBL(K_GTP3DNRR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points3_perspective)
GLNAME(_mesa_sse_transform_points3_perspective):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP3PR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVSS ( M(0), XMM1 ) /* - | - | - | m0 */
MOVSS ( M(5), XMM2 ) /* - | - | - | m5 */
UNPCKLPS ( XMM2, XMM1 ) /* - | - | m5 | m0 */
MOVLPS ( M(8), XMM2 ) /* - | - | m9 | m8 */
MOVSS ( M(10), XMM3 ) /* m10 */
MOVSS ( M(14), XMM4 ) /* m14 */
XORPS ( XMM6, XMM6 ) /* 0 */
 
ALIGNTEXT32
LLBL(K_GTP3PR_top):
MOVLPS ( S(0), XMM0 ) /* oy | ox */
MULPS ( XMM1, XMM0 ) /* oy*m5 | ox*m0 */
MOVSS ( S(2), XMM5 ) /* oz */
SHUFPS ( CONST(0x0), XMM5, XMM5 ) /* oz | oz */
MULPS ( XMM2, XMM5 ) /* oz*m9 | oz*m8 */
ADDPS ( XMM5, XMM0 ) /* +oy*m5 | +ox*m0 */
MOVLPS ( XMM0, D(0) ) /* ->D(1) | ->D(0) */
 
MOVSS ( S(2), XMM0 ) /* oz */
MULSS ( XMM3, XMM0 ) /* oz*m10 */
ADDSS ( XMM4, XMM0 ) /* +m14 */
MOVSS ( XMM0, D(2) ) /* ->D(2) */
 
MOVSS ( S(2), XMM0 ) /* oz */
MOVSS ( XMM6, XMM5 ) /* 0 */
SUBPS ( XMM0, XMM5 ) /* -oz */
MOVSS ( XMM5, D(3) ) /* ->D(3) */
 
LLBL(K_GTP3PR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP3PR_top) )
 
LLBL(K_GTP3PR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points3_2d)
GLNAME(_mesa_sse_transform_points3_2d):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP3P2DR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVLPS( M(0), XMM0 ) /* m1 | m0 */
MOVLPS( M(4), XMM1 ) /* m5 | m4 */
MOVLPS( M(12), XMM2 ) /* m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP3P2DR_top):
MOVSS ( S(0), XMM3 ) /* ox */
SHUFPS ( CONST(0x0), XMM3, XMM3 ) /* ox | ox */
MULPS ( XMM0, XMM3 ) /* ox*m1 | ox*m0 */
MOVSS ( S(1), XMM4 ) /* oy */
SHUFPS ( CONST(0x0), XMM4, XMM4 ) /* oy | oy */
MULPS ( XMM1, XMM4 ) /* oy*m5 | oy*m4 */
 
ADDPS ( XMM4, XMM3 )
ADDPS ( XMM2, XMM3 )
MOVLPS ( XMM3, D(0) )
 
MOVSS ( S(2), XMM3 )
MOVSS ( XMM3, D(2) )
 
LLBL(K_GTP3P2DR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_GTP3P2DR_top) )
 
LLBL(K_GTP3P2DR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points3_2d_no_rot)
GLNAME(_mesa_sse_transform_points3_2d_no_rot):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP3P2DNRR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVSS ( M(0), XMM1 ) /* m0 */
MOVSS ( M(5), XMM2 ) /* m5 */
UNPCKLPS ( XMM2, XMM1 ) /* m5 | m0 */
MOVLPS ( M(12), XMM2 ) /* m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP3P2DNRR_top):
MOVLPS( S(0), XMM0 ) /* oy | ox */
MULPS( XMM1, XMM0 ) /* oy*m5 | ox*m0 */
ADDPS( XMM2, XMM0 ) /* +m13 | +m12 */
MOVLPS( XMM0, D(0) ) /* ->D(1) | ->D(0) */
 
MOVSS( S(2), XMM0 )
MOVSS( XMM0, D(2) )
 
LLBL(K_GTP3P2DNRR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP3P2DNRR_top) )
 
LLBL(K_GTP3P2DNRR_finish):
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
 
 
 
 
ALIGNTEXT4
GLOBL GLNAME(_mesa_sse_transform_points3_3d)
GLNAME(_mesa_sse_transform_points3_3d):
 
#define FRAME_OFFSET 8
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( REGOFF(OFFSET_SOURCE+8, ESP), ESI ) /* ptr to source GLvector4f */
MOV_L( REGOFF(OFFSET_DEST+8, ESP), EDI ) /* ptr to dest GLvector4f */
 
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP3P3DR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) ) /* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
 
ALIGNTEXT32
MOVAPS( M(0), XMM0 ) /* m2 | m1 | m0 */
MOVAPS( M(4), XMM1 ) /* m6 | m5 | m4 */
MOVAPS( M(8), XMM2 ) /* m10 | m9 | m8 */
MOVAPS( M(12), XMM3 ) /* m14 | m13 | m12 */
 
ALIGNTEXT32
LLBL(K_GTP3P3DR_top):
MOVSS( S(0), XMM4 )
SHUFPS( CONST(0x0), XMM4, XMM4 ) /* ox | ox | ox */
MULPS( XMM0, XMM4 ) /* ox*m2 | ox*m1 | ox*m0 */
 
MOVSS( S(1), XMM5 )
SHUFPS( CONST(0x0), XMM5, XMM5 ) /* oy | oy | oy */
MULPS( XMM1, XMM5 ) /* oy*m6 | oy*m5 | oy*m4 */
 
MOVSS( S(2), XMM6 )
SHUFPS( CONST(0x0), XMM6, XMM6 ) /* oz | oz | oz */
MULPS( XMM2, XMM6 ) /* oz*m10 | oz*m9 | oz*m8 */
 
ADDPS( XMM5, XMM4 ) /* + | + | + */
ADDPS( XMM6, XMM4 ) /* + | + | + */
ADDPS( XMM3, XMM4 ) /* + | + | + */
 
MOVLPS( XMM4, D(0) ) /* => D(1) | => D(0) */
UNPCKHPS( XMM4, XMM4 )
MOVSS( XMM4, D(2) )
 
LLBL(K_GTP3P3DR_skip):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP3P3DR_top) )
 
LLBL(K_GTP3P3DR_finish):
POP_L( EDI )
POP_L( ESI )
RET
#undef FRAME_OFFSET
/shark/trunk/ports/mesa/src/X86/sse_xform4.s
0,0 → 1,226
/* $Id: sse_xform4.s,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
#include "matypes.h"
#include "xform_args.h"
 
SEG_TEXT
 
#define FRAME_OFFSET 8
 
#define SRC(i) REGOFF(i * 4, ESI)
#define DST(i) REGOFF(i * 4, EDI)
#define MAT(i) REGOFF(i * 4, EDX)
 
#define SELECT(r0, r1, r2, r3) CONST( r0 * 64 + r1 * 16 + r2 * 4 + r3 )
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_sse_transform_points4_general )
GLNAME( _mesa_sse_transform_points4_general ):
 
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX ) /* verify non-zero count */
JE( LLBL( sse_general_done ) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )/* set dest size */
 
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
 
PREFETCHT0( REGIND(ESI) )
 
MOVAPS( MAT(0), XMM4 ) /* m3 | m2 | m1 | m0 */
MOVAPS( MAT(4), XMM5 ) /* m7 | m6 | m5 | m4 */
MOVAPS( MAT(8), XMM6 ) /* m11 | m10 | m9 | m8 */
MOVAPS( MAT(12), XMM7 ) /* m15 | m14 | m13 | m12 */
 
ALIGNTEXT16
LLBL( sse_general_loop ):
 
MOVSS( SRC(0), XMM0 ) /* ox */
SHUFPS( CONST(0x0), XMM0, XMM0 ) /* ox | ox | ox | ox */
MULPS( XMM4, XMM0 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */
 
MOVSS( SRC(1), XMM1 ) /* oy */
SHUFPS( CONST(0x0), XMM1, XMM1 ) /* oy | oy | oy | oy */
MULPS( XMM5, XMM1 ) /* oy*m7 | oy*m6 | oy*m5 | oy*m4 */
 
MOVSS( SRC(2), XMM2 ) /* oz */
SHUFPS( CONST(0x0), XMM2, XMM2 ) /* oz | oz | oz | oz */
MULPS( XMM6, XMM2 ) /* oz*m11 | oz*m10 | oz*m9 | oz*m8 */
 
MOVSS( SRC(3), XMM3 ) /* ow */
SHUFPS( CONST(0x0), XMM3, XMM3 ) /* ow | ow | ow | ow */
MULPS( XMM7, XMM3 ) /* ow*m15 | ow*m14 | ow*m13 | ow*m12 */
 
ADDPS( XMM1, XMM0 ) /* ox*m3+oy*m7 | ... */
ADDPS( XMM2, XMM0 ) /* ox*m3+oy*m7+oz*m11 | ... */
ADDPS( XMM3, XMM0 ) /* ox*m3+oy*m7+oz*m11+ow*m15 | ... */
MOVAPS( XMM0, DST(0) ) /* ->D(3) | ->D(2) | ->D(1) | ->D(0) */
 
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
 
DEC_L( ECX )
JNZ( LLBL( sse_general_loop ) )
 
LLBL( sse_general_done ):
 
POP_L( EDI )
POP_L( ESI )
RET
 
 
 
 
ALIGNTEXT4
GLOBL GLNAME( _mesa_sse_transform_points4_3d )
GLNAME( _mesa_sse_transform_points4_3d ):
 
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI ) /* ptr to source GLvector4f */
MOV_L( ARG_DEST, EDI ) /* ptr to dest GLvector4f */
 
MOV_L( ARG_MATRIX, EDX ) /* ptr to matrix */
MOV_L( REGOFF(V4F_COUNT, ESI), ECX ) /* source count */
 
TEST_L( ECX, ECX)
JZ( LLBL(K_GTP43P3DR_finish) ) /* count was zero; go to finish */
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_3), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(3), REGOFF(V4F_SIZE, EDI) )/* set dest size */
 
SHL_L( CONST(4), ECX ) /* count *= 16 */
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
MOVAPS( MAT(0), XMM0 ) /* m3 | m2 | m1 | m0 */
MOVAPS( MAT(4), XMM1 ) /* m7 | m6 | m5 | m4 */
MOVAPS( MAT(8), XMM2 ) /* m11 | m10 | m9 | m8 */
MOVAPS( MAT(12), XMM3 ) /* m15 | m14 | m13 | m12 */
 
ALIGNTEXT32
LLBL( K_GTP43P3DR_top ):
MOVSS( SRC(0), XMM4 ) /* ox */
SHUFPS( CONST(0x0), XMM4, XMM4 ) /* ox | ox | ox | ox */
MULPS( XMM0, XMM4 ) /* ox*m3 | ox*m2 | ox*m1 | ox*m0 */
 
MOVSS( SRC(1), XMM5 ) /* oy */
SHUFPS( CONST(0x0), XMM5, XMM5 ) /* oy | oy | oy | oy */
MULPS( XMM1, XMM5 ) /* oy*m7 | oy*m6 | oy*m5 | oy*m4 */
 
MOVSS( SRC(2), XMM6 ) /* oz */
SHUFPS( CONST(0x0), XMM6, XMM6 ) /* oz | oz | oz | oz */
MULPS( XMM2, XMM6 ) /* oz*m11 | oz*m10 | oz*m9 | oz*m8 */
 
MOVSS( SRC(3), XMM7 ) /* ow */
SHUFPS( CONST(0x0), XMM7, XMM7 ) /* ow | ow | ow | ow */
MULPS( XMM3, XMM7 ) /* ow*m15 | ow*m14 | ow*m13 | ow*m12 */
 
ADDPS( XMM5, XMM4 ) /* ox*m3+oy*m7 | ... */
ADDPS( XMM6, XMM4 ) /* ox*m3+oy*m7+oz*m11 | ... */
ADDPS( XMM7, XMM4 ) /* ox*m3+oy*m7+oz*m11+ow*m15 | ... */
MOVAPS( XMM4, DST(0) ) /* ->D(3) | ->D(2) | ->D(1) | ->D(0) */
 
MOVSS( SRC(3), XMM4 ) /* ow */
MOVSS( XMM4, DST(3) ) /* ->D(3) */
 
LLBL( K_GTP43P3DR_skip ):
ADD_L( CONST(16), EDI )
ADD_L( EAX, ESI )
CMP_L( ECX, EDI )
JNE( LLBL(K_GTP43P3DR_top) )
 
LLBL( K_GTP43P3DR_finish ):
POP_L( EDI )
POP_L( ESI )
RET
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_sse_transform_points4_identity )
GLNAME( _mesa_sse_transform_points4_identity ):
 
PUSH_L( ESI )
PUSH_L( EDI )
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_MATRIX, EDX )
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
 
TEST_L( ECX, ECX ) /* verify non-zero count */
JE( LLBL( sse_identity_done ) )
 
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX ) /* stride */
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) ) /* set dest flags */
 
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) ) /* set dest count */
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )/* set dest size */
 
MOV_L( REGOFF(V4F_START, ESI), ESI ) /* ptr to first source vertex */
MOV_L( REGOFF(V4F_START, EDI), EDI ) /* ptr to first dest vertex */
 
ALIGNTEXT16
LLBL( sse_identity_loop ):
 
PREFETCHNTA( REGOFF(32, ESI) )
 
MOVAPS( REGIND(ESI), XMM0 )
ADD_L( EAX, ESI )
 
MOVAPS( XMM0, REGIND(EDI) )
ADD_L( CONST(16), EDI )
 
DEC_L( ECX )
JNZ( LLBL( sse_identity_loop ) )
 
LLBL( sse_identity_done ):
 
POP_L( EDI )
POP_L( ESI )
RET
/shark/trunk/ports/mesa/src/X86/x86_cliptest.s
0,0 → 1,401
/* $Id: x86_cliptest.s,v 1.1 2003-02-28 11:49:40 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* NOTE: Avoid using spaces in between '(' ')' and arguments, especially
* with macros like CONST, LLBL that expand to CONCAT(...). Putting spaces
* in there will break the build on some platforms.
*/
 
#include "matypes.h"
#include "clip_args.h"
 
#define SRC0 REGOFF(0, ESI)
#define SRC1 REGOFF(4, ESI)
#define SRC2 REGOFF(8, ESI)
#define SRC3 REGOFF(12, ESI)
#define DST0 REGOFF(0, EDI)
#define DST1 REGOFF(4, EDI)
#define DST2 REGOFF(8, EDI)
#define DST3 REGOFF(12, EDI)
#define MAT0 REGOFF(0, EDX)
#define MAT1 REGOFF(4, EDX)
#define MAT2 REGOFF(8, EDX)
#define MAT3 REGOFF(12, EDX)
 
 
/*
* Table for clip test.
*
* bit6 = SRC3 < 0
* bit5 = SRC2 < 0
* bit4 = abs(S(2)) > abs(S(3))
* bit3 = SRC1 < 0
* bit2 = abs(S(1)) > abs(S(3))
* bit1 = SRC0 < 0
* bit0 = abs(S(0)) > abs(S(3))
*/
 
SEG_DATA
 
clip_table:
D_BYTE 0x00, 0x01, 0x00, 0x02, 0x04, 0x05, 0x04, 0x06
D_BYTE 0x00, 0x01, 0x00, 0x02, 0x08, 0x09, 0x08, 0x0a
D_BYTE 0x20, 0x21, 0x20, 0x22, 0x24, 0x25, 0x24, 0x26
D_BYTE 0x20, 0x21, 0x20, 0x22, 0x28, 0x29, 0x28, 0x2a
D_BYTE 0x00, 0x01, 0x00, 0x02, 0x04, 0x05, 0x04, 0x06
D_BYTE 0x00, 0x01, 0x00, 0x02, 0x08, 0x09, 0x08, 0x0a
D_BYTE 0x10, 0x11, 0x10, 0x12, 0x14, 0x15, 0x14, 0x16
D_BYTE 0x10, 0x11, 0x10, 0x12, 0x18, 0x19, 0x18, 0x1a
D_BYTE 0x3f, 0x3d, 0x3f, 0x3e, 0x37, 0x35, 0x37, 0x36
D_BYTE 0x3f, 0x3d, 0x3f, 0x3e, 0x3b, 0x39, 0x3b, 0x3a
D_BYTE 0x2f, 0x2d, 0x2f, 0x2e, 0x27, 0x25, 0x27, 0x26
D_BYTE 0x2f, 0x2d, 0x2f, 0x2e, 0x2b, 0x29, 0x2b, 0x2a
D_BYTE 0x3f, 0x3d, 0x3f, 0x3e, 0x37, 0x35, 0x37, 0x36
D_BYTE 0x3f, 0x3d, 0x3f, 0x3e, 0x3b, 0x39, 0x3b, 0x3a
D_BYTE 0x1f, 0x1d, 0x1f, 0x1e, 0x17, 0x15, 0x17, 0x16
D_BYTE 0x1f, 0x1d, 0x1f, 0x1e, 0x1b, 0x19, 0x1b, 0x1a
 
 
SEG_TEXT
 
/*
* _mesa_x86_cliptest_points4
*
* AL: ormask
* AH: andmask
* EBX: temp0
* ECX: temp1
* EDX: clipmask[]
* ESI: clip[]
* EDI: proj[]
* EBP: temp2
*/
 
#if defined(__ELF__) && defined(__PIC__) && defined(GNU_ASSEMBLER) && !defined(ELFPIC)
#define ELFPIC
#endif
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_cliptest_points4 )
GLNAME( _mesa_x86_cliptest_points4 ):
 
#ifdef ELFPIC
#define FRAME_OFFSET 20
#else
#define FRAME_OFFSET 16
#endif
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBP )
PUSH_L( EBX )
 
#ifdef ELFPIC
/* store pointer to clip_table on stack */
CALL( LLBL(ctp4_get_eip) )
ADD_L( CONST(_GLOBAL_OFFSET_TABLE_), EBX )
MOV_L( REGOFF(clip_table@GOT, EBX), EBX )
PUSH_L( EBX )
JMP( LLBL(ctp4_clip_table_ready) )
 
LLBL(ctp4_get_eip):
/* store eip in ebx */
MOV_L( REGIND(ESP), EBX )
RET
 
LLBL(ctp4_clip_table_ready):
#endif
 
MOV_L( ARG_SOURCE, ESI )
MOV_L( ARG_DEST, EDI )
 
MOV_L( ARG_CLIP, EDX )
MOV_L( ARG_OR, EBX )
 
MOV_L( ARG_AND, EBP )
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
 
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
OR_L( CONST(VEC_SIZE_4), REGOFF(V4F_FLAGS, EDI) )
MOV_L( EAX, ARG_SOURCE ) /* put stride in ARG_SOURCE */
 
MOV_L( CONST(4), REGOFF(V4F_SIZE, EDI) )
MOV_L( ECX, REGOFF(V4F_COUNT, EDI) )
 
MOV_L( REGOFF(V4F_START, EDI), EDI )
ADD_L( EDX, ECX )
 
MOV_L( ECX, ARG_CLIP ) /* put clipmask + count in ARG_CLIP */
CMP_L( ECX, EDX )
 
MOV_B( REGIND(EBX), AL )
MOV_B( REGIND(EBP), AH )
 
JZ( LLBL(ctp4_finish) )
 
ALIGNTEXT16
LLBL(ctp4_top):
 
FLD1 /* F3 */
FDIV_S( SRC3 ) /* GH: don't care about div-by-zero */
 
MOV_L( SRC3, EBP )
MOV_L( SRC2, EBX )
 
XOR_L( ECX, ECX )
ADD_L( EBP, EBP ) /* ebp = abs(S(3))*2 ; carry = sign of S(3) */
 
ADC_L( ECX, ECX )
ADD_L( EBX, EBX ) /* ebx = abs(S(2))*2 ; carry = sign of S(2) */
 
ADC_L( ECX, ECX )
CMP_L( EBX, EBP ) /* carry = abs(S(2))*2 > abs(S(3))*2 */
 
ADC_L( ECX, ECX )
MOV_L( SRC1, EBX )
 
ADD_L( EBX, EBX ) /* ebx = abs(S(1))*2 ; carry = sign of S(1) */
 
ADC_L( ECX, ECX )
CMP_L( EBX, EBP ) /* carry = abs(S(1))*2 > abs(S(3))*2 */
 
ADC_L( ECX, ECX )
MOV_L( SRC0, EBX )
 
ADD_L( EBX, EBX ) /* ebx = abs(S(0))*2 ; carry = sign of S(0) */
 
ADC_L( ECX, ECX )
CMP_L( EBX, EBP ) /* carry = abs(S(0))*2 > abs(S(3))*2 */
 
ADC_L( ECX, ECX )
 
#ifdef ELFPIC
MOV_L( REGIND(ESP), EBP ) /* clip_table */
 
MOV_B( REGBI(EBP, ECX), CL )
#else
MOV_B( REGOFF(clip_table,ECX), CL )
#endif
 
OR_B( CL, AL )
AND_B( CL, AH )
 
TEST_B( CL, CL )
MOV_B( CL, REGIND(EDX) )
 
JZ( LLBL(ctp4_proj) )
 
LLBL(ctp4_noproj):
 
FSTP( ST(0) ) /* */
 
MOV_L( CONST(0), DST0 )
MOV_L( CONST(0), DST1 )
MOV_L( CONST(0), DST2 )
MOV_L( CONST(0x3f800000), DST3 )
 
JMP( LLBL(ctp4_next) )
 
LLBL(ctp4_proj):
 
FLD_S( SRC0 ) /* F0 F3 */
FMUL2( ST(1), ST0 )
 
FLD_S( SRC1 ) /* F1 F0 F3 */
FMUL2( ST(2), ST0 )
 
FLD_S( SRC2 ) /* F2 F1 F0 F3 */
FMUL2( ST(3), ST0 )
 
FXCH( ST(2) ) /* F0 F1 F2 F3 */
FSTP_S( DST0 ) /* F1 F2 F3 */
FSTP_S( DST1 ) /* F2 F3 */
FSTP_S( DST2 ) /* F3 */
FSTP_S( DST3 ) /* */
 
LLBL(ctp4_next):
 
INC_L( EDX )
ADD_L( CONST(16), EDI )
 
ADD_L( ARG_SOURCE, ESI )
CMP_L( EDX, ARG_CLIP )
 
JNZ( LLBL(ctp4_top) )
 
MOV_L( ARG_OR, ECX )
MOV_L( ARG_AND, EDX )
 
MOV_B( AL, REGIND(ECX) )
MOV_B( AH, REGIND(EDX) )
 
LLBL(ctp4_finish):
 
MOV_L( ARG_DEST, EAX )
#ifdef ELFPIC
POP_L( ESI ) /* discard ptr to clip_table */
#endif
POP_L( EBX )
POP_L( EBP )
POP_L( EDI )
POP_L( ESI )
 
RET
 
 
 
 
 
 
 
ALIGNTEXT16
GLOBL GLNAME( _mesa_x86_cliptest_points4_np )
GLNAME( _mesa_x86_cliptest_points4_np ):
 
#ifdef ELFPIC
#define FRAME_OFFSET 20
#else
#define FRAME_OFFSET 16
#endif
PUSH_L( ESI )
PUSH_L( EDI )
PUSH_L( EBP )
PUSH_L( EBX )
 
#ifdef ELFPIC
/* store pointer to clip_table on stack */
CALL( LLBL(ctp4_np_get_eip) )
ADD_L( CONST(_GLOBAL_OFFSET_TABLE_), EBX )
MOV_L( REGOFF(clip_table@GOT, EBX), EBX )
PUSH_L( EBX )
JMP( LLBL(ctp4_np_clip_table_ready) )
 
LLBL(ctp4_np_get_eip):
/* store eip in ebx */
MOV_L( REGIND(ESP), EBX )
RET
 
LLBL(ctp4_np_clip_table_ready):
#endif
 
MOV_L( ARG_SOURCE, ESI )
/* slot */
 
MOV_L( ARG_CLIP, EDX )
MOV_L( ARG_OR, EBX )
 
MOV_L( ARG_AND, EBP )
MOV_L( REGOFF(V4F_STRIDE, ESI), EAX )
 
MOV_L( REGOFF(V4F_COUNT, ESI), ECX )
MOV_L( REGOFF(V4F_START, ESI), ESI )
 
MOV_L( EAX, ARG_DEST ) /* put stride in ARG_DEST */
ADD_L( EDX, ECX )
 
MOV_L( ECX, EDI ) /* put clipmask + count in EDI */
CMP_L( ECX, EDX )
 
MOV_B( REGIND(EBX), AL )
MOV_B( REGIND(EBP), AH )
 
JZ( LLBL(ctp4_np_finish) )
 
ALIGNTEXT16
LLBL(ctp4_np_top):
 
MOV_L( SRC3, EBP )
MOV_L( SRC2, EBX )
 
XOR_L( ECX, ECX )
ADD_L( EBP, EBP ) /* ebp = abs(S(3))*2 ; carry = sign of S(3) */
 
ADC_L( ECX, ECX )
ADD_L( EBX, EBX ) /* ebx = abs(S(2))*2 ; carry = sign of S(2) */
 
ADC_L( ECX, ECX )
CMP_L( EBX, EBP ) /* carry = abs(S(2))*2 > abs(S(3))*2 */
 
ADC_L( ECX, ECX )
MOV_L( SRC1, EBX )
 
ADD_L( EBX, EBX ) /* ebx = abs(S(1))*2 ; carry = sign of S(1) */
 
ADC_L( ECX, ECX )
CMP_L( EBX, EBP ) /* carry = abs(S(1))*2 > abs(S(3))*2 */
 
ADC_L( ECX, ECX )
MOV_L( SRC0, EBX )
 
ADD_L( EBX, EBX ) /* ebx = abs(S(0))*2 ; carry = sign of S(0) */
 
ADC_L( ECX, ECX )
CMP_L( EBX, EBP ) /* carry = abs(S(0))*2 > abs(S(3))*2 */
 
ADC_L( ECX, ECX )
 
#ifdef ELFPIC
MOV_L( REGIND(ESP), EBP ) /* clip_table */
 
MOV_B( REGBI(EBP, ECX), CL )
#else
MOV_B( REGOFF(clip_table,ECX), CL )
#endif
 
OR_B( CL, AL )
AND_B( CL, AH )
 
TEST_B( CL, CL )
MOV_B( CL, REGIND(EDX) )
 
INC_L( EDX )
/* slot */
 
ADD_L( ARG_DEST, ESI )
CMP_L( EDX, EDI )
 
JNZ( LLBL(ctp4_np_top) )
 
MOV_L( ARG_OR, ECX )
MOV_L( ARG_AND, EDX )
 
MOV_B( AL, REGIND(ECX) )
MOV_B( AH, REGIND(EDX) )
 
LLBL(ctp4_np_finish):
 
MOV_L( ARG_SOURCE, EAX )
#ifdef ELFPIC
POP_L( ESI ) /* discard ptr to clip_table */
#endif
POP_L( EBX )
POP_L( EBP )
POP_L( EDI )
POP_L( ESI )
 
RET
/shark/trunk/ports/mesa/src/X86/assyntax.h
0,0 → 1,1697
/* $Id: assyntax.h,v 1.1 2003-02-28 11:49:38 pj Exp $ */
 
#ifndef __ASSYNTAX_H__
#define __ASSYNTAX_H__
 
/*
* Copyright 1992 Vrije Universiteit, The Netherlands
*
* Permission to use, copy, modify, and distribute this software and its
* documentation for any purpose and without fee is hereby granted, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the Vrije Universiteit not be used in
* advertising or publicity pertaining to distribution of the software without
* specific, written prior permission. The Vrije Universiteit makes no
* representations about the suitability of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*
* The Vrije Universiteit DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
* SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS,
* IN NO EVENT SHALL The Vrije Universiteit BE LIABLE FOR ANY SPECIAL,
* INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
* OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*/
 
/*
* assyntax.h
*
* Select the syntax appropriate to the 386 assembler being used
* To add support for more assemblers add more columns to the CHOICE
* macro. Note that register names must also have uppercase names
* to avoid macro recursion. e.g., #define ah %ah recurses!
*
* NB 1. Some of the macros for certain assemblers imply that the code is to
* run in protected mode!! Caveat emptor.
*
* NB 2. 486 specific instructions are not included. This is to discourage
* their accidental use in code that is intended to run on 386 and 486
* systems.
*
* Supported assemblers:
*
* (a) AT&T SysVr4 as(1): define ATT_ASSEMBLER
* (b) GNU Assembler gas: define GNU_ASSEMBLER (default)
* (c) Amsterdam Compiler kit: define ACK_ASSEMBLER
* (d) The Netwide Assembler: define NASM_ASSEMBLER
* (e) Microsoft Assembler: define MASM_ASSEMBLER (UNTESTED!)
*
* The following naming conventions have been used to identify the various
* data types:
* _SR = segment register version
* Integer:
* _Q = quadword = 64 bits
* _L = long = 32 bits
* _W = short = 16 bits
* _B = byte = 8 bits
* Floating-point:
* _X = m80real = 80 bits
* _D = double = 64 bits
* _S = single = 32 bits
*
* Author: Gregory J. Sharp, Sept 1992
* Vrije Universiteit, Amsterdam, The Netherlands
*
* [support for Intel syntax added by Josh Vanderhoof, 1999]
*/
 
#if !(defined(NASM_ASSEMBLER) || defined(MASM_ASSEMBLER))
 
/* Default to ATT_ASSEMBLER when SVR4 or SYSV are defined */
#if (defined(SVR4) || defined(SYSV)) && !defined(GNU_ASSEMBLER)
#define ATT_ASSEMBLER
#endif
 
#if !defined(ATT_ASSEMBLER) && !defined(GNU_ASSEMBLER) && !defined(ACK_ASSEMBLER)
#define GNU_ASSEMBLER
#endif
 
#if (defined(__STDC__) && !defined(UNIXCPP)) || (defined (sun) && defined (i386) && defined (SVR4) && defined (__STDC__) && !defined (__GNUC__))
#define CONCAT(x, y) x ## y
#else
#define CONCAT(x, y) x/**/y
#endif
 
#ifdef ACK_ASSEMBLER
 
/* Assume we write code for 32-bit protected mode! */
 
/* Redefine register names for GAS & AT&T assemblers */
#define AL al
#define AH ah
#define AX ax
#define EAX ax
#define BL bl
#define BH bh
#define BX bx
#define EBX bx
#define CL cl
#define CH ch
#define CX cx
#define ECX cx
#define DL dl
#define DH dh
#define DX dx
#define EDX dx
#define BP bp
#define EBP bp
#define SI si
#define ESI si
#define DI di
#define EDI di
#define SP sp
#define ESP sp
#define CS cs
#define SS ss
#define DS ds
#define ES es
#define FS fs
#define GS gs
/* Control Registers */
#define CR0 cr0
#define CR1 cr1
#define CR2 cr2
#define CR3 cr3
/* Debug Registers */
#define DR0 dr0
#define DR1 dr1
#define DR2 dr2
#define DR3 dr3
#define DR4 dr4
#define DR5 dr5
#define DR6 dr6
#define DR7 dr7
/* Floating-point Stack */
#define ST st
 
#define AS_BEGIN .sect .text; .sect .rom; .sect .data; .sect .bss; .sect .text
 
 
#define _WTOG o16 /* word toggle for _W instructions */
#define _LTOG /* long toggle for _L instructions */
#define ADDR_TOGGLE a16
#define OPSZ_TOGGLE o16
#define USE16 .use16
#define USE32 .use32
 
#define CHOICE(a,b,c) c
 
#else /* AT&T or GAS */
 
/* Redefine register names for GAS & AT&T assemblers */
#define AL %al
#define AH %ah
#define AX %ax
#define EAX %eax
#define BL %bl
#define BH %bh
#define BX %bx
#define EBX %ebx
#define CL %cl
#define CH %ch
#define CX %cx
#define ECX %ecx
#define DL %dl
#define DH %dh
#define DX %dx
#define EDX %edx
#define BP %bp
#define EBP %ebp
#define SI %si
#define ESI %esi
#define DI %di
#define EDI %edi
#define SP %sp
#define ESP %esp
#define CS %cs
#define SS %ss
#define DS %ds
#define ES %es
#define FS %fs
#define GS %gs
/* Control Registers */
#define CR0 %cr0
#define CR1 %cr1
#define CR2 %cr2
#define CR3 %cr3
/* Debug Registers */
#define DR0 %db0
#define DR1 %db1
#define DR2 %db2
#define DR3 %db3
#define DR4 %db4
#define DR5 %db5
#define DR6 %db6
#define DR7 %db7
/* Floating-point Stack */
#define _STX0 %st(0)
#define _STX1 %st(1)
#define _STX2 %st(2)
#define _STX3 %st(3)
#define _STX4 %st(4)
#define _STX5 %st(5)
#define _STX6 %st(6)
#define _STX7 %st(7)
#define ST(x) CONCAT(_STX,x)
#ifdef GNU_ASSEMBLER
#define ST0 %st(0)
#else
#define ST0 %st
#endif
/* MMX Registers */
#define MM0 %mm0
#define MM1 %mm1
#define MM2 %mm2
#define MM3 %mm3
#define MM4 %mm4
#define MM5 %mm5
#define MM6 %mm6
#define MM7 %mm7
/* SSE Registers */
#define XMM0 %xmm0
#define XMM1 %xmm1
#define XMM2 %xmm2
#define XMM3 %xmm3
#define XMM4 %xmm4
#define XMM5 %xmm5
#define XMM6 %xmm6
#define XMM7 %xmm7
 
#define AS_BEGIN
#define USE16
#define USE32
 
#ifdef GNU_ASSEMBLER
 
#define ADDR_TOGGLE aword
#define OPSZ_TOGGLE word
 
#define CHOICE(a,b,c) b
 
#else
/*
* AT&T ASSEMBLER SYNTAX
* *********************
*/
#define CHOICE(a,b,c) a
 
#define ADDR_TOGGLE addr16
#define OPSZ_TOGGLE data16
 
#endif /* GNU_ASSEMBLER */
#endif /* ACK_ASSEMBLER */
 
 
#if defined(__QNX__) || defined(Lynx) || (defined(SYSV) || defined(SVR4)) && !defined(ACK_ASSEMBLER) || defined(__ELF__) || defined(__GNU__) || defined(__GNUC__) && !defined(DJGPP)
#define GLNAME(a) a
#else
#define GLNAME(a) CONCAT(_,a)
#endif
 
 
/****************************************/
/* */
/* Select the various choices */
/* */
/****************************************/
 
 
/* Redefine assembler directives */
/*********************************/
#define GLOBL CHOICE(.globl, .globl, .extern)
#define GLOBAL GLOBL
#define EXTERN GLOBL
/*
#define ALIGNTEXT32 CHOICE(.align 32, .align ARG2(5,0x90), .align 32)
*/
#define ALIGNTEXT32 CHOICE(.align 32, .balign 32, .align 32)
#define ALIGNTEXT16 CHOICE(.align 16, .balign 16, .align 16)
#define ALIGNTEXT8 CHOICE(.align 8, .balign 8, .align 8)
#define ALIGNTEXT4 CHOICE(.align 4, .balign 4, .align 4)
#define ALIGNTEXT2 CHOICE(.align 2, .balign 2, .align 2)
/* ALIGNTEXT4ifNOP is the same as ALIGNTEXT4, but only if the space is
* guaranteed to be filled with NOPs. Otherwise it does nothing.
*/
#define ALIGNTEXT32ifNOP CHOICE(.align 32, .balign ARG2(32,0x90), /*can't do it*/)
#define ALIGNTEXT16ifNOP CHOICE(.align 16, .balign ARG2(16,0x90), /*can't do it*/)
#define ALIGNTEXT8ifNOP CHOICE(.align 8, .balign ARG2(8,0x90), /*can't do it*/)
#define ALIGNTEXT4ifNOP CHOICE(.align 4, .balign ARG2(4,0x90), /*can't do it*/)
#define ALIGNDATA32 CHOICE(.align 32, .balign ARG2(32,0x0), .align 32)
#define ALIGNDATA16 CHOICE(.align 16, .balign ARG2(16,0x0), .align 16)
#define ALIGNDATA8 CHOICE(.align 8, .balign ARG2(8,0x0), .align 8)
#define ALIGNDATA4 CHOICE(.align 4, .balign ARG2(4,0x0), .align 4)
#define ALIGNDATA2 CHOICE(.align 2, .balign ARG2(2,0x0), .align 2)
#define FILE(s) CHOICE(.file s, .file s, .file s)
#define STRING(s) CHOICE(.string s, .asciz s, .asciz s)
#define D_LONG CHOICE(.long, .long, .data4)
#define D_WORD CHOICE(.value, .short, .data2)
#define D_BYTE CHOICE(.byte, .byte, .data1)
#define SPACE CHOICE(.comm, .space, .space)
#define COMM CHOICE(.comm, .comm, .comm)
#define SEG_DATA CHOICE(.data, .data, .sect .data)
#define SEG_TEXT CHOICE(.text, .text, .sect .text)
#define SEG_BSS CHOICE(.bss, .bss, .sect .bss)
 
#ifdef GNU_ASSEMBLER
#define D_SPACE(n) . = . + n
#else
#define D_SPACE(n) .space n
#endif
 
/* Addressing Modes */
/* Immediate Mode */
#define ADDR(a) CHOICE(CONCAT($,a), CONCAT($,a), a)
#define CONST(a) CHOICE(CONCAT($,a), CONCAT($,a), a)
 
/* Indirect Mode */
#define CONTENT(a) CHOICE(a, a, (a)) /* take contents of variable */
#define REGIND(a) CHOICE((a), (a), (a)) /* Register a indirect */
/* Register b indirect plus displacement a */
#define REGOFF(a, b) CHOICE(a(b), a(b), a(b))
/* Reg indirect Base + Index + Displacement - this is mainly for 16-bit mode
* which has no scaling
*/
#define REGBID(b,i,d) CHOICE(d(b,i), d(b,i), d(b)(i))
/* Reg indirect Base + (Index * Scale) */
#define REGBIS(b,i,s) CHOICE((b,i,s), (b,i,s), (b)(i*s))
/* Reg indirect Base + (Index * Scale) + Displacement */
#define REGBISD(b,i,s,d) CHOICE(d(b,i,s), d(b,i,s), d(b)(i*s))
/* Displaced Scaled Index: */
#define REGDIS(d,i,s) CHOICE(d(,i,s), d(,i,s), d(i * s))
/* Indexed Base: */
#define REGBI(b,i) CHOICE((b,i), (b,i), (b)(i))
/* Displaced Base: */
#define REGDB(d,b) CHOICE(d(b), d(b), d(b))
/* Variable indirect: */
#define VARINDIRECT(var) CHOICE(*var, *var, (var))
/* Use register contents as jump/call target: */
#define CODEPTR(reg) CHOICE(*reg, *reg, reg)
 
/* For expressions requiring bracketing
* eg. (CRT0_PM | CRT_EM)
*/
 
#define EXPR(a) CHOICE([a], (a), [a])
#define ENOT(a) CHOICE(0!a, ~a, ~a)
#define EMUL(a,b) CHOICE(a\*b, a*b, a*b)
#define EDIV(a,b) CHOICE(a\/b, a/b, a/b)
 
/*
* We have to beat the problem of commas within arguments to choice.
* eg. choice (add a,b, add b,a) will get argument mismatch. Luckily ANSI
* and other known cpp definitions evaluate arguments before substitution
* so the following works.
*/
#define ARG2(a, b) a,b
#define ARG3(a,b,c) a,b,c
 
/* Redefine assembler commands */
#define AAA CHOICE(aaa, aaa, aaa)
#define AAD CHOICE(aad, aad, aad)
#define AAM CHOICE(aam, aam, aam)
#define AAS CHOICE(aas, aas, aas)
#define ADC_L(a, b) CHOICE(adcl ARG2(a,b), adcl ARG2(a,b), _LTOG adc ARG2(b,a))
#define ADC_W(a, b) CHOICE(adcw ARG2(a,b), adcw ARG2(a,b), _WTOG adc ARG2(b,a))
#define ADC_B(a, b) CHOICE(adcb ARG2(a,b), adcb ARG2(a,b), adcb ARG2(b,a))
#define ADD_L(a, b) CHOICE(addl ARG2(a,b), addl ARG2(a,b), _LTOG add ARG2(b,a))
#define ADD_W(a, b) CHOICE(addw ARG2(a,b), addw ARG2(a,b), _WTOG add ARG2(b,a))
#define ADD_B(a, b) CHOICE(addb ARG2(a,b), addb ARG2(a,b), addb ARG2(b,a))
#define AND_L(a, b) CHOICE(andl ARG2(a,b), andl ARG2(a,b), _LTOG and ARG2(b,a))
#define AND_W(a, b) CHOICE(andw ARG2(a,b), andw ARG2(a,b), _WTOG and ARG2(b,a))
#define AND_B(a, b) CHOICE(andb ARG2(a,b), andb ARG2(a,b), andb ARG2(b,a))
#define ARPL(a,b) CHOICE(arpl ARG2(a,b), arpl ARG2(a,b), arpl ARG2(b,a))
#define BOUND_L(a, b) CHOICE(boundl ARG2(a,b), boundl ARG2(b,a), _LTOG bound ARG2(b,a))
#define BOUND_W(a, b) CHOICE(boundw ARG2(a,b), boundw ARG2(b,a), _WTOG bound ARG2(b,a))
#define BSF_L(a, b) CHOICE(bsfl ARG2(a,b), bsfl ARG2(a,b), _LTOG bsf ARG2(b,a))
#define BSF_W(a, b) CHOICE(bsfw ARG2(a,b), bsfw ARG2(a,b), _WTOG bsf ARG2(b,a))
#define BSR_L(a, b) CHOICE(bsrl ARG2(a,b), bsrl ARG2(a,b), _LTOG bsr ARG2(b,a))
#define BSR_W(a, b) CHOICE(bsrw ARG2(a,b), bsrw ARG2(a,b), _WTOG bsr ARG2(b,a))
#define BT_L(a, b) CHOICE(btl ARG2(a,b), btl ARG2(a,b), _LTOG bt ARG2(b,a))
#define BT_W(a, b) CHOICE(btw ARG2(a,b), btw ARG2(a,b), _WTOG bt ARG2(b,a))
#define BTC_L(a, b) CHOICE(btcl ARG2(a,b), btcl ARG2(a,b), _LTOG btc ARG2(b,a))
#define BTC_W(a, b) CHOICE(btcw ARG2(a,b), btcw ARG2(a,b), _WTOG btc ARG2(b,a))
#define BTR_L(a, b) CHOICE(btrl ARG2(a,b), btrl ARG2(a,b), _LTOG btr ARG2(b,a))
#define BTR_W(a, b) CHOICE(btrw ARG2(a,b), btrw ARG2(a,b), _WTOG btr ARG2(b,a))
#define BTS_L(a, b) CHOICE(btsl ARG2(a,b), btsl ARG2(a,b), _LTOG bts ARG2(b,a))
#define BTS_W(a, b) CHOICE(btsw ARG2(a,b), btsw ARG2(a,b), _WTOG bts ARG2(b,a))
#define CALL(a) CHOICE(call a, call a, call a)
#define CALLF(s,a) CHOICE(lcall ARG2(s,a), lcall ARG2(s,a), callf s:a)
#define CBW CHOICE(cbtw, cbw, cbw)
#define CWDE CHOICE(cwtd, cwde, cwde)
#define CLC CHOICE(clc, clc, clc)
#define CLD CHOICE(cld, cld, cld)
#define CLI CHOICE(cli, cli, cli)
#define CLTS CHOICE(clts, clts, clts)
#define CMC CHOICE(cmc, cmc, cmc)
#define CMP_L(a, b) CHOICE(cmpl ARG2(a,b), cmpl ARG2(a,b), _LTOG cmp ARG2(b,a))
#define CMP_W(a, b) CHOICE(cmpw ARG2(a,b), cmpw ARG2(a,b), _WTOG cmp ARG2(b,a))
#define CMP_B(a, b) CHOICE(cmpb ARG2(a,b), cmpb ARG2(a,b), cmpb ARG2(b,a))
#define CMPS_L CHOICE(cmpsl, cmpsl, _LTOG cmps)
#define CMPS_W CHOICE(cmpsw, cmpsw, _WTOG cmps)
#define CMPS_B CHOICE(cmpsb, cmpsb, cmpsb)
#define CWD CHOICE(cwtl, cwd, cwd)
#define CDQ CHOICE(cltd, cdq, cdq)
#define DAA CHOICE(daa, daa, daa)
#define DAS CHOICE(das, das, das)
#define DEC_L(a) CHOICE(decl a, decl a, _LTOG dec a)
#define DEC_W(a) CHOICE(decw a, decw a, _WTOG dec a)
#define DEC_B(a) CHOICE(decb a, decb a, decb a)
#define DIV_L(a) CHOICE(divl a, divl a, div a)
#define DIV_W(a) CHOICE(divw a, divw a, div a)
#define DIV_B(a) CHOICE(divb a, divb a, divb a)
#define ENTER(a,b) CHOICE(enter ARG2(a,b), enter ARG2(a,b), enter ARG2(b,a))
#define HLT CHOICE(hlt, hlt, hlt)
#define IDIV_L(a) CHOICE(idivl a, idivl a, _LTOG idiv a)
#define IDIV_W(a) CHOICE(idivw a, idivw a, _WTOG idiv a)
#define IDIV_B(a) CHOICE(idivb a, idivb a, idivb a)
/* More forms than this for imul!! */
#define IMUL_L(a, b) CHOICE(imull ARG2(a,b), imull ARG2(a,b), _LTOG imul ARG2(b,a))
#define IMUL_W(a, b) CHOICE(imulw ARG2(a,b), imulw ARG2(a,b), _WTOG imul ARG2(b,a))
#define IMUL_B(a) CHOICE(imulb a, imulb a, imulb a)
#define IN_L CHOICE(inl (DX), inl ARG2(DX,EAX), _LTOG in DX)
#define IN_W CHOICE(inw (DX), inw ARG2(DX,AX), _WTOG in DX)
#define IN_B CHOICE(inb (DX), inb ARG2(DX,AL), inb DX)
/* Please AS code writer: use the following ONLY, if you refer to ports<256
* directly, but not in IN1_W(DX), for instance, even if IN1_ looks nicer
*/
#if defined (sun)
#define IN1_L(a) CHOICE(inl (a), inl ARG2(a,EAX), _LTOG in a)
#define IN1_W(a) CHOICE(inw (a), inw ARG2(a,AX), _WTOG in a)
#define IN1_B(a) CHOICE(inb (a), inb ARG2(a,AL), inb a)
#else
#define IN1_L(a) CHOICE(inl a, inl ARG2(a,EAX), _LTOG in a)
#define IN1_W(a) CHOICE(inw a, inw ARG2(a,AX), _WTOG in a)
#define IN1_B(a) CHOICE(inb a, inb ARG2(a,AL), inb a)
#endif
#define INC_L(a) CHOICE(incl a, incl a, _LTOG inc a)
#define INC_W(a) CHOICE(incw a, incw a, _WTOG inc a)
#define INC_B(a) CHOICE(incb a, incb a, incb a)
#define INS_L CHOICE(insl, insl, _LTOG ins)
#define INS_W CHOICE(insw, insw, _WTOG ins)
#define INS_B CHOICE(insb, insb, insb)
#define INT(a) CHOICE(int a, int a, int a)
#define INT3 CHOICE(int CONST(3), int3, int CONST(3))
#define INTO CHOICE(into, into, into)
#define IRET CHOICE(iret, iret, iret)
#define IRETD CHOICE(iret, iret, iretd)
#define JA(a) CHOICE(ja a, ja a, ja a)
#define JAE(a) CHOICE(jae a, jae a, jae a)
#define JB(a) CHOICE(jb a, jb a, jb a)
#define JBE(a) CHOICE(jbe a, jbe a, jbe a)
#define JC(a) CHOICE(jc a, jc a, jc a)
#define JE(a) CHOICE(je a, je a, je a)
#define JG(a) CHOICE(jg a, jg a, jg a)
#define JGE(a) CHOICE(jge a, jge a, jge a)
#define JL(a) CHOICE(jl a, jl a, jl a)
#define JLE(a) CHOICE(jle a, jle a, jle a)
#define JNA(a) CHOICE(jna a, jna a, jna a)
#define JNAE(a) CHOICE(jnae a, jnae a, jnae a)
#define JNB(a) CHOICE(jnb a, jnb a, jnb a)
#define JNBE(a) CHOICE(jnbe a, jnbe a, jnbe a)
#define JNC(a) CHOICE(jnc a, jnc a, jnc a)
#define JNE(a) CHOICE(jne a, jne a, jne a)
#define JNG(a) CHOICE(jng a, jng a, jng a)
#define JNGE(a) CHOICE(jnge a, jnge a, jnge a)
#define JNL(a) CHOICE(jnl a, jnl a, jnl a)
#define JNLE(a) CHOICE(jnle a, jnle a, jnle a)
#define JNO(a) CHOICE(jno a, jno a, jno a)
#define JNP(a) CHOICE(jnp a, jnp a, jnp a)
#define JNS(a) CHOICE(jns a, jns a, jns a)
#define JNZ(a) CHOICE(jnz a, jnz a, jnz a)
#define JO(a) CHOICE(jo a, jo a, jo a)
#define JP(a) CHOICE(jp a, jp a, jp a)
#define JPE(a) CHOICE(jpe a, jpe a, jpe a)
#define JPO(a) CHOICE(jpo a, jpo a, jpo a)
#define JS(a) CHOICE(js a, js a, js a)
#define JZ(a) CHOICE(jz a, jz a, jz a)
#define JMP(a) CHOICE(jmp a, jmp a, jmp a)
#define JMPF(s,a) CHOICE(ljmp ARG2(s,a), ljmp ARG2(s,a), jmpf s:a)
#define LAHF CHOICE(lahf, lahf, lahf)
#if !defined(_REAL_MODE) && !defined(_V86_MODE)
#define LAR(a, b) CHOICE(lar ARG2(a, b), lar ARG2(a, b), lar ARG2(b, a))
#endif
#define LEA_L(a, b) CHOICE(leal ARG2(a,b), leal ARG2(a,b), _LTOG lea ARG2(b,a))
#define LEA_W(a, b) CHOICE(leaw ARG2(a,b), leaw ARG2(a,b), _WTOG lea ARG2(b,a))
#define LEAVE CHOICE(leave, leave, leave)
#define LGDT(a) CHOICE(lgdt a, lgdt a, lgdt a)
#define LIDT(a) CHOICE(lidt a, lidt a, lidt a)
#define LDS(a, b) CHOICE(ldsl ARG2(a,b), lds ARG2(a,b), lds ARG2(b,a))
#define LES(a, b) CHOICE(lesl ARG2(a,b), les ARG2(a,b), les ARG2(b,a))
#define LFS(a, b) CHOICE(lfsl ARG2(a,b), lfs ARG2(a,b), lfs ARG2(b,a))
#define LGS(a, b) CHOICE(lgsl ARG2(a,b), lgs ARG2(a,b), lgs ARG2(b,a))
#define LSS(a, b) CHOICE(lssl ARG2(a,b), lss ARG2(a,b), lss ARG2(b,a))
#define LLDT(a) CHOICE(lldt a, lldt a, lldt a)
#define LMSW(a) CHOICE(lmsw a, lmsw a, lmsw a)
#define LOCK CHOICE(lock, lock, lock)
#define LODS_L CHOICE(lodsl, lodsl, _LTOG lods)
#define LODS_W CHOICE(lodsw, lodsw, _WTOG lods)
#define LODS_B CHOICE(lodsb, lodsb, lodsb)
#define LOOP(a) CHOICE(loop a, loop a, loop a)
#define LOOPE(a) CHOICE(loope a, loope a, loope a)
#define LOOPZ(a) CHOICE(loopz a, loopz a, loopz a)
#define LOOPNE(a) CHOICE(loopne a, loopne a, loopne a)
#define LOOPNZ(a) CHOICE(loopnz a, loopnz a, loopnz a)
#if !defined(_REAL_MODE) && !defined(_V86_MODE)
#define LSL(a, b) CHOICE(lsl ARG2(a,b), lsl ARG2(a,b), lsl ARG2(b,a))
#endif
#define LTR(a) CHOICE(ltr a, ltr a, ltr a)
#define MOV_SR(a, b) CHOICE(movw ARG2(a,b), mov ARG2(a,b), mov ARG2(b,a))
#define MOV_L(a, b) CHOICE(movl ARG2(a,b), movl ARG2(a,b), _LTOG mov ARG2(b,a))
#define MOV_W(a, b) CHOICE(movw ARG2(a,b), movw ARG2(a,b), _WTOG mov ARG2(b,a))
#define MOV_B(a, b) CHOICE(movb ARG2(a,b), movb ARG2(a,b), movb ARG2(b,a))
#define MOVS_L CHOICE(movsl, movsl, _LTOG movs)
#define MOVS_W CHOICE(movsw, movsw, _WTOG movs)
#define MOVS_B CHOICE(movsb, movsb, movsb)
#define MOVSX_BL(a, b) CHOICE(movsbl ARG2(a,b), movsbl ARG2(a,b), movsx ARG2(b,a))
#define MOVSX_BW(a, b) CHOICE(movsbw ARG2(a,b), movsbw ARG2(a,b), movsx ARG2(b,a))
#define MOVSX_WL(a, b) CHOICE(movswl ARG2(a,b), movswl ARG2(a,b), movsx ARG2(b,a))
#define MOVZX_BL(a, b) CHOICE(movzbl ARG2(a,b), movzbl ARG2(a,b), movzx ARG2(b,a))
#define MOVZX_BW(a, b) CHOICE(movzbw ARG2(a,b), movzbw ARG2(a,b), movzx ARG2(b,a))
#define MOVZX_WL(a, b) CHOICE(movzwl ARG2(a,b), movzwl ARG2(a,b), movzx ARG2(b,a))
#define MUL_L(a) CHOICE(mull a, mull a, _LTOG mul a)
#define MUL_W(a) CHOICE(mulw a, mulw a, _WTOG mul a)
#define MUL_B(a) CHOICE(mulb a, mulb a, mulb a)
#define NEG_L(a) CHOICE(negl a, negl a, _LTOG neg a)
#define NEG_W(a) CHOICE(negw a, negw a, _WTOG neg a)
#define NEG_B(a) CHOICE(negb a, negb a, negb a)
#define NOP CHOICE(nop, nop, nop)
#define NOT_L(a) CHOICE(notl a, notl a, _LTOG not a)
#define NOT_W(a) CHOICE(notw a, notw a, _WTOG not a)
#define NOT_B(a) CHOICE(notb a, notb a, notb a)
#define OR_L(a,b) CHOICE(orl ARG2(a,b), orl ARG2(a,b), _LTOG or ARG2(b,a))
#define OR_W(a,b) CHOICE(orw ARG2(a,b), orw ARG2(a,b), _WTOG or ARG2(b,a))
#define OR_B(a,b) CHOICE(orb ARG2(a,b), orb ARG2(a,b), orb ARG2(b,a))
#define OUT_L CHOICE(outl (DX), outl ARG2(EAX,DX), _LTOG out DX)
#define OUT_W CHOICE(outw (DX), outw ARG2(AX,DX), _WTOG out DX)
#define OUT_B CHOICE(outb (DX), outb ARG2(AL,DX), outb DX)
/* Please AS code writer: use the following ONLY, if you refer to ports<256
* directly, but not in OUT1_W(DX), for instance, even if OUT1_ looks nicer
*/
#define OUT1_L(a) CHOICE(outl (a), outl ARG2(EAX,a), _LTOG out a)
#define OUT1_W(a) CHOICE(outw (a), outw ARG2(AX,a), _WTOG out a)
#define OUT1_B(a) CHOICE(outb (a), outb ARG2(AL,a), outb a)
#define OUTS_L CHOICE(outsl, outsl, _LTOG outs)
#define OUTS_W CHOICE(outsw, outsw, _WTOG outs)
#define OUTS_B CHOICE(outsb, outsb, outsb)
#define POP_SR(a) CHOICE(pop a, pop a, pop a)
#define POP_L(a) CHOICE(popl a, popl a, _LTOG pop a)
#define POP_W(a) CHOICE(popw a, popw a, _WTOG pop a)
#define POPA_L CHOICE(popal, popal, _LTOG popa)
#define POPA_W CHOICE(popaw, popaw, _WTOG popa)
#define POPF_L CHOICE(popfl, popfl, _LTOG popf)
#define POPF_W CHOICE(popfw, popfw, _WTOG popf)
#define PUSH_SR(a) CHOICE(push a, push a, push a)
#define PUSH_L(a) CHOICE(pushl a, pushl a, _LTOG push a)
#define PUSH_W(a) CHOICE(pushw a, pushw a, _WTOG push a)
#define PUSH_B(a) CHOICE(push a, pushb a, push a)
#define PUSHA_L CHOICE(pushal, pushal, _LTOG pusha)
#define PUSHA_W CHOICE(pushaw, pushaw, _WTOG pusha)
#define PUSHF_L CHOICE(pushfl, pushfl, _LTOG pushf)
#define PUSHF_W CHOICE(pushfw, pushfw, _WTOG pushf)
#define RCL_L(a, b) CHOICE(rcll ARG2(a,b), rcll ARG2(a,b), _LTOG rcl ARG2(b,a))
#define RCL_W(a, b) CHOICE(rclw ARG2(a,b), rclw ARG2(a,b), _WTOG rcl ARG2(b,a))
#define RCL_B(a, b) CHOICE(rclb ARG2(a,b), rclb ARG2(a,b), rclb ARG2(b,a))
#define RCR_L(a, b) CHOICE(rcrl ARG2(a,b), rcrl ARG2(a,b), _LTOG rcr ARG2(b,a))
#define RCR_W(a, b) CHOICE(rcrw ARG2(a,b), rcrw ARG2(a,b), _WTOG rcr ARG2(b,a))
#define RCR_B(a, b) CHOICE(rcrb ARG2(a,b), rcrb ARG2(a,b), rcrb ARG2(b,a))
#define ROL_L(a, b) CHOICE(roll ARG2(a,b), roll ARG2(a,b), _LTOG rol ARG2(b,a))
#define ROL_W(a, b) CHOICE(rolw ARG2(a,b), rolw ARG2(a,b), _WTOG rol ARG2(b,a))
#define ROL_B(a, b) CHOICE(rolb ARG2(a,b), rolb ARG2(a,b), rolb ARG2(b,a))
#define ROR_L(a, b) CHOICE(rorl ARG2(a,b), rorl ARG2(a,b), _LTOG ror ARG2(b,a))
#define ROR_W(a, b) CHOICE(rorw ARG2(a,b), rorw ARG2(a,b), _WTOG ror ARG2(b,a))
#define ROR_B(a, b) CHOICE(rorb ARG2(a,b), rorb ARG2(a,b), rorb ARG2(b,a))
#define REP CHOICE(rep ;, rep ;, repe)
#define REPE CHOICE(repz ;, repe ;, repe)
#define REPNE CHOICE(repnz ;, repne ;, repne)
#define REPNZ REPNE
#define REPZ REPE
#define RET CHOICE(ret, ret, ret)
#define SAHF CHOICE(sahf, sahf, sahf)
#define SAL_L(a, b) CHOICE(sall ARG2(a,b), sall ARG2(a,b), _LTOG sal ARG2(b,a))
#define SAL_W(a, b) CHOICE(salw ARG2(a,b), salw ARG2(a,b), _WTOG sal ARG2(b,a))
#define SAL_B(a, b) CHOICE(salb ARG2(a,b), salb ARG2(a,b), salb ARG2(b,a))
#define SAR_L(a, b) CHOICE(sarl ARG2(a,b), sarl ARG2(a,b), _LTOG sar ARG2(b,a))
#define SAR_W(a, b) CHOICE(sarw ARG2(a,b), sarw ARG2(a,b), _WTOG sar ARG2(b,a))
#define SAR_B(a, b) CHOICE(sarb ARG2(a,b), sarb ARG2(a,b), sarb ARG2(b,a))
#define SBB_L(a, b) CHOICE(sbbl ARG2(a,b), sbbl ARG2(a,b), _LTOG sbb ARG2(b,a))
#define SBB_W(a, b) CHOICE(sbbw ARG2(a,b), sbbw ARG2(a,b), _WTOG sbb ARG2(b,a))
#define SBB_B(a, b) CHOICE(sbbb ARG2(a,b), sbbb ARG2(a,b), sbbb ARG2(b,a))
#define SCAS_L CHOICE(scasl, scasl, _LTOG scas)
#define SCAS_W CHOICE(scasw, scasw, _WTOG scas)
#define SCAS_B CHOICE(scasb, scasb, scasb)
#define SETA(a) CHOICE(seta a, seta a, seta a)
#define SETAE(a) CHOICE(setae a, setae a, setae a)
#define SETB(a) CHOICE(setb a, setb a, setb a)
#define SETBE(a) CHOICE(setbe a, setbe a, setbe a)
#define SETC(a) CHOICE(setc a, setb a, setb a)
#define SETE(a) CHOICE(sete a, sete a, sete a)
#define SETG(a) CHOICE(setg a, setg a, setg a)
#define SETGE(a) CHOICE(setge a, setge a, setge a)
#define SETL(a) CHOICE(setl a, setl a, setl a)
#define SETLE(a) CHOICE(setle a, setle a, setle a)
#define SETNA(a) CHOICE(setna a, setna a, setna a)
#define SETNAE(a) CHOICE(setnae a, setnae a, setnae a)
#define SETNB(a) CHOICE(setnb a, setnb a, setnb a)
#define SETNBE(a) CHOICE(setnbe a, setnbe a, setnbe a)
#define SETNC(a) CHOICE(setnc a, setnb a, setnb a)
#define SETNE(a) CHOICE(setne a, setne a, setne a)
#define SETNG(a) CHOICE(setng a, setng a, setng a)
#define SETNGE(a) CHOICE(setnge a, setnge a, setnge a)
#define SETNL(a) CHOICE(setnl a, setnl a, setnl a)
#define SETNLE(a) CHOICE(setnle a, setnle a, setnle a)
#define SETNO(a) CHOICE(setno a, setno a, setno a)
#define SETNP(a) CHOICE(setnp a, setnp a, setnp a)
#define SETNS(a) CHOICE(setns a, setns a, setna a)
#define SETNZ(a) CHOICE(setnz a, setnz a, setnz a)
#define SETO(a) CHOICE(seto a, seto a, seto a)
#define SETP(a) CHOICE(setp a, setp a, setp a)
#define SETPE(a) CHOICE(setpe a, setpe a, setpe a)
#define SETPO(a) CHOICE(setpo a, setpo a, setpo a)
#define SETS(a) CHOICE(sets a, sets a, seta a)
#define SETZ(a) CHOICE(setz a, setz a, setz a)
#define SGDT(a) CHOICE(sgdt a, sgdt a, sgdt a)
#define SIDT(a) CHOICE(sidt a, sidt a, sidt a)
#define SHL_L(a, b) CHOICE(shll ARG2(a,b), shll ARG2(a,b), _LTOG shl ARG2(b,a))
#define SHL_W(a, b) CHOICE(shlw ARG2(a,b), shlw ARG2(a,b), _WTOG shl ARG2(b,a))
#define SHL_B(a, b) CHOICE(shlb ARG2(a,b), shlb ARG2(a,b), shlb ARG2(b,a))
#define SHLD_L(a,b,c) CHOICE(shldl ARG3(a,b,c), shldl ARG3(a,b,c), _LTOG shld ARG3(c,b,a))
#define SHLD2_L(a,b) CHOICE(shldl ARG2(a,b), shldl ARG3(CL,a,b), _LTOG shld ARG3(b,a,CL))
#define SHLD_W(a,b,c) CHOICE(shldw ARG3(a,b,c), shldw ARG3(a,b,c), _WTOG shld ARG3(c,b,a))
#define SHLD2_W(a,b) CHOICE(shldw ARG2(a,b), shldw ARG3(CL,a,b), _WTOG shld ARG3(b,a,CL))
#define SHR_L(a, b) CHOICE(shrl ARG2(a,b), shrl ARG2(a,b), _LTOG shr ARG2(b,a))
#define SHR_W(a, b) CHOICE(shrw ARG2(a,b), shrw ARG2(a,b), _WTOG shr ARG2(b,a))
#define SHR_B(a, b) CHOICE(shrb ARG2(a,b), shrb ARG2(a,b), shrb ARG2(b,a))
#define SHRD_L(a,b,c) CHOICE(shrdl ARG3(a,b,c), shrdl ARG3(a,b,c), _LTOG shrd ARG3(c,b,a))
#define SHRD2_L(a,b) CHOICE(shrdl ARG2(a,b), shrdl ARG3(CL,a,b), _LTOG shrd ARG3(b,a,CL))
#define SHRD_W(a,b,c) CHOICE(shrdw ARG3(a,b,c), shrdw ARG3(a,b,c), _WTOG shrd ARG3(c,b,a))
#define SHRD2_W(a,b) CHOICE(shrdw ARG2(a,b), shrdw ARG3(CL,a,b), _WTOG shrd ARG3(b,a,CL))
#define SLDT(a) CHOICE(sldt a, sldt a, sldt a)
#define SMSW(a) CHOICE(smsw a, smsw a, smsw a)
#define STC CHOICE(stc, stc, stc)
#define STD CHOICE(std, std, std)
#define STI CHOICE(sti, sti, sti)
#define STOS_L CHOICE(stosl, stosl, _LTOG stos)
#define STOS_W CHOICE(stosw, stosw, _WTOG stos)
#define STOS_B CHOICE(stosb, stosb, stosb)
#define STR(a) CHOICE(str a, str a, str a)
#define SUB_L(a, b) CHOICE(subl ARG2(a,b), subl ARG2(a,b), _LTOG sub ARG2(b,a))
#define SUB_W(a, b) CHOICE(subw ARG2(a,b), subw ARG2(a,b), _WTOG sub ARG2(b,a))
#define SUB_B(a, b) CHOICE(subb ARG2(a,b), subb ARG2(a,b), subb ARG2(b,a))
#define TEST_L(a, b) CHOICE(testl ARG2(a,b), testl ARG2(a,b), _LTOG test ARG2(b,a))
#define TEST_W(a, b) CHOICE(testw ARG2(a,b), testw ARG2(a,b), _WTOG test ARG2(b,a))
#define TEST_B(a, b) CHOICE(testb ARG2(a,b), testb ARG2(a,b), testb ARG2(b,a))
#define VERR(a) CHOICE(verr a, verr a, verr a)
#define VERW(a) CHOICE(verw a, verw a, verw a)
#define WAIT CHOICE(wait, wait, wait)
#define XCHG_L(a, b) CHOICE(xchgl ARG2(a,b), xchgl ARG2(a,b), _LTOG xchg ARG2(b,a))
#define XCHG_W(a, b) CHOICE(xchgw ARG2(a,b), xchgw ARG2(a,b), _WTOG xchg ARG2(b,a))
#define XCHG_B(a, b) CHOICE(xchgb ARG2(a,b), xchgb ARG2(a,b), xchgb ARG2(b,a))
#define XLAT CHOICE(xlat, xlat, xlat)
#define XOR_L(a, b) CHOICE(xorl ARG2(a,b), xorl ARG2(a,b), _LTOG xor ARG2(b,a))
#define XOR_W(a, b) CHOICE(xorw ARG2(a,b), xorw ARG2(a,b), _WTOG xor ARG2(b,a))
#define XOR_B(a, b) CHOICE(xorb ARG2(a,b), xorb ARG2(a,b), xorb ARG2(b,a))
 
 
/* Floating Point Instructions */
#define F2XM1 CHOICE(f2xm1, f2xm1, f2xm1)
#define FABS CHOICE(fabs, fabs, fabs)
#define FADD_D(a) CHOICE(faddl a, faddl a, faddd a)
#define FADD_S(a) CHOICE(fadds a, fadds a, fadds a)
#define FADD2(a, b) CHOICE(fadd ARG2(a,b), fadd ARG2(a,b), fadd ARG2(b,a))
#define FADDP(a, b) CHOICE(faddp ARG2(a,b), faddp ARG2(a,b), faddp ARG2(b,a))
#define FIADD_L(a) CHOICE(fiaddl a, fiaddl a, fiaddl a)
#define FIADD_W(a) CHOICE(fiadd a, fiadds a, fiadds a)
#define FBLD(a) CHOICE(fbld a, fbld a, fbld a)
#define FBSTP(a) CHOICE(fbstp a, fbstp a, fbstp a)
#define FCHS CHOICE(fchs, fchs, fchs)
#define FCLEX CHOICE(fclex, wait; fnclex, wait; fclex)
#define FNCLEX CHOICE(fnclex, fnclex, fclex)
#define FCOM(a) CHOICE(fcom a, fcom a, fcom a)
#define FCOM_D(a) CHOICE(fcoml a, fcoml a, fcomd a)
#define FCOM_S(a) CHOICE(fcoms a, fcoms a, fcoms a)
#define FCOMP(a) CHOICE(fcomp a, fcomp a, fcomp a)
#define FCOMP_D(a) CHOICE(fcompl a, fcompl a, fcompd a)
#define FCOMP_S(a) CHOICE(fcomps a, fcomps a, fcomps a)
#define FCOMPP CHOICE(fcompp, fcompp, fcompp)
#define FCOS CHOICE(fcos, fcos, fcos)
#define FDECSTP CHOICE(fdecstp, fdecstp, fdecstp)
#define FDIV_D(a) CHOICE(fdivl a, fdivl a, fdivd a)
#define FDIV_S(a) CHOICE(fdivs a, fdivs a, fdivs a)
#define FDIV2(a, b) CHOICE(fdiv ARG2(a,b), fdiv ARG2(a,b), fdiv ARG2(b,a))
#define FDIVP(a, b) CHOICE(fdivp ARG2(a,b), fdivp ARG2(a,b), fdivp ARG2(b,a))
#define FIDIV_L(a) CHOICE(fidivl a, fidivl a, fidivl a)
#define FIDIV_W(a) CHOICE(fidiv a, fidivs a, fidivs a)
#define FDIVR_D(a) CHOICE(fdivrl a, fdivrl a, fdivrd a)
#define FDIVR_S(a) CHOICE(fdivrs a, fdivrs a, fdivrs a)
#define FDIVR2(a, b) CHOICE(fdivr ARG2(a,b), fdivr ARG2(a,b), fdivr ARG2(b,a))
#define FDIVRP(a, b) CHOICE(fdivrp ARG2(a,b), fdivrp ARG2(a,b), fdivrp ARG2(b,a))
#define FIDIVR_L(a) CHOICE(fidivrl a, fidivrl a, fidivrl a)
#define FIDIVR_W(a) CHOICE(fidivr a, fidivrs a, fidivrs a)
#define FFREE(a) CHOICE(ffree a, ffree a, ffree a)
#define FICOM_L(a) CHOICE(ficoml a, ficoml a, ficoml a)
#define FICOM_W(a) CHOICE(ficom a, ficoms a, ficoms a)
#define FICOMP_L(a) CHOICE(ficompl a, ficompl a, ficompl a)
#define FICOMP_W(a) CHOICE(ficomp a, ficomps a, ficomps a)
#define FILD_Q(a) CHOICE(fildll a, fildq a, fildq a)
#define FILD_L(a) CHOICE(fildl a, fildl a, fildl a)
#define FILD_W(a) CHOICE(fild a, filds a, filds a)
#define FINCSTP CHOICE(fincstp, fincstp, fincstp)
#define FINIT CHOICE(finit, wait; fninit, wait; finit)
#define FNINIT CHOICE(fninit, fninit, finit)
#define FIST_L(a) CHOICE(fistl a, fistl a, fistl a)
#define FIST_W(a) CHOICE(fist a, fists a, fists a)
#define FISTP_Q(a) CHOICE(fistpll a, fistpq a, fistpq a)
#define FISTP_L(a) CHOICE(fistpl a, fistpl a, fistpl a)
#define FISTP_W(a) CHOICE(fistp a, fistps a, fistps a)
#define FLD_X(a) CHOICE(fldt a, fldt a, fldx a) /* 80 bit data type! */
#define FLD_D(a) CHOICE(fldl a, fldl a, fldd a)
#define FLD_S(a) CHOICE(flds a, flds a, flds a)
#define FLD1 CHOICE(fld1, fld1, fld1)
#define FLDL2T CHOICE(fldl2t, fldl2t, fldl2t)
#define FLDL2E CHOICE(fldl2e, fldl2e, fldl2e)
#define FLDPI CHOICE(fldpi, fldpi, fldpi)
#define FLDLG2 CHOICE(fldlg2, fldlg2, fldlg2)
#define FLDLN2 CHOICE(fldln2, fldln2, fldln2)
#define FLDZ CHOICE(fldz, fldz, fldz)
#define FLDCW(a) CHOICE(fldcw a, fldcw a, fldcw a)
#define FLDENV(a) CHOICE(fldenv a, fldenv a, fldenv a)
#define FMUL_S(a) CHOICE(fmuls a, fmuls a, fmuls a)
#define FMUL_D(a) CHOICE(fmull a, fmull a, fmuld a)
#define FMUL2(a, b) CHOICE(fmul ARG2(a,b), fmul ARG2(a,b), fmul ARG2(b,a))
#define FMULP(a, b) CHOICE(fmulp ARG2(a,b), fmulp ARG2(a,b), fmulp ARG2(b,a))
#define FIMUL_L(a) CHOICE(fimull a, fimull a, fimull a)
#define FIMUL_W(a) CHOICE(fimul a, fimuls a, fimuls a)
#define FNOP CHOICE(fnop, fnop, fnop)
#define FPATAN CHOICE(fpatan, fpatan, fpatan)
#define FPREM CHOICE(fprem, fprem, fprem)
#define FPREM1 CHOICE(fprem1, fprem1, fprem1)
#define FPTAN CHOICE(fptan, fptan, fptan)
#define FRNDINT CHOICE(frndint, frndint, frndint)
#define FRSTOR(a) CHOICE(frstor a, frstor a, frstor a)
#define FSAVE(a) CHOICE(fsave a, wait; fnsave a, wait; fsave a)
#define FNSAVE(a) CHOICE(fnsave a, fnsave a, fsave a)
#define FSCALE CHOICE(fscale, fscale, fscale)
#define FSIN CHOICE(fsin, fsin, fsin)
#define FSINCOS CHOICE(fsincos, fsincos, fsincos)
#define FSQRT CHOICE(fsqrt, fsqrt, fsqrt)
#define FST_D(a) CHOICE(fstl a, fstl a, fstd a)
#define FST_S(a) CHOICE(fsts a, fsts a, fsts a)
#define FSTP_X(a) CHOICE(fstpt a, fstpt a, fstpx a)
#define FSTP_D(a) CHOICE(fstpl a, fstpl a, fstpd a)
#define FSTP_S(a) CHOICE(fstps a, fstps a, fstps a)
#define FSTP(a) CHOICE(fstp a, fstp a, fstp a)
#define FSTCW(a) CHOICE(fstcw a, wait; fnstcw a, wait; fstcw a)
#define FNSTCW(a) CHOICE(fnstcw a, fnstcw a, fstcw a)
#define FSTENV(a) CHOICE(fstenv a, wait; fnstenv a, fstenv a)
#define FNSTENV(a) CHOICE(fnstenv a, fnstenv a, fstenv a)
#define FSTSW(a) CHOICE(fstsw a, wait; fnstsw a, wait; fstsw a)
#define FNSTSW(a) CHOICE(fnstsw a, fnstsw a, fstsw a)
#define FSUB_S(a) CHOICE(fsubs a, fsubs a, fsubs a)
#define FSUB_D(a) CHOICE(fsubl a, fsubl a, fsubd a)
#define FSUB2(a, b) CHOICE(fsub ARG2(a,b), fsub ARG2(a,b), fsub ARG2(b,a))
#define FSUBP(a, b) CHOICE(fsubp ARG2(a,b), fsubp ARG2(a,b), fsubp ARG2(b,a))
#define FISUB_L(a) CHOICE(fisubl a, fisubl a, fisubl a)
#define FISUB_W(a) CHOICE(fisub a, fisubs a, fisubs a)
#define FSUBR_S(a) CHOICE(fsubrs a, fsubrs a, fsubrs a)
#define FSUBR_D(a) CHOICE(fsubrl a, fsubrl a, fsubrd a)
#define FSUBR2(a, b) CHOICE(fsubr ARG2(a,b), fsubr ARG2(a,b), fsubr ARG2(b,a))
#define FSUBRP(a, b) CHOICE(fsubrp ARG2(a,b), fsubrp ARG2(a,b), fsubrp ARG2(b,a))
#define FISUBR_L(a) CHOICE(fisubrl a, fisubrl a, fisubrl a)
#define FISUBR_W(a) CHOICE(fisubr a, fisubrs a, fisubrs a)
#define FTST CHOICE(ftst, ftst, ftst)
#define FUCOM(a) CHOICE(fucom a, fucom a, fucom a)
#define FUCOMP(a) CHOICE(fucomp a, fucomp a, fucomp a)
#define FUCOMPP CHOICE(fucompp, fucompp, fucompp)
#define FWAIT CHOICE(wait, wait, wait)
#define FXAM CHOICE(fxam, fxam, fxam)
#define FXCH(a) CHOICE(fxch a, fxch a, fxch a)
#define FXTRACT CHOICE(fxtract, fxtract, fxtract)
#define FYL2X CHOICE(fyl2x, fyl2x, fyl2x)
#define FYL2XP1 CHOICE(fyl2xp1, fyl2xp1, fyl2xp1)
 
/* New instructions */
#define CPUID CHOICE(D_BYTE ARG2(15, 162), cpuid, D_BYTE ARG2(15, 162))
#define RDTSC CHOICE(D_BYTE ARG2(15, 49), rdtsc, D_BYTE ARG2(15, 49))
 
#else /* NASM_ASSEMBLER || MASM_ASSEMBLER is defined */
 
/****************************************/
/* */
/* Intel style assemblers. */
/* (NASM and MASM) */
/* */
/****************************************/
 
#define P_EAX EAX
#define L_EAX EAX
#define W_AX AX
#define B_AH AH
#define B_AL AL
 
#define P_EBX EBX
#define L_EBX EBX
#define W_BX BX
#define B_BH BH
#define B_BL BL
 
#define P_ECX ECX
#define L_ECX ECX
#define W_CX CX
#define B_CH CH
#define B_CL CL
 
#define P_EDX EDX
#define L_EDX EDX
#define W_DX DX
#define B_DH DH
#define B_DL DL
 
#define P_EBP EBP
#define L_EBP EBP
#define W_BP BP
 
#define P_ESI ESI
#define L_ESI ESI
#define W_SI SI
 
#define P_EDI EDI
#define L_EDI EDI
#define W_DI DI
 
#define P_ESP ESP
#define L_ESP ESP
#define W_SP SP
 
#define W_CS CS
#define W_SS SS
#define W_DS DS
#define W_ES ES
#define W_FS FS
#define W_GS GS
 
#define X_ST ST
#define D_ST ST
#define L_ST ST
 
#define P_MM0 mm0
#define P_MM1 mm1
#define P_MM2 mm2
#define P_MM3 mm3
#define P_MM4 mm4
#define P_MM5 mm5
#define P_MM6 mm6
#define P_MM7 mm7
 
#define P_XMM0 xmm0
#define P_XMM1 xmm1
#define P_XMM2 xmm2
#define P_XMM3 xmm3
#define P_XMM4 xmm4
#define P_XMM5 xmm5
#define P_XMM6 xmm6
#define P_XMM7 xmm7
 
#define CONCAT(x, y) x ## y
 
#if defined(NASM_ASSEMBLER)
 
#define ST(n) st ## n
#define ST0 st0
 
#define TBYTE_PTR tword
#define QWORD_PTR qword
#define DWORD_PTR dword
#define WORD_PTR word
#define BYTE_PTR byte
 
#define OFFSET
 
#define GLOBL GLOBAL
#define ALIGNTEXT32 ALIGN 32
#define ALIGNTEXT16 ALIGN 16
#define ALIGNTEXT8 ALIGN 8
#define ALIGNTEXT4 ALIGN 4
#define ALIGNTEXT2 ALIGN 2
#define ALIGNTEXT32ifNOP ALIGN 32
#define ALIGNTEXT16ifNOP ALIGN 16
#define ALIGNTEXT8ifNOP ALIGN 8
#define ALIGNTEXT4ifNOP ALIGN 4
#define ALIGNDATA32 ALIGN 32
#define ALIGNDATA16 ALIGN 16
#define ALIGNDATA8 ALIGN 8
#define ALIGNDATA4 ALIGN 4
#define ALIGNDATA2 ALIGN 2
#define FILE(s)
#define STRING(s) db s
#define D_LONG dd
#define D_WORD dw
#define D_BYTE db
/* #define SPACE */
/* #define COMM */
#if defined(__WATCOMC__)
SECTION _TEXT public align=16 class=CODE use32 flat
SECTION _DATA public align=16 class=DATA use32 flat
#define SEG_TEXT SECTION _TEXT
#define SEG_DATA SECTION _DATA
#define SEG_BSS SECTION .bss
#else
#define SEG_DATA SECTION .data
#define SEG_TEXT SECTION .text
#define SEG_BSS SECTION .bss
#endif
 
#define D_SPACE(n) db n REP 0
 
#define AS_BEGIN
 
/* Jcc's should be handled better than this... */
#define NEAR near
 
#else /* MASM */
 
#define TBYTE_PTR tbyte ptr
#define QWORD_PTR qword ptr
#define DWORD_PTR dword ptr
#define WORD_PTR word ptr
#define BYTE_PTR byte ptr
 
#define OFFSET offset
 
#define GLOBL GLOBAL
#define ALIGNTEXT32 ALIGN 32
#define ALIGNTEXT16 ALIGN 16
#define ALIGNTEXT8 ALIGN 8
#define ALIGNTEXT4 ALIGN 4
#define ALIGNTEXT2 ALIGN 2
#define ALIGNTEXT32ifNOP ALIGN 32
#define ALIGNTEXT16ifNOP ALIGN 16
#define ALIGNTEXT8ifNOP ALIGN 8
#define ALIGNTEXT4ifNOP ALIGN 4
#define ALIGNDATA32 ALIGN 32
#define ALIGNDATA16 ALIGN 16
#define ALIGNDATA8 ALIGN 8
#define ALIGNDATA4 ALIGN 4
#define ALIGNDATA2 ALIGN 2
#define FILE(s)
#define STRING(s) db s
#define D_LONG dd
#define D_WORD dw
#define D_BYTE db
/* #define SPACE */
/* #define COMM */
#define SEG_DATA .DATA
#define SEG_TEXT .CODE
#define SEG_BSS .DATA
 
#define D_SPACE(n) db n REP 0
 
#define AS_BEGIN
 
#define NEAR
 
#endif
 
#if defined(Lynx) || (defined(SYSV) || defined(SVR4)) \
|| (defined(__linux__) || defined(__OS2ELF__)) && defined(__ELF__) \
|| defined(__FreeBSD__) && __FreeBSD__ >= 3
#define GLNAME(a) a
#else
#define GLNAME(a) CONCAT(_, a)
#endif
 
/*
* Addressing Modes
*/
 
/* Immediate Mode */
#define P_ADDR(a) OFFSET a
#define X_ADDR(a) OFFSET a
#define D_ADDR(a) OFFSET a
#define L_ADDR(a) OFFSET a
#define W_ADDR(a) OFFSET a
#define B_ADDR(a) OFFSET a
 
#define P_CONST(a) a
#define X_CONST(a) a
#define D_CONST(a) a
#define L_CONST(a) a
#define W_CONST(a) a
#define B_CONST(a) a
 
/* Indirect Mode */
#ifdef NASM_ASSEMBLER
#define P_CONTENT(a) [a]
#define X_CONTENT(a) TBYTE_PTR [a]
#define D_CONTENT(a) QWORD_PTR [a]
#define L_CONTENT(a) DWORD_PTR [a]
#define W_CONTENT(a) WORD_PTR [a]
#define B_CONTENT(a) BYTE_PTR [a]
#else
#define P_CONTENT(a) a
#define X_CONTENT(a) TBYTE_PTR a
#define D_CONTENT(a) QWORD_PTR a
#define L_CONTENT(a) DWORD_PTR a
#define W_CONTENT(a) WORD_PTR a
#define B_CONTENT(a) BYTE_PTR a
#endif
 
/* Register a indirect */
#define P_REGIND(a) [a]
#define X_REGIND(a) TBYTE_PTR [a]
#define D_REGIND(a) QWORD_PTR [a]
#define L_REGIND(a) DWORD_PTR [a]
#define W_REGIND(a) WORD_PTR [a]
#define B_REGIND(a) BYTE_PTR [a]
 
/* Register b indirect plus displacement a */
#define P_REGOFF(a, b) [b + a]
#define X_REGOFF(a, b) TBYTE_PTR [b + a]
#define D_REGOFF(a, b) QWORD_PTR [b + a]
#define L_REGOFF(a, b) DWORD_PTR [b + a]
#define W_REGOFF(a, b) WORD_PTR [b + a]
#define B_REGOFF(a, b) BYTE_PTR [b + a]
 
/* Reg indirect Base + Index + Displacement - this is mainly for 16-bit mode
* which has no scaling
*/
#define P_REGBID(b, i, d) [b + i + d]
#define X_REGBID(b, i, d) TBYTE_PTR [b + i + d]
#define D_REGBID(b, i, d) QWORD_PTR [b + i + d]
#define L_REGBID(b, i, d) DWORD_PTR [b + i + d]
#define W_REGBID(b, i, d) WORD_PTR [b + i + d]
#define B_REGBID(b, i, d) BYTE_PTR [b + i + d]
 
/* Reg indirect Base + (Index * Scale) */
#define P_REGBIS(b, i, s) [b + i * s]
#define X_REGBIS(b, i, s) TBYTE_PTR [b + i * s]
#define D_REGBIS(b, i, s) QWORD_PTR [b + i * s]
#define L_REGBIS(b, i, s) DWORD_PTR [b + i * s]
#define W_REGBIS(b, i, s) WORD_PTR [b + i * s]
#define B_REGBIS(b, i, s) BYTE_PTR [b + i * s]
 
/* Reg indirect Base + (Index * Scale) + Displacement */
#define P_REGBISD(b, i, s, d) [b + i * s + d]
#define X_REGBISD(b, i, s, d) TBYTE_PTR [b + i * s + d]
#define D_REGBISD(b, i, s, d) QWORD_PTR [b + i * s + d]
#define L_REGBISD(b, i, s, d) DWORD_PTR [b + i * s + d]
#define W_REGBISD(b, i, s, d) WORD_PTR [b + i * s + d]
#define B_REGBISD(b, i, s, d) BYTE_PTR [b + i * s + d]
 
/* Displaced Scaled Index: */
#define P_REGDIS(d, i, s) [i * s + d]
#define X_REGDIS(d, i, s) TBYTE_PTR [i * s + d]
#define D_REGDIS(d, i, s) QWORD_PTR [i * s + d]
#define L_REGDIS(d, i, s) DWORD_PTR [i * s + d]
#define W_REGDIS(d, i, s) WORD_PTR [i * s + d]
#define B_REGDIS(d, i, s) BYTE_PTR [i * s + d]
 
/* Indexed Base: */
#define P_REGBI(b, i) [b + i]
#define X_REGBI(b, i) TBYTE_PTR [b + i]
#define D_REGBI(b, i) QWORD_PTR [b + i]
#define L_REGBI(b, i) DWORD_PTR [b + i]
#define W_REGBI(b, i) WORD_PTR [b + i]
#define B_REGBI(b, i) BYTE_PTR [b + i]
 
/* Displaced Base: */
#define P_REGDB(d, b) [b + d]
#define X_REGDB(d, b) TBYTE_PTR [b + d]
#define D_REGDB(d, b) QWORD_PTR [b + d]
#define L_REGDB(d, b) DWORD_PTR [b + d]
#define W_REGDB(d, b) WORD_PTR [b + d]
#define B_REGDB(d, b) BYTE_PTR [b + d]
 
/* Variable indirect: */
#define VARINDIRECT(var) var
 
/* Use register contents as jump/call target: */
#define CODEPTR(reg) P_(reg)
 
/*
* Redefine assembler commands
*/
 
#define P_(a) P_ ## a
#define X_(a) X_ ## a
#define D_(a) D_ ## a
#define S_(a) L_ ## a
#define L_(a) L_ ## a
#define W_(a) W_ ## a
#define B_(a) B_ ## a
 
#define AAA aaa
#define AAD aad
#define AAM aam
#define AAS aas
#define ADC_L(a, b) adc L_(b), L_(a)
#define ADC_W(a, b) adc W_(b), W_(a)
#define ADC_B(a, b) adc B_(b), B_(a)
#define ADD_L(a, b) add L_(b), L_(a)
#define ADD_W(a, b) add W_(b), W_(a)
#define ADD_B(a, b) add B_(b), B_(a)
#define AND_L(a, b) and L_(b), L_(a)
#define AND_W(a, b) and W_(b), W_(a)
#define AND_B(a, b) and B_(b), B_(a)
#define ARPL(a,b) arpl W_(b), a
#define BOUND_L(a, b) bound L_(b), L_(a)
#define BOUND_W(a, b) bound W_(b), W_(a)
#define BSF_L(a, b) bsf L_(b), L_(a)
#define BSF_W(a, b) bsf W_(b), W_(a)
#define BSR_L(a, b) bsr L_(b), L_(a)
#define BSR_W(a, b) bsr W_(b), W_(a)
#define BT_L(a, b) bt L_(b), L_(a)
#define BT_W(a, b) bt W_(b), W_(a)
#define BTC_L(a, b) btc L_(b), L_(a)
#define BTC_W(a, b) btc W_(b), W_(a)
#define BTR_L(a, b) btr L_(b), L_(a)
#define BTR_W(a, b) btr W_(b), W_(a)
#define BTS_L(a, b) bts L_(b), L_(a)
#define BTS_W(a, b) bts W_(b), W_(a)
#define CALL(a) call a
#define CALLF(s,a) call far s:a
#define CBW cbw
#define CWDE cwde
#define CLC clc
#define CLD cld
#define CLI cli
#define CLTS clts
#define CMC cmc
#define CMP_L(a, b) cmp L_(b), L_(a)
#define CMP_W(a, b) cmp W_(b), W_(a)
#define CMP_B(a, b) cmp B_(b), B_(a)
#define CMPS_L cmpsd
#define CMPS_W cmpsw
#define CMPS_B cmpsb
#define CPUID cpuid
#define CWD cwd
#define CDQ cdq
#define DAA daa
#define DAS das
#define DEC_L(a) dec L_(a)
#define DEC_W(a) dec W_(a)
#define DEC_B(a) dec B_(a)
#define DIV_L(a) div L_(a)
#define DIV_W(a) div W_(a)
#define DIV_B(a) div B_(a)
#define ENTER(a,b) enter b, a
#define HLT hlt
#define IDIV_L(a) idiv L_(a)
#define IDIV_W(a) idiv W_(a)
#define IDIV_B(a) idiv B_(a)
#define IMUL_L(a, b) imul L_(b), L_(a)
#define IMUL_W(a, b) imul W_(b), W_(a)
#define IMUL_B(a) imul B_(a)
#define IN_L in EAX, DX
#define IN_W in AX, DX
#define IN_B in AL, DX
#define IN1_L(a) in1 L_(a)
#define IN1_W(a) in1 W_(a)
#define IN1_B(a) in1 B_(a)
#define INC_L(a) inc L_(a)
#define INC_W(a) inc W_(a)
#define INC_B(a) inc B_(a)
#define INS_L ins
#define INS_W ins
#define INS_B ins
#define INT(a) int B_(a)
#define INT3 int3
#define INTO into
#define IRET iret
#define IRETD iretd
#define JA(a) ja NEAR a
#define JAE(a) jae NEAR a
#define JB(a) jb NEAR a
#define JBE(a) jbe NEAR a
#define JC(a) jc NEAR a
#define JE(a) je NEAR a
#define JG(a) jg NEAR a
#define JGE(a) jge NEAR a
#define JL(a) jl NEAR a
#define JLE(a) jle NEAR a
#define JNA(a) jna NEAR a
#define JNAE(a) jnae NEAR a
#define JNB(a) jnb NEAR a
#define JNBE(a) jnbe NEAR a
#define JNC(a) jnc NEAR a
#define JNE(a) jne NEAR a
#define JNG(a) jng NEAR a
#define JNGE(a) jnge NEAR a
#define JNL(a) jnl NEAR a
#define JNLE(a) jnle NEAR a
#define JNO(a) jno NEAR a
#define JNP(a) jnp NEAR a
#define JNS(a) jns NEAR a
#define JNZ(a) jnz NEAR a
#define JO(a) jo NEAR a
#define JP(a) jp NEAR a
#define JPE(a) jpe NEAR a
#define JPO(a) jpo NEAR a
#define JS(a) js NEAR a
#define JZ(a) jz NEAR a
#define JMP(a) jmp a
#define JMPF(s,a) jmp far s:a
#define LAHF lahf
#define LAR(a, b) lar b, a
#define LEA_L(a, b) lea P_(b), P_(a)
#define LEA_W(a, b) lea P_(b), P_(a)
#define LEAVE leave
#define LGDT(a) lgdt a
#define LIDT(a) lidt a
#define LDS(a, b) lds b, a
#define LES(a, b) les b, a
#define LFS(a, b) lfs b, a
#define LGS(a, b) lgs b, a
#define LSS(a, b) lss b, a
#define LLDT(a) lldt a
#define LMSW(a) lmsw a
#define LOCK lock
#define LODS_L lodsd
#define LODS_W lodsw
#define LODS_B lodsb
#define LOOP(a) loop a
#define LOOPE(a) loope a
#define LOOPZ(a) loopz a
#define LOOPNE(a) loopne a
#define LOOPNZ(a) loopnz a
#define LSL(a, b) lsl b, a
#define LTR(a) ltr a
#define MOV_SR(a, b) mov S_(b), S_(a)
#define MOV_L(a, b) mov L_(b), L_(a)
#define MOV_W(a, b) mov W_(b), W_(a)
#define MOV_B(a, b) mov B_(b), B_(a)
#define MOVS_L movsd
#define MOVS_W movsw
#define MOVS_B movsb
#define MOVSX_BL(a, b) movsx B_(b), B_(a)
#define MOVSX_BW(a, b) movsx B_(b), B_(a)
#define MOVSX_WL(a, b) movsx W_(b), W_(a)
#define MOVZX_BL(a, b) movzx B_(b), B_(a)
#define MOVZX_BW(a, b) movzx B_(b), B_(a)
#define MOVZX_WL(a, b) movzx W_(b), W_(a)
#define MUL_L(a) mul L_(a)
#define MUL_W(a) mul W_(a)
#define MUL_B(a) mul B_(a)
#define NEG_L(a) neg L_(a)
#define NEG_W(a) neg W_(a)
#define NEG_B(a) neg B_(a)
#define NOP nop
#define NOT_L(a) not L_(a)
#define NOT_W(a) not W_(a)
#define NOT_B(a) not B_(a)
#define OR_L(a,b) or L_(b), L_(a)
#define OR_W(a,b) or W_(b), W_(a)
#define OR_B(a,b) or B_(b), B_(a)
#define OUT_L out DX, EAX
#define OUT_W out DX, AX
#define OUT_B out DX, AL
#define OUT1_L(a) out1 L_(a)
#define OUT1_W(a) out1 W_(a)
#define OUT1_B(a) out1 B_(a)
#define OUTS_L outsd
#define OUTS_W outsw
#define OUTS_B outsb
#define POP_SR(a) pop S_(a)
#define POP_L(a) pop L_(a)
#define POP_W(a) pop W_(a)
#define POPA_L popad
#define POPA_W popa
#define POPF_L popfd
#define POPF_W popf
#define PUSH_SR(a) push S_(a)
#define PUSH_L(a) push L_(a)
#define PUSH_W(a) push W_(a)
#define PUSH_B(a) push B_(a)
#define PUSHA_L pushad
#define PUSHA_W pusha
#define PUSHF_L pushfd
#define PUSHF_W pushf
#define RCL_L(a, b) rcl L_(b), L_(a)
#define RCL_W(a, b) rcl W_(b), W_(a)
#define RCL_B(a, b) rcl B_(b), B_(a)
#define RCR_L(a, b) rcr L_(b), L_(a)
#define RCR_W(a, b) rcr W_(b), W_(a)
#define RCR_B(a, b) rcr B_(b), B_(a)
#define RDTSC rdtsc
#define ROL_L(a, b) rol L_(b), L_(a)
#define ROL_W(a, b) rol W_(b), W_(a)
#define ROL_B(a, b) rol B_(b), B_(a)
#define ROR_L(a, b) ror L_(b), L_(a)
#define ROR_W(a, b) ror W_(b), W_(a)
#define ROR_B(a, b) ror B_(b), B_(a)
#define REP rep
#define REPE repe
#define REPNE repne
#define REPNZ REPNE
#define REPZ REPE
#define RET ret
#define SAHF sahf
#define SAL_L(a, b) sal L_(b), L_(a)
#define SAL_W(a, b) sal W_(b), W_(a)
#define SAL_B(a, b) sal B_(b), B_(a)
#define SAR_L(a, b) sar L_(b), L_(a)
#define SAR_W(a, b) sar W_(b), W_(a)
#define SAR_B(a, b) sar B_(b), B_(a)
#define SBB_L(a, b) sbb L_(b), L_(a)
#define SBB_W(a, b) sbb W_(b), W_(a)
#define SBB_B(a, b) sbb B_(b), B_(a)
#define SCAS_L scas
#define SCAS_W scas
#define SCAS_B scas
#define SETA(a) seta a
#define SETAE(a) setae a
#define SETB(a) setb a
#define SETBE(a) setbe a
#define SETC(a) setc a
#define SETE(a) sete a
#define SETG(a) setg a
#define SETGE(a) setge a
#define SETL(a) setl a
#define SETLE(a) setle a
#define SETNA(a) setna a
#define SETNAE(a) setnae a
#define SETNB(a) setnb a
#define SETNBE(a) setnbe a
#define SETNC(a) setnc a
#define SETNE(a) setne a
#define SETNG(a) setng a
#define SETNGE(a) setnge a
#define SETNL(a) setnl a
#define SETNLE(a) setnle a
#define SETNO(a) setno a
#define SETNP(a) setnp a
#define SETNS(a) setns a
#define SETNZ(a) setnz a
#define SETO(a) seto a
#define SETP(a) setp a
#define SETPE(a) setpe a
#define SETPO(a) setpo a
#define SETS(a) sets a
#define SETZ(a) setz a
#define SGDT(a) sgdt a
#define SIDT(a) sidt a
#define SHL_L(a, b) shl L_(b), L_(a)
#define SHL_W(a, b) shl W_(b), W_(a)
#define SHL_B(a, b) shl B_(b), B_(a)
#define SHLD_L(a,b,c) shld
#define SHLD2_L(a,b) shld L_(b), L_(a)
#define SHLD_W(a,b,c) shld
#define SHLD2_W(a,b) shld W_(b), W_(a)
#define SHR_L(a, b) shr L_(b), L_(a)
#define SHR_W(a, b) shr W_(b), W_(a)
#define SHR_B(a, b) shr B_(b), B_(a)
#define SHRD_L(a,b,c) shrd
#define SHRD2_L(a,b) shrd L_(b), L_(a)
#define SHRD_W(a,b,c) shrd
#define SHRD2_W(a,b) shrd W_(b), W_(a)
#define SLDT(a) sldt a
#define SMSW(a) smsw a
#define STC stc
#define STD std
#define STI sti
#define STOS_L stos
#define STOS_W stos
#define STOS_B stos
#define STR(a) str a
#define SUB_L(a, b) sub L_(b), L_(a)
#define SUB_W(a, b) sub W_(b), W_(a)
#define SUB_B(a, b) sub B_(b), B_(a)
#define TEST_L(a, b) test L_(b), L_(a)
#define TEST_W(a, b) test W_(b), W_(a)
#define TEST_B(a, b) test B_(b), B_(a)
#define VERR(a) verr a
#define VERW(a) verw a
#define WAIT wait
#define XCHG_L(a, b) xchg L_(b), L_(a)
#define XCHG_W(a, b) xchg W_(b), W_(a)
#define XCHG_B(a, b) xchg B_(b), B_(a)
#define XLAT xlat
#define XOR_L(a, b) xor L_(b), L_(a)
#define XOR_W(a, b) xor W_(b), W_(a)
#define XOR_B(a, b) xor B_(b), B_(a)
 
 
/* Floating Point Instructions */
#define F2XM1 f2xm1
#define FABS fabs
#define FADD_D(a) fadd D_(a)
#define FADD_S(a) fadd S_(a)
#define FADD2(a, b) fadd b, a
#define FADDP(a, b) faddp b, a
#define FIADD_L(a) fiadd L_(a)
#define FIADD_W(a) fiadd W_(a)
#define FBLD(a) fbld a
#define FBSTP(a) fbstp a
#define FCHS fchs
#define FCLEX fclex
#define FNCLEX fnclex
#define FCOM(a) fcom a
#define FCOM_D(a) fcom D_(a)
#define FCOM_S(a) fcom S_(a)
#define FCOMP(a) fcomp a
#define FCOMP_D(a) fcomp D_(a)
#define FCOMP_S(a) fcomp S_(a)
#define FCOMPP fcompp
#define FCOS fcos
#define FDECSTP fdecstp
#define FDIV_D(a) fdiv D_(a)
#define FDIV_S(a) fdiv S_(a)
#define FDIV2(a, b) fdiv b, a
#define FDIVP(a, b) fdivp b, a
#define FIDIV_L(a) fidiv L_(a)
#define FIDIV_W(a) fidiv W_(a)
#define FDIVR_D(a) fdivr D_(a)
#define FDIVR_S(a) fdivr S_(a)
#define FDIVR2(a, b) fdivr b, a
#define FDIVRP(a, b) fdivrp b, a
#define FIDIVR_L(a) fidivr L_(a)
#define FIDIVR_W(a) fidivr W_(a)
#define FFREE(a) ffree a
#define FICOM_L(a) ficom L_(a)
#define FICOM_W(a) ficom W_(a)
#define FICOMP_L(a) ficomp L_(a)
#define FICOMP_W(a) ficomp W_(a)
#define FILD_Q(a) fild D_(a)
#define FILD_L(a) fild L_(a)
#define FILD_W(a) fild W_(a)
#define FINCSTP fincstp
#define FINIT finit
#define FNINIT fninit
#define FIST_L(a) fist L_(a)
#define FIST_W(a) fist W_(a)
#define FISTP_Q(a) fistp D_(a)
#define FISTP_L(a) fistp L_(a)
#define FISTP_W(a) fistp W_(a)
#define FLD_X(a) fld X_(a)
#define FLD_D(a) fld D_(a)
#define FLD_S(a) fld S_(a)
#define FLD1 fld1
#define FLDL2T fldl2t
#define FLDL2E fldl2e
#define FLDPI fldpi
#define FLDLG2 fldlg2
#define FLDLN2 fldln2
#define FLDZ fldz
#define FLDCW(a) fldcw a
#define FLDENV(a) fldenv a
#define FMUL_S(a) fmul S_(a)
#define FMUL_D(a) fmul D_(a)
#define FMUL2(a, b) fmul b, a
#define FMULP(a, b) fmulp b, a
#define FIMUL_L(a) fimul L_(a)
#define FIMUL_W(a) fimul W_(a)
#define FNOP fnop
#define FPATAN fpatan
#define FPREM fprem
#define FPREM1 fprem1
#define FPTAN fptan
#define FRNDINT frndint
#define FRSTOR(a) frstor a
#define FSAVE(a) fsave a
#define FNSAVE(a) fnsave a
#define FSCALE fscale
#define FSIN fsin
#define FSINCOS fsincos
#define FSQRT fsqrt
#define FST_D(a) fst D_(a)
#define FST_S(a) fst S_(a)
#define FSTP_X(a) fstp X_(a)
#define FSTP_D(a) fstp D_(a)
#define FSTP_S(a) fstp S_(a)
#define FSTP(a) fstp a
#define FSTCW(a) fstcw a
#define FNSTCW(a) fnstcw a
#define FSTENV(a) fstenv a
#define FNSTENV(a) fnstenv a
#define FSTSW(a) fstsw a
#define FNSTSW(a) fnstsw a
#define FSUB_S(a) fsub S_(a)
#define FSUB_D(a) fsub D_(a)
#define FSUB2(a, b) fsub b, a
#define FSUBP(a, b) fsubp b, a
#define FISUB_L(a) fisub L_(a)
#define FISUB_W(a) fisub W_(a)
#define FSUBR_S(a) fsubr S_(a)
#define FSUBR_D(a) fsubr D_(a)
#define FSUBR2(a, b) fsubr b, a
#define FSUBRP(a, b) fsubrp b, a
#define FISUBR_L(a) fisubr L_(a)
#define FISUBR_W(a) fisubr W_(a)
#define FTST ftst
#define FUCOM(a) fucom a
#define FUCOMP(a) fucomp a
#define FUCOMPP fucompp
#define FWAIT fwait
#define FXAM fxam
#define FXCH(a) fxch a
#define FXTRACT fxtract
#define FYL2X fyl2x
#define FYL2XP1 fyl2xp1
 
#endif /* NASM_ASSEMBLER, MASM_ASSEMBLER */
 
/****************************************/
/* */
/* Extensions to x86 insn set - */
/* MMX, 3DNow! */
/* */
/****************************************/
 
#if defined(NASM_ASSEMBLER) || defined(MASM_ASSEMBLER)
#define P_ARG1(a) P_ ## a
#define P_ARG2(a, b) P_ ## b, P_ ## a
#define P_ARG3(a, b, c) P_ ## c, P_ ## b, P_ ## a
#else
#define P_ARG1(a) a
#define P_ARG2(a, b) a, b
#define P_ARG3(a, b, c) a, b, c
#endif
 
/* MMX */
#define MOVD(a, b) movd P_ARG2(a, b)
#define MOVQ(a, b) movq P_ARG2(a, b)
 
#define PADDB(a, b) paddb P_ARG2(a, b)
#define PADDW(a, b) paddw P_ARG2(a, b)
#define PADDD(a, b) paddd P_ARG2(a, b)
 
#define PADDSB(a, b) paddsb P_ARG2(a, b)
#define PADDSW(a, b) paddsw P_ARG2(a, b)
 
#define PADDUSB(a, b) paddusb P_ARG2(a, b)
#define PADDUSW(a, b) paddusw P_ARG2(a, b)
 
#define PSUBB(a, b) psubb P_ARG2(a, b)
#define PSUBW(a, b) psubw P_ARG2(a, b)
#define PSUBD(a, b) psubd P_ARG2(a, b)
 
#define PSUBSB(a, b) psubsb P_ARG2(a, b)
#define PSUBSW(a, b) psubsw P_ARG2(a, b)
 
#define PSUBUSB(a, b) psubusb P_ARG2(a, b)
#define PSUBUSW(a, b) psubusw P_ARG2(a, b)
 
#define PCMPEQB(a, b) pcmpeqb P_ARG2(a, b)
#define PCMPEQW(a, b) pcmpeqw P_ARG2(a, b)
#define PCMPEQD(a, b) pcmpeqd P_ARG2(a, b)
 
#define PCMPGTB(a, b) pcmpgtb P_ARG2(a, b)
#define PCMPGTW(a, b) pcmpgtw P_ARG2(a, b)
#define PCMPGTD(a, b) pcmpgtd P_ARG2(a, b)
 
#define PMULHW(a, b) pmulhw P_ARG2(a, b)
#define PMULLW(a, b) pmullw P_ARG2(a, b)
 
#define PMADDWD(a, b) pmaddwd P_ARG2(a, b)
 
#define PAND(a, b) pand P_ARG2(a, b)
 
#define PANDN(a, b) pandn P_ARG2(a, b)
 
#define POR(a, b) por P_ARG2(a, b)
 
#define PXOR(a, b) pxor P_ARG2(a, b)
 
#define PSRAW(a, b) psraw P_ARG2(a, b)
#define PSRAD(a, b) psrad P_ARG2(a, b)
 
#define PSRLW(a, b) psrlw P_ARG2(a, b)
#define PSRLD(a, b) psrld P_ARG2(a, b)
#define PSRLQ(a, b) psrlq P_ARG2(a, b)
 
#define PSLLW(a, b) psllw P_ARG2(a, b)
#define PSLLD(a, b) pslld P_ARG2(a, b)
#define PSLLQ(a, b) psllq P_ARG2(a, b)
 
#define PACKSSWB(a, b) packsswb P_ARG2(a, b)
#define PACKSSDW(a, b) packssdw P_ARG2(a, b)
#define PACKUSWB(a, b) packuswb P_ARG2(a, b)
 
#define PUNPCKHBW(a, b) punpckhbw P_ARG2(a, b)
#define PUNPCKHWD(a, b) punpckhwd P_ARG2(a, b)
#define PUNPCKHDQ(a, b) punpckhdq P_ARG2(a, b)
#define PUNPCKLBW(a, b) punpcklbw P_ARG2(a, b)
#define PUNPCKLWD(a, b) punpcklwd P_ARG2(a, b)
#define PUNPCKLDQ(a, b) punpckldq P_ARG2(a, b)
 
#define EMMS emms
 
/* AMD 3DNow! */
#define PAVGUSB(a, b) pavgusb P_ARG2(a, b)
#define PFADD(a, b) pfadd P_ARG2(a, b)
#define PFSUB(a, b) pfsub P_ARG2(a, b)
#define PFSUBR(a, b) pfsubr P_ARG2(a, b)
#define PFACC(a, b) pfacc P_ARG2(a, b)
#define PFCMPGE(a, b) pfcmpge P_ARG2(a, b)
#define PFCMPGT(a, b) pfcmpgt P_ARG2(a, b)
#define PFCMPEQ(a, b) pfcmpeq P_ARG2(a, b)
#define PFMIN(a, b) pfmin P_ARG2(a, b)
#define PFMAX(a, b) pfmax P_ARG2(a, b)
#define PI2FD(a, b) pi2fd P_ARG2(a, b)
#define PF2ID(a, b) pf2id P_ARG2(a, b)
#define PFRCP(a, b) pfrcp P_ARG2(a, b)
#define PFRSQRT(a, b) pfrsqrt P_ARG2(a, b)
#define PFMUL(a, b) pfmul P_ARG2(a, b)
#define PFRCPIT1(a, b) pfrcpit1 P_ARG2(a, b)
#define PFRSQIT1(a, b) pfrsqit1 P_ARG2(a, b)
#define PFRCPIT2(a, b) pfrcpit2 P_ARG2(a, b)
#define PMULHRW(a, b) pmulhrw P_ARG2(a, b)
 
#define FEMMS femms
#define PREFETCH(a) prefetch P_ARG1(a)
#define PREFETCHW(a) prefetchw P_ARG1(a)
 
/* Intel SSE */
#define ADDPS(a, b) addps P_ARG2(a, b)
#define ADDSS(a, b) addss P_ARG2(a, b)
#define ANDNPS(a, b) andnps P_ARG2(a, b)
#define ANDPS(a, b) andps P_ARG2(a, b)
/* NASM only knows the pseudo ops for these.
#define CMPPS(a, b, c) cmpps P_ARG3(a, b, c)
#define CMPSS(a, b, c) cmpss P_ARG3(a, b, c)
*/
#define CMPEQPS(a, b) cmpeqps P_ARG2(a, b)
#define CMPLTPS(a, b) cmpltps P_ARG2(a, b)
#define CMPLEPS(a, b) cmpleps P_ARG2(a, b)
#define CMPUNORDPS(a, b) cmpunordps P_ARG2(a, b)
#define CMPNEQPS(a, b) cmpneqps P_ARG2(a, b)
#define CMPNLTPS(a, b) cmpnltps P_ARG2(a, b)
#define CMPNLEPS(a, b) cmpnleps P_ARG2(a, b)
#define CMPORDPS(a, b) cmpordps P_ARG2(a, b)
#define CMPEQSS(a, b) cmpeqss P_ARG2(a, b)
#define CMPLTSS(a, b) cmpltss P_ARG2(a, b)
#define CMPLESS(a, b) cmpless P_ARG2(a, b)
#define CMPUNORDSS(a, b) cmpunordss P_ARG2(a, b)
#define CMPNEQSS(a, b) cmpneqss P_ARG2(a, b)
#define CMPNLTSS(a, b) cmpnltss P_ARG2(a, b)
#define CMPNLESS(a, b) cmpnless P_ARG2(a, b)
#define CMPORDSS(a, b) cmpordss P_ARG2(a, b)
#define COMISS(a, b) comiss P_ARG2(a, b)
#define CVTPI2PS(a, b) cvtpi2ps P_ARG2(a, b)
#define CVTPS2PI(a, b) cvtps2pi P_ARG2(a, b)
#define CVTSI2SS(a, b) cvtsi2ss P_ARG2(a, b)
#define CVTSS2SI(a, b) cvtss2si P_ARG2(a, b)
#define CVTTPS2PI(a, b) cvttps2pi P_ARG2(a, b)
#define CVTTSS2SI(a, b) cvttss2si P_ARG2(a, b)
#define DIVPS(a, b) divps P_ARG2(a, b)
#define DIVSS(a, b) divss P_ARG2(a, b)
#define FXRSTOR(a) fxrstor P_ARG1(a)
#define FXSAVE(a) fxsave P_ARG1(a)
#define LDMXCSR(a) ldmxcsr P_ARG1(a)
#define MAXPS(a, b) maxps P_ARG2(a, b)
#define MAXSS(a, b) maxss P_ARG2(a, b)
#define MINPS(a, b) minps P_ARG2(a, b)
#define MINSS(a, b) minss P_ARG2(a, b)
#define MOVAPS(a, b) movaps P_ARG2(a, b)
#define MOVHLPS(a, b) movhlps P_ARG2(a, b)
#define MOVHPS(a, b) movhps P_ARG2(a, b)
#define MOVLHPS(a, b) movlhps P_ARG2(a, b)
#define MOVLPS(a, b) movlps P_ARG2(a, b)
#define MOVMSKPS(a, b) movmskps P_ARG2(a, b)
#define MOVNTPS(a, b) movntps P_ARG2(a, b)
#define MOVNTQ(a, b) movntq P_ARG2(a, b)
#define MOVSS(a, b) movss P_ARG2(a, b)
#define MOVUPS(a, b) movups P_ARG2(a, b)
#define MULPS(a, b) mulps P_ARG2(a, b)
#define MULSS(a, b) mulss P_ARG2(a, b)
#define ORPS(a, b) orps P_ARG2(a, b)
#define RCPPS(a, b) rcpps P_ARG2(a, b)
#define RCPSS(a, b) rcpss P_ARG2(a, b)
#define RSQRTPS(a, b) rsqrtps P_ARG2(a, b)
#define RSQRTSS(a, b) rsqrtss P_ARG2(a, b)
#define SHUFPS(a, b, c) shufps P_ARG3(a, b, c)
#define SQRTPS(a, b) sqrtps P_ARG2(a, b)
#define SQRTSS(a, b) sqrtss P_ARG2(a, b)
#define STMXCSR(a) stmxcsr P_ARG1(a)
#define SUBPS(a, b) subps P_ARG2(a, b)
#define UCOMISS(a, b) ucomiss P_ARG2(a, b)
#define UNPCKHPS(a, b) unpckhps P_ARG2(a, b)
#define UNPCKLPS(a, b) unpcklps P_ARG2(a, b)
#define XORPS(a, b) xorps P_ARG2(a, b)
 
#define PREFETCHNTA(a) prefetchnta P_ARG1(a)
#define PREFETCHT0(a) prefetcht0 P_ARG1(a)
#define PREFETCHT1(a) prefetcht1 P_ARG1(a)
#define PREFETCHT2(a) prefetcht2 P_ARG1(a)
#define SFENCE sfence
 
/* Added by BrianP for FreeBSD (per David Dawes) */
#if !defined(NASM_ASSEMBLER) && !defined(MASM_ASSEMBLER) && !defined(__bsdi__)
#define LLBL(a) CONCAT(.L,a)
#else
#define LLBL(a) a
#endif
 
 
#endif /* __ASSYNTAX_H__ */
/shark/trunk/ports/mesa/src/X86/sse_normal.s
0,0 → 1,252
/* $Id: sse_normal.s,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/** TODO:
* - insert PREFETCH instructions to avoid cache-misses !
* - some more optimizations are possible...
* - for 40-50% more performance in the SSE-functions, the
* data (trans-matrix, src_vert, dst_vert) needs to be 16byte aligned !
*/
 
#include "matypes.h"
#include "norm_args.h"
 
SEG_TEXT
 
#define M(i) REGOFF(i * 4, EDX)
#define S(i) REGOFF(i * 4, ESI)
#define D(i) REGOFF(i * 4, EDI)
#define STRIDE REGOFF(12, ESI)
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_sse_transform_rescale_normals_no_rot)
GLNAME(_mesa_sse_transform_rescale_normals_no_rot):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L ( ARG_IN, ESI ) /* ptr to source GLvector3f */
MOV_L ( ARG_DEST, EDI ) /* ptr to dest GLvector3f */
 
MOV_L ( ARG_MAT, EDX ) /* ptr to matrix */
MOV_L ( REGOFF(MATRIX_INV, EDX), EDX) /* matrix->inv */
 
MOV_L ( REGOFF(V3F_COUNT, ESI), ECX ) /* source count */
 
TEST_L ( ECX, ECX )
JZ( LLBL(K_G3TRNNRR_finish) ) /* count was zero; go to finish */
 
MOV_L ( STRIDE, EAX ) /* stride */
MOV_L ( ECX, REGOFF(V3F_COUNT, EDI) ) /* set dest-count */
 
IMUL_L( CONST(16), ECX ) /* count *= 16 */
MOV_L( REGOFF(V3F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V3F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVSS ( M(0), XMM1 ) /* m0 */
MOVSS ( M(5), XMM2 ) /* m5 */
UNPCKLPS( XMM2, XMM1 ) /* m5 | m0 */
MOVSS ( ARG_SCALE, XMM0 ) /* scale */
SHUFPS ( CONST(0x0), XMM0, XMM0 ) /* scale | scale */
MULPS ( XMM0, XMM1 ) /* m5*scale | m0*scale */
MULSS ( M(10), XMM0 ) /* m10*scale */
 
ALIGNTEXT32
LLBL(K_G3TRNNRR_top):
MOVLPS ( S(0), XMM2 ) /* uy | ux */
MULPS ( XMM1, XMM2 ) /* uy*m5*scale | ux*m0*scale */
MOVLPS ( XMM2, D(0) ) /* ->D(1) | D(0) */
 
MOVSS ( S(2), XMM2 ) /* uz */
MULSS ( XMM0, XMM2 ) /* uz*m10*scale */
MOVSS ( XMM2, D(2) ) /* ->D(2) */
 
LLBL(K_G3TRNNRR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_G3TRNNRR_top) )
 
LLBL(K_G3TRNNRR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_sse_transform_rescale_normals)
GLNAME(_mesa_sse_transform_rescale_normals):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L ( ARG_IN, ESI ) /* ptr to source GLvector3f */
MOV_L ( ARG_DEST, EDI ) /* ptr to dest GLvector3f */
 
MOV_L ( ARG_MAT, EDX ) /* ptr to matrix */
MOV_L ( REGOFF(MATRIX_INV, EDX), EDX) /* matrix->inv */
 
MOV_L ( REGOFF(V3F_COUNT, ESI), ECX ) /* source count */
 
TEST_L ( ECX, ECX )
JZ( LLBL(K_G3TRNR_finish) ) /* count was zero; go to finish */
 
MOV_L ( STRIDE, EAX ) /* stride */
MOV_L ( ECX, REGOFF(V3F_COUNT, EDI) ) /* set dest-count */
 
IMUL_L( CONST(16), ECX ) /* count *= 16 */
MOV_L( REGOFF(V3F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V3F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVSS ( M(0), XMM0 ) /* m0 */
MOVSS ( M(4), XMM1 ) /* m4 */
UNPCKLPS( XMM1, XMM0 ) /* m4 | m0 */
 
MOVSS ( ARG_SCALE, XMM4 ) /* scale */
SHUFPS ( CONST(0x0), XMM4, XMM4 ) /* scale | scale */
 
MULPS ( XMM4, XMM0 ) /* m4*scale | m0*scale */
MOVSS ( M(1), XMM1 ) /* m1 */
MOVSS ( M(5), XMM2 ) /* m5 */
UNPCKLPS( XMM2, XMM1 ) /* m5 | m1 */
MULPS ( XMM4, XMM1 ) /* m5*scale | m1*scale */
MOVSS ( M(2), XMM2 ) /* m2 */
MOVSS ( M(6), XMM3 ) /* m6 */
UNPCKLPS( XMM3, XMM2 ) /* m6 | m2 */
MULPS ( XMM4, XMM2 ) /* m6*scale | m2*scale */
 
MOVSS ( M(8), XMM6 ) /* m8 */
MULSS ( ARG_SCALE, XMM6 ) /* m8*scale */
MOVSS ( M(9), XMM7 ) /* m9 */
MULSS ( ARG_SCALE, XMM7 ) /* m9*scale */
 
ALIGNTEXT32
LLBL(K_G3TRNR_top):
MOVSS ( S(0), XMM3 ) /* ux */
SHUFPS ( CONST(0x0), XMM3, XMM3 ) /* ux | ux */
MULPS ( XMM0, XMM3 ) /* ux*m4 | ux*m0 */
MOVSS ( S(1), XMM4 ) /* uy */
SHUFPS ( CONST(0x0), XMM4, XMM4 ) /* uy | uy */
MULPS ( XMM1, XMM4 ) /* uy*m5 | uy*m1 */
MOVSS ( S(2), XMM5 ) /* uz */
SHUFPS ( CONST(0x0), XMM5, XMM5 ) /* uz | uz */
MULPS ( XMM2, XMM5 ) /* uz*m6 | uz*m2 */
 
ADDPS ( XMM4, XMM3 )
ADDPS ( XMM5, XMM3 )
MOVLPS ( XMM3, D(0) )
 
MOVSS ( M(10), XMM3 ) /* m10 */
MULSS ( ARG_SCALE, XMM3 ) /* m10*scale */
MULSS ( S(2), XMM3 ) /* m10*scale*uz */
MOVSS ( S(1), XMM4 ) /* uy */
MULSS ( XMM7, XMM4 ) /* uy*m9*scale */
MOVSS ( S(0), XMM5 ) /* ux */
MULSS ( XMM6, XMM5 ) /* ux*m8*scale */
 
ADDSS ( XMM4, XMM3 )
ADDSS ( XMM5, XMM3 )
MOVSS ( XMM3, D(2) )
 
LLBL(K_G3TRNR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_G3TRNR_top) )
 
LLBL(K_G3TRNR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
 
 
ALIGNTEXT16
GLOBL GLNAME(_mesa_sse_transform_normals_no_rot)
GLNAME(_mesa_sse_transform_normals_no_rot):
 
#define FRAME_OFFSET 8
PUSH_L ( ESI )
PUSH_L ( EDI )
 
MOV_L ( ARG_IN, ESI ) /* ptr to source GLvector3f */
MOV_L ( ARG_DEST, EDI ) /* ptr to dest GLvector3f */
 
MOV_L ( ARG_MAT, EDX ) /* ptr to matrix */
MOV_L ( REGOFF(MATRIX_INV, EDX), EDX) /* matrix->inv */
 
MOV_L ( REGOFF(V3F_COUNT, ESI), ECX ) /* source count */
 
TEST_L ( ECX, ECX )
JZ( LLBL(K_G3TNNRR_finish) ) /* count was zero; go to finish */
 
MOV_L ( STRIDE, EAX ) /* stride */
MOV_L ( ECX, REGOFF(V3F_COUNT, EDI) ) /* set dest-count */
 
IMUL_L( CONST(16), ECX ) /* count *= 16 */
MOV_L( REGOFF(V3F_START, ESI), ESI ) /* ptr to first source vertex */
 
MOV_L( REGOFF(V3F_START, EDI), EDI ) /* ptr to first dest vertex */
ADD_L( EDI, ECX ) /* count += dest ptr */
 
ALIGNTEXT32
MOVSS( M(0), XMM0 ) /* m0 */
MOVSS( M(5), XMM1 ) /* m5 */
UNPCKLPS( XMM1, XMM0 ) /* m5 | m0 */
MOVSS( M(10), XMM1 ) /* m10 */
 
ALIGNTEXT32
LLBL(K_G3TNNRR_top):
MOVLPS( S(0), XMM2 ) /* uy | ux */
MULPS( XMM0, XMM2 ) /* uy*m5 | ux*m0 */
MOVLPS( XMM2, D(0) )
 
MOVSS( S(2), XMM2 ) /* uz */
MULSS( XMM1, XMM2 ) /* uz*m10 */
MOVSS( XMM2, D(2) )
 
LLBL(K_G3TNNRR_skip):
ADD_L ( CONST(16), EDI )
ADD_L ( EAX, ESI )
CMP_L ( ECX, EDI )
JNE ( LLBL(K_G3TNNRR_top) )
 
LLBL(K_G3TNNRR_finish):
POP_L ( EDI )
POP_L ( ESI )
RET
#undef FRAME_OFFSET
/shark/trunk/ports/mesa/src/X86/x86.c
0,0 → 1,96
/* $Id: x86.c,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* Intel x86 assembly code by Josh Vanderhoof
*/
 
#include "glheader.h"
#include "context.h"
#include "math/m_xform.h"
#include "tnl/t_context.h"
 
#include "x86.h"
#include "common_x86_macros.h"
 
#ifdef DEBUG
#include "math/m_debug.h"
#endif
 
 
#ifdef USE_X86_ASM
DECLARE_XFORM_GROUP( x86, 2 )
DECLARE_XFORM_GROUP( x86, 3 )
DECLARE_XFORM_GROUP( x86, 4 )
 
 
extern GLvector4f * _ASMAPI
_mesa_x86_cliptest_points4( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
GLubyte *andMask );
 
extern GLvector4f * _ASMAPI
_mesa_x86_cliptest_points4_np( GLvector4f *clip_vec,
GLvector4f *proj_vec,
GLubyte clipMask[],
GLubyte *orMask,
GLubyte *andMask );
 
extern void _ASMAPI
_mesa_v16_x86_cliptest_points4( GLfloat *first_vert,
GLfloat *last_vert,
GLubyte *or_mask,
GLubyte *and_mask,
GLubyte *clip_mask );
 
extern void _ASMAPI
_mesa_v16_x86_general_xform( GLfloat *dest,
const GLfloat *m,
const GLfloat *src,
GLuint src_stride,
GLuint count );
#endif
 
 
void _mesa_init_x86_transform_asm( void )
{
#ifdef USE_X86_ASM
ASSIGN_XFORM_GROUP( x86, 2 );
ASSIGN_XFORM_GROUP( x86, 3 );
ASSIGN_XFORM_GROUP( x86, 4 );
 
_mesa_clip_tab[4] = _mesa_x86_cliptest_points4;
_mesa_clip_np_tab[4] = _mesa_x86_cliptest_points4_np;
 
#ifdef DEBUG
_math_test_all_transform_functions( "x86" );
_math_test_all_cliptest_functions( "x86" );
#endif
#endif
}
 
/shark/trunk/ports/mesa/src/X86/matypes.h
0,0 → 1,204
/*
* This file is automatically generated from the Mesa internal type
* definitions. Do not edit directly.
*/
 
#ifndef __ASM_TYPES_H__
#define __ASM_TYPES_H__
 
#include "assyntax.h"
 
 
/* =============================================================
* Offsets for GLcontext
*/
 
#define CTX_DRIVER_CTX 680
 
#define CTX_LIGHT_ENABLED 37140
#define CTX_LIGHT_SHADE_MODEL 37144
#define CTX_LIGHT_COLOR_MAT_FACE 37148
#define CTX_LIGHT_COLOR_MAT_MODE 37152
#define CTX_LIGHT_COLOR_MAT_MASK 37156
#define CTX_LIGHT_COLOR_MAT_ENABLED 37160
#define CTX_LIGHT_ENABLED_LIST 37164
#define CTX_LIGHT_NEED_VERTS 41520
#define CTX_LIGHT_FLAGS 41524
#define CTX_LIGHT_BASE_COLOR 41528
 
 
/* =============================================================
* Offsets for struct vertex_buffer
*/
 
#define VB_SIZE 0
#define VB_COUNT 4
 
#define VB_FIRST_CLIPPED 8
#define VB_FIRST_PRIMITIVE 12
 
#define VB_ELTS 16
#define VB_OBJ_PTR 20
#define VB_EYE_PTR 24
#define VB_CLIP_PTR 28
#define VB_PROJ_CLIP_PTR 32
#define VB_CLIP_OR_MASK 36
#define VB_CLIP_MASK 40
#define VB_NORMAL_PTR 44
#define VB_EDGE_FLAG 52
#define VB_TEX0_COORD_PTR 56
#define VB_TEX1_COORD_PTR 60
#define VB_TEX2_COORD_PTR 64
#define VB_TEX3_COORD_PTR 68
#define VB_INDEX_PTR 88
#define VB_COLOR_PTR 96
#define VB_SECONDARY_COLOR_PTR 104
#define VB_FOG_COORD_PTR 116
#define VB_POINT_SIZE_PTR 112
#define VB_MATERIAL 120
#define VB_MATERIAL_MASK 124
#define VB_FLAG 128
#define VB_PRIMITIVE 132
#define VB_PRIMITIVE_LENGTH 136
 
#define VB_IMPORTABLE_DATA 204
 
#define VB_LAST_CLIPPED 216
 
/*
* Flags for struct vertex_buffer
*/
 
#define VERT_BIT_OBJ 0x1
#define VERT_BIT_NORM 0x4
#define VERT_BIT_RGBA 0x8
#define VERT_BIT_SPEC_RGB 0x10
#define VERT_BIT_FOG_COORD 0x20
#define VERT_BIT_INDEX 0x40
#define VERT_BIT_EDGE 0x80
#define VERT_BIT_TEX0 0x100
#define VERT_BIT_TEX1 0x200
#define VERT_BIT_TEX2 0x400
#define VERT_BIT_TEX3 0x800
#define VERT_BIT_EVAL_C1 0x10000
#define VERT_BIT_EVAL_C2 0x20000
#define VERT_BIT_EVAL_P1 0x40000
#define VERT_BIT_EVAL_P2 0x80000
#define VERT_BIT_OBJ_3 0x100000
#define VERT_BIT_OBJ_4 0x200000
#define VERT_BIT_MATERIAL 0x400000
#define VERT_BIT_ELT 0x800000
#define VERT_BIT_BEGIN 0x1000000
#define VERT_BIT_END 0x2000000
#define VERT_BIT_END_VB 0x4000000
#define VERT_BIT_POINT_SIZE 0x8000000
#define VERT_BIT_EYE 0x1000000
#define VERT_BIT_CLIP 0x2000000
 
#define VERT_BIT_OBJ_23 0x100000
#define VERT_BIT_OBJ_234 0x200000
 
 
/* =============================================================
* Offsets for GLvector3f
*/
 
#define V3F_DATA 0
#define V3F_START 4
#define V3F_COUNT 8
#define V3F_STRIDE 12
#define V3F_FLAGS 16
 
 
/* =============================================================
* Offsets for GLvector4f
*/
 
#define V4F_DATA 0
#define V4F_START 4
#define V4F_COUNT 8
#define V4F_STRIDE 12
#define V4F_SIZE 16
#define V4F_FLAGS 20
 
/*
* Flags for GLvector4f
*/
 
#define VEC_MALLOC 0x10
#define VEC_NOT_WRITEABLE 0x40
#define VEC_BAD_STRIDE 0x100
 
#define VEC_SIZE_1 0x1
#define VEC_SIZE_2 0x3
#define VEC_SIZE_3 0x7
#define VEC_SIZE_4 0xf
 
 
/* =============================================================
* Offsets for GLmatrix
*/
 
#define MATRIX_DATA 0
#define MATRIX_INV 4
#define MATRIX_FLAGS 8
#define MATRIX_TYPE 12
 
 
/* =============================================================
* Offsets for struct gl_light
*/
 
#define LIGHT_NEXT 0
#define LIGHT_PREV 4
 
#define LIGHT_AMBIENT 8
#define LIGHT_DIFFUSE 24
#define LIGHT_SPECULAR 40
#define LIGHT_EYE_POSITION 56
#define LIGHT_EYE_DIRECTION 72
#define LIGHT_SPOT_EXPONENT 88
#define LIGHT_SPOT_CUTOFF 92
#define LIGHT_COS_CUTOFF 96
#define LIGHT_CONST_ATTEN 100
#define LIGHT_LINEAR_ATTEN 104
#define LIGHT_QUADRATIC_ATTEN 108
#define LIGHT_ENABLED 112
 
#define LIGHT_FLAGS 116
 
#define LIGHT_POSITION 120
#define LIGHT_VP_INF_NORM 136
#define LIGHT_H_INF_NORM 148
#define LIGHT_NORM_DIRECTION 160
#define LIGHT_VP_INF_SPOT_ATTEN 176
 
#define LIGHT_SPOT_EXP_TABLE 180
#define LIGHT_MAT_AMBIENT 4276
#define LIGHT_MAT_DIFFUSE 4300
#define LIGHT_MAT_SPECULAR 4324
 
#define SIZEOF_GL_LIGHT 4356
 
/*
* Flags for struct gl_light
*/
 
#define LIGHT_SPOT 0x1
#define LIGHT_LOCAL_VIEWER 0x2
#define LIGHT_POSITIONAL 0x4
 
#define LIGHT_NEED_VERTICES 0x6
 
 
/* =============================================================
* Offsets for struct gl_lightmodel
*/
 
#define LIGHT_MODEL_AMBIENT 0
#define LIGHT_MODEL_LOCAL_VIEWER 16
#define LIGHT_MODEL_TWO_SIDE 17
#define LIGHT_MODEL_COLOR_CONTROL 20
 
 
#endif /* __ASM_TYPES_H__ */
/shark/trunk/ports/mesa/src/X86/x86.h
0,0 → 1,36
/* $Id: x86.h,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* Intel x86 assembly code by Josh Vanderhoof
*/
 
#ifndef __X86_H__
#define __X86_H__
 
extern void _mesa_init_x86_transform_asm( void );
 
#endif
/shark/trunk/ports/mesa/src/X86/sse.c
0,0 → 1,119
/* $Id: sse.c,v 1.1 2003-02-28 11:49:39 pj Exp $ */
 
/*
* Mesa 3-D graphics library
* Version: 3.5
*
* Copyright (C) 1999-2001 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.
*/
 
/*
* PentiumIII-SIMD (SSE) optimizations contributed by
* Andre Werthmann <wertmann@cs.uni-potsdam.de>
*/
 
#include "glheader.h"
#include "context.h"
#include "math/m_xform.h"
#include "tnl/t_context.h"
 
#include "sse.h"
#include "common_x86_macros.h"
 
#ifdef DEBUG
#include "math/m_debug.h"
#endif
 
 
#ifdef USE_SSE_ASM
DECLARE_XFORM_GROUP( sse, 2 )
DECLARE_XFORM_GROUP( sse, 3 )
 
#if 1
/* Some functions are not written in SSE-assembly, because the fpu ones are faster */
extern void _mesa_sse_transform_normals_no_rot( NORM_ARGS );
extern void _mesa_sse_transform_rescale_normals( NORM_ARGS );
extern void _mesa_sse_transform_rescale_normals_no_rot( NORM_ARGS );
 
extern void _mesa_sse_transform_points4_general( XFORM_ARGS );
extern void _mesa_sse_transform_points4_3d( XFORM_ARGS );
extern void _mesa_sse_transform_points4_identity( XFORM_ARGS );
#else
DECLARE_NORM_GROUP( sse )
#endif
 
 
extern void _ASMAPI
_mesa_v16_sse_general_xform( GLfloat *first_vert,
const GLfloat *m,
const GLfloat *src,
GLuint src_stride,
GLuint count );
 
extern void _ASMAPI
_mesa_sse_project_vertices( GLfloat *first,
GLfloat *last,
const GLfloat *m,
GLuint stride );
 
extern void _ASMAPI
_mesa_sse_project_clipped_vertices( GLfloat *first,
GLfloat *last,
const GLfloat *m,
GLuint stride,
const GLubyte *clipmask );
#endif
 
 
void _mesa_init_sse_transform_asm( void )
{
#ifdef USE_SSE_ASM
ASSIGN_XFORM_GROUP( sse, 2 );
ASSIGN_XFORM_GROUP( sse, 3 );
 
#if 1
/* TODO: Finish these off.
*/
_mesa_transform_tab[4][MATRIX_GENERAL] =
_mesa_sse_transform_points4_general;
_mesa_transform_tab[4][MATRIX_3D] =
_mesa_sse_transform_points4_3d;
_mesa_transform_tab[4][MATRIX_IDENTITY] =
_mesa_sse_transform_points4_identity;
 
_mesa_normal_tab[NORM_TRANSFORM_NO_ROT] =
_mesa_sse_transform_normals_no_rot;
_mesa_normal_tab[NORM_TRANSFORM | NORM_RESCALE] =
_mesa_sse_transform_rescale_normals;
_mesa_normal_tab[NORM_TRANSFORM_NO_ROT | NORM_RESCALE] =
_mesa_sse_transform_rescale_normals_no_rot;
#else
ASSIGN_XFORM_GROUP( sse, 4 );
 
ASSIGN_NORM_GROUP( sse );
#endif
 
#ifdef DEBUG
_math_test_all_transform_functions( "SSE" );
_math_test_all_normal_transform_functions( "SSE" );
#endif
#endif
}
 
/shark/trunk/ports/mesa/src/X86/mmx_blendtmp.h
0,0 → 1,113
/*
* Written by José Fonseca <j_r_fonseca@yahoo.co.uk>
*/
 
 
/*
* void _mesa_mmx_blend( GLcontext *ctx,
* GLuint n,
* const GLubyte mask[],
* GLchan rgba[][4],
* CONST GLchan dest[][4] )
*
*/
ALIGNTEXT16
GLOBL GLNAME( TAG(_mesa_mmx_blend) )
 
GLNAME( TAG(_mesa_mmx_blend) ):
 
PUSH_L ( EBP )
MOV_L ( ESP, EBP )
PUSH_L ( ESI )
PUSH_L ( EDI )
PUSH_L ( EBX )
 
MOV_L ( REGOFF(12, EBP), ECX ) /* n */
CMP_L ( CONST(0), ECX)
JE ( LLBL ( TAG(GMB_return) ) )
 
MOV_L ( REGOFF(16, EBP), EBX ) /* mask */
MOV_L ( REGOFF(20, EBP), EDI ) /* rgba */
MOV_L ( REGOFF(24, EBP), ESI ) /* dest */
 
INIT
TEST_L ( CONST(4), EDI ) /* align rgba on an 8-byte boundary */
JZ ( LLBL ( TAG(GMB_align_end) ) )
 
CMP_B ( CONST(0), REGIND(EBX) ) /* *mask == 0 */
JE ( LLBL ( TAG(GMB_align_continue) ) )
 
/* runin */
#define ONE(x) x
#define TWO(x)
MAIN ( EDI, ESI )
#undef ONE
#undef TWO
 
LLBL ( TAG(GMB_align_continue) ):
 
DEC_L ( ECX ) /* n -= 1 */
INC_L ( EBX ) /* mask += 1 */
ADD_L ( CONST(4), EDI ) /* rgba += 1 */
ADD_L ( CONST(4), ESI ) /* dest += 1 */
 
LLBL ( TAG(GMB_align_end) ):
 
CMP_L ( CONST(2), ECX)
JB ( LLBL ( TAG(GMB_loop_end) ) )
 
ALIGNTEXT16
LLBL ( TAG(GMB_loop_begin) ):
 
CMP_W ( CONST(0), REGIND(EBX) ) /* *mask == 0 && *(mask + 1) == 0 */
JE ( LLBL ( TAG(GMB_loop_continue) ) )
 
/* main loop */
#define ONE(x)
#define TWO(x) x
MAIN ( EDI, ESI )
#undef ONE
#undef TWO
 
LLBL ( TAG(GMB_loop_continue) ):
 
DEC_L ( ECX )
DEC_L ( ECX ) /* n -= 2 */
ADD_L ( CONST(2), EBX ) /* mask += 2 */
ADD_L ( CONST(8), EDI ) /* rgba += 2 */
ADD_L ( CONST(8), ESI ) /* dest += 2 */
CMP_L ( CONST(2), ECX )
JAE ( LLBL ( TAG(GMB_loop_begin) ) )
 
LLBL ( TAG(GMB_loop_end) ):
 
CMP_L ( CONST(1), ECX )
JB ( LLBL ( TAG(GMB_done) ) )
 
CMP_B ( CONST(0), REGIND(EBX) ) /* *mask == 0 */
JE ( LLBL ( TAG(GMB_done) ) )
 
/* runout */
#define ONE(x) x
#define TWO(x)
MAIN ( EDI, ESI )
#undef ONE
#undef TWO
 
LLBL ( TAG(GMB_done) ):
 
EMMS
 
LLBL ( TAG(GMB_return) ):
 
POP_L ( EBX )
POP_L ( EDI )
POP_L ( ESI )
MOV_L ( EBP, ESP )
POP_L ( EBP )
RET
 
#undef TAG
#undef INIT
#undef MAIN