diff options
author | Eric Anholt <[email protected]> | 2007-05-24 13:59:50 -0700 |
---|---|---|
committer | Eric Anholt <[email protected]> | 2007-05-24 16:46:54 -0700 |
commit | fd9d27e0686f5a15803d13d207e58be1972fdf31 (patch) | |
tree | 79f8847e0fd723567032fa201d7b3ff2fdf5621d | |
parent | b1fcabefa2f3fa81a20c1556383458315bb49bbf (diff) | |
parent | f116aed1ede0d802e9f3c5989290002975c00330 (diff) |
Merge branch 'master' into i915-unification
Conflicts:
src/mesa/drivers/dri/i915tex/i830_texstate.c
src/mesa/drivers/dri/i915tex/i915_texstate.c
104 files changed, 2851 insertions, 2885 deletions
diff --git a/docs/relnotes-7.1.html b/docs/relnotes-7.1.html index 974b3096eaa..b684447e709 100644 --- a/docs/relnotes-7.1.html +++ b/docs/relnotes-7.1.html @@ -23,6 +23,7 @@ TBD <h2>New features</h2> <ul> +<li>GL_EXT_texture_from_pixmap extension for Xlib driver </ul> diff --git a/include/GL/gl.h b/include/GL/gl.h index 6e92481a536..a388de36e49 100644 --- a/include/GL/gl.h +++ b/include/GL/gl.h @@ -2221,8 +2221,13 @@ GLAPI void APIENTRY glFramebufferTextureLayerEXT(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); #endif /* GL_GLEXT_PROTOTYPES */ +#if 0 +/* (temporarily) disabled because of collision with typedef in glext.h + * that happens if apps include both gl.h and glext.h + */ typedef void (APIENTRYP PFNGLFRAMEBUFFERTEXTURELAYEREXTPROC) (GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer); +#endif #define GL_TEXTURE_1D_ARRAY_EXT 0x8C18 #define GL_PROXY_TEXTURE_1D_ARRAY_EXT 0x8C19 diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index a3de2c6aab3..8d24e311f84 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -361,6 +361,18 @@ struct __DRIscreenRec { void * (*createNewContext)(__DRInativeDisplay *dpy, const __GLcontextModes *modes, int render_type, void *sharedPrivate, __DRIcontext *pctx); + + /** + * Method to override base texture image with a driver specific 'offset'. + * The depth passed in allows e.g. to ignore the alpha channel of texture + * images where the non-alpha components don't occupy a whole texel. + * + * For GLX_EXT_texture_from_pixmap with AIGLX. + * + * \since Internal API version 20070121. + */ + void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch); }; /** diff --git a/include/GL/xmesa.h b/include/GL/xmesa.h index f185a15cdb8..98139af8336 100644 --- a/include/GL/xmesa.h +++ b/include/GL/xmesa.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 4.1 + * Version: 7.1 * - * Copyright (C) 1999-2002 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -397,6 +397,25 @@ extern XMesaBuffer XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, +/* + * Texture from Pixmap + * New in Mesa 7.1 + */ +extern void +XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer, + const int *attrib_list); + +extern void +XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer); + + +extern XMesaBuffer +XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p, + XMesaColormap cmap, + int format, int target, int mipmap); + + + #ifdef __cplusplus } #endif diff --git a/include/GL/xmesa_x.h b/include/GL/xmesa_x.h index 721d8b51070..865bab4313b 100644 --- a/include/GL/xmesa_x.h +++ b/include/GL/xmesa_x.h @@ -66,6 +66,7 @@ typedef XColor XMesaColor; #define XMesaDrawPoints XDrawPoints #define XMesaDrawLine XDrawLine #define XMesaFillRectangle XFillRectangle +#define XMesaGetImage XGetImage #define XMesaPutImage XPutImage #define XMesaCopyArea XCopyArea diff --git a/include/GL/xmesa_xf86.h b/include/GL/xmesa_xf86.h index 0a15110f651..18908a133fa 100644 --- a/include/GL/xmesa_xf86.h +++ b/include/GL/xmesa_xf86.h @@ -42,8 +42,15 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "scrnintstr.h" #include "pixmapstr.h" #include "gcstruct.h" +#include "servermd.h" -typedef struct _XMesaImageRec XMesaImage; + +typedef struct _XMesaImageRec { + int width, height; + char *data; + int bytes_per_line; /* Padded to 32 bits */ + int bits_per_pixel; +} XMesaImage; typedef ScreenRec XMesaDisplay; typedef PixmapPtr XMesaPixmap; @@ -120,6 +127,26 @@ do { \ (*__gc->ops->PolyFillRect)((DrawablePtr)__b, __gc, 1, __r); \ } while (0) +static _X_INLINE XMesaImage *XMesaGetImage(XMesaDisplay *dpy, PixmapPtr p, int x, + int y, unsigned int width, + unsigned int height, + unsigned long plane_mask, int format) +{ + XMesaImage *img = Xcalloc(sizeof(*img)); + + img->width = p->drawable.width; + img->height = p->drawable.height; + img->bits_per_pixel = p->drawable.bitsPerPixel; + img->bytes_per_line = PixmapBytePad(width, p->drawable.depth); + img->data = malloc(height * img->bytes_per_line); + + /* Assumes: Images are always in ZPixmap format */ + (*p->drawable.pScreen->GetImage)(&p->drawable, x, y, width, height, + plane_mask, ZPixmap, img->data); + + return img; +} + #define XMesaPutImage(__d,__b,__gc,__i,__sx,__sy,__x,__y,__w,__h) \ do { \ /* Assumes: Images are always in ZPixmap format */ \ diff --git a/progs/xdemos/Makefile b/progs/xdemos/Makefile index ec85464bec0..d1d7fecea1c 100644 --- a/progs/xdemos/Makefile +++ b/progs/xdemos/Makefile @@ -23,6 +23,7 @@ PROGS = glthreads \ overlay \ pbinfo \ pbdemo \ + texture_from_pixmap \ wincopy \ xfont \ xrotfontdemo \ diff --git a/progs/xdemos/texture_from_pixmap.c b/progs/xdemos/texture_from_pixmap.c new file mode 100644 index 00000000000..50870c4df4a --- /dev/null +++ b/progs/xdemos/texture_from_pixmap.c @@ -0,0 +1,383 @@ +/* + * Mesa 3-D graphics library + * Version: 7.1 + * + * Copyright (C) 1999-2007 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. + */ + + +/* + * Test the GLX_EXT_texture_from_pixmap extension + * Brian Paul + * 19 May 2007 + */ + + +#define GL_GLEXT_PROTOTYPES +#define GLX_GLXEXT_PROTOTYPES +#include <GL/gl.h> +#include <GL/glx.h> +#include <X11/keysym.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + + +static float top, bottom; + + +static Display * +OpenDisplay(void) +{ + int screen; + Display *dpy; + const char *ext; + + dpy = XOpenDisplay(NULL); + if (!dpy) { + printf("Couldn't open default display!\n"); + exit(1); + } + + screen = DefaultScreen(dpy); + ext = glXQueryExtensionsString(dpy, screen); + if (!strstr(ext, "GLX_EXT_texture_from_pixmap")) { + printf("GLX_EXT_texture_from_pixmap not supported by GLX\n"); + exit(1); + } + + return dpy; +} + + +static GLXFBConfig +ChoosePixmapFBConfig(Display *display) +{ + int screen = DefaultScreen(display); + GLXFBConfig *fbconfigs; + int i, nfbconfigs, value; + + fbconfigs = glXGetFBConfigs(display, screen, &nfbconfigs); + for (i = 0; i < nfbconfigs; i++) { + + glXGetFBConfigAttrib(display, fbconfigs[i], GLX_DRAWABLE_TYPE, &value); + if (!(value & GLX_PIXMAP_BIT)) + continue; + + glXGetFBConfigAttrib(display, fbconfigs[i], + GLX_BIND_TO_TEXTURE_TARGETS_EXT, &value); + if (!(value & GLX_TEXTURE_2D_BIT_EXT)) + continue; + + glXGetFBConfigAttrib(display, fbconfigs[i], + GLX_BIND_TO_TEXTURE_RGBA_EXT, &value); + if (value == False) { + glXGetFBConfigAttrib(display, fbconfigs[i], + GLX_BIND_TO_TEXTURE_RGB_EXT, &value); + if (value == False) + continue; + } + + glXGetFBConfigAttrib(display, fbconfigs[i], + GLX_Y_INVERTED_EXT, &value); + if (value == True) { + top = 0.0f; + bottom = 1.0f; + } + else { + top = 1.0f; + bottom = 0.0f; + } + + break; + } + + if (i == nfbconfigs) { + printf("Unable to find FBconfig for texturing\n"); + exit(1); + } + + return fbconfigs[i]; +} + + +static GLXPixmap +CreatePixmap(Display *dpy, GLXFBConfig config, int w, int h, Pixmap *p) +{ + GLXPixmap gp; + const int pixmapAttribs[] = { + GLX_TEXTURE_TARGET_EXT, GLX_TEXTURE_2D_EXT, + GLX_TEXTURE_FORMAT_EXT, GLX_TEXTURE_FORMAT_RGB_EXT, + None + }; + Window root = RootWindow(dpy, 0); + + *p = XCreatePixmap(dpy, root, w, h, 24); + XSync(dpy, 0); + gp = glXCreatePixmap(dpy, config, *p, pixmapAttribs); + XSync(dpy, 0); + + return gp; +} + + +static void +DrawPixmapImage(Display *dpy, Pixmap pm, int w, int h) +{ + XGCValues gcvals; + GC gc; + + gcvals.background = 0; + gc = XCreateGC(dpy, pm, GCBackground, &gcvals); + + XSetForeground(dpy, gc, 0x0); + XFillRectangle(dpy, pm, gc, 0, 0, w, h); + + XSetForeground(dpy, gc, 0xff0000); + XFillRectangle(dpy, pm, gc, 0, 0, 50, 50); + + XSetForeground(dpy, gc, 0x00ff00); + XFillRectangle(dpy, pm, gc, w - 50, 0, 50, 50); + + XSetForeground(dpy, gc, 0x0000ff); + XFillRectangle(dpy, pm, gc, 0, h - 50, 50, 50); + + XSetForeground(dpy, gc, 0xffffff); + XFillRectangle(dpy, pm, gc, h - 50, h - 50, 50, 50); + + XSetForeground(dpy, gc, 0xffff00); + XSetLineAttributes(dpy, gc, 3, LineSolid, CapButt, JoinBevel); + XDrawLine(dpy, pm, gc, 0, 0, w, h); + XDrawLine(dpy, pm, gc, 0, h, w, 0); + + XFreeGC(dpy, gc); +} + + +static XVisualInfo * +ChooseWindowVisual(Display *dpy) +{ + int screen = DefaultScreen(dpy); + XVisualInfo *visinfo; + int attribs[] = { + GLX_RGBA, + GLX_RED_SIZE, 1, + GLX_GREEN_SIZE, 1, + GLX_BLUE_SIZE, 1, + GLX_DOUBLEBUFFER, + None + }; + + visinfo = glXChooseVisual(dpy, screen, attribs); + if (!visinfo) { + printf("Unable to find RGB, double-buffered visual\n"); + exit(1); + } + + return visinfo; +} + + +static Window +CreateWindow(Display *dpy, XVisualInfo *visinfo, + int width, int height, const char *name) +{ + int screen = DefaultScreen(dpy); + Window win; + XSetWindowAttributes attr; + unsigned long mask; + Window root; + + root = RootWindow(dpy, screen); + + /* window attributes */ + attr.background_pixel = 0; + attr.border_pixel = 0; + attr.colormap = XCreateColormap(dpy, root, visinfo->visual, AllocNone); + attr.event_mask = StructureNotifyMask | ExposureMask | KeyPressMask; + mask = CWBackPixel | CWBorderPixel | CWColormap | CWEventMask; + + win = XCreateWindow(dpy, root, 0, 0, width, height, + 0, visinfo->depth, InputOutput, + visinfo->visual, mask, &attr); + if (win) { + XSizeHints sizehints; + sizehints.width = width; + sizehints.height = height; + sizehints.flags = USSize; + XSetNormalHints(dpy, win, &sizehints); + XSetStandardProperties(dpy, win, name, name, + None, (char **)NULL, 0, &sizehints); + + XMapWindow(dpy, win); + } + return win; +} + + +static void +BindPixmapTexture(Display *dpy, GLXPixmap gp) +{ + GLuint texture; + + glGenTextures(1, &texture); + glBindTexture(GL_TEXTURE_2D, texture); + + glXBindTexImageEXT(dpy, gp, GLX_FRONT_LEFT_EXT, NULL); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glEnable(GL_TEXTURE_2D); + /* + glXReleaseTexImageEXT (display, glxpixmap, GLX_FRONT_LEFT_EXT); + */ +} + + +static void +Resize(Window win, unsigned int width, unsigned int height) +{ + float sz = 1.5; + glViewport(0, 0, width, height); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(-sz, sz, -sz, sz, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); +} + + +static void +Redraw(Display *dpy, Window win, float rot) +{ + glClearColor(0.25, 0.25, 0.25, 0.0); + glClear(GL_COLOR_BUFFER_BIT); + glPushMatrix(); + glRotatef(rot, 0, 0, 1); + glRotatef(2.0 * rot, 1, 0, 0); + + glBegin(GL_QUADS); + glTexCoord2d(0.0, bottom); + glVertex2f(-1, -1); + glTexCoord2d(1.0, bottom); + glVertex2f( 1, -1); + glTexCoord2d(1.0, top); + glVertex2d(1.0, 1.0); + glTexCoord2d(0.0, top); + glVertex2f(-1.0, 1.0); + glEnd(); + + glPopMatrix(); + + glXSwapBuffers(dpy, win); +} + + +static void +EventLoop(Display *dpy, Window win) +{ + GLfloat rot = 0.0; + int anim = 0; + + while (1) { + if (!anim || XPending(dpy) > 0) { + XEvent event; + XNextEvent(dpy, &event); + + switch (event.type) { + case Expose: + Redraw(dpy, win, rot); + break; + case ConfigureNotify: + Resize(event.xany.window, + event.xconfigure.width, + event.xconfigure.height); + break; + case KeyPress: + { + char buf[100]; + KeySym keySym; + XComposeStatus stat; + XLookupString(&event.xkey, buf, sizeof(buf), &keySym, &stat); + if (keySym == XK_Escape) { + return; /* exit */ + } + else if (keySym == XK_r) { + rot += 1.0; + Redraw(dpy, win, rot); + } + else if (keySym == XK_a) { + anim = !anim; + } + else if (keySym == XK_R) { + rot -= 1.0; + Redraw(dpy, win, rot); + } + } + break; + default: + ; /*no-op*/ + } + } + else { + /* animate */ + rot += 1.0; + Redraw(dpy, win, rot); + } + } +} + + + +int +main(int argc, char *argv[]) +{ + Display *dpy; + GLXFBConfig pixmapConfig; + XVisualInfo *windowVis; + GLXPixmap gp; + Window win; + GLXContext ctx; + Pixmap p; + + dpy = OpenDisplay(); + + pixmapConfig = ChoosePixmapFBConfig(dpy); + windowVis = ChooseWindowVisual(dpy); + win = CreateWindow(dpy, windowVis, 500, 500, "Texture From Pixmap"); + + gp = CreatePixmap(dpy, pixmapConfig, 512, 512, &p); + DrawPixmapImage(dpy, p, 512, 512); + + ctx = glXCreateContext(dpy, windowVis, NULL, True); + if (!ctx) { + printf("Couldn't create GLX context\n"); + exit(1); + } + + glXMakeCurrent(dpy, win, ctx); + + BindPixmapTexture(dpy, gp); + + EventLoop(dpy, win); + + return 0; +} diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index adf9aafe596..9b1c3f1e060 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -292,3 +292,97 @@ _mesa_init_glsl_driver_functions(struct dd_function_table *driver) driver->UseProgram = _mesa_use_program; driver->ValidateProgram = _mesa_validate_program; } + + +/** + * Call the ctx->Driver.* state functions with current values to initialize + * driver state. + * Only the Intel drivers use this so far. + */ +void +_mesa_init_driver_state(GLcontext *ctx) +{ + ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); + + ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); + + ctx->Driver.BlendEquationSeparate(ctx, + ctx->Color.BlendEquationRGB, + ctx->Color.BlendEquationA); + + ctx->Driver.BlendFuncSeparate(ctx, + ctx->Color.BlendSrcRGB, + ctx->Color.BlendDstRGB, + ctx->Color.BlendSrcA, ctx->Color.BlendDstA); + + ctx->Driver.ColorMask(ctx, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode); + ctx->Driver.DepthFunc(ctx, ctx->Depth.Func); + ctx->Driver.DepthMask(ctx, ctx->Depth.Mask); + + ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); + ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled); + ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled); + ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled); + ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag); + ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); + ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag); + ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled); + ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled); + ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag); + ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag); + ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled); + ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); + ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE); + ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); + + ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); + ctx->Driver.Fogfv(ctx, GL_FOG_MODE, 0); + ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); + ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); + ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); + + ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); + + { + GLfloat f = (GLfloat) ctx->Light.Model.ColorControl; + ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f); + } + + ctx->Driver.LineWidth(ctx, ctx->Line.Width); + ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp); + ctx->Driver.PointSize(ctx, ctx->Point.Size); + ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple); + ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, + ctx->Scissor.Width, ctx->Scissor.Height); + ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel); + ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, + ctx->Stencil.Function[0], + ctx->Stencil.Ref[0], + ctx->Stencil.ValueMask[0]); + ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, + ctx->Stencil.Function[1], + ctx->Stencil.Ref[1], + ctx->Stencil.ValueMask[1]); + ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]); + ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]); + ctx->Driver.StencilOpSeparate(ctx, GL_FRONT, + ctx->Stencil.FailFunc[0], + ctx->Stencil.ZFailFunc[0], + ctx->Stencil.ZPassFunc[0]); + ctx->Driver.StencilOpSeparate(ctx, GL_BACK, + ctx->Stencil.FailFunc[1], + ctx->Stencil.ZFailFunc[1], + ctx->Stencil.ZPassFunc[1]); + + + ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]); +} diff --git a/src/mesa/drivers/common/driverfuncs.h b/src/mesa/drivers/common/driverfuncs.h index 50f2b4271dc..6ed23c4520e 100644 --- a/src/mesa/drivers/common/driverfuncs.h +++ b/src/mesa/drivers/common/driverfuncs.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -33,4 +33,9 @@ _mesa_init_driver_functions(struct dd_function_table *driver); extern void _mesa_init_glsl_driver_functions(struct dd_function_table *driver); + +extern void +_mesa_init_driver_state(GLcontext *ctx); + + #endif diff --git a/src/mesa/drivers/dri/Makefile b/src/mesa/drivers/dri/Makefile index 4abcc16c1bc..f466ce6c3cc 100644 --- a/src/mesa/drivers/dri/Makefile +++ b/src/mesa/drivers/dri/Makefile @@ -32,7 +32,7 @@ install: clean: @for dir in $(DRI_DIRS) ; do \ if [ -d $$dir ] ; then \ - (cd $$dir && $(MAKE) clean ; \ + (cd $$dir && $(MAKE) clean) ; \ fi \ done -rm -f common/*.o diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 07ac4c7cd5f..dd52f7e9151 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -995,6 +995,9 @@ __driUtilCreateNewScreen(__DRInativeDisplay *dpy, int scrn, __DRIscreen *psc, psc->getMSC = driGetMSC; psc->createNewContext = driCreateNewContext; + if (internal_api_version >= 20070121) + psc->setTexOffset = psp->DriverAPI.setTexOffset; + if ( (psp->DriverAPI.InitDriver != NULL) && !(*psp->DriverAPI.InitDriver)(psp) ) { _mesa_free( psp ); diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 8639535abb2..539d28d1149 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -189,6 +189,12 @@ struct __DriverAPIRec { /*@}*/ void (*CopySubBuffer)(__DRIdrawablePrivate *driDrawPriv, int x, int y, int w, int h); + + /** + * See corresponding field in \c __DRIscreenRec. + */ + void (*setTexOffset)(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch); }; diff --git a/src/mesa/drivers/dri/ffb/ffb_tris.c b/src/mesa/drivers/dri/ffb/ffb_tris.c index ca0e514dc0e..9fae8c8283e 100644 --- a/src/mesa/drivers/dri/ffb/ffb_tris.c +++ b/src/mesa/drivers/dri/ffb/ffb_tris.c @@ -138,10 +138,10 @@ static void ffb_translate_vertex(GLcontext *ctx, const ffb_vertex *src, const GLfloat ty = m[13]; const GLfloat tz = m[14]; - dst->win[0] = sx * src->x + tx; - dst->win[1] = sy * src->y + ty; - dst->win[2] = sz * src->z + tz; - dst->win[3] = 1.0; + dst->attrib[FRAG_ATTRIB_WPOS][0] = sx * src->x + tx; + dst->attrib[FRAG_ATTRIB_WPOS][1] = sy * src->y + ty; + dst->attrib[FRAG_ATTRIB_WPOS][2] = sz * src->z + tz; + dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0; dst->color[0] = FFB_UBYTE_FROM_COLOR(src->color[0].red); dst->color[1] = FFB_UBYTE_FROM_COLOR(src->color[0].green); diff --git a/src/mesa/drivers/dri/i915/i830_state.c b/src/mesa/drivers/dri/i915/i830_state.c index 95125190108..f7980201f9a 100644 --- a/src/mesa/drivers/dri/i915/i830_state.c +++ b/src/mesa/drivers/dri/i915/i830_state.c @@ -34,6 +34,8 @@ #include "texmem.h" +#include "drivers/common/driverfuncs.h" + #include "intel_screen.h" #include "intel_batchbuffer.h" @@ -1074,7 +1076,7 @@ void i830InitState( i830ContextPtr i830 ) i830_init_packets( i830 ); - intelInitState( ctx ); + _mesa_init_driver_state(ctx); memcpy( &i830->initial, &i830->state, sizeof(i830->state) ); @@ -1085,8 +1087,3 @@ void i830InitState( i830ContextPtr i830 ) I830_UPLOAD_CTX | I830_UPLOAD_BUFFERS); } - - - - - diff --git a/src/mesa/drivers/dri/i915/i915_fragprog.c b/src/mesa/drivers/dri/i915/i915_fragprog.c index a28c8bb6fc2..702b8788282 100644 --- a/src/mesa/drivers/dri/i915/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915/i915_fragprog.c @@ -857,11 +857,6 @@ static void i915BindProgram( GLcontext *ctx, assert(p->on_hardware == 0); assert(p->params_uptodate == 0); - /* Hack: make sure fog is correctly enabled according to this - * fragment program's fog options. - */ - ctx->Driver.Enable( ctx, GL_FRAGMENT_PROGRAM_ARB, - ctx->FragmentProgram.Enabled ); } } @@ -935,9 +930,6 @@ static void i915ProgramStringNotify( GLcontext *ctx, /* Hack: make sure fog is correctly enabled according to this * fragment program's fog options. */ - ctx->Driver.Enable( ctx, GL_FRAGMENT_PROGRAM_ARB, - ctx->FragmentProgram.Enabled ); - if (p->FragProg.FogOption) { /* add extra instructions to do fog, then turn off FogOption field */ _mesa_append_fog_code(ctx, &p->FragProg); diff --git a/src/mesa/drivers/dri/i915/i915_state.c b/src/mesa/drivers/dri/i915/i915_state.c index 0d5ca32969a..1c4ec747558 100644 --- a/src/mesa/drivers/dri/i915/i915_state.c +++ b/src/mesa/drivers/dri/i915/i915_state.c @@ -36,6 +36,8 @@ #include "texmem.h" +#include "drivers/common/driverfuncs.h" + #include "intel_screen.h" #include "intel_batchbuffer.h" @@ -961,15 +963,8 @@ void i915InitState( i915ContextPtr i915 ) i915_init_packets( i915 ); - intelInitState( ctx ); + _mesa_init_driver_state(ctx); memcpy( &i915->initial, &i915->state, sizeof(i915->state) ); i915->current = &i915->state; } - - - - - - - diff --git a/src/mesa/drivers/dri/i915/i915_texstate.c b/src/mesa/drivers/dri/i915/i915_texstate.c index 3b639e71443..9f0c9491b22 100644 --- a/src/mesa/drivers/dri/i915/i915_texstate.c +++ b/src/mesa/drivers/dri/i915/i915_texstate.c @@ -172,12 +172,8 @@ static void i915LayoutTextureImages( i915ContextPtr i915, t->intel.image[0][i].offset = total_height * pitch; t->intel.image[0][i].internalFormat = baseImage->_BaseFormat; - if (t->intel.image[0][i].image->IsCompressed) - { - if (t->intel.image[0][i].image->Height > 4) - total_height += t->intel.image[0][i].image->Height/4; - else - total_height += 1; + if (t->intel.image[0][i].image->IsCompressed) { + total_height += (t->intel.image[0][i].image->Height + 3) / 4; } else total_height += MAX2(2, t->intel.image[0][i].image->Height); diff --git a/src/mesa/drivers/dri/i915/intel_context.c b/src/mesa/drivers/dri/i915/intel_context.c index e1e7cdb7233..e747fc6991b 100644 --- a/src/mesa/drivers/dri/i915/intel_context.c +++ b/src/mesa/drivers/dri/i915/intel_context.c @@ -766,98 +766,3 @@ void intelCopySubBuffer( __DRIdrawablePrivate *dPriv, fprintf(stderr, "%s: drawable has no context!\n", __FUNCTION__); } } - -void intelInitState( GLcontext *ctx ) -{ - /* Mesa should do this for us: - */ - ctx->Driver.AlphaFunc( ctx, - ctx->Color.AlphaFunc, - ctx->Color.AlphaRef); - - ctx->Driver.BlendColor( ctx, - ctx->Color.BlendColor ); - - ctx->Driver.BlendEquationSeparate( ctx, - ctx->Color.BlendEquationRGB, - ctx->Color.BlendEquationA); - - ctx->Driver.BlendFuncSeparate( ctx, - ctx->Color.BlendSrcRGB, - ctx->Color.BlendDstRGB, - ctx->Color.BlendSrcA, - ctx->Color.BlendDstA); - - ctx->Driver.ColorMask( ctx, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP]); - - ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode ); - ctx->Driver.DepthFunc( ctx, ctx->Depth.Func ); - ctx->Driver.DepthMask( ctx, ctx->Depth.Mask ); - - ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); - ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled ); - ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled ); - ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled ); - ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag ); - ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test ); - ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag ); - ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled ); - ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled ); - ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); - ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); - ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); - ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); - ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE ); - - ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); - ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); - ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); - ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); - ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); - - ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace ); - - { - GLfloat f = (GLfloat)ctx->Light.Model.ColorControl; - ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); - } - - ctx->Driver.LineWidth( ctx, ctx->Line.Width ); - ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp ); - ctx->Driver.PointSize( ctx, ctx->Point.Size ); - ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple ); - ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height ); - ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel ); - ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT, - ctx->Stencil.Function[0], - ctx->Stencil.Ref[0], - ctx->Stencil.ValueMask[0] ); - ctx->Driver.StencilFuncSeparate( ctx, GL_BACK, - ctx->Stencil.Function[1], - ctx->Stencil.Ref[1], - ctx->Stencil.ValueMask[1] ); - ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] ); - ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] ); - ctx->Driver.StencilOpSeparate( ctx, GL_FRONT, - ctx->Stencil.FailFunc[0], - ctx->Stencil.ZFailFunc[0], - ctx->Stencil.ZPassFunc[0]); - ctx->Driver.StencilOpSeparate( ctx, GL_BACK, - ctx->Stencil.FailFunc[1], - ctx->Stencil.ZFailFunc[1], - ctx->Stencil.ZPassFunc[1]); - - - ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] ); -} - - diff --git a/src/mesa/drivers/dri/i915/intel_context.h b/src/mesa/drivers/dri/i915/intel_context.h index 05195e76d65..c48b074cc51 100644 --- a/src/mesa/drivers/dri/i915/intel_context.h +++ b/src/mesa/drivers/dri/i915/intel_context.h @@ -473,7 +473,6 @@ extern void intelSetBackClipRects(intelContextPtr intel); extern void intelSetFrontClipRects(intelContextPtr intel); extern void intelWindowMoved( intelContextPtr intel ); -extern void intelInitState( GLcontext *ctx ); extern const GLubyte *intelGetString( GLcontext *ctx, GLenum name ); diff --git a/src/mesa/drivers/dri/i915/intel_tex.c b/src/mesa/drivers/dri/i915/intel_tex.c index 6012d3e7999..98ddc796724 100644 --- a/src/mesa/drivers/dri/i915/intel_tex.c +++ b/src/mesa/drivers/dri/i915/intel_tex.c @@ -634,18 +634,12 @@ static void intelUploadTexImage( intelContextPtr intel, image->Height); } else if (image->IsCompressed) { - GLuint row_len = image->Width * 2; + GLuint row_len = 0; GLubyte *dst = (GLubyte *)(t->BufAddr + offset); GLubyte *src = (GLubyte *)image->Data; GLuint j; - if (INTEL_DEBUG & DEBUG_TEXTURE) - fprintf(stderr, - "Upload image %dx%dx%d offset %xm row_len %x " - "pitch %x depth_pitch %x\n", - image->Width, image->Height, image->Depth, offset, - row_len, t->Pitch, t->depth_pitch); - + /* must always copy whole blocks (8/16 bytes) */ switch (image->InternalFormat) { case GL_COMPRESSED_RGB_FXT1_3DFX: case GL_COMPRESSED_RGBA_FXT1_3DFX: @@ -653,24 +647,32 @@ static void intelUploadTexImage( intelContextPtr intel, case GL_RGB4_S3TC: case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { - __memcpy(dst, src, row_len ); - src += row_len; - } + row_len = (image->Width * 2 + 7) & ~7; break; case GL_RGBA_S3TC: case GL_RGBA4_S3TC: case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - for (j = 0 ; j < image->Height/4 ; j++, dst += (t->Pitch)) { - __memcpy(dst, src, (image->Width*4) ); - src += image->Width*4; - } + row_len = (image->Width * 4 + 15) & ~15; break; default: fprintf(stderr,"Internal Compressed format not supported %d\n", image->InternalFormat); break; } + + if (INTEL_DEBUG & DEBUG_TEXTURE) + fprintf(stderr, + "Upload image %dx%dx%d offset %xm row_len %x " + "pitch %x depth_pitch %x\n", + image->Width, image->Height, image->Depth, offset, + row_len, t->Pitch, t->depth_pitch); + + if (row_len) { + for (j = 0 ; j < (image->Height + 3)/4 ; j++, dst += (t->Pitch)) { + __memcpy(dst, src, row_len ); + src += row_len; + } + } } /* Time for another vtbl entry: */ diff --git a/src/mesa/drivers/dri/i915tex/i830_reg.h b/src/mesa/drivers/dri/i915tex/i830_reg.h index 24ac5245005..41280bca7ce 100644 --- a/src/mesa/drivers/dri/i915tex/i830_reg.h +++ b/src/mesa/drivers/dri/i915tex/i830_reg.h @@ -575,6 +575,7 @@ #define MT_16BIT_DIB_RGB565_8888 (7<<3) #define MT_32BIT_ARGB8888 (0<<3) /* SURFACE_32BIT */ #define MT_32BIT_ABGR8888 (1<<3) +#define MT_32BIT_XRGB8888 (2<<3) /* XXX: Guess from i915_reg.h */ #define MT_32BIT_BUMP_XLDVDU_8888 (6<<3) #define MT_32BIT_DIB_8888 (7<<3) #define MT_411_YUV411 (0<<3) /* SURFACE_411 */ diff --git a/src/mesa/drivers/dri/i915tex/i830_state.c b/src/mesa/drivers/dri/i915tex/i830_state.c index 812daa65246..3c149e69055 100644 --- a/src/mesa/drivers/dri/i915tex/i830_state.c +++ b/src/mesa/drivers/dri/i915tex/i830_state.c @@ -34,6 +34,8 @@ #include "texmem.h" +#include "drivers/common/driverfuncs.h" + #include "intel_screen.h" #include "intel_batchbuffer.h" #include "intel_fbo.h" @@ -1101,7 +1103,7 @@ i830InitState(struct i830_context *i830) i830_init_packets(i830); - intelInitState(ctx); + _mesa_init_driver_state(ctx); memcpy(&i830->initial, &i830->state, sizeof(i830->state)); diff --git a/src/mesa/drivers/dri/i915tex/i830_texstate.c b/src/mesa/drivers/dri/i915tex/i830_texstate.c index b25ec199f8a..7613b9d2a6f 100644 --- a/src/mesa/drivers/dri/i915tex/i830_texstate.c +++ b/src/mesa/drivers/dri/i915tex/i830_texstate.c @@ -117,7 +117,7 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; struct intel_texture_object *intelObj = intel_texture_object(tObj); struct gl_texture_image *firstImage; - GLuint *state = i830->state.Tex[unit]; + GLuint *state = i830->state.Tex[unit], format, pitch; memset(state, 0, sizeof(state)); @@ -128,7 +128,7 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) i830->state.tex_buffer[unit] = NULL; } - if (!intel_finalize_mipmap_tree(intel, unit)) + if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit)) return GL_FALSE; /* Get first image here, since intelObj->firstLevel will get set in @@ -136,12 +136,34 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) */ firstImage = tObj->Image[0][intelObj->firstLevel]; - dri_bo_reference(intelObj->mt->region->buffer); - i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; - i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, - intelObj-> - firstLevel); + if (intelObj->imageOverride) { + i830->state.tex_buffer[unit] = NULL; + i830->state.tex_offset[unit] = intelObj->textureOffset; + switch (intelObj->depthOverride) { + case 32: + format = MAPSURF_32BIT | MT_32BIT_ARGB8888; + break; + case 24: + default: + format = MAPSURF_32BIT | MT_32BIT_XRGB8888; + break; + case 16: + format = MAPSURF_16BIT | MT_16BIT_RGB565; + break; + } + + pitch = intelObj->pitchOverride; + } else { + dri_bo_reference(intelObj->mt->region->buffer); + i830->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i830->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, + 0, intelObj-> + firstLevel); + + format = translate_texture_format(firstImage->TexFormat->MesaFormat); + pitch = intelObj->mt->pitch * intelObj->mt->cpp; + } state[I830_TEXREG_TM0LI] = (_3DSTATE_LOAD_STATE_IMMEDIATE_2 | (LOAD_TEXTURE_MAP0 << unit) | 4); @@ -152,12 +174,10 @@ i830_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) state[I830_TEXREG_TM0S1] = (((firstImage->Height - 1) << TM0S1_HEIGHT_SHIFT) | - ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | - translate_texture_format(firstImage->TexFormat->MesaFormat)); + ((firstImage->Width - 1) << TM0S1_WIDTH_SHIFT) | format); state[I830_TEXREG_TM0S2] = - (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); + ((((pitch / 4) - 1) << TM0S2_PITCH_SHIFT) | TM0S2_CUBE_FACE_ENA_MASK); { if (tObj->Target == GL_TEXTURE_CUBE_MAP) diff --git a/src/mesa/drivers/dri/i915tex/i915_fragprog.c b/src/mesa/drivers/dri/i915tex/i915_fragprog.c index cbea6092a81..a4b22a0c32c 100644 --- a/src/mesa/drivers/dri/i915tex/i915_fragprog.c +++ b/src/mesa/drivers/dri/i915tex/i915_fragprog.c @@ -849,11 +849,6 @@ i915BindProgram(GLcontext * ctx, GLenum target, struct gl_program *prog) assert(p->on_hardware == 0); assert(p->params_uptodate == 0); - /* Hack: make sure fog is correctly enabled according to this - * fragment program's fog options. - */ - ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, - ctx->FragmentProgram.Enabled); } } @@ -926,9 +921,6 @@ i915ProgramStringNotify(GLcontext * ctx, /* Hack: make sure fog is correctly enabled according to this * fragment program's fog options. */ - ctx->Driver.Enable(ctx, GL_FRAGMENT_PROGRAM_ARB, - ctx->FragmentProgram.Enabled); - if (p->FragProg.FogOption) { /* add extra instructions to do fog, then turn off FogOption field */ _mesa_append_fog_code(ctx, &p->FragProg); diff --git a/src/mesa/drivers/dri/i915tex/i915_state.c b/src/mesa/drivers/dri/i915tex/i915_state.c index d3217fa0caa..e5d8d279936 100644 --- a/src/mesa/drivers/dri/i915tex/i915_state.c +++ b/src/mesa/drivers/dri/i915tex/i915_state.c @@ -36,6 +36,8 @@ #include "texmem.h" +#include "drivers/common/driverfuncs.h" + #include "intel_fbo.h" #include "intel_screen.h" #include "intel_batchbuffer.h" @@ -1005,7 +1007,7 @@ i915InitState(struct i915_context *i915) i915_init_packets(i915); - intelInitState(ctx); + _mesa_init_driver_state(ctx); memcpy(&i915->initial, &i915->state, sizeof(i915->state)); i915->current = &i915->state; diff --git a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c index 2e1600cfdfa..7b761a7b221 100644 --- a/src/mesa/drivers/dri/i915tex/i915_tex_layout.c +++ b/src/mesa/drivers/dri/i915tex/i915_tex_layout.c @@ -113,7 +113,7 @@ i915_miptree_layout(struct intel_mipmap_tree * mt) */ for (level = mt->first_level; level <= MAX2(8, mt->last_level); level++) { - intel_miptree_set_level_info(mt, level, 1, 0, mt->total_height, + intel_miptree_set_level_info(mt, level, depth, 0, mt->total_height, width, height, depth); @@ -161,11 +161,9 @@ i915_miptree_layout(struct intel_mipmap_tree * mt) if (mt->compressed) img_height = MAX2(1, height / 4); else - img_height = MAX2(2, height); + img_height = (MAX2(2, height) + 1) & ~1; mt->total_height += img_height; - mt->total_height += 1; - mt->total_height &= ~1; width = minify(width); height = minify(height); diff --git a/src/mesa/drivers/dri/i915tex/i915_texstate.c b/src/mesa/drivers/dri/i915tex/i915_texstate.c index 31d18759ee5..09684e87b4e 100644 --- a/src/mesa/drivers/dri/i915tex/i915_texstate.c +++ b/src/mesa/drivers/dri/i915tex/i915_texstate.c @@ -122,7 +122,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) struct gl_texture_object *tObj = ctx->Texture.Unit[unit]._Current; struct intel_texture_object *intelObj = intel_texture_object(tObj); struct gl_texture_image *firstImage; - GLuint *state = i915->state.Tex[unit]; + GLuint *state = i915->state.Tex[unit], format, pitch; memset(state, 0, sizeof(state)); @@ -133,7 +133,7 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) i915->state.tex_buffer[unit] = NULL; } - if (!intel_finalize_mipmap_tree(intel, unit)) + if (!intelObj->imageOverride && !intel_finalize_mipmap_tree(intel, unit)) return GL_FALSE; /* Get first image here, since intelObj->firstLevel will get set in @@ -141,26 +141,45 @@ i915_update_tex_unit(struct intel_context *intel, GLuint unit, GLuint ss3) */ firstImage = tObj->Image[0][intelObj->firstLevel]; - dri_bo_reference(intelObj->mt->region->buffer); - i915->state.tex_buffer[unit] = intelObj->mt->region->buffer; + if (intelObj->imageOverride) { + i915->state.tex_buffer[unit] = NULL; + i915->state.tex_offset[unit] = intelObj->textureOffset; - i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, 0, - intelObj-> - firstLevel); + switch (intelObj->depthOverride) { + case 32: + format = MAPSURF_32BIT | MT_32BIT_ARGB8888; + break; + case 24: + default: + format = MAPSURF_32BIT | MT_32BIT_XRGB8888; + break; + case 16: + format = MAPSURF_16BIT | MT_16BIT_RGB565; + break; + } + + pitch = intelObj->pitchOverride; + } else { + dri_bo_reference(intelObj->mt->region->buffer); + i915->state.tex_buffer[unit] = intelObj->mt->region->buffer; + i915->state.tex_offset[unit] = intel_miptree_image_offset(intelObj->mt, + 0, intelObj-> + firstLevel); + + format = translate_texture_format(firstImage->TexFormat->MesaFormat); + pitch = intelObj->mt->pitch * intelObj->mt->cpp; + } state[I915_TEXREG_MS3] = (((firstImage->Height - 1) << MS3_HEIGHT_SHIFT) | - ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | - translate_texture_format(firstImage->TexFormat->MesaFormat) | + ((firstImage->Width - 1) << MS3_WIDTH_SHIFT) | format | MS3_USE_FENCE_REGS); state[I915_TEXREG_MS4] = - (((((intelObj->mt->pitch * intelObj->mt->cpp) / 4) - - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK | - ((((intelObj->lastLevel - - intelObj->firstLevel) * - 4)) << MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - - 1) << MS4_VOLUME_DEPTH_SHIFT)); + ((((pitch / 4) - 1) << MS4_PITCH_SHIFT) | MS4_CUBE_FACE_ENA_MASK | + ((((intelObj->lastLevel - intelObj->firstLevel) * 4)) << + MS4_MAX_LOD_SHIFT) | ((firstImage->Depth - 1) << + MS4_VOLUME_DEPTH_SHIFT)); { diff --git a/src/mesa/drivers/dri/i915tex/i915_vtbl.c b/src/mesa/drivers/dri/i915tex/i915_vtbl.c index 50571b7e83b..2a3ccd01a05 100644 --- a/src/mesa/drivers/dri/i915tex/i915_vtbl.c +++ b/src/mesa/drivers/dri/i915tex/i915_vtbl.c @@ -378,11 +378,13 @@ i915_emit_state(struct intel_context *intel) DRM_BO_FLAG_MEM_TT | DRM_BO_FLAG_READ, state->tex_offset[i]); } - else { + else if (state == &i915->meta) { assert(i == 0); - assert(state == &i915->meta); OUT_BATCH(0); } + else { + OUT_BATCH(state->tex_offset[i]); + } OUT_BATCH(state->Tex[i][I915_TEXREG_MS3]); OUT_BATCH(state->Tex[i][I915_TEXREG_MS4]); diff --git a/src/mesa/drivers/dri/i915tex/intel_context.h b/src/mesa/drivers/dri/i915tex/intel_context.h index d03c4c5dd1c..a55f7d984e3 100644 --- a/src/mesa/drivers/dri/i915tex/intel_context.h +++ b/src/mesa/drivers/dri/i915tex/intel_context.h @@ -91,6 +91,10 @@ struct intel_texture_object * regions will be copied to this region and the old storage freed. */ struct intel_mipmap_tree *mt; + + GLboolean imageOverride; + GLint depthOverride; + GLuint pitchOverride; }; @@ -388,7 +392,6 @@ extern GLboolean intelInitContext(struct intel_context *intel, extern void intelGetLock(struct intel_context *intel, GLuint flags); -extern void intelInitState(GLcontext * ctx); extern void intelFinish(GLcontext * ctx); extern void intelFlush(GLcontext * ctx); diff --git a/src/mesa/drivers/dri/i915tex/intel_screen.c b/src/mesa/drivers/dri/i915tex/intel_screen.c index 0005cfad9d2..4d61407909d 100644 --- a/src/mesa/drivers/dri/i915tex/intel_screen.c +++ b/src/mesa/drivers/dri/i915tex/intel_screen.c @@ -764,7 +764,8 @@ static const struct __DriverAPIRec intelAPI = { .WaitForMSC = driWaitForMSC32, .WaitForSBC = NULL, .SwapBuffersMSC = NULL, - .CopySubBuffer = intelCopySubBuffer + .CopySubBuffer = intelCopySubBuffer, + .setTexOffset = intelSetTexOffset, }; diff --git a/src/mesa/drivers/dri/i915tex/intel_state.c b/src/mesa/drivers/dri/i915tex/intel_state.c index f85d8ef8353..271511037e9 100644 --- a/src/mesa/drivers/dri/i915tex/intel_state.c +++ b/src/mesa/drivers/dri/i915tex/intel_state.c @@ -267,97 +267,3 @@ intelInitStateFuncs(struct dd_function_table *functions) functions->DepthRange = intelDepthRange; functions->ClearColor = intelClearColor; } - - - - -void -intelInitState(GLcontext * ctx) -{ - /* Mesa should do this for us: - */ - ctx->Driver.AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); - - ctx->Driver.BlendColor(ctx, ctx->Color.BlendColor); - - ctx->Driver.BlendEquationSeparate(ctx, - ctx->Color.BlendEquationRGB, - ctx->Color.BlendEquationA); - - ctx->Driver.BlendFuncSeparate(ctx, - ctx->Color.BlendSrcRGB, - ctx->Color.BlendDstRGB, - ctx->Color.BlendSrcA, ctx->Color.BlendDstA); - - ctx->Driver.ColorMask(ctx, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP]); - - ctx->Driver.CullFace(ctx, ctx->Polygon.CullFaceMode); - ctx->Driver.DepthFunc(ctx, ctx->Depth.Func); - ctx->Driver.DepthMask(ctx, ctx->Depth.Mask); - - ctx->Driver.Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); - ctx->Driver.Enable(ctx, GL_BLEND, ctx->Color.BlendEnabled); - ctx->Driver.Enable(ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled); - ctx->Driver.Enable(ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled); - ctx->Driver.Enable(ctx, GL_CULL_FACE, ctx->Polygon.CullFlag); - ctx->Driver.Enable(ctx, GL_DEPTH_TEST, ctx->Depth.Test); - ctx->Driver.Enable(ctx, GL_DITHER, ctx->Color.DitherFlag); - ctx->Driver.Enable(ctx, GL_FOG, ctx->Fog.Enabled); - ctx->Driver.Enable(ctx, GL_LIGHTING, ctx->Light.Enabled); - ctx->Driver.Enable(ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag); - ctx->Driver.Enable(ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag); - ctx->Driver.Enable(ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled); - ctx->Driver.Enable(ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled); - ctx->Driver.Enable(ctx, GL_TEXTURE_1D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_2D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_3D, GL_FALSE); - ctx->Driver.Enable(ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE); - - ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); - ctx->Driver.Fogfv(ctx, GL_FOG_MODE, 0); - ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); - ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); - ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); - - ctx->Driver.FrontFace(ctx, ctx->Polygon.FrontFace); - - { - GLfloat f = (GLfloat) ctx->Light.Model.ColorControl; - ctx->Driver.LightModelfv(ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f); - } - - ctx->Driver.LineWidth(ctx, ctx->Line.Width); - ctx->Driver.LogicOpcode(ctx, ctx->Color.LogicOp); - ctx->Driver.PointSize(ctx, ctx->Point.Size); - ctx->Driver.PolygonStipple(ctx, (const GLubyte *) ctx->PolygonStipple); - ctx->Driver.Scissor(ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height); - ctx->Driver.ShadeModel(ctx, ctx->Light.ShadeModel); - ctx->Driver.StencilFuncSeparate(ctx, GL_FRONT, - ctx->Stencil.Function[0], - ctx->Stencil.Ref[0], - ctx->Stencil.ValueMask[0]); - ctx->Driver.StencilFuncSeparate(ctx, GL_BACK, - ctx->Stencil.Function[1], - ctx->Stencil.Ref[1], - ctx->Stencil.ValueMask[1]); - ctx->Driver.StencilMaskSeparate(ctx, GL_FRONT, ctx->Stencil.WriteMask[0]); - ctx->Driver.StencilMaskSeparate(ctx, GL_BACK, ctx->Stencil.WriteMask[1]); - ctx->Driver.StencilOpSeparate(ctx, GL_FRONT, - ctx->Stencil.FailFunc[0], - ctx->Stencil.ZFailFunc[0], - ctx->Stencil.ZPassFunc[0]); - ctx->Driver.StencilOpSeparate(ctx, GL_BACK, - ctx->Stencil.FailFunc[1], - ctx->Stencil.ZFailFunc[1], - ctx->Stencil.ZPassFunc[1]); - - - /* XXX this isn't really needed */ - ctx->Driver.DrawBuffer(ctx, ctx->Color.DrawBuffer[0]); -} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex.h b/src/mesa/drivers/dri/i915tex/intel_tex.h index 6e9938fe534..b77d7a1d8af 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex.h +++ b/src/mesa/drivers/dri/i915tex/intel_tex.h @@ -135,6 +135,9 @@ void intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, const struct gl_texture_object *texObj, const struct gl_texture_image *texImage); +void intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch); + GLuint intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit); void intel_tex_map_images(struct intel_context *intel, diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_image.c b/src/mesa/drivers/dri/i915tex/intel_tex_image.c index f9c8bc5801f..b15569681a5 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_image.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_image.c @@ -377,6 +377,9 @@ intelTexImage(GLcontext * ctx, assert(!intelObj->mt); } + if (!pixels) + return; + if (!intelObj->mt) { guess_and_alloc_mipmap_tree(intel, intelObj, intelImage); if (!intelObj->mt) { @@ -384,7 +387,6 @@ intelTexImage(GLcontext * ctx, } } - assert(!intelImage->mt); if (intelObj->mt && @@ -666,3 +668,23 @@ intelGetCompressedTexImage(GLcontext *ctx, GLenum target, GLint level, texObj, texImage, 1); } + +void +intelSetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch) +{ + struct intel_context *intel = (struct intel_context*) + ((__DRIcontextPrivate*)pDRICtx->private)->driverPrivate; + struct gl_texture_object *tObj = _mesa_lookup_texture(&intel->ctx, texname); + struct intel_texture_object *intelObj = intel_texture_object(tObj); + + if (!intelObj) + return; + + intelObj->imageOverride = GL_TRUE; + intelObj->depthOverride = depth; + intelObj->pitchOverride = pitch; + + if (offset) + intelObj->textureOffset = offset; +} diff --git a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c index 79d587a1744..0ae4fee1ba0 100644 --- a/src/mesa/drivers/dri/i915tex/intel_tex_validate.c +++ b/src/mesa/drivers/dri/i915tex/intel_tex_validate.c @@ -105,6 +105,8 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) { struct gl_texture_object *tObj = intel->ctx.Texture.Unit[unit]._Current; struct intel_texture_object *intelObj = intel_texture_object(tObj); + int comp_byte = 0; + int cpp; GLuint face, i; GLuint nr_faces = 0; @@ -148,6 +150,12 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) intel_miptree_reference(&intelObj->mt, firstImage->mt); } + if (firstImage->base.IsCompressed) { + comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); + cpp = comp_byte; + } + else cpp = firstImage->base.TexFormat->TexelBytes; + /* Check tree can hold all active levels. Check tree matches * target, imageFormat, etc. * @@ -165,7 +173,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) intelObj->mt->width0 != firstImage->base.Width || intelObj->mt->height0 != firstImage->base.Height || intelObj->mt->depth0 != firstImage->base.Depth || - intelObj->mt->cpp != firstImage->base.TexFormat->TexelBytes || + intelObj->mt->cpp != cpp || intelObj->mt->compressed != firstImage->base.IsCompressed)) { intel_miptree_release(intel, &intelObj->mt); } @@ -174,10 +182,6 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) /* May need to create a new tree: */ if (!intelObj->mt) { - int comp_byte = 0; - - if (firstImage->base.IsCompressed) - comp_byte = intel_compressed_num_bytes(firstImage->base.TexFormat->MesaFormat); intelObj->mt = intel_miptree_create(intel, intelObj->base.Target, firstImage->base.InternalFormat, @@ -186,8 +190,7 @@ intel_finalize_mipmap_tree(struct intel_context *intel, GLuint unit) firstImage->base.Width, firstImage->base.Height, firstImage->base.Depth, - firstImage->base.TexFormat-> - TexelBytes, + cpp, comp_byte); } diff --git a/src/mesa/drivers/dri/i965/brw_draw.c b/src/mesa/drivers/dri/i965/brw_draw.c index c7798b14a93..0c64d7e756d 100644 --- a/src/mesa/drivers/dri/i965/brw_draw.c +++ b/src/mesa/drivers/dri/i965/brw_draw.c @@ -47,6 +47,7 @@ #include "tnl/tnl.h" #include "vbo/vbo_context.h" #include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" diff --git a/src/mesa/drivers/dri/i965/brw_vs_tnl.c b/src/mesa/drivers/dri/i965/brw_vs_tnl.c index 35adc4846a0..b69be350a92 100644 --- a/src/mesa/drivers/dri/i965/brw_vs_tnl.c +++ b/src/mesa/drivers/dri/i965/brw_vs_tnl.c @@ -1154,7 +1154,9 @@ static void build_fog( struct tnl_program *p ) { struct ureg fog = register_output(p, VERT_RESULT_FOGC); struct ureg input; - + GLuint useabs = p->state->fog_source_is_depth && p->state->fog_option && + (p->state->fog_option != FOG_EXP2); + if (p->state->fog_source_is_depth) { input = swizzle1(get_eye_position(p), Z); } @@ -1171,26 +1173,30 @@ static void build_fog( struct tnl_program *p ) emit_op1(p, OPCODE_MOV, fog, 0, id); + if (useabs) { + emit_op1(p, OPCODE_ABS, tmp, 0, input); + } + switch (p->state->fog_option) { case FOG_LINEAR: { - emit_op1(p, OPCODE_ABS, tmp, 0, input); - emit_op3(p, OPCODE_MAD, tmp, 0, tmp, swizzle1(params,X), swizzle1(params,Y)); + emit_op3(p, OPCODE_MAD, tmp, 0, useabs ? tmp : input, + swizzle1(params,X), swizzle1(params,Y)); emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); break; } case FOG_EXP: - emit_op1(p, OPCODE_ABS, tmp, 0, input); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z)); + emit_op2(p, OPCODE_MUL, tmp, 0, useabs ? tmp : input, + swizzle1(params,Z)); emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, ureg_negate(tmp)); break; case FOG_EXP2: emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); + emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, ureg_negate(tmp)); break; } - + release_temp(p, tmp); } else { @@ -1198,7 +1204,7 @@ static void build_fog( struct tnl_program *p ) * * KW: Is it really necessary to do anything in this case? */ - emit_op1(p, OPCODE_MOV, fog, 0, input); + emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, 0, input); } } diff --git a/src/mesa/drivers/dri/i965/intel_context.h b/src/mesa/drivers/dri/i965/intel_context.h index 808512f7fd5..a3c65b66e08 100644 --- a/src/mesa/drivers/dri/i965/intel_context.h +++ b/src/mesa/drivers/dri/i965/intel_context.h @@ -399,7 +399,6 @@ extern GLboolean intelInitContext( struct intel_context *intel, extern void intelGetLock(struct intel_context *intel, GLuint flags); -extern void intelInitState( GLcontext *ctx ); extern void intelFinish( GLcontext *ctx ); extern void intelFlush( GLcontext *ctx ); diff --git a/src/mesa/drivers/dri/i965/intel_state.c b/src/mesa/drivers/dri/i965/intel_state.c index ec6e0465d4a..2e442db6198 100644 --- a/src/mesa/drivers/dri/i965/intel_state.c +++ b/src/mesa/drivers/dri/i965/intel_state.c @@ -197,99 +197,3 @@ void intelInitStateFuncs( struct dd_function_table *functions ) functions->RenderMode = intelRenderMode; functions->ClearColor = intelClearColor; } - - - - -void intelInitState( GLcontext *ctx ) -{ - /* Mesa should do this for us: - */ - ctx->Driver.AlphaFunc( ctx, - ctx->Color.AlphaFunc, - ctx->Color.AlphaRef); - - ctx->Driver.BlendColor( ctx, - ctx->Color.BlendColor ); - - ctx->Driver.BlendEquationSeparate( ctx, - ctx->Color.BlendEquationRGB, - ctx->Color.BlendEquationA); - - ctx->Driver.BlendFuncSeparate( ctx, - ctx->Color.BlendSrcRGB, - ctx->Color.BlendDstRGB, - ctx->Color.BlendSrcA, - ctx->Color.BlendDstA); - - ctx->Driver.ColorMask( ctx, - ctx->Color.ColorMask[RCOMP], - ctx->Color.ColorMask[GCOMP], - ctx->Color.ColorMask[BCOMP], - ctx->Color.ColorMask[ACOMP]); - - ctx->Driver.CullFace( ctx, ctx->Polygon.CullFaceMode ); - ctx->Driver.DepthFunc( ctx, ctx->Depth.Func ); - ctx->Driver.DepthMask( ctx, ctx->Depth.Mask ); - - ctx->Driver.Enable( ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled ); - ctx->Driver.Enable( ctx, GL_BLEND, ctx->Color.BlendEnabled ); - ctx->Driver.Enable( ctx, GL_COLOR_LOGIC_OP, ctx->Color.ColorLogicOpEnabled ); - ctx->Driver.Enable( ctx, GL_COLOR_SUM, ctx->Fog.ColorSumEnabled ); - ctx->Driver.Enable( ctx, GL_CULL_FACE, ctx->Polygon.CullFlag ); - ctx->Driver.Enable( ctx, GL_DEPTH_TEST, ctx->Depth.Test ); - ctx->Driver.Enable( ctx, GL_DITHER, ctx->Color.DitherFlag ); - ctx->Driver.Enable( ctx, GL_FOG, ctx->Fog.Enabled ); - ctx->Driver.Enable( ctx, GL_LIGHTING, ctx->Light.Enabled ); - ctx->Driver.Enable( ctx, GL_LINE_SMOOTH, ctx->Line.SmoothFlag ); - ctx->Driver.Enable( ctx, GL_POLYGON_STIPPLE, ctx->Polygon.StippleFlag ); - ctx->Driver.Enable( ctx, GL_SCISSOR_TEST, ctx->Scissor.Enabled ); - ctx->Driver.Enable( ctx, GL_STENCIL_TEST, ctx->Stencil.Enabled ); - ctx->Driver.Enable( ctx, GL_TEXTURE_1D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_2D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_RECTANGLE_NV, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_3D, GL_FALSE ); - ctx->Driver.Enable( ctx, GL_TEXTURE_CUBE_MAP, GL_FALSE ); - - ctx->Driver.Fogfv( ctx, GL_FOG_COLOR, ctx->Fog.Color ); - ctx->Driver.Fogfv( ctx, GL_FOG_MODE, 0 ); - ctx->Driver.Fogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); - ctx->Driver.Fogfv( ctx, GL_FOG_START, &ctx->Fog.Start ); - ctx->Driver.Fogfv( ctx, GL_FOG_END, &ctx->Fog.End ); - - ctx->Driver.FrontFace( ctx, ctx->Polygon.FrontFace ); - - { - GLfloat f = (GLfloat)ctx->Light.Model.ColorControl; - ctx->Driver.LightModelfv( ctx, GL_LIGHT_MODEL_COLOR_CONTROL, &f ); - } - - ctx->Driver.LineWidth( ctx, ctx->Line.Width ); - ctx->Driver.LogicOpcode( ctx, ctx->Color.LogicOp ); - ctx->Driver.PointSize( ctx, ctx->Point.Size ); - ctx->Driver.PolygonStipple( ctx, (const GLubyte *)ctx->PolygonStipple ); - ctx->Driver.Scissor( ctx, ctx->Scissor.X, ctx->Scissor.Y, - ctx->Scissor.Width, ctx->Scissor.Height ); - ctx->Driver.ShadeModel( ctx, ctx->Light.ShadeModel ); - ctx->Driver.StencilFuncSeparate( ctx, GL_FRONT, - ctx->Stencil.Function[0], - ctx->Stencil.Ref[0], - ctx->Stencil.ValueMask[0] ); - ctx->Driver.StencilFuncSeparate( ctx, GL_BACK, - ctx->Stencil.Function[1], - ctx->Stencil.Ref[1], - ctx->Stencil.ValueMask[1] ); - ctx->Driver.StencilMaskSeparate( ctx, GL_FRONT, ctx->Stencil.WriteMask[0] ); - ctx->Driver.StencilMaskSeparate( ctx, GL_BACK, ctx->Stencil.WriteMask[1] ); - ctx->Driver.StencilOpSeparate( ctx, GL_FRONT, - ctx->Stencil.FailFunc[0], - ctx->Stencil.ZFailFunc[0], - ctx->Stencil.ZPassFunc[0]); - ctx->Driver.StencilOpSeparate( ctx, GL_BACK, - ctx->Stencil.FailFunc[1], - ctx->Stencil.ZFailFunc[1], - ctx->Stencil.ZPassFunc[1]); - - - ctx->Driver.DrawBuffer( ctx, ctx->Color.DrawBuffer[0] ); -} diff --git a/src/mesa/drivers/dri/intel/intel_tex_layout.c b/src/mesa/drivers/dri/intel/intel_tex_layout.c index f3564802171..fcb5cc39068 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_layout.c +++ b/src/mesa/drivers/dri/intel/intel_tex_layout.c @@ -74,7 +74,7 @@ void i945_miptree_layout_2d( struct intel_mipmap_tree *mt ) GLuint img_height; intel_miptree_set_level_info(mt, level, 1, x, y, width, - mt->compressed ? height/4 : height, 1); + height, 1); if (mt->compressed) img_height = MAX2(1, height/4); diff --git a/src/mesa/drivers/dri/mach64/mach64_native_vb.c b/src/mesa/drivers/dri/mach64/mach64_native_vb.c index 81bcf802c71..75cf0e2ed2d 100644 --- a/src/mesa/drivers/dri/mach64/mach64_native_vb.c +++ b/src/mesa/drivers/dri/mach64/mach64_native_vb.c @@ -44,7 +44,7 @@ void TAG(translate_vertex)(GLcontext *ctx, UNVIEWPORT_VARS; CARD32 *p = (CARD32 *)src + 10 - mmesa->vertex_size; - dst->win[3] = 1.0; + dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0; switch ( format ) { case TEX1_VERTEX_FORMAT: @@ -75,17 +75,17 @@ void TAG(translate_vertex)(GLcontext *ctx, dst->attrib[FRAG_ATTRIB_TEX0][1] = LE32_IN_FLOAT( p++ ); #endif dst->attrib[FRAG_ATTRIB_TEX0][3] = 1.0; - dst->win[3] = LE32_IN_FLOAT( p++ ); + dst->attrib[FRAG_ATTRIB_WPOS][3] = LE32_IN_FLOAT( p++ ); case NOTEX_VERTEX_FORMAT: - dst->specular[2] = ((GLubyte *)p)[0]; - dst->specular[1] = ((GLubyte *)p)[1]; - dst->specular[0] = ((GLubyte *)p)[2]; - dst->attrib[FRAG_ATTRIB_FOGC][0] = ((GLubyte *)p)[3]; + dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(((GLubyte *)p)[0]); + dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(((GLubyte *)p)[1]); + dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(((GLubyte *)p)[2]); + dst->attrib[FRAG_ATTRIB_FOGC][0] = ((GLubyte *)p)[3]; /*XXX int->float?*/ p++; case TINY_VERTEX_FORMAT: - dst->win[2] = UNVIEWPORT_Z( LE32_IN( p++ ) ); + dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( LE32_IN( p++ ) ); dst->color[2] = ((GLubyte *)p)[0]; dst->color[1] = ((GLubyte *)p)[1]; @@ -96,8 +96,8 @@ void TAG(translate_vertex)(GLcontext *ctx, { GLuint xy = LE32_IN( p ); - dst->win[0] = UNVIEWPORT_X( (GLfloat)(GLshort)( xy >> 16 ) ); - dst->win[1] = UNVIEWPORT_Y( (GLfloat)(GLshort)( xy & 0xffff ) ); + dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( (GLfloat)(GLshort)( xy >> 16 ) ); + dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( (GLfloat)(GLshort)( xy & 0xffff ) ); } } diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.c b/src/mesa/drivers/dri/r300/r300_cmdbuf.c index d13649ddc0d..0351989b2e4 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.c +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.c @@ -148,7 +148,7 @@ static void r300PrintStateAtom(r300ContextPtr r300, struct r300_state_atom *stat * The caller must have ensured that there is enough space in the command * buffer. */ -static __inline__ void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) +static inline void r300EmitAtoms(r300ContextPtr r300, GLboolean dirty) { struct r300_state_atom *atom; uint32_t *dest; diff --git a/src/mesa/drivers/dri/r300/r300_cmdbuf.h b/src/mesa/drivers/dri/r300/r300_cmdbuf.h index bfb2eda26fe..acb6e38c6df 100644 --- a/src/mesa/drivers/dri/r300/r300_cmdbuf.h +++ b/src/mesa/drivers/dri/r300/r300_cmdbuf.h @@ -52,7 +52,7 @@ extern void r300DestroyCmdBuf(r300ContextPtr r300); * * \param dwords The number of dwords we need to be free on the command buffer */ -static __inline__ void r300EnsureCmdBufSpace(r300ContextPtr r300, +static inline void r300EnsureCmdBufSpace(r300ContextPtr r300, int dwords, const char *caller) { assert(dwords < r300->cmdbuf.size); @@ -68,7 +68,7 @@ static __inline__ void r300EnsureCmdBufSpace(r300ContextPtr r300, * causes state reemission after a flush. This is necessary to ensure * correct hardware state after an unlock. */ -static __inline__ uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300, +static inline uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300, int dwords, const char *caller) { uint32_t *ptr; @@ -80,7 +80,7 @@ static __inline__ uint32_t *r300RawAllocCmdBuf(r300ContextPtr r300, return ptr; } -static __inline__ uint32_t *r300AllocCmdBuf(r300ContextPtr r300, +static inline uint32_t *r300AllocCmdBuf(r300ContextPtr r300, int dwords, const char *caller) { uint32_t *ptr; diff --git a/src/mesa/drivers/dri/r300/r300_context.h b/src/mesa/drivers/dri/r300/r300_context.h index dbcd5d04d6d..01caa617667 100644 --- a/src/mesa/drivers/dri/r300/r300_context.h +++ b/src/mesa/drivers/dri/r300/r300_context.h @@ -80,7 +80,7 @@ typedef struct r300_context *r300ContextPtr; /** * This function takes a float and packs it into a uint32_t */ -static __inline__ uint32_t r300PackFloat32(float fl) +static inline uint32_t r300PackFloat32(float fl) { union { float fl; @@ -97,7 +97,7 @@ static __inline__ uint32_t r300PackFloat32(float fl) * But it works for most things. I'll fix it later if someone * else with a better clue doesn't */ -static __inline__ uint32_t r300PackFloat24(float f) +static inline uint32_t r300PackFloat24(float f) { float mantissa; int exponent; @@ -191,6 +191,8 @@ struct r300_tex_obj { drm_radeon_tex_image_t image[6][RADEON_MAX_TEXTURE_LEVELS]; /* Six, for the cube faces */ + GLboolean image_override; /* Image overridden by GLX_EXT_tfp */ + GLuint pitch; /* this isn't sent to hardware just used in calculations */ /* hardware register values */ /* Note that R200 has 8 registers per texture and R300 only 7 */ diff --git a/src/mesa/drivers/dri/r300/r300_emit.h b/src/mesa/drivers/dri/r300/r300_emit.h index 7be098f743c..4f841a54139 100644 --- a/src/mesa/drivers/dri/r300/r300_emit.h +++ b/src/mesa/drivers/dri/r300/r300_emit.h @@ -59,7 +59,7 @@ #define CP_PACKET0(reg, n) (RADEON_CP_PACKET0 | ((n)<<16) | ((reg)>>2)) -static __inline__ uint32_t cmdpacket0(int reg, int count) +static inline uint32_t cmdpacket0(int reg, int count) { drm_r300_cmd_header_t cmd; @@ -71,7 +71,7 @@ static __inline__ uint32_t cmdpacket0(int reg, int count) return cmd.u; } -static __inline__ uint32_t cmdvpu(int addr, int count) +static inline uint32_t cmdvpu(int addr, int count) { drm_r300_cmd_header_t cmd; @@ -83,7 +83,7 @@ static __inline__ uint32_t cmdvpu(int addr, int count) return cmd.u; } -static __inline__ uint32_t cmdpacket3(int packet) +static inline uint32_t cmdpacket3(int packet) { drm_r300_cmd_header_t cmd; @@ -93,7 +93,7 @@ static __inline__ uint32_t cmdpacket3(int packet) return cmd.u; } -static __inline__ uint32_t cmdcpdelay(unsigned short count) +static inline uint32_t cmdcpdelay(unsigned short count) { drm_r300_cmd_header_t cmd; @@ -103,7 +103,7 @@ static __inline__ uint32_t cmdcpdelay(unsigned short count) return cmd.u; } -static __inline__ uint32_t cmdwait(unsigned char flags) +static inline uint32_t cmdwait(unsigned char flags) { drm_r300_cmd_header_t cmd; @@ -113,7 +113,7 @@ static __inline__ uint32_t cmdwait(unsigned char flags) return cmd.u; } -static __inline__ uint32_t cmdpacify(void) +static inline uint32_t cmdpacify(void) { drm_r300_cmd_header_t cmd; diff --git a/src/mesa/drivers/dri/r300/r300_reg.h b/src/mesa/drivers/dri/r300/r300_reg.h index 0a31f0b9785..e64f5095bc5 100644 --- a/src/mesa/drivers/dri/r300/r300_reg.h +++ b/src/mesa/drivers/dri/r300/r300_reg.h @@ -628,17 +628,11 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * Set INTERP_USED on all interpolators that produce data used by * the fragment program. INTERP_USED looks like a swizzling mask, * but I haven't seen it used that way. - * - * Note: The _UNKNOWN constants are always set in their respective - * register. I don't know if this is necessary. */ #define R300_RS_INTERP_0 0x4310 #define R300_RS_INTERP_1 0x4314 -# define R300_RS_INTERP_1_UNKNOWN 0x40 #define R300_RS_INTERP_2 0x4318 -# define R300_RS_INTERP_2_UNKNOWN 0x80 #define R300_RS_INTERP_3 0x431C -# define R300_RS_INTERP_3_UNKNOWN 0xC0 #define R300_RS_INTERP_4 0x4320 #define R300_RS_INTERP_5 0x4324 #define R300_RS_INTERP_6 0x4328 diff --git a/src/mesa/drivers/dri/r300/r300_render.c b/src/mesa/drivers/dri/r300/r300_render.c index 6cec2bb1ea7..143fe9fd35d 100644 --- a/src/mesa/drivers/dri/r300/r300_render.c +++ b/src/mesa/drivers/dri/r300/r300_render.c @@ -45,6 +45,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * obviously this does work... Further investigation is needed. * * \author Nicolai Haehnle <[email protected]> + * + * \todo Add immediate implementation back? Perhaps this is useful if there are + * no bugs... */ #include "glheader.h" diff --git a/src/mesa/drivers/dri/r300/r300_state.c b/src/mesa/drivers/dri/r300/r300_state.c index e8d67f9aec1..b235baaf10f 100644 --- a/src/mesa/drivers/dri/r300/r300_state.c +++ b/src/mesa/drivers/dri/r300/r300_state.c @@ -65,6 +65,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "drirenderbuffer.h" +extern int future_hw_tcl_on; +extern void _tnl_UpdateFixedFunctionProgram(GLcontext * ctx); + static void r300BlendColor(GLcontext * ctx, const GLfloat cf[4]) { GLubyte color[4]; @@ -462,97 +465,6 @@ static void r300SetDepthState(GLcontext * ctx) r300SetEarlyZState(ctx); } -/** - * Handle glEnable()/glDisable(). - * - * \note Mesa already filters redundant calls to glEnable/glDisable. - */ -static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) -{ - r300ContextPtr r300 = R300_CONTEXT(ctx); - - if (RADEON_DEBUG & DEBUG_STATE) - fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__, - _mesa_lookup_enum_by_nr(cap), - state ? "GL_TRUE" : "GL_FALSE"); - - switch (cap) { - /* Fast track this one... - */ - case GL_TEXTURE_1D: - case GL_TEXTURE_2D: - case GL_TEXTURE_3D: - break; - - case GL_FOG: - R300_STATECHANGE(r300, fogs); - if (state) { - r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FOG_ENABLE; - - ctx->Driver.Fogfv(ctx, GL_FOG_MODE, NULL); - ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, - &ctx->Fog.Density); - ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); - ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); - ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); - } else { - r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FOG_ENABLE; - } - - break; - - case GL_ALPHA_TEST: - r300SetAlphaState(ctx); - break; - - case GL_BLEND: - case GL_COLOR_LOGIC_OP: - r300SetBlendState(ctx); - break; - - case GL_DEPTH_TEST: - r300SetDepthState(ctx); - break; - - case GL_STENCIL_TEST: - if (r300->state.stencil.hw_stencil) { - R300_STATECHANGE(r300, zs); - if (state) { - r300->hw.zs.cmd[R300_ZS_CNTL_0] |= - R300_RB3D_STENCIL_ENABLE; - } else { - r300->hw.zs.cmd[R300_ZS_CNTL_0] &= - ~R300_RB3D_STENCIL_ENABLE; - } - } else { -#if R200_MERGED - FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state); -#endif - } - break; - - case GL_CULL_FACE: - r300UpdateCulling(ctx); - break; - - case GL_POLYGON_OFFSET_POINT: - case GL_POLYGON_OFFSET_LINE: - break; - - case GL_POLYGON_OFFSET_FILL: - R300_STATECHANGE(r300, occlusion_cntl); - if (state) { - r300->hw.occlusion_cntl.cmd[1] |= (3 << 0); - } else { - r300->hw.occlusion_cntl.cmd[1] &= ~(3 << 0); - } - break; - default: - radeonEnable(ctx, cap, state); - return; - } -} - static void r300UpdatePolygonMode(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); @@ -1442,17 +1354,6 @@ union r300_outputs_written { static void r300SetupRSUnit(GLcontext * ctx) { r300ContextPtr r300 = R300_CONTEXT(ctx); - /* I'm still unsure if these are needed */ - GLuint interp_magic[8] = { - 0x00, - R300_RS_INTERP_1_UNKNOWN, - R300_RS_INTERP_2_UNKNOWN, - R300_RS_INTERP_3_UNKNOWN, - 0x00, - 0x00, - 0x00, - 0x00 - }; union r300_outputs_written OutputsWritten; GLuint InputsRead; int fp_reg, high_rr; @@ -1498,8 +1399,7 @@ static void r300SetupRSUnit(GLcontext * ctx) for (i = 0; i < ctx->Const.MaxTextureUnits; i++) { r300->hw.ri.cmd[R300_RI_INTERP_0 + i] = 0 | R300_RS_INTERP_USED - | (in_texcoords << R300_RS_INTERP_SRC_SHIFT) - | interp_magic[i]; + | (in_texcoords << R300_RS_INTERP_SRC_SHIFT); r300->hw.rr.cmd[R300_RR_ROUTE_0 + fp_reg] = 0; if (InputsRead & (FRAG_BIT_TEX0 << i)) { @@ -1812,6 +1712,96 @@ static void r300SetupVertexShader(r300ContextPtr rmesa) } /** + * Enable/Disable states. + * + * \note Mesa already filters redundant calls to this function. + */ +static void r300Enable(GLcontext * ctx, GLenum cap, GLboolean state) +{ + r300ContextPtr r300 = R300_CONTEXT(ctx); + + if (RADEON_DEBUG & DEBUG_STATE) + fprintf(stderr, "%s( %s = %s )\n", __FUNCTION__, + _mesa_lookup_enum_by_nr(cap), + state ? "GL_TRUE" : "GL_FALSE"); + + switch (cap) { + /* Fast track this one... + */ + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + break; + + case GL_FOG: + R300_STATECHANGE(r300, fogs); + if (state) { + r300->hw.fogs.cmd[R300_FOGS_STATE] |= R300_FOG_ENABLE; + + r300Fogfv(ctx, GL_FOG_MODE, NULL); + r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); + r300Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); + r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); + r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); + } else { + r300->hw.fogs.cmd[R300_FOGS_STATE] &= ~R300_FOG_ENABLE; + } + + break; + + case GL_ALPHA_TEST: + r300SetAlphaState(ctx); + break; + + case GL_BLEND: + case GL_COLOR_LOGIC_OP: + r300SetBlendState(ctx); + break; + + case GL_DEPTH_TEST: + r300SetDepthState(ctx); + break; + + case GL_STENCIL_TEST: + if (r300->state.stencil.hw_stencil) { + R300_STATECHANGE(r300, zs); + if (state) { + r300->hw.zs.cmd[R300_ZS_CNTL_0] |= + R300_RB3D_STENCIL_ENABLE; + } else { + r300->hw.zs.cmd[R300_ZS_CNTL_0] &= + ~R300_RB3D_STENCIL_ENABLE; + } + } else { +#if R200_MERGED + FALLBACK(&r300->radeon, RADEON_FALLBACK_STENCIL, state); +#endif + } + break; + + case GL_CULL_FACE: + r300UpdateCulling(ctx); + break; + + case GL_POLYGON_OFFSET_POINT: + case GL_POLYGON_OFFSET_LINE: + break; + + case GL_POLYGON_OFFSET_FILL: + R300_STATECHANGE(r300, occlusion_cntl); + if (state) { + r300->hw.occlusion_cntl.cmd[1] |= (3 << 0); + } else { + r300->hw.occlusion_cntl.cmd[1] &= ~(3 << 0); + } + break; + default: + radeonEnable(ctx, cap, state); + return; + } +} + +/** * Completely recalculates hardware state based on the Mesa state. */ static void r300ResetHwState(r300ContextPtr r300) @@ -1825,12 +1815,6 @@ static void r300ResetHwState(r300ContextPtr r300) if (RADEON_DEBUG & DEBUG_STATE) fprintf(stderr, "%s\n", __FUNCTION__); - /* This is a place to initialize registers which - have bitfields accessed by different functions - and not all bits are used */ - - /* go and compute register values from GL state */ - r300UpdateWindow(ctx); r300ColorMask(ctx, @@ -1860,13 +1844,11 @@ static void r300ResetHwState(r300ContextPtr r300) r300AlphaFunc(ctx, ctx->Color.AlphaFunc, ctx->Color.AlphaRef); r300Enable(ctx, GL_ALPHA_TEST, ctx->Color.AlphaEnabled); - /* Initialize magic registers - TODO : learn what they really do, or get rid of - those we don't have to touch */ if (!has_tcl) r300->hw.vap_cntl.cmd[1] = 0x0014045a; else r300->hw.vap_cntl.cmd[1] = 0x0030045A; //0x0030065a /* Dangerous */ + r300->hw.vte.cmd[1] = R300_VPORT_X_SCALE_ENA | R300_VPORT_X_OFFSET_ENA | R300_VPORT_Y_SCALE_ENA @@ -1895,11 +1877,15 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.unk2220.cmd[3] = r300PackFloat32(1.0); r300->hw.unk2220.cmd[4] = r300PackFloat32(1.0); - /* what about other chips than r300 or rv350??? */ - if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) + /* XXX: Other families? */ + switch (r300->radeon.radeonScreen->chip_family) { + case CHIP_FAMILY_R300: r300->hw.unk2288.cmd[1] = R300_2288_R300; - else + break; + default: r300->hw.unk2288.cmd[1] = R300_2288_RV350; + break; + } r300->hw.gb_enable.cmd[1] = R300_GB_POINT_STUFF_ENABLE | R300_GB_LINE_STUFF_ENABLE @@ -1907,26 +1893,35 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_0] = 0x66666666; r300->hw.gb_misc.cmd[R300_GB_MISC_MSPOS_1] = 0x06666666; - if ((r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R300) || - (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R350)) - r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = - R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_R300 | - R300_GB_TILE_SIZE_16; - else if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_RV410) - r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = - R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_RV410 | - R300_GB_TILE_SIZE_16; - else if (r300->radeon.radeonScreen->chip_family == CHIP_FAMILY_R420) - r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = - R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_R420 | - R300_GB_TILE_SIZE_16; - else - r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = - R300_GB_TILE_ENABLE | R300_GB_TILE_PIPE_COUNT_RV300 | - R300_GB_TILE_SIZE_16; - /* set to 0 when fog is disabled? */ + + /* XXX: Other families? */ + r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] = + R300_GB_TILE_ENABLE | R300_GB_TILE_SIZE_16; + switch (r300->radeon.radeonScreen->chip_family) { + case CHIP_FAMILY_R300: + case CHIP_FAMILY_R350: + r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |= + R300_GB_TILE_PIPE_COUNT_R300; + break; + case CHIP_FAMILY_RV410: + r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |= + R300_GB_TILE_PIPE_COUNT_RV410; + break; + case CHIP_FAMILY_R420: + r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |= + R300_GB_TILE_PIPE_COUNT_R420; + break; + default: + r300->hw.gb_misc.cmd[R300_GB_MISC_TILE_CONFIG] |= + R300_GB_TILE_PIPE_COUNT_RV300; + break; + } + + /* XXX: set to 0 when fog is disabled? */ r300->hw.gb_misc.cmd[R300_GB_MISC_SELECT] = R300_GB_FOG_SELECT_1_1_W; - r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = R300_AA_DISABLE; /* No antialiasing */ + + /* XXX: Enable anti-aliasing? */ + r300->hw.gb_misc.cmd[R300_GB_MISC_AA_CONFIG] = R300_AA_DISABLE; r300->hw.unk4200.cmd[1] = r300PackFloat32(0.0); r300->hw.unk4200.cmd[2] = r300PackFloat32(0.0); @@ -1977,12 +1972,12 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.unk46A4.cmd[5] = 0x00000001; r300Enable(ctx, GL_FOG, ctx->Fog.Enabled); - ctx->Driver.Fogfv(ctx, GL_FOG_MODE, NULL); - ctx->Driver.Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); - ctx->Driver.Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); - ctx->Driver.Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); - ctx->Driver.Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); - ctx->Driver.Fogfv(ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL); + r300Fogfv(ctx, GL_FOG_MODE, NULL); + r300Fogfv(ctx, GL_FOG_DENSITY, &ctx->Fog.Density); + r300Fogfv(ctx, GL_FOG_START, &ctx->Fog.Start); + r300Fogfv(ctx, GL_FOG_END, &ctx->Fog.End); + r300Fogfv(ctx, GL_FOG_COLOR, ctx->Fog.Color); + r300Fogfv(ctx, GL_FOG_COORDINATE_SOURCE_EXT, NULL); r300->hw.at.cmd[R300_AT_UNKNOWN] = 0; r300->hw.unk4BD8.cmd[1] = 0; @@ -2047,7 +2042,7 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.zb.cmd[R300_ZB_PITCH] = r300->radeon.radeonScreen->depthPitch; if (r300->radeon.sarea->tiling_enabled) { - /* Turn off when clearing buffers ? */ + /* XXX: Turn off when clearing buffers ? */ r300->hw.zb.cmd[R300_ZB_PITCH] |= R300_DEPTH_TILE_ENABLE; if (ctx->Visual.depthBits == 24) @@ -2070,14 +2065,10 @@ static void r300ResetHwState(r300ContextPtr r300) r300->hw.vps.cmd[R300_VPS_POINTSIZE] = r300PackFloat32(1.0); r300->hw.vps.cmd[R300_VPS_ZERO_3] = 0; } -//END: TODO + r300->hw.all_dirty = GL_TRUE; } - -extern void _tnl_UpdateFixedFunctionProgram(GLcontext * ctx); - -extern int future_hw_tcl_on; void r300UpdateShaders(r300ContextPtr rmesa) { GLcontext *ctx; diff --git a/src/mesa/drivers/dri/r300/r300_tex.h b/src/mesa/drivers/dri/r300/r300_tex.h index 74fa08e97d9..f67a8e6ba65 100644 --- a/src/mesa/drivers/dri/r300/r300_tex.h +++ b/src/mesa/drivers/dri/r300/r300_tex.h @@ -35,6 +35,10 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #ifndef __r300_TEX_H__ #define __r300_TEX_H__ +extern void r300SetTexOffset(__DRIcontext *pDRICtx, GLint texname, + unsigned long long offset, GLint depth, + GLuint pitch); + extern void r300UpdateTextureState(GLcontext * ctx); extern int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, diff --git a/src/mesa/drivers/dri/r300/r300_texmem.c b/src/mesa/drivers/dri/r300/r300_texmem.c index 60e7dc967b1..e2e8355d275 100644 --- a/src/mesa/drivers/dri/r300/r300_texmem.c +++ b/src/mesa/drivers/dri/r300/r300_texmem.c @@ -508,6 +508,9 @@ int r300UploadTexImages(r300ContextPtr rmesa, r300TexObjPtr t, GLuint face) { const int numLevels = t->base.lastLevel - t->base.firstLevel + 1; + if (t->image_override) + return 0; + if (RADEON_DEBUG & (DEBUG_TEXTURE | DEBUG_IOCTL)) { fprintf(stderr, "%s( %p, %p ) sz=%d lvls=%d-%d\n", __FUNCTION__, (void *)rmesa->radeon.glCtx, (void *)t->base.tObj, diff --git a/src/mesa/drivers/dri/r300/r300_texstate.c b/src/mesa/drivers/dri/r300/r300_texstate.c index 705502ebf2b..eeaba584df8 100644 --- a/src/mesa/drivers/dri/r300/r300_texstate.c +++ b/src/mesa/drivers/dri/r300/r300_texstate.c @@ -40,6 +40,8 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "context.h" #include "macros.h" #include "texformat.h" +#include "teximage.h" +#include "texobj.h" #include "enums.h" #include "r300_context.h" @@ -52,7 +54,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define VALID_FORMAT(f) ( ((f) <= MESA_FORMAT_RGBA_DXT5 \ || ((f) >= MESA_FORMAT_RGBA_FLOAT32 && \ (f) <= MESA_FORMAT_INTENSITY_FLOAT16)) \ - && tx_table_le[f].flag ) + && tx_table[f].flag ) #define _ASSIGN(entry, format) \ [ MESA_FORMAT_ ## entry ] = { format, 0, 1} @@ -66,58 +68,22 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * identically. -- paulus */ -static const struct { +static const struct tx_table { GLuint format, filter, flag; -} tx_table_be[] = { - /* *INDENT-OFF* */ - _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)), - _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)), - _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)), - _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)), - _ASSIGN(RGB888, 0xffffffff), - _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), - _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), - _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)), - _ASSIGN(ARGB4444_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)), - _ASSIGN(ARGB1555, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)), - _ASSIGN(ARGB1555_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5)), - _ASSIGN(AL88, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)), - _ASSIGN(AL88_REV, R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8)), - _ASSIGN(RGB332, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z3Y3X2)), - _ASSIGN(A8, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, X8)), - _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)), - _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)), - _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)), - _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE ), - _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE), - _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)), - _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)), - _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)), - _ASSIGN(RGBA_DXT5, R300_EASY_TX_FORMAT(Y, Z, W, X, DXT5)), - _ASSIGN(RGBA_FLOAT32, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R32G32B32A32)), - _ASSIGN(RGBA_FLOAT16, R300_EASY_TX_FORMAT(Z, Y, X, W, FL_R16G16B16A16)), - _ASSIGN(RGB_FLOAT32, 0xffffffff), - _ASSIGN(RGB_FLOAT16, 0xffffffff), - _ASSIGN(ALPHA_FLOAT32, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I32)), - _ASSIGN(ALPHA_FLOAT16, R300_EASY_TX_FORMAT(ZERO, ZERO, ZERO, X, FL_I16)), - _ASSIGN(LUMINANCE_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I32)), - _ASSIGN(LUMINANCE_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, ONE, FL_I16)), - _ASSIGN(LUMINANCE_ALPHA_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I32A32)), - _ASSIGN(LUMINANCE_ALPHA_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, Y, FL_I16A16)), - _ASSIGN(INTENSITY_FLOAT32, R300_EASY_TX_FORMAT(X, X, X, X, FL_I32)), - _ASSIGN(INTENSITY_FLOAT16, R300_EASY_TX_FORMAT(X, X, X, X, FL_I16)), - /* *INDENT-ON* */ -}; - -static const struct { - GLuint format, filter, flag; -} tx_table_le[] = { +} tx_table[] = { /* *INDENT-OFF* */ +#ifdef MESA_LITTLE_ENDIAN _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)), _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)), _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)), _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)), - _ASSIGN(RGB888, 0xffffffff), +#else + _ASSIGN(RGBA8888, R300_EASY_TX_FORMAT(Z, Y, X, W, W8Z8Y8X8)), + _ASSIGN(RGBA8888_REV, R300_EASY_TX_FORMAT(Y, Z, W, X, W8Z8Y8X8)), + _ASSIGN(ARGB8888, R300_EASY_TX_FORMAT(W, Z, Y, X, W8Z8Y8X8)), + _ASSIGN(ARGB8888_REV, R300_EASY_TX_FORMAT(X, Y, Z, W, W8Z8Y8X8)), +#endif + _ASSIGN(RGB888, R300_EASY_TX_FORMAT(X, Y, Z, ONE, W8Z8Y8X8)), _ASSIGN(RGB565, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), _ASSIGN(RGB565_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5)), _ASSIGN(ARGB4444, R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4)), @@ -131,8 +97,8 @@ static const struct { _ASSIGN(L8, R300_EASY_TX_FORMAT(X, X, X, ONE, X8)), _ASSIGN(I8, R300_EASY_TX_FORMAT(X, X, X, X, X8)), _ASSIGN(CI8, R300_EASY_TX_FORMAT(X, X, X, X, X8)), - _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE ), - _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8)|R300_TX_FORMAT_YUV_MODE), + _ASSIGN(YCBCR, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE), + _ASSIGN(YCBCR_REV, R300_EASY_TX_FORMAT(X, Y, Z, ONE, G8R8_G8B8) | R300_TX_FORMAT_YUV_MODE), _ASSIGN(RGB_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, ONE, DXT1)), _ASSIGN(RGBA_DXT1, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT1)), _ASSIGN(RGBA_DXT3, R300_EASY_TX_FORMAT(X, Y, Z, W, DXT3)), @@ -178,23 +144,11 @@ static void r300SetTexImages(r300ContextPtr rmesa, /* Set the hardware texture format */ - if (VALID_FORMAT(baseImage->TexFormat->MesaFormat)) { - if (_mesa_little_endian()) { - t->format = - tx_table_le[baseImage->TexFormat->MesaFormat]. - format; - t->filter |= - tx_table_le[baseImage->TexFormat->MesaFormat]. - filter; - } else { - t->format = - tx_table_be[baseImage->TexFormat->MesaFormat]. - format; - t->filter |= - tx_table_be[baseImage->TexFormat->MesaFormat]. - filter; - } - } else { + if (!t->image_override + && VALID_FORMAT(baseImage->TexFormat->MesaFormat)) { + t->format = tx_table[baseImage->TexFormat->MesaFormat].format; + t->filter |= tx_table[baseImage->TexFormat->MesaFormat].filter; + } else if (!t->image_override) { _mesa_problem(NULL, "unexpected texture format in %s", __FUNCTION__); return; @@ -382,9 +336,10 @@ static void r300SetTexImages(r300ContextPtr rmesa, t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width * texelBytes) + 63) & ~(63); t->size |= R300_TX_SIZE_TXPITCH_EN; - t->pitch_reg = - (((tObj->Image[0][t->base.firstLevel]->Width) + - align) & ~align) - 1; + if (!t->image_override) + t->pitch_reg = + (((tObj->Image[0][t->base.firstLevel]->Width) + + align) & ~align) - 1; } else { t->pitch = ((tObj->Image[0][t->base.firstLevel]->Width * @@ -411,9 +366,10 @@ static GLboolean r300EnableTexture2D(GLcontext * ctx, int unit) if (t->base.dirty_images[0]) { R300_FIREVERTICES(rmesa); + r300SetTexImages(rmesa, tObj); r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0); - if (!t->base.memBlock) + if (!t->base.memBlock && !t->image_override) return GL_FALSE; } @@ -492,9 +448,11 @@ static GLboolean r300EnableTextureRect(GLcontext * ctx, int unit) if (t->base.dirty_images[0]) { R300_FIREVERTICES(rmesa); + r300SetTexImages(rmesa, tObj); r300UploadTexImages(rmesa, (r300TexObjPtr) tObj->DriverData, 0); - if (!t->base.memBlock && !rmesa->prefer_gart_client_texturing) + if (!t->base.memBlock && !t->image_override && + !rmesa->prefer_gart_client_texturing) return GL_FALSE; } @@ -534,6 +492,52 @@ static GLboolean r300UpdateTexture(GLcontext * ctx, int unit) return !t->border_fallback; } +void r300SetTexOffset(__DRIcontext * pDRICtx, GLint texname, + unsigned long long offset, GLint depth, GLuint pitch) +{ + r300ContextPtr rmesa = + (r300ContextPtr) ((__DRIcontextPrivate *) pDRICtx->private)-> + driverPrivate; + struct gl_texture_object *tObj = + _mesa_lookup_texture(rmesa->radeon.glCtx, texname); + r300TexObjPtr t; + int idx; + + if (!tObj) + return; + + t = (r300TexObjPtr) tObj->DriverData; + + t->image_override = GL_TRUE; + + if (!offset) + return; + + t->offset = offset; + t->pitch_reg = pitch; + + switch (depth) { + case 32: + idx = 2; + t->pitch_reg /= 4; + break; + case 24: + default: + idx = 4; + t->pitch_reg /= 4; + break; + case 16: + idx = 5; + t->pitch_reg /= 2; + break; + } + + t->pitch_reg--; + + t->format = tx_table[idx].format; + t->filter |= tx_table[idx].filter; +} + static GLboolean r300UpdateTextureUnit(GLcontext * ctx, int unit) { struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index 1d90ade2ed1..16dddf6557d 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -222,7 +222,7 @@ static unsigned long t_src_class(enum register_file file) } } -static __inline unsigned long t_swizzle(GLubyte swizzle) +static inline unsigned long t_swizzle(GLubyte swizzle) { /* this is in fact a NOP as the Mesa SWIZZLE_* are all identical to VSF_IN_COMPONENT_* */ return swizzle; diff --git a/src/mesa/drivers/dri/radeon/radeon_screen.c b/src/mesa/drivers/dri/radeon/radeon_screen.c index b476864d035..aa7fb633dd1 100644 --- a/src/mesa/drivers/dri/radeon/radeon_screen.c +++ b/src/mesa/drivers/dri/radeon/radeon_screen.c @@ -56,6 +56,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #elif RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) #include "r300_context.h" #include "r300_fragprog.h" +#include "r300_tex.h" #include "radeon_span.h" #endif @@ -952,6 +953,9 @@ static struct __DriverAPIRec radeonAPI = { .WaitForSBC = NULL, .SwapBuffersMSC = NULL, .CopySubBuffer = radeonCopySubBuffer, +#if RADEON_COMMON && defined(RADEON_COMMON_FOR_R300) + .setTexOffset = r300SetTexOffset, +#endif }; #else static const struct __DriverAPIRec r200API = { diff --git a/src/mesa/drivers/dri/s3v/s3v_tritmp.h b/src/mesa/drivers/dri/s3v/s3v_tritmp.h index 696fc02250f..2321bd414ff 100644 --- a/src/mesa/drivers/dri/s3v/s3v_tritmp.h +++ b/src/mesa/drivers/dri/s3v/s3v_tritmp.h @@ -43,12 +43,12 @@ #define SORT_LINE_VERT() \ do { \ - if(v[0].win[1] <= v[1].win[1]) { \ + if(v[0].attrib[FRAG_ATTRIB_WPOS][1] <= v[1].attrib[FRAG_ATTRIB_WPOS][1]) { \ \ idx[0] = 0; \ idx[1] = 1; \ \ - } else if (v[0].win[1] > v[1].win[1]) { \ + } else if (v[0].attrib[FRAG_ATTRIB_WPOS][1] > v[1].attrib[FRAG_ATTRIB_WPOS][1]) { \ \ idx[0] = 1; \ idx[1] = 0; \ @@ -58,19 +58,19 @@ do { \ #define SET_LINE_VERT() \ do { \ - x[0] = (v[idx[0]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \ - y[0] = fy[0] = dPriv->h - v[idx[0]].win[1]; \ - z[0] = (v[idx[0]].win[2]) * 1024.0f * 32.0f; /* 0x8000; */ \ + x[0] = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][0] * 1024.0f * 1024.0f); /* 0x100000 */ \ + y[0] = fy[0] = dPriv->h - v[idx[0]].attrib[FRAG_ATTRIB_WPOS][1]; \ + z[0] = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][2]) * 1024.0f * 32.0f; /* 0x8000; */ \ \ - x[1] = (v[idx[1]].win[0] * 1024.0f * 1024.0f); /* 0x100000 */ \ - y[1] = dPriv->h - v[idx[1]].win[1]; \ - z[1] = (v[idx[1]].win[2]) * 1024.0f * 32.0f; /* 0x8000 */ \ + x[1] = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][0] * 1024.0f * 1024.0f); /* 0x100000 */ \ + y[1] = dPriv->h - v[idx[1]].attrib[FRAG_ATTRIB_WPOS][1]; \ + z[1] = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][2]) * 1024.0f * 32.0f; /* 0x8000 */ \ } while(0) #define SET_LINE_XY() \ do { \ - tmp = v[idx[0]].win[0]; \ - tmp2 = v[idx[1]].win[0]; \ + tmp = v[idx[0]].attrib[FRAG_ATTRIB_WPOS][0]; \ + tmp2 = v[idx[1]].attrib[FRAG_ATTRIB_WPOS][0]; \ \ dx01 = x[0] - x[1]; \ dy01 = y[0] - y[1]; \ @@ -265,7 +265,7 @@ do { \ #define SORT_VERT() \ do { \ for (i=0; i<3; i++) \ - fy[i] = v[i].win[1]; \ + fy[i] = v[i].attrib[FRAG_ATTRIB_WPOS][1]; \ \ if (fy[1] > fy[0]) { /* (fy[1] > fy[0]) */ \ \ @@ -305,9 +305,9 @@ do { \ do { \ for (i=0; i<3; i++) \ { \ - x[i] = ((v[idx[i]].win[0]) * /* 0x100000*/ 1024.0 * 1024.0); \ - y[i] = fy[i] = (dPriv->h - v[idx[i]].win[1]); \ - z[i] = ((v[idx[i]].win[2]) * /* 0x8000 */ 1024.0 * 32.0); \ + x[i] = ((v[idx[i]].attrib[FRAG_ATTRIB_WPOS][0]) * /* 0x100000*/ 1024.0 * 1024.0); \ + y[i] = fy[i] = (dPriv->h - v[idx[i]].attrib[FRAG_ATTRIB_WPOS][1]); \ + z[i] = ((v[idx[i]].attrib[FRAG_ATTRIB_WPOS][2]) * /* 0x8000 */ 1024.0 * 32.0); \ } \ \ ydiff = fy[0] - (float)y[0]; \ @@ -420,9 +420,9 @@ do { \ v2 = (v[idx[2]].attrib[FRAG_ATTRIB_TEX0][1] \ * (GLfloat)(t->globj->Image[0][0]->Height) * 256.0); \ \ - w0 = (v[idx[0]].win[3]); \ - w1 = (v[idx[1]].win[3]); \ - w2 = (v[idx[2]].win[3]); \ + w0 = (v[idx[0]].attrib[FRAG_ATTRIB_WPOS][3]); \ + w1 = (v[idx[1]].attrib[FRAG_ATTRIB_WPOS][3]); \ + w2 = (v[idx[2]].attrib[FRAG_ATTRIB_WPOS][3]); \ } while (0) #define SET_BASEUV() \ @@ -732,8 +732,8 @@ DEBUG(("***\n")); #if (IND & S3V_RAST_CULL_BIT) cull = vmesa->backface_sign * - ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) + - (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0])); + ((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) + + (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0])); if (cull < vmesa->cull_zero /* -0.02f */) return; #endif @@ -842,8 +842,8 @@ static void TAG(s3v_quad)( s3vContextPtr vmesa, #if (IND & S3V_RAST_CULL_BIT) cull = vmesa->backface_sign * - ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) + - (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0])); + ((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) + + (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0])); if (cull < vmesa->cull_zero /* -0.02f */) goto second; /* return; */ /* (a) */ #endif @@ -897,8 +897,8 @@ second: #if (IND & S3V_RAST_CULL_BIT) cull = vmesa->backface_sign * - ((v[1].win[0] - v[0].win[0]) * (v[0].win[1] - v[2].win[1]) + - (v[1].win[1] - v[0].win[1]) * (v[2].win[0] - v[0].win[0])); + ((v[1].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0]) * (v[0].attrib[FRAG_ATTRIB_WPOS][1] - v[2].attrib[FRAG_ATTRIB_WPOS][1]) + + (v[1].attrib[FRAG_ATTRIB_WPOS][1] - v[0].attrib[FRAG_ATTRIB_WPOS][1]) * (v[2].attrib[FRAG_ATTRIB_WPOS][0] - v[0].attrib[FRAG_ATTRIB_WPOS][0])); if (cull < /* -0.02f */ vmesa->cull_zero) return; #endif diff --git a/src/mesa/drivers/dri/tdfx/tdfx_tris.c b/src/mesa/drivers/dri/tdfx/tdfx_tris.c index 4ba2f40b9e8..96f9ae27fc1 100644 --- a/src/mesa/drivers/dri/tdfx/tdfx_tris.c +++ b/src/mesa/drivers/dri/tdfx/tdfx_tris.c @@ -142,10 +142,10 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst) tdfxContextPtr fxMesa = TDFX_CONTEXT(ctx); if (fxMesa->vertexFormat == TDFX_LAYOUT_TINY) { - dst->win[0] = src->x - fxMesa->x_offset; - dst->win[1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); - dst->win[2] = src->z; - dst->win[3] = 1.0; + dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset; + dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); + dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z; + dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0; dst->color[0] = src->color[2]; dst->color[1] = src->color[1]; @@ -155,10 +155,10 @@ tdfx_translate_vertex( GLcontext *ctx, const tdfxVertex *src, SWvertex *dst) else { GLfloat w = 1.0 / src->rhw; - dst->win[0] = src->x - fxMesa->x_offset; - dst->win[1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); - dst->win[2] = src->z; - dst->win[3] = src->rhw; + dst->attrib[FRAG_ATTRIB_WPOS][0] = src->x - fxMesa->x_offset; + dst->attrib[FRAG_ATTRIB_WPOS][1] = src->y - (fxMesa->screen_height - fxMesa->height - fxMesa->y_offset); + dst->attrib[FRAG_ATTRIB_WPOS][2] = src->z; + dst->attrib[FRAG_ATTRIB_WPOS][3] = src->rhw; dst->color[0] = src->color[2]; dst->color[1] = src->color[1]; diff --git a/src/mesa/drivers/x11/fakeglx.c b/src/mesa/drivers/x11/fakeglx.c index 86a4deabc67..1587df66bcd 100644 --- a/src/mesa/drivers/x11/fakeglx.c +++ b/src/mesa/drivers/x11/fakeglx.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -78,6 +78,7 @@ "GLX_MESA_pixmap_colormap " \ "GLX_MESA_release_buffers " \ "GLX_ARB_get_proc_address " \ + "GLX_EXT_texture_from_pixmap " \ "GLX_EXT_visual_info " \ "GLX_EXT_visual_rating " \ /*"GLX_SGI_video_sync "*/ \ @@ -1223,6 +1224,30 @@ choose_visual( Display *dpy, int screen, const int *list, GLboolean fbConfig ) /* ignore */ break; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + parselist++; /*skip*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + parselist++; + if (*parselist & ~(GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT)) { + /* invalid bit */ + return NULL; + } + break; + case GLX_Y_INVERTED_EXT: + parselist++; /*skip*/ + break; +#endif + case None: /* end of list */ break; @@ -1878,6 +1903,27 @@ get_config( XMesaVisual xmvis, int attrib, int *value, GLboolean fbconfig ) *value = xmvis->visinfo->visualid; break; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_BIND_TO_TEXTURE_RGB_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_RGBA_EXT: + /* XXX review */ + *value = xmvis->mesa_visual.alphaBits > 0 ? True : False; + break; + case GLX_BIND_TO_MIPMAP_TEXTURE_EXT: + *value = True; /*XXX*/ + break; + case GLX_BIND_TO_TEXTURE_TARGETS_EXT: + *value = (GLX_TEXTURE_1D_BIT_EXT | + GLX_TEXTURE_2D_BIT_EXT | + GLX_TEXTURE_RECTANGLE_BIT_EXT); /*XXX*/ + break; + case GLX_Y_INVERTED_EXT: + *value = True; /*XXX*/ + break; +#endif + default: return GLX_BAD_ATTRIBUTE; } @@ -2145,16 +2191,102 @@ Fake_glXCreatePixmap( Display *dpy, GLXFBConfig config, Pixmap pixmap, { XMesaVisual v = (XMesaVisual) config; XMesaBuffer b; - - (void) dpy; - (void) config; - (void) pixmap; - (void) attribList; /* Ignored in GLX 1.3 */ + const int *attr; + int target = 0, format = 0, mipmap = 0; + int value; if (!dpy || !config || !pixmap) return 0; - b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + for (attr = attribList; *attr; attr++) { + switch (*attr) { + case GLX_TEXTURE_FORMAT_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_FORMAT_NONE_EXT: + case GLX_TEXTURE_FORMAT_RGB_EXT: + case GLX_TEXTURE_FORMAT_RGBA_EXT: + format = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_TEXTURE_TARGET_EXT: + attr++; + switch (*attr) { + case GLX_TEXTURE_1D_EXT: + case GLX_TEXTURE_2D_EXT: + case GLX_TEXTURE_RECTANGLE_EXT: + target = *attr; + break; + default: + /* error */ + return 0; + } + break; + case GLX_MIPMAP_TEXTURE_EXT: + attr++; + if (*attr) + mipmap = 1; + break; + default: + /* error */ + return 0; + } + } + + if (format == GLX_TEXTURE_FORMAT_RGB_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGB_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + else if (format == GLX_TEXTURE_FORMAT_RGBA_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_RGBA_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (mipmap) { + if (get_config(v, GLX_BIND_TO_MIPMAP_TEXTURE_EXT, + &value, GL_TRUE) != Success + || !value) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_1D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_1D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + else if (target == GLX_TEXTURE_2D_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_2D_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + if (target == GLX_TEXTURE_RECTANGLE_EXT) { + if (get_config(v, GLX_BIND_TO_TEXTURE_TARGETS_EXT, + &value, GL_TRUE) != Success + || (value & GLX_TEXTURE_RECTANGLE_BIT_EXT) == 0) { + return 0; /* error! */ + } + } + + if (format || target || mipmap) { + /* texture from pixmap */ + b = XMesaCreatePixmapTextureBuffer(v, pixmap, 0, format, target, mipmap); + } + else { + b = XMesaCreatePixmapBuffer( v, pixmap, 0 ); + } if (!b) { return 0; } @@ -2260,8 +2392,20 @@ Fake_glXQueryDrawable( Display *dpy, GLXDrawable draw, int attribute, case GLX_FBCONFIG_ID: *value = xmbuf->xm_visual->visinfo->visualid; return; +#ifdef GLX_EXT_texture_from_pixmap + case GLX_TEXTURE_FORMAT_EXT: + *value = xmbuf->TextureFormat; + break; + case GLX_TEXTURE_TARGET_EXT: + *value = xmbuf->TextureTarget; + break; + case GLX_MIPMAP_TEXTURE_EXT: + *value = xmbuf->TextureMipmap; + break; +#endif + default: - return; /* GLX_BAD_ATTRIBUTE? */ + return; /* raise BadValue error */ } } @@ -2854,6 +2998,26 @@ Fake_glXGetAGPOffsetMESA( const GLvoid *pointer ) } +/*** GLX_EXT_texture_from_pixmap ***/ + +static void +Fake_glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaBindTexImage(dpy, b, buffer, attrib_list); +} + +static void +Fake_glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +{ + XMesaBuffer b = XMesaFindBuffer(dpy, drawable); + if (b) + XMesaReleaseTexImage(dpy, b, buffer); +} + + /* silence warning */ extern struct _glxapi_table *_mesa_GetGLXDispatchTable(void); @@ -3009,5 +3173,9 @@ _mesa_GetGLXDispatchTable(void) /*** GLX_MESA_agp_offset ***/ glx.GetAGPOffsetMESA = Fake_glXGetAGPOffsetMESA; + /*** GLX_EXT_texture_from_pixmap ***/ + glx.BindTexImageEXT = Fake_glXBindTexImageEXT; + glx.ReleaseTexImageEXT = Fake_glXReleaseTexImageEXT; + return &glx; } diff --git a/src/mesa/drivers/x11/glxapi.c b/src/mesa/drivers/x11/glxapi.c index 973f3940451..5f11c90c13c 100644 --- a/src/mesa/drivers/x11/glxapi.c +++ b/src/mesa/drivers/x11/glxapi.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -1104,6 +1104,27 @@ glXGetMemoryOffsetMESA(Display *dpy, int scrn, const void *pointer) } +/*** GLX_EXT_texture_from_pixmap */ + +void +glXBindTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (t) + t->BindTexImageEXT(dpy, drawable, buffer, attrib_list); +} + +void +glXReleaseTexImageEXT(Display *dpy, GLXDrawable drawable, int buffer) +{ + struct _glxapi_table *t; + GET_DISPATCH(dpy, t); + if (t) + t->ReleaseTexImageEXT(dpy, drawable, buffer); +} + /**********************************************************************/ /* GLX API management functions */ @@ -1148,6 +1169,9 @@ _glxapi_get_extensions(void) #ifdef GLX_SGIX_pbuffer "GLX_SGIX_pbuffer", #endif +#ifdef GLX_EXT_texture_from_pixmap, + "GLX_EXT_texture_from_pixmap", +#endif NULL }; return extensions; @@ -1333,6 +1357,10 @@ static struct name_address_pair GLX_functions[] = { { "glXFreeMemoryMESA", (__GLXextFuncPtr) glXFreeMemoryMESA }, { "glXGetMemoryOffsetMESA", (__GLXextFuncPtr) glXGetMemoryOffsetMESA }, + /*** GLX_EXT_texture_from_pixmap ***/ + { "glXBindTexImageEXT", (__GLXextFuncPtr) glXBindTexImageEXT }, + { "glXReleaseTexImageEXT", (__GLXextFuncPtr) glXReleaseTexImageEXT }, + { NULL, NULL } /* end of list */ }; diff --git a/src/mesa/drivers/x11/glxapi.h b/src/mesa/drivers/x11/glxapi.h index 3187534c9a3..37de81e55ac 100644 --- a/src/mesa/drivers/x11/glxapi.h +++ b/src/mesa/drivers/x11/glxapi.h @@ -196,6 +196,11 @@ struct _glxapi_table { /*** GLX_MESA_agp_offset ***/ GLuint (*GetAGPOffsetMESA)( const GLvoid *pointer ); + + /*** GLX_EXT_texture_from_pixmap ***/ + void (*BindTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer, + const int *attrib_list); + void (*ReleaseTexImageEXT)(Display *dpy, GLXDrawable drawable, int buffer); }; diff --git a/src/mesa/drivers/x11/xm_api.c b/src/mesa/drivers/x11/xm_api.c index a07d0a90cf3..cff64d17ade 100644 --- a/src/mesa/drivers/x11/xm_api.c +++ b/src/mesa/drivers/x11/xm_api.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.2 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -63,6 +63,7 @@ #endif #include "glxheader.h" +#include "GL/glxtokens.h" #include "GL/xmesa.h" #include "xmesaP.h" #include "context.h" @@ -72,6 +73,7 @@ #include "imports.h" #include "macros.h" #include "renderbuffer.h" +#include "teximage.h" #include "swrast/swrast.h" #include "swrast_setup/swrast_setup.h" #include "vbo/vbo.h" @@ -292,8 +294,20 @@ static GLboolean window_exists( XMesaDisplay *dpy, Window win ) XSetErrorHandler(old_handler); return WindowExistsFlag; } -#endif +static Status +get_drawable_size( XMesaDisplay *dpy, Drawable d, GLuint *width, GLuint *height ) +{ + Window root; + Status stat; + int xpos, ypos; + unsigned int w, h, bw, depth; + stat = XGetGeometry(dpy, d, &root, &xpos, &ypos, &w, &h, &bw, &depth); + *width = w; + *height = h; + return stat; +} +#endif /** @@ -310,22 +324,14 @@ xmesa_get_window_size(XMesaDisplay *dpy, XMesaBuffer b, *width = MIN2(b->frontxrb->drawable->width, MAX_WIDTH); *height = MIN2(b->frontxrb->drawable->height, MAX_HEIGHT); #else - Window root; Status stat; - int xpos, ypos; - unsigned int w, h, bw, depth; _glthread_LOCK_MUTEX(_xmesa_lock); XSync(b->xm_visual->display, 0); /* added for Chromium */ - stat = XGetGeometry(dpy, b->frontxrb->pixmap, &root, &xpos, &ypos, - &w, &h, &bw, &depth); + stat = get_drawable_size(dpy, b->frontxrb->pixmap, width, height); _glthread_UNLOCK_MUTEX(_xmesa_lock); - if (stat) { - *width = w; - *height = h; - } - else { + if (!stat) { /* probably querying a window that's recently been destroyed */ _mesa_warning(NULL, "XGetGeometry failed!\n"); *width = *height = 1; @@ -431,6 +437,11 @@ create_xmesa_buffer(XMesaDrawable d, BufferType type, b->swAlpha, vis->mesa_visual.numAuxBuffers > 0 ); + /* GLX_EXT_texture_from_pixmap */ + b->TextureTarget = 0; + b->TextureFormat = GLX_TEXTURE_FORMAT_NONE_EXT; + b->TextureMipmap = 0; + /* insert buffer into linked list */ b->Next = XMesaBufferList; XMesaBufferList = b; @@ -1673,6 +1684,67 @@ XMesaCreatePixmapBuffer(XMesaVisual v, XMesaPixmap p, XMesaColormap cmap) } +/** + * For GLX_EXT_texture_from_pixmap + */ +XMesaBuffer +XMesaCreatePixmapTextureBuffer(XMesaVisual v, XMesaPixmap p, + XMesaColormap cmap, + int format, int target, int mipmap) +{ + GET_CURRENT_CONTEXT(ctx); + XMesaBuffer b; + GLuint width, height; + + assert(v); + + b = create_xmesa_buffer((XMesaDrawable) p, PIXMAP, v, cmap); + if (!b) + return NULL; + + /* get pixmap size, update framebuffer/renderbuffer dims */ + xmesa_get_window_size(v->display, b, &width, &height); + _mesa_resize_framebuffer(NULL, &(b->mesa_buffer), width, height); + + if (target == 0) { + /* examine dims */ + if (ctx->Extensions.ARB_texture_non_power_of_two) { + target = GLX_TEXTURE_2D_EXT; + } + else if ( _mesa_bitcount(width) == 1 + && _mesa_bitcount(height) == 1) { + /* power of two size */ + if (height == 1) { + target = GLX_TEXTURE_1D_EXT; + } + else { + target = GLX_TEXTURE_2D_EXT; + } + } + else if (ctx->Extensions.NV_texture_rectangle) { + target = GLX_TEXTURE_RECTANGLE_EXT; + } + else { + /* non power of two textures not supported */ + XMesaDestroyBuffer(b); + return 0; + } + } + + b->TextureTarget = target; + b->TextureFormat = format; + b->TextureMipmap = mipmap; + + if (!initialize_visual_and_buffer(v, b, v->mesa_visual.rgbMode, + (XMesaDrawable) p, cmap)) { + xmesa_free_buffer(b); + return NULL; + } + + return b; +} + + XMesaBuffer XMesaCreatePBuffer(XMesaVisual v, XMesaColormap cmap, @@ -2254,3 +2326,154 @@ XMesaResizeBuffers( XMesaBuffer b ) xmesa_check_and_update_buffer_size(xmctx, b); } + +static GLint +xbuffer_to_renderbuffer(int buffer) +{ + assert(MAX_AUX_BUFFERS <= 4); + + switch (buffer) { + case GLX_FRONT_LEFT_EXT: + return BUFFER_FRONT_LEFT; + case GLX_FRONT_RIGHT_EXT: + return BUFFER_FRONT_RIGHT; + case GLX_BACK_LEFT_EXT: + return BUFFER_BACK_LEFT; + case GLX_BACK_RIGHT_EXT: + return BUFFER_BACK_RIGHT; + case GLX_AUX0_EXT: + return BUFFER_AUX0; + case GLX_AUX1_EXT: + return BUFFER_AUX1; + case GLX_AUX2_EXT: + return BUFFER_AUX2; + case GLX_AUX3_EXT: + return BUFFER_AUX3; + case GLX_AUX4_EXT: + case GLX_AUX5_EXT: + case GLX_AUX6_EXT: + case GLX_AUX7_EXT: + case GLX_AUX8_EXT: + case GLX_AUX9_EXT: + default: + /* BadValue error */ + return -1; + } +} + + +PUBLIC void +XMesaBindTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer, + const int *attrib_list) +{ +#if 0 + GET_CURRENT_CONTEXT(ctx); + const GLuint unit = ctx->Texture.CurrentUnit; + struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *texObj; +#endif + struct gl_renderbuffer *rb; + struct xmesa_renderbuffer *xrb; + GLint b; + XMesaImage *img = NULL; + GLboolean freeImg = GL_FALSE; + + b = xbuffer_to_renderbuffer(buffer); + if (b < 0) + return; + + if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_NONE_EXT) + return; /* BadMatch error */ + + rb = drawable->mesa_buffer.Attachment[b].Renderbuffer; + if (!rb) { + /* invalid buffer */ + return; + } + xrb = xmesa_renderbuffer(rb); + +#if 0 + switch (drawable->TextureTarget) { + case GLX_TEXTURE_1D_EXT: + texObj = texUnit->Current1D; + break; + case GLX_TEXTURE_2D_EXT: + texObj = texUnit->Current2D; + break; + case GLX_TEXTURE_RECTANGLE_EXT: + texObj = texUnit->CurrentRect; + break; + default: + return; /* BadMatch error */ + } +#endif + + /* + * The following is a quick and simple way to implement + * BindTexImage. The better way is to write some new FetchTexel() + * functions which would extract texels from XImages. We'd still + * need to use GetImage when texturing from a Pixmap (front buffer) + * but texturing from a back buffer (XImage) would avoid an image + * copy. + */ + + /* get XImage */ + if (xrb->pixmap) { + img = XMesaGetImage(dpy, xrb->pixmap, 0, 0, rb->Width, rb->Height, ~0L, + ZPixmap); + freeImg = GL_TRUE; + } + else if (xrb->ximage) { + img = xrb->ximage; + } + + /* store the XImage as a new texture image */ + if (img) { + GLenum format, type, intFormat; + if (img->bits_per_pixel == 32) { + format = GL_BGRA; + type = GL_UNSIGNED_BYTE; + intFormat = GL_RGBA; + } + else if (img->bits_per_pixel == 24) { + format = GL_BGR; + type = GL_UNSIGNED_BYTE; + intFormat = GL_RGB; + } + else if (img->bits_per_pixel == 16) { + format = GL_BGR; + type = GL_UNSIGNED_SHORT_5_6_5; + intFormat = GL_RGB; + } + else { + _mesa_problem(NULL, "Unexpected XImage format in XMesaBindTexImage"); + return; + } + if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGBA_EXT) { + intFormat = GL_RGBA; + } + else if (drawable->TextureFormat == GLX_TEXTURE_FORMAT_RGB_EXT) { + intFormat = GL_RGB; + } + + _mesa_TexImage2D(GL_TEXTURE_2D, 0, intFormat, rb->Width, rb->Height, 0, + format, type, img->data); + + if (freeImg) { + XMesaDestroyImage(img); + } + } +} + + + +PUBLIC void +XMesaReleaseTexImage(XMesaDisplay *dpy, XMesaBuffer drawable, int buffer) +{ + const GLint b = xbuffer_to_renderbuffer(buffer); + if (b < 0) + return; + + /* no-op for now */ +} + diff --git a/src/mesa/drivers/x11/xm_image.h b/src/mesa/drivers/x11/xm_image.h index 240ccee1af5..2a5e0f37779 100644 --- a/src/mesa/drivers/x11/xm_image.h +++ b/src/mesa/drivers/x11/xm_image.h @@ -36,13 +36,6 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XMESA_USE_PUTPIXEL_MACRO -struct _XMesaImageRec { - int width, height; - char *data; - int bytes_per_line; /* Padded to 32 bits */ - int bits_per_pixel; -}; - extern XMesaImage *XMesaCreateImage(int bitsPerPixel, int width, int height, char *data); extern void XMesaDestroyImage(XMesaImage *image); diff --git a/src/mesa/drivers/x11/xm_line.c b/src/mesa/drivers/x11/xm_line.c index 8537256d2e2..deeae5019c4 100644 --- a/src/mesa/drivers/x11/xm_line.c +++ b/src/mesa/drivers/x11/xm_line.c @@ -556,10 +556,10 @@ xor_line(GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1) vert1->color[0], vert1->color[1], vert1->color[2], vert1->color[3], xmesa->pixelformat); - int x0 = (int) vert0->win[0]; - int y0 = YFLIP(xrb, (GLint) vert0->win[1]); - int x1 = (int) vert1->win[0]; - int y1 = YFLIP(xrb, (GLint) vert1->win[1]); + int x0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][0]; + int y0 = YFLIP(xrb, (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1]); + int x1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0]; + int y1 = YFLIP(xrb, (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][1]); XMesaSetForeground(dpy, gc, pixel); XMesaSetFunction(dpy, gc, GXxor); XSetLineAttributes(dpy, gc, (int) ctx->Line.Width, diff --git a/src/mesa/drivers/x11/xmesaP.h b/src/mesa/drivers/x11/xmesaP.h index 01988867476..e3d7cf381f7 100644 --- a/src/mesa/drivers/x11/xmesaP.h +++ b/src/mesa/drivers/x11/xmesaP.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -267,6 +267,11 @@ struct xmesa_buffer { fxMesaContext FXctx; #endif + /* GLX_EXT_texture_from_pixmap */ + GLint TextureTarget; /** GLX_TEXTURE_1D_EXT, for example */ + GLint TextureFormat; /** GLX_TEXTURE_FORMAT_RGB_EXT, for example */ + GLint TextureMipmap; /** 0 or 1 */ + struct xmesa_buffer *Next; /* Linked list pointer: */ }; diff --git a/src/mesa/main/attrib.c b/src/mesa/main/attrib.c index 4654704afd1..1aa0a02fc78 100644 --- a/src/mesa/main/attrib.c +++ b/src/mesa/main/attrib.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -348,6 +348,8 @@ _mesa_PushAttrib(GLbitfield mask) ctx->Texture.Unit[u].Current3D->RefCount++; ctx->Texture.Unit[u].CurrentCubeMap->RefCount++; ctx->Texture.Unit[u].CurrentRect->RefCount++; + ctx->Texture.Unit[u].Current1DArray->RefCount++; + ctx->Texture.Unit[u].Current2DArray->RefCount++; } attr = MALLOC_STRUCT( gl_texture_attrib ); MEMCPY( attr, &ctx->Texture, sizeof(struct gl_texture_attrib) ); @@ -363,6 +365,10 @@ _mesa_PushAttrib(GLbitfield mask) attr->Unit[u].CurrentCubeMap); _mesa_copy_texture_object(&attr->Unit[u].SavedRect, attr->Unit[u].CurrentRect); + _mesa_copy_texture_object(&attr->Unit[u].Saved1DArray, + attr->Unit[u].Current1DArray); + _mesa_copy_texture_object(&attr->Unit[u].Saved2DArray, + attr->Unit[u].Current2DArray); } _mesa_unlock_context_textures(ctx); @@ -776,6 +782,7 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib) _mesa_TexParameteri(target, GL_TEXTURE_MAG_FILTER, obj->MagFilter); _mesa_TexParameterf(target, GL_TEXTURE_MIN_LOD, obj->MinLod); _mesa_TexParameterf(target, GL_TEXTURE_MAX_LOD, obj->MaxLod); + _mesa_TexParameterf(target, GL_TEXTURE_LOD_BIAS, obj->LodBias); _mesa_TexParameteri(target, GL_TEXTURE_BASE_LEVEL, obj->BaseLevel); if (target != GL_TEXTURE_RECTANGLE_ARB) _mesa_TexParameteri(target, GL_TEXTURE_MAX_LEVEL, obj->MaxLevel); @@ -809,6 +816,8 @@ pop_texture_group(GLcontext *ctx, const struct gl_texture_attrib *texAttrib) ctx->Texture.Unit[u].Current3D->RefCount--; ctx->Texture.Unit[u].CurrentCubeMap->RefCount--; ctx->Texture.Unit[u].CurrentRect->RefCount--; + ctx->Texture.Unit[u].Current1DArray->RefCount--; + ctx->Texture.Unit[u].Current2DArray->RefCount--; } } diff --git a/src/mesa/main/dlist.c b/src/mesa/main/dlist.c index c8c68214ce8..91ddcbf9ed6 100644 --- a/src/mesa/main/dlist.c +++ b/src/mesa/main/dlist.c @@ -6596,9 +6596,6 @@ execute_list(GLcontext *ctx, GLuint list) CALL_EvalPoint2(ctx->Exec, (n[1].i, n[2].i)); break; - - - case OPCODE_CONTINUE: n = (Node *) n[1].next; break; @@ -8407,8 +8404,6 @@ print_list(GLcontext *ctx, GLuint list) _mesa_printf("EVAL_P2 %d %d\n", n[1].i, n[2].i); break; - - /* * meta opcodes/commands */ diff --git a/src/mesa/main/light.c b/src/mesa/main/light.c index 92d8a0ae0d4..6e057614bad 100644 --- a/src/mesa/main/light.c +++ b/src/mesa/main/light.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.0 * - * Copyright (C) 1999-2005 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -1117,6 +1117,13 @@ compute_light_positions( GLcontext *ctx ) } light->_VP_inf_spot_attenuation = 1.0; } + else { + /* positional light w/ homogeneous coordinate, divide by W */ + GLfloat wInv = 1.0 / light->_Position[3]; + light->_Position[0] *= wInv; + light->_Position[1] *= wInv; + light->_Position[2] *= wInv; + } if (light->_Flags & LIGHT_SPOT) { if (ctx->_NeedEyeCoords) { diff --git a/src/mesa/main/mtypes.h b/src/mesa/main/mtypes.h index 894b9edb36f..fc712def576 100644 --- a/src/mesa/main/mtypes.h +++ b/src/mesa/main/mtypes.h @@ -1397,7 +1397,6 @@ struct gl_texture_image */ struct gl_texture_object { - _glthread_Mutex Mutex; /**< for thread safety */ GLint RefCount; /**< reference count */ GLuint Name; /**< the user-visible texture object ID */ GLenum Target; /**< GL_TEXTURE_1D, GL_TEXTURE_2D, etc. */ diff --git a/src/mesa/main/points.c b/src/mesa/main/points.c index 9caa9ab3ab2..8674c7299c5 100644 --- a/src/mesa/main/points.c +++ b/src/mesa/main/points.c @@ -5,9 +5,9 @@ /* * Mesa 3-D graphics library - * Version: 6.5.1 + * Version: 7.0 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -61,10 +61,6 @@ _mesa_PointSize( GLfloat size ) ctx->Point.MinSize, ctx->Point.MaxSize); - ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 || - ctx->Point.Params[1] != 0.0 || - ctx->Point.Params[2] != 0.0); - if (ctx->Driver.PointSize) ctx->Driver.PointSize(ctx, size); } @@ -122,6 +118,9 @@ _mesa_PointParameterfvEXT( GLenum pname, const GLfloat *params) return; FLUSH_VERTICES(ctx, _NEW_POINT); COPY_3V(ctx->Point.Params, params); + ctx->Point._Attenuated = (ctx->Point.Params[0] != 1.0 || + ctx->Point.Params[1] != 0.0 || + ctx->Point.Params[2] != 0.0); } else { _mesa_error(ctx, GL_INVALID_ENUM, diff --git a/src/mesa/main/teximage.h b/src/mesa/main/teximage.h index 68457f4728c..f2cad7eb2da 100644 --- a/src/mesa/main/teximage.h +++ b/src/mesa/main/teximage.h @@ -107,18 +107,19 @@ _mesa_test_proxy_teximage(GLcontext *ctx, GLenum target, GLint level, GLint width, GLint height, GLint depth, GLint border); -/* Lock a texture for updating. See also _mesa_lock_context_textures(). +/** + * Lock a texture for updating. See also _mesa_lock_context_textures(). */ -static INLINE void _mesa_lock_texture(GLcontext *ctx, - struct gl_texture_object *texObj) +static INLINE void +_mesa_lock_texture(GLcontext *ctx, struct gl_texture_object *texObj) { _glthread_LOCK_MUTEX(ctx->Shared->TexMutex); ctx->Shared->TextureStateStamp++; (void) texObj; } -static INLINE void _mesa_unlock_texture(GLcontext *ctx, - struct gl_texture_object *texObj) +static INLINE void +_mesa_unlock_texture(GLcontext *ctx, struct gl_texture_object *texObj) { _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex); } diff --git a/src/mesa/main/texobj.c b/src/mesa/main/texobj.c index bd447ac0688..0d2946e95a7 100644 --- a/src/mesa/main/texobj.c +++ b/src/mesa/main/texobj.c @@ -42,10 +42,6 @@ #include "mtypes.h" -#ifdef __VMS -#define _mesa_sprintf sprintf -#endif - /**********************************************************************/ /** \name Internal functions */ /*@{*/ @@ -110,7 +106,6 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, _mesa_bzero(obj, sizeof(*obj)); /* init the non-zero fields */ - _glthread_INIT_MUTEX(obj->Mutex); obj->RefCount = 1; obj->Name = name; obj->Target = target; @@ -140,13 +135,13 @@ _mesa_initialize_texture_object( struct gl_texture_object *obj, obj->CompareFunc = GL_LEQUAL; /* ARB_shadow */ obj->DepthMode = GL_LUMINANCE; /* ARB_depth_texture */ obj->ShadowAmbient = 0.0F; /* ARB/SGIX_shadow_ambient */ - _mesa_init_colortable(&obj->Palette); } /** * Deallocate a texture object struct. It should have already been * removed from the texture object pool. + * Called via ctx->Driver.DeleteTexture() if not overriden by a driver. * * \param shared the shared GL state to which the object belongs. * \param texOjb the texture object to delete. @@ -169,9 +164,6 @@ _mesa_delete_texture_object( GLcontext *ctx, struct gl_texture_object *texObj ) } } - /* destroy the mutex -- it may have allocated memory (eg on bsd) */ - _glthread_DESTROY_MUTEX(texObj->Mutex); - /* free this object */ _mesa_free(texObj); } @@ -532,13 +524,6 @@ _mesa_test_texobj_completeness( const GLcontext *ctx, /** \name API functions */ /*@{*/ -/** - * Texture name generation lock. - * - * Used by _mesa_GenTextures() to guarantee that the generation and allocation - * of texture IDs is atomic. - */ -_glthread_DECLARE_STATIC_MUTEX(GenTexturesLock); /** * Generate texture names. @@ -548,9 +533,9 @@ _glthread_DECLARE_STATIC_MUTEX(GenTexturesLock); * * \sa glGenTextures(). * - * While holding the GenTexturesLock lock, calls _mesa_HashFindFreeKeyBlock() - * to find a block of free texture IDs which are stored in \p textures. - * Corresponding empty texture objects are also generated. + * Calls _mesa_HashFindFreeKeyBlock() to find a block of free texture + * IDs which are stored in \p textures. Corresponding empty texture + * objects are also generated. */ void GLAPIENTRY _mesa_GenTextures( GLsizei n, GLuint *textures ) @@ -571,7 +556,7 @@ _mesa_GenTextures( GLsizei n, GLuint *textures ) /* * This must be atomic (generation and allocation of texture IDs) */ - _glthread_LOCK_MUTEX(GenTexturesLock); + _glthread_LOCK_MUTEX(ctx->Shared->Mutex); first = _mesa_HashFindFreeKeyBlock(ctx->Shared->TexObjects, n); @@ -582,20 +567,18 @@ _mesa_GenTextures( GLsizei n, GLuint *textures ) GLenum target = 0; texObj = (*ctx->Driver.NewTextureObject)( ctx, name, target); if (!texObj) { - _glthread_UNLOCK_MUTEX(GenTexturesLock); + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); _mesa_error(ctx, GL_OUT_OF_MEMORY, "glGenTextures"); return; } /* insert into hash table */ - _glthread_LOCK_MUTEX(ctx->Shared->Mutex); _mesa_HashInsert(ctx->Shared->TexObjects, texObj->Name, texObj); - _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); textures[i] = name; } - _glthread_UNLOCK_MUTEX(GenTexturesLock); + _glthread_UNLOCK_MUTEX(ctx->Shared->Mutex); } @@ -1097,14 +1080,21 @@ _mesa_IsTexture( GLuint texture ) return t && t->Target; } -/* Simplest implementation of texture locking: Grab the a new mutex in + +/** + * Simplest implementation of texture locking: Grab the a new mutex in * the shared context. Examine the shared context state timestamp and * if there has been a change, set the appropriate bits in * ctx->NewState. * - * See also _mesa_lock/unlock_texture in texobj.h + * This is used to deal with synchronizing things when a texture object + * is used/modified by different contexts (or threads) which are sharing + * the texture. + * + * See also _mesa_lock/unlock_texture() in teximage.h */ -void _mesa_lock_context_textures( GLcontext *ctx ) +void +_mesa_lock_context_textures( GLcontext *ctx ) { _glthread_LOCK_MUTEX(ctx->Shared->TexMutex); @@ -1115,7 +1105,8 @@ void _mesa_lock_context_textures( GLcontext *ctx ) } -void _mesa_unlock_context_textures( GLcontext *ctx ) +void +_mesa_unlock_context_textures( GLcontext *ctx ) { assert(ctx->Shared->TextureStateStamp == ctx->TextureStateTimestamp); _glthread_UNLOCK_MUTEX(ctx->Shared->TexMutex); diff --git a/src/mesa/main/texobj.h b/src/mesa/main/texobj.h index ec7cf8cd86e..2a2bde36017 100644 --- a/src/mesa/main/texobj.h +++ b/src/mesa/main/texobj.h @@ -61,8 +61,11 @@ extern void _mesa_test_texobj_completeness( const GLcontext *ctx, struct gl_texture_object *obj ); -extern void _mesa_unlock_context_textures( GLcontext *ctx ); -extern void _mesa_lock_context_textures( GLcontext *ctx ); +extern void +_mesa_unlock_context_textures( GLcontext *ctx ); + +extern void +_mesa_lock_context_textures( GLcontext *ctx ); /*@}*/ diff --git a/src/mesa/shader/prog_statevars.c b/src/mesa/shader/prog_statevars.c index 975a617ac89..d37d7fb9bf4 100644 --- a/src/mesa/shader/prog_statevars.c +++ b/src/mesa/shader/prog_statevars.c @@ -507,6 +507,8 @@ _mesa_program_state_flags(const gl_state_index state[STATE_LENGTH]) switch (state[1]) { case STATE_TEXRECT_SCALE: return _NEW_TEXTURE; + case STATE_FOG_PARAMS_OPTIMIZED: + return _NEW_FOG; default: /* unknown state indexes are silently ignored and * no flag set, since it is handled by the driver. diff --git a/src/mesa/swrast/s_aaline.c b/src/mesa/swrast/s_aaline.c index 3bb53dc2d7f..d6a9afb4212 100644 --- a/src/mesa/swrast/s_aaline.c +++ b/src/mesa/swrast/s_aaline.c @@ -59,19 +59,13 @@ struct LineInfo /* 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_ATTRIBS */ - GLfloat sPlane[FRAG_ATTRIB_MAX][4]; - GLfloat tPlane[FRAG_ATTRIB_MAX][4]; - GLfloat uPlane[FRAG_ATTRIB_MAX][4]; - GLfloat vPlane[FRAG_ATTRIB_MAX][4]; + GLfloat wPlane[4]; + GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4]; GLfloat lambda[FRAG_ATTRIB_MAX]; GLfloat texWidth[FRAG_ATTRIB_MAX]; GLfloat texHeight[FRAG_ATTRIB_MAX]; @@ -483,35 +477,24 @@ segment(GLcontext *ctx, #define NAME(x) aa_ci_##x #define DO_Z -#define DO_FOG +#define DO_ATTRIBS /* for 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 NAME(x) aa_general_rgba_##x #define DO_Z -#define DO_FOG #define DO_RGBA #define DO_ATTRIBS #include "s_aalinetemp.h" -#define NAME(x) aa_multitex_spec_##x -#define DO_Z -#define DO_FOG -#define DO_RGBA -#define DO_ATTRIBS -#define DO_SPEC -#include "s_aalinetemp.h" - - void _swrast_choose_aa_line_function(GLcontext *ctx) @@ -523,14 +506,12 @@ _swrast_choose_aa_line_function(GLcontext *ctx) if (ctx->Visual.rgbMode) { /* RGBA */ if (ctx->Texture._EnabledCoordUnits != 0 - || ctx->FragmentProgram._Current) { - - if (ctx->Light.Model.ColorControl==GL_SEPARATE_SPECULAR_COLOR || - ctx->Fog.ColorSumEnabled) - swrast->Line = aa_multitex_spec_line; - else - swrast->Line = aa_tex_rgba_line; - + || ctx->FragmentProgram._Current + || (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR) + || ctx->Fog.ColorSumEnabled + || swrast->_FogEnabled) { + swrast->Line = aa_general_rgba_line; } else { swrast->Line = aa_rgba_line; diff --git a/src/mesa/swrast/s_aalinetemp.h b/src/mesa/swrast/s_aalinetemp.h index 80cec0b31d4..8756f122d09 100644 --- a/src/mesa/swrast/s_aalinetemp.h +++ b/src/mesa/swrast/s_aalinetemp.h @@ -63,9 +63,6 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) #ifdef DO_Z line->span.array->z[i] = (GLuint) solve_plane(fx, fy, line->zPlane); #endif -#ifdef DO_FOG - line->span.array->attribs[FRAG_ATTRIB_FOGC][i][0] = 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); @@ -75,31 +72,31 @@ NAME(plot)(GLcontext *ctx, struct LineInfo *line, int ix, int iy) #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 #if defined(DO_ATTRIBS) ATTRIB_LOOP_BEGIN GLfloat (*attribArray)[4] = line->span.array->attribs[attr]; - GLfloat invQ; - if (ctx->FragmentProgram._Active) { - invQ = 1.0F; - } - else { - invQ = solve_plane_recip(fx, fy, line->vPlane[attr]); - } - attribArray[i][0] = solve_plane(fx, fy, line->sPlane[attr]) * invQ; - attribArray[i][1] = solve_plane(fx, fy, line->tPlane[attr]) * invQ; - attribArray[i][2] = solve_plane(fx, fy, line->uPlane[attr]) * invQ; - if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) { + if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0 + && !ctx->FragmentProgram._Active) { + /* texcoord w/ divide by Q */ const GLuint unit = attr - FRAG_ATTRIB_TEX0; + const GLfloat invQ = solve_plane_recip(fx, fy, line->attrPlane[attr][3]); + GLuint c; + for (c = 0; c < 3; c++) { + attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invQ; + } line->span.array->lambda[unit][i] - = compute_lambda(line->sPlane[attr], - line->tPlane[attr], invQ, + = compute_lambda(line->attrPlane[attr][0], + line->attrPlane[attr][1], invQ, line->texWidth[attr], line->texHeight[attr]); } + else { + /* non-texture attrib */ + const GLfloat invW = solve_plane_recip(fx, fy, line->wPlane); + GLuint c; + for (c = 0; c < 4; c++) { + attribArray[i][c] = solve_plane(fx, fy, line->attrPlane[attr][c]) * invW; + } + } ATTRIB_LOOP_END #endif @@ -128,10 +125,10 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) /* 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.x0 = v0->attrib[FRAG_ATTRIB_WPOS][0]; + line.y0 = v0->attrib[FRAG_ATTRIB_WPOS][1]; + line.x1 = v1->attrib[FRAG_ATTRIB_WPOS][0]; + line.y1 = v1->attrib[FRAG_ATTRIB_WPOS][1]; line.dx = line.x1 - line.x0; line.dy = line.y1 - line.y0; line.len = SQRTF(line.dx * line.dx + line.dy * line.dy); @@ -148,14 +145,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) #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->attrib[FRAG_ATTRIB_FOGC][0], - v1->attrib[FRAG_ATTRIB_FOGC][0], - line.fPlane); + v0->attrib[FRAG_ATTRIB_WPOS][2], v1->attrib[FRAG_ATTRIB_WPOS][2], line.zPlane); #endif #ifdef DO_RGBA line.span.arrayMask |= SPAN_RGBA; @@ -176,51 +166,32 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) 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, - v0->index, v1->index, line.iPlane); + v0->attrib[FRAG_ATTRIB_CI][0], + v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane); } else { - constant_plane(v1->index, line.iPlane); + constant_plane(v1->attrib[FRAG_ATTRIB_CI][0], line.iPlane); } #endif #if defined(DO_ATTRIBS) { - const GLfloat invW0 = v0->win[3]; - const GLfloat invW1 = v1->win[3]; - line.span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING); + const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3]; + const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3]; + line.span.arrayMask |= SPAN_LAMBDA; + compute_plane(line.x0, line.y0, line.x1, line.y1, invW0, invW1, line.wPlane); ATTRIB_LOOP_BEGIN - const GLfloat s0 = v0->attrib[attr][0] * invW0; - const GLfloat s1 = v1->attrib[attr][0] * invW1; - const GLfloat t0 = v0->attrib[attr][1] * invW0; - const GLfloat t1 = v1->attrib[attr][1] * invW1; - const GLfloat r0 = v0->attrib[attr][2] * invW0; - const GLfloat r1 = v1->attrib[attr][2] * invW1; - const GLfloat q0 = v0->attrib[attr][3] * invW0; - const GLfloat q1 = v1->attrib[attr][3] * invW1; - compute_plane(line.x0, line.y0, line.x1, line.y1, s0, s1, line.sPlane[attr]); - compute_plane(line.x0, line.y0, line.x1, line.y1, t0, t1, line.tPlane[attr]); - compute_plane(line.x0, line.y0, line.x1, line.y1, r0, r1, line.uPlane[attr]); - compute_plane(line.x0, line.y0, line.x1, line.y1, q0, q1, line.vPlane[attr]); - if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) { + GLuint c; + for (c = 0; c < 4; c++) { + const GLfloat a0 = v0->attrib[attr][c] * invW0; + const GLfloat a1 = v1->attrib[attr][c] * invW1; + compute_plane(line.x0, line.y0, line.x1, line.y1, a0, a1, line.attrPlane[attr][c]); + } + line.span.arrayAttribs |= (1 << attr); + if (attr >= FRAG_ATTRIB_TEX0 && attr < FRAG_ATTRIB_VAR0) { const GLuint u = attr - FRAG_ATTRIB_TEX0; const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; @@ -286,9 +257,7 @@ NAME(line)(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) #undef DO_Z -#undef DO_FOG #undef DO_RGBA #undef DO_INDEX -#undef DO_SPEC #undef DO_ATTRIBS #undef NAME diff --git a/src/mesa/swrast/s_aatriangle.c b/src/mesa/swrast/s_aatriangle.c index 0d95f06a9de..66891f9fec8 100644 --- a/src/mesa/swrast/s_aatriangle.c +++ b/src/mesa/swrast/s_aatriangle.c @@ -144,6 +144,19 @@ solve_plane_chan(GLfloat x, GLfloat y, const GLfloat plane[4]) } +static INLINE GLfloat +plane_dx(const GLfloat plane[4]) +{ + return -plane[0] / plane[2]; +} + +static INLINE GLfloat +plane_dy(const GLfloat plane[4]) +{ + return -plane[1] / plane[2]; +} + + /* * Compute how much (area) of the given pixel is inside the triangle. @@ -337,7 +350,6 @@ compute_coveragei(const GLfloat v0[3], const GLfloat v1[3], } - static void rgba_aa_tri(GLcontext *ctx, const SWvertex *v0, @@ -345,7 +357,6 @@ rgba_aa_tri(GLcontext *ctx, const SWvertex *v2) { #define DO_Z -#define DO_FOG #define DO_RGBA #include "s_aatritemp.h" } @@ -358,72 +369,21 @@ index_aa_tri(GLcontext *ctx, 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_ATTRIBS +#define DO_INDEX #include "s_aatritemp.h" } static void -spec_tex_aa_tri(GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1, - const SWvertex *v2) +general_aa_tri(GLcontext *ctx, + const SWvertex *v0, + const SWvertex *v1, + const SWvertex *v2) { #define DO_Z -#define DO_FOG #define DO_RGBA #define DO_ATTRIBS -#define DO_SPEC #include "s_aatritemp.h" } @@ -436,16 +396,15 @@ spec_tex_aa_tri(GLcontext *ctx, void _swrast_set_aa_triangle_function(GLcontext *ctx) { + SWcontext *swrast = SWRAST_CONTEXT(ctx); + ASSERT(ctx->Polygon.SmoothFlag); if (ctx->Texture._EnabledCoordUnits != 0 - || ctx->FragmentProgram._Current) { - if (NEED_SECONDARY_COLOR(ctx)) { - SWRAST_CONTEXT(ctx)->Triangle = spec_tex_aa_tri; - } - else { - SWRAST_CONTEXT(ctx)->Triangle = tex_aa_tri; - } + || ctx->FragmentProgram._Current + || swrast->_FogEnabled + || NEED_SECONDARY_COLOR(ctx)) { + SWRAST_CONTEXT(ctx)->Triangle = general_aa_tri; } else if (ctx->Visual.rgbMode) { SWRAST_CONTEXT(ctx)->Triangle = rgba_aa_tri; diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index 4162ed68532..34a2305b393 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -35,16 +35,15 @@ * 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_ATTRIBS - if defined, compute texcoords, varying, etc. */ /*void triangle( GLcontext *ctx, GLuint v0, GLuint v1, GLuint v2, GLuint pv )*/ { const SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLfloat *p0 = v0->win; - const GLfloat *p1 = v1->win; - const GLfloat *p2 = v2->win; + const GLfloat *p0 = v0->attrib[FRAG_ATTRIB_WPOS]; + const GLfloat *p1 = v1->attrib[FRAG_ATTRIB_WPOS]; + const GLfloat *p2 = v2->attrib[FRAG_ATTRIB_WPOS]; const SWvertex *vMin, *vMid, *vMax; GLint iyMin, iyMax; GLfloat yMin, yMax; @@ -56,27 +55,15 @@ #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 #if defined(DO_ATTRIBS) - GLfloat sPlane[FRAG_ATTRIB_MAX][4]; /* texture S */ - GLfloat tPlane[FRAG_ATTRIB_MAX][4]; /* texture T */ - GLfloat uPlane[FRAG_ATTRIB_MAX][4]; /* texture R */ - GLfloat vPlane[FRAG_ATTRIB_MAX][4]; /* texture Q */ - GLfloat texWidth[FRAG_ATTRIB_MAX]; - GLfloat texHeight[FRAG_ATTRIB_MAX]; + GLfloat attrPlane[FRAG_ATTRIB_MAX][4][4]; + GLfloat wPlane[4]; /* win[3] */ #endif GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign; @@ -86,9 +73,9 @@ /* determine bottom to top order of vertices */ { - GLfloat y0 = v0->win[1]; - GLfloat y1 = v1->win[1]; - GLfloat y2 = v2->win[1]; + GLfloat y0 = v0->attrib[FRAG_ATTRIB_WPOS][1]; + GLfloat y1 = v1->attrib[FRAG_ATTRIB_WPOS][1]; + GLfloat y2 = v2->attrib[FRAG_ATTRIB_WPOS][1]; if (y0 <= y1) { if (y1 <= y2) { vMin = v0; vMid = v1; vMax = v2; /* y0<=y1<=y2 */ @@ -113,12 +100,12 @@ } } - majDx = vMax->win[0] - vMin->win[0]; - majDy = vMax->win[1] - vMin->win[1]; + majDx = vMax->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0]; + majDy = vMax->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1]; { - const GLfloat botDx = vMid->win[0] - vMin->win[0]; - const GLfloat botDy = vMid->win[1] - vMin->win[1]; + const GLfloat botDx = vMid->attrib[FRAG_ATTRIB_WPOS][0] - vMin->attrib[FRAG_ATTRIB_WPOS][0]; + const GLfloat botDy = vMid->attrib[FRAG_ATTRIB_WPOS][1] - vMin->attrib[FRAG_ATTRIB_WPOS][1]; const GLfloat area = majDx * botDy - botDx * majDy; /* Do backface culling */ if (area * bf < 0 || area == 0 || IS_INF_OR_NAN(area)) @@ -135,14 +122,6 @@ 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->attrib[FRAG_ATTRIB_FOGC][0], - v1->attrib[FRAG_ATTRIB_FOGC][0], - v2->attrib[FRAG_ATTRIB_FOGC][0], - fogPlane); - span.arrayMask |= SPAN_FOG; -#endif #ifdef DO_RGBA if (ctx->Light.ShadeModel == GL_SMOOTH) { compute_plane(p0, p1, p2, v0->color[RCOMP], v1->color[RCOMP], v2->color[RCOMP], rPlane); @@ -160,62 +139,43 @@ #endif #ifdef DO_INDEX if (ctx->Light.ShadeModel == GL_SMOOTH) { - compute_plane(p0, p1, p2, (GLfloat) v0->index, - v1->index, v2->index, iPlane); + compute_plane(p0, p1, p2, (GLfloat) v0->attrib[FRAG_ATTRIB_CI][0], + v1->attrib[FRAG_ATTRIB_CI][0], v2->attrib[FRAG_ATTRIB_CI][0], iPlane); } else { - constant_plane(v2->index, iPlane); + constant_plane(v2->attrib[FRAG_ATTRIB_CI][0], iPlane); } span.arrayMask |= SPAN_INDEX; #endif -#ifdef DO_SPEC - if (ctx->Light.ShadeModel == GL_SMOOTH) { - compute_plane(p0, p1, p2, v0->specular[RCOMP], v1->specular[RCOMP], v2->specular[RCOMP], srPlane); - compute_plane(p0, p1, p2, v0->specular[GCOMP], v1->specular[GCOMP], v2->specular[GCOMP], sgPlane); - compute_plane(p0, p1, p2, v0->specular[BCOMP], v1->specular[BCOMP], v2->specular[BCOMP], 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 #if defined(DO_ATTRIBS) { - const GLfloat invW0 = v0->win[3]; - const GLfloat invW1 = v1->win[3]; - const GLfloat invW2 = v2->win[3]; + const GLfloat invW0 = v0->attrib[FRAG_ATTRIB_WPOS][3]; + const GLfloat invW1 = v1->attrib[FRAG_ATTRIB_WPOS][3]; + const GLfloat invW2 = v2->attrib[FRAG_ATTRIB_WPOS][3]; + compute_plane(p0, p1, p2, invW0, invW1, invW2, wPlane); + span.attrStepX[FRAG_ATTRIB_WPOS][3] = plane_dx(wPlane); + span.attrStepY[FRAG_ATTRIB_WPOS][3] = plane_dy(wPlane); ATTRIB_LOOP_BEGIN - const GLfloat s0 = v0->attrib[attr][0] * invW0; - const GLfloat s1 = v1->attrib[attr][0] * invW1; - const GLfloat s2 = v2->attrib[attr][0] * invW2; - const GLfloat t0 = v0->attrib[attr][1] * invW0; - const GLfloat t1 = v1->attrib[attr][1] * invW1; - const GLfloat t2 = v2->attrib[attr][1] * invW2; - const GLfloat r0 = v0->attrib[attr][2] * invW0; - const GLfloat r1 = v1->attrib[attr][2] * invW1; - const GLfloat r2 = v2->attrib[attr][2] * invW2; - const GLfloat q0 = v0->attrib[attr][3] * invW0; - const GLfloat q1 = v1->attrib[attr][3] * invW1; - const GLfloat q2 = v2->attrib[attr][3] * invW2; - compute_plane(p0, p1, p2, s0, s1, s2, sPlane[attr]); - compute_plane(p0, p1, p2, t0, t1, t2, tPlane[attr]); - compute_plane(p0, p1, p2, r0, r1, r2, uPlane[attr]); - compute_plane(p0, p1, p2, q0, q1, q2, vPlane[attr]); - if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) { - const GLuint u = attr - FRAG_ATTRIB_TEX0; - const struct gl_texture_object *obj = ctx->Texture.Unit[u]._Current; - const struct gl_texture_image *texImage = obj->Image[0][obj->BaseLevel]; - texWidth[attr] = (GLfloat) texImage->Width; - texHeight[attr] = (GLfloat) texImage->Height; + GLuint c; + if (swrast->_InterpMode[attr] == GL_FLAT) { + for (c = 0; c < 4; c++) { + constant_plane(v2->attrib[attr][c] * invW2, attrPlane[attr][c]); + } } else { - texWidth[attr] = texHeight[attr] = 1.0; + for (c = 0; c < 4; c++) { + const GLfloat a0 = v0->attrib[attr][c] * invW0; + const GLfloat a1 = v1->attrib[attr][c] * invW1; + const GLfloat a2 = v2->attrib[attr][c] * invW2; + compute_plane(p0, p1, p2, a0, a1, a2, attrPlane[attr][c]); + } + } + for (c = 0; c < 4; c++) { + span.attrStepX[attr][c] = plane_dx(attrPlane[attr][c]); + span.attrStepY[attr][c] = plane_dy(attrPlane[attr][c]); } ATTRIB_LOOP_END } - span.arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA | SPAN_VARYING); #endif /* Begin bottom-to-top scan over the triangle. @@ -224,16 +184,16 @@ * 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]; + yMin = vMin->attrib[FRAG_ATTRIB_WPOS][1]; + yMax = vMax->attrib[FRAG_ATTRIB_WPOS][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 *pMin = vMin->attrib[FRAG_ATTRIB_WPOS]; + const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS]; + const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS]; const GLfloat dxdy = majDx / majDy; const GLfloat xAdj = dxdy < 0.0F ? -dxdy : 0.0F; GLfloat x = pMin[0] - (yMin - iyMin) * dxdy; @@ -253,6 +213,18 @@ /* enter interior of triangle */ ix = startX; + +#if defined(DO_ATTRIBS) + /* compute attributes at left-most fragment */ + span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 0.5, iy + 0.5, wPlane); + ATTRIB_LOOP_BEGIN + GLuint c; + for (c = 0; c < 4; c++) { + span.attrStart[attr][c] = solve_plane(ix + 0.5, iy + 0.5, attrPlane[attr][c]); + } + ATTRIB_LOOP_END +#endif + count = 0; while (coverage > 0.0F) { /* (cx,cy) = center of fragment */ @@ -266,9 +238,6 @@ #ifdef DO_Z array->z[count] = (GLuint) solve_plane(cx, cy, zPlane); #endif -#ifdef DO_FOG - array->attribs[FRAG_ATTRIB_FOGC][count][0] = 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); @@ -278,25 +247,6 @@ #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 -#if defined(DO_ATTRIBS) - ATTRIB_LOOP_BEGIN - GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]); - array->attribs[attr][count][0] = solve_plane(cx, cy, sPlane[attr]) * invQ; - array->attribs[attr][count][1] = solve_plane(cx, cy, tPlane[attr]) * invQ; - array->attribs[attr][count][2] = solve_plane(cx, cy, uPlane[attr]) * invQ; - if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) { - const GLuint unit = attr - FRAG_ATTRIB_TEX0; - array->lambda[unit][count] = compute_lambda(sPlane[attr], tPlane[attr], - vPlane[attr], cx, cy, invQ, - texWidth[attr], texHeight[attr]); - } - ATTRIB_LOOP_END -#endif ix++; count++; coverage = compute_coveragef(pMin, pMid, pMax, ix, iy); @@ -308,7 +258,6 @@ span.x = startX; span.y = iy; span.end = (GLuint) ix - (GLuint) startX; - ASSERT(span.interpMask == 0); #if defined(DO_RGBA) _swrast_write_rgba_span(ctx, &span); #else @@ -318,9 +267,9 @@ } else { /* scan right to left */ - const GLfloat *pMin = vMin->win; - const GLfloat *pMid = vMid->win; - const GLfloat *pMax = vMax->win; + const GLfloat *pMin = vMin->attrib[FRAG_ATTRIB_WPOS]; + const GLfloat *pMid = vMid->attrib[FRAG_ATTRIB_WPOS]; + const GLfloat *pMax = vMax->attrib[FRAG_ATTRIB_WPOS]; const GLfloat dxdy = majDx / majDy; const GLfloat xAdj = dxdy > 0 ? dxdy : 0.0F; GLfloat x = pMin[0] - (yMin - iyMin) * dxdy; @@ -358,9 +307,6 @@ #ifdef DO_Z array->z[ix] = (GLuint) solve_plane(cx, cy, zPlane); #endif -#ifdef DO_FOG - array->attribs[FRAG_ATTRIB_FOGC][ix][0] = 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); @@ -370,33 +316,22 @@ #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 -#if defined(DO_ATTRIBS) - ATTRIB_LOOP_BEGIN - GLfloat invQ = solve_plane_recip(cx, cy, vPlane[attr]); - array->attribs[attr][ix][0] = solve_plane(cx, cy, sPlane[attr]) * invQ; - array->attribs[attr][ix][1] = solve_plane(cx, cy, tPlane[attr]) * invQ; - array->attribs[attr][ix][2] = solve_plane(cx, cy, uPlane[attr]) * invQ; - if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) { - const GLuint unit = attr - FRAG_ATTRIB_TEX0; - array->lambda[unit][ix] = compute_lambda(sPlane[attr], - tPlane[attr], - vPlane[attr], - cx, cy, invQ, - texWidth[attr], - texHeight[attr]); - } - ATTRIB_LOOP_END -#endif ix--; count++; coverage = compute_coveragef(pMin, pMax, pMid, ix, iy); } +#if defined(DO_ATTRIBS) + /* compute attributes at left-most fragment */ + span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5, iy + 0.5, wPlane); + ATTRIB_LOOP_BEGIN + GLuint c; + for (c = 0; c < 4; c++) { + span.attrStart[attr][c] = solve_plane(ix + 1.5, iy + 0.5, attrPlane[attr][c]); + } + ATTRIB_LOOP_END +#endif + if (startX <= ix) continue; @@ -410,48 +345,22 @@ SWspanarrays *array = span.array; GLint j; for (j = 0; j < (GLint) n; j++) { + array->coverage[j] = array->coverage[j + left]; #ifdef DO_RGBA COPY_CHAN4(array->rgba[j], array->rgba[j + left]); #endif -#ifdef DO_SPEC - COPY_CHAN4(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->attribs[FRAG_ATTRIB_FOGC][j][0] - = array->attribs[FRAG_ATTRIB_FOGC][j + left][0]; -#endif -#if defined(DO_ATTRIBS) - array->lambda[0][j] = array->lambda[0][j + left]; -#endif - array->coverage[j] = array->coverage[j + left]; } } -#ifdef DO_ATTRIBS - /* shift texcoords, varying */ - { - SWspanarrays *array = span.array; - ATTRIB_LOOP_BEGIN - GLint j; - for (j = 0; j < (GLint) n; j++) { - array->attribs[attr][j][0] = array->attribs[attr][j + left][0]; - array->attribs[attr][j][1] = array->attribs[attr][j + left][1]; - array->attribs[attr][j][2] = array->attribs[attr][j + left][2]; - /*array->lambda[unit][j] = array->lambda[unit][j + left];*/ - } - ATTRIB_LOOP_END - } -#endif span.x = left; span.y = iy; span.end = n; - ASSERT(span.interpMask == 0); #if defined(DO_RGBA) _swrast_write_rgba_span(ctx, &span); #else @@ -462,30 +371,8 @@ } -#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_ATTRIBS #undef DO_ATTRIBS -#endif - -#ifdef DO_OCCLUSION_TEST #undef DO_OCCLUSION_TEST -#endif diff --git a/src/mesa/swrast/s_alpha.c b/src/mesa/swrast/s_alpha.c index af8a6baddc2..3c55d3e9e33 100644 --- a/src/mesa/swrast/s_alpha.c +++ b/src/mesa/swrast/s_alpha.c @@ -111,13 +111,13 @@ _swrast_alpha_test(const GLcontext *ctx, SWspan *span) if (span->arrayMask & SPAN_RGBA) { /* Use array's alpha values */ if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; + GLubyte (*rgba)[4] = span->array->rgba8; GLubyte ref; CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef); ALPHA_TEST(rgba[i][ACOMP], ;); } else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; + GLushort (*rgba)[4] = span->array->rgba16; GLushort ref; CLAMPED_FLOAT_TO_USHORT(ref, ctx->Color.AlphaRef); ALPHA_TEST(rgba[i][ACOMP], ;); diff --git a/src/mesa/swrast/s_bitmap.c b/src/mesa/swrast/s_bitmap.c index 4c237052457..563b5fe602c 100644 --- a/src/mesa/swrast/s_bitmap.c +++ b/src/mesa/swrast/s_bitmap.c @@ -83,15 +83,7 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, _swrast_validate_derived( ctx ); INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_XY); - - _swrast_span_default_color(ctx, &span); - _swrast_span_default_secondary_color(ctx, &span); - if (ctx->Depth.Test) - _swrast_span_default_z(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - if (ctx->Texture._EnabledCoordUnits) - _swrast_span_default_texcoords(ctx, &span); + _swrast_span_default_attribs(ctx, &span); for (row = 0; row < height; row++) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, @@ -189,20 +181,13 @@ _swrast_Bitmap( GLcontext *ctx, GLint px, GLint py, _swrast_validate_derived( ctx ); INIT_SPAN(span, GL_BITMAP, width, 0, SPAN_MASK); + _swrast_span_default_attribs(ctx, &span); /*span.arrayMask |= SPAN_MASK;*/ /* we'll init span.mask[] */ span.x = px; span.y = py; /*span.end = width;*/ - _swrast_span_default_color(ctx, &span); - if (ctx->Depth.Test) - _swrast_span_default_z(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - if (ctx->Texture._EnabledCoordUnits) - _swrast_span_default_texcoords(ctx, &span); - for (row=0; row<height; row++, span.y++) { const GLubyte *src = (const GLubyte *) _mesa_image_address2d(unpack, bitmap, width, height, GL_COLOR_INDEX, GL_BITMAP, row, 0); diff --git a/src/mesa/swrast/s_context.c b/src/mesa/swrast/s_context.c index 2f25edbd811..f373fde781b 100644 --- a/src/mesa/swrast/s_context.c +++ b/src/mesa/swrast/s_context.c @@ -189,6 +189,37 @@ _swrast_update_texture_env( GLcontext *ctx ) /** + * Determine if we can defer texturing/shading until after Z/stencil + * testing. This potentially allows us to skip texturing/shading for + * lots of fragments. + */ +static void +_swrast_update_deferred_texture(GLcontext *ctx) +{ + SWcontext *swrast = SWRAST_CONTEXT(ctx); + if (ctx->Color.AlphaEnabled) { + /* alpha test depends on post-texture/shader colors */ + swrast->_DeferredTexture = GL_FALSE; + } + else { + const struct gl_fragment_program *fprog + = ctx->FragmentProgram._Current; + if (fprog && (fprog->Base.OutputsWritten & (1 << FRAG_RESULT_DEPR))) { + /* Z comes from fragment program/shader */ + swrast->_DeferredTexture = GL_FALSE; + } + else if (ctx->Query.CurrentOcclusionObject) { + /* occlusion query depends on shader discard/kill results */ + swrast->_DeferredTexture = GL_FALSE; + } + else { + swrast->_DeferredTexture = GL_TRUE; + } + } +} + + +/** * Update swrast->_FogColor and swrast->_FogEnable values. */ static void @@ -324,7 +355,6 @@ _swrast_validate_line( GLcontext *ctx, const SWvertex *v0, const SWvertex *v1 ) swrast->Line = _swrast_add_spec_terms_line; } - swrast->Line( ctx, v0, v1 ); } @@ -505,50 +535,59 @@ _swrast_update_texture_samplers(GLcontext *ctx) /** - * Update swrast->_ActiveAttribs and swrast->_NumActiveAttribs + * Update swrast->_ActiveAttribs, swrast->_NumActiveAttribs, swrast->_ActiveAtttribMask. */ static void _swrast_update_fragment_attribs(GLcontext *ctx) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint attribsMask; - + + /* + * Compute _ActiveAttribsMask = which fragment attributes are needed. + */ if (ctx->FragmentProgram._Current) { + /* fragment program/shader */ attribsMask = ctx->FragmentProgram._Current->Base.InputsRead; + attribsMask &= ~FRAG_BIT_WPOS; /* WPOS is always handled specially */ + } + else if (ctx->ATIFragmentShader._Enabled) { + attribsMask = ~0; /* XXX fix me */ } else { - GLuint u; + /* fixed function */ attribsMask = 0x0; -#if 0 /* not yet */ - if (ctx->Depth.Test) - attribsMask |= FRAG_BIT_WPOS; - if (NEED_SECONDARY_COLOR(ctx)) - attribsMask |= FRAG_BIT_COL1; +#if CHAN_TYPE == GL_FLOAT + attribsMask |= FRAG_BIT_COL0; #endif + + if (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { + attribsMask |= FRAG_BIT_COL1; + } + if (swrast->_FogEnabled) attribsMask |= FRAG_BIT_FOGC; - for (u = 0; u < ctx->Const.MaxTextureUnits; u++) { - if (ctx->Texture.Unit[u]._ReallyEnabled) { - attribsMask |= FRAG_BIT_TEX(u); - } - } + attribsMask |= (ctx->Texture._EnabledUnits << FRAG_ATTRIB_TEX0); } - /* don't want to interpolate these generic attribs just yet */ - /* XXX temporary */ - attribsMask &= ~(FRAG_BIT_WPOS | - FRAG_BIT_COL0 | - FRAG_BIT_COL1 | - FRAG_BIT_FOGC); + swrast->_ActiveAttribMask = attribsMask; /* Update _ActiveAttribs[] list */ { GLuint i, num = 0; for (i = 0; i < FRAG_ATTRIB_MAX; i++) { - if (attribsMask & (1 << i)) + if (attribsMask & (1 << i)) { swrast->_ActiveAttribs[num++] = i; + /* how should this attribute be interpolated? */ + if (i == FRAG_ATTRIB_COL0 || i == FRAG_ATTRIB_COL1) + swrast->_InterpMode[i] = ctx->Light.ShadeModel; + else + swrast->_InterpMode[i] = GL_SMOOTH; + } } swrast->_NumActiveAttribs = num; } @@ -627,14 +666,19 @@ _swrast_validate_derived( GLcontext *ctx ) if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) _swrast_update_texture_samplers( ctx ); - if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) - _swrast_validate_texture_images( ctx ); + if (swrast->NewState & (_NEW_TEXTURE | _NEW_PROGRAM)) { + _swrast_validate_texture_images(ctx); + if (swrast->NewState & (_NEW_COLOR)) { + _swrast_update_deferred_texture(ctx); + } + } if (swrast->NewState & _SWRAST_NEW_RASTERMASK) _swrast_update_rasterflags( ctx ); if (swrast->NewState & (_NEW_DEPTH | _NEW_FOG | + _NEW_LIGHT | _NEW_PROGRAM | _NEW_TEXTURE)) _swrast_update_fragment_attribs(ctx); @@ -787,14 +831,11 @@ _swrast_CreateContext( GLcontext *ctx ) } swrast->SpanArrays->ChanType = CHAN_TYPE; #if CHAN_TYPE == GL_UNSIGNED_BYTE - swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz1.rgba; - swrast->SpanArrays->spec = swrast->SpanArrays->color.sz1.spec; + swrast->SpanArrays->rgba = swrast->SpanArrays->rgba8; #elif CHAN_TYPE == GL_UNSIGNED_SHORT - swrast->SpanArrays->rgba = swrast->SpanArrays->color.sz2.rgba; - swrast->SpanArrays->spec = swrast->SpanArrays->color.sz2.spec; + swrast->SpanArrays->rgba = swrast->SpanArrays->rgba16; #else swrast->SpanArrays->rgba = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL0]; - swrast->SpanArrays->spec = swrast->SpanArrays->attribs[FRAG_ATTRIB_COL1]; #endif /* init point span buffer */ @@ -896,7 +937,10 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) 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]); + v->attrib[FRAG_ATTRIB_WPOS][0], + v->attrib[FRAG_ATTRIB_WPOS][1], + v->attrib[FRAG_ATTRIB_WPOS][2], + v->attrib[FRAG_ATTRIB_WPOS][3]); for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) if (ctx->Texture.Unit[i]._ReallyEnabled) @@ -909,18 +953,17 @@ _swrast_print_vertex( GLcontext *ctx, const SWvertex *v ) #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, "spec %g %g %g %g\n", + v->attrib[FRAG_ATTRIB_COL1][0], + v->attrib[FRAG_ATTRIB_COL1][1], + v->attrib[FRAG_ATTRIB_COL1][2], + v->attrib[FRAG_ATTRIB_COL1][3]); _mesa_debug(ctx, "fog %f\n", v->attrib[FRAG_ATTRIB_FOGC][0]); - _mesa_debug(ctx, "index %d\n", v->index); + _mesa_debug(ctx, "index %d\n", v->attrib[FRAG_ATTRIB_CI][0]); _mesa_debug(ctx, "pointsize %f\n", v->pointSize); _mesa_debug(ctx, "\n"); } diff --git a/src/mesa/swrast/s_context.h b/src/mesa/swrast/s_context.h index c8333b8e0a1..f118eb92ca4 100644 --- a/src/mesa/swrast/s_context.h +++ b/src/mesa/swrast/s_context.h @@ -132,6 +132,7 @@ typedef struct GLboolean _PreferPixelFog; /* Compute fog blend factor per fragment? */ GLboolean _AnyTextureCombine; GLboolean _FogEnabled; + GLboolean _DeferredTexture; GLenum _FogMode; /* either GL_FOG_MODE or fragment program's fog mode */ /** Multiple render targets */ @@ -140,8 +141,12 @@ typedef struct /** List/array of the fragment attributes to interpolate */ GLuint _ActiveAttribs[FRAG_ATTRIB_MAX]; + /** Same info, but as a bitmask */ + GLbitfield _ActiveAttribMask; /** Number of fragment attributes to interpolate */ GLuint _NumActiveAttribs; + /** Indicates how each attrib is to be interpolated (lines/tris) */ + GLenum _InterpMode[FRAG_ATTRIB_MAX]; /* GL_FLAT or GL_SMOOTH (for now) */ /* Accum buffer temporaries. */ diff --git a/src/mesa/swrast/s_copypix.c b/src/mesa/swrast/s_copypix.c index 012839cb88a..53e584b3b6b 100644 --- a/src/mesa/swrast/s_copypix.c +++ b/src/mesa/swrast/s_copypix.c @@ -94,7 +94,6 @@ 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); GLint row; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; const GLbitfield transferOps = ctx->_ImageTransferState; @@ -104,12 +103,7 @@ copy_conv_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, SWspan span; INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); - - if (ctx->Depth.Test) - _swrast_span_default_z(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - _swrast_span_default_secondary_color(ctx, &span); + _swrast_span_default_attribs(ctx, &span); /* allocate space for GLfloat image */ tmpImage = (GLfloat *) _mesa_malloc(width * height * 4 * sizeof(GLfloat)); @@ -194,7 +188,6 @@ static void copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLfloat *tmpImage, *p; GLint sy, dy, stepy, row; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0F || ctx->Pixel.ZoomY != 1.0F; @@ -240,11 +233,7 @@ copy_rgba_pixels(GLcontext *ctx, GLint srcx, GLint srcy, } INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); - if (ctx->Depth.Test) - _swrast_span_default_z(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - _swrast_span_default_secondary_color(ctx, &span); + _swrast_span_default_attribs(ctx, &span); if (overlapping) { tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat) * 4); @@ -313,7 +302,6 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); GLuint *tmpImage,*p; GLint sy, dy, stepy; GLint j; @@ -327,6 +315,7 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, } INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX); + _swrast_span_default_attribs(ctx, &span); if (ctx->DrawBuffer == ctx->ReadBuffer) { overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, @@ -350,11 +339,6 @@ copy_ci_pixels( GLcontext *ctx, GLint srcx, GLint srcy, stepy = 1; } - if (ctx->Depth.Test) - _swrast_span_default_z(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - if (overlapping) { GLint ssy = sy; tmpImage = (GLuint *) _mesa_malloc(width * height * sizeof(GLuint)); @@ -450,7 +434,6 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, GLint width, GLint height, GLint destx, GLint desty ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); struct gl_framebuffer *fb = ctx->ReadBuffer; struct gl_renderbuffer *readRb = fb->_DepthBuffer; GLfloat *p, *tmpImage; @@ -466,6 +449,7 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, } INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z); + _swrast_span_default_attribs(ctx, &span); if (ctx->DrawBuffer == ctx->ReadBuffer) { overlapping = regions_overlap(srcx, srcy, destx, desty, width, height, @@ -489,11 +473,6 @@ copy_depth_pixels( GLcontext *ctx, GLint srcx, GLint srcy, stepy = 1; } - _swrast_span_default_color(ctx, &span); - _swrast_span_default_secondary_color(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - if (overlapping) { GLint ssy = sy; tmpImage = (GLfloat *) _mesa_malloc(width * height * sizeof(GLfloat)); diff --git a/src/mesa/swrast/s_drawpix.c b/src/mesa/swrast/s_drawpix.c index cd5b7bc2935..d971d90fb9a 100644 --- a/src/mesa/swrast/s_drawpix.c +++ b/src/mesa/swrast/s_drawpix.c @@ -71,13 +71,7 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, } INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); - _swrast_span_default_secondary_color(ctx, &span); - if (ctx->Depth.Test) - _swrast_span_default_z(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - if (ctx->Texture._EnabledCoordUnits) - _swrast_span_default_texcoords(ctx, &span); + _swrast_span_default_attribs(ctx, &span); /* copy input params since clipping may change them */ unpack = *userUnpack; @@ -274,9 +268,9 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, for (row = 0; row < drawHeight; row++) { ASSERT(drawWidth <= MAX_WIDTH); _mesa_map_ci8_to_rgba8(ctx, drawWidth, src, - span.array->color.sz1.rgba); + span.array->rgba8); rb->PutRow(ctx, rb, drawWidth, destX, destY, - span.array->color.sz1.rgba, NULL); + span.array->rgba8, NULL); src += unpack.RowLength; destY += yStep; } @@ -287,12 +281,12 @@ fast_draw_rgba_pixels(GLcontext *ctx, GLint x, GLint y, for (row = 0; row < drawHeight; row++) { ASSERT(drawWidth <= MAX_WIDTH); _mesa_map_ci8_to_rgba8(ctx, drawWidth, src, - span.array->color.sz1.rgba); + span.array->rgba8); span.x = destX; span.y = destY; span.end = drawWidth; _swrast_write_zoomed_rgba_span(ctx, imgX, imgY, &span, - span.array->color.sz1.rgba); + span.array->rgba8); src += unpack.RowLength; destY++; } @@ -333,18 +327,13 @@ draw_index_pixels( GLcontext *ctx, GLint x, GLint y, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLint imgX = x, imgY = y; const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; GLint row, skipPixels; SWspan span; INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_INDEX); - - if (ctx->Depth.Test) - _swrast_span_default_z(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); + _swrast_span_default_attribs(ctx, &span); /* * General solution @@ -433,20 +422,13 @@ draw_depth_pixels( GLcontext *ctx, GLint x, GLint y, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLboolean scaleOrBias = ctx->Pixel.DepthScale != 1.0 || ctx->Pixel.DepthBias != 0.0; const GLboolean zoom = ctx->Pixel.ZoomX != 1.0 || ctx->Pixel.ZoomY != 1.0; SWspan span; INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_Z); - - _swrast_span_default_color(ctx, &span); - _swrast_span_default_secondary_color(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - if (ctx->Texture._EnabledCoordUnits) - _swrast_span_default_texcoords(ctx, &span); + _swrast_span_default_attribs(ctx, &span); if (type == GL_UNSIGNED_SHORT && ctx->DrawBuffer->Visual.depthBits == 16 @@ -550,7 +532,6 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels ) { - SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLint imgX = x, imgY = y; const GLboolean zoom = ctx->Pixel.ZoomX!=1.0 || ctx->Pixel.ZoomY!=1.0; GLfloat *convImage = NULL; @@ -562,14 +543,8 @@ draw_rgba_pixels( GLcontext *ctx, GLint x, GLint y, unpack, pixels)) return; - INIT_SPAN(span, GL_BITMAP, 0, 0, SPAN_RGBA); - _swrast_span_default_secondary_color(ctx, &span); - if (ctx->Depth.Test) - _swrast_span_default_z(ctx, &span); - if (swrast->_FogEnabled) - _swrast_span_default_fog(ctx, &span); - if (ctx->Texture._EnabledCoordUnits) - _swrast_span_default_texcoords(ctx, &span); + INIT_SPAN(span, GL_BITMAP, 0, 0x0, SPAN_RGBA); + _swrast_span_default_attribs(ctx, &span); if (ctx->Pixel.Convolution2DEnabled || ctx->Pixel.Separable2DEnabled) { /* Convolution has to be handled specially. We'll create an diff --git a/src/mesa/swrast/s_feedback.c b/src/mesa/swrast/s_feedback.c index 3a15d0c3675..606afc63ba9 100644 --- a/src/mesa/swrast/s_feedback.c +++ b/src/mesa/swrast/s_feedback.c @@ -42,17 +42,17 @@ feedback_vertex(GLcontext * ctx, const SWvertex * v, const SWvertex * pv) GLfloat color[4]; const GLfloat *vtc = v->attrib[FRAG_ATTRIB_TEX0]; - win[0] = v->win[0]; - win[1] = v->win[1]; - win[2] = v->win[2] / ctx->DrawBuffer->_DepthMaxF; - win[3] = 1.0F / v->win[3]; + win[0] = v->attrib[FRAG_ATTRIB_WPOS][0]; + win[1] = v->attrib[FRAG_ATTRIB_WPOS][1]; + win[2] = v->attrib[FRAG_ATTRIB_WPOS][2] / ctx->DrawBuffer->_DepthMaxF; + win[3] = 1.0F / v->attrib[FRAG_ATTRIB_WPOS][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]); - _mesa_feedback_vertex(ctx, win, color, (GLfloat) v->index, vtc); + _mesa_feedback_vertex(ctx, win, color, v->attrib[FRAG_ATTRIB_CI][0], vtc); } @@ -120,9 +120,10 @@ _swrast_select_triangle(GLcontext *ctx, const SWvertex *v0, { if (_swrast_culltriangle(ctx, v0, v1, v2)) { const GLfloat zs = 1.0F / ctx->DrawBuffer->_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); + + _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs ); + _mesa_update_hitflag( ctx, v1->attrib[FRAG_ATTRIB_WPOS][2] * zs ); + _mesa_update_hitflag( ctx, v2->attrib[FRAG_ATTRIB_WPOS][2] * zs ); } } @@ -131,8 +132,8 @@ void _swrast_select_line(GLcontext *ctx, const SWvertex *v0, const SWvertex *v1) { const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; - _mesa_update_hitflag(ctx, v0->win[2] * zs); - _mesa_update_hitflag(ctx, v1->win[2] * zs); + _mesa_update_hitflag( ctx, v0->attrib[FRAG_ATTRIB_WPOS][2] * zs ); + _mesa_update_hitflag( ctx, v1->attrib[FRAG_ATTRIB_WPOS][2] * zs ); } @@ -140,5 +141,5 @@ void _swrast_select_point(GLcontext *ctx, const SWvertex *v) { const GLfloat zs = 1.0F / ctx->DrawBuffer->_DepthMaxF; - _mesa_update_hitflag(ctx, v->win[2] * zs); + _mesa_update_hitflag( ctx, v->attrib[FRAG_ATTRIB_WPOS][2] * zs ); } diff --git a/src/mesa/swrast/s_fog.c b/src/mesa/swrast/s_fog.c index 433fc4a4d0c..ed47964a66a 100644 --- a/src/mesa/swrast/s_fog.c +++ b/src/mesa/swrast/s_fog.c @@ -65,30 +65,92 @@ _swrast_z_to_fogfactor(GLcontext *ctx, GLfloat z) } +#define LINEAR_FOG(f, coord) f = (fogEnd - coord) * fogScale + +#define EXP_FOG(f, coord) f = EXPF(density * coord) + +#define EXP2_FOG(f, coord) \ +do { \ + GLfloat tmp = negDensitySquared * coord * coord; \ + if (tmp < FLT_MIN_10_EXP) \ + tmp = FLT_MIN_10_EXP; \ + f = EXPF(tmp); \ + } while(0) + + +#define BLEND_FOG(f, coord) f = coord + + + /** * Template code for computing fog blend factor and applying it to colors. * \param TYPE either GLubyte, GLushort or GLfloat. * \param COMPUTE_F code to compute the fog blend factor, f. */ -#define FOG_LOOP(TYPE, COMPUTE_F) \ -do { \ - const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \ - GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \ - const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F;\ - GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; \ - GLuint i; \ - for (i = 0; i < span->end; i++) { \ - GLfloat f, oneMinusF; \ - COMPUTE_F; \ - f = CLAMP(f, 0.0F, 1.0F); \ - oneMinusF = 1.0F - f; \ - rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \ - rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \ - rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \ - fogCoord += fogStep; \ - w += wStep; \ - } \ -} while (0) +#define FOG_LOOP(TYPE, FOG_FUNC) \ +if (span->arrayAttribs & FRAG_BIT_FOGC) { \ + GLuint i; \ + for (i = 0; i < span->end; i++) { \ + const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; \ + const GLfloat c = FABSF(fogCoord); \ + GLfloat f, oneMinusF; \ + FOG_FUNC(f, c); \ + f = CLAMP(f, 0.0F, 1.0F); \ + oneMinusF = 1.0F - f; \ + rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \ + rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \ + rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \ + } \ +} \ +else { \ + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \ + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \ + const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3]; \ + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; \ + GLuint i; \ + for (i = 0; i < span->end; i++) { \ + const GLfloat c = FABSF(fogCoord) / w; \ + GLfloat f, oneMinusF; \ + FOG_FUNC(f, c); \ + f = CLAMP(f, 0.0F, 1.0F); \ + oneMinusF = 1.0F - f; \ + rgba[i][RCOMP] = (TYPE) (f * rgba[i][RCOMP] + oneMinusF * rFog); \ + rgba[i][GCOMP] = (TYPE) (f * rgba[i][GCOMP] + oneMinusF * gFog); \ + rgba[i][BCOMP] = (TYPE) (f * rgba[i][BCOMP] + oneMinusF * bFog); \ + fogCoord += fogStep; \ + w += wStep; \ + } \ +} + +/* As above, but CI mode (XXX try to merge someday) */ +#define FOG_LOOP_CI(FOG_FUNC) \ +if (span->arrayAttribs & FRAG_BIT_FOGC) { \ + GLuint i; \ + for (i = 0; i < span->end; i++) { \ + const GLfloat fogCoord = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; \ + const GLfloat c = FABSF(fogCoord); \ + GLfloat f; \ + FOG_FUNC(f, c); \ + f = CLAMP(f, 0.0F, 1.0F); \ + index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); \ + } \ +} \ +else { \ + const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; \ + GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; \ + const GLfloat wStep = span->attrStepX[FRAG_ATTRIB_WPOS][3]; \ + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; \ + GLuint i; \ + for (i = 0; i < span->end; i++) { \ + const GLfloat c = FABSF(fogCoord) / w; \ + GLfloat f; \ + FOG_FUNC(f, c); \ + f = CLAMP(f, 0.0F, 1.0F); \ + index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); \ + fogCoord += fogStep; \ + w += wStep; \ + } \ +} @@ -104,12 +166,12 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) { const SWcontext *swrast = SWRAST_CONTEXT(ctx); GLfloat rFog, gFog, bFog; - const GLuint haveW = (span->interpMask & SPAN_W); ASSERT(swrast->_FogEnabled); - ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG); + ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_FOGC); ASSERT(span->arrayMask & SPAN_RGBA); + /* compute (scaled) fog color */ if (span->array->ChanType == GL_UNSIGNED_BYTE) { rFog = ctx->Fog.Color[RCOMP] * 255.0; gFog = ctx->Fog.Color[GCOMP] * 255.0; @@ -126,79 +188,68 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) bFog = ctx->Fog.Color[BCOMP]; } - - /* NOTE: if haveW is true, that means the fog start/step values are - * perspective-corrected and we have to divide each fog coord by W. - */ - - /* we need to compute fog blend factors */ if (swrast->_PreferPixelFog) { /* The span's fog values are fog coordinates, now compute blend factors * and blend the fragment colors with the fog color. */ - const GLfloat fogEnd = ctx->Fog.End; - const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) - ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); - const GLfloat density = -ctx->Fog.Density; - const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; - switch (swrast->_FogMode) { case GL_LINEAR: -#define COMPUTE_F f = (fogEnd - FABSF(fogCoord) / w) * fogScale; - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; - FOG_LOOP(GLubyte, COMPUTE_F); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; - FOG_LOOP(GLushort, COMPUTE_F); - } - else { - GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; - ASSERT(span->array->ChanType == GL_FLOAT); - FOG_LOOP(GLfloat, COMPUTE_F); + { + const GLfloat fogEnd = ctx->Fog.End; + const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) + ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = span->array->rgba8; + FOG_LOOP(GLubyte, LINEAR_FOG); + } + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = span->array->rgba16; + FOG_LOOP(GLushort, LINEAR_FOG); + } + else { + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + ASSERT(span->array->ChanType == GL_FLOAT); + FOG_LOOP(GLfloat, LINEAR_FOG); + } } -#undef COMPUTE_F break; case GL_EXP: -#define COMPUTE_F f = EXPF(density * FABSF(fogCoord) / w); - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; - FOG_LOOP(GLubyte, COMPUTE_F); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; - FOG_LOOP(GLushort, COMPUTE_F); - } - else { - GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; - ASSERT(span->array->ChanType == GL_FLOAT); - FOG_LOOP(GLfloat, COMPUTE_F); + { + const GLfloat density = -ctx->Fog.Density; + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = span->array->rgba8; + FOG_LOOP(GLubyte, EXP_FOG); + } + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = span->array->rgba16; + FOG_LOOP(GLushort, EXP_FOG); + } + else { + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + ASSERT(span->array->ChanType == GL_FLOAT); + FOG_LOOP(GLfloat, EXP_FOG); + } } -#undef COMPUTE_F break; case GL_EXP2: -#define COMPUTE_F const GLfloat coord = fogCoord / w; \ - GLfloat tmp = negDensitySquared * coord * coord; \ - if (tmp < FLT_MIN_10_EXP) \ - tmp = FLT_MIN_10_EXP; \ - f = EXPF(tmp); - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; - FOG_LOOP(GLubyte, COMPUTE_F); - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; - FOG_LOOP(GLushort, COMPUTE_F); - } - else { - GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; - ASSERT(span->array->ChanType == GL_FLOAT); - FOG_LOOP(GLfloat, COMPUTE_F); + { + const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; + if (span->array->ChanType == GL_UNSIGNED_BYTE) { + GLubyte (*rgba)[4] = span->array->rgba8; + FOG_LOOP(GLubyte, EXP2_FOG); + } + else if (span->array->ChanType == GL_UNSIGNED_SHORT) { + GLushort (*rgba)[4] = span->array->rgba16; + FOG_LOOP(GLushort, EXP2_FOG); + } + else { + GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + ASSERT(span->array->ChanType == GL_FLOAT); + FOG_LOOP(GLfloat, EXP2_FOG); + } } -#undef COMPUTE_F break; default: @@ -206,63 +257,23 @@ _swrast_fog_rgba_span( const GLcontext *ctx, SWspan *span ) return; } } - else if (span->arrayMask & SPAN_FOG) { - /* The span's fog array values are blend factors. - * They were previously computed per-vertex. - */ - GLuint i; - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; - for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; - const GLfloat oneMinusF = 1.0F - f; - rgba[i][RCOMP] = (GLubyte) (f * rgba[i][RCOMP] + oneMinusF * rFog); - rgba[i][GCOMP] = (GLubyte) (f * rgba[i][GCOMP] + oneMinusF * gFog); - rgba[i][BCOMP] = (GLubyte) (f * rgba[i][BCOMP] + oneMinusF * bFog); - } - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; - for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; - const GLfloat oneMinusF = 1.0F - f; - rgba[i][RCOMP] = (GLushort) (f * rgba[i][RCOMP] + oneMinusF * rFog); - rgba[i][GCOMP] = (GLushort) (f * rgba[i][GCOMP] + oneMinusF * gFog); - rgba[i][BCOMP] = (GLushort) (f * rgba[i][BCOMP] + oneMinusF * bFog); - } - } - else { - GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; - ASSERT(span->array->ChanType == GL_FLOAT); - for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; - const GLfloat oneMinusF = 1.0F - f; - rgba[i][RCOMP] = f * rgba[i][RCOMP] + oneMinusF * rFog; - rgba[i][GCOMP] = f * rgba[i][GCOMP] + oneMinusF * gFog; - rgba[i][BCOMP] = f * rgba[i][BCOMP] + oneMinusF * bFog; - } - } - - } else { - /* The span's fog start/step values are blend factors. + /* The span's fog start/step/array values are blend factors in [0,1]. * They were previously computed per-vertex. */ -#define COMPUTE_F f = fogCoord / w; if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; - FOG_LOOP(GLubyte, COMPUTE_F); + GLubyte (*rgba)[4] = span->array->rgba8; + FOG_LOOP(GLubyte, BLEND_FOG); } else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; - FOG_LOOP(GLushort, COMPUTE_F); + GLushort (*rgba)[4] = span->array->rgba16; + FOG_LOOP(GLushort, BLEND_FOG); } else { GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; ASSERT(span->array->ChanType == GL_FLOAT); - FOG_LOOP(GLfloat, COMPUTE_F); + FOG_LOOP(GLfloat, BLEND_FOG); } -#undef COMPUTE_F } } @@ -274,13 +285,11 @@ void _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) { const SWcontext *swrast = SWRAST_CONTEXT(ctx); - const GLuint haveW = (span->interpMask & SPAN_W); const GLuint fogIndex = (GLuint) ctx->Fog.Index; GLuint *index = span->array->index; ASSERT(swrast->_FogEnabled); ASSERT(span->arrayMask & SPAN_INDEX); - ASSERT((span->interpMask | span->arrayMask) & SPAN_FOG); /* we need to compute fog blend factors */ if (swrast->_PreferPixelFog) { @@ -293,60 +302,19 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) const GLfloat fogEnd = ctx->Fog.End; const GLfloat fogScale = (ctx->Fog.Start == ctx->Fog.End) ? 1.0F : 1.0F / (ctx->Fog.End - ctx->Fog.Start); - const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; - GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; - GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; - GLuint i; - for (i = 0; i < span->end; i++) { - GLfloat f = (fogEnd - fogCoord / w) * fogScale; - f = CLAMP(f, 0.0F, 1.0F); - index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); - fogCoord += fogStep; - w += wStep; - } + FOG_LOOP_CI(LINEAR_FOG); } break; case GL_EXP: { const GLfloat density = -ctx->Fog.Density; - const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; - GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; - GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; - GLuint i; - for (i = 0; i < span->end; i++) { - GLfloat f = EXPF(density * fogCoord / w); - f = CLAMP(f, 0.0F, 1.0F); - index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); - fogCoord += fogStep; - w += wStep; - } + FOG_LOOP_CI(EXP_FOG); } break; case GL_EXP2: { const GLfloat negDensitySquared = -ctx->Fog.Density * ctx->Fog.Density; - const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; - GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; - GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; - GLuint i; - for (i = 0; i < span->end; i++) { - const GLfloat coord = fogCoord / w; - GLfloat tmp = negDensitySquared * coord * coord; - GLfloat f; -#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 - f = EXPF(tmp); - f = CLAMP(f, 0.0F, 1.0F); - index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); - fogCoord += fogStep; - w += wStep; - } + FOG_LOOP_CI(EXP2_FOG); } break; default: @@ -354,31 +322,10 @@ _swrast_fog_ci_span( const GLcontext *ctx, SWspan *span ) return; } } - else if (span->arrayMask & SPAN_FOG) { - /* The span's fog array values are blend factors. - * They were previously computed per-vertex. - */ - GLuint i; - for (i = 0; i < span->end; i++) { - const GLfloat f = span->array->attribs[FRAG_ATTRIB_FOGC][i][0]; - index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); - } - } else { - /* The span's fog start/step values are blend factors. + /* The span's fog start/step/array values are blend factors in [0,1]. * They were previously computed per-vertex. */ - const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; - GLfloat fog = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; - GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; - GLuint i; - ASSERT(span->interpMask & SPAN_FOG); - for (i = 0; i < span->end; i++) { - const GLfloat f = fog / w; - index[i] = (GLuint) ((GLfloat) index[i] + (1.0F - f) * fogIndex); - fog += fogStep; - w += wStep; - } + FOG_LOOP_CI(BLEND_FOG); } } diff --git a/src/mesa/swrast/s_lines.c b/src/mesa/swrast/s_lines.c index 80702e41a3c..781146e67f9 100644 --- a/src/mesa/swrast/s_lines.c +++ b/src/mesa/swrast/s_lines.c @@ -121,29 +121,29 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor ) /**********************************************************************/ /* Simple color index line (no stipple, width=1, no Z, no fog, no tex)*/ -#define NAME simple_ci_line +#define NAME simple_no_z_ci_line #define INTERP_INDEX #define RENDER_SPAN(span) _swrast_write_index_span(ctx, &span) #include "s_linetemp.h" /* Simple RGBA index line (no stipple, width=1, no Z, no fog, no tex)*/ -#define NAME simple_rgba_line +#define NAME simple_no_z_rgba_line #define INTERP_RGBA #define RENDER_SPAN(span) _swrast_write_rgba_span(ctx, &span); #include "s_linetemp.h" /* Z, fog, wide, stipple color index line */ -#define NAME general_ci_line +#define NAME ci_line #define INTERP_INDEX #define INTERP_Z -#define INTERP_FOG +#define INTERP_ATTRIBS /* for fog */ #define RENDER_SPAN(span) \ if (ctx->Line.StippleFlag) { \ span.arrayMask |= SPAN_MASK; \ compute_stipple_mask(ctx, span.end, span.array->mask); \ } \ - if (ctx->Line._Width > 1.0) { \ + if (ctx->Line._Width > 1.0) { \ draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ } \ else { \ @@ -153,16 +153,15 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor ) /* Z, fog, wide, stipple RGBA line */ -#define NAME general_rgba_line +#define NAME rgba_line #define INTERP_RGBA #define INTERP_Z -#define INTERP_FOG #define RENDER_SPAN(span) \ if (ctx->Line.StippleFlag) { \ span.arrayMask |= SPAN_MASK; \ compute_stipple_mask(ctx, span.end, span.array->mask); \ } \ - if (ctx->Line._Width > 1.0) { \ + if (ctx->Line._Width > 1.0) { \ draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ } \ else { \ @@ -171,19 +170,17 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor ) #include "s_linetemp.h" -/* General-purpose textured line (any/all features). */ -#define NAME textured_line +/* General-purpose line (any/all features). */ +#define NAME general_line #define INTERP_RGBA -#define INTERP_SPEC #define INTERP_Z -#define INTERP_FOG #define INTERP_ATTRIBS #define RENDER_SPAN(span) \ if (ctx->Line.StippleFlag) { \ span.arrayMask |= SPAN_MASK; \ compute_stipple_mask(ctx, span.end, span.array->mask); \ } \ - if (ctx->Line._Width > 1.0) { \ + if (ctx->Line._Width > 1.0) { \ draw_wide_line(ctx, &span, (GLboolean)(dx > dy)); \ } \ else { \ @@ -194,48 +191,39 @@ draw_wide_line( GLcontext *ctx, SWspan *span, GLboolean xMajor ) void -_swrast_add_spec_terms_line( GLcontext *ctx, - const SWvertex *v0, - const SWvertex *v1 ) +_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 ); + GLfloat rSum, gSum, bSum; + GLchan cSave[2][4]; + + /* save original colors */ + COPY_CHAN4(cSave[0], ncv0->color); + COPY_CHAN4(cSave[1], ncv1->color); + /* sum v0 */ + rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0]; + gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1]; + bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2]; + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); + /* sum v1 */ + rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0]; + gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1]; + bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2]; + UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum); + /* draw */ SWRAST_CONTEXT(ctx)->SpecLine( ctx, ncv0, ncv1 ); - COPY_CHAN4( ncv0->color, c[0] ); - COPY_CHAN4( ncv1->color, c[1] ); + /* restore original colors */ + COPY_CHAN4( ncv0->attrib[FRAG_ATTRIB_COL0], cSave[0] ); + COPY_CHAN4( ncv1->attrib[FRAG_ATTRIB_COL0], cSave[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 == simple_ci_line) - _mesa_printf("simple_ci_line\n"); - else if (swrast->Line == simple_rgba_line) - _mesa_printf("simple_rgba_line\n"); - else if (swrast->Line == general_ci_line) - _mesa_printf("general_ci_line\n"); - else if (swrast->Line == general_rgba_line) - _mesa_printf("general_rgba_line\n"); - else if (swrast->Line == textured_line) - _mesa_printf("textured_line\n"); - else - _mesa_printf("Driver func %p\n", (void *(*)()) swrast->Line); -} -#endif - - #ifdef DEBUG @@ -257,7 +245,7 @@ do { \ -/* +/** * Determine which line drawing function to use given the current * rendering context. * @@ -269,6 +257,9 @@ _swrast_choose_line( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); const GLboolean rgbmode = ctx->Visual.rgbMode; + GLboolean specular = (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); if (ctx->RenderMode == GL_RENDER) { if (ctx->Line.SmoothFlag) { @@ -277,24 +268,27 @@ _swrast_choose_line( GLcontext *ctx ) ASSERT(swrast->Line); } else if (ctx->Texture._EnabledCoordUnits - || ctx->FragmentProgram._Current) { - /* textured lines */ - USE(textured_line); + || ctx->FragmentProgram._Current + || swrast->_FogEnabled + || specular) { + USE(general_line); } - else if (ctx->Depth.Test || swrast->_FogEnabled || ctx->Line._Width != 1.0 + else if (ctx->Depth.Test + || ctx->Line._Width != 1.0 || ctx->Line.StippleFlag) { /* no texture, but Z, fog, width>1, stipple, etc. */ if (rgbmode) - USE(general_rgba_line); + USE(rgba_line); else - USE(general_ci_line); + USE(ci_line); } else { - /* simplest lines */ + ASSERT(!ctx->Depth.Test); + /* simple lines */ if (rgbmode) - USE(simple_rgba_line); + USE(simple_no_z_rgba_line); else - USE(simple_ci_line); + USE(simple_no_z_ci_line); } } else if (ctx->RenderMode == GL_FEEDBACK) { @@ -304,6 +298,4 @@ _swrast_choose_line( GLcontext *ctx ) ASSERT(ctx->RenderMode == GL_SELECT); USE(_swrast_select_line); } - - /*_mesa_print_line_function(ctx);*/ } diff --git a/src/mesa/swrast/s_linetemp.h b/src/mesa/swrast/s_linetemp.h index b6e8f287f45..55548f27b08 100644 --- a/src/mesa/swrast/s_linetemp.h +++ b/src/mesa/swrast/s_linetemp.h @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.0 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -31,9 +31,7 @@ * 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_RGBA - if defined, interpolate RGBA values - * INTERP_SPEC - if defined, interpolate specular RGB values * INTERP_INDEX - if defined, interpolate color index values * INTERP_ATTRIBS - if defined, interpolate attribs (texcoords, varying, etc) * @@ -72,10 +70,10 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) const SWcontext *swrast = SWRAST_CONTEXT(ctx); SWspan span; GLuint interpFlags = 0; - 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 x0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][0]; + GLint x1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][0]; + GLint y0 = (GLint) vert0->attrib[FRAG_ATTRIB_WPOS][1]; + GLint y1 = (GLint) vert1->attrib[FRAG_ATTRIB_WPOS][1]; GLint dx, dy; GLint numPixels; GLint xstep, ystep; @@ -104,8 +102,8 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) /* Cull primitives with malformed coordinates. */ { - GLfloat tmp = vert0->win[0] + vert0->win[1] - + vert1->win[0] + vert1->win[1]; + GLfloat tmp = vert0->attrib[FRAG_ATTRIB_WPOS][0] + vert0->attrib[FRAG_ATTRIB_WPOS][1] + + vert1->attrib[FRAG_ATTRIB_WPOS][0] + vert1->attrib[FRAG_ATTRIB_WPOS][1]; if (IS_INF_OR_NAN(tmp)) return; } @@ -113,8 +111,12 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) /* 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]); + vert0->attrib[FRAG_ATTRIB_WPOS][0], + vert0->attrib[FRAG_ATTRIB_WPOS][1], + vert0->attrib[FRAG_ATTRIB_WPOS][2], + vert1->attrib[FRAG_ATTRIB_WPOS][0], + vert1->attrib[FRAG_ATTRIB_WPOS][1], + vert1->attrib[FRAG_ATTRIB_WPOS][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]); @@ -154,6 +156,18 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) if (dx == 0 && dy == 0) return; + /* + printf("%s %d,%d %g %g %g %g %g %g %g %g\n", __FUNCTION__, dx, dy, + vert0->attrib[FRAG_ATTRIB_COL1][0], + vert0->attrib[FRAG_ATTRIB_COL1][1], + vert0->attrib[FRAG_ATTRIB_COL1][2], + vert0->attrib[FRAG_ATTRIB_COL1][3], + vert1->attrib[FRAG_ATTRIB_COL1][0], + vert1->attrib[FRAG_ATTRIB_COL1][1], + vert1->attrib[FRAG_ATTRIB_COL1][2], + vert1->attrib[FRAG_ATTRIB_COL1][3]); + */ + #ifdef DEPTH_TYPE zPtr = (DEPTH_TYPE *) zrb->GetPointer(ctx, zrb, x0, y0); #endif @@ -232,33 +246,15 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) span.alphaStep = 0; } #endif -#ifdef INTERP_SPEC - interpFlags |= SPAN_SPEC; - if (ctx->Light.ShadeModel == GL_SMOOTH) { - span.specRed = ChanToFixed(vert0->specular[0]); - span.specGreen = ChanToFixed(vert0->specular[1]); - span.specBlue = ChanToFixed(vert0->specular[2]); - span.specRedStep = (ChanToFixed(vert1->specular[0]) - span.specRed) / numPixels; - span.specGreenStep = (ChanToFixed(vert1->specular[1]) - span.specBlue) / numPixels; - span.specBlueStep = (ChanToFixed(vert1->specular[2]) - span.specGreen) / numPixels; - } - else { - 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; - } -#endif #ifdef INTERP_INDEX interpFlags |= SPAN_INDEX; if (ctx->Light.ShadeModel == GL_SMOOTH) { - span.index = FloatToFixed(vert0->index); - span.indexStep = FloatToFixed(vert1->index - vert0->index) / numPixels; + span.index = FloatToFixed(vert0->attrib[FRAG_ATTRIB_CI][0]); + span.indexStep = FloatToFixed( vert1->attrib[FRAG_ATTRIB_CI][0] + - vert0->attrib[FRAG_ATTRIB_CI][0]) / numPixels; } else { - span.index = FloatToFixed(vert1->index); + span.index = FloatToFixed(vert1->attrib[FRAG_ATTRIB_CI][0]); span.indexStep = 0; } #endif @@ -266,57 +262,49 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) interpFlags |= SPAN_Z; { if (depthBits <= 16) { - span.z = FloatToFixed(vert0->win[2]) + FIXED_HALF; - span.zStep = FloatToFixed(vert1->win[2] - vert0->win[2]) / numPixels; + span.z = FloatToFixed(vert0->attrib[FRAG_ATTRIB_WPOS][2]) + FIXED_HALF; + span.zStep = FloatToFixed( vert1->attrib[FRAG_ATTRIB_WPOS][2] + - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels; } else { /* don't use fixed point */ - span.z = (GLuint) vert0->win[2]; - span.zStep = (GLint) ((vert1->win[2] - vert0->win[2]) / numPixels); + span.z = (GLuint) vert0->attrib[FRAG_ATTRIB_WPOS][2]; + span.zStep = (GLint) (( vert1->attrib[FRAG_ATTRIB_WPOS][2] + - vert0->attrib[FRAG_ATTRIB_WPOS][2]) / numPixels); } } #endif -#ifdef INTERP_FOG - interpFlags |= SPAN_FOG; - span.attrStart[FRAG_ATTRIB_FOGC][0] = vert0->attrib[FRAG_ATTRIB_FOGC][0]; - span.attrStepX[FRAG_ATTRIB_FOGC][0] = (vert1->attrib[FRAG_ATTRIB_FOGC][0] - - vert0->attrib[FRAG_ATTRIB_FOGC][0]) / numPixels; -#endif #if defined(INTERP_ATTRIBS) - interpFlags |= (SPAN_TEXTURE | SPAN_VARYING); { const GLfloat invLen = 1.0F / numPixels; - const GLfloat invw0 = vert0->win[3]; - const GLfloat invw1 = vert1->win[3]; + const GLfloat invw0 = vert0->attrib[FRAG_ATTRIB_WPOS][3]; + const GLfloat invw1 = vert1->attrib[FRAG_ATTRIB_WPOS][3]; + + span.attrStart[FRAG_ATTRIB_WPOS][3] = invw0; + span.attrStepX[FRAG_ATTRIB_WPOS][3] = (invw1 - invw0) * invLen; + span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0; + ATTRIB_LOOP_BEGIN - GLfloat ds, dt, dr, dq; - span.attrStart[attr][0] = invw0 * vert0->attrib[attr][0]; - span.attrStart[attr][1] = invw0 * vert0->attrib[attr][1]; - span.attrStart[attr][2] = invw0 * vert0->attrib[attr][2]; - span.attrStart[attr][3] = invw0 * vert0->attrib[attr][3]; - ds = (invw1 * vert1->attrib[attr][0]) - span.attrStart[attr][0]; - dt = (invw1 * vert1->attrib[attr][1]) - span.attrStart[attr][1]; - dr = (invw1 * vert1->attrib[attr][2]) - span.attrStart[attr][2]; - dq = (invw1 * vert1->attrib[attr][3]) - span.attrStart[attr][3]; - span.attrStepX[attr][0] = ds * invLen; - span.attrStepX[attr][1] = dt * invLen; - span.attrStepX[attr][2] = dr * invLen; - span.attrStepX[attr][3] = dq * invLen; - span.attrStepY[attr][0] = 0.0F; - span.attrStepY[attr][1] = 0.0F; - span.attrStepY[attr][2] = 0.0F; - span.attrStepY[attr][3] = 0.0F; + if (swrast->_InterpMode[attr] == GL_FLAT) { + COPY_4V(span.attrStart[attr], vert1->attrib[attr]); + ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0); + } + else { + GLuint c; + for (c = 0; c < 4; c++) { + float da; + span.attrStart[attr][c] = invw0 * vert0->attrib[attr][c]; + da = (invw1 * vert1->attrib[attr][c]) - span.attrStart[attr][c]; + span.attrStepX[attr][c] = da * invLen; + } + } + ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0); ATTRIB_LOOP_END } #endif INIT_SPAN(span, GL_LINE, numPixels, interpFlags, SPAN_XY); - /* Need these for fragment prog texcoord interpolation */ - span.attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; - span.attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; - span.attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; - /* * Draw */ @@ -346,7 +334,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) #ifdef PIXEL_ADDRESS pixelPtr = (PIXEL_TYPE*) ((GLubyte*) pixelPtr + pixelXstep); #endif - if (error<0) { + if (error < 0) { error += errorInc; } else { @@ -413,9 +401,7 @@ NAME( GLcontext *ctx, const SWvertex *vert0, const SWvertex *vert1 ) #undef NAME #undef INTERP_Z -#undef INTERP_FOG #undef INTERP_RGBA -#undef INTERP_SPEC #undef INTERP_ATTRIBS #undef INTERP_INDEX #undef PIXEL_ADDRESS diff --git a/src/mesa/swrast/s_logic.c b/src/mesa/swrast/s_logic.c index e680732beed..0af9063968a 100644 --- a/src/mesa/swrast/s_logic.c +++ b/src/mesa/swrast/s_logic.c @@ -229,13 +229,13 @@ _swrast_logicop_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, if (span->array->ChanType == GL_UNSIGNED_BYTE) { /* treat 4*GLubyte as GLuint */ logicop_uint1(ctx, span->end, - (GLuint *) span->array->color.sz1.rgba, + (GLuint *) span->array->rgba8, (const GLuint *) rbPixels, span->array->mask); } else if (span->array->ChanType == GL_UNSIGNED_SHORT) { /* treat 2*GLushort as GLuint */ logicop_uint2(ctx, 2 * span->end, - (GLuint *) span->array->color.sz2.rgba, + (GLuint *) span->array->rgba16, (const GLuint *) rbPixels, span->array->mask); } else { diff --git a/src/mesa/swrast/s_masking.c b/src/mesa/swrast/s_masking.c index 8800f7d8e34..a69720e83ae 100644 --- a/src/mesa/swrast/s_masking.c +++ b/src/mesa/swrast/s_masking.c @@ -61,7 +61,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, const GLuint srcMask = *((GLuint *) ctx->Color.ColorMask); const GLuint dstMask = ~srcMask; const GLuint *dst = (const GLuint *) rbPixels; - GLuint *src = (GLuint *) span->array->color.sz1.rgba; + GLuint *src = (GLuint *) span->array->rgba8; GLuint i; for (i = 0; i < n; i++) { src[i] = (src[i] & srcMask) | (dst[i] & dstMask); @@ -75,7 +75,7 @@ _swrast_mask_rgba_span(GLcontext *ctx, struct gl_renderbuffer *rb, const GLushort bMask = ctx->Color.ColorMask[BCOMP] ? 0xffff : 0x0; const GLushort aMask = ctx->Color.ColorMask[ACOMP] ? 0xffff : 0x0; const GLushort (*dst)[4] = (const GLushort (*)[4]) rbPixels; - GLushort (*src)[4] = span->array->color.sz2.rgba; + GLushort (*src)[4] = span->array->rgba16; GLuint i; for (i = 0; i < n; i++) { src[i][RCOMP] = (src[i][RCOMP] & rMask) | (dst[i][RCOMP] & ~rMask); diff --git a/src/mesa/swrast/s_points.c b/src/mesa/swrast/s_points.c index 1401b772caf..02c9d9b4251 100644 --- a/src/mesa/swrast/s_points.c +++ b/src/mesa/swrast/s_points.c @@ -34,7 +34,6 @@ #include "s_span.h" - #define RGBA 0x1 #define INDEX 0x2 #define SMOOTH 0x4 @@ -154,16 +153,26 @@ #include "s_pointtemp.h" - -void _swrast_add_spec_terms_point( GLcontext *ctx, - const SWvertex *v0 ) +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] ); + SWvertex *ncv0 = (SWvertex *) v0; + GLfloat rSum, gSum, bSum; + GLchan cSave[4]; + + /* save */ + COPY_CHAN4( cSave, ncv0->color ); + /* sum */ + rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0]; + gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1]; + bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2]; + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); + /* draw */ + SWRAST_CONTEXT(ctx)->SpecPoint(ctx, ncv0); + /* restore */ + COPY_CHAN4(ncv0->color, cSave); } @@ -196,6 +205,9 @@ _swrast_choose_point( GLcontext *ctx ) { SWcontext *swrast = SWRAST_CONTEXT(ctx); GLboolean rgbMode = ctx->Visual.rgbMode; + GLboolean specular = (ctx->Fog.ColorSumEnabled || + (ctx->Light.Enabled && + ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)); if (ctx->RenderMode==GL_RENDER) { if (ctx->Point.PointSprite) { @@ -242,8 +254,10 @@ _swrast_choose_point( GLcontext *ctx ) USE(atten_general_ci_point); } } - else if (ctx->Texture._EnabledCoordUnits && rgbMode) { - /* textured */ + else if ((ctx->Texture._EnabledCoordUnits + || specular + || swrast->_FogEnabled) && rgbMode) { + /* textured, fogged */ USE(textured_rgba_point); } else if (ctx->Point._Size != 1.0) { @@ -258,6 +272,7 @@ _swrast_choose_point( GLcontext *ctx ) else { /* single pixel points */ if (rgbMode) { + assert((swrast->_ActiveAttribMask & FRAG_BIT_COL1) == 0); USE(size1_rgba_point); } else { diff --git a/src/mesa/swrast/s_pointtemp.h b/src/mesa/swrast/s_pointtemp.h index dddc2f7f40c..206085b5b87 100644 --- a/src/mesa/swrast/s_pointtemp.h +++ b/src/mesa/swrast/s_pointtemp.h @@ -40,7 +40,6 @@ * RGBA = do rgba instead of color index * SMOOTH = do antialiasing * ATTRIBS = general attributes (texcoords, etc) - * SPECULAR = do separate specular color * LARGE = do points with diameter > 1 pixel * ATTENUATE = compute point size attenuation * SPRITE = GL_ARB_point_sprite / GL_NV_point_sprite @@ -78,13 +77,8 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) 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 = (GLuint) vert->index; /* XXX round? */ + const GLuint colorIndex = (GLuint) vert->attrib[FRAG_ATTRIB_CI][0]; /* XXX round? */ #endif #if FLAGS & ATTRIBS GLfloat attrib[FRAG_ATTRIB_MAX][4]; /* texture & varying */ @@ -92,10 +86,22 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) SWcontext *swrast = SWRAST_CONTEXT(ctx); SWspan *span = &(swrast->PointSpan); + /* + printf("%s %g %g %g %g\n", __FUNCTION__, + vert->attrib[FRAG_ATTRIB_COL1][0], + vert->attrib[FRAG_ATTRIB_COL1][1], + vert->attrib[FRAG_ATTRIB_COL1][2], + vert->attrib[FRAG_ATTRIB_COL1][3]); + if ( vert->attrib[FRAG_ATTRIB_COL1][0] == 0.0 && + vert->attrib[FRAG_ATTRIB_COL1][1] == 1.0 && + vert->attrib[FRAG_ATTRIB_COL1][2] == 0.0) + foo(); + */ + /* Cull primitives with malformed coordinates. */ { - float tmp = vert->win[0] + vert->win[1]; + float tmp = vert->attrib[FRAG_ATTRIB_WPOS][0] + vert->attrib[FRAG_ATTRIB_WPOS][1]; if (IS_INF_OR_NAN(tmp)) return; } @@ -103,49 +109,37 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) /* * Span init */ - span->interpMask = SPAN_FOG; + span->interpMask = 0; span->arrayMask = SPAN_XY | SPAN_Z; - span->attrStart[FRAG_ATTRIB_FOGC][0] = vert->attrib[FRAG_ATTRIB_FOGC][0]; - span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; - span->attrStepY[FRAG_ATTRIB_FOGC][0] = 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 & ATTRIBS - span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); - if (ctx->FragmentProgram._Active) { - /* Don't divide texture s,t,r by q (use TXP to do that) */ - ATTRIB_LOOP_BEGIN - COPY_4V(attrib[attr], vert->attrib[attr]); - ATTRIB_LOOP_END - } - else { - /* Divide texture s,t,r by q here */ - ATTRIB_LOOP_BEGIN - const GLfloat q = vert->attrib[attr][3]; - const GLfloat invQ = (q == 0.0F || q == 1.0F) ? 1.0F : (1.0F / q); - attrib[attr][0] = vert->attrib[attr][0] * invQ; - attrib[attr][1] = vert->attrib[attr][1] * invQ; - attrib[attr][2] = vert->attrib[attr][2] * invQ; - attrib[attr][3] = q; - ATTRIB_LOOP_END - } + span->arrayMask |= SPAN_LAMBDA; + + /* we're filling in the attrib arrays: */ + span->arrayAttribs = swrast->_ActiveAttribMask; + + ATTRIB_LOOP_BEGIN + COPY_4V(attrib[attr], vert->attrib[attr]); + ATTRIB_LOOP_END + /* need these for fragment programs */ span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0F; span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0F; span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0F; +#else + assert((swrast->_ActiveAttribMask & FRAG_BIT_COL1) == 0); #endif + #if FLAGS & SMOOTH span->arrayMask |= SPAN_COVERAGE; #endif #if FLAGS & SPRITE - span->arrayMask |= (SPAN_TEXTURE | SPAN_LAMBDA); + span->arrayMask |= SPAN_LAMBDA; #endif /* Compute point size if not known to be one */ @@ -189,7 +183,7 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) {{ GLint x, y; const GLfloat radius = 0.5F * size; - const GLuint z = (GLuint) (vert->win[2] + 0.5F); + const GLuint z = (GLuint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); GLuint count; #if FLAGS & SMOOTH const GLfloat rmin = radius - 0.7071F; /* 0.7071 = sqrt(2)/2 */ @@ -197,10 +191,10 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) 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); + const GLint xmin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] - radius); + const GLint xmax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] + radius); + const GLint ymin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] - radius); + const GLint ymax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] + radius); #else /* non-smooth */ GLint xmin, xmax, ymin, ymax; @@ -210,16 +204,16 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) 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); + xmin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] - iRadius); + xmax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][0] + iRadius); + ymin = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] - iRadius); + ymax = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][1] + iRadius); } else { /* even size */ - xmin = (GLint) vert->win[0] - iRadius + 1; + xmin = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0] - iRadius + 1; xmax = xmin + iSize - 1; - ymin = (GLint) vert->win[1] - iRadius + 1; + ymin = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1] - iRadius + 1; ymax = ymin + iSize - 1; } #endif /*SMOOTH*/ @@ -264,29 +258,26 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) 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 & ATTRIBS ATTRIB_LOOP_BEGIN COPY_4V(span->array->attribs[attr][count], attrib[attr]); - if (attr < FRAG_ATTRIB_VAR0 && attr >= FRAG_ATTRIB_TEX0) { + /** + if (attr < FRAG_ATTRIB_VAR0) { const GLuint u = attr - FRAG_ATTRIB_TEX0; span->array->lambda[u][count] = 0.0; } + **/ ATTRIB_LOOP_END #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 dx = x - vert->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F; + const GLfloat dy = y - vert->attrib[FRAG_ATTRIB_WPOS][1] + 0.5F; const GLfloat dist2 = dx * dx + dy * dy; if (dist2 < rmax2) { if (dist2 >= rmin2) { @@ -327,12 +318,12 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) GLuint attr = FRAG_ATTRIB_TEX0 + u; if (ctx->Texture.Unit[u]._ReallyEnabled) { if (ctx->Point.CoordReplace[u]) { - GLfloat s = 0.5F + (x + 0.5F - vert->win[0]) / size; + GLfloat s = 0.5F + (x + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][0]) / size; GLfloat t, r; if (ctx->Point.SpriteOrigin == GL_LOWER_LEFT) - t = 0.5F + (y + 0.5F - vert->win[1]) / size; + t = 0.5F + (y + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][1]) / size; else /* GL_UPPER_LEFT */ - t = 0.5F - (y + 0.5F - vert->win[1]) / size; + t = 0.5F - (y + 0.5F - vert->attrib[FRAG_ATTRIB_WPOS][1]) / size; if (ctx->Point.SpriteRMode == GL_ZERO) r = 0.0F; else if (ctx->Point.SpriteRMode == GL_S) @@ -389,11 +380,6 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) 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 @@ -403,9 +389,10 @@ NAME ( GLcontext *ctx, const SWvertex *vert ) ATTRIB_LOOP_END #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->array->x[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][0]; + span->array->y[count] = (GLint) vert->attrib[FRAG_ATTRIB_WPOS][1]; + span->array->z[count] = (GLint) (vert->attrib[FRAG_ATTRIB_WPOS][2] + 0.5F); + span->end = count + 1; }} diff --git a/src/mesa/swrast/s_span.c b/src/mesa/swrast/s_span.c index 097d2c7b51c..90a3d5545f8 100644 --- a/src/mesa/swrast/s_span.c +++ b/src/mesa/swrast/s_span.c @@ -52,53 +52,30 @@ /** - * Init span's Z interpolation values to the RasterPos Z. - * Used during setup for glDraw/CopyPixels. + * Set default fragment attributes for the span using the + * current raster values. Used prior to glDraw/CopyPixels + * and glBitmap. */ void -_swrast_span_default_z( GLcontext *ctx, SWspan *span ) +_swrast_span_default_attribs(GLcontext *ctx, SWspan *span) { - const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; - if (ctx->DrawBuffer->Visual.depthBits <= 16) - span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); - else - span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); - span->zStep = 0; - span->interpMask |= SPAN_Z; -} - - -/** - * Init span's fogcoord interpolation values to the RasterPos fog. - * Used during setup for glDraw/CopyPixels. - */ -void -_swrast_span_default_fog( GLcontext *ctx, SWspan *span ) -{ - const SWcontext *swrast = SWRAST_CONTEXT(ctx); - GLfloat fogVal; /* a coord or a blend factor */ - if (swrast->_PreferPixelFog) { - /* fog blend factors will be computed from fog coordinates per pixel */ - fogVal = ctx->Current.RasterDistance; - } - else { - /* fog blend factor should be computed from fogcoord now */ - fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + /* Z*/ + { + const GLfloat depthMax = ctx->DrawBuffer->_DepthMaxF; + if (ctx->DrawBuffer->Visual.depthBits <= 16) + span->z = FloatToFixed(ctx->Current.RasterPos[2] * depthMax + 0.5F); + else + span->z = (GLint) (ctx->Current.RasterPos[2] * depthMax + 0.5F); + span->zStep = 0; + span->interpMask |= SPAN_Z; } - span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal; - span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; - span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; - span->interpMask |= SPAN_FOG; -} + /* W (for perspective correction) */ + span->attrStart[FRAG_ATTRIB_WPOS][3] = 1.0; + span->attrStepX[FRAG_ATTRIB_WPOS][3] = 0.0; + span->attrStepY[FRAG_ATTRIB_WPOS][3] = 0.0; -/** - * Init span's rgba or index interpolation values to the RasterPos color. - * Used during setup for glDraw/CopyPixels. - */ -void -_swrast_span_default_color( GLcontext *ctx, SWspan *span ) -{ + /* primary color, or color index */ if (ctx->Visual.rgbMode) { GLchan r, g, b, a; UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterColor[0]); @@ -121,97 +98,129 @@ _swrast_span_default_color( GLcontext *ctx, SWspan *span ) span->blueStep = 0; span->alphaStep = 0; span->interpMask |= SPAN_RGBA; + + COPY_4V(span->attrStart[FRAG_ATTRIB_COL0], ctx->Current.RasterColor); + ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL0], 0.0, 0.0, 0.0, 0.0); } else { span->index = FloatToFixed(ctx->Current.RasterIndex); span->indexStep = 0; span->interpMask |= SPAN_INDEX; } -} - -/** - * Set the span's secondary color info to the current raster position's - * secondary color, when needed (lighting enabled or colorsum enabled). - */ -void -_swrast_span_default_secondary_color(GLcontext *ctx, SWspan *span) -{ + /* Secondary color */ if (ctx->Visual.rgbMode && (ctx->Light.Enabled || ctx->Fog.ColorSumEnabled)) { - GLchan r, g, b, a; - UNCLAMPED_FLOAT_TO_CHAN(r, ctx->Current.RasterSecondaryColor[0]); - UNCLAMPED_FLOAT_TO_CHAN(g, ctx->Current.RasterSecondaryColor[1]); - UNCLAMPED_FLOAT_TO_CHAN(b, ctx->Current.RasterSecondaryColor[2]); - UNCLAMPED_FLOAT_TO_CHAN(a, ctx->Current.RasterSecondaryColor[3]); -#if CHAN_TYPE == GL_FLOAT - span->specRed = r; - span->specGreen = g; - span->specBlue = b; - /*span->specAlpha = a;*/ -#else - span->specRed = IntToFixed(r); - span->specGreen = IntToFixed(g); - span->specBlue = IntToFixed(b); - /*span->specAlpha = IntToFixed(a);*/ -#endif - span->specRedStep = 0; - span->specGreenStep = 0; - span->specBlueStep = 0; - /*span->specAlphaStep = 0;*/ - span->interpMask |= SPAN_SPEC; + COPY_4V(span->attrStart[FRAG_ATTRIB_COL1], ctx->Current.RasterSecondaryColor); + ASSIGN_4V(span->attrStepX[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(span->attrStepY[FRAG_ATTRIB_COL1], 0.0, 0.0, 0.0, 0.0); + } + + /* fog */ + { + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + GLfloat fogVal; /* a coord or a blend factor */ + if (swrast->_PreferPixelFog) { + /* fog blend factors will be computed from fog coordinates per pixel */ + fogVal = ctx->Current.RasterDistance; + } + else { + /* fog blend factor should be computed from fogcoord now */ + fogVal = _swrast_z_to_fogfactor(ctx, ctx->Current.RasterDistance); + } + span->attrStart[FRAG_ATTRIB_FOGC][0] = fogVal; + span->attrStepX[FRAG_ATTRIB_FOGC][0] = 0.0; + span->attrStepY[FRAG_ATTRIB_FOGC][0] = 0.0; + } + + /* texcoords */ + { + GLuint i; + for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { + const GLuint attr = FRAG_ATTRIB_TEX0 + i; + const GLfloat *tc = ctx->Current.RasterTexCoords[i]; + if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { + COPY_4V(span->attrStart[attr], tc); + } + else if (tc[3] > 0.0F) { + /* use (s/q, t/q, r/q, 1) */ + span->attrStart[attr][0] = tc[0] / tc[3]; + span->attrStart[attr][1] = tc[1] / tc[3]; + span->attrStart[attr][2] = tc[2] / tc[3]; + span->attrStart[attr][3] = 1.0; + } + else { + ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); + } + ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); + ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); + } } } /** - * Init span's texcoord interpolation values to the RasterPos texcoords. - * Used during setup for glDraw/CopyPixels. + * Interpolate the active attributes (and'd with attrMask) to + * fill in span->array->attribs[]. + * Perspective correction will be done. The point/line/triangle function + * should have computed attrStart/Step values for FRAG_ATTRIB_WPOS[3]! */ -void -_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span ) +static INLINE void +interpolate_active_attribs(GLcontext *ctx, SWspan *span, GLbitfield attrMask) { - GLuint i; - for (i = 0; i < ctx->Const.MaxTextureCoordUnits; i++) { - const GLuint attr = FRAG_ATTRIB_TEX0 + i; - const GLfloat *tc = ctx->Current.RasterTexCoords[i]; - if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { - COPY_4V(span->attrStart[attr], tc); - } - else if (tc[3] > 0.0F) { - /* use (s/q, t/q, r/q, 1) */ - span->attrStart[attr][0] = tc[0] / tc[3]; - span->attrStart[attr][1] = tc[1] / tc[3]; - span->attrStart[attr][2] = tc[2] / tc[3]; - span->attrStart[attr][3] = 1.0; - } - else { - ASSIGN_4V(span->attrStart[attr], 0.0F, 0.0F, 0.0F, 1.0F); + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + + ATTRIB_LOOP_BEGIN + if (attrMask & (1 << attr)) { + const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; + GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; + const GLfloat dv0dx = span->attrStepX[attr][0]; + const GLfloat dv1dx = span->attrStepX[attr][1]; + const GLfloat dv2dx = span->attrStepX[attr][2]; + const GLfloat dv3dx = span->attrStepX[attr][3]; + GLfloat v0 = span->attrStart[attr][0]; + GLfloat v1 = span->attrStart[attr][1]; + GLfloat v2 = span->attrStart[attr][2]; + GLfloat v3 = span->attrStart[attr][3]; + GLuint k; + for (k = 0; k < span->end; k++) { + const GLfloat invW = 1.0f / w; + span->array->attribs[attr][k][0] = v0 * invW; + span->array->attribs[attr][k][1] = v1 * invW; + span->array->attribs[attr][k][2] = v2 * invW; + span->array->attribs[attr][k][3] = v3 * invW; + v0 += dv0dx; + v1 += dv1dx; + v2 += dv2dx; + v3 += dv3dx; + w += dwdx; + } + span->arrayAttribs |= (1 << attr); } - ASSIGN_4V(span->attrStepX[attr], 0.0F, 0.0F, 0.0F, 0.0F); - ASSIGN_4V(span->attrStepY[attr], 0.0F, 0.0F, 0.0F, 0.0F); - } - span->interpMask |= SPAN_TEXTURE; + ATTRIB_LOOP_END } /** - * Interpolate primary colors to fill in the span->array->color array. + * Interpolate primary colors to fill in the span->array->rgba8 (or rgb16) + * color array. */ static INLINE void -interpolate_colors(SWspan *span) +interpolate_int_colors(GLcontext *ctx, SWspan *span) { const GLuint n = span->end; GLuint i; - ASSERT((span->interpMask & SPAN_RGBA) && - !(span->arrayMask & SPAN_RGBA)); +#if CHAN_BITS != 32 + ASSERT(!(span->arrayMask & SPAN_RGBA)); +#endif switch (span->array->ChanType) { #if CHAN_BITS != 32 case GL_UNSIGNED_BYTE: { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; + GLubyte (*rgba)[4] = span->array->rgba8; if (span->interpMask & SPAN_FLAT) { GLubyte color[4]; color[RCOMP] = FixedToInt(span->red); @@ -246,7 +255,7 @@ interpolate_colors(SWspan *span) break; case GL_UNSIGNED_SHORT: { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; + GLushort (*rgba)[4] = span->array->rgba16; if (span->interpMask & SPAN_FLAT) { GLushort color[4]; color[RCOMP] = FixedToInt(span->red); @@ -258,7 +267,7 @@ interpolate_colors(SWspan *span) } } else { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; + GLushort (*rgba)[4] = span->array->rgba16; GLfixed r, g, b, a; GLint dr, dg, db, da; r = span->red; @@ -284,162 +293,76 @@ interpolate_colors(SWspan *span) break; #endif case GL_FLOAT: - { - GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; - GLfloat r, g, b, a, dr, dg, db, da; - r = span->red; - g = span->green; - b = span->blue; - a = span->alpha; - if (span->interpMask & SPAN_FLAT) { - dr = dg = db = da = 0.0; - } - else { - dr = span->redStep; - dg = span->greenStep; - db = span->blueStep; - da = span->alphaStep; - } - for (i = 0; i < n; i++) { - rgba[i][RCOMP] = r; - rgba[i][GCOMP] = g; - rgba[i][BCOMP] = b; - rgba[i][ACOMP] = a; - r += dr; - g += dg; - b += db; - a += da; - } - } + interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); break; default: - _mesa_problem(NULL, "bad datatype in interpolate_colors"); + _mesa_problem(NULL, "bad datatype in interpolate_int_colors"); } span->arrayMask |= SPAN_RGBA; } /** - * Interpolate specular/secondary colors. + * Populate the FRAG_ATTRIB_COL0 array. */ static INLINE void -interpolate_specular(SWspan *span) +interpolate_float_colors(SWspan *span) { + GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; const GLuint n = span->end; GLuint i; - switch (span->array->ChanType) { -#if CHAN_BITS != 32 - case GL_UNSIGNED_BYTE: - { - GLubyte (*spec)[4] = span->array->color.sz1.spec; - if (span->interpMask & SPAN_FLAT) { - GLubyte color[4]; - color[RCOMP] = FixedToInt(span->specRed); - color[GCOMP] = FixedToInt(span->specGreen); - color[BCOMP] = FixedToInt(span->specBlue); - color[ACOMP] = 0; - for (i = 0; i < n; i++) { - COPY_4UBV(spec[i], color); - } - } - else { - GLfixed r = span->specRed; - GLfixed g = span->specGreen; - GLfixed b = span->specBlue; - GLint dr = span->specRedStep; - GLint dg = span->specGreenStep; - GLint db = span->specBlueStep; - for (i = 0; i < n; i++) { - spec[i][RCOMP] = CLAMP(FixedToChan(r), 0, 255); - spec[i][GCOMP] = CLAMP(FixedToChan(g), 0, 255); - spec[i][BCOMP] = CLAMP(FixedToChan(b), 0, 255); - spec[i][ACOMP] = 0; - r += dr; - g += dg; - b += db; - } - } + assert(!(span->arrayAttribs & FRAG_BIT_COL0)); + + if (span->arrayMask & SPAN_RGBA) { + /* convert array of int colors */ + for (i = 0; i < n; i++) { + col0[i][0] = UBYTE_TO_FLOAT(span->array->rgba8[i][0]); + col0[i][1] = UBYTE_TO_FLOAT(span->array->rgba8[i][1]); + col0[i][2] = UBYTE_TO_FLOAT(span->array->rgba8[i][2]); + col0[i][3] = UBYTE_TO_FLOAT(span->array->rgba8[i][3]); } - break; - case GL_UNSIGNED_SHORT: - { - GLushort (*spec)[4] = span->array->color.sz2.spec; - if (span->interpMask & SPAN_FLAT) { - GLushort color[4]; - color[RCOMP] = FixedToInt(span->specRed); - color[GCOMP] = FixedToInt(span->specGreen); - color[BCOMP] = FixedToInt(span->specBlue); - color[ACOMP] = 0; - for (i = 0; i < n; i++) { - COPY_4V(spec[i], color); - } - } - else { - GLfixed r = FloatToFixed(span->specRed); - GLfixed g = FloatToFixed(span->specGreen); - GLfixed b = FloatToFixed(span->specBlue); - GLint dr = FloatToFixed(span->specRedStep); - GLint dg = FloatToFixed(span->specGreenStep); - GLint db = FloatToFixed(span->specBlueStep); - for (i = 0; i < n; i++) { - spec[i][RCOMP] = FixedToInt(r); - spec[i][GCOMP] = FixedToInt(g); - spec[i][BCOMP] = FixedToInt(b); - spec[i][ACOMP] = 0; - r += dr; - g += dg; - b += db; - } + } + else { + /* interpolate red/green/blue/alpha to get float colors */ + ASSERT(span->interpMask & SPAN_RGBA); + if (span->interpMask & SPAN_FLAT) { + GLfloat r = FixedToFloat(span->red); + GLfloat g = FixedToFloat(span->green); + GLfloat b = FixedToFloat(span->blue); + GLfloat a = FixedToFloat(span->alpha); + for (i = 0; i < n; i++) { + ASSIGN_4V(col0[i], r, g, b, a); } } - break; -#endif - case GL_FLOAT: - { - GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; -#if CHAN_BITS <= 16 - GLfloat r = CHAN_TO_FLOAT(FixedToChan(span->specRed)); - GLfloat g = CHAN_TO_FLOAT(FixedToChan(span->specGreen)); - GLfloat b = CHAN_TO_FLOAT(FixedToChan(span->specBlue)); -#else - GLfloat r = span->specRed; - GLfloat g = span->specGreen; - GLfloat b = span->specBlue; -#endif - GLfloat dr, dg, db; - if (span->interpMask & SPAN_FLAT) { - dr = dg = db = 0.0; - } - else { -#if CHAN_BITS <= 16 - dr = CHAN_TO_FLOAT(FixedToChan(span->specRedStep)); - dg = CHAN_TO_FLOAT(FixedToChan(span->specGreenStep)); - db = CHAN_TO_FLOAT(FixedToChan(span->specBlueStep)); -#else - dr = span->specRedStep; - dg = span->specGreenStep; - db = span->specBlueStep; -#endif - } + else { + GLfloat r = FixedToFloat(span->red); + GLfloat g = FixedToFloat(span->green); + GLfloat b = FixedToFloat(span->blue); + GLfloat a = FixedToFloat(span->alpha); + GLfloat dr = FixedToFloat(span->redStep); + GLfloat dg = FixedToFloat(span->greenStep); + GLfloat db = FixedToFloat(span->blueStep); + GLfloat da = FixedToFloat(span->alphaStep); for (i = 0; i < n; i++) { - spec[i][RCOMP] = r; - spec[i][GCOMP] = g; - spec[i][BCOMP] = b; - spec[i][ACOMP] = 0.0F; + col0[i][0] = r; + col0[i][1] = g; + col0[i][2] = b; + col0[i][3] = a; r += dr; g += dg; b += db; + a += da; } } - break; - default: - _mesa_problem(NULL, "bad datatype in interpolate_specular"); } - span->arrayMask |= SPAN_SPEC; + + span->arrayAttribs |= FRAG_BIT_COL0; + span->array->ChanType = GL_FLOAT; } + /* Fill in the span.color.index array from the interpolation values */ static INLINE void interpolate_indexes(GLcontext *ctx, SWspan *span) @@ -450,8 +373,8 @@ interpolate_indexes(GLcontext *ctx, SWspan *span) GLuint *indexes = span->array->index; GLuint i; (void) ctx; - ASSERT((span->interpMask & SPAN_INDEX) && - !(span->arrayMask & SPAN_INDEX)); + + ASSERT(!(span->arrayMask & SPAN_INDEX)); if ((span->interpMask & SPAN_FLAT) || (indexStep == 0)) { /* constant color */ @@ -472,35 +395,16 @@ interpolate_indexes(GLcontext *ctx, SWspan *span) } -/* Fill in the span.array.fog values from the interpolation values */ -static INLINE void -interpolate_fog(const GLcontext *ctx, SWspan *span) -{ - GLfloat (*fog)[4] = span->array->attribs[FRAG_ATTRIB_FOGC]; - const GLfloat fogStep = span->attrStepX[FRAG_ATTRIB_FOGC][0]; - GLfloat fogCoord = span->attrStart[FRAG_ATTRIB_FOGC][0]; - const GLuint haveW = (span->interpMask & SPAN_W); - const GLfloat wStep = haveW ? span->attrStepX[FRAG_ATTRIB_WPOS][3] : 0.0F; - GLfloat w = haveW ? span->attrStart[FRAG_ATTRIB_WPOS][3] : 1.0F; - GLuint i; - for (i = 0; i < span->end; i++) { - fog[i][0] = fogCoord / w; - fogCoord += fogStep; - w += wStep; - } - span->arrayMask |= SPAN_FOG; -} - - -/* Fill in the span.zArray array from the interpolation values */ +/** + * Fill in the span.zArray array from the span->z, zStep values. + */ void _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ) { const GLuint n = span->end; GLuint i; - ASSERT((span->interpMask & SPAN_Z) && - !(span->arrayMask & SPAN_Z)); + ASSERT(!(span->arrayMask & SPAN_Z)); if (ctx->DrawBuffer->Visual.depthBits <= 16) { GLfixed zval = span->z; @@ -524,7 +428,8 @@ _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ) } -/* +/** + * Compute mipmap LOD from partial derivatives. * This the ideal solution, as given in the OpenGL spec. */ #if 0 @@ -546,8 +451,9 @@ compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, #endif -/* - * This is a faster approximation +/** + * Compute mipmap LOD from partial derivatives. + * This is a faster approximation than above function. */ GLfloat _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, @@ -572,14 +478,15 @@ _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, /** - * Fill in the span.texcoords array from the interpolation values. + * Fill in the span.array->attrib[FRAG_ATTRIB_TEXn] arrays from the + * using the attrStart/Step values. + * + * This function only used during fixed-function fragment processing. + * * Note: in the places where we divide by Q (or mult by invQ) we're * really doing two things: perspective correction and texcoord * projection. Remember, for texcoord (s,t,r,q) we need to index * texels with (s/q, t/q, r/q). - * If we're using a fragment program, we never do the division - * for texcoord projection. That's done by the TXP instruction - * or user-written code. */ static void interpolate_texcoords(GLcontext *ctx, SWspan *span) @@ -588,11 +495,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) = (ctx->Texture._EnabledCoordUnits > 1) ? ctx->Const.MaxTextureUnits : 1; GLuint u; - ASSERT(span->interpMask & SPAN_TEXTURE); - ASSERT(!(span->arrayMask & SPAN_TEXTURE)); - - span->arrayMask |= SPAN_TEXTURE; - /* XXX CoordUnits vs. ImageUnits */ for (u = 0; u < maxUnit; u++) { if (ctx->Texture._EnabledCoordUnits & (1 << u)) { @@ -724,55 +626,6 @@ interpolate_texcoords(GLcontext *ctx, SWspan *span) } - -/** - * Fill in the arrays->attribs[FRAG_ATTRIB_VARx] arrays from the - * interpolation values. - * XXX since interpolants/arrays are getting uniformed, we might merge - * this with interpolate_texcoords(), interpolate_Fog(), etc. someday. - */ -static INLINE void -interpolate_varying(GLcontext *ctx, SWspan *span) -{ - GLuint var; - const GLbitfield inputsUsed = ctx->FragmentProgram._Current->Base.InputsRead; - - ASSERT(span->interpMask & SPAN_VARYING); - ASSERT(!(span->arrayMask & SPAN_VARYING)); - - span->arrayMask |= SPAN_VARYING; - - for (var = 0; var < MAX_VARYING; var++) { - if (inputsUsed & FRAG_BIT_VAR(var)) { - const GLuint attr = FRAG_ATTRIB_VAR0 + var; - const GLfloat dwdx = span->attrStepX[FRAG_ATTRIB_WPOS][3]; - GLfloat w = span->attrStart[FRAG_ATTRIB_WPOS][3]; - const GLfloat dv0dx = span->attrStepX[attr][0]; - const GLfloat dv1dx = span->attrStepX[attr][1]; - const GLfloat dv2dx = span->attrStepX[attr][2]; - const GLfloat dv3dx = span->attrStepX[attr][3]; - GLfloat v0 = span->attrStart[attr][0]; - GLfloat v1 = span->attrStart[attr][1]; - GLfloat v2 = span->attrStart[attr][2]; - GLfloat v3 = span->attrStart[attr][3]; - GLuint k; - for (k = 0; k < span->end; k++) { - GLfloat invW = 1.0f / w; - span->array->attribs[attr][k][0] = v0 * invW; - span->array->attribs[attr][k][1] = v1 * invW; - span->array->attribs[attr][k][2] = v2 * invW; - span->array->attribs[attr][k][3] = v3 * invW; - v0 += dv0dx; - v1 += dv1dx; - v2 += dv2dx; - v3 += dv3dx; - w += dwdx; - } - } - } -} - - /** * Fill in the arrays->attribs[FRAG_ATTRIB_WPOS] array. */ @@ -934,7 +787,9 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) 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 */ @@ -981,7 +836,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) /* Stencil and Z testing */ if (ctx->Depth.Test || ctx->Stencil.Enabled) { - if (span->interpMask & SPAN_Z) + if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled) { @@ -1022,7 +877,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) ctx->Color.IndexLogicOpEnabled || ctx->Color.IndexMask != 0xffffffff || (span->arrayMask & SPAN_COVERAGE)) { - if (span->interpMask & SPAN_INDEX) { + if (!(span->arrayMask & SPAN_INDEX) /*span->interpMask & SPAN_INDEX*/) { interpolate_indexes(ctx, span); } } @@ -1071,7 +926,7 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) _swrast_mask_ci_span(ctx, rb, span); } - if ((span->interpMask & SPAN_INDEX) && span->indexStep == 0) { + if (!(span->arrayMask & SPAN_INDEX) && span->indexStep == 0) { /* all fragments have same color index */ GLubyte index8; GLushort index16; @@ -1151,63 +1006,52 @@ _swrast_write_index_span( GLcontext *ctx, SWspan *span) /** - * Add specular color to base color. This is used only when - * GL_LIGHT_MODEL_COLOR_CONTROL = GL_SEPARATE_SPECULAR_COLOR. + * Add specular colors to primary colors. + * Only called during fixed-function operation. + * Result is float color array (FRAG_ATTRIB_COL0). */ static INLINE void add_specular(GLcontext *ctx, SWspan *span) { - switch (span->array->ChanType) { - case GL_UNSIGNED_BYTE: - { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; - GLubyte (*spec)[4] = span->array->color.sz1.spec; - GLuint i; - for (i = 0; i < span->end; i++) { - GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; - GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; - GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; - GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; - rgba[i][RCOMP] = MIN2(r, 255); - rgba[i][GCOMP] = MIN2(g, 255); - rgba[i][BCOMP] = MIN2(b, 255); - rgba[i][ACOMP] = MIN2(a, 255); - } + const SWcontext *swrast = SWRAST_CONTEXT(ctx); + const GLubyte *mask = span->array->mask; + GLfloat (*col0)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; + GLfloat (*col1)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; + GLuint i; + + ASSERT(!ctx->FragmentProgram._Current); + ASSERT(span->arrayMask & SPAN_RGBA); + ASSERT(swrast->_ActiveAttribMask & FRAG_BIT_COL1); + + if (span->array->ChanType == GL_FLOAT) { + if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { + interpolate_active_attribs(ctx, span, FRAG_BIT_COL0); } - break; - case GL_UNSIGNED_SHORT: - { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; - GLushort (*spec)[4] = span->array->color.sz2.spec; - GLuint i; - for (i = 0; i < span->end; i++) { - GLint r = rgba[i][RCOMP] + spec[i][RCOMP]; - GLint g = rgba[i][GCOMP] + spec[i][GCOMP]; - GLint b = rgba[i][BCOMP] + spec[i][BCOMP]; - GLint a = rgba[i][ACOMP] + spec[i][ACOMP]; - rgba[i][RCOMP] = MIN2(r, 65535); - rgba[i][GCOMP] = MIN2(g, 65535); - rgba[i][BCOMP] = MIN2(b, 65535); - rgba[i][ACOMP] = MIN2(a, 65535); - } + } + else { + /* need float colors */ + if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { + interpolate_float_colors(span); } - break; - case GL_FLOAT: - { - GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; - GLfloat (*spec)[4] = span->array->attribs[FRAG_ATTRIB_COL1]; - GLuint i; - for (i = 0; i < span->end; i++) { - rgba[i][RCOMP] += spec[i][RCOMP]; - rgba[i][GCOMP] += spec[i][GCOMP]; - rgba[i][BCOMP] += spec[i][BCOMP]; - rgba[i][ACOMP] += spec[i][ACOMP]; - } + } + + if ((span->arrayAttribs & FRAG_BIT_COL1) == 0) { + /* XXX could avoid this and interpolate COL1 in the loop below */ + interpolate_active_attribs(ctx, span, FRAG_BIT_COL1); + } + + ASSERT(span->arrayAttribs & FRAG_BIT_COL0); + ASSERT(span->arrayAttribs & FRAG_BIT_COL1); + + for (i = 0; i < span->end; i++) { + if (mask[i]) { + col0[i][0] += col1[i][0]; + col0[i][1] += col1[i][1]; + col0[i][2] += col1[i][2]; } - break; - default: - _mesa_problem(ctx, "Invalid datatype in add_specular"); } + + span->array->ChanType = GL_FLOAT; } @@ -1220,7 +1064,7 @@ apply_aa_coverage(SWspan *span) const GLfloat *coverage = span->array->coverage; GLuint i; if (span->array->ChanType == GL_UNSIGNED_BYTE) { - GLubyte (*rgba)[4] = span->array->color.sz1.rgba; + GLubyte (*rgba)[4] = span->array->rgba8; for (i = 0; i < span->end; i++) { const GLfloat a = rgba[i][ACOMP] * coverage[i]; rgba[i][ACOMP] = (GLubyte) CLAMP(a, 0.0, 255.0); @@ -1229,7 +1073,7 @@ apply_aa_coverage(SWspan *span) } } else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - GLushort (*rgba)[4] = span->array->color.sz2.rgba; + GLushort (*rgba)[4] = span->array->rgba16; for (i = 0; i < span->end; i++) { const GLfloat a = rgba[i][ACOMP] * coverage[i]; rgba[i][ACOMP] = (GLushort) CLAMP(a, 0.0, 65535.0); @@ -1239,6 +1083,7 @@ apply_aa_coverage(SWspan *span) GLfloat (*rgba)[4] = span->array->attribs[FRAG_ATTRIB_COL0]; for (i = 0; i < span->end; i++) { rgba[i][ACOMP] = rgba[i][ACOMP] * coverage[i]; + /* clamp later */ } } } @@ -1278,18 +1123,18 @@ convert_color_type(SWspan *span, GLenum newType, GLuint output) span->array->ChanType = GL_FLOAT; } else if (span->array->ChanType == GL_UNSIGNED_BYTE) { - src = span->array->color.sz1.rgba; + src = span->array->rgba8; } else { ASSERT(span->array->ChanType == GL_UNSIGNED_SHORT); - src = span->array->color.sz2.rgba; + src = span->array->rgba16; } if (newType == GL_UNSIGNED_BYTE) { - dst = span->array->color.sz1.rgba; + dst = span->array->rgba8; } else if (newType == GL_UNSIGNED_SHORT) { - dst = span->array->color.sz2.rgba; + dst = span->array->rgba16; } else { dst = span->array->attribs[FRAG_ATTRIB_COL0]; @@ -1321,42 +1166,16 @@ shade_texture_span(GLcontext *ctx, SWspan *span) inputsRead = ~0; } - if ((inputsRead & FRAG_BIT_COL0) && (span->interpMask & SPAN_RGBA)) - interpolate_colors(span); - - if (ctx->Texture._EnabledCoordUnits && (span->interpMask & SPAN_TEXTURE)) - interpolate_texcoords(ctx, span); - if (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled) { - /* use float colors if running a fragment program or shader */ - const GLenum oldType = span->array->ChanType; - const GLenum newType = GL_FLOAT; - - if ((inputsRead & FRAG_BIT_COL0) && (oldType != newType)) { - GLvoid *src = (oldType == GL_UNSIGNED_BYTE) - ? (GLvoid *) span->array->color.sz1.rgba - : (GLvoid *) span->array->color.sz2.rgba; - assert(span->arrayMask & SPAN_RGBA); - _mesa_convert_colors(oldType, src, - newType, span->array->attribs[FRAG_ATTRIB_COL0], - span->end, span->array->mask); - } - span->array->ChanType = newType; - - /* fragment programs/shaders may need specular, fog and Z coords */ - if ((inputsRead & FRAG_BIT_COL1) && (span->interpMask & SPAN_SPEC)) - interpolate_specular(span); + /* programmable shading */ + span->array->ChanType = GL_FLOAT; - if ((inputsRead & FRAG_BIT_FOGC) && (span->interpMask & SPAN_FOG)) - interpolate_fog(ctx, span); + interpolate_active_attribs(ctx, span, ~0); - if (span->interpMask & SPAN_Z) + if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z (ctx, span); - if ((inputsRead >= FRAG_BIT_VAR0) && (span->interpMask & SPAN_VARYING)) - interpolate_varying(ctx, span); - #if 0 if (inputsRead & FRAG_BIT_WPOS) #else @@ -1373,8 +1192,20 @@ shade_texture_span(GLcontext *ctx, SWspan *span) _swrast_exec_fragment_shader(ctx, span); } } - else if (ctx->Texture._EnabledUnits && (span->arrayMask & SPAN_TEXTURE)) { + else if (ctx->Texture._EnabledUnits) { /* conventional texturing */ + +#if CHAN_BITS == 32 + if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { + interpolate_int_colors(ctx, span); + } +#else + if (!(span->arrayMask & SPAN_RGBA)) + interpolate_int_colors(ctx, span); +#endif + if ((span->arrayAttribs & FRAG_BITS_TEX_ANY) == 0x0) + interpolate_texcoords(ctx, span); + _swrast_texture_span(ctx, span); } } @@ -1395,13 +1226,13 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) const GLuint colorMask = *((GLuint *) ctx->Color.ColorMask); const GLbitfield origInterpMask = span->interpMask; const GLbitfield origArrayMask = span->arrayMask; + const GLbitfield origArrayAttribs = span->arrayAttribs; const GLenum chanType = span->array->ChanType; const GLboolean shader = (ctx->FragmentProgram._Current || ctx->ATIFragmentShader._Enabled); const GLboolean shaderOrTexture = shader || ctx->Texture._EnabledUnits; struct gl_framebuffer *fb = ctx->DrawBuffer; GLuint output; - GLboolean deferredTexture; /* printf("%s() interp 0x%x array 0x%x\n", __FUNCTION__, @@ -1413,41 +1244,6 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) span->primitive == GL_POLYGON || span->primitive == GL_BITMAP); ASSERT(span->end <= MAX_WIDTH); - ASSERT((span->interpMask & span->arrayMask) == 0); - ASSERT((span->interpMask & SPAN_RGBA) ^ (span->arrayMask & SPAN_RGBA)); - - /* check for conditions that prevent deferred shading (doing shading - * after stencil/ztest). - * XXX move this code into state validation. - */ - if (ctx->Color.AlphaEnabled) { - /* alpha test depends on post-texture/shader colors */ - deferredTexture = GL_FALSE; - } - else if (shaderOrTexture) { - if (ctx->FragmentProgram._Current) { - if (ctx->FragmentProgram._Current->Base.OutputsWritten - & (1 << FRAG_RESULT_DEPR)) { - /* Z comes from fragment program/shader */ - deferredTexture = GL_FALSE; - } - else if (ctx->Query.CurrentOcclusionObject) { - /* occlusion query depends on shader discard/kill results */ - deferredTexture = GL_FALSE; - } - else { - deferredTexture = GL_TRUE; - } - } - else { - /* ATI frag shader or conventional texturing */ - deferredTexture = GL_TRUE; - } - } - else { - /* no texturing or shadering */ - deferredTexture = GL_FALSE; - } /* Fragment write masks */ if (span->arrayMask & SPAN_MASK) { @@ -1486,12 +1282,10 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) stipple_polygon_span(ctx, span); } - /* This is the normal place to compute the resulting fragment color/Z. - * As an optimization, we try to defer this until after Z/stencil - * testing in order to try to avoid computing colors that we won't - * actually need. + /* This is the normal place to compute the fragment color/Z + * from texturing or shading. */ - if (shaderOrTexture && !deferredTexture) { + if (shaderOrTexture && !swrast->_DeferredTexture) { shade_texture_span(ctx, span); } @@ -1504,7 +1298,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) /* Stencil and Z testing */ if (ctx->Stencil.Enabled || ctx->Depth.Test) { - if (span->interpMask & SPAN_Z) + if (!(span->arrayMask & SPAN_Z)) _swrast_span_interpolate_z(ctx, span); if (ctx->Stencil.Enabled && fb->Visual.stencilBits > 0) { @@ -1544,14 +1338,19 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) * a good chance that many fragments will have already been killed by * Z/stencil testing. */ - if (deferredTexture) { - ASSERT(shaderOrTexture); + if (shaderOrTexture && swrast->_DeferredTexture) { shade_texture_span(ctx, span); } +#if CHAN_BITS == 32 + if ((span->arrayAttribs & FRAG_BIT_COL0) == 0) { + interpolate_int_colors(ctx, span); + } +#else if ((span->arrayMask & SPAN_RGBA) == 0) { - interpolate_colors(span); + interpolate_int_colors(ctx, span); } +#endif ASSERT(span->arrayMask & SPAN_RGBA); @@ -1560,17 +1359,7 @@ _swrast_write_rgba_span( GLcontext *ctx, SWspan *span) if (ctx->Fog.ColorSumEnabled || (ctx->Light.Enabled && ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR)) { - if (span->interpMask & SPAN_SPEC) { - interpolate_specular(span); - } - if (span->arrayMask & SPAN_SPEC) { - add_specular(ctx, span); - } - else { - /* We probably added the base/specular colors during the - * vertex stage! - */ - } + add_specular(ctx, span); } } @@ -1659,6 +1448,7 @@ end: /* restore these values before returning */ span->interpMask = origInterpMask; span->arrayMask = origArrayMask; + span->arrayAttribs = origArrayAttribs; span->array->ChanType = chanType; } @@ -1921,18 +1711,9 @@ _swrast_get_dest_rgba(GLcontext *ctx, struct gl_renderbuffer *rb, void *rbPixels; /* - * Determine pixel size (in bytes). * Point rbPixels to a temporary space (use specular color arrays). */ - if (span->array->ChanType == GL_UNSIGNED_BYTE) { - rbPixels = span->array->color.sz1.spec; - } - else if (span->array->ChanType == GL_UNSIGNED_SHORT) { - rbPixels = span->array->color.sz2.spec; - } - else { - rbPixels = span->array->attribs[FRAG_ATTRIB_COL1]; - } + rbPixels = span->array->attribs[FRAG_ATTRIB_COL1]; /* Get destination values from renderbuffer */ if (span->arrayMask & SPAN_XY) { diff --git a/src/mesa/swrast/s_span.h b/src/mesa/swrast/s_span.h index f650a27d665..585cce91ee9 100644 --- a/src/mesa/swrast/s_span.h +++ b/src/mesa/swrast/s_span.h @@ -33,45 +33,24 @@ /** * \defgroup SpanFlags - * Bitflags used for interpMask and arrayMask fields below to indicate - * which interpolant values and fragment arrays are in use, respectively. + * Special bitflags to describe span data. * - * XXX We should replace these flags with the FRAG_BIT_ values someday... + * In general, the point/line/triangle functions interpolate/emit the + * attributes specified by swrast->_ActiveAttribs (i.e. FRAT_BIT_* values). + * Some things don't fit into that, though, so we have these flags. */ /*@{*/ -#define SPAN_RGBA 0x001 -#define SPAN_SPEC 0x002 -#define SPAN_INDEX 0x004 -#define SPAN_Z 0x008 -#define SPAN_W 0x010 -#define SPAN_FOG 0x020 -#define SPAN_TEXTURE 0x040 -#define SPAN_INT_TEXTURE 0x080 -#define SPAN_LAMBDA 0x100 -#define SPAN_COVERAGE 0x200 -#define SPAN_FLAT 0x400 /**< flat shading? */ -#define SPAN_XY 0x800 -#define SPAN_MASK 0x1000 -#define SPAN_VARYING 0x2000 +#define SPAN_RGBA 0x01 /**< interpMask and arrayMask */ +#define SPAN_INDEX 0x02 /**< interpMask and arrayMask */ +#define SPAN_Z 0x04 /**< interpMask and arrayMask */ +#define SPAN_FLAT 0x08 /**< interpMask: flat shading? */ +#define SPAN_XY 0x10 /**< array.x[], y[] valid? */ +#define SPAN_MASK 0x20 /**< was array.mask[] filled in by caller? */ +#define SPAN_LAMBDA 0x40 /**< array.lambda[] valid? */ +#define SPAN_COVERAGE 0x80 /**< array.coverage[] valid? */ /*@}*/ -#if 0 -/* alternate arrangement for code below */ -struct arrays2 { - union { - GLubyte sz1[MAX_WIDTH][4]; /* primary color */ - GLushort sz2[MAX_WIDTH][4]; - } rgba; - union { - GLubyte sz1[MAX_WIDTH][4]; /* specular color and temp storage */ - GLushort sz2[MAX_WIDTH][4]; - } spec; -}; -#endif - - - /** * \sw_span_arrays * \brief Arrays of fragment values. @@ -92,26 +71,19 @@ typedef struct sw_span_arrays GLubyte mask[MAX_WIDTH]; GLenum ChanType; /**< Color channel type, GL_UNSIGNED_BYTE, GL_FLOAT */ - union { - struct { - GLubyte rgba[MAX_WIDTH][4]; /**< primary color */ - GLubyte spec[MAX_WIDTH][4]; /**< specular color and temp storage */ - } sz1; - struct { - GLushort rgba[MAX_WIDTH][4]; - GLushort spec[MAX_WIDTH][4]; - } sz2; - } color; - /** XXX these are temporary fields, pointing into above color arrays */ - GLchan (*rgba)[4]; - GLchan (*spec)[4]; + /** Attribute arrays that don't fit into attribs[] array above */ + /*@{*/ + GLubyte rgba8[MAX_WIDTH][4]; + GLushort rgba16[MAX_WIDTH][4]; + GLchan (*rgba)[4]; /** either == rgba8 or rgba16 */ GLint x[MAX_WIDTH]; /**< fragment X coords */ GLint y[MAX_WIDTH]; /**< fragment Y coords */ GLuint z[MAX_WIDTH]; /**< fragment Z coords */ GLuint index[MAX_WIDTH]; /**< Color indexes */ GLfloat lambda[MAX_TEXTURE_COORD_UNITS][MAX_WIDTH]; /**< Texture LOD */ GLfloat coverage[MAX_WIDTH]; /**< Fragment coverage for AA/smoothing */ + /*@}*/ } SWspanarrays; @@ -160,26 +132,13 @@ typedef struct sw_span /* For horizontal spans, step is the partial derivative wrt X. * For lines, step is the delta from one fragment to the next. */ -#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; /* XXX z should probably be GLuint */ - GLfixed intTex[2], intTexStep[2]; /* s, t only */ + GLfixed z, zStep; /**< XXX z should probably be GLuint */ + GLfixed intTex[2], intTexStep[2]; /**< (s,t) for unit[0] only */ /** * This bitmask (of \link SpanFlags SPAN_* flags\endlink) indicates @@ -187,6 +146,8 @@ typedef struct sw_span */ GLbitfield arrayMask; + GLbitfield arrayAttribs; + /** * We store the arrays of fragment values in a separate struct so * that we can allocate sw_span structs on the stack without using @@ -203,6 +164,7 @@ do { \ (S).primitive = (PRIMITIVE); \ (S).interpMask = (INTERP_MASK); \ (S).arrayMask = (ARRAY_MASK); \ + (S).arrayAttribs = 0x0; \ (S).end = (END); \ (S).facing = 0; \ (S).array = SWRAST_CONTEXT(ctx)->SpanArrays; \ @@ -211,23 +173,11 @@ do { \ extern void -_swrast_span_default_z( GLcontext *ctx, SWspan *span ); +_swrast_span_default_attribs(GLcontext *ctx, SWspan *span); extern void _swrast_span_interpolate_z( const GLcontext *ctx, SWspan *span ); -extern void -_swrast_span_default_fog( GLcontext *ctx, SWspan *span ); - -extern void -_swrast_span_default_color( GLcontext *ctx, SWspan *span ); - -extern void -_swrast_span_default_secondary_color(GLcontext *ctx, SWspan *span); - -extern void -_swrast_span_default_texcoords( GLcontext *ctx, SWspan *span ); - extern GLfloat _swrast_compute_lambda(GLfloat dsdx, GLfloat dsdy, GLfloat dtdx, GLfloat dtdy, GLfloat dqdx, GLfloat dqdy, GLfloat texW, GLfloat texH, diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c index ebb4c0d936d..4ac7222daa5 100644 --- a/src/mesa/swrast/s_texcombine.c +++ b/src/mesa/swrast/s_texcombine.c @@ -1080,7 +1080,6 @@ _swrast_texture_span( GLcontext *ctx, SWspan *span ) GLuint unit; ASSERT(span->end < MAX_WIDTH); - ASSERT(span->arrayMask & SPAN_TEXTURE); /* * Save copy of the incoming fragment colors (the GL_PRIMARY_COLOR) diff --git a/src/mesa/swrast/s_triangle.c b/src/mesa/swrast/s_triangle.c index fc9d29bbf7f..c2555452173 100644 --- a/src/mesa/swrast/s_triangle.c +++ b/src/mesa/swrast/s_triangle.c @@ -52,10 +52,10 @@ _swrast_culltriangle( GLcontext *ctx, 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 ex = v1->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0]; + GLfloat ey = v1->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1]; + GLfloat fx = v2->attrib[FRAG_ATTRIB_WPOS][0] - v0->attrib[FRAG_ATTRIB_WPOS][0]; + GLfloat fy = v2->attrib[FRAG_ATTRIB_WPOS][1] - v0->attrib[FRAG_ATTRIB_WPOS][1]; GLfloat c = ex*fy-ey*fx; if (c * SWRAST_CONTEXT(ctx)->_BackfaceSign > 0) @@ -71,7 +71,7 @@ _swrast_culltriangle( GLcontext *ctx, */ #define NAME ci_triangle #define INTERP_Z 1 -#define INTERP_FOG 1 +#define INTERP_ATTRIBS 1 /* just for fog */ #define INTERP_INDEX 1 #define RENDER_SPAN( span ) _swrast_write_index_span(ctx, &span); #include "s_tritemp.h" @@ -83,7 +83,6 @@ _swrast_culltriangle( GLcontext *ctx, */ #define NAME flat_rgba_triangle #define INTERP_Z 1 -#define INTERP_FOG 1 #define SETUP_CODE \ ASSERT(ctx->Texture._EnabledCoordUnits == 0);\ ASSERT(ctx->Light.ShadeModel==GL_FLAT); \ @@ -106,7 +105,6 @@ _swrast_culltriangle( GLcontext *ctx, */ #define NAME smooth_rgba_triangle #define INTERP_Z 1 -#define INTERP_FOG 1 #define INTERP_RGB 1 #define INTERP_ALPHA 1 #define SETUP_CODE \ @@ -228,7 +226,6 @@ _swrast_culltriangle( GLcontext *ctx, #include "s_tritemp.h" - #if CHAN_TYPE != GL_FLOAT struct affine_info @@ -511,7 +508,6 @@ affine_span(GLcontext *ctx, SWspan *span, */ #define NAME affine_textured_triangle #define INTERP_Z 1 -#define INTERP_FOG 1 #define INTERP_RGB 1 #define INTERP_ALPHA 1 #define INTERP_INT_TEX 1 @@ -784,8 +780,6 @@ fast_persp_span(GLcontext *ctx, SWspan *span, */ #define NAME persp_textured_triangle #define INTERP_Z 1 -#define INTERP_W 1 -#define INTERP_FOG 1 #define INTERP_RGB 1 #define INTERP_ALPHA 1 #define INTERP_ATTRIBS 1 @@ -843,10 +837,8 @@ fast_persp_span(GLcontext *ctx, SWspan *span, #include "s_tritemp.h" +#endif /*CHAN_TYPE != GL_FLOAT*/ -#endif /* CHAN_BITS != GL_FLOAT */ - - /* @@ -854,10 +846,7 @@ fast_persp_span(GLcontext *ctx, SWspan *span, */ #define NAME general_triangle #define INTERP_Z 1 -#define INTERP_W 1 -#define INTERP_FOG 1 #define INTERP_RGB 1 -#define INTERP_SPEC 1 #define INTERP_ALPHA 1 #define INTERP_ATTRIBS 1 #define RENDER_SPAN( span ) _swrast_write_rgba_span(ctx, &span); @@ -924,51 +913,47 @@ nodraw_triangle( GLcontext *ctx, * 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 ) +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]; + GLchan cSave[3][4]; + /* save original colors */ - COPY_CHAN4( c[0], ncv0->color ); - COPY_CHAN4( c[1], ncv1->color ); - COPY_CHAN4( c[2], ncv2->color ); + COPY_CHAN4( cSave[0], ncv0->color ); + COPY_CHAN4( cSave[1], ncv1->color ); + COPY_CHAN4( cSave[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); + rSum = CHAN_TO_FLOAT(ncv0->color[0]) + ncv0->attrib[FRAG_ATTRIB_COL1][0]; + gSum = CHAN_TO_FLOAT(ncv0->color[1]) + ncv0->attrib[FRAG_ATTRIB_COL1][1]; + bSum = CHAN_TO_FLOAT(ncv0->color[2]) + ncv0->attrib[FRAG_ATTRIB_COL1][2]; + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[0], rSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[1], gSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv0->color[2], bSum); /* 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); + rSum = CHAN_TO_FLOAT(ncv1->color[0]) + ncv1->attrib[FRAG_ATTRIB_COL1][0]; + gSum = CHAN_TO_FLOAT(ncv1->color[1]) + ncv1->attrib[FRAG_ATTRIB_COL1][1]; + bSum = CHAN_TO_FLOAT(ncv1->color[2]) + ncv1->attrib[FRAG_ATTRIB_COL1][2]; + UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[0], rSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[1], gSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv1->color[2], bSum); /* 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); + rSum = CHAN_TO_FLOAT(ncv2->color[0]) + ncv2->attrib[FRAG_ATTRIB_COL1][0]; + gSum = CHAN_TO_FLOAT(ncv2->color[1]) + ncv2->attrib[FRAG_ATTRIB_COL1][1]; + bSum = CHAN_TO_FLOAT(ncv2->color[2]) + ncv2->attrib[FRAG_ATTRIB_COL1][2]; + UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[0], rSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[1], gSum); + UNCLAMPED_FLOAT_TO_CHAN(ncv2->color[2], bSum); /* 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] ); + COPY_CHAN4( ncv0->color, cSave[0] ); + COPY_CHAN4( ncv1->color, cSave[1] ); + COPY_CHAN4( ncv2->color, cSave[2] ); } @@ -1044,9 +1029,15 @@ _swrast_choose_triangle( GLcontext *ctx ) return; } + /* + * XXX should examine swrast->_ActiveAttribMask to determine what + * needs to be interpolated. + */ if (ctx->Texture._EnabledCoordUnits || ctx->FragmentProgram._Current || - ctx->ATIFragmentShader._Enabled) { + ctx->ATIFragmentShader._Enabled || + NEED_SECONDARY_COLOR(ctx) || + swrast->_FogEnabled) { /* 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; @@ -1072,6 +1063,7 @@ _swrast_choose_triangle( GLcontext *ctx ) && (format == MESA_FORMAT_RGB || format == MESA_FORMAT_RGBA) && minFilter == magFilter && ctx->Light.Model.ColorControl == GL_SINGLE_COLOR + && !swrast->_FogEnabled && ctx->Texture.Unit[0].EnvMode != GL_COMBINE_EXT) { if (ctx->Hint.PerspectiveCorrection==GL_FASTEST) { if (minFilter == GL_NEAREST @@ -1091,7 +1083,7 @@ _swrast_choose_triangle( GLcontext *ctx ) } } else { -#if (CHAN_BITS == 16 || CHAN_BITS == 32) +#if CHAN_BITS != 8 USE(general_triangle); #else USE(affine_textured_triangle); @@ -1099,7 +1091,7 @@ _swrast_choose_triangle( GLcontext *ctx ) } } else { -#if (CHAN_BITS == 16 || CHAN_BITS == 32) +#if CHAN_BITS != 8 USE(general_triangle); #else USE(persp_textured_triangle); @@ -1112,14 +1104,23 @@ _swrast_choose_triangle( GLcontext *ctx ) } } else { - ASSERT(!ctx->Texture._EnabledCoordUnits); + ASSERT(!swrast->_FogEnabled); + ASSERT(!NEED_SECONDARY_COLOR(ctx)); if (ctx->Light.ShadeModel==GL_SMOOTH) { /* smooth shaded, no texturing, stippled or some raster ops */ - USE(smooth_rgba_triangle); +#if CHAN_BITS != 8 + USE(general_triangle); +#else + USE(smooth_rgba_triangle); +#endif } else { /* flat shaded, no texturing, stippled or some raster ops */ +#if CHAN_BITS != 8 + USE(general_triangle); +#else USE(flat_rgba_triangle); +#endif } } } diff --git a/src/mesa/swrast/s_tritemp.h b/src/mesa/swrast/s_tritemp.h index dcc3e958cb1..2a90ffd85f8 100644 --- a/src/mesa/swrast/s_tritemp.h +++ b/src/mesa/swrast/s_tritemp.h @@ -29,18 +29,16 @@ * * The following macros may be defined to indicate what auxillary information * must be interpolated across the triangle: - * INTERP_Z - if defined, interpolate vertex Z values - * INTERP_W - if defined, interpolate vertex W 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_Z - if defined, interpolate integer Z values + * INTERP_RGB - if defined, interpolate integer RGB values + * INTERP_ALPHA - if defined, interpolate integer Alpha values * INTERP_INDEX - if defined, interpolate color index values * INTERP_INT_TEX - if defined, interpolate integer ST texcoords - * (fast, simple 2-D texture mapping) + * (fast, simple 2-D texture mapping, without + * perspective correction) * INTERP_ATTRIBS - if defined, interpolate arbitrary attribs (texcoords, - * varying vars, etc) - * NOTE: OpenGL STRQ = Mesa STUV (R was taken for red) + * varying vars, etc) This also causes W to be + * computed for perspective correction). * * When one can directly address pixels in the color buffer the following * macros can be defined and used to compute pixel addresses during @@ -51,12 +49,11 @@ * Y==0 at bottom of screen and increases upward. * * Similarly, for direct depth buffer access, this type is used for depth - * buffer addressing: + * buffer addressing (see zRow): * 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. @@ -94,29 +91,6 @@ * SUB_PIXEL_BITS. */ -/* - * ColorTemp is used for intermediate color values. - */ -#if CHAN_TYPE == GL_FLOAT -#define ColorTemp GLfloat -#else -#define ColorTemp GLint /* same as GLfixed */ -#endif - - -/* - * Walk triangle edges with GLfixed or GLdouble - */ -#if TRIANGLE_WALK_DOUBLE -#define GLinterp GLdouble -#define InterpToInt(X) ((GLint) (X)) -#define INTERP_ONE 1.0 -#else -#define GLinterp GLfixed -#define InterpToInt(X) FixedToInt(X) -#define INTERP_ONE FIXED_ONE -#endif - /* * Some code we unfortunately need to prevent negative interpolated colors. @@ -141,15 +115,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { typedef struct { const SWvertex *v0, *v1; /* Y(v0) < Y(v1) */ -#if TRIANGLE_WALK_DOUBLE - GLdouble dx; /* X(v1) - X(v0) */ - GLdouble dy; /* Y(v1) - Y(v0) */ - GLdouble dxdy; /* dx/dy */ - GLdouble adjy; /* adjust from v[0]->fy to fsy, scaled */ - GLdouble fsx; /* first sample point x coord */ - GLdouble fsy; - GLdouble fx0; /*X of lower endpoint */ -#else GLfloat dx; /* X(v1) - X(v0) */ GLfloat dy; /* Y(v1) - Y(v0) */ GLfloat dxdy; /* dx/dy */ @@ -158,7 +123,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfixed fsx; /* first sample point x coord */ GLfixed fsy; GLfixed fx0; /* fixed pt X of lower endpoint */ -#endif GLint lines; /* number of lines to be sampled on this edge */ } EdgeT; @@ -173,10 +137,8 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfloat oneOverArea; const SWvertex *vMin, *vMid, *vMax; /* Y(vMin)<=Y(vMid)<=Y(vMax) */ GLfloat bf = SWRAST_CONTEXT(ctx)->_BackfaceSign; -#if !TRIANGLE_WALK_DOUBLE const GLint snapMask = ~((FIXED_ONE / (1 << SUB_PIXEL_BITS)) - 1); /* for x/y coord snapping */ -#endif - GLinterp vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; + GLfixed vMin_fx, vMin_fy, vMid_fx, vMid_fy, vMax_fx, vMax_fy; SWspan span; @@ -191,28 +153,27 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, /* 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]); - */ - /* - ASSERT(v0->win[2] >= 0.0); - ASSERT(v1->win[2] >= 0.0); - ASSERT(v2->win[2] >= 0.0); + printf(" %g, %g, %g\n", + v0->attrib[FRAG_ATTRIB_WPOS][0], + v0->attrib[FRAG_ATTRIB_WPOS][1], + v0->attrib[FRAG_ATTRIB_WPOS][2]); + printf(" %g, %g, %g\n", + v1->attrib[FRAG_ATTRIB_WPOS][0], + v1->attrib[FRAG_ATTRIB_WPOS][1], + v1->attrib[FRAG_ATTRIB_WPOS][2]); + printf(" %g, %g, %g\n", + v2->attrib[FRAG_ATTRIB_WPOS][0], + v2->attrib[FRAG_ATTRIB_WPOS][1], + v2->attrib[FRAG_ATTRIB_WPOS][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. */ { -#if TRIANGLE_WALK_DOUBLE - const GLdouble fy0 = v0->win[1] - 0.5; - const GLdouble fy1 = v1->win[1] - 0.5; - const GLdouble fy2 = v2->win[1] - 0.5; -#else - 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; -#endif + const GLfixed fy0 = FloatToFixed(v0->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask; + const GLfixed fy1 = FloatToFixed(v1->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask; + const GLfixed fy2 = FloatToFixed(v2->attrib[FRAG_ATTRIB_WPOS][1] - 0.5F) & snapMask; if (fy0 <= fy1) { if (fy1 <= fy2) { /* y0 <= y1 <= y2 */ @@ -252,15 +213,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } /* fixed point X coords */ -#if TRIANGLE_WALK_DOUBLE - vMin_fx = vMin->win[0] + 0.5; - vMid_fx = vMid->win[0] + 0.5; - vMax_fx = vMax->win[0] + 0.5; -#else - 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; -#endif + vMin_fx = FloatToFixed(vMin->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask; + vMid_fx = FloatToFixed(vMid->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask; + vMax_fx = FloatToFixed(vMax->attrib[FRAG_ATTRIB_WPOS][0] + 0.5F) & snapMask; } /* vertex/edge relationship */ @@ -269,29 +224,16 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, eBot.v0 = vMin; eBot.v1 = vMid; /* compute deltas for each edge: vertex[upper] - vertex[lower] */ -#if TRIANGLE_WALK_DOUBLE - eMaj.dx = vMax_fx - vMin_fx; - eMaj.dy = vMax_fy - vMin_fy; - eTop.dx = vMax_fx - vMid_fx; - eTop.dy = vMax_fy - vMid_fy; - eBot.dx = vMid_fx - vMin_fx; - eBot.dy = vMid_fy - vMin_fy; -#else 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); -#endif /* compute area, oneOverArea and perform backface culling */ { -#if TRIANGLE_WALK_DOUBLE - const GLdouble area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; -#else const GLfloat area = eMaj.dx * eBot.dy - eBot.dx * eMaj.dy; -#endif /* Do backface culling */ if (area * bf < 0.0) return; @@ -307,70 +249,37 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, /* Edge setup. For a triangle strip these could be reused... */ { -#if TRIANGLE_WALK_DOUBLE - eMaj.fsy = CEILF(vMin_fy); - eMaj.lines = (GLint) CEILF(vMax_fy - eMaj.fsy); -#else eMaj.fsy = FixedCeil(vMin_fy); eMaj.lines = FixedToInt(FixedCeil(vMax_fy - eMaj.fsy)); -#endif if (eMaj.lines > 0) { eMaj.dxdy = eMaj.dx / eMaj.dy; -#if TRIANGLE_WALK_DOUBLE - eMaj.adjy = (eMaj.fsy - vMin_fy) * FIXED_SCALE; /* SCALED! */ - eMaj.fx0 = vMin_fx; - eMaj.fsx = eMaj.fx0 + (eMaj.adjy * eMaj.dxdy) / (GLdouble) FIXED_SCALE; -#else eMaj.fdxdy = SignedFloatToFixed(eMaj.dxdy); eMaj.adjy = (GLfloat) (eMaj.fsy - vMin_fy); /* SCALED! */ eMaj.fx0 = vMin_fx; eMaj.fsx = eMaj.fx0 + (GLfixed) (eMaj.adjy * eMaj.dxdy); -#endif } else { return; /*CULLED*/ } -#if TRIANGLE_WALK_DOUBLE - eTop.fsy = CEILF(vMid_fy); - eTop.lines = (GLint) CEILF(vMax_fy - eTop.fsy); -#else eTop.fsy = FixedCeil(vMid_fy); eTop.lines = FixedToInt(FixedCeil(vMax_fy - eTop.fsy)); -#endif if (eTop.lines > 0) { eTop.dxdy = eTop.dx / eTop.dy; -#if TRIANGLE_WALK_DOUBLE - eTop.adjy = (eTop.fsy - vMid_fy) * FIXED_SCALE; /* SCALED! */ - eTop.fx0 = vMid_fx; - eTop.fsx = eTop.fx0 + (eTop.adjy * eTop.dxdy) / (GLdouble) FIXED_SCALE; -#else eTop.fdxdy = SignedFloatToFixed(eTop.dxdy); eTop.adjy = (GLfloat) (eTop.fsy - vMid_fy); /* SCALED! */ eTop.fx0 = vMid_fx; eTop.fsx = eTop.fx0 + (GLfixed) (eTop.adjy * eTop.dxdy); -#endif } -#if TRIANGLE_WALK_DOUBLE - eBot.fsy = CEILF(vMin_fy); - eBot.lines = (GLint) CEILF(vMid_fy - eBot.fsy); -#else eBot.fsy = FixedCeil(vMin_fy); eBot.lines = FixedToInt(FixedCeil(vMid_fy - eBot.fsy)); -#endif if (eBot.lines > 0) { eBot.dxdy = eBot.dx / eBot.dy; -#if TRIANGLE_WALK_DOUBLE - eBot.adjy = (eBot.fsy - vMin_fy) * FIXED_SCALE; /* SCALED! */ - eBot.fx0 = vMin_fx; - eBot.fsx = eBot.fx0 + (eBot.adjy * eBot.dxdy) / (GLdouble) FIXED_SCALE; -#else eBot.fdxdy = SignedFloatToFixed(eBot.dxdy); eBot.adjy = (GLfloat) (eBot.fsy - vMin_fy); /* SCALED! */ eBot.fx0 = vMin_fx; eBot.fsx = eBot.fx0 + (GLfixed) (eBot.adjy * eBot.dxdy); -#endif } } @@ -428,10 +337,11 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_Z span.interpMask |= SPAN_Z; { - GLfloat eMaj_dz = vMax->win[2] - vMin->win[2]; - GLfloat eBot_dz = vMid->win[2] - vMin->win[2]; + GLfloat eMaj_dz = vMax->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2]; + GLfloat eBot_dz = vMid->attrib[FRAG_ATTRIB_WPOS][2] - vMin->attrib[FRAG_ATTRIB_WPOS][2]; span.attrStepX[FRAG_ATTRIB_WPOS][2] = oneOverArea * (eMaj_dz * eBot.dy - eMaj.dy * eBot_dz); - if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) { + if (span.attrStepX[FRAG_ATTRIB_WPOS][2] > maxDepth || + span.attrStepX[FRAG_ATTRIB_WPOS][2] < -maxDepth) { /* probably a sliver triangle */ span.attrStepX[FRAG_ATTRIB_WPOS][2] = 0.0; span.attrStepY[FRAG_ATTRIB_WPOS][2] = 0.0; @@ -445,42 +355,18 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.zStep = (GLint) span.attrStepX[FRAG_ATTRIB_WPOS][2]; } #endif -#ifdef INTERP_W - span.interpMask |= SPAN_W; - { - const GLfloat eMaj_dw = vMax->win[3] - vMin->win[3]; - const GLfloat eBot_dw = vMid->win[3] - vMin->win[3]; - span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); - span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); - } -#endif -#ifdef INTERP_FOG - span.interpMask |= SPAN_FOG; - { -# ifdef INTERP_W - const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; - const GLfloat eMaj_dfog = vMax->attrib[FRAG_ATTRIB_FOGC][0] * wMax - vMin->attrib[FRAG_ATTRIB_FOGC][0] * wMin; - const GLfloat eBot_dfog = vMid->attrib[FRAG_ATTRIB_FOGC][0] * wMid - vMin->attrib[FRAG_ATTRIB_FOGC][0] * wMin; -# else - const GLfloat eMaj_dfog = vMax->attrib[FRAG_ATTRIB_FOGC][0] - vMin->attrib[FRAG_ATTRIB_FOGC][0]; - const GLfloat eBot_dfog = vMid->attrib[FRAG_ATTRIB_FOGC][0] - vMin->attrib[FRAG_ATTRIB_FOGC][0]; -# endif - span.attrStepX[FRAG_ATTRIB_FOGC][0] = oneOverArea * (eMaj_dfog * eBot.dy - eMaj.dy * eBot_dfog); - span.attrStepY[FRAG_ATTRIB_FOGC][0] = 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 = (GLfloat) ((ColorTemp) vMax->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]); - GLfloat eBot_dr = (GLfloat) ((ColorTemp) vMid->color[RCOMP] - (ColorTemp) vMin->color[RCOMP]); - GLfloat eMaj_dg = (GLfloat) ((ColorTemp) vMax->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]); - GLfloat eBot_dg = (GLfloat) ((ColorTemp) vMid->color[GCOMP] - (ColorTemp) vMin->color[GCOMP]); - GLfloat eMaj_db = (GLfloat) ((ColorTemp) vMax->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]); - GLfloat eBot_db = (GLfloat) ((ColorTemp) vMid->color[BCOMP] - (ColorTemp) vMin->color[BCOMP]); + GLfloat eMaj_dr = (GLfloat) (vMax->color[RCOMP] - vMin->color[RCOMP]); + GLfloat eBot_dr = (GLfloat) (vMid->color[RCOMP] - vMin->color[RCOMP]); + GLfloat eMaj_dg = (GLfloat) (vMax->color[GCOMP] - vMin->color[GCOMP]); + GLfloat eBot_dg = (GLfloat) (vMid->color[GCOMP] - vMin->color[GCOMP]); + GLfloat eMaj_db = (GLfloat) (vMax->color[BCOMP] - vMin->color[BCOMP]); + GLfloat eBot_db = (GLfloat) (vMid->color[BCOMP] - vMin->color[BCOMP]); # ifdef INTERP_ALPHA - GLfloat eMaj_da = (GLfloat) ((ColorTemp) vMax->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]); - GLfloat eBot_da = (GLfloat) ((ColorTemp) vMid->color[ACOMP] - (ColorTemp) vMin->color[ACOMP]); + GLfloat eMaj_da = (GLfloat) (vMax->color[ACOMP] - vMin->color[ACOMP]); + GLfloat eBot_da = (GLfloat) (vMid->color[ACOMP] - vMin->color[ACOMP]); # endif span.attrStepX[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj_dr * eBot.dy - eMaj.dy * eBot_dr); span.attrStepY[FRAG_ATTRIB_COL0][0] = oneOverArea * (eMaj.dx * eBot_dr - eMaj_dr * eBot.dx); @@ -488,23 +374,13 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.attrStepY[FRAG_ATTRIB_COL0][1] = oneOverArea * (eMaj.dx * eBot_dg - eMaj_dg * eBot.dx); span.attrStepX[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj_db * eBot.dy - eMaj.dy * eBot_db); span.attrStepY[FRAG_ATTRIB_COL0][2] = oneOverArea * (eMaj.dx * eBot_db - eMaj_db * eBot.dx); -# if CHAN_TYPE == GL_FLOAT - span.redStep = span.attrStepX[FRAG_ATTRIB_COL0][0]; - span.greenStep = span.attrStepX[FRAG_ATTRIB_COL0][1]; - span.blueStep = span.attrStepX[FRAG_ATTRIB_COL0][2]; -# else span.redStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][0]); span.greenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][1]); span.blueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][2]); -# endif /* GL_FLOAT */ # ifdef INTERP_ALPHA span.attrStepX[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); span.attrStepY[FRAG_ATTRIB_COL0][3] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); -# if CHAN_TYPE == GL_FLOAT - span.alphaStep = span.attrStepX[FRAG_ATTRIB_COL0][3]; -# else span.alphaStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL0][3]); -# endif /* GL_FLOAT */ # endif /* INTERP_ALPHA */ } else { @@ -513,70 +389,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, span.attrStepX[FRAG_ATTRIB_COL0][0] = span.attrStepY[FRAG_ATTRIB_COL0][0] = 0.0F; span.attrStepX[FRAG_ATTRIB_COL0][1] = span.attrStepY[FRAG_ATTRIB_COL0][1] = 0.0F; span.attrStepX[FRAG_ATTRIB_COL0][2] = span.attrStepY[FRAG_ATTRIB_COL0][2] = 0.0F; -# if CHAN_TYPE == GL_FLOAT - span.redStep = 0.0F; - span.greenStep = 0.0F; - span.blueStep = 0.0F; -# else span.redStep = 0; span.greenStep = 0; span.blueStep = 0; -# endif /* GL_FLOAT */ # ifdef INTERP_ALPHA - span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepY[FRAG_ATTRIB_COL0][3] = 0.0F; -# if CHAN_TYPE == GL_FLOAT - span.alphaStep = 0.0F; -# else + span.attrStepX[FRAG_ATTRIB_COL0][3] = span.attrStepX[FRAG_ATTRIB_COL0][3] = 0.0F; span.alphaStep = 0; -# endif /* GL_FLOAT */ # endif } #endif /* INTERP_RGB */ -#ifdef INTERP_SPEC - span.interpMask |= SPAN_SPEC; - if (ctx->Light.ShadeModel == GL_SMOOTH) { - GLfloat eMaj_dsr = (GLfloat) ((ColorTemp) vMax->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]); - GLfloat eBot_dsr = (GLfloat) ((ColorTemp) vMid->specular[RCOMP] - (ColorTemp) vMin->specular[RCOMP]); - GLfloat eMaj_dsg = (GLfloat) ((ColorTemp) vMax->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]); - GLfloat eBot_dsg = (GLfloat) ((ColorTemp) vMid->specular[GCOMP] - (ColorTemp) vMin->specular[GCOMP]); - GLfloat eMaj_dsb = (GLfloat) ((ColorTemp) vMax->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]); - GLfloat eBot_dsb = (GLfloat) ((ColorTemp) vMid->specular[BCOMP] - (ColorTemp) vMin->specular[BCOMP]); - span.attrStepX[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj_dsr * eBot.dy - eMaj.dy * eBot_dsr); - span.attrStepY[FRAG_ATTRIB_COL1][0] = oneOverArea * (eMaj.dx * eBot_dsr - eMaj_dsr * eBot.dx); - span.attrStepX[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj_dsg * eBot.dy - eMaj.dy * eBot_dsg); - span.attrStepY[FRAG_ATTRIB_COL1][1] = oneOverArea * (eMaj.dx * eBot_dsg - eMaj_dsg * eBot.dx); - span.attrStepX[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj_dsb * eBot.dy - eMaj.dy * eBot_dsb); - span.attrStepY[FRAG_ATTRIB_COL1][2] = oneOverArea * (eMaj.dx * eBot_dsb - eMaj_dsb * eBot.dx); -# if CHAN_TYPE == GL_FLOAT - span.specRedStep = span.attrStepX[FRAG_ATTRIB_COL1][0]; - span.specGreenStep = span.attrStepX[FRAG_ATTRIB_COL1][1]; - span.specBlueStep = span.attrStepX[FRAG_ATTRIB_COL1][2]; -# else - span.specRedStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][0]); - span.specGreenStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][1]); - span.specBlueStep = SignedFloatToFixed(span.attrStepX[FRAG_ATTRIB_COL1][2]); -# endif - } - else { - span.attrStepX[FRAG_ATTRIB_COL1][0] = span.attrStepY[FRAG_ATTRIB_COL1][0] = 0.0F; - span.attrStepX[FRAG_ATTRIB_COL1][1] = span.attrStepY[FRAG_ATTRIB_COL1][1] = 0.0F; - span.attrStepX[FRAG_ATTRIB_COL1][2] = span.attrStepY[FRAG_ATTRIB_COL1][2] = 0.0F; -# if CHAN_TYPE == GL_FLOAT - span.specRedStep = 0.0F; - span.specGreenStep = 0.0F; - span.specBlueStep = 0.0F; -# else - span.specRedStep = 0; - span.specGreenStep = 0; - span.specBlueStep = 0; -# endif - } -#endif /* INTERP_SPEC */ #ifdef INTERP_INDEX span.interpMask |= SPAN_INDEX; if (ctx->Light.ShadeModel == GL_SMOOTH) { - GLfloat eMaj_di = vMax->index - vMin->index; - GLfloat eBot_di = vMid->index - vMin->index; + GLfloat eMaj_di = vMax->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0]; + GLfloat eBot_di = vMid->attrib[FRAG_ATTRIB_CI][0] - vMin->attrib[FRAG_ATTRIB_CI][0]; didx = oneOverArea * (eMaj_di * eBot.dy - eMaj.dy * eBot_di); didy = oneOverArea * (eMaj.dx * eBot_di - eMaj_di * eBot.dx); span.indexStep = SignedFloatToFixed(didx); @@ -588,7 +414,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } #endif #ifdef INTERP_INT_TEX - span.interpMask |= SPAN_INT_TEXTURE; { GLfloat eMaj_ds = (vMax->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; GLfloat eBot_ds = (vMid->attrib[FRAG_ATTRIB_TEX0][0] - vMin->attrib[FRAG_ATTRIB_TEX0][0]) * S_SCALE; @@ -603,27 +428,31 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } #endif #ifdef INTERP_ATTRIBS - span.interpMask |= (SPAN_TEXTURE | SPAN_VARYING); { - /* win[3] is 1/W */ - const GLfloat wMax = vMax->win[3], wMin = vMin->win[3], wMid = vMid->win[3]; + /* attrib[FRAG_ATTRIB_WPOS][3] is 1/W */ + const GLfloat wMax = vMax->attrib[FRAG_ATTRIB_WPOS][3]; + const GLfloat wMin = vMin->attrib[FRAG_ATTRIB_WPOS][3]; + const GLfloat wMid = vMid->attrib[FRAG_ATTRIB_WPOS][3]; + { + const GLfloat eMaj_dw = wMax - wMin; + const GLfloat eBot_dw = wMid - wMin; + span.attrStepX[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj_dw * eBot.dy - eMaj.dy * eBot_dw); + span.attrStepY[FRAG_ATTRIB_WPOS][3] = oneOverArea * (eMaj.dx * eBot_dw - eMaj_dw * eBot.dx); + } ATTRIB_LOOP_BEGIN - GLfloat eMaj_ds = vMax->attrib[attr][0] * wMax - vMin->attrib[attr][0] * wMin; - GLfloat eBot_ds = vMid->attrib[attr][0] * wMid - vMin->attrib[attr][0] * wMin; - GLfloat eMaj_dt = vMax->attrib[attr][1] * wMax - vMin->attrib[attr][1] * wMin; - GLfloat eBot_dt = vMid->attrib[attr][1] * wMid - vMin->attrib[attr][1] * wMin; - GLfloat eMaj_du = vMax->attrib[attr][2] * wMax - vMin->attrib[attr][2] * wMin; - GLfloat eBot_du = vMid->attrib[attr][2] * wMid - vMin->attrib[attr][2] * wMin; - GLfloat eMaj_dv = vMax->attrib[attr][3] * wMax - vMin->attrib[attr][3] * wMin; - GLfloat eBot_dv = vMid->attrib[attr][3] * wMid - vMin->attrib[attr][3] * wMin; - span.attrStepX[attr][0] = oneOverArea * (eMaj_ds * eBot.dy - eMaj.dy * eBot_ds); - span.attrStepY[attr][0] = oneOverArea * (eMaj.dx * eBot_ds - eMaj_ds * eBot.dx); - span.attrStepX[attr][1] = oneOverArea * (eMaj_dt * eBot.dy - eMaj.dy * eBot_dt); - span.attrStepY[attr][1] = oneOverArea * (eMaj.dx * eBot_dt - eMaj_dt * eBot.dx); - span.attrStepX[attr][2] = oneOverArea * (eMaj_du * eBot.dy - eMaj.dy * eBot_du); - span.attrStepY[attr][2] = oneOverArea * (eMaj.dx * eBot_du - eMaj_du * eBot.dx); - span.attrStepX[attr][3] = oneOverArea * (eMaj_dv * eBot.dy - eMaj.dy * eBot_dv); - span.attrStepY[attr][3] = oneOverArea * (eMaj.dx * eBot_dv - eMaj_dv * eBot.dx); + if (swrast->_InterpMode[attr] == GL_FLAT) { + ASSIGN_4V(span.attrStepX[attr], 0.0, 0.0, 0.0, 0.0); + ASSIGN_4V(span.attrStepY[attr], 0.0, 0.0, 0.0, 0.0); + } + else { + GLuint c; + for (c = 0; c < 4; c++) { + GLfloat eMaj_da = vMax->attrib[attr][c] * wMax - vMin->attrib[attr][c] * wMin; + GLfloat eBot_da = vMid->attrib[attr][c] * wMid - vMin->attrib[attr][c] * wMin; + span.attrStepX[attr][c] = oneOverArea * (eMaj_da * eBot.dy - eMaj.dy * eBot_da); + span.attrStepY[attr][c] = oneOverArea * (eMaj.dx * eBot_da - eMaj_da * eBot.dx); + } + } ATTRIB_LOOP_END } #endif @@ -677,9 +506,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, { GLint subTriangle; - GLinterp fxLeftEdge = 0, fxRightEdge = 0; - GLinterp fdxLeftEdge = 0, fdxRightEdge = 0; - GLinterp fError = 0, fdError = 0; + GLfixed fxLeftEdge = 0, fxRightEdge = 0; + GLfixed fdxLeftEdge = 0, fdxRightEdge = 0; + GLfixed fError = 0, fdError = 0; #ifdef PIXEL_ADDRESS PIXEL_TYPE *pRow = NULL; GLint dPRowOuter = 0, dPRowInner; /* offset in bytes */ @@ -694,24 +523,13 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLuint zLeft = 0; GLfixed fdzOuter = 0, fdzInner; #endif -#ifdef INTERP_W - GLfloat wLeft = 0, dwOuter = 0, dwInner; -#endif -#ifdef INTERP_FOG - GLfloat fogLeft = 0, dfogOuter = 0, dfogInner; -#endif #ifdef INTERP_RGB - ColorTemp rLeft = 0, fdrOuter = 0, fdrInner; - ColorTemp gLeft = 0, fdgOuter = 0, fdgInner; - ColorTemp bLeft = 0, fdbOuter = 0, fdbInner; + GLint rLeft = 0, fdrOuter = 0, fdrInner; + GLint gLeft = 0, fdgOuter = 0, fdgInner; + GLint bLeft = 0, fdbOuter = 0, fdbInner; #endif #ifdef INTERP_ALPHA - ColorTemp aLeft = 0, fdaOuter = 0, fdaInner; -#endif -#ifdef INTERP_SPEC - ColorTemp srLeft=0, dsrOuter=0, dsrInner; - ColorTemp sgLeft=0, dsgOuter=0, dsgInner; - ColorTemp sbLeft=0, dsbOuter=0, dsbInner; + GLint aLeft = 0, fdaOuter = 0, fdaInner; #endif #ifdef INTERP_INDEX GLfixed iLeft=0, diOuter=0, diInner; @@ -721,14 +539,9 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, GLfixed tLeft=0, dtOuter=0, dtInner; #endif #ifdef INTERP_ATTRIBS - GLfloat sLeft[FRAG_ATTRIB_MAX]; - GLfloat tLeft[FRAG_ATTRIB_MAX]; - GLfloat uLeft[FRAG_ATTRIB_MAX]; - GLfloat vLeft[FRAG_ATTRIB_MAX]; - GLfloat dsOuter[FRAG_ATTRIB_MAX], dsInner[FRAG_ATTRIB_MAX]; - GLfloat dtOuter[FRAG_ATTRIB_MAX], dtInner[FRAG_ATTRIB_MAX]; - GLfloat duOuter[FRAG_ATTRIB_MAX], duInner[FRAG_ATTRIB_MAX]; - GLfloat dvOuter[FRAG_ATTRIB_MAX], dvInner[FRAG_ATTRIB_MAX]; + GLfloat wLeft = 0, dwOuter = 0, dwInner; + GLfloat attrLeft[FRAG_ATTRIB_MAX][4]; + GLfloat daOuter[FRAG_ATTRIB_MAX][4], daInner[FRAG_ATTRIB_MAX][4]; #endif for (subTriangle=0; subTriangle<=1; subTriangle++) { @@ -775,30 +588,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, if (setupLeft && eLeft->lines > 0) { const SWvertex *vLower = eLeft->v0; -#if TRIANGLE_WALK_DOUBLE - const GLdouble fsy = eLeft->fsy; - const GLdouble fsx = eLeft->fsx; - const GLdouble fx = CEILF(fsx); - const GLdouble adjx = (fx - eLeft->fx0) * FIXED_SCALE; /* SCALED! */ -#else const GLfixed fsy = eLeft->fsy; const GLfixed fsx = eLeft->fsx; /* no fractional part */ const GLfixed fx = FixedCeil(fsx); /* no fractional part */ - const GLfixed adjx = (GLinterp) (fx - eLeft->fx0); /* SCALED! */ -#endif - const GLinterp adjy = (GLinterp) eLeft->adjy; /* SCALED! */ + const GLfixed adjx = (GLfixed) (fx - eLeft->fx0); /* SCALED! */ + const GLfixed adjy = (GLfixed) eLeft->adjy; /* SCALED! */ GLint idxOuter; -#if TRIANGLE_WALK_DOUBLE - GLdouble dxOuter; - - fError = fx - fsx - 1.0; - fxLeftEdge = fsx; - fdxLeftEdge = eLeft->dxdy; - dxOuter = FLOORF(fdxLeftEdge); - fdError = dxOuter - fdxLeftEdge + 1.0; - idxOuter = (GLint) dxOuter; - span.y = (GLint) fsy; -#else GLfloat dxOuter; GLfixed fdxOuter; @@ -810,7 +605,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, idxOuter = FixedToInt(fdxOuter); dxOuter = (GLfloat) idxOuter; span.y = FixedToInt(fsy); -#endif /* silence warnings on some compilers */ (void) dxOuter; @@ -820,7 +614,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef PIXEL_ADDRESS { - pRow = (PIXEL_TYPE *) PIXEL_ADDRESS(InterpToInt(fxLeftEdge), span.y); + 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 */ } @@ -837,7 +631,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_Z { - GLfloat z0 = vLower->win[2]; + GLfloat z0 = vLower->attrib[FRAG_ATTRIB_WPOS][2]; if (depthBits <= 16) { /* interpolate fixed-pt values */ GLfloat tmp = (z0 * FIXED_SCALE @@ -847,129 +641,71 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, zLeft = (GLfixed) tmp; else zLeft = MAX_GLUINT / 2; - fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); + fdzOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_WPOS][2] + + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } else { /* interpolate depth values w/out scaling */ zLeft = (GLuint) (z0 + span.attrStepX[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjx) + span.attrStepY[FRAG_ATTRIB_WPOS][2] * FixedToFloat(adjy)); - fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); + fdzOuter = (GLint) (span.attrStepY[FRAG_ATTRIB_WPOS][2] + + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][2]); } # ifdef DEPTH_TYPE zRow = (DEPTH_TYPE *) - zrb->GetPointer(ctx, zrb, InterpToInt(fxLeftEdge), span.y); + zrb->GetPointer(ctx, zrb, FixedToInt(fxLeftEdge), span.y); dZRowOuter = (ctx->DrawBuffer->Width + idxOuter) * sizeof(DEPTH_TYPE); # endif } #endif -#ifdef INTERP_W - wLeft = vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_WPOS][3] * adjx + span.attrStepY[FRAG_ATTRIB_WPOS][3] * adjy) * (1.0F/FIXED_SCALE); - dwOuter = span.attrStepY[FRAG_ATTRIB_WPOS][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_WPOS][3]; -#endif -#ifdef INTERP_FOG -# ifdef INTERP_W - fogLeft = vLower->attrib[FRAG_ATTRIB_FOGC][0] * vLower->win[3] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE); -# else - fogLeft = vLower->attrib[FRAG_ATTRIB_FOGC][0] + (span.attrStepX[FRAG_ATTRIB_FOGC][0] * adjx + span.attrStepY[FRAG_ATTRIB_FOGC][0] * adjy) * (1.0F/FIXED_SCALE); -# endif - dfogOuter = span.attrStepY[FRAG_ATTRIB_FOGC][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_FOGC][0]; -#endif #ifdef INTERP_RGB if (ctx->Light.ShadeModel == GL_SMOOTH) { -# if CHAN_TYPE == GL_FLOAT - rLeft = vLower->color[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) * (1.0F / FIXED_SCALE); - gLeft = vLower->color[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) * (1.0F / FIXED_SCALE); - bLeft = vLower->color[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) * (1.0F / FIXED_SCALE); - fdrOuter = span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]; - fdgOuter = span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]; - fdbOuter = span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]; -# else - rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF; - gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF; - bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF; - fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]); - fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]); - fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]); -# endif + rLeft = (GLint)(ChanToFixed(vLower->color[RCOMP]) + + span.attrStepX[FRAG_ATTRIB_COL0][0] * adjx + + span.attrStepY[FRAG_ATTRIB_COL0][0] * adjy) + FIXED_HALF; + gLeft = (GLint)(ChanToFixed(vLower->color[GCOMP]) + + span.attrStepX[FRAG_ATTRIB_COL0][1] * adjx + + span.attrStepY[FRAG_ATTRIB_COL0][1] * adjy) + FIXED_HALF; + bLeft = (GLint)(ChanToFixed(vLower->color[BCOMP]) + + span.attrStepX[FRAG_ATTRIB_COL0][2] * adjx + + span.attrStepY[FRAG_ATTRIB_COL0][2] * adjy) + FIXED_HALF; + fdrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][0] + + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][0]); + fdgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][1] + + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][1]); + fdbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][2] + + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][2]); # ifdef INTERP_ALPHA -# if CHAN_TYPE == GL_FLOAT - aLeft = vLower->color[ACOMP] + (span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) * (1.0F / FIXED_SCALE); - fdaOuter = span.attrStepY[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]; -# else - aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF; - fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]); -# endif + aLeft = (GLint)(ChanToFixed(vLower->color[ACOMP]) + + span.attrStepX[FRAG_ATTRIB_COL0][3] * adjx + + span.attrStepY[FRAG_ATTRIB_COL0][3] * adjy) + FIXED_HALF; + fdaOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL0][3] + + dxOuter * span.attrStepX[FRAG_ATTRIB_COL0][3]); # endif } else { ASSERT(ctx->Light.ShadeModel == GL_FLAT); -# if CHAN_TYPE == GL_FLOAT - rLeft = v2->color[RCOMP]; - gLeft = v2->color[GCOMP]; - bLeft = v2->color[BCOMP]; - fdrOuter = fdgOuter = fdbOuter = 0.0F; -# else rLeft = ChanToFixed(v2->color[RCOMP]); gLeft = ChanToFixed(v2->color[GCOMP]); bLeft = ChanToFixed(v2->color[BCOMP]); fdrOuter = fdgOuter = fdbOuter = 0; -# endif # ifdef INTERP_ALPHA -# if CHAN_TYPE == GL_FLOAT - aLeft = v2->color[ACOMP]; - fdaOuter = 0.0F; -# else aLeft = ChanToFixed(v2->color[ACOMP]); fdaOuter = 0; -# endif # endif } #endif /* INTERP_RGB */ -#ifdef INTERP_SPEC - if (ctx->Light.ShadeModel == GL_SMOOTH) { -# if CHAN_TYPE == GL_FLOAT - srLeft = vLower->specular[RCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) * (1.0F / FIXED_SCALE); - sgLeft = vLower->specular[GCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) * (1.0F / FIXED_SCALE); - sbLeft = vLower->specular[BCOMP] + (span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) * (1.0F / FIXED_SCALE); - dsrOuter = span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]; - dsgOuter = span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]; - dsbOuter = span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]; -# else - srLeft = (GLfixed) (ChanToFixed(vLower->specular[RCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][0] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][0] * adjy) + FIXED_HALF; - sgLeft = (GLfixed) (ChanToFixed(vLower->specular[GCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][1] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][1] * adjy) + FIXED_HALF; - sbLeft = (GLfixed) (ChanToFixed(vLower->specular[BCOMP]) + span.attrStepX[FRAG_ATTRIB_COL1][2] * adjx + span.attrStepY[FRAG_ATTRIB_COL1][2] * adjy) + FIXED_HALF; - dsrOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][0]); - dsgOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][1]); - dsbOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_COL1][2] + dxOuter * span.attrStepX[FRAG_ATTRIB_COL1][2]); -# endif - } - else { - ASSERT(ctx->Light.ShadeModel == GL_FLAT); -#if CHAN_TYPE == GL_FLOAT - srLeft = v2->specular[RCOMP]; - sgLeft = v2->specular[GCOMP]; - sbLeft = v2->specular[BCOMP]; - dsrOuter = dsgOuter = dsbOuter = 0.0F; -# else - srLeft = ChanToFixed(v2->specular[RCOMP]); - sgLeft = ChanToFixed(v2->specular[GCOMP]); - sbLeft = ChanToFixed(v2->specular[BCOMP]); - dsrOuter = dsgOuter = dsbOuter = 0; -# endif - } -#endif - #ifdef INTERP_INDEX if (ctx->Light.ShadeModel == GL_SMOOTH) { - iLeft = (GLfixed)(vLower->index * FIXED_SCALE + iLeft = (GLfixed)(vLower->attrib[FRAG_ATTRIB_CI][0] * FIXED_SCALE + didx * adjx + didy * adjy) + FIXED_HALF; diOuter = SignedFloatToFixed(didy + dxOuter * didx); } else { ASSERT(ctx->Light.ShadeModel == GL_FLAT); - iLeft = FloatToFixed(v2->index); + iLeft = FloatToFixed(v2->attrib[FRAG_ATTRIB_CI][0]); diOuter = 0; } #endif @@ -979,42 +715,50 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, s0 = vLower->attrib[FRAG_ATTRIB_TEX0][0] * S_SCALE; sLeft = (GLfixed)(s0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][0] * adjx + span.attrStepY[FRAG_ATTRIB_TEX0][0] * adjy) + FIXED_HALF; - dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]); + dsOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][0] + + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][0]); t0 = vLower->attrib[FRAG_ATTRIB_TEX0][1] * T_SCALE; tLeft = (GLfixed)(t0 * FIXED_SCALE + span.attrStepX[FRAG_ATTRIB_TEX0][1] * adjx + span.attrStepY[FRAG_ATTRIB_TEX0][1] * adjy) + FIXED_HALF; - dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]); + dtOuter = SignedFloatToFixed(span.attrStepY[FRAG_ATTRIB_TEX0][1] + + dxOuter * span.attrStepX[FRAG_ATTRIB_TEX0][1]); } #endif #ifdef INTERP_ATTRIBS + { + const GLuint attr = FRAG_ATTRIB_WPOS; + wLeft = vLower->attrib[FRAG_ATTRIB_WPOS][3] + + (span.attrStepX[attr][3] * adjx + + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); + dwOuter = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; + } ATTRIB_LOOP_BEGIN - const GLfloat invW = vLower->win[3]; - const GLfloat s0 = vLower->attrib[attr][0] * invW; - const GLfloat t0 = vLower->attrib[attr][1] * invW; - const GLfloat u0 = vLower->attrib[attr][2] * invW; - const GLfloat v0 = vLower->attrib[attr][3] * invW; - sLeft[attr] = s0 + (span.attrStepX[attr][0] * adjx + span.attrStepY[attr][0] * adjy) * (1.0F/FIXED_SCALE); - tLeft[attr] = t0 + (span.attrStepX[attr][1] * adjx + span.attrStepY[attr][1] * adjy) * (1.0F/FIXED_SCALE); - uLeft[attr] = u0 + (span.attrStepX[attr][2] * adjx + span.attrStepY[attr][2] * adjy) * (1.0F/FIXED_SCALE); - vLeft[attr] = v0 + (span.attrStepX[attr][3] * adjx + span.attrStepY[attr][3] * adjy) * (1.0F/FIXED_SCALE); - dsOuter[attr] = span.attrStepY[attr][0] + dxOuter * span.attrStepX[attr][0]; - dtOuter[attr] = span.attrStepY[attr][1] + dxOuter * span.attrStepX[attr][1]; - duOuter[attr] = span.attrStepY[attr][2] + dxOuter * span.attrStepX[attr][2]; - dvOuter[attr] = span.attrStepY[attr][3] + dxOuter * span.attrStepX[attr][3]; + const GLfloat invW = vLower->attrib[FRAG_ATTRIB_WPOS][3]; + if (swrast->_InterpMode[attr] == GL_FLAT) { + GLuint c; + for (c = 0; c < 4; c++) { + attrLeft[attr][c] = v2->attrib[attr][c] * invW; + daOuter[attr][c] = 0.0; + } + } + else { + GLuint c; + for (c = 0; c < 4; c++) { + const GLfloat a = vLower->attrib[attr][c] * invW; + attrLeft[attr][c] = a + ( span.attrStepX[attr][c] * adjx + + span.attrStepY[attr][c] * adjy) * (1.0F/FIXED_SCALE); + daOuter[attr][c] = span.attrStepY[attr][c] + dxOuter * span.attrStepX[attr][c]; + } + } ATTRIB_LOOP_END #endif } /*if setupLeft*/ if (setupRight && eRight->lines>0) { -#if TRIANGLE_WALK_DOUBLE - fxRightEdge = eRight->fsx; - fdxRightEdge = eRight->dxdy; -#else fxRightEdge = eRight->fsx - FIXED_EPSILON; fdxRightEdge = eRight->fdxdy; -#endif } if (lines==0) { @@ -1032,12 +776,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif fdzInner = fdzOuter + span.zStep; #endif -#ifdef INTERP_W - dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3]; -#endif -#ifdef INTERP_FOG - dfogInner = dfogOuter + span.attrStepX[FRAG_ATTRIB_FOGC][0]; -#endif #ifdef INTERP_RGB fdrInner = fdrOuter + span.redStep; fdgInner = fdgOuter + span.greenStep; @@ -1046,11 +784,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA fdaInner = fdaOuter + span.alphaStep; #endif -#ifdef INTERP_SPEC - dsrInner = dsrOuter + span.specRedStep; - dsgInner = dsgOuter + span.specGreenStep; - dsbInner = dsbOuter + span.specBlueStep; -#endif #ifdef INTERP_INDEX diInner = diOuter + span.indexStep; #endif @@ -1059,19 +792,20 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, dtInner = dtOuter + span.intTexStep[1]; #endif #ifdef INTERP_ATTRIBS + dwInner = dwOuter + span.attrStepX[FRAG_ATTRIB_WPOS][3]; ATTRIB_LOOP_BEGIN - dsInner[attr] = dsOuter[attr] + span.attrStepX[attr][0]; - dtInner[attr] = dtOuter[attr] + span.attrStepX[attr][1]; - duInner[attr] = duOuter[attr] + span.attrStepX[attr][2]; - dvInner[attr] = dvOuter[attr] + span.attrStepX[attr][3]; + GLuint c; + for (c = 0; c < 4; c++) { + daInner[attr][c] = daOuter[attr][c] + span.attrStepX[attr][c]; + } ATTRIB_LOOP_END #endif while (lines > 0) { /* initialize the span interpolants to the leftmost value */ /* ff = fixed-pt fragment */ - const GLint right = InterpToInt(fxRightEdge); - span.x = InterpToInt(fxLeftEdge); + const GLint right = FixedToInt(fxRightEdge); + span.x = FixedToInt(fxLeftEdge); if (right <= span.x) span.end = 0; else @@ -1080,12 +814,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_Z span.z = zLeft; #endif -#ifdef INTERP_W - span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft; -#endif -#ifdef INTERP_FOG - span.attrStart[FRAG_ATTRIB_FOGC][0] = fogLeft; -#endif #ifdef INTERP_RGB span.red = rLeft; span.green = gLeft; @@ -1094,11 +822,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA span.alpha = aLeft; #endif -#ifdef INTERP_SPEC - span.specRed = srLeft; - span.specGreen = sgLeft; - span.specBlue = sbLeft; -#endif #ifdef INTERP_INDEX span.index = iLeft; #endif @@ -1108,11 +831,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #endif #ifdef INTERP_ATTRIBS + span.attrStart[FRAG_ATTRIB_WPOS][3] = wLeft; ATTRIB_LOOP_BEGIN - span.attrStart[attr][0] = sLeft[attr]; - span.attrStart[attr][1] = tLeft[attr]; - span.attrStart[attr][2] = uLeft[attr]; - span.attrStart[attr][3] = vLeft[attr]; + GLuint c; + for (c = 0; c < 4; c++) { + span.attrStart[attr][c] = attrLeft[attr][c]; + } ATTRIB_LOOP_END #endif @@ -1131,11 +855,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA CLAMP_INTERPOLANT(alpha, alphaStep, len); #endif -#ifdef INTERP_SPEC - CLAMP_INTERPOLANT(specRed, specRedStep, len); - CLAMP_INTERPOLANT(specGreen, specGreenStep, len); - CLAMP_INTERPOLANT(specBlue, specBlueStep, len); -#endif #ifdef INTERP_INDEX CLAMP_INTERPOLANT(index, indexStep, len); #endif @@ -1158,7 +877,7 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, fError += fdError; if (fError >= 0) { - fError -= INTERP_ONE; + fError -= FIXED_ONE; #ifdef PIXEL_ADDRESS pRow = (PIXEL_TYPE *) ((GLubyte *) pRow + dPRowOuter); @@ -1169,12 +888,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif zLeft += fdzOuter; #endif -#ifdef INTERP_W - wLeft += dwOuter; -#endif -#ifdef INTERP_FOG - fogLeft += dfogOuter; -#endif #ifdef INTERP_RGB rLeft += fdrOuter; gLeft += fdgOuter; @@ -1183,11 +896,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA aLeft += fdaOuter; #endif -#ifdef INTERP_SPEC - srLeft += dsrOuter; - sgLeft += dsgOuter; - sbLeft += dsbOuter; -#endif #ifdef INTERP_INDEX iLeft += diOuter; #endif @@ -1196,11 +904,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, tLeft += dtOuter; #endif #ifdef INTERP_ATTRIBS + wLeft += dwOuter; ATTRIB_LOOP_BEGIN - sLeft[attr] += dsOuter[attr]; - tLeft[attr] += dtOuter[attr]; - uLeft[attr] += duOuter[attr]; - vLeft[attr] += dvOuter[attr]; + GLuint c; + for (c = 0; c < 4; c++) { + attrLeft[attr][c] += daOuter[attr][c]; + } ATTRIB_LOOP_END #endif } @@ -1214,12 +923,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, # endif zLeft += fdzInner; #endif -#ifdef INTERP_W - wLeft += dwInner; -#endif -#ifdef INTERP_FOG - fogLeft += dfogInner; -#endif #ifdef INTERP_RGB rLeft += fdrInner; gLeft += fdgInner; @@ -1228,11 +931,6 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #ifdef INTERP_ALPHA aLeft += fdaInner; #endif -#ifdef INTERP_SPEC - srLeft += dsrInner; - sgLeft += dsgInner; - sbLeft += dsbInner; -#endif #ifdef INTERP_INDEX iLeft += diInner; #endif @@ -1241,11 +939,12 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, tLeft += dtInner; #endif #ifdef INTERP_ATTRIBS + wLeft += dwInner; ATTRIB_LOOP_BEGIN - sLeft[attr] += dsInner[attr]; - tLeft[attr] += dtInner[attr]; - uLeft[attr] += duInner[attr]; - vLeft[attr] += dvInner[attr]; + GLuint c; + for (c = 0; c < 4; c++) { + attrLeft[attr][c] += daInner[attr][c]; + } ATTRIB_LOOP_END #endif } @@ -1254,14 +953,10 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, } /* for subTriangle */ } -#ifdef CLEANUP_CODE - CLEANUP_CODE -#endif } } #undef SETUP_CODE -#undef CLEANUP_CODE #undef RENDER_SPAN #undef PIXEL_TYPE @@ -1270,24 +965,15 @@ static void NAME(GLcontext *ctx, const SWvertex *v0, #undef DEPTH_TYPE #undef INTERP_Z -#undef INTERP_W -#undef INTERP_FOG #undef INTERP_RGB #undef INTERP_ALPHA -#undef INTERP_SPEC #undef INTERP_INDEX #undef INTERP_INT_TEX #undef INTERP_ATTRIBS -#undef TEX_UNIT_LOOP -#undef VARYING_LOOP #undef S_SCALE #undef T_SCALE #undef FixedToDepth -#undef ColorTemp -#undef GLinterp -#undef InterpToInt -#undef INTERP_ONE #undef NAME diff --git a/src/mesa/swrast/s_zoom.c b/src/mesa/swrast/s_zoom.c index 0908265fe9d..78fa137d3fd 100644 --- a/src/mesa/swrast/s_zoom.c +++ b/src/mesa/swrast/s_zoom.c @@ -155,14 +155,11 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, zoomed_arrays.ChanType = span->array->ChanType; /* XXX temporary */ #if CHAN_TYPE == GL_UNSIGNED_BYTE - zoomed_arrays.rgba = zoomed_arrays.color.sz1.rgba; - zoomed_arrays.spec = zoomed_arrays.color.sz1.spec; + zoomed_arrays.rgba = zoomed_arrays.rgba8; #elif CHAN_TYPE == GL_UNSIGNED_SHORT - zoomed_arrays.rgba = zoomed_arrays.color.sz2.rgba; - zoomed_arrays.spec = zoomed_arrays.color.sz2.spec; + zoomed_arrays.rgba = zoomed_arrays.rgba16; #else zoomed_arrays.rgba = zoomed_arrays.attribs[FRAG_ATTRIB_COL0]; - zoomed_arrays.spec = zoomed_arrays.attribs[FRAG_ATTRIB_COL1]; #endif @@ -219,7 +216,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); ASSERT(j < (GLint) span->end); - COPY_4UBV(zoomed.array->color.sz1.rgba[i], rgba[j]); + COPY_4UBV(zoomed.array->rgba8[i], rgba[j]); } } else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) { @@ -229,7 +226,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); ASSERT(j < (GLint) span->end); - COPY_4V(zoomed.array->color.sz2.rgba[i], rgba[j]); + COPY_4V(zoomed.array->rgba16[i], rgba[j]); } } else { @@ -251,10 +248,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); ASSERT(j < (GLint) span->end); - zoomed.array->color.sz1.rgba[i][0] = rgb[j][0]; - zoomed.array->color.sz1.rgba[i][1] = rgb[j][1]; - zoomed.array->color.sz1.rgba[i][2] = rgb[j][2]; - zoomed.array->color.sz1.rgba[i][3] = 0xff; + zoomed.array->rgba8[i][0] = rgb[j][0]; + zoomed.array->rgba8[i][1] = rgb[j][1]; + zoomed.array->rgba8[i][2] = rgb[j][2]; + zoomed.array->rgba8[i][3] = 0xff; } } else if (zoomed.array->ChanType == GL_UNSIGNED_SHORT) { @@ -264,10 +261,10 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, GLint j = unzoom_x(ctx->Pixel.ZoomX, imgX, x0 + i) - span->x; ASSERT(j >= 0); ASSERT(j < (GLint) span->end); - zoomed.array->color.sz2.rgba[i][0] = rgb[j][0]; - zoomed.array->color.sz2.rgba[i][1] = rgb[j][1]; - zoomed.array->color.sz2.rgba[i][2] = rgb[j][2]; - zoomed.array->color.sz2.rgba[i][3] = 0xffff; + zoomed.array->rgba16[i][0] = rgb[j][0]; + zoomed.array->rgba16[i][1] = rgb[j][1]; + zoomed.array->rgba16[i][2] = rgb[j][2]; + zoomed.array->rgba16[i][3] = 0xffff; } } else { @@ -314,8 +311,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, * Also, clipping may change the span end value, so store it as well. */ const GLint end = zoomed.end; /* save */ - /* use specular color array for temp storage */ - void *rgbaSave = zoomed.array->spec; + GLuint rgbaSave[MAX_WIDTH][4]; const GLint pixelSize = (zoomed.array->ChanType == GL_UNSIGNED_BYTE) ? 4 * sizeof(GLubyte) : ((zoomed.array->ChanType == GL_UNSIGNED_SHORT) ? 4 * sizeof(GLushort) @@ -334,7 +330,7 @@ zoom_span( GLcontext *ctx, GLint imgX, GLint imgY, const SWspan *span, } else if (format == GL_COLOR_INDEX) { /* use specular color array for temp storage */ - GLuint *indexSave = (GLuint *) zoomed.array->spec; + GLuint *indexSave = (GLuint *) zoomed.array->attribs[FRAG_ATTRIB_FOGC]; const GLint end = zoomed.end; /* save */ if (y1 - y0 > 1) { MEMCPY(indexSave, zoomed.array->index, zoomed.end * sizeof(GLuint)); diff --git a/src/mesa/swrast/swrast.h b/src/mesa/swrast/swrast.h index 12264a159ad..d101a9e2ae2 100644 --- a/src/mesa/swrast/swrast.h +++ b/src/mesa/swrast/swrast.h @@ -45,6 +45,14 @@ * improve its usefulness as a fallback mechanism for hardware * drivers. * + * wpos = attr[FRAG_ATTRIB_WPOS] and MUST BE THE FIRST values in the + * vertex because of the tnl clipping code. + + * wpos[0] and [1] are the screen-coords of SWvertex. + * wpos[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]). + * wpos[3] is 1/w where w is the clip-space W coord. This is the value + * that clip{XYZ} were multiplied by to get ndc{XYZ}. + * * Full software drivers: * - Register the rastersetup and triangle functions from * utils/software_helper. @@ -61,20 +69,15 @@ * primitives unaccelerated), hook in swrast_setup instead. */ typedef struct { - /** win[0], win[1] are the screen-coords of SWvertex. - * win[2] is the z-buffer coord (if 16-bit Z buffer, in range [0,65535]). - * win[3] is 1/w where w is the clip-space W coord. This is the value - * that clip{XYZ} were multiplied by to get ndc{XYZ}. - */ - GLfloat win[4]; - GLchan color[4]; - GLchan specular[4]; - GLfloat index; + GLfloat attrib[FRAG_ATTRIB_MAX][4]; + GLchan color[4]; /** integer color */ GLfloat pointSize; - GLfloat attrib[FRAG_ATTRIB_MAX][4]; /**< texcoords & varying, more to come */ } SWvertex; +#define FRAG_ATTRIB_CI FRAG_ATTRIB_COL0 + + struct swrast_device_driver; diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index 3f6d29403cc..cd4ac57d37d 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -1,6 +1,6 @@ /* * Mesa 3-D graphics library - * Version: 6.5.3 + * Version: 7.1 * * Copyright (C) 1999-2007 Brian Paul All Rights Reserved. * @@ -120,16 +120,26 @@ setup_vertex_format(GLcontext *ctx) RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); - EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, win ); + EMIT_ATTR( _TNL_ATTRIB_POS, EMIT_4F_VIEWPORT, attrib[FRAG_ATTRIB_WPOS] ); - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR0 )) - EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color ); + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR0 )) { + swsetup->intColors = !ctx->FragmentProgram._Current + && !ctx->ATIFragmentShader._Enabled + && CHAN_TYPE == GL_UNSIGNED_BYTE; + if (swsetup->intColors) + EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4CHAN_4F_RGBA, color ); + else + EMIT_ATTR( _TNL_ATTRIB_COLOR0, EMIT_4F, attrib[FRAG_ATTRIB_COL0]); + } - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) - EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4CHAN_4F_RGBA, specular); + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { + EMIT_ATTR( _TNL_ATTRIB_COLOR1, EMIT_4F, attrib[FRAG_ATTRIB_COL1]); + } - if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR_INDEX )) - EMIT_ATTR( _TNL_ATTRIB_COLOR_INDEX, EMIT_1F, index ); + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR_INDEX )) { + EMIT_ATTR( _TNL_ATTRIB_COLOR_INDEX, EMIT_1F, + attrib[FRAG_ATTRIB_CI][0] ); + } if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { const GLint emit = ctx->FragmentProgram._Current ? EMIT_4F : EMIT_1F; @@ -184,6 +194,10 @@ _swsetup_RenderStart( GLcontext *ctx ) _swsetup_choose_trifuncs(ctx); } + if (swsetup->NewState & _NEW_PROGRAM) { + RENDERINPUTS_ZERO( swsetup->last_index_bitset ); + } + swsetup->NewState = 0; _swrast_render_start(ctx); @@ -258,10 +272,10 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest ) _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POS, tmp ); - dest->win[0] = m[0] * tmp[0] + m[12]; - dest->win[1] = m[5] * tmp[1] + m[13]; - dest->win[2] = m[10] * tmp[2] + m[14]; - dest->win[3] = tmp[3]; + dest->attrib[FRAG_ATTRIB_WPOS][0] = m[0] * tmp[0] + m[12]; + dest->attrib[FRAG_ATTRIB_WPOS][1] = m[5] * tmp[1] + m[13]; + dest->attrib[FRAG_ATTRIB_WPOS][2] = m[10] * tmp[2] + m[14]; + dest->attrib[FRAG_ATTRIB_WPOS][3] = tmp[3]; /** XXX try to limit these loops someday */ for (i = 0 ; i < ctx->Const.MaxTextureCoordUnits ; i++) @@ -276,13 +290,16 @@ _swsetup_Translate( GLcontext *ctx, const void *vertex, SWvertex *dest ) UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->color, tmp ); _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR1, tmp ); + COPY_4V(dest->attrib[FRAG_ATTRIB_COL1], tmp); + /* UNCLAMPED_FLOAT_TO_RGBA_CHAN( dest->specular, tmp ); + */ _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_FOG, tmp ); dest->attrib[FRAG_ATTRIB_FOGC][0] = tmp[0]; _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_COLOR_INDEX, tmp ); - dest->index = tmp[0]; + dest->attrib[FRAG_ATTRIB_CI][0] = tmp[0]; /* XXX See _tnl_get_attr about pointsize ... */ _tnl_get_attr( ctx, vertex, _TNL_ATTRIB_POINTSIZE, tmp ); diff --git a/src/mesa/swrast_setup/ss_context.h b/src/mesa/swrast_setup/ss_context.h index e5d890447a7..11f9ded3ffb 100644 --- a/src/mesa/swrast_setup/ss_context.h +++ b/src/mesa/swrast_setup/ss_context.h @@ -1,9 +1,8 @@ - /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.1 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -39,6 +38,7 @@ typedef struct { GLenum render_prim; DECLARE_RENDERINPUTS(last_index_bitset); SWvertex *verts; + GLboolean intColors; } SScontext; #define SWSETUP_CONTEXT(ctx) ((SScontext *)ctx->swsetup_context) diff --git a/src/mesa/swrast_setup/ss_triangle.c b/src/mesa/swrast_setup/ss_triangle.c index 628e9288e87..b4207f2c64a 100644 --- a/src/mesa/swrast_setup/ss_triangle.c +++ b/src/mesa/swrast_setup/ss_triangle.c @@ -57,7 +57,7 @@ static void _swsetup_render_line_tri( GLcontext *ctx, SWvertex *v1 = &verts[e1]; SWvertex *v2 = &verts[e2]; GLchan c[2][4]; - GLchan s[2][4]; + GLfloat s[2][4]; GLfloat i[2]; /* cull testing */ @@ -71,17 +71,17 @@ static void _swsetup_render_line_tri( GLcontext *ctx, if (ctx->Light.ShadeModel == GL_FLAT) { COPY_CHAN4(c[0], v0->color); COPY_CHAN4(c[1], v1->color); - COPY_CHAN4(s[0], v0->specular); - COPY_CHAN4(s[1], v1->specular); - i[0] = v0->index; - i[1] = v1->index; + COPY_4V(s[0], v0->attrib[FRAG_ATTRIB_COL1]); + COPY_4V(s[1], v1->attrib[FRAG_ATTRIB_COL1]); + i[0] = v0->attrib[FRAG_ATTRIB_CI][0]; + i[1] = v1->attrib[FRAG_ATTRIB_CI][0]; COPY_CHAN4(v0->color, v2->color); COPY_CHAN4(v1->color, v2->color); - COPY_CHAN4(v0->specular, v2->specular); - COPY_CHAN4(v1->specular, v2->specular); - v0->index = v2->index; - v1->index = v2->index; + COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]); + COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]); + v0->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0]; + v1->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0]; } if (swsetup->render_prim == GL_POLYGON) { @@ -97,10 +97,10 @@ static void _swsetup_render_line_tri( GLcontext *ctx, if (ctx->Light.ShadeModel == GL_FLAT) { COPY_CHAN4(v0->color, c[0]); COPY_CHAN4(v1->color, c[1]); - COPY_CHAN4(v0->specular, s[0]); - COPY_CHAN4(v1->specular, s[1]); - v0->index = i[0]; - v1->index = i[1]; + COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], s[0]); + COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], s[1]); + v0->attrib[FRAG_ATTRIB_CI][0] = i[0]; + v1->attrib[FRAG_ATTRIB_CI][0] = i[1]; } } @@ -116,7 +116,7 @@ static void _swsetup_render_point_tri( GLcontext *ctx, SWvertex *v1 = &verts[e1]; SWvertex *v2 = &verts[e2]; GLchan c[2][4]; - GLchan s[2][4]; + GLfloat s[2][4]; GLfloat i[2]; /* cull testing */ @@ -131,18 +131,18 @@ static void _swsetup_render_point_tri( GLcontext *ctx, /* save colors/indexes for v0, v1 vertices */ COPY_CHAN4(c[0], v0->color); COPY_CHAN4(c[1], v1->color); - COPY_CHAN4(s[0], v0->specular); - COPY_CHAN4(s[1], v1->specular); - i[0] = v0->index; - i[1] = v1->index; + COPY_4V(s[0], v0->attrib[FRAG_ATTRIB_COL1]); + COPY_4V(s[1], v1->attrib[FRAG_ATTRIB_COL1]); + i[0] = v0->attrib[FRAG_ATTRIB_CI][0]; + i[1] = v1->attrib[FRAG_ATTRIB_CI][0]; /* copy v2 color/indexes to v0, v1 indexes */ COPY_CHAN4(v0->color, v2->color); COPY_CHAN4(v1->color, v2->color); - COPY_CHAN4(v0->specular, v2->specular); - COPY_CHAN4(v1->specular, v2->specular); - v0->index = v2->index; - v1->index = v2->index; + COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]); + COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], v2->attrib[FRAG_ATTRIB_COL1]); + v0->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0]; + v1->attrib[FRAG_ATTRIB_CI][0] = v2->attrib[FRAG_ATTRIB_CI][0]; } if (ef[e0]) _swrast_Point( ctx, v0 ); @@ -153,10 +153,10 @@ static void _swsetup_render_point_tri( GLcontext *ctx, /* restore v0, v1 colores/indexes */ COPY_CHAN4(v0->color, c[0]); COPY_CHAN4(v1->color, c[1]); - COPY_CHAN4(v0->specular, s[0]); - COPY_CHAN4(v1->specular, s[1]); - v0->index = i[0]; - v1->index = i[1]; + COPY_4V(v0->attrib[FRAG_ATTRIB_COL1], s[0]); + COPY_4V(v1->attrib[FRAG_ATTRIB_COL1], s[1]); + v0->attrib[FRAG_ATTRIB_CI][0] = i[0]; + v1->attrib[FRAG_ATTRIB_CI][0] = i[1]; } _swrast_flush(ctx); } diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index 1fdf0cb5999..c14468e9514 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.1 + * Version: 7.1 * - * Copyright (C) 1999-2004 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -26,9 +26,14 @@ */ +/** + * This is where we handle assigning vertex colors based on front/back + * facing, compute polygon offset and handle glPolygonMode(). + */ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) { struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + SScontext *swsetup = SWSETUP_CONTEXT(ctx); SWvertex *verts = SWSETUP_CONTEXT(ctx)->verts; SWvertex *v[3]; GLfloat z[3]; @@ -36,7 +41,8 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) GLenum mode = GL_FILL; GLuint facing = 0; GLchan saved_color[3][4]; - GLchan saved_spec[3][4]; + GLfloat saved_col0[3][4]; + GLfloat saved_spec[3][4]; GLfloat saved_index[3]; v[0] = &verts[e0]; @@ -46,10 +52,10 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (IND & (SS_TWOSIDE_BIT | SS_OFFSET_BIT | SS_UNFILLED_BIT)) { - GLfloat ex = v[0]->win[0] - v[2]->win[0]; - GLfloat ey = v[0]->win[1] - v[2]->win[1]; - GLfloat fx = v[1]->win[0] - v[2]->win[0]; - GLfloat fy = v[1]->win[1] - v[2]->win[1]; + GLfloat ex = v[0]->attrib[FRAG_ATTRIB_WPOS][0] - v[2]->attrib[FRAG_ATTRIB_WPOS][0]; + GLfloat ey = v[0]->attrib[FRAG_ATTRIB_WPOS][1] - v[2]->attrib[FRAG_ATTRIB_WPOS][1]; + GLfloat fx = v[1]->attrib[FRAG_ATTRIB_WPOS][0] - v[2]->attrib[FRAG_ATTRIB_WPOS][0]; + GLfloat fy = v[1]->attrib[FRAG_ATTRIB_WPOS][1] - v[2]->attrib[FRAG_ATTRIB_WPOS][1]; GLfloat cc = ex*fy - ey*fx; if (IND & (SS_TWOSIDE_BIT | SS_UNFILLED_BIT)) @@ -66,49 +72,71 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (VB->ColorPtr[1]) { GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data; - COPY_CHAN4(saved_color[0], v[0]->color); - COPY_CHAN4(saved_color[1], v[1]->color); - COPY_CHAN4(saved_color[2], v[2]->color); + if (swsetup->intColors) { + COPY_CHAN4(saved_color[0], v[0]->color); + COPY_CHAN4(saved_color[1], v[1]->color); + COPY_CHAN4(saved_color[2], v[2]->color); + } + else { + COPY_4V(saved_col0[0], v[0]->attrib[FRAG_ATTRIB_COL0]); + COPY_4V(saved_col0[1], v[1]->attrib[FRAG_ATTRIB_COL0]); + COPY_4V(saved_col0[2], v[2]->attrib[FRAG_ATTRIB_COL0]); + } if (VB->ColorPtr[1]->stride) { - SS_COLOR(v[0]->color, vbcolor[e0]); - SS_COLOR(v[1]->color, vbcolor[e1]); - SS_COLOR(v[2]->color, vbcolor[e2]); + if (swsetup->intColors) { + SS_COLOR(v[0]->color, vbcolor[e0]); + SS_COLOR(v[1]->color, vbcolor[e1]); + SS_COLOR(v[2]->color, vbcolor[e2]); + } + else { + COPY_4V(v[0]->attrib[FRAG_ATTRIB_COL0], vbcolor[e0]); + COPY_4V(v[1]->attrib[FRAG_ATTRIB_COL0], vbcolor[e1]); + COPY_4V(v[2]->attrib[FRAG_ATTRIB_COL0], vbcolor[e2]); + } } else { - SS_COLOR(v[0]->color, vbcolor[0]); - SS_COLOR(v[1]->color, vbcolor[0]); - SS_COLOR(v[2]->color, vbcolor[0]); + /* flat shade */ + if (swsetup->intColors) { + SS_COLOR(v[0]->color, vbcolor[0]); + SS_COLOR(v[1]->color, vbcolor[0]); + SS_COLOR(v[2]->color, vbcolor[0]); + } + else { + COPY_4V(v[0]->attrib[FRAG_ATTRIB_COL0], vbcolor[0]); + COPY_4V(v[1]->attrib[FRAG_ATTRIB_COL0], vbcolor[0]); + COPY_4V(v[2]->attrib[FRAG_ATTRIB_COL0], vbcolor[0]); + } } } if (VB->SecondaryColorPtr[1]) { GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data; - COPY_CHAN4(saved_spec[0], v[0]->specular); - COPY_CHAN4(saved_spec[1], v[1]->specular); - COPY_CHAN4(saved_spec[2], v[2]->specular); + COPY_4V(saved_spec[0], v[0]->attrib[FRAG_ATTRIB_COL1]); + COPY_4V(saved_spec[1], v[1]->attrib[FRAG_ATTRIB_COL1]); + COPY_4V(saved_spec[2], v[2]->attrib[FRAG_ATTRIB_COL1]); if (VB->SecondaryColorPtr[1]->stride) { - SS_SPEC(v[0]->specular, vbspec[e0]); - SS_SPEC(v[1]->specular, vbspec[e1]); - SS_SPEC(v[2]->specular, vbspec[e2]); + SS_SPEC(v[0]->attrib[FRAG_ATTRIB_COL1], vbspec[e0]); + SS_SPEC(v[1]->attrib[FRAG_ATTRIB_COL1], vbspec[e1]); + SS_SPEC(v[2]->attrib[FRAG_ATTRIB_COL1], vbspec[e2]); } else { - SS_SPEC(v[0]->specular, vbspec[0]); - SS_SPEC(v[1]->specular, vbspec[0]); - SS_SPEC(v[2]->specular, vbspec[0]); + SS_SPEC(v[0]->attrib[FRAG_ATTRIB_COL1], vbspec[0]); + SS_SPEC(v[1]->attrib[FRAG_ATTRIB_COL1], vbspec[0]); + SS_SPEC(v[2]->attrib[FRAG_ATTRIB_COL1], vbspec[0]); } } } else { GLfloat *vbindex = (GLfloat *)VB->IndexPtr[1]->data; - saved_index[0] = v[0]->index; - saved_index[1] = v[1]->index; - saved_index[2] = v[2]->index; + saved_index[0] = v[0]->attrib[FRAG_ATTRIB_CI][0]; + saved_index[1] = v[1]->attrib[FRAG_ATTRIB_CI][0]; + saved_index[2] = v[2]->attrib[FRAG_ATTRIB_CI][0]; - SS_IND(v[0]->index, (GLuint) vbindex[e0]); - SS_IND(v[1]->index, (GLuint) vbindex[e1]); - SS_IND(v[2]->index, (GLuint) vbindex[e2]); + SS_IND(v[0]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e0]); + SS_IND(v[1]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e1]); + SS_IND(v[2]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e2]); } } } @@ -117,9 +145,9 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) if (IND & SS_OFFSET_BIT) { offset = ctx->Polygon.OffsetUnits * ctx->DrawBuffer->_MRD; - z[0] = v[0]->win[2]; - z[1] = v[1]->win[2]; - z[2] = v[2]->win[2]; + z[0] = v[0]->attrib[FRAG_ATTRIB_WPOS][2]; + z[1] = v[1]->attrib[FRAG_ATTRIB_WPOS][2]; + z[2] = v[2]->attrib[FRAG_ATTRIB_WPOS][2]; if (cc * cc > 1e-16) { const GLfloat ez = z[0] - z[2]; const GLfloat fz = z[1] - z[2]; @@ -130,60 +158,70 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) /* Unfortunately, we need to clamp to prevent negative Zs below. * Technically, we should do the clamping per-fragment. */ - offset = MAX2(offset, -v[0]->win[2]); - offset = MAX2(offset, -v[1]->win[2]); - offset = MAX2(offset, -v[2]->win[2]); + offset = MAX2(offset, -v[0]->attrib[FRAG_ATTRIB_WPOS][2]); + offset = MAX2(offset, -v[1]->attrib[FRAG_ATTRIB_WPOS][2]); + offset = MAX2(offset, -v[2]->attrib[FRAG_ATTRIB_WPOS][2]); } } } if (mode == GL_POINT) { if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetPoint) { - v[0]->win[2] += offset; - v[1]->win[2] += offset; - v[2]->win[2] += offset; + v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset; + v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset; + v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset; } _swsetup_render_point_tri( ctx, e0, e1, e2, facing ); } else if (mode == GL_LINE) { if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetLine) { - v[0]->win[2] += offset; - v[1]->win[2] += offset; - v[2]->win[2] += offset; + v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset; + v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset; + v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset; } _swsetup_render_line_tri( ctx, e0, e1, e2, facing ); } else { if ((IND & SS_OFFSET_BIT) && ctx->Polygon.OffsetFill) { - v[0]->win[2] += offset; - v[1]->win[2] += offset; - v[2]->win[2] += offset; + v[0]->attrib[FRAG_ATTRIB_WPOS][2] += offset; + v[1]->attrib[FRAG_ATTRIB_WPOS][2] += offset; + v[2]->attrib[FRAG_ATTRIB_WPOS][2] += offset; } _swrast_Triangle( ctx, v[0], v[1], v[2] ); } + /* + * Restore original vertex colors, etc. + */ if (IND & SS_OFFSET_BIT) { - v[0]->win[2] = z[0]; - v[1]->win[2] = z[1]; - v[2]->win[2] = z[2]; + v[0]->attrib[FRAG_ATTRIB_WPOS][2] = z[0]; + v[1]->attrib[FRAG_ATTRIB_WPOS][2] = z[1]; + v[2]->attrib[FRAG_ATTRIB_WPOS][2] = z[2]; } if (IND & SS_TWOSIDE_BIT) { if (facing == 1) { if (IND & SS_RGBA_BIT) { if (VB->ColorPtr[1]) { - COPY_CHAN4(v[0]->color, saved_color[0]); - COPY_CHAN4(v[1]->color, saved_color[1]); - COPY_CHAN4(v[2]->color, saved_color[2]); + if (swsetup->intColors) { + COPY_CHAN4(v[0]->color, saved_color[0]); + COPY_CHAN4(v[1]->color, saved_color[1]); + COPY_CHAN4(v[2]->color, saved_color[2]); + } + else { + COPY_4V(v[0]->attrib[FRAG_ATTRIB_COL0], saved_col0[0]); + COPY_4V(v[1]->attrib[FRAG_ATTRIB_COL0], saved_col0[1]); + COPY_4V(v[2]->attrib[FRAG_ATTRIB_COL0], saved_col0[2]); + } } if (VB->SecondaryColorPtr[1]) { - COPY_CHAN4(v[0]->specular, saved_spec[0]); - COPY_CHAN4(v[1]->specular, saved_spec[1]); - COPY_CHAN4(v[2]->specular, saved_spec[2]); + COPY_4V(v[0]->attrib[FRAG_ATTRIB_COL1], saved_spec[0]); + COPY_4V(v[1]->attrib[FRAG_ATTRIB_COL1], saved_spec[1]); + COPY_4V(v[2]->attrib[FRAG_ATTRIB_COL1], saved_spec[2]); } } else { - v[0]->index = saved_index[0]; - v[1]->index = saved_index[1]; - v[2]->index = saved_index[2]; + v[0]->attrib[FRAG_ATTRIB_CI][0] = saved_index[0]; + v[1]->attrib[FRAG_ATTRIB_CI][0] = saved_index[1]; + v[2]->attrib[FRAG_ATTRIB_CI][0] = saved_index[2]; } } } diff --git a/src/mesa/tnl/t_vb_fog.c b/src/mesa/tnl/t_vb_fog.c index 5440ff7894d..f6518500d80 100644 --- a/src/mesa/tnl/t_vb_fog.c +++ b/src/mesa/tnl/t_vb_fog.c @@ -114,7 +114,7 @@ compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in) else d = 1.0F / (ctx->Fog.End - ctx->Fog.Start); for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - const GLfloat z = FABSF(*v); + const GLfloat z = *v; GLfloat f = (end - z) * d; data[i][0] = CLAMP(f, 0.0F, 1.0F); } @@ -122,14 +122,14 @@ compute_fog_blend_factors(GLcontext *ctx, GLvector4f *out, const GLvector4f *in) case GL_EXP: d = ctx->Fog.Density; for ( i = 0 ; i < n ; i++, STRIDE_F(v,stride)) { - const GLfloat z = FABSF(*v); + const GLfloat z = *v; NEG_EXP( data[i][0], d * z ); } break; case GL_EXP2: d = ctx->Fog.Density*ctx->Fog.Density; for ( i = 0 ; i < n ; i++, STRIDE_F(v, stride)) { - const GLfloat z = FABSF(*v); + const GLfloat z = *v; NEG_EXP( data[i][0], d * z * z ); } break; @@ -153,6 +153,8 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) if (ctx->Fog.FogCoordinateSource == GL_FRAGMENT_DEPTH_EXT) { + GLuint i; + GLfloat *coord; /* Fog is computed from vertex or fragment Z values */ /* source = VB->ObjPtr or VB->EyePtr coords */ /* dest = VB->AttribPtr[_TNL_ATTRIB_FOG] = fog stage private storage */ @@ -168,6 +170,8 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) input = &store->fogcoord; /* NOTE: negate plane here so we get positive fog coords! */ + /* NOTE2: this doesn't always work (tests/fog - all frag depth fog + coords will be negative). */ plane[0] = -m[2]; plane[1] = -m[6]; plane[2] = -m[10]; @@ -180,18 +184,29 @@ run_fog_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) VB->ObjPtr, plane ); input->count = VB->ObjPtr->count; + + /* make sure coords are really positive + NOTE should avoid going through array twice */ + coord = input->start; + for (i = 0; i < input->count; i++) { + input->data[i][0] = FABSF(*coord); + STRIDE_F(coord, input->stride); + } } else { /* fog coordinates = eye Z coordinates (use ABS later) */ - input = &store->input; + input = &store->fogcoord; if (VB->EyePtr->size < 2) _mesa_vector4f_clean_elem( VB->EyePtr, VB->Count, 2 ); - input->data = (GLfloat (*)[4]) &(VB->EyePtr->data[0][2]); - input->start = VB->EyePtr->start+2; - input->stride = VB->EyePtr->stride; + input->stride = 4 * sizeof(GLfloat); input->count = VB->EyePtr->count; + coord = VB->EyePtr->start; + for (i = 0 ; i < VB->EyePtr->count; i++) { + input->data[i][0] = FABSF(coord[2]); + STRIDE_F(coord, VB->EyePtr->stride); + } } } else { diff --git a/src/mesa/tnl/t_vb_points.c b/src/mesa/tnl/t_vb_points.c index 9327f8c273c..1ac14fedf99 100644 --- a/src/mesa/tnl/t_vb_points.c +++ b/src/mesa/tnl/t_vb_points.c @@ -1,8 +1,8 @@ /* * Mesa 3-D graphics library - * Version: 6.5 + * Version: 7.0 * - * Copyright (C) 1999-2006 Brian Paul All Rights Reserved. + * Copyright (C) 1999-2007 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"), @@ -50,7 +50,8 @@ run_point_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) if (ctx->Point._Attenuated && !ctx->VertexProgram._Current) { struct point_stage_data *store = POINT_STAGE_DATA(stage); struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; - const GLfloat (*eye)[4] = (const GLfloat (*)[4]) VB->EyePtr->data; + const GLfloat *eyeCoord = (GLfloat *) VB->EyePtr->data + 2; + const GLint eyeCoordStride = VB->EyePtr->stride / sizeof(GLfloat); const GLfloat p0 = ctx->Point.Params[0]; const GLfloat p1 = ctx->Point.Params[1]; const GLfloat p2 = ctx->Point.Params[2]; @@ -59,10 +60,11 @@ run_point_stage(GLcontext *ctx, struct tnl_pipeline_stage *stage) GLuint i; for (i = 0; i < VB->Count; i++) { - const GLfloat dist = FABSF(eye[i][2]); + const GLfloat dist = FABSF(*eyeCoord); const GLfloat q = p0 + dist * (p1 + dist * p2); const GLfloat atten = (q != 0.0) ? SQRTF(1.0 / q) : 1.0; size[i][0] = pointSize * atten; /* clamping done in rasterization */ + eyeCoord += eyeCoordStride; } VB->AttribPtr[_TNL_ATTRIB_POINTSIZE] = &store->PointSize; diff --git a/src/mesa/tnl/t_vp_build.c b/src/mesa/tnl/t_vp_build.c index dff062a417c..2a1cae77f29 100644 --- a/src/mesa/tnl/t_vp_build.c +++ b/src/mesa/tnl/t_vp_build.c @@ -1103,7 +1103,9 @@ static void build_fog( struct tnl_program *p ) { struct ureg fog = register_output(p, VERT_RESULT_FOGC); struct ureg input; - + GLuint useabs = p->state->fog_source_is_depth && p->state->fog_mode && + (p->state->fog_mode != FOG_EXP2); + if (p->state->fog_source_is_depth) { input = swizzle1(get_eye_position(p), Z); } @@ -1111,31 +1113,36 @@ static void build_fog( struct tnl_program *p ) input = swizzle1(register_input(p, VERT_ATTRIB_FOG), X); } - if (p->state->tnl_do_vertex_fog) { + if (p->state->fog_mode && p->state->tnl_do_vertex_fog) { struct ureg params = register_param2(p, STATE_INTERNAL, STATE_FOG_PARAMS_OPTIMIZED); struct ureg tmp = get_temp(p); + if (useabs) { + emit_op1(p, OPCODE_ABS, tmp, 0, input); + } + switch (p->state->fog_mode) { case FOG_LINEAR: { struct ureg id = get_identity_param(p); - emit_op3(p, OPCODE_MAD, tmp, 0, input, swizzle1(params,X), swizzle1(params,Y)); + emit_op3(p, OPCODE_MAD, tmp, 0, useabs ? tmp : input, + swizzle1(params,X), swizzle1(params,Y)); emit_op2(p, OPCODE_MAX, tmp, 0, tmp, swizzle1(id,X)); /* saturate */ emit_op2(p, OPCODE_MIN, fog, WRITEMASK_X, tmp, swizzle1(id,W)); break; } case FOG_EXP: - emit_op1(p, OPCODE_ABS, tmp, 0, input); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, swizzle1(params,Z)); + emit_op2(p, OPCODE_MUL, tmp, 0, useabs ? tmp : input, + swizzle1(params,Z)); emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); break; case FOG_EXP2: emit_op2(p, OPCODE_MUL, tmp, 0, input, swizzle1(params,W)); - emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); + emit_op2(p, OPCODE_MUL, tmp, 0, tmp, tmp); emit_op1(p, OPCODE_EX2, fog, WRITEMASK_X, negate(tmp)); break; } - + release_temp(p, tmp); } else { @@ -1143,7 +1150,7 @@ static void build_fog( struct tnl_program *p ) * * KW: Is it really necessary to do anything in this case? */ - emit_op1(p, OPCODE_MOV, fog, WRITEMASK_X, input); + emit_op1(p, useabs ? OPCODE_ABS : OPCODE_MOV, fog, WRITEMASK_X, input); } } diff --git a/src/mesa/tnl_dd/t_dd_vb.c b/src/mesa/tnl_dd/t_dd_vb.c index 6cdd1bc0313..ab3bb37631b 100644 --- a/src/mesa/tnl_dd/t_dd_vb.c +++ b/src/mesa/tnl_dd/t_dd_vb.c @@ -89,15 +89,15 @@ void TAG(translate_vertex)(GLcontext *ctx, if (format == TINY_VERTEX_FORMAT) { if (HAVE_HW_VIEWPORT) { - dst->win[0] = s[0] * src->v.x + s[12]; - dst->win[1] = s[5] * src->v.y + s[13]; - dst->win[2] = s[10] * src->v.z + s[14]; - dst->win[3] = 1.0; + dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0] * src->v.x + s[12]; + dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5] * src->v.y + s[13]; + dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14]; + dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0; } else { - dst->win[0] = UNVIEWPORT_X( src->v.x ); - dst->win[1] = UNVIEWPORT_Y( src->v.y ); - dst->win[2] = UNVIEWPORT_Z( src->v.z ); - dst->win[3] = 1.0; + dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x ); + dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y ); + dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z ); + dst->attrib[FRAG_ATTRIB_WPOS][3] = 1.0; } dst->color[0] = src->tv.color.red; @@ -109,21 +109,21 @@ void TAG(translate_vertex)(GLcontext *ctx, if (HAVE_HW_VIEWPORT) { if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) { GLfloat oow = 1.0 / src->v.w; - dst->win[0] = s[0] * src->v.x * oow + s[12]; - dst->win[1] = s[5] * src->v.y * oow + s[13]; - dst->win[2] = s[10] * src->v.z * oow + s[14]; - dst->win[3] = oow; + dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0] * src->v.x * oow + s[12]; + dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5] * src->v.y * oow + s[13]; + dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z * oow + s[14]; + dst->attrib[FRAG_ATTRIB_WPOS][3] = oow; } else { - dst->win[0] = s[0] * src->v.x + s[12]; - dst->win[1] = s[5] * src->v.y + s[13]; - dst->win[2] = s[10] * src->v.z + s[14]; - dst->win[3] = src->v.w; + dst->attrib[FRAG_ATTRIB_WPOS][0] = s[0] * src->v.x + s[12]; + dst->attrib[FRAG_ATTRIB_WPOS][1] = s[5] * src->v.y + s[13]; + dst->attrib[FRAG_ATTRIB_WPOS][2] = s[10] * src->v.z + s[14]; + dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w; } } else { - dst->win[0] = UNVIEWPORT_X( src->v.x ); - dst->win[1] = UNVIEWPORT_Y( src->v.y ); - dst->win[2] = UNVIEWPORT_Z( src->v.z ); - dst->win[3] = src->v.w; + dst->attrib[FRAG_ATTRIB_WPOS][0] = UNVIEWPORT_X( src->v.x ); + dst->attrib[FRAG_ATTRIB_WPOS][1] = UNVIEWPORT_Y( src->v.y ); + dst->attrib[FRAG_ATTRIB_WPOS][2] = UNVIEWPORT_Z( src->v.z ); + dst->attrib[FRAG_ATTRIB_WPOS][3] = src->v.w; } dst->color[0] = src->v.color.red; @@ -131,11 +131,11 @@ void TAG(translate_vertex)(GLcontext *ctx, dst->color[2] = src->v.color.blue; dst->color[3] = src->v.color.alpha; - dst->specular[0] = src->v.specular.red; - dst->specular[1] = src->v.specular.green; - dst->specular[2] = src->v.specular.blue; + dst->attrib[FRAG_ATTRIB_COL1][0] = UBYTE_TO_FLOAT(src->v.specular.red); + dst->attrib[FRAG_ATTRIB_COL1][1] = UBYTE_TO_FLOAT(src->v.specular.green); + dst->attrib[FRAG_ATTRIB_COL1][2] = UBYTE_TO_FLOAT(src->v.specular.blue); - dst->attrib[FRAG_ATTRIB_FOGC][0] = src->v.specular.alpha/255.0; + dst->attrib[FRAG_ATTRIB_FOGC][0] = UBYTE_TO_FLOAT(src->v.specular.alpha); if (HAVE_PTEX_VERTICES && ((HAVE_TEX2_VERTICES && format == PROJ_TEX3_VERTEX_FORMAT) || |