diff options
author | dawes <dawes> | 2001-03-19 17:45:15 +0000 |
---|---|---|
committer | dawes <dawes> | 2001-03-19 17:45:15 +0000 |
commit | 7bf7bda7738b2029bc71015f9ea08304c15e7240 (patch) | |
tree | 95c06cadb9f7fdb6d456eafb2cb015653c617724 /xc/lib/GL/mesa/src | |
parent | 856c96701fa6c514447af12b4b881f762e59767c (diff) |
Import of XFree86 4.0.99.1X_4_0_99_1
Diffstat (limited to 'xc/lib/GL/mesa/src')
100 files changed, 18711 insertions, 3655 deletions
diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile index 88b259502..6639512c2 100644 --- a/xc/lib/GL/mesa/src/drv/Imakefile +++ b/xc/lib/GL/mesa/src/drv/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/Imakefile,v 1.16 2000/12/04 18:54:13 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/Imakefile,v 1.17 2001/01/08 01:07:17 martin Exp $ #define DoNormalLib NormalLibGlx #define DoSharedLib SharedLibGlx @@ -23,7 +23,10 @@ DRIVER += common mga DRIVER += common i810 #endif #if GlxBuiltInR128 -DRIVER += r128 +DRIVER += common r128 +#endif +#if GlxBuiltInRadeon +DRIVER += common radeon #endif #if GlxBuiltInFfb DRIVER += ffb @@ -43,17 +46,19 @@ SUBDIRS += gamma SUBDIRS += mga SUBDIRS += i810 SUBDIRS += r128 +SUBDIRS += radeon SUBDIRS += sis #if HasGlide3 SUBDIRS += tdfx #endif -#elif defined(AlphaArchitecture) +#elif defined(AlphaArchitecture) SUBDIRS += common SUBDIRS += gamma SUBDIRS += mga SUBDIRS += r128 +SUBDIRS += radeon #if HasGlide3 SUBDIRS += tdfx #endif @@ -64,7 +69,7 @@ SUBDIRS += ffb #else -SUBDIRS = +SUBDIRS = #endif /* architecture */ diff --git a/xc/lib/GL/mesa/src/drv/ffb/Imakefile b/xc/lib/GL/mesa/src/drv/ffb/Imakefile index d66bc2bfb..fdb762ec8 100644 --- a/xc/lib/GL/mesa/src/drv/ffb/Imakefile +++ b/xc/lib/GL/mesa/src/drv/ffb/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/ffb/Imakefile,v 1.6 2000/10/20 12:57:22 alanh Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/ffb/Imakefile,v 1.7 2001/02/16 01:26:09 dawes Exp $ #include <Threads.tmpl> @@ -227,7 +227,7 @@ NormalLintTarget($(SRCS)) LIBNAME = ffb_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE -SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +SharedDriModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) #endif diff --git a/xc/lib/GL/mesa/src/drv/gamma/Imakefile b/xc/lib/GL/mesa/src/drv/gamma/Imakefile index 95a1b6450..cfe2f0af3 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/Imakefile +++ b/xc/lib/GL/mesa/src/drv/gamma/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.16 2000/12/12 23:24:27 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/gamma/Imakefile,v 1.18 2001/02/16 01:26:10 dawes Exp $ #include <Threads.tmpl> @@ -64,7 +64,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ gamma_matrix.c \ gamma_inithw.c \ gamma_texture.c \ - /* gamma_dlist.c */ + gamma_dlist.c GAMMAOBJS = gamma_gl.o \ gamma_xmesa.o \ @@ -72,7 +72,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ gamma_matrix.o \ gamma_inithw.o \ gamma_texture.o \ - /* gamma_dlist.o */ + gamma_dlist.o MESASRCS = ../../aatriangle.c \ ../../accum.c \ @@ -346,7 +346,7 @@ NormalLintTarget($(SRCS)) LIBNAME = gamma_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE -SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +SharedDriModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) #ifdef GlxSoProf diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_dlist.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_dlist.c new file mode 100644 index 000000000..f0e39a678 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_dlist.c @@ -0,0 +1,3314 @@ +/* + * Mesa 3-D graphics library + * Version: 3.0 + * Copyright (C) 1995-1998 Brian Paul + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +/* + * Pinched from Mesa v3.0 to glue into gamma driver + * then glued up, to match some of the Mesa v3.3 back end. + * Alan Hourihane <alanh@fairlite.demon.co.uk> + */ + +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_dlist.c,v 1.3 2001/02/12 01:11:24 tsi Exp $*/ + +#ifdef PC_HEADER +#include "all.h" +#else +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "accum.h" +#include "alpha.h" +#include "attrib.h" +#include "bitmap.h" +#include "blend.h" +#include "clip.h" +#include "colortab.h" +#include "context.h" +#include "copypix.h" +#include "depth.h" +#include "drawpix.h" +#include "enable.h" +#include "eval.h" +#include "feedback.h" +#include "fog.h" +#include "hash.h" +#include "image.h" +#include "light.h" +#include "lines.h" +#include "logic.h" +#include "macros.h" +#include "masking.h" +#include "matrix.h" +#include "mem.h" +#include "pixel.h" +#include "points.h" +#include "polygon.h" +#include "rastpos.h" +#include "rect.h" +#include "scissor.h" +#include "stencil.h" +#include "texobj.h" +#include "teximage.h" +#include "texstate.h" +#include "types.h" +#include "vb.h" +#include "vbfill.h" +#include "winpos.h" +#endif + +#include "gamma_gl.h" +#include "gamma_init.h" +#include "gamma_dlist.h" + + +/* +Functions which aren't compiled but executed immediately: + glIsList + glGenLists + glDeleteLists + glEndList + glFeedbackBuffer + glSelectBuffer + glRenderMode + glReadPixels + glPixelStore + glFlush + glFinish + glIsEnabled + glGet* + +Functions which cause errors if called while compiling a display list: + glNewList +*/ + + + +/* + * Display list instructions are stored as sequences of "nodes". Nodes + * are allocated in blocks. Each block has BLOCK_SIZE nodes. Blocks + * are linked together with a pointer. + */ + + +/* How many nodes to allocate at a time: */ +#define BLOCK_SIZE 500 + + +/* + * Display list opcodes. + * + * The fact that these identifiers are assigned consecutive + * integer values starting at 0 is very important, see InstSize array usage) + */ +typedef enum { + OPCODE_ACCUM, + OPCODE_ALPHA_FUNC, + OPCODE_BEGIN, + OPCODE_BIND_TEXTURE, + OPCODE_BITMAP, + OPCODE_BLEND_FUNC, + OPCODE_CALL_LIST, + OPCODE_CALL_LIST_OFFSET, + OPCODE_CLEAR, + OPCODE_CLEAR_ACCUM, + OPCODE_CLEAR_COLOR, + OPCODE_CLEAR_DEPTH, + OPCODE_CLEAR_INDEX, + OPCODE_CLEAR_STENCIL, + OPCODE_CLIP_PLANE, + OPCODE_COLOR_3F, + OPCODE_COLOR_4F, + OPCODE_COLOR_4UB, + OPCODE_COLOR_MASK, + OPCODE_COLOR_MATERIAL, + OPCODE_COPY_PIXELS, + OPCODE_COPY_TEX_IMAGE1D, + OPCODE_COPY_TEX_IMAGE2D, + OPCODE_COPY_TEX_SUB_IMAGE1D, + OPCODE_COPY_TEX_SUB_IMAGE2D, + OPCODE_CULL_FACE, + OPCODE_DEPTH_FUNC, + OPCODE_DEPTH_MASK, + OPCODE_DEPTH_RANGE, + OPCODE_DISABLE, + OPCODE_DRAW_BUFFER, + OPCODE_DRAW_PIXELS, + OPCODE_EDGE_FLAG, + OPCODE_ENABLE, + OPCODE_END, + OPCODE_EVALCOORD1, + OPCODE_EVALCOORD2, + OPCODE_EVALMESH1, + OPCODE_EVALMESH2, + OPCODE_EVALPOINT1, + OPCODE_EVALPOINT2, + OPCODE_FOG, + OPCODE_FRONT_FACE, + OPCODE_FRUSTUM, + OPCODE_HINT, + OPCODE_INDEX, + OPCODE_INDEX_MASK, + OPCODE_INIT_NAMES, + OPCODE_LIGHT, + OPCODE_LIGHT_MODEL, + OPCODE_LINE_STIPPLE, + OPCODE_LINE_WIDTH, + OPCODE_LIST_BASE, + OPCODE_LOAD_IDENTITY, + OPCODE_LOAD_MATRIX, + OPCODE_LOAD_NAME, + OPCODE_LOGIC_OP, + OPCODE_MAP1, + OPCODE_MAP2, + OPCODE_MAPGRID1, + OPCODE_MAPGRID2, + OPCODE_MATERIAL, + OPCODE_MATRIX_MODE, + OPCODE_MULT_MATRIX, + OPCODE_NORMAL, + OPCODE_ORTHO, + OPCODE_PASSTHROUGH, + OPCODE_PIXEL_MAP, + OPCODE_PIXEL_TRANSFER, + OPCODE_PIXEL_ZOOM, + OPCODE_POINT_SIZE, + OPCODE_POLYGON_MODE, + OPCODE_POLYGON_STIPPLE, + OPCODE_POLYGON_OFFSET, + OPCODE_POP_ATTRIB, + OPCODE_POP_MATRIX, + OPCODE_POP_NAME, + OPCODE_PRIORITIZE_TEXTURE, + OPCODE_PUSH_ATTRIB, + OPCODE_PUSH_MATRIX, + OPCODE_PUSH_NAME, + OPCODE_RASTER_POS, + OPCODE_RECTF, + OPCODE_READ_BUFFER, + OPCODE_SCALE, + OPCODE_SCISSOR, + OPCODE_SHADE_MODEL, + OPCODE_STENCIL_FUNC, + OPCODE_STENCIL_MASK, + OPCODE_STENCIL_OP, + OPCODE_TEXCOORD2, + OPCODE_TEXCOORD4, + OPCODE_TEXENV, + OPCODE_TEXGEN, + OPCODE_TEXPARAMETER, + OPCODE_TEX_IMAGE1D, + OPCODE_TEX_IMAGE2D, + OPCODE_TEX_IMAGE3D, + OPCODE_TEX_SUB_IMAGE1D, + OPCODE_TEX_SUB_IMAGE2D, + OPCODE_TRANSLATE, + OPCODE_VERTEX2, + OPCODE_VERTEX3, + OPCODE_VERTEX4, + OPCODE_VIEWPORT, + /* The following two are meta instructions */ + OPCODE_CONTINUE, + OPCODE_END_OF_LIST +} OpCode; + + +/* + * Each instruction in the display list is stored as a sequence of + * contiguous nodes in memory. + * Each node is the union of a variety of datatypes. + */ +union node { + OpCode opcode; + GLboolean b; + GLbitfield bf; + GLubyte ub; + GLshort s; + GLushort us; + GLint i; + GLuint ui; + GLenum e; + GLfloat f; + GLvoid *data; + void *next; /* If prev node's opcode==OPCODE_CONTINUE */ +}; + + + +/* Number of nodes of storage needed for each instruction: */ +static GLuint InstSize[ OPCODE_END_OF_LIST+1 ]; + + + +/**********************************************************************/ +/***** Private *****/ +/**********************************************************************/ + + +/* + * Allocate space for a display list instruction. + * Input: opcode - type of instruction + * argcount - number of arguments following the instruction + * Return: pointer to first node in the instruction + */ +static Node *alloc_instruction( OpCode opcode, GLint argcount ) +{ + Node *n, *newblock; + GLuint count = InstSize[opcode]; + + assert( (GLint) count == argcount+1 ); + + if (gCCPriv->CurrentPos + count + 2 > BLOCK_SIZE) { + /* This block is full. Allocate a new block and chain to it */ + n = gCCPriv->CurrentBlock + gCCPriv->CurrentPos; + n[0].opcode = OPCODE_CONTINUE; + newblock = (Node *) malloc( sizeof(Node) * BLOCK_SIZE ); + if (!newblock) { + gamma_error( GL_OUT_OF_MEMORY, "Building display list" ); + return NULL; + } + n[1].next = (Node *) newblock; + gCCPriv->CurrentBlock = newblock; + gCCPriv->CurrentPos = 0; + } + + n = gCCPriv->CurrentBlock + gCCPriv->CurrentPos; + gCCPriv->CurrentPos += count; + + n[0].opcode = opcode; + + return n; +} + + + +/* + * Make an empty display list. This is used by glGenLists() to + * reserver display list IDs. + */ +static Node *make_empty_list( void ) +{ + Node *n = (Node *) malloc( sizeof(Node) ); + n[0].opcode = OPCODE_END_OF_LIST; + return n; +} + + + +/* + * Destroy all nodes in a display list. + * Input: list - display list number + */ +void gamma_destroy_list( GLuint list ) +{ + Node *n, *block; + GLboolean done; + + block = (Node *) _mesa_HashLookup(gCCPriv->DisplayList, list); + n = block; + + done = block ? GL_FALSE : GL_TRUE; + while (!done) { + switch (n[0].opcode) { + /* special cases first */ + case OPCODE_MAP1: + free( n[6].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_MAP2: + free( n[10].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_DRAW_PIXELS: + free( n[5].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_BITMAP: + free( n[7].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_POLYGON_STIPPLE: + free( n[1].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_IMAGE1D: + free( n[8].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_IMAGE2D: + free( n[9].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_SUB_IMAGE1D: + free( n[7].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_TEX_SUB_IMAGE2D: + free( n[9].data ); + n += InstSize[n[0].opcode]; + break; + case OPCODE_CONTINUE: + n = (Node *) n[1].next; + free( block ); + block = n; + break; + case OPCODE_END_OF_LIST: + free( block ); + done = GL_TRUE; + break; + default: + /* Most frequent case */ + n += InstSize[n[0].opcode]; + break; + } + } + + _mesa_HashRemove(gCCPriv->DisplayList, list); +} + + + +/* + * Translate the nth element of list from type to GLuint. + */ +static GLuint translate_id( GLsizei n, GLenum type, const GLvoid *list ) +{ + GLbyte *bptr; + GLubyte *ubptr; + GLshort *sptr; + GLushort *usptr; + GLint *iptr; + GLuint *uiptr; + GLfloat *fptr; + + switch (type) { + case GL_BYTE: + bptr = (GLbyte *) list; + return (GLuint) *(bptr+n); + case GL_UNSIGNED_BYTE: + ubptr = (GLubyte *) list; + return (GLuint) *(ubptr+n); + case GL_SHORT: + sptr = (GLshort *) list; + return (GLuint) *(sptr+n); + case GL_UNSIGNED_SHORT: + usptr = (GLushort *) list; + return (GLuint) *(usptr+n); + case GL_INT: + iptr = (GLint *) list; + return (GLuint) *(iptr+n); + case GL_UNSIGNED_INT: + uiptr = (GLuint *) list; + return (GLuint) *(uiptr+n); + case GL_FLOAT: + fptr = (GLfloat *) list; + return (GLuint) *(fptr+n); + case GL_2_BYTES: + ubptr = ((GLubyte *) list) + 2*n; + return (GLuint) *ubptr * 256 + (GLuint) *(ubptr+1); + case GL_3_BYTES: + ubptr = ((GLubyte *) list) + 3*n; + return (GLuint) *ubptr * 65536 + + (GLuint) *(ubptr+1) * 256 + + (GLuint) *(ubptr+2); + case GL_4_BYTES: + ubptr = ((GLubyte *) list) + 4*n; + return (GLuint) *ubptr * 16777216 + + (GLuint) *(ubptr+1) * 65536 + + (GLuint) *(ubptr+2) * 256 + + (GLuint) *(ubptr+3); + default: + return 0; + } +} + + + + +/**********************************************************************/ +/***** Public *****/ +/**********************************************************************/ + +void gamma_init_lists( void ) +{ + static int init_flag = 0; + + if (init_flag==0) { + InstSize[OPCODE_ACCUM] = 3; + InstSize[OPCODE_ALPHA_FUNC] = 3; + InstSize[OPCODE_BEGIN] = 2; + InstSize[OPCODE_BIND_TEXTURE] = 3; + InstSize[OPCODE_BITMAP] = 8; + InstSize[OPCODE_BLEND_FUNC] = 3; + InstSize[OPCODE_CALL_LIST] = 2; + InstSize[OPCODE_CALL_LIST_OFFSET] = 2; + InstSize[OPCODE_CLEAR] = 2; + InstSize[OPCODE_CLEAR_ACCUM] = 5; + InstSize[OPCODE_CLEAR_COLOR] = 5; + InstSize[OPCODE_CLEAR_DEPTH] = 2; + InstSize[OPCODE_CLEAR_INDEX] = 2; + InstSize[OPCODE_CLEAR_STENCIL] = 2; + InstSize[OPCODE_CLIP_PLANE] = 6; + InstSize[OPCODE_COLOR_3F] = 4; + InstSize[OPCODE_COLOR_4F] = 5; + InstSize[OPCODE_COLOR_4UB] = 5; + InstSize[OPCODE_COLOR_MASK] = 5; + InstSize[OPCODE_COLOR_MATERIAL] = 3; + InstSize[OPCODE_COPY_PIXELS] = 6; + InstSize[OPCODE_COPY_TEX_IMAGE1D] = 8; + InstSize[OPCODE_COPY_TEX_IMAGE2D] = 9; + InstSize[OPCODE_COPY_TEX_SUB_IMAGE1D] = 7; + InstSize[OPCODE_COPY_TEX_SUB_IMAGE2D] = 9; + InstSize[OPCODE_CULL_FACE] = 2; + InstSize[OPCODE_DEPTH_FUNC] = 2; + InstSize[OPCODE_DEPTH_MASK] = 2; + InstSize[OPCODE_DEPTH_RANGE] = 3; + InstSize[OPCODE_DISABLE] = 2; + InstSize[OPCODE_DRAW_BUFFER] = 2; + InstSize[OPCODE_DRAW_PIXELS] = 2; + InstSize[OPCODE_ENABLE] = 2; + InstSize[OPCODE_EDGE_FLAG] = 2; + InstSize[OPCODE_END] = 1; + InstSize[OPCODE_EVALCOORD1] = 2; + InstSize[OPCODE_EVALCOORD2] = 3; + InstSize[OPCODE_EVALMESH1] = 4; + InstSize[OPCODE_EVALMESH2] = 6; + InstSize[OPCODE_EVALPOINT1] = 2; + InstSize[OPCODE_EVALPOINT2] = 3; + InstSize[OPCODE_FOG] = 6; + InstSize[OPCODE_FRONT_FACE] = 2; + InstSize[OPCODE_FRUSTUM] = 7; + InstSize[OPCODE_HINT] = 3; + InstSize[OPCODE_INDEX] = 2; + InstSize[OPCODE_INDEX_MASK] = 2; + InstSize[OPCODE_INIT_NAMES] = 1; + InstSize[OPCODE_LIGHT] = 7; + InstSize[OPCODE_LIGHT_MODEL] = 6; + InstSize[OPCODE_LINE_STIPPLE] = 3; + InstSize[OPCODE_LINE_WIDTH] = 2; + InstSize[OPCODE_LIST_BASE] = 2; + InstSize[OPCODE_LOAD_IDENTITY] = 1; + InstSize[OPCODE_LOAD_MATRIX] = 17; + InstSize[OPCODE_LOAD_NAME] = 2; + InstSize[OPCODE_LOGIC_OP] = 2; + InstSize[OPCODE_MAP1] = 7; + InstSize[OPCODE_MAP2] = 11; + InstSize[OPCODE_MAPGRID1] = 4; + InstSize[OPCODE_MAPGRID2] = 7; + InstSize[OPCODE_MATERIAL] = 7; + InstSize[OPCODE_MATRIX_MODE] = 2; + InstSize[OPCODE_MULT_MATRIX] = 17; + InstSize[OPCODE_NORMAL] = 4; + InstSize[OPCODE_ORTHO] = 7; + InstSize[OPCODE_PASSTHROUGH] = 2; + InstSize[OPCODE_PIXEL_MAP] = 4; + InstSize[OPCODE_PIXEL_TRANSFER] = 3; + InstSize[OPCODE_PIXEL_ZOOM] = 3; + InstSize[OPCODE_POINT_SIZE] = 2; + InstSize[OPCODE_POLYGON_MODE] = 3; + InstSize[OPCODE_POLYGON_STIPPLE] = 2; + InstSize[OPCODE_POLYGON_OFFSET] = 3; + InstSize[OPCODE_POP_ATTRIB] = 1; + InstSize[OPCODE_POP_MATRIX] = 1; + InstSize[OPCODE_POP_NAME] = 1; + InstSize[OPCODE_PRIORITIZE_TEXTURE] = 3; + InstSize[OPCODE_PUSH_ATTRIB] = 2; + InstSize[OPCODE_PUSH_MATRIX] = 1; + InstSize[OPCODE_PUSH_NAME] = 2; + InstSize[OPCODE_RASTER_POS] = 5; + InstSize[OPCODE_RECTF] = 5; + InstSize[OPCODE_READ_BUFFER] = 2; + InstSize[OPCODE_SCALE] = 4; + InstSize[OPCODE_SCISSOR] = 5; + InstSize[OPCODE_STENCIL_FUNC] = 4; + InstSize[OPCODE_STENCIL_MASK] = 2; + InstSize[OPCODE_STENCIL_OP] = 4; + InstSize[OPCODE_SHADE_MODEL] = 2; + InstSize[OPCODE_TEXCOORD2] = 3; + InstSize[OPCODE_TEXCOORD4] = 5; + InstSize[OPCODE_TEXENV] = 7; + InstSize[OPCODE_TEXGEN] = 7; + InstSize[OPCODE_TEXPARAMETER] = 7; + InstSize[OPCODE_TEX_IMAGE1D] = 9; + InstSize[OPCODE_TEX_IMAGE2D] = 10; + InstSize[OPCODE_TEX_IMAGE3D] = 11; + InstSize[OPCODE_TEX_SUB_IMAGE1D] = 8; + InstSize[OPCODE_TEX_SUB_IMAGE2D] = 10; + InstSize[OPCODE_TRANSLATE] = 4; + InstSize[OPCODE_VERTEX2] = 3; + InstSize[OPCODE_VERTEX3] = 4; + InstSize[OPCODE_VERTEX4] = 5; + InstSize[OPCODE_VIEWPORT] = 5; + InstSize[OPCODE_CONTINUE] = 2; + InstSize[OPCODE_END_OF_LIST] = 1; + } + init_flag = 1; +} + + +/* + * Display List compilation functions + */ + + +void gl_save_Accum( GLenum op, GLfloat value ) +{ + Node *n = alloc_instruction( OPCODE_ACCUM, 2 ); + if (n) { + n[1].e = op; + n[2].f = value; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Accum( op, value ); + } +} + + +void gl_save_AlphaFunc( GLenum func, GLclampf ref ) +{ + Node *n = alloc_instruction( OPCODE_ALPHA_FUNC, 2 ); + if (n) { + n[1].e = func; + n[2].f = (GLfloat) ref; + } + if (gCCPriv->ExecuteFlag) { + _gamma_AlphaFunc( func, ref ); + } +} + +void gl_save_ArrayElement( GLint i ) +{ + if (gCCPriv->Array.NormalEnabled) { + GLbyte *p = (GLbyte*) gCCPriv->Array.NormalPtr + + i * gCCPriv->Array.NormalStrideB; + switch (gCCPriv->Array.NormalType) { + case GL_BYTE: + (*gCCPriv->API->Normal3bv)( (GLbyte*) p ); + break; + case GL_SHORT: + (*gCCPriv->API->Normal3sv)( (GLshort*) p ); + break; + case GL_INT: + (*gCCPriv->API->Normal3iv)( (GLint*) p ); + break; + case GL_FLOAT: + (*gCCPriv->API->Normal3fv)( (GLfloat*) p ); + break; + case GL_DOUBLE: + (*gCCPriv->API->Normal3dv)( (GLdouble*) p ); + break; + default: +#if 0 + gl_problem("Bad normal type in gl_save_ArrayElement"); +#endif + return; + } + } + + if (gCCPriv->Array.ColorEnabled) { + GLbyte *p = (GLbyte*) gCCPriv->Array.ColorPtr + i * gCCPriv->Array.ColorStrideB; + switch (gCCPriv->Array.ColorType) { + case GL_BYTE: + switch (gCCPriv->Array.ColorSize) { + case 3: (*gCCPriv->API->Color3bv)( (GLbyte*) p ); break; + case 4: (*gCCPriv->API->Color4bv)( (GLbyte*) p ); break; + } + break; + case GL_UNSIGNED_BYTE: + switch (gCCPriv->Array.ColorSize) { + case 3: (*gCCPriv->API->Color3ubv)( (GLubyte*) p ); break; + case 4: (*gCCPriv->API->Color4ubv)( (GLubyte*) p ); break; + } + break; + case GL_SHORT: + switch (gCCPriv->Array.ColorSize) { + case 3: (*gCCPriv->API->Color3sv)( (GLshort*) p ); break; + case 4: (*gCCPriv->API->Color4sv)( (GLshort*) p ); break; + } + break; + case GL_UNSIGNED_SHORT: + switch (gCCPriv->Array.ColorSize) { + case 3: (*gCCPriv->API->Color3usv)( (GLushort*) p ); break; + case 4: (*gCCPriv->API->Color4usv)( (GLushort*) p ); break; + } + break; + case GL_INT: + switch (gCCPriv->Array.ColorSize) { + case 3: (*gCCPriv->API->Color3iv)( (GLint*) p ); break; + case 4: (*gCCPriv->API->Color4iv)( (GLint*) p ); break; + } + break; + case GL_UNSIGNED_INT: + switch (gCCPriv->Array.ColorSize) { + case 3: (*gCCPriv->API->Color3uiv)( (GLuint*) p ); break; + case 4: (*gCCPriv->API->Color4uiv)( (GLuint*) p ); break; + } + break; + case GL_FLOAT: + switch (gCCPriv->Array.ColorSize) { + case 3: (*gCCPriv->API->Color3fv)( (GLfloat*) p ); break; + case 4: (*gCCPriv->API->Color4fv)( (GLfloat*) p ); break; + } + break; + case GL_DOUBLE: + switch (gCCPriv->Array.ColorSize) { + case 3: (*gCCPriv->API->Color3dv)( (GLdouble*) p ); break; + case 4: (*gCCPriv->API->Color4dv)( (GLdouble*) p ); break; + } + break; + default: +#if 0 + gl_problem("Bad color type in gl_save_ArrayElement"); +#endif + return; + } + } + + if (gCCPriv->Array.IndexEnabled) { + GLbyte *p = (GLbyte*) gCCPriv->Array.IndexPtr + i * gCCPriv->Array.IndexStrideB; + switch (gCCPriv->Array.IndexType) { + case GL_SHORT: + (*gCCPriv->API->Indexsv)( (GLshort*) p ); + break; + case GL_INT: + (*gCCPriv->API->Indexiv)( (GLint*) p ); + break; + case GL_FLOAT: + (*gCCPriv->API->Indexfv)( (GLfloat*) p ); + break; + case GL_DOUBLE: + (*gCCPriv->API->Indexdv)( (GLdouble*) p ); + break; + default: +#if 0 + gl_problem("Bad index type in gl_save_ArrayElement"); +#endif + return; + } + } + + if (gCCPriv->Array.EdgeFlagEnabled) { + GLbyte *b = (GLbyte*) gCCPriv->Array.EdgeFlagPtr + i * gCCPriv->Array.EdgeFlagStrideB; + (*gCCPriv->API->EdgeFlagv)( (GLboolean*) b ); + } + + if (gCCPriv->Array.VertexEnabled) { + GLbyte *b = (GLbyte*) gCCPriv->Array.VertexPtr + + i * gCCPriv->Array.VertexStrideB; + switch (gCCPriv->Array.VertexType) { + case GL_SHORT: + switch (gCCPriv->Array.VertexSize) { + case 2: (*gCCPriv->API->Vertex2sv)( (GLshort*) b ); break; + case 3: (*gCCPriv->API->Vertex3sv)( (GLshort*) b ); break; + case 4: (*gCCPriv->API->Vertex4sv)( (GLshort*) b ); break; + } + break; + case GL_INT: + switch (gCCPriv->Array.VertexSize) { + case 2: (*gCCPriv->API->Vertex2iv)( (GLint*) b ); break; + case 3: (*gCCPriv->API->Vertex3iv)( (GLint*) b ); break; + case 4: (*gCCPriv->API->Vertex4iv)( (GLint*) b ); break; + } + break; + case GL_FLOAT: + switch (gCCPriv->Array.VertexSize) { + case 2: (*gCCPriv->API->Vertex2fv)( (GLfloat*) b ); break; + case 3: (*gCCPriv->API->Vertex3fv)( (GLfloat*) b ); break; + case 4: (*gCCPriv->API->Vertex4fv)( (GLfloat*) b ); break; + } + break; + case GL_DOUBLE: + switch (gCCPriv->Array.VertexSize) { + case 2: (*gCCPriv->API->Vertex2dv)( (GLdouble*) b ); break; + case 3: (*gCCPriv->API->Vertex3dv)( (GLdouble*) b ); break; + case 4: (*gCCPriv->API->Vertex4dv)( (GLdouble*) b ); break; + } + break; + default: +#if 0 + gl_problem("Bad vertex type in gl_save_ArrayElement"); +#endif + return; + } + } +} + + +void gl_save_Begin( GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_BEGIN, 1 ); + if (n) { + n[1].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Begin( mode ); + } +} + + +void gl_save_BindTexture( GLenum target, GLuint texture ) +{ + Node *n = alloc_instruction( OPCODE_BIND_TEXTURE, 2 ); + if (n) { + n[1].e = target; + n[2].ui = texture; + } + if (gCCPriv->ExecuteFlag) { + _gamma_BindTexture( target, texture ); + } +} + + +void gl_save_Bitmap( + GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ) +{ + GLvoid *image = _mesa_unpack_bitmap(width, height, bitmap, &gCCPriv->Unpack); + Node *n = alloc_instruction( OPCODE_BITMAP, 7 ); + if (n) { + n[1].i = (GLint) width; + n[2].i = (GLint) height; + n[3].f = xorig; + n[4].f = yorig; + n[5].f = xmove; + n[6].f = ymove; + n[7].data = image; + } else + if (image) { + free(image); + } + if (gCCPriv->ExecuteFlag) { + _gamma_Bitmap( width, height, + xorig, yorig, xmove, ymove, bitmap ); + } +} + + +void gl_save_BlendFunc( GLenum sfactor, GLenum dfactor ) +{ + Node *n = alloc_instruction( OPCODE_BLEND_FUNC, 2 ); + if (n) { + n[1].e = sfactor; + n[2].e = dfactor; + } + if (gCCPriv->ExecuteFlag) { + _gamma_BlendFunc( sfactor, dfactor ); + } +} + +void gl_save_CallList( GLuint list ) +{ + Node *n = alloc_instruction( OPCODE_CALL_LIST, 1 ); + if (n) { + n[1].ui = list; + } + if (gCCPriv->ExecuteFlag) { + _gamma_CallList( list ); + } +} + + +void gl_save_CallLists( + GLsizei n, GLenum type, const GLvoid *lists ) +{ + GLint i; + + for (i=0;i<n;i++) { + GLuint list = translate_id( i, type, lists ); + Node *n = alloc_instruction( OPCODE_CALL_LIST_OFFSET, 1 ); + if (n) { + n[1].ui = list; + } + } + if (gCCPriv->ExecuteFlag) { + _gamma_CallLists( n, type, lists ); + } +} + + +void gl_save_Clear( GLbitfield mask ) +{ + Node *n = alloc_instruction( OPCODE_CLEAR, 1 ); + if (n) { + n[1].bf = mask; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Clear( mask ); + } +} + + +void gl_save_ClearAccum( GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ) +{ + Node *n = alloc_instruction( OPCODE_CLEAR_ACCUM, 4 ); + if (n) { + n[1].f = red; + n[2].f = green; + n[3].f = blue; + n[4].f = alpha; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ClearAccum( red, green, blue, alpha ); + } +} + + +void gl_save_ClearColor( GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha ) +{ + Node *n = alloc_instruction( OPCODE_CLEAR_COLOR, 4 ); + if (n) { + n[1].f = red; + n[2].f = green; + n[3].f = blue; + n[4].f = alpha; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ClearColor( red, green, blue, alpha ); + } +} + + +void gl_save_ClearDepth( GLclampd depth ) +{ + Node *n = alloc_instruction( OPCODE_CLEAR_DEPTH, 1 ); + if (n) { + n[1].f = (GLfloat) depth; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ClearDepth( depth ); + } +} + + +void gl_save_ClearIndex( GLfloat c ) +{ + Node *n = alloc_instruction( OPCODE_CLEAR_INDEX, 1 ); + if (n) { + n[1].f = c; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ClearIndex( c ); + } +} + + +void gl_save_ClearStencil( GLint s ) +{ + Node *n = alloc_instruction( OPCODE_CLEAR_STENCIL, 1 ); + if (n) { + n[1].i = s; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ClearStencil( s ); + } +} + + +void gl_save_ClipPlane( GLenum plane, const GLdouble *equ ) +{ + Node *n = alloc_instruction( OPCODE_CLIP_PLANE, 5 ); + if (n) { + n[1].e = plane; + n[2].f = equ[0]; + n[3].f = equ[1]; + n[4].f = equ[2]; + n[5].f = equ[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ClipPlane( plane, equ ); + } +} + + +void gl_save_Color3f( GLfloat r, GLfloat g, GLfloat b ) +{ + Node *n = alloc_instruction( OPCODE_COLOR_3F, 3 ); + if (n) { + n[1].f = r; + n[2].f = g; + n[3].f = b; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Color3f( r, g, b ); + } +} + + +void gl_save_Color3fv( const GLfloat *c ) +{ + Node *n = alloc_instruction( OPCODE_COLOR_3F, 3 ); + if (n) { + n[1].f = c[0]; + n[2].f = c[1]; + n[3].f = c[2]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Color3fv( c ); + } +} + + +void gl_save_Color4f( GLfloat r, GLfloat g, + GLfloat b, GLfloat a ) +{ + Node *n = alloc_instruction( OPCODE_COLOR_4F, 4 ); + if (n) { + n[1].f = r; + n[2].f = g; + n[3].f = b; + n[4].f = a; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Color4f( r, g, b, a ); + } +} + + +void gl_save_Color4fv( const GLfloat *c ) +{ + Node *n = alloc_instruction( OPCODE_COLOR_4F, 4 ); + if (n) { + n[1].f = c[0]; + n[2].f = c[1]; + n[3].f = c[2]; + n[4].f = c[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Color4fv( c ); + } +} + + +void gl_save_Color4ub( GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + Node *n = alloc_instruction( OPCODE_COLOR_4UB, 4 ); + if (n) { + n[1].ub = r; + n[2].ub = g; + n[3].ub = b; + n[4].ub = a; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Color4ub( r, g, b, a ); + } +} + + +void gl_save_Color4ubv( const GLubyte *c ) +{ + Node *n = alloc_instruction( OPCODE_COLOR_4UB, 4 ); + if (n) { + n[1].ub = c[0]; + n[2].ub = c[1]; + n[3].ub = c[2]; + n[4].ub = c[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Color4ubv( c ); + } +} + + +void gl_save_ColorMask( GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha ) +{ + Node *n = alloc_instruction( OPCODE_COLOR_MASK, 4 ); + if (n) { + n[1].b = red; + n[2].b = green; + n[3].b = blue; + n[4].b = alpha; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ColorMask( red, green, blue, alpha ); + } +} + + +void gl_save_ColorMaterial( GLenum face, GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_COLOR_MATERIAL, 2 ); + if (n) { + n[1].e = face; + n[2].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ColorMaterial( face, mode ); + } +} + + +void gl_save_CopyPixels( GLint x, GLint y, + GLsizei width, GLsizei height, GLenum type ) +{ + Node *n = alloc_instruction( OPCODE_COPY_PIXELS, 5 ); + if (n) { + n[1].i = x; + n[2].i = y; + n[3].i = (GLint) width; + n[4].i = (GLint) height; + n[5].e = type; + } + if (gCCPriv->ExecuteFlag) { + _gamma_CopyPixels( x, y, width, height, type ); + } +} + + + +void gl_save_CopyTexImage1D( + GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, GLsizei width, + GLint border ) +{ + Node *n = alloc_instruction( OPCODE_COPY_TEX_IMAGE1D, 7 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].e = internalformat; + n[4].i = x; + n[5].i = y; + n[6].i = width; + n[7].i = border; + } + if (gCCPriv->ExecuteFlag) { + _gamma_CopyTexImage1D( target, level, internalformat, + x, y, width, border ); + } +} + + +void gl_save_CopyTexImage2D( + GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, GLsizei width, + GLsizei height, GLint border ) +{ + Node *n = alloc_instruction( OPCODE_COPY_TEX_IMAGE2D, 8 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].e = internalformat; + n[4].i = x; + n[5].i = y; + n[6].i = width; + n[7].i = height; + n[8].i = border; + } + if (gCCPriv->ExecuteFlag) { + _gamma_CopyTexImage2D( target, level, internalformat, + x, y, width, height, border ); + } +} + + + +void gl_save_CopyTexSubImage1D( + GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, + GLsizei width ) +{ + Node *n = alloc_instruction( OPCODE_COPY_TEX_SUB_IMAGE1D, 6 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = x; + n[5].i = y; + n[6].i = width; + } + if (gCCPriv->ExecuteFlag) { + _gamma_CopyTexSubImage1D( target, level, xoffset, x, y, width ); + } +} + + +void gl_save_CopyTexSubImage2D( + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLint height ) +{ + Node *n = alloc_instruction( OPCODE_COPY_TEX_SUB_IMAGE2D, 8 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = yoffset; + n[5].i = x; + n[6].i = y; + n[7].i = width; + n[8].i = height; + } + if (gCCPriv->ExecuteFlag) { + _gamma_CopyTexSubImage2D( target, level, xoffset, yoffset, + x, y, width, height ); + } +} + + +void gl_save_CullFace( GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_CULL_FACE, 1 ); + if (n) { + n[1].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_CullFace( mode ); + } +} + + +void gl_save_DepthFunc( GLenum func ) +{ + Node *n = alloc_instruction( OPCODE_DEPTH_FUNC, 1 ); + if (n) { + n[1].e = func; + } + if (gCCPriv->ExecuteFlag) { + _gamma_DepthFunc( func ); + } +} + + +void gl_save_DepthMask( GLboolean mask ) +{ + Node *n = alloc_instruction( OPCODE_DEPTH_MASK, 1 ); + if (n) { + n[1].b = mask; + } + if (gCCPriv->ExecuteFlag) { + _gamma_DepthMask( mask ); + } +} + + +void gl_save_DepthRange( GLclampd nearval, GLclampd farval ) +{ + Node *n = alloc_instruction( OPCODE_DEPTH_RANGE, 2 ); + if (n) { + n[1].f = (GLfloat) nearval; + n[2].f = (GLfloat) farval; + } + if (gCCPriv->ExecuteFlag) { + _gamma_DepthRange( nearval, farval ); + } +} + + +void gl_save_Disable( GLenum cap ) +{ + Node *n = alloc_instruction( OPCODE_DISABLE, 1 ); + if (n) { + n[1].e = cap; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Disable( cap ); + } +} + +void gl_save_DrawArrays( + GLenum mode, GLint first, GLsizei count ) +{ + GLint i; + +#if 0 + if (INSIDE_BEGIN_END(ctx)) { + gamma_error( GL_INVALID_OPERATION, "glDrawArrays" ); + return; + } +#endif + if (count<0) { + gamma_error( GL_INVALID_VALUE, "glDrawArrays(count)" ); + return; + } + switch (mode) { + case GL_POINTS: + case GL_LINES: + case GL_LINE_STRIP: + case GL_LINE_LOOP: + case GL_TRIANGLES: + case GL_TRIANGLE_STRIP: + case GL_TRIANGLE_FAN: + case GL_QUADS: + case GL_QUAD_STRIP: + case GL_POLYGON: + /* OK */ + break; + default: + gamma_error( GL_INVALID_ENUM, "glDrawArrays(mode)" ); + return; + } + + /* Note: this will do compile AND execute if needed */ + gl_save_Begin( mode ); + for (i=0;i<count;i++) { + gl_save_ArrayElement( first+i ); + } + gl_save_End( ); +} + + +void gl_save_DrawBuffer( GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_DRAW_BUFFER, 1 ); + if (n) { + n[1].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_DrawBuffer( mode ); + } +} + + +void gl_save_DrawElements( + GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices ) +{ + switch (type) { + case GL_UNSIGNED_BYTE: + { + GLubyte *ub_indices = (GLubyte *) indices; + GLint i; + gl_save_Begin( mode ); + for (i=0;i<count;i++) { + gl_save_ArrayElement( (GLint) ub_indices[i] ); + } + gl_save_End( ); + } + break; + case GL_UNSIGNED_SHORT: + { + GLushort *us_indices = (GLushort *) indices; + GLint i; + gl_save_Begin( mode ); + for (i=0;i<count;i++) { + gl_save_ArrayElement( (GLint) us_indices[i] ); + } + gl_save_End( ); + } + break; + case GL_UNSIGNED_INT: + { + GLuint *ui_indices = (GLuint *) indices; + GLint i; + gl_save_Begin( mode ); + for (i=0;i<count;i++) { + gl_save_ArrayElement( (GLint) ui_indices[i] ); + } + gl_save_End( ); + } + break; + default: + gamma_error( GL_INVALID_ENUM, "glDrawElements(type)" ); + return; + } +} + + +void gl_save_DrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, + pixels, &gCCPriv->Unpack); + Node *n = alloc_instruction( OPCODE_DRAW_PIXELS, 5 ); + if (n) { + n[1].i = width; + n[2].i = height; + n[3].e = format; + n[4].e = type; + n[5].data = image; + } else + if (image) { + free(image); + } + if (gCCPriv->ExecuteFlag) { + _gamma_DrawPixels( width, height, format, type, pixels ); + } +} + + +void gl_save_EdgeFlag( GLboolean flag ) +{ + Node *n = alloc_instruction( OPCODE_EDGE_FLAG, 1 ); + if (n) { + n[1].b = flag; + } + if (gCCPriv->ExecuteFlag) { + _gamma_EdgeFlag( flag ); + } +} + + +void gl_save_Enable( GLenum cap ) +{ + Node *n = alloc_instruction( OPCODE_ENABLE, 1 ); + if (n) { + n[1].e = cap; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Enable( cap ); + } +} + + +void gl_save_End( void ) +{ + (void) alloc_instruction( OPCODE_END, 0 ); + if (gCCPriv->ExecuteFlag) { + _gamma_End( ); + } +} + + +void gl_save_EvalCoord1f( GLfloat u ) +{ + Node *n = alloc_instruction( OPCODE_EVALCOORD1, 1 ); + if (n) { + n[1].f = u; + } + if (gCCPriv->ExecuteFlag) { + _gamma_EvalCoord1f( u ); + } +} + + +void gl_save_EvalCoord2f( GLfloat u, GLfloat v ) +{ + Node *n = alloc_instruction( OPCODE_EVALCOORD2, 2 ); + if (n) { + n[1].f = u; + n[2].f = v; + } + if (gCCPriv->ExecuteFlag) { + _gamma_EvalCoord2f( u, v ); + } +} + + +void gl_save_EvalMesh1( + GLenum mode, GLint i1, GLint i2 ) +{ + Node *n = alloc_instruction( OPCODE_EVALMESH1, 3 ); + if (n) { + n[1].e = mode; + n[2].i = i1; + n[3].i = i2; + } + if (gCCPriv->ExecuteFlag) { + _gamma_EvalMesh1( mode, i1, i2 ); + } +} + + +void gl_save_EvalMesh2( + GLenum mode, GLint i1, GLint i2, GLint j1, GLint j2 ) +{ + Node *n = alloc_instruction( OPCODE_EVALMESH2, 5 ); + if (n) { + n[1].e = mode; + n[2].i = i1; + n[3].i = i2; + n[4].i = j1; + n[5].i = j2; + } + if (gCCPriv->ExecuteFlag) { + _gamma_EvalMesh2( mode, i1, i2, j1, j2 ); + } +} + + +void gl_save_EvalPoint1( GLint i ) +{ + Node *n = alloc_instruction( OPCODE_EVALPOINT1, 1 ); + if (n) { + n[1].i = i; + } + if (gCCPriv->ExecuteFlag) { + _gamma_EvalPoint1( i ); + } +} + + +void gl_save_EvalPoint2( GLint i, GLint j ) +{ + Node *n = alloc_instruction( OPCODE_EVALPOINT2, 2 ); + if (n) { + n[1].i = i; + n[2].i = j; + } + if (gCCPriv->ExecuteFlag) { + _gamma_EvalPoint2( i, j ); + } +} + + +void gl_save_Fogfv( GLenum pname, const GLfloat *params ) +{ + Node *n = alloc_instruction( OPCODE_FOG, 5 ); + if (n) { + n[1].e = pname; + n[2].f = params[0]; + n[3].f = params[1]; + n[4].f = params[2]; + n[5].f = params[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Fogfv( pname, params ); + } +} + + +void gl_save_FrontFace( GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_FRONT_FACE, 1 ); + if (n) { + n[1].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_FrontFace( mode ); + } +} + + +void gl_save_Frustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + Node *n = alloc_instruction( OPCODE_FRUSTUM, 6 ); + if (n) { + n[1].f = left; + n[2].f = right; + n[3].f = bottom; + n[4].f = top; + n[5].f = nearval; + n[6].f = farval; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Frustum( left, right, bottom, top, nearval, farval ); + } +} + + +void gl_save_Hint( GLenum target, GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_HINT, 2 ); + if (n) { + n[1].e = target; + n[2].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Hint( target, mode ); + } +} + + +void gl_save_Indexi( GLint index ) +{ + Node *n = alloc_instruction( OPCODE_INDEX, 1 ); + if (n) { + n[1].i = index; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Indexi( index ); + } +} + + +void gl_save_Indexf( GLfloat index ) +{ + Node *n = alloc_instruction( OPCODE_INDEX, 1 ); + if (n) { + n[1].i = (GLint) index; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Indexf( index ); + } +} + + +void gl_save_IndexMask( GLuint mask ) +{ + Node *n = alloc_instruction( OPCODE_INDEX_MASK, 1 ); + if (n) { + n[1].ui = mask; + } + if (gCCPriv->ExecuteFlag) { + _gamma_IndexMask( mask ); + } +} + + +void gl_save_InitNames( void ) +{ + (void) alloc_instruction( OPCODE_INIT_NAMES, 0 ); + if (gCCPriv->ExecuteFlag) { + _gamma_InitNames( ); + } +} + + +void gl_save_Lightfv( GLenum light, GLenum pname, + const GLfloat *params ) +{ + Node *n = alloc_instruction( OPCODE_LIGHT, 6 ); + if (OPCODE_LIGHT) { + GLint i, nParams; + n[1].e = light; + n[2].e = pname; + switch (pname) { + case GL_AMBIENT: + nParams = 4; + break; + case GL_DIFFUSE: + nParams = 4; + break; + case GL_SPECULAR: + nParams = 4; + break; + case GL_POSITION: + nParams = 4; + break; + case GL_SPOT_DIRECTION: + nParams = 3; + break; + case GL_SPOT_EXPONENT: + nParams = 1; + break; + case GL_SPOT_CUTOFF: + nParams = 1; + break; + case GL_CONSTANT_ATTENUATION: + nParams = 1; + break; + case GL_LINEAR_ATTENUATION: + nParams = 1; + break; + case GL_QUADRATIC_ATTENUATION: + nParams = 1; + break; + default: + nParams = 0; + } + for (i = 0; i < nParams; i++) { + n[3+i].f = params[i]; + } + } + if (gCCPriv->ExecuteFlag) { + _gamma_Lightfv( light, pname, params ); + } +} + + +void gl_save_LightModelfv( + GLenum pname, const GLfloat *params ) +{ + Node *n = alloc_instruction( OPCODE_LIGHT_MODEL, 5 ); + if (n) { + n[1].e = pname; + n[2].f = params[0]; + n[3].f = params[1]; + n[4].f = params[2]; + n[5].f = params[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_LightModelfv( pname, params ); + } +} + + +void gl_save_LineStipple( GLint factor, GLushort pattern ) +{ + Node *n = alloc_instruction( OPCODE_LINE_STIPPLE, 2 ); + if (n) { + n[1].i = factor; + n[2].us = pattern; + } + if (gCCPriv->ExecuteFlag) { + _gamma_LineStipple( factor, pattern ); + } +} + + +void gl_save_LineWidth( GLfloat width ) +{ + Node *n = alloc_instruction( OPCODE_LINE_WIDTH, 1 ); + if (n) { + n[1].f = width; + } + if (gCCPriv->ExecuteFlag) { + _gamma_LineWidth( width ); + } +} + + +void gl_save_ListBase( GLuint base ) +{ + Node *n = alloc_instruction( OPCODE_LIST_BASE, 1 ); + if (n) { + n[1].ui = base; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ListBase( base ); + } +} + + +void gl_save_LoadIdentity( void ) +{ + (void) alloc_instruction( OPCODE_LOAD_IDENTITY, 0 ); + if (gCCPriv->ExecuteFlag) { + _gamma_LoadIdentity( ); + } +} + + +void gl_save_LoadMatrixf( const GLfloat *m ) +{ + Node *n = alloc_instruction( OPCODE_LOAD_MATRIX, 16 ); + if (n) { + GLuint i; + for (i=0;i<16;i++) { + n[1+i].f = m[i]; + } + } + if (gCCPriv->ExecuteFlag) { + _gamma_LoadMatrixf( m ); + } +} + + +void gl_save_LoadName( GLuint name ) +{ + Node *n = alloc_instruction( OPCODE_LOAD_NAME, 1 ); + if (n) { + n[1].ui = name; + } + if (gCCPriv->ExecuteFlag) { + _gamma_LoadName( name ); + } +} + + +void gl_save_LogicOp( GLenum opcode ) +{ + Node *n = alloc_instruction( OPCODE_LOGIC_OP, 1 ); + if (n) { + n[1].e = opcode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_LogicOp( opcode ); + } +} + + +void gl_save_Map1f( + GLenum target, GLfloat u1, GLfloat u2, GLint stride, + GLint order, const GLfloat *points ) +{ + Node *n = alloc_instruction( OPCODE_MAP1, 6 ); + if (n) { + GLfloat *pnts = gl_copy_map_points1f( target, stride, order, points ); + n[1].e = target; + n[2].f = u1; + n[3].f = u2; + n[4].i = _mesa_evaluator_components(target); /* stride */ + n[5].i = order; + n[6].data = (void *) pnts; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Map1f( target, u1, u2, stride, order, points ); + } +} + + +void gl_save_Map2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points ) +{ + Node *n = alloc_instruction( OPCODE_MAP2, 10 ); + if (n) { + GLfloat *pnts = gl_copy_map_points2f( target, ustride, uorder, + vstride, vorder, points ); + n[1].e = target; + n[2].f = u1; + n[3].f = u2; + n[4].f = v1; + n[5].f = v2; + /* XXX verify these strides are correct */ + n[6].i = _mesa_evaluator_components(target) * vorder; /*ustride*/ + n[7].i = _mesa_evaluator_components(target); /*vstride*/ + n[8].i = uorder; + n[9].i = vorder; + n[10].data = (void *) pnts; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Map2f( target, + u1, u2, ustride, uorder, + v1, v2, vstride, vorder, points ); + } +} + + +void gl_save_MapGrid1f( GLint un, GLfloat u1, GLfloat u2 ) +{ + Node *n = alloc_instruction( OPCODE_MAPGRID1, 3 ); + if (n) { + n[1].i = un; + n[2].f = u1; + n[3].f = u2; + } + if (gCCPriv->ExecuteFlag) { + _gamma_MapGrid1f( un, u1, u2 ); + } +} + + +void gl_save_MapGrid2f( + GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ) +{ + Node *n = alloc_instruction( OPCODE_MAPGRID2, 6 ); + if (n) { + n[1].i = un; + n[2].f = u1; + n[3].f = u2; + n[4].i = vn; + n[5].f = v1; + n[6].f = v2; + } + if (gCCPriv->ExecuteFlag) { + _gamma_MapGrid2f( un, u1, u2, vn, v1, v2 ); + } +} + + +void gl_save_Materialfv( + GLenum face, GLenum pname, const GLfloat *params ) +{ + Node *n = alloc_instruction( OPCODE_MATERIAL, 6 ); + if (n) { + n[1].e = face; + n[2].e = pname; + n[3].f = params[0]; + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Materialfv( face, pname, params ); + } +} + + +void gl_save_MatrixMode( GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_MATRIX_MODE, 1 ); + if (n) { + n[1].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_MatrixMode( mode ); + } +} + + +void gl_save_MultMatrixf( const GLfloat *m ) +{ + Node *n = alloc_instruction( OPCODE_MULT_MATRIX, 16 ); + if (n) { + GLuint i; + for (i=0;i<16;i++) { + n[1+i].f = m[i]; + } + } + if (gCCPriv->ExecuteFlag) { + _gamma_MultMatrixf( m ); + } +} + + +void gl_save_NewList( GLuint list, GLenum mode ) +{ + /* It's an error to call this function while building a display list */ + gamma_error( GL_INVALID_OPERATION, "glNewList" ); + (void) list; + (void) mode; +} + + +void gl_save_Normal3fv( const GLfloat norm[3] ) +{ + Node *n = alloc_instruction( OPCODE_NORMAL, 3 ); + if (n) { + n[1].f = norm[0]; + n[2].f = norm[1]; + n[3].f = norm[2]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Normal3fv( norm ); + } +} + + +void gl_save_Normal3f( GLfloat nx, GLfloat ny, GLfloat nz ) +{ + Node *n = alloc_instruction( OPCODE_NORMAL, 3 ); + if (n) { + n[1].f = nx; + n[2].f = ny; + n[3].f = nz; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Normal3f( nx, ny, nz ); + } +} + + +void gl_save_Ortho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ) +{ + Node *n = alloc_instruction( OPCODE_ORTHO, 6 ); + if (n) { + n[1].f = left; + n[2].f = right; + n[3].f = bottom; + n[4].f = top; + n[5].f = nearval; + n[6].f = farval; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Ortho( left, right, bottom, top, nearval, farval ); + } +} + + +void gl_save_PixelMapfv( + GLenum map, GLint mapsize, const GLfloat *values ) +{ + Node *n = alloc_instruction( OPCODE_PIXEL_MAP, 3 ); + if (n) { + n[1].e = map; + n[2].i = mapsize; + n[3].data = (void *) malloc( mapsize * sizeof(GLfloat) ); + MEMCPY( n[3].data, (void *) values, mapsize * sizeof(GLfloat) ); + } + if (gCCPriv->ExecuteFlag) { + _gamma_PixelMapfv( map, mapsize, values ); + } +} + + +void gl_save_PixelTransferf( GLenum pname, GLfloat param ) +{ + Node *n = alloc_instruction( OPCODE_PIXEL_TRANSFER, 2 ); + if (n) { + n[1].e = pname; + n[2].f = param; + } + if (gCCPriv->ExecuteFlag) { + _gamma_PixelTransferf( pname, param ); + } +} + + +void gl_save_PixelZoom( GLfloat xfactor, GLfloat yfactor ) +{ + Node *n = alloc_instruction( OPCODE_PIXEL_ZOOM, 2 ); + if (n) { + n[1].f = xfactor; + n[2].f = yfactor; + } + if (gCCPriv->ExecuteFlag) { + _gamma_PixelZoom( xfactor, yfactor ); + } +} + + +void gl_save_PointSize( GLfloat size ) +{ + Node *n = alloc_instruction( OPCODE_POINT_SIZE, 1 ); + if (n) { + n[1].f = size; + } + if (gCCPriv->ExecuteFlag) { + _gamma_PointSize( size ); + } +} + + +void gl_save_PolygonMode( GLenum face, GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_POLYGON_MODE, 2 ); + if (n) { + n[1].e = face; + n[2].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_PolygonMode( face, mode ); + } +} + + +/* + * Polygon stipple must have been upacked already! + */ +void gl_save_PolygonStipple( const GLubyte *pattern ) +{ + Node *n = alloc_instruction( OPCODE_POLYGON_STIPPLE, 1 ); + if (n) { + void *data; + n[1].data = malloc( 32 * 4 ); + data = n[1].data; /* This needed for Acorn compiler */ + MEMCPY( data, pattern, 32 * 4 ); + } + if (gCCPriv->ExecuteFlag) { + _gamma_PolygonStipple( pattern ); + } +} + + +void gl_save_PolygonOffset( GLfloat factor, GLfloat units ) +{ + Node *n = alloc_instruction( OPCODE_POLYGON_OFFSET, 2 ); + if (n) { + n[1].f = factor; + n[2].f = units; + } + if (gCCPriv->ExecuteFlag) { + _gamma_PolygonOffset( factor, units ); + } +} + + +void gl_save_PopAttrib( void ) +{ + (void) alloc_instruction( OPCODE_POP_ATTRIB, 0 ); + if (gCCPriv->ExecuteFlag) { + _gamma_PopAttrib( ); + } +} + + +void gl_save_PopMatrix( void ) +{ + (void) alloc_instruction( OPCODE_POP_MATRIX, 0 ); + if (gCCPriv->ExecuteFlag) { + _gamma_PopMatrix( ); + } +} + + +void gl_save_PopName( void ) +{ + (void) alloc_instruction( OPCODE_POP_NAME, 0 ); + if (gCCPriv->ExecuteFlag) { + _gamma_PopName( ); + } +} + + +void gl_save_PrioritizeTextures( + GLsizei num, const GLuint *textures, + const GLclampf *priorities ) +{ + GLint i; + + for (i=0;i<num;i++) { + Node *n = alloc_instruction( OPCODE_PRIORITIZE_TEXTURE, 2 ); + if (n) { + n[1].ui = textures[i]; + n[2].f = priorities[i]; + } + } + if (gCCPriv->ExecuteFlag) { + _gamma_PrioritizeTextures( num, textures, priorities ); + } +} + + +void gl_save_PushAttrib( GLbitfield mask ) +{ + Node *n = alloc_instruction( OPCODE_PUSH_ATTRIB, 1 ); + if (n) { + n[1].bf = mask; + } + if (gCCPriv->ExecuteFlag) { + _gamma_PushAttrib( mask ); + } +} + + +void gl_save_PushMatrix( void ) +{ + (void) alloc_instruction( OPCODE_PUSH_MATRIX, 0 ); + if (gCCPriv->ExecuteFlag) { + _gamma_PushMatrix( ); + } +} + + +void gl_save_PushName( GLuint name ) +{ + Node *n = alloc_instruction( OPCODE_PUSH_NAME, 1 ); + if (n) { + n[1].ui = name; + } + if (gCCPriv->ExecuteFlag) { + _gamma_PushName( name ); + } +} + + +void gl_save_RasterPos4f( + GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + Node *n = alloc_instruction( OPCODE_RASTER_POS, 4 ); + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + n[4].f = w; + } + if (gCCPriv->ExecuteFlag) { + _gamma_RasterPos4f( x, y, z, w ); + } +} + + +void gl_save_PassThrough( GLfloat token ) +{ + Node *n = alloc_instruction( OPCODE_PASSTHROUGH, 1 ); + if (n) { + n[1].f = token; + } + if (gCCPriv->ExecuteFlag) { + _gamma_PassThrough( token ); + } +} + + +void gl_save_ReadBuffer( GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_READ_BUFFER, 1 ); + if (n) { + n[1].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ReadBuffer( mode ); + } +} + + +void gl_save_Rectf( + GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ) +{ + Node *n = alloc_instruction( OPCODE_RECTF, 4 ); + if (n) { + n[1].f = x1; + n[2].f = y1; + n[3].f = x2; + n[4].f = y2; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Rectf( x1, y1, x2, y2 ); + } +} + + +void gl_save_Rotatef( GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ) +{ + GLfloat m[16]; + gl_rotation_matrix( angle, x, y, z, m ); + gl_save_MultMatrixf( m ); /* save and maybe execute */ +} + + +void gl_save_Scalef( GLfloat x, GLfloat y, GLfloat z ) +{ + Node *n = alloc_instruction( OPCODE_SCALE, 3 ); + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Scalef( x, y, z ); + } +} + + +void gl_save_Scissor( + GLint x, GLint y, GLsizei width, GLsizei height ) +{ + Node *n = alloc_instruction( OPCODE_SCISSOR, 4 ); + if (n) { + n[1].i = x; + n[2].i = y; + n[3].i = width; + n[4].i = height; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Scissor( x, y, width, height ); + } +} + + +void gl_save_ShadeModel( GLenum mode ) +{ + Node *n = alloc_instruction( OPCODE_SHADE_MODEL, 1 ); + if (n) { + n[1].e = mode; + } + if (gCCPriv->ExecuteFlag) { + _gamma_ShadeModel( mode ); + } +} + + +void gl_save_StencilFunc( GLenum func, GLint ref, GLuint mask ) +{ + Node *n = alloc_instruction( OPCODE_STENCIL_FUNC, 3 ); + if (n) { + n[1].e = func; + n[2].i = ref; + n[3].ui = mask; + } + if (gCCPriv->ExecuteFlag) { + _gamma_StencilFunc( func, ref, mask ); + } +} + + +void gl_save_StencilMask( GLuint mask ) +{ + Node *n = alloc_instruction( OPCODE_STENCIL_MASK, 1 ); + if (n) { + n[1].ui = mask; + } + if (gCCPriv->ExecuteFlag) { + _gamma_StencilMask( mask ); + } +} + + +void gl_save_StencilOp( + GLenum fail, GLenum zfail, GLenum zpass ) +{ + Node *n = alloc_instruction( OPCODE_STENCIL_OP, 3 ); + if (n) { + n[1].e = fail; + n[2].e = zfail; + n[3].e = zpass; + } + if (gCCPriv->ExecuteFlag) { + _gamma_StencilOp( fail, zfail, zpass ); + } +} + + +void gl_save_TexCoord2f( GLfloat s, GLfloat t ) +{ + Node *n = alloc_instruction( OPCODE_TEXCOORD2, 2 ); + if (n) { + n[1].f = s; + n[2].f = t; + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexCoord2f( s, t ); + } +} + +void gl_save_TexCoord2fv( const GLfloat *v ) +{ + Node *n = alloc_instruction( OPCODE_TEXCOORD2, 2 ); + if (n) { + n[1].f = v[0]; + n[2].f = v[1]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexCoord2f( n[1].f, n[2].f ); + } +} + +void gl_save_TexCoord3fv( const GLfloat *v ) +{ + Node *n = alloc_instruction( OPCODE_TEXCOORD4, 4 ); + if (n) { + n[1].f = v[0]; + n[2].f = v[1]; + n[1].f = v[2]; + n[2].f = 1.0f; + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexCoord4f( n[1].f, n[2].f, n[3].f, n[4].f ); + } +} + +void gl_save_TexCoord4f( GLfloat s, GLfloat t, + GLfloat r, GLfloat q ) +{ + Node *n = alloc_instruction( OPCODE_TEXCOORD4, 4 ); + if (n) { + n[1].f = s; + n[2].f = t; + n[3].f = r; + n[4].f = q; + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexCoord4f( s, t, r, q ); + } +} + + +void gl_save_TexEnvfv( + GLenum target, GLenum pname, const GLfloat *params ) +{ + Node *n = alloc_instruction( OPCODE_TEXENV, 6 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].f = params[0]; + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexEnvfv( target, pname, params ); + } +} + + +void gl_save_TexGenfv( + GLenum coord, GLenum pname, const GLfloat *params ) +{ + Node *n = alloc_instruction( OPCODE_TEXGEN, 6 ); + if (n) { + n[1].e = coord; + n[2].e = pname; + n[3].f = params[0]; + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexGenfv( coord, pname, params ); + } +} + + +void gl_save_TexParameterfv( GLenum target, + GLenum pname, const GLfloat *params ) +{ + Node *n = alloc_instruction( OPCODE_TEXPARAMETER, 6 ); + if (n) { + n[1].e = target; + n[2].e = pname; + n[3].f = params[0]; + n[4].f = params[1]; + n[5].f = params[2]; + n[6].f = params[3]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexParameterfv( target, pname, params ); + } +} + + +void gl_save_TexImage1D( GLenum target, + GLint level, GLint components, + GLsizei width, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + if (target == GL_PROXY_TEXTURE_1D) { + /* don't compile, execute immediately */ + _gamma_TexImage1D( target, level, components, width, + border, format, type, pixels ); + } + else { + GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, + pixels, &gCCPriv->Unpack); + Node *n; + n = alloc_instruction( OPCODE_TEX_IMAGE1D, 8 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = components; + n[4].i = (GLint) width; + n[5].i = border; + n[6].e = format; + n[7].e = type; + n[8].data = image; + } + else if (image) { + FREE(image); + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexImage1D( target, level, components, width, + border, format, type, pixels ); + } + } +} + + +void gl_save_TexImage2D( GLenum target, + GLint level, GLint components, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + if (target == GL_PROXY_TEXTURE_2D) { + /* don't compile, execute immediately */ + _gamma_TexImage2D( target, level, components, width, + height, border, format, type, pixels ); + } + else { + GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, + pixels, &gCCPriv->Unpack); + Node *n; + n = alloc_instruction( OPCODE_TEX_IMAGE2D, 9 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = components; + n[4].i = (GLint) width; + n[5].i = (GLint) height; + n[6].i = border; + n[7].e = format; + n[8].e = type; + n[9].data = image; + } + else if (image) { + FREE(image); + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexImage2D( target, level, components, width, + height, border, format, type, pixels ); + } + } +} + + +void gl_save_TexSubImage1D( + GLenum target, GLint level, GLint xoffset, + GLsizei width, GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GLvoid *image = _mesa_unpack_image(width, 1, 1, format, type, + pixels, &gCCPriv->Unpack); + Node *n = alloc_instruction( OPCODE_TEX_SUB_IMAGE1D, 7 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = (GLint) width; + n[5].e = format; + n[6].e = type; + n[7].data = image; + } else + if (image) { + free(image); + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexSubImage1D( target, level, xoffset, width, + format, type, image ); + } +} + + +void gl_save_TexSubImage2D( + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ) +{ + GLvoid *image = _mesa_unpack_image(width, height, 1, format, type, + pixels, &gCCPriv->Unpack); + Node *n = alloc_instruction( OPCODE_TEX_SUB_IMAGE2D, 9 ); + if (n) { + n[1].e = target; + n[2].i = level; + n[3].i = xoffset; + n[4].i = yoffset; + n[5].i = (GLint) width; + n[6].i = (GLint) height; + n[7].e = format; + n[8].e = type; + n[9].data = image; + } else + if (image) { + free(image); + } + if (gCCPriv->ExecuteFlag) { + _gamma_TexSubImage2D( target, level, xoffset, yoffset, + width, height, format, type, image ); + } +} + + +void gl_save_Translatef( GLfloat x, GLfloat y, GLfloat z ) +{ + Node *n = alloc_instruction( OPCODE_TRANSLATE, 3 ); + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Translatef( x, y, z ); + } +} + + +void gl_save_Vertex2f( GLfloat x, GLfloat y ) +{ + Node *n = alloc_instruction( OPCODE_VERTEX2, 2 ); + if (n) { + n[1].f = x; + n[2].f = y; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Vertex2f( x, y ); + } +} + + +void gl_save_Vertex3f( GLfloat x, GLfloat y, GLfloat z ) +{ + Node *n = alloc_instruction( OPCODE_VERTEX3, 3 ); + + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Vertex3f( x, y, z ); + } +} + + +void gl_save_Vertex4f( + GLfloat x, GLfloat y, GLfloat z, GLfloat w ) +{ + Node *n = alloc_instruction( OPCODE_VERTEX4, 4 ); + if (n) { + n[1].f = x; + n[2].f = y; + n[3].f = z; + n[4].f = w; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Vertex4f( x, y, z, w ); + } +} + + +void gl_save_Vertex3fv( const GLfloat v[3] ) +{ + Node *n = alloc_instruction( OPCODE_VERTEX3, 3 ); + if (n) { + n[1].f = v[0]; + n[2].f = v[1]; + n[3].f = v[2]; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Vertex3fv( v ); + } +} + + +void gl_save_Viewport( + GLint x, GLint y, GLsizei width, GLsizei height ) +{ + Node *n = alloc_instruction( OPCODE_VIEWPORT, 4 ); + if (n) { + n[1].i = x; + n[2].i = y; + n[3].i = (GLint) width; + n[4].i = (GLint) height; + } + if (gCCPriv->ExecuteFlag) { + _gamma_Viewport( x, y, width, height ); + } +} + + +/**********************************************************************/ +/* Display list execution */ +/**********************************************************************/ + + +/* + * Execute a display list. Note that the ListBase offset must have already + * been added before calling this function. I.e. the list argument is + * the absolute list number, not relative to ListBase. + * Input: list - display list number + */ +static void execute_list( GLuint list ) +{ + Node *n; + GLboolean done; + OpCode opcode; + + if (!_gamma_IsList(list)) + return; + + gCCPriv->CallDepth++; + + n = (Node *) _mesa_HashLookup(gCCPriv->DisplayList, list); + + done = GL_FALSE; + while (!done) { + opcode = n[0].opcode; + + switch (opcode) { + /* Frequently called functions: */ + case OPCODE_VERTEX2: + _gamma_Vertex2f( n[1].f, n[2].f ); + break; + case OPCODE_VERTEX3: + _gamma_Vertex3f( n[1].f, n[2].f, n[3].f ); + break; + case OPCODE_VERTEX4: + _gamma_Vertex4f( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_NORMAL: + _gamma_Normal3f( n[1].f, n[2].f, n[3].f ); +#if 0 /* NOT_DONE */ + gCCPriv->VB->MonoNormal = GL_FALSE; +#endif + break; + case OPCODE_COLOR_4UB: + _gamma_Color4ub( n[1].ub, n[2].ub, n[3].ub, n[4].ub ); + break; + case OPCODE_COLOR_3F: + _gamma_Color3f( n[1].f, n[2].f, n[3].f ); + break; + case OPCODE_COLOR_4F: + _gamma_Color4f( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_INDEX: + gCCPriv->Current.Index = n[1].ui; +#if 0 /* NOT_DONE */ + gCCPriv->VB->MonoColor = GL_FALSE; +#endif + break; + case OPCODE_BEGIN: + _gamma_Begin( n[1].e ); + break; + case OPCODE_END: + _gamma_End( ); + break; + case OPCODE_TEXCOORD2: + _gamma_TexCoord2f( n[1].f, n[2].f ); + break; + case OPCODE_TEXCOORD4: + _gamma_TexCoord4f( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_ACCUM: + _gamma_Accum( n[1].e, n[2].f ); + break; + case OPCODE_ALPHA_FUNC: + _gamma_AlphaFunc( n[1].e, n[2].f ); + break; + case OPCODE_BIND_TEXTURE: + _gamma_BindTexture( n[1].e, n[2].ui ); + break; + case OPCODE_BITMAP: + { + struct gl_pixelstore_attrib save = gCCPriv->Unpack; + gCCPriv->Unpack = _mesa_native_packing; + _gamma_Bitmap( (GLsizei) n[1].i, (GLsizei) n[2].i, + n[3].f, n[4].f, n[5].f, n[6].f, (const GLubyte *) n[7].data ); + gCCPriv->Unpack = save; /* restore */ + } + break; + case OPCODE_BLEND_FUNC: + _gamma_BlendFunc( n[1].e, n[2].e ); + break; + case OPCODE_CALL_LIST: + /* Generated by glCallList(), don't add ListBase */ + if (gCCPriv->CallDepth<MAX_LIST_NESTING) { + execute_list( n[1].ui ); + } + break; + case OPCODE_CALL_LIST_OFFSET: + /* Generated by glCallLists() so we must add ListBase */ + if (gCCPriv->CallDepth<MAX_LIST_NESTING) { + execute_list( gCCPriv->List.ListBase + n[1].ui ); + } + break; + case OPCODE_CLEAR: + _gamma_Clear( n[1].bf ); + break; + case OPCODE_CLEAR_COLOR: + _gamma_ClearColor( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_CLEAR_ACCUM: + _gamma_ClearAccum( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_CLEAR_DEPTH: + _gamma_ClearDepth( (GLclampd) n[1].f ); + break; + case OPCODE_CLEAR_INDEX: + _gamma_ClearIndex( n[1].ui ); + break; + case OPCODE_CLEAR_STENCIL: + _gamma_ClearStencil( n[1].i ); + break; + case OPCODE_CLIP_PLANE: + { + GLdouble equ[4]; + equ[0] = n[2].f; + equ[1] = n[3].f; + equ[2] = n[4].f; + equ[3] = n[5].f; + _gamma_ClipPlane( n[1].e, equ ); + } + break; + case OPCODE_COLOR_MASK: + _gamma_ColorMask( n[1].b, n[2].b, n[3].b, n[4].b ); + break; + case OPCODE_COLOR_MATERIAL: + _gamma_ColorMaterial( n[1].e, n[2].e ); + break; + case OPCODE_COPY_PIXELS: + _gamma_CopyPixels( n[1].i, n[2].i, + (GLsizei) n[3].i, (GLsizei) n[4].i, n[5].e ); + break; + case OPCODE_COPY_TEX_IMAGE1D: + _gamma_CopyTexImage1D( n[1].e, n[2].i, n[3].e, n[4].i, + n[5].i, n[6].i, n[7].i ); + break; + case OPCODE_COPY_TEX_IMAGE2D: + _gamma_CopyTexImage2D( n[1].e, n[2].i, n[3].e, n[4].i, + n[5].i, n[6].i, n[7].i, n[8].i ); + break; + case OPCODE_COPY_TEX_SUB_IMAGE1D: + { + struct gl_pixelstore_attrib save = gCCPriv->Unpack; + gCCPriv->Unpack = _mesa_native_packing; + _gamma_TexSubImage1D( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].e, + n[6].e, n[7].data ); + gCCPriv->Unpack = save; /* restore */ + } + break; + case OPCODE_COPY_TEX_SUB_IMAGE2D: + { + struct gl_pixelstore_attrib save = gCCPriv->Unpack; + gCCPriv->Unpack = _mesa_native_packing; + _gamma_TexSubImage2D( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].e, + n[6].i, n[7].e, n[8].e, n[9].data ); + gCCPriv->Unpack = save; /* restore */ + } + break; + case OPCODE_CULL_FACE: + _gamma_CullFace( n[1].e ); + break; + case OPCODE_DEPTH_FUNC: + _gamma_DepthFunc( n[1].e ); + break; + case OPCODE_DEPTH_MASK: + _gamma_DepthMask( n[1].b ); + break; + case OPCODE_DEPTH_RANGE: + _gamma_DepthRange( (GLclampd) n[1].f, (GLclampd) n[2].f ); + break; + case OPCODE_DISABLE: + _gamma_Disable( n[1].e ); + break; + case OPCODE_DRAW_BUFFER: + _gamma_DrawBuffer( n[1].e ); + break; + case OPCODE_DRAW_PIXELS: + { + struct gl_pixelstore_attrib save = gCCPriv->Unpack; + gCCPriv->Unpack = _mesa_native_packing; + _gamma_DrawPixels( n[1].i, n[2].i, n[3].e, n[4].e, + n[5].data ); + gCCPriv->Unpack = save; /* restore */ + } + break; + case OPCODE_EDGE_FLAG: + gCCPriv->Current.EdgeFlag = n[1].b; + break; + case OPCODE_ENABLE: + _gamma_Enable( n[1].e ); + break; + case OPCODE_EVALCOORD1: + _gamma_EvalCoord1f( n[1].f ); + break; + case OPCODE_EVALCOORD2: + _gamma_EvalCoord2f( n[1].f, n[2].f ); + break; + case OPCODE_EVALMESH1: + _gamma_EvalMesh1( n[1].e, n[2].i, n[3].i ); + break; + case OPCODE_EVALMESH2: + _gamma_EvalMesh2( n[1].e, n[2].i, n[3].i, n[4].i, n[5].i ); + break; + case OPCODE_EVALPOINT1: + _gamma_EvalPoint1( n[1].i ); + break; + case OPCODE_EVALPOINT2: + _gamma_EvalPoint2( n[1].i, n[2].i ); + break; + case OPCODE_FOG: + { + GLfloat p[4]; + p[0] = n[2].f; + p[1] = n[3].f; + p[2] = n[4].f; + p[3] = n[5].f; + _gamma_Fogfv( n[1].e, p ); + } + break; + case OPCODE_FRONT_FACE: + _gamma_FrontFace( n[1].e ); + break; + case OPCODE_FRUSTUM: + _gamma_Frustum( n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f ); + break; + case OPCODE_HINT: + _gamma_Hint( n[1].e, n[2].e ); + break; + case OPCODE_INDEX_MASK: + _gamma_IndexMask( n[1].ui ); + break; + case OPCODE_INIT_NAMES: + _gamma_InitNames( ); + break; + case OPCODE_LIGHT: + { + GLfloat p[4]; + p[0] = n[3].f; + p[1] = n[4].f; + p[2] = n[5].f; + p[3] = n[6].f; + _gamma_Lightfv( n[1].e, n[2].e, p ); + } + break; + case OPCODE_LIGHT_MODEL: + { + GLfloat p[4]; + p[0] = n[2].f; + p[1] = n[3].f; + p[2] = n[4].f; + p[3] = n[5].f; + _gamma_LightModelfv( n[1].e, p ); + } + break; + case OPCODE_LINE_STIPPLE: + _gamma_LineStipple( n[1].i, n[2].us ); + break; + case OPCODE_LINE_WIDTH: + _gamma_LineWidth( n[1].f ); + break; + case OPCODE_LIST_BASE: + _gamma_ListBase( n[1].ui ); + break; + case OPCODE_LOAD_IDENTITY: + _gamma_LoadIdentity( ); + break; + case OPCODE_LOAD_MATRIX: + if (sizeof(Node)==sizeof(GLfloat)) { + _gamma_LoadMatrixf( &n[1].f ); + } + else { + GLfloat m[16]; + GLuint i; + for (i=0;i<16;i++) { + m[i] = n[1+i].f; + } + _gamma_LoadMatrixf( m ); + } + break; + case OPCODE_LOAD_NAME: + _gamma_LoadName( n[1].ui ); + break; + case OPCODE_LOGIC_OP: + _gamma_LogicOp( n[1].e ); + break; + case OPCODE_MAP1: + _gamma_Map1f( n[1].e, n[2].f, n[3].f, + n[4].i, n[5].i, (GLfloat *) n[6].data ); + break; + case OPCODE_MAP2: + _gamma_Map2f( n[1].e, + n[2].f, n[3].f, /* u1, u2 */ + n[6].i, n[8].i, /* ustride, uorder */ + n[4].f, n[5].f, /* v1, v2 */ + n[7].i, n[9].i, /* vstride, vorder */ + (GLfloat *) n[10].data); + break; + case OPCODE_MAPGRID1: + _gamma_MapGrid1f( n[1].i, n[2].f, n[3].f ); + break; + case OPCODE_MAPGRID2: + _gamma_MapGrid2f( n[1].i, n[2].f, n[3].f, n[4].i, n[5].f, n[6].f); + break; + case OPCODE_MATERIAL: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + _gamma_Materialfv( n[1].e, n[2].e, params ); + } + break; + case OPCODE_MATRIX_MODE: + _gamma_MatrixMode( n[1].e ); + break; + case OPCODE_MULT_MATRIX: + if (sizeof(Node)==sizeof(GLfloat)) { + _gamma_MultMatrixf( &n[1].f ); + } + else { + GLfloat m[16]; + GLuint i; + for (i=0;i<16;i++) { + m[i] = n[1+i].f; + } + _gamma_MultMatrixf( m ); + } + break; + case OPCODE_ORTHO: + _gamma_Ortho( n[1].f, n[2].f, n[3].f, n[4].f, n[5].f, n[6].f ); + break; + case OPCODE_PASSTHROUGH: + _gamma_PassThrough( n[1].f ); + break; + case OPCODE_PIXEL_MAP: + _gamma_PixelMapfv( n[1].e, n[2].i, (GLfloat *) n[3].data ); + break; + case OPCODE_PIXEL_TRANSFER: + _gamma_PixelTransferf( n[1].e, n[2].f ); + break; + case OPCODE_PIXEL_ZOOM: + _gamma_PixelZoom( n[1].f, n[2].f ); + break; + case OPCODE_POINT_SIZE: + _gamma_PointSize( n[1].f ); + break; + case OPCODE_POLYGON_MODE: + _gamma_PolygonMode( n[1].e, n[2].e ); + break; + case OPCODE_POLYGON_STIPPLE: + _gamma_PolygonStipple( (GLubyte *) n[1].data ); + break; + case OPCODE_POLYGON_OFFSET: + _gamma_PolygonOffset( n[1].f, n[2].f ); + break; + case OPCODE_POP_ATTRIB: + _gamma_PopAttrib( ); + break; + case OPCODE_POP_MATRIX: + _gamma_PopMatrix( ); + break; + case OPCODE_POP_NAME: + _gamma_PopName( ); + break; + case OPCODE_PRIORITIZE_TEXTURE: + _gamma_PrioritizeTextures( 1, &n[1].ui, &n[2].f ); + break; + case OPCODE_PUSH_ATTRIB: + _gamma_PushAttrib( n[1].bf ); + break; + case OPCODE_PUSH_MATRIX: + _gamma_PushMatrix( ); + break; + case OPCODE_PUSH_NAME: + _gamma_PushName( n[1].ui ); + break; + case OPCODE_RASTER_POS: + _gamma_RasterPos4f( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_READ_BUFFER: + _gamma_ReadBuffer( n[1].e ); + break; + case OPCODE_RECTF: + _gamma_Rectf( n[1].f, n[2].f, n[3].f, n[4].f ); + break; + case OPCODE_SCALE: + _gamma_Scalef( n[1].f, n[2].f, n[3].f ); + break; + case OPCODE_SCISSOR: + _gamma_Scissor( n[1].i, n[2].i, n[3].i, n[4].i ); + break; + case OPCODE_SHADE_MODEL: + _gamma_ShadeModel( n[1].e ); + break; + case OPCODE_STENCIL_FUNC: + _gamma_StencilFunc( n[1].e, n[2].i, n[3].ui ); + break; + case OPCODE_STENCIL_MASK: + _gamma_StencilMask( n[1].ui ); + break; + case OPCODE_STENCIL_OP: + _gamma_StencilOp( n[1].e, n[2].e, n[3].e ); + break; + case OPCODE_TEXENV: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + _gamma_TexEnvfv( n[1].e, n[2].e, params ); + } + break; + case OPCODE_TEXGEN: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + _gamma_TexGenfv( n[1].e, n[2].e, params ); + } + break; + case OPCODE_TEXPARAMETER: + { + GLfloat params[4]; + params[0] = n[3].f; + params[1] = n[4].f; + params[2] = n[5].f; + params[3] = n[6].f; + _gamma_TexParameterfv( n[1].e, n[2].e, params ); + } + break; + case OPCODE_TEX_IMAGE1D: + { + struct gl_pixelstore_attrib save = gCCPriv->Unpack; + gCCPriv->Unpack = _mesa_native_packing; + _gamma_TexImage1D( n[1].e, /* target */ + n[2].i, /* level */ + n[3].i, /* components */ + n[4].i, /* width */ + n[5].e, /* border */ + n[6].e, /* format */ + n[7].e, /* type */ + n[8].data ); + gCCPriv->Unpack = save; /* restore */ + } + break; + case OPCODE_TEX_IMAGE2D: + { + struct gl_pixelstore_attrib save = gCCPriv->Unpack; + gCCPriv->Unpack = _mesa_native_packing; + _gamma_TexImage2D( n[1].e, /* target */ + n[2].i, /* level */ + n[3].i, /* components */ + n[4].i, /* width */ + n[5].i, /* height */ + n[6].e, /* border */ + n[7].e, /* format */ + n[8].e, /* type */ + n[9].data ); + gCCPriv->Unpack = save; /* restore */ + } + break; + case OPCODE_TEX_SUB_IMAGE1D: + { + struct gl_pixelstore_attrib save = gCCPriv->Unpack; + gCCPriv->Unpack = _mesa_native_packing; + _gamma_TexSubImage1D( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].e, + n[6].e, n[7].data ); + gCCPriv->Unpack = save; /* restore */ + } + break; + case OPCODE_TEX_SUB_IMAGE2D: + { + struct gl_pixelstore_attrib save = gCCPriv->Unpack; + gCCPriv->Unpack = _mesa_native_packing; + _gamma_TexSubImage2D( n[1].e, n[2].i, n[3].i, + n[4].i, n[5].e, + n[6].i, n[7].e, n[8].e, n[9].data ); + gCCPriv->Unpack = save; /* restore */ + } + break; + case OPCODE_TRANSLATE: + _gamma_Translatef( n[1].f, n[2].f, n[3].f ); + break; + case OPCODE_VIEWPORT: + _gamma_Viewport( n[1].i, n[2].i, (GLsizei) n[3].i, (GLsizei) n[4].i ); + break; + case OPCODE_CONTINUE: + n = (Node *) n[1].next; + break; + case OPCODE_END_OF_LIST: + done = GL_TRUE; + break; + default: + { + char msg[1000]; + sprintf(msg, "Error in execute_list: opcode=%d", (int) opcode); +#if 0 + gl_problem( msg ); +#endif + } + done = GL_TRUE; + } + + /* increment n to point to next compiled command */ + if (opcode!=OPCODE_CONTINUE) { + n += InstSize[opcode]; + } + + } + gCCPriv->CallDepth--; +} + + + +/**********************************************************************/ +/* GL functions */ +/**********************************************************************/ + + + +/* + * Test if a display list number is valid. + */ +GLboolean _gamma_IsList( GLuint list ) +{ + if (list > 0 && _mesa_HashLookup(gCCPriv->DisplayList, list)) { + return GL_TRUE; + } + else { + return GL_FALSE; + } +} + + + +/* + * Delete a sequence of consecutive display lists. + */ +void _gamma_DeleteLists( GLuint list, GLsizei range ) +{ + GLuint i; + +#if 0 + if (INSIDE_BEGIN_END(ctx)) { + gamma_error( GL_INVALID_OPERATION, "glDeleteLists" ); + return; + } +#endif + if (range<0) { + gamma_error( GL_INVALID_VALUE, "glDeleteLists" ); + return; + } + for (i=list;i<list+range;i++) { + gamma_destroy_list( i ); + } +} + + + +/* + * Return a display list number, n, such that lists n through n+range-1 + * are free. + */ +GLuint _gamma_GenLists( GLsizei range ) +{ + GLuint base; + +#if 0 + if (INSIDE_BEGIN_END(ctx)) { + gamma_error( GL_INVALID_OPERATION, "glGenLists" ); + return 0; + } +#endif + if (range<0) { + gamma_error( GL_INVALID_VALUE, "glGenLists" ); + return 0; + } + if (range==0) { + return 0; + } + + base = _mesa_HashFindFreeKeyBlock(gCCPriv->DisplayList, range); + if (base) { + /* reserve the list IDs by with empty/dummy lists */ + GLint i; + for (i=0; i<range; i++) { + _mesa_HashInsert(gCCPriv->DisplayList, base+i, make_empty_list()); + } + } + return base; +} + + + +/* + * Begin a new display list. + */ +void _gamma_NewList( GLuint list, GLenum mode ) +{ +#if 0 + if (INSIDE_BEGIN_END(ctx)) { + gamma_error( GL_INVALID_OPERATION, "glNewList" ); + return; + } +#endif + if (list==0) { + gamma_error( GL_INVALID_VALUE, "glNewList" ); + return; + } + if (mode!=GL_COMPILE && mode!=GL_COMPILE_AND_EXECUTE) { + gamma_error( GL_INVALID_ENUM, "glNewList" ); + return; + } + if (gCCPriv->CurrentListPtr) { + /* already compiling a display list */ + gamma_error( GL_INVALID_OPERATION, "glNewList" ); + return; + } + + /* Allocate new display list */ + gCCPriv->CurrentListNum = list; + gCCPriv->CurrentListPtr = gCCPriv->CurrentBlock = (Node *) malloc( sizeof(Node) * BLOCK_SIZE ); + gCCPriv->CurrentPos = 0; + + gCCPriv->CompileFlag = GL_TRUE; + if (mode==GL_COMPILE) { + gCCPriv->ExecuteFlag = GL_FALSE; + } + else { + /* Compile and execute */ + gCCPriv->ExecuteFlag = GL_TRUE; + } + + _glapi_set_dispatch(gCCPriv->Save); + gCCPriv->API = gCCPriv->Save; /* Switch the API function pointers */ +} + + + +/* + * End definition of current display list. + */ +void _gamma_EndList( void ) +{ + /* Check that a list is under construction */ + if (!gCCPriv->CurrentListPtr) { + gamma_error( GL_INVALID_OPERATION, "glEndList" ); + return; + } + + (void) alloc_instruction( OPCODE_END_OF_LIST, 0 ); + + /* Destroy old list, if any */ + gamma_destroy_list(gCCPriv->CurrentListNum); + /* Install the list */ + _mesa_HashInsert(gCCPriv->DisplayList, gCCPriv->CurrentListNum, gCCPriv->CurrentListPtr); + + gCCPriv->CurrentListNum = 0; + gCCPriv->CurrentListPtr = NULL; + gCCPriv->ExecuteFlag = GL_TRUE; + gCCPriv->CompileFlag = GL_FALSE; + + _glapi_set_dispatch(gCCPriv->Exec); + gCCPriv->API = gCCPriv->Exec; /* Switch the API function pointers */ +} + + + +void _gamma_CallList( GLuint list ) +{ + /* VERY IMPORTANT: Save the CompileFlag status, turn it off, */ + /* execute the display list, and restore the CompileFlag. */ + GLboolean save_compile_flag; + save_compile_flag = gCCPriv->CompileFlag; + gCCPriv->CompileFlag = GL_FALSE; + execute_list( list ); + gCCPriv->CompileFlag = save_compile_flag; + + /* also restore API function pointers to point to "save" versions */ + if (save_compile_flag) { + _glapi_set_dispatch(gCCPriv->Save); + gCCPriv->API = gCCPriv->Save; + } +} + + + +/* + * Execute glCallLists: call multiple display lists. + */ +void _gamma_CallLists( + GLsizei n, GLenum type, const GLvoid *lists ) +{ + GLuint list; + GLint i; + GLboolean save_compile_flag; + + /* Save the CompileFlag status, turn it off, execute display list, + * and restore the CompileFlag. + */ + save_compile_flag = gCCPriv->CompileFlag; + gCCPriv->CompileFlag = GL_FALSE; + + for (i=0;i<n;i++) { + list = translate_id( i, type, lists ); + execute_list( gCCPriv->List.ListBase + list ); + } + + gCCPriv->CompileFlag = save_compile_flag; + + /* also restore API function pointers to point to "save" versions */ + if (save_compile_flag) { + _glapi_set_dispatch(gCCPriv->Save); + gCCPriv->API = gCCPriv->Save; + } +} + + + +/* + * Set the offset added to list numbers in glCallLists. + */ +void _gamma_ListBase( GLuint base ) +{ +#if 0 + if (INSIDE_BEGIN_END(ctx)) { + gamma_error( GL_INVALID_OPERATION, "glListBase" ); + return; + } +#endif + gCCPriv->List.ListBase = base; +} diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_dlist.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_dlist.h new file mode 100644 index 000000000..a8523da2d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_dlist.h @@ -0,0 +1,381 @@ +/* + * Mesa 3-D graphics library + * Version: 3.0 + * Copyright (C) 1995-1998 Brian Paul + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Library General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Library General Public License for more details. + * + * You should have received a copy of the GNU Library General Public + * License along with this library; if not, write to the Free + * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_dlist.h,v 1.3 2001/02/12 01:11:25 tsi Exp $ */ + + +#ifndef DLIST_H +#define DLIST_H + +#include "types.h" + +extern void gamma_init_lists( void ); + +extern void gamma_destroy_list( GLuint list ); + + + +extern void gl_CallList( GLuint list ); + +extern void gl_CallLists( + GLsizei n, GLenum type, const GLvoid *lists ); + +extern void gl_DeleteLists( GLuint list, GLsizei range ); + +extern void gl_EndList( void ); + +extern GLuint gl_GenLists( GLsizei range ); + +extern GLboolean gl_IsList( GLuint list ); + +extern void gl_ListBase( GLuint base ); + +extern void gl_NewList( GLuint list, GLenum mode ); + +extern void gl_save_Accum( GLenum op, GLfloat value ); + +extern void gl_save_AlphaFunc( GLenum func, GLclampf ref ); + +extern void gl_save_ArrayElement( GLint i ); + +extern void gl_save_BlendFunc( + GLenum sfactor, GLenum dfactor ); + +extern void gl_save_Begin( GLenum mode ); + +extern void gl_save_BindTexture( + GLenum target, GLuint texture ); + +extern void gl_save_Bitmap( GLsizei width, GLsizei height, + GLfloat xorig, GLfloat yorig, + GLfloat xmove, GLfloat ymove, + const GLubyte *bitmap ); + +extern void gl_save_CallList( GLuint list ); + +extern void gl_save_CallLists( + GLsizei n, GLenum type, const GLvoid *lists ); + +extern void gl_save_Clear( GLbitfield mask ); + +extern void gl_save_ClearAccum( GLfloat red, GLfloat green, + GLfloat blue, GLfloat alpha ); + +extern void gl_save_ClearColor( GLclampf red, GLclampf green, + GLclampf blue, GLclampf alpha ); + +extern void gl_save_ClearDepth( GLclampd depth ); + +extern void gl_save_ClearIndex( GLfloat c ); + +extern void gl_save_ClearStencil( GLint s ); + +extern void gl_save_ClipPlane( + GLenum plane, const GLdouble *equ ); + +extern void gl_save_Color3f( GLfloat r, GLfloat g, GLfloat b ); + +extern void gl_save_Color3fv( const GLfloat *c ); + +extern void gl_save_Color4f( GLfloat r, GLfloat g, + GLfloat b, GLfloat a ); + +extern void gl_save_Color4fv( const GLfloat *c ); + +extern void gl_save_Color4ub( GLubyte r, GLubyte g, + GLubyte b, GLubyte a ); + +extern void gl_save_Color4ubv( const GLubyte *c ); + +extern void gl_save_ColorMask( GLboolean red, GLboolean green, + GLboolean blue, GLboolean alpha ); + +extern void gl_save_ColorMaterial( GLenum face, GLenum mode ); + +extern void gl_save_CopyPixels( GLint x, GLint y, + GLsizei width, GLsizei height, GLenum type ); + +extern void gl_save_CopyTexImage1D( + GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, GLsizei width, + GLint border ); + +extern void gl_save_CopyTexImage2D( + GLenum target, GLint level, + GLenum internalformat, + GLint x, GLint y, GLsizei width, + GLsizei height, GLint border ); + +extern void gl_save_CopyTexSubImage1D( + GLenum target, GLint level, + GLint xoffset, GLint x, GLint y, + GLsizei width ); + +extern void gl_save_CopyTexSubImage2D( + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLint x, GLint y, + GLsizei width, GLint height ); + +extern void gl_save_CullFace( GLenum mode ); + +extern void gl_save_DepthFunc( GLenum func ); + +extern void gl_save_DepthMask( GLboolean mask ); + +extern void gl_save_DepthRange( + GLclampd nearval, GLclampd farval ); + +extern void gl_save_Disable( GLenum cap ); + +extern void gl_save_DrawArrays( + GLenum mode, GLint first, GLsizei count ); + +extern void gl_save_DrawBuffer( GLenum mode ); + +extern void gl_save_DrawElements( + GLenum mode, GLsizei count, + GLenum type, const GLvoid *indices ); + +extern void gl_save_DrawPixels( GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + +extern void gl_save_EdgeFlag( GLboolean flag ); + +extern void gl_save_Enable( GLenum cap ); + +extern void gl_save_End( void ); + +extern void gl_save_EvalCoord1f( GLfloat u ); + +extern void gl_save_EvalCoord2f( GLfloat u, GLfloat v ); + +extern void gl_save_EvalMesh1( + GLenum mode, GLint i1, GLint i2 ); + +extern void gl_save_EvalMesh2( GLenum mode, GLint i1, GLint i2, + GLint j1, GLint j2 ); + +extern void gl_save_EvalPoint1( GLint i ); + +extern void gl_save_EvalPoint2( GLint i, GLint j ); + +extern void gl_save_Fogfv( + GLenum pname, const GLfloat *params ); + +extern void gl_save_FrontFace( GLenum mode ); + +extern void gl_save_Frustum( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ); + +extern void gl_save_Hint( GLenum target, GLenum mode ); + +extern void gl_save_Indexf( GLfloat index ); + +extern void gl_save_Indexi( GLint index ); + +extern void gl_save_IndexMask( GLuint mask ); + +extern void gl_save_InitNames( void ); + +extern void gl_save_Lightfv( GLenum light, GLenum pname, + const GLfloat *params ); + +extern void gl_save_LightModelfv( GLenum pname, + const GLfloat *params ); + +extern void gl_save_LineWidth( GLfloat width ); + +extern void gl_save_LineStipple( GLint factor, + GLushort pattern ); + +extern void gl_save_ListBase( GLuint base ); + +extern void gl_save_LoadIdentity( void ); + +extern void gl_save_LoadMatrixf( const GLfloat *m ); + +extern void gl_save_LoadName( GLuint name ); + +extern void gl_save_LogicOp( GLenum opcode ); + +extern void gl_save_Map1f( GLenum target, + GLfloat u1, GLfloat u2, GLint stride, + GLint order, const GLfloat *points); + +extern void gl_save_Map2f( GLenum target, + GLfloat u1, GLfloat u2, GLint ustride, GLint uorder, + GLfloat v1, GLfloat v2, GLint vstride, GLint vorder, + const GLfloat *points); + +extern void gl_save_MapGrid1f( GLint un, + GLfloat u1, GLfloat u2 ); + +extern void gl_save_MapGrid2f( + GLint un, GLfloat u1, GLfloat u2, + GLint vn, GLfloat v1, GLfloat v2 ); + +extern void gl_save_Materialfv( GLenum face, GLenum pname, + const GLfloat *params ); + +extern void gl_save_MatrixMode( GLenum mode ); + +extern void gl_save_MultMatrixf( const GLfloat *m ); + +extern void gl_save_NewList( GLuint list, GLenum mode ); + +extern void gl_save_Normal3fv( const GLfloat n[3] ); + +extern void gl_save_Normal3f( + GLfloat nx, GLfloat ny, GLfloat nz ); + +extern void gl_save_Ortho( GLdouble left, GLdouble right, + GLdouble bottom, GLdouble top, + GLdouble nearval, GLdouble farval ); + +extern void gl_save_PassThrough( GLfloat token ); + +extern void gl_save_PixelMapfv( GLenum map, GLint mapsize, + const GLfloat *values ); + +extern void gl_save_PixelTransferf( + GLenum pname, GLfloat param ); + +extern void gl_save_PixelZoom( + GLfloat xfactor, GLfloat yfactor ); + +extern void gl_save_PointParameterfvEXT( GLenum pname, + const GLfloat *params ); + +extern void gl_save_PointSize( GLfloat size ); + +extern void gl_save_PolygonMode( GLenum face, GLenum mode ); + +extern void gl_save_PolygonStipple( const GLubyte *pattern ); + +extern void gl_save_PolygonOffset( + GLfloat factor, GLfloat units ); + +extern void gl_save_PopAttrib( void ); + +extern void gl_save_PopMatrix( void ); + +extern void gl_save_PopName( void ); + +extern void gl_save_PrioritizeTextures( + GLsizei n, const GLuint *textures, + const GLclampf *priorities ); + +extern void gl_save_PushAttrib( GLbitfield mask ); + +extern void gl_save_PushMatrix( void ); + +extern void gl_save_PushName( GLuint name ); + +extern void gl_save_RasterPos4f( + GLfloat x, GLfloat y, GLfloat z, GLfloat w ); + +extern void gl_save_ReadBuffer( GLenum mode ); + +extern void gl_save_Rectf( + GLfloat x1, GLfloat y1, GLfloat x2, GLfloat y2 ); + +extern void gl_save_Rotatef( GLfloat angle, + GLfloat x, GLfloat y, GLfloat z ); + +extern void gl_save_Scalef( GLfloat x, GLfloat y, GLfloat z ); + +extern void gl_save_Scissor( + GLint x, GLint y, GLsizei width, GLsizei height ); + +extern void gl_save_ShadeModel( GLenum mode ); + +extern void gl_save_StencilFunc( + GLenum func, GLint ref, GLuint mask ); + +extern void gl_save_StencilMask( GLuint mask ); + +extern void gl_save_StencilOp( + GLenum fail, GLenum zfail, GLenum zpass ); + +extern void gl_save_TexCoord2f( GLfloat s, GLfloat t ); + +extern void gl_save_TexCoord2fv( const GLfloat *v ); + +extern void gl_save_TexCoord3fv( const GLfloat *v ); + +extern void gl_save_TexCoord4f( GLfloat s, GLfloat t, + GLfloat r, GLfloat q ); + +extern void gl_save_TexEnvfv( GLenum target, GLenum pname, + const GLfloat *params ); + +extern void gl_save_TexParameterfv( GLenum target, + GLenum pname, const GLfloat *params ); + +extern void gl_save_TexGenfv( GLenum coord, GLenum pname, + const GLfloat *params ); + +extern void gl_save_TexImage1D( GLenum target, + GLint level, GLint components, + GLsizei width, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +extern void gl_save_TexImage2D( GLenum target, + GLint level, GLint components, + GLsizei width, GLsizei height, GLint border, + GLenum format, GLenum type, + const GLvoid *pixels ); + +extern void gl_save_TexSubImage1D( + GLenum target, GLint level, + GLint xoffset, GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels ); + + +extern void gl_save_TexSubImage2D( + GLenum target, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels ); + +extern void gl_save_Translatef( + GLfloat x, GLfloat y, GLfloat z ); + +extern void gl_save_Vertex2f( + GLfloat x, GLfloat y ); + +extern void gl_save_Vertex3f( + GLfloat x, GLfloat y, GLfloat z ); + +extern void gl_save_Vertex4f( + GLfloat x, GLfloat y, GLfloat z, GLfloat w ); + +extern void gl_save_Vertex3fv( const GLfloat *v ); + +extern void gl_save_Viewport( GLint x, GLint y, + GLsizei width, GLsizei height ); + +#endif diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c index 930039fa4..d859e5d50 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c,v 1.7 2000/11/27 10:59:36 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_gl.c,v 1.9 2001/02/07 13:26:16 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -39,14 +39,89 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include <math.h> #include "gamma_gl.h" #include "gamma_init.h" +#include "gamma_dlist.h" #include "glint_dri.h" -#ifdef RANDOMIZE_COLORS -#include <stdlib.h> + +/* Here for now, will change get.c to move them into macros.h later */ + +#define FLOAT_TO_BOOL(X) ( (X)==0.0F ? GL_FALSE : GL_TRUE ) +#define INT_TO_BOOL(I) ( (I)==0 ? GL_FALSE : GL_TRUE ) +#define ENUM_TO_BOOL(E) ( (E)==0 ? GL_FALSE : GL_TRUE ) + +void gamma_error( GLenum error, const char *s ) +{ + GLboolean debug; + +#ifdef DEBUG + debug = GL_TRUE; +#else + if (getenv("MESA_DEBUG")) { + debug = GL_TRUE; + } + else { + debug = GL_FALSE; + } #endif + if (debug) { + char errstr[1000]; + + switch (error) { + case GL_NO_ERROR: + strcpy( errstr, "GL_NO_ERROR" ); + break; + case GL_INVALID_VALUE: + strcpy( errstr, "GL_INVALID_VALUE" ); + break; + case GL_INVALID_ENUM: + strcpy( errstr, "GL_INVALID_ENUM" ); + break; + case GL_INVALID_OPERATION: + strcpy( errstr, "GL_INVALID_OPERATION" ); + break; + case GL_STACK_OVERFLOW: + strcpy( errstr, "GL_STACK_OVERFLOW" ); + break; + case GL_STACK_UNDERFLOW: + strcpy( errstr, "GL_STACK_UNDERFLOW" ); + break; + case GL_OUT_OF_MEMORY: + strcpy( errstr, "GL_OUT_OF_MEMORY" ); + break; + default: + strcpy( errstr, "unknown" ); + break; + } + fprintf( stderr, "Mesa user error: %s in %s\n", errstr, s ); + } + + if (gCCPriv->ErrorValue==GL_NO_ERROR) { + gCCPriv->ErrorValue = error; + } + + /* _gamma_Error( ); use hwLog or something later */ +} + + void _gamma_Accum(GLenum op, GLfloat value) { DEBUG_GLCMDS(("Accum: %d %f\n", (int)op, value)); + + switch (op) { + case GL_ACCUM: + break; + case GL_LOAD: + break; + case GL_ADD: + break; + case GL_MULT: + break; + case GL_RETURN: + break; + default: + gCCPriv->ErrorValue = GL_INVALID_ENUM; + return; + } } void _gamma_AlphaFunc(GLenum func, GLclampf ref) @@ -350,6 +425,7 @@ void _gamma_BlendFunc(GLenum sfactor, GLenum dfactor) } } +#if 0 /* Now in dlist.c */ void _gamma_CallList(GLuint list) { DEBUG_GLCMDS(("CallList: %d\n", (unsigned int)list)); @@ -359,6 +435,7 @@ void _gamma_CallLists(GLsizei n, GLenum type, const GLvoid *lists) { DEBUG_GLCMDS(("CallLists: %d %04x\n", (int)n, (int)type)); } +#endif void _gamma_Clear(GLbitfield mask) { @@ -445,7 +522,7 @@ void _gamma_Clear(GLbitfield mask) temp = (gCCPriv->LBReadMode & LBPartialProdMask) | LBWindowOriginBot; /* UGH - move this later ! */ - if (gDRIPriv->numMXDevices == 2) temp |= LBScanLineInt2; + if (gDRIPriv->numMultiDevices == 2) temp |= LBScanLineInt2; CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, LBReadMode, temp); @@ -634,28 +711,16 @@ void _gamma_ClipPlane(GLenum plane, const GLdouble *equation) void _gamma_Color3b(GLbyte red, GLbyte green, GLbyte blue) { - GLfloat r,g,b; - DEBUG_GLCMDS(("Color3b: %d %d %d\n", red, green, blue)); - r = BYTE_TO_FLOAT(red); - g = BYTE_TO_FLOAT(green); - b = BYTE_TO_FLOAT(blue); - - _gamma_Color3f(r,g,b); + _gamma_Color3f((GLfloat)red,(GLfloat)green,(GLfloat)blue); } void _gamma_Color3bv(const GLbyte *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Color3bv: %d %d %d\n", v[0], v[1], v[2])); - p[0] = BYTE_TO_FLOAT(v[0]); - p[1] = BYTE_TO_FLOAT(v[1]); - p[2] = BYTE_TO_FLOAT(v[2]); - - _gamma_Color3f(p[0],p[1],p[2]); + _gamma_Color3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); } void _gamma_Color3d(GLdouble red, GLdouble green, GLdouble blue) @@ -669,13 +734,18 @@ void _gamma_Color3dv(const GLdouble *v) { DEBUG_GLCMDS(("Color3dv: %f %f %f\n", v[0], v[1], v[2])); - _gamma_Color3fv((GLfloat*)v); + _gamma_Color3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); } void _gamma_Color3f(GLfloat red, GLfloat green, GLfloat blue) { DEBUG_GLCMDS(("Color3f: %f %f %f\n", red, green, blue)); + gCCPriv->Current.Color[0] = red; + gCCPriv->Current.Color[1] = green; + gCCPriv->Current.Color[2] = blue; + gCCPriv->Current.Color[3] = 1.0f; + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); WRITEF(gCCPriv->buf, Cb, blue); WRITEF(gCCPriv->buf, Cg, green); @@ -686,62 +756,35 @@ void _gamma_Color3fv(const GLfloat *v) { DEBUG_GLCMDS(("Color3fv: %f %f %f\n", v[0], v[1], v[2])); - CHECK_DMA_BUFFER(gCC, gCCPriv, 3); - WRITEF(gCCPriv->buf, Cb, v[2]); - WRITEF(gCCPriv->buf, Cg, v[1]); - WRITEF(gCCPriv->buf, Cr3, v[0]); + _gamma_Color3f(v[0],v[1],v[2]); } void _gamma_Color3i(GLint red, GLint green, GLint blue) { - GLfloat r,g,b; - DEBUG_GLCMDS(("Color3i: %d %d %d\n", (int)red, (int)green, (int)blue)); - r = INT_TO_FLOAT(red); - g = INT_TO_FLOAT(green); - b = INT_TO_FLOAT(blue); - - _gamma_Color3f(r,g,b); + _gamma_Color3f((GLfloat)red,(GLfloat)green,(GLfloat)blue); } void _gamma_Color3iv(const GLint *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Color3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2])); - p[0] = INT_TO_FLOAT(v[0]); - p[1] = INT_TO_FLOAT(v[1]); - p[2] = INT_TO_FLOAT(v[2]); - - _gamma_Color3f(p[0],p[1],p[2]); + _gamma_Color3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); } void _gamma_Color3s(GLshort red, GLshort green, GLshort blue) { - GLfloat r,g,b; - DEBUG_GLCMDS(("Color3s: %d %d %d\n", red, green, blue)); - r = SHORT_TO_FLOAT(red); - g = SHORT_TO_FLOAT(green); - b = SHORT_TO_FLOAT(blue); - - _gamma_Color3f(r,g,b); + _gamma_Color3f((GLfloat)red,(GLfloat)green,(GLfloat)blue); } void _gamma_Color3sv(const GLshort *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Color3sv: %d %d %d\n", v[0], v[1], v[2])); - p[0] = SHORT_TO_FLOAT(v[0]); - p[1] = SHORT_TO_FLOAT(v[1]); - p[2] = SHORT_TO_FLOAT(v[2]); - - _gamma_Color3f(p[0],p[1],p[2]); + _gamma_Color3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); } void _gamma_Color3ub(GLubyte red, GLubyte green, GLubyte blue) @@ -770,56 +813,32 @@ void _gamma_Color3ubv(const GLubyte *v) void _gamma_Color3ui(GLuint red, GLuint green, GLuint blue) { - GLfloat r,g,b; - DEBUG_GLCMDS(("Color3ui: %d %d %d\n", (unsigned int)red, (unsigned int)green, (unsigned int)blue)); - r = UINT_TO_FLOAT(red); - g = UINT_TO_FLOAT(green); - b = UINT_TO_FLOAT(blue); - - _gamma_Color3f(r,g,b); + _gamma_Color3f((GLfloat)red,(GLfloat)green,(GLfloat)blue); } void _gamma_Color3uiv(const GLuint *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Color3uiv: %d %d %d\n", (unsigned int)v[0], (unsigned int)v[1], (unsigned int)v[2])); - p[0] = UINT_TO_FLOAT(v[0]); - p[1] = UINT_TO_FLOAT(v[1]); - p[2] = UINT_TO_FLOAT(v[2]); - - _gamma_Color3f(p[0],p[1],p[2]); + _gamma_Color3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); } void _gamma_Color3us(GLushort red, GLushort green, GLushort blue) { - GLfloat r,g,b; - DEBUG_GLCMDS(("Color3us: %d %d %d\n", red, green, blue)); - r = USHORT_TO_FLOAT(red); - g = USHORT_TO_FLOAT(green); - b = USHORT_TO_FLOAT(blue); - - _gamma_Color3f(r,g,b); + _gamma_Color3f((GLfloat)red,(GLfloat)green,(GLfloat)blue); } void _gamma_Color3usv(const GLushort *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Color3usv: %d %d %d\n", v[0], v[1], v[2])); - p[0] = USHORT_TO_FLOAT(v[0]); - p[1] = USHORT_TO_FLOAT(v[1]); - p[2] = USHORT_TO_FLOAT(v[2]); - - _gamma_Color3f(p[0],p[1],p[2]); + _gamma_Color3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); } void _gamma_Color4b(GLbyte red, GLbyte green, GLbyte blue, GLbyte alpha) @@ -847,7 +866,7 @@ void _gamma_Color4bv(const GLbyte *v) p[2] = BYTE_TO_FLOAT(v[2]); p[3] = BYTE_TO_FLOAT(v[3]); - _gamma_Color4f(p[0],p[1],p[2],p[3]); + _gamma_Color4fv(p); } void _gamma_Color4d(GLdouble red, GLdouble green, GLdouble blue, GLdouble alpha) @@ -861,13 +880,18 @@ void _gamma_Color4dv(const GLdouble *v) { DEBUG_GLCMDS(("Color4dv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); - _gamma_Color4fv((GLfloat*)v); + _gamma_Color4f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2],(GLfloat)v[3]); } void _gamma_Color4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha) { DEBUG_GLCMDS(("Color4f: %f %f %f %f\n", red, green, blue, alpha)); + gCCPriv->Current.Color[0] = red; + gCCPriv->Current.Color[1] = green; + gCCPriv->Current.Color[2] = blue; + gCCPriv->Current.Color[3] = alpha; + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); WRITEF(gCCPriv->buf, Ca, alpha); WRITEF(gCCPriv->buf, Cb, blue); @@ -879,6 +903,11 @@ void _gamma_Color4fv(const GLfloat *v) { DEBUG_GLCMDS(("Color4fv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); + gCCPriv->Current.Color[0] = v[0]; + gCCPriv->Current.Color[1] = v[1]; + gCCPriv->Current.Color[2] = v[2]; + gCCPriv->Current.Color[3] = v[3]; + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); WRITEF(gCCPriv->buf, Ca, v[3]); WRITEF(gCCPriv->buf, Cb, v[2]); @@ -913,7 +942,7 @@ void _gamma_Color4iv(const GLint *v) p[2] = INT_TO_FLOAT(v[2]); p[3] = INT_TO_FLOAT(v[3]); - _gamma_Color4f(p[0],p[1],p[2],p[3]); + _gamma_Color4fv(p); } void _gamma_Color4s(GLshort red, GLshort green, GLshort blue, GLshort alpha) @@ -941,7 +970,7 @@ void _gamma_Color4sv(const GLshort *v) p[2] = SHORT_TO_FLOAT(v[2]); p[3] = SHORT_TO_FLOAT(v[3]); - _gamma_Color4f(p[0],p[1],p[2],p[3]); + _gamma_Color4fv(p); } void _gamma_Color4ub(GLubyte red, GLubyte green, GLubyte blue, GLubyte alpha) @@ -997,7 +1026,7 @@ void _gamma_Color4uiv(const GLuint *v) p[2] = UINT_TO_FLOAT(v[2]); p[3] = UINT_TO_FLOAT(v[3]); - _gamma_Color4f(p[0],p[1],p[2],p[3]); + _gamma_Color4fv(p); } void _gamma_Color4us(GLushort red, GLushort green, GLushort blue, GLushort alpha) @@ -1025,7 +1054,7 @@ void _gamma_Color4usv(const GLushort *v) p[2] = USHORT_TO_FLOAT(v[2]); p[3] = USHORT_TO_FLOAT(v[3]); - _gamma_Color4f(p[0],p[1],p[2],p[3]); + _gamma_Color4fv(p); } void _gamma_ColorMask(GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha) @@ -1037,8 +1066,7 @@ void _gamma_ColorMaterial(GLenum face, GLenum mode) { DEBUG_GLCMDS(("ColorMaterial: %04x %04x\n", (int)face, (int)mode)); - gCCPriv->MaterialMode &= ~MaterialModeEnable; - gCCPriv->ColorMaterialMode = ColorMaterialModeDisable; + gCCPriv->ColorMaterialMode &= ~ColorMaterialModeMask; switch (face) { case GL_FRONT: @@ -1070,15 +1098,56 @@ void _gamma_ColorMaterial(GLenum face, GLenum mode) break; } - CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, ColorMaterialMode, gCCPriv->ColorMaterialMode); - WRITE(gCCPriv->buf, MaterialMode, gCCPriv->MaterialMode); } void _gamma_ColorPointer(GLint size, GLenum type, GLsizei stride, const GLvoid *pointer) { DEBUG_GLCMDS(("ColorPointer: %d %04x %d\n", (int)size, (int)type, (int)stride)); + + if (size<3 || size>4) { + gamma_error( GL_INVALID_VALUE, "glColorPointer(size)" ); + return; + } + if (stride<0) { + gamma_error( GL_INVALID_VALUE, "glColorPointer(stride)" ); + return; + } + switch (type) { + case GL_BYTE: + gCCPriv->Array.ColorStrideB = stride ? stride : size*sizeof(GLbyte); + break; + case GL_UNSIGNED_BYTE: + gCCPriv->Array.ColorStrideB = stride ? stride : size*sizeof(GLubyte); + break; + case GL_SHORT: + gCCPriv->Array.ColorStrideB = stride ? stride : size*sizeof(GLshort); + break; + case GL_UNSIGNED_SHORT: + gCCPriv->Array.ColorStrideB = stride ? stride : size*sizeof(GLushort); + break; + case GL_INT: + gCCPriv->Array.ColorStrideB = stride ? stride : size*sizeof(GLint); + break; + case GL_UNSIGNED_INT: + gCCPriv->Array.ColorStrideB = stride ? stride : size*sizeof(GLuint); + break; + case GL_FLOAT: + gCCPriv->Array.ColorStrideB = stride ? stride : size*sizeof(GLfloat); + break; + case GL_DOUBLE: + gCCPriv->Array.ColorStrideB = stride ? stride : size*sizeof(GLdouble); + break; + default: + gamma_error( GL_INVALID_ENUM, "glColorPointer(type)" ); + return; + } + gCCPriv->Array.ColorSize = size; + gCCPriv->Array.ColorType = type; + gCCPriv->Array.ColorStride = stride; + gCCPriv->Array.ColorPtr = (void *) pointer; } void _gamma_CopyPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum type) @@ -1140,10 +1209,12 @@ void _gamma_CullFace(GLenum mode) WRITE(gCCPriv->buf, GeometryMode, gCCPriv->GeometryMode); } +#if 0 /* Now in dlist.c */ void _gamma_DeleteLists(GLuint list, GLsizei range) { DEBUG_GLCMDS(("DeleteLists: %d %d\n", (unsigned int)list, (int)range)); } +#endif void _gamma_DeleteTextures(GLsizei n, const GLuint *textures) { @@ -1262,7 +1333,7 @@ void _gamma_Disable(GLenum cap) gCCPriv->Window &= ~W_DepthFCP; /* Turn depth mode off */ - CHECK_DMA_BUFFER(gCC, gCCPriv, 4); + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); WRITE(gCCPriv->buf, DepthMode, gCCPriv->DepthMode); WRITE(gCCPriv->buf, DeltaMode, gCCPriv->DeltaMode); WRITE(gCCPriv->buf, LBReadModeAnd, ~LBReadDstEnable); @@ -1314,6 +1385,22 @@ void _gamma_Disable(GLenum cap) CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode); break; + case GL_LOGIC_OP: + gCCPriv->LogicalOpMode &= ~LogicalOpModeEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, LogicalOpMode, gCCPriv->LogicalOpMode); + break; + case GL_NORMALIZE: + gCCPriv->NormalizeMode &= ~NormalizeModeEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, NormalizeMode, gCCPriv->NormalizeMode); + WRITE(gCCPriv->buf, TransformModeOr, 0xc); + break; + case GL_SCISSOR_TEST: + gCCPriv->ScissorMode &= ~UserScissorEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, ScissorMode, gCCPriv->ScissorMode); + break; case GL_TEXTURE_2D: gCCPriv->Texture2DEnabled = GL_FALSE; gCCPriv->Begin &= ~B_TextureEnable; @@ -1344,6 +1431,29 @@ void _gamma_Disable(GLenum cap) void _gamma_DisableClientState(GLenum array) { DEBUG_GLCMDS(("DisableClientState: %04x\n", (int)array)); + + switch (array) { + case GL_VERTEX_ARRAY: + gCCPriv->Array.VertexEnabled = GL_FALSE; + break; + case GL_NORMAL_ARRAY: + gCCPriv->Array.NormalEnabled = GL_FALSE; + break; + case GL_COLOR_ARRAY: + gCCPriv->Array.ColorEnabled = GL_FALSE; + break; + case GL_INDEX_ARRAY: + gCCPriv->Array.IndexEnabled = GL_FALSE; + break; + case GL_TEXTURE_COORD_ARRAY: + gCCPriv->Array.TexCoordEnabled = GL_FALSE; + break; + case GL_EDGE_FLAG_ARRAY: + gCCPriv->Array.EdgeFlagEnabled = GL_FALSE; + break; + default: + gamma_error( GL_INVALID_ENUM, "glEnable/DisableClientState" ); + } } void _gamma_DrawArrays(GLenum mode, GLint first, GLsizei count) @@ -1406,7 +1516,7 @@ void _gamma_Enable(GLenum cap) #endif /* Turn depth mode on */ - CHECK_DMA_BUFFER(gCC, gCCPriv, 4); + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); WRITE(gCCPriv->buf, DepthMode, gCCPriv->DepthMode); WRITE(gCCPriv->buf, DeltaMode, gCCPriv->DeltaMode); WRITE(gCCPriv->buf, LBReadModeOr, LBReadDstEnable); @@ -1464,6 +1574,22 @@ void _gamma_Enable(GLenum cap) CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode); break; + case GL_LOGIC_OP: + gCCPriv->LogicalOpMode |= LogicalOpModeEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, LogicalOpMode, gCCPriv->LogicalOpMode); + break; + case GL_NORMALIZE: + gCCPriv->NormalizeMode |= NormalizeModeEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, NormalizeMode, gCCPriv->NormalizeMode); + WRITE(gCCPriv->buf, TransformModeAnd, 0xffffff3f); + break; + case GL_SCISSOR_TEST: + gCCPriv->ScissorMode |= UserScissorEnable; + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, ScissorMode, gCCPriv->ScissorMode); + break; case GL_TEXTURE_2D: gCCPriv->Texture2DEnabled = GL_TRUE; #ifndef TURN_OFF_TEXTURES @@ -1496,6 +1622,29 @@ void _gamma_Enable(GLenum cap) void _gamma_EnableClientState(GLenum array) { DEBUG_GLCMDS(("EnableClientState: %04x\n", (int)array)); + + switch (array) { + case GL_VERTEX_ARRAY: + gCCPriv->Array.VertexEnabled = GL_TRUE; + break; + case GL_NORMAL_ARRAY: + gCCPriv->Array.NormalEnabled = GL_TRUE; + break; + case GL_COLOR_ARRAY: + gCCPriv->Array.ColorEnabled = GL_TRUE; + break; + case GL_INDEX_ARRAY: + gCCPriv->Array.IndexEnabled = GL_TRUE; + break; + case GL_TEXTURE_COORD_ARRAY: + gCCPriv->Array.TexCoordEnabled = GL_TRUE; + break; + case GL_EDGE_FLAG_ARRAY: + gCCPriv->Array.EdgeFlagEnabled = GL_TRUE; + break; + default: + gamma_error( GL_INVALID_ENUM, "glEnable/DisableClientState" ); + } } void _gamma_End(void) @@ -1519,10 +1668,12 @@ void _gamma_End(void) #endif } +#if 0 /* Now in dlist.c */ void _gamma_EndList(void) { DEBUG_GLCMDS(("EndList\n")); } +#endif void _gamma_EvalCoord1d(GLdouble u) { @@ -1620,8 +1771,10 @@ void _gamma_Fogfv(GLenum pname, const GLfloat *params) switch (pname) { case GL_FOG_COLOR: - color = ((int)params[3]<<24) | ((int)params[2]<<16) | - ((int)params[1]<<8) | ((int)params[0]); + color = (FLOAT_TO_UBYTE(params[3])<<24) | + (FLOAT_TO_UBYTE(params[2])<<16) | + (FLOAT_TO_UBYTE(params[1])<<8) | + (FLOAT_TO_UBYTE(params[0])); CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, FogColor, color); break; @@ -1704,12 +1857,14 @@ void _gamma_Frustum(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top gammaLoadHWMatrix(); } +#if 0 /* Now in dlist.c */ GLuint _gamma_GenLists(GLsizei range) { DEBUG_GLCMDS(("GenLists: %d\n", (int)range)); return GL_TRUE; } +#endif void _gamma_GenTextures(GLsizei n, GLuint *textures) { @@ -1718,7 +1873,36 @@ void _gamma_GenTextures(GLsizei n, GLuint *textures) void _gamma_GetBooleanv(GLenum val, GLboolean *b) { + int loop; + DEBUG_GLCMDS(("GetBooleanv: %04x\n", (int)val)); + + switch (val) { + case GL_CURRENT_COLOR: + b[0] = FLOAT_TO_BOOL(gCCPriv->Current.Color[0]); + b[1] = FLOAT_TO_BOOL(gCCPriv->Current.Color[1]); + b[2] = FLOAT_TO_BOOL(gCCPriv->Current.Color[2]); + b[3] = FLOAT_TO_BOOL(gCCPriv->Current.Color[3]); + break; + case GL_CURRENT_NORMAL: + b[0] = FLOAT_TO_BOOL(gCCPriv->Current.Normal[0]); + b[1] = FLOAT_TO_BOOL(gCCPriv->Current.Normal[1]); + b[2] = FLOAT_TO_BOOL(gCCPriv->Current.Normal[2]); + break; + case GL_MAX_TEXTURE_SIZE: + *b = FLOAT_TO_BOOL(GAMMA_MAX_TEXTURE_SIZE); + break; + case GL_MODELVIEW_MATRIX: + for (loop = 0; loop < 16; loop++) + b[loop] = FLOAT_TO_BOOL(gCCPriv->ModelView[loop]); + break; + case GL_CURRENT_TEXTURE_COORDS: + b[0] = FLOAT_TO_BOOL(gCCPriv->Current.TexCoord[0]); + b[1] = FLOAT_TO_BOOL(gCCPriv->Current.TexCoord[1]); + b[2] = FLOAT_TO_BOOL(gCCPriv->Current.TexCoord[2]); + b[3] = FLOAT_TO_BOOL(gCCPriv->Current.TexCoord[3]); + break; + } } void _gamma_GetClipPlane(GLenum plane, GLdouble *equation) @@ -1729,25 +1913,75 @@ void _gamma_GetClipPlane(GLenum plane, GLdouble *equation) void _gamma_GetDoublev(GLenum val, GLdouble *d) { + int loop; + DEBUG_GLCMDS(("GetDoublev: %04x\n", (int)val)); + + switch (val) { + case GL_CURRENT_COLOR: + d[0] = (GLdouble)gCCPriv->Current.Color[0]; + d[1] = (GLdouble)gCCPriv->Current.Color[1]; + d[2] = (GLdouble)gCCPriv->Current.Color[2]; + d[3] = (GLdouble)gCCPriv->Current.Color[3]; + break; + case GL_CURRENT_NORMAL: + d[0] = (GLdouble)gCCPriv->Current.Normal[0]; + d[1] = (GLdouble)gCCPriv->Current.Normal[1]; + d[2] = (GLdouble)gCCPriv->Current.Normal[2]; + break; + case GL_MAX_TEXTURE_SIZE: + *d = (GLdouble)INT_TO_FLOAT(GAMMA_MAX_TEXTURE_SIZE); + break; + case GL_MODELVIEW_MATRIX: + for (loop = 0; loop < 16; loop++) + d[loop] = (GLdouble)gCCPriv->ModelView[loop]; + break; + case GL_CURRENT_TEXTURE_COORDS: + d[0] = (GLdouble)gCCPriv->Current.TexCoord[0]; + d[1] = (GLdouble)gCCPriv->Current.TexCoord[1]; + d[2] = (GLdouble)gCCPriv->Current.TexCoord[2]; + d[3] = (GLdouble)gCCPriv->Current.TexCoord[3]; + break; + } } GLenum _gamma_GetError(void) { DEBUG_GLCMDS(("GetError\n")); - return 0; + + return gCCPriv->ErrorValue; } void _gamma_GetFloatv(GLenum val, GLfloat *f) { - int i; + int loop; DEBUG_GLCMDS(("GetFloatv: %04x\n", (int)val)); switch (val) { + case GL_CURRENT_COLOR: + f[0] = gCCPriv->Current.Color[0]; + f[1] = gCCPriv->Current.Color[1]; + f[2] = gCCPriv->Current.Color[2]; + f[3] = gCCPriv->Current.Color[3]; + break; + case GL_CURRENT_NORMAL: + f[0] = gCCPriv->Current.Normal[0]; + f[1] = gCCPriv->Current.Normal[1]; + f[2] = gCCPriv->Current.Normal[2]; + break; + case GL_MAX_TEXTURE_SIZE: + *f = INT_TO_FLOAT(GAMMA_MAX_TEXTURE_SIZE); + break; case GL_MODELVIEW_MATRIX: - for (i = 0; i < 16; i++) - f[i] = gCCPriv->ModelView[i]; + for (loop = 0; loop < 16; loop++) + f[loop] = gCCPriv->ModelView[loop]; + break; + case GL_CURRENT_TEXTURE_COORDS: + f[0] = gCCPriv->Current.TexCoord[0]; + f[1] = gCCPriv->Current.TexCoord[1]; + f[2] = gCCPriv->Current.TexCoord[2]; + f[3] = gCCPriv->Current.TexCoord[3]; break; default: break; @@ -1756,11 +1990,34 @@ void _gamma_GetFloatv(GLenum val, GLfloat *f) void _gamma_GetIntegerv(GLenum val, GLint *i) { + int loop; + DEBUG_GLCMDS(("GetIntegerv: %04x\n", (int)val)); switch (val) { + case GL_CURRENT_COLOR: + i[0] = FLOAT_TO_INT(gCCPriv->Current.Color[0]); + i[1] = FLOAT_TO_INT(gCCPriv->Current.Color[1]); + i[2] = FLOAT_TO_INT(gCCPriv->Current.Color[2]); + i[3] = FLOAT_TO_INT(gCCPriv->Current.Color[3]); + break; + case GL_CURRENT_NORMAL: + i[0] = FLOAT_TO_INT(gCCPriv->Current.Normal[0]); + i[1] = FLOAT_TO_INT(gCCPriv->Current.Normal[1]); + i[2] = FLOAT_TO_INT(gCCPriv->Current.Normal[2]); + break; case GL_MAX_TEXTURE_SIZE: - *i = 2048; + *i = GAMMA_MAX_TEXTURE_SIZE; + break; + case GL_MODELVIEW_MATRIX: + for (loop = 0; loop < 16; loop++) + i[loop] = FLOAT_TO_INT(gCCPriv->ModelView[loop]); + break; + case GL_CURRENT_TEXTURE_COORDS: + i[0] = FLOAT_TO_INT(gCCPriv->Current.TexCoord[0]); + i[1] = FLOAT_TO_INT(gCCPriv->Current.TexCoord[1]); + i[2] = FLOAT_TO_INT(gCCPriv->Current.TexCoord[2]); + i[3] = FLOAT_TO_INT(gCCPriv->Current.TexCoord[3]); break; } } @@ -1967,12 +2224,14 @@ GLboolean _gamma_IsEnabled(GLenum cap) return GL_TRUE; } +#if 0 /* Now in dlist.c */ GLboolean _gamma_IsList(GLuint list) { DEBUG_GLCMDS(("IsList: %04x\n", (unsigned int)list)); return GL_TRUE; } +#endif GLboolean _gamma_IsTexture(GLuint texture) { @@ -2001,7 +2260,7 @@ void _gamma_LightModelfv(GLenum pname, const GLfloat *params) WRITEF(gCCPriv->buf, SceneAmbientColorRed, params[0]); break; case GL_LIGHT_MODEL_LOCAL_VIEWER: - if ((int)params[0] != 0) + if (params[0] != 0.0) gCCPriv->LightingMode |= LightingModeLocalViewer; else gCCPriv->LightingMode &= ~LightingModeLocalViewer; @@ -2009,7 +2268,7 @@ void _gamma_LightModelfv(GLenum pname, const GLfloat *params) WRITE(gCCPriv->buf, LightingMode, gCCPriv->LightingMode); break; case GL_LIGHT_MODEL_TWO_SIDE: - if ((int)params[0] != 0) { + if (params[0] == 1.0f) { gCCPriv->LightingMode |= LightingModeTwoSides; gCCPriv->MaterialMode |= MaterialModeTwoSides; } else { @@ -2039,7 +2298,7 @@ void _gamma_Lightf(GLenum light, GLenum pname, GLfloat param) void _gamma_Lightfv(GLenum light, GLenum pname, const GLfloat *params) { - GLfloat l,x,y,z; + GLfloat l,x,y,z,w; DEBUG_GLCMDS(("Lightfv: %04x %04x %f\n", (int)light, (int)pname, *params)); @@ -2069,12 +2328,13 @@ void _gamma_Lightfv(GLenum light, GLenum pname, const GLfloat *params) break; case GL_POSITION: /* Normalize <x,y,z> */ - x = params[0]; y = params[1]; z = params[2]; - l = sqrt(x*x + y*y + z*z); + x = params[0]; y = params[1]; z = params[2]; w = params[3]; + l = sqrt(x*x + y*y + z*z + w*w); + w /= l; x /= l; y /= l; z /= l; - if ((int)params[3] != 0) { + if (params[3] != 0.0) { gCCPriv->Light0Mode |= Light0ModeAttenuation; gCCPriv->Light0Mode |= Light0ModeLocal; } else { @@ -2083,30 +2343,30 @@ void _gamma_Lightfv(GLenum light, GLenum pname, const GLfloat *params) } CHECK_DMA_BUFFER(gCC, gCCPriv, 5); WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode); - WRITEF(gCCPriv->buf, Light0PositionW, params[3]); + WRITEF(gCCPriv->buf, Light0PositionW, w); WRITEF(gCCPriv->buf, Light0PositionZ, z); WRITEF(gCCPriv->buf, Light0PositionY, y); WRITEF(gCCPriv->buf, Light0PositionX, x); break; case GL_SPOT_DIRECTION: CHECK_DMA_BUFFER(gCC, gCCPriv, 3); - WRITEF(gCCPriv->buf, Light0SpotlightDirectionZ, params[3]); - WRITEF(gCCPriv->buf, Light0SpotlightDirectionY, params[2]); - WRITEF(gCCPriv->buf, Light0SpotlightDirectionX, params[1]); - /* WRITEF(gCCPriv->buf, Light0SpotlightDirectionW, params[0]); */ + /* WRITEF(gCCPriv->buf, Light0SpotlightDirectionW, params[3]); */ + WRITEF(gCCPriv->buf, Light0SpotlightDirectionZ, params[2]); + WRITEF(gCCPriv->buf, Light0SpotlightDirectionY, params[1]); + WRITEF(gCCPriv->buf, Light0SpotlightDirectionX, params[0]); break; case GL_SPOT_EXPONENT: CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITEF(gCCPriv->buf, Light0SpotlightExponent, params[0]); break; case GL_SPOT_CUTOFF: - if ((int)params[0] != -1) + if (params[0] != 180.0) gCCPriv->Light0Mode |= Light0ModeSpotLight; else gCCPriv->Light0Mode &= ~Light0ModeSpotLight; CHECK_DMA_BUFFER(gCC, gCCPriv, 2); WRITE(gCCPriv->buf, Light0Mode, gCCPriv->Light0Mode); - WRITEF(gCCPriv->buf, Light0CosSpotlightCutoffAngle, params[0]); + WRITEF(gCCPriv->buf, Light0CosSpotlightCutoffAngle, cos(params[0]*DEG2RAD)); break; case GL_CONSTANT_ATTENUATION: CHECK_DMA_BUFFER(gCC, gCCPriv, 1); @@ -2152,7 +2412,7 @@ void _gamma_Lightfv(GLenum light, GLenum pname, const GLfloat *params) x /= l; y /= l; z /= l; - if ((int)params[3] != 0) { + if (params[3] != 0.0) { gCCPriv->Light1Mode |= Light1ModeAttenuation; gCCPriv->Light1Mode |= Light1ModeLocal; } else { @@ -2168,23 +2428,23 @@ void _gamma_Lightfv(GLenum light, GLenum pname, const GLfloat *params) break; case GL_SPOT_DIRECTION: CHECK_DMA_BUFFER(gCC, gCCPriv, 3); - WRITEF(gCCPriv->buf, Light1SpotlightDirectionZ, params[3]); - WRITEF(gCCPriv->buf, Light1SpotlightDirectionY, params[2]); - WRITEF(gCCPriv->buf, Light1SpotlightDirectionX, params[1]); - /* WRITEF(gCCPriv->buf, Light1SpotlightDirectionW, params[0]); */ + /* WRITEF(gCCPriv->buf, Light1SpotlightDirectionW, params[3]); */ + WRITEF(gCCPriv->buf, Light1SpotlightDirectionZ, params[2]); + WRITEF(gCCPriv->buf, Light1SpotlightDirectionY, params[1]); + WRITEF(gCCPriv->buf, Light1SpotlightDirectionX, params[0]); break; case GL_SPOT_EXPONENT: CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITEF(gCCPriv->buf, Light1SpotlightExponent, params[0]); break; case GL_SPOT_CUTOFF: - if ((int)params[0] != -1) + if (params[0] != 180.0) gCCPriv->Light1Mode |= Light1ModeSpotLight; else gCCPriv->Light1Mode &= ~Light1ModeSpotLight; CHECK_DMA_BUFFER(gCC, gCCPriv, 2); WRITE(gCCPriv->buf, Light1Mode, gCCPriv->Light1Mode); - WRITEF(gCCPriv->buf, Light1CosSpotlightCutoffAngle, params[0]); + WRITEF(gCCPriv->buf, Light1CosSpotlightCutoffAngle, cos(params[0]*DEG2RAD)); break; case GL_CONSTANT_ATTENUATION: CHECK_DMA_BUFFER(gCC, gCCPriv, 1); @@ -2220,10 +2480,12 @@ void _gamma_LineWidth(GLfloat width) DEBUG_GLCMDS(("LineWidth: %f\n", width)); } +#if 0 /* Now in dlist.c */ void _gamma_ListBase(GLuint base) { DEBUG_GLCMDS(("ListBase: %d\n", (unsigned int)base)); } +#endif void _gamma_LoadIdentity(void) { @@ -2261,6 +2523,13 @@ void _gamma_LoadName(GLuint name) void _gamma_LogicOp(GLenum opcode) { DEBUG_GLCMDS(("LogicOp: %04x\n", (int)opcode)); + + gCCPriv->LogicalOpMode &= ~LogicalOpModeMask; + + gCCPriv->LogicalOpMode |= (opcode & 0x0f) << 1; + + CHECK_DMA_BUFFER(gCC, gCCPriv, 1); + WRITE(gCCPriv->buf, LogicalOpMode, gCCPriv->LogicalOpMode); } void _gamma_Map1d(GLenum target, GLdouble u1, GLdouble u2, GLint stride, GLint order, const GLdouble *pnts) @@ -2318,6 +2587,8 @@ void _gamma_MapGrid2f(GLint un, GLfloat u1, GLfloat u2, GLint vn, GLfloat v1, GL void _gamma_Materialf(GLenum face, GLenum pname, GLfloat param) { DEBUG_GLCMDS(("Materialf: %04x %04x %f\n", (int)face, (int)pname, param)); + + _gamma_Materialfv(face, pname, ¶m); } void _gamma_Materialfv(GLenum face, GLenum pname, const GLfloat *params) @@ -2453,7 +2724,6 @@ void _gamma_MatrixMode(GLenum mode) /* ERROR!!! */ break; } - } void _gamma_MultMatrixd(const GLdouble *m) @@ -2476,15 +2746,15 @@ void _gamma_MultMatrixf(const GLfloat *m) gammaLoadHWMatrix(); } +#if 0 /* Now in dlist.c */ void _gamma_NewList(GLuint list, GLenum mode) { DEBUG_GLCMDS(("NewList: %d %04x\n", (unsigned int)list, (int)mode)); } +#endif void _gamma_Normal3b(GLbyte nx, GLbyte ny, GLbyte nz) { - GLfloat x,y,z; - DEBUG_GLCMDS(("Normal3b: %d %d %d\n", nx, ny, nz)); _gamma_Normal3f((GLfloat)nx,(GLfloat)ny,(GLfloat)nz); @@ -2492,8 +2762,6 @@ void _gamma_Normal3b(GLbyte nx, GLbyte ny, GLbyte nz) void _gamma_Normal3bv(const GLbyte *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Normal3bv: %d %d %d\n", v[0], v[1], v[2])); _gamma_Normal3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); @@ -2517,6 +2785,10 @@ void _gamma_Normal3f(GLfloat nx, GLfloat ny, GLfloat nz) { DEBUG_GLCMDS(("Normal3f: %f %f %f\n", nx, ny, nz)); + gCCPriv->Current.Normal[0] = nx; + gCCPriv->Current.Normal[1] = ny; + gCCPriv->Current.Normal[2] = nz; + CHECK_DMA_BUFFER(gCC, gCCPriv, 3); WRITEF(gCCPriv->buf, Nz, nz); WRITEF(gCCPriv->buf, Ny, ny); @@ -2532,8 +2804,6 @@ void _gamma_Normal3fv(const GLfloat *v) void _gamma_Normal3i(GLint nx, GLint ny, GLint nz) { - GLfloat x,y,z; - DEBUG_GLCMDS(("Normal3i: %d %d %d\n", (int)nx, (int)ny, (int)nz)); _gamma_Normal3f((GLfloat)nx,(GLfloat)ny,(GLfloat)nz); @@ -2541,8 +2811,6 @@ void _gamma_Normal3i(GLint nx, GLint ny, GLint nz) void _gamma_Normal3iv(const GLint *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Normal3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2])); _gamma_Normal3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); @@ -2550,8 +2818,6 @@ void _gamma_Normal3iv(const GLint *v) void _gamma_Normal3s(GLshort nx, GLshort ny, GLshort nz) { - GLfloat x,y,z; - DEBUG_GLCMDS(("Normal3s: %d %d %d\n", nx, ny, nz)); _gamma_Normal3f((GLfloat)nx,(GLfloat)ny,(GLfloat)nz); @@ -2559,8 +2825,6 @@ void _gamma_Normal3s(GLshort nx, GLshort ny, GLshort nz) void _gamma_Normal3sv(const GLshort *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Normal3sv: %d %d %d\n", v[0], v[1], v[2])); _gamma_Normal3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); @@ -2569,6 +2833,34 @@ void _gamma_Normal3sv(const GLshort *v) void _gamma_NormalPointer(GLenum type, GLsizei stride, const GLvoid *pointer) { DEBUG_GLCMDS(("NormalPointer: %04x %d\n", (int)type, (int)stride)); + + if (stride<0) { + gamma_error( GL_INVALID_VALUE, "glNormalPointer(stride)" ); + return; + } + switch (type) { + case GL_BYTE: + gCCPriv->Array.NormalStrideB = stride ? stride : 3*sizeof(GLbyte); + break; + case GL_SHORT: + gCCPriv->Array.NormalStrideB = stride ? stride : 3*sizeof(GLshort); + break; + case GL_INT: + gCCPriv->Array.NormalStrideB = stride ? stride : 3*sizeof(GLint); + break; + case GL_FLOAT: + gCCPriv->Array.NormalStrideB = stride ? stride : 3*sizeof(GLfloat); + break; + case GL_DOUBLE: + gCCPriv->Array.NormalStrideB = stride ? stride : 3*sizeof(GLdouble); + break; + default: + gamma_error( GL_INVALID_ENUM, "glNormalPointer(type)" ); + return; + } + gCCPriv->Array.NormalType = type; + gCCPriv->Array.NormalStride = stride; + gCCPriv->Array.NormalPtr = (void *) pointer; } void _gamma_Ortho(GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar) @@ -2844,22 +3136,38 @@ void _gamma_PushName(GLuint name) void _gamma_RasterPos2d(GLdouble x, GLdouble y) { + DEBUG_GLCMDS(("RasterPos2d: %f %f\n", x, y)); + + _gamma_RasterPos2f((GLfloat)x,(GLfloat)y); } void _gamma_RasterPos2dv(const GLdouble *v) { + _gamma_RasterPos2f((GLfloat)v[0],(GLfloat)v[1]); } void _gamma_RasterPos2f(GLfloat x, GLfloat y) { + DEBUG_GLCMDS(("RasterPos2f: %f %f\n", x, y)); + + gCCPriv->Current.RasterPos[0] = x; + gCCPriv->Current.RasterPos[1] = y; + gCCPriv->Current.RasterPos[2] = 0.0f; + gCCPriv->Current.RasterPos[3] = 1.0f; + + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITEF(gCCPriv->buf, RPy, y); + WRITEF(gCCPriv->buf, RPx2, x); } void _gamma_RasterPos2fv(const GLfloat *v) { + _gamma_RasterPos2f(v[0],v[1]); } void _gamma_RasterPos2i(GLint x, GLint y) { + _gamma_RasterPos2f((GLfloat)x,(GLfloat)y); } void _gamma_RasterPos2iv(const GLint *v) @@ -3118,8 +3426,21 @@ void _gamma_Scalef(GLfloat x, GLfloat y, GLfloat z) void _gamma_Scissor(GLint x, GLint y, GLsizei width, GLsizei height) { + GLint x1, y1, x2, y2; + DEBUG_GLCMDS(("Scissor: %d %d %d %d\n", (int)x, (int)y, (int)width, (int)height)); + + x1 = gCC->driDrawablePriv->x + x; + y1 = gCC->driScreenPriv->fbHeight - + (gCC->driDrawablePriv->y + + gCC->driDrawablePriv->h) + y; + x2 = x1 + width; + y2 = y1 + height; + + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); + WRITE(gCCPriv->buf, ScissorMinXY, (y1&0xffff)<<16 | (x1&0xffff)); + WRITE(gCCPriv->buf, ScissorMaxXY, (y2&0xffff)<<16 | (x2&0xffff)); } void _gamma_SelectBuffer(GLsizei numnames, GLuint *buffer) @@ -3188,6 +3509,11 @@ void _gamma_TexCoord1f(GLfloat s) { DEBUG_GLCMDS(("TexCoord1f: %f\n", s)); + gCCPriv->Current.TexCoord[0] = s; + gCCPriv->Current.TexCoord[1] = 0.0f; + gCCPriv->Current.TexCoord[2] = 0.0f; + gCCPriv->Current.TexCoord[3] = 1.0f; + WRITEF(gCCPriv->buf, Ts1, s); } @@ -3195,6 +3521,11 @@ void _gamma_TexCoord1fv(const GLfloat *v) { DEBUG_GLCMDS(("TexCoord1fv: %f\n", *v)); + gCCPriv->Current.TexCoord[0] = v[0]; + gCCPriv->Current.TexCoord[1] = 0.0f; + gCCPriv->Current.TexCoord[2] = 0.0f; + gCCPriv->Current.TexCoord[3] = 1.0f; + WRITEF(gCCPriv->buf, Ts1, v[0]); } @@ -3260,6 +3591,11 @@ void _gamma_TexCoord2f(GLfloat s, GLfloat t) { DEBUG_GLCMDS(("TexCoord2f: %f %f\n", s, t)); + gCCPriv->Current.TexCoord[0] = s; + gCCPriv->Current.TexCoord[1] = t; + gCCPriv->Current.TexCoord[2] = 0.0f; + gCCPriv->Current.TexCoord[3] = 1.0f; + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); WRITEF(gCCPriv->buf, Tt2, t); WRITEF(gCCPriv->buf, Ts2, s); @@ -3269,6 +3605,11 @@ void _gamma_TexCoord2fv(const GLfloat *v) { DEBUG_GLCMDS(("TexCoord2fv: %f %f\n", v[0], v[1])); + gCCPriv->Current.TexCoord[0] = v[0]; + gCCPriv->Current.TexCoord[1] = v[1]; + gCCPriv->Current.TexCoord[2] = 0.0f; + gCCPriv->Current.TexCoord[3] = 1.0f; + CHECK_DMA_BUFFER(gCC, gCCPriv, 2); WRITEF(gCCPriv->buf, Tt2, v[1]); WRITEF(gCCPriv->buf, Ts2, v[0]); @@ -3429,6 +3770,11 @@ void _gamma_TexCoord4f(GLfloat s, GLfloat t, GLfloat r, GLfloat q) { DEBUG_GLCMDS(("TexCoord4f: %f %f %f %f\n", s, t, r, q)); + gCCPriv->Current.TexCoord[0] = s; + gCCPriv->Current.TexCoord[1] = t; + gCCPriv->Current.TexCoord[2] = t; + gCCPriv->Current.TexCoord[3] = q; + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); WRITEF(gCCPriv->buf, Tq4, q); WRITEF(gCCPriv->buf, Tr4, r); @@ -3440,6 +3786,11 @@ void _gamma_TexCoord4fv(const GLfloat *v) { DEBUG_GLCMDS(("TexCoord4fv: %f %f %f %f\n", v[0], v[1], v[2], v[3])); + gCCPriv->Current.TexCoord[0] = v[0]; + gCCPriv->Current.TexCoord[1] = v[1]; + gCCPriv->Current.TexCoord[2] = v[2]; + gCCPriv->Current.TexCoord[3] = v[3]; + CHECK_DMA_BUFFER(gCC, gCCPriv, 4); WRITEF(gCCPriv->buf, Tq4, v[3]); WRITEF(gCCPriv->buf, Tr4, v[2]); @@ -3508,6 +3859,36 @@ void _gamma_TexCoordPointer(GLint size, GLenum type, GLsizei stride, const GLvoi { DEBUG_GLCMDS(("TexCoordPointer: %d %04x %d\n", (int)size, (int)type, (int)stride)); + + if (size<1 || size>4) { + gamma_error( GL_INVALID_VALUE, "glTexCoordPointer(size)" ); + return; + } + if (stride<0) { + gamma_error( GL_INVALID_VALUE, "glTexCoordPointer(stride)" ); + return; + } + switch (type) { + case GL_SHORT: + gCCPriv->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLshort); + break; + case GL_INT: + gCCPriv->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLint); + break; + case GL_FLOAT: + gCCPriv->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLfloat); + break; + case GL_DOUBLE: + gCCPriv->Array.TexCoordStrideB = stride ? stride : size*sizeof(GLdouble); + break; + default: + gamma_error( GL_INVALID_ENUM, "glTexCoordPointer(type)" ); + return; + } + gCCPriv->Array.TexCoordSize = size; + gCCPriv->Array.TexCoordType = type; + gCCPriv->Array.TexCoordStride = stride; + gCCPriv->Array.TexCoordPtr = (void *) pointer; } void _gamma_TexEnvf(GLenum target, GLenum pname, GLfloat param) @@ -4158,8 +4539,6 @@ void _gamma_Vertex2fv(const GLfloat *v) void _gamma_Vertex2i(GLint x, GLint y) { - GLfloat a,b; - DEBUG_GLCMDS(("Vertex2i: %d %d\n", (int)x, (int)y)); _gamma_Vertex2f((GLfloat)x,(GLfloat)y); @@ -4167,8 +4546,6 @@ void _gamma_Vertex2i(GLint x, GLint y) void _gamma_Vertex2iv(const GLint *v) { - GLfloat p[2]; - DEBUG_GLCMDS(("Vertex2iv: %d %d\n", (int)v[0], (int)v[1])); _gamma_Vertex2f((GLfloat)v[0],(GLfloat)v[1]); @@ -4176,8 +4553,6 @@ void _gamma_Vertex2iv(const GLint *v) void _gamma_Vertex2s(GLshort x, GLshort y) { - GLfloat a,b; - DEBUG_GLCMDS(("Vertex2s: %d %d\n", x, y)); _gamma_Vertex2f((GLfloat)x,(GLfloat)y); @@ -4185,8 +4560,6 @@ void _gamma_Vertex2s(GLshort x, GLshort y) void _gamma_Vertex2sv(const GLshort *v) { - GLfloat p[2]; - DEBUG_GLCMDS(("Vertex2sv: %d %d\n", v[0], v[1])); _gamma_Vertex2f((GLfloat)v[0],(GLfloat)v[1]); @@ -4225,8 +4598,6 @@ void _gamma_Vertex3fv(const GLfloat *v) void _gamma_Vertex3i(GLint x, GLint y, GLint z) { - GLfloat a,b,c; - DEBUG_GLCMDS(("Vertex3i: %d %d %d\n", (int)x, (int)y, (int)z)); _gamma_Vertex3f((GLfloat)x,(GLfloat)y,(GLfloat)z); @@ -4234,8 +4605,6 @@ void _gamma_Vertex3i(GLint x, GLint y, GLint z) void _gamma_Vertex3iv(const GLint *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Vertex3iv: %d %d %d\n", (int)v[0], (int)v[1], (int)v[2])); _gamma_Vertex3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); @@ -4243,8 +4612,6 @@ void _gamma_Vertex3iv(const GLint *v) void _gamma_Vertex3s(GLshort x, GLshort y, GLshort z) { - GLfloat a,b,c; - DEBUG_GLCMDS(("Vertex3s: %d %d %d\n", x, y, z)); _gamma_Vertex3f((GLfloat)x,(GLfloat)y,(GLfloat)z); @@ -4252,8 +4619,6 @@ void _gamma_Vertex3s(GLshort x, GLshort y, GLshort z) void _gamma_Vertex3sv(const GLshort *v) { - GLfloat p[3]; - DEBUG_GLCMDS(("Vertex3sv: %d %d %d\n", v[0], v[1], v[2])); _gamma_Vertex3f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2]); @@ -4293,8 +4658,6 @@ void _gamma_Vertex4fv(const GLfloat *v) void _gamma_Vertex4i(GLint x, GLint y, GLint z, GLint w) { - GLfloat a,b,c,d; - DEBUG_GLCMDS(("Vertex4i: %d %d %d %d\n", (int)x, (int)y, (int)z, (int)w)); _gamma_Vertex4f((GLfloat)x,(GLfloat)y,(GLfloat)z,(GLfloat)w); @@ -4302,8 +4665,6 @@ void _gamma_Vertex4i(GLint x, GLint y, GLint z, GLint w) void _gamma_Vertex4iv(const GLint *v) { - GLfloat p[4]; - DEBUG_GLCMDS(("Vertex4iv: %d %d %d %d\n", (int)v[0], (int)v[1], (int)v[2], (int)v[3])); @@ -4312,8 +4673,6 @@ void _gamma_Vertex4iv(const GLint *v) void _gamma_Vertex4s(GLshort x, GLshort y, GLshort z, GLshort w) { - GLfloat a,b,c,d; - DEBUG_GLCMDS(("Vertex4s: %d %d %d %d\n", x, y, z, w)); _gamma_Vertex4f((GLfloat)x,(GLfloat)y,(GLfloat)z,(GLfloat)w); @@ -4321,8 +4680,6 @@ void _gamma_Vertex4s(GLshort x, GLshort y, GLshort z, GLshort w) void _gamma_Vertex4sv(const GLshort *v) { - GLfloat p[4]; - DEBUG_GLCMDS(("Vertex4sv: %d %d %d %d\n", v[0], v[1], v[2], v[3])); _gamma_Vertex4f((GLfloat)v[0],(GLfloat)v[1],(GLfloat)v[2],(GLfloat)v[3]); @@ -4332,6 +4689,36 @@ void _gamma_VertexPointer(GLint size, GLenum type, GLsizei stride, const GLvoid { DEBUG_GLCMDS(("VertexPointer: %d %04x %d\n", (int)size, (int)type, (int)stride)); + + if (size<2 || size>4) { + gamma_error( GL_INVALID_VALUE, "glVertexPointer(size)" ); + return; + } + if (stride<0) { + gamma_error( GL_INVALID_VALUE, "glVertexPointer(stride)" ); + return; + } + switch (type) { + case GL_SHORT: + gCCPriv->Array.VertexStrideB = stride ? stride : size*sizeof(GLshort); + break; + case GL_INT: + gCCPriv->Array.VertexStrideB = stride ? stride : size*sizeof(GLint); + break; + case GL_FLOAT: + gCCPriv->Array.VertexStrideB = stride ? stride : size*sizeof(GLfloat); + break; + case GL_DOUBLE: + gCCPriv->Array.VertexStrideB = stride ? stride : size*sizeof(GLdouble); + break; + default: + gamma_error( GL_INVALID_ENUM, "glVertexPointer(type)" ); + return; + } + gCCPriv->Array.VertexSize = size; + gCCPriv->Array.VertexType = type; + gCCPriv->Array.VertexStride = stride; + gCCPriv->Array.VertexPtr = (void *) pointer; } void _gamma_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) @@ -4357,10 +4744,10 @@ void _gamma_Viewport(GLint x, GLint y, GLsizei width, GLsizei height) oy = y + sy; CHECK_DMA_BUFFER(gCC, gCCPriv, 4); - WRITEF(gCCPriv->buf, ViewPortScaleX, sx); - WRITEF(gCCPriv->buf, ViewPortScaleY, sy); WRITEF(gCCPriv->buf, ViewPortOffsetX, ox); WRITEF(gCCPriv->buf, ViewPortOffsetY, oy); + WRITEF(gCCPriv->buf, ViewPortScaleX, sx); + WRITEF(gCCPriv->buf, ViewPortScaleY, sy); #if 1 /* Err - this shouldn't be needed, but something isn't flushing */ FLUSH_DMA_BUFFER(gCC,gCCPriv); #endif @@ -4395,7 +4782,7 @@ init_no_op_table(struct _glapi_table *table) void -_gamma_init_dispatch(struct _glapi_table *dispatch) +_gamma_init_exec(struct _glapi_table *dispatch) { init_no_op_table(dispatch); @@ -4710,7 +5097,7 @@ _gamma_init_dispatch(struct _glapi_table *dispatch) /* 1.1 */ dispatch->AreTexturesResident = _gamma_AreTexturesResident; - dispatch->ArrayElement = _gamma_ArrayElement; + dispatch->ArrayElement = gl_save_ArrayElement; /*_gamma_ArrayElement;*/ dispatch->BindTexture = _gamma_BindTexture; dispatch->ColorPointer = _gamma_ColorPointer; dispatch->CopyTexImage1D = _gamma_CopyTexImage1D; @@ -4740,5 +5127,186 @@ _gamma_init_dispatch(struct _glapi_table *dispatch) dispatch->VertexPointer = _gamma_VertexPointer; } - +void +_gamma_init_save(struct _glapi_table *table) +{ + init_no_op_table(table); + + table->Accum = gl_save_Accum; + table->AlphaFunc = gl_save_AlphaFunc; + table->AreTexturesResident = _gamma_AreTexturesResident; /* NOT SAVED */ + table->ArrayElement = gl_save_ArrayElement; + table->Begin = gl_save_Begin; + table->BindTexture = gl_save_BindTexture; + table->Bitmap = gl_save_Bitmap; + table->BlendFunc = gl_save_BlendFunc; + table->CallList = gl_save_CallList; + table->CallLists = gl_save_CallLists; + table->Clear = gl_save_Clear; + table->ClearAccum = gl_save_ClearAccum; + table->ClearColor = gl_save_ClearColor; + table->ClearDepth = gl_save_ClearDepth; + table->ClearIndex = gl_save_ClearIndex; + table->ClearStencil = gl_save_ClearStencil; + table->ClipPlane = gl_save_ClipPlane; + table->Color3f = gl_save_Color3f; + table->Color3fv = gl_save_Color3fv; + table->Color4f = gl_save_Color4f; + table->Color4fv = gl_save_Color4fv; + table->Color4ub = gl_save_Color4ub; + table->Color4ubv = gl_save_Color4ubv; + table->ColorMask = gl_save_ColorMask; + table->ColorMaterial = gl_save_ColorMaterial; + table->ColorPointer = _gamma_ColorPointer; /* NOT SAVED */ + table->CopyPixels = gl_save_CopyPixels; + table->CopyTexImage1D = gl_save_CopyTexImage1D; + table->CopyTexImage2D = gl_save_CopyTexImage2D; + table->CopyTexSubImage1D = gl_save_CopyTexSubImage1D; + table->CopyTexSubImage2D = gl_save_CopyTexSubImage2D; + table->CullFace = gl_save_CullFace; + table->DeleteLists = _gamma_DeleteLists; /* NOT SAVED */ + table->DeleteTextures = _gamma_DeleteTextures; /* NOT SAVED */ + table->DepthFunc = gl_save_DepthFunc; + table->DepthMask = gl_save_DepthMask; + table->DepthRange = gl_save_DepthRange; + table->Disable = gl_save_Disable; + table->DisableClientState = _gamma_DisableClientState; /* NOT SAVED */ + table->DrawArrays = gl_save_DrawArrays; + table->DrawBuffer = gl_save_DrawBuffer; + table->DrawElements = gl_save_DrawElements; + table->DrawPixels = gl_save_DrawPixels; + table->EdgeFlag = gl_save_EdgeFlag; + table->EdgeFlagPointer = _gamma_EdgeFlagPointer; /* NOT SAVED */ + table->Enable = gl_save_Enable; + table->EnableClientState = _gamma_EnableClientState; /* NOT SAVED */ + table->End = gl_save_End; + table->EndList = _gamma_EndList; /* NOT SAVED */ + table->EvalCoord1f = gl_save_EvalCoord1f; + table->EvalCoord2f = gl_save_EvalCoord2f; + table->EvalMesh1 = gl_save_EvalMesh1; + table->EvalMesh2 = gl_save_EvalMesh2; + table->EvalPoint1 = gl_save_EvalPoint1; + table->EvalPoint2 = gl_save_EvalPoint2; + table->FeedbackBuffer = _gamma_FeedbackBuffer; /* NOT SAVED */ + table->Finish = _gamma_Finish; /* NOT SAVED */ + table->Flush = _gamma_Flush; /* NOT SAVED */ + table->Fogfv = gl_save_Fogfv; + table->FrontFace = gl_save_FrontFace; + table->Frustum = gl_save_Frustum; + table->GenLists = _gamma_GenLists; /* NOT SAVED */ + table->GenTextures = _gamma_GenTextures; /* NOT SAVED */ + + /* NONE OF THESE COMMANDS ARE COMPILED INTO DISPLAY LISTS */ + table->GetBooleanv = _gamma_GetBooleanv; + table->GetClipPlane = _gamma_GetClipPlane; + table->GetDoublev = _gamma_GetDoublev; + table->GetError = _gamma_GetError; + table->GetFloatv = _gamma_GetFloatv; + table->GetIntegerv = _gamma_GetIntegerv; + table->GetString = _gamma_GetString; + table->GetLightfv = _gamma_GetLightfv; + table->GetLightiv = _gamma_GetLightiv; + table->GetMapdv = _gamma_GetMapdv; + table->GetMapfv = _gamma_GetMapfv; + table->GetMapiv = _gamma_GetMapiv; + table->GetMaterialfv = _gamma_GetMaterialfv; + table->GetMaterialiv = _gamma_GetMaterialiv; + table->GetPixelMapfv = _gamma_GetPixelMapfv; + table->GetPixelMapuiv = _gamma_GetPixelMapuiv; + table->GetPixelMapusv = _gamma_GetPixelMapusv; + table->GetPointerv = _gamma_GetPointerv; + table->GetPolygonStipple = _gamma_GetPolygonStipple; + table->GetTexEnvfv = _gamma_GetTexEnvfv; + table->GetTexEnviv = _gamma_GetTexEnviv; + table->GetTexGendv = _gamma_GetTexGendv; + table->GetTexGenfv = _gamma_GetTexGenfv; + table->GetTexGeniv = _gamma_GetTexGeniv; + table->GetTexImage = _gamma_GetTexImage; + table->GetTexLevelParameterfv = _gamma_GetTexLevelParameterfv; + table->GetTexLevelParameteriv = _gamma_GetTexLevelParameteriv; + table->GetTexParameterfv = _gamma_GetTexParameterfv; + table->GetTexParameteriv = _gamma_GetTexParameteriv; + + table->Hint = gl_save_Hint; + table->IndexMask = gl_save_IndexMask; + table->Indexf = gl_save_Indexf; + table->Indexi = gl_save_Indexi; + table->IndexPointer = _gamma_IndexPointer; /* NOT SAVED */ + table->InitNames = gl_save_InitNames; + table->InterleavedArrays = _gamma_InterleavedArrays; /* NOT SAVED */ + table->IsEnabled = _gamma_IsEnabled; /* NOT SAVED */ + table->IsTexture = _gamma_IsTexture; /* NOT SAVED */ + table->IsList = _gamma_IsList; /* NOT SAVED */ + table->LightModelfv = gl_save_LightModelfv; + table->Lightfv = gl_save_Lightfv; + table->LineStipple = gl_save_LineStipple; + table->LineWidth = gl_save_LineWidth; + table->ListBase = gl_save_ListBase; + table->LoadIdentity = gl_save_LoadIdentity; + table->LoadMatrixf = gl_save_LoadMatrixf; + table->LoadName = gl_save_LoadName; + table->LogicOp = gl_save_LogicOp; + table->Map1f = gl_save_Map1f; + table->Map2f = gl_save_Map2f; + table->MapGrid1f = gl_save_MapGrid1f; + table->MapGrid2f = gl_save_MapGrid2f; + table->Materialfv = gl_save_Materialfv; + table->MatrixMode = gl_save_MatrixMode; + table->MultMatrixf = gl_save_MultMatrixf; + table->NewList = gl_save_NewList; + table->Normal3f = gl_save_Normal3f; + table->Normal3fv = gl_save_Normal3fv; + table->NormalPointer = _gamma_NormalPointer; /* NOT SAVED */ + table->Ortho = gl_save_Ortho; + table->PassThrough = gl_save_PassThrough; + table->PixelMapfv = gl_save_PixelMapfv; + table->PixelStorei = _gamma_PixelStorei; /* NOT SAVED */ + table->PixelTransferf = gl_save_PixelTransferf; + table->PixelZoom = gl_save_PixelZoom; + table->PointSize = gl_save_PointSize; + table->PolygonMode = gl_save_PolygonMode; + table->PolygonOffset = gl_save_PolygonOffset; + table->PolygonStipple = gl_save_PolygonStipple; + table->PopAttrib = gl_save_PopAttrib; + table->PopClientAttrib = _gamma_PopClientAttrib; /* NOT SAVED */ + table->PopMatrix = gl_save_PopMatrix; + table->PopName = gl_save_PopName; + table->PrioritizeTextures = gl_save_PrioritizeTextures; + table->PushAttrib = gl_save_PushAttrib; + table->PushClientAttrib = _gamma_PushClientAttrib; /* NOT SAVED */ + table->PushMatrix = gl_save_PushMatrix; + table->PushName = gl_save_PushName; + table->RasterPos4f = gl_save_RasterPos4f; + table->ReadBuffer = gl_save_ReadBuffer; + table->ReadPixels = _gamma_ReadPixels; /* NOT SAVED */ + table->Rectf = gl_save_Rectf; + table->RenderMode = _gamma_RenderMode; /* NOT SAVED */ + table->Rotatef = gl_save_Rotatef; + table->Scalef = gl_save_Scalef; + table->Scissor = gl_save_Scissor; + table->SelectBuffer = _gamma_SelectBuffer; /* NOT SAVED */ + table->ShadeModel = gl_save_ShadeModel; + table->StencilFunc = gl_save_StencilFunc; + table->StencilMask = gl_save_StencilMask; + table->StencilOp = gl_save_StencilOp; + table->TexCoord2f = gl_save_TexCoord2f; + table->TexCoord2fv = gl_save_TexCoord2fv; + table->TexCoord3fv = gl_save_TexCoord3fv; + table->TexCoord4f = gl_save_TexCoord4f; + table->TexCoordPointer = _gamma_TexCoordPointer; /* NOT SAVED */ + table->TexEnvfv = gl_save_TexEnvfv; + table->TexGenfv = gl_save_TexGenfv; + table->TexImage1D = gl_save_TexImage1D; + table->TexImage2D = gl_save_TexImage2D; + table->TexSubImage1D = gl_save_TexSubImage1D; + table->TexSubImage2D = gl_save_TexSubImage2D; + table->TexParameterfv = gl_save_TexParameterfv; + table->Translatef = gl_save_Translatef; + table->Vertex2f = gl_save_Vertex2f; + table->Vertex3f = gl_save_Vertex3f; + table->Vertex4f = gl_save_Vertex4f; + table->Vertex3fv = gl_save_Vertex3fv; + table->VertexPointer = _gamma_VertexPointer; /* NOT SAVED */ + table->Viewport = gl_save_Viewport; +} #endif diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.h index 37fd75eca..212f91895 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_gl.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_gl.h,v 1.4 2000/03/02 16:07:36 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_gl.h,v 1.5 2001/02/07 13:26:16 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -38,6 +38,8 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "GL/gl.h" #include "glapi.h" +extern void gamma_error(GLenum error, const char *s); + extern void _gamma_Accum(GLenum op, GLfloat value); extern void _gamma_AlphaFunc(GLenum func, GLclampf ref); extern GLboolean _gamma_AreTexturesResident(GLsizei n, const GLuint *textures, GLboolean *residences); @@ -376,6 +378,7 @@ extern void _gamma_VertexPointer(GLint size, GLenum type, GLsizei stride, const extern void _gamma_Viewport(GLint x, GLint y, GLsizei width, GLsizei height); -extern void _gamma_init_dispatch(struct _glapi_table *dispatch); +extern void _gamma_init_exec(struct _glapi_table *dispatch); +extern void _gamma_init_save(struct _glapi_table *dispatch); #endif /* _GAMMA_GL_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h index 6714bbc26..ecf33b959 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_init.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_init.h,v 1.3 2000/06/17 00:02:56 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_init.h,v 1.4 2001/02/07 13:26:16 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -63,11 +63,69 @@ typedef union { #define GAMMA_STENCIL_BUFFER 0x00000008 #define GAMMA_ACCUM_BUFFER 0x00000010 +#define GAMMA_MAX_TEXTURE_SIZE 2048 + /* These are the minimum requirements and should probably be increased */ #define MAX_MODELVIEW_STACK 16 #define MAX_PROJECTION_STACK 2 #define MAX_TEXTURE_STACK 2 +struct gamma_current_attrib { +/* GLubyte ByteColor[4]; old */ /* Current RGBA color */ + GLuint Index; /* Current color index */ + GLfloat Color[4]; /* Current RGBA color */ + GLfloat Normal[3]; /* Current normal vector */ + GLfloat TexCoord[4]; /* points into MultiTexCoord */ + GLfloat RasterPos[4]; /* Current raster position */ + GLfloat RasterDistance; /* Current raster distance */ + GLfloat RasterColor[4]; /* Current raster color */ + GLuint RasterIndex; /* Current raster index */ + GLfloat *RasterTexCoord; /* Current raster texcoord*/ + GLboolean RasterPosValid; /* Raster po valid flag */ + GLboolean EdgeFlag; /* Current edge flag */ +}; + +struct gamma_array_attrib { + GLint VertexSize; + GLenum VertexType; + GLsizei VertexStride; /* user-specified stride */ + GLsizei VertexStrideB; /* actual stride in bytes */ + void *VertexPtr; + GLboolean VertexEnabled; + + GLenum NormalType; + GLsizei NormalStride; /* user-specified stride */ + GLsizei NormalStrideB; /* actual stride in bytes */ + void *NormalPtr; + GLboolean NormalEnabled; + + GLint ColorSize; + GLenum ColorType; + GLsizei ColorStride; /* user-specified stride */ + GLsizei ColorStrideB; /* actual stride in bytes */ + void *ColorPtr; + GLboolean ColorEnabled; + + GLenum IndexType; + GLsizei IndexStride; /* user-specified stride */ + GLsizei IndexStrideB; /* actual stride in bytes */ + void *IndexPtr; + GLboolean IndexEnabled; + + GLsizei EdgeFlagStride; /* user-specified stride */ + GLsizei EdgeFlagStrideB; /* actual stride in bytes */ + GLboolean *EdgeFlagPtr; + GLboolean EdgeFlagEnabled; + + GLint TexCoordSize; + GLenum TexCoordType; + GLsizei TexCoordStride; /* user-specified stride */ + GLsizei TexCoordStrideB; /* actual stride in bytes */ + void *TexCoordPtr; + GLboolean TexCoordEnabled; + GLint TexCoordInterleaveFactor; +}; + typedef struct { drmContext hHWContext; @@ -91,11 +149,34 @@ typedef struct { int EnabledFlags; int DepthSize; int Begin; + GLenum ErrorValue; + + struct _glapi_table *Exec; + struct _glapi_table *Save; + struct _glapi_table *API; + + struct _mesa_HashTable *DisplayList; + + struct gl_list_attrib List; + struct gl_pixelstore_attrib Unpack; /* Pixel unpacking */ + + struct gamma_array_attrib Array; /* From Mesa v3.0 */ + struct gamma_current_attrib Current; /* From Mesa v3.0 */ + + /* Display lists */ + GLuint CallDepth; /* Current recursion calling depth */ + GLboolean ExecuteFlag; /* Execute GL commands? */ + GLboolean CompileFlag; /* Compile GL commands into display list? */ + Node *CurrentListPtr; /* Head of list being compiled */ + GLuint CurrentListNum; /* Number of the list being compiled */ + Node *CurrentBlock; /* Pointer to current block of nodes */ + GLuint CurrentPos; /* Index into current block of nodes */ float ClearColor[4]; float ClearDepth; int MatrixMode; int DepthMode; + int TransformMode; float zNear, zFar; int LBReadMode; int FBReadMode; @@ -110,9 +191,25 @@ typedef struct { int DeltaMode; int ColorMaterialMode; int MaterialMode; + int NormalizeMode; int LightingMode; int Light0Mode; int Light1Mode; + int Light2Mode; + int Light3Mode; + int Light4Mode; + int Light5Mode; + int Light6Mode; + int Light7Mode; + int Light8Mode; + int Light9Mode; + int Light10Mode; + int Light11Mode; + int Light12Mode; + int Light13Mode; + int Light14Mode; + int Light15Mode; + int LogicalOpMode; int ScissorMode; int Window; /* GID part probably should be in draw priv */ diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c index 83cec4bcb..6c87559bf 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c,v 1.6 2000/11/27 10:59:37 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_inithw.c,v 1.7 2001/01/31 16:15:37 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -43,7 +43,7 @@ void gammaInitHW(gammaContextPrivate *gcp) __DRIscreenPrivate *driScrnPriv = gcp->gammaScrnPriv->driScrnPriv; GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv; - if (gDRIPriv->numMXDevices == 2) { + if (gDRIPriv->numMultiDevices == 2) { /* Set up each MX's ScanLineOwnership for OpenGL */ CHECK_DMA_BUFFER(nullCC, gcp, 4); WRITE(gcp->buf, BroadcastMask, 1); @@ -142,7 +142,7 @@ void gammaInitHW(gammaContextPrivate *gcp) WRITE(gcp->buf, AlphaTestMode, gcp->AlphaTestMode); WRITE(gcp->buf, AlphaBlendMode, gcp->AlphaBlendMode); WRITE(gcp->buf, DitherMode, DitherModeEnable | DM_ColorOrder_RGB); - if (gDRIPriv->numMXDevices == 2) + if (gDRIPriv->numMultiDevices == 2) WRITE(gcp->buf, RasterizerMode, RM_MultiGLINT | RM_BiasCoordNearHalf); else WRITE(gcp->buf, RasterizerMode, RM_BiasCoordNearHalf); diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h b/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h index 85c2b925a..613385909 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h,v 1.3 2000/06/17 00:02:56 martin Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_regs.h,v 1.4 2001/02/07 13:26:17 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -487,8 +487,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. /* LightingMode */ #define LightingModeDisable 0x00000000 #define LightingModeEnable 0x00000001 -#define LightingModeTwoSides 0x00000002 +#define LightingModeTwoSides 0x00000004 #define LightingModeLocalViewer 0x00000008 +#define LightingModeSpecularEnable 0x00008000 /* Light0Mode */ #define Light0ModeDisable 0x00000000 @@ -552,6 +553,11 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define PM_AntialiasQuality_4x4 0x00000000 #define PM_AntialiasQuality_8x8 0x00000002 +/* LogicalOpMode */ +#define LogicalOpModeDisable 0x00000000 +#define LogicalOpModeEnable 0x00000001 +#define LogicalOpModeMask 0x0000001e + /* LineMode */ #define LM_StippleDisable 0x00000000 #define LM_StippleEnable 0x00000001 @@ -577,6 +583,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #define XM_XformNormals 0x00000004 #define XM_XformFaceNormals 0x00000008 #define XM_XformTexture 0x00000010 +#define XM_XMask 0x00000013 #define XM_TexGenModeS_None 0x00000000 #define XM_TexGenModeS_ObjLinear 0x00000020 #define XM_TexGenModeS_EyeLinear 0x00000040 diff --git a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c index a442ee913..3a1fa9ae7 100644 --- a/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c,v 1.8 2000/12/07 20:26:05 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/gamma/gamma_xmesa.c,v 1.11 2001/02/07 13:26:17 alanh Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -40,28 +40,28 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "gamma_gl.h" #include "glapi.h" #include "glint_dri.h" +#include "gamma_dlist.h" #include "context.h" #include "mmath.h" +#include "hash.h" __DRIcontextPrivate *nullCC = NULL; __DRIcontextPrivate *gCC = NULL; gammaContextPrivate *gCCPriv = NULL; -static struct _glapi_table *Dispatch = NULL; - - GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { gammaScreenPrivate *gsp; +#if 0 /* Check the DRI version */ { int major, minor, patch; if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { + if (major != 3 || minor != 1 || patch < 0) { char msg[1000]; - sprintf(msg, "gamma DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch); + sprintf(msg, "gamma DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch); __driMesaMessage(msg); return GL_FALSE; } @@ -87,6 +87,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) __driMesaMessage(msg); return GL_FALSE; } +#endif /* Allocate the private area */ gsp = (gammaScreenPrivate *)Xmalloc(sizeof(gammaScreenPrivate)); @@ -148,17 +149,25 @@ GLboolean XMesaCreateContext( Display *dpy, gammaScreenPrivate *gPriv = (gammaScreenPrivate *)driScrnPriv->private; GLINTDRIPtr gDRIPriv = (GLINTDRIPtr)driScrnPriv->pDevPriv; - if (!Dispatch) { - GLuint size = _glapi_get_dispatch_table_size() * sizeof(GLvoid *); - Dispatch = (struct _glapi_table *) malloc(size); - _gamma_init_dispatch(Dispatch); - } - cPriv = (gammaContextPrivate *)Xmalloc(sizeof(gammaContextPrivate)); if (!cPriv) { return GL_FALSE; } + if (!cPriv->Exec) { + GLuint size = _glapi_get_dispatch_table_size() * sizeof(GLvoid *); + cPriv->Exec = (struct _glapi_table *) malloc(size); + _gamma_init_exec(cPriv->Exec); + } + + cPriv->API = cPriv->Exec; + + if (!cPriv->Save) { + GLuint size = _glapi_get_dispatch_table_size() * sizeof(GLvoid *); + cPriv->Save = (struct _glapi_table *) malloc(size); + _gamma_init_save(cPriv->Save); + } + cPriv->hHWContext = driContextPriv->hHWContext; GET_FIRST_DMA(driScrnPriv->fd, cPriv->hHWContext, 1, &cPriv->bufIndex, &cPriv->bufSize, @@ -170,6 +179,54 @@ GLboolean XMesaCreateContext( Display *dpy, &cPriv->WCbuf, &cPriv->WCbufCount, gPriv); #endif + gamma_init_lists(); + + /* Display List stuff */ + cPriv->DisplayList = _mesa_NewHashTable(); + cPriv->List.ListBase = 0; + cPriv->CallDepth = 0; + cPriv->ExecuteFlag = GL_TRUE; + cPriv->CompileFlag = GL_FALSE; + cPriv->CurrentListPtr = NULL; + cPriv->CurrentBlock = NULL; + cPriv->CurrentListNum = 0; + cPriv->CurrentPos = 0; + + /* Vertex arrays */ + cPriv->Array.VertexSize = 4; + cPriv->Array.VertexType = GL_FLOAT; + cPriv->Array.VertexStride = 0; + cPriv->Array.VertexStrideB = 0; + cPriv->Array.VertexPtr = NULL; + cPriv->Array.VertexEnabled = GL_FALSE; + cPriv->Array.NormalType = GL_FLOAT; + cPriv->Array.NormalStride = 0; + cPriv->Array.NormalStrideB = 0; + cPriv->Array.NormalPtr = NULL; + cPriv->Array.NormalEnabled = GL_FALSE; + cPriv->Array.ColorSize = 4; + cPriv->Array.ColorType = GL_FLOAT; + cPriv->Array.ColorStride = 0; + cPriv->Array.ColorStrideB = 0; + cPriv->Array.ColorPtr = NULL; + cPriv->Array.ColorEnabled = GL_FALSE; + cPriv->Array.IndexType = GL_FLOAT; + cPriv->Array.IndexStride = 0; + cPriv->Array.IndexStrideB = 0; + cPriv->Array.IndexPtr = NULL; + cPriv->Array.IndexEnabled = GL_FALSE; + cPriv->Array.EdgeFlagStride = 0; + cPriv->Array.EdgeFlagStrideB = 0; + cPriv->Array.EdgeFlagPtr = NULL; + cPriv->Array.EdgeFlagEnabled = GL_FALSE; + + cPriv->Unpack.Alignment = 4; + cPriv->Unpack.RowLength = 0; + cPriv->Unpack.SkipPixels = 0; + cPriv->Unpack.SkipRows = 0; + cPriv->Unpack.SwapBytes = GL_FALSE; + cPriv->Unpack.LsbFirst = GL_FALSE; + cPriv->ClearColor[0] = 0.0; cPriv->ClearColor[1] = 0.0; cPriv->ClearColor[2] = 0.0; @@ -208,7 +265,7 @@ GLboolean XMesaCreateContext( Display *dpy, FBWindowOriginBot | gDRIPriv->pprod); - if (gDRIPriv->numMXDevices == 2) { + if (gDRIPriv->numMultiDevices == 2) { cPriv->LBReadMode |= LBScanLineInt2; cPriv->FBReadMode |= FBScanLineInt2; cPriv->FBWindowBase =driScrnPriv->fbWidth*(driScrnPriv->fbHeight/2 - 1); @@ -354,14 +411,32 @@ GLboolean XMesaCreateContext( Display *dpy, cPriv->gammaScrnPriv = gPriv; - cPriv->LightingMode = LightingModeDisable; + cPriv->LightingMode = LightingModeDisable | LightingModeSpecularEnable; cPriv->Light0Mode = LNM_Off; cPriv->Light1Mode = LNM_Off; + cPriv->Light2Mode = LNM_Off; + cPriv->Light3Mode = LNM_Off; + cPriv->Light4Mode = LNM_Off; + cPriv->Light5Mode = LNM_Off; + cPriv->Light6Mode = LNM_Off; + cPriv->Light7Mode = LNM_Off; + cPriv->Light8Mode = LNM_Off; + cPriv->Light9Mode = LNM_Off; + cPriv->Light10Mode = LNM_Off; + cPriv->Light11Mode = LNM_Off; + cPriv->Light12Mode = LNM_Off; + cPriv->Light13Mode = LNM_Off; + cPriv->Light14Mode = LNM_Off; + cPriv->Light15Mode = LNM_Off; + + cPriv->LogicalOpMode = LogicalOpModeDisable; cPriv->MaterialMode = MaterialModeDisable; cPriv->ScissorMode = UserScissorDisable | ScreenScissorDisable; + cPriv->TransformMode = XM_UseModelViewProjMatrix; + driContextPriv->driverPrivate = cPriv; /* Initialize the HW to a known state */ @@ -511,7 +586,7 @@ GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, CHECK_DMA_BUFFER(gCC, gCCPriv, 1); WRITE(gCCPriv->buf, GLINTWindow, gCCPriv->Window); - _glapi_set_dispatch(Dispatch); + _glapi_set_dispatch(gCCPriv->API); _gamma_Viewport(0, 0, driDrawPriv->w, driDrawPriv->h); } else { diff --git a/xc/lib/GL/mesa/src/drv/i810/Imakefile b/xc/lib/GL/mesa/src/drv/i810/Imakefile index 570c1bad9..1ef237343 100644 --- a/xc/lib/GL/mesa/src/drv/i810/Imakefile +++ b/xc/lib/GL/mesa/src/drv/i810/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i810/Imakefile,v 1.13 2000/12/12 23:24:27 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/i810/Imakefile,v 1.14 2001/02/16 01:26:10 dawes Exp $ #include <Threads.tmpl> @@ -354,7 +354,7 @@ NormalLintTarget($(SRCS)) LIBNAME = i810_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE -SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +SharedDriModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) #ifdef GlxSoProf diff --git a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c index 43d1d4973..f5aecb98e 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c,v 1.9 2000/12/07 20:26:06 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/i810/i810_xmesa.c,v 1.11 2000/12/21 14:06:56 alanh Exp $ */ /* * Authors: @@ -135,9 +135,9 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { int major, minor, patch; if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { + if (major != 3 || minor != 1 || patch < 0) { char msg[1000]; - sprintf(msg, "i810 DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch); + sprintf(msg, "i810 DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch); __driMesaMessage(msg); return GL_FALSE; } @@ -159,7 +159,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) sPriv->drmMinor != 1 || sPriv->drmPatch < 0) { char msg[1000]; - sprintf(msg, "i810 DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + sprintf(msg, "i810 DRI driver expected DRM driver version 1.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); __driMesaMessage(msg); return GL_FALSE; } diff --git a/xc/lib/GL/mesa/src/drv/i810/i810tex.c b/xc/lib/GL/mesa/src/drv/i810/i810tex.c index 299a2ce86..5c1615128 100644 --- a/xc/lib/GL/mesa/src/drv/i810/i810tex.c +++ b/xc/lib/GL/mesa/src/drv/i810/i810tex.c @@ -194,10 +194,10 @@ static i810TextureObjectPtr i810CreateTexObj(i810ContextPtr imesa, switch( image->Format ) { case GL_RGB: case GL_LUMINANCE: - case GL_ALPHA: t->texelBytes = 2; textureFormat = MI1_FMT_16BPP | MI1_PF_16BPP_RGB565; break; + case GL_ALPHA: case GL_LUMINANCE_ALPHA: case GL_INTENSITY: case GL_RGBA: diff --git a/xc/lib/GL/mesa/src/drv/mga/Imakefile b/xc/lib/GL/mesa/src/drv/mga/Imakefile index 62fecb053..fa7af7f93 100644 --- a/xc/lib/GL/mesa/src/drv/mga/Imakefile +++ b/xc/lib/GL/mesa/src/drv/mga/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.13 2000/12/12 23:24:28 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/mga/Imakefile,v 1.15 2001/02/16 01:26:11 dawes Exp $ #include <Threads.tmpl> @@ -63,6 +63,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ mgafastpath.c \ mgaioctl.c \ mgapipeline.c \ + mgapixel.c \ mgaspan.c \ mgastate.c \ mgatex.c \ @@ -78,6 +79,7 @@ MESA_INCLUDES = -I. -I.. -I../../include \ mgafastpath.o \ mgaioctl.o \ mgapipeline.o \ + mgapixel.o \ mgaspan.o \ mgastate.o \ mgatex.o \ @@ -362,7 +364,7 @@ NormalLintTarget($(SRCS)) LIBNAME = mga_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE -SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +SharedDriModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) #ifdef GlxSoProf diff --git a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c index 7524a52a1..ddbba0eea 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.8 2000/12/07 20:26:06 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mga_xmesa.c,v 1.10 2001/01/08 01:07:18 martin Exp $ */ /************************************************************************** Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas. @@ -53,6 +53,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mgatris.h" #include "mgapipeline.h" #include "mgabuffers.h" +#include "mgapixel.h" #include "xf86dri.h" #include "mga_xmesa.h" @@ -106,9 +107,9 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { int major, minor, patch; if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { + if (major != 3 || minor != 1 || patch < 0) { char msg[1000]; - sprintf(msg, "MGA DRI driver expected DRI version 3.0.x but got version %d.%d.%d", major, minor, patch); + sprintf(msg, "MGA DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch); __driMesaMessage(msg); return GL_FALSE; } @@ -127,18 +128,21 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) /* Check that the DRM driver version is compatible */ if (sPriv->drmMajor != 2 || - sPriv->drmMinor != 0 || + sPriv->drmMinor != 1 || sPriv->drmPatch < 0) { char msg[1000]; - sprintf(msg, "MGA DRI driver expected DRM driver version 2.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + sprintf(msg, "MGA DRI driver expected DRM driver version 2.{0,1}.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); __driMesaMessage(msg); return GL_FALSE; } + /* Allocate the private area */ mgaScreen = (mgaScreenPrivate *)MALLOC(sizeof(mgaScreenPrivate)); - if (!mgaScreen) + if (!mgaScreen) { + __driMesaMessage("Couldn't malloc screen struct"); return GL_FALSE; + } mgaScreen->sPriv = sPriv; sPriv->private = (void *)mgaScreen; @@ -147,6 +151,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) serverInfo->chipset != MGA_CARD_TYPE_G400) { XFree(mgaScreen); sPriv->private = NULL; + __driMesaMessage("Unrecognized chipset"); return GL_FALSE; } @@ -174,6 +179,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) { Xfree(mgaScreen); sPriv->private = NULL; + __driMesaMessage("Couldn't map agp region"); return GL_FALSE; } @@ -206,6 +212,7 @@ GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) /*drmUnmap(mgaScreen->agp_tex.map, mgaScreen->agp_tex.size);*/ XFree(mgaScreen); sPriv->private = NULL; + __driMesaMessage("Couldn't map dma buffers"); return GL_FALSE; } @@ -326,14 +333,6 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, mmesa->hw_stencil = mesaVis->StencilBits && mesaVis->DepthBits == 24; -/* fprintf(stderr, */ -/* "mesaVis->DepthBits: %d " */ -/* "mmesa->glCtx->Visual->DepthBits: %d " */ -/* "mmesa->glCtx->Visual->DepthMax: %x\n", */ -/* mesaVis->DepthBits, */ -/* ctx->Visual->DepthBits, */ -/* ctx->Visual->DepthMax); */ - switch (mesaVis->DepthBits) { case 16: mmesa->depth_scale = 1.0/(GLdouble)0xffff; @@ -377,6 +376,7 @@ GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, mgaDDInitSpanFuncs( ctx ); mgaDDInitDriverFuncs( ctx ); mgaDDInitIoctlFuncs( ctx ); + mgaDDInitPixelFuncs( ctx ); ctx->Driver.TriangleCaps = (DD_TRI_CULL| @@ -530,7 +530,8 @@ void mgaGetLock( mgaContextPtr mmesa, GLuint flags ) drmGetLock(mmesa->driFd, mmesa->hHWContext, flags); - if (*(dPriv->pStamp) != dPriv->lastStamp) { + if (*(dPriv->pStamp) != mmesa->lastStamp) { + mmesa->lastStamp = *(dPriv->pStamp); mmesa->setupdone = 0; mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK); mgaUpdateRects( mmesa, (MGA_FRONT|MGA_BACK) ); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c index 75d322c47..5568024d8 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgabuffers.c @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.4 2000/09/24 13:51:05 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgabuffers.c,v 1.5 2001/01/08 01:07:18 martin Exp $ */ /* * Authors: @@ -78,7 +78,7 @@ static void mgaXMesaSetBackClipRects( mgaContextPtr mmesa ) } - +#if 0 static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa ) { __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; @@ -128,7 +128,7 @@ static void mgaUpdateRectsFromSarea( mgaContextPtr mmesa ) mmesa->dirty_cliprects = (MGA_FRONT|MGA_BACK) & ~(sarea->exported_buffers); } - +#endif static void printSareaRects( mgaContextPtr mmesa ) @@ -205,45 +205,22 @@ void mgaUpdateRects( mgaContextPtr mmesa, GLuint buffers ) __DRIdrawablePrivate *driDrawable = mmesa->driDrawable; drm_mga_sarea_t *sarea = mmesa->sarea; - /* The MGA X driver will try to push one set of cliprects (back or - * front, the last active) for one drawable (the last used) into - * the sarea. See if that window was ours, else retrieve both back - * and front rects from the X server via a protocol request. - * - * If there isn't room for the cliprects in the sarea, the X server - * clears the drawable value to indicate failure. - */ - if (0) printSareaRects(mmesa); - - if (0 && - sarea->exported_drawable == driDrawable->draw && - (sarea->exported_buffers & buffers) == buffers) - { - mgaUpdateRectsFromSarea( mmesa ); - } - else - { - if(MGA_DEBUG & DEBUG_VERBOSE_MSG) - fprintf(stderr, "^"); - driDrawable->lastStamp = 0; - - XMESA_VALIDATE_DRAWABLE_INFO(mmesa->display, - mmesa->driScreen, - driDrawable); - mmesa->dirty_cliprects = 0; - } +/* fprintf(stderr, "%s\n", __FUNCTION__); */ + + XMESA_VALIDATE_DRAWABLE_INFO(mmesa->display, + mmesa->driScreen, + driDrawable); + mmesa->dirty_cliprects = 0; if (mmesa->draw_buffer == MGA_FRONT) mgaXMesaSetFrontClipRects( mmesa ); else mgaXMesaSetBackClipRects( mmesa ); - - if (0) printMmesaRects(mmesa); +/* printMmesaRects(mmesa); */ sarea->req_drawable = driDrawable->draw; sarea->req_draw_buffer = mmesa->draw_buffer; - mgaUpdateClipping( mmesa->glCtx ); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h index 1f6ffc6c6..46ccae02f 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgacontext.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgacontext.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.1 2000/09/24 13:51:06 alanh Exp $*/ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgacontext.h,v 1.2 2001/01/08 01:07:18 martin Exp $*/ /* * GLX Hardware Device Driver for Matrox Millenium G200 * Copyright (C) 1999 Wittawat Yamwong @@ -117,7 +117,8 @@ typedef struct mga_texture_object_s struct mga_context_t { GLcontext *glCtx; - + GLuint lastStamp; /* fullscreen breaks dpriv->laststamp, + * need to shadow it here. */ /* Bookkeeping for texturing */ @@ -175,8 +176,8 @@ struct mga_context_t { GLuint Setup[MGA_CTX_SETUP_SIZE]; GLuint warp_pipe; GLuint vertsize; - GLushort MonoColor; - GLushort ClearColor; + GLuint MonoColor; + GLuint ClearColor; GLuint ClearDepth; GLuint poly_stipple; GLfloat depth_scale; @@ -250,6 +251,9 @@ struct mga_context_t { #define MGAPACKCOLOR565(r,g,b) \ ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) +#define MGAPACKCOLOR88(l, a) \ + (((l) << 8) | (a)) + #define MGAPACKCOLOR888(r,g,b) \ (((r) << 16) | ((g) << 8) | (b)) diff --git a/xc/lib/GL/mesa/src/drv/mga/mgadd.c b/xc/lib/GL/mesa/src/drv/mga/mgadd.c index f9c3357ce..93ecfdf28 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgadd.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgadd.c @@ -23,7 +23,7 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.6 2000/11/08 05:02:45 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgadd.c,v 1.7 2001/01/08 01:07:18 martin Exp $ */ @@ -114,6 +114,12 @@ void mgaDDExtensionsInit( GLcontext *ctx ) if (MGA_IS_G400(MGA_CONTEXT(ctx))) { gl_extensions_enable( ctx, "GL_EXT_texture_env_add" ); + gl_extensions_enable( ctx, "GL_MESA_packed_depth_stencil" ); + +#if defined (MESA_experimetal_agp_allocator) + if (!getenv("MGA_DISABLE_AGP_ALLOCATOR")) + gl_extensions_enable( ctx, "GL_MESA_experimental_agp_allocator" ); +#endif } /* we don't support point parameters in hardware yet */ diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c index 8d31caa1d..46ff452b1 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.8 2000/11/08 05:02:45 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.c,v 1.9 2001/01/08 01:07:18 martin Exp $ */ #include <stdio.h> @@ -19,9 +19,6 @@ #include "drm.h" #include <sys/ioctl.h> -#define DEPTH_SCALE_16 ((GLfloat)0xffff) -#define DEPTH_SCALE_32 ((GLfloat)0xffffffff) - static void mga_iload_dma_ioctl(mgaContextPtr mmesa, unsigned long dest, int length) @@ -162,8 +159,6 @@ GLbitfield mgaClear( GLcontext *ctx, GLbitfield mask, GLboolean all, int i; static int nrclears; - if (0) fprintf(stderr, "clear %d: %d,%d %dx%d\n", all,cx,cy,cw,ch); - clear.flags = 0; clear.clear_color = mmesa->ClearColor; clear.clear_depth = 0; @@ -308,8 +303,6 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) pbox = dPriv->pClipRects; nbox = dPriv->numClipRects; - if (0) fprintf(stderr, "swap, nbox %d\n", nbox); - for (i = 0 ; i < nbox ; ) { int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); @@ -320,20 +313,11 @@ void mgaSwapBuffers( mgaContextPtr mmesa ) for ( ; i < nr ; i++) *b++ = pbox[i]; - if (0) - fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n"); - -#if 1 if((retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_SWAP, &swap))) { printf("send swap retcode = %d\n", retcode); + UNLOCK_HARDWARE( mmesa ); exit(1); } -#else - mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); -#endif - - if (0) - fprintf(stderr, "finished swap %d\n", ++nrswaps); } tmp = GET_ENQUEUE_AGE(mmesa); @@ -371,7 +355,6 @@ void mgaDDFinish( GLcontext *ctx ) void mgaWaitAgeLocked( mgaContextPtr mmesa, int age ) { if (GET_DISPATCH_AGE(mmesa) < age) { - if (0) fprintf(stderr, "\n\n\nmgaWaitAgeLocked\n"); mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); } } @@ -382,7 +365,6 @@ void mgaWaitAge( mgaContextPtr mmesa, int age ) if (GET_DISPATCH_AGE(mmesa) < age) { LOCK_HARDWARE(mmesa); if (GET_DISPATCH_AGE(mmesa) < age) { - if (0) fprintf(stderr, "\n\n\nmgaWaitAge\n"); mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); } UNLOCK_HARDWARE(mmesa); @@ -436,14 +418,6 @@ void mgaFlushVerticesLocked( mgaContextPtr mmesa ) */ mmesa->sarea->dirty |= MGA_UPLOAD_CTX; - /* FIXME: dstorg bug - */ - if (0) - if (mmesa->lastX != mmesa->drawX || mmesa->lastY != mmesa->drawY) - fprintf(stderr, "****** last: %d,%d current: %d,%d\n", - mmesa->lastX, mmesa->lastY, - mmesa->drawX, mmesa->drawY); - vertex.idx = buffer->idx; vertex.used = buffer->used; vertex.discard = 0; @@ -454,6 +428,7 @@ void mgaFlushVerticesLocked( mgaContextPtr mmesa ) if (nbox >= MGA_NR_SAREA_CLIPRECTS) mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; +#if 0 if (!vertex.used || !(mmesa->dirty & MGA_UPLOAD_CLIPRECTS)) { if (nbox == 1) @@ -469,6 +444,7 @@ void mgaFlushVerticesLocked( mgaContextPtr mmesa ) age_mmesa(mmesa, mmesa->sarea->last_enqueue); } else +#endif { for (i = 0 ; i < nbox ; ) { @@ -596,6 +572,18 @@ void mgaGetILoadBufferLocked( mgaContextPtr mmesa ) mmesa->iload_buffer = mga_get_buffer_ioctl( mmesa ); } +drmBufPtr mgaGetBufferLocked( mgaContextPtr mmesa ) +{ + return mga_get_buffer_ioctl( mmesa ); +} + +void mgaGetEltBufLocked( mgaContextPtr mmesa ) +{ + mmesa->elt_buf = mga_get_buffer_ioctl( mmesa ); +} + + + void mgaDDFlush( GLcontext *ctx ) { @@ -609,7 +597,6 @@ void mgaDDFlush( GLcontext *ctx ) */ if (1 || GET_DISPATCH_AGE( mmesa ) < mmesa->sarea->last_enqueue) { LOCK_HARDWARE( mmesa ); - if (0) fprintf(stderr, "mgaDDFlush %d %d\n", GET_DISPATCH_AGE( mmesa ), mmesa->sarea->last_enqueue); mgaUpdateLock( mmesa, DRM_LOCK_FLUSH ); UNLOCK_HARDWARE( mmesa ); } @@ -628,9 +615,6 @@ void mgaFireEltsLocked( mgaContextPtr mmesa, drm_mga_indices_t elts; int i; - - if (0) fprintf(stderr, "FireElts %d %d\n", start/4, end/4); - if (!buffer) return; @@ -662,8 +646,6 @@ void mgaFireEltsLocked( mgaContextPtr mmesa, else mmesa->sarea->nbox = nbox; - if (0) - fprintf(stderr, "Firing elts -- case a nbox %d\n", nbox); elts.discard = discard; ioctl(mmesa->driFd, DRM_IOCTL_MGA_INDICES, &elts); @@ -704,8 +686,6 @@ void mgaFireEltsLocked( mgaContextPtr mmesa, if (nr == nbox) elts.discard = discard; - if (0) - fprintf(stderr, "Firing elts -- case b nbox %d\n", nbox); mmesa->sarea->dirty |= MGA_UPLOAD_CLIPRECTS; ioctl(mmesa->driFd, DRM_IOCTL_MGA_INDICES, &elts); @@ -716,10 +696,6 @@ void mgaFireEltsLocked( mgaContextPtr mmesa, mmesa->dirty &= ~MGA_UPLOAD_CLIPRECTS; } -void mgaGetEltBufLocked( mgaContextPtr mmesa ) -{ - mmesa->elt_buf = mga_get_buffer_ioctl( mmesa ); -} void mgaReleaseBufLocked( mgaContextPtr mmesa, drmBufPtr buffer ) { diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h index 869d50160..72e1fe29b 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaioctl.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.5 2000/09/24 13:51:07 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaioctl.h,v 1.6 2001/01/08 01:07:18 martin Exp $ */ #ifndef MGA_IOCTL_H #define MGA_IOCTL_H @@ -18,6 +18,7 @@ GLuint *mgaAllocVertexDwords( mgaContextPtr mmesa, int dwords ); void mgaGetILoadBufferLocked( mgaContextPtr mmesa ); +drmBufPtr mgaGetBufferLocked( mgaContextPtr mmesa ); void mgaFireILoadLocked( mgaContextPtr mmesa, diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapixel.c b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c new file mode 100644 index 000000000..e28ead85b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgapixel.c @@ -0,0 +1,635 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.c,v 1.1 2001/01/08 01:07:18 martin Exp $ */ +/************************************************************************** + +Copyright 2000 Compaq Computer Inc. and VA Linux, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#include "enums.h" +#include "types.h" +#include "texutil.h" +#include "mgadd.h" +#include "mgacontext.h" +#include "mgaioctl.h" +#include "mgapixel.h" +#include "mgabuffers.h" + +#include "drm.h" +#include <sys/ioctl.h> + +#define IS_AGP_MEM(mmesa, p) \ + (mmesa->mgaScreen->agp.map <= ((char *)p) && \ + mmesa->mgaScreen->agp.map + \ + mmesa->mgaScreen->agp.size > ((char *)p)) +#define AGP_OFFSET(mmesa, p) \ + (((char *)p) - mmesa->mgaScreen->agp.map ) + + +#if defined(MESA_packed_depth_stencil) +static GLboolean +check_depth_stencil_24_8( const GLcontext *ctx, GLenum type, + const struct gl_pixelstore_attrib *packing, + const void *pixels, GLint sz, + GLint pitch ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + return (type == GL_UNSIGNED_INT_24_8_MESA && + ctx->Visual->DepthBits == 24 && + ctx->Visual->StencilBits == 8 && + mmesa->mgaScreen->cpp == 4 && + mmesa->hw_stencil && + !ctx->Pixel.IndexShift && + !ctx->Pixel.IndexOffset && + !ctx->Pixel.MapStencilFlag && + ctx->Pixel.DepthBias == 0.0 && + ctx->Pixel.DepthScale == 1.0 && + !packing->SwapBytes && + pitch % 32 == 0 && + pitch < 4096); + +} +#endif + + +static GLboolean +check_depth( const GLcontext *ctx, GLenum type, + const struct gl_pixelstore_attrib *packing, + const void *pixels, GLint sz, GLint pitch ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + if (IS_AGP_MEM(mmesa, pixels) && + !((type == GL_UNSIGNED_INT && mmesa->mgaScreen->cpp == 4) || + (type == GL_UNSIGNED_SHORT && mmesa->mgaScreen->cpp == 2))) + return GL_FALSE; + + return (ctx->Pixel.DepthBias == 0.0 && + ctx->Pixel.DepthScale == 1.0 && + !packing->SwapBytes && + pitch % 32 == 0 && + pitch < 4096); +} + + +static GLboolean +check_color( const GLcontext *ctx, GLenum type, GLenum format, + const struct gl_pixelstore_attrib *packing, + const void *pixels, GLint sz, GLint pitch ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + GLuint cpp = mmesa->mgaScreen->cpp; + + /* Can't do conversions on agp reads/draws. + */ + if (IS_AGP_MEM(mmesa, pixels) && + !(pitch % 32 == 0 && + pitch < 4096 && + ((type == GL_UNSIGNED_BYTE && cpp == 4 && format == GL_BGRA) || + (type == GL_UNSIGNED_INT_8_8_8_8 && cpp == 4 && format == GL_BGRA) || + (type == GL_UNSIGNED_SHORT_5_6_5_REV && cpp==2 && format == GL_RGB)))) + return GL_FALSE; + + return + (ctx->ColorMatrix.type == MATRIX_IDENTITY && + !ctx->Pixel.ScaleOrBiasRGBA && + !ctx->Pixel.ScaleOrBiasRGBApcm && + !ctx->Pixel.MapColorFlag && + !ctx->Pixel.ColorTableEnabled && + !ctx->Pixel.PostColorMatrixColorTableEnabled && + !ctx->Pixel.MinMaxEnabled && + !ctx->Pixel.HistogramEnabled && + !packing->SwapBytes && + !packing->LsbFirst); +} + +static GLboolean +check_color_per_fragment_ops( const GLcontext *ctx ) +{ + return (!(ctx->RasterMask & ~(SCISSOR_BIT|WINCLIP_BIT|MULTI_DRAW_BIT)) && + ctx->Current.RasterPosValid && + ctx->Pixel.ZoomX == 1.0F && + (ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F)); +} + +static GLboolean +check_depth_per_fragment_ops( const GLcontext *ctx ) +{ + return (ctx->Current.RasterPosValid && + ctx->Color.ColorMask[RCOMP] == 0 && + ctx->Color.ColorMask[BCOMP] == 0 && + ctx->Color.ColorMask[GCOMP] == 0 && + ctx->Color.ColorMask[ACOMP] == 0 && + ctx->Pixel.ZoomX == 1.0F && + (ctx->Pixel.ZoomY == 1.0F || ctx->Pixel.ZoomY == -1.0F)); +} + +/* In addition to the requirements for depth: + */ +#if defined(MESA_packed_depth_stencil) +static GLboolean +check_stencil_per_fragment_ops( const GLcontext *ctx ) +{ + return (!ctx->Pixel.IndexShift && + !ctx->Pixel.IndexOffset); +} +#endif + + +static GLboolean +clip_pixelrect( const GLcontext *ctx, + const GLframebuffer *buffer, + GLint *x, GLint *y, + GLsizei *width, GLsizei *height, + GLint *skipPixels, GLint *skipRows, + GLint *size ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + *width = MIN2(*width, MAX_WIDTH); /* redundant? */ + + /* left clipping */ + if (*x < buffer->Xmin) { + *skipPixels += (buffer->Xmin - *x); + *width -= (buffer->Xmin - *x); + *x = buffer->Xmin; + } + + /* right clipping */ + if (*x + *width > buffer->Xmax) + *width -= (*x + *width - buffer->Xmax - 1); + + if (*width <= 0) + return GL_FALSE; + + /* bottom clipping */ + if (*y < buffer->Ymin) { + *skipRows += (buffer->Ymin - *y); + *height -= (buffer->Ymin - *y); + *y = buffer->Ymin; + } + + /* top clipping */ + if (*y + *height > buffer->Ymax) + *height -= (*y + *height - buffer->Ymax - 1); + + if (*height <= 0) + return GL_FALSE; + + *size = ((*y + *height - 1) * mmesa->mgaScreen->frontPitch + + (*x + *width - 1) * mmesa->mgaScreen->cpp); + + return GL_TRUE; +} + +static GLboolean +mgaDDReadPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + drm_mga_blit_t blit; + GLint size, skipPixels, skipRows; + GLint pitch = pack->RowLength ? pack->RowLength : width; + GLboolean ok; + + if (!clip_pixelrect(ctx, ctx->ReadBuffer, + &x, &y, &width, &height, + &skipPixels, &skipRows, &size)) { + return GL_TRUE; + } + + /* Only accelerate reading to agp buffers. + */ + if ( !IS_AGP_MEM(mmesa, (char *)pixels) || + !IS_AGP_MEM(mmesa, (char *)pixels + size) ) + return GL_FALSE; + + switch (format) { +#if defined(MESA_packed_depth_stencil) + case GL_DEPTH_STENCIL_MESA: + ok = check_depth_stencil_24_8(ctx, type, pack, pixels, size, pitch); + blit.planemask = ~0; + blit.source = mmesa->mgaScreen->depthOffset; + break; +#endif + + case GL_DEPTH_COMPONENT: + ok = check_depth(ctx, type, pack, pixels, size, pitch); + + /* Can't accelerate at this depth -- planemask does the wrong + * thing; it doesn't clear the low order bits in the + * destination, instead it leaves them untouched. + * + * Could get the acclerator to solid fill the destination with + * zeros first... Or get the cpu to do it... + */ + if (ctx->Visual->DepthBits == 24) + return GL_FALSE; + + blit.planemask = ~0; + blit.source = mmesa->mgaScreen->depthOffset; + break; + + case GL_RGB: + case GL_BGRA: + ok = check_color(ctx, type, format, pack, pixels, size, pitch); + blit.planemask = ~0; + blit.source = (mmesa->draw_buffer == MGA_FRONT ? + mmesa->mgaScreen->frontOffset : + mmesa->mgaScreen->backOffset); + break; + + default: + return GL_FALSE; + } + + if (!ok) { + return GL_FALSE; + } + + + LOCK_HARDWARE( mmesa ); + + { + __DRIdrawablePrivate *dPriv = mmesa->driDrawable; + int nbox, retcode, i; + + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); + + if (mmesa->dirty_cliprects & MGA_FRONT) + mgaUpdateRects( mmesa, MGA_FRONT ); + + nbox = dPriv->numClipRects; + + y = dPriv->h - y - height; + x += mmesa->drawX; + y += mmesa->drawY; + + blit.dest = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) | + DO_dstmap_sys | DO_dstacc_agp); + blit.source_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp; + blit.dest_pitch = pitch; + blit.delta_sx = 0; + blit.delta_sy = 0; + blit.delta_dx = -x; + blit.delta_dy = -y; + blit.height = 2*y + height; + blit.ydir = -1; + + if (0) fprintf(stderr, "XX doing readpixel blit src_pitch %d dst_pitch %d\n", + blit.source_pitch, blit.dest_pitch); + + + + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + XF86DRIClipRectRec *box = dPriv->pClipRects; + drm_clip_rect_t *b = mmesa->sarea->boxes; + int n = 0; + + for ( ; i < nr ; i++) { + GLint bx = box[i].x1; + GLint by = box[i].y1; + GLint bw = box[i].x2 - bx; + GLint bh = box[i].y2 - by; + + if (bx < x) bw -= x - bx, bx = x; + if (by < y) bh -= y - by, by = y; + if (bx + bw > x + width) bw = x + width - bx; + if (by + bh > y + height) bh = y + height - by; + if (bw <= 0) continue; + if (bh <= 0) continue; + + b->x1 = bx; + b->y1 = by; + b->x2 = bx + bw; + b->y2 = by + bh; + b++; + n++; + } + + mmesa->sarea->nbox = n; + + if (n && (retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_BLIT, &blit))) { + fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode); + UNLOCK_HARDWARE( mmesa ); + exit(1); + } + } + + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); + } + + UNLOCK_HARDWARE( mmesa ); + + return GL_TRUE; +} + + + +static void do_draw_pix( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLint pitch, + const void *pixels, + GLuint dest, GLuint planemask) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + drm_mga_blit_t blit; + __DRIdrawablePrivate *dPriv = mmesa->driDrawable; + XF86DRIClipRectPtr pbox = dPriv->pClipRects; + int nbox = dPriv->numClipRects; + int retcode, i; + + y = dPriv->h - y - height; + x += mmesa->drawX; + y += mmesa->drawY; + + blit.dest = dest; + blit.planemask = planemask; + blit.source = ((mmesa->mgaScreen->agp.handle + AGP_OFFSET(mmesa, pixels)) + | SO_srcmap_sys | SO_srcacc_agp); + blit.dest_pitch = mmesa->mgaScreen->frontPitch / mmesa->mgaScreen->cpp; + blit.source_pitch = pitch; + blit.delta_sx = -x; + blit.delta_sy = -y; + blit.delta_dx = 0; + blit.delta_dy = 0; + if (ctx->Pixel.ZoomY == -1) { + blit.height = height; + blit.ydir = 1; + } else { + blit.height = height; + blit.ydir = -1; + } + + if (0) fprintf(stderr, + "doing drawpixel blit src_pitch %d dst_pitch %d\n", + blit.source_pitch, blit.dest_pitch); + + for (i = 0 ; i < nbox ; ) + { + int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects); + XF86DRIClipRectRec *box = mmesa->pClipRects; + drm_clip_rect_t *b = mmesa->sarea->boxes; + int n = 0; + + for ( ; i < nr ; i++) { + GLint bx = box[i].x1; + GLint by = box[i].y1; + GLint bw = box[i].x2 - bx; + GLint bh = box[i].y2 - by; + + if (bx < x) bw -= x - bx, bx = x; + if (by < y) bh -= y - by, by = y; + if (bx + bw > x + width) bw = x + width - bx; + if (by + bh > y + height) bh = y + height - by; + if (bw <= 0) continue; + if (bh <= 0) continue; + + b->x1 = bx; + b->y1 = by; + b->x2 = bx + bw; + b->y2 = by + bh; + b++; + n++; + } + + mmesa->sarea->nbox = n; + + if (n && (retcode = ioctl(mmesa->driFd, DRM_IOCTL_MGA_BLIT, &blit))) { + fprintf(stderr, "blit ioctl failed, retcode = %d\n", retcode); + UNLOCK_HARDWARE( mmesa ); + exit(1); + } + } +} + + + + +static GLboolean +mgaDDDrawPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + GLint size, skipPixels, skipRows; + GLint pitch = unpack->RowLength ? unpack->RowLength : width; + GLuint dest, planemask; + GLuint cpp = mmesa->mgaScreen->cpp; + + if (!clip_pixelrect(ctx, ctx->DrawBuffer, + &x, &y, &width, &height, + &skipPixels, &skipRows, &size)) { + return GL_TRUE; + } + + + switch (format) { +#if defined(MESA_packed_depth_stencil) + case GL_DEPTH_STENCIL_MESA: + dest = mmesa->mgaScreen->depthOffset; + planemask = ~0; + if (!check_depth_stencil_24_8(ctx, type, unpack, pixels, size, pitch) || + !check_depth_per_fragment_ops(ctx) || + !check_stencil_per_fragment_ops(ctx)) + return GL_FALSE; + break; +#endif + + case GL_DEPTH_COMPONENT: + dest = mmesa->mgaScreen->depthOffset; + + if (ctx->Visual->DepthBits == 24) + planemask = ~0xff; + else + planemask = ~0; + + if (!check_depth(ctx, type, unpack, pixels, size, pitch) || + !check_depth_per_fragment_ops(ctx)) + return GL_FALSE; + break; + + case GL_RGB: + case GL_BGRA: + dest = (mmesa->draw_buffer == MGA_FRONT ? + mmesa->mgaScreen->frontOffset : + mmesa->mgaScreen->backOffset); + + planemask = mgaPackColor(cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP]); + + if (cpp == 2) + planemask |= planemask << 16; + + if (!check_color(ctx, type, format, unpack, pixels, size, pitch)) { + return GL_FALSE; + } + if (!check_color_per_fragment_ops(ctx)) { + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + LOCK_HARDWARE( mmesa ); + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); + + if (mmesa->dirty_cliprects & MGA_FRONT) + mgaUpdateRects( mmesa, MGA_FRONT ); + + if ( IS_AGP_MEM(mmesa, (char *)pixels) && + IS_AGP_MEM(mmesa, (char *)pixels + size) ) + { + do_draw_pix( ctx, x, y, width, height, pitch, pixels, + dest, planemask ); + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); + } + else + { + /* Pixels is in regular memory -- get dma buffers and perform + * upload through them. + */ +/* drmBufPtr buf = mgaGetBufferLocked(mmesa); */ + GLuint bufferpitch = (width*cpp+31)&~31; + char *address = mmesa->mgaScreen->agp.map; + + do { +/* GLuint rows = MIN2( height, MGA_DMA_BUF_SZ / bufferpitch ); */ + GLuint rows = height; + + + if (0) fprintf(stderr, "trying to upload %d rows (pitch %d)\n", + rows, bufferpitch); + + /* The texture conversion code is so slow that there is only + * negligble speedup when the buffers/images don't exactly + * match: + */ +#if 1 + if (cpp == 2) { + if (!_mesa_convert_teximage( MESA_R5_G6_B5, + width, rows, + address, bufferpitch, + width, rows, + format, type, + pixels, unpack )) { +/* mgaReleaseBufLocked( mmesa, buf ); */ + UNLOCK_HARDWARE(mmesa); + return GL_FALSE; + } + } else { + if (!_mesa_convert_teximage( MESA_A8_R8_G8_B8, + width, rows, + address, bufferpitch, + width, rows, + format, type, + pixels, unpack )) { +/* mgaReleaseBufLocked( mmesa, buf ); */ + UNLOCK_HARDWARE(mmesa); + return GL_FALSE; + } + } +#else + MEMCPY( address, pixels, rows*bufferpitch ); +#endif + + do_draw_pix( ctx, x, y, width, rows, + bufferpitch/cpp, address, dest, planemask ); + + /* Fix me -- use multiple buffers to avoid flush. + */ + mgaUpdateLock( mmesa, DRM_LOCK_FLUSH | DRM_LOCK_QUIESCENT ); + + pixels = (void *)((char *) pixels + rows * pitch); + height -= rows; + y += rows; + } while (height); + +/* mgaReleaseBufLocked( mmesa, buf ); */ + } + + UNLOCK_HARDWARE( mmesa ); + mmesa->dirty |= MGA_UPLOAD_CLIPRECTS; + + return GL_TRUE; +} + + + + +/* Stub functions - not a real allocator, always returns pointer to + * the same block of agp space which isn't used for anything else at + * present. + */ +#if defined(MESA_hacked_agp_allocator) +static void mgaDDFreeAgpMemory( GLcontext *ctx, void *ptr ) +{ + (void) ptr; +} + +static void *mgaDDAllocateAgpMemory( GLcontext *ctx, GLsizei size ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + if (size < mmesa->mgaScreen->textureSize[MGA_AGP_HEAP]) + return mmesa->mgaScreen->texVirtual[MGA_AGP_HEAP]; + else + return 0; +} + +static GLint mgaDDGetAgpOffset( GLcontext *ctx, const void *ptr ) +{ + mgaContextPtr mmesa = MGA_CONTEXT(ctx); + + if (!IS_AGP_MEM(mmesa, ptr)) + return -1; + + return AGP_OFFSET(mmesa, ptr); +} +#endif + + +void mgaDDInitPixelFuncs( GLcontext *ctx ) +{ +#if defined (MESA_hacked_agp_allocator) + ctx->Driver.AllocateAgpMemory = mgaDDAllocateAgpMemory; + ctx->Driver.GetAgpOffset = mgaDDGetAgpOffset; + ctx->Driver.FreeAgpMemory = mgaDDFreeAgpMemory; +#endif + if (getenv("MGA_BLIT_PIXELS")) { + ctx->Driver.ReadPixels = mgaDDReadPixels; /* requires agp dest */ + ctx->Driver.DrawPixels = mgaDDDrawPixels; /* works with agp/normal mem */ + } +} diff --git a/xc/lib/GL/mesa/src/drv/mga/mgapixel.h b/xc/lib/GL/mesa/src/drv/mga/mgapixel.h new file mode 100644 index 000000000..a413467e4 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/mga/mgapixel.h @@ -0,0 +1,36 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgapixel.h,v 1.1 2001/01/08 01:07:18 martin Exp $ */ +/************************************************************************** + +Copyright 2000 Compaq Computer Inc. and VA Linux, Inc. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +#ifndef MGA_PIXELS_H +#define MGA_PIXELS_H + +#include "types.h" + +extern void mgaDDInitPixelFuncs( GLcontext *ctx ); + +#endif + diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaregs.h b/xc/lib/GL/mesa/src/drv/mga/mgaregs.h index 3842ee258..6e381a9cc 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaregs.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgaregs.h @@ -1048,6 +1048,8 @@ #define TMC_tformat_tw16 0x3 /* val 3, shift 0 */ #define TMC_tformat_tw12 0x4 /* val 4, shift 0 */ #define TMC_tformat_tw32 0x6 /* val 6, shift 0 */ + #define TMC_tformat_tw8a 0x7 /* val 7, shift 0 */ + #define TMC_tformat_tw8al 0x8 /* val 8, shift 0 */ #define TMC_tformat_tw422 0xa /* val 10, shift 0 */ #define TMC_tpitchlin_MASK 0xfffffeff /* bit 8 */ #define TMC_tpitchlin_disable 0x0 @@ -1162,6 +1164,7 @@ #define TO_texorgacc_MASK 0xfffffffd /* bit 1 */ #define TO_texorgacc_pci 0x0 #define TO_texorgacc_agp 0x2 + #define TO_texorgoffsetsel 0x4 #define TO_texorg_MASK 0x1f /* bits 5-31 */ #define TO_texorg_SHIFT 5 diff --git a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c index 3df15ddce..0b9893175 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgaspan.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgaspan.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.5 2000/09/24 13:51:07 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgaspan.c,v 1.6 2001/01/08 01:07:18 martin Exp $ */ #include "types.h" #include "mgadd.h" @@ -23,7 +23,7 @@ mmesa->drawOffset + \ dPriv->x * mgaScreen->cpp + \ dPriv->y * pitch); \ - GLushort p = MGA_CONTEXT( ctx )->MonoColor; \ + GLuint p = MGA_CONTEXT( ctx )->MonoColor; \ (void) read_buf; (void) buf; (void) p @@ -36,7 +36,7 @@ GLuint height = dPriv->h; \ char *buf = (char *)(sPriv->pFB + \ mgaScreen->depthOffset + \ - dPriv->x * 2 + \ + dPriv->x * mgaScreen->cpp + \ dPriv->y * pitch) #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS @@ -174,7 +174,7 @@ do { \ } #define READ_DEPTH( d, _x, _y ) \ - d = *(GLuint *)(buf + _x*4 + _y*pitch) >> 8; + d = *(GLuint *)(buf + _x*4 + _y*pitch) & ~0xff; #define TAG(x) mga##x##_24_8 @@ -225,7 +225,7 @@ void mgaDDInitSpanFuncs( GLcontext *ctx ) ctx->Driver.ReadRGBASpan = mgaReadRGBASpan_8888; ctx->Driver.ReadRGBAPixels = mgaReadRGBAPixels_8888; - if (mmesa->hw_stencil) { + if (!mmesa->hw_stencil) { ctx->Driver.ReadDepthSpan = mgaReadDepthSpan_32; ctx->Driver.WriteDepthSpan = mgaWriteDepthSpan_32; ctx->Driver.ReadDepthPixels = mgaReadDepthPixels_32; @@ -243,13 +243,4 @@ void mgaDDInitSpanFuncs( GLcontext *ctx ) } break; } - - - ctx->Driver.WriteCI8Span = 0; - ctx->Driver.WriteCI32Span = 0; - ctx->Driver.WriteMonoCISpan = 0; - ctx->Driver.WriteCI32Pixels = 0; - ctx->Driver.WriteMonoCIPixels = 0; - ctx->Driver.ReadCI32Span = 0; - ctx->Driver.ReadCI32Pixels = 0; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgastate.c b/xc/lib/GL/mesa/src/drv/mga/mgastate.c index 06b69554d..f790adc9a 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgastate.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgastate.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.6 2000/11/08 05:02:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgastate.c,v 1.7 2001/01/08 01:07:18 martin Exp $ */ #include <stdio.h> @@ -834,16 +834,8 @@ void mgaEmitHwStateLocked( mgaContextPtr mmesa ) mmesa->sarea->WarpPipe = mmesa->warp_pipe; mmesa->sarea->vertexsize = mmesa->vertsize; -/* mmesa->sarea->vertexsize = 10; */ mmesa->sarea->dirty |= mmesa->dirty; -#if 0 - if (mmesa->dirty & MGA_UPLOAD_PIPE) - mgaPrintSetupFlags("warp pipe", mmesa->sarea->WarpPipe); -/* fprintf(stderr, "in mgaEmitHwStateLocked: dirty now %x\n", */ -/* mmesa->sarea->dirty); */ -#endif - mmesa->dirty &= (MGA_UPLOAD_CLIPRECTS|MGA_WAIT_AGE); } @@ -1051,9 +1043,6 @@ void mgaDDUpdateState( GLcontext *ctx ) if (mmesa->new_state & MGA_NEW_TEXTURE) mgaDDUpdateHwState( ctx ); - if (0) fprintf(stderr, "fallback %x indirect %x\n", mmesa->Fallback, - mmesa->IndirectTriangles); - if (!mmesa->Fallback) { ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; ctx->IndirectTriangles |= mmesa->IndirectTriangles; diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.c b/xc/lib/GL/mesa/src/drv/mga/mgatex.c index 5039750de..629dbfed1 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.c @@ -25,7 +25,7 @@ * 9/20/99 rewrite by John Carmack <johnc@idsoftware.com> * 13/1/00 port to DRI by Keith Whitwell <keithw@precisioninsight.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.7 2000/11/08 05:02:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.c,v 1.8 2001/01/08 01:07:18 martin Exp $ */ #include <stdlib.h> #include <stdio.h> @@ -625,24 +625,14 @@ static void mgaDDTexSubImage( GLcontext *ctx, GLenum target, mgaTextureObjectPtr t; t = (mgaTextureObjectPtr) tObj->DriverData; - - - /* just free the mga texture if it exists, it will be recreated at - mgaUpdateTextureState time. */ - t = (mgaTextureObjectPtr) tObj->DriverData; - if ( t ) { + if (t) { if (t->bound) FLUSH_BATCH(mmesa); - /* if this is the current object, it will force an update */ - mgaDestroyTexObj( mmesa, t ); - mmesa->new_state |= MGA_NEW_TEXTURE; + LOCK_HARDWARE( mmesa ); + /* the texture currently exists, so directly update it */ + mgaUploadSubImageLocked( mmesa, t, level, + xoffset, yoffset, width, height ); + UNLOCK_HARDWARE( mmesa ); } - - - -#if 0 - /* the texture currently exists, so directly update it */ - mgaUploadSubImage( t, level, xoffset, yoffset, width, height ); -#endif } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatex.h b/xc/lib/GL/mesa/src/drv/mga/mgatex.h index 02e95f59f..bd977f1e8 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatex.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatex.h @@ -24,7 +24,7 @@ * John Carmack <johnc@idsoftware.com> * Keith Whitwell <keithw@precisioninsight.com> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.4 2000/09/24 13:51:07 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatex.h,v 1.5 2001/01/08 01:07:19 martin Exp $ */ #ifndef MGATEX_INC #define MGATEX_INC @@ -40,14 +40,15 @@ typedef struct mga_texture_object_s *mgaTextureObjectPtr; */ void mgaUpdateTextureState( GLcontext *ctx ); - -/* Driver functions which are called directly from mesa */ - void mgaConvertTexture( GLuint *dest, int texelBytes, struct gl_texture_image *image, int x, int y, int width, int height ); +void mgaUploadSubImageLocked( mgaContextPtr mmesa, + mgaTextureObjectPtr t, + int level, + int x, int y, int width, int height ); int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ); diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c b/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c index 9d328f064..2390429d0 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatexmem.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.1 2000/09/24 13:51:08 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatexmem.c,v 1.2 2001/01/08 01:07:19 martin Exp $ */ #include <stdlib.h> #include <stdio.h> @@ -257,10 +257,10 @@ void mgaAgeTextures( mgaContextPtr mmesa, int heap ) * * Performed with the hardware lock held. */ -static void mgaUploadSubImageLocked( mgaContextPtr mmesa, - mgaTextureObjectPtr t, - int level, - int x, int y, int width, int height ) +void mgaUploadSubImageLocked( mgaContextPtr mmesa, + mgaTextureObjectPtr t, + int level, + int x, int y, int width, int height ) { int x2; int dwords; @@ -387,13 +387,12 @@ static void mgaUploadTexLevel( mgaContextPtr mmesa, mgaTextureObjectPtr t, int l ) { -/* return; */ - mgaUploadSubImageLocked( mmesa, - t, - l, - 0, 0, - t->tObj->Image[l]->Width, - t->tObj->Image[l]->Height); + mgaUploadSubImageLocked( mmesa, + t, + l, + 0, 0, + t->tObj->Image[l]->Width, + t->tObj->Image[l]->Height); } @@ -435,16 +434,14 @@ int mgaUploadTexImages( mgaContextPtr mmesa, mgaTextureObjectPtr t ) break; if (mmesa->TexObjList[heap].prev->bound) { - fprintf(stderr, - "Hit bound texture in upload\n"); + fprintf(stderr, "Hit bound texture in upload\n"); return -1; } if (mmesa->TexObjList[heap].prev == &(mmesa->TexObjList[heap])) { - fprintf(stderr, "Failed to upload texture, " - "sz %d\n", t->totalSize); + fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize); mmDumpMemInfo( mmesa->texHeap[heap] ); return -1; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.c b/xc/lib/GL/mesa/src/drv/mga/mgatris.c index d842e5252..4344003af 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.c @@ -23,7 +23,7 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.5 2000/09/24 13:51:08 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.c,v 1.6 2001/01/08 01:07:19 martin Exp $ */ #include <stdio.h> #include <math.h> @@ -129,7 +129,7 @@ void mgaDDTrifuncInit() -#define ALL_FALLBACK (DD_MULTIDRAW | DD_SELECT | DD_FEEDBACK) +#define ALL_FALLBACK (DD_SELECT | DD_FEEDBACK) #define POINT_FALLBACK (ALL_FALLBACK | DD_POINT_SMOOTH) #define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE) #define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_UNFILLED) diff --git a/xc/lib/GL/mesa/src/drv/mga/mgatris.h b/xc/lib/GL/mesa/src/drv/mga/mgatris.h index 0c27ab43d..03f95ddf3 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgatris.h +++ b/xc/lib/GL/mesa/src/drv/mga/mgatris.h @@ -23,7 +23,7 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.5 2000/09/24 13:51:08 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgatris.h,v 1.6 2001/01/08 01:07:19 martin Exp $ */ #ifndef MGATIS_INC #define MGATIS_INC @@ -41,92 +41,15 @@ extern void mgaDDTrifuncInit( void ); #define MGA_NODRAW_BIT 0x8 #define MGA_FALLBACK_BIT 0x10 -extern int nrswaps; - - -#define VERTSIZE vertsize - -/* static float _v0[] = { */ -/* 242.202515, */ -/* 250.469604, */ -/* 0.961081, */ -/* 0.013503, */ -/* 0, */ -/* 0.000000, */ -/* 2.600000, */ -/* 0.000000, */ -/* 1.000000, */ -/* 0.600000 */ -/* }; */ - -/* static float _v1[] = { */ -/* 246.448914, */ -/* 54.697876, */ -/* 0.953817, */ -/* 0.014156, */ -/* 0, */ -/* 0.000000, */ -/* 2.600000, */ -/* 2.000000, */ -/* 1.000000, */ -/* 1.600000 */ -/* }; */ - -/* static float _v2[] = { */ -/* 55.999474, */ -/* 85.196106, */ -/* 0.942609, */ -/* 0.015165, */ -/* 0, */ -/* 0.000000, */ -/* 0.600000, */ -/* 2.000000, */ -/* 0.000000, */ -/* 1.600000, */ -/* }; */ - static __inline void mga_draw_triangle( mgaContextPtr mmesa, mgaVertex *v0, mgaVertex *v1, mgaVertex *v2 ) { GLuint vertsize = mmesa->vertsize; - GLuint *wv = mgaAllocVertexDwordsInline( mmesa, 3 * VERTSIZE ); + GLuint *wv = mgaAllocVertexDwordsInline( mmesa, 3 * vertsize ); int j; - (void) vertsize; - -/* for (j = 0 ; j < vertsize ; j++) */ -/* fprintf(stderr, "v0 %d: %f 0x%x\n", j, v0->f[j], v0->ui[j]); */ - -/* for (j = 0 ; j < vertsize ; j++) */ -/* fprintf(stderr, "v1 %d: %f 0x%x\n", j, v1->f[j], v1->ui[j]); */ - -/* for (j = 0 ; j < vertsize ; j++) */ -/* fprintf(stderr, "v2 %d: %f 0x%x\n", j, v2->f[j], v2->ui[j]); */ - -/* v0 = (mgaVertex *)_v0; */ -/* v1 = (mgaVertex *)_v1; */ -/* v2 = (mgaVertex *)_v2; */ - - -/* if (v0->v.x < 0 || v0->v.x > 1920 || */ -/* v0->v.y < 0 || v0->v.y > 1440 || */ -/* v0->v.z < 0 || v0->v.z > 1) */ -/* fprintf(stderr, "v0 %f %f %f %f\n", v0->v.x, v0->v.y, v0->v.z, v0->v.rhw); */ - - -/* if (v1->v.x < 0 || v1->v.x > 1920 || */ -/* v1->v.y < 0 || v1->v.y > 1440 || */ -/* v1->v.z < 0 || v1->v.z > 1) */ -/* fprintf(stderr, "v1 %f %f %f %f\n", v1->v.x, v1->v.y, v1->v.z, v1->v.rhw); */ - -/* if (v2->v.x < 0 || v2->v.x > 1920 || */ -/* v2->v.y < 0 || v2->v.y > 1440 || */ -/* v2->v.z < 0 || v2->v.z > 1) */ -/* fprintf(stderr, "v2 %f %f %f %f\n", v2->v.x, v2->v.y, v2->v.z, v2->v.rhw); */ - - #if defined (USE_X86_ASM) /* GTH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is @@ -135,26 +58,26 @@ static __inline void mga_draw_triangle( mgaContextPtr mmesa, */ __asm__ __volatile__( "rep ; movsl" : "=%c" (j) - : "0" (VERTSIZE), "D" ((long)wv), "S" ((long)v0) + : "0" (vertsize), "D" ((long)wv), "S" ((long)v0) : "memory" ); __asm__ __volatile__( "rep ; movsl" : "=%c" (j) - : "0" (VERTSIZE), "S" ((long)v1) + : "0" (vertsize), "S" ((long)v1) : "memory" ); __asm__ __volatile__( "rep ; movsl" : "=%c" (j) - : "0" (VERTSIZE), "S" ((long)v2) + : "0" (vertsize), "S" ((long)v2) : "memory" ); #else { for (j = 0 ; j < vertsize ; j++) wv[j] = v0->ui[j]; - wv += VERTSIZE; + wv += vertsize; for (j = 0 ; j < vertsize ; j++) wv[j] = v1->ui[j]; - wv += VERTSIZE; + wv += vertsize; for (j = 0 ; j < vertsize ; j++) wv[j] = v2->ui[j]; } @@ -166,38 +89,38 @@ static __inline void mga_draw_point( mgaContextPtr mmesa, mgaVertex *tmp, float sz ) { GLuint vertsize = mmesa->vertsize; - GLuint *wv = mgaAllocVertexDwords( mmesa, 6*VERTSIZE); + GLuint *wv = mgaAllocVertexDwords( mmesa, 6*vertsize); int j; *(float *)&wv[0] = tmp->v.x - sz; *(float *)&wv[1] = tmp->v.y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp->v.x + sz; *(float *)&wv[1] = tmp->v.y - sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp->v.x + sz; *(float *)&wv[1] = tmp->v.y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp->v.x + sz; *(float *)&wv[1] = tmp->v.y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp->v.x - sz; *(float *)&wv[1] = tmp->v.y + sz; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp->v.x - sz; *(float *)&wv[1] = tmp->v.y - sz; @@ -212,7 +135,7 @@ static __inline void mga_draw_line( mgaContextPtr mmesa, float width ) { GLuint vertsize = mmesa->vertsize; - GLuint *wv = mgaAllocVertexDwords( mmesa, 6 * VERTSIZE ); + GLuint *wv = mgaAllocVertexDwords( mmesa, 6 * vertsize ); float dx, dy, ix, iy; int j; @@ -232,37 +155,37 @@ static __inline void mga_draw_line( mgaContextPtr mmesa, *(float *)&wv[1] = tmp0->v.y - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp1->v.x + ix; *(float *)&wv[1] = tmp1->v.y + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp0->v.x + ix; *(float *)&wv[1] = tmp0->v.y + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp0->v.x - ix; *(float *)&wv[1] = tmp0->v.y - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp0->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp1->v.x - ix; *(float *)&wv[1] = tmp1->v.y - iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; - wv += VERTSIZE; + wv += vertsize; *(float *)&wv[0] = tmp1->v.x + ix; *(float *)&wv[1] = tmp1->v.y + iy; for (j = 2 ; j < vertsize ; j++) wv[j] = tmp1->ui[j]; - wv += VERTSIZE; + wv += vertsize; } diff --git a/xc/lib/GL/mesa/src/drv/mga/mgavb.c b/xc/lib/GL/mesa/src/drv/mga/mgavb.c index 75073a8c6..d804814e0 100644 --- a/xc/lib/GL/mesa/src/drv/mga/mgavb.c +++ b/xc/lib/GL/mesa/src/drv/mga/mgavb.c @@ -23,7 +23,7 @@ * * Wittawat Yamwong <Wittawat.Yamwong@stud.uni-hannover.de> */ -/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.7 2000/11/08 05:02:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/mga/mgavb.c,v 1.8 2001/01/08 01:07:19 martin Exp $ */ #include "mgacontext.h" #include "mgavb.h" @@ -297,11 +297,6 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx) mmesa->tmu_source[0] = 1; mmesa->tex_dest[1] = MGA_TEX0_BIT; - /* This doesn't work for non-RGBA textures - if (ctx->Texture.Unit[1].EnvMode == GL_REPLACE) - funcindex &= ~MGA_RGBA_BIT; - */ - if (ctx->Texture.Unit[0].EnvMode == GL_BLEND && mmesa->envcolor) { @@ -315,15 +310,6 @@ void mgaChooseRasterSetupFunc(GLcontext *ctx) } } -/* if (mmesa->multitex == 0) { */ -/* mmesa->tmu_source[1] = mmesa->tmu_source[0]; */ -/* mmesa->tex_dest[1] = mmesa->tex_dest[0]; */ -/* mmesa->vertsize = 10; */ -/* mmesa->multitex = 1; */ -/* funcindex |= MGA_TEX0_BIT|MGA_TEX1_BIT; */ -/* } */ - -/* mmesa->vertsize = 10; */ if (multi != mmesa->multitex) mmesa->new_state |= MGA_NEW_WARP; @@ -424,7 +410,7 @@ void mgaDDDoRasterSetup( struct vertex_buffer *VB ) /* Can't lock, won't lock */ - REFRESH_DRAWABLE_INFO( mmesa ); +/* REFRESH_DRAWABLE_INFO( mmesa ); */ if (VB->Type == VB_CVA_PRECALC) mgaDDPartialRasterSetup( VB ); diff --git a/xc/lib/GL/mesa/src/drv/r128/Imakefile b/xc/lib/GL/mesa/src/drv/r128/Imakefile index 7e15a1074..9832bc2c3 100644 --- a/xc/lib/GL/mesa/src/drv/r128/Imakefile +++ b/xc/lib/GL/mesa/src/drv/r128/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.11 2000/12/12 23:24:28 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/r128/Imakefile,v 1.12 2001/02/16 01:26:11 dawes Exp $ #include <Threads.tmpl> @@ -373,7 +373,7 @@ NormalLintTarget($(SRCS)) LIBNAME = r128_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE -SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +SharedDriModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) #ifdef GlxSoProf diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c index e11a47a47..f0749ff10 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.4 2000/12/12 17:17:06 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.5 2001/01/08 01:07:20 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -60,188 +60,176 @@ int R128_DEBUG = (0 ); #endif -/* Create the device specific context */ -GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, - __DRIcontextPrivate *driContextPriv) +/* Create the device specific context. + */ +GLboolean r128CreateContext( Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv ) { - r128ContextPtr r128ctx; - r128ScreenPtr r128scrn; - GLcontext *ctx = driContextPriv->mesaContext; - int i; - char *v; - __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; - - r128ctx = (r128ContextPtr)Xcalloc(1, sizeof(*r128ctx)); - if (!r128ctx) return GL_FALSE; - - /* Initialize r128Context */ - r128ctx->glCtx = ctx; - r128ctx->display = dpy; - - r128ctx->driContext = driContextPriv; - r128ctx->driScreen = sPriv; - r128ctx->driDrawable = NULL; /* Set by XMesaMakeCurrent */ - - r128ctx->hHWContext = driContextPriv->hHWContext; - r128ctx->driFd = sPriv->fd; - r128ctx->driHwLock = &sPriv->pSAREA->lock; + GLcontext *ctx = driContextPriv->mesaContext; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + r128ContextPtr rmesa; + r128ScreenPtr r128scrn; + int i; + + rmesa = (r128ContextPtr) CALLOC( sizeof(*rmesa) ); + if ( !rmesa ) return GL_FALSE; + + rmesa->glCtx = ctx; + rmesa->display = dpy; + + rmesa->driContext = driContextPriv; + rmesa->driScreen = sPriv; + rmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */ + + rmesa->hHWContext = driContextPriv->hHWContext; + rmesa->driHwLock = &sPriv->pSAREA->lock; + rmesa->driFd = sPriv->fd; + + r128scrn = rmesa->r128Screen = (r128ScreenPtr)(sPriv->private); + + rmesa->sarea = (R128SAREAPrivPtr)((char *)sPriv->pSAREA + + sizeof(XF86DRISAREARec)); + + rmesa->tmp_matrix = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + if ( !rmesa->tmp_matrix ) { + FREE( rmesa ); + return GL_FALSE; + } + + rmesa->CurrentTexObj[0] = NULL; + rmesa->CurrentTexObj[1] = NULL; + + make_empty_list( &rmesa->SwappedOut ); + + for ( i = 0 ; i < r128scrn->numTexHeaps ; i++ ) { + make_empty_list( &rmesa->TexObjList[i] ); + rmesa->texHeap[i] = mmInit( 0, r128scrn->texSize[i] ); + rmesa->lastTexAge[i] = -1; + } + rmesa->lastTexHeap = r128scrn->numTexHeaps; + + rmesa->RenderIndex = -1; /* Impossible value */ + rmesa->OnFastPath = 0; + + rmesa->vert_buf = NULL; + rmesa->num_verts = 0; + + rmesa->elt_buf = NULL; + rmesa->retained_buf = NULL; + rmesa->vert_heap = r128scrn->buffers->list->address; + + /* KW: Set the maximum texture size small enough that we can + * guarentee that both texture units can bind a maximal texture + * and have them both in on-card memory at once. (Kevin or + * Gareth: Please check these numbers are OK) + */ + if ( r128scrn->texSize[0] < 2*1024*1024 ) { + ctx->Const.MaxTextureLevels = 9; + ctx->Const.MaxTextureSize = (1 << 8); + } else if ( r128scrn->texSize[0] < 8*1024*1024 ) { + ctx->Const.MaxTextureLevels = 10; + ctx->Const.MaxTextureSize = (1 << 9); + } else { + ctx->Const.MaxTextureLevels = 11; + ctx->Const.MaxTextureSize = (1 << 10); + } + + ctx->Const.MaxTextureUnits = 2; - r128scrn = r128ctx->r128Screen = (r128ScreenPtr)(sPriv->private); - - r128ctx->sarea = (R128SAREAPriv *)((char *)sPriv->pSAREA + - sizeof(XF86DRISAREARec)); - - r128ctx->CurrentTexObj[0] = NULL; - r128ctx->CurrentTexObj[1] = NULL; - make_empty_list(&r128ctx->SwappedOut); - for (i = 0; i < r128scrn->NRTexHeaps; i++) { - make_empty_list(&r128ctx->TexObjList[i]); - r128ctx->texHeap[i] = mmInit(0, r128scrn->texSize[i]); - r128ctx->lastTexAge[i] = -1; - } - r128ctx->lastTexHeap = r128scrn->NRTexHeaps; - - r128ctx->DepthSize = glVisual->DepthBits; - r128ctx->StencilSize = glVisual->StencilBits; - - r128ctx->useFastPath = GL_FALSE; - r128ctx->lod_bias = 0x3f; +#if ENABLE_PERF_BOXES + if ( getenv( "LIBGL_PERFORMANCE_BOXES" ) ) { + rmesa->boxes = 1; + } else { + rmesa->boxes = 0; + } +#endif - r128ctx->num_verts = 0; - r128ctx->vert_buf = NULL; + ctx->DriverCtx = (void *)rmesa; - r128ctx->elt_buf = NULL; - r128ctx->retained_buf = NULL; - r128ctx->vert_heap = r128ctx->r128Screen->buffers->list->address; + r128DDInitExtensions( ctx ); -#if 0 - r128ctx->CCEbuf= (CARD32 *)MALLOC(sizeof(*r128ctx->CCEbuf) * - r128scrn->ringEntries); - r128ctx->CCEcount = 0; -#endif + r128DDInitDriverFuncs( ctx ); + r128DDInitIoctlFuncs( ctx ); + r128DDInitStateFuncs( ctx ); + r128DDInitSpanFuncs( ctx ); + r128DDInitTextureFuncs( ctx ); - if ((v = getenv("LIBGL_CCE_TIMEOUT"))) - r128ctx->CCEtimeout = strtoul(v, NULL, 10); - else - r128ctx->CCEtimeout = (R128_DEFAULT_TOTAL_CCE_TIMEOUT / - R128_DEFAULT_CCE_TIMEOUT); - if (r128ctx->CCEtimeout <= 0) r128ctx->CCEtimeout = 1; - - /* Initialize GLcontext */ - ctx->DriverCtx = (void *)r128ctx; - - r128DDInitExtensions(ctx); - - r128DDInitDriverFuncs(ctx); - r128DDInitIoctlFuncs(ctx); - r128DDInitStateFuncs(ctx); - r128DDInitSpanFuncs(ctx); - r128DDInitTextureFuncs(ctx); - - ctx->Driver.TriangleCaps = (DD_TRI_CULL - | DD_TRI_LIGHT_TWOSIDE - | DD_TRI_OFFSET); - - /* Ask Mesa to clip fog coordinates for us - */ - ctx->TriangleCaps |= DD_CLIP_FOG_COORD; - - /* Reset Mesa's current 2D texture pointers to the driver's textures */ - ctx->Shared->DefaultD[2][0].DriverData = NULL; - ctx->Shared->DefaultD[2][1].DriverData = NULL; - - /* KW: Set the maximum texture size small enough that we can - * guarentee that both texture units can bind a maximal texture - * and have them both in on-card memory at once. (Kevin or - * Gareth: Please check these numbers are OK) - */ - if (r128scrn->texSize[0] < 2*1024*1024) { - ctx->Const.MaxTextureLevels = 9; - ctx->Const.MaxTextureSize = 1<<8; - } else if (r128scrn->texSize[0] < 8*1024*1024) { - ctx->Const.MaxTextureLevels = 10; - ctx->Const.MaxTextureSize = 1<<9; - } else { - ctx->Const.MaxTextureLevels = 11; - ctx->Const.MaxTextureSize = 1<<10; - } - - ctx->Const.MaxTextureUnits = 2; + ctx->Driver.TriangleCaps = (DD_TRI_CULL | + DD_TRI_LIGHT_TWOSIDE | + DD_TRI_STIPPLE | + DD_TRI_OFFSET); -#if ENABLE_PERF_BOXES - if (getenv("LIBGL_PERFORMANCE_BOXES")) - r128ctx->boxes = 1; - else - r128ctx->boxes = 0; -#endif + /* Ask Mesa to clip fog coordinates for us. + */ + ctx->TriangleCaps |= DD_CLIP_FOG_COORD; - /* If Mesa has current a vertex buffer, make sure the driver's VB - data is up to date */ - if (ctx->VB) r128DDRegisterVB(ctx->VB); + if ( ctx->VB ) + r128DDRegisterVB( ctx->VB ); - /* Register the fast path */ - if (ctx->NrPipelineStages) - ctx->NrPipelineStages = - r128DDRegisterPipelineStages(ctx->PipelineStage, - ctx->PipelineStage, - ctx->NrPipelineStages); + if ( ctx->NrPipelineStages ) { + ctx->NrPipelineStages = + r128DDRegisterPipelineStages( ctx->PipelineStage, + ctx->PipelineStage, + ctx->NrPipelineStages ); + } - r128DDInitState(r128ctx); + r128DDInitState( rmesa ); - driContextPriv->driverPrivate = (void *)r128ctx; + driContextPriv->driverPrivate = (void *)rmesa; - return GL_TRUE; + return GL_TRUE; } -/* Destroy the device specific context */ -void r128DestroyContext(r128ContextPtr r128ctx) +/* Destroy the device specific context. + */ +void r128DestroyContext( r128ContextPtr rmesa ) { - if (r128ctx) { - r128TexObjPtr t, next_t; - int i; + if ( rmesa ) { + r128TexObjPtr t, next_t; + int i; -#if 0 - FREE( r128ctx->CCEbuf ); -#endif + for ( i = 0 ; i < rmesa->r128Screen->numTexHeaps ; i++ ) { + foreach_s ( t, next_t, &rmesa->TexObjList[i] ) { + r128DestroyTexObj( rmesa, t ); + } + mmDestroy( rmesa->texHeap[i] ); + } - for (i = 0; i < r128ctx->r128Screen->NRTexHeaps; i++) { - foreach_s (t, next_t, &r128ctx->TexObjList[i]) - r128DestroyTexObj(r128ctx, t); - } + foreach_s ( t, next_t, &rmesa->SwappedOut ) { + r128DestroyTexObj( rmesa, t ); + } - foreach_s (t, next_t, &r128ctx->SwappedOut) - r128DestroyTexObj(r128ctx, t); - - Xfree(r128ctx); - } + ALIGN_FREE( rmesa->tmp_matrix ); + FREE( rmesa ); + } #if 0 - glx_fini_prof(); + /* Use this to force shared object profiling. */ + glx_fini_prof(); #endif } /* Load the device specific context into the hardware. The actual - setting of the hardware state is done in the r128UpdateHWState(). */ -r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx, - r128ContextPtr newCtx, - __DRIdrawablePrivate *dPriv) + * setting of the hardware state is done in the r128UpdateHWState(). + */ +r128ContextPtr r128MakeCurrent( r128ContextPtr oldCtx, + r128ContextPtr newCtx, + __DRIdrawablePrivate *dPriv ) { - if (oldCtx) { - if (!R128CCE_USE_RING_BUFFER(newCtx->r128Screen->CCEMode)) - newCtx->dirty |= R128_REQUIRE_QUIESCENCE; - if (oldCtx != newCtx) { - newCtx->new_state |= R128_NEW_CONTEXT; - newCtx->dirty = R128_UPLOAD_ALL; - } - if (oldCtx->driDrawable != dPriv) { - newCtx->new_state |= R128_NEW_WINDOW; - } - } else { - newCtx->new_state |= R128_NEW_CONTEXT; - newCtx->dirty = R128_UPLOAD_ALL; - } - - newCtx->driDrawable = dPriv; - - return newCtx; + if ( oldCtx ) { + if ( oldCtx != newCtx ) { + newCtx->new_state |= R128_NEW_CONTEXT; + newCtx->dirty = R128_UPLOAD_ALL; + } + if ( oldCtx->driDrawable != dPriv ) { + newCtx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; + } + } else { + newCtx->new_state |= R128_NEW_CONTEXT; + newCtx->dirty = R128_UPLOAD_ALL; + } + + newCtx->driDrawable = dPriv; + + return newCtx; } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_context.h b/xc/lib/GL/mesa/src/drv/r128/r128_context.h index a6f5b31ae..8c5e2fdfc 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.h,v 1.4 2000/12/12 17:17:06 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.h,v 1.5 2001/01/08 01:07:20 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -33,8 +33,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -#ifndef _R128_CONTEXT_H_ -#define _R128_CONTEXT_H_ +#ifndef __R128_CONTEXT_H__ +#define __R128_CONTEXT_H__ #ifdef GLX_DIRECT_RENDERING @@ -67,7 +67,7 @@ typedef struct r128_context *r128ContextPtr; #define R128_NEW_CLIP 0x0008 #define R128_NEW_CULL 0x0010 #define R128_NEW_MASKS 0x0020 -#define R128_NEW_RENDER 0x0040 +#define R128_NEW_RENDER_NOT 0x0040 #define R128_NEW_WINDOW 0x0080 #define R128_NEW_TEXTURE 0x0100 #define R128_NEW_CONTEXT 0x0200 @@ -101,168 +101,155 @@ typedef void (*r128_interp_func)( GLfloat t, struct r128_elt_tab { void (*emit_unclipped_verts)( struct vertex_buffer *VB ); - void (*build_tri_verts)( r128ContextPtr r128ctx, + void (*build_tri_verts)( r128ContextPtr rmesa, struct vertex_buffer *VB, GLfloat *O, GLuint *elt ); void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); - void (*project_and_emit_verts)( r128ContextPtr r128ctx, + void (*project_and_emit_verts)( r128ContextPtr rmesa, const GLfloat *verts, GLuint *elts, - int nr ); + GLuint nr ); }; struct r128_context { - GLcontext *glCtx; /* Mesa context */ + GLcontext *glCtx; /* Mesa context */ /* Driver and hardware state management */ - GLuint new_state; - GLuint dirty; /* Hardware state to be updated */ - r128_context_regs_t setup; + GLuint new_state; + GLuint dirty; /* Hardware state to be updated */ + r128_context_regs_t setup; - GLuint vertsize; - CARD32 vc_format; - GLfloat depth_scale; + GLuint vertsize; + GLuint vc_format; + GLfloat depth_scale; - CARD32 Color; /* Current draw color */ - CARD32 ClearColor; /* Color used to clear color buffer */ - CARD32 ClearDepth; /* Value used to clear depth buffer */ - CARD32 ClearStencil; /* Value used to clear stencil */ + CARD32 Color; /* Current draw color */ + CARD32 ClearColor; /* Color used to clear color buffer */ + CARD32 ClearDepth; /* Value used to clear depth buffer */ + CARD32 ClearStencil; /* Value used to clear stencil */ /* Map GL texture units onto hardware */ - GLint multitex; - GLint tmu_source[2]; - GLint tex_dest[2]; - GLuint blend_flags; - CARD32 env_color; - GLint lod_bias; + GLint multitex; + GLint tmu_source[2]; + GLint tex_dest[2]; + GLuint tex_combine[2]; + GLuint blend_flags; + GLuint env_color; /* Texture object bookkeeping */ - r128TexObjPtr CurrentTexObj[2]; - r128TexObj TexObjList[R128_NR_TEX_HEAPS]; - r128TexObj SwappedOut; - memHeap_t *texHeap[R128_NR_TEX_HEAPS]; - GLint lastTexAge[R128_NR_TEX_HEAPS]; - GLint lastTexHeap; + r128TexObjPtr CurrentTexObj[2]; + r128TexObj TexObjList[R128_NR_TEX_HEAPS]; + r128TexObj SwappedOut; + memHeap_t *texHeap[R128_NR_TEX_HEAPS]; + GLint lastTexAge[R128_NR_TEX_HEAPS]; + GLint lastTexHeap; /* Current rendering state, fallbacks */ - points_func PointsFunc; - line_func LineFunc; - triangle_func TriangleFunc; - quad_func QuadFunc; + points_func PointsFunc; + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; - CARD32 IndirectTriangles; - CARD32 Fallback; + GLuint IndirectTriangles; + GLuint Fallback; /* Fast path */ - GLuint useFastPath; - GLuint SetupIndex; - GLuint SetupDone; - GLuint RenderIndex; - r128_interp_func interp; + GLuint SetupIndex; + GLuint SetupDone; + GLuint RenderIndex; + GLuint OnFastPath; + r128_interp_func interp; + GLfloat *tmp_matrix; /* Vertex buffers */ - drmBufPtr vert_buf; - GLuint num_verts; + drmBufPtr vert_buf; + GLuint num_verts; /* Elt path */ - drmBufPtr elt_buf, retained_buf; - GLushort *first_elt, *next_elt; - GLfloat *next_vert, *vert_heap; - GLushort next_vert_index; - GLushort first_vert_index; - GLuint elt_vertsize; - struct r128_elt_tab *elt_tab; - GLfloat device_matrix[16]; - - /* CCE command packets + drmBufPtr elt_buf, retained_buf; + GLushort *first_elt, *next_elt; + GLfloat *next_vert, *vert_heap; + GLushort next_vert_index; + GLushort first_vert_index; + GLuint elt_vertsize; + struct r128_elt_tab *elt_tab; + GLfloat device_matrix[16]; + + /* Page flipping */ -#if 0 - CARD32 *CCEbuf; /* buffer to submit to CCE */ - GLuint CCEcount; /* number of dwords in CCEbuf */ -#endif - GLint CCEtimeout; /* number of times to loop - before exiting */ + GLuint doPageFlip; + GLuint currentPage; - /* Visual, drawable, cliprect and scissor information + /* Drawable, cliprect and scissor information */ - GLint DepthSize; /* Bits in depth buffer */ - GLint StencilSize; /* Bits in stencil buffer */ - - GLenum DrawBuffer; /* Optimize draw buffer update */ - GLint drawOffset, drawPitch; - GLint drawX, drawY; - GLint readOffset, readPitch; - GLint readX, readY; + GLenum DrawBuffer; /* Optimize draw buffer update */ + GLint drawOffset, drawPitch; + GLint readOffset, readPitch; - GLuint numClipRects; /* Cliprects for the draw buffer */ - XF86DRIClipRectPtr pClipRects; + GLuint numClipRects; /* Cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; - GLuint scissor; - XF86DRIClipRectRec ScissorRect; /* Current software scissor */ + GLuint scissor; + XF86DRIClipRectRec ScissorRect; /* Current software scissor */ /* Mirrors of some DRI state */ - Display *display; /* X server display */ + Display *display; /* X server display */ __DRIcontextPrivate *driContext; /* DRI context */ __DRIscreenPrivate *driScreen; /* DRI screen */ __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ - drmContext hHWContext; - drmLock *driHwLock; - int driFd; + drmContext hHWContext; + drmLock *driHwLock; + int driFd; - r128ScreenPtr r128Screen; /* Screen private DRI data */ - R128SAREAPriv *sarea; /* Private SAREA data */ + r128ScreenPtr r128Screen; /* Screen private DRI data */ + R128SAREAPrivPtr sarea; /* Private SAREA data */ /* Performance counters - */ - GLuint boxes; /* Draw performance boxes */ - GLuint hardwareWentIdle; - GLuint c_clears; - GLuint c_drawWaits; - GLuint c_textureSwaps; - GLuint c_textureBytes; - GLuint c_vertexBuffers; + */ + GLuint boxes; /* Draw performance boxes */ + GLuint hardwareWentIdle; + GLuint c_clears; + GLuint c_drawWaits; + GLuint c_textureSwaps; + GLuint c_textureBytes; + GLuint c_vertexBuffers; }; #define R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx)) -#define R128_MESACTX(r128ctx) ((r128ctx)->glCtx) -#define R128_DRIDRAWABLE(r128ctx) ((r128ctx)->driDrawable) -#define R128_DRISCREEN(r128ctx) ((r128ctx)->r128Screen->driScreen) - -#define R128_IS_PLAIN( r128ctx ) \ - (r128ctx->r128Screen->chipset == R128_CARD_TYPE_R128) -#define R128_IS_PRO( r128ctx ) \ - (r128ctx->r128Screen->chipset == R128_CARD_TYPE_R128_PRO) -#define R128_IS_MOBILITY( r128ctx ) \ - (r128ctx->r128Screen->chipset == R128_CARD_TYPE_R128_MOBILITY) +#define R128_IS_PLAIN( rmesa ) \ + (rmesa->r128Screen->chipset == R128_CARD_TYPE_R128) +#define R128_IS_PRO( rmesa ) \ + (rmesa->r128Screen->chipset == R128_CARD_TYPE_R128_PRO) +#define R128_IS_MOBILITY( rmesa ) \ + (rmesa->r128Screen->chipset == R128_CARD_TYPE_R128_MOBILITY) -extern GLboolean r128CreateContext(Display *dpy, GLvisual *glVisual, - __DRIcontextPrivate *driContextPriv); -extern void r128DestroyContext(r128ContextPtr r128ctx); -extern r128ContextPtr r128MakeCurrent(r128ContextPtr oldCtx, - r128ContextPtr newCtx, - __DRIdrawablePrivate *dPriv); +extern GLboolean r128CreateContext( Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv ); +extern void r128DestroyContext( r128ContextPtr rmesa ); +extern r128ContextPtr r128MakeCurrent( r128ContextPtr oldCtx, + r128ContextPtr newCtx, + __DRIdrawablePrivate *dPriv ); /* ================================================================ * Debugging: */ #define DEBUG 0 -#define DEBUG_LOCKING 0 #define ENABLE_PERF_BOXES 0 #if DEBUG @@ -280,4 +267,4 @@ extern int R128_DEBUG; #define DEBUG_VERBOSE_2D 0x40 #endif -#endif /* _R128_CONTEXT_H_ */ +#endif /* __R128_CONTEXT_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c index a16b04276..8d9473093 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.c,v 1.6 2000/12/15 22:48:38 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.c,v 1.9 2001/01/11 03:36:54 tsi Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -45,51 +45,56 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "X86/common_x86_asm.h" #endif -#define R128_DATE "20001215" +#define R128_DATE "20010101" -/* Return the current color buffer size */ + +/* Return the width and height of the current color buffer. + */ static void r128DDGetBufferSize( GLcontext *ctx, GLuint *width, GLuint *height ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - *width = r128ctx->driDrawable->w; - *height = r128ctx->driDrawable->h; + LOCK_HARDWARE( rmesa ); + *width = rmesa->driDrawable->w; + *height = rmesa->driDrawable->h; + UNLOCK_HARDWARE( rmesa ); } -/* Return various strings for glGetString() */ +/* Return various strings for glGetString(). + */ static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); static GLubyte buffer[128]; switch ( name ) { case GL_VENDOR: - return (const GLubyte *)"VA Linux Systems, Inc."; + return (GLubyte *)"VA Linux Systems, Inc."; case GL_RENDERER: sprintf((void *)buffer, "Mesa DRI Rage128 " R128_DATE ); /* Append any chipset-specific information. */ - if ( R128_IS_PRO( r128ctx ) ) { - strncat( buffer, " Pro", 4 ); + if ( R128_IS_PRO( rmesa ) ) { + strncat( (pointer)buffer, " Pro", 4 ); } - if ( R128_IS_MOBILITY( r128ctx ) ) { - strncat( buffer, " M3", 3 ); + if ( R128_IS_MOBILITY( rmesa ) ) { + strncat( (pointer)buffer, " M3", 3 ); } /* Append any AGP-specific information. */ - switch ( r128ctx->r128Screen->AGPMode ) { + switch ( rmesa->r128Screen->AGPMode ) { case 1: - strncat( buffer, " AGP 1x", 7 ); + strncat( (pointer)buffer, " AGP 1x", 7 ); break; case 2: - strncat( buffer, " AGP 2x", 7 ); + strncat( (pointer)buffer, " AGP 2x", 7 ); break; case 4: - strncat( buffer, " AGP 4x", 7 ); + strncat( (pointer)buffer, " AGP 4x", 7 ); break; } @@ -97,17 +102,17 @@ static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name ) */ #ifdef USE_X86_ASM if ( gl_x86_cpu_features ) { - strncat( buffer, " x86", 4 ); + strncat( (pointer)buffer, " x86", 4 ); } #endif #ifdef USE_3DNOW_ASM if ( cpu_has_3dnow ) { - strncat( buffer, "/3DNow!", 7 ); + strncat( (pointer)buffer, "/3DNow!", 7 ); } #endif #ifdef USE_KATMAI_ASM if ( cpu_has_xmm ) { - strncat( buffer, "/SSE", 4 ); + strncat( (pointer)buffer, "/SSE", 4 ); } #endif return buffer; @@ -124,19 +129,19 @@ static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name ) */ static void r128DDFlush( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); #if ENABLE_PERF_BOXES - if ( r128ctx->boxes ) { - LOCK_HARDWARE( r128ctx ); - r128PerformanceBoxesLocked( r128ctx ); - UNLOCK_HARDWARE( r128ctx ); + if ( rmesa->boxes ) { + LOCK_HARDWARE( rmesa ); + r128PerformanceBoxesLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); } /* Log the performance counters if necessary */ - r128PerformanceCounters( r128ctx ); + r128PerformanceCounters( rmesa ); #endif } @@ -145,21 +150,22 @@ static void r128DDFlush( GLcontext *ctx ) */ static void r128DDFinish( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); #if ENABLE_PERF_BOXES /* Bump the performance counter */ - r128ctx->c_drawWaits++; + rmesa->c_drawWaits++; #endif r128DDFlush( ctx ); - r128WaitForIdle( r128ctx ); + r128WaitForIdle( rmesa ); } -/* Return various parameters requested by Mesa (this is deprecated) */ +/* Return various parameters requested by Mesa (this is deprecated). + */ static GLint r128DDGetParameteri( const GLcontext *ctx, GLint param ) { - switch (param) { + switch ( param ) { case DD_HAVE_HARDWARE_FOG: return 1; default: @@ -167,45 +173,49 @@ static GLint r128DDGetParameteri( const GLcontext *ctx, GLint param ) } } -/* Initialize the extensions supported by this driver */ +/* Initialize the extensions supported by this driver. + */ void r128DDInitExtensions( GLcontext *ctx ) { - /* FIXME: Are there other extensions to enable/disable??? */ - gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); - gl_extensions_disable( ctx, "GL_EXT_paletted_texture" ); - gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); - gl_extensions_disable( ctx, "ARB_imaging" ); - gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); + gl_extensions_disable( ctx, "GL_ARB_imaging" ); + gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); + gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); + + gl_extensions_disable( ctx, "GL_EXT_blend_color" ); gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" ); + gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); - gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + gl_extensions_disable( ctx, "GL_EXT_convolution" ); + gl_extensions_disable( ctx, "GL_EXT_paletted_texture" ); + gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); + gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); + gl_extensions_disable( ctx, "GL_EXT_texture_env_combine" ); - if ( getenv( "LIBGL_NO_MULTITEXTURE" ) ) - gl_extensions_disable( ctx, "GL_ARB_multitexture" ); + gl_extensions_disable( ctx, "GL_HP_occlusion_test" ); + + gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); gl_extensions_disable( ctx, "GL_SGI_color_matrix" ); gl_extensions_disable( ctx, "GL_SGI_color_table" ); gl_extensions_disable( ctx, "GL_SGIX_pixel_texture" ); - gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); - gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); - gl_extensions_disable( ctx, "GL_EXT_convolution" ); } -/* Initialize the driver's misc functions */ +/* Initialize the driver's misc functions. + */ void r128DDInitDriverFuncs( GLcontext *ctx ) { - ctx->Driver.GetBufferSize = r128DDGetBufferSize; - ctx->Driver.GetString = r128DDGetString; - ctx->Driver.Finish = r128DDFinish; - ctx->Driver.Flush = r128DDFlush; + ctx->Driver.GetBufferSize = r128DDGetBufferSize; + ctx->Driver.GetString = r128DDGetString; + ctx->Driver.Finish = r128DDFinish; + ctx->Driver.Flush = r128DDFlush; - ctx->Driver.Error = NULL; - ctx->Driver.GetParameteri = r128DDGetParameteri; + ctx->Driver.Error = NULL; + ctx->Driver.GetParameteri = r128DDGetParameteri; - ctx->Driver.DrawPixels = NULL; - ctx->Driver.Bitmap = NULL; + ctx->Driver.DrawPixels = NULL; + ctx->Driver.Bitmap = NULL; - ctx->Driver.RegisterVB = r128DDRegisterVB; - ctx->Driver.UnregisterVB = r128DDUnregisterVB; - ctx->Driver.BuildPrecalcPipeline = r128DDBuildPrecalcPipeline; + ctx->Driver.RegisterVB = r128DDRegisterVB; + ctx->Driver.UnregisterVB = r128DDUnregisterVB; + ctx->Driver.BuildPrecalcPipeline = r128DDBuildPrecalcPipeline; } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h index 447745c43..17061f332 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.h,v 1.2 2000/12/04 19:21:45 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.h,v 1.3 2001/01/08 01:07:20 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,18 +28,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_DD_H_ -#define _R128_DD_H_ +#ifndef __R128_DD_H__ +#define __R128_DD_H__ #ifdef GLX_DIRECT_RENDERING -extern void r128DDInitExtensions(GLcontext *ctx); -extern void r128DDInitDriverFuncs(GLcontext *ctx); +extern void r128DDInitExtensions( GLcontext *ctx ); +extern void r128DDInitDriverFuncs( GLcontext *ctx ); #endif -#endif /* _R128_DD_H_ */ +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c index 02085932a..25548c649 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c @@ -1,25 +1,35 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c,v 1.2 2000/12/07 20:26:08 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_eltpath.c,v 1.3 2001/01/08 01:07:20 martin Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + /* - * GLX Hardware Device Driver for Matrox G400 - * Copyright (C) 1999 Keith Whitwell - * - * 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 - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Authors: + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> * */ @@ -39,193 +49,168 @@ #include "mmath.h" #include "xform.h" -#define DEBUG_ELTPATH 0 /* Always use a full-sized stride for vertices. [FIXME] * Stride in the buffers must be a quadword multiple. */ #define CLIP_STRIDE 10 -static void fire_elts( r128ContextPtr r128ctx ) +static void fire_elts( r128ContextPtr rmesa ) { - int vertsize = r128ctx->vertsize; + GLuint vertsize = rmesa->vertsize; - LOCK_HARDWARE( r128ctx ); - - if ( DEBUG_ELTPATH ) - fprintf( stderr, "\n%s: elt=%p ret=%p vs=%d\n", - __FUNCTION__, r128ctx->elt_buf, - r128ctx->retained_buf, vertsize ); + LOCK_HARDWARE( rmesa ); /* Fire queued elements and discard that buffer if its contents * won't be referenced by future elements. */ - if ( r128ctx->elt_buf ) + if ( rmesa->elt_buf ) { - GLuint retain = (r128ctx->elt_buf == r128ctx->retained_buf); - - if ( r128ctx->first_elt != r128ctx->next_elt ) { - r128FireEltsLocked( r128ctx, - ((GLuint)r128ctx->first_elt - - (GLuint)r128ctx->elt_buf->address), - ((GLuint)r128ctx->next_elt - - (GLuint)r128ctx->elt_buf->address), + GLuint retain = (rmesa->elt_buf == rmesa->retained_buf); + + if ( rmesa->first_elt != rmesa->next_elt ) { + r128FireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), !retain ); } else if ( !retain ) { - r128ReleaseBufLocked( r128ctx, r128ctx->elt_buf ); + r128ReleaseBufLocked( rmesa, rmesa->elt_buf ); } - r128ctx->elt_buf = 0; + rmesa->elt_buf = 0; } - else if ( r128ctx->vert_buf ) + else if ( rmesa->vert_buf ) { - r128FlushVerticesLocked( r128ctx ); + r128FlushVerticesLocked( rmesa ); } - r128GetEltBufLocked( r128ctx ); + r128GetEltBufLocked( rmesa ); - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); /* Give the compiler a chance to optimize the divisions. */ switch ( vertsize ) { case 8: - r128ctx->next_vert_index = (GLushort) - (((r128ctx->elt_buf->idx + 1) * + rmesa->next_vert_index = (GLushort) + (((rmesa->elt_buf->idx + 1) * R128_BUFFER_SIZE / (8 * sizeof(GLuint))) - 1); - r128ctx->next_vert = (GLfloat *) - ((GLuint)r128ctx->vert_heap + - r128ctx->next_vert_index * 8 * sizeof(GLfloat)); + rmesa->next_vert = (GLfloat *) + ((GLuint)rmesa->vert_heap + + rmesa->next_vert_index * 8 * sizeof(GLfloat)); break; case 10: - r128ctx->next_vert_index = (GLushort) - (((r128ctx->elt_buf->idx + 1) * + rmesa->next_vert_index = (GLushort) + (((rmesa->elt_buf->idx + 1) * R128_BUFFER_SIZE / (10 * sizeof(GLuint))) - 1); - r128ctx->next_vert = (GLfloat *) - ((GLuint)r128ctx->vert_heap + - r128ctx->next_vert_index * 10 * sizeof(GLfloat)); + rmesa->next_vert = (GLfloat *) + ((GLuint)rmesa->vert_heap + + rmesa->next_vert_index * 10 * sizeof(GLfloat)); break; } - r128ctx->first_elt = r128ctx->next_elt = (GLushort *) - ((GLubyte *)r128ctx->elt_buf->address + R128_INDEX_PRIM_OFFSET); - - r128ctx->elt_vertsize = vertsize; - - if ( DEBUG_ELTPATH ) - fprintf( stderr, "new elt=%p idx=%d tot=%d next=%p idx=%d\n\n", - r128ctx->elt_buf, r128ctx->elt_buf->idx, - r128ctx->elt_buf->total, - r128ctx->next_vert, r128ctx->next_vert_index ); + rmesa->first_elt = rmesa->next_elt = (GLushort *) + ((GLubyte *)rmesa->elt_buf->address + R128_INDEX_PRIM_OFFSET); - { - GLint space = (GLint)((GLuint)r128ctx->next_vert - - (GLuint)r128ctx->next_elt); - if ( DEBUG_ELTPATH ) - fprintf( stderr, " new nv=%p ne=%p space=%d\n", - r128ctx->next_vert, r128ctx->next_elt, space ); - } + rmesa->elt_vertsize = vertsize; } -static void release_bufs( r128ContextPtr r128ctx ) +static void release_bufs( r128ContextPtr rmesa ) { - if ( DEBUG_ELTPATH ) - fprintf( stderr, "%s: %d idx=%d\n", - __FUNCTION__, - r128ctx->retained_buf && - r128ctx->retained_buf != r128ctx->elt_buf, - r128ctx->retained_buf ? r128ctx->retained_buf->idx : -1 ); - - if ( r128ctx->retained_buf && r128ctx->retained_buf != r128ctx->elt_buf ) + if ( rmesa->retained_buf && rmesa->retained_buf != rmesa->elt_buf ) { - LOCK_HARDWARE( r128ctx ); - if ( r128ctx->first_elt != r128ctx->next_elt ) { - r128FireEltsLocked( r128ctx, - ((GLuint)r128ctx->first_elt - - (GLuint)r128ctx->elt_buf->address), - ((GLuint)r128ctx->next_elt - - (GLuint)r128ctx->elt_buf->address), + LOCK_HARDWARE( rmesa ); + if ( rmesa->first_elt != rmesa->next_elt ) { + r128FireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), 0 ); - ALIGN_NEXT_ELT( r128ctx ); - r128ctx->first_elt = r128ctx->next_elt; + ALIGN_NEXT_ELT( rmesa ); + rmesa->first_elt = rmesa->next_elt; } - r128ReleaseBufLocked( r128ctx, r128ctx->retained_buf ); - UNLOCK_HARDWARE( r128ctx ); + r128ReleaseBufLocked( rmesa, rmesa->retained_buf ); + UNLOCK_HARDWARE( rmesa ); } - r128ctx->retained_buf = 0; + rmesa->retained_buf = 0; } -#define NEGATIVE(f) (f < 0) -#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) -#define LINTERP( T, A, B ) ( (A) + (T) * ( (B) - (A) ) ) +#define NEGATIVE( f ) (f < 0) +#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0) +#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) -#define INTERP_RGBA(t, out, a, b) { \ - int i; \ - for (i = 0; i < 4; i++) { \ - GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR(a[i]); \ - GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR(b[i]); \ - GLfloat fo = LINTERP(t, fa, fb); \ - FLOAT_COLOR_TO_UBYTE_COLOR(out[i], fo); \ - } \ +#define INTERP_RGBA( t, out, a, b ) { \ + GLuint i; \ + for ( i = 0 ; i < 4 ; i++ ) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \ + GLfloat fo = LINTERP( t, fa, fb ); \ + FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \ + } \ } -#define CLIP(SGN,V,PLANE) \ -if (mask & PLANE) { \ - GLuint *indata = inlist[in]; \ - GLuint *outdata = inlist[in ^= 1]; \ - GLuint nr = n; \ - GLfloat *J = verts[indata[nr-1]]; \ - GLfloat dpJ = (SGN J[V]) + J[3]; \ - \ - for (i = n = 0 ; i < nr ; i++) { \ - GLuint elt_i = indata[i]; \ - GLfloat *I = verts[elt_i]; \ - GLfloat dpI = (SGN I[V]) + I[3]; \ - \ - if (DIFFERENT_SIGNS(dpI, dpJ)) { \ - GLfloat *O = verts[next_vert]; \ - outdata[n++] = next_vert++; \ - \ - if (NEGATIVE(dpI)) { \ - GLfloat t = dpI / (dpI - dpJ); \ - interp(t, O, I, J); \ - } \ - else \ - { \ - GLfloat t = dpJ / (dpJ - dpI); \ - interp(t, O, J, I); \ - } \ - } \ - \ - if (!NEGATIVE(dpI)) \ - outdata[n++] = elt_i; \ - \ - J = I; \ - dpJ = dpI; \ - } \ - \ - if (n < 3) return; \ -} +#define CLIP( SGN, V, PLANE ) \ +do { \ + if ( mask & PLANE ) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]]; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + for ( i = n = 0 ; i < nr ; i++ ) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i]; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ + GLfloat *O = verts[next_vert]; \ + outdata[n++] = next_vert++; \ + \ + if ( NEGATIVE( dpI ) ) { \ + GLfloat t = dpI / (dpI - dpJ); \ + interp( t, O, I, J ); \ + } \ + else \ + { \ + GLfloat t = dpJ / (dpJ - dpI); \ + interp( t, O, J, I ); \ + } \ + } \ + \ + if ( !NEGATIVE( dpI ) ) \ + outdata[n++] = elt_i; \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if ( n < 3 ) return; \ + } \ +} while (0) -static void r128_tri_clip( r128ContextPtr r128ctx, +static void r128_tri_clip( r128ContextPtr rmesa, struct vertex_buffer *VB, GLuint *elt, GLubyte mask ) { - struct r128_elt_tab *tab = r128ctx->elt_tab; + struct r128_elt_tab *tab = rmesa->elt_tab; r128_interp_func interp = tab->interp; - GLint vertsize = r128ctx->vertsize; + GLuint vertsize = rmesa->vertsize; GLuint inlist[2][VB_MAX_CLIPPED_VERTS]; GLuint in = 0; GLuint n = 3, next_vert = 3; @@ -235,55 +220,44 @@ static void r128_tri_clip( r128ContextPtr r128ctx, /* Build temporary vertices in clipspace. This is the potential * downside to this path. */ - tab->build_tri_verts( r128ctx, VB, (GLfloat *)verts, elt ); + tab->build_tri_verts( rmesa, VB, (GLfloat *)verts, elt ); inlist[0][0] = 0; inlist[0][1] = 1; inlist[0][2] = 2; - CLIP(-,0,CLIP_RIGHT_BIT); - CLIP(+,0,CLIP_LEFT_BIT); - CLIP(-,1,CLIP_TOP_BIT); - CLIP(+,1,CLIP_BOTTOM_BIT); - CLIP(-,2,CLIP_FAR_BIT); - CLIP(+,2,CLIP_NEAR_BIT); + CLIP( -, 0, CLIP_RIGHT_BIT ); + CLIP( +, 0, CLIP_LEFT_BIT ); + CLIP( -, 1, CLIP_TOP_BIT ); + CLIP( +, 1, CLIP_BOTTOM_BIT ); + CLIP( -, 2, CLIP_FAR_BIT ); + CLIP( +, 2, CLIP_NEAR_BIT ); { GLuint *out = inlist[in]; - GLint space = (GLint)((GLuint)r128ctx->next_vert - - (GLuint)r128ctx->next_elt); + GLint space = (GLint)((GLuint)rmesa->next_vert - + (GLuint)rmesa->next_elt); - if ( DEBUG_ELTPATH ) - fprintf( stderr, " clip nv=%p ne=%p space=%d thresh=%d %d\n", - r128ctx->next_vert, r128ctx->next_elt, - space, (GLint)n * (vertsize + 2) * (GLint)sizeof(GLuint), - space < (GLint)n * (vertsize + 2) * (GLint)sizeof(GLuint) ); - - /* GH: Why the hell do we explicitly have to test the sign of the - * available space here? - */ - if ( space < (GLint)n * (vertsize + 2) * (GLint)sizeof(GLuint) ) { - fire_elts( r128ctx ); + if ( space < (GLint)(n * (vertsize + 2) * sizeof(GLuint)) ) { + fire_elts( rmesa ); } /* Project the new vertices and emit to dma buffers. Translate * out values to physical addresses for setup dma. */ - tab->project_and_emit_verts( r128ctx, (GLfloat *)verts, out, n ); + tab->project_and_emit_verts( rmesa, (GLfloat *)verts, out, n ); /* Convert the planar polygon to a list of triangles and emit to * elt buffers. */ - for (i = 2 ; i < n ; i++) { - r128ctx->next_elt[0] = (GLushort) out[0]; - r128ctx->next_elt[1] = (GLushort) out[i-1]; - r128ctx->next_elt[2] = (GLushort) out[i]; - r128ctx->next_elt += 3; + for ( i = 2 ; i < n ; i++ ) { + rmesa->next_elt[0] = (GLushort) out[0]; + rmesa->next_elt[1] = (GLushort) out[i-1]; + rmesa->next_elt[2] = (GLushort) out[i]; + rmesa->next_elt += 3; } } - if ( DEBUG_ELTPATH ) - fflush( stderr ); } @@ -295,37 +269,22 @@ static void r128_tri_clip( r128ContextPtr r128ctx, * unclipped primitives from the original list. */ -#define INIT(x) +#define INIT( x ) #define TRI_THRESHOLD (GLint)(2 * sizeof(GLuint)) -#define UNCLIPPED_VERT(x) (GLushort)(r128ctx->first_vert_index - x) +#define UNCLIPPED_VERT( x ) (GLushort)(rmesa->first_vert_index - x) #define TRIANGLE( e2, e1, e0 ) \ do { \ - if ( DEBUG_ELTPATH ) \ - fprintf( stderr, " tri nv=%p ne=%p space=%d thresh=%d %d\n", \ - r128ctx->next_vert, r128ctx->next_elt, \ - (GLint)((GLuint)r128ctx->next_vert - \ - (GLuint)r128ctx->next_elt), TRI_THRESHOLD, \ - ( (GLint)((GLuint)r128ctx->next_vert - \ - (GLuint)r128ctx->next_elt) < TRI_THRESHOLD ) );\ - if ( (GLint)((GLuint)r128ctx->next_vert - \ - (GLuint)r128ctx->next_elt) < TRI_THRESHOLD ) { \ - if ( DEBUG_ELTPATH ) \ - fprintf( stderr, " firing elts...\n" ); \ - fire_elts( r128ctx ); \ + if ( (GLint)((GLuint)rmesa->next_vert - \ + (GLuint)rmesa->next_elt) < TRI_THRESHOLD ) { \ + fire_elts( rmesa ); \ } \ - r128ctx->next_elt[0] = UNCLIPPED_VERT( e2 ); \ - r128ctx->next_elt[1] = UNCLIPPED_VERT( e1 ); \ - r128ctx->next_elt[2] = UNCLIPPED_VERT( e0 ); \ - if ( 0 ) \ - fprintf( stderr, " tri %d,%d,%d -> %hd,%hd,%hd\n", \ - e2, e1, e0, r128ctx->next_elt[0], \ - r128ctx->next_elt[1], r128ctx->next_elt[2]); \ - r128ctx->next_elt += 3; \ - if ( DEBUG_ELTPATH ) \ - fflush( stderr ); \ + rmesa->next_elt[0] = UNCLIPPED_VERT( e2 ); \ + rmesa->next_elt[1] = UNCLIPPED_VERT( e1 ); \ + rmesa->next_elt[2] = UNCLIPPED_VERT( e0 ); \ + rmesa->next_elt += 3; \ } while (0) #define CLIP_TRIANGLE( e2, e1, e0 ) \ @@ -337,16 +296,16 @@ do { \ out[0] = e2; \ out[1] = e1; \ out[2] = e0; \ - r128_tri_clip( r128ctx, VB, out, ormask ); \ + r128_tri_clip( rmesa, VB, out, ormask ); \ } \ } while (0) #define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT( VB->ctx ); \ + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); \ GLuint *elt = VB->EltPtr->data; \ GLuint out[VB_MAX_CLIPPED_VERTS]; \ GLubyte *mask = VB->ClipMask; \ - (void) mask; (void) out; (void) elt; (void) r128ctx; + (void) mask; (void) out; (void) elt; (void) rmesa; @@ -355,7 +314,7 @@ do { \ #define RENDER_TRI( i2, i1, i0, pv, parity ) \ do { \ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ - if (parity) e2 = elt[i1], e1 = elt[i2]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ CLIP_TRIANGLE( e2, e1, e0 ); \ } while (0) @@ -369,20 +328,20 @@ do { \ #define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT( VB->ctx ); \ + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); \ GLuint *elt = VB->EltPtr->data; \ - (void) elt; (void) r128ctx; + (void) elt; (void) rmesa; #define RENDER_POINTS( start, count ) #define RENDER_LINE( i1, i0 ) #define RENDER_TRI( i2, i1, i0, pv, parity ) \ do { \ GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ - if (parity) e2 = elt[i1], e1 = elt[i2]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ TRIANGLE( e2, e1, e0 ); \ } while (0) -#define RENDER_QUAD(i3, i2, i1, i0, pv ) \ +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ TRIANGLE( elt[i2], elt[i1], elt[i0] ) @@ -394,16 +353,16 @@ do { \ static void refresh_projection_matrix( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); GLmatrix *mat = &ctx->Viewport.WindowMap; - GLfloat *m = r128ctx->device_matrix; + GLfloat *m = rmesa->device_matrix; m[MAT_SX] = mat->m[MAT_SX]; m[MAT_TX] = mat->m[MAT_TX]; m[MAT_SY] = -mat->m[MAT_SY]; - m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h; - m[MAT_SZ] = mat->m[MAT_SZ] * r128ctx->depth_scale; - m[MAT_TZ] = mat->m[MAT_TZ] * r128ctx->depth_scale; + m[MAT_TY] = -mat->m[MAT_TY] + rmesa->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * rmesa->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * rmesa->depth_scale; } #define CLIP_UBYTE_B 0 @@ -439,7 +398,7 @@ static void refresh_projection_matrix( GLcontext *ctx ) /* Very sparsely popluated array - fix the indices. */ -static struct r128_elt_tab r128EltTab[0x80]; +static struct r128_elt_tab r128EltTab[R128_MAX_SETUPFUNC]; void r128DDEltPathInit( void ) { @@ -451,7 +410,9 @@ void r128DDEltPathInit( void ) r128_init_eltpath_TEX0( &r128EltTab[R128_TEX0_BIT] ); r128_init_eltpath_RGBA_TEX0( &r128EltTab[R128_RGBA_BIT|R128_TEX0_BIT] ); r128_init_eltpath_TEX0_TEX1( &r128EltTab[R128_TEX0_BIT|R128_TEX1_BIT] ); - r128_init_eltpath_RGBA_TEX0_TEX1( &r128EltTab[R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT] ); + r128_init_eltpath_RGBA_TEX0_TEX1( &r128EltTab[(R128_RGBA_BIT | + R128_TEX0_BIT | + R128_TEX1_BIT)] ); } #define VALID_SETUP (R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT) @@ -473,17 +434,11 @@ void r128DDEltPath( struct vertex_buffer *VB ) { GLcontext *ctx = VB->ctx; GLenum prim = ctx->CVA.elt_mode; - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - struct r128_elt_tab *tab = &r128EltTab[r128ctx->SetupIndex & VALID_SETUP]; - GLint vertsize = r128ctx->vertsize; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct r128_elt_tab *tab = &r128EltTab[rmesa->SetupIndex & VALID_SETUP]; + GLuint vertsize = rmesa->vertsize; GLint space; - if ( DEBUG_ELTPATH ) - fprintf( stderr, "\n\n\n%s: count=%d space=%d\n", - __FUNCTION__, VB->Count, - (GLint)((GLuint)r128ctx->next_vert - - (GLuint)r128ctx->next_elt) ); - VB->ClipPtr = TransformRaw( &VB->Clip, &ctx->ModelProjectMatrix, VB->ObjPtr ); @@ -498,40 +453,27 @@ void r128DDEltPath( struct vertex_buffer *VB ) &VB->ClipOrMask, &VB->ClipAndMask ); - if ( VB->ClipAndMask ) { - if ( DEBUG_ELTPATH ) - fprintf( stderr, " clipped, returning...\n" ); + if ( VB->ClipAndMask ) return; - } - if ( r128ctx->vert_buf ) { - r128FlushVertices( r128ctx ); - } - if ( r128ctx->new_state ) { + + if ( rmesa->vert_buf ) + r128FlushVertices( rmesa ); + + if ( rmesa->new_state ) r128DDUpdateHWState( ctx ); - } - space = (GLint)((GLuint)r128ctx->next_vert - - (GLuint)r128ctx->next_elt); + space = (GLint)((GLuint)rmesa->next_vert - + (GLuint)rmesa->next_elt); /* Allocate a single buffer to hold unclipped vertices. All * unclipped vertices must be contiguous. */ - if ( DEBUG_ELTPATH ) - fprintf( stderr, " top nv=%p ne=%p space=%d reqd=%d count=%d clip=0x%x\n\n", - r128ctx->next_vert, r128ctx->next_elt, space, - (GLint)VB->Count * vertsize * sizeof(GLuint), - VB->Count, VB->ClipOrMask ); - - /* Because we need to adjust the next_elt pointer to accomodate the - * CCE packet header, we can sometimes go past the next_vert pointer - * and thus have negative space. - */ - if ( space < (GLint)VB->Count * vertsize * (GLint)sizeof(GLuint) || - r128ctx->vertsize != r128ctx->elt_vertsize ) { - fire_elts( r128ctx ); + if ( space < (GLint)(VB->Count * vertsize * sizeof(GLuint)) || + rmesa->vertsize != rmesa->elt_vertsize ) { + fire_elts( rmesa ); } - r128ctx->retained_buf = r128ctx->elt_buf; + rmesa->retained_buf = rmesa->elt_buf; /* Emit unclipped vertices to the buffer. */ @@ -540,7 +482,7 @@ void r128DDEltPath( struct vertex_buffer *VB ) /* Emit indices and clipped vertices to one or more buffers. */ if ( VB->ClipOrMask ) { - r128ctx->elt_tab = tab; + rmesa->elt_tab = tab; r128_render_tab_elt[prim]( VB, 0, VB->EltPtr->count, 0 ); } else { r128_render_tab_elt_unclipped[prim]( VB, 0, VB->EltPtr->count, 0 ); @@ -548,20 +490,10 @@ void r128DDEltPath( struct vertex_buffer *VB ) /* Send to hardware and release the elt buffer. */ - release_bufs( r128ctx ); + release_bufs( rmesa ); /* This indicates that there is no cached data to reuse. */ VB->pipeline->data_valid = 0; VB->pipeline->new_state = 0; - - if ( DEBUG_ELTPATH ) { - FLUSH_BATCH( r128ctx ); - - LOCK_HARDWARE( r128ctx ); - drmR128WaitForIdleCCE( r128ctx->driFd ); - UNLOCK_HARDWARE( r128ctx ); - - __asm__ __volatile__ ( "int $3" ); - } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h index ba82a261f..11e30fbfe 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h @@ -1,25 +1,35 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h,v 1.1 2000/12/04 19:21:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_elttmp.h,v 1.2 2001/01/08 01:07:20 martin Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + Cedar Park, Texas. +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, PRECISION INSIGHT AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + /* - * DRI Hardware Device Driver for G200/G400 - * Copyright (C) 1999 Keith Whitwell - * - * 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 - * KEITH WHITWELL, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM, - * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR - * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE - * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * Authors: + * Keith Whitwell <keithw@valinux.com> + * Gareth Hughes <gareth@valinux.com> * */ @@ -34,8 +44,7 @@ */ static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) { - GLuint i; - r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); GLfloat *dev = VB->Projected->start; GLubyte *color = VB->ColorPtr->start; GLfloat *tex0_data = VB->TexCoordPtr[0]->start; @@ -43,45 +52,38 @@ static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) GLuint color_stride = VB->ColorPtr->stride; GLuint tex0_stride = VB->TexCoordPtr[0]->stride; GLuint tex1_stride = VB->TexCoordPtr[1]->stride; - GLuint buffer_stride = r128ctx->vertsize; + GLuint buffer_stride = rmesa->vertsize; - GLfloat *f = r128ctx->next_vert; + GLfloat *f = rmesa->next_vert; GLuint count = VB->Count; GLubyte *clipmask = VB->ClipMask; - const GLfloat *m = r128ctx->device_matrix; + const GLfloat *m = rmesa->device_matrix; const GLfloat sx = m[0], sy = m[5], sz = m[10]; const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLuint i; - if ( 0 ) - fprintf( stderr, "%s: stride=%d\n", __FUNCTION__, buffer_stride ); - - r128ctx->retained_buf = r128ctx->elt_buf; - r128ctx->first_vert_index = r128ctx->next_vert_index; + rmesa->retained_buf = rmesa->elt_buf; + rmesa->first_vert_index = rmesa->next_vert_index; for ( i = 0 ; i < count ; f -= buffer_stride, i++ ) { if ( !clipmask[i] ) { - if ( 0 ) - fprintf( stderr, "vert=%d addr=%p space=0x%x\n", - i, f, (GLuint)f - (GLuint)r128ctx->elt_buf->address ); - f[0] = sx * dev[0] + tx; f[1] = sy * dev[1] + ty; f[2] = sz * dev[2] + tz; f[3] = dev[3]; - if (TYPE & R128_RGBA_BIT) { + if ( TYPE & R128_RGBA_BIT ) { #if 0 /*defined(USE_X86_ASM)*/ - __asm__ ( - "movl (%%edx),%%eax \n" - "bswap %%eax \n" - "rorl $8,%%eax \n" - "movl %%eax,16(%%edi) \n" - : - : "d" (color), "D" (f) - : "%eax" ); + __asm__ ( "movl (%%edx),%%eax \n" + "bswap %%eax \n" + "rorl $8,%%eax \n" + "movl %%eax,16(%%edi) \n" + : + : "d" (color), "D" (f) + : "%eax" ); #else GLubyte *b = (GLubyte *)&f[4]; b[CLIP_UBYTE_B] = color[2]; @@ -91,25 +93,25 @@ static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) #endif } - if (TYPE & R128_TEX0_BIT) { - *(int*)&f[6] = *(int*)&tex0_data[0]; - *(int*)&f[7] = *(int*)&tex0_data[1]; + if ( TYPE & R128_TEX0_BIT ) { + *(GLuint *)&f[6] = *(GLuint *)&tex0_data[0]; + *(GLuint *)&f[7] = *(GLuint *)&tex0_data[1]; } - if (TYPE & R128_TEX1_BIT) { - *(int*)&f[8] = *(int*)&tex1_data[0]; - *(int*)&f[9] = *(int*)&tex1_data[1]; + if ( TYPE & R128_TEX1_BIT ) { + *(GLuint *)&f[8] = *(GLuint *)&tex1_data[0]; + *(GLuint *)&f[9] = *(GLuint *)&tex1_data[1]; } } - STRIDE_F(dev, 16); - if (TYPE & R128_RGBA_BIT) color += color_stride; - if (TYPE & R128_TEX0_BIT) STRIDE_F(tex0_data, tex0_stride); - if (TYPE & R128_TEX1_BIT) STRIDE_F(tex1_data, tex1_stride); + STRIDE_F( dev, 16 ); + if ( TYPE & R128_RGBA_BIT ) color += color_stride; + if ( TYPE & R128_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); + if ( TYPE & R128_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); } - r128ctx->next_vert = f; - r128ctx->next_vert_index -= count; + rmesa->next_vert = f; + rmesa->next_vert_index -= count; } @@ -117,12 +119,12 @@ static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) * Recreate from the VB data rather than trying to read back from * uncached memory. */ -static void TAG(build_tri_verts)( r128ContextPtr r128ctx, +static void TAG(build_tri_verts)( r128ContextPtr rmesa, struct vertex_buffer *VB, GLfloat *O, GLuint *elt ) { - int i; + GLint i; for ( i = 0 ; i < 3 ; i++, O += CLIP_STRIDE ) { GLfloat *clip = VB->Clip.start + elt[i]*4; @@ -132,8 +134,8 @@ static void TAG(build_tri_verts)( r128ContextPtr r128ctx, O[2] = clip[2]; O[3] = clip[3]; - if (TYPE & R128_RGBA_BIT) { - GLubyte *col = VEC_ELT(VB->ColorPtr, GLubyte, elt[i]); + if ( TYPE & R128_RGBA_BIT ) { + GLubyte *col = VEC_ELT( VB->ColorPtr, GLubyte, elt[i] ); GLubyte *b = (GLubyte *)&O[4]; b[CLIP_UBYTE_R] = col[0]; b[CLIP_UBYTE_G] = col[1]; @@ -141,22 +143,16 @@ static void TAG(build_tri_verts)( r128ContextPtr r128ctx, b[CLIP_UBYTE_A] = col[3]; } - if ( 0 ) - fprintf(stderr, - "build_tri_vert elt[%d]=%d index=0x%x (first_index=0x%x)\n", - i, elt[i], (GLuint)UNCLIPPED_VERT(elt[i]), - (GLuint)r128ctx->first_vert_index); - *(GLuint *)&O[5] = UNCLIPPED_VERT(elt[i]); - if (TYPE & R128_TEX0_BIT) { - GLfloat *tex0_data = VEC_ELT(VB->TexCoordPtr[0], GLfloat, elt[i]); + if ( TYPE & R128_TEX0_BIT ) { + GLfloat *tex0_data = VEC_ELT( VB->TexCoordPtr[0], GLfloat, elt[i] ); *(int*)&O[6] = *(int*)&tex0_data[0]; *(int*)&O[7] = *(int*)&tex0_data[1]; } - if (TYPE & R128_TEX1_BIT) { - GLfloat *tex1_data = VEC_ELT(VB->TexCoordPtr[1], GLfloat, elt[i]); + if ( TYPE & R128_TEX1_BIT ) { + GLfloat *tex1_data = VEC_ELT( VB->TexCoordPtr[1], GLfloat, elt[i] ); *(int*)&O[8] = *(int*)&tex1_data[0]; *(int*)&O[9] = *(int*)&tex1_data[1]; } @@ -171,30 +167,28 @@ static void TAG(interp)( GLfloat t, const GLfloat *I, const GLfloat *J ) { - O[0] = LINTERP(t, I[0], J[0]); - O[1] = LINTERP(t, I[1], J[1]); - O[2] = LINTERP(t, I[2], J[2]); - O[3] = LINTERP(t, I[3], J[3]); - - if (TYPE & R128_RGBA_BIT) { - INTERP_RGBA(t, - ((GLubyte *)&(O[4])), - ((GLubyte *)&(I[4])), - ((GLubyte *)&(J[4]))); + O[0] = LINTERP( t, I[0], J[0] ); + O[1] = LINTERP( t, I[1], J[1] ); + O[2] = LINTERP( t, I[2], J[2] ); + O[3] = LINTERP( t, I[3], J[3] ); + + if ( TYPE & R128_RGBA_BIT ) { + INTERP_RGBA( t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4])) ); } - if (0) fprintf(stderr, "setting 0x%x to ~0\n", (GLuint)&O[5]); - *(GLuint *)&O[5] = ~0; /* note that this is a new vertex */ - if (TYPE & R128_TEX0_BIT) { - O[6] = LINTERP(t, I[6], J[6]); - O[7] = LINTERP(t, I[7], J[7]); + if ( TYPE & R128_TEX0_BIT ) { + O[6] = LINTERP( t, I[6], J[6] ); + O[7] = LINTERP( t, I[7], J[7] ); } - if (TYPE & R128_TEX1_BIT) { - O[8] = LINTERP(t, I[8], J[8]); - O[9] = LINTERP(t, I[9], J[9]); + if ( TYPE & R128_TEX1_BIT ) { + O[8] = LINTERP( t, I[8], J[8] ); + O[9] = LINTERP( t, I[9], J[9] ); } } @@ -204,30 +198,26 @@ static void TAG(interp)( GLfloat t, * new ones to dma buffers. Update the element list to a format * suitable for sending to hardware. */ -static void TAG(project_and_emit_verts)( r128ContextPtr r128ctx, +static void TAG(project_and_emit_verts)( r128ContextPtr rmesa, const GLfloat *verts, GLuint *elt, - int nr) + GLuint nr) { - GLfloat *O = r128ctx->next_vert; - GLushort index = r128ctx->next_vert_index; - GLuint buffer_stride = r128ctx->vertsize; + GLfloat *O = rmesa->next_vert; + GLushort index = rmesa->next_vert_index; + GLuint buffer_stride = rmesa->vertsize; - const GLfloat *m = r128ctx->device_matrix; + const GLfloat *m = rmesa->device_matrix; const GLfloat sx = m[0], sy = m[5], sz = m[10]; const GLfloat tx = m[12], ty = m[13], tz = m[14]; GLuint i; - for (i = 0 ; i < nr ; i++) { + for ( i = 0 ; i < nr ; i++ ) { const GLfloat *I = &verts[elt[i] * CLIP_STRIDE]; GLuint tmp = *(GLuint *)&I[5]; - if (0) fprintf(stderr, "elt[%d] (tmp 0x%x %d) %d --> ", - i, (GLuint)&I[5], tmp, elt[i]); - - if ((elt[i] = tmp) == ~0) - { - GLfloat oow = 1.0/I[3]; + if ( (elt[i] = tmp) == ~0 ) { + GLfloat oow = 1.0 / I[3]; elt[i] = index--; @@ -236,37 +226,36 @@ static void TAG(project_and_emit_verts)( r128ContextPtr r128ctx, O[2] = sz * I[2] * oow + tz; O[3] = oow; - if (TYPE & R128_RGBA_BIT) { - *(int*)&O[4] = *(int*)&I[4]; + if ( TYPE & R128_RGBA_BIT ) { + *(GLuint *)&O[4] = *(GLuint *)&I[4]; } - if (TYPE & R128_TEX0_BIT) { - *(int*)&O[6] = *(int*)&I[6]; - *(int*)&O[7] = *(int*)&I[7]; + if ( TYPE & R128_TEX0_BIT ) { + *(GLuint *)&O[6] = *(GLuint *)&I[6]; + *(GLuint *)&O[7] = *(GLuint *)&I[7]; } - if (TYPE & R128_TEX1_BIT) { - *(int*)&O[8] = *(int*)&I[8]; - *(int*)&O[9] = *(int*)&I[9]; + if ( TYPE & R128_TEX1_BIT ) { + *(GLuint *)&O[8] = *(GLuint *)&I[8]; + *(GLuint *)&O[9] = *(GLuint *)&I[9]; } O -= buffer_stride; } - if (0) fprintf(stderr, "0x%x\n", elt[i]); } - r128ctx->next_vert = O; - r128ctx->next_vert_index = index; + rmesa->next_vert = O; + rmesa->next_vert_index = index; } static void TAG(r128_init_eltpath)( struct r128_elt_tab *tab ) { - tab->emit_unclipped_verts = TAG(emit_unclipped_verts); - tab->build_tri_verts = TAG(build_tri_verts); - tab->interp = TAG(interp); - tab->project_and_emit_verts = TAG(project_and_emit_verts); + tab->emit_unclipped_verts = TAG(emit_unclipped_verts); + tab->build_tri_verts = TAG(build_tri_verts); + tab->interp = TAG(interp); + tab->project_and_emit_verts = TAG(project_and_emit_verts); } #undef TYPE diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c index 57dab53a9..44c996125 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c,v 1.4 2000/12/04 19:21:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c,v 1.5 2001/01/08 01:07:20 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -29,8 +29,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Keith Whitwell <keithw@valinux.com> - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -44,67 +44,58 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "cva.h" #include "vertices.h" -/* HACK: Declare this global for now */ -static GLfloat m[16] __attribute__ ((aligned (16))); - -/* FIXME: These routines were copied from the i810 driver, and were only - slightly modified for the Rage 128. They still need to be optmizied - and cleaned up. Also, support for USE_RHW2 needs to be added. - - KW: The fastpath never does projective texturing, so RHW2 support - isn't necesary here. -*/ struct r128_fast_tab { void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest ); void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); }; -#define POINT(x) r128_draw_point( r128ctx, &vert[x], psize ) -#define LINE(x,y) r128_draw_line( r128ctx, &vert[x], &vert[y], lwidth ) -#define TRI(x,y,z) r128_draw_triangle( r128ctx, &vert[x], &vert[y], &vert[z] ) +#define POINT(x) r128_draw_point( rmesa, &vert[x], psize ) +#define LINE(x,y) r128_draw_line( rmesa, &vert[x], &vert[y], lwidth ) +#define TRI(x,y,z) r128_draw_triangle( rmesa, &vert[x], &vert[y], &vert[z] ) /* Direct, and no clipping required. The clip funcs have not been - written yet, so this is only useful for the fast path. */ -#define RENDER_POINTS(start, count) \ + * written yet, so this is only useful for the fast path. + */ +#define RENDER_POINTS( start, count ) \ do { \ GLuint e; \ - for (e = start; e < count; e++) \ - POINT(elt[e]); \ + for ( e = start ; e < count ; e++ ) \ + POINT( elt[e] ); \ } while (0) -#define RENDER_LINE(i1, i) \ +#define RENDER_LINE( i1, i ) \ do { \ GLuint e1 = elt[i1], e = elt[i]; \ - LINE(e1, e); \ + LINE( e1, e ); \ } while (0) -#define RENDER_TRI(i2, i1, i, pv, parity) \ +#define RENDER_TRI( i2, i1, i, pv, parity ) \ do { \ GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - if (parity) { \ + if ( parity ) { \ GLuint tmp = e2; \ e2 = e1; \ e1 = tmp; \ } \ - TRI(e2, e1, e); \ + TRI( e2, e1, e ); \ } while (0) -#define RENDER_QUAD(i3, i2, i1, i, pv) \ +#define RENDER_QUAD( i3, i2, i1, i, pv ) \ do { \ GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ - TRI(e3, e2, e); \ - TRI(e2, e1, e); \ + TRI( e3, e2, e ); \ + TRI( e2, e1, e ); \ } while (0) #define LOCAL_VARS \ - r128VertexPtr vert = R128_DRIVER_DATA(VB)->verts; \ - const GLuint *elt = VB->EltPtr->data; \ - GLcontext *ctx = VB->ctx; \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - const GLfloat lwidth = ctx->Line.Width; \ - const GLfloat psize = ctx->Point.Size; \ + r128VertexPtr vert = R128_DRIVER_DATA(VB)->verts; \ + const GLuint *elt = VB->EltPtr->data; \ + GLcontext *ctx = VB->ctx; \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + const GLfloat lwidth = ctx->Line.Width; \ + const GLfloat psize = ctx->Point.Size; \ (void) lwidth; (void) psize; (void) vert; #define TAG(x) r128_##x##_smooth_indirect @@ -112,12 +103,12 @@ do { \ -#define NEGATIVE(f) (f < 0) -#define DIFFERENT_SIGNS(a,b) ((a*b) < 0) -#define LINTERP(T, A, B) ((A) + (T) * ((B) - (A))) +#define NEGATIVE( f ) (f < 0) +#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0) +#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) -#define INTERP_RGBA(t, out, a, b) \ +#define INTERP_RGBA( t, out, a, b ) \ do { \ int i; \ for (i = 0; i < 4; i++) { \ @@ -129,9 +120,9 @@ do { \ } while (0) -#define CLIP(SGN, V, PLANE) \ +#define CLIP( SGN, V, PLANE ) \ do { \ - if (mask & PLANE) { \ + if ( mask & PLANE ) { \ GLuint *indata = inlist[in]; \ GLuint *outdata = inlist[in ^= 1]; \ GLuint nr = n; \ @@ -139,16 +130,16 @@ do { \ GLfloat dpJ = (SGN J[V]) + J[3]; \ \ inlist[0] = vlist1; \ - for (i = n = 0 ; i < nr ; i++) { \ + for ( i = n = 0 ; i < nr ; i++ ) { \ GLuint elt_i = indata[i]; \ GLfloat *I = verts[elt_i].f; \ GLfloat dpI = (SGN I[V]) + I[3]; \ \ - if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ GLfloat *O = verts[next_vert].f; \ GLfloat t, *in, *out; \ \ - if (NEGATIVE(dpI)) { \ + if ( NEGATIVE( dpI ) ) { \ t = dpI / (dpI - dpJ); \ in = I; \ out = J; \ @@ -158,7 +149,7 @@ do { \ out = I; \ } \ \ - interp(t, O, in, out); \ + interp( t, O, in, out ); \ \ clipmask[next_vert] = 0; \ outdata[n++] = next_vert++; \ @@ -166,7 +157,7 @@ do { \ \ clipmask[elt_i] |= PLANE; /* don't set up */ \ \ - if (!NEGATIVE(dpI)) { \ + if ( !NEGATIVE( dpI ) ) { \ outdata[n++] = elt_i; \ clipmask[elt_i] &= ~PLANE; /* set up after all */ \ } \ @@ -175,25 +166,25 @@ do { \ dpJ = dpI; \ } \ \ - if (n < 3) return; \ + if ( n < 3 ) return; \ } \ } while (0) -#define LINE_CLIP(x,y,z,w,PLANE) \ +#define LINE_CLIP( x, y, z, w, PLANE ) \ do { \ - if (mask & PLANE) { \ - GLfloat dpI = DOT4V(I,x,y,z,w); \ - GLfloat dpJ = DOT4V(J,x,y,z,w); \ + if ( mask & PLANE ) { \ + GLfloat dpI = DOT4V( I, x, y, z, w ); \ + GLfloat dpJ = DOT4V( J, x, y, z, w ); \ \ - if (DIFFERENT_SIGNS(dpI, dpJ)) { \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ GLfloat *O = verts[next_vert].f; \ GLfloat t = dpI / (dpI - dpJ); \ \ - interp(t, O, I, J); \ + interp( t, O, I, J ); \ \ clipmask[next_vert] = 0; \ \ - if (NEGATIVE(dpI)) { \ + if ( NEGATIVE( dpI ) ) { \ clipmask[elts[0]] |= PLANE; \ I = O; \ elts[0] = next_vert++; \ @@ -202,13 +193,13 @@ do { \ J = O; \ elts[1] = next_vert++; \ } \ - } else if (NEGATIVE(dpI)) return; \ + } else if ( NEGATIVE( dpI ) ) return; \ } \ } while (0) static __inline void r128_tri_clip( GLuint **p_elts, - r128Vertex *verts, + r128VertexPtr verts, GLubyte *clipmask, GLuint *p_next_vert, GLubyte mask, @@ -237,7 +228,7 @@ static __inline void r128_tri_clip( GLuint **p_elts, /* Convert the planar polygon to a list of triangles */ out = inlist[in]; - for (i = 2 ; i < n ; i++) { + for ( i = 2 ; i < n ; i++ ) { elts[0] = out[0]; elts[1] = out[i-1]; elts[2] = out[i]; @@ -250,7 +241,7 @@ static __inline void r128_tri_clip( GLuint **p_elts, static __inline void r128_line_clip( GLuint **p_elts, - r128Vertex *verts, + r128VertexPtr verts, GLubyte *clipmask, GLuint *p_next_vert, GLubyte mask, @@ -274,26 +265,27 @@ static __inline void r128_line_clip( GLuint **p_elts, -#define CLIP_POINT(e) \ +#define CLIP_POINT( e ) \ do { \ if (mask[e]) *out++ = e; \ } while (0) -#define CLIP_LINE(e1, e0) \ +#define CLIP_LINE( e1, e0 ) \ do { \ GLubyte ormask = mask[e0] | mask[e1]; \ out[0] = e1; \ out[1] = e0; \ out += 2; \ - if (ormask) { \ + if ( ormask ) { \ out-=2; \ - if (!(mask[e0] & mask[e1])) { \ - r128_line_clip(&out, verts, mask, &next_vert, ormask, interp); \ + if ( !(mask[e0] & mask[e1]) ) { \ + r128_line_clip( &out, verts, mask, \ + &next_vert, ormask, interp ); \ } \ } \ } while (0) -#define CLIP_TRIANGLE(e2, e1, e0) \ +#define CLIP_TRIANGLE( e2, e1, e0 ) \ do { \ GLubyte ormask; \ out[0] = e2; \ @@ -301,10 +293,11 @@ do { \ out[2] = e0; \ out += 3; \ ormask = mask[e2] | mask[e1] | mask[e0]; \ - if (ormask) { \ + if ( ormask ) { \ out -= 3; \ - if (!(mask[e2] & mask[e1] & mask[e0])) { \ - r128_tri_clip(&out, verts, mask, &next_vert, ormask, interp); \ + if ( !(mask[e2] & mask[e1] & mask[e0]) ) { \ + r128_tri_clip( &out, verts, mask, \ + &next_vert, ormask, interp ); \ } \ } \ } while (0) @@ -316,47 +309,47 @@ do { \ * ie (points, lines, triangles) containing all the clipped and * unclipped primitives from the original list. */ -#define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \ - r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); \ - GLuint *elt = VB->EltPtr->data; \ - r128Vertex *verts = r128VB->verts; \ - GLuint next_vert = r128VB->last_vert; \ - GLuint *out = r128VB->clipped_elements.data; \ - GLubyte *mask = VB->ClipMask; \ - r128_interp_func interp = r128ctx->interp; \ +#define LOCAL_VARS \ + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); \ + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); \ + GLuint *elt = VB->EltPtr->data; \ + r128VertexPtr verts = r128VB->verts; \ + GLuint next_vert = r128VB->last_vert; \ + GLuint *out = r128VB->clipped_elements.data; \ + GLubyte *mask = VB->ClipMask; \ + r128_interp_func interp = rmesa->interp; \ (void) interp; (void) verts; -#define POSTFIX \ - r128VB->clipped_elements.count = out - r128VB->clipped_elements.data; \ +#define POSTFIX \ + r128VB->clipped_elements.count = out - r128VB->clipped_elements.data;\ r128VB->last_vert = next_vert; -#define INIT(x) +#define INIT( x ) -#define RENDER_POINTS(start, count) \ -do { \ - GLuint i; \ - for (i = start; i < count; i++) \ - CLIP_POINT(elt[i]); \ +#define RENDER_POINTS( start, count ) \ +do { \ + GLuint i; \ + for ( i = start ; i < count ; i++ ) \ + CLIP_POINT( elt[i] ); \ } while (0) -#define RENDER_LINE(i1, i0) \ -do { \ - CLIP_LINE(elt[i1], elt[i0]); \ +#define RENDER_LINE( i1, i0 ) \ +do { \ + CLIP_LINE( elt[i1], elt[i0] ); \ } while (0) -#define RENDER_TRI(i2, i1, i0, pv, parity) \ -do { \ - GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ - if (parity) e2 = elt[i1], e1 = elt[i2]; \ - CLIP_TRIANGLE(e2, e1, e0); \ +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ } while (0) -#define RENDER_QUAD(i3, i2, i1, i0, pv) \ -do { \ - CLIP_TRIANGLE(elt[i3], elt[i2], elt[i0]); \ - CLIP_TRIANGLE(elt[i2], elt[i1], elt[i0]); \ +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ +do { \ + CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ); \ } while (0) #define TAG(x) r128_##x##_clip_elt @@ -406,17 +399,16 @@ do { \ -/* Render elements directly from original list of vertices. */ static void r128_render_elements_direct( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - GLenum prim = ctx->CVA.elt_mode; - GLuint nr = VB->EltPtr->count; - render_func func = r128_render_tab_smooth_indirect[prim]; - GLuint p = 0; - - if ( r128ctx->new_state ) + GLcontext *ctx = VB->ctx; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLenum prim = ctx->CVA.elt_mode; + GLuint nr = VB->EltPtr->count; + render_func func = r128_render_tab_smooth_indirect[prim]; + GLuint p = 0; + + if ( rmesa->new_state ) r128DDUpdateHWState( ctx ); do { @@ -425,20 +417,20 @@ static void r128_render_elements_direct( struct vertex_buffer *VB ) ctx->Driver.MultipassFunc( VB, ++p ) ); } -/* Project vertices from clip to device space */ static void r128_project_vertices( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; - GLmatrix *mat = &ctx->Viewport.WindowMap; - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLfloat *m = rmesa->tmp_matrix; m[MAT_SX] = mat->m[MAT_SX]; m[MAT_TX] = mat->m[MAT_TX]; m[MAT_SY] = -mat->m[MAT_SY]; - m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h; - m[MAT_SZ] = mat->m[MAT_SZ] * r128ctx->depth_scale; - m[MAT_TZ] = mat->m[MAT_TZ] * r128ctx->depth_scale; + m[MAT_TY] = -mat->m[MAT_TY] + rmesa->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * rmesa->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * rmesa->depth_scale; gl_project_v16( r128VB->verts[VB->CopyStart].f, r128VB->verts[r128VB->last_vert].f, @@ -446,20 +438,20 @@ static void r128_project_vertices( struct vertex_buffer *VB ) 16 * 4 ); } -/* Project clipped vertices from clip to device space */ static void r128_project_clipped_vertices( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; - GLmatrix *mat = &ctx->Viewport.WindowMap; - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); + GLfloat *m = rmesa->tmp_matrix; m[MAT_SX] = mat->m[MAT_SX]; m[MAT_TX] = mat->m[MAT_TX]; m[MAT_SY] = -mat->m[MAT_SY]; - m[MAT_TY] = -mat->m[MAT_TY] + r128ctx->driDrawable->h; - m[MAT_SZ] = mat->m[MAT_SZ] * r128ctx->depth_scale; - m[MAT_TZ] = mat->m[MAT_TZ] * r128ctx->depth_scale; + m[MAT_TY] = -mat->m[MAT_TY] + rmesa->driDrawable->h; + m[MAT_SZ] = mat->m[MAT_SZ] * rmesa->depth_scale; + m[MAT_TZ] = mat->m[MAT_TZ] * rmesa->depth_scale; gl_project_clipped_v16( r128VB->verts[VB->CopyStart].f, r128VB->verts[r128VB->last_vert].f, @@ -468,9 +460,8 @@ static void r128_project_clipped_vertices( struct vertex_buffer *VB ) VB->ClipMask + VB->CopyStart ); } -static struct r128_fast_tab r128FastTab[0x80]; +static struct r128_fast_tab r128FastTab[R128_MAX_SETUPFUNC]; -/* Initialize the table of fast path support functions */ void r128DDFastPathInit( void ) { r128_render_init_clip_elt(); @@ -481,25 +472,26 @@ void r128DDFastPathInit( void ) r128_init_fastpath_TEX0( &r128FastTab[R128_TEX0_BIT] ); r128_init_fastpath_RGBA_TEX0( &r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT] ); r128_init_fastpath_TEX0_TEX1( &r128FastTab[R128_TEX0_BIT|R128_TEX1_BIT] ); - r128_init_fastpath_RGBA_TEX0_TEX1( &r128FastTab[R128_RGBA_BIT|R128_TEX0_BIT| - R128_TEX1_BIT] ); + r128_init_fastpath_RGBA_TEX0_TEX1( &r128FastTab[(R128_RGBA_BIT | + R128_TEX0_BIT | + R128_TEX1_BIT)] ); } #define VALID_SETUP (R128_RGBA_BIT | R128_TEX0_BIT | R128_TEX1_BIT) void r128DDFastPath( struct vertex_buffer *VB ) { - GLcontext *ctx = VB->ctx; + GLcontext *ctx = VB->ctx; GLenum prim = ctx->CVA.elt_mode; - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - struct r128_fast_tab *tab = &r128FastTab[r128ctx->SetupIndex & VALID_SETUP]; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct r128_fast_tab *tab = &r128FastTab[rmesa->SetupIndex & VALID_SETUP]; GLuint do_cliptest = 1; gl_prepare_arrays_cva( VB ); /* still need this */ if ( ( gl_reduce_prim[prim] == GL_TRIANGLES ) && ( VB->Count < (R128_BUFFER_SIZE / (10 * sizeof(GLuint))) ) && - ( ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL| + ( ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL | MAT_FLAG_PERSPECTIVE) ) ) { r128DDEltPath( VB ); @@ -514,14 +506,14 @@ void r128DDFastPath( struct vertex_buffer *VB ) tab->build_vertices( VB, do_cliptest ); /* object->clip space */ - if ( r128ctx->new_state ) + if ( rmesa->new_state ) r128DDUpdateHWState( ctx ); if ( VB->ClipOrMask ) { if ( !VB->ClipAndMask ) { render_func *clip = r128_render_tab_clip_elt; - r128ctx->interp = tab->interp; + rmesa->interp = tab->interp; clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h index 8f51fe74c..4370a553c 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h,v 1.2 2000/12/04 19:21:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h,v 1.3 2001/01/08 01:07:20 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -33,12 +33,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -/* FIXME: These routines were copied from the i810 driver, and were only - slightly modified for the Rage 128. They still need to be optmizied - and cleaned up. Also, support for USE_RHW2 needs to be added. */ - /* The first part of setup is applied to all vertices, clipped or - * unclipped. This data w!ill be used for clipping, and then all + * unclipped. This data will be used for clipping, and then all * vertices with a zero clipmask will be projected to device space. * * This could be split into several loops, but - it seems that the @@ -46,106 +42,107 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * performance factor, and that multiple loops mean multiple cache * misses.... */ -static void TAG(r128_setup_full)(struct vertex_buffer *VB, GLuint do_cliptest) +static void TAG(r128_setup_full)( struct vertex_buffer *VB, + GLuint do_cliptest ) { - GLcontext *ctx = VB->ctx; - r128VertexBufferPtr r128VB = R128_DRIVER_DATA(VB); - const GLfloat *m = ctx->ModelProjectMatrix.m; - GLuint start = VB->CopyStart; - GLuint count = VB->Count; + GLcontext *ctx = VB->ctx; + r128VertexBufferPtr rvb = R128_DRIVER_DATA(VB); + const GLfloat *m = ctx->ModelProjectMatrix.m; + GLuint start = VB->CopyStart; + GLuint count = VB->Count; - gl_xform_points3_v16_general(r128VB->verts[start].f, + gl_xform_points3_v16_general( rvb->verts[start].f, m, VB->ObjPtr->start, VB->ObjPtr->stride, - count - start); - - if (do_cliptest) { - VB->ClipAndMask = ~0; - VB->ClipOrMask = 0; - gl_cliptest_points4_v16(r128VB->verts[start].f, - r128VB->verts[count].f, - &(VB->ClipOrMask), - &(VB->ClipAndMask), - VB->ClipMask + start); - } - - /* These branches are all resolved at compile time. Hopefully all - * the pointers are valid addresses even when not enabled. - */ - if (TYPE) { - GLubyte *color = VB->ColorPtr->start; - GLfloat *tex0_data = VB->TexCoordPtr[0]->start; - GLfloat *tex1_data = VB->TexCoordPtr[1]->start; - - GLuint color_stride = VB->ColorPtr->stride; - GLuint tex0_stride = VB->TexCoordPtr[0]->stride; - GLuint tex1_stride = VB->TexCoordPtr[1]->stride; - - GLfloat *f = r128VB->verts[start].f; - GLfloat *end = f + (16 * (count - start)); - - while (f != end) { - if (TYPE & R128_RGBA_BIT) { + count - start ); + + if ( do_cliptest ) { + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + gl_cliptest_points4_v16( rvb->verts[start].f, + rvb->verts[count].f, + &(VB->ClipOrMask), + &(VB->ClipAndMask), + VB->ClipMask + start ); + } + + /* These branches are all resolved at compile time. Hopefully all + * the pointers are valid addresses even when not enabled. + */ + if ( TYPE ) { + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + + GLfloat *f = rvb->verts[start].f; + GLfloat *end = f + (16 * (count - start)); + + while ( f != end ) { + if ( TYPE & R128_RGBA_BIT ) { #if defined(USE_X86_ASM) - /* GTH: I'd like to get some accurate timing data on the - * bswap instruction, but it gives a nice speedup anyway. - */ - __asm__ ("movl (%%edx),%%eax \n" + /* GH: I'd like to get some accurate timing data on the + * bswap instruction, but it gives a nice speedup anyway. + */ + __asm__ ( "movl (%%edx),%%eax \n" "bswap %%eax \n" "rorl $8,%%eax \n" "movl %%eax,16(%%edi) \n" : : "d" (color), "D" (f) - : "%eax"); + : "%eax" ); #else - GLubyte *col = color; - GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; - b[CLIP_UBYTE_B] = col[2]; - b[CLIP_UBYTE_G] = col[1]; - b[CLIP_UBYTE_R] = col[0]; - b[CLIP_UBYTE_A] = col[3]; + GLubyte *col = color; + GLubyte *b = (GLubyte *)&f[CLIP_UBYTE_COLOR]; + b[CLIP_UBYTE_B] = col[2]; + b[CLIP_UBYTE_G] = col[1]; + b[CLIP_UBYTE_R] = col[0]; + b[CLIP_UBYTE_A] = col[3]; #endif - } - if (TYPE & R128_TEX0_BIT) { + } + if ( TYPE & R128_TEX0_BIT ) { #if defined (USE_X86_ASM) - __asm__ ("movl (%%ecx), %%eax \n" + __asm__ ( "movl (%%ecx), %%eax \n" "movl %%eax, 24(%%edi) \n" "movl 4(%%ecx), %%eax \n" "movl %%eax, 28(%%edi)" : : "c" (tex0_data), "D" (f) - : "%eax"); + : "%eax" ); #else - *(unsigned int *)(f+CLIP_S0) = *(unsigned int *)tex0_data; - *(unsigned int *)(f+CLIP_T0) = *(unsigned int *)(tex0_data+1); + *(GLuint *)(f+CLIP_S0) = *(GLuint *)tex0_data; + *(GLuint *)(f+CLIP_T0) = *(GLuint *)(tex0_data+1); #endif - } - if (TYPE & R128_TEX1_BIT) { - /* Hits a second cache line. - */ + } + if ( TYPE & R128_TEX1_BIT ) { + /* Hits a second cache line. + */ #if defined (USE_X86_ASM) - __asm__ ("movl (%%esi), %%eax \n" + __asm__ ( "movl (%%esi), %%eax \n" "movl %%eax, 32(%%edi) \n" "movl 4(%%esi), %%eax \n" "movl %%eax, 36(%%edi)" : : "S" (tex1_data), "D" (f) - : "%eax"); + : "%eax" ); #else - *(unsigned int *)(f+CLIP_S1) = *(unsigned int *)tex1_data; - *(unsigned int *)(f+CLIP_T1) = *(unsigned int *)(tex1_data+1); + *(GLuint *)(f+CLIP_S1) = *(GLuint *)tex1_data; + *(GLuint *)(f+CLIP_T1) = *(GLuint *)(tex1_data+1); #endif - } - if (TYPE & R128_RGBA_BIT) color += color_stride; - if (TYPE & R128_TEX0_BIT) STRIDE_F(tex0_data, tex0_stride); - if (TYPE & R128_TEX1_BIT) STRIDE_F(tex1_data, tex1_stride); - f += 16; - } - } - - r128VB->clipped_elements.count = start; - r128VB->last_vert = count; + } + if ( TYPE & R128_RGBA_BIT ) color += color_stride; + if ( TYPE & R128_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); + if ( TYPE & R128_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); + f += 16; + } + } + + rvb->clipped_elements.count = start; + rvb->last_vert = count; } @@ -153,39 +150,39 @@ static void TAG(r128_setup_full)(struct vertex_buffer *VB, GLuint do_cliptest) * routine into the header. Less code and better chance of doing some * of this stuff in assembly. */ -static void TAG(r128_interp_vert)(GLfloat t, - GLfloat *O, - const GLfloat *I, - const GLfloat *J) +static void TAG(r128_interp_vert)( GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J ) { - O[0] = LINTERP(t, I[0], J[0]); - O[1] = LINTERP(t, I[1], J[1]); - O[2] = LINTERP(t, I[2], J[2]); - O[3] = LINTERP(t, I[3], J[3]); - - if (TYPE & R128_RGBA_BIT) { - INTERP_RGBA(t, - ((GLubyte *)&(O[4])), - ((GLubyte *)&(I[4])), - ((GLubyte *)&(J[4]))); - } - - if (TYPE & R128_TEX0_BIT) { - O[6] = LINTERP(t, I[6], J[6]); - O[7] = LINTERP(t, I[7], J[7]); - } - - if (TYPE & R128_TEX1_BIT) { - O[8] = LINTERP(t, I[8], J[8]); - O[9] = LINTERP(t, I[9], J[9]); - } + O[0] = LINTERP( t, I[0], J[0] ); + O[1] = LINTERP( t, I[1], J[1] ); + O[2] = LINTERP( t, I[2], J[2] ); + O[3] = LINTERP( t, I[3], J[3] ); + + if ( TYPE & R128_RGBA_BIT ) { + INTERP_RGBA( t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4])) ); + } + + if ( TYPE & R128_TEX0_BIT ) { + O[6] = LINTERP( t, I[6], J[6] ); + O[7] = LINTERP( t, I[7], J[7] ); + } + + if ( TYPE & R128_TEX1_BIT ) { + O[8] = LINTERP( t, I[8], J[8] ); + O[9] = LINTERP( t, I[9], J[9] ); + } } static void TAG(r128_init_fastpath)(struct r128_fast_tab *tab) { - tab->build_vertices = TAG(r128_setup_full); - tab->interp = TAG(r128_interp_vert); + tab->build_vertices = TAG(r128_setup_full); + tab->interp = TAG(r128_interp_vert); } #undef TYPE diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c index 2ae7fe4b5..7b0fecedd 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c,v 1.2 2000/12/12 17:17:07 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c,v 1.3 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -38,7 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "mem.h" -#define R128_TIMEOUT 2000000 +#define R128_TIMEOUT 2048 /* ============================================================= @@ -47,9 +47,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* Get a new VB from the pool of vertex buffers in AGP space. */ -drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) +drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa ) { - int fd = r128ctx->r128Screen->driScreen->fd; + int fd = rmesa->r128Screen->driScreen->fd; int index = 0; int size = 0; drmDMAReq dma; @@ -57,7 +57,7 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) int to = 0; int ret; - dma.context = r128ctx->hHWContext; + dma.context = rmesa->hHWContext; dma.send_count = 0; dma.send_list = NULL; dma.send_sizes = NULL; @@ -68,15 +68,15 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) dma.request_sizes = &size; dma.granted_count = 0; - while ( !buf && ( to++ < r128ctx->CCEtimeout ) ) { + while ( !buf && ( to++ < R128_TIMEOUT ) ) { ret = drmDMA( fd, &dma ); if ( ret == 0 ) { - buf = &r128ctx->r128Screen->buffers->list[index]; + buf = &rmesa->r128Screen->buffers->list[index]; buf->used = 0; #if ENABLE_PERF_BOXES /* Bump the performance counter */ - r128ctx->c_vertexBuffers++; + rmesa->c_vertexBuffers++; #endif return buf; } @@ -84,6 +84,7 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) if ( !buf ) { drmR128EngineReset( fd ); + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "Error: Could not get new VB... exiting\n" ); exit( -1 ); } @@ -91,57 +92,50 @@ drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ) return buf; } -void r128FlushVerticesLocked( r128ContextPtr r128ctx ) +void r128FlushVerticesLocked( r128ContextPtr rmesa ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - drmBufPtr buffer = r128ctx->vert_buf; - int count = r128ctx->num_verts; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->vert_buf; + int count = rmesa->num_verts; int prim = R128_TRIANGLES; - int fd = r128ctx->driScreen->fd; + int fd = rmesa->driScreen->fd; int i; - if ( 0 ) - fprintf( stderr, "%s: buf=%d count=%d\n", - __FUNCTION__, buffer ? buffer->idx : -1, count ); + rmesa->num_verts = 0; + rmesa->vert_buf = NULL; - r128ctx->num_verts = 0; - r128ctx->vert_buf = NULL; - - if ( !buffer ) { + if ( !buffer ) return; - } - if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { - r128EmitHwStateLocked( r128ctx ); - } + if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) + r128EmitHwStateLocked( rmesa ); - if ( !nbox ) { + if ( !nbox ) count = 0; - } - if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; - } - if ( !count || !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + + if ( !count || !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128FlushVertexBuffer( fd, prim, buffer->idx, count, 1 ); } else { - for (i = 0 ; i < nbox ; ) { + for ( i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; int discard = 0; - r128ctx->sarea->nbox = nr - i; - for ( ; i < nr ; i++) { + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++ ) { *b++ = pbox[i]; } @@ -151,12 +145,12 @@ void r128FlushVerticesLocked( r128ContextPtr r128ctx ) discard = 1; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128FlushVertexBuffer( fd, prim, buffer->idx, count, discard ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } @@ -165,60 +159,53 @@ void r128FlushVerticesLocked( r128ContextPtr r128ctx ) * Indexed vertex buffer handling */ -void r128GetEltBufLocked( r128ContextPtr r128ctx ) +void r128GetEltBufLocked( r128ContextPtr rmesa ) { - r128ctx->elt_buf = r128GetBufferLocked( r128ctx ); + rmesa->elt_buf = r128GetBufferLocked( rmesa ); } -void r128FireEltsLocked( r128ContextPtr r128ctx, +void r128FireEltsLocked( r128ContextPtr rmesa, GLuint start, GLuint end, GLuint discard ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - drmBufPtr buffer = r128ctx->elt_buf; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->elt_buf; int prim = R128_TRIANGLES; - int fd = r128ctx->driScreen->fd; + int fd = rmesa->driScreen->fd; int i; - if ( 0 ) - fprintf( stderr, "%s: start=%d end=%d discard=%d\n", - __FUNCTION__, start, end, discard ); - - if ( !buffer ) { + if ( !buffer ) return; - } - if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { - r128EmitHwStateLocked( r128ctx ); - } + if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) + r128EmitHwStateLocked( rmesa ); - if ( !nbox ) { + if ( !nbox ) end = start; - } - if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; - } - if ( start == end || !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + + if ( start == end || !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128FlushIndices( fd, prim, buffer->idx, start, end, discard ); } else { - for (i = 0 ; i < nbox ; ) { + for ( i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; int d = 0; - r128ctx->sarea->nbox = nr - i; - for ( ; i < nr ; i++) { + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++ ) { *b++ = pbox[i]; } @@ -228,44 +215,40 @@ void r128FireEltsLocked( r128ContextPtr r128ctx, d = discard; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128FlushIndices( fd, prim, buffer->idx, start, end, discard ); } } if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) { - drmR128WaitForIdleCCE( r128ctx->driFd ); + drmR128WaitForIdleCCE( rmesa->driFd ); } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -void r128FlushEltsLocked( r128ContextPtr r128ctx ) +void r128FlushEltsLocked( r128ContextPtr rmesa ) { - if ( r128ctx->first_elt != r128ctx->next_elt ) { - r128FireEltsLocked( r128ctx, - ((GLuint)r128ctx->first_elt - - (GLuint)r128ctx->elt_buf->address), - ((GLuint)r128ctx->next_elt - - (GLuint)r128ctx->elt_buf->address), + if ( rmesa->first_elt != rmesa->next_elt ) { + r128FireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), 0 ); - ALIGN_NEXT_ELT( r128ctx ); - r128ctx->first_elt = r128ctx->next_elt; + ALIGN_NEXT_ELT( rmesa ); + rmesa->first_elt = rmesa->next_elt; } } -void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer ) +void r128ReleaseBufLocked( r128ContextPtr rmesa, drmBufPtr buffer ) { - int fd = r128ctx->driScreen->fd; - - if ( 0 ) - fprintf( stderr, "%s: buffer=%p\n", - __FUNCTION__, buffer ); + int fd = rmesa->driScreen->fd; - if ( !buffer ) { + if ( !buffer ) return; - } + drmR128FlushVertexBuffer( fd, R128_TRIANGLES, buffer->idx, 0, 1 ); } @@ -273,28 +256,28 @@ void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer ) /* Allocate some space in the current vertex buffer. If the current * buffer is full, flush it and grab another one. */ -CARD32 *r128AllocVertices( r128ContextPtr r128ctx, int count ) +CARD32 *r128AllocVertices( r128ContextPtr rmesa, int count ) { - return r128AllocVerticesInline( r128ctx, count ); + return r128AllocVerticesInline( rmesa, count ); } - /* ================================================================ * Texture uploads */ -void r128FireBlitLocked( r128ContextPtr r128ctx, drmBufPtr buffer, +void r128FireBlitLocked( r128ContextPtr rmesa, drmBufPtr buffer, GLint offset, GLint pitch, GLint format, GLint x, GLint y, GLint width, GLint height ) { GLint ret; - ret = drmR128TextureBlit( r128ctx->driFd, buffer->idx, + ret = drmR128TextureBlit( rmesa->driFd, buffer->idx, offset, pitch, format, x, y, width, height ); if ( ret ) { + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "drmR128TextureBlit: return = %d\n", ret ); exit( 1 ); } @@ -317,16 +300,16 @@ static void delay( void ) { * long as we want for a frame to complete. If it never does, then * the card has locked. */ -static int r128WaitForFrameCompletion( r128ContextPtr r128ctx ) +static int r128WaitForFrameCompletion( r128ContextPtr rmesa ) { - unsigned char *R128MMIO = r128ctx->r128Screen->mmio; + unsigned char *R128MMIO = rmesa->r128Screen->mmio.map; CARD32 frame; int i; int wait = 0; while ( 1 ) { frame = INREG( R128_LAST_FRAME_REG ); - if ( r128ctx->sarea->last_frame - frame <= R128_MAX_OUTSTANDING ) { + if ( rmesa->sarea->last_frame - frame <= R128_MAX_OUTSTANDING ) { break; } @@ -340,68 +323,129 @@ static int r128WaitForFrameCompletion( r128ContextPtr r128ctx ) return wait; } -/* Copy the back color buffer to the front color buffer */ -void r128SwapBuffers( r128ContextPtr r128ctx ) +/* Copy the back color buffer to the front color buffer. + */ +void r128SwapBuffers( r128ContextPtr rmesa ) { - GLint nbox = r128ctx->numClipRects; + GLint nbox = rmesa->numClipRects; GLint i; GLint ret; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "\n********************************\n" ); fprintf( stderr, "\n%s( %p )\n\n", - __FUNCTION__, r128ctx->glCtx ); + __FUNCTION__, rmesa->glCtx ); fflush( stderr ); } - /* Flush any outstanding vertex buffers */ - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - LOCK_HARDWARE( r128ctx ); + LOCK_HARDWARE( rmesa ); /* Throttle the frame rate -- only allow one pending swap buffers * request at a time. */ - if ( !r128WaitForFrameCompletion( r128ctx ) ) { - r128ctx->hardwareWentIdle = 1; + if ( !r128WaitForFrameCompletion( rmesa ) ) { + rmesa->hardwareWentIdle = 1; } else { - r128ctx->hardwareWentIdle = 0; + rmesa->hardwareWentIdle = 0; } for ( i = 0 ; i < nbox ; ) { GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , nbox ); - XF86DRIClipRectPtr box = r128ctx->pClipRects; - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr box = rmesa->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; GLint n = 0; for ( ; i < nr ; i++ ) { *b++ = *(XF86DRIClipRectRec *)&box[i]; n++; } - r128ctx->sarea->nbox = n; + rmesa->sarea->nbox = n; - ret = drmR128SwapBuffers( r128ctx->driFd ); + ret = drmR128SwapBuffers( rmesa->driFd ); if ( ret ) { + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "drmR128SwapBuffers: return = %d\n", ret ); exit( 1 ); } } if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) { - drmR128WaitForIdleCCE( r128ctx->driFd ); + drmR128WaitForIdleCCE( rmesa->driFd ); } - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= (R128_UPLOAD_CONTEXT | - R128_UPLOAD_MASKS | - R128_UPLOAD_CLIPRECTS); + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_MASKS | + R128_UPLOAD_CLIPRECTS); #if ENABLE_PERF_BOXES /* Log the performance counters if necessary */ - r128PerformanceCounters( r128ctx ); + r128PerformanceCounters( rmesa ); +#endif +} + +void r128PageFlip( r128ContextPtr rmesa ) +{ + GLint ret; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n%s( %p ): page=%d\n\n", + __FUNCTION__, rmesa->glCtx, rmesa->currentPage ); + } + + FLUSH_BATCH( rmesa ); + + LOCK_HARDWARE( rmesa ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + if ( !r128WaitForFrameCompletion( rmesa ) ) { + rmesa->hardwareWentIdle = 1; + } else { + rmesa->hardwareWentIdle = 0; + } + + /* The kernel will have been initialized to perform page flipping + * on a swapbuffers ioctl. + */ + ret = drmR128SwapBuffers( rmesa->driFd ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "drmR128SwapBuffers: return = %d\n", ret ); + exit( 1 ); + } + + if ( rmesa->currentPage == 0 ) { + rmesa->drawOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->r128Screen->frontPitch; + rmesa->currentPage = 1; + } else { + rmesa->drawOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->r128Screen->backPitch; + rmesa->currentPage = 0; + } + + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + rmesa->new_state |= R128_NEW_WINDOW; + + /* FIXME: Do we need this anymore? */ + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_MASKS | + R128_UPLOAD_CLIPRECTS); + +#if ENABLE_PERF_BOXES + /* Log the performance counters if necessary */ + r128PerformanceCounters( rmesa ); #endif } @@ -413,8 +457,8 @@ void r128SwapBuffers( r128ContextPtr r128ctx ) static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, GLint cx, GLint cy, GLint cw, GLint ch ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; GLuint flags = 0; GLint i; GLint ret; @@ -423,13 +467,13 @@ static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, fprintf( stderr, "%s:\n", __FUNCTION__ ); } - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); /* Update and emit any new state. We need to do this here to catch * changes to the masks. * FIXME: Just update the masks? */ - if ( r128ctx->new_state ) + if ( rmesa->new_state ) r128DDUpdateHWState( ctx ); if ( mask & DD_FRONT_LEFT_BIT ) { @@ -454,24 +498,23 @@ static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } #endif - if ( !flags ) { + if ( !flags ) return mask; - } /* Flip top to bottom */ cx += dPriv->x; cy = dPriv->y + dPriv->h - cy - ch; - LOCK_HARDWARE( r128ctx ); + LOCK_HARDWARE( rmesa ); - if ( r128ctx->dirty & ~R128_UPLOAD_CLIPRECTS ) { - r128EmitHwStateLocked( r128ctx ); + if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) { + r128EmitHwStateLocked( rmesa ); } - for ( i = 0 ; i < r128ctx->numClipRects ; ) { - GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , r128ctx->numClipRects ); - XF86DRIClipRectPtr box = r128ctx->pClipRects; - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + for ( i = 0 ; i < rmesa->numClipRects ; ) { + GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , rmesa->numClipRects ); + XF86DRIClipRectPtr box = rmesa->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; GLint n = 0; if ( !all ) { @@ -502,30 +545,31 @@ static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, } } - r128ctx->sarea->nbox = n; + rmesa->sarea->nbox = n; if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) { fprintf( stderr, "drmR128Clear: flag 0x%x color %x depth %x nbox %d\n", flags, - (GLuint)r128ctx->ClearColor, - (GLuint)r128ctx->ClearDepth, - r128ctx->sarea->nbox ); + (GLuint)rmesa->ClearColor, + (GLuint)rmesa->ClearDepth, + rmesa->sarea->nbox ); } - ret = drmR128Clear( r128ctx->driFd, flags, + ret = drmR128Clear( rmesa->driFd, flags, cx, cy, cw, ch, - r128ctx->ClearColor, r128ctx->ClearDepth ); + rmesa->ClearColor, rmesa->ClearDepth ); if ( ret ) { + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "drmR128Clear: return = %d\n", ret ); exit( 1 ); } } - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; return mask; } @@ -535,29 +579,29 @@ static GLbitfield r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, * Depth spans, pixels */ -void r128WriteDepthSpanLocked( r128ContextPtr r128ctx, +void r128WriteDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y, const GLdepth depth[], const GLubyte mask[] ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - int fd = r128ctx->driScreen->fd; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; int i; if ( !nbox || !n ) { return; } if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; } - if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128WriteDepthSpan( fd, n, x, y, depth, mask ); @@ -566,44 +610,44 @@ void r128WriteDepthSpanLocked( r128ContextPtr r128ctx, { for (i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; - r128ctx->sarea->nbox = nr - i; + rmesa->sarea->nbox = nr - i; for ( ; i < nr ; i++) { *b++ = pbox[i]; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128WriteDepthSpan( fd, n, x, y, depth, mask ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -void r128WriteDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, +void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[], const GLdepth depth[], const GLubyte mask[] ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - int fd = r128ctx->driScreen->fd; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; int i; if ( !nbox || !n ) { return; } if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; } - if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128WriteDepthPixels( fd, n, x, y, depth, mask ); @@ -612,42 +656,42 @@ void r128WriteDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, { for (i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; - r128ctx->sarea->nbox = nr - i; + rmesa->sarea->nbox = nr - i; for ( ; i < nr ; i++) { *b++ = pbox[i]; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128WriteDepthPixels( fd, n, x, y, depth, mask ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -void r128ReadDepthSpanLocked( r128ContextPtr r128ctx, +void r128ReadDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - int fd = r128ctx->driScreen->fd; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; int i; if ( !nbox || !n ) { return; } if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; } - if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128ReadDepthSpan( fd, n, x, y ); @@ -656,42 +700,42 @@ void r128ReadDepthSpanLocked( r128ContextPtr r128ctx, { for (i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; - r128ctx->sarea->nbox = nr - i; + rmesa->sarea->nbox = nr - i; for ( ; i < nr ; i++) { *b++ = pbox[i]; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128ReadDepthSpan( fd, n, x, y ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -void r128ReadDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, +void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[] ) { - XF86DRIClipRectPtr pbox = r128ctx->pClipRects; - int nbox = r128ctx->numClipRects; - int fd = r128ctx->driScreen->fd; + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; int i; if ( !nbox || !n ) { return; } if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { - r128ctx->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; } - if ( !(r128ctx->dirty & R128_UPLOAD_CLIPRECTS) ) + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) { if ( nbox < 3 ) { - r128ctx->sarea->nbox = 0; + rmesa->sarea->nbox = 0; } else { - r128ctx->sarea->nbox = nbox; + rmesa->sarea->nbox = nbox; } drmR128ReadDepthPixels( fd, n, x, y ); @@ -700,60 +744,35 @@ void r128ReadDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, { for (i = 0 ; i < nbox ; ) { int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); - XF86DRIClipRectPtr b = r128ctx->sarea->boxes; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; - r128ctx->sarea->nbox = nr - i; + rmesa->sarea->nbox = nr - i; for ( ; i < nr ; i++) { *b++ = pbox[i]; } - r128ctx->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; drmR128ReadDepthPixels( fd, n, x, y ); } } - r128ctx->dirty &= ~R128_UPLOAD_CLIPRECTS; + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; } -/* ================================================================ - * Deprecated function... - */ -void r128SubmitPacketLocked( r128ContextPtr r128ctx, - CARD32 *buf, GLuint count ) -{ - CARD32 *b; - int c = count; - int fd = r128ctx->r128Screen->driScreen->fd; - int to = 0; - int ret; - - do { - b = buf + (count - c); - ret = drmR128SubmitPacket( fd, b, &c, 0 ); - } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) ); - - if ( ret < 0 ) { - drmR128EngineReset( fd ); - fprintf( stderr, "Error: Could not submit packet... exiting\n" ); - exit( -1 ); - } -} - - - -void r128WaitForIdleLocked( r128ContextPtr r128ctx ) +void r128WaitForIdleLocked( r128ContextPtr rmesa ) { - int fd = r128ctx->r128Screen->driScreen->fd; + int fd = rmesa->r128Screen->driScreen->fd; int to = 0; int ret; do { ret = drmR128WaitForIdleCCE( fd ); - } while ( ( ret == -EBUSY ) && ( to++ < r128ctx->CCEtimeout ) ); + } while ( ( ret == -EBUSY ) && ( to++ < R128_TIMEOUT ) ); if ( ret < 0 ) { drmR128EngineReset( fd ); + UNLOCK_HARDWARE( rmesa ); fprintf( stderr, "Error: Rage 128 timed out... exiting\n" ); exit( -1 ); } @@ -762,5 +781,5 @@ void r128WaitForIdleLocked( r128ContextPtr r128ctx ) void r128DDInitIoctlFuncs( GLcontext *ctx ) { - ctx->Driver.Clear = r128DDClear; + ctx->Driver.Clear = r128DDClear; } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h index 43b77659b..76f777912 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h,v 1.1 2000/12/04 19:21:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h,v 1.2 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -44,174 +44,128 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "xf86drm.h" #include "xf86drmR128.h" -#define R128_DEFAULT_TOTAL_CCE_TIMEOUT 1000000 /* usecs */ - #define R128_BUFFER_MAX_DWORDS (R128_BUFFER_SIZE / sizeof(CARD32)) -#define FLUSH_BATCH( r128ctx ) \ -do { \ - if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) \ - fprintf( stderr, "FLUSH_BATCH in %s\n", __FUNCTION__ ); \ - if ( r128ctx->vert_buf ) { \ - r128FlushVertices( r128ctx ); \ - } else if ( r128ctx->next_elt != r128ctx->first_elt ) { \ - r128FlushElts( r128ctx ); \ - } \ -} while (0) - -#define r128FlushVertices( r128ctx ) \ -do { \ - LOCK_HARDWARE( r128ctx ); \ - r128FlushVerticesLocked( r128ctx ); \ - UNLOCK_HARDWARE( r128ctx ); \ -} while (0) - - -extern drmBufPtr r128GetBufferLocked( r128ContextPtr r128ctx ); -extern void r128FlushVerticesLocked( r128ContextPtr r128ctx ); +extern drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa ); +extern void r128FlushVerticesLocked( r128ContextPtr rmesa ); - -#define r128FlushElts( r128ctx ) \ -do { \ - LOCK_HARDWARE( r128ctx ); \ - r128FlushEltsLocked( r128ctx ); \ - UNLOCK_HARDWARE( r128ctx ); \ -} while (0) - -extern void r128GetEltBufLocked( r128ContextPtr r128ctx ); -extern void r128FlushEltsLocked( r128ContextPtr r128ctx ); -extern void r128FireEltsLocked( r128ContextPtr r128ctx, +extern void r128GetEltBufLocked( r128ContextPtr rmesa ); +extern void r128FlushEltsLocked( r128ContextPtr rmesa ); +extern void r128FireEltsLocked( r128ContextPtr rmesa, GLuint start, GLuint end, GLuint discard ); -extern void r128ReleaseBufLocked( r128ContextPtr r128ctx, drmBufPtr buffer ); - - -/* 64-bit align the next element address, and then make room for the - * next indexed prim packet header. - */ -#define ALIGN_NEXT_ELT( r128ctx ) \ -do { \ - r128ctx->next_elt = (GLushort *) \ - (((GLuint)r128ctx->next_elt + 7) & ~0x7); \ - r128ctx->next_elt = (GLushort *) \ - ((GLubyte *)r128ctx->next_elt + R128_INDEX_PRIM_OFFSET); \ -} while (0) - +extern void r128ReleaseBufLocked( r128ContextPtr rmesa, drmBufPtr buffer ); /* Make this available as both a regular and an inline function. */ -extern CARD32 *r128AllocVertices( r128ContextPtr r128ctx, int count ); +extern CARD32 *r128AllocVertices( r128ContextPtr rmesa, int count ); -static __inline CARD32 *r128AllocVerticesInline( r128ContextPtr r128ctx, +static __inline CARD32 *r128AllocVerticesInline( r128ContextPtr rmesa, int count ) { - int bytes = count * r128ctx->vertsize * sizeof(CARD32); - CARD32 *head; + int bytes = count * rmesa->vertsize * sizeof(CARD32); + CARD32 *head; - if ( !r128ctx->vert_buf ) { - LOCK_HARDWARE( r128ctx ); + if ( !rmesa->vert_buf ) { + LOCK_HARDWARE( rmesa ); - if ( r128ctx->first_elt != r128ctx->next_elt ) { - r128FlushEltsLocked( r128ctx ); - } + if ( rmesa->first_elt != rmesa->next_elt ) { + r128FlushEltsLocked( rmesa ); + } - r128ctx->vert_buf = r128GetBufferLocked( r128ctx ); + rmesa->vert_buf = r128GetBufferLocked( rmesa ); - UNLOCK_HARDWARE( r128ctx ); - } else if ( r128ctx->vert_buf->used + bytes > r128ctx->vert_buf->total ) { - LOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); + } else if ( rmesa->vert_buf->used + bytes > rmesa->vert_buf->total ) { + LOCK_HARDWARE( rmesa ); - r128FlushVerticesLocked( r128ctx ); - r128ctx->vert_buf = r128GetBufferLocked( r128ctx ); + r128FlushVerticesLocked( rmesa ); + rmesa->vert_buf = r128GetBufferLocked( rmesa ); - UNLOCK_HARDWARE( r128ctx ); - } + UNLOCK_HARDWARE( rmesa ); + } - head = (CARD32 *)((char *)r128ctx->vert_buf->address + - r128ctx->vert_buf->used); + head = (CARD32 *)((char *)rmesa->vert_buf->address + + rmesa->vert_buf->used); - r128ctx->num_verts += count; - r128ctx->vert_buf->used += bytes; - return head; + rmesa->num_verts += count; + rmesa->vert_buf->used += bytes; + return head; } - -extern void r128FireBlitLocked( r128ContextPtr r128ctx, drmBufPtr buffer, +extern void r128FireBlitLocked( r128ContextPtr rmesa, drmBufPtr buffer, GLint offset, GLint pitch, GLint format, GLint x, GLint y, GLint width, GLint height ); - -extern void r128WriteDepthSpanLocked( r128ContextPtr r128ctx, +extern void r128WriteDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y, const GLdepth depth[], const GLubyte mask[] ); -extern void r128WriteDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, +extern void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[], const GLdepth depth[], const GLubyte mask[] ); -extern void r128ReadDepthSpanLocked( r128ContextPtr r128ctx, +extern void r128ReadDepthSpanLocked( r128ContextPtr rmesa, GLuint n, GLint x, GLint y ); -extern void r128ReadDepthPixelsLocked( r128ContextPtr r128ctx, GLuint n, +extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, const GLint x[], const GLint y[] ); +extern void r128SwapBuffers( r128ContextPtr rmesa ); +extern void r128PageFlip( r128ContextPtr rmesa ); -extern void r128SwapBuffers( r128ContextPtr r128ctx ); - - -#define r128WaitForIdle( r128ctx ) \ -do { \ - LOCK_HARDWARE( r128ctx ); \ - r128WaitForIdleLocked( r128ctx ); \ - UNLOCK_HARDWARE( r128ctx ); \ -} while (0) - -extern void r128WaitForIdleLocked( r128ContextPtr r128ctx ); +extern void r128WaitForIdleLocked( r128ContextPtr rmesa ); extern void r128DDInitIoctlFuncs( GLcontext *ctx ); - /* ================================================================ - * Deprecated functions: + * Helper macros: */ -typedef union { - float f; - int i; -} floatTOint; - -/* Insert an integer value into the CCE ring buffer. */ -#define R128CCE(v) \ -do { \ - r128ctx->CCEbuf[r128ctx->CCEcount] = (v); \ - r128ctx->CCEcount++; \ +#define FLUSH_BATCH( rmesa ) \ +do { \ + if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) \ + fprintf( stderr, "FLUSH_BATCH in %s\n", __FUNCTION__ ); \ + if ( rmesa->vert_buf ) { \ + r128FlushVertices( rmesa ); \ + } else if ( rmesa->next_elt != rmesa->first_elt ) { \ + r128FlushElts( rmesa ); \ + } \ } while (0) -/* Insert an floating point value into the CCE ring buffer. */ -#define R128CCEF(v) \ -do { \ - floatTOint fTi; \ - fTi.f = (v); \ - r128ctx->CCEbuf[r128ctx->CCEcount] = fTi.i; \ - r128ctx->CCEcount++; \ +/* 64-bit align the next element address, and then make room for the + * next indexed prim packet header. + */ +#define ALIGN_NEXT_ELT( rmesa ) \ +do { \ + rmesa->next_elt = (GLushort *) \ + (((GLuint)rmesa->next_elt + 7) & ~0x7); \ + rmesa->next_elt = (GLushort *) \ + ((GLubyte *)rmesa->next_elt + R128_INDEX_PRIM_OFFSET); \ } while (0) -/* Insert a type-[0123] packet header into the ring buffer */ -#define R128CCE0(p,r,n) R128CCE((p) | ((n) << 16) | ((r) >> 2)) -#define R128CCE1(p,r1,r2) R128CCE((p) | (((r2) >> 2) << 11) | ((r1) >> 2)) -#define R128CCE2(p) R128CCE((p)) -#define R128CCE3(p,n) R128CCE((p) | ((n) << 16)) +#define r128FlushVertices( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + r128FlushVerticesLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) -#define R128CCE_SUBMIT_PACKET() \ -do { \ - r128SubmitPacketLocked( r128ctx, r128ctx->CCEbuf, r128ctx->CCEcount ); \ - r128ctx->CCEcount = 0; \ +#define r128FlushElts( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + r128FlushEltsLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ } while (0) -extern void r128SubmitPacketLocked( r128ContextPtr r128ctx, - CARD32 *buf, GLuint count ); +#define r128WaitForIdle( rmesa ) \ + do { \ + LOCK_HARDWARE( rmesa ); \ + r128WaitForIdleLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ + } while (0) #endif #endif /* __R128_IOCTL_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c index 6c9331c74..90ca2d7e1 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.c,v 1.1 2000/12/04 19:21:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.c,v 1.2 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -38,7 +38,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #if DEBUG_LOCKING char *prevLockFile = NULL; -int prevLockLine = 0; +int prevLockLine = 0; #endif @@ -50,15 +50,15 @@ int prevLockLine = 0; * the hardware lock when it changes the window state, this routine will * automatically be called after such a change. */ -void r128GetLock( r128ContextPtr r128ctx, GLuint flags ) +void r128GetLock( r128ContextPtr rmesa, GLuint flags ) { - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; - __DRIscreenPrivate *sPriv = r128ctx->driScreen; - R128SAREAPriv *sarea = r128ctx->sarea; + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + __DRIscreenPrivate *sPriv = rmesa->driScreen; + R128SAREAPrivPtr sarea = rmesa->sarea; int stamp = dPriv->lastStamp; int i; - drmGetLock( r128ctx->driFd, r128ctx->hHWContext, flags ); + drmGetLock( rmesa->driFd, rmesa->hHWContext, flags ); /* The window might have moved, so we might need to get new clip * rects. @@ -68,26 +68,26 @@ void r128GetLock( r128ContextPtr r128ctx, GLuint flags ) * Since the hardware state depends on having the latest drawable * clip rects, all state checking must be done _after_ this call. */ - XMESA_VALIDATE_DRAWABLE_INFO( r128ctx->display, sPriv, dPriv ); + XMESA_VALIDATE_DRAWABLE_INFO( rmesa->display, sPriv, dPriv ); if ( stamp != dPriv->lastStamp ) { - r128ctx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; - r128ctx->SetupDone = 0; + rmesa->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; + rmesa->SetupDone = 0; } - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_CLIPRECTS; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_CLIPRECTS; - r128ctx->numClipRects = dPriv->numClipRects; - r128ctx->pClipRects = dPriv->pClipRects; + rmesa->numClipRects = dPriv->numClipRects; + rmesa->pClipRects = dPriv->pClipRects; - if ( sarea->ctxOwner != r128ctx->hHWContext ) { - sarea->ctxOwner = r128ctx->hHWContext; - r128ctx->dirty = R128_UPLOAD_ALL; + if ( sarea->ctxOwner != rmesa->hHWContext ) { + sarea->ctxOwner = rmesa->hHWContext; + rmesa->dirty = R128_UPLOAD_ALL; } - for ( i = 0 ; i < r128ctx->lastTexHeap ; i++ ) { - if ( sarea->texAge[i] != r128ctx->lastTexAge[i] ) { - r128AgeTextures( r128ctx, i ); + for ( i = 0 ; i < rmesa->lastTexHeap ; i++ ) { + if ( sarea->texAge[i] != rmesa->lastTexAge[i] ) { + r128AgeTextures( rmesa, i ); } } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h index 7ae5b639a..e734ba29d 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.h,v 1.3 2000/12/07 15:43:37 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.h,v 1.4 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -33,40 +33,42 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. * */ -#ifndef _R128_LOCK_H_ -#define _R128_LOCK_H_ +#ifndef __R128_LOCK_H__ +#define __R128_LOCK_H__ #ifdef GLX_DIRECT_RENDERING -extern void r128GetLock( r128ContextPtr r128ctx, GLuint flags ); +extern void r128GetLock( r128ContextPtr rmesa, GLuint flags ); +/* Turn DEBUG_LOCKING on to find locking conflicts. + */ +#define DEBUG_LOCKING 0 -/* Turn DEBUG_LOCKING on to find locking conflicts (see r128_init.h) */ -#ifdef DEBUG_LOCKING +#if DEBUG_LOCKING extern char *prevLockFile; -extern int prevLockLine; - -#define DEBUG_LOCK() \ - do { \ - prevLockFile = (__FILE__); \ - prevLockLine = (__LINE__); \ - } while (0) - -#define DEBUG_RESET() \ - do { \ - prevLockFile = 0; \ - prevLockLine = 0; \ - } while (0) - -#define DEBUG_CHECK_LOCK() \ - do { \ - if (prevLockFile) { \ - fprintf(stderr, \ - "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ - prevLockFile, prevLockLine, __FILE__, __LINE__); \ - exit(1); \ - } \ - } while (0) +extern int prevLockLine; + +#define DEBUG_LOCK() \ + do { \ + prevLockFile = (__FILE__); \ + prevLockLine = (__LINE__); \ + } while (0) + +#define DEBUG_RESET() \ + do { \ + prevLockFile = 0; \ + prevLockLine = 0; \ + } while (0) + +#define DEBUG_CHECK_LOCK() \ + do { \ + if ( prevLockFile ) { \ + fprintf( stderr, \ + "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ + prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ + exit( 1 ); \ + } \ + } while (0) #else @@ -84,26 +86,26 @@ extern int prevLockLine; /* Lock the hardware and validate our state. */ -#define LOCK_HARDWARE( r128ctx ) \ +#define LOCK_HARDWARE( rmesa ) \ do { \ char __ret = 0; \ DEBUG_CHECK_LOCK(); \ - DRM_CAS( r128ctx->driHwLock, r128ctx->hHWContext, \ - (DRM_LOCK_HELD | r128ctx->hHWContext), __ret ); \ + DRM_CAS( rmesa->driHwLock, rmesa->hHWContext, \ + (DRM_LOCK_HELD | rmesa->hHWContext), __ret ); \ if ( __ret ) \ - r128GetLock( r128ctx, 0 ); \ + r128GetLock( rmesa, 0 ); \ DEBUG_LOCK(); \ } while (0) /* Unlock the hardware. */ -#define UNLOCK_HARDWARE( r128ctx ) \ +#define UNLOCK_HARDWARE( rmesa ) \ do { \ - DRM_UNLOCK( r128ctx->driFd, \ - r128ctx->driHwLock, \ - r128ctx->hHWContext ); \ + DRM_UNLOCK( rmesa->driFd, \ + rmesa->driHwLock, \ + rmesa->hHWContext ); \ DEBUG_RESET(); \ } while (0) #endif -#endif /* _R128_LOCK_H_ */ +#endif /* __R128_LOCK_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c index 4b17e5636..7c85141be 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c,v 1.3 2000/12/04 19:21:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c,v 1.4 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -41,7 +41,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "fog.h" static struct gl_pipeline_stage r128_fast_stage = { - "R128 Fast Path", + "r128 Fast Path", (PIPE_OP_VERT_XFORM | PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1 | @@ -66,10 +66,10 @@ static struct gl_pipeline_stage r128_fast_stage = { */ GLboolean r128DDBuildPrecalcPipeline( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); struct gl_pipeline *pipe = &ctx->CVA.pre; - if ( r128ctx->RenderIndex == 0 && + if ( rmesa->RenderIndex == 0 && (ctx->Enabled & ILLEGAL_ENABLES) == 0 && (ctx->Array.Flags & (VERT_OBJ_234 | VERT_TEX0_4 | @@ -81,15 +81,15 @@ GLboolean r128DDBuildPrecalcPipeline( GLcontext *ctx ) pipe->new_inputs = ctx->RenderFlags & VERT_DATA; pipe->ops = pipe->stages[0]->ops; - r128ctx->useFastPath = GL_TRUE; + rmesa->OnFastPath = GL_TRUE; return GL_TRUE; } - if ( r128ctx->useFastPath ) { - r128ctx->useFastPath = GL_FALSE; + if ( rmesa->OnFastPath ) { + rmesa->OnFastPath = GL_FALSE; - ctx->CVA.VB->ClipOrMask = 0; - ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; + ctx->CVA.VB->ClipOrMask = 0; + ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; ctx->Array.NewArrayState |= ctx->Array.Summary; } @@ -123,7 +123,6 @@ static void r128DDCheckRasterSetup( GLcontext *ctx, } -/* Register the pipeline with our stages included */ GLuint r128DDRegisterPipelineStages( struct gl_pipeline_stage *out, const struct gl_pipeline_stage *in, GLuint nr ) diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h index 84c667240..1cfb27d44 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h,v 1.3 2000/12/04 19:21:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h,v 1.4 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,13 +28,15 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_PIPELINE_H_ -#define _R128_PIPELINE_H_ +#ifndef __R128_PIPELINE_H__ +#define __R128_PIPELINE_H__ + +#ifdef GLX_DIRECT_RENDERING extern GLboolean r128DDBuildPrecalcPipeline( GLcontext *ctx ); extern GLuint r128DDRegisterPipelineStages( struct gl_pipeline_stage *out, @@ -47,4 +49,5 @@ extern void r128DDFastPath( struct vertex_buffer *VB ); extern void r128DDEltPathInit( void ); extern void r128DDEltPath( struct vertex_buffer *VB ); -#endif /* _R128_PIPELINE_H_ */ +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c index 139e7fbc3..e6aff7f00 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.3 2000/12/04 19:21:46 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.4 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -41,7 +41,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_vb.h" #include "r128_pipeline.h" -#include <sys/mman.h> +#include "mem.h" #if 1 /* Including xf86PciInfo.h introduces a bunch of errors... @@ -57,208 +57,157 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #endif -/* Create the device specific screen private data struct */ -r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv) +/* Create the device specific screen private data struct. + */ +r128ScreenPtr r128CreateScreen( __DRIscreenPrivate *sPriv ) { - r128ScreenPtr r128Screen; - R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv; - int cpp; - - /* Allocate the private area */ - r128Screen = (r128ScreenPtr)Xmalloc(sizeof(*r128Screen)); - if (!r128Screen) return NULL; - - /* This is first since which regions we map depends on whether or - not we are using a PCI card */ - r128Screen->IsPCI = r128DRIPriv->IsPCI; - - r128Screen->mmioRgn.handle = r128DRIPriv->registerHandle; - r128Screen->mmioRgn.size = r128DRIPriv->registerSize; - if (drmMap(sPriv->fd, - r128Screen->mmioRgn.handle, - r128Screen->mmioRgn.size, - (drmAddressPtr)&r128Screen->mmio)) { - Xfree(r128Screen); - return NULL; - } - - if (!r128Screen->IsPCI) { - r128Screen->ringRgn.handle = r128DRIPriv->ringHandle; - r128Screen->ringRgn.size = r128DRIPriv->ringMapSize; - if (drmMap(sPriv->fd, - r128Screen->ringRgn.handle, - r128Screen->ringRgn.size, - (drmAddressPtr)&r128Screen->ring)) { - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - - r128Screen->ringReadRgn.handle = r128DRIPriv->ringReadPtrHandle; - r128Screen->ringReadRgn.size = r128DRIPriv->ringReadMapSize; - if (drmMap(sPriv->fd, - r128Screen->ringReadRgn.handle, - r128Screen->ringReadRgn.size, - (drmAddressPtr)&r128Screen->ringReadPtr)) { - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - - r128Screen->bufRgn.handle = r128DRIPriv->bufHandle; - r128Screen->bufRgn.size = r128DRIPriv->bufMapSize; - if (drmMap(sPriv->fd, - r128Screen->bufRgn.handle, - r128Screen->bufRgn.size, - (drmAddressPtr)&r128Screen->buf)) { - drmUnmap((drmAddress)r128Screen->ringReadPtr, - r128Screen->ringReadRgn.size); - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - r128Screen->bufOffset = r128DRIPriv->bufOffset; - - r128Screen->agpTexRgn.handle = r128DRIPriv->agpTexHandle; - r128Screen->agpTexRgn.size = r128DRIPriv->agpTexMapSize; - if (drmMap(sPriv->fd, - r128Screen->agpTexRgn.handle, - r128Screen->agpTexRgn.size, - (drmAddressPtr)&r128Screen->agpTex)) { - drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); - drmUnmap((drmAddress)r128Screen->ringReadPtr, - r128Screen->ringReadRgn.size); - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - r128Screen->agpTexOffset = r128DRIPriv->agpTexOffset; - - if (!(r128Screen->buffers = drmMapBufs(sPriv->fd))) { - drmUnmap((drmAddress)r128Screen->agpTex, - r128Screen->agpTexRgn.size); - drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); - drmUnmap((drmAddress)r128Screen->ringReadPtr, - r128Screen->ringReadRgn.size); - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); - Xfree(r128Screen); - return NULL; - } - } - - /* Allow both AGP and PCI cards to use vertex buffers. PCI cards use - * the ring walker method, ie. the vertex buffer data is actually part - * of the command stream. - */ - r128Screen->bufMapSize = r128DRIPriv->bufMapSize; - - r128Screen->deviceID = r128DRIPriv->deviceID; - - r128Screen->depth = r128DRIPriv->depth; - r128Screen->bpp = r128DRIPriv->bpp; - r128Screen->pixel_code = (r128Screen->bpp != 16 ? - r128Screen->bpp : - r128Screen->depth); - - cpp = r128Screen->bpp / 8; - - r128Screen->fb = sPriv->pFB; - r128Screen->fbOffset = sPriv->fbOrigin; - r128Screen->fbStride = sPriv->fbStride; - r128Screen->fbSize = sPriv->fbSize; - - r128Screen->frontOffset = r128DRIPriv->frontOffset; - r128Screen->frontPitch = r128DRIPriv->frontPitch; - r128Screen->backOffset = r128DRIPriv->backOffset; - r128Screen->backPitch = r128DRIPriv->backPitch; - r128Screen->depthOffset = r128DRIPriv->depthOffset; - r128Screen->depthPitch = r128DRIPriv->depthPitch; - r128Screen->spanOffset = r128DRIPriv->spanOffset; - - r128Screen->texOffset[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureOffset; - r128Screen->texSize[R128_LOCAL_TEX_HEAP] = r128DRIPriv->textureSize; - r128Screen->log2TexGran[R128_LOCAL_TEX_HEAP] = r128DRIPriv->log2TexGran; - - if (r128Screen->IsPCI) { - r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0; - r128Screen->texSize[R128_AGP_TEX_HEAP] = 0; - r128Screen->log2TexGran[R128_AGP_TEX_HEAP] = 0; - r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS-1; - } else { - r128Screen->texOffset[R128_AGP_TEX_HEAP] = 0; - r128Screen->texSize[R128_AGP_TEX_HEAP] = - r128DRIPriv->agpTexMapSize; - r128Screen->log2TexGran[R128_AGP_TEX_HEAP] = - r128DRIPriv->log2AGPTexGran; - r128Screen->NRTexHeaps = R128_NR_TEX_HEAPS; - } - - r128Screen->AGPMode = r128DRIPriv->AGPMode; - - r128Screen->CCEMode = r128DRIPriv->CCEMode; - r128Screen->CCEFifoSize = r128DRIPriv->CCEFifoSize; - - r128Screen->ringEntries = r128DRIPriv->ringSize/sizeof(CARD32); - if (!r128Screen->IsPCI) { - r128Screen->ringStartPtr = (int *)r128Screen->ring; - r128Screen->ringEndPtr = (int *)(r128Screen->ring - + r128DRIPriv->ringSize); - } - - r128Screen->MMIOFifoSlots = 0; - r128Screen->CCEFifoSlots = 0; - - r128Screen->CCEFifoAddr = R128_PM4_FIFO_DATA_EVEN; - - r128Screen->driScreen = sPriv; - - switch ( r128DRIPriv->deviceID ) { - case PCI_CHIP_RAGE128RE: - case PCI_CHIP_RAGE128RF: - case PCI_CHIP_RAGE128RK: - case PCI_CHIP_RAGE128RL: - r128Screen->chipset = R128_CARD_TYPE_R128; - break; - case PCI_CHIP_RAGE128PF: - r128Screen->chipset = R128_CARD_TYPE_R128_PRO; - break; - case PCI_CHIP_RAGE128LE: - case PCI_CHIP_RAGE128LF: - r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY; - break; - default: - r128Screen->chipset = R128_CARD_TYPE_R128; - break; - } - - r128DDFastPathInit(); - r128DDEltPathInit(); - r128DDTriangleFuncsInit(); - r128DDSetupInit(); - - return r128Screen; + r128ScreenPtr r128Screen; + R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv; + + /* Check the DRI version */ + { + int major, minor, patch; + if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { + if ( major != 3 || minor != 1 || patch < 0 ) { + char msg[128]; + sprintf( msg, "r128 DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if ( sPriv->ddxMajor != 4 || + sPriv->ddxMinor != 0 || + sPriv->ddxPatch < 0 ) { + char msg[128]; + sprintf( msg, "r128 DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if ( sPriv->drmMajor != 2 || + sPriv->drmMinor != 1 || + sPriv->drmPatch < 0 ) { + char msg[128]; + sprintf( msg, "r128 DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + + /* Allocate the private area */ + r128Screen = (r128ScreenPtr) CALLOC( sizeof(*r128Screen) ); + if ( !r128Screen ) return NULL; + + /* This is first since which regions we map depends on whether or + * not we are using a PCI card. + */ + r128Screen->IsPCI = r128DRIPriv->IsPCI; + + r128Screen->mmio.handle = r128DRIPriv->registerHandle; + r128Screen->mmio.size = r128DRIPriv->registerSize; + if ( drmMap( sPriv->fd, + r128Screen->mmio.handle, + r128Screen->mmio.size, + (drmAddressPtr)&r128Screen->mmio.map ) ) { + FREE( r128Screen ); + return NULL; + } + + r128Screen->buffers = drmMapBufs( sPriv->fd ); + if ( !r128Screen->buffers ) { + drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size ); + FREE( r128Screen ); + return NULL; + } + + if ( !r128Screen->IsPCI ) { + r128Screen->agpTextures.handle = r128DRIPriv->agpTexHandle; + r128Screen->agpTextures.size = r128DRIPriv->agpTexMapSize; + if ( drmMap( sPriv->fd, + r128Screen->agpTextures.handle, + r128Screen->agpTextures.size, + (drmAddressPtr)&r128Screen->agpTextures.map ) ) { + drmUnmapBufs( r128Screen->buffers ); + drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size ); + FREE( r128Screen ); + return NULL; + } + } + + switch ( r128DRIPriv->deviceID ) { + case PCI_CHIP_RAGE128RE: + case PCI_CHIP_RAGE128RF: + case PCI_CHIP_RAGE128RK: + case PCI_CHIP_RAGE128RL: + r128Screen->chipset = R128_CARD_TYPE_R128; + break; + case PCI_CHIP_RAGE128PF: + r128Screen->chipset = R128_CARD_TYPE_R128_PRO; + break; + case PCI_CHIP_RAGE128LE: + case PCI_CHIP_RAGE128LF: + r128Screen->chipset = R128_CARD_TYPE_R128_MOBILITY; + break; + default: + r128Screen->chipset = R128_CARD_TYPE_R128; + break; + } + + r128Screen->cpp = r128DRIPriv->bpp / 8; + r128Screen->AGPMode = r128DRIPriv->AGPMode; + + r128Screen->frontOffset = r128DRIPriv->frontOffset; + r128Screen->frontPitch = r128DRIPriv->frontPitch; + r128Screen->backOffset = r128DRIPriv->backOffset; + r128Screen->backPitch = r128DRIPriv->backPitch; + r128Screen->depthOffset = r128DRIPriv->depthOffset; + r128Screen->depthPitch = r128DRIPriv->depthPitch; + r128Screen->spanOffset = r128DRIPriv->spanOffset; + + r128Screen->texOffset[R128_CARD_HEAP] = r128DRIPriv->textureOffset; + r128Screen->texSize[R128_CARD_HEAP] = r128DRIPriv->textureSize; + r128Screen->logTexGranularity[R128_CARD_HEAP] = r128DRIPriv->log2TexGran; + + if ( r128Screen->IsPCI ) { + r128Screen->numTexHeaps = R128_NR_TEX_HEAPS - 1; + r128Screen->texOffset[R128_AGP_HEAP] = 0; + r128Screen->texSize[R128_AGP_HEAP] = 0; + r128Screen->logTexGranularity[R128_AGP_HEAP] = 0; + } else { + r128Screen->numTexHeaps = R128_NR_TEX_HEAPS; + r128Screen->texOffset[R128_AGP_HEAP] = + r128DRIPriv->agpTexOffset + R128_AGP_TEX_OFFSET; + r128Screen->texSize[R128_AGP_HEAP] = r128DRIPriv->agpTexMapSize; + r128Screen->logTexGranularity[R128_AGP_HEAP] = + r128DRIPriv->log2AGPTexGran; + } + + r128Screen->driScreen = sPriv; + + r128DDSetupInit(); + r128DDTriangleFuncsInit(); + r128DDFastPathInit(); + r128DDEltPathInit(); + + return r128Screen; } -/* Destroy the device specific screen private data struct */ -void r128DestroyScreen(__DRIscreenPrivate *sPriv) +/* Destroy the device specific screen private data struct. + */ +void r128DestroyScreen( __DRIscreenPrivate *sPriv ) { - r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private; - - if (!r128Screen->IsPCI) { - drmUnmapBufs(r128Screen->buffers); + r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private; - drmUnmap((drmAddress)r128Screen->agpTex, r128Screen->agpTexRgn.size); - drmUnmap((drmAddress)r128Screen->buf, r128Screen->bufRgn.size); - drmUnmap((drmAddress)r128Screen->ringReadPtr, - r128Screen->ringReadRgn.size); - drmUnmap((drmAddress)r128Screen->ring, r128Screen->ringRgn.size); - } - drmUnmap((drmAddress)r128Screen->mmio, r128Screen->mmioRgn.size); + if ( !r128Screen->IsPCI ) { + drmUnmap( (drmAddress)r128Screen->agpTextures.map, + r128Screen->agpTextures.size ); + } + drmUnmapBufs( r128Screen->buffers ); + drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size ); - Xfree(r128Screen); - sPriv->private = NULL; + FREE( r128Screen ); + sPriv->private = NULL; } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h index 4fd6b7ac7..82e8dda81 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.h,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.h,v 1.4 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,98 +28,58 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_SCREEN_H_ -#define _R128_SCREEN_H_ +#ifndef __R128_SCREEN_H__ +#define __R128_SCREEN_H__ #ifdef GLX_DIRECT_RENDERING #include "r128_sarea.h" typedef struct { - drmHandle handle; /* Handle to the DRM region */ - drmSize size; /* Size of the DRM region */ + drmHandle handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ + unsigned char *map; /* Mapping of the DRM region */ } r128RegionRec, *r128RegionPtr; typedef struct { - /* MMIO register data */ - r128RegionRec mmioRgn; - unsigned char *mmio; - - /* CCE ring buffer data */ - r128RegionRec ringRgn; - unsigned char *ring; - - /* CCE ring read pointer data */ - r128RegionRec ringReadRgn; - - /* CCE vertex/indirect buffer data */ - r128RegionRec bufRgn; - unsigned char *buf; - int bufOffset; - int bufMapSize; - drmBufMapPtr buffers; - - /* CCE AGP Texture data */ - r128RegionRec agpTexRgn; - unsigned char *agpTex; - int agpTexOffset; - - /* Frame buffer data */ - unsigned char *fb; - unsigned long fbOffset; - int fbStride; - int fbSize; - - unsigned int frontX, frontY; /* Start of front buffer */ - unsigned int frontOffset, frontPitch; - unsigned int backX, backY; /* Start of shared back buffer */ - unsigned int backOffset, backPitch; - unsigned int depthX, depthY; /* Start of shared depth buffer */ - unsigned int depthOffset, depthPitch; - unsigned int spanOffset; - - int chipset; - int IsPCI; /* Current card is a PCI card */ - int AGPMode; - - int CCEMode; /* CCE mode that server/clients use */ - int CCEFifoSize; /* Size of the CCE command FIFO */ - - /* CCE ring buffer data */ - int ringEntries; - - volatile int *ringReadPtr; /* Pointer to current read addr */ - int *ringStartPtr; /* Pointer to end of ring buffer */ - int *ringEndPtr; /* Pointer to end of ring buffer */ - - /* DRI screen private data */ - int deviceID; /* PCI device ID */ - int depth; /* Depth of display (8, 15, 16, 24) */ - int bpp; /* Bit depth of disp (8, 16, 24, 32) */ - int pixel_code; /* 8, 15, 16, 24, 32 */ + + GLint chipset; + GLint cpp; + GLint IsPCI; /* Current card is a PCI card */ + GLint AGPMode; + + GLuint frontOffset; + GLuint frontPitch; + GLuint backOffset; + GLuint backPitch; + + GLuint depthOffset; + GLuint depthPitch; + GLuint spanOffset; /* Shared texture data */ - int NRTexHeaps; - int texOffset[R128_NR_TEX_HEAPS]; - int texSize[R128_NR_TEX_HEAPS]; - int log2TexGran[R128_NR_TEX_HEAPS]; - - int MMIOFifoSlots; /* Free slots in the FIFO (64 max) */ - int CCEFifoSlots; /* Free slots in the CCE FIFO */ - - int CCEFifoAddr; /* MMIO offset to write next CCE - value (only used when CCE is - in PIO mode). */ - __DRIscreenPrivate *driScreen; + GLint numTexHeaps; + GLint texOffset[R128_NR_TEX_HEAPS]; + GLint texSize[R128_NR_TEX_HEAPS]; + GLint logTexGranularity[R128_NR_TEX_HEAPS]; + + r128RegionRec mmio; + r128RegionRec agpTextures; + + drmBufMapPtr buffers; + + __DRIscreenPrivate *driScreen; + } r128ScreenRec, *r128ScreenPtr; -r128ScreenPtr r128CreateScreen(__DRIscreenPrivate *sPriv); -void r128DestroyScreen(__DRIscreenPrivate *sPriv); + +extern r128ScreenPtr r128CreateScreen( __DRIscreenPrivate *sPriv ); +extern void r128DestroyScreen( __DRIscreenPrivate *sPriv ); #endif -#endif /* _R128_SCREEN_H_ */ +#endif /* __R128_SCREEN_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.c b/xc/lib/GL/mesa/src/drv/r128/r128_span.c index c25250378..6f71c2c78 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.4 2000/12/12 17:17:07 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.5 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,9 +28,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> - * Keith Whitwell <keithw@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -47,32 +47,34 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #define HAVE_HW_DEPTH_PIXELS 1 #define LOCAL_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ - GLuint pitch = r128scrn->fbStride; \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + r128ScreenPtr r128scrn = rmesa->r128Screen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + GLuint pitch = r128scrn->frontPitch * r128scrn->cpp; \ GLuint height = dPriv->h; \ - char *buf = (char *)(r128scrn->fb + \ - r128ctx->drawOffset + \ - (dPriv->x * r128scrn->bpp/8) + \ + char *buf = (char *)(sPriv->pFB + \ + rmesa->drawOffset + \ + (dPriv->x * r128scrn->cpp) + \ (dPriv->y * pitch)); \ - char *read_buf = (char *)(r128scrn->fb + \ - r128ctx->readOffset + \ - (dPriv->x * r128scrn->bpp/8) + \ + char *read_buf = (char *)(sPriv->pFB + \ + rmesa->readOffset + \ + (dPriv->x * r128scrn->cpp) + \ (dPriv->y * pitch)); \ GLushort p; \ (void) read_buf; (void) buf; (void) p #define LOCAL_DEPTH_VARS \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + r128ScreenPtr r128scrn = rmesa->r128Screen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ GLuint height = dPriv->h; \ - (void) height + (void) r128scrn; (void) sPriv; (void) height #define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS -#define INIT_MONO_PIXEL( p ) \ - p = r128ctx->Color +#define INIT_MONO_PIXEL( p ) p = rmesa->Color #define CLIPPIXEL( _x, _y ) \ ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) @@ -88,18 +90,18 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx) + 1; \ } -#define Y_FLIP( _y ) (height - _y - 1) +#define Y_FLIP( _y ) (height - _y - 1) #define HW_LOCK() \ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); \ - FLUSH_BATCH( r128ctx ); \ - LOCK_HARDWARE( r128ctx ); \ - r128WaitForIdleLocked( r128ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + FLUSH_BATCH( rmesa ); \ + LOCK_HARDWARE( rmesa ); \ + r128WaitForIdleLocked( rmesa ); #define HW_CLIPLOOP() \ do { \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ int _nc = dPriv->numClipRects; \ \ while ( _nc-- ) { \ @@ -113,7 +115,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. } while (0) #define HW_UNLOCK() \ - UNLOCK_HARDWARE( r128ctx ) \ + UNLOCK_HARDWARE( rmesa ) @@ -122,23 +124,26 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. */ /* 16 bit, RGB565 color spanline and pixel functions - */ \ + */ #define WRITE_RGBA( _x, _y, r, g, b, a ) \ *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \ (((int)g & 0xfc) << 3) | \ (((int)b & 0xf8) >> 3)) #define WRITE_PIXEL( _x, _y, p ) \ - *(GLushort *)(buf + _x*2 + _y*pitch) = p + *(GLushort *)(buf + _x*2 + _y*pitch) = p #define READ_RGBA( rgba, _x, _y ) \ - do { \ - GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ - rgba[0] = (p >> 8) & 0xf8; \ - rgba[1] = (p >> 3) & 0xfc; \ - rgba[2] = (p << 3) & 0xf8; \ - rgba[3] = 0xff; \ - } while (0) + do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 8) & 0xf8; \ + rgba[1] = (p >> 3) & 0xfc; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = 0xff; \ + if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \ + if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \ + if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \ + } while (0) #define TAG(x) r128##x##_RGB565 #include "spantmp.h" @@ -175,9 +180,8 @@ do { \ /* 16-bit depth buffer functions */ - #define WRITE_DEPTH_SPAN() \ - r128WriteDepthSpanLocked( r128ctx, n, \ + r128WriteDepthSpanLocked( rmesa, n, \ x + dPriv->x, \ y + dPriv->y, \ depth, mask ); @@ -192,20 +196,19 @@ do { \ for ( i = 0 ; i < n ; i++ ) { \ oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ } \ - r128WriteDepthPixelsLocked( r128ctx, n, ox, oy, depth, mask ); \ + r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \ } while (0) #define READ_DEPTH_SPAN() \ do { \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - GLushort *buf = (GLushort *)((GLubyte *)r128scrn->fb + \ + GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \ r128scrn->spanOffset); \ GLint i; \ \ - r128ReadDepthSpanLocked( r128ctx, n, \ + r128ReadDepthSpanLocked( rmesa, n, \ x + dPriv->x, \ y + dPriv->y ); \ - r128WaitForIdleLocked( r128ctx ); \ + r128WaitForIdleLocked( rmesa ); \ \ for ( i = 0 ; i < n ; i++ ) { \ depth[i] = buf[i]; \ @@ -214,8 +217,7 @@ do { \ #define READ_DEPTH_PIXELS() \ do { \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - GLushort *buf = (GLushort *)((GLubyte *)r128scrn->fb + \ + GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \ r128scrn->spanOffset); \ GLint i, remaining = n; \ \ @@ -236,8 +238,8 @@ do { \ oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ } \ \ - r128ReadDepthPixelsLocked( r128ctx, count, ox, oy ); \ - r128WaitForIdleLocked( r128ctx ); \ + r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \ + r128WaitForIdleLocked( rmesa ); \ \ for ( i = 0 ; i < count ; i++ ) { \ depth[i] = buf[i]; \ @@ -256,7 +258,7 @@ do { \ /* 24-bit depth, 8-bit stencil buffer functions */ #define WRITE_DEPTH_SPAN() \ - r128WriteDepthSpanLocked( r128ctx, n, \ + r128WriteDepthSpanLocked( rmesa, n, \ x + dPriv->x, \ y + dPriv->y, \ depth, mask ); @@ -271,20 +273,19 @@ do { \ for ( i = 0 ; i < n ; i++ ) { \ oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ } \ - r128WriteDepthPixelsLocked( r128ctx, n, ox, oy, depth, mask ); \ + r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \ } while (0) #define READ_DEPTH_SPAN() \ do { \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - GLuint *buf = (GLuint *)((GLubyte *)r128scrn->fb + \ + GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \ r128scrn->spanOffset); \ GLint i; \ \ - r128ReadDepthSpanLocked( r128ctx, n, \ + r128ReadDepthSpanLocked( rmesa, n, \ x + dPriv->x, \ y + dPriv->y ); \ - r128WaitForIdleLocked( r128ctx ); \ + r128WaitForIdleLocked( rmesa ); \ \ for ( i = 0 ; i < n ; i++ ) { \ depth[i] = buf[i] & 0x00ffffff; \ @@ -293,8 +294,7 @@ do { \ #define READ_DEPTH_PIXELS() \ do { \ - r128ScreenPtr r128scrn = r128ctx->r128Screen; \ - GLuint *buf = (GLuint *)((GLubyte *)r128scrn->fb + \ + GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \ r128scrn->spanOffset); \ GLint i, remaining = n; \ \ @@ -315,8 +315,8 @@ do { \ oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ } \ \ - r128ReadDepthPixelsLocked( r128ctx, count, ox, oy ); \ - r128WaitForIdleLocked( r128ctx ); \ + r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \ + r128WaitForIdleLocked( rmesa ); \ \ for ( i = 0 ; i < count ; i++ ) { \ depth[i] = buf[i] & 0x00ffffff; \ @@ -344,10 +344,10 @@ do { \ void r128DDInitSpanFuncs( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - switch ( r128ctx->r128Screen->bpp ) { - case 16: + switch ( rmesa->r128Screen->cpp ) { + case 2: ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_RGB565; ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_RGB565; ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB565; @@ -357,7 +357,7 @@ void r128DDInitSpanFuncs( GLcontext *ctx ) ctx->Driver.ReadRGBAPixels = r128ReadRGBAPixels_RGB565; break; - case 32: + case 4: ctx->Driver.WriteRGBASpan = r128WriteRGBASpan_ARGB8888; ctx->Driver.WriteRGBSpan = r128WriteRGBSpan_ARGB8888; ctx->Driver.WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB8888; @@ -371,7 +371,7 @@ void r128DDInitSpanFuncs( GLcontext *ctx ) break; } - switch ( r128ctx->DepthSize ) { + switch ( rmesa->glCtx->Visual->DepthBits ) { case 16: ctx->Driver.ReadDepthSpan = r128ReadDepthSpan_16; ctx->Driver.WriteDepthSpan = r128WriteDepthSpan_16; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_span.h b/xc/lib/GL/mesa/src/drv/r128/r128_span.h index 486445d31..44356c5b2 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.h,v 1.2 2000/12/04 19:21:47 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.h,v 1.3 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,17 +28,17 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_SPAN_H_ -#define _R128_SPAN_H_ +#ifndef __R128_SPAN_H__ +#define __R128_SPAN_H__ #ifdef GLX_DIRECT_RENDERING -extern void r128DDInitSpanFuncs(GLcontext *ctx); +extern void r128DDInitSpanFuncs( GLcontext *ctx ); #endif -#endif /* _R128_SPAN_H_ */ +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.c b/xc/lib/GL/mesa/src/drv/r128/r128_state.c index 10a955af7..598d2c6bc 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.6 2000/12/12 17:17:07 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.7 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -29,6 +29,7 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * Keith Whitwell <keithw@valinux.com> * */ @@ -51,9 +52,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. static void r128UpdateAlphaMode( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 a = r128ctx->setup.misc_3d_state_cntl_reg; - CARD32 t = r128ctx->setup.tex_cntl_c; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 a = rmesa->setup.misc_3d_state_cntl_reg; + CARD32 t = rmesa->setup.tex_cntl_c; if ( ctx->Color.AlphaEnabled ) { GLubyte ref = ctx->Color.AlphaRef; @@ -63,7 +64,6 @@ static void r128UpdateAlphaMode( GLcontext *ctx ) switch ( ctx->Color.AlphaFunc ) { case GL_NEVER: a |= R128_ALPHA_TEST_NEVER; - ref = 0; break; case GL_LESS: a |= R128_ALPHA_TEST_LESS; @@ -159,48 +159,48 @@ static void r128UpdateAlphaMode( GLcontext *ctx ) t &= ~R128_ALPHA_ENABLE; } - if ( r128ctx->setup.misc_3d_state_cntl_reg != a ) { - r128ctx->setup.misc_3d_state_cntl_reg = a; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + if ( rmesa->setup.misc_3d_state_cntl_reg != a ) { + rmesa->setup.misc_3d_state_cntl_reg = a; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } - if ( r128ctx->setup.tex_cntl_c != t ) { - r128ctx->setup.tex_cntl_c = t; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } } static void r128DDAlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; } static void r128DDBlendEquation( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; } static void r128DDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; } static void r128DDBlendFuncSeparate( GLcontext *ctx, GLenum sfactorRGB, GLenum dfactorRGB, GLenum sfactorA, GLenum dfactorA ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; } @@ -210,9 +210,9 @@ static void r128DDBlendFuncSeparate( GLcontext *ctx, static void r128UpdateZMode( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 z = r128ctx->setup.z_sten_cntl_c; - CARD32 t = r128ctx->setup.tex_cntl_c; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 z = rmesa->setup.z_sten_cntl_c; + CARD32 t = rmesa->setup.tex_cntl_c; if ( ctx->Depth.Test ) { z &= ~R128_Z_TEST_MASK; @@ -255,45 +255,45 @@ static void r128UpdateZMode( GLcontext *ctx ) t &= ~R128_Z_WRITE_ENABLE; } - if ( r128ctx->setup.z_sten_cntl_c != z ) { - r128ctx->setup.z_sten_cntl_c = z; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + if ( rmesa->setup.z_sten_cntl_c != z ) { + rmesa->setup.z_sten_cntl_c = z; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } - if ( r128ctx->setup.tex_cntl_c != t ) { - r128ctx->setup.tex_cntl_c = t; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } } static void r128DDDepthFunc( GLcontext *ctx, GLenum func ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_DEPTH; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; } static void r128DDDepthMask( GLcontext *ctx, GLboolean flag ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_DEPTH; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; } static void r128DDClearDepth( GLcontext *ctx, GLclampd d ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - switch ( r128ctx->DepthSize ) { - case 16: - r128ctx->ClearDepth = d * 0x0000ffff; + switch ( rmesa->setup.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK ) { + case R128_Z_PIX_WIDTH_16: + rmesa->ClearDepth = d * 0x0000ffff; break; - case 24: - r128ctx->ClearDepth = d * 0x00ffffff; + case R128_Z_PIX_WIDTH_24: + rmesa->ClearDepth = d * 0x00ffffff; break; - case 32: - r128ctx->ClearDepth = d * 0xffffffff; + case R128_Z_PIX_WIDTH_32: + rmesa->ClearDepth = d * 0xffffffff; break; } } @@ -305,8 +305,8 @@ static void r128DDClearDepth( GLcontext *ctx, GLclampd d ) static void r128UpdateFogAttrib( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 t = r128ctx->setup.tex_cntl_c; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 t = rmesa->setup.tex_cntl_c; GLubyte c[4]; CARD32 col; @@ -316,25 +316,25 @@ static void r128UpdateFogAttrib( GLcontext *ctx ) t &= ~R128_FOG_ENABLE; } - FLOAT_RGBA_TO_UBYTE_RGBA( c, ctx->Fog.Color ); - col = r128PackColor( 32, c[0], c[1], c[2], c[3] ); + FLOAT_RGB_TO_UBYTE_RGB( c, ctx->Fog.Color ); + col = r128PackColor( 4, c[0], c[1], c[2], 0 ); - if ( r128ctx->setup.fog_color_c != col ) { - r128ctx->setup.fog_color_c = col; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + if ( rmesa->setup.fog_color_c != col ) { + rmesa->setup.fog_color_c = col; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } - if ( r128ctx->setup.tex_cntl_c != t ) { - r128ctx->setup.tex_cntl_c = t; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } } static void r128DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_FOG; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_FOG; } @@ -344,14 +344,14 @@ static void r128DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) static void r128UpdateClipping( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - if ( r128ctx->driDrawable ) { - __DRIdrawablePrivate *drawable = r128ctx->driDrawable; + if ( rmesa->driDrawable ) { + __DRIdrawablePrivate *drawable = rmesa->driDrawable; int x1 = 0; int y1 = 0; - int x2 = r128ctx->driDrawable->w - 1; - int y2 = r128ctx->driDrawable->h - 1; + int x2 = drawable->w - 1; + int y2 = drawable->h - 1; if ( ctx->Scissor.Enabled ) { if ( ctx->Scissor.X > x1 ) { @@ -368,51 +368,25 @@ static void r128UpdateClipping( GLcontext *ctx ) } } - x1 += r128ctx->driDrawable->x; - y1 += r128ctx->driDrawable->y; - x2 += r128ctx->driDrawable->x; - y2 += r128ctx->driDrawable->y; - - if ( 0 ) { - fprintf( stderr, "%s: drawable %3d %3d %3d %3d\n", - __FUNCTION__, - r128ctx->driDrawable->x, - r128ctx->driDrawable->y, - r128ctx->driDrawable->w, - r128ctx->driDrawable->h ); - fprintf( stderr, "%s: draw buf %3d %3d %3d %3d\n", - __FUNCTION__, - ctx->DrawBuffer->Xmin, - ctx->DrawBuffer->Ymin, - ctx->DrawBuffer->Xmax, - ctx->DrawBuffer->Ymax ); - fprintf( stderr, "%s: scissor %3d %3d %3d %3d\n", - __FUNCTION__, - ctx->Scissor.X, - ctx->Scissor.Y, - ctx->Scissor.Width, - ctx->Scissor.Height ); - fprintf( stderr, "%s: final %3d %3d %3d %3d\n", - __FUNCTION__, x1, y1, x2, y2 ); - fprintf( stderr, "\n" ); - } + x1 += drawable->x; + y1 += drawable->y; + x2 += drawable->x; + y2 += drawable->y; - r128ctx->setup.sc_top_left_c = ((x1 << 0) | - (y1 << 16)); - r128ctx->setup.sc_bottom_right_c = ((x2 << 0) | - (y2 << 16)); + rmesa->setup.sc_top_left_c = ((y1 << 16) | x1); + rmesa->setup.sc_bottom_right_c = ((y2 << 16) | x2); - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } } static void r128DDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_CLIP; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CLIP; } @@ -422,8 +396,8 @@ static void r128DDScissor( GLcontext *ctx, static void r128UpdateCull( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 f = r128ctx->setup.pm4_vc_fpu_setup; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 f = rmesa->setup.pm4_vc_fpu_setup; f &= ~R128_FRONT_DIR_MASK; @@ -453,26 +427,26 @@ static void r128UpdateCull( GLcontext *ctx ) } } - if ( r128ctx->setup.pm4_vc_fpu_setup != f ) { - r128ctx->setup.pm4_vc_fpu_setup = f; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP; + if ( rmesa->setup.pm4_vc_fpu_setup != f ) { + rmesa->setup.pm4_vc_fpu_setup = f; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_SETUP; } } static void r128DDCullFace( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_CULL; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; } static void r128DDFrontFace( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_CULL; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; } @@ -482,17 +456,17 @@ static void r128DDFrontFace( GLcontext *ctx, GLenum mode ) static void r128UpdateMasks( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - GLuint mask = r128PackColor( r128ctx->r128Screen->bpp, + GLuint mask = r128PackColor( rmesa->r128Screen->cpp, ctx->Color.ColorMask[RCOMP], ctx->Color.ColorMask[GCOMP], ctx->Color.ColorMask[BCOMP], ctx->Color.ColorMask[ACOMP] ); - if ( r128ctx->setup.plane_3d_mask_c != mask ) { - r128ctx->setup.plane_3d_mask_c = mask; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + if ( rmesa->setup.plane_3d_mask_c != mask ) { + rmesa->setup.plane_3d_mask_c = mask; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } } @@ -500,10 +474,10 @@ static GLboolean r128DDColorMask( GLcontext *ctx, GLboolean r, GLboolean g, GLboolean b, GLboolean a ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_MASKS; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_MASKS; return GL_TRUE; } @@ -517,48 +491,33 @@ static GLboolean r128DDColorMask( GLcontext *ctx, * sense to break them out of the core texture state update routines. */ -static void r128UpdateRenderAttrib( GLcontext *ctx ) -{ - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 t = r128ctx->setup.tex_cntl_c; - CARD32 bias = r128ctx->lod_bias & 0xff;; - - t &= ~R128_LOD_BIAS_MASK; - t |= (bias << R128_LOD_BIAS_SHIFT); - - if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { - t |= R128_SPEC_LIGHT_ENABLE; - } else { - t &= ~R128_SPEC_LIGHT_ENABLE; - } - - if ( ctx->Color.DitherFlag ) { - t |= R128_DITHER_ENABLE; - } else { - t &= ~R128_DITHER_ENABLE; - } - - if ( r128ctx->setup.tex_cntl_c != t ) { - r128ctx->setup.tex_cntl_c = t; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; - } -} - static void r128DDLightModelfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_RENDER; + CARD32 t = rmesa->setup.tex_cntl_c; + + FLUSH_BATCH( rmesa ); + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { + t |= R128_SPEC_LIGHT_ENABLE; + } else { + t &= ~R128_SPEC_LIGHT_ENABLE; + } + + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + } } } static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 s = r128ctx->setup.pm4_vc_fpu_setup; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 s = rmesa->setup.pm4_vc_fpu_setup; s &= ~R128_FPU_COLOR_MASK; @@ -573,12 +532,12 @@ static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) return; } - if ( r128ctx->setup.pm4_vc_fpu_setup != s ) { - FLUSH_BATCH( r128ctx ); - r128ctx->setup.pm4_vc_fpu_setup = s; + if ( rmesa->setup.pm4_vc_fpu_setup != s ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.pm4_vc_fpu_setup = s; - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= R128_UPLOAD_SETUP; + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_SETUP; } } @@ -589,14 +548,14 @@ static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) void r128UpdateWindow( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int x = r128ctx->driDrawable->x; - int y = r128ctx->driDrawable->y; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + int x = rmesa->driDrawable->x; + int y = rmesa->driDrawable->y; - r128ctx->setup.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | - (x << R128_WINDOW_X_SHIFT)); + rmesa->setup.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | + (x << R128_WINDOW_X_SHIFT)); - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW; } @@ -607,73 +566,65 @@ void r128UpdateWindow( GLcontext *ctx ) static void r128DDClearColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128ctx->ClearColor = r128PackColor( r128ctx->r128Screen->bpp, - r, g, b, a ); + rmesa->ClearColor = r128PackColor( rmesa->r128Screen->cpp, + r, g, b, a ); } static void r128DDColor( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128ctx->Color = r128PackColor( r128ctx->r128Screen->bpp, - r, g, b, a ); + rmesa->Color = r128PackColor( rmesa->r128Screen->cpp, + r, g, b, a ); } static void r128DDLogicOpCode( GLcontext *ctx, GLenum opcode ) { if ( ctx->Color.ColorLogicOpEnabled ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); if ( opcode == GL_COPY ) { - r128ctx->Fallback &= ~R128_FALLBACK_LOGICOP; + rmesa->Fallback &= ~R128_FALLBACK_LOGICOP; } else { - r128ctx->Fallback |= R128_FALLBACK_LOGICOP; + rmesa->Fallback |= R128_FALLBACK_LOGICOP; } } } static GLboolean r128DDSetDrawBuffer( GLcontext *ctx, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); int found = GL_TRUE; - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - if ( r128ctx->DrawBuffer != mode ) { - r128ctx->DrawBuffer = mode; - r128ctx->Fallback &= ~R128_FALLBACK_DRAW_BUFFER; + if ( rmesa->DrawBuffer != mode ) { + rmesa->DrawBuffer = mode; + rmesa->Fallback &= ~R128_FALLBACK_DRAW_BUFFER; switch ( mode ) { case GL_FRONT_LEFT: - r128ctx->drawX = r128ctx->r128Screen->frontX; - r128ctx->drawY = r128ctx->r128Screen->frontY; - r128ctx->drawOffset = r128ctx->r128Screen->frontOffset; - r128ctx->drawPitch = r128ctx->r128Screen->frontPitch; - r128ctx->readX = r128ctx->r128Screen->frontX; - r128ctx->readY = r128ctx->r128Screen->frontY; + rmesa->drawOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->r128Screen->frontPitch; break; case GL_BACK_LEFT: - r128ctx->drawX = r128ctx->r128Screen->backX; - r128ctx->drawY = r128ctx->r128Screen->backY; - r128ctx->drawOffset = r128ctx->r128Screen->backOffset; - r128ctx->drawPitch = r128ctx->r128Screen->backPitch; - r128ctx->readX = r128ctx->r128Screen->backX; - r128ctx->readY = r128ctx->r128Screen->backY; + rmesa->drawOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->r128Screen->backPitch; break; default: - r128ctx->Fallback |= R128_FALLBACK_DRAW_BUFFER; + rmesa->Fallback |= R128_FALLBACK_DRAW_BUFFER; found = GL_FALSE; break; } - r128ctx->setup.dst_pitch_offset_c = (((r128ctx->drawPitch/8) << 21) | - (r128ctx->drawOffset >> 5)); - r128ctx->new_state |= R128_NEW_WINDOW; + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + rmesa->new_state |= R128_NEW_WINDOW; } return found; @@ -683,25 +634,21 @@ static void r128DDSetReadBuffer( GLcontext *ctx, GLframebuffer *colorBuffer, GLenum mode ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); - r128ctx->Fallback &= ~R128_FALLBACK_READ_BUFFER; + rmesa->Fallback &= ~R128_FALLBACK_READ_BUFFER; switch ( mode ) { case GL_FRONT_LEFT: - r128ctx->readOffset = r128ctx->r128Screen->frontOffset; - r128ctx->readPitch = r128ctx->r128Screen->frontPitch; - r128ctx->readX = r128ctx->r128Screen->frontX; - r128ctx->readY = r128ctx->r128Screen->frontY; + rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->readPitch = rmesa->r128Screen->frontPitch; break; case GL_BACK_LEFT: - r128ctx->readOffset = r128ctx->r128Screen->backOffset; - r128ctx->readPitch = r128ctx->r128Screen->backPitch; - r128ctx->readX = r128ctx->r128Screen->backX; - r128ctx->readY = r128ctx->r128Screen->backY; + rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->readPitch = rmesa->r128Screen->backPitch; break; default: - r128ctx->Fallback |= R128_FALLBACK_READ_BUFFER; + rmesa->Fallback |= R128_FALLBACK_READ_BUFFER; break; } } @@ -713,28 +660,27 @@ static void r128DDSetReadBuffer( GLcontext *ctx, static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); GLuint *stipple = (GLuint *)mask; - FLUSH_BATCH( r128ctx ); - ctx->Driver.TriangleCaps |= DD_TRI_STIPPLE; + FLUSH_BATCH( rmesa ); - r128ctx->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; + rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; if ( ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON ) { - r128ctx->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA; + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA; } else { - r128ctx->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR; + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR; } - LOCK_HARDWARE( r128ctx ); + LOCK_HARDWARE( rmesa ); - drmR128PolygonStipple( r128ctx->driFd, stipple ); + drmR128PolygonStipple( rmesa->driFd, stipple ); - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } @@ -744,7 +690,7 @@ static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %s = %s )\n", @@ -755,68 +701,81 @@ static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) switch ( cap ) { case GL_ALPHA_TEST: case GL_BLEND: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; break; case GL_CULL_FACE: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_CULL; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; break; case GL_DEPTH_TEST: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_DEPTH; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; break; case GL_DITHER: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_RENDER; + do { + CARD32 t = rmesa->setup.tex_cntl_c; + FLUSH_BATCH( rmesa ); + + if ( ctx->Color.DitherFlag ) { + t |= R128_DITHER_ENABLE; + } else { + t &= ~R128_DITHER_ENABLE; + } + + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + } + } while (0); break; case GL_FOG: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_FOG; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_FOG; break; case GL_INDEX_LOGIC_OP: case GL_COLOR_LOGIC_OP: - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); if ( state && ctx->Color.LogicOp != GL_COPY ) { - r128ctx->Fallback |= R128_FALLBACK_LOGICOP; + rmesa->Fallback |= R128_FALLBACK_LOGICOP; } else { - r128ctx->Fallback &= ~R128_FALLBACK_LOGICOP; + rmesa->Fallback &= ~R128_FALLBACK_LOGICOP; } break; case GL_SCISSOR_TEST: - FLUSH_BATCH( r128ctx ); - r128ctx->scissor = state; - r128ctx->new_state |= R128_NEW_CLIP; + FLUSH_BATCH( rmesa ); + rmesa->scissor = state; + rmesa->new_state |= R128_NEW_CLIP; break; case GL_TEXTURE_1D: case GL_TEXTURE_2D: case GL_TEXTURE_3D: - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_TEXTURE; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_TEXTURE; break; case GL_POLYGON_STIPPLE: if ( (ctx->Driver.TriangleCaps & DD_TRI_STIPPLE) && ctx->PB->primitive == GL_POLYGON ) { - FLUSH_BATCH( r128ctx ); - r128ctx->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; + FLUSH_BATCH( rmesa ); + rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; if ( state ) { - r128ctx->setup.dp_gui_master_cntl_c |= + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA; } else { - r128ctx->setup.dp_gui_master_cntl_c |= + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR; } - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } break; @@ -860,51 +819,65 @@ static void r128DDPrintDirty( const char *msg, GLuint state ) * Blits of any type should always upload the context and masks after * they are done. */ -void r128EmitHwStateLocked( r128ContextPtr r128ctx ) +void r128EmitHwStateLocked( r128ContextPtr rmesa ) { - R128SAREAPrivPtr sarea = r128ctx->sarea; - r128_context_regs_t *regs = &(r128ctx->setup); - r128TexObjPtr t0 = r128ctx->CurrentTexObj[0]; - r128TexObjPtr t1 = r128ctx->CurrentTexObj[1]; + R128SAREAPrivPtr sarea = rmesa->sarea; + r128_context_regs_t *regs = &(rmesa->setup); + r128TexObjPtr t0 = rmesa->CurrentTexObj[0]; + r128TexObjPtr t1 = rmesa->CurrentTexObj[1]; if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) { - r128DDPrintDirty( "r128EmitHwStateLocked", r128ctx->dirty ); + r128DDPrintDirty( "r128EmitHwStateLocked", rmesa->dirty ); } - if ( r128ctx->dirty & R128_UPLOAD_TEX0IMAGES ) { - if ( t0 ) r128UploadTexImages( r128ctx, t0 ); - r128ctx->dirty &= ~R128_UPLOAD_TEX0IMAGES; + if ( rmesa->dirty & R128_UPLOAD_TEX0IMAGES ) { + if ( t0 ) r128UploadTexImages( rmesa, t0 ); + rmesa->dirty &= ~R128_UPLOAD_TEX0IMAGES; } - if ( r128ctx->dirty & R128_UPLOAD_TEX1IMAGES ) { - if ( t1 ) r128UploadTexImages( r128ctx, t1 ); - r128ctx->dirty &= ~R128_UPLOAD_TEX1IMAGES; + if ( rmesa->dirty & R128_UPLOAD_TEX1IMAGES ) { + if ( t1 ) r128UploadTexImages( rmesa, t1 ); + rmesa->dirty &= ~R128_UPLOAD_TEX1IMAGES; } - if ( r128ctx->dirty & (R128_UPLOAD_CONTEXT | - R128_UPLOAD_SETUP | - R128_UPLOAD_MASKS | - R128_UPLOAD_WINDOW | - R128_UPLOAD_CORE | - R128_UPLOAD_TEX0) ) { + if ( rmesa->dirty & (R128_UPLOAD_CONTEXT | + R128_UPLOAD_SETUP | + R128_UPLOAD_MASKS | + R128_UPLOAD_WINDOW | + R128_UPLOAD_CORE | + R128_UPLOAD_TEX0) ) { memcpy( &sarea->ContextState, regs, sizeof(sarea->ContextState) ); } - if ( (r128ctx->dirty & R128_UPLOAD_TEX0) && t0 ) { - memcpy( &sarea->TexState[0], &t0->setup, sizeof(sarea->TexState[0]) ); + if ( (rmesa->dirty & R128_UPLOAD_TEX0) && t0 ) { + r128_texture_regs_t *tex = &sarea->TexState[0]; + + tex->tex_cntl = t0->setup.tex_cntl; + tex->tex_combine_cntl = rmesa->tex_combine[0]; + tex->tex_size_pitch = t0->setup.tex_size_pitch; + memcpy( &tex->tex_offset[0], &t0->setup.tex_offset[0], + sizeof(tex->tex_offset ) ); + tex->tex_border_color = t0->setup.tex_border_color; } - if ( (r128ctx->dirty & R128_UPLOAD_TEX1) && t1 ) { - memcpy( &sarea->TexState[1], &t1->setup, sizeof(sarea->TexState[1]) ); + if ( (rmesa->dirty & R128_UPLOAD_TEX1) && t1 ) { + r128_texture_regs_t *tex = &sarea->TexState[1]; + + tex->tex_cntl = t1->setup.tex_cntl; + tex->tex_combine_cntl = rmesa->tex_combine[1]; + tex->tex_size_pitch = t1->setup.tex_size_pitch; + memcpy( &tex->tex_offset[0], &t1->setup.tex_offset[0], + sizeof(tex->tex_offset ) ); + tex->tex_border_color = t1->setup.tex_border_color; } - sarea->vertsize = r128ctx->vertsize; - sarea->vc_format = r128ctx->vc_format; + sarea->vertsize = rmesa->vertsize; + sarea->vc_format = rmesa->vc_format; /* Turn off the texture cache flushing */ - r128ctx->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; + rmesa->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; - sarea->dirty |= r128ctx->dirty; - r128ctx->dirty &= R128_UPLOAD_CLIPRECTS; + sarea->dirty |= rmesa->dirty; + rmesa->dirty &= R128_UPLOAD_CLIPRECTS; } static void r128DDPrintState( const char *msg, GLuint flags ) @@ -924,17 +897,16 @@ static void r128DDPrintState( const char *msg, GLuint flags ) (flags & R128_NEW_WINDOW) ? "window, " : "" ); } -/* Update the hardware state */ void r128DDUpdateHWState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int new_state = r128ctx->new_state; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + int new_state = rmesa->new_state; if ( new_state ) { - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - r128ctx->new_state = 0; + rmesa->new_state = 0; if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) r128DDPrintState( "r128UpdateHwState", new_state ); @@ -959,9 +931,6 @@ void r128DDUpdateHWState( GLcontext *ctx ) if ( new_state & R128_NEW_MASKS ) r128UpdateMasks( ctx ); - if ( new_state & R128_NEW_RENDER ) - r128UpdateRenderAttrib( ctx ); - if ( new_state & R128_NEW_WINDOW ) r128UpdateWindow( ctx ); @@ -980,8 +949,8 @@ void r128DDUpdateHWState( GLcontext *ctx ) */ static void r128DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - CARD32 f = r128ctx->setup.pm4_vc_fpu_setup; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + CARD32 f = rmesa->setup.pm4_vc_fpu_setup; f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID; @@ -1000,14 +969,14 @@ static void r128DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) } } - if ( r128ctx->setup.pm4_vc_fpu_setup != f ) { - FLUSH_BATCH( r128ctx ); - r128ctx->setup.pm4_vc_fpu_setup = f; + if ( rmesa->setup.pm4_vc_fpu_setup != f ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.pm4_vc_fpu_setup = f; /* NOTE: Only upload the setup state, everything else has been * uploaded by the usual means already. */ - r128ctx->dirty |= R128_UPLOAD_SETUP; + rmesa->dirty |= R128_UPLOAD_SETUP; } } @@ -1020,7 +989,7 @@ static void r128DDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) void r128DDUpdateState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); if ( ctx->NewState & INTERESTED ) { r128DDChooseRenderState( ctx ); @@ -1030,188 +999,182 @@ void r128DDUpdateState( GLcontext *ctx ) /* Need to do this here to detect texture fallbacks before * setting triangle functions. */ - if ( r128ctx->new_state & R128_NEW_TEXTURE ) { + if ( rmesa->new_state & R128_NEW_TEXTURE ) { r128DDUpdateHWState( ctx ); } - if ( !r128ctx->Fallback ) { + if ( !rmesa->Fallback ) { ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; - ctx->IndirectTriangles |= r128ctx->IndirectTriangles; + ctx->IndirectTriangles |= rmesa->IndirectTriangles; - ctx->Driver.PointsFunc = r128ctx->PointsFunc; - ctx->Driver.LineFunc = r128ctx->LineFunc; - ctx->Driver.TriangleFunc = r128ctx->TriangleFunc; - ctx->Driver.QuadFunc = r128ctx->QuadFunc; + ctx->Driver.PointsFunc = rmesa->PointsFunc; + ctx->Driver.LineFunc = rmesa->LineFunc; + ctx->Driver.TriangleFunc = rmesa->TriangleFunc; + ctx->Driver.QuadFunc = rmesa->QuadFunc; } } -/* Initialize the context's hardware state */ -void r128DDInitState( r128ContextPtr r128ctx ) +/* Initialize the context's hardware state. + */ +void r128DDInitState( r128ContextPtr rmesa ) { int dst_bpp, depth_bpp; - CARD32 bias; - switch ( r128ctx->r128Screen->bpp ) { - case 16: dst_bpp = R128_GMC_DST_16BPP; break; - case 32: dst_bpp = R128_GMC_DST_32BPP; break; + switch ( rmesa->r128Screen->cpp ) { + case 2: + dst_bpp = R128_GMC_DST_16BPP; + break; + case 4: + dst_bpp = R128_GMC_DST_32BPP; + break; default: - fprintf( stderr, "Error: Unsupported pixel depth %d... exiting\n", - r128ctx->r128Screen->bpp ); + fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); exit( -1 ); } - switch ( r128ctx->DepthSize ) { + rmesa->ClearColor = 0x00000000; + + switch ( rmesa->glCtx->Visual->DepthBits ) { case 16: - r128ctx->ClearDepth = 0x0000ffff; + rmesa->ClearDepth = 0x0000ffff; depth_bpp = R128_Z_PIX_WIDTH_16; - r128ctx->depth_scale = 1.0 / 65536.0; + rmesa->depth_scale = 1.0 / (GLfloat)0xffff; break; case 24: - r128ctx->ClearDepth = 0x00ffffff; + rmesa->ClearDepth = 0x00ffffff; depth_bpp = R128_Z_PIX_WIDTH_24; - r128ctx->depth_scale = 1.0 / 16777216.0; - break; - case 32: - r128ctx->ClearDepth = 0xffffffff; - depth_bpp = R128_Z_PIX_WIDTH_32; - r128ctx->depth_scale = 1.0 / 4294967296.0; + rmesa->depth_scale = 1.0 / (GLfloat)0xffffff; break; default: fprintf( stderr, "Error: Unsupported depth %d... exiting\n", - r128ctx->DepthSize ); + rmesa->glCtx->Visual->DepthBits ); exit( -1 ); } - r128ctx->ClearColor = 0x00000000; + rmesa->RenderIndex = R128_FALLBACK_BIT; + rmesa->PointsFunc = NULL; + rmesa->LineFunc = NULL; + rmesa->TriangleFunc = NULL; + rmesa->QuadFunc = NULL; - r128ctx->RenderIndex = R128_FALLBACK_BIT; - r128ctx->PointsFunc = NULL; - r128ctx->LineFunc = NULL; - r128ctx->TriangleFunc = NULL; - r128ctx->QuadFunc = NULL; + rmesa->IndirectTriangles = 0; + rmesa->Fallback = 0; - r128ctx->IndirectTriangles = 0; - r128ctx->Fallback = 0; - - if ( r128ctx->glCtx->Visual->DBflag ) { - r128ctx->DrawBuffer = GL_BACK_LEFT; - r128ctx->drawOffset = r128ctx->readOffset = - r128ctx->r128Screen->backOffset; - r128ctx->drawPitch = r128ctx->readPitch = - r128ctx->r128Screen->backPitch; + if ( rmesa->glCtx->Visual->DBflag ) { + rmesa->DrawBuffer = GL_BACK_LEFT; + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; } else { - r128ctx->DrawBuffer = GL_FRONT_LEFT; - r128ctx->drawOffset = r128ctx->readOffset = - r128ctx->r128Screen->frontOffset; - r128ctx->drawPitch = r128ctx->readPitch = - r128ctx->r128Screen->frontPitch; + rmesa->DrawBuffer = GL_FRONT_LEFT; + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; } /* Harware state: */ - r128ctx->setup.dst_pitch_offset_c = (((r128ctx->drawPitch/8) << 21) | - (r128ctx->drawOffset >> 5)); - - r128ctx->setup.dp_gui_master_cntl_c = (R128_GMC_DST_PITCH_OFFSET_CNTL | - R128_GMC_DST_CLIPPING | - R128_GMC_BRUSH_SOLID_COLOR | - dst_bpp | - R128_GMC_SRC_DATATYPE_COLOR | - R128_GMC_BYTE_MSB_TO_LSB | - R128_GMC_CONVERSION_TEMP_6500 | - R128_ROP3_S | - R128_DP_SRC_SOURCE_MEMORY | - R128_GMC_3D_FCN_EN | - R128_GMC_CLR_CMP_CNTL_DIS | - R128_GMC_AUX_CLIP_DIS | - R128_GMC_WR_MSK_DIS); - - r128ctx->setup.sc_top_left_c = 0x00000000; - r128ctx->setup.sc_bottom_right_c = 0x1fff1fff; - - r128ctx->setup.z_offset_c = r128ctx->r128Screen->depthOffset; - r128ctx->setup.z_pitch_c = ((r128ctx->r128Screen->depthPitch >> 3) | - R128_Z_TILE); - - r128ctx->setup.z_sten_cntl_c = (depth_bpp | - R128_Z_TEST_LESS | - R128_STENCIL_TEST_ALWAYS | - R128_STENCIL_S_FAIL_KEEP | - R128_STENCIL_ZPASS_KEEP | - R128_STENCIL_ZFAIL_KEEP); - - bias = r128ctx->lod_bias & 0xff; - r128ctx->setup.tex_cntl_c = (R128_Z_WRITE_ENABLE | - R128_SHADE_ENABLE | - R128_DITHER_ENABLE | - R128_ALPHA_IN_TEX_COMPLETE_A | - R128_LIGHT_DIS | - R128_ALPHA_LIGHT_DIS | - R128_TEX_CACHE_FLUSH | - (bias << R128_LOD_BIAS_SHIFT)); - - r128ctx->setup.misc_3d_state_cntl_reg = (R128_MISC_SCALE_3D_TEXMAP_SHADE | - R128_MISC_SCALE_PIX_REPLICATE | - R128_ALPHA_COMB_ADD_CLAMP | - R128_FOG_VERTEX | - R128_ALPHA_BLEND_SRC_ONE | - R128_ALPHA_BLEND_DST_ZERO | - R128_ALPHA_TEST_ALWAYS); - - r128ctx->setup.texture_clr_cmp_clr_c = 0x00000000; - r128ctx->setup.texture_clr_cmp_msk_c = 0xffffffff; - - r128ctx->setup.fog_color_c = 0x00000000; - - r128ctx->setup.pm4_vc_fpu_setup = (R128_FRONT_DIR_CCW | - R128_BACKFACE_SOLID | - R128_FRONTFACE_SOLID | - R128_FPU_COLOR_GOURAUD | - R128_FPU_SUB_PIX_4BITS | - R128_FPU_MODE_3D | - R128_TRAP_BITS_DISABLE | - R128_XFACTOR_2 | - R128_YFACTOR_2 | - R128_FLAT_SHADE_VERTEX_OGL | - R128_FPU_ROUND_TRUNCATE | - R128_WM_SEL_8DW); - - r128ctx->setup.setup_cntl = (R128_COLOR_GOURAUD | - R128_PRIM_TYPE_TRI | - R128_TEXTURE_ST_MULT_W | - R128_STARTING_VERTEX_1 | - R128_ENDING_VERTEX_3 | - R128_SU_POLY_LINE_NOT_LAST | - R128_SUB_PIX_4BITS); - - r128ctx->setup.tex_size_pitch_c = 0x00000000; - r128ctx->setup.constant_color_c = 0x00ffffff; - - r128ctx->setup.dp_write_mask = 0xffffffff; - r128ctx->setup.sten_ref_mask_c = 0xffff0000; - r128ctx->setup.plane_3d_mask_c = 0xffffffff; - - r128ctx->setup.window_xy_offset = 0x00000000; - - r128ctx->setup.scale_3d_cntl = (R128_SCALE_DITHER_TABLE | - R128_TEX_CACHE_SIZE_FULL | - R128_DITHER_INIT_RESET | - R128_SCALE_3D_TEXMAP_SHADE | - R128_SCALE_PIX_REPLICATE | - R128_ALPHA_COMB_ADD_CLAMP | - R128_FOG_VERTEX | - R128_ALPHA_BLEND_SRC_ONE | - R128_ALPHA_BLEND_DST_ZERO | - R128_ALPHA_TEST_ALWAYS | - R128_COMPOSITE_SHADOW_CMP_EQUAL | - R128_TEX_MAP_ALPHA_IN_TEXTURE | - R128_TEX_CACHE_LINE_SIZE_4QW); - - r128ctx->new_state = R128_NEW_ALL; + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + + rmesa->setup.dp_gui_master_cntl_c = (R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_DST_CLIPPING | + R128_GMC_BRUSH_SOLID_COLOR | + dst_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_GMC_BYTE_MSB_TO_LSB | + R128_GMC_CONVERSION_TEMP_6500 | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_3D_FCN_EN | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS); + + rmesa->setup.sc_top_left_c = 0x00000000; + rmesa->setup.sc_bottom_right_c = 0x1fff1fff; + + rmesa->setup.z_offset_c = rmesa->r128Screen->depthOffset; + rmesa->setup.z_pitch_c = ((rmesa->r128Screen->depthPitch >> 3) | + R128_Z_TILE); + + rmesa->setup.z_sten_cntl_c = (depth_bpp | + R128_Z_TEST_LESS | + R128_STENCIL_TEST_ALWAYS | + R128_STENCIL_S_FAIL_KEEP | + R128_STENCIL_ZPASS_KEEP | + R128_STENCIL_ZFAIL_KEEP); + + rmesa->setup.tex_cntl_c = (R128_Z_WRITE_ENABLE | + R128_SHADE_ENABLE | + R128_DITHER_ENABLE | + R128_ALPHA_IN_TEX_COMPLETE_A | + R128_LIGHT_DIS | + R128_ALPHA_LIGHT_DIS | + R128_TEX_CACHE_FLUSH | + (0x3f << R128_LOD_BIAS_SHIFT)); + + rmesa->setup.misc_3d_state_cntl_reg = (R128_MISC_SCALE_3D_TEXMAP_SHADE | + R128_MISC_SCALE_PIX_REPLICATE | + R128_ALPHA_COMB_ADD_CLAMP | + R128_FOG_VERTEX | + R128_ALPHA_BLEND_SRC_ONE | + R128_ALPHA_BLEND_DST_ZERO | + R128_ALPHA_TEST_ALWAYS); + + rmesa->setup.texture_clr_cmp_clr_c = 0x00000000; + rmesa->setup.texture_clr_cmp_msk_c = 0xffffffff; + + rmesa->setup.fog_color_c = 0x00000000; + + rmesa->setup.pm4_vc_fpu_setup = (R128_FRONT_DIR_CCW | + R128_BACKFACE_SOLID | + R128_FRONTFACE_SOLID | + R128_FPU_COLOR_GOURAUD | + R128_FPU_SUB_PIX_4BITS | + R128_FPU_MODE_3D | + R128_TRAP_BITS_DISABLE | + R128_XFACTOR_2 | + R128_YFACTOR_2 | + R128_FLAT_SHADE_VERTEX_OGL | + R128_FPU_ROUND_TRUNCATE | + R128_WM_SEL_8DW); + + rmesa->setup.setup_cntl = (R128_COLOR_GOURAUD | + R128_PRIM_TYPE_TRI | + R128_TEXTURE_ST_MULT_W | + R128_STARTING_VERTEX_1 | + R128_ENDING_VERTEX_3 | + R128_SU_POLY_LINE_NOT_LAST | + R128_SUB_PIX_4BITS); + + rmesa->setup.tex_size_pitch_c = 0x00000000; + rmesa->setup.constant_color_c = 0x00ffffff; + + rmesa->setup.dp_write_mask = 0xffffffff; + rmesa->setup.sten_ref_mask_c = 0xffff0000; + rmesa->setup.plane_3d_mask_c = 0xffffffff; + + rmesa->setup.window_xy_offset = 0x00000000; + + rmesa->setup.scale_3d_cntl = (R128_SCALE_DITHER_TABLE | + R128_TEX_CACHE_SIZE_FULL | + R128_DITHER_INIT_RESET | + R128_SCALE_3D_TEXMAP_SHADE | + R128_SCALE_PIX_REPLICATE | + R128_ALPHA_COMB_ADD_CLAMP | + R128_FOG_VERTEX | + R128_ALPHA_BLEND_SRC_ONE | + R128_ALPHA_BLEND_DST_ZERO | + R128_ALPHA_TEST_ALWAYS | + R128_COMPOSITE_SHADOW_CMP_EQUAL | + R128_TEX_MAP_ALPHA_IN_TEXTURE | + R128_TEX_CACHE_LINE_SIZE_4QW); + + rmesa->new_state = R128_NEW_ALL; } -/* Initialize the driver's state functions */ +/* Initialize the driver's state functions. + */ void r128DDInitStateFuncs( GLcontext *ctx ) { ctx->Driver.UpdateState = r128DDUpdateState; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_state.h b/xc/lib/GL/mesa/src/drv/r128/r128_state.h index 6d122879d..c51ac2394 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.h,v 1.2 2000/12/04 19:21:47 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.h,v 1.3 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,29 +28,27 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_STATE_H_ -#define _R128_STATE_H_ +#ifndef __R128_STATE_H__ +#define __R128_STATE_H__ #ifdef GLX_DIRECT_RENDERING #include "r128_context.h" -extern void r128DDInitState( r128ContextPtr r128ctx ); +extern void r128DDInitState( r128ContextPtr rmesa ); extern void r128DDInitStateFuncs( GLcontext *ctx ); extern void r128DDUpdateState( GLcontext *ctx ); extern void r128DDUpdateHWState( GLcontext *ctx ); extern void r128UpdateWindow( GLcontext *ctx ); -extern void r128SetClipRects( r128ContextPtr r128ctx, - XF86DRIClipRectPtr pc, int nc ); -extern void r128EmitHwStateLocked( r128ContextPtr r128ctx ); +extern void r128EmitHwStateLocked( r128ContextPtr rmesa ); #endif -#endif /* _R128_STATE_H_ */ +#endif diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c index ff619fa46..f518720f5 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.6 2000/12/04 19:21:47 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.7 2001/01/08 01:07:21 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -44,14 +44,77 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "enums.h" #include "mem.h" +#define TEX_0 1 +#define TEX_1 2 -static void r128SetTexWrap(r128TexObjPtr t, GLenum srwap, GLenum twrap); -static void r128SetTexFilter(r128TexObjPtr t, GLenum minf, GLenum magf); -static void r128SetTexBorderColor(r128TexObjPtr t, GLubyte c[4]); -/* Allocate and initialize hardware state associated with texture `t' */ -/* NOTE: This function is only called while holding the hardware lock */ -static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, +static void r128SetTexWrap( r128TexObjPtr t, GLenum swrap, GLenum twrap ) +{ + t->setup.tex_cntl &= ~(R128_TEX_CLAMP_S_MASK | R128_TEX_CLAMP_T_MASK); + + switch ( swrap ) { + case GL_CLAMP: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; + break; + case GL_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_WRAP; + break; + } + + switch ( twrap ) { + case GL_CLAMP: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; + break; + case GL_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_WRAP; + break; + } +} + +static void r128SetTexFilter( r128TexObjPtr t, GLenum minf, GLenum magf ) +{ + t->setup.tex_cntl &= ~(R128_MIN_BLEND_MASK | R128_MAG_BLEND_MASK); + + switch ( minf ) { + case GL_NEAREST: + t->setup.tex_cntl |= R128_MIN_BLEND_NEAREST; + break; + case GL_LINEAR: + t->setup.tex_cntl |= R128_MIN_BLEND_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + t->setup.tex_cntl |= R128_MIN_BLEND_MIPNEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + t->setup.tex_cntl |= R128_MIN_BLEND_MIPLINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPLINEAR; + break; + } + + switch ( magf ) { + case GL_NEAREST: + t->setup.tex_cntl |= R128_MAG_BLEND_NEAREST; + break; + case GL_LINEAR: + t->setup.tex_cntl |= R128_MAG_BLEND_LINEAR; + break; + } +} + +static void r128SetTexBorderColor( r128TexObjPtr t, GLubyte c[4] ) +{ + t->setup.tex_border_color = r128PackColor( 4, c[0], c[1], c[2], c[3] ); +} + + +/* Allocate and initialize hardware state associated with texture `t'. + */ +static r128TexObjPtr r128CreateTexObj( r128ContextPtr rmesa, struct gl_texture_object *tObj ) { r128TexObjPtr t; @@ -64,7 +127,7 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, if ( !image ) return NULL; - t = (r128TexObjPtr)CALLOC( sizeof(*t) ); + t = (r128TexObjPtr) CALLOC( sizeof(*t) ); if ( !t ) return NULL; @@ -75,8 +138,7 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, case GL_RGBA: case GL_ALPHA: case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: - if ( r128ctx->r128Screen->bpp == 32 ) { + if ( rmesa->r128Screen->cpp == 4 ) { t->texelBytes = 4; t->textureFormat = R128_DATATYPE_ARGB8888; } else { @@ -86,7 +148,7 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, break; case GL_RGB: - if ( r128ctx->r128Screen->bpp == 32 ) { + if ( rmesa->r128Screen->cpp == 4 ) { t->texelBytes = 4; t->textureFormat = R128_DATATYPE_ARGB8888; } else { @@ -96,14 +158,9 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, break; case GL_LUMINANCE: - if ( r128ctx->r128Screen->bpp == 32 ) { - t->texelBytes = 4; - t->textureFormat = R128_DATATYPE_ARGB8888; - } else { - t->texelBytes = 2; - /* Use this to get true greys */ - t->textureFormat = R128_DATATYPE_ARGB1555; - } + case GL_INTENSITY: + t->texelBytes = 1; + t->textureFormat = R128_DATATYPE_RGB8; break; case GL_COLOR_INDEX: @@ -176,7 +233,7 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, (log2Height << R128_TEX_HEIGHT_SHIFT) | (log2MinSize << R128_TEX_MIN_SIZE_SHIFT)); - for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { t->setup.tex_offset[i] = 0x00000000; } t->setup.tex_border_color = 0x00000000; @@ -196,12 +253,13 @@ static r128TexObjPtr r128CreateTexObj( r128ContextPtr r128ctx, return t; } -/* Destroy hardware state associated with texture `t' */ -void r128DestroyTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) +/* Destroy hardware state associated with texture `t'. + */ +void r128DestroyTexObj( r128ContextPtr rmesa, r128TexObjPtr t ) { #if ENABLE_PERF_BOXES /* Bump the performace counter */ - r128ctx->c_textureSwaps++; + rmesa->c_textureSwaps++; #endif if ( !t ) return; @@ -212,19 +270,21 @@ void r128DestroyTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) if ( t->tObj ) t->tObj->DriverData = NULL; - if ( t->bound ) - r128ctx->CurrentTexObj[t->bound-1] = NULL; + + if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL; + if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL; remove_from_list( t ); FREE( t ); } -/* Keep track of swapped out texture objects */ -static void r128SwapOutTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) +/* Keep track of swapped out texture objects. + */ +static void r128SwapOutTexObj( r128ContextPtr rmesa, r128TexObjPtr t ) { #if ENABLE_PERF_BOXES /* Bump the performace counter */ - r128ctx->c_textureSwaps++; + rmesa->c_textureSwaps++; #endif if ( t->memBlock ) { mmFreeMem( t->memBlock ); @@ -232,18 +292,19 @@ static void r128SwapOutTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ) } t->dirty_images = ~0; - move_to_tail( &r128ctx->SwappedOut, t ); + move_to_tail( &rmesa->SwappedOut, t ); } -/* Print out debugging information about texture LRU */ -void r128PrintLocalLRU( r128ContextPtr r128ctx, int heap ) +/* Print out debugging information about texture LRU. + */ +void r128PrintLocalLRU( r128ContextPtr rmesa, int heap ) { r128TexObjPtr t; - int sz = 1 << (r128ctx->r128Screen->log2TexGran[heap]); + int sz = 1 << (rmesa->r128Screen->logTexGranularity[heap]); fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); - foreach( t, &r128ctx->TexObjList[heap] ) { + foreach ( t, &rmesa->TexObjList[heap] ) { if ( !t->tObj ) { fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n", t->memBlock->ofs / sz, @@ -260,9 +321,9 @@ void r128PrintLocalLRU( r128ContextPtr r128ctx, int heap ) fprintf( stderr, "\n" ); } -void r128PrintGlobalLRU( r128ContextPtr r128ctx, int heap ) +void r128PrintGlobalLRU( r128ContextPtr rmesa, int heap ) { - r128_tex_region_t *list = r128ctx->sarea->texList[heap]; + r128_tex_region_t *list = rmesa->sarea->texList[heap]; int i, j; fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); @@ -285,12 +346,12 @@ void r128PrintGlobalLRU( r128ContextPtr r128ctx, int heap ) fprintf( stderr, "\n" ); } -/* Reset the global texture LRU */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128ResetGlobalLRU( r128ContextPtr r128ctx, int heap ) +/* Reset the global texture LRU. + */ +static void r128ResetGlobalLRU( r128ContextPtr rmesa, int heap ) { - r128_tex_region_t *list = r128ctx->sarea->texList[heap]; - int sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; + r128_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = 1 << rmesa->r128Screen->logTexGranularity[heap]; int i; /* (Re)initialize the global circular LRU list. The last element in @@ -298,7 +359,7 @@ static void r128ResetGlobalLRU( r128ContextPtr r128ctx, int heap ) * the end of the array allows it to be addressed rationally when * looking up objects at a particular location in texture memory. */ - for ( i = 0 ; (i+1) * sz <= r128ctx->r128Screen->texSize[heap] ; i++ ) { + for ( i = 0 ; (i+1) * sz <= rmesa->r128Screen->texSize[heap] ; i++ ) { list[i].prev = i-1; list[i].next = i+1; list[i].age = 0; @@ -310,21 +371,21 @@ static void r128ResetGlobalLRU( r128ContextPtr r128ctx, int heap ) list[i].next = R128_NR_TEX_REGIONS; list[R128_NR_TEX_REGIONS].prev = i; list[R128_NR_TEX_REGIONS].next = 0; - r128ctx->sarea->texAge[heap] = 0; + rmesa->sarea->texAge[heap] = 0; } -/* Update the local and glock texture LRUs */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128UpdateTexLRU( r128ContextPtr r128ctx, r128TexObjPtr t ) +/* Update the local and glock texture LRUs. + */ +static void r128UpdateTexLRU( r128ContextPtr rmesa, r128TexObjPtr t ) { int heap = t->heap; - r128_tex_region_t *list = r128ctx->sarea->texList[heap]; - int log2sz = r128ctx->r128Screen->log2TexGran[heap]; + r128_tex_region_t *list = rmesa->sarea->texList[heap]; + int log2sz = rmesa->r128Screen->logTexGranularity[heap]; int start = t->memBlock->ofs >> log2sz; int end = (t->memBlock->ofs + t->memBlock->size - 1) >> log2sz; int i; - r128ctx->lastTexAge[heap] = ++r128ctx->sarea->texAge[heap]; + rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap]; if ( !t->memBlock ) { fprintf( stderr, "no memblock\n\n" ); @@ -332,12 +393,12 @@ static void r128UpdateTexLRU( r128ContextPtr r128ctx, r128TexObjPtr t ) } /* Update our local LRU */ - move_to_head( &r128ctx->TexObjList[heap], t ); + move_to_head( &rmesa->TexObjList[heap], t ); /* Update the global LRU */ for ( i = start ; i <= end ; i++ ) { list[i].in_use = 1; - list[i].age = r128ctx->lastTexAge[heap]; + list[i].age = rmesa->lastTexAge[heap]; /* remove_from_list(i) */ list[(CARD32)list[i].next].prev = list[i].prev; @@ -351,23 +412,23 @@ static void r128UpdateTexLRU( r128ContextPtr r128ctx, r128TexObjPtr t ) } if ( 0 ) { - r128PrintGlobalLRU( r128ctx, t->heap ); - r128PrintLocalLRU( r128ctx, t->heap ); + r128PrintGlobalLRU( rmesa, t->heap ); + r128PrintLocalLRU( rmesa, t->heap ); } } /* Update our notion of what textures have been changed since we last - held the lock. This pertains to both our local textures and the - textures belonging to other clients. Keep track of other client's - textures by pushing a placeholder texture onto the LRU list -- these - are denoted by (tObj == NULL). */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128TexturesGone( r128ContextPtr r128ctx, int heap, + * held the lock. This pertains to both our local textures and the + * textures belonging to other clients. Keep track of other client's + * textures by pushing a placeholder texture onto the LRU list -- these + * are denoted by (tObj == NULL). + */ +static void r128TexturesGone( r128ContextPtr rmesa, int heap, int offset, int size, int in_use ) { r128TexObjPtr t, tmp; - foreach_s ( t, tmp, &r128ctx->TexObjList[heap] ) { + foreach_s ( t, tmp, &rmesa->TexObjList[heap] ) { if ( t->memBlock->ofs >= offset + size || t->memBlock->ofs + t->memBlock->size <= offset ) continue; @@ -376,37 +437,38 @@ static void r128TexturesGone( r128ContextPtr r128ctx, int heap, * bound objects, however. */ if ( t->bound ) { - r128SwapOutTexObj( r128ctx, t ); + r128SwapOutTexObj( rmesa, t ); } else { - r128DestroyTexObj( r128ctx, t ); + r128DestroyTexObj( rmesa, t ); } } if ( in_use ) { t = (r128TexObjPtr) CALLOC( sizeof(*t) ); - if (!t) return; + if ( !t ) return; - t->memBlock = mmAllocMem( r128ctx->texHeap[heap], size, 0, offset ); + t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset ); if ( !t->memBlock ) { fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", (int)size, (int)offset ); - mmDumpMemInfo( r128ctx->texHeap[heap] ); + mmDumpMemInfo( rmesa->texHeap[heap] ); return; } - insert_at_head( &r128ctx->TexObjList[heap], t ); + insert_at_head( &rmesa->TexObjList[heap], t ); } } /* Update our client's shared texture state. If another client has - modified a region in which we have textures, then we need to figure - out which of our textures has been removed, and update our global - LRU. */ -void r128AgeTextures( r128ContextPtr r128ctx, int heap ) + * modified a region in which we have textures, then we need to figure + * out which of our textures has been removed, and update our global + * LRU. + */ +void r128AgeTextures( r128ContextPtr rmesa, int heap ) { - R128SAREAPriv *sarea = r128ctx->sarea; + R128SAREAPrivPtr sarea = rmesa->sarea; - if ( sarea->texAge[heap] != r128ctx->lastTexAge[heap] ) { - int sz = 1 << r128ctx->r128Screen->log2TexGran[heap]; + if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) { + int sz = 1 << rmesa->r128Screen->logTexGranularity[heap]; int nr = 0; int idx; @@ -418,15 +480,16 @@ void r128AgeTextures( r128ContextPtr r128ctx, int heap ) idx = sarea->texList[heap][idx].prev, nr++ ) { /* If switching texturing schemes, then the SAREA might not - have been properly cleared, so we need to reset the - global texture LRU. */ - if ( idx * sz > r128ctx->r128Screen->texSize[heap] ) { + * have been properly cleared, so we need to reset the + * global texture LRU. + */ + if ( idx * sz > rmesa->r128Screen->texSize[heap] ) { nr = R128_NR_TEX_REGIONS; break; } - if ( sarea->texList[heap][idx].age > r128ctx->lastTexAge[heap] ) { - r128TexturesGone( r128ctx, heap, idx * sz, sz, + if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) { + r128TexturesGone( rmesa, heap, idx * sz, sz, sarea->texList[heap][idx].in_use ); } } @@ -436,24 +499,30 @@ void r128AgeTextures( r128ContextPtr r128ctx, int heap ) * global texture LRU. */ if ( nr == R128_NR_TEX_REGIONS ) { - r128TexturesGone( r128ctx, heap, 0, - r128ctx->r128Screen->texSize[heap], 0 ); - r128ResetGlobalLRU( r128ctx, heap ); + r128TexturesGone( rmesa, heap, 0, + rmesa->r128Screen->texSize[heap], 0 ); + r128ResetGlobalLRU( rmesa, heap ); } if ( 0 ) { - r128PrintGlobalLRU( r128ctx, heap ); - r128PrintLocalLRU( r128ctx, heap ); + r128PrintGlobalLRU( rmesa, heap ); + r128PrintLocalLRU( rmesa, heap ); } - r128ctx->dirty |= (R128_UPLOAD_CONTEXT | - R128_UPLOAD_TEX0IMAGES | - R128_UPLOAD_TEX1IMAGES); - r128ctx->lastTexAge[heap] = sarea->texAge[heap]; + rmesa->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_TEX0IMAGES | + R128_UPLOAD_TEX1IMAGES); + rmesa->lastTexAge[heap] = sarea->texAge[heap]; } } -/* Convert a block of Mesa-formatted texture to an 8bpp hardware format */ + +/* ================================================================ + * Texture image conversions + */ + +/* Convert a block of Mesa-formatted texture to an 8bpp hardware format. + */ static void r128ConvertTexture8bpp( CARD32 *dst, struct gl_texture_image *image, int x, int y, int width, int height, @@ -463,20 +532,6 @@ static void r128ConvertTexture8bpp( CARD32 *dst, int i, j; switch ( image->Format ) { - case GL_RGB: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; - for ( j = width >> 2 ; j ; j-- ) { - *dst++= ((R128PACKCOLOR332( src[0], src[1], src[2] )) | - (R128PACKCOLOR332( src[3], src[4], src[5] ) << 8) | - (R128PACKCOLOR332( src[6], src[7], src[8] ) << 16) | - (R128PACKCOLOR332( src[9], src[10], src[11] ) << 24)); - src += 12; - } - } - break; - - case GL_ALPHA: case GL_LUMINANCE: case GL_INTENSITY: case GL_COLOR_INDEX: @@ -496,7 +551,8 @@ static void r128ConvertTexture8bpp( CARD32 *dst, } } -/* Convert a block of Mesa-formatted texture to a 16bpp hardware format */ +/* Convert a block of Mesa-formatted texture to a 16bpp hardware format. + */ static void r128ConvertTexture16bpp( CARD32 *dst, struct gl_texture_image *image, int x, int y, int width, int height, @@ -512,17 +568,6 @@ static void r128ConvertTexture16bpp( CARD32 *dst, switch ( image->Format ) { - case GL_RGB: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((R128PACKCOLOR565( src[0], src[1], src[2] )) | - (R128PACKCOLOR565( src[3], src[4], src[5] ) << 16)); - src += 6; - } - } - break; - case GL_RGBA: for ( i = 0 ; i < height ; i++ ) { src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; @@ -534,23 +579,23 @@ static void r128ConvertTexture16bpp( CARD32 *dst, } break; - case GL_ALPHA: + case GL_RGB: for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[0] )) | - (R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[1] ) << 16)); - src += 2; + *dst++ = ((R128PACKCOLOR565( src[0], src[1], src[2] )) | + (R128PACKCOLOR565( src[3], src[4], src[5] ) << 16)); + src += 6; } } break; - case GL_LUMINANCE: + case GL_ALPHA: for ( i = 0 ; i < height ; i++ ) { src = (CARD8 *)image->Data + ((y + i) * pitch + x); for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((R128PACKCOLOR1555( src[0], src[0], src[0], 0xff )) | - (R128PACKCOLOR1555( src[1], src[1], src[1], 0xff ) << 16)); + *dst++ = ((R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[0] )) | + (R128PACKCOLOR4444( 0xff, 0xff, 0xff, src[1] ) << 16)); src += 2; } } @@ -567,17 +612,6 @@ static void r128ConvertTexture16bpp( CARD32 *dst, } break; - case GL_INTENSITY: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for ( j = width >> 1 ; j ; j-- ) { - *dst++ = ((R128PACKCOLOR4444( src[0], src[0], src[0], src[0] )) | - (R128PACKCOLOR4444( src[1], src[1], src[1], src[1] ) << 16)); - src += 2; - } - } - break; - default: fprintf( stderr, "%s: unsupported format 0x%x\n", __FUNCTION__, image->Format ); @@ -585,7 +619,8 @@ static void r128ConvertTexture16bpp( CARD32 *dst, } } -/* Convert a block of Mesa-formatted texture to a 32bpp hardware format */ +/* Convert a block of Mesa-formatted texture to a 32bpp hardware format. + */ static void r128ConvertTexture32bpp( CARD32 *dst, struct gl_texture_image *image, int x, int y, int width, int height, @@ -595,16 +630,6 @@ static void r128ConvertTexture32bpp( CARD32 *dst, int i, j; switch ( image->Format ) { - case GL_RGB: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; - for ( j = width ; j ; j-- ) { - *dst++ = R128PACKCOLOR8888( src[0], src[1], src[2], 0xff ); - src += 3; - } - } - break; - case GL_RGBA: for ( i = 0 ; i < height ; i++ ) { src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; @@ -615,21 +640,21 @@ static void r128ConvertTexture32bpp( CARD32 *dst, } break; - case GL_ALPHA: + case GL_RGB: for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; for ( j = width ; j ; j-- ) { - *dst++ = R128PACKCOLOR8888( 0xff, 0xff, 0xff, src[0] ); - src += 1; + *dst++ = R128PACKCOLOR8888( src[0], src[1], src[2], 0xff ); + src += 3; } } break; - case GL_LUMINANCE: + case GL_ALPHA: for ( i = 0 ; i < height ; i++ ) { src = (CARD8 *)image->Data + ((y + i) * pitch + x); for ( j = width ; j ; j-- ) { - *dst++ = R128PACKCOLOR8888( src[0], src[0], src[0], 0xff ); + *dst++ = R128PACKCOLOR8888( 0xff, 0xff, 0xff, src[0] ); src += 1; } } @@ -645,16 +670,6 @@ static void r128ConvertTexture32bpp( CARD32 *dst, } break; - case GL_INTENSITY: - for ( i = 0 ; i < height ; i++ ) { - src = (CARD8 *)image->Data + ((y + i) * pitch + x); - for ( j = width ; j ; j-- ) { - *dst++ = R128PACKCOLOR8888( src[0], src[0], src[0], src[0] ); - src += 1; - } - } - break; - default: fprintf( stderr, "%s: unsupported format 0x%x\n", __FUNCTION__, image->Format ); @@ -663,9 +678,9 @@ static void r128ConvertTexture32bpp( CARD32 *dst, } /* Upload the texture image associated with texture `t' at level `level' - at the address relative to `start'. */ -/* NOTE: This function is only called while holding the hardware lock */ -static void r128UploadSubImage( r128ContextPtr r128ctx, + * at the address relative to `start'. + */ +static void r128UploadSubImage( r128ContextPtr rmesa, r128TexObjPtr t, int level, int x, int y, int width, int height ) { @@ -680,7 +695,7 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, int i; /* Ensure we have a valid texture to upload */ - if ( ( level < 0 ) || ( level > R128_TEX_MAXLEVELS ) ) + if ( ( level < 0 ) || ( level > R128_MAX_TEXTURE_LEVELS ) ) return; image = t->tObj->Image[level]; @@ -694,7 +709,7 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, } #if 1 - /* FIXME: The subimage index calcs are wrong - who changed them? */ + /* FIXME: The subimage index calcs are wrong... */ x = 0; y = 0; width = image->Width; @@ -768,23 +783,17 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, dwords = width * height / texelsPerDword; offset = t->bufAddr + t->image[level].offset; - /* Fix offset for AGP textures */ - if ( t->heap == R128_AGP_TEX_HEAP ) { - offset += R128_AGP_TEX_OFFSET + r128ctx->r128Screen->agpTexOffset; - } - #if ENABLE_PERF_BOXES /* Bump the performace counter */ - r128ctx->c_textureBytes += (dwords << 2); + rmesa->c_textureBytes += (dwords << 2); #endif - if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "r128UploadSubImage: %d,%d of %d,%d at %d,%d\n", width, height, image->Width, image->Height, x, y ); fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d " "level: %d format: %x\n", - (int)offset, pitch, dwords, level, format ); + (GLuint)offset, (GLuint)pitch, dwords, level, format ); } /* Subdivide the texture if required */ @@ -803,11 +812,11 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, " blitting: %d,%d at %d,%d - %d dwords\n", - width, height, x, y, dwords ); + width, height, x, y, dwords ); } /* Grab the indirect buffer for the texture blit */ - buffer = r128GetBufferLocked( r128ctx ); + buffer = r128GetBufferLocked( rmesa ); dst = (CARD32 *)((char *)buffer->address + R128_HOSTDATA_BLIT_OFFSET); @@ -827,13 +836,13 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, break; } - r128FireBlitLocked( r128ctx, buffer, + r128FireBlitLocked( rmesa, buffer, offset, pitch, format, x, y, width, height ); } - r128ctx->new_state |= R128_NEW_CONTEXT; - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; } /* Upload the texture images associated with texture `t'. This might @@ -841,7 +850,7 @@ static void r128UploadSubImage( r128ContextPtr r128ctx, * make room for these images. */ /* NOTE: This function is only called while holding the hardware lock */ -int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) +int r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ) { int i; int minLevel; @@ -850,47 +859,47 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p, %p )\n", - __FUNCTION__, r128ctx->glCtx, t ); + __FUNCTION__, rmesa->glCtx, t ); } if ( !t ) return 0; /* Choose the heap appropriately */ - heap = t->heap = R128_LOCAL_TEX_HEAP; - if ( !r128ctx->r128Screen->IsPCI && - t->totalSize > r128ctx->r128Screen->texSize[heap] ) { - heap = t->heap = R128_AGP_TEX_HEAP; + heap = t->heap = R128_CARD_HEAP; + if ( !rmesa->r128Screen->IsPCI && + t->totalSize > rmesa->r128Screen->texSize[heap] ) { + heap = t->heap = R128_AGP_HEAP; } /* Do we need to eject LRU texture objects? */ if ( !t->memBlock ) { /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ - t->memBlock = mmAllocMem( r128ctx->texHeap[heap], t->totalSize, 12, 0 ); + t->memBlock = mmAllocMem( rmesa->texHeap[heap], t->totalSize, 12, 0 ); /* Try AGP before kicking anything out of local mem */ - if ( !t->memBlock && heap == R128_LOCAL_TEX_HEAP ) { - t->memBlock = mmAllocMem( r128ctx->texHeap[R128_AGP_TEX_HEAP], + if ( !t->memBlock && heap == R128_CARD_HEAP ) { + t->memBlock = mmAllocMem( rmesa->texHeap[R128_AGP_HEAP], t->totalSize, 12, 0 ); if ( t->memBlock ) - heap = t->heap = R128_AGP_TEX_HEAP; + heap = t->heap = R128_AGP_HEAP; } /* Kick out textures until the requested texture fits */ while ( !t->memBlock ) { - if ( r128ctx->TexObjList[heap].prev->bound ) { + if ( rmesa->TexObjList[heap].prev->bound ) { fprintf( stderr, "r128UploadTexImages: ran into bound texture\n" ); return -1; } - if ( r128ctx->TexObjList[heap].prev == &r128ctx->TexObjList[heap] ) { - if ( r128ctx->r128Screen->IsPCI ) { + if ( rmesa->TexObjList[heap].prev == &rmesa->TexObjList[heap] ) { + if ( rmesa->r128Screen->IsPCI ) { fprintf( stderr, "r128UploadTexImages: upload texture " "failure on local texture heaps, sz=%d\n", t->totalSize ); return -1; - } else if ( heap == R128_LOCAL_TEX_HEAP ) { - heap = t->heap = R128_AGP_TEX_HEAP; + } else if ( heap == R128_CARD_HEAP ) { + heap = t->heap = R128_AGP_HEAP; continue; } else { fprintf( stderr, "r128UploadTexImages: upload texture " @@ -901,14 +910,14 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) } } - r128DestroyTexObj( r128ctx, r128ctx->TexObjList[heap].prev ); + r128DestroyTexObj( rmesa, rmesa->TexObjList[heap].prev ); - t->memBlock = mmAllocMem( r128ctx->texHeap[heap], + t->memBlock = mmAllocMem( rmesa->texHeap[heap], t->totalSize, 12, 0 ); } /* Set the base offset of the texture image */ - t->bufAddr = r128ctx->r128Screen->texOffset[heap] + t->memBlock->ofs; + t->bufAddr = rmesa->r128Screen->texOffset[heap] + t->memBlock->ofs; maxLevel = ((t->setup.tex_size_pitch & R128_TEX_SIZE_MASK) >> R128_TEX_SIZE_SHIFT); @@ -917,7 +926,7 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) /* Set texture offsets */ if ( t->setup.tex_cntl & R128_MIP_MAP_DISABLE ) { - for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { t->setup.tex_offset[i] = t->bufAddr; } } else { @@ -926,22 +935,15 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) (t->image[maxLevel-i].offset + t->bufAddr); } } - /* Fix AGP texture offsets */ - if ( heap == R128_AGP_TEX_HEAP ) { - for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { - t->setup.tex_offset[i] += R128_AGP_TEX_OFFSET + - r128ctx->r128Screen->agpTexOffset; - } - } /* Force loading the new state into the hardware */ switch ( t->bound ) { case 1: - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX0; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX0; break; case 2: - r128ctx->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX1; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_TEX1; break; default: @@ -950,7 +952,7 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) } /* Let the world know we've used this memory recently */ - r128UpdateTexLRU( r128ctx, t ); + r128UpdateTexLRU( rmesa, t ); /* Upload any images that are new */ if ( t->dirty_images ) { @@ -961,14 +963,14 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) for ( i = 0 ; i <= num_levels ; i++ ) { if ( t->dirty_images & (1 << i) ) { - r128UploadSubImage( r128ctx, t, i, 0, 0, + r128UploadSubImage( rmesa, t, i, 0, 0, t->image[i].width, t->image[i].height ); } } - r128ctx->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + rmesa->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } t->dirty_images = 0; @@ -976,47 +978,50 @@ int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ) } -/* - * Texture combiners: +/* ================================================================ + * Texture combine functions */ -#define COLOR_COMB_DISABLE (R128_COMB_DIS | \ - R128_COLOR_FACTOR_TEX) -#define COLOR_COMB_COPY_INPUT (R128_COMB_COPY_INP | \ - R128_COLOR_FACTOR_TEX) -#define COLOR_COMB_MODULATE (R128_COMB_MODULATE | \ - R128_COLOR_FACTOR_TEX) -#define COLOR_COMB_MODULATE_NTEX (R128_COMB_MODULATE | \ - R128_COLOR_FACTOR_NTEX) -#define COLOR_COMB_ADD (R128_COMB_ADD | \ - R128_COLOR_FACTOR_TEX) -#define COLOR_COMB_BLEND_TEX (R128_COMB_BLEND_TEXTURE | \ - R128_COLOR_FACTOR_TEX) - -#define ALPHA_COMB_DISABLE (R128_COMB_ALPHA_DIS | \ - R128_ALPHA_FACTOR_TEX_ALPHA) -#define ALPHA_COMB_COPY_INPUT (R128_COMB_ALPHA_COPY_INP | \ - R128_ALPHA_FACTOR_TEX_ALPHA) -#define ALPHA_COMB_MODULATE (R128_COMB_ALPHA_MODULATE | \ - R128_ALPHA_FACTOR_TEX_ALPHA) -#define ALPHA_COMB_MODULATE_NTEX (R128_COMB_ALPHA_MODULATE | \ - R128_ALPHA_FACTOR_NTEX_ALPHA) -#define ALPHA_COMB_ADD (R128_COMB_ADD | \ - R128_ALPHA_FACTOR_TEX_ALPHA) - -#define INPUT_INTERP (R128_INPUT_FACTOR_INT_COLOR | \ - R128_INP_FACTOR_A_INT_ALPHA) -#define INPUT_PREVIOUS (R128_INPUT_FACTOR_PREV_COLOR | \ - R128_INP_FACTOR_A_PREV_ALPHA) - -static void r128UpdateTextureStage( GLcontext *ctx, int unit ) +#define COLOR_COMB_DISABLE (R128_COMB_DIS | \ + R128_COLOR_FACTOR_TEX) +#define COLOR_COMB_COPY_INPUT (R128_COMB_COPY_INP | \ + R128_COLOR_FACTOR_TEX) +#define COLOR_COMB_MODULATE (R128_COMB_MODULATE | \ + R128_COLOR_FACTOR_TEX) +#define COLOR_COMB_MODULATE_NTEX (R128_COMB_MODULATE | \ + R128_COLOR_FACTOR_NTEX) +#define COLOR_COMB_ADD (R128_COMB_ADD | \ + R128_COLOR_FACTOR_TEX) +#define COLOR_COMB_BLEND_TEX (R128_COMB_BLEND_TEXTURE | \ + R128_COLOR_FACTOR_TEX) +/* Rage 128 Pro/M3 only! */ +#define COLOR_COMB_BLEND_COLOR (R128_COMB_MODULATE2X | \ + R128_COMB_FCN_MSB | \ + R128_COLOR_FACTOR_CONST_COLOR) + +#define ALPHA_COMB_DISABLE (R128_COMB_ALPHA_DIS | \ + R128_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_COPY_INPUT (R128_COMB_ALPHA_COPY_INP | \ + R128_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_MODULATE (R128_COMB_ALPHA_MODULATE | \ + R128_ALPHA_FACTOR_TEX_ALPHA) +#define ALPHA_COMB_MODULATE_NTEX (R128_COMB_ALPHA_MODULATE | \ + R128_ALPHA_FACTOR_NTEX_ALPHA) +#define ALPHA_COMB_ADD (R128_COMB_ALPHA_ADD | \ + R128_ALPHA_FACTOR_TEX_ALPHA) + +#define INPUT_INTERP (R128_INPUT_FACTOR_INT_COLOR | \ + R128_INP_FACTOR_A_INT_ALPHA) +#define INPUT_PREVIOUS (R128_INPUT_FACTOR_PREV_COLOR | \ + R128_INP_FACTOR_A_PREV_ALPHA) + +static void r128UpdateTextureEnv( GLcontext *ctx, int unit ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int source = r128ctx->tmu_source[unit]; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLint source = rmesa->tmu_source[unit]; struct gl_texture_object *tObj; - r128TexObjPtr t; GLuint enabled; - CARD32 combine; + GLuint combine; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p, %d )\n", @@ -1038,9 +1043,6 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) return; - /* We definately have a valid texture now */ - t = tObj->DriverData; - if ( unit == 0 ) { combine = INPUT_INTERP; } else { @@ -1120,20 +1122,63 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) break; case GL_BLEND: - /* Catch the cases of GL_BLEND we can't handle (yet, in some cases). + /* Rage 128 Pro and M3 can handle GL_BLEND texturing. + */ + if ( !R128_IS_PLAIN( rmesa ) ) { + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-Ct)+CcCt */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; + + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-Ct)+CcCt */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; + + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; + + case GL_INTENSITY: + /* GH: We could be smarter about this... */ + switch ( rmesa->env_color & 0xff000000 ) { + case 0x00000000: + combine |= (COLOR_COMB_BLEND_COLOR | /* C = Cf(1-It)+CcIt */ + ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-It) */ + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + rmesa->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + break; + + case GL_COLOR_INDEX: + default: + return; + } + break; + } + + /* Rage 128 has to fake some cases of GL_BLEND, otherwise fallback + * to software rendering. */ - if ( r128ctx->blend_flags ) { - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + if ( rmesa->blend_flags ) { + rmesa->Fallback |= R128_FALLBACK_TEXTURE; } switch ( tObj->Image[0]->Format ) { case GL_RGBA: case GL_LUMINANCE_ALPHA: - switch ( r128ctx->env_color ) { + switch ( rmesa->env_color & 0x00ffffff ) { case 0x00000000: combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ ALPHA_COMB_MODULATE); /* A = AfAt */ break; - case 0xffffffff: + case 0x00ffffff: if ( unit == 0 ) { combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ ALPHA_COMB_MODULATE); /* A = AfAt */ @@ -1145,18 +1190,18 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_MODULATE); /* A = fallback */ - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; break; } break; case GL_RGB: case GL_LUMINANCE: - switch ( r128ctx->env_color ) { + switch ( rmesa->env_color & 0x00ffffff ) { case 0x00000000: combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ ALPHA_COMB_COPY_INPUT); /* A = Af */ break; - case 0xffffffff: + case 0x00ffffff: if ( unit == 0 ) { combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ ALPHA_COMB_COPY_INPUT); /* A = Af */ @@ -1168,42 +1213,52 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_COPY_INPUT); /* A = fallback */ - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; break; } break; case GL_ALPHA: - combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ - ALPHA_COMB_MODULATE); /* A = AfAt */ + if ( unit == 0 ) { + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + } else { + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + } break; case GL_INTENSITY: - switch ( r128ctx->env_color ) { + switch ( rmesa->env_color & 0x00ffffff ) { case 0x00000000: - combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ - ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ + combine |= COLOR_COMB_MODULATE_NTEX; /* C = Cf(1-It) */ break; case 0x00ffffff: if ( unit == 0 ) { - combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ - ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ + combine |= COLOR_COMB_MODULATE_NTEX; /* C = Cf(1-It) */ } else { - combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ - ALPHA_COMB_COPY_INPUT); /* A = Af */ + combine |= COLOR_COMB_ADD; /* C = Cf+It */ } break; - case 0xffffffff: + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + rmesa->Fallback |= R128_FALLBACK_TEXTURE; + break; + } + switch ( rmesa->env_color & 0xff000000 ) { + case 0x00000000: + combine |= ALPHA_COMB_MODULATE_NTEX; /* A = Af(1-It) */ + break; + case 0xff000000: if ( unit == 0 ) { - combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ - ALPHA_COMB_MODULATE_NTEX); /* A = Af(1-Ct) */ + combine |= ALPHA_COMB_MODULATE_NTEX; /* A = Af(1-It) */ } else { - combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ - ALPHA_COMB_ADD); /* A = Af+At */ + combine |= ALPHA_COMB_ADD; /* A = Af+It */ } break; default: combine |= (COLOR_COMB_MODULATE | /* C = fallback */ ALPHA_COMB_MODULATE); /* A = fallback */ - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; break; } break; @@ -1217,7 +1272,6 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) switch ( tObj->Image[0]->Format ) { case GL_RGBA: case GL_LUMINANCE_ALPHA: - case GL_INTENSITY: combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ ALPHA_COMB_MODULATE); /* A = AfAt */ break; @@ -1230,6 +1284,10 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ ALPHA_COMB_MODULATE); /* A = AfAt */ break; + case GL_INTENSITY: + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_ADD); /* A = Af+At */ + break; case GL_COLOR_INDEX: default: return; @@ -1240,13 +1298,13 @@ static void r128UpdateTextureStage( GLcontext *ctx, int unit ) return; } - t->setup.tex_combine_cntl = combine; + rmesa->tex_combine[unit] = combine; } static void r128UpdateTextureObject( GLcontext *ctx, int unit ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int source = r128ctx->tmu_source[unit]; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + int source = rmesa->tmu_source[unit]; struct gl_texture_object *tObj; r128TexObjPtr t; GLuint enabled; @@ -1256,14 +1314,10 @@ static void r128UpdateTextureObject( GLcontext *ctx, int unit ) __FUNCTION__, ctx, unit, ctx->Texture.ReallyEnabled ); } - /* Disable all texturing until it is known to be good */ - r128ctx->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE | - R128_SEC_TEXMAP_ENABLE); - enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) { if ( enabled ) - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; return; } @@ -1272,13 +1326,13 @@ static void r128UpdateTextureObject( GLcontext *ctx, int unit ) */ tObj = ctx->Texture.Unit[source].Current; if ( !tObj || !tObj->Complete ) { - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; return; } if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) { - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; return; } @@ -1286,13 +1340,13 @@ static void r128UpdateTextureObject( GLcontext *ctx, int unit ) /* If this is the first time the texture has been used, then create * a new texture object for it. */ - r128CreateTexObj( r128ctx, tObj ); + r128CreateTexObj( rmesa, tObj ); if ( !tObj->DriverData ) { /* Can't create a texture object... */ fprintf( stderr, "%s: texture object creation failed!\n", __FUNCTION__ ); - r128ctx->Fallback |= R128_FALLBACK_TEXTURE; + rmesa->Fallback |= R128_FALLBACK_TEXTURE; return; } } @@ -1301,39 +1355,37 @@ static void r128UpdateTextureObject( GLcontext *ctx, int unit ) t = tObj->DriverData; /* Force the texture unit state to be loaded into the hardware */ - r128ctx->dirty |= R128_UPLOAD_CONTEXT | (R128_UPLOAD_TEX0 << unit); + rmesa->dirty |= R128_UPLOAD_CONTEXT | (R128_UPLOAD_TEX0 << unit); /* Force any texture images to be loaded into the hardware */ if ( t->dirty_images ) - r128ctx->dirty |= (R128_UPLOAD_TEX0IMAGES << unit); + rmesa->dirty |= (R128_UPLOAD_TEX0IMAGES << unit); /* Bind to the given texture unit */ - r128ctx->CurrentTexObj[unit] = t; - t->bound = unit + 1; + rmesa->CurrentTexObj[unit] = t; + t->bound |= unit + 1; if ( t->memBlock ) - r128UpdateTexLRU( r128ctx, t ); + r128UpdateTexLRU( rmesa, t ); if ( unit == 0 ) { - r128ctx->setup.tex_cntl_c |= R128_TEXMAP_ENABLE; - r128ctx->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0; - r128ctx->setup.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT; + rmesa->setup.tex_cntl_c |= R128_TEXMAP_ENABLE; + rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 0; + rmesa->setup.scale_3d_cntl &= ~R128_TEX_CACHE_SPLIT; t->setup.tex_cntl &= ~R128_SEC_SELECT_SEC_ST; } else { t->setup.tex_cntl |= R128_SEC_SELECT_SEC_ST; - r128ctx->setup.tex_cntl_c |= (R128_TEXMAP_ENABLE | - R128_SEC_TEXMAP_ENABLE) ; - r128ctx->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16; - r128ctx->setup.scale_3d_cntl |= R128_TEX_CACHE_SPLIT; + rmesa->setup.tex_cntl_c |= R128_SEC_TEXMAP_ENABLE; + rmesa->setup.tex_size_pitch_c |= t->setup.tex_size_pitch << 16; + rmesa->setup.scale_3d_cntl |= R128_TEX_CACHE_SPLIT; } } -/* Update the hardware texture state */ void r128UpdateTextureState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %p ) en=0x%x\n", @@ -1341,112 +1393,47 @@ void r128UpdateTextureState( GLcontext *ctx ) } /* Clear any texturing fallbacks */ - r128ctx->Fallback &= ~R128_FALLBACK_TEXTURE; + rmesa->Fallback &= ~R128_FALLBACK_TEXTURE; - /* Unbind any currently bound textures */ - if ( r128ctx->CurrentTexObj[0] ) r128ctx->CurrentTexObj[0]->bound = 0; - if ( r128ctx->CurrentTexObj[1] ) r128ctx->CurrentTexObj[1]->bound = 0; - r128ctx->CurrentTexObj[0] = NULL; - r128ctx->CurrentTexObj[1] = NULL; + /* Unbind any currently bound textures */ + if ( rmesa->CurrentTexObj[0] ) rmesa->CurrentTexObj[0]->bound = 0; + if ( rmesa->CurrentTexObj[1] ) rmesa->CurrentTexObj[1]->bound = 0; + rmesa->CurrentTexObj[0] = NULL; + rmesa->CurrentTexObj[1] = NULL; - r128ctx->setup.tex_size_pitch_c = 0x00000000; + if ( ctx->Enabled & (TEXTURE0_3D|TEXTURE1_3D) ) + rmesa->Fallback |= R128_FALLBACK_TEXTURE; + + /* Disable all texturing until it is known to be good */ + rmesa->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE | + R128_SEC_TEXMAP_ENABLE); + rmesa->setup.tex_size_pitch_c = 0x00000000; r128UpdateTextureObject( ctx, 0 ); - r128UpdateTextureStage( ctx, 0 ); + r128UpdateTextureEnv( ctx, 0 ); - if ( r128ctx->multitex ) { + if ( rmesa->multitex ) { r128UpdateTextureObject( ctx, 1 ); - r128UpdateTextureStage( ctx, 1 ); + r128UpdateTextureEnv( ctx, 1 ); } - r128ctx->dirty |= R128_UPLOAD_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; } -/* Set the texture wrap mode */ -static void r128SetTexWrap( r128TexObjPtr t, GLenum swrap, GLenum twrap ) -{ - t->setup.tex_cntl &= ~(R128_TEX_CLAMP_S_MASK | R128_TEX_CLAMP_T_MASK); - - switch ( swrap ) { - case GL_CLAMP: - t->setup.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; - break; - case GL_REPEAT: - t->setup.tex_cntl |= R128_TEX_CLAMP_S_WRAP; - break; - } - - switch ( twrap ) { - case GL_CLAMP: - t->setup.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; - break; - case GL_REPEAT: - t->setup.tex_cntl |= R128_TEX_CLAMP_T_WRAP; - break; - } -} - -/* Set the texture filter mode */ -static void r128SetTexFilter( r128TexObjPtr t, GLenum minf, GLenum magf ) -{ - t->setup.tex_cntl &= ~(R128_MIN_BLEND_MASK | R128_MAG_BLEND_MASK); - - switch ( minf ) { - case GL_NEAREST: - t->setup.tex_cntl |= R128_MIN_BLEND_NEAREST; - break; - case GL_LINEAR: - t->setup.tex_cntl |= R128_MIN_BLEND_LINEAR; - break; - case GL_NEAREST_MIPMAP_NEAREST: - t->setup.tex_cntl |= R128_MIN_BLEND_MIPNEAREST; - break; - case GL_LINEAR_MIPMAP_NEAREST: - t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST; - break; - case GL_NEAREST_MIPMAP_LINEAR: - t->setup.tex_cntl |= R128_MIN_BLEND_MIPLINEAR; - break; - case GL_LINEAR_MIPMAP_LINEAR: - t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPLINEAR; - break; - } - - switch ( magf ) { - case GL_NEAREST: - t->setup.tex_cntl |= R128_MAG_BLEND_NEAREST; - break; - case GL_LINEAR: - t->setup.tex_cntl |= R128_MAG_BLEND_LINEAR; - break; - } -} - -/* Set the texture border color */ -static void r128SetTexBorderColor( r128TexObjPtr t, GLubyte c[4] ) -{ - t->setup.tex_border_color = r128PackColor( 32, c[0], c[1], c[2], c[3] ); -} - - -/* -============================================================================ - -Driver functions called directly from mesa - -============================================================================ -*/ - +/* ================================================================ + * DD interface texturing functions + * + * FIXME: Many of these are deprecated -- we should move to the new + * single-copy texture interface. + */ -/* Set the texture environment state */ static void r128DDTexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); struct gl_texture_unit *texUnit; GLubyte c[4]; - int bias; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { fprintf( stderr, "%s( %s )\n", @@ -1455,59 +1442,71 @@ static void r128DDTexEnv( GLcontext *ctx, GLenum target, switch ( pname ) { case GL_TEXTURE_ENV_MODE: - /* TexEnv modes are handled in UpdateTextureState */ - FLUSH_BATCH( r128ctx ); - r128ctx->new_state |= R128_NEW_TEXTURE | R128_NEW_ALPHA; + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_TEXTURE | R128_NEW_ALPHA; break; case GL_TEXTURE_ENV_COLOR: texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; FLOAT_RGBA_TO_UBYTE_RGBA( c, texUnit->EnvColor ); - r128ctx->env_color = r128PackColor( 32, c[0], c[1], c[2], c[3] ); - if ( r128ctx->setup.constant_color_c != r128ctx->env_color ) { - FLUSH_BATCH( r128ctx ); - r128ctx->setup.constant_color_c = r128ctx->env_color; + rmesa->env_color = r128PackColor( 4, c[0], c[1], c[2], c[3] ); + if ( rmesa->setup.constant_color_c != rmesa->env_color ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.constant_color_c = rmesa->env_color; - r128ctx->new_state |= R128_NEW_TEXTURE; + rmesa->new_state |= R128_NEW_TEXTURE; /* More complex multitexture/multipass fallbacks for GL_BLEND * can be done later, but this allows a single pass GL_BLEND - * in some cases (ie. Performer town demo). + * in some cases (ie. Performer town demo). This is only + * applicable to the regular Rage 128, as the Pro and M3 can + * handle true single-pass GL_BLEND texturing. */ - r128ctx->blend_flags &= ~R128_BLEND_ENV_COLOR; - if ( r128ctx->env_color != 0x00000000 && - r128ctx->env_color != 0xff000000 /*&& - r128ctx->env_color != 0x00ffffff && - r128ctx->env_color != 0xffffffff */ ) { - r128ctx->blend_flags |= R128_BLEND_ENV_COLOR; + rmesa->blend_flags &= ~R128_BLEND_ENV_COLOR; + if ( R128_IS_PLAIN( rmesa ) && + rmesa->env_color != 0x00000000 && + rmesa->env_color != 0xff000000 && + rmesa->env_color != 0x00ffffff && + rmesa->env_color != 0xffffffff ) { + rmesa->blend_flags |= R128_BLEND_ENV_COLOR; } } break; case GL_TEXTURE_LOD_BIAS_EXT: - /* GTH: This isn't exactly correct, but gives good results up to a - * certain point. It is better than completely ignoring the LOD - * bias. Unfortunately there isn't much range in the bias, the - * spec mentions strides that vary between 0.5 and 2.0 but these - * numbers don't seem to relate the the GL LOD bias value at all. - */ - if ( param[0] >= 1.0 ) { - bias = -128; - } else if ( param[0] >= 0.5 ) { - bias = -64; - } else if ( param[0] >= 0.25 ) { - bias = 0; - } else if ( param[0] >= 0.0 ) { - bias = 63; - } else { - bias = 127; - } - if ( r128ctx->lod_bias != bias ) { - FLUSH_BATCH( r128ctx ); - r128ctx->lod_bias = bias; + do { + CARD32 t = rmesa->setup.tex_cntl_c; + GLint bias; + CARD32 b; + + /* GTH: This isn't exactly correct, but gives good results up to a + * certain point. It is better than completely ignoring the LOD + * bias. Unfortunately there isn't much range in the bias, the + * spec mentions strides that vary between 0.5 and 2.0 but these + * numbers don't seem to relate the the GL LOD bias value at all. + */ + if ( param[0] >= 1.0 ) { + bias = -128; + } else if ( param[0] >= 0.5 ) { + bias = -64; + } else if ( param[0] >= 0.25 ) { + bias = 0; + } else if ( param[0] >= 0.0 ) { + bias = 63; + } else { + bias = 127; + } - r128ctx->new_state |= R128_NEW_RENDER; - } + b = (CARD32)bias & 0xff; + t &= ~R128_LOD_BIAS_MASK; + t |= (b << R128_LOD_BIAS_SHIFT); + + if ( rmesa->setup.tex_cntl_c != t ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + } + } while (0); break; default: @@ -1515,35 +1514,37 @@ static void r128DDTexEnv( GLcontext *ctx, GLenum target, } } -/* Upload a new texture image */ static void r128DDTexImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint internalFormat, const struct gl_texture_image *image ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); r128TexObjPtr t; if ( R128_DEBUG & DEBUG_VERBOSE_API ) fprintf( stderr, "%s( %p, level %d )\n", __FUNCTION__, tObj, level ); - if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; - if ( level >= R128_TEX_MAXLEVELS ) return; + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + if ( level >= R128_MAX_TEXTURE_LEVELS ) + return; t = (r128TexObjPtr)tObj->DriverData; if ( t ) { - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); /* Destroy the old texture, and upload a new one. The actual * uploading of the texture image occurs in the UploadSubImage * function. */ - r128DestroyTexObj( r128ctx, t ); - r128ctx->new_state |= R128_NEW_TEXTURE; + r128DestroyTexObj( rmesa, t ); + rmesa->new_state |= R128_NEW_TEXTURE; } } -/* Upload a new texture sub-image */ static void r128DDTexSubImage( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLint level, GLint xoffset, GLint yoffset, @@ -1551,7 +1552,7 @@ static void r128DDTexSubImage( GLcontext *ctx, GLenum target, GLint internalFormat, const struct gl_texture_image *image ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); r128TexObjPtr t; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { @@ -1560,31 +1561,34 @@ static void r128DDTexSubImage( GLcontext *ctx, GLenum target, image->Width, image->Height ); } - if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; - if ( level >= R128_TEX_MAXLEVELS ) return; + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + if ( level >= R128_MAX_TEXTURE_LEVELS ) + return; t = (r128TexObjPtr)tObj->DriverData; if ( t ) { - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); - LOCK_HARDWARE( r128ctx ); - r128UploadSubImage( r128ctx, t, level, + LOCK_HARDWARE( rmesa ); + r128UploadSubImage( rmesa, t, level, xoffset, yoffset, width, height ); - UNLOCK_HARDWARE( r128ctx ); + UNLOCK_HARDWARE( rmesa ); /* Update the context state */ - r128ctx->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + rmesa->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; - r128ctx->new_state |= R128_NEW_TEXTURE; + rmesa->new_state |= R128_NEW_TEXTURE; } } -/* Set the texture parameter state */ static void r128DDTexParameter( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj, GLenum pname, const GLfloat *params ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { @@ -1592,24 +1596,32 @@ static void r128DDTexParameter( GLcontext *ctx, GLenum target, __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); } - if ( !t || !t->bound ) return; - if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) return; + /* If we don't have a hardware texture, it will be automatically + * created with current state before it is used, so we don't have + * to do anything now. + */ + if ( !t || !t->bound ) + return; + + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; switch ( pname ) { case GL_TEXTURE_MIN_FILTER: case GL_TEXTURE_MAG_FILTER: - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); r128SetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); break; case GL_TEXTURE_WRAP_S: case GL_TEXTURE_WRAP_T: - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); r128SetTexWrap( t, tObj->WrapS, tObj->WrapT ); break; case GL_TEXTURE_BORDER_COLOR: - if ( t->bound ) FLUSH_BATCH( r128ctx ); + if ( t->bound ) FLUSH_BATCH( rmesa ); r128SetTexBorderColor( t, tObj->BorderColor ); break; @@ -1617,14 +1629,13 @@ static void r128DDTexParameter( GLcontext *ctx, GLenum target, return; } - r128ctx->new_state |= R128_NEW_TEXTURE; + rmesa->new_state |= R128_NEW_TEXTURE; } -/* Bind a texture to the currently active texture unit */ static void r128DDBindTexture( GLcontext *ctx, GLenum target, struct gl_texture_object *tObj ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); GLint unit = ctx->Texture.CurrentUnit; if ( R128_DEBUG & DEBUG_VERBOSE_API ) { @@ -1632,50 +1643,46 @@ static void r128DDBindTexture( GLcontext *ctx, GLenum target, __FUNCTION__, tObj, unit ); } - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - /* Unbind the old texture */ - if ( r128ctx->CurrentTexObj[unit] ) { - r128ctx->CurrentTexObj[unit]->bound &= ~(unit+1); - r128ctx->CurrentTexObj[unit] = NULL; + if ( rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit]->bound &= ~(unit+1); + rmesa->CurrentTexObj[unit] = NULL; } - /* The actualy binding occurs in the Tex[01]UpdateState function */ - r128ctx->new_state |= R128_NEW_TEXTURE; + rmesa->new_state |= R128_NEW_TEXTURE; } -/* Remove texture from AGP/local texture memory */ static void r128DDDeleteTexture( GLcontext *ctx, struct gl_texture_object *tObj ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; if ( t ) { if ( t->bound ) { - FLUSH_BATCH( r128ctx ); + FLUSH_BATCH( rmesa ); - r128ctx->CurrentTexObj[t->bound-1] = 0; - r128ctx->new_state |= R128_NEW_TEXTURE; + if ( t->bound & TEX_0 ) rmesa->CurrentTexObj[0] = NULL; + if ( t->bound & TEX_1 ) rmesa->CurrentTexObj[1] = NULL; + rmesa->new_state |= R128_NEW_TEXTURE; } - r128DestroyTexObj( r128ctx, t ); + r128DestroyTexObj( rmesa, t ); tObj->DriverData = NULL; } } -/* Determine if a texture is currently residing in either AGP/local - * texture memory. - */ static GLboolean r128DDIsTextureResident( GLcontext *ctx, struct gl_texture_object *tObj ) { r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; - return t && t->memBlock; + return ( t && t->memBlock ); } -/* Initialize the driver's texture functions */ + + void r128DDInitTextureFuncs( GLcontext *ctx ) { ctx->Driver.TexEnv = r128DDTexEnv; diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h index fbe39b8c0..e1f67a56d 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.h,v 1.3 2000/12/12 17:17:08 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.h,v 1.4 2001/01/08 01:07:23 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,58 +28,65 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_TEX_H_ -#define _R128_TEX_H_ +#ifndef __R128_TEX_H__ +#define __R128_TEX_H__ #ifdef GLX_DIRECT_RENDERING extern void r128UpdateTextureState( GLcontext *ctx ); -extern int r128UploadTexImages( r128ContextPtr r128ctx, r128TexObjPtr t ); +extern int r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ); -extern void r128AgeTextures( r128ContextPtr r128ctx, int heap ); -extern void r128DestroyTexObj( r128ContextPtr r128ctx, r128TexObjPtr t ); +extern void r128AgeTextures( r128ContextPtr rmesa, int heap ); +extern void r128DestroyTexObj( r128ContextPtr rmesa, r128TexObjPtr t ); -extern void r128PrintLocalLRU( r128ContextPtr r128ctx, int heap ); -extern void r128PrintGlobalLRU( r128ContextPtr r128ctx, int heap ); +extern void r128PrintLocalLRU( r128ContextPtr rmesa, int heap ); +extern void r128PrintGlobalLRU( r128ContextPtr rmesa, int heap ); extern void r128DDInitTextureFuncs( GLcontext *ctx ); -#define R128PACKCOLOR332(r, g, b) \ - (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) +/* ================================================================ + * Color conversion macros: + */ + +#define R128PACKCOLOR332( r, g, b ) \ + (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) -#define R128PACKCOLOR1555(r, g, b, a) \ - ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ - ((a) ? 0x8000 : 0)) +#define R128PACKCOLOR1555( r, g, b, a ) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) -#define R128PACKCOLOR565(r, g, b) \ - ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) +#define R128PACKCOLOR565( r, g, b ) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) -#define R128PACKCOLOR888(r, g, b) \ - (((r) << 16) | ((g) << 8) | (b)) +#define R128PACKCOLOR888( r, g, b ) \ + (((r) << 16) | ((g) << 8) | (b)) -#define R128PACKCOLOR8888(r, g, b, a) \ - (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) +#define R128PACKCOLOR8888( r, g, b, a ) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) -#define R128PACKCOLOR4444(r, g, b, a) \ - ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) +#define R128PACKCOLOR4444( r, g, b, a ) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) -static __inline__ CARD32 r128PackColor( GLuint bpp, +static __inline__ CARD32 r128PackColor( GLuint cpp, GLubyte r, GLubyte g, GLubyte b, GLubyte a ) { - switch ( bpp ) { - case 16: return R128PACKCOLOR565( r, g, b ); - case 32: return R128PACKCOLOR8888( r, g, b, a ); - default: return 0; + switch ( cpp ) { + case 2: + return R128PACKCOLOR565( r, g, b ); + case 4: + return R128PACKCOLOR8888( r, g, b, a ); + default: + return 0; } } #endif -#endif /* _R128_TEX_H_ */ +#endif /* __R128_TEX_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h index 59b568321..9939c219b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_texobj.h,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_texobj.h,v 1.4 2001/01/08 01:07:24 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -39,44 +39,45 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. #include "r128_sarea.h" #include "mm.h" -/* Individual texture image information */ +/* Individual texture image information. + */ typedef struct { - GLuint offset; /* Offset into locally shared texture space (i.e., - relative to bufAddr (below) */ - GLuint width; /* Width of texture image */ - GLuint height; /* Height of texture image */ + GLuint offset; /* Relative to local texture space */ + GLuint width; + GLuint height; } r128TexImage; typedef struct r128_tex_obj r128TexObj, *r128TexObjPtr; -/* Texture object in locally shared texture space */ +/* Texture object in locally shared texture space. + */ struct r128_tex_obj { - r128TexObjPtr next, prev; + r128TexObjPtr next, prev; struct gl_texture_object *tObj; /* Mesa texture object */ - PMemBlock memBlock; /* Memory block containing texture */ - CARD32 bufAddr; /* Offset to start of locally + PMemBlock memBlock; /* Memory block containing texture */ + CARD32 bufAddr; /* Offset to start of locally shared texture block */ - CARD32 dirty_images; /* Flags for whether or not + CARD32 dirty_images; /* Flags for whether or not images need to be uploaded to local or AGP texture space */ - GLuint age; - GLint bound; /* Texture unit currently bound to */ - GLint heap; /* Texture heap currently stored in */ - r128TexImage image[R128_TEX_MAXLEVELS]; /* Image data for all - mipmap levels */ + GLuint age; + GLint bound; /* Texture unit currently bound to */ + GLint heap; /* Texture heap currently stored in */ + r128TexImage image[R128_MAX_TEXTURE_LEVELS]; /* Image data for all + mipmap levels */ - GLint totalSize; /* Total size of the texture + GLint totalSize; /* Total size of the texture including all mipmap levels */ - GLuint internFormat; /* Internal GL format used to store + GLuint internFormat; /* Internal GL format used to store texture on card */ - CARD32 textureFormat; /* Actual hardware format */ - GLint texelBytes; /* Number of bytes per texel */ + CARD32 textureFormat; /* Actual hardware format */ + GLint texelBytes; /* Number of bytes per texel */ - r128_texture_regs_t setup; /* Setup regs for texture */ + r128_texture_regs_t setup; /* Setup regs for texture */ }; #endif /* _R128_TEXOBJ_H_ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c index 8d1053e90..4d83e27e0 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ /* -*- c-basic-offset: 3 -*- */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.4 2001/01/08 01:07:24 martin Exp $ */ /* -*- c-basic-offset: 3 -*- */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -49,25 +49,28 @@ static struct { quad_func quad; } rast_tab[R128_MAX_TRIFUNC]; -#define R128_COLOR(to, from) \ -do { \ - (to)[0] = (from)[2]; \ - (to)[1] = (from)[1]; \ - (to)[2] = (from)[0]; \ - (to)[3] = (from)[3]; \ +#define R128_COLOR( to, from ) \ +do { \ + (to)[0] = (from)[2]; \ + (to)[1] = (from)[1]; \ + (to)[2] = (from)[0]; \ + (to)[3] = (from)[3]; \ } while (0) static void r128_null_quad( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint v3, GLuint pv ) { + GLuint v1, GLuint v2, GLuint v3, GLuint pv ) +{ } static void r128_null_triangle( GLcontext *ctx, GLuint v0, - GLuint v1, GLuint v2, GLuint pv ) { + GLuint v1, GLuint v2, GLuint pv ) +{ } -static void r128_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) { +static void r128_null_line( GLcontext *ctx, GLuint v1, GLuint v2, GLuint pv ) +{ } - -static void r128_null_points( GLcontext *ctx, GLuint first, GLuint last ) { +static void r128_null_points( GLcontext *ctx, GLuint first, GLuint last ) +{ } static void r128PrintRenderState( const char *msg, GLuint state ) @@ -114,10 +117,9 @@ static void r128PrintRenderState( const char *msg, GLuint state ) #include "r128_tritmp.h" -/* Initialize the table of points, line and triangle drawing functions */ void r128DDTriangleFuncsInit( void ) { - int i; + GLint i; init(); init_flat(); @@ -128,12 +130,12 @@ void r128DDTriangleFuncsInit( void ) init_twoside_offset(); init_twoside_offset_flat(); - for ( i = 0 ; i < 0x20 ; i++ ) { - if ( (i & (R128_NODRAW_BIT | R128_FALLBACK_BIT)) == R128_NODRAW_BIT ) { - rast_tab[i].points = r128_null_points; - rast_tab[i].line = r128_null_line; - rast_tab[i].triangle = r128_null_triangle; - rast_tab[i].quad = r128_null_quad; + for ( i = 0 ; i < R128_MAX_TRIFUNC ; i++ ) { + if ( i & R128_NODRAW_BIT ) { + rast_tab[i].points = r128_null_points; + rast_tab[i].line = r128_null_line; + rast_tab[i].triangle = r128_null_triangle; + rast_tab[i].quad = r128_null_quad; } } } @@ -147,7 +149,7 @@ void r128DDTriangleFuncsInit( void ) #define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE) #define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_STIPPLE | DD_TRI_UNFILLED) #define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) -#define ANY_RASTER_FLAGS (/*DD_FLATSHADE |*/ DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_Z_NEVER) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_Z_NEVER) /* Setup the Point, Line, Triangle and Quad functions based on the * current rendering state. Wherever possible, use the hardware to @@ -155,12 +157,12 @@ void r128DDTriangleFuncsInit( void ) */ void r128DDChooseRenderState( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); + r128ContextPtr rmesa = R128_CONTEXT(ctx); GLuint flags = ctx->TriangleCaps; - CARD32 index = 0; + GLuint index = 0; - if ( r128ctx->Fallback ) { - r128ctx->RenderIndex = R128_FALLBACK_BIT; + if ( rmesa->Fallback ) { + rmesa->RenderIndex = R128_FALLBACK_BIT; return; } @@ -171,37 +173,38 @@ void r128DDChooseRenderState( GLcontext *ctx ) if ( flags & DD_Z_NEVER ) index |= R128_NODRAW_BIT; } - r128ctx->PointsFunc = rast_tab[index].points; - r128ctx->LineFunc = rast_tab[index].line; - r128ctx->TriangleFunc = rast_tab[index].triangle; - r128ctx->QuadFunc = rast_tab[index].quad; + rmesa->PointsFunc = rast_tab[index].points; + rmesa->LineFunc = rast_tab[index].line; + rmesa->TriangleFunc = rast_tab[index].triangle; + rmesa->QuadFunc = rast_tab[index].quad; - r128ctx->RenderIndex = index; - r128ctx->IndirectTriangles = 0; + rmesa->RenderIndex = index; + rmesa->IndirectTriangles = 0; if ( flags & ANY_FALLBACK ) { - r128ctx->RenderIndex |= R128_FALLBACK_BIT; - if ( flags & POINT_FALLBACK ) { - r128ctx->PointsFunc = 0; - r128ctx->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + rmesa->RenderIndex |= R128_FALLBACK_BIT; + rmesa->PointsFunc = 0; + rmesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE; } if ( flags & LINE_FALLBACK ) { - r128ctx->LineFunc = 0; - r128ctx->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + rmesa->RenderIndex |= R128_FALLBACK_BIT; + rmesa->LineFunc = 0; + rmesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; } if ( flags & TRI_FALLBACK ) { - r128ctx->TriangleFunc = 0; - r128ctx->QuadFunc = 0; - r128ctx->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | - DD_QUAD_SW_RASTERIZE); + rmesa->RenderIndex |= R128_FALLBACK_BIT; + rmesa->TriangleFunc = 0; + rmesa->QuadFunc = 0; + rmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | + DD_QUAD_SW_RASTERIZE); } } if ( 0 ) { gl_print_tri_caps( "tricaps", ctx->TriangleCaps ); - r128PrintRenderState( "r128 render state", r128ctx->RenderIndex ); + r128PrintRenderState( "r128 render state", rmesa->RenderIndex ); } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h index 364aa02c9..79b3fb69e 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.3 2000/12/04 19:21:47 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.4 2001/01/08 01:07:24 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,22 +28,21 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_TRIS_H_ -#define _R128_TRIS_H_ +#ifndef __R128_TRIS_H__ +#define __R128_TRIS_H__ #ifdef GLX_DIRECT_RENDERING #include "r128_vb.h" -extern void r128DDChooseRenderState(GLcontext *ctx); -extern void r128DDTriangleFuncsInit(void); +extern void r128DDChooseRenderState( GLcontext *ctx ); +extern void r128DDTriangleFuncsInit( void ); -#define R128_ANTIALIAS_BIT 0x00 /* Ignored for now */ #define R128_FLAT_BIT 0x01 #define R128_OFFSET_BIT 0x02 #define R128_TWOSIDE_BIT 0x04 @@ -51,18 +50,18 @@ extern void r128DDTriangleFuncsInit(void); #define R128_FALLBACK_BIT 0x10 #define R128_MAX_TRIFUNC 0x20 -/* Draw a triangle from the vertices in the vertex buffer */ -static __inline void r128_draw_triangle( r128ContextPtr r128ctx, - r128Vertex *v0, - r128Vertex *v1, - r128Vertex *v2 ) + +static __inline void r128_draw_triangle( r128ContextPtr rmesa, + r128VertexPtr v0, + r128VertexPtr v1, + r128VertexPtr v2 ) { - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 3 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 3 ); int j; #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of + /* GH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is * automagically updated with this instruction, so we don't have * to manually take care of incrementing it. @@ -93,19 +92,18 @@ static __inline void r128_draw_triangle( r128ContextPtr r128ctx, #endif } -/* Draw a quad from the vertices in the vertex buffer */ -static __inline void r128_draw_quad( r128ContextPtr r128ctx, - r128Vertex *v0, - r128Vertex *v1, - r128Vertex *v2, - r128Vertex *v3 ) +static __inline void r128_draw_quad( r128ContextPtr rmesa, + r128VertexPtr v0, + r128VertexPtr v1, + r128VertexPtr v2, + r128VertexPtr v3 ) { - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 6 ); int j; #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of + /* GH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is * automagically updated with this instruction, so we don't have * to manually take care of incrementing it. @@ -160,15 +158,14 @@ static __inline void r128_draw_quad( r128ContextPtr r128ctx, #endif } -/* Draw a line from the vertices in the vertex buffer */ -static __inline void r128_draw_line( r128ContextPtr r128ctx, - r128Vertex *tmp0, - r128Vertex *tmp1, +static __inline void r128_draw_line( r128ContextPtr rmesa, + r128VertexPtr tmp0, + r128VertexPtr tmp1, float width ) { #if 1 - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 6 ); float dx, dy, ix, iy; int j; @@ -221,12 +218,12 @@ static __inline void r128_draw_line( r128ContextPtr r128ctx, #else - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 2 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 2 ); int j; #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of + /* GH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is * automagically updated with this instruction, so we don't have * to manually take care of incrementing it. @@ -250,13 +247,12 @@ static __inline void r128_draw_line( r128ContextPtr r128ctx, #endif } -/* Draw a point from the vertices in the vertex buffer */ -static __inline void r128_draw_point( r128ContextPtr r128ctx, - r128Vertex *tmp, float sz ) +static __inline void r128_draw_point( r128ContextPtr rmesa, + r128VertexPtr tmp, float sz ) { #if 1 - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 6 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 6 ); int j; *(float *)&vb[0] = tmp->v.x - sz; @@ -295,12 +291,12 @@ static __inline void r128_draw_point( r128ContextPtr r128ctx, vb[j] = tmp->ui[j]; #else - int vertsize = r128ctx->vertsize; - CARD32 *vb = r128AllocVerticesInline( r128ctx, 1 ); + int vertsize = rmesa->vertsize; + CARD32 *vb = r128AllocVerticesInline( rmesa, 1 ); int j; #if defined (USE_X86_ASM) - /* GTH: We can safely assume the vertex stride is some number of + /* GH: We can safely assume the vertex stride is some number of * dwords, and thus a "rep movsd" is okay. The vb pointer is * automagically updated with this instruction, so we don't have * to manually take care of incrementing it. @@ -317,4 +313,4 @@ static __inline void r128_draw_point( r128ContextPtr r128ctx, } #endif -#endif /* _R128_TRIS_H_ */ +#endif /* __R128_TRIS_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h index d448493d0..a9ca8d1bc 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h,v 1.4 2000/12/04 22:46:01 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h,v 1.5 2001/01/08 01:07:24 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,38 +28,31 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#if !defined(TAG) || !defined(IND) -this is an error -#endif - -/* Draw a single triangle. Note that the device-dependent vertex data - might need to be changed based on the render state. */ static __inline void TAG(triangle)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2, GLuint pv ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); struct vertex_buffer *VB = ctx->VB; - r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; - r128Vertex *v[3]; + r128VertexPtr verts = R128_DRIVER_DATA(VB)->verts; + r128VertexPtr v[3]; #if (IND & R128_OFFSET_BIT) GLfloat offset; GLfloat z[3]; #endif - #if (IND & R128_TWOSIDE_BIT) GLuint c[3]; #endif - v[0] = &r128verts[e0]; - v[1] = &r128verts[e1]; - v[2] = &r128verts[e2]; + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; #if (IND & R128_TWOSIDE_BIT) c[0] = v[0]->ui[4]; @@ -73,13 +66,13 @@ static __inline void TAG(triangle)( GLcontext *ctx, GLfloat ey = v[0]->v.y - v[2]->v.y; GLfloat fx = v[1]->v.x - v[2]->v.x; GLfloat fy = v[1]->v.y - v[2]->v.y; - GLfloat cc = ex*fy - ey*fx; + GLfloat cc = ex*fy - ey*fx; #if (IND & R128_TWOSIDE_BIT) { - GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; + GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit; GLubyte (*vbcolor)[4] = VB->Color[facing]->data; - if (IND & R128_FLAT_BIT) { + if ( IND & R128_FLAT_BIT ) { R128_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; } else { @@ -92,21 +85,21 @@ static __inline void TAG(triangle)( GLcontext *ctx, #if (IND & R128_OFFSET_BIT) { - offset = ctx->Polygon.OffsetUnits * r128ctx->depth_scale; + offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale; z[0] = v[0]->v.z; z[1] = v[1]->v.z; z[2] = v[2]->v.z; - if (cc * cc > 1e-16) { - GLfloat ez = z[0] - z[2]; - GLfloat fz = z[1] - z[2]; - GLfloat a = ey*fz - ez*fy; - GLfloat b = ez*fx - ex*fz; - GLfloat ic = 1.0 / cc; - GLfloat ac = a * ic; - GLfloat bc = b * ic; - if (ac < 0.0f) ac = -ac; - if (bc < 0.0f) bc = -bc; - offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; + if ( cc * cc > 1e-16 ) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; } v[0]->v.z += offset; v[1]->v.z += offset; @@ -116,7 +109,7 @@ static __inline void TAG(triangle)( GLcontext *ctx, } #endif - r128_draw_triangle( r128ctx, v[0], v[1], v[2] ); + r128_draw_triangle( rmesa, v[0], v[1], v[2] ); #if (IND & R128_OFFSET_BIT) v[0]->v.z = z[0]; @@ -140,24 +133,23 @@ static void TAG(quad)( GLcontext *ctx, TAG(triangle)( ctx, e0, e1, e3, pv ); TAG(triangle)( ctx, e1, e2, e3, pv ); #else - r128ContextPtr r128ctx = R128_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); struct vertex_buffer *VB = ctx->VB; - r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; - r128Vertex *v[4]; + r128VertexPtr verts = R128_DRIVER_DATA(VB)->verts; + r128VertexPtr v[4]; #if (IND & R128_OFFSET_BIT) GLfloat offset; GLfloat z[4]; #endif - #if (IND & R128_TWOSIDE_BIT) int c[4]; #endif - v[0] = &r128verts[e0]; - v[1] = &r128verts[e1]; - v[2] = &r128verts[e2]; - v[3] = &r128verts[e3]; + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; + v[3] = &verts[e3]; #if (IND & R128_TWOSIDE_BIT) c[0] = v[0]->ui[4]; @@ -172,42 +164,42 @@ static void TAG(quad)( GLcontext *ctx, GLfloat ey = v[0]->v.y - v[2]->v.y; GLfloat fx = v[1]->v.x - v[2]->v.x; GLfloat fy = v[1]->v.y - v[2]->v.y; - GLfloat cc = ex*fy - ey*fx; + GLfloat cc = ex*fy - ey*fx; #if (IND & R128_TWOSIDE_BIT) { - GLuint facing = (cc > 0.0) ^ ctx->Polygon.FrontBit; + GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit; GLubyte (*vbcolor)[4] = VB->Color[facing]->data; - if (IND & R128_FLAT_BIT) { - R128_COLOR((char *)&v[0]->ui[4], vbcolor[pv]); + if ( IND & R128_FLAT_BIT ) { + R128_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); v[3]->ui[4] = v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; } else { - R128_COLOR((char *)&v[0]->ui[4], vbcolor[e0]); - R128_COLOR((char *)&v[1]->ui[4], vbcolor[e1]); - R128_COLOR((char *)&v[2]->ui[4], vbcolor[e2]); - R128_COLOR((char *)&v[3]->ui[4], vbcolor[e3]); + R128_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + R128_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + R128_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); + R128_COLOR( (char *)&v[3]->ui[4], vbcolor[e3] ); } } #endif #if (IND & R128_OFFSET_BIT) { - offset = ctx->Polygon.OffsetUnits * r128ctx->depth_scale; + offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale; z[0] = v[0]->v.z; z[1] = v[1]->v.z; z[2] = v[2]->v.z; z[3] = v[3]->v.z; - if (cc * cc > 1e-16) { - GLfloat ez = z[0] - z[2]; - GLfloat fz = z[1] - z[2]; - GLfloat a = ey*fz - ez*fy; - GLfloat b = ez*fx - ex*fz; - GLfloat ic = 1.0 / cc; - GLfloat ac = a * ic; - GLfloat bc = b * ic; - if (ac < 0.0f) ac = -ac; - if (bc < 0.0f) bc = -bc; - offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor; + if ( cc * cc > 1e-16 ) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; } v[0]->v.z += offset; v[1]->v.z += offset; @@ -218,7 +210,7 @@ static void TAG(quad)( GLcontext *ctx, } #endif - r128_draw_quad( r128ctx, v[0], v[1], v[2], v[3] ); + r128_draw_quad( rmesa, v[0], v[1], v[2], v[3] ); #if (IND & R128_OFFSET_BIT) v[0]->v.z = z[0]; @@ -237,23 +229,15 @@ static void TAG(quad)( GLcontext *ctx, } -/* Draw a single line. Note that the device-dependent vertex data - * might need to be changed based on the render state. - * - * Polygon offset for GL_LINE triangles is dependent on a harness in - * core mesa setting up LineZoffset on a per-triangle basis. - * - * Twosided lighting for GL_LINE triangles is dependent on the same - * harness. - */ static void TAG(line)( GLcontext *ctx, GLuint e0, GLuint e1, GLuint pv ) { - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - r128VertexPtr r128verts = R128_DRIVER_DATA(ctx->VB)->verts; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + r128VertexPtr verts = R128_DRIVER_DATA(VB)->verts; GLfloat width = ctx->Line.Width; - r128Vertex *v[2]; + r128VertexPtr v[2]; #if (IND & R128_OFFSET_BIT) GLfloat offset; @@ -263,8 +247,8 @@ static void TAG(line)( GLcontext *ctx, int c[2]; #endif - v[0] = &r128verts[e0]; - v[1] = &r128verts[e1]; + v[0] = &verts[e0]; + v[1] = &verts[e1]; #if (IND & R128_TWOSIDE_BIT) c[0] = v[0]->ui[4]; @@ -274,7 +258,7 @@ static void TAG(line)( GLcontext *ctx, #if (IND & R128_TWOSIDE_BIT) { GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; - if (IND & R128_FLAT_BIT) { + if ( IND & R128_FLAT_BIT ) { R128_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); v[1]->ui[4] = v[0]->ui[4]; } else { @@ -285,14 +269,14 @@ static void TAG(line)( GLcontext *ctx, #endif #if (IND & R128_OFFSET_BIT) - offset = ctx->LineZoffset * r128ctx->depth_scale; + offset = ctx->LineZoffset * rmesa->depth_scale; z[0] = v[0]->v.z; z[1] = v[1]->v.z; v[0]->v.z += offset; v[1]->v.z += offset; #endif - r128_draw_line( r128ctx, v[0], v[1], width ); + r128_draw_line( rmesa, v[0], v[1], width ); #if (IND & R128_OFFSET_BIT) v[0]->v.z = z[0]; @@ -303,81 +287,46 @@ static void TAG(line)( GLcontext *ctx, v[0]->ui[4] = c[0]; v[1]->ui[4] = c[1]; #endif - -#if 0 - - - if (IND & (R128_TWOSIDE_BIT|R128_FLAT_BIT|R128_OFFSET_BIT)) { - r128Vertex tmp0 = r128verts[e0]; - r128Vertex tmp1 = r128verts[e1]; - - if (IND & R128_TWOSIDE_BIT) { - GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; - - if (IND & R128_FLAT_BIT) { - R128_COLOR((char *)&tmp0.v.color, vbcolor[pv]); - *(int *)&tmp1.v.color = *(int *)&tmp0.v.color; - } else { - R128_COLOR((char *)&tmp0.v.color, vbcolor[e0]); - R128_COLOR((char *)&tmp1.v.color, vbcolor[e1]); - } - } else if (IND & R128_FLAT_BIT) { - *(int *)&tmp0.v.color = *(int *)&r128verts[pv].v.color; - *(int *)&tmp1.v.color = *(int *)&r128verts[pv].v.color; - } - - if (IND & R128_OFFSET_BIT) { - GLfloat offset = ctx->LineZoffset * r128ctx->depth_scale; - tmp0.v.z += offset; - tmp1.v.z += offset; - } - - r128_draw_line( r128ctx, &tmp0, &tmp1, width ); - } else { - r128_draw_line( r128ctx, &r128verts[e0], &r128verts[e1], width ); - } -#endif } -/* Draw a set of points. Note that the device-dependent vertex data - might need to be changed based on the render state. */ -static void TAG(points)(GLcontext *ctx, - GLuint first, GLuint last) -{ - r128ContextPtr r128ctx = R128_CONTEXT(ctx); - struct vertex_buffer *VB = ctx->VB; - r128VertexPtr r128verts = R128_DRIVER_DATA(VB)->verts; - GLfloat size = ctx->Point.Size * 0.5; - int i; +static void TAG(points)( GLcontext *ctx, + GLuint first, GLuint last ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + r128VertexPtr verts = R128_DRIVER_DATA(VB)->verts; + GLfloat size = ctx->Point.Size * 0.5; + int i; - for(i = first; i < last; i++) { - if(VB->ClipMask[i] == 0) { - if (IND & (R128_TWOSIDE_BIT|R128_OFFSET_BIT)) { - r128Vertex tmp0 = r128verts[i]; + for ( i = first ; i < last ; i++) { + if ( VB->ClipMask[i] == 0 ) { + if ( IND & (R128_TWOSIDE_BIT|R128_OFFSET_BIT) ) { + r128Vertex tmp0 = verts[i]; - if (IND & R128_TWOSIDE_BIT) { + if ( IND & R128_TWOSIDE_BIT ) { GLubyte (*vbcolor)[4] = VB->ColorPtr->data; - R128_COLOR((char *)&tmp0.v.color, vbcolor[i]); + R128_COLOR( (char *)&tmp0.v.color, vbcolor[i] ); } - if (IND & R128_OFFSET_BIT) { - GLfloat offset = ctx->PointZoffset * r128ctx->depth_scale; + if ( IND & R128_OFFSET_BIT ) { + GLfloat offset = ctx->PointZoffset * rmesa->depth_scale; tmp0.v.z += offset; } - r128_draw_point( r128ctx, &tmp0, size ); - } else - r128_draw_point( r128ctx, &r128verts[i], size ); + r128_draw_point( rmesa, &tmp0, size ); + } else { + r128_draw_point( rmesa, &verts[i], size ); + } } } } -/* Initialize the table of primitives to render. */ -static void TAG(init)(void) + +static void TAG(init)( void ) { - rast_tab[IND].triangle = TAG(triangle); - rast_tab[IND].quad = TAG(quad); - rast_tab[IND].line = TAG(line); - rast_tab[IND].points = TAG(points); + rast_tab[IND].points = TAG(points); + rast_tab[IND].line = TAG(line); + rast_tab[IND].triangle = TAG(triangle); + rast_tab[IND].quad = TAG(quad); } #undef IND diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c index 744b3c7c4..06a63e152 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.10 2000/12/12 17:17:08 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.11 2001/01/08 01:07:24 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,8 +28,8 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ @@ -78,10 +78,10 @@ do { \ #define TEX0_4 \ do { \ - if (VB->TexCoordPtr[0]->size == 4) { \ + if ( VB->TexCoordPtr[0]->size == 4 ) { \ GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ v = &(R128_DRIVER_DATA(VB)->verts[start]); \ - for (i = start; i < end; i++, v++) { \ + for ( i = start ; i < end ; i++, v++ ) { \ float oow = 1.0 / tc[i][3]; \ v->v.rhw *= tc[i][3]; \ v->v.tu0 *= oow; \ @@ -94,10 +94,10 @@ do { \ #define TEX1_4 \ do { \ - if (VB->TexCoordPtr[1]->size == 4) { \ + if ( VB->TexCoordPtr[1]->size == 4 ) { \ GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \ v = &(R128_DRIVER_DATA(VB)->verts[start]); \ - for (i = start; i < end; i++, v++) { \ + for ( i = start ; i < end ; i++, v++ ) { \ float oow = 1.0 / tc[i][3]; \ v->v.rhw2 *= tc[i][3]; \ v->v.tu1 *= oow; \ @@ -109,9 +109,9 @@ do { \ #define COORD \ do { \ GLfloat *win = VB->Win.data[i]; \ - v->v.x = win[0] + SUBPIXEL_X; \ - v->v.y = r128height - win[1] + SUBPIXEL_Y; \ - v->v.z = scale * win[2]; \ + v->v.x = win[0] + xoffset; \ + v->v.y = - win[1] + yoffset; \ + v->v.z = depth_scale * win[2]; \ v->v.rhw = v->v.rhw2 = win[3]; \ } while (0) @@ -122,43 +122,44 @@ do { \ #define COORD \ do { \ GLfloat *win = VB->Win.data[i]; \ - v->v.x = win[0] + SUBPIXEL_X; \ - v->v.y = r128height - win[1] + SUBPIXEL_Y; \ - v->v.z = scale * win[2]; \ - v->v.rhw = win[3]; \ + v->v.x = win[0] + xoffset; \ + v->v.y = - win[1] + yoffset; \ + v->v.z = depth_scale * win[2]; \ + v->v.rhw = win[3]; \ } while (0) #endif /* USE_RHW2 */ #define NOP -/* Setup the r128 vertex buffer entries */ + #define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \ -static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ +static void name( struct vertex_buffer *VB, GLuint start, GLuint end ) \ { \ - r128ContextPtr r128ctx = R128_CONTEXT(VB->ctx); \ - __DRIdrawablePrivate *dPriv = r128ctx->driDrawable; \ - r128VertexPtr v; \ - GLfloat (*tc0)[4]; \ - GLfloat (*tc1)[4]; \ - GLfloat r128height = dPriv->h; \ - GLfloat scale = r128ctx->depth_scale; \ - int i; \ + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + r128VertexPtr v; \ + GLfloat (*tc0)[4]; \ + GLfloat (*tc1)[4]; \ + const GLfloat depth_scale = rmesa->depth_scale; \ + const GLfloat xoffset = SUBPIXEL_X; \ + const GLfloat yoffset = dPriv->h + SUBPIXEL_Y; \ + GLint i; \ \ - (void) r128height; (void) r128ctx; (void) scale; \ + (void) xoffset; (void) yoffset; (void) depth_scale; \ \ - gl_import_client_data(VB, VB->ctx->RenderFlags, \ - (VB->ClipOrMask \ - ? VEC_WRITABLE | VEC_GOOD_STRIDE \ - : VEC_GOOD_STRIDE)); \ + gl_import_client_data( VB, VB->ctx->RenderFlags, \ + (VB->ClipOrMask \ + ? VEC_WRITABLE | VEC_GOOD_STRIDE \ + : VEC_GOOD_STRIDE) ); \ \ - tc0 = VB->TexCoordPtr[r128ctx->tmu_source[0]]->data; \ - tc1 = VB->TexCoordPtr[r128ctx->tmu_source[1]]->data; \ + tc0 = VB->TexCoordPtr[rmesa->tmu_source[0]]->data; \ + tc1 = VB->TexCoordPtr[rmesa->tmu_source[1]]->data; \ \ v = &(R128_DRIVER_DATA(VB)->verts[start]); \ \ - if (VB->ClipOrMask == 0) { \ - for (i = start; i < end; i++, v++) { \ + if ( VB->ClipOrMask == 0 ) { \ + for ( i = start ; i < end ; i++, v++ ) { \ win; \ col; \ spec; \ @@ -167,8 +168,8 @@ static void name(struct vertex_buffer *VB, GLuint start, GLuint end) \ tex1; \ } \ } else { \ - for (i = start; i < end; i++, v++) { \ - if (VB->ClipMask[i] == 0) { \ + for ( i = start ; i < end ; i++, v++ ) { \ + if ( VB->ClipMask[i] == 0 ) { \ win; \ spec; \ fog; \ @@ -221,20 +222,23 @@ SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) static void rs_invalid( struct vertex_buffer *VB, GLuint start, GLuint end ) { - fprintf(stderr, "r128RasterSetup(): invalid setup function\n"); + fprintf( stderr, "r128RasterSetup(): invalid setup function\n" ); } -typedef void (*setupFunc)(struct vertex_buffer *, GLuint, GLuint); -static setupFunc setup_func[0x40]; +typedef void (*setupFunc)( struct vertex_buffer *, GLuint, GLuint ); +static setupFunc setup_func[R128_MAX_SETUPFUNC]; + -/* Initialize the table of vertex buffer setup functions */ void r128DDSetupInit( void ) { - int i; + GLint i; - for (i = 0; i < 0x20; i++) setup_func[i] = rs_invalid; + for ( i = 0 ; i < R128_MAX_SETUPFUNC ; i++ ) { + setup_func[i] = rs_invalid; + } - /* Functions to build vertices from scratch */ + /* Functions to build vertices from scratch + */ setup_func[R128_WIN_BIT|R128_TEX0_BIT] = rs_wt0; setup_func[R128_WIN_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wt0t1; setup_func[R128_WIN_BIT|R128_FOG_BIT|R128_TEX0_BIT] = rs_wft0; @@ -252,7 +256,8 @@ void r128DDSetupInit( void ) setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT] = rs_wgfst0; setup_func[R128_WIN_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_wgfst0t1; - /* Repair functions */ + /* Repair functions + */ setup_func[R128_TEX0_BIT] = rs_t0; setup_func[R128_TEX0_BIT|R128_TEX1_BIT] = rs_t0t1; setup_func[R128_FOG_BIT] = rs_f; @@ -272,6 +277,7 @@ void r128DDSetupInit( void ) setup_func[R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT] = rs_gfst0t1; } + void r128PrintSetupFlags( char *msg, GLuint flags ) { fprintf( stderr, "%s: %d %s%s%s%s%s%s\n", @@ -285,29 +291,31 @@ void r128PrintSetupFlags( char *msg, GLuint flags ) (flags & R128_TEX1_BIT) ? " tex-1," : "" ); } + /* Initialize the vertex buffer setup functions based on the current - rendering state */ + * rendering state. + */ void r128DDChooseRasterSetupFunc( GLcontext *ctx ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int index = R128_WIN_BIT | R128_RGBA_BIT; - - r128ctx->multitex = 0; - r128ctx->vertsize = 8; - r128ctx->vc_format = R128_TEX0_VERTEX_FORMAT; - r128ctx->tmu_source[0] = 0; - r128ctx->tmu_source[1] = 1; - r128ctx->tex_dest[0] = R128_TEX0_BIT; - r128ctx->tex_dest[1] = R128_TEX1_BIT; - r128ctx->blend_flags &= ~R128_BLEND_MULTITEX; + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLint index = R128_WIN_BIT | R128_RGBA_BIT; + + rmesa->multitex = 0; + rmesa->vertsize = 8; + rmesa->vc_format = R128_TEX0_VERTEX_FORMAT; + rmesa->tmu_source[0] = 0; + rmesa->tmu_source[1] = 1; + rmesa->tex_dest[0] = R128_TEX0_BIT; + rmesa->tex_dest[1] = R128_TEX1_BIT; + rmesa->blend_flags &= ~R128_BLEND_MULTITEX; if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { - if ( ctx->Texture.Unit[0].EnvMode == GL_BLEND && - (r128ctx->env_color & 0x00ffffff) ) { - r128ctx->multitex = 1; - r128ctx->vertsize = 10; - r128ctx->vc_format = R128_TEX1_VERTEX_FORMAT; - r128ctx->tmu_source[1] = 0; + if ( R128_IS_PLAIN( rmesa ) && /* Pro/M3 support GL_BLEND */ + ctx->Texture.Unit[0].EnvMode == GL_BLEND && rmesa->env_color ) { + rmesa->multitex = 1; + rmesa->vertsize = 10; + rmesa->vc_format = R128_TEX1_VERTEX_FORMAT; + rmesa->tmu_source[1] = 0; index |= R128_TEX1_BIT; } @@ -316,23 +324,24 @@ void r128DDChooseRasterSetupFunc( GLcontext *ctx ) if ( ctx->Texture.ReallyEnabled & ENABLE_TEX1 ) { if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { - r128ctx->multitex = 1; - r128ctx->vertsize = 10; - r128ctx->vc_format = R128_TEX1_VERTEX_FORMAT; - r128ctx->blend_flags |= R128_BLEND_MULTITEX; + rmesa->multitex = 1; + rmesa->vertsize = 10; + rmesa->vc_format = R128_TEX1_VERTEX_FORMAT; + if ( R128_IS_PLAIN( rmesa ) ) /* Pro/M3 support GL_BLEND */ + rmesa->blend_flags |= R128_BLEND_MULTITEX; index |= R128_TEX1_BIT; } else { /* Just a funny way of doing single texturing. */ - r128ctx->tmu_source[0] = 1; - r128ctx->tex_dest[1] = R128_TEX0_BIT; - - if ( ctx->Texture.Unit[1].EnvMode == GL_BLEND && - (r128ctx->env_color & 0x00ffffff) ) { - r128ctx->multitex = 1; - r128ctx->vertsize = 10; - r128ctx->vc_format = R128_TEX1_VERTEX_FORMAT; - r128ctx->tmu_source[1] = 1; + rmesa->tmu_source[0] = 1; + rmesa->tex_dest[1] = R128_TEX0_BIT; + + if ( R128_IS_PLAIN( rmesa ) && /* Pro/M3 support GL_BLEND */ + ctx->Texture.Unit[1].EnvMode == GL_BLEND && rmesa->env_color ) { + rmesa->multitex = 1; + rmesa->vertsize = 10; + rmesa->vc_format = R128_TEX1_VERTEX_FORMAT; + rmesa->tmu_source[1] = 1; index |= R128_TEX1_BIT; } @@ -351,57 +360,61 @@ void r128DDChooseRasterSetupFunc( GLcontext *ctx ) r128PrintSetupFlags( "full setup function", index ); } - r128ctx->new_state |= R128_NEW_TEXTURE; - r128ctx->SetupIndex = index; + rmesa->new_state |= R128_NEW_TEXTURE; + rmesa->SetupIndex = index; ctx->Driver.RasterSetup = setup_func[index]; } -/* Check to see if any updates of the vertex buffer entries are needed */ +/* Check to see if any updates of the vertex buffer entries are needed. + */ void r128DDCheckPartialRasterSetup( GLcontext *ctx, struct gl_pipeline_stage *s ) { - r128ContextPtr r128ctx = R128_CONTEXT( ctx ); - int tmp = r128ctx->SetupDone; + r128ContextPtr rmesa = R128_CONTEXT( ctx ); + GLint tmp = rmesa->SetupDone; s->type = 0; - r128ctx->SetupDone = GL_FALSE; + rmesa->SetupDone = 0; - if ((ctx->Array.Summary & VERT_OBJ_ANY) == 0) return; - if (ctx->IndirectTriangles) return; + if ( (ctx->Array.Summary & VERT_OBJ_ANY) == 0 ) + return; - r128ctx->SetupDone = tmp; -} + if ( ctx->IndirectTriangles ) + return; + rmesa->SetupDone = tmp; +} -/* Update the vertex buffer entries, if necessary */ +/* Repair existing precalculated vertices with new data. + */ void r128DDPartialRasterSetup( struct vertex_buffer *VB ) { - r128ContextPtr r128ctx = R128_CONTEXT( VB->ctx ); - int new = VB->pipeline->new_outputs; - int available = VB->pipeline->outputs; - int index = 0; + r128ContextPtr rmesa = R128_CONTEXT(VB->ctx); + GLuint new = VB->pipeline->new_outputs; + GLuint available = VB->pipeline->outputs; + GLuint index = 0; - if (new & VERT_WIN) { + if ( new & VERT_WIN ) { new = available; index |= R128_WIN_BIT | R128_FOG_BIT; } - if (new & VERT_RGBA) + if ( new & VERT_RGBA ) index |= R128_RGBA_BIT | R128_SPEC_BIT; - if (new & VERT_TEX0_ANY) + if ( new & VERT_TEX0_ANY ) index |= R128_TEX0_BIT; - if (new & VERT_TEX1_ANY) - index |= r128ctx->tex_dest[1]; + if ( new & VERT_TEX1_ANY ) + index |= rmesa->tex_dest[1]; - if (new & VERT_FOG_COORD) + if ( new & VERT_FOG_COORD ) index |= R128_FOG_BIT; - r128ctx->SetupDone &= ~index; - index &= r128ctx->SetupIndex; - r128ctx->SetupDone |= index; + rmesa->SetupDone &= ~index; + index &= rmesa->SetupIndex; + rmesa->SetupDone |= index; if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) r128PrintSetupFlags( "partial setup function", index ); @@ -410,7 +423,6 @@ void r128DDPartialRasterSetup( struct vertex_buffer *VB ) setup_func[index]( VB, VB->Start, VB->Count ); } -/* Perform the raster setup for the fast path, if using CVA */ void r128DDDoRasterSetup( struct vertex_buffer *VB ) { GLcontext *ctx = VB->ctx; @@ -418,87 +430,85 @@ void r128DDDoRasterSetup( struct vertex_buffer *VB ) if ( VB->Type == VB_CVA_PRECALC ) { r128DDPartialRasterSetup( VB ); } else if ( ctx->Driver.RasterSetup ) { - ctx->Driver.RasterSetup( VB, - VB->CopyStart, - VB->Count ); + ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count ); } } -/* Resize an existing vertex buffer */ + +/* ================================================================ + * Hardware-format vertex buffers + */ + void r128DDResizeVB( struct vertex_buffer *VB, GLuint size ) { - r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); + r128VertexBufferPtr rvb = R128_DRIVER_DATA(VB); - while ( r128vb->size < size ) - r128vb->size *= 2; + while ( rvb->size < size ) + rvb->size *= 2; - ALIGN_FREE( r128vb->vert_store ); - r128vb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * r128vb->size, 32 ); - if ( !r128vb->vert_store ) { + ALIGN_FREE( rvb->vert_store ); + rvb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * rvb->size, 32 ); + if ( !rvb->vert_store ) { fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); exit( 1 ); } - r128vb->verts = (r128VertexPtr)r128vb->vert_store; + rvb->verts = (r128VertexPtr)rvb->vert_store; - gl_vector1ui_free( &r128vb->clipped_elements ); - gl_vector1ui_alloc( &r128vb->clipped_elements, - VEC_WRITABLE, r128vb->size, 32 ); - if ( !r128vb->clipped_elements.start ) { + gl_vector1ui_free( &rvb->clipped_elements ); + gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 ); + if ( !rvb->clipped_elements.start ) { fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); exit( 1 ); } ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * r128vb->size, 32 ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 ); if ( !VB->ClipMask ) { fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); exit( 1 ); } } -/* Create a new device-dependent vertex buffer */ void r128DDRegisterVB( struct vertex_buffer *VB ) { - r128VertexBufferPtr r128vb; + r128VertexBufferPtr rvb; - r128vb = (r128VertexBufferPtr)CALLOC( sizeof(*r128vb) ); + rvb = (r128VertexBufferPtr)CALLOC( sizeof(*rvb) ); - r128vb->size = VB->Size * 2; - r128vb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * r128vb->size, 32 ); - if ( !r128vb->vert_store ) { + rvb->size = VB->Size * 2; + rvb->vert_store = ALIGN_MALLOC( sizeof(r128Vertex) * rvb->size, 32 ); + if ( !rvb->vert_store ) { fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); exit( 1 ); } - r128vb->verts = (r128VertexPtr)r128vb->vert_store; + rvb->verts = (r128VertexPtr)rvb->vert_store; - gl_vector1ui_alloc( &r128vb->clipped_elements, - VEC_WRITABLE, r128vb->size, 32 ); - if ( !r128vb->clipped_elements.start ) { + gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 ); + if ( !rvb->clipped_elements.start ) { fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); exit( 1 ); } ALIGN_FREE( VB->ClipMask ); - VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * r128vb->size, 32 ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 ); if ( !VB->ClipMask ) { fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); exit( 1 ); } - VB->driver_data = r128vb; + VB->driver_data = rvb; } -/* Destroy a device-dependent vertex buffer */ void r128DDUnregisterVB( struct vertex_buffer *VB ) { - r128VertexBufferPtr r128vb = R128_DRIVER_DATA(VB); + r128VertexBufferPtr rvb = R128_DRIVER_DATA(VB); - if ( r128vb ) { - if ( r128vb->vert_store ) ALIGN_FREE( r128vb->vert_store ); - gl_vector1ui_free( &r128vb->clipped_elements ); - FREE( r128vb ); + if ( rvb ) { + if ( rvb->vert_store ) ALIGN_FREE( rvb->vert_store ); + gl_vector1ui_free( &rvb->clipped_elements ); + FREE( rvb ); VB->driver_data = 0; } } diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h index f1afdff2c..1a00d9eea 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.h,v 1.3 2000/12/04 19:21:48 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.h,v 1.4 2001/01/08 01:07:24 martin Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -28,80 +28,78 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. /* * Authors: - * Kevin E. Martin <martin@valinux.com> * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * */ -#ifndef _R128_VB_H_ -#define _R128_VB_H_ +#ifndef __R128_VB_H__ +#define __R128_VB_H__ #ifdef GLX_DIRECT_RENDERING /* FIXME: This is endian-specific */ typedef struct { - GLubyte blue; - GLubyte green; - GLubyte red; - GLubyte alpha; + GLubyte blue; + GLubyte green; + GLubyte red; + GLubyte alpha; } r128_color_t; /* The vertex structure. The final tu1/tv1 values are only used in * multitexture modes, and the rhw2 value is currently never used. */ typedef struct { - GLfloat x, y, z; /* Coordinates in screen space */ - GLfloat rhw; /* Reciprocal homogeneous w */ - r128_color_t color; /* Diffuse color */ - r128_color_t specular; /* Specular color (alpha is fog) */ - GLfloat tu0, tv0; /* Texture 0 coordinates */ - GLfloat tu1, tv1; /* Texture 1 coordinates */ - GLfloat rhw2; /* Reciprocal homogeneous w2 */ + GLfloat x, y, z; /* Coordinates in screen space */ + GLfloat rhw; /* Reciprocal homogeneous w */ + r128_color_t color; /* Diffuse color */ + r128_color_t specular; /* Specular color (alpha is fog) */ + GLfloat tu0, tv0; /* Texture 0 coordinates */ + GLfloat tu1, tv1; /* Texture 1 coordinates */ + GLfloat rhw2; /* Reciprocal homogeneous w2 */ } r128_vertex; -/* Format of vertices in r128_vertex struct */ -#define R128_TEX0_VERTEX_FORMAT \ - R128_CCE_VC_FRMT_RHW | \ - R128_CCE_VC_FRMT_DIFFUSE_ARGB | \ - R128_CCE_VC_FRMT_SPEC_FRGB | \ - R128_CCE_VC_FRMT_S_T - -#define R128_TEX1_VERTEX_FORMAT \ - R128_CCE_VC_FRMT_RHW | \ - R128_CCE_VC_FRMT_DIFFUSE_ARGB | \ - R128_CCE_VC_FRMT_SPEC_FRGB | \ - R128_CCE_VC_FRMT_S_T | \ - R128_CCE_VC_FRMT_S2_T2 - -#define R128_PROJ_TEX1_VERTEX_FORMAT \ - R128_CCE_VC_FRMT_RHW | \ - R128_CCE_VC_FRMT_DIFFUSE_ARGB | \ - R128_CCE_VC_FRMT_SPEC_FRGB | \ - R128_CCE_VC_FRMT_S_T | \ - R128_CCE_VC_FRMT_S2_T2 | \ - R128_CCE_VC_FRMT_RHW2 - - -/* FIXME: We currently only have assembly for 16-stride vertices */ +/* Format of vertices in r128_vertex struct: + */ +#define R128_TEX0_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB |\ + R128_CCE_VC_FRMT_SPEC_FRGB | \ + R128_CCE_VC_FRMT_S_T) + +#define R128_TEX1_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB |\ + R128_CCE_VC_FRMT_SPEC_FRGB | \ + R128_CCE_VC_FRMT_S_T | \ + R128_CCE_VC_FRMT_S2_T2) + +#define R128_PROJ_TEX1_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB |\ + R128_CCE_VC_FRMT_SPEC_FRGB | \ + R128_CCE_VC_FRMT_S_T | \ + R128_CCE_VC_FRMT_S2_T2 | \ + R128_CCE_VC_FRMT_RHW2) + + +/* The fastpath code still expects a 16-float stride vertex. + */ union r128_vertex_t { - r128_vertex v; - GLfloat f[16]; - CARD32 ui[16]; + r128_vertex v; + GLfloat f[16]; + GLuint ui[16]; }; typedef union r128_vertex_t r128Vertex; typedef union r128_vertex_t *r128VertexPtr; -/* Vertex buffer for use when on the fast path */ typedef struct { - GLuint size; /* Number of vertices in store */ - void *vert_store; /* Storage for vertex buffer */ - r128VertexPtr verts; /* Aligned start of verts in storage */ - int last_vert; /* Index of last vertex used */ - GLvector1ui clipped_elements; /* List of clipped elements */ + r128VertexPtr verts; + GLvector1ui clipped_elements; + GLint last_vert; + void *vert_store; + GLuint size; } *r128VertexBufferPtr; -#define R128_DRIVER_DATA(vb) ((r128VertexBufferPtr)((vb)->driver_data)) +#define R128_DRIVER_DATA(vb) ((r128VertexBufferPtr)((vb)->driver_data)) #define R128_WIN_BIT 0x01 #define R128_RGBA_BIT 0x02 @@ -109,20 +107,21 @@ typedef struct { #define R128_SPEC_BIT 0x08 #define R128_TEX0_BIT 0x10 #define R128_TEX1_BIT 0x20 - -extern void r128DDSetupInit( void ); +#define R128_MAX_SETUPFUNC 0x40 extern void r128DDChooseRasterSetupFunc( GLcontext *ctx ); extern void r128PrintSetupFlags( char *msg, GLuint flags ); extern void r128DDCheckPartialRasterSetup( GLcontext *ctx, - struct gl_pipeline_stage *s ); -extern void r128DDPartialRasterSetup(struct vertex_buffer *VB); -extern void r128DDDoRasterSetup(struct vertex_buffer *VB); + struct gl_pipeline_stage *s ); +extern void r128DDPartialRasterSetup( struct vertex_buffer *VB ); +extern void r128DDDoRasterSetup( struct vertex_buffer *VB ); -extern void r128DDResizeVB(struct vertex_buffer *VB, GLuint size); -extern void r128DDRegisterVB(struct vertex_buffer *VB); -extern void r128DDUnregisterVB(struct vertex_buffer *VB); +extern void r128DDResizeVB( struct vertex_buffer *VB, GLuint size ); +extern void r128DDRegisterVB( struct vertex_buffer *VB ); +extern void r128DDUnregisterVB( struct vertex_buffer *VB ); + +extern void r128DDSetupInit( void ); #endif -#endif /* _R128_VB_H_ */ +#endif /* __R128_VB_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c index 07450e3c0..53908e3bf 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c,v 1.4 2000/12/12 17:17:08 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c,v 1.7 2001/01/23 18:14:38 alanh Exp $ */ /************************************************************************** Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., @@ -48,42 +48,79 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. extern void __driRegisterExtensions( void ); -static r128ContextPtr r128Context = NULL; +static r128ContextPtr r128Ctx = NULL; -/* Initialize the driver specific screen private data */ -GLboolean XMesaInitDriver(__DRIscreenPrivate *sPriv) +/* Initialize the driver specific screen private data. + */ +GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) { - sPriv->private = (void *)r128CreateScreen(sPriv); - if (!sPriv->private) { - r128DestroyScreen(sPriv); - return GL_FALSE; - } - - return GL_TRUE; + sPriv->private = (void *) r128CreateScreen( sPriv ); + + /* Check the DRI version */ + { + int major, minor, patch; + if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { + if (major != 3 || minor != 1 || patch < 0) { + char msg[1000]; + sprintf(msg, "R128 DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch); + __driMesaMessage(msg); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if (sPriv->ddxMajor != 4 || + sPriv->ddxMinor != 0 || + sPriv->ddxPatch < 0) { + char msg[1000]; + sprintf(msg, "R128 DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); + __driMesaMessage(msg); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if (sPriv->drmMajor != 2 || + sPriv->drmMinor != 1 || + sPriv->drmPatch < 4) { + char msg[1000]; + sprintf(msg, "R128 DRI driver expected DRM driver version 2.1.x (x>=4) but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + __driMesaMessage(msg); + return GL_FALSE; + } + + if ( !sPriv->private ) { + r128DestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; } -/* Reset the driver specific screen private data */ -void XMesaResetDriver(__DRIscreenPrivate *sPriv) +/* Reset the driver specific screen private data. + */ +void XMesaResetDriver( __DRIscreenPrivate *sPriv ) { - r128DestroyScreen(sPriv); + r128DestroyScreen( sPriv ); } -/* Create and initialize the Mesa and driver specific visual data */ -GLvisual *XMesaCreateVisual(Display *dpy, - __DRIscreenPrivate *driScrnPriv, - const XVisualInfo *visinfo, - const __GLXvisualConfig *config) +/* Create and initialize the Mesa and driver specific visual data. + */ +GLvisual *XMesaCreateVisual( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config ) { - /* Drivers may change the args to _mesa_create_visual() in order to - * setup special visuals. + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. */ - return _mesa_create_visual(config->rgba, + return _mesa_create_visual( config->rgba, config->doubleBuffer, config->stereo, - _mesa_bitcount(visinfo->red_mask), - _mesa_bitcount(visinfo->green_mask), - _mesa_bitcount(visinfo->blue_mask), + _mesa_bitcount( visinfo->red_mask ), + _mesa_bitcount( visinfo->green_mask ), + _mesa_bitcount( visinfo->blue_mask ), config->alphaSize, 0, /* index bits */ config->depthSize, @@ -92,134 +129,186 @@ GLvisual *XMesaCreateVisual(Display *dpy, config->accumGreenSize, config->accumBlueSize, config->accumAlphaSize, - 0 /* num samples */); + 0 /* num samples */ ); } -/* Create and initialize the Mesa and driver specific context data */ -GLboolean XMesaCreateContext(Display *dpy, GLvisual *mesaVis, - __DRIcontextPrivate *driContextPriv) +/* Create and initialize the Mesa and driver specific context data. + */ +GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv ) { - return r128CreateContext(dpy, mesaVis, driContextPriv); + return r128CreateContext( dpy, mesaVis, driContextPriv ); } -/* Destroy the Mesa and driver specific context data */ +/* Destroy the Mesa and driver specific context data. + */ void XMesaDestroyContext(__DRIcontextPrivate *driContextPriv) { - r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate; + r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; - if (r128ctx == (void *)r128Context) r128Context = NULL; - r128DestroyContext(r128ctx); + if ( rmesa == r128Ctx ) r128Ctx = NULL; + r128DestroyContext(rmesa); } -/* Create and initialize the Mesa and driver specific pixmap buffer data */ -GLframebuffer *XMesaCreateWindowBuffer(Display *dpy, - __DRIscreenPrivate *driScrnPriv, - __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis) +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis ) { - return gl_create_framebuffer(mesaVis, - GL_FALSE, /* software depth buffer? */ - mesaVis->StencilBits > 0, - mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0 - ); + return gl_create_framebuffer( mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 ); } -/* Create and initialize the Mesa and driver specific pixmap buffer data */ +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, __DRIscreenPrivate *driScrnPriv, __DRIdrawablePrivate *driDrawPriv, - GLvisual *mesaVis) + GLvisual *mesaVis ) { #if 0 - /* Different drivers may have different combinations of hardware and - * software ancillary buffers. - */ - return gl_create_framebuffer(mesaVis, + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer( mesaVis, GL_FALSE, /* software depth buffer? */ mesaVis->StencilBits > 0, mesaVis->AccumRedBits > 0, - mesaVis->AlphaBits > 0); + mesaVis->AlphaBits > 0 ); #else - return NULL; /* not implemented yet */ + return NULL; /* not implemented yet */ #endif } /* Copy the back color buffer to the front color buffer */ -void XMesaSwapBuffers(__DRIdrawablePrivate *driDrawPriv) +void XMesaSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) { - /* FIXME: This assumes buffer is currently bound to a context. This - needs to be able to swap buffers when not currently bound. Also, - this needs to swap according to buffer, and NOT according to - context! */ - if (r128Context == NULL) return; - - /* Only swap buffers when a back buffer exists */ - if (R128_MESACTX(r128Context)->Visual->DBflag) { - FLUSH_VB(R128_MESACTX(r128Context), "swap buffers"); - r128SwapBuffers(r128Context); - } + /* FIXME: This assumes buffer is currently bound to a context. This + * needs to be able to swap buffers when not currently bound. Also, + * this needs to swap according to buffer, and NOT according to + * context! + */ + if ( r128Ctx == NULL ) + return; + + /* Only swap buffers when a back buffer exists. + */ + if ( r128Ctx->glCtx->Visual->DBflag ) { + FLUSH_VB( r128Ctx->glCtx, "swap buffers" ); + if ( !r128Ctx->doPageFlip ) { + r128SwapBuffers( r128Ctx ); + } else { + r128PageFlip( r128Ctx ); + } + } } /* Force the context `c' to be the current context and associate with it - buffer `b' */ -GLboolean XMesaMakeCurrent(__DRIcontextPrivate *driContextPriv, - __DRIdrawablePrivate *driDrawPriv, - __DRIdrawablePrivate *driReadPriv) + * buffer `b'. + */ +GLboolean XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) { - if (driContextPriv) { - r128ContextPtr r128ctx = (r128ContextPtr)driContextPriv->driverPrivate; - - r128Context = r128MakeCurrent(r128Context, r128ctx, driDrawPriv); - - gl_make_current2(R128_MESACTX(r128Context), - driDrawPriv->mesaBuffer, driReadPriv->mesaBuffer); - - if (r128Context->driDrawable != driDrawPriv) { - r128Context->driDrawable = driDrawPriv; - r128Context->dirty = R128_UPLOAD_ALL; - } - - /* GH: We need this to correctly calculate the window offset - * and aux scissor rects. - */ - r128Context->new_state = R128_NEW_WINDOW | R128_NEW_CLIP; - - if (!R128_MESACTX(r128Context)->Viewport.Width) { - gl_Viewport(R128_MESACTX(r128Context), 0, 0, - driDrawPriv->w, driDrawPriv->h); - } - } else { - gl_make_current(0,0); - r128Context = NULL; - } - - return GL_TRUE; + if ( driContextPriv ) { + r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; + + r128Ctx = r128MakeCurrent( r128Ctx, rmesa, driDrawPriv ); + + gl_make_current2( r128Ctx->glCtx, + driDrawPriv->mesaBuffer, + driReadPriv->mesaBuffer ); + + if ( r128Ctx->driDrawable != driDrawPriv ) { + r128Ctx->driDrawable = driDrawPriv; + r128Ctx->dirty = R128_UPLOAD_ALL; + } + + /* GH: We need this to correctly calculate the window offset + * and aux scissor rects. + */ + r128Ctx->new_state = R128_NEW_WINDOW | R128_NEW_CLIP; + + if ( !r128Ctx->glCtx->Viewport.Width ) { + gl_Viewport( r128Ctx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); + } + } else { + gl_make_current( 0, 0 ); + r128Ctx = NULL; + } + + return GL_TRUE; } -/* Force the context `c' to be unbound from its buffer */ -GLboolean XMesaUnbindContext(__DRIcontextPrivate *driContextPriv) +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean XMesaUnbindContext( __DRIcontextPrivate *driContextPriv ) { - return GL_TRUE; + return GL_TRUE; } /* This function is called by libGL.so as soon as libGL.so is loaded. - * This is where we'd register new extension functions with the dispatcher. + * This is where we'd register new extension functions with the + * dispatcher. */ void __driRegisterExtensions( void ) { } +/* Initialize the fullscreen mode. + */ GLboolean -XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv) +XMesaOpenFullScreen( __DRIcontextPrivate *driContextPriv ) { - return GL_TRUE; + r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; + GLint ret; + + /* FIXME: Do we need to check this? + */ + if ( !r128Ctx->glCtx->Visual->DBflag ) + return GL_TRUE; + + LOCK_HARDWARE( rmesa ); + r128WaitForIdleLocked( rmesa ); + + /* Ignore errors. If this fails, we simply don't do page flipping. + */ + ret = drmR128FullScreen( rmesa->driFd, GL_TRUE ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->doPageFlip = ( ret == 0 ); + + return GL_TRUE; } +/* Shut down the fullscreen mode. + */ GLboolean -XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv) +XMesaCloseFullScreen( __DRIcontextPrivate *driContextPriv ) { - return GL_TRUE; + r128ContextPtr rmesa = (r128ContextPtr)driContextPriv->driverPrivate; + + LOCK_HARDWARE( rmesa ); + r128WaitForIdleLocked( rmesa ); + + /* Don't care if this fails, we're not page flipping anymore. + */ + drmR128FullScreen( rmesa->driFd, GL_FALSE ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->doPageFlip = GL_FALSE; + rmesa->currentPage = 0; + + return GL_TRUE; } #endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/Imakefile b/xc/lib/GL/mesa/src/drv/radeon/Imakefile new file mode 100644 index 000000000..52787a5fc --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile @@ -0,0 +1,386 @@ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/radeon/Imakefile,v 1.1 2001/01/08 01:07:26 martin Exp $ + +#include <Threads.tmpl> + +#define DoNormalLib NormalLibGlx +#define DoSharedLib SharedLibGlx +#define DoExtraLib SharedLibGlx +#define DoDebugLib DebugLibGlx +#define DoProfileLib ProfileLibGlx + +#if Malloc0ReturnsNull +ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL +#endif + +#ifdef i386Architecture +#if MesaUseMMX + MMX_DEFS = -DUSE_MMX_ASM +#endif +#if MesaUse3DNow + 3DNOW_DEFS = -DUSE_3DNOW_ASM +#endif +#if MesaUseKatmai + KATMAI_DEFS = -DUSE_KATMAI_ASM +#endif + ASM_DEFINES = -DUSE_X86_ASM $(MMX_DEFS) $(3DNOW_DEFS) $(KATMAI_DEFS) +#endif + +#if BuildXF86DRI + DRI_DEFINES = GlxDefines -DDRIVERTS + DRI_INCLUDES = -I../../../../dri \ + -I../../../../glx \ + -I../../../dri \ + -I$(TOP)/include \ + -I$(TOP)/include/GL \ + -I$(XF86OSSRC) \ + -I$(XF86COMSRC) \ + -I$(SERVERSRC)/GL/dri \ + -I$(XF86DRIVERSRC)/ati \ + -I../../../include \ + -I../.. \ + -I../../X \ + -I../common +#endif + +MESA_INCLUDES = -I. -I.. -I../../include \ + -I../../../../dri/drm + + DEFINES = $(ALLOC_DEFINES) $(DRI_DEFINES) $(ASM_DEFINES) + INCLUDES = -I$(XLIBSRC) -I$(EXTINCSRC) $(MESA_INCLUDES) $(DRI_INCLUDES) + + RADEONSRCS = radeon_context.c \ + radeon_dd.c \ + radeon_fastpath.c \ + radeon_eltpath.c \ + radeon_ioctl.c \ + radeon_lock.c \ + radeon_pipeline.c \ + radeon_screen.c \ + radeon_span.c \ + radeon_state.c \ + radeon_tex.c \ + radeon_tris.c \ + radeon_vb.c \ + radeon_xmesa.c + + RADEONOBJS = radeon_context.o \ + radeon_dd.o \ + radeon_fastpath.o \ + radeon_eltpath.o \ + radeon_ioctl.o \ + radeon_lock.o \ + radeon_pipeline.o \ + radeon_screen.o \ + radeon_span.o \ + radeon_state.o \ + radeon_tex.o \ + radeon_tris.o \ + radeon_vb.o \ + radeon_xmesa.o + +#if !GlxUseBuiltInDRIDriver + DRISRCS = ../../../dri/dri_mesa.c \ + ../../../../dri/dri_tmm.c + + DRIOBJS = ../../../dri/dri_mesa.o \ + ../../../../dri/dri_tmm.o + + DRMSRCS = ../../../../dri/drm/xf86drm.c \ + ../../../../dri/drm/xf86drmHash.c \ + ../../../../dri/drm/xf86drmRandom.c \ + ../../../../dri/drm/xf86drmSL.c \ + ../../../../dri/drm/xf86drmRadeon.c + + DRMOBJS = ../../../../dri/drm/xf86drm.o \ + ../../../../dri/drm/xf86drmHash.o \ + ../../../../dri/drm/xf86drmRandom.o \ + ../../../../dri/drm/xf86drmSL.o \ + ../../../../dri/drm/xf86drmRadeon.o + + MESASRCS = ../../aatriangle.c \ + ../../accum.c \ + ../../alpha.c \ + ../../alphabuf.c \ + ../../attrib.c \ + ../../bbox.c \ + ../../bitmap.c \ + ../../blend.c \ + ../../buffers.c \ + ../../clip.c \ + ../../colortab.c \ + ../../config.c \ + ../../context.c \ + ../../copypix.c \ + ../../cva.c \ + ../../debug_xform.c \ + ../../depth.c \ + ../../dlist.c \ + ../../drawpix.c \ + ../../enable.c \ + ../../enums.c \ + ../../eval.c \ + ../../extensions.c \ + ../../feedback.c \ + ../../fog.c \ + ../../get.c \ + ../../glapi.c \ + ../../glapinoop.c \ + ../../glthread.c \ + ../../hash.c \ + ../../image.c \ + ../../imaging.c \ + ../../light.c \ + ../../lines.c \ + ../../logic.c \ + ../../masking.c \ + ../../matrix.c \ + ../../mem.c \ + ../../mmath.c \ + ../../pb.c \ + ../../pipeline.c \ + ../../pixel.c \ + ../../pixeltex.c \ + ../../points.c \ + ../../polygon.c \ + ../../quads.c \ + ../../rastpos.c \ + ../../readpix.c \ + ../../rect.c \ + ../../scissor.c \ + ../../shade.c \ + ../../span.c \ + ../../stages.c \ + ../../state.c \ + ../../stencil.c \ + ../../teximage.c \ + ../../texobj.c \ + ../../texstate.c \ + ../../texture.c \ + ../../texutil.c \ + ../../translate.c \ + ../../triangle.c \ + ../../varray.c \ + ../../vb.c \ + ../../vbcull.c \ + ../../vbfill.c \ + ../../vbindirect.c \ + ../../vbrender.c \ + ../../vbxform.c \ + ../../vector.c \ + ../../vertices.c \ + ../../winpos.c \ + ../../xform.c \ + ../../zoom.c + + MESAOBJS = ../../aatriangle.o \ + ../../accum.o \ + ../../alpha.o \ + ../../alphabuf.o \ + ../../attrib.o \ + ../../bbox.o \ + ../../bitmap.o \ + ../../blend.o \ + ../../buffers.o \ + ../../clip.o \ + ../../colortab.o \ + ../../config.o \ + ../../context.o \ + ../../copypix.o \ + ../../cva.o \ + ../../debug_xform.o \ + ../../depth.o \ + ../../dlist.o \ + ../../drawpix.o \ + ../../enable.o \ + ../../enums.o \ + ../../eval.o \ + ../../extensions.o \ + ../../feedback.o \ + ../../fog.o \ + ../../get.o \ + ../../hash.o \ + ../../hint.o \ + ../../image.o \ + ../../imaging.o \ + ../../light.o \ + ../../lines.o \ + ../../logic.o \ + ../../masking.o \ + ../../matrix.o \ + ../../mem.o \ + ../../mmath.o \ + ../../pb.o \ + ../../pipeline.o \ + ../../pixel.o \ + ../../pixeltex.o \ + ../../points.o \ + ../../polygon.o \ + ../../quads.o \ + ../../rastpos.o \ + ../../readpix.o \ + ../../rect.o \ + ../../scissor.o \ + ../../shade.o \ + ../../span.o \ + ../../stages.o \ + ../../state.o \ + ../../stencil.o \ + ../../teximage.o \ + ../../texobj.o \ + ../../texstate.o \ + ../../texture.o \ + ../../texutil.o \ + ../../translate.o \ + ../../triangle.o \ + ../../varray.o \ + ../../vb.o \ + ../../vbcull.o \ + ../../vbfill.o \ + ../../vbindirect.o \ + ../../vbrender.o \ + ../../vbxform.o \ + ../../vector.o \ + ../../vertices.o \ + ../../winpos.o \ + ../../xform.o \ + ../../zoom.o + +#ifdef i386Architecture + X86_SRCS = ../../X86/common_x86.c \ + ../../X86/common_x86_asm.S \ + ../../X86/x86.c \ + ../../X86/x86_cliptest.S \ + ../../X86/x86_vertex.S \ + ../../X86/x86_xform_masked2.S \ + ../../X86/x86_xform_masked3.S \ + ../../X86/x86_xform_masked4.S \ + ../../X86/x86_xform_raw2.S \ + ../../X86/x86_xform_raw3.S \ + ../../X86/x86_xform_raw4.S + + X86_OBJS = ../../X86/common_x86.o \ + ../../X86/common_x86_asm.o \ + ../../X86/x86.o \ + ../../X86/x86_cliptest.o \ + ../../X86/x86_vertex.o \ + ../../X86/x86_xform_masked2.o \ + ../../X86/x86_xform_masked3.o \ + ../../X86/x86_xform_masked4.o \ + ../../X86/x86_xform_raw2.o \ + ../../X86/x86_xform_raw3.o \ + ../../X86/x86_xform_raw4.o + +#if MesaUseMMX + MMX_SRCS = ../../X86/mmx_blend.S + + MMX_OBJS = ../../X86/mmx_blend.o +#endif + +#if MesaUse3DNow + 3DNOW_SRCS = ../../X86/3dnow.c \ + ../../X86/3dnow_norm_raw.S \ + ../../X86/3dnow_vertex.S \ + ../../X86/3dnow_xform_masked1.S \ + ../../X86/3dnow_xform_masked2.S \ + ../../X86/3dnow_xform_masked3.S \ + ../../X86/3dnow_xform_masked4.S \ + ../../X86/3dnow_xform_raw1.S \ + ../../X86/3dnow_xform_raw2.S \ + ../../X86/3dnow_xform_raw3.S \ + ../../X86/3dnow_xform_raw4.S + + 3DNOW_OBJS = ../../X86/3dnow.o \ + ../../X86/3dnow_norm_raw.o \ + ../../X86/3dnow_vertex.o \ + ../../X86/3dnow_xform_masked1.o \ + ../../X86/3dnow_xform_masked2.o \ + ../../X86/3dnow_xform_masked3.o \ + ../../X86/3dnow_xform_masked4.o \ + ../../X86/3dnow_xform_raw1.o \ + ../../X86/3dnow_xform_raw2.o \ + ../../X86/3dnow_xform_raw3.o \ + ../../X86/3dnow_xform_raw4.o +#endif + +#if MesaUseKatmai + KATMAI_SRCS = ../../X86/katmai.c \ + ../../X86/katmai_norm_raw.S \ + ../../X86/katmai_vertex.S \ + ../../X86/katmai_xform_masked1.S \ + ../../X86/katmai_xform_masked2.S \ + ../../X86/katmai_xform_masked3.S \ + ../../X86/katmai_xform_masked4.S \ + ../../X86/katmai_xform_raw1.S \ + ../../X86/katmai_xform_raw2.S \ + ../../X86/katmai_xform_raw3.S \ + ../../X86/katmai_xform_raw4.S + + KATMAI_OBJS = ../../X86/katmai.o \ + ../../X86/katmai_norm_raw.o \ + ../../X86/katmai_vertex.o \ + ../../X86/katmai_xform_masked1.o \ + ../../X86/katmai_xform_masked2.o \ + ../../X86/katmai_xform_masked3.o \ + ../../X86/katmai_xform_masked4.o \ + ../../X86/katmai_xform_raw1.o \ + ../../X86/katmai_xform_raw2.o \ + ../../X86/katmai_xform_raw3.o \ + ../../X86/katmai_xform_raw4.o +#endif +#endif +#endif + +#ifdef GlxSoProf + LOSRCS = ../../../../lowpc.c + HISRCS = ../../../../highpc.c + + LOOBJS = ../../../../lowpc.o + HIOBJS = ../../../../highpc.o +#endif + + ASMSRCS = $(X86_SRCS) $(MMX_SRCS) $(3DNOW_SRCS) $(KATMAI_SRCS) + ASMOBJS = $(X86_OBJS) $(MMX_OBJS) $(3DNOW_OBJS) $(KATMAI_OBJS) + + COMMONSRCS = ../common/mm.c ../common/hwlog.c + COMMONOBJS = ../common/mm.o ../common/hwlog.o + + SRCS = $(LOSRCS) $(DRISRCS) $(DRMSRCS) $(MESASRCS) \ + $(ASMSRCS) $(COMMONSRCS) $(RADEONSRCS) $(HISRCS) + OBJS = $(LOOBJS) $(DRIOBJS) $(DRMOBJS) $(MESAOBJS) \ + $(ASMOBJS) $(COMMONOBJS) $(RADEONOBJS) $(HIOBJS) + +REQUIREDLIBS += MathLibrary +#if !GlxBuiltInRadeon +REQUIREDLIBS += -L../../../.. -lGL +#endif + + +#if !GlxUseBuiltInDRIDriver +#undef DoNormalLib NormalLibGlx +#undef DoExtraLib SharedLibGlx +#undef DoDebugLib DebugLibGlx +#undef DoProfileLib ProfileLibGlx +#endif + +#include <Library.tmpl> + +LibraryObjectRule() + +SubdirLibraryRule($(OBJS)) +NormalLintTarget($(SRCS)) + +#if !GlxUseBuiltInDRIDriver +LIBNAME = radeon_dri.so +ALL_OBJS = $(OBJS) +ALL_DEPS = DONE +SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) + +#ifdef GlxSoProf +SOPROF_LIBNAME = _radeon_dri_p +NormalDepLibraryTarget($(SOPROF_LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +InstallLibrary($(SOPROF_LIBNAME),$(MODULEDIR)/dri) +#endif +#endif + +DependTarget() diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c new file mode 100644 index 000000000..9af8b5691 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -0,0 +1,234 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.c,v 1.1 2001/01/08 01:07:26 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include <stdlib.h> + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_dd.h" +#include "radeon_state.h" +#include "radeon_span.h" +#include "radeon_tex.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include "context.h" +#include "simple_list.h" +#include "mem.h" + +#ifndef RADEON_DEBUG +int RADEON_DEBUG = (0 +/* | DEBUG_ALWAYS_SYNC */ +/* | DEBUG_VERBOSE_API */ +/* | DEBUG_VERBOSE_MSG */ +/* | DEBUG_VERBOSE_LRU */ +/* | DEBUG_VERBOSE_DRI */ +/* | DEBUG_VERBOSE_IOCTL */ +/* | DEBUG_VERBOSE_2D */ + ); +#endif + +/* Create the device specific context. + */ +GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv ) +{ + GLcontext *ctx = driContextPriv->mesaContext; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + radeonContextPtr rmesa; + radeonScreenPtr radeonScreen; + int i; + + rmesa = (radeonContextPtr) CALLOC( sizeof(*rmesa) ); + if ( !rmesa ) return GL_FALSE; + + rmesa->glCtx = ctx; + rmesa->display = dpy; + + rmesa->driContext = driContextPriv; + rmesa->driScreen = sPriv; + rmesa->driDrawable = NULL; /* Set by XMesaMakeCurrent */ + + rmesa->hHWContext = driContextPriv->hHWContext; + rmesa->driHwLock = &sPriv->pSAREA->lock; + rmesa->driFd = sPriv->fd; + + radeonScreen = rmesa->radeonScreen = (radeonScreenPtr)(sPriv->private); + + rmesa->sarea = (RADEONSAREAPrivPtr)((char *)sPriv->pSAREA + + sizeof(XF86DRISAREARec)); + + rmesa->tmp_matrix = (GLfloat *) ALIGN_MALLOC( 16 * sizeof(GLfloat), 16 ); + if ( !rmesa->tmp_matrix ) { + FREE( rmesa ); + return GL_FALSE; + } + + make_empty_list( &rmesa->SwappedOut ); + + for ( i = 0 ; i < radeonScreen->numTexHeaps ; i++ ) { + rmesa->CurrentTexObj[i] = NULL; + make_empty_list( &rmesa->TexObjList[i] ); + rmesa->texHeap[i] = mmInit( 0, radeonScreen->texSize[i] ); + rmesa->lastTexAge[i] = -1; + } + rmesa->lastTexHeap = radeonScreen->numTexHeaps; + + rmesa->RenderIndex = -1; /* Impossible value */ + rmesa->OnFastPath = 0; + + rmesa->vert_buf = NULL; + rmesa->num_verts = 0; + + rmesa->elt_buf = NULL; + rmesa->retained_buf = NULL; + rmesa->vert_heap = radeonScreen->buffers->list->address; + + /* KW: Set the maximum texture size small enough that we can + * guarentee that both texture units can bind a maximal texture + * and have them both in on-card memory at once. (Kevin or + * Gareth: Please check these numbers are OK) + */ + if ( radeonScreen->texSize[0] < 2*1024*1024 ) { + ctx->Const.MaxTextureLevels = 9; + ctx->Const.MaxTextureSize = (1 << 8); + } else if ( radeonScreen->texSize[0] < 8*1024*1024 ) { + ctx->Const.MaxTextureLevels = 10; + ctx->Const.MaxTextureSize = (1 << 9); + } else { + ctx->Const.MaxTextureLevels = 11; + ctx->Const.MaxTextureSize = (1 << 10); + } + + /* FIXME: Support all available texture units... */ + ctx->Const.MaxTextureUnits = 2; + +#if ENABLE_PERF_BOXES + if (getenv("LIBGL_PERFORMANCE_BOXES")) + rmesa->boxes = 1; + else + rmesa->boxes = 0; +#endif + + ctx->DriverCtx = (void *)rmesa; + + radeonDDInitExtensions( ctx ); + + radeonDDInitDriverFuncs( ctx ); + radeonDDInitIoctlFuncs( ctx ); + radeonDDInitStateFuncs( ctx ); + radeonDDInitSpanFuncs( ctx ); + radeonDDInitTextureFuncs( ctx ); + + ctx->Driver.TriangleCaps = (DD_TRI_CULL | + DD_TRI_LIGHT_TWOSIDE | + DD_TRI_STIPPLE | + DD_TRI_OFFSET); + + /* Ask Mesa to clip fog coordinates for us. + */ + ctx->TriangleCaps |= DD_CLIP_FOG_COORD; + + if ( ctx->VB ) + radeonDDRegisterVB( ctx->VB ); + + if ( ctx->NrPipelineStages ) { + ctx->NrPipelineStages = + radeonDDRegisterPipelineStages( ctx->PipelineStage, + ctx->PipelineStage, + ctx->NrPipelineStages ); + } + + radeonDDInitState( rmesa ); + + driContextPriv->driverPrivate = (void *)rmesa; + + return GL_TRUE; +} + +/* Destroy the device specific context. + */ +void radeonDestroyContext( radeonContextPtr rmesa ) +{ + if ( rmesa ) { + radeonTexObjPtr t, next_t; + int i; + + for ( i = 0 ; i < rmesa->radeonScreen->numTexHeaps ; i++ ) { + foreach_s ( t, next_t, &rmesa->TexObjList[i] ) { + radeonDestroyTexObj( rmesa, t ); + } + mmDestroy( rmesa->texHeap[i] ); + } + + foreach_s ( t, next_t, &rmesa->SwappedOut ) { + radeonDestroyTexObj( rmesa, t ); + } + + ALIGN_FREE( rmesa->tmp_matrix ); + FREE( rmesa ); + } + +#if 0 + /* Use this to force shared object profiling. */ + glx_fini_prof(); +#endif +} + +/* Load the device specific context into the hardware. The actual + * setting of the hardware state is done in the radeonUpdateHWState(). + */ +radeonContextPtr radeonMakeCurrent( radeonContextPtr oldCtx, + radeonContextPtr newCtx, + __DRIdrawablePrivate *dPriv ) +{ + if ( oldCtx ) { + if ( oldCtx != newCtx ) { + newCtx->new_state |= RADEON_NEW_CONTEXT; + newCtx->dirty = RADEON_UPLOAD_ALL; + } + if ( oldCtx->driDrawable != dPriv ) { + newCtx->new_state |= RADEON_NEW_WINDOW | RADEON_NEW_CLIP; + } + } else { + newCtx->new_state |= RADEON_NEW_CONTEXT; + newCtx->dirty = RADEON_UPLOAD_ALL; + } + + newCtx->driDrawable = dPriv; + + return newCtx; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h new file mode 100644 index 000000000..cae9d5b30 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h @@ -0,0 +1,253 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_context.h,v 1.1 2001/01/08 01:07:26 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_CONTEXT_H__ +#define __RADEON_CONTEXT_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include <X11/Xlibint.h> + +#include "dri_mesaint.h" +#include "dri_tmm.h" + +#include "xf86drm.h" +#include "xf86drmRadeon.h" + +#include "types.h" + +#include "radeon_sarea.h" +#include "radeon_reg.h" + +struct radeon_context; +typedef struct radeon_context radeonContextRec; +typedef struct radeon_context *radeonContextPtr; + +#include "radeon_lock.h" +#include "radeon_texobj.h" +#include "radeon_screen.h" + +/* Flags for what context state needs to be updated */ +#define RADEON_NEW_ALPHA 0x0001 +#define RADEON_NEW_DEPTH 0x0002 +#define RADEON_NEW_FOG 0x0004 +#define RADEON_NEW_CLIP 0x0008 +#define RADEON_NEW_CULL 0x0010 +#define RADEON_NEW_MASKS 0x0020 +#define RADEON_NEW_WINDOW 0x0040 +#define RADEON_NEW_TEXTURE 0x0080 +#define RADEON_NEW_CONTEXT 0x0100 +#define RADEON_NEW_ALL 0x01ff + +/* Flags for software fallback cases */ +#define RADEON_FALLBACK_TEXTURE 0x0001 +#define RADEON_FALLBACK_DRAW_BUFFER 0x0002 +#define RADEON_FALLBACK_READ_BUFFER 0x0004 +#define RADEON_FALLBACK_STENCIL 0x0008 +#define RADEON_FALLBACK_RENDER_MODE 0x0010 +#define RADEON_FALLBACK_MULTIDRAW 0x0020 +#define RADEON_FALLBACK_LOGICOP 0x0040 + +typedef void (*radeon_interp_func)( GLfloat t, + GLfloat *result, + const GLfloat *in, + const GLfloat *out ); + +struct radeon_elt_tab { + void (*emit_unclipped_verts)( struct vertex_buffer *VB ); + + void (*build_tri_verts)( radeonContextPtr rmesa, + struct vertex_buffer *VB, + GLfloat *O, GLuint *elt ); + + void (*interp)( GLfloat t, GLfloat *O, + const GLfloat *I, const GLfloat *J ); + + void (*project_and_emit_verts)( radeonContextPtr rmesa, + const GLfloat *verts, + GLuint *elts, + GLuint nr ); +}; + +struct radeon_context { + GLcontext *glCtx; /* Mesa context */ + + /* Driver and hardware state management + */ + GLuint new_state; + GLuint dirty; /* Hardware state to be updated */ + radeon_context_regs_t setup; + + GLuint vertsize; + GLuint vc_format; + GLfloat depth_scale; + + CARD32 Color; /* Current draw color */ + CARD32 ClearColor; /* Color used to clear color buffer */ + CARD32 ClearDepth; /* Value used to clear depth buffer */ + CARD32 ClearStencil; /* Value used to clear stencil */ + + /* Map GL texture units onto hardware + */ + GLint multitex; + GLint tmu_source[RADEON_MAX_TEXTURE_UNITS]; + GLint tex_dest[RADEON_MAX_TEXTURE_UNITS]; + GLuint color_combine[RADEON_MAX_TEXTURE_UNITS]; + GLuint alpha_combine[RADEON_MAX_TEXTURE_UNITS]; + GLuint env_color[RADEON_MAX_TEXTURE_UNITS]; + GLuint lod_bias[RADEON_MAX_TEXTURE_UNITS]; + + /* Texture object bookkeeping + */ + radeonTexObjPtr CurrentTexObj[RADEON_MAX_TEXTURE_UNITS]; + radeonTexObj TexObjList[RADEON_NR_TEX_HEAPS]; + radeonTexObj SwappedOut; + memHeap_t *texHeap[RADEON_NR_TEX_HEAPS]; + GLint lastTexAge[RADEON_NR_TEX_HEAPS]; + GLint lastTexHeap; + + /* Current rendering state, fallbacks + */ + points_func PointsFunc; + line_func LineFunc; + triangle_func TriangleFunc; + quad_func QuadFunc; + + GLuint IndirectTriangles; + GLuint Fallback; + + /* Fast path + */ + GLuint SetupIndex; + GLuint SetupDone; + GLuint RenderIndex; + GLuint OnFastPath; + radeon_interp_func interp; + GLfloat *tmp_matrix; + + /* Vertex buffers + */ + drmBufPtr vert_buf; + GLuint vert_prim; + GLuint num_verts; + + /* Elt path + */ + drmBufPtr elt_buf, retained_buf; + GLushort *first_elt, *next_elt; + GLfloat *next_vert, *vert_heap; + GLushort next_vert_index; + GLushort first_vert_index; + GLuint elt_vertsize; + struct radeon_elt_tab *elt_tab; + GLfloat device_matrix[16]; + + /* Page flipping + */ + GLuint doPageFlip; + GLuint currentPage; + + /* Drawable, cliprect and scissor information + */ + GLenum DrawBuffer; /* Optimize draw buffer update */ + GLint drawOffset, drawPitch; + GLint readOffset, readPitch; + + GLuint numClipRects; /* Cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; + + GLuint scissor; + XF86DRIClipRectRec scissor_rect; /* Current software scissor */ + + /* Mirrors of some DRI state + */ + Display *display; /* X server display */ + + __DRIcontextPrivate *driContext; /* DRI context */ + __DRIscreenPrivate *driScreen; /* DRI screen */ + __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ + + drmContext hHWContext; + drmLock *driHwLock; + int driFd; + + radeonScreenPtr radeonScreen; /* Screen private DRI data */ + RADEONSAREAPrivPtr sarea; /* Private SAREA data */ + + /* Performance counters + */ + GLuint boxes; /* Draw performance boxes */ + GLuint hardwareWentIdle; + GLuint c_clears; + GLuint c_drawWaits; + GLuint c_textureSwaps; + GLuint c_textureBytes; + GLuint c_vertexBuffers; +}; + +#define RADEON_CONTEXT(ctx) ((radeonContextPtr)(ctx->DriverCtx)) + + +extern GLboolean radeonCreateContext( Display *dpy, GLvisual *glVisual, + __DRIcontextPrivate *driContextPriv ); +extern void radeonDestroyContext( radeonContextPtr rmesa ); +extern radeonContextPtr radeonMakeCurrent( radeonContextPtr oldCtx, + radeonContextPtr newCtx, + __DRIdrawablePrivate *dPriv ); + + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 0 +#define ENABLE_PERF_BOXES 0 + +#if DO_DEBUG +extern int RADEON_DEBUG; +#else +#define RADEON_DEBUG 0 +#endif + +#define DEBUG_ALWAYS_SYNC 0x01 +#define DEBUG_VERBOSE_API 0x02 +#define DEBUG_VERBOSE_MSG 0x04 +#define DEBUG_VERBOSE_LRU 0x08 +#define DEBUG_VERBOSE_DRI 0x10 +#define DEBUG_VERBOSE_IOCTL 0x20 +#define DEBUG_VERBOSE_2D 0x40 + +#endif +#endif /* __RADEON_CONTEXT_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c new file mode 100644 index 000000000..52cf810cc --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c @@ -0,0 +1,217 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c,v 1.3 2001/01/21 21:19:09 tsi Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" +#include "radeon_dd.h" + +#include "extensions.h" +#if defined(USE_X86_ASM) || defined(USE_3DNOW_ASM) || defined(USE_KATMAI_ASM) +#include "X86/common_x86_asm.h" +#endif + +#define RADEON_DATE "20010105" + + +/* Return the width and height of the current color buffer. + */ +static void radeonDDGetBufferSize( GLcontext *ctx, + GLuint *width, GLuint *height ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + LOCK_HARDWARE( rmesa ); + *width = rmesa->driDrawable->w; + *height = rmesa->driDrawable->h; + UNLOCK_HARDWARE( rmesa ); +} + +/* Return various strings for glGetString(). + */ +static const GLubyte *radeonDDGetString( GLcontext *ctx, GLenum name ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + static char buffer[128]; + + switch ( name ) { + case GL_VENDOR: + return (GLubyte *)"VA Linux Systems, Inc."; + + case GL_RENDERER: + sprintf( buffer, "Mesa DRI Radeon " RADEON_DATE ); + + /* Append any chipset-specific information. None yet. + */ + + /* Append any AGP-specific information. + */ + switch ( rmesa->radeonScreen->AGPMode ) { + case 1: + strncat( buffer, " AGP 1x", 7 ); + break; + case 2: + strncat( buffer, " AGP 2x", 7 ); + break; + case 4: + strncat( buffer, " AGP 4x", 7 ); + break; + } + + /* Append any CPU-specific information. + */ +#ifdef USE_X86_ASM + if ( gl_x86_cpu_features ) { + strncat( buffer, " x86", 4 ); + } +#endif +#ifdef USE_3DNOW_ASM + if ( cpu_has_3dnow ) { + strncat( buffer, "/3DNow!", 7 ); + } +#endif +#ifdef USE_KATMAI_ASM + if ( cpu_has_xmm ) { + strncat( buffer, "/SSE", 4 ); + } +#endif + return (GLubyte *)buffer; + + default: + return NULL; + } +} + +/* Send all commands to the hardware. If vertex buffers or indirect + * buffers are in use, then we need to make sure they are sent to the + * hardware. All commands that are normally sent to the ring are + * already considered `flushed'. + */ +static void radeonDDFlush( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + +#if ENABLE_PERF_BOXES + if ( rmesa->boxes ) { + LOCK_HARDWARE( rmesa ); + radeonPerformanceBoxesLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); + } + + /* Log the performance counters if necessary */ + radeonPerformanceCounters( rmesa ); +#endif +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +static void radeonDDFinish( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + rmesa->c_drawWaits++; +#endif + + radeonDDFlush( ctx ); + radeonWaitForIdle( rmesa ); +} + +/* Return various parameters requested by Mesa (this is deprecated). + */ +static GLint radeonDDGetParameteri( const GLcontext *ctx, GLint param ) +{ + switch ( param ) { + case DD_HAVE_HARDWARE_FOG: + return 1; + default: + return 0; + } +} + +/* Initialize the extensions supported by this driver. + */ +void radeonDDInitExtensions( GLcontext *ctx ) +{ + gl_extensions_disable( ctx, "GL_ARB_imaging" ); + gl_extensions_disable( ctx, "GL_ARB_texture_compression" ); + gl_extensions_disable( ctx, "GL_ARB_texture_cube_map" ); + + gl_extensions_disable( ctx, "GL_EXT_blend_color" ); + gl_extensions_disable( ctx, "GL_EXT_blend_logic_op" ); + gl_extensions_disable( ctx, "GL_EXT_blend_minmax" ); + gl_extensions_disable( ctx, "GL_EXT_blend_subtract" ); + gl_extensions_disable( ctx, "GL_EXT_convolution" ); + gl_extensions_disable( ctx, "GL_EXT_paletted_texture" ); + gl_extensions_disable( ctx, "GL_EXT_point_parameters" ); + gl_extensions_disable( ctx, "GL_EXT_shared_texture_palette" ); + gl_extensions_enable( ctx, "GL_EXT_texture_env_combine" ); + gl_extensions_enable( ctx, "GL_EXT_texture_env_dot3" ); + + gl_extensions_disable( ctx, "GL_HP_occlusion_test" ); + + gl_extensions_disable( ctx, "GL_INGR_blend_func_separate" ); + + gl_extensions_disable( ctx, "GL_SGI_color_matrix" ); + gl_extensions_disable( ctx, "GL_SGI_color_table" ); + gl_extensions_disable( ctx, "GL_SGIX_pixel_texture" ); +} + +/* Initialize the driver's misc functions. + */ +void radeonDDInitDriverFuncs( GLcontext *ctx ) +{ + ctx->Driver.GetBufferSize = radeonDDGetBufferSize; + ctx->Driver.GetString = radeonDDGetString; + ctx->Driver.Finish = radeonDDFinish; + ctx->Driver.Flush = radeonDDFlush; + + ctx->Driver.Error = NULL; + ctx->Driver.GetParameteri = radeonDDGetParameteri; + + ctx->Driver.DrawPixels = NULL; + ctx->Driver.Bitmap = NULL; + + ctx->Driver.RegisterVB = radeonDDRegisterVB; + ctx->Driver.UnregisterVB = radeonDDUnregisterVB; + ctx->Driver.BuildPrecalcPipeline = radeonDDBuildPrecalcPipeline; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h new file mode 100644 index 000000000..5e16e5e62 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h @@ -0,0 +1,46 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h,v 1.1 2001/01/08 01:07:26 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_DD_H__ +#define __RADEON_DD_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonDDInitExtensions( GLcontext *ctx ); +extern void radeonDDInitDriverFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c new file mode 100644 index 000000000..6b2f36614 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c @@ -0,0 +1,504 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c,v 1.1 2001/01/08 01:07:26 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + */ + +#include <stdio.h> + +#include "radeon_context.h" +#include "radeon_pipeline.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_state.h" +#include "radeon_vb.h" + +#include "types.h" +#include "enums.h" +#include "cva.h" +#include "vertices.h" +#include "mmath.h" +#include "xform.h" + +/* Always use a full-sized stride for vertices. [FIXME] + * Stride in the buffers must be a quadword multiple. + */ +#define CLIP_STRIDE 10 + +static void fire_elts( radeonContextPtr rmesa ) +{ + GLuint vertsize = rmesa->vertsize; + + LOCK_HARDWARE( rmesa ); + + /* Fire queued elements and discard that buffer if its contents + * won't be referenced by future elements. + */ + if ( rmesa->elt_buf ) + { + GLuint retain = (rmesa->elt_buf == rmesa->retained_buf); + + if ( rmesa->first_elt != rmesa->next_elt ) { + radeonFireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), + !retain ); + } else if ( !retain ) { + radeonReleaseBufLocked( rmesa, rmesa->elt_buf ); + } + + rmesa->elt_buf = 0; + } + else if ( rmesa->vert_buf ) + { + radeonFlushVerticesLocked( rmesa ); + } + + radeonGetEltBufLocked( rmesa ); + + UNLOCK_HARDWARE( rmesa ); + + /* Give the compiler a chance to optimize the divisions. + */ + switch ( vertsize ) { + case 8: + rmesa->next_vert_index = (GLushort) + (((rmesa->elt_buf->idx + 1) * + RADEON_BUFFER_SIZE / (8 * sizeof(GLuint))) - 1); + rmesa->next_vert = (GLfloat *) + ((GLuint)rmesa->vert_heap + + rmesa->next_vert_index * 8 * sizeof(GLfloat)); + break; + + case 10: + rmesa->next_vert_index = (GLushort) + (((rmesa->elt_buf->idx + 1) * + RADEON_BUFFER_SIZE / (10 * sizeof(GLuint))) - 1); + rmesa->next_vert = (GLfloat *) + ((GLuint)rmesa->vert_heap + + rmesa->next_vert_index * 10 * sizeof(GLfloat)); + break; + } + + rmesa->first_elt = rmesa->next_elt = (GLushort *) + ((GLubyte *)rmesa->elt_buf->address + RADEON_INDEX_PRIM_OFFSET); + + rmesa->elt_vertsize = vertsize; +} + + +static void release_bufs( radeonContextPtr rmesa ) +{ + if ( rmesa->retained_buf && rmesa->retained_buf != rmesa->elt_buf ) + { + LOCK_HARDWARE( rmesa ); + if ( rmesa->first_elt != rmesa->next_elt ) { + radeonFireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), + 0 ); + + ALIGN_NEXT_ELT( rmesa ); + rmesa->first_elt = rmesa->next_elt; + } + + radeonReleaseBufLocked( rmesa, rmesa->retained_buf ); + UNLOCK_HARDWARE( rmesa ); + } + + rmesa->retained_buf = 0; +} + + + + +#define NEGATIVE( f ) (f < 0) +#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0) +#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) + + +#define INTERP_RGBA( t, out, a, b ) { \ + GLuint i; \ + for ( i = 0 ; i < 4 ; i++ ) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \ + GLfloat fo = LINTERP( t, fa, fb ); \ + FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \ + } \ +} + + +#define CLIP( SGN, V, PLANE ) \ +do { \ + if ( mask & PLANE ) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]]; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + for ( i = n = 0 ; i < nr ; i++ ) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i]; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ + GLfloat *O = verts[next_vert]; \ + outdata[n++] = next_vert++; \ + \ + if ( NEGATIVE( dpI ) ) { \ + GLfloat t = dpI / (dpI - dpJ); \ + interp( t, O, I, J ); \ + } \ + else \ + { \ + GLfloat t = dpJ / (dpJ - dpI); \ + interp( t, O, J, I ); \ + } \ + } \ + \ + if ( !NEGATIVE( dpI ) ) \ + outdata[n++] = elt_i; \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if ( n < 3 ) return; \ + } \ +} while (0) + + +static void radeon_tri_clip( radeonContextPtr rmesa, + struct vertex_buffer *VB, + GLuint *elt, + GLubyte mask ) +{ + struct radeon_elt_tab *tab = rmesa->elt_tab; + radeon_interp_func interp = tab->interp; + GLuint vertsize = rmesa->vertsize; + GLuint inlist[2][VB_MAX_CLIPPED_VERTS]; + GLuint in = 0; + GLuint n = 3, next_vert = 3; + GLuint i; + GLfloat verts[VB_MAX_CLIPPED_VERTS][CLIP_STRIDE]; + + /* Build temporary vertices in clipspace. This is the potential + * downside to this path. + */ + tab->build_tri_verts( rmesa, VB, (GLfloat *)verts, elt ); + + inlist[0][0] = 0; + inlist[0][1] = 1; + inlist[0][2] = 2; + + CLIP( -, 0, CLIP_RIGHT_BIT ); + CLIP( +, 0, CLIP_LEFT_BIT ); + CLIP( -, 1, CLIP_TOP_BIT ); + CLIP( +, 1, CLIP_BOTTOM_BIT ); + CLIP( -, 2, CLIP_FAR_BIT ); + CLIP( +, 2, CLIP_NEAR_BIT ); + + + { + GLuint *out = inlist[in]; + GLint space = (GLint)((GLuint)rmesa->next_vert - + (GLuint)rmesa->next_elt); + + if ( space < (GLint)(n * (vertsize + 2) * sizeof(GLuint)) ) { + fire_elts( rmesa ); + } + + /* Project the new vertices and emit to dma buffers. Translate + * out values to physical addresses for setup dma. + */ + tab->project_and_emit_verts( rmesa, (GLfloat *)verts, out, n ); + + /* Convert the planar polygon to a list of triangles and emit to + * elt buffers. + */ + for ( i = 2 ; i < n ; i++ ) { + rmesa->next_elt[0] = (GLushort) out[0]; + rmesa->next_elt[1] = (GLushort) out[i-1]; + rmesa->next_elt[2] = (GLushort) out[i]; + rmesa->next_elt += 3; + } + } +} + + + + +/* Build a table of functions to clip each primitive type. These + * produce a list of elements in the appropriate 'reduced' primitive, + * ie (points, lines, triangles) containing all the clipped and + * unclipped primitives from the original list. + */ + +#define INIT( x ) + +#define TRI_THRESHOLD (GLint)(2 * sizeof(GLuint)) + +#define UNCLIPPED_VERT( x ) (GLushort)(rmesa->first_vert_index - x) + +#define TRIANGLE( e2, e1, e0 ) \ +do { \ + if ( (GLint)((GLuint)rmesa->next_vert - \ + (GLuint)rmesa->next_elt) < TRI_THRESHOLD ) { \ + fire_elts( rmesa ); \ + } \ + rmesa->next_elt[0] = UNCLIPPED_VERT( e2 ); \ + rmesa->next_elt[1] = UNCLIPPED_VERT( e1 ); \ + rmesa->next_elt[2] = UNCLIPPED_VERT( e0 ); \ + rmesa->next_elt += 3; \ +} while (0) + +#define CLIP_TRIANGLE( e2, e1, e0 ) \ +do { \ + GLubyte ormask = mask[e2] | mask[e1] | mask[e0]; \ + if ( ormask == 0 ) { \ + TRIANGLE( e2, e1, e0 ); \ + } else if ( (mask[e2] & mask[e1] & mask[e0]) == 0 ) { \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + radeon_tri_clip( rmesa, VB, out, ormask ); \ + } \ +} while (0) + +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \ + GLuint *elt = VB->EltPtr->data; \ + GLuint out[VB_MAX_CLIPPED_VERTS]; \ + GLubyte *mask = VB->ClipMask; \ + (void) mask; (void) out; (void) elt; (void) rmesa; + + + +#define RENDER_POINTS( start, count ) +#define RENDER_LINE( i1, i0 ) +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ + CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ) + +#define TAG(x) radeon_##x##_elt +#include "render_tmp.h" + + + +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \ + GLuint *elt = VB->EltPtr->data; \ + (void) elt; (void) rmesa; + +#define RENDER_POINTS( start, count ) +#define RENDER_LINE( i1, i0 ) +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ + TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ + TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + TRIANGLE( elt[i2], elt[i1], elt[i0] ) + +#define TAG(x) radeon_##x##_elt_unclipped +#include "render_tmp.h" + + + + +static void refresh_projection_matrix( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLmatrix *mat = &ctx->Viewport.WindowMap; + GLfloat *m = rmesa->device_matrix; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY]; + m[MAT_SZ] = mat->m[MAT_SZ]; + m[MAT_TZ] = mat->m[MAT_TZ]; +} + +#define CLIP_UBYTE_R 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_B 2 +#define CLIP_UBYTE_A 3 + + +#define TYPE (0) +#define TAG(x) x +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "radeon_elttmp.h" + +#define TYPE (RADEON_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT|RADEON_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "radeon_elttmp.h" + +#define TYPE (RADEON_TEX0_BIT|RADEON_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "radeon_elttmp.h" + + +/* Very sparsely popluated array - fix the indices. + */ +static struct radeon_elt_tab radeonEltTab[RADEON_MAX_SETUPFUNC]; + +void radeonDDEltPathInit( void ) +{ + radeon_render_init_elt(); + radeon_render_init_elt_unclipped(); + + radeon_init_eltpath( &radeonEltTab[0] ); + radeon_init_eltpath_RGBA( &radeonEltTab[RADEON_RGBA_BIT] ); + radeon_init_eltpath_TEX0( &radeonEltTab[RADEON_TEX0_BIT] ); + radeon_init_eltpath_RGBA_TEX0( &radeonEltTab[(RADEON_RGBA_BIT | + RADEON_TEX0_BIT)] ); + radeon_init_eltpath_TEX0_TEX1( &radeonEltTab[(RADEON_TEX0_BIT | + RADEON_TEX1_BIT)] ); + radeon_init_eltpath_RGBA_TEX0_TEX1( &radeonEltTab[(RADEON_RGBA_BIT | + RADEON_TEX0_BIT | + RADEON_TEX1_BIT)] ); +} + +#define VALID_SETUP (RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT) + + + +/* Use a temporary array for device coordinates, so that we can easily + * tap into existing mesa assembly. Otherwise consider emitting + * device coordinates to dma buffers directly from the project/cliptest + * routine. (requires output stride, potential loss of writecombining + * efficiency?) + * + * This path is a lot closer to the standard vertex path in the + * initial stages than the original fastpath. A slightly more optimal + * path could be constructed, but would require us to write new + * assembly. + */ +void radeonDDEltPath( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct radeon_elt_tab *tab = + &radeonEltTab[rmesa->SetupIndex & VALID_SETUP]; + GLint vertsize = rmesa->vertsize; + GLint space; + + VB->ClipPtr = TransformRaw( &VB->Clip, + &ctx->ModelProjectMatrix, + VB->ObjPtr ); + + refresh_projection_matrix( ctx ); + + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + VB->Projected = gl_clip_tab[VB->ClipPtr->size]( VB->ClipPtr, + &VB->Win, + VB->ClipMask, + &VB->ClipOrMask, + &VB->ClipAndMask ); + + if ( VB->ClipAndMask ) + return; + + if ( rmesa->vert_buf ) + radeonFlushVertices( rmesa ); + + if ( rmesa->new_state ) + radeonDDUpdateHWState( ctx ); + + space = (GLint)((GLuint)rmesa->next_vert - + (GLuint)rmesa->next_elt); + + /* Allocate a single buffer to hold unclipped vertices. All + * unclipped vertices must be contiguous. + */ + if ( space < (GLint)(VB->Count * vertsize * sizeof(GLuint)) || + rmesa->vertsize != rmesa->elt_vertsize ) { + fire_elts( rmesa ); + } + + rmesa->retained_buf = rmesa->elt_buf; + + /* Emit unclipped vertices to the buffer. + */ + tab->emit_unclipped_verts( VB ); + + /* Emit indices and clipped vertices to one or more buffers. + */ + if ( VB->ClipOrMask ) { + rmesa->elt_tab = tab; + radeon_render_tab_elt[prim]( VB, 0, VB->EltPtr->count, 0 ); + } else { + radeon_render_tab_elt_unclipped[prim]( VB, 0, VB->EltPtr->count, 0 ); + } + + /* Send to hardware and release the elt buffer. + */ + release_bufs( rmesa ); + + /* This indicates that there is no cached data to reuse. + */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; + + FLUSH_BATCH( rmesa ); +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h new file mode 100644 index 000000000..56c0ccedd --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h @@ -0,0 +1,246 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +/* Buffers fill from high addresses down with vertices and from low + * addresses up with elements. + */ + + +/* Emit the bulk of the vertices to the first dma buffer. Leave + * empty slots for clipped vertices so that we can still address + * vertices by index. + */ +static void TAG(emit_unclipped_verts)( struct vertex_buffer *VB ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); + GLfloat *dev = VB->Projected->start; + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + GLuint buffer_stride = rmesa->vertsize; + + GLfloat *f = rmesa->next_vert; + GLuint count = VB->Count; + GLubyte *clipmask = VB->ClipMask; + + const GLfloat *m = rmesa->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLuint i; + + rmesa->retained_buf = rmesa->elt_buf; + rmesa->first_vert_index = rmesa->next_vert_index; + + for ( i = 0 ; i < count ; f -= buffer_stride, i++ ) + { + if ( !clipmask[i] ) + { + f[0] = sx * dev[0] + tx; + f[1] = sy * dev[1] + ty; + f[2] = sz * dev[2] + tz; + f[3] = dev[3]; + + if ( TYPE & RADEON_RGBA_BIT ) { + *(GLuint *)&f[4] = *(GLuint *)color; + } + + if ( TYPE & RADEON_TEX0_BIT ) { + *(GLuint *)&f[6] = *(GLuint *)&tex0_data[0]; + *(GLuint *)&f[7] = *(GLuint *)&tex0_data[1]; + } + + if ( TYPE & RADEON_TEX1_BIT ) { + *(GLuint *)&f[8] = *(GLuint *)&tex1_data[0]; + *(GLuint *)&f[9] = *(GLuint *)&tex1_data[1]; + } + } + + STRIDE_F( dev, 16 ); + if ( TYPE & RADEON_RGBA_BIT ) color += color_stride; + if ( TYPE & RADEON_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); + if ( TYPE & RADEON_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); + } + + rmesa->next_vert = f; + rmesa->next_vert_index -= count; +} + + +/* Build three temporary clipspace vertex for clipping a triangle. + * Recreate from the VB data rather than trying to read back from + * uncached memory. + */ +static void TAG(build_tri_verts)( radeonContextPtr rmesa, + struct vertex_buffer *VB, + GLfloat *O, + GLuint *elt ) +{ + GLint i; + + for ( i = 0 ; i < 3 ; i++, O += CLIP_STRIDE ) { + GLfloat *clip = VB->Clip.start + elt[i]*4; + + O[0] = clip[0]; + O[1] = clip[1]; + O[2] = clip[2]; + O[3] = clip[3]; + + if ( TYPE & RADEON_RGBA_BIT ) { + GLubyte *color = VEC_ELT(VB->ColorPtr, GLubyte, elt[i]); + *(GLuint *)&O[4] = *(GLuint *)color; + } + + *(GLuint *)&O[5] = UNCLIPPED_VERT(elt[i]); + + if ( TYPE & RADEON_TEX0_BIT ) { + GLfloat *tex0_data = VEC_ELT(VB->TexCoordPtr[0], GLfloat, elt[i]); + *(GLuint *)&O[6] = *(GLuint *)&tex0_data[0]; + *(GLuint *)&O[7] = *(GLuint *)&tex0_data[1]; + } + + if ( TYPE & RADEON_TEX1_BIT ) { + GLfloat *tex1_data = VEC_ELT(VB->TexCoordPtr[1], GLfloat, elt[i]); + *(GLuint *)&O[8] = *(GLuint *)&tex1_data[0]; + *(GLuint *)&O[9] = *(GLuint *)&tex1_data[1]; + } + } +} + + +/* Interpolate between two of the vertices constructed above. + */ +static void TAG(interp)( GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J ) +{ + O[0] = LINTERP( t, I[0], J[0] ); + O[1] = LINTERP( t, I[1], J[1] ); + O[2] = LINTERP( t, I[2], J[2] ); + O[3] = LINTERP( t, I[3], J[3] ); + + if ( TYPE & RADEON_RGBA_BIT ) { + INTERP_RGBA( t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4])) ); + } + + *(GLuint *)&O[5] = ~0; /* note that this is a new vertex */ + + if ( TYPE & RADEON_TEX0_BIT ) { + O[6] = LINTERP( t, I[6], J[6] ); + O[7] = LINTERP( t, I[7], J[7] ); + } + + if ( TYPE & RADEON_TEX1_BIT ) { + O[8] = LINTERP( t, I[8], J[8] ); + O[9] = LINTERP( t, I[9], J[9] ); + } +} + + + +/* When clipping is complete, scan the final vertex list and emit any + * new ones to dma buffers. Update the element list to a format + * suitable for sending to hardware. + */ +static void TAG(project_and_emit_verts)( radeonContextPtr rmesa, + const GLfloat *verts, + GLuint *elt, + GLuint nr) +{ + GLfloat *O = rmesa->next_vert; + GLushort index = rmesa->next_vert_index; + GLuint buffer_stride = rmesa->vertsize; + + const GLfloat *m = rmesa->device_matrix; + const GLfloat sx = m[0], sy = m[5], sz = m[10]; + const GLfloat tx = m[12], ty = m[13], tz = m[14]; + GLuint i; + + for ( i = 0 ; i < nr ; i++ ) { + const GLfloat *I = &verts[elt[i] * CLIP_STRIDE]; + GLuint tmp = *(GLuint *)&I[5]; + + if ( (elt[i] = tmp) == ~0 ) { + GLfloat oow = 1.0 / I[3]; + + elt[i] = index--; + + O[0] = sx * I[0] * oow + tx; + O[1] = sy * I[1] * oow + ty; + O[2] = sz * I[2] * oow + tz; + O[3] = oow; + + if ( TYPE & RADEON_RGBA_BIT ) { + *(GLuint *)&O[4] = *(GLuint *)&I[4]; + } + + if ( TYPE & RADEON_TEX0_BIT ) { + *(GLuint *)&O[6] = *(GLuint *)&I[6]; + *(GLuint *)&O[7] = *(GLuint *)&I[7]; + } + + if ( TYPE & RADEON_TEX1_BIT ) { + *(GLuint *)&O[8] = *(GLuint *)&I[8]; + *(GLuint *)&O[9] = *(GLuint *)&I[9]; + } + + O -= buffer_stride; + } + } + + rmesa->next_vert = O; + rmesa->next_vert_index = index; +} + + + +static void TAG(radeon_init_eltpath)( struct radeon_elt_tab *tab ) +{ + tab->emit_unclipped_verts = TAG(emit_unclipped_verts); + tab->build_tri_verts = TAG(build_tri_verts); + tab->interp = TAG(interp); + tab->project_and_emit_verts = TAG(project_and_emit_verts); +} + +#undef TYPE +#undef TAG +#undef STRIDE diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c new file mode 100644 index 000000000..1ff701435 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c @@ -0,0 +1,542 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_state.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" + +#include "mmath.h" +#include "cva.h" +#include "vertices.h" + + +struct radeon_fast_tab { + void (*build_vertices)( struct vertex_buffer *VB, GLuint do_cliptest ); + void (*interp)( GLfloat t, GLfloat *O, const GLfloat *I, const GLfloat *J ); +}; + +#define POINT(x) radeon_draw_point( rmesa, &vert[x], psize ) +#define LINE(x,y) radeon_draw_line( rmesa, &vert[x], &vert[y], lwidth ) +#define TRI(x,y,z) radeon_draw_triangle( rmesa, &vert[x], &vert[y], &vert[z] ) + + +/* Direct, and no clipping required. The clip funcs have not been + * written yet, so this is only useful for the fast path. + */ +#define RENDER_POINTS( start, count ) \ +do { \ + GLuint e; \ + for ( e = start ; e < count ; e++ ) \ + POINT( elt[e] ); \ +} while (0) + +#define RENDER_LINE( i1, i ) \ +do { \ + GLuint e1 = elt[i1], e = elt[i]; \ + LINE( e1, e ); \ +} while (0) + +#define RENDER_TRI( i2, i1, i, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + if ( parity ) { \ + GLuint tmp = e2; \ + e2 = e1; \ + e1 = tmp; \ + } \ + TRI( e2, e1, e ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i, pv ) \ +do { \ + GLuint e3 = elt[i3], e2 = elt[i2], e1 = elt[i1], e = elt[i]; \ + TRI( e3, e2, e ); \ + TRI( e2, e1, e ); \ +} while (0) + +#define LOCAL_VARS \ + radeonVertexPtr vert = RADEON_DRIVER_DATA(VB)->verts; \ + const GLuint *elt = VB->EltPtr->data; \ + GLcontext *ctx = VB->ctx; \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + const GLfloat lwidth = ctx->Line.Width; \ + const GLfloat psize = ctx->Point.Size; \ + (void) lwidth; (void) psize; (void) vert; + +#define TAG(x) radeon_##x##_smooth_indirect +#include "render_tmp.h" + + + +#define NEGATIVE( f ) (f < 0) +#define DIFFERENT_SIGNS( a, b ) ((a * b) < 0) +#define LINTERP( T, A, B ) ((A) + (T) * ((B) - (A))) + + +#define INTERP_RGBA( t, out, a, b ) \ +do { \ + int i; \ + for ( i = 0 ; i < 4 ; i++ ) { \ + GLfloat fa = UBYTE_COLOR_TO_FLOAT_COLOR( a[i] ); \ + GLfloat fb = UBYTE_COLOR_TO_FLOAT_COLOR( b[i] ); \ + GLfloat fo = LINTERP( t, fa, fb ); \ + FLOAT_COLOR_TO_UBYTE_COLOR( out[i], fo ); \ + } \ +} while (0) + + +#define CLIP( SGN, V, PLANE ) \ +do { \ + if ( mask & PLANE ) { \ + GLuint *indata = inlist[in]; \ + GLuint *outdata = inlist[in ^= 1]; \ + GLuint nr = n; \ + GLfloat *J = verts[indata[nr-1]].f; \ + GLfloat dpJ = (SGN J[V]) + J[3]; \ + \ + inlist[0] = vlist1; \ + for ( i = n = 0 ; i < nr ; i++ ) { \ + GLuint elt_i = indata[i]; \ + GLfloat *I = verts[elt_i].f; \ + GLfloat dpI = (SGN I[V]) + I[3]; \ + \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t, *in, *out; \ + \ + if ( NEGATIVE( dpI ) ) { \ + t = dpI / (dpI - dpJ); \ + in = I; \ + out = J; \ + } else { \ + t = dpJ / (dpJ - dpI); \ + in = J; \ + out = I; \ + } \ + \ + interp( t, O, in, out ); \ + \ + clipmask[next_vert] = 0; \ + outdata[n++] = next_vert++; \ + } \ + \ + clipmask[elt_i] |= PLANE; /* don't set up */ \ + \ + if ( !NEGATIVE( dpI ) ) { \ + outdata[n++] = elt_i; \ + clipmask[elt_i] &= ~PLANE; /* set up after all */ \ + } \ + \ + J = I; \ + dpJ = dpI; \ + } \ + \ + if ( n < 3 ) return; \ + } \ +} while (0) + +#define LINE_CLIP( x, y, z, w, PLANE ) \ +do { \ + if ( mask & PLANE ) { \ + GLfloat dpI = DOT4V( I, x, y, z, w); \ + GLfloat dpJ = DOT4V( J, x, y, z, w); \ + \ + if ( DIFFERENT_SIGNS( dpI, dpJ ) ) { \ + GLfloat *O = verts[next_vert].f; \ + GLfloat t = dpI / (dpI - dpJ); \ + \ + interp( t, O, I, J ); \ + \ + clipmask[next_vert] = 0; \ + \ + if ( NEGATIVE( dpI ) ) { \ + clipmask[elts[0]] |= PLANE; \ + I = O; \ + elts[0] = next_vert++; \ + } else { \ + clipmask[elts[1]] |= PLANE; \ + J = O; \ + elts[1] = next_vert++; \ + } \ + } else if ( NEGATIVE( dpI ) ) return; \ + } \ +} while (0) + + +static __inline void radeon_tri_clip( GLuint **p_elts, + radeonVertexPtr verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + radeon_interp_func interp ) +{ + GLuint *elts = *p_elts; + GLuint next_vert = *p_next_vert; + GLuint in = 0; + GLuint n = 3; + GLuint vlist1[VB_MAX_CLIPPED_VERTS]; + GLuint vlist2[VB_MAX_CLIPPED_VERTS]; + GLuint *inlist[2]; + GLuint *out; + GLuint i; + + inlist[0] = elts; + inlist[1] = vlist2; + + CLIP( -, 0, CLIP_RIGHT_BIT ); + CLIP( +, 0, CLIP_LEFT_BIT ); + CLIP( -, 1, CLIP_TOP_BIT ); + CLIP( +, 1, CLIP_BOTTOM_BIT ); + CLIP( -, 2, CLIP_FAR_BIT ); + CLIP( +, 2, CLIP_NEAR_BIT ); + + /* Convert the planar polygon to a list of triangles */ + out = inlist[in]; + + for ( i = 2 ; i < n ; i++ ) { + elts[0] = out[0]; + elts[1] = out[i-1]; + elts[2] = out[i]; + elts += 3; + } + + *p_next_vert = next_vert; + *p_elts = elts; +} + + +static __inline void radeon_line_clip( GLuint **p_elts, + radeonVertexPtr verts, + GLubyte *clipmask, + GLuint *p_next_vert, + GLubyte mask, + radeon_interp_func interp ) +{ + GLuint *elts = *p_elts; + GLfloat *I = verts[elts[0]].f; + GLfloat *J = verts[elts[1]].f; + GLuint next_vert = *p_next_vert; + + LINE_CLIP( 1, 0, 0, -1, CLIP_LEFT_BIT ); + LINE_CLIP( -1, 0, 0, 1, CLIP_RIGHT_BIT ); + LINE_CLIP( 0, 1, 0, -1, CLIP_TOP_BIT ); + LINE_CLIP( 0, -1, 0, 1, CLIP_BOTTOM_BIT ); + LINE_CLIP( 0, 0, 1, -1, CLIP_FAR_BIT ); + LINE_CLIP( 0, 0, -1, 1, CLIP_NEAR_BIT ); + + *p_next_vert = next_vert; + *p_elts += 2; +} + + + +#define CLIP_POINT( e ) \ +do { \ + if ( mask[e] ) *out++ = e; \ +} while (0) + +#define CLIP_LINE( e1, e0 ) \ +do { \ + GLubyte ormask = mask[e0] | mask[e1]; \ + out[0] = e1; \ + out[1] = e0; \ + out += 2; \ + if ( ormask ) { \ + out-=2; \ + if ( !(mask[e0] & mask[e1]) ) { \ + radeon_line_clip( &out, verts, mask, \ + &next_vert, ormask, interp ); \ + } \ + } \ +} while (0) + +#define CLIP_TRIANGLE( e2, e1, e0 ) \ +do { \ + GLubyte ormask; \ + out[0] = e2; \ + out[1] = e1; \ + out[2] = e0; \ + out += 3; \ + ormask = mask[e2] | mask[e1] | mask[e0]; \ + if ( ormask ) { \ + out -= 3; \ + if ( !(mask[e2] & mask[e1] & mask[e0]) ) { \ + radeon_tri_clip( &out, verts, mask, \ + &next_vert, ormask, interp ); \ + } \ + } \ +} while (0) + + + +/* Build a table of functions to clip each primitive type. These + * produce a list of elements in the appropriate 'reduced' primitive, + * ie (points, lines, triangles) containing all the clipped and + * unclipped primitives from the original list. + */ +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \ + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); \ + GLuint *elt = VB->EltPtr->data; \ + radeonVertexPtr verts = rvb->verts; \ + GLuint next_vert = rvb->last_vert; \ + GLuint *out = rvb->clipped_elements.data; \ + GLubyte *mask = VB->ClipMask; \ + radeon_interp_func interp = rmesa->interp; \ + (void) interp; (void) verts; + +#define POSTFIX \ + rvb->clipped_elements.count = out - rvb->clipped_elements.data; \ + rvb->last_vert = next_vert; + + +#define INIT( x ) + +#define RENDER_POINTS( start, count ) \ +do { \ + GLuint i; \ + for ( i = start; i < count ; i++ ) \ + CLIP_POINT( elt[i] ); \ +} while (0) + +#define RENDER_LINE( i1, i0 ) \ +do { \ + CLIP_LINE( elt[i1], elt[i0] ); \ +} while (0) + +#define RENDER_TRI( i2, i1, i0, pv, parity ) \ +do { \ + GLuint e2 = elt[i2], e1 = elt[i1], e0 = elt[i0]; \ + if ( parity ) e2 = elt[i1], e1 = elt[i2]; \ + CLIP_TRIANGLE( e2, e1, e0 ); \ +} while (0) + +#define RENDER_QUAD( i3, i2, i1, i0, pv ) \ +do { \ + CLIP_TRIANGLE( elt[i3], elt[i2], elt[i0] ); \ + CLIP_TRIANGLE( elt[i2], elt[i1], elt[i0] ); \ +} while (0) + +#define TAG(x) radeon_##x##_clip_elt +#include "render_tmp.h" + + + +/* Pack rgba and/or texture into the remaining half of a 32 byte vertex. + */ +#define CLIP_UBYTE_COLOR 4 +#define CLIP_UBYTE_R 0 +#define CLIP_UBYTE_G 1 +#define CLIP_UBYTE_B 2 +#define CLIP_UBYTE_A 3 +#define CLIP_S0 6 +#define CLIP_T0 7 +#define CLIP_S1 8 +#define CLIP_T1 9 + +#define TYPE (0) +#define TAG(x) x +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT) +#define TAG(x) x##_RGBA +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_TEX0_BIT) +#define TAG(x) x##_TEX0 +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT | RADEON_TEX0_BIT) +#define TAG(x) x##_RGBA_TEX0 +#include "radeon_fasttmp.h" + +#define TYPE (RADEON_RGBA_BIT | RADEON_TEX0_BIT | RADEON_TEX1_BIT) +#define TAG(x) x##_RGBA_TEX0_TEX1 +#include "radeon_fasttmp.h" + +/* This one *could* get away with sneaking TEX1 into the color and + * specular slots, thus fitting inside a cache line. Would be even + * better to switch to a smaller vertex. + */ +#define TYPE (RADEON_TEX0_BIT | RADEON_TEX1_BIT) +#define TAG(x) x##_TEX0_TEX1 +#include "radeon_fasttmp.h" + + + +static void radeon_render_elements_direct( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLenum prim = ctx->CVA.elt_mode; + GLuint nr = VB->EltPtr->count; + render_func func = radeon_render_tab_smooth_indirect[prim]; + GLuint p = 0; + + if ( rmesa->new_state ) + radeonDDUpdateHWState( ctx ); + + do { + func( VB, 0, nr, 0 ); + } while ( ctx->Driver.MultipassFunc && + ctx->Driver.MultipassFunc( VB, ++p ) ); +} + +/* GH: These should go away altogether on the Radeon. We should disable + * the viewport mapping entirely in Mesa and let the hardware do it in + * all cases. + */ +static void radeon_project_vertices( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + GLfloat *m = rmesa->tmp_matrix; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY]; + m[MAT_SZ] = mat->m[MAT_SZ]; + m[MAT_TZ] = mat->m[MAT_TZ]; + + gl_project_v16( rvb->verts[VB->CopyStart].f, + rvb->verts[rvb->last_vert].f, + m, + 16 * 4 ); +} + +static void radeon_project_clipped_vertices( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLmatrix *mat = &ctx->Viewport.WindowMap; + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + GLfloat *m = rmesa->tmp_matrix; + + m[MAT_SX] = mat->m[MAT_SX]; + m[MAT_TX] = mat->m[MAT_TX]; + m[MAT_SY] = -mat->m[MAT_SY]; + m[MAT_TY] = -mat->m[MAT_TY]; + m[MAT_SZ] = mat->m[MAT_SZ]; + m[MAT_TZ] = mat->m[MAT_TZ]; + + gl_project_clipped_v16( rvb->verts[VB->CopyStart].f, + rvb->verts[rvb->last_vert].f, + m, + 16 * 4, + VB->ClipMask + VB->CopyStart ); +} + +static struct radeon_fast_tab radeonFastTab[RADEON_MAX_SETUPFUNC]; + +void radeonDDFastPathInit( void ) +{ + radeon_render_init_clip_elt(); + radeon_render_init_smooth_indirect(); + + radeon_init_fastpath( &radeonFastTab[0] ); + radeon_init_fastpath_RGBA( &radeonFastTab[RADEON_RGBA_BIT] ); + radeon_init_fastpath_TEX0( &radeonFastTab[RADEON_TEX0_BIT] ); + radeon_init_fastpath_RGBA_TEX0( &radeonFastTab[(RADEON_RGBA_BIT | + RADEON_TEX0_BIT)] ); + radeon_init_fastpath_TEX0_TEX1( &radeonFastTab[(RADEON_TEX0_BIT | + RADEON_TEX1_BIT)] ); + radeon_init_fastpath_RGBA_TEX0_TEX1( &radeonFastTab[(RADEON_RGBA_BIT | + RADEON_TEX0_BIT | + RADEON_TEX1_BIT)] ); +} + +#define VALID_SETUP (RADEON_RGBA_BIT | RADEON_TEX0_BIT | RADEON_TEX1_BIT) + +void radeonDDFastPath( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + GLenum prim = ctx->CVA.elt_mode; + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + struct radeon_fast_tab *tab = + &radeonFastTab[rmesa->SetupIndex & VALID_SETUP]; + GLuint do_cliptest = 1; + + gl_prepare_arrays_cva( VB ); /* still need this */ + + if ( ( gl_reduce_prim[prim] == GL_TRIANGLES ) && + ( VB->Count < (RADEON_BUFFER_SIZE / (10 * sizeof(GLuint))) ) && + ( ctx->ModelProjectMatrix.flags & (MAT_FLAG_GENERAL | + MAT_FLAG_PERSPECTIVE) ) ) + { + radeonDDEltPath( VB ); + return; + } + + /* Reserve enough space for the pathological case */ + if ( VB->EltPtr->count * 12 > RADEON_DRIVER_DATA(VB)->size ) { + radeonDDResizeVB( VB, VB->EltPtr->count * 12 ); + do_cliptest = 1; + } + + tab->build_vertices( VB, do_cliptest ); /* object->clip space */ + + if ( rmesa->new_state ) + radeonDDUpdateHWState( ctx ); + + if ( VB->ClipOrMask ) { + if ( !VB->ClipAndMask ) { + render_func *clip = radeon_render_tab_clip_elt; + + rmesa->interp = tab->interp; + + clip[prim]( VB, 0, VB->EltPtr->count, 0 ); /* build new elts */ + + ctx->CVA.elt_mode = gl_reduce_prim[prim]; + VB->EltPtr = &(RADEON_DRIVER_DATA(VB)->clipped_elements); + + radeon_project_clipped_vertices( VB ); /* clip->device space */ + radeon_render_elements_direct( VB ); /* render using new list */ + } + } else { + radeon_project_vertices( VB ); /* clip->device space */ + radeon_render_elements_direct( VB ); /* render using orig list */ + } + + /* This indicates that there is no cached data to reuse */ + VB->pipeline->data_valid = 0; + VB->pipeline->new_state = 0; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h new file mode 100644 index 000000000..dc444aa8a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h @@ -0,0 +1,185 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell <keithw@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +/* The first part of setup is applied to all vertices, clipped or + * unclipped. This data w!ill be used for clipping, and then all + * vertices with a zero clipmask will be projected to device space. + * + * This could be split into several loops, but - it seems that the + * large stride of the fxVertices makes cache issues the big + * performance factor, and that multiple loops mean multiple cache + * misses.... + */ +static void TAG(radeon_setup_full)( struct vertex_buffer *VB, + GLuint do_cliptest ) +{ + GLcontext *ctx = VB->ctx; + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + const GLfloat *m = ctx->ModelProjectMatrix.m; + GLuint start = VB->CopyStart; + GLuint count = VB->Count; + + gl_xform_points3_v16_general( rvb->verts[start].f, + m, + VB->ObjPtr->start, + VB->ObjPtr->stride, + count - start ); + + if ( do_cliptest ) { + VB->ClipAndMask = ~0; + VB->ClipOrMask = 0; + gl_cliptest_points4_v16( rvb->verts[start].f, + rvb->verts[count].f, + &(VB->ClipOrMask), + &(VB->ClipAndMask), + VB->ClipMask + start ); + } + + /* These branches are all resolved at compile time. Hopefully all + * the pointers are valid addresses even when not enabled. + */ + if ( TYPE ) { + GLubyte *color = VB->ColorPtr->start; + GLfloat *tex0_data = VB->TexCoordPtr[0]->start; + GLfloat *tex1_data = VB->TexCoordPtr[1]->start; + + GLuint color_stride = VB->ColorPtr->stride; + GLuint tex0_stride = VB->TexCoordPtr[0]->stride; + GLuint tex1_stride = VB->TexCoordPtr[1]->stride; + + GLfloat *f = rvb->verts[start].f; + GLfloat *end = f + (16 * (count - start)); + + while ( f != end ) { + if ( TYPE & RADEON_RGBA_BIT ) { +#if defined (USE_X86_ASM) + /* GH: Finally! Some damned hardware manufacturer uses + * little-endian RGBA for vertex color... + */ + __asm__ ( "movl (%%ecx), %%eax \n" + "movl %%eax, 16(%%edi) \n" + : + : "c" (color), "D" (f) + : "%eax" ); +#else + *(GLuint *)(f+CLIP_UBYTE_COLOR) = *(GLuint *)color; +#endif + } + if ( TYPE & RADEON_TEX0_BIT ) { +#if defined (USE_X86_ASM) + __asm__ ( "movl (%%ecx), %%eax \n" + "movl %%eax, 24(%%edi) \n" + "movl 4(%%ecx), %%eax \n" + "movl %%eax, 28(%%edi)" + : + : "c" (tex0_data), "D" (f) + : "%eax" ); +#else + *(GLuint *)(f+CLIP_S0) = *(GLuint *)tex0_data; + *(GLuint *)(f+CLIP_T0) = *(GLuint *)(tex0_data+1); +#endif + } + if ( TYPE & RADEON_TEX1_BIT ) { + /* Hits a second cache line. + */ +#if defined (USE_X86_ASM) + __asm__ ( "movl (%%esi), %%eax \n" + "movl %%eax, 32(%%edi) \n" + "movl 4(%%esi), %%eax \n" + "movl %%eax, 36(%%edi)" + : + : "S" (tex1_data), "D" (f) + : "%eax" ); +#else + *(GLuint *)(f+CLIP_S1) = *(GLuint *)tex1_data; + *(GLuint *)(f+CLIP_T1) = *(GLuint *)(tex1_data+1); +#endif + } + if ( TYPE & RADEON_RGBA_BIT ) color += color_stride; + if ( TYPE & RADEON_TEX0_BIT ) STRIDE_F( tex0_data, tex0_stride ); + if ( TYPE & RADEON_TEX1_BIT ) STRIDE_F( tex1_data, tex1_stride ); + f += 16; + } + } + + rvb->clipped_elements.count = start; + rvb->last_vert = count; +} + + +/* Changed to just put the interp func instead of the whole clip + * routine into the header. Less code and better chance of doing some + * of this stuff in assembly. + */ +static void TAG(radeon_interp_vert)( GLfloat t, + GLfloat *O, + const GLfloat *I, + const GLfloat *J ) +{ + O[0] = LINTERP( t, I[0], J[0] ); + O[1] = LINTERP( t, I[1], J[1] ); + O[2] = LINTERP( t, I[2], J[2] ); + O[3] = LINTERP( t, I[3], J[3] ); + + if ( TYPE & RADEON_RGBA_BIT ) { + INTERP_RGBA( t, + ((GLubyte *)&(O[4])), + ((GLubyte *)&(I[4])), + ((GLubyte *)&(J[4])) ); + } + + if ( TYPE & RADEON_TEX0_BIT ) { + O[6] = LINTERP( t, I[6], J[6] ); + O[7] = LINTERP( t, I[7], J[7] ); + } + + if ( TYPE & RADEON_TEX1_BIT ) { + O[8] = LINTERP( t, I[8], J[8] ); + O[9] = LINTERP( t, I[9], J[9] ); + } +} + + +static void TAG(radeon_init_fastpath)( struct radeon_fast_tab *tab ) +{ + tab->build_vertices = TAG(radeon_setup_full); + tab->interp = TAG(radeon_interp_vert); +} + +#undef TYPE +#undef TAG +#undef SIZE diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c new file mode 100644 index 000000000..5273072e7 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c @@ -0,0 +1,703 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" + +#include "mem.h" + +#define RADEON_TIMEOUT 2048 +#define USE_IN_MEMORY_SCRATCH_REGS 0 + + +/* ============================================================= + * Hardware vertex buffer handling + */ + +/* Get a new VB from the pool of vertex buffers in AGP space. + */ +drmBufPtr radeonGetBufferLocked( radeonContextPtr rmesa ) +{ + int fd = rmesa->radeonScreen->driScreen->fd; + int index = 0; + int size = 0; + drmDMAReq dma; + drmBufPtr buf = NULL; + int to = 0; + int ret; + + dma.context = rmesa->hHWContext; + dma.send_count = 0; + dma.send_list = NULL; + dma.send_sizes = NULL; + dma.flags = 0; + dma.request_count = 1; + dma.request_size = RADEON_BUFFER_SIZE; + dma.request_list = &index; + dma.request_sizes = &size; + dma.granted_count = 0; + + while ( !buf && ( to++ < RADEON_TIMEOUT ) ) { + ret = drmDMA( fd, &dma ); + + if ( ret == 0 ) { + buf = &rmesa->radeonScreen->buffers->list[index]; + buf->used = 0; +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + rmesa->c_vertexBuffers++; +#endif + return buf; + } + } + + if ( !buf ) { + drmRadeonEngineReset( fd ); + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "Error: Could not get new VB... exiting\n" ); + exit( -1 ); + } + + return buf; +} + +static GLboolean intersect_rect( XF86DRIClipRectPtr out, + XF86DRIClipRectPtr a, + XF86DRIClipRectPtr b ) +{ + *out = *a; + if ( b->x1 > out->x1 ) out->x1 = b->x1; + if ( b->y1 > out->y1 ) out->y1 = b->y1; + if ( b->x2 < out->x2 ) out->x2 = b->x2; + if ( b->y2 < out->y2 ) out->y2 = b->y2; + if ( out->x1 >= out->x2 ) return GL_FALSE; + if ( out->y1 >= out->y2 ) return GL_FALSE; + return GL_TRUE; +} + +void radeonFlushVerticesLocked( radeonContextPtr rmesa ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->vert_buf; + int count = rmesa->num_verts; + int prim = RADEON_TRIANGLES; + int fd = rmesa->driScreen->fd; + int i; + + rmesa->vert_buf = NULL; + rmesa->num_verts = 0; + + if ( !buffer ) + return; + + if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) + radeonEmitHwStateLocked( rmesa ); + + if ( !nbox ) + count = 0; + + if ( nbox >= RADEON_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS; + + if ( !count || !(rmesa->dirty & RADEON_UPLOAD_CLIPRECTS) ) + { + if ( nbox == 1 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + drmRadeonFlushVertexBuffer( fd, prim, buffer->idx, count, 1 ); + } + else + { + for ( i = 0 ; i < nbox ; ) { + int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + int discard = 0; + + if ( rmesa->scissor ) { + rmesa->sarea->nbox = 0; + + for ( ; i < nr ; i++ ) { + *b = pbox[i]; + if ( intersect_rect( b, b, &rmesa->scissor_rect ) ) { + rmesa->sarea->nbox++; + b++; + } + } + + /* Culled? + */ + if ( !rmesa->sarea->nbox ) { + if ( nr < nbox ) continue; + count = 0; + } + } else { + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + discard = 1; + } + + rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS; + drmRadeonFlushVertexBuffer( fd, prim, buffer->idx, count, discard ); + } + } + + rmesa->dirty &= ~RADEON_UPLOAD_CLIPRECTS; +} + + + +/* ================================================================ + * Indexed vertex buffer handling + */ + +void radeonGetEltBufLocked( radeonContextPtr rmesa ) +{ + rmesa->elt_buf = radeonGetBufferLocked( rmesa ); +} + +void radeonFireEltsLocked( radeonContextPtr rmesa, + GLuint start, GLuint end, + GLuint discard ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->elt_buf; + int prim = RADEON_TRIANGLES; + int fd = rmesa->driScreen->fd; + int i; + + if ( !buffer ) + return; + + if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) + radeonEmitHwStateLocked( rmesa ); + + if ( !nbox ) + end = start; + + if ( nbox >= RADEON_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS; + + if ( start == end || !(rmesa->dirty & RADEON_UPLOAD_CLIPRECTS) ) + { + if ( nbox == 1 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + drmRadeonFlushIndices( fd, prim, buffer->idx, start, end, discard ); + } + else + { + for ( i = 0 ; i < nbox ; ) { + int nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + int d = 0; + + if ( rmesa->scissor ) { + rmesa->sarea->nbox = 0; + + for ( ; i < nr ; i++ ) { + *b = pbox[i]; + if ( intersect_rect( b, b, &rmesa->scissor_rect ) ) { + rmesa->sarea->nbox++; + b++; + } + } + + /* Culled? + */ + if ( !rmesa->sarea->nbox ) { + if ( nr < nbox ) continue; + end = start; + } + } else { + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + d = discard; + } + + rmesa->sarea->dirty |= RADEON_UPLOAD_CLIPRECTS; + drmRadeonFlushIndices( fd, prim, buffer->idx, start, end, discard ); + } + } + + rmesa->dirty &= ~RADEON_UPLOAD_CLIPRECTS; +} + +void radeonFlushEltsLocked( radeonContextPtr rmesa ) +{ + if ( rmesa->first_elt != rmesa->next_elt ) { + radeonFireEltsLocked( rmesa, + ((GLuint)rmesa->first_elt - + (GLuint)rmesa->elt_buf->address), + ((GLuint)rmesa->next_elt - + (GLuint)rmesa->elt_buf->address), + 0 ); + + ALIGN_NEXT_ELT( rmesa ); + rmesa->first_elt = rmesa->next_elt; + } +} + +void radeonReleaseBufLocked( radeonContextPtr rmesa, drmBufPtr buffer ) +{ + int fd = rmesa->driScreen->fd; + + if ( !buffer ) + return; + + drmRadeonFlushVertexBuffer( fd, RADEON_TRIANGLES, buffer->idx, 0, 1 ); +} + + +/* Allocate some space in the current vertex buffer. If the current + * buffer is full, flush it and grab another one. + */ +CARD32 *radeonAllocVertices( radeonContextPtr rmesa, GLuint count ) +{ + return radeonAllocVerticesInline( rmesa, count ); +} + + +/* ================================================================ + * Texture uploads + */ + +void radeonFireBlitLocked( radeonContextPtr rmesa, drmBufPtr buffer, + GLint offset, GLint pitch, GLint format, + GLint x, GLint y, GLint width, GLint height ) +{ + GLint ret; + + ret = drmRadeonTextureBlit( rmesa->driFd, buffer->idx, + offset, pitch, format, + x, y, width, height ); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "drmRadeonTextureBlit: return = %d\n", ret ); + exit( 1 ); + } +} + + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +#define RADEON_MAX_OUTSTANDING 2 + +/* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + * GH: We probably don't want a timeout here, as we can wait as + * long as we want for a frame to complete. If it never does, then + * the card has locked. + */ +#if USE_IN_MEMORY_SCRATCH_REGS +static int radeonWaitForFrameCompletion( radeonContextPtr rmesa ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + __volatile__ CARD32 *scratch = rmesa->radeonScreen->scratch; + CARD32 frame; + int wait = 0; + + while ( 1 ) { + /* Read the frame counter from the in-memory copy of the scratch + * register. Nifty, eh? Should significantly reduce the bus + * traffic for SwapBuffers-limited apps (generally pretty trivial + * ones, but anyway). + */ + frame = scratch[0]; + if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) { + break; + } + wait++; + } + + return wait; +} +#else +static void delay( void ) { +/* Prevent an optimizing compiler from removing a spin loop */ +} + +static int radeonWaitForFrameCompletion( radeonContextPtr rmesa ) +{ + unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map; + RADEONSAREAPrivPtr sarea = rmesa->sarea; + CARD32 frame; + int wait = 0; + int i; + + while ( 1 ) { + frame = INREG( RADEON_LAST_FRAME_REG ); + if ( sarea->last_frame - frame <= RADEON_MAX_OUTSTANDING ) { + break; + } + wait++; + /* Spin in place a bit so we aren't hammering the bus */ + for ( i = 0 ; i < 1024 ; i++ ) { + delay(); + } + } + + return wait; +} +#endif + +/* Copy the back color buffer to the front color buffer. + */ +void radeonSwapBuffers( radeonContextPtr rmesa ) +{ + GLint nbox = rmesa->numClipRects; + GLint i; + GLint ret; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n%s( %p )\n\n", __FUNCTION__, rmesa->glCtx ); + } + + FLUSH_BATCH( rmesa ); + + LOCK_HARDWARE( rmesa ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + if ( !radeonWaitForFrameCompletion( rmesa ) ) { + rmesa->hardwareWentIdle = 1; + } else { + rmesa->hardwareWentIdle = 0; + } + + for ( i = 0 ; i < nbox ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS , nbox ); + XF86DRIClipRectPtr box = rmesa->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + GLint n = 0; + + for ( ; i < nr ; i++ ) { + *b++ = *(XF86DRIClipRectRec *)&box[i]; + n++; + } + rmesa->sarea->nbox = n; + + ret = drmRadeonSwapBuffers( rmesa->driFd ); + + if ( ret ) { + fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret ); + UNLOCK_HARDWARE( rmesa ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( rmesa ); + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_MASKS | + RADEON_UPLOAD_CLIPRECTS); + +#if ENABLE_PERF_BOXES + /* Log the performance counters if necessary */ + radeonPerformanceCounters( rmesa ); +#endif +} + +void radeonPageFlip( radeonContextPtr rmesa ) +{ + GLint ret; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n%s( %p ): page=%d\n\n", + __FUNCTION__, rmesa->glCtx, rmesa->currentPage ); + } + + FLUSH_BATCH( rmesa ); + + LOCK_HARDWARE( rmesa ); + + /* Throttle the frame rate -- only allow one pending swap buffers + * request at a time. + */ + if ( !radeonWaitForFrameCompletion( rmesa ) ) { + rmesa->hardwareWentIdle = 1; + } else { + rmesa->hardwareWentIdle = 0; + } + + /* The kernel will have been initialized to perform page flipping + * on a swapbuffers ioctl. + */ + ret = drmRadeonSwapBuffers( rmesa->driFd ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "drmRadeonSwapBuffers: return = %d\n", ret ); + exit( 1 ); + } + + if ( rmesa->currentPage == 0 ) { + rmesa->drawOffset = rmesa->radeonScreen->frontOffset; + rmesa->drawPitch = rmesa->radeonScreen->frontPitch; + rmesa->currentPage = 1; + } else { + rmesa->drawOffset = rmesa->radeonScreen->backOffset; + rmesa->drawPitch = rmesa->radeonScreen->backPitch; + rmesa->currentPage = 0; + } + + rmesa->setup.rb3d_coloroffset = rmesa->drawOffset; + rmesa->setup.rb3d_colorpitch = rmesa->drawPitch; + + rmesa->new_state |= RADEON_NEW_WINDOW; + + /* FIXME: Do we need this anymore? */ + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_MASKS | + RADEON_UPLOAD_CLIPRECTS); + +#if ENABLE_PERF_BOXES + /* Log the performance counters if necessary */ + radeonPerformanceCounters( rmesa ); +#endif +} + + +/* ================================================================ + * Buffer clear + */ +#define RADEON_MAX_CLEARS 256 + +static GLbitfield radeonDDClear( GLcontext *ctx, GLbitfield mask, + GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + RADEONSAREAPrivPtr sarea = rmesa->sarea; +#if USE_IN_MEMORY_SCRATCH_REGS + __volatile__ CARD32 *scratch = rmesa->radeonScreen->scratch; +#else + unsigned char *RADEONMMIO = rmesa->radeonScreen->mmio.map; +#endif + CARD32 clear; + GLuint flags = 0; + GLint ret, i; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s: all=%d cx=%d cy=%d cw=%d ch=%d\n", + __FUNCTION__, all, cx, cy, cw, ch ); + } + + FLUSH_BATCH( rmesa ); + + /* Update and emit any new state. We need to do this here to catch + * changes to the masks. + * FIXME: Just update the masks? + */ + if ( rmesa->new_state ) + radeonDDUpdateHWState( ctx ); + + if ( mask & DD_FRONT_LEFT_BIT ) { + flags |= DRM_RADEON_FRONT; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ( mask & DD_BACK_LEFT_BIT ) { + flags |= DRM_RADEON_BACK; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ( mask & DD_DEPTH_BIT ) { + if ( ctx->Depth.Mask ) { + flags |= DRM_RADEON_DEPTH; + } + mask &= ~DD_DEPTH_BIT; + } +#if 0 + /* FIXME: Add stencil support */ + if ( mask & DD_STENCIL_BIT ) { + flags |= DRM_RADEON_DEPTH; + mask &= ~DD_STENCIL_BIT; + } +#endif + + if ( !flags ) + return mask; + + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE( rmesa ); + + /* Throttle the number of clear ioctls we do. + */ +#if USE_IN_MEMORY_SCRATCH_REGS + while ( 1 ) { + clear = scratch[2]; + if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) { + break; + } + } +#else + while ( 1 ) { + clear = INREG( RADEON_LAST_CLEAR_REG ); + if ( sarea->last_clear - clear <= RADEON_MAX_CLEARS ) { + break; + } + /* Spin in place a bit so we aren't hammering the bus */ + for ( i = 0 ; i < 1024 ; i++ ) { + delay(); + } + } +#endif + + if ( rmesa->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeonEmitHwStateLocked( rmesa ); + } + + for ( i = 0 ; i < rmesa->numClipRects ; ) { + GLint nr = MIN2( i + RADEON_NR_SAREA_CLIPRECTS, rmesa->numClipRects ); + XF86DRIClipRectPtr box = rmesa->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + GLint n = 0; + + if ( !all ) { + for ( ; i < nr ; i++ ) { + GLint x = box[i].x1; + GLint y = box[i].y1; + GLint w = box[i].x2 - x; + GLint h = box[i].y2 - y; + + if ( x < cx ) w -= cx - x, x = cx; + if ( y < cy ) h -= cy - y, y = cy; + if ( x + w > cx + cw ) w = cx + cw - x; + if ( y + h > cy + ch ) h = cy + ch - y; + if ( w <= 0 ) continue; + if ( h <= 0 ) continue; + + b->x1 = x; + b->y1 = y; + b->x2 = x + w; + b->y2 = y + h; + b++; + n++; + } + } else { + for ( ; i < nr ; i++ ) { + *b++ = *(XF86DRIClipRectRec *)&box[i]; + n++; + } + } + + rmesa->sarea->nbox = n; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_IOCTL ) { + fprintf( stderr, + "drmRadeonClear: flag 0x%x color %x depth %x nbox %d\n", + flags, + (GLuint)rmesa->ClearColor, + (GLuint)rmesa->ClearDepth, + rmesa->sarea->nbox ); + } + + ret = drmRadeonClear( rmesa->driFd, flags, + cx, cy, cw, ch, + rmesa->ClearColor, rmesa->ClearDepth ); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "drmRadeonClear: return = %d\n", ret ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( rmesa ); + + rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS; + + return mask; +} + + +void radeonWaitForIdleLocked( radeonContextPtr rmesa ) +{ + int fd = rmesa->radeonScreen->driScreen->fd; + int to = 0; + int ret; + + do { + ret = drmRadeonWaitForIdleCP( fd ); + } while ( ( ret == -EBUSY ) && ( to++ < RADEON_TIMEOUT ) ); + + if ( ret < 0 ) { + drmRadeonEngineReset( fd ); + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "Error: Radeon timed out... exiting\n" ); + exit( -1 ); + } +} + + +void radeonDDInitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Clear = radeonDDClear; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h new file mode 100644 index 000000000..7b22a8766 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h @@ -0,0 +1,161 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_IOCTL_H__ +#define __RADEON_IOCTL_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_dri.h" +#include "radeon_lock.h" + +#include "xf86drm.h" +#include "xf86drmRadeon.h" + +#define RADEON_BUFFER_MAX_DWORDS (RADEON_BUFFER_SIZE / sizeof(CARD32)) + + +extern drmBufPtr radeonGetBufferLocked( radeonContextPtr rmesa ); +extern void radeonFlushVerticesLocked( radeonContextPtr rmesa ); + +extern void radeonGetEltBufLocked( radeonContextPtr rmesa ); +extern void radeonFlushEltsLocked( radeonContextPtr rmesa ); +extern void radeonFireEltsLocked( radeonContextPtr rmesa, + GLuint start, GLuint end, + GLuint discard ); +extern void radeonReleaseBufLocked( radeonContextPtr rmesa, drmBufPtr buffer ); + +/* Make this available as both a regular and an inline function. + */ +extern CARD32 *radeonAllocVertices( radeonContextPtr rmesa, GLuint count ); + +static __inline CARD32 *radeonAllocVerticesInline( radeonContextPtr rmesa, + GLuint count ) +{ + int bytes = count * rmesa->vertsize * 4; + CARD32 *head; + + if ( !rmesa->vert_buf ) { + LOCK_HARDWARE( rmesa ); + + if ( rmesa->first_elt != rmesa->next_elt ) { + radeonFlushEltsLocked( rmesa ); + } + + rmesa->vert_buf = radeonGetBufferLocked( rmesa ); + + UNLOCK_HARDWARE( rmesa ); + } else if ( rmesa->vert_buf->used + bytes > rmesa->vert_buf->total ) { + LOCK_HARDWARE( rmesa ); + + radeonFlushVerticesLocked( rmesa ); + rmesa->vert_buf = radeonGetBufferLocked( rmesa ); + + UNLOCK_HARDWARE( rmesa ); + } + + head = (CARD32 *)((char *)rmesa->vert_buf->address + + rmesa->vert_buf->used); + + rmesa->vert_buf->used += bytes; + rmesa->num_verts += count; + return head; +} + +extern void radeonFireBlitLocked( radeonContextPtr rmesa, + drmBufPtr buffer, + GLint offset, GLint pitch, GLint format, + GLint x, GLint y, + GLint width, GLint height ); + +extern void radeonSwapBuffers( radeonContextPtr rmesa ); +extern void radeonPageFlip( radeonContextPtr rmesa ); + +extern void radeonWaitForIdleLocked( radeonContextPtr rmesa ); + + +extern void radeonDDInitIoctlFuncs( GLcontext *ctx ); + + +/* ================================================================ + * Helper macros: + */ + +#define FLUSH_BATCH( rmesa ) \ +do { \ + if ( RADEON_DEBUG & DEBUG_VERBOSE_IOCTL ) \ + fprintf( stderr, "FLUSH_BATCH in %s\n", __FUNCTION__ ); \ + if ( rmesa->vert_buf ) { \ + radeonFlushVertices( rmesa ); \ + } else if ( rmesa->next_elt != rmesa->first_elt ) { \ + radeonFlushElts( rmesa ); \ + } \ +} while (0) + +/* 64-bit align the next element address, and then make room for the + * next indexed prim packet header. + */ +#define ALIGN_NEXT_ELT( rmesa ) \ +do { \ + rmesa->next_elt = (GLushort *) \ + (((GLuint)rmesa->next_elt + 7) & ~0x7); \ + rmesa->next_elt = (GLushort *) \ + ((GLubyte *)rmesa->next_elt + RADEON_INDEX_PRIM_OFFSET); \ +} while (0) + +#define radeonFlushVertices( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + radeonFlushVerticesLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) + +#define radeonFlushElts( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + radeonFlushEltsLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) + +#define radeonWaitForIdle( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + radeonWaitForIdleLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) + +#endif +#endif /* __RADEON_IOCTL_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c new file mode 100644 index 000000000..65658e997 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c @@ -0,0 +1,95 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_lock.h" +#include "radeon_tex.h" + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + + +/* Update the hardware state. This is called if another context has + * grabbed the hardware lock, which includes the X server. This + * function also updates the driver's window state after the X server + * moves, resizes or restacks a window -- the change will be reflected + * in the drawable position and clip rects. Since the X server grabs + * the hardware lock when it changes the window state, this routine will + * automatically be called after such a change. + */ +void radeonGetLock( radeonContextPtr rmesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + __DRIscreenPrivate *sPriv = rmesa->driScreen; + RADEONSAREAPrivPtr sarea = rmesa->sarea; + int stamp = dPriv->lastStamp; + int i; + + drmGetLock( rmesa->driFd, rmesa->hHWContext, flags ); + + /* The window might have moved, so we might need to get new clip + * rects. + * + * NOTE: This releases and regrabs the hw lock to allow the X server + * to respond to the DRI protocol request for new drawable info. + * Since the hardware state depends on having the latest drawable + * clip rects, all state checking must be done _after_ this call. + */ + XMESA_VALIDATE_DRAWABLE_INFO( rmesa->display, sPriv, dPriv ); + + if ( stamp != dPriv->lastStamp ) { + rmesa->new_state |= RADEON_NEW_WINDOW | RADEON_NEW_CLIP; + rmesa->SetupDone = 0; + } + + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_CLIPRECTS; + + rmesa->numClipRects = dPriv->numClipRects; + rmesa->pClipRects = dPriv->pClipRects; + + if ( sarea->ctxOwner != rmesa->hHWContext ) { + sarea->ctxOwner = rmesa->hHWContext; + rmesa->dirty = RADEON_UPLOAD_ALL; + } + + for ( i = 0 ; i < rmesa->lastTexHeap ; i++ ) { + if ( sarea->texAge[i] != rmesa->lastTexAge[i] ) { + radeonAgeTextures( rmesa, i ); + } + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h new file mode 100644 index 000000000..7cdb1b23d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h @@ -0,0 +1,112 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_LOCK_H__ +#define __RADEON_LOCK_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonGetLock( radeonContextPtr rmesa, GLuint flags ); + +/* Turn DEBUG_LOCKING on to find locking conflicts. + */ +#define DEBUG_LOCKING 0 + +#if DEBUG_LOCKING +extern char *prevLockFile; +extern int prevLockLine; + +#define DEBUG_LOCK() \ + do { \ + prevLockFile = (__FILE__); \ + prevLockLine = (__LINE__); \ + } while (0) + +#define DEBUG_RESET() \ + do { \ + prevLockFile = 0; \ + prevLockLine = 0; \ + } while (0) + +#define DEBUG_CHECK_LOCK() \ + do { \ + if ( prevLockFile ) { \ + fprintf( stderr, \ + "LOCK SET!\n\tPrevious %s:%d\n\tCurrent: %s:%d\n", \ + prevLockFile, prevLockLine, __FILE__, __LINE__ ); \ + exit( 1 ); \ + } \ + } while (0) + +#else + +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() + +#endif + +/* + * !!! We may want to separate locks from locks with validation. This + * could be used to improve performance for those things commands that + * do not do any drawing !!! + */ + +/* Lock the hardware and validate our state. + */ +#define LOCK_HARDWARE( rmesa ) \ + do { \ + char __ret = 0; \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS( rmesa->driHwLock, rmesa->hHWContext, \ + (DRM_LOCK_HELD | rmesa->hHWContext), __ret ); \ + if ( __ret ) \ + radeonGetLock( rmesa, 0 ); \ + DEBUG_LOCK(); \ + } while (0) + +/* Unlock the hardware. + */ +#define UNLOCK_HARDWARE( rmesa ) \ + do { \ + DRM_UNLOCK( rmesa->driFd, \ + rmesa->driHwLock, \ + rmesa->hHWContext ); \ + DEBUG_RESET(); \ + } while (0) + +#endif +#endif /* __RADEON_LOCK_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c new file mode 100644 index 000000000..fe0eb013e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c @@ -0,0 +1,168 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include "types.h" +#include "fog.h" + +static struct gl_pipeline_stage radeon_fast_stage = { + "Radeon Fast Path", + (PIPE_OP_VERT_XFORM | + PIPE_OP_RAST_SETUP_0 | + PIPE_OP_RAST_SETUP_1 | + PIPE_OP_RENDER), + PIPE_PRECALC, + 0, 0, 0, 0, 0, 0, 0, 0, 0, + radeonDDFastPath +}; + +#define ILLEGAL_ENABLES (TEXTURE0_3D | \ + TEXTURE1_3D | \ + ENABLE_TEXMAT0 | \ + ENABLE_TEXMAT1 | \ + ENABLE_TEXGEN0 | \ + ENABLE_TEXGEN1 | \ + ENABLE_USERCLIP | \ + ENABLE_LIGHT | \ + ENABLE_FOG) + +/* Build the PRECALC pipeline with our stage, if possible. Otherwise, + * return GL_FALSE. + */ +GLboolean radeonDDBuildPrecalcPipeline( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_pipeline *pipe = &ctx->CVA.pre; + + if ( rmesa->RenderIndex == 0 && + (ctx->Enabled & ILLEGAL_ENABLES) == 0 && + (ctx->Array.Flags & (VERT_OBJ_234 | + VERT_TEX0_4 | + VERT_TEX1_4 | + VERT_ELT)) == (VERT_OBJ_23 | VERT_ELT) ) + { + pipe->stages[0] = &radeon_fast_stage; + pipe->stages[1] = 0; + pipe->new_inputs = ctx->RenderFlags & VERT_DATA; + pipe->ops = pipe->stages[0]->ops; + + rmesa->OnFastPath = GL_TRUE; + return GL_TRUE; + } + + if ( rmesa->OnFastPath ) { + rmesa->OnFastPath = GL_FALSE; + + ctx->CVA.VB->ClipOrMask = 0; + ctx->CVA.VB->ClipAndMask = CLIP_ALL_BITS; + ctx->Array.NewArrayState |= ctx->Array.Summary; + } + + return GL_FALSE; +} + + +/* Still do the normal fixup and copy-to-current, so this isn't so + * bad. + */ +#define ILLEGAL_INPUTS_IMM (VERT_OBJ_4 | \ + VERT_TEX0_4 | \ + VERT_TEX1_4 | \ + VERT_MATERIAL) + +static void radeonDDCheckRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *d ) +{ + d->type = PIPE_IMMEDIATE | PIPE_PRECALC; + d->inputs = ctx->RenderFlags; + + /* Radeon requires an extra input: + */ + if ( ctx->FogMode == FOG_FRAGMENT ) + d->inputs |= VERT_FOG_COORD; + + d->outputs = VERT_SETUP_FULL; + + if ( ctx->IndirectTriangles & DD_SW_SETUP ) + d->type = PIPE_IMMEDIATE; +} + + +GLuint radeonDDRegisterPipelineStages( struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr ) +{ + int i, o; + + for ( i = o = 0 ; i < nr ; i++ ) { + switch ( in[i].ops ) { + /* Completely replace Mesa's fog processing to generate fog + * coordinates instead of messing with colors. + */ + case PIPE_OP_FOG: + out[o] = gl_fog_coord_stage; + o++; + break; + + case PIPE_OP_RAST_SETUP_0: + out[o] = in[i]; + out[o].cva_state_change = (NEW_LIGHTING | + NEW_TEXTURING | + NEW_RASTER_OPS); + out[o].state_change = ~0; + out[o].check = radeonDDCheckPartialRasterSetup; + out[o].run = radeonDDPartialRasterSetup; + o++; + break; + + case PIPE_OP_RAST_SETUP_0 | PIPE_OP_RAST_SETUP_1: + out[o] = in[i]; + out[o].check = radeonDDCheckRasterSetup; + out[o].run = radeonDDDoRasterSetup; + o++; + break; + + default: + out[o++] = in[i]; + break; + } + } + + return o; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h new file mode 100644 index 000000000..1af4e3eec --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h @@ -0,0 +1,54 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_PIPELINE_H__ +#define __RADEON_PIPELINE_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern GLboolean radeonDDBuildPrecalcPipeline( GLcontext *ctx ); +extern GLuint radeonDDRegisterPipelineStages( struct gl_pipeline_stage *out, + const struct gl_pipeline_stage *in, + GLuint nr ); + +extern void radeonDDFastPathInit( void ); +extern void radeonDDFastPath( struct vertex_buffer *VB ); + +extern void radeonDDEltPathInit( void ); +extern void radeonDDEltPath( struct vertex_buffer *VB ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c new file mode 100644 index 000000000..e3cb90812 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c @@ -0,0 +1,220 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_dri.h" + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_vb.h" +#include "radeon_pipeline.h" + +#include "mem.h" + +#if 1 +/* Including xf86PciInfo.h introduces a bunch of errors... + */ +#define PCI_CHIP_RADEON_QD 0x5144 +#define PCI_CHIP_RADEON_QE 0x5145 +#define PCI_CHIP_RADEON_QF 0x5146 +#define PCI_CHIP_RADEON_QG 0x5147 +#endif + + +/* Create the device specific screen private data struct. + */ +radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ) +{ + radeonScreenPtr radeonScreen; + RADEONDRIPtr radeonDRIPriv = (RADEONDRIPtr)sPriv->pDevPriv; + + /* Check the DRI version */ + { + int major, minor, patch; + if ( XF86DRIQueryVersion( sPriv->display, &major, &minor, &patch ) ) { + if ( major != 3 || minor != 1 || patch < 0 ) { + char msg[128]; + sprintf( msg, "Radeon DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if ( sPriv->ddxMajor != 4 || + sPriv->ddxMinor != 0 || + sPriv->ddxPatch < 0 ) { + char msg[128]; + sprintf( msg, "Radeon DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if ( sPriv->drmMajor != 1 || + sPriv->drmMinor != 0 || + sPriv->drmPatch < 0 ) { + char msg[128]; + sprintf( msg, "Radeon DRI driver expected DRM driver version 2.1.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch ); + __driMesaMessage( msg ); + return GL_FALSE; + } + + /* Allocate the private area */ + radeonScreen = (radeonScreenPtr) CALLOC( sizeof(*radeonScreen) ); + if ( !radeonScreen ) return NULL; + + /* This is first since which regions we map depends on whether or + * not we are using a PCI card. + */ + radeonScreen->IsPCI = radeonDRIPriv->IsPCI; + + radeonScreen->mmio.handle = radeonDRIPriv->registerHandle; + radeonScreen->mmio.size = radeonDRIPriv->registerSize; + if ( drmMap( sPriv->fd, + radeonScreen->mmio.handle, + radeonScreen->mmio.size, + &radeonScreen->mmio.map ) ) { + FREE( radeonScreen ); + return NULL; + } + + radeonScreen->status.handle = radeonDRIPriv->statusHandle; + radeonScreen->status.size = radeonDRIPriv->statusSize; + if ( drmMap( sPriv->fd, + radeonScreen->status.handle, + radeonScreen->status.size, + &radeonScreen->status.map ) ) { + drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + FREE( radeonScreen ); + return NULL; + } + radeonScreen->scratch = (__volatile__ CARD32 *) + ((GLubyte *)radeonScreen->status.map + RADEON_SCRATCH_REG_OFFSET); + + radeonScreen->buffers = drmMapBufs( sPriv->fd ); + if ( !radeonScreen->buffers ) { + drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); + drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + FREE( radeonScreen ); + return NULL; + } + + if ( !radeonScreen->IsPCI ) { + radeonScreen->agpTextures.handle = radeonDRIPriv->agpTexHandle; + radeonScreen->agpTextures.size = radeonDRIPriv->agpTexMapSize; + if ( drmMap( sPriv->fd, + radeonScreen->agpTextures.handle, + radeonScreen->agpTextures.size, + (drmAddressPtr)&radeonScreen->agpTextures.map ) ) { + drmUnmapBufs( radeonScreen->buffers ); + drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); + drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + FREE( radeonScreen ); + return NULL; + } + } + + + switch ( radeonDRIPriv->deviceID ) { + case PCI_CHIP_RADEON_QD: + case PCI_CHIP_RADEON_QE: + case PCI_CHIP_RADEON_QF: + case PCI_CHIP_RADEON_QG: + radeonScreen->chipset = RADEON_CARD_TYPE_RADEON; + break; + default: + radeonScreen->chipset = RADEON_CARD_TYPE_RADEON; + break; + } + + radeonScreen->cpp = radeonDRIPriv->bpp / 8; + radeonScreen->AGPMode = radeonDRIPriv->AGPMode; + + radeonScreen->frontOffset = radeonDRIPriv->frontOffset; + radeonScreen->frontPitch = radeonDRIPriv->frontPitch; + radeonScreen->backOffset = radeonDRIPriv->backOffset; + radeonScreen->backPitch = radeonDRIPriv->backPitch; + radeonScreen->depthOffset = radeonDRIPriv->depthOffset; + radeonScreen->depthPitch = radeonDRIPriv->depthPitch; + + radeonScreen->texOffset[RADEON_CARD_HEAP] = radeonDRIPriv->textureOffset; + radeonScreen->texSize[RADEON_CARD_HEAP] = radeonDRIPriv->textureSize; + radeonScreen->logTexGranularity[RADEON_CARD_HEAP] = + radeonDRIPriv->log2TexGran; + + if ( radeonScreen->IsPCI ) { + radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS - 1; + radeonScreen->texOffset[RADEON_AGP_HEAP] = 0; + radeonScreen->texSize[RADEON_AGP_HEAP] = 0; + radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = 0; + } else { + radeonScreen->numTexHeaps = RADEON_NR_TEX_HEAPS; + radeonScreen->texOffset[RADEON_AGP_HEAP] = + radeonDRIPriv->agpTexOffset + RADEON_AGP_TEX_OFFSET; + radeonScreen->texSize[RADEON_AGP_HEAP] = radeonDRIPriv->agpTexMapSize; + radeonScreen->logTexGranularity[RADEON_AGP_HEAP] = + radeonDRIPriv->log2AGPTexGran; + } + + radeonScreen->driScreen = sPriv; + + radeonDDSetupInit(); + radeonDDTriangleFuncsInit(); + radeonDDFastPathInit(); + radeonDDEltPathInit(); + + return radeonScreen; +} + +/* Destroy the device specific screen private data struct. + */ +void radeonDestroyScreen( __DRIscreenPrivate *sPriv ) +{ + radeonScreenPtr radeonScreen = (radeonScreenPtr)sPriv->private; + + if ( !radeonScreen->IsPCI ) { + drmUnmap( radeonScreen->agpTextures.map, + radeonScreen->agpTextures.size ); + } + drmUnmapBufs( radeonScreen->buffers ); + drmUnmap( radeonScreen->status.map, radeonScreen->status.size ); + drmUnmap( radeonScreen->mmio.map, radeonScreen->mmio.size ); + + FREE( radeonScreen ); + sPriv->private = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h new file mode 100644 index 000000000..852e4f30a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h @@ -0,0 +1,87 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h,v 1.1 2001/01/08 01:07:27 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_SCREEN_H__ +#define __RADEON_SCREEN_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_sarea.h" + +typedef struct { + drmHandle handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ + drmAddress map; /* Mapping of the DRM region */ +} radeonRegionRec, *radeonRegionPtr; + +typedef struct { + + GLint chipset; + GLint cpp; + GLint IsPCI; /* Current card is a PCI card */ + GLint AGPMode; + + GLuint frontOffset; + GLuint frontPitch; + GLuint backOffset; + GLuint backPitch; + + GLuint depthOffset; + GLuint depthPitch; + + /* Shared texture data */ + int numTexHeaps; + int texOffset[RADEON_NR_TEX_HEAPS]; + int texSize[RADEON_NR_TEX_HEAPS]; + int logTexGranularity[RADEON_NR_TEX_HEAPS]; + + radeonRegionRec mmio; + radeonRegionRec status; + radeonRegionRec agpTextures; + + drmBufMapPtr buffers; + + __volatile__ CARD32 *scratch; + + __DRIscreenPrivate *driScreen; + +} radeonScreenRec, *radeonScreenPtr; + +extern radeonScreenPtr radeonCreateScreen( __DRIscreenPrivate *sPriv ); +extern void radeonDestroyScreen( __DRIscreenPrivate *sPriv ); + +#endif +#endif /* __RADEON_SCREEN_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c new file mode 100644 index 000000000..74ce2c827 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c @@ -0,0 +1,346 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_span.c,v 1.2 2001/01/16 05:10:58 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_span.h" + +#define DBG 0 + +#define LOCAL_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + radeonScreenPtr radeonScreen = rmesa->radeonScreen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + GLuint pitch = radeonScreen->frontPitch * radeonScreen->cpp; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(sPriv->pFB + \ + rmesa->drawOffset + \ + (dPriv->x * radeonScreen->cpp) + \ + (dPriv->y * pitch)); \ + char *read_buf = (char *)(sPriv->pFB + \ + rmesa->readOffset + \ + (dPriv->x * radeonScreen->cpp) + \ + (dPriv->y * pitch)); \ + GLushort p; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + radeonScreenPtr radeonScreen = rmesa->radeonScreen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + GLuint height = dPriv->h; \ + GLuint xo = dPriv->x; \ + GLuint yo = dPriv->y; \ + char *buf = (char *)(sPriv->pFB + radeonScreen->depthOffset); \ + (void) buf + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +#define INIT_MONO_PIXEL( p ) p = rmesa->Color + +#define CLIPPIXEL( _x, _y ) \ + ((_x >= minx) && (_x < maxx) && (_y >= miny) && (_y < maxy)) + + +#define CLIPSPAN( _x, _y, _n, _x1, _n1, _i ) \ + if ((_y < miny) || (_y >= maxy)) { \ + _n1 = 0, _x1 = x; \ + } else { \ + _n1 = _n; \ + _x1 = _x; \ + if (_x1 < minx) _i += (minx - _x1), _x1 = minx; \ + if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx); \ + } + +#define Y_FLIP( _y ) (height - _y - 1) + + +#define HW_LOCK() \ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); \ + FLUSH_BATCH( rmesa ); \ + LOCK_HARDWARE( rmesa ); \ + radeonWaitForIdleLocked( rmesa ); + +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + int _nc = dPriv->numClipRects; \ + \ + while ( _nc-- ) { \ + int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \ + int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \ + int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \ + int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; + +#define HW_ENDCLIPLOOP() \ + } \ + } while (0) + +#define HW_UNLOCK() \ + UNLOCK_HARDWARE( rmesa ) + + + +/* ================================================================ + * Color buffer + */ + +/* 16 bit, RGB565 color spanline and pixel functions + */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = ((((int)r & 0xf8) << 8) | \ + (((int)g & 0xfc) << 3) | \ + (((int)b & 0xf8) >> 3)) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*2 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ + do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*pitch); \ + rgba[0] = (p >> 8) & 0xf8; \ + rgba[1] = (p >> 3) & 0xfc; \ + rgba[2] = (p << 3) & 0xf8; \ + rgba[3] = 0xff; \ + if ( rgba[0] & 0x08 ) rgba[0] |= 0x07; \ + if ( rgba[1] & 0x04 ) rgba[1] |= 0x03; \ + if ( rgba[2] & 0x08 ) rgba[2] |= 0x07; \ + } while (0) + +#define TAG(x) radeon##x##_RGB565 +#include "spantmp.h" + +/* 32 bit, ARGB8888 color spanline and pixel functions + */ +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = ((b << 0) | \ + (g << 8) | \ + (r << 16) | \ + (a << 24) ) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLuint p = *(GLuint *)(read_buf + _x*4 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = (p >> 24) & 0xff; \ +} while (0) + +#define TAG(x) radeon##x##_ARGB8888 +#include "spantmp.h" + + + +/* ================================================================ + * Depth buffer + */ + +/* The Radeon has depth tiling on all the time, so we have to convert + * the x,y coordinates into the memory bus address (mba) in the same + * manner as the engine. In each case, the linear block address (ba) + * is calculated, and then wired with x and y to produce the final + * memory address. + */ +static __inline GLuint radeon_mba_z16( radeonContextPtr rmesa, + GLint x, GLint y ) +{ + radeonScreenPtr radeonScreen = rmesa->radeonScreen; + GLuint pitch = radeonScreen->frontPitch; + GLuint ba, address = 0; /* a[0] = 0 */ + + ba = (y / 16) * (pitch / 32) + (x / 32); + + address |= (x & 0x7) << 1; /* a[1..3] = x[0..2] */ + address |= (y & 0x7) << 4; /* a[4..6] = y[0..2] */ + address |= (x & 0x8) << 4; /* a[7] = x[3] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= ((x & 0x10) ^ (y & 0x10)) << 7; /* a[11] = x[4] ^ y[4] */ + address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ + + return address; +} + +static GLuint radeon_mba_z32( radeonContextPtr rmesa, + GLint x, GLint y ) +{ + radeonScreenPtr radeonScreen = rmesa->radeonScreen; + GLuint pitch = radeonScreen->frontPitch; + GLuint ba, address = 0; /* a[0..1] = 0 */ + + ba = (y / 16) * (pitch / 16) + (x / 16); + + address |= (x & 0x7) << 2; /* a[2..4] = x[0..2] */ + address |= (y & 0x3) << 5; /* a[5..6] = y[0..1] */ + address |= + (((x & 0x10) >> 2) ^ (y & 0x4)) << 5; /* a[7] = x[4] ^ y[2] */ + address |= (ba & 0x3) << 8; /* a[8..9] = ba[0..1] */ + + address |= (y & 0x8) << 7; /* a[10] = y[3] */ + address |= + (((x & 0x8) << 1) ^ (y & 0x10)) << 7; /* a[11] = x[3] ^ y[4] */ + address |= (ba & ~0x3) << 10; /* a[12..] = ba[2..] */ + + return address; +} + + +/* 16-bit depth buffer functions + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + radeon_mba_z16( rmesa, _x+xo, _y+yo )) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + radeon_mba_z16( rmesa, _x+xo, _y+yo )); + +#define TAG(x) radeon##x##_16 +#include "depthtmp.h" + +/* 24 bit depth, 8 bit stencil depthbuffer functions + */ +#define WRITE_DEPTH( _x, _y, d ) \ +do { \ + GLuint offset = radeon_mba_z32( rmesa, _x+xo, _y+yo ); \ + GLuint tmp = *(GLuint *)(buf + offset); \ + tmp &= 0xff000000; \ + tmp |= ((d) & 0x00ffffff); \ + *(GLuint *)(buf + offset) = tmp; \ +} while (0) + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x+xo, _y+yo )) & 0x00ffffff; + +#define TAG(x) radeon##x##_24_8 +#include "depthtmp.h" + + +/* ================================================================ + * Stencil buffer + */ + +/* 24 bit depth, 8 bit stencil depthbuffer functions + */ +#define WRITE_STENCIL( _x, _y, d ) \ +do { \ + GLuint offset = radeon_mba_z32( rmesa, _x+xo, _y+yo ); \ + GLuint tmp = *(GLuint *)(buf + offset); \ + tmp &= 0x00ffffff; \ + tmp |= (((d) & 0xff) << 24); \ + *(GLuint *)(buf + offset) = tmp; \ +} while (0) + +#define READ_STENCIL( d, _x, _y ) \ +do { \ + GLuint offset = radeon_mba_z32( rmesa, _x+xo, _y+yo ); \ + GLuint tmp = *(GLuint *)(buf + offset); \ + tmp &= 0xff000000; \ + d = tmp >> 24; \ +} while (0) + +#define TAG(x) radeon##x##_24_8 +#include "stenciltmp.h" + + + +void radeonDDInitSpanFuncs( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + switch ( rmesa->radeonScreen->cpp ) { + case 2: + ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_RGB565; + ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_RGB565; + ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_RGB565; + ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_RGB565; + ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_RGB565; + ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_RGB565; + ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_RGB565; + break; + + case 4: + ctx->Driver.WriteRGBASpan = radeonWriteRGBASpan_ARGB8888; + ctx->Driver.WriteRGBSpan = radeonWriteRGBSpan_ARGB8888; + ctx->Driver.WriteMonoRGBASpan = radeonWriteMonoRGBASpan_ARGB8888; + ctx->Driver.WriteRGBAPixels = radeonWriteRGBAPixels_ARGB8888; + ctx->Driver.WriteMonoRGBAPixels = radeonWriteMonoRGBAPixels_ARGB8888; + ctx->Driver.ReadRGBASpan = radeonReadRGBASpan_ARGB8888; + ctx->Driver.ReadRGBAPixels = radeonReadRGBAPixels_ARGB8888; + break; + + default: + break; + } + + switch ( rmesa->glCtx->Visual->DepthBits ) { + case 16: + ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_16; + ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_16; + ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_16; + ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_16; + break; + + case 24: + ctx->Driver.ReadDepthSpan = radeonReadDepthSpan_24_8; + ctx->Driver.WriteDepthSpan = radeonWriteDepthSpan_24_8; + ctx->Driver.ReadDepthPixels = radeonReadDepthPixels_24_8; + ctx->Driver.WriteDepthPixels = radeonWriteDepthPixels_24_8; + + ctx->Driver.ReadStencilSpan = radeonReadStencilSpan_24_8; + ctx->Driver.WriteStencilSpan = radeonWriteStencilSpan_24_8; + ctx->Driver.ReadStencilPixels = radeonReadStencilPixels_24_8; + ctx->Driver.WriteStencilPixels = radeonWriteStencilPixels_24_8; + break; + + default: + break; + } + + ctx->Driver.WriteCI8Span = NULL; + ctx->Driver.WriteCI32Span = NULL; + ctx->Driver.WriteMonoCISpan = NULL; + ctx->Driver.WriteCI32Pixels = NULL; + ctx->Driver.WriteMonoCIPixels = NULL; + ctx->Driver.ReadCI32Span = NULL; + ctx->Driver.ReadCI32Pixels = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h new file mode 100644 index 000000000..241f11c1e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h @@ -0,0 +1,45 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_span.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_SPAN_H__ +#define __RADEON_SPAN_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonDDInitSpanFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c new file mode 100644 index 000000000..8cec8ff52 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c @@ -0,0 +1,1338 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.c,v 1.1 2001/01/08 01:07:28 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * Keith Whitwell <keithw@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_tris.h" +#include "radeon_vb.h" +#include "radeon_tex.h" + +#include "mmath.h" +#include "pb.h" +#include "enums.h" + + +/* ============================================================= + * Alpha blending + */ + +static void radeonUpdateAlphaMode( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 a = rmesa->setup.pp_misc; + CARD32 p = rmesa->setup.pp_cntl; + CARD32 b = rmesa->setup.rb3d_blendcntl; + CARD32 c = rmesa->setup.rb3d_cntl; + + if ( ctx->Color.AlphaEnabled ) { + GLubyte ref = ctx->Color.AlphaRef; + + a &= ~(RADEON_ALPHA_TEST_OP_MASK | RADEON_REF_ALPHA_MASK); + + switch ( ctx->Color.AlphaFunc ) { + case GL_NEVER: + a |= RADEON_ALPHA_TEST_FAIL; + break; + case GL_LESS: + a |= RADEON_ALPHA_TEST_LESS; + break; + case GL_LEQUAL: + a |= RADEON_ALPHA_TEST_LEQUAL; + break; + case GL_EQUAL: + a |= RADEON_ALPHA_TEST_EQUAL; + break; + case GL_GEQUAL: + a |= RADEON_ALPHA_TEST_GEQUAL; + break; + case GL_GREATER: + a |= RADEON_ALPHA_TEST_GREATER; + break; + case GL_NOTEQUAL: + a |= RADEON_ALPHA_TEST_NEQUAL; + break; + case GL_ALWAYS: + a |= RADEON_ALPHA_TEST_PASS; + break; + } + + a |= (ref & RADEON_REF_ALPHA_MASK); + p |= RADEON_ALPHA_TEST_ENABLE; + } else { + p &= ~RADEON_ALPHA_TEST_ENABLE; + } + + if ( ctx->Color.BlendEnabled ) { + b &= ~(RADEON_SRC_BLEND_MASK | RADEON_DST_BLEND_MASK); + + switch ( ctx->Color.BlendSrcRGB ) { + case GL_ZERO: + b |= RADEON_SRC_BLEND_GL_ZERO; + break; + case GL_ONE: + b |= RADEON_SRC_BLEND_GL_ONE; + break; + case GL_DST_COLOR: + b |= RADEON_SRC_BLEND_GL_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR; + break; + case GL_SRC_ALPHA: + b |= RADEON_SRC_BLEND_GL_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + b |= RADEON_SRC_BLEND_GL_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + b |= RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA; + break; + case GL_SRC_ALPHA_SATURATE: + b |= RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE; + break; + } + + switch ( ctx->Color.BlendDstRGB ) { + case GL_ZERO: + b |= RADEON_DST_BLEND_GL_ZERO; + break; + case GL_ONE: + b |= RADEON_DST_BLEND_GL_ONE; + break; + case GL_SRC_COLOR: + b |= RADEON_DST_BLEND_GL_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR; + break; + case GL_SRC_ALPHA: + b |= RADEON_DST_BLEND_GL_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + b |= RADEON_DST_BLEND_GL_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + b |= RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA; + break; + } + + c |= RADEON_ALPHA_BLEND_ENABLE; + } else { + c &= ~RADEON_ALPHA_BLEND_ENABLE; + } + + if ( rmesa->setup.pp_misc != a ) { + rmesa->setup.pp_misc = a; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( rmesa->setup.pp_cntl != p ) { + rmesa->setup.pp_cntl = p; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( rmesa->setup.rb3d_blendcntl != b ) { + rmesa->setup.rb3d_blendcntl = b; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } + if ( rmesa->setup.rb3d_cntl != c ) { + rmesa->setup.rb3d_cntl = c; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } +} + +static void radeonDDAlphaFunc( GLcontext *ctx, GLenum func, GLclampf ref ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendEquation( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; +} + +static void radeonDDBlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; +} + + +/* ============================================================= + * Depth testing + */ + +static void radeonUpdateZMode( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 z = rmesa->setup.rb3d_zstencilcntl; + CARD32 c = rmesa->setup.rb3d_cntl; + + if ( ctx->Depth.Test ) { + z &= ~RADEON_Z_TEST_MASK; + + switch ( ctx->Depth.Func ) { + case GL_NEVER: + z |= RADEON_Z_TEST_NEVER; + break; + case GL_ALWAYS: + z |= RADEON_Z_TEST_ALWAYS; + break; + case GL_LESS: + z |= RADEON_Z_TEST_LESS; + break; + case GL_LEQUAL: + z |= RADEON_Z_TEST_LEQUAL; + break; + case GL_EQUAL: + z |= RADEON_Z_TEST_EQUAL; + break; + case GL_GEQUAL: + z |= RADEON_Z_TEST_GEQUAL; + break; + case GL_GREATER: + z |= RADEON_Z_TEST_GREATER; + break; + case GL_NOTEQUAL: + z |= RADEON_Z_TEST_NEQUAL; + break; + } + + c |= RADEON_Z_ENABLE; + } else { + c &= ~RADEON_Z_ENABLE; + } + + if ( ctx->Depth.Mask ) { + z |= RADEON_Z_WRITE_ENABLE; + } else { + z &= ~RADEON_Z_WRITE_ENABLE; + } + + if ( rmesa->setup.rb3d_zstencilcntl != z ) { + rmesa->setup.rb3d_zstencilcntl = z; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + if ( rmesa->setup.rb3d_cntl != c ) { + rmesa->setup.rb3d_cntl = c; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } +} + +static void radeonDDDepthFunc( GLcontext *ctx, GLenum func ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_DEPTH; +} + +static void radeonDDDepthMask( GLcontext *ctx, GLboolean flag ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_DEPTH; +} + +static void radeonDDClearDepth( GLcontext *ctx, GLclampd d ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + switch ( rmesa->setup.rb3d_zstencilcntl & RADEON_DEPTH_FORMAT_MASK ) { + case RADEON_DEPTH_FORMAT_16BIT_INT_Z: + rmesa->ClearDepth = d * 0x0000ffff; + break; + case RADEON_DEPTH_FORMAT_24BIT_INT_Z: + rmesa->ClearDepth = d * 0x00ffffff; + break; + } +} + + +/* ============================================================= + * Fog + */ + +static void radeonUpdateFogAttrib( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 p = rmesa->setup.pp_cntl; + GLubyte c[4]; + CARD32 col; + + if ( ctx->FogMode == FOG_FRAGMENT ) { + p |= RADEON_FOG_ENABLE; + } else { + p &= ~RADEON_FOG_ENABLE; + } + + FLOAT_RGB_TO_UBYTE_RGB( c, ctx->Fog.Color ); + col = radeonPackColor( 4, c[0], c[1], c[2], 0 ); + + if ( rmesa->setup.pp_fog_color != col ) { + rmesa->setup.pp_fog_color = col; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + if ( rmesa->setup.pp_cntl != p ) { + rmesa->setup.pp_cntl = p; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } +} + +static void radeonDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *param ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_FOG; +} + + +/* ============================================================= + * Clipping + */ + +static void radeonUpdateClipping( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( rmesa->driDrawable ) { + __DRIdrawablePrivate *drawable = rmesa->driDrawable; + int x = 0; + int y = 0; + int w = drawable->w - 1; + int h = drawable->h - 1; + + if ( ctx->Scissor.Enabled ) { + if ( ctx->Scissor.X > x ) { + x = ctx->Scissor.X; + } + if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y ) { + y = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height; + } + if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < w ) { + w = ctx->Scissor.X + ctx->Scissor.Width - 1; + } + if ( drawable->h - ctx->Scissor.Y - 1 < h ) { + h = drawable->h - ctx->Scissor.Y - 1; + } + } + + rmesa->scissor_rect.x1 = x + rmesa->driDrawable->x; + rmesa->scissor_rect.y1 = y + rmesa->driDrawable->y; + rmesa->scissor_rect.x2 = w + rmesa->driDrawable->x; + rmesa->scissor_rect.y2 = h + rmesa->driDrawable->y; + + rmesa->dirty |= RADEON_UPLOAD_CLIPRECTS; + } +} + +static void radeonDDScissor( GLcontext *ctx, + GLint x, GLint y, GLsizei w, GLsizei h ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_CLIP; +} + + +/* ============================================================= + * Culling + */ + +static void radeonUpdateCull( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 s = rmesa->setup.se_cntl; + + s &= ~RADEON_FFACE_CULL_DIR_MASK; + + switch ( ctx->Polygon.FrontFace ) { + case GL_CW: + s |= RADEON_FFACE_CULL_CW; + break; + case GL_CCW: + s |= RADEON_FFACE_CULL_CCW; + break; + } + + s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; + + if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + s &= ~RADEON_FFACE_SOLID; + break; + case GL_BACK: + s &= ~RADEON_BFACE_SOLID; + break; + case GL_FRONT_AND_BACK: + s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID); + break; + } + } + + if ( rmesa->setup.se_cntl != s ) { + rmesa->setup.se_cntl = s; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_SETUP; + } +} + +static void radeonDDCullFace( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_CULL; +} + +static void radeonDDFrontFace( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_CULL; +} + + +/* ============================================================= + * Masks + */ + +static void radeonUpdateMasks( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + GLuint mask = radeonPackColor( rmesa->radeonScreen->cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] ); + + if ( rmesa->setup.rb3d_planemask != mask ) { + rmesa->setup.rb3d_planemask = mask; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; + } +} + +static GLboolean radeonDDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_MASKS; + + return GL_TRUE; +} + + +/* ============================================================= + * Rendering attributes + * + * We really don't want to recalculate all this every time we bind a + * texture. These things shouldn't change all that often, so it makes + * sense to break them out of the core texture state update routines. + */ + +static void radeonDDLightModelfv( GLcontext *ctx, GLenum pname, + const GLfloat *param ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { + CARD32 p = rmesa->setup.pp_cntl; + + FLUSH_BATCH( rmesa ); + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) { + p |= RADEON_SPECULAR_ENABLE; + } else { + p &= ~RADEON_SPECULAR_ENABLE; + } + + if ( rmesa->setup.pp_cntl != p ) { + rmesa->setup.pp_cntl = p; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + } +} + +static void radeonDDShadeModel( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 s = rmesa->setup.se_cntl; + + s &= ~(RADEON_DIFFUSE_SHADE_MASK | + RADEON_ALPHA_SHADE_MASK | + RADEON_SPECULAR_SHADE_MASK | + RADEON_FOG_SHADE_MASK); + + switch ( mode ) { + case GL_FLAT: + s |= (RADEON_DIFFUSE_SHADE_FLAT | + RADEON_ALPHA_SHADE_FLAT | + RADEON_SPECULAR_SHADE_FLAT | + RADEON_FOG_SHADE_FLAT); + break; + case GL_SMOOTH: + s |= (RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_ALPHA_SHADE_GOURAUD | + RADEON_SPECULAR_SHADE_GOURAUD | + RADEON_FOG_SHADE_GOURAUD); + break; + default: + return; + } + + if ( rmesa->setup.se_cntl != s ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.se_cntl = s; + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_SETUP; + } +} + + +/* ============================================================= + * Window position + */ + +void radeonUpdateWindow( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + GLfloat xoffset = (GLfloat)dPriv->x; + GLfloat yoffset = (GLfloat)dPriv->y + dPriv->h; + const GLfloat one = 1.0; +#if 0 + CARD32 m = rmesa->setup.re_misc; + CARD32 sx, sy; +#endif + + rmesa->setup.se_vport_xscale = *(GLuint *)&one; + rmesa->setup.se_vport_xoffset = *(GLuint *)&xoffset; + rmesa->setup.se_vport_yscale = *(GLuint *)&one; + rmesa->setup.se_vport_yoffset = *(GLuint *)&yoffset; + rmesa->setup.se_vport_zscale = *(GLuint *)&rmesa->depth_scale; + rmesa->setup.se_vport_zoffset = 0x00000000; + +#if 0 + /* FIXME: This appears to be broken... + */ + m &= ~(RADEON_STIPPLE_X_OFFSET_MASK | + RADEON_STIPPLE_Y_OFFSET_MASK); + + sx = rmesa->driDrawable->x & RADEON_STIPPLE_COORD_MASK; + sy = rmesa->driDrawable->y & RADEON_STIPPLE_COORD_MASK; + + m |= ((sx << RADEON_STIPPLE_X_OFFSET_SHIFT) | + (sy << RADEON_STIPPLE_Y_OFFSET_SHIFT)); + + if ( rmesa->setup.re_misc != m ) { + rmesa->setup.re_misc = m; + rmesa->dirty |= RADEON_UPLOAD_MISC; + } +#endif + rmesa->dirty |= RADEON_UPLOAD_VIEWPORT; +} + + +/* ============================================================= + * Miscellaneous + */ + +static void radeonDDClearColor( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + rmesa->ClearColor = radeonPackColor( rmesa->radeonScreen->cpp, + r, g, b, a ); +} + +static void radeonDDColor( GLcontext *ctx, + GLubyte r, GLubyte g, GLubyte b, GLubyte a ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + rmesa->Color = radeonPackColor( rmesa->radeonScreen->cpp, + r, g, b, a ); +} + +static void radeonDDLogicOpCode( GLcontext *ctx, GLenum opcode ) +{ + if ( ctx->Color.ColorLogicOpEnabled ) { + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + + /* FIXME: We can do color logic ops. + */ + if ( opcode == GL_COPY ) { + rmesa->Fallback &= ~RADEON_FALLBACK_LOGICOP; + } else { + rmesa->Fallback |= RADEON_FALLBACK_LOGICOP; + } + } +} + +static GLboolean radeonDDSetDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int found = GL_TRUE; + + FLUSH_BATCH( rmesa ); + + if ( rmesa->DrawBuffer != mode ) { + rmesa->DrawBuffer = mode; + rmesa->Fallback &= ~RADEON_FALLBACK_DRAW_BUFFER; + + switch ( mode ) { + case GL_FRONT_LEFT: + rmesa->drawOffset = rmesa->radeonScreen->frontOffset; + rmesa->drawPitch = rmesa->radeonScreen->frontPitch; + break; + case GL_BACK_LEFT: + rmesa->drawOffset = rmesa->radeonScreen->backOffset; + rmesa->drawPitch = rmesa->radeonScreen->backPitch; + break; + default: + rmesa->Fallback |= RADEON_FALLBACK_DRAW_BUFFER; + found = GL_FALSE; + break; + } + + rmesa->setup.rb3d_coloroffset = + (rmesa->drawOffset & RADEON_COLOROFFSET_MASK); + rmesa->setup.rb3d_colorpitch = rmesa->drawPitch; + + rmesa->new_state |= RADEON_NEW_WINDOW; + } + + return found; +} + +static void radeonDDSetReadBuffer( GLcontext *ctx, + GLframebuffer *colorBuffer, + GLenum mode ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + rmesa->Fallback &= ~RADEON_FALLBACK_READ_BUFFER; + + switch ( mode ) { + case GL_FRONT_LEFT: + rmesa->readOffset = rmesa->radeonScreen->frontOffset; + rmesa->readPitch = rmesa->radeonScreen->frontPitch; + break; + case GL_BACK_LEFT: + rmesa->readOffset = rmesa->radeonScreen->backOffset; + rmesa->readPitch = rmesa->radeonScreen->backPitch; + break; + default: + rmesa->Fallback |= RADEON_FALLBACK_READ_BUFFER; + break; + } +} + + +/* ============================================================= + * Polygon stipple + */ + +static void radeonDDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint *stipple = (GLuint *)mask; + + FLUSH_BATCH( rmesa ); + + if ( ctx->Polygon.StippleFlag && ctx->PB->primitive == GL_POLYGON ) { + rmesa->setup.pp_cntl |= RADEON_STIPPLE_ENABLE; + } else { + rmesa->setup.pp_cntl &= ~RADEON_STIPPLE_ENABLE; + } + + LOCK_HARDWARE( rmesa ); + + /* FIXME: Use window x,y offsets into stipple RAM. + */ + drmRadeonPolygonStipple( rmesa->driFd, stipple ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; +} + + +/* ============================================================= + * State enable/disable + */ + +static void radeonDDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + switch ( cap ) { + case GL_ALPHA_TEST: + case GL_BLEND: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_ALPHA; + break; + + case GL_CULL_FACE: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_CULL; + break; + + case GL_DEPTH_TEST: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_DEPTH; + break; + + case GL_DITHER: + do { + CARD32 r = rmesa->setup.rb3d_cntl; + FLUSH_BATCH( rmesa ); + + if ( ctx->Color.DitherFlag ) { + r |= RADEON_DITHER_ENABLE; + } else { + r &= ~RADEON_DITHER_ENABLE; + } + + if ( rmesa->setup.rb3d_cntl != r ) { + rmesa->setup.rb3d_cntl = r; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + } while (0); + break; + + case GL_FOG: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_FOG; + break; + + case GL_INDEX_LOGIC_OP: + case GL_COLOR_LOGIC_OP: + FLUSH_BATCH( rmesa ); + if ( state && ctx->Color.LogicOp != GL_COPY ) { + rmesa->Fallback |= RADEON_FALLBACK_LOGICOP; + } else { + rmesa->Fallback &= ~RADEON_FALLBACK_LOGICOP; + } + break; + + case GL_SCISSOR_TEST: + FLUSH_BATCH( rmesa ); + rmesa->scissor = state; + rmesa->new_state |= RADEON_NEW_CLIP; + break; + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_TEXTURE; + break; + + case GL_POLYGON_STIPPLE: + if ( ctx->PB->primitive == GL_POLYGON ) { + FLUSH_BATCH( rmesa ); + if ( state ) { + rmesa->setup.pp_cntl |= RADEON_STIPPLE_ENABLE; + } else { + rmesa->setup.pp_cntl &= ~RADEON_STIPPLE_ENABLE; + } + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + break; + + default: + return; + } +} + + +/* ============================================================= + * State initialization, management + */ + +static void radeonDDPrintDirty( const char *msg, GLuint state ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + state, + (state & RADEON_UPLOAD_CONTEXT) ? "context, " : "", + (state & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "", + (state & RADEON_UPLOAD_LINE) ? "line, " : "", + (state & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", + (state & RADEON_UPLOAD_MASKS) ? "masks, " : "", + (state & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", + (state & RADEON_UPLOAD_SETUP) ? "setup, " : "", + (state & RADEON_UPLOAD_TCL) ? "tcl, " : "", + (state & RADEON_UPLOAD_MISC) ? "misc, " : "", + (state & RADEON_UPLOAD_TEX0) ? "tex0, " : "", + (state & RADEON_UPLOAD_TEX1) ? "tex1, " : "", + (state & RADEON_UPLOAD_TEX2) ? "tex2, " : "", + (state & RADEON_UPLOAD_TEX0IMAGES) ? "tex0 images, " : "", + (state & RADEON_UPLOAD_TEX1IMAGES) ? "tex1 images, " : "", + (state & RADEON_UPLOAD_TEX2IMAGES) ? "tex2 images, " : "", + (state & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (state & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); +} + +/* + * Load the current context's state into the hardware. + * + * NOTE: Be VERY careful about ensuring the context state is marked for + * upload, the only place it shouldn't be uploaded is when the setup + * state has changed in ReducedPrimitiveChange as this comes right after + * a state update. + * + * Blits of any type should always upload the context and masks after + * they are done. + */ +void radeonEmitHwStateLocked( radeonContextPtr rmesa ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + radeon_context_regs_t *regs = &(rmesa->setup); + radeonTexObjPtr t0 = rmesa->CurrentTexObj[0]; + radeonTexObjPtr t1 = rmesa->CurrentTexObj[1]; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + radeonDDPrintDirty( "radeonEmitHwStateLocked", rmesa->dirty ); + } + + if ( (rmesa->dirty & RADEON_UPLOAD_TEX0IMAGES) && t0 ) { + radeonUploadTexImages( rmesa, t0 ); + rmesa->dirty &= ~RADEON_UPLOAD_TEX0IMAGES; + } + if ( (rmesa->dirty & RADEON_UPLOAD_TEX1IMAGES) && t1 ) { + radeonUploadTexImages( rmesa, t1 ); + rmesa->dirty &= ~RADEON_UPLOAD_TEX1IMAGES; + } + if ( rmesa->dirty & RADEON_UPLOAD_TEX2IMAGES ) { + /* FIXME: Enable the third texture unit... */ + rmesa->dirty &= ~RADEON_UPLOAD_TEX2IMAGES; + } + + if ( rmesa->dirty & (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_VERTFMT | + RADEON_UPLOAD_LINE | + RADEON_UPLOAD_BUMPMAP | + RADEON_UPLOAD_MASKS | + RADEON_UPLOAD_VIEWPORT | + RADEON_UPLOAD_SETUP | + RADEON_UPLOAD_TCL | + RADEON_UPLOAD_MISC) ) { + memcpy( &sarea->ContextState, regs, sizeof(sarea->ContextState) ); + } + + /* Assemble the texture state, combining the texture object and + * texture environment state into the hardware texture unit state. + */ + if ( (rmesa->dirty & RADEON_UPLOAD_TEX0) && t0 ) { + radeon_texture_regs_t *tex = &sarea->TexState[0]; + + tex->pp_txfilter = t0->setup.pp_txfilter | rmesa->lod_bias[0] << 8; + tex->pp_txformat = t0->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ0; + tex->pp_txoffset = t0->setup.pp_txoffset; + + tex->pp_txcblend = rmesa->color_combine[0]; + tex->pp_txablend = rmesa->alpha_combine[0]; + tex->pp_tfactor = rmesa->env_color[0]; + + tex->pp_border_color = t0->setup.pp_border_color; + } + + if ( (rmesa->dirty & RADEON_UPLOAD_TEX1) && t1 ) { + radeon_texture_regs_t *tex = &sarea->TexState[1]; + + tex->pp_txfilter = t1->setup.pp_txfilter | rmesa->lod_bias[1] << 8; + tex->pp_txformat = t1->setup.pp_txformat | RADEON_TXF_ST_ROUTE_STQ1; + tex->pp_txoffset = t1->setup.pp_txoffset; + + tex->pp_txcblend = rmesa->color_combine[1]; + tex->pp_txablend = rmesa->alpha_combine[1]; + tex->pp_tfactor = rmesa->env_color[1]; + + tex->pp_border_color = t1->setup.pp_border_color; + } + + if ( rmesa->dirty & RADEON_UPLOAD_TEX2 ) { + /* FIXME: Enable the third texture unit... */ + memset( &sarea->TexState[2], 0, sizeof(sarea->TexState[2]) ); + } + + sarea->vertsize = rmesa->vertsize; + sarea->vc_format = rmesa->vc_format; + + sarea->dirty |= rmesa->dirty; + rmesa->dirty &= RADEON_UPLOAD_CLIPRECTS; +} + +static void radeonDDPrintState( const char *msg, GLuint flags ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & RADEON_NEW_CONTEXT) ? "context, " : "", + (flags & RADEON_NEW_ALPHA) ? "alpha, " : "", + (flags & RADEON_NEW_DEPTH) ? "depth, " : "", + (flags & RADEON_NEW_FOG) ? "fog, " : "", + (flags & RADEON_NEW_CLIP) ? "clip, " : "", + (flags & RADEON_NEW_TEXTURE) ? "texture, " : "", + (flags & RADEON_NEW_CULL) ? "cull, " : "", + (flags & RADEON_NEW_MASKS) ? "masks, " : "", + (flags & RADEON_NEW_WINDOW) ? "window, " : "" ); +} + +void radeonDDUpdateHWState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int new_state = rmesa->new_state; + + if ( new_state ) { + FLUSH_BATCH( rmesa ); + + rmesa->new_state = 0; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) + radeonDDPrintState( "radeonUpdateHwState", new_state ); + + /* Update the various parts of the context's state. + */ + if ( new_state & RADEON_NEW_ALPHA ) + radeonUpdateAlphaMode( ctx ); + + if ( new_state & RADEON_NEW_DEPTH ) + radeonUpdateZMode( ctx ); + + if ( new_state & RADEON_NEW_FOG ) + radeonUpdateFogAttrib( ctx ); + + if ( new_state & RADEON_NEW_CLIP ) + radeonUpdateClipping( ctx ); + + if ( new_state & RADEON_NEW_CULL ) + radeonUpdateCull( ctx ); + + if ( new_state & RADEON_NEW_MASKS ) + radeonUpdateMasks( ctx ); + + if ( new_state & RADEON_NEW_WINDOW ) + radeonUpdateWindow( ctx ); + + if ( new_state & RADEON_NEW_TEXTURE ) + radeonUpdateTextureState( ctx ); + } +} + +/* This is called when Mesa switches between rendering triangle + * primitives (such as GL_POLYGON, GL_QUADS, GL_TRIANGLE_STRIP, etc), + * and lines, points and bitmaps. + * + * As the radeon uses triangles to render lines and points, it is + * necessary to turn off hardware culling when rendering these + * primitives. + */ +static void radeonDDReducedPrimitiveChange( GLcontext *ctx, GLenum prim ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + CARD32 s = rmesa->setup.se_cntl; + + s |= RADEON_FFACE_SOLID | RADEON_BFACE_SOLID; + + if ( ctx->Polygon.CullFlag && ctx->PB->primitive == GL_POLYGON ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + s &= ~RADEON_FFACE_SOLID; + break; + case GL_BACK: + s &= ~RADEON_BFACE_SOLID; + break; + case GL_FRONT_AND_BACK: + s &= ~(RADEON_FFACE_SOLID | RADEON_BFACE_SOLID); + break; + } + } + + if ( rmesa->setup.se_cntl != s ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.se_cntl = s; + + /* NOTE: Only upload the setup state, everything else has been + * uploaded by the usual means already. Also, note that this is + * an optimization (see comment in the kernel's radeon_state.c), + * which will not be necessary when/if we use the Radeon's + * native point/line support. + */ + rmesa->dirty |= RADEON_UPLOAD_SETUP; + } +} + + +#define INTERESTED (~(NEW_MODELVIEW | \ + NEW_PROJECTION | \ + NEW_TEXTURE_MATRIX | \ + NEW_USER_CLIP | \ + NEW_CLIENT_STATE)) + +void radeonDDUpdateState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( ctx->NewState & INTERESTED ) { + radeonDDChooseRenderState( ctx ); + radeonDDChooseRasterSetupFunc( ctx ); + } + + /* Need to do this here to detect texture fallbacks before + * setting triangle functions. + * GH: Do we need this anymore? The Radeon doesn't really have + * texturing fallbacks like the r128... + */ + if ( rmesa->new_state & RADEON_NEW_TEXTURE ) { + radeonDDUpdateHWState( ctx ); + } + + if ( !rmesa->Fallback ) { + ctx->IndirectTriangles &= ~DD_SW_RASTERIZE; + ctx->IndirectTriangles |= rmesa->IndirectTriangles; + + ctx->Driver.PointsFunc = rmesa->PointsFunc; + ctx->Driver.LineFunc = rmesa->LineFunc; + ctx->Driver.TriangleFunc = rmesa->TriangleFunc; + ctx->Driver.QuadFunc = rmesa->QuadFunc; + } +} + + +/* Initialize the context's hardware state. + */ +void radeonDDInitState( radeonContextPtr rmesa ) +{ + GLuint color_fmt, depth_fmt; + + switch ( rmesa->radeonScreen->cpp ) { + case 2: + color_fmt = RADEON_COLOR_FORMAT_RGB565; + break; + case 4: + color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + break; + default: + fprintf( stderr, "Error: Unsupported pixel depth... exiting\n" ); + exit( -1 ); + } + + rmesa->ClearColor = 0x00000000; + + switch ( rmesa->glCtx->Visual->DepthBits ) { + case 16: + rmesa->ClearDepth = 0x0000ffff; + depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + rmesa->depth_scale = 1.0 / (GLfloat)0xffff; + break; + case 24: + rmesa->ClearDepth = 0x00ffffff; + depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + rmesa->depth_scale = 1.0 / (GLfloat)0xffffff; + break; + default: + fprintf( stderr, "Error: Unsupported depth %d... exiting\n", + rmesa->glCtx->Visual->DepthBits ); + exit( -1 ); + } + + rmesa->RenderIndex = RADEON_FALLBACK_BIT; + rmesa->PointsFunc = NULL; + rmesa->LineFunc = NULL; + rmesa->TriangleFunc = NULL; + rmesa->QuadFunc = NULL; + + rmesa->IndirectTriangles = 0; + rmesa->Fallback = 0; + + if ( rmesa->glCtx->Visual->DBflag ) { + rmesa->DrawBuffer = GL_BACK_LEFT; + rmesa->drawOffset = rmesa->readOffset = rmesa->radeonScreen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->radeonScreen->backPitch; + } else { + rmesa->DrawBuffer = GL_FRONT_LEFT; + rmesa->drawOffset = rmesa->readOffset = rmesa->radeonScreen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->radeonScreen->frontPitch; + } + + /* Harware state: + */ + rmesa->setup.pp_misc = (RADEON_ALPHA_TEST_PASS | + RADEON_CHROMA_FUNC_FAIL | + RADEON_CHROMA_KEY_NEAREST | + RADEON_SHADOW_FUNC_EQUAL | + RADEON_SHADOW_PASS_1 | + RADEON_RIGHT_HAND_CUBE_OGL); + + rmesa->setup.pp_fog_color = ((0x00000000 & RADEON_FOG_COLOR_MASK) | + RADEON_FOG_VERTEX | + RADEON_FOG_USE_DEPTH); + + rmesa->setup.re_solid_color = 0x00000000; + + rmesa->setup.rb3d_blendcntl = (RADEON_SRC_BLEND_GL_ONE | + RADEON_DST_BLEND_GL_ZERO ); + + rmesa->setup.rb3d_depthoffset = rmesa->radeonScreen->depthOffset; + + rmesa->setup.rb3d_depthpitch = ((rmesa->radeonScreen->depthPitch & + RADEON_DEPTHPITCH_MASK) | + RADEON_DEPTH_ENDIAN_NO_SWAP); + + rmesa->setup.rb3d_zstencilcntl = (depth_fmt | + RADEON_Z_TEST_LESS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_KEEP | + RADEON_STENCIL_ZPASS_KEEP | + RADEON_STENCIL_ZFAIL_KEEP | + RADEON_Z_WRITE_ENABLE); + + rmesa->setup.pp_cntl = (RADEON_SCISSOR_ENABLE | + RADEON_ANTI_ALIAS_NONE); + + rmesa->setup.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | + color_fmt | + RADEON_ZBLOCK16); + + rmesa->setup.rb3d_coloroffset = (rmesa->drawOffset & + RADEON_COLOROFFSET_MASK); + + rmesa->setup.re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) | + (0x7ff << RADEON_RE_HEIGHT_SHIFT)); + + rmesa->setup.rb3d_colorpitch = ((rmesa->drawPitch & + RADEON_COLORPITCH_MASK) | + RADEON_COLOR_ENDIAN_NO_SWAP); + + rmesa->setup.se_cntl = (RADEON_FFACE_CULL_CW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_FLAT_SHADE_VTX_LAST | + RADEON_DIFFUSE_SHADE_GOURAUD | + RADEON_ALPHA_SHADE_GOURAUD | + RADEON_SPECULAR_SHADE_GOURAUD | + RADEON_FOG_SHADE_GOURAUD | + RADEON_VPORT_XY_XFORM_ENABLE | + RADEON_VPORT_Z_XFORM_ENABLE | + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_8TH_PIX); + + rmesa->setup.se_coord_fmt = (RADEON_VTX_XY_PRE_MULT_1_OVER_W0 | + RADEON_VTX_Z_PRE_MULT_1_OVER_W0 | + RADEON_TEX1_W_ROUTING_USE_Q1); + + rmesa->setup.re_line_pattern = ((0x0000 & RADEON_LINE_PATTERN_MASK) | + (0 << RADEON_LINE_REPEAT_COUNT_SHIFT) | + (0 << RADEON_LINE_PATTERN_START_SHIFT) | + RADEON_LINE_PATTERN_LITTLE_BIT_ORDER); + + rmesa->setup.re_line_state = ((0 << RADEON_LINE_CURRENT_PTR_SHIFT) | + (0 << RADEON_LINE_CURRENT_COUNT_SHIFT)); + + rmesa->setup.se_line_width = 0x0000000; + + rmesa->setup.pp_lum_matrix = 0x00000000; + + rmesa->setup.pp_rot_matrix_0 = 0x00000000; + rmesa->setup.pp_rot_matrix_1 = 0x00000000; + + rmesa->setup.rb3d_stencilrefmask = ((0x00 << RADEON_STENCIL_REF_SHIFT) | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + (0xff << RADEON_STENCIL_WRITEMASK_SHIFT)); + + rmesa->setup.rb3d_ropcntl = 0x00000000; + rmesa->setup.rb3d_planemask = 0xffffffff; + + rmesa->setup.se_vport_xscale = 0x00000000; + rmesa->setup.se_vport_xoffset = 0x00000000; + rmesa->setup.se_vport_yscale = 0x00000000; + rmesa->setup.se_vport_yoffset = 0x00000000; + rmesa->setup.se_vport_zscale = 0x00000000; + rmesa->setup.se_vport_zoffset = 0x00000000; + + rmesa->setup.se_cntl_status = (RADEON_VC_NO_SWAP | + RADEON_TCL_BYPASS); + +#ifdef TCL_ENABLE + /* FIXME: Obviously these need to be properly initialized */ + rmesa->setup.se_tcl_material_emmissive.red = 0x00000000; + rmesa->setup.se_tcl_material_emmissive.green = 0x00000000; + rmesa->setup.se_tcl_material_emmissive.blue = 0x00000000; + rmesa->setup.se_tcl_material_emmissive.alpha = 0x00000000; + + rmesa->setup.se_tcl_material_ambient.red = 0x00000000; + rmesa->setup.se_tcl_material_ambient.green = 0x00000000; + rmesa->setup.se_tcl_material_ambient.blue = 0x00000000; + rmesa->setup.se_tcl_material_ambient.alpha = 0x00000000; + + rmesa->setup.se_tcl_material_diffuse.red = 0x00000000; + rmesa->setup.se_tcl_material_diffuse.green = 0x00000000; + rmesa->setup.se_tcl_material_diffuse.blue = 0x00000000; + rmesa->setup.se_tcl_material_diffuse.alpha = 0x00000000; + + rmesa->setup.se_tcl_material_specular.red = 0x00000000; + rmesa->setup.se_tcl_material_specular.green = 0x00000000; + rmesa->setup.se_tcl_material_specular.blue = 0x00000000; + rmesa->setup.se_tcl_material_specular.alpha = 0x00000000; + + rmesa->setup.se_tcl_shininess = 0x00000000; + rmesa->setup.se_tcl_output_vtx_fmt = 0x00000000; + rmesa->setup.se_tcl_output_vtx_sel = 0x00000000; + rmesa->setup.se_tcl_matrix_select_0 = 0x00000000; + rmesa->setup.se_tcl_matrix_select_1 = 0x00000000; + rmesa->setup.se_tcl_ucp_vert_blend_ctl = 0x00000000; + rmesa->setup.se_tcl_texture_proc_ctl = 0x00000000; + rmesa->setup.se_tcl_light_model_ctl = 0x00000000; + for ( i = 0 ; i < 4 ; i++ ) { + rmesa->setup.se_tcl_per_light_ctl[i] = 0x00000000; + } +#endif + + rmesa->setup.re_top_left = ((0 << RADEON_RE_LEFT_SHIFT) | + (0 << RADEON_RE_TOP_SHIFT) ); + + rmesa->setup.re_misc = ((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) | + (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) | + RADEON_STIPPLE_LITTLE_BIT_ORDER); + + rmesa->env_color[0] = 0x00000000; + rmesa->env_color[1] = 0x00000000; + rmesa->env_color[2] = 0x00000000; + + rmesa->new_state = RADEON_NEW_ALL; +} + +/* Initialize the driver's state functions. + */ +void radeonDDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = radeonDDUpdateState; + + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = radeonDDClearColor; + ctx->Driver.Index = NULL; + ctx->Driver.Color = radeonDDColor; + ctx->Driver.SetDrawBuffer = radeonDDSetDrawBuffer; + ctx->Driver.SetReadBuffer = radeonDDSetReadBuffer; + + ctx->Driver.IndexMask = NULL; + ctx->Driver.ColorMask = radeonDDColorMask; + ctx->Driver.LogicOp = NULL; + ctx->Driver.Dither = NULL; + + ctx->Driver.NearFar = NULL; + + ctx->Driver.RenderStart = radeonDDUpdateHWState; + ctx->Driver.RenderFinish = NULL; + ctx->Driver.RasterSetup = NULL; + + ctx->Driver.RenderVBClippedTab = NULL; + ctx->Driver.RenderVBCulledTab = NULL; + ctx->Driver.RenderVBRawTab = NULL; + + ctx->Driver.ReducedPrimitiveChange = radeonDDReducedPrimitiveChange; + ctx->Driver.MultipassFunc = NULL; + + ctx->Driver.AlphaFunc = radeonDDAlphaFunc; + ctx->Driver.BlendEquation = radeonDDBlendEquation; + ctx->Driver.BlendFunc = radeonDDBlendFunc; + ctx->Driver.BlendFuncSeparate = radeonDDBlendFuncSeparate; + ctx->Driver.ClearDepth = radeonDDClearDepth; + ctx->Driver.CullFace = radeonDDCullFace; + ctx->Driver.FrontFace = radeonDDFrontFace; + ctx->Driver.DepthFunc = radeonDDDepthFunc; + ctx->Driver.DepthMask = radeonDDDepthMask; + ctx->Driver.DepthRange = NULL; + ctx->Driver.Enable = radeonDDEnable; + ctx->Driver.Fogfv = radeonDDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LightModelfv = radeonDDLightModelfv; + ctx->Driver.LogicOpcode = radeonDDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = radeonDDPolygonStipple; + ctx->Driver.Scissor = radeonDDScissor; + ctx->Driver.ShadeModel = radeonDDShadeModel; + ctx->Driver.ClearStencil = NULL; + ctx->Driver.StencilFunc = NULL; + ctx->Driver.StencilMask = NULL; + ctx->Driver.StencilOp = NULL; + ctx->Driver.Viewport = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h new file mode 100644 index 000000000..9a368d989 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h @@ -0,0 +1,55 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_state.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_STATE_H__ +#define __RADEON_STATE_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_context.h" + +extern void radeonDDInitState( radeonContextPtr rmesa ); +extern void radeonDDInitStateFuncs( GLcontext *ctx ); + +extern void radeonDDUpdateState( GLcontext *ctx ); +extern void radeonDDUpdateHWState( GLcontext *ctx ); + +extern void radeonUpdateWindow( GLcontext *ctx ); + +extern void radeonEmitHwStateLocked( radeonContextPtr rmesa ); + +#endif +#endif diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c new file mode 100644 index 000000000..32709537b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c @@ -0,0 +1,2253 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c,v 1.2 2001/01/16 05:10:59 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_state.h" +#include "radeon_ioctl.h" +#include "radeon_vb.h" +#include "radeon_tex.h" + +#include "mmath.h" +#include "simple_list.h" +#include "enums.h" +#include "mem.h" + + +static void radeonSetTexWrap( radeonTexObjPtr t, GLenum swrap, GLenum twrap ) +{ + t->setup.pp_txfilter &= ~(RADEON_CLAMP_S_MASK | RADEON_CLAMP_T_MASK); + + switch ( swrap ) { + case GL_REPEAT: + t->setup.pp_txfilter |= RADEON_CLAMP_S_WRAP; + break; + case GL_CLAMP: + t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; + break; + case GL_CLAMP_TO_EDGE: + t->setup.pp_txfilter |= RADEON_CLAMP_S_CLAMP_LAST; + break; + } + + switch ( twrap ) { + case GL_REPEAT: + t->setup.pp_txfilter |= RADEON_CLAMP_T_WRAP; + break; + case GL_CLAMP: + t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; + break; + case GL_CLAMP_TO_EDGE: + t->setup.pp_txfilter |= RADEON_CLAMP_T_CLAMP_LAST; + break; + } +} + +static void radeonSetTexFilter( radeonTexObjPtr t, GLenum minf, GLenum magf ) +{ + t->setup.pp_txfilter &= ~(RADEON_MIN_FILTER_MASK | RADEON_MAG_FILTER_MASK); + + switch ( minf ) { + case GL_NEAREST: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST; + break; + case GL_LINEAR: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_NEAREST; + break; + case GL_LINEAR_MIPMAP_NEAREST: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_NEAREST_MIP_LINEAR; + break; + case GL_LINEAR_MIPMAP_LINEAR: + t->setup.pp_txfilter |= RADEON_MIN_FILTER_LINEAR_MIP_LINEAR; + break; + } + + switch ( magf ) { + case GL_NEAREST: + t->setup.pp_txfilter |= RADEON_MAG_FILTER_NEAREST; + break; + case GL_LINEAR: + t->setup.pp_txfilter |= RADEON_MAG_FILTER_LINEAR; + break; + } +} + +static void radeonSetTexBorderColor( radeonTexObjPtr t, GLubyte c[4] ) +{ + t->setup.pp_border_color = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); +} + + +/* Allocate and initialize hardware state associated with texture `t'. + */ +static radeonTexObjPtr radeonCreateTexObj( radeonContextPtr rmesa, + struct gl_texture_object *tObj ) +{ + radeonTexObjPtr t; + struct gl_texture_image *image; + GLint log2Width, log2Height, log2Size, log2MinSize; + GLint totalSize; + GLint texelsPerDword = 0, blitWidth = 0, blitPitch = 0; + GLint x, y, width, height; + GLint i; + GLuint txformat, txalpha; + + image = tObj->Image[0]; + if ( !image ) + return NULL; + + t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); + if ( !t ) + return NULL; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) + fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj ); + + switch ( image->Format ) { + case GL_RGBA: + if ( image->IntFormat != GL_RGBA4 && + ( image->IntFormat == GL_RGBA8 || + rmesa->radeonScreen->cpp == 4 ) ) { + t->texelBytes = 4; + txformat = RADEON_TXF_32BPP_ARGB8888; + } else { + t->texelBytes = 2; + txformat = RADEON_TXF_16BPP_ARGB4444; + } + txalpha = RADEON_TXF_ALPHA_IN_MAP; + break; + + case GL_RGB: + if ( image->IntFormat != GL_RGB5 && + ( image->IntFormat == GL_RGB8 || + rmesa->radeonScreen->cpp == 4 ) ) { + t->texelBytes = 4; + txformat = RADEON_TXF_32BPP_ARGB8888; + } else { + t->texelBytes = 2; + txformat = RADEON_TXF_16BPP_RGB565; + } + txalpha = 0; + break; + + case GL_ALPHA: + case GL_LUMINANCE_ALPHA: + t->texelBytes = 2; + txformat = RADEON_TXF_16BPP_AI88; + txalpha = RADEON_TXF_ALPHA_IN_MAP; + break; + + case GL_LUMINANCE: + t->texelBytes = 2; + txformat = RADEON_TXF_16BPP_AI88; + txalpha = 0; + break; + + case GL_INTENSITY: + t->texelBytes = 1; + txformat = RADEON_TXF_8BPP_I; + txalpha = 0; + break; + + case GL_COLOR_INDEX: + default: + fprintf( stderr, "%s: bad image->Format\n", __FUNCTION__ ); + FREE( t ); + return NULL; + } + + /* Calculate dimensions in log domain. + */ + for ( i = 1, log2Height = 0 ; i < image->Height ; i *= 2 ) { + log2Height++; + } + for ( i = 1, log2Width = 0 ; i < image->Width ; i *= 2 ) { + log2Width++; + } + if ( image->Width > image->Height ) { + log2Size = log2Width; + } else { + log2Size = log2Height; + } + + t->dirty_images = 0; + + /* The Radeon has a 64-byte minimum pitch for all blits. We + * calculate the equivalent number of texels to simplify the + * calculation of the texture image area. + */ + switch ( t->texelBytes ) { + case 1: + texelsPerDword = 4; + blitPitch = 64; + break; + case 2: + texelsPerDword = 2; + blitPitch = 32; + break; + case 4: + texelsPerDword = 1; + blitPitch = 16; + break; + } + + /* Select the larger of the two widths for our global texture image + * coordinate space. As the Radeon has very strict offset rules, we + * can't upload mipmaps directly and have to reference their location + * from the aligned start of the whole image. + */ + blitWidth = MAX2( image->Width, blitPitch ); + + /* Calculate mipmap offsets and dimensions. + */ + totalSize = 0; + x = 0; + y = 0; + + for ( i = 0 ; i <= log2Size ; i++ ) { + GLuint size; + + image = tObj->Image[i]; + if ( !image ) + break; + + width = image->Width; + height = image->Height; + + /* Texture images have a minimum pitch of 32 bytes (half of the + * 64-byte minimum pitch for blits). For images that have a + * width smaller than this, we must pad each texture image + * scanline out to this amount. + */ + if ( width < blitPitch / 2 ) { + width = blitPitch / 2; + } + + size = width * height * t->texelBytes; + totalSize += size; + + t->dirty_images |= (1 << i); + + while ( width < blitWidth && height > 1 ) { + width *= 2; + height /= 2; + } + + t->image[i].x = x; + t->image[i].y = y; + + t->image[i].width = width; + t->image[i].height = height; + + t->image[i].dwords = size / sizeof(CARD32); + + /* While blits must have a pitch of at least 64 bytes, mipmaps + * must be aligned on a 32-byte boundary (just like each texture + * image scanline). + */ + if ( width >= blitWidth ) { + y += height; + } else { + x += width; + if ( x >= blitWidth ) { + x = 0; + y++; + } + } + + if ( 0 ) + fprintf( stderr, "level=%d p=%d %dx%d -> %dx%d at (%d,%d) %d dwords\n", + i, blitWidth, image->Width, image->Height, + t->image[i].width, t->image[i].height, + t->image[i].x, t->image[i].y, + t->image[i].dwords ); + } + + log2MinSize = log2Size - i + 1; + + /* Align the total size of texture memory block. + */ + totalSize = (totalSize + RADEON_OFFSET_MASK) & ~RADEON_OFFSET_MASK; + + t->totalSize = totalSize; + + t->bound = 0; + t->heap = 0; + t->tObj = tObj; + + t->memBlock = NULL; + t->bufAddr = 0; + + /* Hardware state: + */ + t->setup.pp_txfilter = ((log2Size << RADEON_MAX_MIP_LEVEL_SHIFT) | + RADEON_BORDER_MODE_OGL); + + t->setup.pp_txformat = (txformat | txalpha | + (log2Width << RADEON_TXF_WIDTH_SHIFT) | + (log2Height << RADEON_TXF_HEIGHT_SHIFT) | + RADEON_TXF_ENDIAN_NO_SWAP | + RADEON_TXF_PERSPECTIVE_ENABLE); + + t->setup.pp_txoffset = 0x00000000; + t->setup.pp_txcblend = 0x00000000; + t->setup.pp_txablend = 0x00000000; + t->setup.pp_tfactor = 0x00000000; + t->setup.pp_border_color = 0x00000000; + + radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT ); + radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + radeonSetTexBorderColor( t, tObj->BorderColor ); + + tObj->DriverData = t; + + make_empty_list( t ); + + return t; +} + +/* Destroy hardware state associated with texture `t'. + */ +void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + rmesa->c_textureSwaps++; +#endif + if ( !t ) return; + + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + if ( t->tObj ) + t->tObj->DriverData = NULL; + if ( t->bound ) + rmesa->CurrentTexObj[t->bound-1] = NULL; + + remove_from_list( t ); + FREE( t ); +} + +/* Keep track of swapped out texture objects. + */ +static void radeonSwapOutTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + rmesa->c_textureSwaps++; +#endif + if ( t->memBlock ) { + mmFreeMem( t->memBlock ); + t->memBlock = NULL; + } + + t->dirty_images = ~0; + move_to_tail( &rmesa->SwappedOut, t ); +} + +/* Print out debugging information about texture LRU. + */ +void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ) +{ + radeonTexObjPtr t; + int sz = 1 << (rmesa->radeonScreen->logTexGranularity[heap]); + + fprintf( stderr, "\nLocal LRU, heap %d:\n", heap ); + + foreach ( t, &rmesa->TexObjList[heap] ) { + if (!t->tObj) { + fprintf( stderr, "Placeholder %d at 0x%x sz 0x%x\n", + t->memBlock->ofs / sz, + t->memBlock->ofs, + t->memBlock->size ); + } else { + fprintf( stderr, "Texture (bound %d) at 0x%x sz 0x%x\n", + t->bound, + t->memBlock->ofs, + t->memBlock->size ); + } + } + + fprintf( stderr, "\n" ); +} + +void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ) +{ + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int i, j; + + fprintf( stderr, "\nGlobal LRU, heap %d list %p:\n", heap, list ); + + for ( i = 0, j = RADEON_NR_TEX_REGIONS ; i < RADEON_NR_TEX_REGIONS ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d\n", + j, list[j].age, list[j].next, list[j].prev ); + j = list[j].next; + if ( j == RADEON_NR_TEX_REGIONS ) break; + } + + if ( j != RADEON_NR_TEX_REGIONS ) { + fprintf( stderr, "Loop detected in global LRU\n" ); + for ( i = 0 ; i < RADEON_NR_TEX_REGIONS ; i++ ) { + fprintf( stderr, "list[%d] age %d next %d prev %d\n", + i, list[i].age, list[i].next, list[i].prev ); + } + } + + fprintf( stderr, "\n" ); +} + +/* Reset the global texture LRU. + */ +static void radeonResetGlobalLRU( radeonContextPtr rmesa, int heap ) +{ + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; + int i; + + /* + * (Re)initialize the global circular LRU list. The last element in + * the array (RADEON_NR_TEX_REGIONS) is the sentinal. Keeping it at + * the end of the array allows it to be addressed rationally when + * looking up objects at a particular location in texture memory. + */ + for ( i = 0 ; (i+1) * sz <= rmesa->radeonScreen->texSize[heap] ; i++ ) { + list[i].prev = i-1; + list[i].next = i+1; + list[i].age = 0; + } + + i--; + list[0].prev = RADEON_NR_TEX_REGIONS; + list[i].prev = i-1; + list[i].next = RADEON_NR_TEX_REGIONS; + list[RADEON_NR_TEX_REGIONS].prev = i; + list[RADEON_NR_TEX_REGIONS].next = 0; + rmesa->sarea->texAge[heap] = 0; +} + +/* Update the local and glock texture LRUs. + */ +static void radeonUpdateTexLRU(radeonContextPtr rmesa, radeonTexObjPtr t ) +{ + int heap = t->heap; + radeon_tex_region_t *list = rmesa->sarea->texList[heap]; + int sz = rmesa->radeonScreen->logTexGranularity[heap]; + int start = t->memBlock->ofs >> sz; + int end = (t->memBlock->ofs + t->memBlock->size-1) >> sz; + int i; + + rmesa->lastTexAge[heap] = ++rmesa->sarea->texAge[heap]; + + if ( !t->memBlock ) { + fprintf( stderr, "no memblock\n\n" ); + return; + } + + /* Update our local LRU */ + move_to_head( &rmesa->TexObjList[heap], t ); + + /* Update the global LRU */ + for ( i = start ; i <= end ; i++ ) { + list[i].in_use = 1; + list[i].age = rmesa->lastTexAge[heap]; + + /* remove_from_list(i) */ + list[(CARD32)list[i].next].prev = list[i].prev; + list[(CARD32)list[i].prev].next = list[i].next; + + /* insert_at_head(list, i) */ + list[i].prev = RADEON_NR_TEX_REGIONS; + list[i].next = list[RADEON_NR_TEX_REGIONS].next; + list[(CARD32)list[RADEON_NR_TEX_REGIONS].next].prev = i; + list[RADEON_NR_TEX_REGIONS].next = i; + } + + if ( 0 ) { + radeonPrintGlobalLRU( rmesa, t->heap ); + radeonPrintLocalLRU( rmesa, t->heap ); + } +} + +/* Update our notion of what textures have been changed since we last + * held the lock. This pertains to both our local textures and the + * textures belonging to other clients. Keep track of other client's + * textures by pushing a placeholder texture onto the LRU list -- these + * are denoted by (tObj == NULL). + */ +static void radeonTexturesGone( radeonContextPtr rmesa, int heap, + int offset, int size, int in_use ) +{ + radeonTexObjPtr t, tmp; + + foreach_s ( t, tmp, &rmesa->TexObjList[heap] ) { + if ( t->memBlock->ofs >= offset + size || + t->memBlock->ofs + t->memBlock->size <= offset ) + continue; + + /* It overlaps - kick it out. Need to hold onto the currently + * bound objects, however. + */ + if ( t->bound ) { + radeonSwapOutTexObj( rmesa, t ); + } else { + radeonDestroyTexObj( rmesa, t ); + } + } + + if ( in_use ) { + t = (radeonTexObjPtr) CALLOC( sizeof(*t) ); + if ( !t ) return; + + t->memBlock = mmAllocMem( rmesa->texHeap[heap], size, 0, offset ); + if ( !t->memBlock ) { + fprintf( stderr, "Couldn't alloc placeholder sz %x ofs %x\n", + (int)size, (int)offset ); + mmDumpMemInfo( rmesa->texHeap[heap] ); + return; + } + insert_at_head( &rmesa->TexObjList[heap], t ); + } +} + +/* Update our client's shared texture state. If another client has + * modified a region in which we have textures, then we need to figure + * out which of our textures has been removed, and update our global + * LRU. + */ +void radeonAgeTextures( radeonContextPtr rmesa, int heap ) +{ + RADEONSAREAPrivPtr sarea = rmesa->sarea; + + if ( sarea->texAge[heap] != rmesa->lastTexAge[heap] ) { + int sz = 1 << rmesa->radeonScreen->logTexGranularity[heap]; + int nr = 0; + int idx; + + for ( idx = sarea->texList[heap][RADEON_NR_TEX_REGIONS].prev ; + idx != RADEON_NR_TEX_REGIONS && nr < RADEON_NR_TEX_REGIONS ; + idx = sarea->texList[heap][idx].prev, nr++ ) + { + /* If switching texturing schemes, then the SAREA might not + * have been properly cleared, so we need to reset the + * global texture LRU. + */ + if ( idx * sz > rmesa->radeonScreen->texSize[heap] ) { + nr = RADEON_NR_TEX_REGIONS; + break; + } + + if ( sarea->texList[heap][idx].age > rmesa->lastTexAge[heap] ) { + radeonTexturesGone( rmesa, heap, idx * sz, sz, + sarea->texList[heap][idx].in_use ); + } + } + + if ( nr == RADEON_NR_TEX_REGIONS ) { + radeonTexturesGone( rmesa, heap, 0, + rmesa->radeonScreen->texSize[heap], 0 ); + radeonResetGlobalLRU( rmesa, heap ); + } + + rmesa->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES); + rmesa->lastTexAge[heap] = sarea->texAge[heap]; + } +} + + +/* ================================================================ + * Texture image conversions + */ + +/* Convert a block of Mesa-formatted texture to an 8bpp hardware format. + */ +static void radeonConvertTexture8bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + + if ( width < 4 ) { + width = 4; + } + +#define ALIGN_DST \ + do { \ + if ( width < 32 ) { \ + dst += ((32 - width) / 4); \ + } \ + } while (0) + + switch ( image->Format ) { + case GL_INTENSITY: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 2 ; j ; j-- ) { + *dst++ = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24); + src += 4; + } + ALIGN_DST; + } + break; + + case GL_COLOR_INDEX: + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} +#undef ALIGN_DST + +/* Convert a block of Mesa-formatted texture to a 16bpp hardware format. + */ +static void radeonConvertTexture16bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + + if ( width < 2 ) { + width = 2; + } + +#define ALIGN_DST \ + do { \ + if ( width < 16 ) { \ + dst += ((16 - width) / 2); \ + } \ + } while (0) + + switch ( image->Format ) { + case GL_RGBA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR4444( src[0], src[1], src[2], src[3] )) | + (RADEONPACKCOLOR4444( src[4], src[5], src[6], src[7] ) << 16)); + src += 8; + } + ALIGN_DST; + } + break; + + case GL_RGB: + { + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR565( src[0], src[1], src[2] )) | + (RADEONPACKCOLOR565( src[3], src[4], src[5] ) << 16)); + src += 6; + } + ALIGN_DST; + } + } + break; + + case GL_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR88( 0x00, src[0] )) | + (RADEONPACKCOLOR88( 0x00, src[1] ) << 16)); + src += 2; + } + ALIGN_DST; + } + break; + + case GL_LUMINANCE: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x); + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR88( src[0], 0xff )) | + (RADEONPACKCOLOR88( src[1], 0xff ) << 16)); + src += 2; + } + ALIGN_DST; + } + break; + + case GL_LUMINANCE_ALPHA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 2; + for ( j = width >> 1 ; j ; j-- ) { + *dst++ = ((RADEONPACKCOLOR88( src[0], src[1] )) | + (RADEONPACKCOLOR88( src[2], src[3] ) << 16)); + src += 4; + } + ALIGN_DST; + } + break; + + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} +#undef ALIGN_DST + +/* Convert a block of Mesa-formatted texture to a 32bpp hardware format. + */ +static void radeonConvertTexture32bpp( CARD32 *dst, + struct gl_texture_image *image, + int x, int y, int width, int height, + int pitch ) +{ + CARD8 *src; + int i, j; + +#define ALIGN_DST \ + do { \ + if ( width < 8 ) { \ + dst += (8 - width); \ + } \ + } while (0) + + switch ( image->Format ) { + case GL_RGBA: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 4; + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], src[3] ); + src += 4; + } + ALIGN_DST; + } + break; + + case GL_RGB: + for ( i = 0 ; i < height ; i++ ) { + src = (CARD8 *)image->Data + ((y + i) * pitch + x) * 3; + for ( j = width ; j ; j-- ) { + *dst++ = RADEONPACKCOLOR8888( src[0], src[1], src[2], 0xff ); + src += 3; + } + ALIGN_DST; + } + break; + + default: + fprintf( stderr, "%s: unsupported format 0x%x\n", + __FUNCTION__, image->Format ); + break; + } +} + +/* Upload the texture image associated with texture `t' at level `level' + * at the address relative to `start'. + */ +static void radeonUploadSubImage( radeonContextPtr rmesa, + radeonTexObjPtr t, GLint level, + GLint x, GLint y, GLint width, GLint height ) +{ + struct gl_texture_image *image; + GLint texelsPerDword = 0; + GLint imageX, imageY, imageWidth, imageHeight; + GLint blitX, blitY, blitWidth, blitHeight; + GLint imageRows, blitRows; + GLint remaining ; + GLint format, dwords; + CARD32 pitch, offset; + drmBufPtr buffer; + CARD32 *dst; + + /* Ensure we have a valid texture to upload */ + if ( ( level < 0 ) || ( level >= RADEON_MAX_TEXTURE_LEVELS ) ) + return; + + image = t->tObj->Image[level]; + if ( !image ) + return; + + switch ( t->texelBytes ) { + case 1: + texelsPerDword = 4; + break; + case 2: + texelsPerDword = 2; + break; + case 4: + texelsPerDword = 1; + break; + } + + format = t->setup.pp_txformat & RADEON_TXF_FORMAT_MASK; + + imageX = 0; + imageY = 0; + imageWidth = image->Width; + imageHeight = image->Height; + + blitX = t->image[level].x; + blitY = t->image[level].y; + blitWidth = t->image[level].width; + blitHeight = t->image[level].height; + + dwords = t->image[level].dwords; + offset = t->bufAddr; + pitch = (t->image[0].width * t->texelBytes) / 64; + +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + rmesa->c_textureBytes += (dwords << 2); +#endif + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, " upload image: %d,%d at %d,%d\n", + imageWidth, imageHeight, imageX, imageY ); + fprintf( stderr, " upload blit: %d,%d at %d,%d\n", + blitWidth, blitHeight, blitX, blitY ); + fprintf( stderr, " blit ofs: 0x%07x pitch: 0x%x dwords: %d " + "level: %d format: %x\n", + (GLuint)offset, (GLuint)pitch, dwords, level, format ); + } + + /* Subdivide the texture if required */ + if ( dwords <= RADEON_BUFFER_MAX_DWORDS / 2 ) { + imageRows = imageHeight; + blitRows = blitHeight; + } else { + imageRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword)/(2 * imageWidth); + blitRows = (RADEON_BUFFER_MAX_DWORDS * texelsPerDword) / (2 * blitWidth); + } + + for ( remaining = imageHeight ; + remaining > 0 ; + remaining -= imageRows, imageY += imageRows, blitY += blitRows ) + { + if ( remaining >= imageRows ) { + imageHeight = imageRows; + blitHeight = blitRows; + } else { + imageHeight = remaining; + blitHeight = blitRows; + } + dwords = blitWidth * blitHeight / texelsPerDword; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + fprintf( stderr, " blitting: %d,%d at %d,%d\n", + imageWidth, imageHeight, imageX, imageY ); + fprintf( stderr, " %d,%d at %d,%d - %d dwords\n", + blitWidth, blitHeight, blitX, blitY, dwords ); + } + + /* Grab the indirect buffer for the texture blit */ + buffer = radeonGetBufferLocked( rmesa ); + + dst = (CARD32 *)((char *)buffer->address + RADEON_HOSTDATA_BLIT_OFFSET); + + /* Actually do the texture conversion */ + switch ( t->texelBytes ) { + case 1: + radeonConvertTexture8bpp( dst, image, + imageX, imageY, imageWidth, imageHeight, + imageWidth ); + break; + case 2: + radeonConvertTexture16bpp( dst, image, + imageX, imageY, imageWidth, imageHeight, + imageWidth ); + break; + case 4: + radeonConvertTexture32bpp( dst, image, + imageX, imageY, imageWidth, imageHeight, + imageWidth ); + break; + } + + radeonFireBlitLocked( rmesa, buffer, + offset, pitch, format, + blitX, blitY, blitWidth, blitHeight ); + } + + rmesa->new_state |= RADEON_NEW_CONTEXT; + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_MASKS; +} + +/* Upload the texture images associated with texture `t'. This might + * require removing our own and/or other client's texture objects to + * make room for these images. + */ +/* NOTE: This function is only called while holding the hardware lock */ +int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ) +{ + int i; + int heap; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %p )\n", + __FUNCTION__, rmesa->glCtx, t ); + } + + if ( !t ) + return 0; + + /* Choose the heap appropriately */ + heap = t->heap = RADEON_CARD_HEAP; +#if 0 + if ( !rmesa->radeonScreen->IsPCI && + t->totalSize > rmesa->radeonScreen->texSize[heap] ) { + heap = t->heap = RADEON_AGP_HEAP; + } +#endif + + /* Do we need to eject LRU texture objects? */ + if ( !t->memBlock ) { + /* Allocate a memory block on a 4k boundary (1<<12 == 4096) */ + t->memBlock = mmAllocMem( rmesa->texHeap[heap], + t->totalSize, 12, 0 ); + +#if 0 + /* Try AGP before kicking anything out of local mem */ + if ( !t->memBlock && heap == RADEON_CARD_HEAP ) { + t->memBlock = mmAllocMem( rmesa->texHeap[RADEON_AGP_HEAP], + t->totalSize, 12, 0 ); + + if ( t->memBlock ) + heap = t->heap = RADEON_AGP_HEAP; + } +#endif + + /* Kick out textures until the requested texture fits */ + while ( !t->memBlock ) { + if ( rmesa->TexObjList[heap].prev->bound ) { + fprintf( stderr, + "radeonUploadTexImages: ran into bound texture\n" ); + return -1; + } + if ( rmesa->TexObjList[heap].prev == + &rmesa->TexObjList[heap] ) { + if ( rmesa->radeonScreen->IsPCI ) { + fprintf( stderr, "radeonUploadTexImages: upload texture " + "failure on local texture heaps, sz=%d\n", + t->totalSize ); + return -1; +#if 0 + } else if ( heap == RADEON_CARD_HEAP ) { + heap = t->heap = RADEON_AGP_HEAP; + continue; +#endif + } else { + fprintf( stderr, "radeonUploadTexImages: upload texture " + "failure on both local and AGP texture heaps, " + "sz=%d\n", + t->totalSize ); + return -1; + } + } + + radeonDestroyTexObj( rmesa, rmesa->TexObjList[heap].prev ); + + t->memBlock = mmAllocMem( rmesa->texHeap[heap], + t->totalSize, 12, 0 ); + } + + /* Set the base offset of the texture image */ + t->bufAddr = rmesa->radeonScreen->texOffset[heap] + t->memBlock->ofs; + + t->setup.pp_txoffset = t->bufAddr; +#if 0 + /* Fix AGP texture offsets */ + if ( heap == RADEON_AGP_HEAP ) { + t->setup.pp_tx_offset += RADEON_AGP_TEX_OFFSET + + rmesa->radeonScreen->agpTexOffset; + } +#endif + + /* Force loading the new state into the hardware */ + switch ( t->bound ) { + case 1: + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX0; + break; + + case 2: + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | RADEON_UPLOAD_TEX1; + break; + + default: + return -1; + } + } + + /* Let the world know we've used this memory recently */ + radeonUpdateTexLRU( rmesa, t ); + + /* Upload any images that are new */ + if ( t->dirty_images ) { + int num_levels = ((t->setup.pp_txfilter & RADEON_MAX_MIP_LEVEL_MASK) >> + RADEON_MAX_MIP_LEVEL_SHIFT); + + for ( i = 0 ; i <= num_levels ; i++ ) { + if ( t->dirty_images & (1 << i) ) { + radeonUploadSubImage( rmesa, t, i, 0, 0, + t->image[i].width, t->image[i].height ); + } + } + + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; + } + + t->dirty_images = 0; + return 0; +} + + +/* ================================================================ + * Texture combine functions + */ + +#define RADEON_DISABLE 0 +#define RADEON_REPLACE 1 +#define RADEON_MODULATE 2 +#define RADEON_DECAL 3 +#define RADEON_BLEND 4 +#define RADEON_ADD 5 +#define RADEON_MAX_COMBFUNC 6 + +static GLuint radeon_color_combine[][RADEON_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00802800 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800142 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T0_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c2d42 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T0_COLOR | + RADEON_COLOR_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c2902 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00812802 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T0_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00803000 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800182 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T1_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c3582 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T1_COLOR | + RADEON_COLOR_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c3102 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00813002 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T1_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 2: + */ + { + /* Disable combiner stage + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_CURRENT_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00803800 + */ + (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x008001c2 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T2_COLOR | + RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x008c3dc2 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_T2_COLOR | + RADEON_COLOR_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x008c3902 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_TFACTOR_COLOR | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00813802 + */ + (RADEON_COLOR_ARG_A_CURRENT_COLOR | + RADEON_COLOR_ARG_B_ZERO | + RADEON_COLOR_ARG_C_T2_COLOR | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + } +}; + +static GLuint radeon_alpha_combine[][RADEON_MAX_COMBFUNC] = +{ + /* Unit 0: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800500 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T0_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800051 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T0_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 1: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800600 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T1_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800061 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T1_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + }, + + /* Unit 2: + */ + { + /* Disable combiner stage + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_REPLACE = 0x00800700 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_MODULATE = 0x00800071 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_T2_ALPHA | + RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_DECAL = 0x00800100 + */ + (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_CURRENT_ALPHA | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_BLEND = 0x00800071 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_TFACTOR_ALPHA | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_BLEND_CTL_BLEND | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + + /* GL_ADD = 0x00800021 + */ + (RADEON_ALPHA_ARG_A_CURRENT_ALPHA | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_ALPHA_ARG_C_T2_ALPHA | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_SCALE_1X | + RADEON_CLAMP_TX), + } +}; + + +/* GL_EXT_texture_env_combine support + */ + +/* The color tables have combine functions for GL_SRC_COLOR, + * GL_ONE_MINUS_SRC_COLOR, GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. + */ +static GLuint radeon_texture_color[][RADEON_MAX_TEXTURE_UNITS] = +{ + { + RADEON_COLOR_ARG_A_T0_COLOR, + RADEON_COLOR_ARG_A_T1_COLOR, + RADEON_COLOR_ARG_A_T2_COLOR + }, + { + RADEON_COLOR_ARG_A_T0_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T1_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T2_COLOR | RADEON_COMP_ARG_A + }, + { + RADEON_COLOR_ARG_A_T0_ALPHA, + RADEON_COLOR_ARG_A_T1_ALPHA, + RADEON_COLOR_ARG_A_T2_ALPHA + }, + { + RADEON_COLOR_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A + }, +}; + +static GLuint radeon_tfactor_color[] = +{ + RADEON_COLOR_ARG_A_TFACTOR_COLOR, + RADEON_COLOR_ARG_A_TFACTOR_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_TFACTOR_ALPHA, + RADEON_COLOR_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_primary_color[] = +{ + RADEON_COLOR_ARG_A_DIFFUSE_COLOR, + RADEON_COLOR_ARG_A_DIFFUSE_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_DIFFUSE_ALPHA, + RADEON_COLOR_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_previous_color[] = +{ + RADEON_COLOR_ARG_A_CURRENT_COLOR, + RADEON_COLOR_ARG_A_CURRENT_COLOR | RADEON_COMP_ARG_A, + RADEON_COLOR_ARG_A_CURRENT_ALPHA, + RADEON_COLOR_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A +}; + +/* The alpha tables only have GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA. + */ +static GLuint radeon_texture_alpha[][RADEON_MAX_TEXTURE_UNITS] = +{ + { + RADEON_ALPHA_ARG_A_T0_ALPHA, + RADEON_ALPHA_ARG_A_T1_ALPHA, + RADEON_ALPHA_ARG_A_T2_ALPHA + }, + { + RADEON_ALPHA_ARG_A_T0_ALPHA | RADEON_COMP_ARG_A, + RADEON_ALPHA_ARG_A_T1_ALPHA | RADEON_COMP_ARG_A, + RADEON_ALPHA_ARG_A_T2_ALPHA | RADEON_COMP_ARG_A + }, +}; + +static GLuint radeon_tfactor_alpha[] = +{ + RADEON_ALPHA_ARG_A_TFACTOR_ALPHA, + RADEON_ALPHA_ARG_A_TFACTOR_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_primary_alpha[] = +{ + RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA, + RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA | RADEON_COMP_ARG_A +}; + +static GLuint radeon_previous_alpha[] = +{ + RADEON_ALPHA_ARG_A_CURRENT_ALPHA, + RADEON_ALPHA_ARG_A_CURRENT_ALPHA | RADEON_COMP_ARG_A +}; + + +/* Extract the arg from slot A, shift it into the correct argument slot + * and set the corresponding complement bit. + */ +#define RADEON_COLOR_ARG( n, arg ) \ +do { \ + color_combine |= \ + ((color_arg[n] & RADEON_COLOR_ARG_MASK) \ + << RADEON_COLOR_ARG_##arg##_SHIFT); \ + color_combine |= \ + ((color_arg[n] >> RADEON_COMP_ARG_SHIFT) \ + << RADEON_COMP_ARG_##arg##_SHIFT); \ +} while (0) + +#define RADEON_ALPHA_ARG( n, arg ) \ +do { \ + alpha_combine |= \ + ((alpha_arg[n] & RADEON_ALPHA_ARG_MASK) \ + << RADEON_ALPHA_ARG_##arg##_SHIFT); \ + alpha_combine |= \ + ((alpha_arg[n] >> RADEON_COMP_ARG_SHIFT) \ + << RADEON_COMP_ARG_##arg##_SHIFT); \ +} while (0) + + +/* ================================================================ + * Texture unit state management + */ + +static void radeonUpdateTextureEnv( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int source = rmesa->tmu_source[unit]; + struct gl_texture_object *tObj; + struct gl_texture_unit *texUnit; + GLuint enabled; + GLuint color_combine, alpha_combine; + GLuint color_arg[3], alpha_arg[3]; + GLuint i, numColorArgs = 0, numAlphaArgs = 0; + GLuint op; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; + if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) + return; + + /* Only update the hardware texture state if the texture is current, + * complete and enabled. + */ + texUnit = &ctx->Texture.Unit[source]; + tObj = texUnit->Current; + if ( !tObj || !tObj->Complete ) + return; + + if ( ( tObj != texUnit->CurrentD[2] ) && + ( tObj != texUnit->CurrentD[1] ) ) + return; + + /* Set the texture environment state. Isn't this nice and clean? + * The Radeon will automagically set the texture alpha to 0xff when + * the texture format does not include an alpha component. This + * reduces the amount of special-casing we have to do, alpha-only + * textures being a notable exception. + */ + switch ( texUnit->EnvMode ) { + case GL_REPLACE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_REPLACE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_REPLACE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_MODULATE: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_MODULATE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_DECAL: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + color_combine = radeon_color_combine[unit][RADEON_DECAL]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_DISABLE]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_BLEND: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_BLEND]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_BLEND]; + alpha_combine = radeon_alpha_combine[unit][RADEON_BLEND]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_ADD: + switch ( tObj->Image[0]->Format ) { + case GL_RGBA: + case GL_RGB: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_ADD]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_ALPHA: + color_combine = radeon_color_combine[unit][RADEON_DISABLE]; + alpha_combine = radeon_alpha_combine[unit][RADEON_MODULATE]; + break; + case GL_INTENSITY: + color_combine = radeon_color_combine[unit][RADEON_ADD]; + alpha_combine = radeon_alpha_combine[unit][RADEON_ADD]; + break; + case GL_COLOR_INDEX: + default: + return; + } + break; + + case GL_COMBINE_EXT: + /* Step 0: + * Calculate how many arguments we need to process. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + numColorArgs = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED_EXT: + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + numColorArgs = 2; + break; + case GL_INTERPOLATE_EXT: + numColorArgs = 3; + break; + default: + return; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + numAlphaArgs = 1; + break; + case GL_MODULATE: + case GL_ADD: + case GL_ADD_SIGNED_EXT: + numAlphaArgs = 2; + break; + case GL_INTERPOLATE_EXT: + numAlphaArgs = 3; + break; + default: + return; + } + + /* Step 1: + * Extract the color and alpha combine function arguments. + */ + for ( i = 0 ; i < numColorArgs ; i++ ) { + op = texUnit->CombineOperandRGB[i] - GL_SRC_COLOR; + switch ( texUnit->CombineSourceRGB[i] ) { + case GL_TEXTURE: + color_arg[i] = radeon_texture_color[op][unit]; + break; + case GL_CONSTANT_EXT: + color_arg[i] = radeon_tfactor_color[op]; + break; + case GL_PRIMARY_COLOR_EXT: + color_arg[i] = radeon_primary_color[op]; + break; + case GL_PREVIOUS_EXT: + color_arg[i] = radeon_previous_color[op]; + break; + default: + return; + } + } + + for ( i = 0 ; i < numAlphaArgs ; i++ ) { + op = texUnit->CombineOperandA[i] - GL_SRC_ALPHA; + switch ( texUnit->CombineSourceA[i] ) { + case GL_TEXTURE: + alpha_arg[i] = radeon_texture_alpha[op][unit]; + break; + case GL_CONSTANT_EXT: + alpha_arg[i] = radeon_tfactor_alpha[op]; + break; + case GL_PRIMARY_COLOR_EXT: + alpha_arg[i] = radeon_primary_alpha[op]; + break; + case GL_PREVIOUS_EXT: + alpha_arg[i] = radeon_previous_alpha[op]; + break; + default: + return; + } + } + + /* Step 2: + * Build up the color and alpha combine functions. + */ + switch ( texUnit->CombineModeRGB ) { + case GL_REPLACE: + color_combine = (RADEON_COLOR_ARG_A_ZERO | + RADEON_COLOR_ARG_B_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, C ); + break; + case GL_MODULATE: + color_combine = (RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, B ); + break; + case GL_ADD: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + break; + case GL_ADD_SIGNED_EXT: + color_combine = (RADEON_COLOR_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, C ); + break; + case GL_INTERPOLATE_EXT: + color_combine = (RADEON_BLEND_CTL_BLEND | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, B ); + RADEON_COLOR_ARG( 1, A ); + RADEON_COLOR_ARG( 2, C ); + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + color_combine = (RADEON_COLOR_ARG_C_ZERO | + RADEON_BLEND_CTL_DOT3 | + RADEON_CLAMP_TX); + RADEON_COLOR_ARG( 0, A ); + RADEON_COLOR_ARG( 1, B ); + break; + default: + return; + } + + switch ( texUnit->CombineModeA ) { + case GL_REPLACE: + alpha_combine = (RADEON_ALPHA_ARG_A_ZERO | + RADEON_ALPHA_ARG_B_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, C ); + break; + case GL_MODULATE: + alpha_combine = (RADEON_ALPHA_ARG_C_ZERO | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, B ); + break; + case GL_ADD: + alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADD | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_ADD_SIGNED_EXT: + alpha_combine = (RADEON_ALPHA_ARG_B_ZERO | + RADEON_COMP_ARG_B | + RADEON_BLEND_CTL_ADDSIGNED | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, A ); + RADEON_ALPHA_ARG( 1, C ); + break; + case GL_INTERPOLATE_EXT: + alpha_combine = (RADEON_BLEND_CTL_BLEND | + RADEON_CLAMP_TX); + RADEON_ALPHA_ARG( 0, B ); + RADEON_ALPHA_ARG( 1, A ); + RADEON_ALPHA_ARG( 2, C ); + break; + default: + return; + } + + if ( texUnit->CombineModeRGB == GL_DOT3_RGB_EXT ) { + alpha_combine |= RADEON_DOT_ALPHA_DONT_REPLICATE; + } + + /* Step 3: + * Apply the scale factor. The EXT extension has a somewhat + * unnecessary restriction that the scale must be 4x. The ARB + * extension will likely drop this and we can just apply the + * scale factors regardless. + */ + if ( texUnit->CombineModeRGB != GL_DOT3_RGB_EXT && + texUnit->CombineModeRGB != GL_DOT3_RGBA_EXT ) { + color_combine |= (texUnit->CombineScaleShiftRGB << 21); + alpha_combine |= (texUnit->CombineScaleShiftA << 21); + } else { + color_combine |= RADEON_SCALE_4X; + alpha_combine |= RADEON_SCALE_4X; + } + + /* All done! + */ + break; + + default: + return; + } + + rmesa->color_combine[source] = color_combine; + rmesa->alpha_combine[source] = alpha_combine; +} + +static void radeonUpdateTextureObject( GLcontext *ctx, int unit ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + int source = rmesa->tmu_source[unit]; + struct gl_texture_object *tObj; + radeonTexObjPtr t; + GLuint enabled; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + enabled = (ctx->Texture.ReallyEnabled >> (source * 4)) & TEXTURE0_ANY; + if ( enabled != TEXTURE0_2D && enabled != TEXTURE0_1D ) { + if ( enabled ) + rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; + return; + } + + /* Only update the hardware texture state if the texture is current, + * complete and enabled. + */ + tObj = ctx->Texture.Unit[source].Current; + if ( !tObj || !tObj->Complete ) + return; + + if ( ( tObj != ctx->Texture.Unit[source].CurrentD[2] ) && + ( tObj != ctx->Texture.Unit[source].CurrentD[1] ) ) + return; + + if ( !tObj->DriverData ) { + /* If this is the first time the texture has been used, then create + * a new texture object for it. + */ + radeonCreateTexObj( rmesa, tObj ); + + if ( !tObj->DriverData ) { + /* Can't create a texture object... */ + fprintf( stderr, "%s: texture object creation failed!\n", + __FUNCTION__ ); + rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; + return; + } + } + + /* We definately have a valid texture now */ + t = tObj->DriverData; + + /* Force the texture unit state to be loaded into the hardware */ + rmesa->dirty |= RADEON_UPLOAD_CONTEXT | (RADEON_UPLOAD_TEX0 << unit); + + /* Force any texture images to be loaded into the hardware */ + if ( t->dirty_images ) + rmesa->dirty |= (RADEON_UPLOAD_TEX0IMAGES << unit); + + /* Bind to the given texture unit */ + rmesa->CurrentTexObj[unit] = t; + t->bound = unit + 1; + + if ( t->memBlock ) + radeonUpdateTexLRU( rmesa, t ); + + switch ( unit ) { + case 0: + rmesa->setup.pp_cntl |= (RADEON_TEX_0_ENABLE | + RADEON_TEX_BLEND_0_ENABLE); + break; + case 1: + rmesa->setup.pp_cntl |= (RADEON_TEX_1_ENABLE | + RADEON_TEX_BLEND_1_ENABLE); + break; + } +} + +void radeonUpdateTextureState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) en=0x%x\n", + __FUNCTION__, ctx, ctx->Texture.ReallyEnabled ); + } + + /* Clear any texturing fallbacks */ + rmesa->Fallback &= ~RADEON_FALLBACK_TEXTURE; + + /* Unbind any currently bound textures */ + if ( rmesa->CurrentTexObj[0] ) rmesa->CurrentTexObj[0]->bound = 0; + if ( rmesa->CurrentTexObj[1] ) rmesa->CurrentTexObj[1]->bound = 0; + rmesa->CurrentTexObj[0] = NULL; + rmesa->CurrentTexObj[1] = NULL; + + if ( ctx->Enabled & (TEXTURE0_3D|TEXTURE1_3D) ) + rmesa->Fallback |= RADEON_FALLBACK_TEXTURE; + + /* Disable all texturing until it is known to be good */ + rmesa->setup.pp_cntl &= ~(RADEON_TEX_ENABLE_MASK | + RADEON_TEX_BLEND_ENABLE_MASK); + + radeonUpdateTextureObject( ctx, 0 ); + radeonUpdateTextureEnv( ctx, 0 ); + + if ( rmesa->multitex ) { + radeonUpdateTextureObject( ctx, 1 ); + radeonUpdateTextureEnv( ctx, 1 ); + } + + rmesa->dirty |= RADEON_UPLOAD_CONTEXT; +} + + +/* ================================================================ + * DD interface texturing functions + * + * FIXME: Many of these are deprecated -- we should move to the new + * single-copy texture interface. + */ +#define SCALED_FLOAT_TO_BYTE( x, scale ) \ + ((((GLint)((256.0F / scale) * (x))) - 1) / 2) + +static void radeonDDTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct gl_texture_unit *texUnit; + GLuint source; + GLubyte c[4]; + GLuint col; + GLfloat bias; + GLubyte b; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); + } + + switch ( pname ) { + case GL_TEXTURE_ENV_MODE: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= RADEON_NEW_TEXTURE | RADEON_NEW_ALPHA; + break; + + case GL_TEXTURE_ENV_COLOR: + source = rmesa->tmu_source[ctx->Texture.CurrentUnit]; + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + FLOAT_RGBA_TO_UBYTE_RGBA( c, texUnit->EnvColor ); + col = radeonPackColor( 4, c[0], c[1], c[2], c[3] ); + if ( rmesa->env_color[source] != col ) { + FLUSH_BATCH( rmesa ); + rmesa->env_color[source] = col; + + rmesa->new_state |= RADEON_NEW_TEXTURE; + } + break; + + case GL_TEXTURE_LOD_BIAS_EXT: + /* The Radeon's LOD bias is a signed 2's complement value with a + * range of -1.0 <= bias < 4.0. We break this into two linear + * functions, one mapping [-1.0,0.0] to [-128,0] and one mapping + * [0.0,4.0] to [0,127]. + */ + source = rmesa->tmu_source[ctx->Texture.CurrentUnit]; + bias = CLAMP( *param, -1.0, 4.0 ); + if ( bias == 0 ) { + b = 0; + } else if ( bias > 0 ) { + b = (GLubyte) SCALED_FLOAT_TO_BYTE( bias, 4.0 ); + } else { + b = (GLubyte) SCALED_FLOAT_TO_BYTE( bias, 1.0 ); + } + if ( rmesa->lod_bias[source] != (GLuint)b ) { + FLUSH_BATCH( rmesa ); + rmesa->lod_bias[source] = (GLuint)b; + + rmesa->new_state |= RADEON_NEW_TEXTURE; + } + break; + + default: + return; + } +} + +static void radeonDDTexImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint internalFormat, + const struct gl_texture_image *image ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) + fprintf( stderr, "%s( %p, level %d )\n", __FUNCTION__, tObj, level ); + + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + if ( level >= RADEON_MAX_TEXTURE_LEVELS ) + return; + + t = (radeonTexObjPtr)tObj->DriverData; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( rmesa ); + + /* Destroy the old texture, and upload a new one. The actual + * uploading of the texture image occurs in the UploadSubImage + * function. + */ + radeonDestroyTexObj( rmesa, t ); + rmesa->new_state |= RADEON_NEW_TEXTURE; + } +} + +static void radeonDDTexSubImage( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLint internalFormat, + const struct gl_texture_image *image ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, level %d ) size: %d,%d of %d,%d\n", + __FUNCTION__, tObj, level, width, height, + image->Width, image->Height ); + } + + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + if ( level >= RADEON_MAX_TEXTURE_LEVELS ) + return; + + t = (radeonTexObjPtr)tObj->DriverData; + if ( t ) { + if ( t->bound ) FLUSH_BATCH( rmesa ); + +#if 0 + /* FIXME: Only upload textures if we already have space in the heap. + */ + LOCK_HARDWARE( rmesa ); + radeonUploadSubImage( rmesa, t, level, + xoffset, yoffset, width, height ); + UNLOCK_HARDWARE( rmesa ); +#else + radeonDestroyTexObj( rmesa, t ); +#endif + /* Update the context state */ + rmesa->new_state |= RADEON_NEW_TEXTURE; + } +} + +static void radeonDDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, gl_lookup_enum_by_nr( pname ) ); + } + + /* If we don't have a hardware texture, it will be automatically + * created with current state before it is used, so we don't have + * to do anything now. + */ + if ( !t || !t->bound ) + return; + + if ( ( target != GL_TEXTURE_2D ) && + ( target != GL_TEXTURE_1D ) ) + return; + + switch ( pname ) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSetTexWrap( t, tObj->WrapS, tObj->WrapT ); + break; + + case GL_TEXTURE_BORDER_COLOR: + if ( t->bound ) FLUSH_BATCH( rmesa ); + radeonSetTexBorderColor( t, tObj->BorderColor ); + break; + + default: + return; + } + + rmesa->new_state |= RADEON_NEW_TEXTURE; +} + +static void radeonDDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLint unit = ctx->Texture.CurrentUnit; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) unit=%d\n", + __FUNCTION__, tObj, ctx->Texture.CurrentUnit ); + } + + FLUSH_BATCH( rmesa ); + + if ( rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit]->bound = 0; + rmesa->CurrentTexObj[unit] = NULL; + } + + rmesa->new_state |= RADEON_NEW_TEXTURE; +} + +static void radeonDDDeleteTexture( GLcontext *ctx, + struct gl_texture_object *tObj ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + if ( t ) { + if ( t->bound ) { + FLUSH_BATCH( rmesa ); + + rmesa->CurrentTexObj[t->bound-1] = 0; + rmesa->new_state |= RADEON_NEW_TEXTURE; + } + + radeonDestroyTexObj( rmesa, t ); + tObj->DriverData = NULL; + } +} + +static GLboolean radeonDDIsTextureResident( GLcontext *ctx, + struct gl_texture_object *tObj ) +{ + radeonTexObjPtr t = (radeonTexObjPtr)tObj->DriverData; + + return ( t && t->memBlock ); +} + + + +void radeonDDInitTextureFuncs( GLcontext *ctx ) +{ + ctx->Driver.TexEnv = radeonDDTexEnv; + ctx->Driver.TexImage = radeonDDTexImage; + ctx->Driver.TexSubImage = radeonDDTexSubImage; + ctx->Driver.TexParameter = radeonDDTexParameter; + ctx->Driver.BindTexture = radeonDDBindTexture; + ctx->Driver.DeleteTexture = radeonDDDeleteTexture; + ctx->Driver.UpdateTexturePalette = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.IsTextureResident = radeonDDIsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h new file mode 100644 index 000000000..2534335aa --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h @@ -0,0 +1,96 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_TEX_H__ +#define __RADEON_TEX_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void radeonUpdateTextureState( GLcontext *ctx ); + +extern int radeonUploadTexImages( radeonContextPtr rmesa, radeonTexObjPtr t ); + +extern void radeonAgeTextures( radeonContextPtr rmesa, int heap ); +extern void radeonDestroyTexObj( radeonContextPtr rmesa, radeonTexObjPtr t ); + +extern void radeonPrintLocalLRU( radeonContextPtr rmesa, int heap ); +extern void radeonPrintGlobalLRU( radeonContextPtr rmesa, int heap ); + +extern void radeonDDInitTextureFuncs( GLcontext *ctx ); + + +/* ================================================================ + * Color conversion macros: + */ + +#define RADEONPACKCOLOR332( r, g, b ) \ + (((r) & 0xe0) | (((g) & 0xe0) >> 3) | (((b) & 0xc0) >> 6)) + +#define RADEONPACKCOLOR1555( r, g, b, a ) \ + ((((r) & 0xf8) << 7) | (((g) & 0xf8) << 2) | (((b) & 0xf8) >> 3) | \ + ((a) ? 0x8000 : 0)) + +#define RADEONPACKCOLOR565( r, g, b ) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define RADEONPACKCOLOR88( i, a ) \ + (((a) << 8) | (i)) + +#define RADEONPACKCOLOR888( r, g, b ) \ + (((r) << 16) | ((g) << 8) | (b)) + +#define RADEONPACKCOLOR8888( r, g, b, a ) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define RADEONPACKCOLOR4444( r, g, b, a ) \ + ((((a) & 0xf0) << 8) | (((r) & 0xf0) << 4) | ((g) & 0xf0) | ((b) >> 4)) + +static __inline__ CARD32 radeonPackColor( GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + switch ( cpp ) { + case 2: + return RADEONPACKCOLOR565( r, g, b ); + case 4: + return RADEONPACKCOLOR8888( r, g, b, a ); + default: + return 0; + } +} + +#endif +#endif /* __RADEON_TEX_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h new file mode 100644 index 000000000..45368e076 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h @@ -0,0 +1,87 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_TEXOBJ_H__ +#define __RADEON_TEXOBJ_H__ + +#include "radeon_sarea.h" +#include "mm.h" + +/* Handle the Radeon's tightly packed mipmaps and strict offset, + * pitch rules for blits by assigning each mipmap a set of + * coordinates that can be used for a hostdata blit. + */ +typedef struct { + GLuint x; /* Blit coordinates */ + GLuint y; + GLuint width; /* Blit dimensions */ + GLuint height; + GLuint dwords; /* Size of image level */ +} radeonTexImage; + +typedef struct radeon_tex_obj radeonTexObj, *radeonTexObjPtr; + +/* Texture object in locally shared texture space. + */ +struct radeon_tex_obj { + radeonTexObjPtr next, prev; + + struct gl_texture_object *tObj; /* Mesa texture object */ + + PMemBlock memBlock; /* Memory block containing texture */ + CARD32 bufAddr; /* Offset to start of locally + shared texture block */ + + CARD32 dirty_images; /* Flags for whether or not + images need to be uploaded to + local or AGP texture space */ + + GLint bound; /* Texture unit currently bound to */ + GLint heap; /* Texture heap currently stored in */ + + radeonTexImage image[RADEON_MAX_TEXTURE_LEVELS]; /* Image data for all + mipmap levels */ + + GLint totalSize; /* Total size of the texture + including all mipmap levels */ + GLint texelBytes; /* Number of bytes per texel */ + + GLboolean hasAlpha; + + radeon_texture_regs_t setup; /* Setup regs for texture */ +}; + +#endif /* __RADEON_TEXOBJ_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c new file mode 100644 index 000000000..bbc766129 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c @@ -0,0 +1,209 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c,v 1.1 2001/01/08 01:07:28 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_vb.h" +#include "radeon_tris.h" +#include "radeon_state.h" + +#include "pipeline.h" +#include "vbindirect.h" + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[RADEON_MAX_TRIFUNC]; + +#define RADEON_COLOR( to, from ) \ +do { \ + *(GLuint *)(to) = *(GLuint *)(from); \ +} while (0) + + +static void radeon_null_quad( GLcontext *ctx, GLuint v0, + GLuint v1, GLuint v2, GLuint v3, GLuint pv ) +{ +} +static void radeon_null_triangle( GLcontext *ctx, GLuint v0, + GLuint v1, GLuint v2, GLuint pv ) +{ +} +static void radeon_null_line( GLcontext *ctx, + GLuint v1, GLuint v2, GLuint pv ) +{ +} +static void radeon_null_points( GLcontext *ctx, GLuint first, GLuint last ) +{ +} + +static void radeonPrintRenderState( const char *msg, GLuint state ) +{ + fprintf( stderr, "%s: (0x%x) %s%s%s%s%s\n", + msg, state, + (state & RADEON_FLAT_BIT) ? "flat, " : "", + (state & RADEON_OFFSET_BIT) ? "offset, " : "", + (state & RADEON_TWOSIDE_BIT) ? "twoside, " : "", + (state & RADEON_NODRAW_BIT) ? "no-draw, " : "", + (state & RADEON_FALLBACK_BIT) ? "fallback" : "" ); +} + +#define IND (0) +#define TAG(x) x +#include "radeon_tritmp.h" + +#define IND (RADEON_FLAT_BIT) +#define TAG(x) x##_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_OFFSET_BIT) +#define TAG(x) x##_offset +#include "radeon_tritmp.h" + +#define IND (RADEON_OFFSET_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_offset_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_twoside_flat +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "radeon_tritmp.h" + +#define IND (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT | RADEON_FLAT_BIT) +#define TAG(x) x##_twoside_offset_flat +#include "radeon_tritmp.h" + + +void radeonDDTriangleFuncsInit( void ) +{ + GLint i; + + init(); + init_flat(); + init_offset(); + init_offset_flat(); + init_twoside(); + init_twoside_flat(); + init_twoside_offset(); + init_twoside_offset_flat(); + + for ( i = 0 ; i < RADEON_MAX_TRIFUNC ; i++ ) { + if ( i & RADEON_NODRAW_BIT ) { + rast_tab[i].points = radeon_null_points; + rast_tab[i].line = radeon_null_line; + rast_tab[i].triangle = radeon_null_triangle; + rast_tab[i].quad = radeon_null_quad; + } + } +} + + +/* FIXME: Only enable software fallback for stencil in 16 bpp mode after + * we have hardware stencil support. + */ +#define ALL_FALLBACK (DD_SELECT | DD_FEEDBACK | DD_STENCIL) +#define POINT_FALLBACK (ALL_FALLBACK | DD_POINT_SMOOTH | DD_POINT_ATTEN) +#define LINE_FALLBACK (ALL_FALLBACK | DD_LINE_SMOOTH | DD_LINE_STIPPLE) +#define TRI_FALLBACK (ALL_FALLBACK | DD_TRI_SMOOTH | DD_TRI_UNFILLED) +#define ANY_FALLBACK (POINT_FALLBACK | LINE_FALLBACK | TRI_FALLBACK) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE | DD_TRI_OFFSET | DD_Z_NEVER) + +/* Setup the Point, Line, Triangle and Quad functions based on the + * current rendering state. Wherever possible, use the hardware to + * render the primitive. Otherwise, fallback to software rendering. + */ +void radeonDDChooseRenderState( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLuint flags = ctx->TriangleCaps; + GLuint index = 0; + + if ( rmesa->Fallback ) { + rmesa->RenderIndex = RADEON_FALLBACK_BIT; + return; + } + + if ( flags & ANY_RASTER_FLAGS ) { + if ( flags & DD_FLATSHADE ) index |= RADEON_FLAT_BIT; + if ( flags & DD_TRI_LIGHT_TWOSIDE ) index |= RADEON_TWOSIDE_BIT; + if ( flags & DD_TRI_OFFSET ) index |= RADEON_OFFSET_BIT; + if ( flags & DD_Z_NEVER ) index |= RADEON_NODRAW_BIT; + } + + rmesa->PointsFunc = rast_tab[index].points; + rmesa->LineFunc = rast_tab[index].line; + rmesa->TriangleFunc = rast_tab[index].triangle; + rmesa->QuadFunc = rast_tab[index].quad; + + rmesa->RenderIndex = index; + rmesa->IndirectTriangles = 0; + + if ( flags & ANY_FALLBACK ) { + if ( flags & POINT_FALLBACK ) { + rmesa->RenderIndex |= RADEON_FALLBACK_BIT; + rmesa->PointsFunc = 0; + rmesa->IndirectTriangles |= DD_POINT_SW_RASTERIZE; + } + + if ( flags & LINE_FALLBACK ) { + rmesa->RenderIndex |= RADEON_FALLBACK_BIT; + rmesa->LineFunc = 0; + rmesa->IndirectTriangles |= DD_LINE_SW_RASTERIZE; + } + + if ( flags & TRI_FALLBACK ) { + rmesa->RenderIndex |= RADEON_FALLBACK_BIT; + rmesa->TriangleFunc = 0; + rmesa->QuadFunc = 0; + rmesa->IndirectTriangles |= (DD_TRI_SW_RASTERIZE | + DD_QUAD_SW_RASTERIZE); + } + } + + if ( 0 ) { + gl_print_tri_caps( "tricaps", ctx->TriangleCaps ); + radeonPrintRenderState( "radeon render state", rmesa->RenderIndex ); + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h new file mode 100644 index 000000000..57fadaeca --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h @@ -0,0 +1,316 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_TRIS_H__ +#define __RADEON_TRIS_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "radeon_vb.h" + +extern void radeonDDChooseRenderState( GLcontext *ctx ); +extern void radeonDDTriangleFuncsInit( void ); + +#define RADEON_ANTIALIAS_BIT 0x00 /* GH: Do we need this? */ +#define RADEON_FLAT_BIT 0x01 +#define RADEON_OFFSET_BIT 0x02 +#define RADEON_TWOSIDE_BIT 0x04 +#define RADEON_NODRAW_BIT 0x08 +#define RADEON_FALLBACK_BIT 0x10 +#define RADEON_MAX_TRIFUNC 0x20 + + +static __inline void radeon_draw_triangle( radeonContextPtr rmesa, + radeonVertexPtr v0, + radeonVertexPtr v1, + radeonVertexPtr v2 ) +{ + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, 3 ); + GLuint j; + +#if defined (USE_X86_ASM) + /* GH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v2) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v2->ui[j]; +#endif +} + +static __inline void radeon_draw_quad( radeonContextPtr rmesa, + radeonVertexPtr v0, + radeonVertexPtr v1, + radeonVertexPtr v2, + radeonVertexPtr v3 ) +{ + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 ); + GLuint j; + +#if defined (USE_X86_ASM) + /* GH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)v0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v3) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v1) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v2) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)v3) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v3->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v1->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v2->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = v3->ui[j]; +#endif +} + +static __inline void radeon_draw_line( radeonContextPtr rmesa, + radeonVertexPtr tmp0, + radeonVertexPtr tmp1, + GLfloat width ) +{ +#if 1 + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 ); + GLfloat dx, dy, ix, iy; + GLuint j; + + dx = tmp0->v.x - tmp1->v.x; + dy = tmp0->v.y - tmp1->v.y; + + ix = width * .5; iy = 0; + + if ((ix<.5) && (ix>0.1)) ix = .5; /* I want to see lines with width + 0.5 also */ + + if (dx * dx > dy * dy) { + iy = ix; ix = 0; + } + + *(float *)&vb[0] = tmp0->v.x - ix; + *(float *)&vb[1] = tmp0->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x + ix; + *(float *)&vb[1] = tmp1->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp0->v.x + ix; + *(float *)&vb[1] = tmp0->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp0->v.x - ix; + *(float *)&vb[1] = tmp0->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp0->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x - ix; + *(float *)&vb[1] = tmp1->v.y - iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp1->v.x + ix; + *(float *)&vb[1] = tmp1->v.y + iy; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp1->ui[j]; +#else + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, RADEON_LINES, 2 ); + GLuint j; + +#if defined (USE_X86_ASM) + /* GH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp0) + : "memory" ); + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "S" ((long)tmp1) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp0->ui[j]; + + vb += vertsize; + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp1->ui[j]; +#endif +#endif +} + +static __inline void radeon_draw_point( radeonContextPtr rmesa, + radeonVertexPtr tmp, GLfloat sz ) +{ +#if 1 + GLuint vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, 6 ); + GLuint j; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x + sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y + sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + vb += vertsize; + + *(float *)&vb[0] = tmp->v.x - sz; + *(float *)&vb[1] = tmp->v.y - sz; + for (j = 2 ; j < vertsize ; j++) + vb[j] = tmp->ui[j]; + +#else + int vertsize = rmesa->vertsize; + CARD32 *vb = radeonAllocVerticesInline( rmesa, RADEON_3_VERTEX_POINTS, 1 ); + int j; + +#if defined (USE_X86_ASM) + /* GH: We can safely assume the vertex stride is some number of + * dwords, and thus a "rep movsd" is okay. The vb pointer is + * automagically updated with this instruction, so we don't have + * to manually take care of incrementing it. + */ + __asm__ __volatile__( "rep ; movsl" + : "=%c" (j) + : "0" (vertsize), "D" ((long)vb), "S" ((long)tmp) + : "memory" ); +#else + for ( j = 0 ; j < vertsize ; j++ ) + vb[j] = tmp->ui[j]; +#endif +#endif +} + +#endif +#endif /* __RADEON_TRIS_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h new file mode 100644 index 000000000..ffa0d4746 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h @@ -0,0 +1,336 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h,v 1.1 2001/01/08 01:07:28 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +static __inline void TAG(triangle)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, + GLuint pv ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts; + radeonVertexPtr v[3]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[3]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + GLuint c[3]; +#endif + + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; + c[2] = v[2]->ui[4]; +#endif + +#if (IND & (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT)) + { + GLfloat ex = v[0]->v.x - v[2]->v.x; + GLfloat ey = v[0]->v.y - v[2]->v.y; + GLfloat fx = v[1]->v.x - v[2]->v.x; + GLfloat fy = v[1]->v.y - v[2]->v.y; + GLfloat cc = ex*fy - ey*fx; + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit; + GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + if ( IND & RADEON_FLAT_BIT ) { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + RADEON_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + { + offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + z[2] = v[2]->v.z; + if ( cc * cc > 1e-16 ) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; + } + v[0]->v.z += offset; + v[1]->v.z += offset; + v[2]->v.z += offset; + } +#endif + } +#endif + + radeon_draw_triangle( rmesa, v[0], v[1], v[2] ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; + v[2]->v.z = z[2]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; + v[2]->ui[4] = c[2]; +#endif +} + + +static void TAG(quad)( GLcontext *ctx, + GLuint e0, GLuint e1, GLuint e2, GLuint e3, + GLuint pv ) +{ +#if 0 + TAG(triangle)( ctx, e0, e1, e3, pv ); + TAG(triangle)( ctx, e1, e2, e3, pv ); +#else + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts; + radeonVertexPtr v[4]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[4]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + int c[4]; +#endif + + v[0] = &verts[e0]; + v[1] = &verts[e1]; + v[2] = &verts[e2]; + v[3] = &verts[e3]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; + c[2] = v[2]->ui[4]; + c[3] = v[3]->ui[4]; +#endif + +#if (IND & (RADEON_TWOSIDE_BIT | RADEON_OFFSET_BIT)) + { + GLfloat ex = v[0]->v.x - v[2]->v.x; + GLfloat ey = v[0]->v.y - v[2]->v.y; + GLfloat fx = v[1]->v.x - v[2]->v.x; + GLfloat fy = v[1]->v.y - v[2]->v.y; + GLfloat cc = ex*fy - ey*fx; + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLuint facing = ( cc > 0.0 ) ^ ctx->Polygon.FrontBit; + GLubyte (*vbcolor)[4] = VB->Color[facing]->data; + if ( IND & RADEON_FLAT_BIT ) { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + v[3]->ui[4] = v[2]->ui[4] = v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + RADEON_COLOR( (char *)&v[2]->ui[4], vbcolor[e2] ); + RADEON_COLOR( (char *)&v[3]->ui[4], vbcolor[e3] ); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + { + offset = ctx->Polygon.OffsetUnits * rmesa->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + z[2] = v[2]->v.z; + z[3] = v[3]->v.z; + if ( cc * cc > 1e-16 ) { + GLfloat ez = z[0] - z[2]; + GLfloat fz = z[1] - z[2]; + GLfloat a = ey*fz - ez*fy; + GLfloat b = ez*fx - ex*fz; + GLfloat ic = 1.0 / cc; + GLfloat ac = a * ic; + GLfloat bc = b * ic; + if ( ac < 0.0f ) ac = -ac; + if ( bc < 0.0f ) bc = -bc; + offset += MAX2( ac, bc ) * ctx->Polygon.OffsetFactor; + } + v[0]->v.z += offset; + v[1]->v.z += offset; + v[2]->v.z += offset; + v[3]->v.z += offset; + } +#endif + } +#endif + + radeon_draw_quad( rmesa, v[0], v[1], v[2], v[3] ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; + v[2]->v.z = z[2]; + v[3]->v.z = z[3]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; + v[2]->ui[4] = c[2]; + v[3]->ui[4] = c[3]; +#endif +#endif +} + + +static void TAG(line)( GLcontext *ctx, + GLuint e0, GLuint e1, + GLuint pv ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts; + GLfloat width = ctx->Line.Width; + radeonVertexPtr v[2]; + +#if (IND & RADEON_OFFSET_BIT) + GLfloat offset; + GLfloat z[2]; +#endif +#if (IND & RADEON_TWOSIDE_BIT) + int c[2]; +#endif + + v[0] = &verts[e0]; + v[1] = &verts[e1]; + +#if (IND & RADEON_TWOSIDE_BIT) + c[0] = v[0]->ui[4]; + c[1] = v[1]->ui[4]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + { + GLubyte (*vbcolor)[4] = ctx->VB->ColorPtr->data; + if ( IND & RADEON_FLAT_BIT ) { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[pv] ); + v[1]->ui[4] = v[0]->ui[4]; + } else { + RADEON_COLOR( (char *)&v[0]->ui[4], vbcolor[e0] ); + RADEON_COLOR( (char *)&v[1]->ui[4], vbcolor[e1] ); + } + } +#endif + +#if (IND & RADEON_OFFSET_BIT) + offset = ctx->LineZoffset * rmesa->depth_scale; + z[0] = v[0]->v.z; + z[1] = v[1]->v.z; + v[0]->v.z += offset; + v[1]->v.z += offset; +#endif + + radeon_draw_line( rmesa, v[0], v[1], width ); + +#if (IND & RADEON_OFFSET_BIT) + v[0]->v.z = z[0]; + v[1]->v.z = z[1]; +#endif + +#if (IND & RADEON_TWOSIDE_BIT) + v[0]->ui[4] = c[0]; + v[1]->ui[4] = c[1]; +#endif +} + + +static void TAG(points)( GLcontext *ctx, + GLuint first, GLuint last ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + struct vertex_buffer *VB = ctx->VB; + radeonVertexPtr verts = RADEON_DRIVER_DATA(VB)->verts; + GLfloat size = ctx->Point.Size * 0.5; + int i; + + for ( i = first ; i < last ; i++ ) { + if ( VB->ClipMask[i] == 0 ) { + if ( IND & (RADEON_TWOSIDE_BIT|RADEON_OFFSET_BIT) ) { + radeonVertex tmp0 = verts[i]; + + if ( IND & RADEON_TWOSIDE_BIT ) { + GLubyte (*vbcolor)[4] = VB->ColorPtr->data; + RADEON_COLOR( (char *)&tmp0.v.color, vbcolor[i] ); + } + if ( IND & RADEON_OFFSET_BIT ) { + GLfloat offset = ctx->PointZoffset * rmesa->depth_scale; + tmp0.v.z += offset; + } + radeon_draw_point( rmesa, &tmp0, size ); + } else { + radeon_draw_point( rmesa, &verts[i], size ); + } + } + } +} + + +static void TAG(init)( void ) +{ + rast_tab[IND].points = TAG(points); + rast_tab[IND].line = TAG(line); + rast_tab[IND].triangle = TAG(triangle); + rast_tab[IND].quad = TAG(quad); +} + +#undef IND +#undef TAG diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c new file mode 100644 index 000000000..bdf19b2d6 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c @@ -0,0 +1,483 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c,v 1.2 2001/01/11 03:36:55 tsi Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_vb.h" + +#include "mem.h" +#include "stages.h" + +#define TEX0 \ +do { \ + v->v.tu0 = tc0[i][0]; \ + v->v.tv0 = tc0[i][1]; \ +} while (0) + +#define TEX1 \ +do { \ + v->v.tu1 = tc1[i][0]; \ + v->v.tv1 = tc1[i][1]; \ +} while (0) + +#define SPC \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.red = spec[0]; \ + v->v.specular.green = spec[1]; \ + v->v.specular.blue = spec[2]; \ +} while (0) + +#define FOG \ +do { \ + GLubyte *spec = &(VB->Spec[0][i][0]); \ + v->v.specular.alpha = spec[3]; \ +} while (0) + +#define COL \ +do { \ + GLubyte *col = &(VB->Color[0]->data[i][0]); \ + v->ui[4] = *(GLuint *)col; \ +} while (0) + +#define TEX0_4 \ +do { \ + if ( VB->TexCoordPtr[0]->size == 4 ) { \ + GLfloat (*tc)[4] = VB->TexCoordPtr[0]->data; \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + for ( i = start ; i < end ; i++, v++ ) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw *= tc[i][3]; \ + v->v.tu0 *= oow; \ + v->v.tv0 *= oow; \ + } \ + } \ +} while (0) + +#ifdef USE_RHW2 + +#define TEX1_4 \ +do { \ + if ( VB->TexCoordPtr[1]->size == 4 ) { \ + GLfloat (*tc)[4] = VB->TexCoordPtr[1]->data; \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + for ( i = start ; i < end ; i++, v++ ) { \ + float oow = 1.0 / tc[i][3]; \ + v->v.rhw2 *= tc[i][3]; \ + v->v.tu1 *= oow; \ + v->v.tv1 *= oow; \ + } \ + } \ +} while (0) + +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = - win[1]; \ + v->v.z = win[2]; \ + v->v.rhw = v->v.rhw2 = win[3]; \ +} while (0) + +#else /* USE_RHW2 */ + +#define TEX1_4 + +#define COORD \ +do { \ + GLfloat *win = VB->Win.data[i]; \ + v->v.x = win[0]; \ + v->v.y = - win[1]; \ + v->v.z = win[2]; \ + v->v.rhw = win[3]; \ +} while (0) \ + +#endif /* USE_RHW2 */ + +#define NOP + + +#define SETUPFUNC(name,win,col,tex0,tex1,tex0_4,tex1_4,spec,fog) \ +static void name( struct vertex_buffer *VB, GLuint start, GLuint end ) \ +{ \ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); \ + radeonVertexPtr v; \ + GLfloat (*tc0)[4]; \ + GLfloat (*tc1)[4]; \ + GLint i; \ + \ + gl_import_client_data( VB, VB->ctx->RenderFlags, \ + (VB->ClipOrMask \ + ? VEC_WRITABLE | VEC_GOOD_STRIDE \ + : VEC_GOOD_STRIDE) ); \ + \ + tc0 = VB->TexCoordPtr[rmesa->tmu_source[0]]->data; \ + tc1 = VB->TexCoordPtr[rmesa->tmu_source[1]]->data; \ + \ + v = &(RADEON_DRIVER_DATA(VB)->verts[start]); \ + \ + if ( VB->ClipOrMask == 0 ) { \ + for ( i = start ; i < end ; i++, v++ ) { \ + win; \ + col; \ + spec; \ + fog; \ + tex0; \ + tex1; \ + } \ + } else { \ + for ( i = start ; i < end ; i++, v++ ) { \ + if ( VB->ClipMask[i] == 0 ) { \ + win; \ + spec; \ + fog; \ + tex0; \ + tex1; \ + } \ + col; \ + } \ + } \ + tex0_4; \ + tex1_4; \ +} + + +SETUPFUNC(rs_wt0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_wt0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wft0, COORD, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_wft0t1, COORD, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wg, COORD, COL, NOP, NOP, NOP, NOP, NOP, NOP) +SETUPFUNC(rs_wgs, COORD, COL, NOP, NOP, NOP, NOP, SPC, NOP) +SETUPFUNC(rs_wgt0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_wgt0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_wgst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP) +SETUPFUNC(rs_wgst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP) +SETUPFUNC(rs_wgf, COORD, COL, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_wgfs, COORD, COL, NOP, NOP, NOP, NOP, SPC, FOG) +SETUPFUNC(rs_wgft0, COORD, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_wgft0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_wgfst0, COORD, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG) +SETUPFUNC(rs_wgfst0t1, COORD, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) + +SETUPFUNC(rs_t0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_t0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_f, NOP, NOP, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_ft0, NOP, NOP, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_ft0t1, NOP, NOP, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_g, NOP, COL, NOP, NOP, NOP, NOP, NOP, NOP) +SETUPFUNC(rs_gs, NOP, COL, NOP, NOP, NOP, NOP, SPC, NOP) +SETUPFUNC(rs_gt0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, NOP) +SETUPFUNC(rs_gt0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, NOP) +SETUPFUNC(rs_gst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, NOP) +SETUPFUNC(rs_gst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, NOP) +SETUPFUNC(rs_gf, NOP, COL, NOP, NOP, NOP, NOP, NOP, FOG) +SETUPFUNC(rs_gfs, NOP, COL, NOP, NOP, NOP, NOP, SPC, FOG) +SETUPFUNC(rs_gft0, NOP, COL, TEX0, NOP, TEX0_4, NOP, NOP, FOG) +SETUPFUNC(rs_gft0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, NOP, FOG) +SETUPFUNC(rs_gfst0, NOP, COL, TEX0, NOP, TEX0_4, NOP, SPC, FOG) +SETUPFUNC(rs_gfst0t1, NOP, COL, TEX0, TEX1, TEX0_4, TEX1_4, SPC, FOG) + + +static void rs_invalid( struct vertex_buffer *VB, GLuint start, GLuint end ) +{ + fprintf( stderr, "radeonRasterSetup(): invalid setup function\n" ); +} + +typedef void (*setupFunc)( struct vertex_buffer *, GLuint, GLuint ); +static setupFunc setup_func[RADEON_MAX_SETUPFUNC]; + + +void radeonDDSetupInit( void ) +{ + GLint i; + + for ( i = 0 ; i < RADEON_MAX_SETUPFUNC ; i++ ) { + setup_func[i] = rs_invalid; + } + + /* Functions to build vertices from scratch + */ + setup_func[RADEON_WIN_BIT|RADEON_TEX0_BIT] = rs_wt0; + setup_func[RADEON_WIN_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wt0t1; + setup_func[RADEON_WIN_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_wft0; + setup_func[RADEON_WIN_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wft0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT] = rs_wg; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT] = rs_wgs; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT] = rs_wgt0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgt0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_wgst0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgst0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT] = rs_wgf; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT] = rs_wgfs; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_wgft0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgft0t1; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_wgfst0; + setup_func[RADEON_WIN_BIT|RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_wgfst0t1; + + /* Repair functions + */ + setup_func[RADEON_TEX0_BIT] = rs_t0; + setup_func[RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_t0t1; + setup_func[RADEON_FOG_BIT] = rs_f; + setup_func[RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_ft0; + setup_func[RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_ft0t1; + setup_func[RADEON_RGBA_BIT] = rs_g; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT] = rs_gs; + setup_func[RADEON_RGBA_BIT|RADEON_TEX0_BIT] = rs_gt0; + setup_func[RADEON_RGBA_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gt0t1; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_gst0; + setup_func[RADEON_RGBA_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gst0t1; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT] = rs_gf; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT] = rs_gfs; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT] = rs_gft0; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gft0t1; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT] = rs_gfst0; + setup_func[RADEON_RGBA_BIT|RADEON_FOG_BIT|RADEON_SPEC_BIT|RADEON_TEX0_BIT|RADEON_TEX1_BIT] = rs_gfst0t1; +} + + +void radeonPrintSetupFlags( char *msg, GLuint flags ) +{ + fprintf( stderr, "%s: %d %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & RADEON_WIN_BIT) ? " xyzw," : "", + (flags & RADEON_RGBA_BIT) ? " rgba," : "", + (flags & RADEON_SPEC_BIT) ? " spec," : "", + (flags & RADEON_FOG_BIT) ? " fog," : "", + (flags & RADEON_TEX0_BIT) ? " tex-0," : "", + (flags & RADEON_TEX1_BIT) ? " tex-1," : "" ); +} + + +/* Initialize the vertex buffer setup functions based on the current + * rendering state. + */ +void radeonDDChooseRasterSetupFunc( GLcontext *ctx ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT( ctx ); + GLint index = RADEON_WIN_BIT | RADEON_RGBA_BIT; + + rmesa->vertsize = 8; + rmesa->vc_format = RADEON_TEX0_VERTEX_FORMAT; + rmesa->tmu_source[0] = 0; + rmesa->tmu_source[1] = 1; + rmesa->tex_dest[0] = RADEON_TEX0_BIT; + rmesa->tex_dest[1] = RADEON_TEX1_BIT; + rmesa->multitex = 0; + + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { + index |= RADEON_TEX0_BIT; + } + + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX1 ) { + if ( ctx->Texture.ReallyEnabled & ENABLE_TEX0 ) { + rmesa->multitex = 1; + rmesa->vertsize = 10; + rmesa->vc_format = RADEON_TEX1_VERTEX_FORMAT; + index |= RADEON_TEX1_BIT; + } else { + /* Just a funny way of doing single texturing. + */ + rmesa->tmu_source[0] = 1; + rmesa->tex_dest[1] = RADEON_TEX0_BIT; + index |= RADEON_TEX0_BIT; + } + } + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR ) + index |= RADEON_SPEC_BIT; + + if ( ctx->Fog.Enabled ) + index |= RADEON_FOG_BIT; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) { + radeonPrintSetupFlags( "full setup function", index ); + } + + rmesa->new_state |= RADEON_NEW_TEXTURE; + rmesa->SetupIndex = index; + + ctx->Driver.RasterSetup = setup_func[index]; +} + +/* Check to see if any updates of the vertex buffer entries are needed. + */ +void radeonDDCheckPartialRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *s ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(ctx); + GLint tmp = rmesa->SetupDone; + + s->type = 0; + rmesa->SetupDone = 0; + + if ( (ctx->Array.Summary & VERT_OBJ_ANY) == 0 ) + return; + + if ( ctx->IndirectTriangles ) + return; + + rmesa->SetupDone = tmp; +} + +/* Repair existing precalculated vertices with new data. + */ +void radeonDDPartialRasterSetup( struct vertex_buffer *VB ) +{ + radeonContextPtr rmesa = RADEON_CONTEXT(VB->ctx); + GLuint new = VB->pipeline->new_outputs; + GLuint available = VB->pipeline->outputs; + GLuint index = 0; + + if ( new & VERT_WIN ) { + new = available; + index |= RADEON_WIN_BIT | RADEON_FOG_BIT; + } + + if ( new & VERT_RGBA ) + index |= RADEON_RGBA_BIT | RADEON_SPEC_BIT; + + if ( new & VERT_TEX0_ANY ) + index |= RADEON_TEX0_BIT; + + if ( new & VERT_TEX1_ANY ) + index |= rmesa->tex_dest[1]; + + if ( new & VERT_FOG_COORD ) + index |= RADEON_FOG_BIT; + + rmesa->SetupDone &= ~index; + index &= rmesa->SetupIndex; + rmesa->SetupDone |= index; + + if ( RADEON_DEBUG & DEBUG_VERBOSE_MSG ) + radeonPrintSetupFlags( "partial setup function", index ); + + if ( index ) + setup_func[index]( VB, VB->Start, VB->Count ); +} + +void radeonDDDoRasterSetup( struct vertex_buffer *VB ) +{ + GLcontext *ctx = VB->ctx; + + if ( VB->Type == VB_CVA_PRECALC ) { + radeonDDPartialRasterSetup( VB ); + } else if ( ctx->Driver.RasterSetup ) { + ctx->Driver.RasterSetup( VB, VB->CopyStart, VB->Count ); + } +} + + +/* ================================================================ + * Hardware-format vertex buffers + */ + +void radeonDDResizeVB( struct vertex_buffer *VB, GLuint size ) +{ + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + + while ( rvb->size < size ) + rvb->size *= 2; + + ALIGN_FREE( rvb->vert_store ); + rvb->vert_store = ALIGN_MALLOC( sizeof(radeonVertex) * rvb->size, 32 ); + if ( !rvb->vert_store ) { + fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); + exit( 1 ); + } + + rvb->verts = (radeonVertexPtr)rvb->vert_store; + + gl_vector1ui_free( &rvb->clipped_elements ); + gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 ); + if ( !rvb->clipped_elements.start ) { + fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); + exit( 1 ); + } + + ALIGN_FREE( VB->ClipMask ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 ); + if ( !VB->ClipMask ) { + fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); + exit( 1 ); + } +} + +void radeonDDRegisterVB( struct vertex_buffer *VB ) +{ + radeonVertexBufferPtr rvb; + + rvb = (radeonVertexBufferPtr)CALLOC( sizeof(*rvb) ); + + rvb->size = VB->Size * 2; + rvb->vert_store = ALIGN_MALLOC( sizeof(radeonVertex) * rvb->size, 32 ); + if ( !rvb->vert_store ) { + fprintf( stderr, "Cannot allocate vertex store! Exiting...\n" ); + exit( 1 ); + } + + rvb->verts = (radeonVertexPtr)rvb->vert_store; + + gl_vector1ui_alloc( &rvb->clipped_elements, VEC_WRITABLE, rvb->size, 32 ); + if ( !rvb->clipped_elements.start ) { + fprintf( stderr, "Cannot allocate clipped elements! Exiting...\n" ); + exit( 1 ); + } + + ALIGN_FREE( VB->ClipMask ); + VB->ClipMask = (GLubyte *)ALIGN_MALLOC( sizeof(GLubyte) * rvb->size, 32 ); + if ( !VB->ClipMask ) { + fprintf( stderr, "Cannot allocate clipmask! Exiting...\n" ); + exit( 1 ); + } + + VB->driver_data = rvb; +} + +void radeonDDUnregisterVB( struct vertex_buffer *VB ) +{ + radeonVertexBufferPtr rvb = RADEON_DRIVER_DATA(VB); + + if ( rvb ) { + if ( rvb->vert_store ) ALIGN_FREE( rvb->vert_store ); + gl_vector1ui_free( &rvb->clipped_elements ); + FREE( rvb ); + VB->driver_data = 0; + } +} diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h new file mode 100644 index 000000000..bd809efbb --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h @@ -0,0 +1,136 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h,v 1.1 2001/01/08 01:07:29 martin Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_VB_H__ +#define __RADEON_VB_H__ + +#ifdef GLX_DIRECT_RENDERING + +/* FIXME: This is endian-specific */ +typedef struct { + GLubyte red; + GLubyte green; + GLubyte blue; + GLubyte alpha; +} radeon_color_t; + +/* The vertex structure. The final tu1/tv1 values are only used in + * multitexture modes, and the rhw2 value is currently never used. + */ +typedef struct { + GLfloat x, y, z; /* Coordinates in screen space */ + GLfloat rhw; /* Reciprocal homogeneous w */ + radeon_color_t color; /* Diffuse color */ + radeon_color_t specular; /* Specular color (alpha is fog) */ + GLfloat tu0, tv0; /* Texture 0 coordinates */ + GLfloat tu1, tv1; /* Texture 1 coordinates */ + GLfloat rhw2; /* Reciprocal homogeneous w2 */ +} radeon_vertex; + +/* Format of vertices in radeon_vertex struct: + */ +#define RADEON_TEX0_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0) + +#define RADEON_TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 | \ + RADEON_CP_VC_FRMT_ST1) + +#if 0 +#define RADEON_PROJ_TEX1_VERTEX_FORMAT (RADEON_CP_VC_FRMT_XY | \ + RADEON_CP_VC_FRMT_Z | \ + RADEON_CP_VC_FRMT_W0 | \ + RADEON_CP_VC_FRMT_PKCOLOR | \ + RADEON_CP_VC_FRMT_PKSPEC | \ + RADEON_CP_VC_FRMT_ST0 | \ + RADEON_CP_VC_FRMT_ST1 | \ + RADEON_CP_VC_FRMT_Q1) +#endif + + +/* The fastpath code still expects a 16-float stride vertex. + */ +union radeon_vertex_t { + radeon_vertex v; + GLfloat f[16]; + GLuint ui[16]; +}; + +typedef union radeon_vertex_t radeonVertex; +typedef union radeon_vertex_t *radeonVertexPtr; + +typedef struct { + radeonVertexPtr verts; + GLvector1ui clipped_elements; + GLint last_vert; + void *vert_store; + GLuint size; +} *radeonVertexBufferPtr; + +#define RADEON_DRIVER_DATA(vb) ((radeonVertexBufferPtr)((vb)->driver_data)) + +#define RADEON_WIN_BIT 0x01 +#define RADEON_RGBA_BIT 0x02 +#define RADEON_FOG_BIT 0x04 +#define RADEON_SPEC_BIT 0x08 +#define RADEON_TEX0_BIT 0x10 +#define RADEON_TEX1_BIT 0x20 +#define RADEON_MAX_SETUPFUNC 0x40 + +extern void radeonDDChooseRasterSetupFunc( GLcontext *ctx ); +extern void radeonPrintSetupFlags( char *msg, GLuint flags ); + +extern void radeonDDCheckPartialRasterSetup( GLcontext *ctx, + struct gl_pipeline_stage *s ); +extern void radeonDDPartialRasterSetup( struct vertex_buffer *VB ); +extern void radeonDDDoRasterSetup( struct vertex_buffer *VB ); + +extern void radeonDDResizeVB( struct vertex_buffer *VB, GLuint size ); +extern void radeonDDRegisterVB( struct vertex_buffer *VB ); +extern void radeonDDUnregisterVB( struct vertex_buffer *VB ); + +extern void radeonDDSetupInit( void ); + +#endif +#endif /* __RADEON_VB_H__ */ diff --git a/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c new file mode 100644 index 000000000..1f24b8409 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c @@ -0,0 +1,314 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c,v 1.2 2001/01/23 18:14:39 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifdef GLX_DIRECT_RENDERING + +/* Radeon Mesa driver includes */ +#include "radeon_context.h" +#include "radeon_ioctl.h" +#include "radeon_state.h" +#include "radeon_tex.h" + +/* Mesa src includes */ +#include "context.h" +#include "simple_list.h" +#include "mmath.h" + +extern void __driRegisterExtensions( void ); + +static radeonContextPtr radeonCtx = NULL; + + +/* Initialize the driver specific screen private data. + */ +GLboolean XMesaInitDriver( __DRIscreenPrivate *sPriv ) +{ + sPriv->private = (void *) radeonCreateScreen( sPriv ); + + /* Check the DRI version */ + { + int major, minor, patch; + if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { + if (major != 3 || minor != 1 || patch < 0) { + char msg[1000]; + sprintf(msg, "RADEON DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch); + __driMesaMessage(msg); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if (sPriv->ddxMajor != 4 || + sPriv->ddxMinor != 0 || + sPriv->ddxPatch < 0) { + char msg[1000]; + sprintf(msg, "RADEON DRI driver expected DDX driver version 4.0.x but got version %d.%d.%d", sPriv->ddxMajor, sPriv->ddxMinor, sPriv->ddxPatch); + __driMesaMessage(msg); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if (sPriv->drmMajor != 1 || + sPriv->drmMinor != 0 || + sPriv->drmPatch < 0) { + char msg[1000]; + sprintf(msg, "RADEON DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", sPriv->drmMajor, sPriv->drmMinor, sPriv->drmPatch); + __driMesaMessage(msg); + return GL_FALSE; + } + + if ( !sPriv->private ) { + radeonDestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + +/* Reset the driver specific screen private data. + */ +void XMesaResetDriver( __DRIscreenPrivate *sPriv ) +{ + radeonDestroyScreen( sPriv ); +} + +/* Create and initialize the Mesa and driver specific visual data. + */ +GLvisual *XMesaCreateVisual( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + const XVisualInfo *visinfo, + const __GLXvisualConfig *config ) +{ + /* Drivers may change the args to _mesa_create_visual() in order to + * setup special visuals. + */ + return _mesa_create_visual( config->rgba, + config->doubleBuffer, + config->stereo, + _mesa_bitcount( visinfo->red_mask ), + _mesa_bitcount( visinfo->green_mask ), + _mesa_bitcount( visinfo->blue_mask ), + config->alphaSize, + 0, /* index bits */ + config->depthSize, + config->stencilSize, + config->accumRedSize, + config->accumGreenSize, + config->accumBlueSize, + config->accumAlphaSize, + 0 /* num samples */); +} + +/* Create and initialize the Mesa and driver specific context data. + */ +GLboolean XMesaCreateContext( Display *dpy, GLvisual *mesaVis, + __DRIcontextPrivate *driContextPriv ) +{ + return radeonCreateContext( dpy, mesaVis, driContextPriv ); +} + +/* Destroy the Mesa and driver specific context data. + */ +void XMesaDestroyContext( __DRIcontextPrivate *driContextPriv ) +{ + radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; + + if ( rmesa == (void *)radeonCtx) radeonCtx = NULL; + radeonDestroyContext( rmesa ); +} + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +GLframebuffer *XMesaCreateWindowBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis ) +{ + return gl_create_framebuffer( mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + GL_FALSE /* software alpha buffer? */ ); +} + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +GLframebuffer *XMesaCreatePixmapBuffer( Display *dpy, + __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + GLvisual *mesaVis ) +{ +#if 0 + /* Different drivers may have different combinations of hardware and + * software ancillary buffers. + */ + return gl_create_framebuffer( mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->StencilBits > 0, + mesaVis->AccumRedBits > 0, + mesaVis->AlphaBits > 0 ); +#else + return NULL; /* not implemented yet */ +#endif +} + +/* Copy the back color buffer to the front color buffer. + */ +void XMesaSwapBuffers( __DRIdrawablePrivate *driDrawPriv ) +{ + /* FIXME: This assumes buffer is currently bound to a context. This + * needs to be able to swap buffers when not currently bound. Also, + * this needs to swap according to buffer, and NOT according to + * context! + */ + if ( radeonCtx == NULL ) return; + + /* Only swap buffers when a back buffer exists. + */ + if ( radeonCtx->glCtx->Visual->DBflag ) { + FLUSH_VB( radeonCtx->glCtx, "swap buffers" ); + if ( !radeonCtx->doPageFlip ) { + radeonSwapBuffers( radeonCtx ); + } else { + radeonPageFlip( radeonCtx ); + } + } +} + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +GLboolean XMesaMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) +{ + if ( driContextPriv ) { + radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; + + radeonCtx = radeonMakeCurrent( radeonCtx, rmesa, driDrawPriv ); + + gl_make_current2( radeonCtx->glCtx, + driDrawPriv->mesaBuffer, + driReadPriv->mesaBuffer ); + + if ( radeonCtx->driDrawable != driDrawPriv ) { + radeonCtx->driDrawable = driDrawPriv; + radeonCtx->dirty = RADEON_UPLOAD_ALL; + } + + /* GH: We need this to correctly calculate the window offset + * and aux scissor rects. + */ + radeonCtx->new_state = RADEON_NEW_WINDOW | RADEON_NEW_CLIP; + + if ( !radeonCtx->glCtx->Viewport.Width ) { + gl_Viewport( radeonCtx->glCtx, 0, 0, driDrawPriv->w, driDrawPriv->h ); + } + } else { + gl_make_current( 0, 0 ); + radeonCtx = NULL; + } + + return GL_TRUE; +} + +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean XMesaUnbindContext( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we'd register new extension functions with the dispatcher. + */ +void __driRegisterExtensions( void ) +{ +} + +/* Initialize the fullscreen mode. + */ +GLboolean +XMesaOpenFullScreen( __DRIcontextPrivate *driContextPriv ) +{ + radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; + GLint ret; + + /* FIXME: Do we need to check this? + */ + if ( !radeonCtx->glCtx->Visual->DBflag ) + return GL_TRUE; + + LOCK_HARDWARE( rmesa ); + radeonWaitForIdleLocked( rmesa ); + + /* Ignore errors. If this fails, we simply don't do page flipping. + */ + ret = drmRadeonFullScreen( rmesa->driFd, GL_TRUE ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->doPageFlip = ( ret == 0 ); + + return GL_TRUE; +} + +/* Shut down the fullscreen mode. + */ +GLboolean +XMesaCloseFullScreen( __DRIcontextPrivate *driContextPriv ) +{ + radeonContextPtr rmesa = (radeonContextPtr)driContextPriv->driverPrivate; + + LOCK_HARDWARE( rmesa ); + radeonWaitForIdleLocked( rmesa ); + + /* Don't care if this fails, we're not page flipping anymore. + */ + drmRadeonFullScreen( rmesa->driFd, GL_FALSE ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->doPageFlip = GL_FALSE; + rmesa->currentPage = 0; + + return GL_TRUE; +} + +#endif diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c b/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c index 1caa57200..b2badf3f9 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_alloc.c,v 1.6 2000/09/26 15:56:48 tsi Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_alloc.c,v 1.7 2001/01/08 01:07:29 martin Exp $ */ /* * Authors: @@ -40,7 +40,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #if defined(XFree86Server) && !defined(XF86DRI) # include "xf86fbman.h" #else +# define CONFIG_DRM_SIS # include "drm.h" +# undef CONFIG_DRM_SIS # include "sis_drm.h" # include <sys/ioctl.h> #endif diff --git a/xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c b/xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c index 24a7e84b9..9e1eb105c 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c @@ -24,7 +24,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c,v 1.6 2000/12/07 20:26:10 dawes Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_xmesa.c,v 1.9 2000/12/22 09:20:04 alanh Exp $ */ /* * Authors: @@ -76,6 +76,39 @@ GLboolean XMesaInitDriver (__DRIscreenPrivate * driScrnPriv) { SISDRIPtr priv = (SISDRIPtr) driScrnPriv->pDevPriv; + /* Check the DRI version */ + { + int major, minor, patch; + if (XF86DRIQueryVersion(driScrnPriv->display, &major, &minor, &patch)) { + if (major != 3 || minor != 1 || patch < 0) { + char msg[1000]; + sprintf(msg, "sis DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch); + __driMesaMessage(msg); + return GL_FALSE; + } + } + } + + /* Check that the DDX driver version is compatible */ + if (driScrnPriv->ddxMajor != 1 || + driScrnPriv->ddxMinor != 0 || + driScrnPriv->ddxPatch < 0) { + char msg[1000]; + sprintf(msg, "sis DRI driver expected DDX driver version 1.0.x but got version %d.%d.%d", driScrnPriv->ddxMajor, driScrnPriv->ddxMinor, driScrnPriv->ddxPatch); + __driMesaMessage(msg); + return GL_FALSE; + } + + /* Check that the DRM driver version is compatible */ + if (driScrnPriv->drmMajor != 1 || + driScrnPriv->drmMinor != 0 || + driScrnPriv->drmPatch < 0) { + char msg[1000]; + sprintf(msg, "sis DRI driver expected DRM driver version 1.0.x but got version %d.%d.%d", driScrnPriv->drmMajor, driScrnPriv->drmMinor, driScrnPriv->drmPatch); + __driMesaMessage(msg); + return GL_FALSE; + } + assert (driScrnPriv->devPrivSize == sizeof (SISDRIRec)); /* Fixme: in quake3, when context changed, XMesaInitDriver is called diff --git a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile index 160a33da6..6b3c488ab 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/Imakefile +++ b/xc/lib/GL/mesa/src/drv/tdfx/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.19 2000/12/12 23:24:28 dawes Exp $ +XCOMM $XFree86: xc/lib/GL/mesa/src/drv/tdfx/Imakefile,v 1.20 2001/02/16 01:26:11 dawes Exp $ #include <Threads.tmpl> @@ -365,7 +365,7 @@ NormalLintTarget($(SRCS)) LIBNAME = tdfx_dri.so ALL_OBJS = $(OBJS) ALL_DEPS = DONE -SharedDepModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) +SharedDriModuleTarget($(LIBNAME),$(ALL_DEPS),$(ALL_OBJS)) InstallDynamicModule($(LIBNAME),$(MODULEDIR),dri) #ifdef GlxSoProf diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c b/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c index 84994a966..c769ff117 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c,v 1.3 2000/12/08 21:34:20 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxddtex.c,v 1.4 2001/01/08 01:07:29 martin Exp $ */ /* * Mesa 3-D graphics library * Version: 3.3 @@ -873,7 +873,7 @@ fxDDTexImage2D(GLcontext * ctx, GLenum target, GLint level, GLboolean * retainInternalCopy) { fxMesaContext fxMesa = FX_CONTEXT(ctx); - const GLboolean allow32bpt = fxMesa->haveHwStencil; + const GLboolean allow32bpt = fxMesa->isNapalm; GrTextureFormat_t gldformat; tfxTexInfo *ti; tfxMipMapLevel *mml; @@ -1239,7 +1239,7 @@ fxDDCompressedTexImage2D( GLcontext *ctx, GLenum target, GLboolean *retainInternalCopy) { fxMesaContext fxMesa = FX_CONTEXT(ctx); - const GLboolean allow32bpt = fxMesa->haveHwStencil; + const GLboolean allow32bpt = fxMesa->isNapalm; GrTextureFormat_t gldformat; tfxTexInfo *ti; tfxMipMapLevel *mml; diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c b/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c index 93e0c915a..bb7393c9e 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c,v 1.2 2000/12/08 19:36:23 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxglidew.c,v 1.3 2001/01/08 01:07:29 martin Exp $ */ /* * Mesa 3-D graphics library * Version: 3.3 @@ -199,7 +199,6 @@ FX_grColorMaskv_NoLock(GLcontext *ctx, const GLboolean rgba[4]) } - FxBool FX_grLfbLock(fxMesaContext fxMesa, GrLock_t type, GrBuffer_t buffer, GrLfbWriteMode_t writeMode, GrOriginLocation_t origin, @@ -268,6 +267,30 @@ FX_getGrStateSize(fxMesaContext fxMesa) } void +FX_grGlideGetVersion(fxMesaContext fxMesa, char *buf) +{ + BEGIN_BOARD_LOCK(fxMesa); + strcpy(buf, grGetString(GR_VERSION)); + END_BOARD_LOCK(fxMesa); +} + +void +FX_grSstPerfStats(GrSstPerfStats_t * st) +{ + FxI32 n; + grGet(GR_STATS_PIXELS_IN, 4, &n); + st->pixelsIn = n; + grGet(GR_STATS_PIXELS_CHROMA_FAIL, 4, &n); + st->chromaFail = n; + grGet(GR_STATS_PIXELS_DEPTHFUNC_FAIL, 4, &n); + st->zFuncFail = n; + grGet(GR_STATS_PIXELS_AFUNC_FAIL, 4, &n); + st->aFuncFail = n; + grGet(GR_STATS_PIXELS_OUT, 4, &n); + st->pixelsOut = n; +} + +void FX_grAADrawLine(fxMesaContext fxMesa, GrVertex * a, GrVertex * b) { /* ToDo */ diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c b/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c index 640a429e3..4585d6bf3 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c,v 1.2 2000/12/08 19:36:23 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxsetup.c,v 1.3 2001/01/08 01:07:29 martin Exp $ */ /* * Mesa 3-D graphics library * Version: 3.3 @@ -93,7 +93,7 @@ fxTexValidate(GLcontext * ctx, struct gl_texture_object *tObj) fxTexGetFormat(tObj->Image[minl]->IntFormat, &(ti->info.format), &(ti->baseLevelInternalFormat), NULL, NULL, - fxMesa->haveHwStencil); + fxMesa->isNapalm); switch (tObj->WrapS) { case GL_CLAMP_TO_EDGE: diff --git a/xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h b/xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h index a71fd7f2c..a1f138e31 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h +++ b/xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h,v 1.3 2000/12/08 19:36:23 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/fxtritmp.h,v 1.4 2001/01/08 01:07:30 martin Exp $ */ /* * Mesa 3-D graphics library * Version: 3.3 @@ -384,12 +384,12 @@ static void TAG(fx_points) (GLcontext * ctx, GLuint first, GLuint last) } if (!VB->ClipOrMask) { - for (i = first; i <= last; i++) { + for (i = first; i < last; i++) { DRAW_POINT(i, radius, color[i]); } } else { - for (i = first; i <= last; i++) { + for (i = first; i < last; i++) { if (VB->ClipMask[i] == 0) { DRAW_POINT(i, radius, color[i]); } @@ -403,12 +403,12 @@ static void TAG(fx_points) (GLcontext * ctx, GLuint first, GLuint last) FX_grRenderBuffer(fxMesa, GR_BUFFER_FRONTBUFFER); if (!VB->ClipOrMask) { - for (i = first; i <= last; i++) { + for (i = first; i < last; i++) { DRAW_POINT(i, radius, color[i]); } } else { - for (i = first; i <= last; i++) { + for (i = first; i < last; i++) { if (VB->ClipMask[i] == 0) { DRAW_POINT(i, radius, color[i]); } diff --git a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c index 9da5a11f8..12775ef64 100644 --- a/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c @@ -25,7 +25,7 @@ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. **************************************************************************/ -/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c,v 1.10 2000/12/08 19:36:24 alanh Exp $ */ +/* $XFree86: xc/lib/GL/mesa/src/drv/tdfx/tdfx_xmesa.c,v 1.11 2000/12/21 13:58:56 alanh Exp $ */ /* * Authors: @@ -60,10 +60,10 @@ XMesaInitDriver(__DRIscreenPrivate * sPriv) { int major, minor, patch; if (XF86DRIQueryVersion(sPriv->display, &major, &minor, &patch)) { - if (major != 3 || minor != 0 || patch < 0) { + if (major != 3 || minor != 1 || patch < 0) { char msg[1000]; sprintf(msg, - "3dfx DRI driver expected DRI version 3.0.x but got version %d.%d.%d", + "3dfx DRI driver expected DRI version 3.1.x but got version %d.%d.%d", major, minor, patch); __driMesaMessage(msg); return GL_FALSE; |