/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 |