diff options
140 files changed, 24087 insertions, 5584 deletions
diff --git a/xc/config/cf/host.def b/xc/config/cf/host.def index 4a2e9c182..f5d510ca6 100644 --- a/xc/config/cf/host.def +++ b/xc/config/cf/host.def @@ -36,6 +36,7 @@ /* #define GlxBuiltInI810 YES */ /* #define GlxBuiltInMga YES */ /* #define GlxBuiltInR128 YES */ +/* #define GlxBuiltInRadeon YES */ /* #define DoLoadableServer NO */ /* Optionally turn this on to change the place where you install the build */ diff --git a/xc/extras/Mesa/include/GL/gl.h b/xc/extras/Mesa/include/GL/gl.h index 5a31ddebd..4c6d2b3fc 100644 --- a/xc/extras/Mesa/include/GL/gl.h +++ b/xc/extras/Mesa/include/GL/gl.h @@ -2228,6 +2228,19 @@ GLAPI void GLAPIENTRY glResizeBuffersMESA( void ); #endif /* GL_MESA_resize_bufffers */ + +/* + * 220. GL_EXT_texture_env_dot3 + */ +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 + +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 + +#endif /* GL_EXT_texture_env_dot3 */ + + #else /* GL_GLEXT_LEGACY */ #include <GL/glext.h> diff --git a/xc/extras/Mesa/include/GL/glext.h b/xc/extras/Mesa/include/GL/glext.h index f721a9fd7..7339398a4 100644 --- a/xc/extras/Mesa/include/GL/glext.h +++ b/xc/extras/Mesa/include/GL/glext.h @@ -13,21 +13,21 @@ extern "C" { ** this file except in compliance with the License. You may obtain a copy ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600 ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at: -** +** ** http://oss.sgi.com/projects/FreeB -** +** ** Note that, as provided in the License, the Software is distributed on an ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT. -** +** ** Original Code. The Original Code is: OpenGL Sample Implementation, ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics, ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc. ** Copyright in any portions created by third parties is as indicated ** elsewhere herein. All Rights Reserved. -** +** ** Additional Notice Provisions: This software was created using the ** OpenGL(R) version 1.2.1 Sample Implementation published by SGI, but has ** not been independently verified as being compliant with the OpenGL(R) @@ -1419,6 +1419,11 @@ extern "C" { #define GL_TEXTURE_COLOR_WRITEMASK_SGIS 0x81EF #endif +#ifndef GL_EXT_texture_env_dot3 +#define GL_DOT3_RGB_EXT 0x8740 +#define GL_DOT3_RGBA_EXT 0x8741 +#endif + /*************************************************************/ @@ -2918,6 +2923,10 @@ extern void APIENTRY glTextureColorMaskSGIS (GLboolean, GLboolean, GLboolean, GL typedef void (APIENTRY * PFNGLTEXTURECOLORMASKSGISPROC) (GLboolean red, GLboolean green, GLboolean blue, GLboolean alpha); #endif +#ifndef GL_EXT_texture_env_dot3 +#define GL_EXT_texture_env_dot3 1 +#endif + #ifdef __cplusplus } diff --git a/xc/extras/Mesa/src/enums.c b/xc/extras/Mesa/src/enums.c index c68cf74b8..bc93f61dc 100644 --- a/xc/extras/Mesa/src/enums.c +++ b/xc/extras/Mesa/src/enums.c @@ -2,19 +2,19 @@ /* * Mesa 3-D graphics library * Version: 3.3 - * + * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -33,12 +33,12 @@ #endif -typedef struct { - const char *c; - int n; +typedef struct { + const char *c; + int n; } enum_elt; -enum_elt all_enums[] = +enum_elt all_enums[] = { /* Boolean values */ { "GL_FALSE", 0 }, @@ -827,7 +827,11 @@ enum_elt all_enums[] = { "GL_INTERPOLATE_EXT", 0x8575 }, { "GL_CONSTANT_EXT", 0x8576 }, { "GL_PRIMARY_COLOR_EXT", 0x8577 }, - { "GL_PREVIOUS_EXT", 0x8578 } + { "GL_PREVIOUS_EXT", 0x8578 }, + + /* GL_EXT_texture_env_dot3 */ + { "GL_DOT3_RGB_EXT", 0x8740 }, + { "GL_DOT3_RGBA_EXT", 0x8741 }, }; @@ -838,7 +842,7 @@ typedef int (GLWINAPIV *cfunc)(const void *, const void *); static enum_elt **index1 = 0; static int sorted = 0; -static int compar_name( const enum_elt *a, const enum_elt *b ) +static int compar_name( const enum_elt *a, const enum_elt *b ) { return strcmp(a->c, b->c); } @@ -846,7 +850,7 @@ static int compar_name( const enum_elt *a, const enum_elt *b ) /* note the extra level of indirection */ -static int compar_nr( const enum_elt **a, const enum_elt **b ) +static int compar_nr( const enum_elt **a, const enum_elt **b ) { return (*a)->n - (*b)->n; } @@ -858,10 +862,10 @@ static void sort_enums( void ) index1 = (enum_elt **)MALLOC( Elements(all_enums) * sizeof(enum_elt *) ); sorted = 1; - qsort( all_enums, Elements(all_enums), sizeof(*all_enums), + qsort( all_enums, Elements(all_enums), sizeof(*all_enums), (cfunc) compar_name ); - for (i = 0 ; i < Elements(all_enums) ; i++) + for (i = 0 ; i < Elements(all_enums) ; i++) index1[i] = &all_enums[i]; qsort( index1, Elements(all_enums), sizeof(*index1), (cfunc) compar_nr ); @@ -874,14 +878,14 @@ int gl_lookup_enum_by_name( const char *symbol ) enum_elt tmp; enum_elt *e; - if (!sorted) + if (!sorted) sort_enums(); - if (!symbol) + if (!symbol) return 0; tmp.c = symbol; - e = (enum_elt *)bsearch( &tmp, all_enums, Elements(all_enums), + e = (enum_elt *)bsearch( &tmp, all_enums, Elements(all_enums), sizeof(*all_enums), (cfunc) compar_name ); return e ? e->n : -1; @@ -892,13 +896,13 @@ const char *gl_lookup_enum_by_nr( int nr ) { enum_elt tmp, *e, **f; - if (!sorted) + if (!sorted) sort_enums(); tmp.n = nr; e = &tmp; - f = (enum_elt **)bsearch( &e, index1, Elements(all_enums), + f = (enum_elt **)bsearch( &e, index1, Elements(all_enums), sizeof(*index1), (cfunc) compar_nr ); return f ? (*f)->c : "(unknown)"; @@ -919,6 +923,6 @@ int main() for (i = 0 ; i < Elements(test) ; i++) { int d = gl_lookup_enum_by_name( test[i] ); printf("%s --> %d --> %s\n", test[i], d, gl_lookup_enum_by_nr( d )); - } + } } #endif diff --git a/xc/extras/Mesa/src/extensions.c b/xc/extras/Mesa/src/extensions.c index f3e771c98..a86c77e02 100644 --- a/xc/extras/Mesa/src/extensions.c +++ b/xc/extras/Mesa/src/extensions.c @@ -2,19 +2,19 @@ /* * Mesa 3-D graphics library * Version: 3.4 - * + * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -42,7 +42,7 @@ struct extension { struct extension *next, *prev; GLint enabled; char name[MAX_EXT_NAMELEN+1]; - void (*notify)( GLcontext *, GLboolean ); + void (*notify)( GLcontext *, GLboolean ); }; @@ -75,6 +75,7 @@ static struct { int enabled; const char *name; } default_extensions[] = { { DEFAULT_OFF, "GL_EXT_texture_env" }, { DEFAULT_ON, "GL_EXT_texture_env_add" }, { DEFAULT_OFF, "GL_EXT_texture_env_combine" }, + { DEFAULT_OFF, "GL_EXT_texture_env_dot3" }, { ALWAYS_ENABLED, "GL_EXT_texture_object" }, { DEFAULT_ON, "GL_EXT_texture_lod_bias" }, { ALWAYS_ENABLED, "GL_EXT_vertex_array" }, @@ -104,6 +105,7 @@ update_extension_flags( GLcontext *ctx ) /* Update flags */ ctx->Extensions.HaveTextureEnvAdd = gl_extension_is_enabled(ctx, "GL_EXT_texture_env_add"); ctx->Extensions.HaveTextureEnvCombine = gl_extension_is_enabled(ctx, "GL_EXT_texture_env_combine"); + ctx->Extensions.HaveTextureEnvDot3 = gl_extension_is_enabled(ctx, "GL_EXT_texture_env_dot3"); ctx->Extensions.HaveTextureLodBias = gl_extension_is_enabled(ctx, "GL_EXT_texture_lod_bias"); ctx->Extensions.HaveHpOcclusionTest = gl_extension_is_enabled(ctx, "GL_HP_occlusion_test"); ctx->Extensions.HaveTextureCubeMap = gl_extension_is_enabled(ctx, "GL_ARB_texture_cube_map"); @@ -115,14 +117,14 @@ update_extension_flags( GLcontext *ctx ) -int gl_extensions_add( GLcontext *ctx, - int state, - const char *name, +int gl_extensions_add( GLcontext *ctx, + int state, + const char *name, void (*notify)(void) ) { (void) notify; - if (ctx->Extensions.ext_string == 0) + if (ctx->Extensions.ext_string == 0) { struct extension *t = MALLOC_STRUCT(extension); t->enabled = state; @@ -142,27 +144,27 @@ int gl_extensions_add( GLcontext *ctx, static int set_extension( GLcontext *ctx, const char *name, GLint state ) { struct extension *i; - foreach( i, ctx->Extensions.ext_list ) - if (strncmp(i->name, name, MAX_EXT_NAMELEN) == 0) + foreach( i, ctx->Extensions.ext_list ) + if (strncmp(i->name, name, MAX_EXT_NAMELEN) == 0) break; if (i == ctx->Extensions.ext_list) return 1; if (!(i->enabled & ALWAYS_ENABLED)) { - if (i->notify) i->notify( ctx, state ); + if (i->notify) i->notify( ctx, state ); i->enabled = state; } update_extension_flags(ctx); return 0; -} +} int gl_extensions_enable( GLcontext *ctx, const char *name ) { - if (ctx->Extensions.ext_string == 0) + if (ctx->Extensions.ext_string == 0) return set_extension( ctx, name, 1 ); return 1; } @@ -170,11 +172,11 @@ int gl_extensions_enable( GLcontext *ctx, const char *name ) int gl_extensions_disable( GLcontext *ctx, const char *name ) { - if (ctx->Extensions.ext_string == 0) + if (ctx->Extensions.ext_string == 0) return set_extension( ctx, name, 0 ); return 1; } - + /* * Test if the named extension is enabled in this context. @@ -208,10 +210,10 @@ void gl_extensions_dtr( GLcontext *ctx ) remove_from_list( i ); FREE( i ); } - + FREE(ctx->Extensions.ext_list); ctx->Extensions.ext_list = 0; - } + } } @@ -224,7 +226,7 @@ void gl_extensions_ctr( GLcontext *ctx ) make_empty_list( ctx->Extensions.ext_list ); for (i = 0 ; i < Elements(default_extensions) ; i++) { - gl_extensions_add( ctx, + gl_extensions_add( ctx, default_extensions[i].enabled, default_extensions[i].name, 0 ); @@ -235,22 +237,22 @@ void gl_extensions_ctr( GLcontext *ctx ) const char *gl_extensions_get_string( GLcontext *ctx ) { - if (ctx->Extensions.ext_string == 0) + if (ctx->Extensions.ext_string == 0) { struct extension *i; char *str; GLuint len = 0; - foreach (i, ctx->Extensions.ext_list) + foreach (i, ctx->Extensions.ext_list) if (i->enabled) len += strlen(i->name) + 1; - - if (len == 0) + + if (len == 0) return ""; str = (char *)MALLOC(len * sizeof(char)); ctx->Extensions.ext_string = str; - foreach (i, ctx->Extensions.ext_list) + foreach (i, ctx->Extensions.ext_list) if (i->enabled) { strcpy(str, i->name); str += strlen(str); @@ -259,6 +261,6 @@ const char *gl_extensions_get_string( GLcontext *ctx ) *(str-1) = 0; } - + return ctx->Extensions.ext_string; } diff --git a/xc/extras/Mesa/src/pipeline.c b/xc/extras/Mesa/src/pipeline.c index efca3012d..79fd74622 100644 --- a/xc/extras/Mesa/src/pipeline.c +++ b/xc/extras/Mesa/src/pipeline.c @@ -1,4 +1,3 @@ -/* $Id: pipeline.c,v 1.9 2000/12/05 19:51:30 dawes Exp $*/ /* * Mesa 3-D graphics library diff --git a/xc/extras/Mesa/src/texstate.c b/xc/extras/Mesa/src/texstate.c index 523dbf82d..1ce0c8ca2 100644 --- a/xc/extras/Mesa/src/texstate.c +++ b/xc/extras/Mesa/src/texstate.c @@ -2,19 +2,19 @@ /* * Mesa 3-D graphics library * Version: 3.4 - * + * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -117,11 +117,19 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) case GL_ADD: case GL_ADD_SIGNED_EXT: case GL_INTERPOLATE_EXT: + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + if ((mode == GL_DOT3_RGB_EXT || + mode == GL_DOT3_RGBA_EXT) && + !ctx->Extensions.HaveTextureEnvDot3) { + gl_error(ctx, GL_INVALID_ENUM, "glTexEnv(param)"); + return; + } if (texUnit->CombineModeRGB == mode) return; /* no change */ texUnit->CombineModeRGB = mode; ctx->NewState |= NEW_TEXTURE_ENV; - break; + break; default: gl_error( ctx, GL_INVALID_ENUM, "glTexEnv(param)" ); return; @@ -355,7 +363,7 @@ _mesa_TexEnvfv( GLenum target, GLenum pname, const GLfloat *param ) } if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) - fprintf(stderr, "glTexEnv %s %s %.1f(%s) ...\n", + fprintf(stderr, "glTexEnv %s %s %.1f(%s) ...\n", gl_lookup_enum_by_nr(target), gl_lookup_enum_by_nr(pname), *param, @@ -619,7 +627,7 @@ _mesa_TexParameterfv( GLenum target, GLenum pname, const GLfloat *params ) ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexParameterfv"); if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) - fprintf(stderr, "texPARAM %s %s %d...\n", + fprintf(stderr, "texPARAM %s %s %d...\n", gl_lookup_enum_by_nr(target), gl_lookup_enum_by_nr(pname), eparam); @@ -1091,7 +1099,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) ASSERT_OUTSIDE_BEGIN_END_AND_FLUSH(ctx, "glTexGenfv"); if (MESA_VERBOSE&(VERBOSE_API|VERBOSE_TEXTURE)) - fprintf(stderr, "texGEN %s %s %x...\n", + fprintf(stderr, "texGEN %s %s %x...\n", gl_lookup_enum_by_nr(coord), gl_lookup_enum_by_nr(pname), *(int *)params); @@ -1241,7 +1249,7 @@ _mesa_TexGenfv( GLenum coord, GLenum pname, const GLfloat *params ) if (pname==GL_TEXTURE_GEN_MODE) { GLenum mode = (GLenum) (GLint) *params; switch (mode) { - case GL_OBJECT_LINEAR: + case GL_OBJECT_LINEAR: texUnit->GenModeQ = GL_OBJECT_LINEAR; texUnit->GenBitQ = TEXGEN_OBJ_LINEAR; break; @@ -1596,7 +1604,7 @@ _mesa_ActiveTextureARB( GLenum target ) ASSERT_OUTSIDE_BEGIN_END( ctx, "glActiveTextureARB" ); if (MESA_VERBOSE & (VERBOSE_API|VERBOSE_TEXTURE)) - fprintf(stderr, "glActiveTexture %s\n", + fprintf(stderr, "glActiveTexture %s\n", gl_lookup_enum_by_nr(target)); if (target >= GL_TEXTURE0_ARB && target < GL_TEXTURE0_ARB + maxUnits) { diff --git a/xc/extras/Mesa/src/texture.c b/xc/extras/Mesa/src/texture.c index 580121f47..93eddec27 100644 --- a/xc/extras/Mesa/src/texture.c +++ b/xc/extras/Mesa/src/texture.c @@ -2,19 +2,19 @@ /* * Mesa 3-D graphics library * Version: 3.4 - * + * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -61,16 +61,16 @@ static texgen_func texgen_sphere_map_tab[4]; typedef void (*build_m_func)(GLfloat f[][3], GLfloat m[], - const GLvector3f *normals, - const GLvector4f *coord_vec, + const GLvector3f *normals, + const GLvector4f *coord_vec, const GLuint flags[], const GLubyte cullmask[] ); -typedef void (*build_f_func)( GLfloat *f, +typedef void (*build_f_func)( GLfloat *f, GLuint fstride, const GLvector3f *normal_vec, - const GLvector4f *coord_vec, + const GLvector4f *coord_vec, const GLuint flags[], const GLubyte cullmask[] ); @@ -83,7 +83,7 @@ typedef void (*build_f_func)( GLfloat *f, #define FIRST_NORMAL normals->start #define NEXT_NORMAL STRIDE_F(normal, normals->stride) #define LOCAL_VARS -#define CHECK +#define CHECK #define IDX 0 #include "texgen_tmp.h" @@ -91,7 +91,7 @@ typedef void (*build_f_func)( GLfloat *f, #define TAG(x) x##_compacted #define FIRST_NORMAL normals->start #define NEXT_NORMAL ((flags[i]&VERT_NORM) ? (normal=first_normal[i]) : (normal)) -#define CHECK +#define CHECK #define IDX 2 #define LOCAL_VARS \ GLfloat (*first_normal)[3] = (GLfloat (*)[3]) FIRST_NORMAL; @@ -101,7 +101,7 @@ typedef void (*build_f_func)( GLfloat *f, #define TAG(x) x##_masked #define FIRST_NORMAL normals->start #define NEXT_NORMAL STRIDE_F(normal, normals->stride) -#define LOCAL_VARS +#define LOCAL_VARS #define CHECK if (cullmask[i]) #define IDX 1 #include "texgen_tmp.h" @@ -189,7 +189,7 @@ void gl_update_texture_unit( GLcontext *ctx, struct gl_texture_unit *texUnit ) fprintf(stderr, "Bad value for texUnit->Enabled %x\n", texUnit->Enabled); break; - } + } } texUnit->ReallyEnabled = 0; @@ -219,7 +219,7 @@ void gl_update_texture_unit( GLcontext *ctx, struct gl_texture_unit *texUnit ) sz = 4; texUnit->GenFlags |= texUnit->GenBitR; } - + texUnit->TexgenSize = sz; texUnit->Holes = (GLubyte) (all_bits[sz] & ~texUnit->TexGenEnabled); texUnit->func = texgen_generic_tab; @@ -232,7 +232,7 @@ void gl_update_texture_unit( GLcontext *ctx, struct gl_texture_unit *texUnit ) texUnit->func = texgen_normal_map_nv_tab; } } - else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) && + else if (texUnit->TexGenEnabled == (S_BIT|T_BIT) && texUnit->GenFlags == TEXGEN_SPHERE_MAP) { texUnit->func = texgen_sphere_map_tab; } @@ -398,7 +398,7 @@ static void palette_sample(const struct gl_texture_object *tObj, } - + /* * Bitflags for texture border color sampling. @@ -2215,6 +2215,29 @@ _mesa_texture_combine(const GLcontext *ctx, rgba[i][BCOMP] = (GLubyte) MIN2(b, 255); } } + break; + case GL_DOT3_RGB_EXT: + case GL_DOT3_RGBA_EXT: + { + const GLubyte (*arg0)[4] = (const GLubyte (*)[4]) argRGB[0]; + const GLubyte (*arg1)[4] = (const GLubyte (*)[4]) argRGB[1]; + /* ATI's EXT extension has a constant scale by 4. The ARB + * one will likely remove this restriction, and we should + * drop the EXT extension in favour of the ARB one. + */ + RGBshift = 6; + for (i = 0; i < n; i++) { + GLuint dot = (PROD(arg0[i][RCOMP] - 128, + arg1[i][RCOMP] - 128) + + PROD(arg0[i][GCOMP] - 128, + arg1[i][GCOMP] - 128) + + PROD(arg0[i][BCOMP] - 128, + arg1[i][BCOMP] - 128)) >> RGBshift; + rgba[i][RCOMP] = (GLubyte) MIN2(dot, 255); + rgba[i][GCOMP] = (GLubyte) MIN2(dot, 255); + rgba[i][BCOMP] = (GLubyte) MIN2(dot, 255); + } + } break; default: gl_problem(NULL, "invalid combine mode"); @@ -2286,6 +2309,14 @@ _mesa_texture_combine(const GLcontext *ctx, default: gl_problem(NULL, "invalid combine mode"); } + + /* Fix the alpha component for GL_DOT3_RGBA_EXT combining. + */ + if (textureUnit->CombineModeRGB == GL_DOT3_RGBA_EXT) { + for (i = 0; i < n; i++) { + rgba[i][ACOMP] = rgba[i][RCOMP]; + } + } } #undef PROD diff --git a/xc/extras/Mesa/src/texutil.c b/xc/extras/Mesa/src/texutil.c index 70f5c26a9..313ef1455 100644 --- a/xc/extras/Mesa/src/texutil.c +++ b/xc/extras/Mesa/src/texutil.c @@ -1,4 +1,3 @@ -/* $Id: texutil.c,v 1.8 2000/11/21 18:01:52 brianp Exp $ */ /* * Mesa 3-D graphics library diff --git a/xc/extras/Mesa/src/types.h b/xc/extras/Mesa/src/types.h index 092760aa5..804de925e 100644 --- a/xc/extras/Mesa/src/types.h +++ b/xc/extras/Mesa/src/types.h @@ -3,19 +3,19 @@ /* * Mesa 3-D graphics library * Version: 3.4 - * + * * Copyright (C) 1999-2000 Brian Paul All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the "Software"), * to deal in the Software without restriction, including without limitation * the rights to use, copy, modify, merge, publish, distribute, sublicense, * and/or sell copies of the Software, and to permit persons to whom the * Software is furnished to do so, subject to the following conditions: - * + * * The above copyright notice and this permission notice shall be included * in all copies or substantial portions of the Software. - * + * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL @@ -27,7 +27,7 @@ #ifndef TYPES_H #define TYPES_H - + #include "glheader.h" #include "config.h" @@ -126,7 +126,7 @@ typedef void (*rect_func)( GLcontext *ctx, GLint x, GLint y, /* - * The auxiliary interpolation function for clipping - now always in + * The auxiliary interpolation function for clipping - now always in * clip space. */ typedef void (*clip_interp_func)( struct vertex_buffer *VB, GLuint dst, @@ -140,7 +140,7 @@ typedef void (*render_vb_func)( GLcontext *ctx ); -typedef void (*render_func)( struct vertex_buffer *VB, +typedef void (*render_func)( struct vertex_buffer *VB, GLuint start, GLuint count, GLuint parity ); @@ -287,7 +287,7 @@ struct gl_light { GLfloat VP_inf_norm[3]; /* Norm direction to infinite light */ GLfloat h_inf_norm[3]; /* Norm( VP_inf_norm + <0,0,1> ) */ GLfloat NormDirection[4]; /* normalized spotlight direction */ - GLfloat VP_inf_spot_attenuation; + GLfloat VP_inf_spot_attenuation; GLfloat SpotExpTable[EXP_TABLE_SIZE][2]; /* to replace a pow() call */ GLfloat MatAmbient[2][3]; /* material ambient * light ambient */ @@ -368,7 +368,7 @@ struct gl_colorbuffer_attrib { struct gl_current_attrib { - /* KW: These values valid only when the VB is flushed. + /* KW: These values valid only when the VB is flushed. */ GLuint Flag; /* Contains size information */ GLfloat Normal[3]; @@ -377,7 +377,7 @@ struct gl_current_attrib { GLboolean EdgeFlag; /* Current edge flag */ GLfloat Texcoord[MAX_TEXTURE_UNITS][4]; /* Current texture coords */ GLenum Primitive; /* Prim or GL_POLYGON+1 */ - + /* KW: No change to these values. */ GLfloat RasterPos[4]; /* Current raster position */ @@ -665,11 +665,11 @@ struct gl_point_attrib { GLboolean SmoothFlag;/* True if GL_POINT_SMOOTH is enabled */ GLfloat UserSize; /* User-specified point size */ GLfloat Size; /* Point size actually used */ - GLfloat Params[3]; /* Point Parameters EXT distance atenuation - factors by default = {1,0,0} */ + GLfloat Params[3]; /* Point Parameters EXT distance atenuation + factors by default = {1,0,0} */ GLfloat MinSize; /* Default 0.0 always >=0 */ GLfloat MaxSize; /* Default MAX_POINT_SIZE */ - GLfloat Threshold; /* Default 1.0 */ + GLfloat Threshold; /* Default 1.0 */ GLboolean Attenuated; }; @@ -775,7 +775,7 @@ struct gl_stencil_attrib { #define ENABLE_TEX_ANY (ENABLE_TEX0 | ENABLE_TEX1) -typedef void (*texgen_func)( struct vertex_buffer *VB, +typedef void (*texgen_func)( struct vertex_buffer *VB, GLuint textureSet); @@ -887,14 +887,14 @@ struct gl_texture_attrib { GLuint CurrentTransformUnit; /* Current texture xform unit */ GLuint ReallyEnabled; /* Really enabled (w.r.t. completeness, etc) */ - + GLuint LastEnabled; /* Decide whether enabled has really changed */ GLboolean NeedNormals; GLboolean NeedEyeCoords; struct gl_texture_unit Unit[MAX_TEXTURE_UNITS]; - + struct gl_texture_object *Proxy1D; struct gl_texture_object *Proxy2D; struct gl_texture_object *Proxy3D; @@ -971,7 +971,7 @@ struct gl_client_array { */ typedef void (*trans_1ui_func)(GLuint *to, const struct gl_client_array *from, - GLuint start, + GLuint start, GLuint n ); typedef void (*trans_1ub_func)(GLubyte *to, @@ -986,52 +986,52 @@ typedef void (*trans_4ub_func)(GLubyte (*to)[4], typedef void (*trans_4f_func)(GLfloat (*to)[4], const struct gl_client_array *from, - GLuint start, + GLuint start, GLuint n ); typedef void (*trans_3f_func)(GLfloat (*to)[3], const struct gl_client_array *from, - GLuint start, + GLuint start, GLuint n ); typedef void (*trans_elt_1ui_func)(GLuint *to, const struct gl_client_array *from, - GLuint *flags, - GLuint *elts, + GLuint *flags, + GLuint *elts, GLuint match, GLuint start, GLuint n ); typedef void (*trans_elt_1ub_func)(GLubyte *to, const struct gl_client_array *from, - GLuint *flags, - GLuint *elts, + GLuint *flags, + GLuint *elts, GLuint match, GLuint start, GLuint n ); typedef void (*trans_elt_4ub_func)(GLubyte (*to)[4], const struct gl_client_array *from, - GLuint *flags, - GLuint *elts, + GLuint *flags, + GLuint *elts, GLuint match, GLuint start, GLuint n ); typedef void (*trans_elt_4f_func)(GLfloat (*to)[4], const struct gl_client_array *from, - GLuint *flags, - GLuint *elts, + GLuint *flags, + GLuint *elts, GLuint match, GLuint start, GLuint n ); typedef void (*trans_elt_3f_func)(GLfloat (*to)[3], const struct gl_client_array *from, - GLuint *flags, - GLuint *elts, + GLuint *flags, + GLuint *elts, GLuint match, GLuint start, GLuint n ); @@ -1051,15 +1051,15 @@ struct gl_array_object { struct gl_client_array EdgeFlag; trans_4f_func VertexFunc; /* conversion functions */ - trans_3f_func NormalFunc; - trans_4ub_func ColorFunc; + trans_3f_func NormalFunc; + trans_4ub_func ColorFunc; trans_1ui_func IndexFunc; trans_4f_func TexCoordFunc[MAX_TEXTURE_UNITS]; trans_1ub_func EdgeFlagFunc; trans_elt_4f_func VertexEltFunc; /* array elt conversion functions */ - trans_elt_3f_func NormalEltFunc; - trans_elt_4ub_func ColorEltFunc; + trans_elt_3f_func NormalEltFunc; + trans_elt_4ub_func ColorEltFunc; trans_elt_1ui_func IndexEltFunc; trans_elt_4f_func TexCoordEltFunc[MAX_TEXTURE_UNITS]; trans_elt_1ub_func EdgeFlagEltFunc; @@ -1068,7 +1068,7 @@ struct gl_array_object { GLuint LockFirst; GLuint LockCount; - + GLuint Flag[VB_SIZE]; /* crock */ GLuint Flags; GLuint Summary; /* Like flags, but no size information */ @@ -1090,15 +1090,15 @@ struct gl_array_attrib { struct gl_client_array EdgeFlag; trans_4f_func VertexFunc; /* conversion functions */ - trans_3f_func NormalFunc; - trans_4ub_func ColorFunc; + trans_3f_func NormalFunc; + trans_4ub_func ColorFunc; trans_1ui_func IndexFunc; trans_4f_func TexCoordFunc[MAX_TEXTURE_UNITS]; trans_1ub_func EdgeFlagFunc; trans_elt_4f_func VertexEltFunc; /* array elt conversion functions */ - trans_elt_3f_func NormalEltFunc; - trans_elt_4ub_func ColorEltFunc; + trans_elt_3f_func NormalEltFunc; + trans_elt_4ub_func ColorEltFunc; trans_elt_1ui_func IndexEltFunc; trans_elt_4f_func TexCoordEltFunc[MAX_TEXTURE_UNITS]; trans_elt_1ub_func EdgeFlagEltFunc; @@ -1108,7 +1108,7 @@ struct gl_array_attrib { GLuint LockFirst; GLuint LockCount; - + GLuint Flag[VB_SIZE]; /* crock */ GLuint Flags; GLuint Summary; /* Like flags, but no size information */ @@ -1200,7 +1200,7 @@ struct gl_pipeline { struct gl_cva { struct gl_pipeline pre; struct gl_pipeline elt; - + struct gl_client_array Elt; trans_1ui_func EltFunc; @@ -1254,7 +1254,7 @@ struct gl_1d_map { GLfloat u1, u2, du; /* u1, u2, 1.0/(u2-u1) */ GLfloat *Points; /* Points to contiguous control points */ }; - + /* * 2-D Evaluator control points @@ -1423,6 +1423,7 @@ struct gl_extensions { /* flags to quickly test if certain extensions are available */ GLboolean HaveTextureEnvAdd; GLboolean HaveTextureEnvCombine; + GLboolean HaveTextureEnvDot3; GLboolean HaveTextureLodBias; GLboolean HaveHpOcclusionTest; GLboolean HaveTextureCubeMap; @@ -1478,7 +1479,7 @@ struct gl_extensions { #define NEW_DRIVER_STATE (NEW_DRVSTATE0 | NEW_DRVSTATE1 | \ - NEW_DRVSTATE2 | NEW_DRVSTATE3) + NEW_DRVSTATE2 | NEW_DRVSTATE3) /* What can the driver do, what requires us to call render_triangle or * a non-driver rasterize function? @@ -1501,13 +1502,13 @@ struct gl_extensions { #define DD_POINT_SIZE 0x8000 #define DD_POINT_ATTEN 0x10000 #define DD_LIGHTING_CULL 0x20000 /* never set by driver */ -#define DD_POINT_SW_RASTERIZE 0x40000 -#define DD_LINE_SW_RASTERIZE 0x80000 -#define DD_TRI_SW_RASTERIZE 0x100000 -#define DD_QUAD_SW_RASTERIZE 0x200000 +#define DD_POINT_SW_RASTERIZE 0x40000 +#define DD_LINE_SW_RASTERIZE 0x80000 +#define DD_TRI_SW_RASTERIZE 0x100000 +#define DD_QUAD_SW_RASTERIZE 0x200000 #define DD_TRI_CULL_FRONT_BACK 0x400000 /* not supported by most drivers */ -#define DD_Z_NEVER 0x800000 -#define DD_STENCIL 0x1000000 +#define DD_Z_NEVER 0x800000 +#define DD_STENCIL 0x1000000 #define DD_CLIP_FOG_COORD 0x2000000 @@ -1528,7 +1529,7 @@ struct gl_extensions { DD_QUAD_SW_RASTERIZE) -/* Vertex buffer clipping flags +/* Vertex buffer clipping flags */ #define CLIP_RIGHT_SHIFT 0 #define CLIP_LEFT_SHIFT 1 @@ -1580,7 +1581,7 @@ struct gl_extensions { */ #define SHADE_TWOSIDE 0x4 -/* Flags for selecting a normal transformation function. +/* Flags for selecting a normal transformation function. */ #define NORM_RESCALE 0x1 /* apply the scale factor */ #define NORM_NORMALIZE 0x2 /* normalize */ @@ -1676,7 +1677,7 @@ typedef union node Node; /* KW: Flags that describe the current vertex state, and the contents - * of a vertex in a vertex-cassette. + * of a vertex in a vertex-cassette. * * For really major expansion, consider a 'VERT_ADDITIONAL_FLAGS' flag, * which means there is data in another flags array (eg, extra_flags[]). @@ -1693,7 +1694,7 @@ typedef union node Node; #define VERT_INDEX 0x100 /* glIndex */ #define VERT_EDGE 0x200 /* glEdgeFlag */ #define VERT_MATERIAL 0x400 /* glMaterial */ -#define VERT_TEX0_1 0x800 +#define VERT_TEX0_1 0x800 #define VERT_TEX0_2 0x1000 #define VERT_TEX0_3 0x2000 #define VERT_TEX0_4 0x4000 @@ -1710,7 +1711,7 @@ typedef union node Node; #define VERT_EVAL_C2 0x2000000 /* - or just use 3 bits */ #define VERT_EVAL_P1 0x4000000 /* */ #define VERT_EVAL_P2 0x8000000 /* */ -#define VERT_SPEC_RGB 0x10000000 +#define VERT_SPEC_RGB 0x10000000 #define VERT_FOG_COORD 0x20000000 /* internal use only, currently */ #define VERT_EYE VERT_BEGIN /* for pipeline management & cva */ @@ -1746,7 +1747,7 @@ typedef union node Node; #define VERT_TEX2_1234 (VERT_TEX2_4|VERT_TEX2_123) #define VERT_TEX2_ANY VERT_TEX2_1 -/* not used +/* not used #define VERT_TEX3_12 (VERT_TEX3_2|VERT_TEX3_1) #define VERT_TEX3_123 (VERT_TEX3_3|VERT_TEX3_12) #define VERT_TEX3_1234 (VERT_TEX3_4|VERT_TEX3_123) @@ -1785,7 +1786,7 @@ typedef union node Node; typedef void (*vb_transform_func)( GLcontext *ctx ); -typedef GLuint (*clip_line_func)( struct vertex_buffer *VB, +typedef GLuint (*clip_line_func)( struct vertex_buffer *VB, GLuint *i, GLuint *j, GLubyte mask); typedef GLuint (*clip_poly_func)( struct vertex_buffer *VB, @@ -1793,7 +1794,7 @@ typedef GLuint (*clip_poly_func)( struct vertex_buffer *VB, GLubyte mask ); /* - * The library context: + * The library context: */ struct gl_context { @@ -1811,7 +1812,7 @@ struct gl_context { /* Driver function pointer table */ struct dd_function_table Driver; - + triangle_func TriangleFunc; /* driver or indirect triangle func */ quad_func QuadFunc; triangle_func ClippedTriangleFunc; @@ -1931,7 +1932,7 @@ struct gl_context { GLboolean IntegerAccumMode; /* Storing unscaled integers? */ GLfloat IntegerAccumScaler; /* Implicit scale factor */ - struct gl_fallback_arrays Fallback; + struct gl_fallback_arrays Fallback; GLenum ErrorValue; /* Last error code */ @@ -1959,7 +1960,7 @@ struct gl_context { clip_interp_func ClipInterpFunc; GLuint ClipTabMask; - normal_func *NormalTransform; + normal_func *NormalTransform; /* Current shading function table */ gl_shade_func *shade_func_tab; @@ -1992,7 +1993,7 @@ struct gl_context { /* The vertex buffer being used by this context. */ struct vertex_buffer *VB; - + /* The pixel buffer being used by this context */ struct pixel_buffer* PB; @@ -2001,7 +2002,7 @@ struct gl_context { /* Should 3Dfx Glide driver catch signals? */ GLboolean CatchSignals; - + /* For debugging/development only */ GLboolean NoRaster; GLboolean FirstTimeCurrent; @@ -2016,7 +2017,7 @@ struct gl_context { #ifdef MESA_DEBUG -extern int MESA_VERBOSE; +extern int MESA_VERBOSE; extern int MESA_DEBUG_FLAGS; #else # define MESA_VERBOSE 0 @@ -2039,12 +2040,12 @@ enum _verbose { VERBOSE_CULL = 0x100, VERBOSE_DISPLAY_LIST = 0x200, VERBOSE_LIGHTING = 0x400 -}; +}; enum _debug { DEBUG_ALWAYS_FLUSH = 0x1 -}; +}; extern void gl_flush_vb( GLcontext *ctx, const char *where ); @@ -2061,7 +2062,7 @@ do { \ -/* Test if we're inside a glBegin / glEnd pair: +/* Test if we're inside a glBegin / glEnd pair: */ #define ASSERT_OUTSIDE_BEGIN_END( ctx, where ) \ do { \ diff --git a/xc/extras/freetype2/builds/cygwin/mkinstalldirs b/xc/extras/freetype2/builds/cygwin/mkinstalldirs index 5d1e52c62..ef1ca1707 100644 --- a/xc/extras/freetype2/builds/cygwin/mkinstalldirs +++ b/xc/extras/freetype2/builds/cygwin/mkinstalldirs @@ -4,7 +4,7 @@ # Created: 1993-05-16 # Public domain -# $Id: mkinstalldirs,v 1.1 2000/12/21 19:23:59 dawes Exp $ +# $Id: mkinstalldirs,v 1.2 2001/01/05 22:57:50 kem Exp $ errstatus=0 diff --git a/xc/extras/freetype2/builds/unix/mkinstalldirs b/xc/extras/freetype2/builds/unix/mkinstalldirs index 5d1e52c62..ef1ca1707 100755 --- a/xc/extras/freetype2/builds/unix/mkinstalldirs +++ b/xc/extras/freetype2/builds/unix/mkinstalldirs @@ -4,7 +4,7 @@ # Created: 1993-05-16 # Public domain -# $Id: mkinstalldirs,v 1.1 2000/12/21 19:23:59 dawes Exp $ +# $Id: mkinstalldirs,v 1.2 2001/01/05 22:57:50 kem Exp $ errstatus=0 diff --git a/xc/extras/ogl-sample/main/doc/man/manglw/Distfile b/xc/extras/ogl-sample/main/doc/man/manglw/Distfile index e5a9fb568..5b89e629e 100755 --- a/xc/extras/ogl-sample/main/doc/man/manglw/Distfile +++ b/xc/extras/ogl-sample/main/doc/man/manglw/Distfile @@ -1,6 +1,6 @@ # -# $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ -# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/doc/man/manglw/Attic/Distfile,v 1.1 2000/11/08 02:53:56 dawes Exp $ +# $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ +# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/doc/man/manglw/Attic/Distfile,v 1.2 2001/01/05 22:57:51 kem Exp $ # DISTDIR_SI = /xc/doc/man/GL/glw diff --git a/xc/extras/ogl-sample/main/doc/man/manglw/GNUmakefile b/xc/extras/ogl-sample/main/doc/man/manglw/GNUmakefile index 8806e8b2d..225c7ce39 100755 --- a/xc/extras/ogl-sample/main/doc/man/manglw/GNUmakefile +++ b/xc/extras/ogl-sample/main/doc/man/manglw/GNUmakefile @@ -32,8 +32,8 @@ # published by SGI, but has not been independently verified as being # compliant with the OpenGL(R) version 1.2.1 Specification. # -# $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ -# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/doc/man/manglw/Attic/GNUmakefile,v 1.1 2000/11/08 02:53:56 dawes Exp $ +# $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ +# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/doc/man/manglw/Attic/GNUmakefile,v 1.2 2001/01/05 22:57:51 kem Exp $ COMMONPREF = standard include $(ROOT)/usr/include/make/commondefs diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/Distfile b/xc/extras/ogl-sample/main/gfx/lib/glw/Distfile index 0d95e763b..499529b90 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/Distfile +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/Distfile @@ -1,6 +1,6 @@ # -# $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ -# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/Distfile,v 1.1 2000/11/08 02:53:56 dawes Exp $ +# $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ +# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/Distfile,v 1.2 2001/01/05 22:57:51 kem Exp $ # DISTFILES_SI = \ diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c index 24a8e0299..cd85dbb18 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c @@ -31,13 +31,13 @@ ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. ** -** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +** $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ */ /* utility routines for GLX. * Since these routines are used both in the Motif and X versions of * the widget, they cannot peek directly into the structure * - * $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDAUtil.c,v 1.1 2000/11/08 02:53:56 dawes Exp $ + * $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDAUtil.c,v 1.2 2001/01/05 22:57:51 kem Exp $ */ /* $XFree86: xc/extras/ogl-sample/main/gfx/lib/glw/GLwDAUtil.c,v 1.2 2000/11/02 20:39:06 dawes Exp $ */ diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.c b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.c index 330e63763..350c0f7c7 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.c +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.c @@ -31,10 +31,10 @@ ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. ** -** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +** $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ */ /* -** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawA.c,v 1.1 2000/11/08 02:53:56 dawes Exp $ +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawA.c,v 1.2 2001/01/05 22:57:51 kem Exp $ */ #include <stdio.h> diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.h b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.h index 3408a1999..67753b0c1 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.h +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawA.h @@ -31,10 +31,10 @@ ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. ** -** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +** $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ */ /* -** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawA.h,v 1.1 2000/11/08 02:53:56 dawes Exp $ +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawA.h,v 1.2 2001/01/05 22:57:51 kem Exp $ */ /* diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawAP.h b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawAP.h index 2e9e7d482..a80d36d48 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawAP.h +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwDrawAP.h @@ -31,10 +31,10 @@ ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. ** -** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +** $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ */ /* -** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawAP.h,v 1.1 2000/11/08 02:53:56 dawes Exp $ +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwDrawAP.h,v 1.2 2001/01/05 22:57:51 kem Exp $ */ /* diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.c b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.c index 215ece61d..ea89e957d 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.c +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.c @@ -31,10 +31,10 @@ ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. ** -** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +** $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ */ /* -** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawA.c,v 1.1 2000/11/08 02:53:56 dawes Exp $ +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawA.c,v 1.2 2001/01/05 22:57:51 kem Exp $ */ #ifndef __GLX_MOTIF diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.h b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.h index ba2265307..d6136c6af 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.h +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawA.h @@ -31,10 +31,10 @@ ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. ** -** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +** $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ */ /* -** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawA.h,v 1.1 2000/11/08 02:53:56 dawes Exp $ +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawA.h,v 1.2 2001/01/05 22:57:51 kem Exp $ */ /* diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawAP.h b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawAP.h index 2541bd4b4..8be9a431a 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawAP.h +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GLwMDrawAP.h @@ -31,10 +31,10 @@ ** published by SGI, but has not been independently verified as being ** compliant with the OpenGL(R) version 1.2.1 Specification. ** -** $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ +** $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ */ /* -** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawAP.h,v 1.1 2000/11/08 02:53:56 dawes Exp $ +** $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GLwMDrawAP.h,v 1.2 2001/01/05 22:57:51 kem Exp $ */ /* diff --git a/xc/extras/ogl-sample/main/gfx/lib/glw/GNUmakefile b/xc/extras/ogl-sample/main/gfx/lib/glw/GNUmakefile index 719638855..a943a5889 100755 --- a/xc/extras/ogl-sample/main/gfx/lib/glw/GNUmakefile +++ b/xc/extras/ogl-sample/main/gfx/lib/glw/GNUmakefile @@ -32,8 +32,8 @@ # published by SGI, but has not been independently verified as being # compliant with the OpenGL(R) version 1.2.1 Specification. # -# $Date: 2000/11/08 02:53:56 $ $Revision: 1.1 $ -# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GNUmakefile,v 1.1 2000/11/08 02:53:56 dawes Exp $ +# $Date: 2001/01/05 22:57:51 $ $Revision: 1.2 $ +# $Header: /home/ajax/dri-backup/xc/xc/extras/ogl-sample/main/gfx/lib/glw/Attic/GNUmakefile,v 1.2 2001/01/05 22:57:51 kem Exp $ include $(ROOT)/usr/include/make/commondefs diff --git a/xc/lib/GL/Imakefile b/xc/lib/GL/Imakefile index d7cf1884a..7c604c105 100644 --- a/xc/lib/GL/Imakefile +++ b/xc/lib/GL/Imakefile @@ -129,13 +129,14 @@ XCOMM nothing GAMMAPOBJS = mesa/src/drv/gamma/profiled/?*.o GAMMADONES = mesa/src/drv/gamma/DONE - DRVOBJS = $(GAMMAOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(GAMMAOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(GAMMAUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(GAMMADOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(GAMMAPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(GAMMADONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/gamma + DRVSUBDIRS = mesa/src/drv/gamma + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInTdfx @@ -145,7 +146,7 @@ XCOMM nothing TDFXPOBJS = mesa/src/drv/tdfx/profiled/?*.o TDFXDONES = mesa/src/drv/tdfx/DONE - DRVOBJS = $(TDFXOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(TDFXOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(TDFXUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(TDFXDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(TDFXPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) @@ -153,7 +154,8 @@ XCOMM nothing REQUIREDLIBS += -lglide3 -ldl - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/tdfx + DRVSUBDIRS = mesa/src/drv/tdfx + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInI810 @@ -163,13 +165,14 @@ REQUIREDLIBS += -lglide3 -ldl I810POBJS = mesa/src/drv/i810/profiled/?*.o I810DONES = mesa/src/drv/i810/DONE - DRVOBJS = $(I810OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(I810OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(I810UOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(I810DOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(I810POBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(I810DONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/i810 + DRVSUBDIRS = mesa/src/drv/i810 + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInMga @@ -179,13 +182,14 @@ REQUIREDLIBS += -lglide3 -ldl MGAPOBJS = mesa/src/drv/mga/profiled/?*.o MGADONES = mesa/src/drv/mga/DONE - DRVOBJS = $(MGAOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(MGAOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(MGAUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(MGADOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(MGAPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(MGADONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/mga + DRVSUBDIRS = mesa/src/drv/mga + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInR128 @@ -195,13 +199,31 @@ REQUIREDLIBS += -lglide3 -ldl R128POBJS = mesa/src/drv/r128/profiled/?*.o R128DONES = mesa/src/drv/r128/DONE - DRVOBJS = $(R128OBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) - DRVUOBJS = $(R128UOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) - DRVDOBJS = $(R128DOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) - DRVPOBJS = $(R128POBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) - DRVDONES = $(R128DONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) + DRVOBJS = $(R128OBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVUOBJS = $(R128UOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) + DRVDOBJS = $(R128DOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) + DRVPOBJS = $(R128POBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) + DRVDONES = $(R128DONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/r128 + DRVSUBDIRS = mesa/src/drv/common mesa/src/drv/r128 + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) + +#elif GlxBuiltInRadeon + + RADEONOBJS = mesa/src/drv/radeon/?*.o + RADEONUOBJS = mesa/src/drv/radeon/unshared/?*.o + RADEONDOBJS = mesa/src/drv/radeon/debugger/?*.o + RADEONPOBJS = mesa/src/drv/radeon/profiled/?*.o + RADEONDONES = mesa/src/drv/radeon/DONE + + DRVOBJS = $(RADEONOBJS) $(COMMONOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVUOBJS = $(RADEONUOBJS) $(COMMONUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) + DRVDOBJS = $(RADEONDOBJS) $(COMMONDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) + DRVPOBJS = $(RADEONPOBJS) $(COMMONPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) + DRVDONES = $(RADEONDONES) $(COMMONDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) + + DRVSUBDIRS = mesa/src/drv/common mesa/src/drv/radeon + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInFfb @@ -217,7 +239,8 @@ REQUIREDLIBS += -lglide3 -ldl DRVPOBJS = $(FFBPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(FFBDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/ffb + DRVSUBDIRS = mesa/src/drv/ffb + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInSIS @@ -227,13 +250,14 @@ REQUIREDLIBS += -lglide3 -ldl SISPOBJS = mesa/src/drv/sis/profiled/?*.o SISDONES = mesa/src/drv/sis/DONE - DRVOBJS = $(SISOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) + DRVOBJS = $(SISOBJS) $(MESAOBJS) $(DRIMESAOBJS) $(DRMOBJS) DRVUOBJS = $(SISUOBJS) $(MESAUOBJS) $(DRIMESAUOBJS) $(DRMUOBJS) DRVDOBJS = $(SISDOBJS) $(MESADOBJS) $(DRIMESADOBJS) $(DRMDOBJS) DRVPOBJS = $(SISPOBJS) $(MESAPOBJS) $(DRIMESAPOBJS) $(DRMPOBJS) DRVDONES = $(SISDONES) $(MESADONES) $(DRIMESADONES) $(DRMDONES) - GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src mesa/src/drv/sis + DRVSUBDIRS = mesa/src/drv/sis + GLXSUBDIRS = glx dri mesa/dri mesa/include/GL mesa/src $(DRVSUBDIRS) #elif GlxBuiltInMesa @@ -343,6 +367,7 @@ XCOMM libGL has now been made, continue with building the drivers. !GlxBuiltInI810 && \ !GlxBuiltInMga && \ !GlxBuiltInR128 && \ + !GlxBuiltInRadeon && \ !GlxBuiltInFfb && \ !GlxBuiltInSIS && \ !GlxBuiltInMesa diff --git a/xc/lib/GL/dri/drm/Imakefile b/xc/lib/GL/dri/drm/Imakefile index ba7b73fea..65085e090 100644 --- a/xc/lib/GL/dri/drm/Imakefile +++ b/xc/lib/GL/dri/drm/Imakefile @@ -16,9 +16,9 @@ ALLOC_DEFINES = -DMALLOC_0_RETURNS_NULL -I$(XF86OSSRC)/$(OS_SUBDIR)/drm/kernel \ -I$(XF86OSSRC) SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c \ - xf86drmR128.c + xf86drmR128.c xf86drmRadeon.c OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o \ - xf86drmR128.o + xf86drmR128.o xf86drmRadeon.o #if defined(LinuxArchitecture) OS_SUBDIR = linux @@ -34,15 +34,22 @@ OS_SUBDIR2 = cygwin #endif LinkSourceFile(xf86drm.c,$(XF86OSSRC)/$(OS_SUBDIR)/drm) + LinkSourceFile(xf86drmHash.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) LinkSourceFile(xf86drmRandom.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) LinkSourceFile(xf86drmSL.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) LinkSourceFile(xf86drmR128.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) +LinkSourceFile(xf86drmRadeon.c,$(XF86OSSRC)/$(OS_SUBDIR2)/drm) + +LinkSourceFile(xf86drm.h,$(XF86OSSRC)) +LinkSourceFile(xf86drmR128.h,$(XF86OSSRC)) +LinkSourceFile(xf86drmRadeon.h,$(XF86OSSRC)) LinkSourceFile(drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) LinkSourceFile(i810_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) LinkSourceFile(mga_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) LinkSourceFile(r128_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) +LinkSourceFile(radeon_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) LinkSourceFile(sis_drm.h,$(XF86OSSRC)/$(OS_SUBDIR2)/drm/kernel) #include <Library.tmpl> diff --git a/xc/lib/GL/mesa/src/drv/Imakefile b/xc/lib/GL/mesa/src/drv/Imakefile index 88b259502..0f0dcebf5 100644 --- a/xc/lib/GL/mesa/src/drv/Imakefile +++ b/xc/lib/GL/mesa/src/drv/Imakefile @@ -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/r128/r128_context.c b/xc/lib/GL/mesa/src/drv/r128/r128_context.c index e11a47a47..03b871538 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.c @@ -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..46ddcff3b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_context.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_context.h @@ -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..67a548339 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.c @@ -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,43 +45,48 @@ 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 "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 ) ) { + if ( R128_IS_PRO( rmesa ) ) { strncat( buffer, " Pro", 4 ); } - if ( R128_IS_MOBILITY( r128ctx ) ) { + if ( R128_IS_MOBILITY( rmesa ) ) { strncat( buffer, " M3", 3 ); } /* Append any AGP-specific information. */ - switch ( r128ctx->r128Screen->AGPMode ) { + switch ( rmesa->r128Screen->AGPMode ) { case 1: strncat( buffer, " AGP 1x", 7 ); break; @@ -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..005949053 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_dd.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_dd.h @@ -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..74c29812f 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 $ */ +/************************************************************************** + +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; + rmesa->first_elt = rmesa->next_elt = (GLushort *) + ((GLubyte *)rmesa->elt_buf->address + R128_INDEX_PRIM_OFFSET); - 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 ); - - { - 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..e477bd7b9 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 $ */ +/************************************************************************** + +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..df382c641 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fastpath.c @@ -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..8a7cef504 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_fasttmp.h @@ -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..713edcd32 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c @@ -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..aafd0859b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h @@ -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..8fdef0d95 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.c @@ -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..2da57bb44 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_lock.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_lock.h @@ -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..e42fa4075 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.c @@ -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..5e40bd6f6 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_pipeline.h @@ -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..029ccd4ca 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.c @@ -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 != 0 || patch < 0 ) { + char msg[128]; + sprintf( msg, "r128 DRI driver expected DRI version 3.0.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..b3e6259e8 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_screen.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_screen.h @@ -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..f0d7c318f 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.c @@ -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..fefa5bd67 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_span.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_span.h @@ -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..18a6f25e3 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.c @@ -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..97b01c7fa 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_state.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_state.h @@ -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..da06d4ed5 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.c @@ -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..92d4c4e3f 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tex.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tex.h @@ -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..b1611468a 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_texobj.h @@ -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..aeddb8f95 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.c @@ -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..fac43f3ce 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tris.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tris.h @@ -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..52a63e628 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_tritmp.h @@ -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..3ebacd027 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.c @@ -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..2e33dcc1b 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_vb.h +++ b/xc/lib/GL/mesa/src/drv/r128/r128_vb.h @@ -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..31ba8afba 100644 --- a/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c +++ b/xc/lib/GL/mesa/src/drv/r128/r128_xmesa.c @@ -48,42 +48,45 @@ 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; - } + sPriv->private = (void *) r128CreateScreen( sPriv ); + if ( !sPriv->private ) { + r128DestroyScreen( sPriv ); + return GL_FALSE; + } - return GL_TRUE; + 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 +95,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..10e71732a --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/Imakefile @@ -0,0 +1,381 @@ +XCOMM $XFree86$ + +#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 +#ifdef MesaUse3DNow + 3DNOW_DEFS = -DUSE_3DNOW_ASM +#endif +#ifdef MesaUseKatmai + KATMAI_DEFS = -DUSE_KATMAI_ASM +#endif + ASM_DEFINES = -DUSE_X86_ASM -DUSE_MMX_ASM $(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 + + MMX_SRCS = ../../X86/mmx_blend.S + + MMX_OBJS = ../../X86/mmx_blend.o + +#ifdef 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 + +#ifdef 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..2ead8e213 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.c @@ -0,0 +1,234 @@ +/* $XFree86$ */ +/************************************************************************** + +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..be3fef41e --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_context.h @@ -0,0 +1,253 @@ +/* $XFree86$ */ +/************************************************************************** + +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..b86506a8d --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.c @@ -0,0 +1,217 @@ +/* $XFree86$ */ +/************************************************************************** + +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 GLubyte buffer[128]; + + switch ( name ) { + case GL_VENDOR: + return "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 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..98dd22fae --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_dd.h @@ -0,0 +1,46 @@ +/* $XFree86$ */ +/************************************************************************** + +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..a2bf4e1f5 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_eltpath.c @@ -0,0 +1,504 @@ +/* $XFree86$ */ +/************************************************************************** + +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..1fa8f60b9 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_elttmp.h @@ -0,0 +1,246 @@ +/* $XFree86$ */ +/************************************************************************** + +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..b5437e7f9 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fastpath.c @@ -0,0 +1,542 @@ +/* $XFree86$ */ +/************************************************************************** + +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..a7bc8e9ca --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_fasttmp.h @@ -0,0 +1,185 @@ +/* $XFree86$ */ +/************************************************************************** + +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..9845732c8 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.c @@ -0,0 +1,703 @@ +/* $XFree86$ */ +/************************************************************************** + +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..ceb9225da --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_ioctl.h @@ -0,0 +1,161 @@ +/* $XFree86$ */ +/************************************************************************** + +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..583fd6dfe --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.c @@ -0,0 +1,95 @@ +/* $XFree86$ */ +/************************************************************************** + +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..966f7c80f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_lock.h @@ -0,0 +1,112 @@ +/* $XFree86$ */ +/************************************************************************** + +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..1c4175575 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.c @@ -0,0 +1,168 @@ +/* $XFree86$ */ +/************************************************************************** + +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..01d5cd884 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_pipeline.h @@ -0,0 +1,54 @@ +/* $XFree86$ */ +/************************************************************************** + +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..dea4bb1ef --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.c @@ -0,0 +1,220 @@ +/* $XFree86$ */ +/************************************************************************** + +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 != 0 || patch < 0 ) { + char msg[128]; + sprintf( msg, "Radeon DRI driver expected DRI version 3.0.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..4aeb5d73f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_screen.h @@ -0,0 +1,87 @@ +/* $XFree86$ */ +/************************************************************************** + +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..75f7a1396 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.c @@ -0,0 +1,345 @@ +/* $XFree86$ */ +/************************************************************************** + +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 pitch = radeonScreen->depthPitch * radeonScreen->cpp; \ + GLuint height = dPriv->h; \ + char *buf = (char *)(sPriv->pFB + \ + radeonScreen->depthOffset + \ + (dPriv->x * radeonScreen->cpp) + \ + (dPriv->y * pitch)); \ + (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 __inline 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, _y )) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + radeon_mba_z16( rmesa, _x, _y )); + +#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 tmp = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )); \ + tmp &= 0xff000000; \ + tmp |= ((d) & 0x00ffffff); \ + *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )) = tmp; \ +} while (0) + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )) & 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 tmp = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )); \ + tmp &= 0x00ffffff; \ + tmp |= (((d) & 0xff) << 24); \ + *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )) = tmp; \ +} while (0) + +#define READ_STENCIL( d, _x, _y ) \ +do { \ + GLuint tmp = *(GLuint *)(buf + radeon_mba_z32( rmesa, _x, _y )); \ + 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..e9cb056b8 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_span.h @@ -0,0 +1,45 @@ +/* $XFree86$ */ +/************************************************************************** + +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..7aa4bc6f6 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.c @@ -0,0 +1,1338 @@ +/* $XFree86$ */ +/************************************************************************** + +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..1be2977af --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_state.h @@ -0,0 +1,55 @@ +/* $XFree86$ */ +/************************************************************************** + +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..5cc4aabef --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.c @@ -0,0 +1,2248 @@ +/* $XFree86$ */ +/************************************************************************** + +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 ); + + LOCK_HARDWARE( rmesa ); + radeonUploadSubImage( rmesa, t, level, + xoffset, yoffset, width, height ); + UNLOCK_HARDWARE( rmesa ); + + /* 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..6bf967761 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tex.h @@ -0,0 +1,96 @@ +/* $XFree86$ */ +/************************************************************************** + +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..b63d5c6a7 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_texobj.h @@ -0,0 +1,87 @@ +/* $XFree86$ */ +/************************************************************************** + +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..71ed6910b --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.c @@ -0,0 +1,209 @@ +/* $XFree86$ */ +/************************************************************************** + +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..5694d5cf1 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tris.h @@ -0,0 +1,316 @@ +/* $XFree86$ */ +/************************************************************************** + +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..ed5006ea2 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_tritmp.h @@ -0,0 +1,336 @@ +/* $XFree86$ */ +/************************************************************************** + +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..bf2255f74 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.c @@ -0,0 +1,483 @@ +/* $XFree86$ */ +/************************************************************************** + +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) + +#if 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..42329c002 --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_vb.h @@ -0,0 +1,136 @@ +/* $XFree86$ */ +/************************************************************************** + +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..e4ff4301f --- /dev/null +++ b/xc/lib/GL/mesa/src/drv/radeon/radeon_xmesa.c @@ -0,0 +1,280 @@ +/* $XFree86$ */ +/************************************************************************** + +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 ); + 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..e166aa96f 100644 --- a/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c +++ b/xc/lib/GL/mesa/src/drv/sis/sis_alloc.c @@ -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/Xft/xftlist.c b/xc/lib/Xft/xftlist.c index 1ee72bc05..478dce07f 100644 --- a/xc/lib/Xft/xftlist.c +++ b/xc/lib/Xft/xftlist.c @@ -1,5 +1,5 @@ /* - * $XFree86: xc/lib/Xft/xftlist.c,v 1.1 2000/11/30 06:59:45 keithp Exp $ + * $XFree86: xc/lib/Xft/xftlist.c,v 1.2 2000/12/07 23:57:28 keithp Exp $ * * Copyright © 2000 Keith Packard, member of The XFree86 Project, Inc. * @@ -70,35 +70,38 @@ XftObjectSetDestroy (XftObjectSet *os) free (os); } -XftObjectSet * -_XftObjectSetVapBuild (const char *first, va_list *vap) -{ - XftObjectSet *os; - const char *object; - va_list va = *vap; - - os = XftObjectSetCreate (); - if (!os) - goto bail0; - object = first; - while (object) - { - if (!XftObjectSetAdd (os, object)) - goto bail1; - object = va_arg (va, const char *); - } - *vap = va; - return os; -bail1: - XftObjectSetDestroy (os); -bail0: - return 0; +#define _XftObjectSetVapBuild(__ret__, __first__, __va__) \ +{ \ + XftObjectSet *__os__; \ + const char *__ob__; \ + \ + __ret__ = 0; \ + __os__ = XftObjectSetCreate (); \ + if (!__os__) \ + goto _XftObjectSetVapBuild_bail0; \ + __ob__ = __first__; \ + while (__ob__) \ + { \ + if (!XftObjectSetAdd (__os__, __ob__)) \ + goto _XftObjectSetVapBuild_bail1; \ + __ob__ = va_arg (__va__, const char *); \ + } \ + __ret__ = __os__; \ + \ +_XftObjectSetVapBuild_bail1: \ + if (!__ret__ && __os__) \ + XftObjectSetDestroy (__os__); \ +_XftObjectSetVapBuild_bail0: \ + ; \ } XftObjectSet * XftObjectSetVaBuild (const char *first, va_list va) { - return _XftObjectSetVapBuild (first, &va); + XftObjectSet *ret; + + _XftObjectSetVapBuild (ret, first, va); + return ret; } XftObjectSet * @@ -108,7 +111,7 @@ XftObjectSetBuild (const char *first, ...) XftObjectSet *os; va_start (va, first); - os = _XftObjectSetVapBuild (first, &va); + _XftObjectSetVapBuild (os, first, va); va_end (va); return os; } @@ -310,10 +313,14 @@ XftListFonts (Display *dpy, const char *first; va_start (va, screen); - pattern = _XftPatternVapBuild (0, &va); + + _XftPatternVapBuild (pattern, 0, va); + first = va_arg (va, const char *); - os = _XftObjectSetVapBuild (first, &va); + _XftObjectSetVapBuild (os, first, va); + va_end (va); + fs = XftListFontsPatternObjects (dpy, screen, pattern, os); XftPatternDestroy (pattern); XftObjectSetDestroy (os); diff --git a/xc/programs/Xserver/Imakefile b/xc/programs/Xserver/Imakefile index b818c9b65..ecf3dbdb1 100644 --- a/xc/programs/Xserver/Imakefile +++ b/xc/programs/Xserver/Imakefile @@ -662,7 +662,8 @@ XF86SERVERSYSLIBS = $(FONTLIBS) $(SYSLIBS) $(LIBDL) $(LIBREGEX) #endif XF86SERVEROBJS = $(XF86DRVOBJS) $(XF86IDRVOBJS) XF86SERVERLIBS = $(XF86DRVLIBS) $(XF86IDRVLIBS) $(XF86LIBS) $(XF86LOADERLIB) \ - $(XF86COMLIB) $(XF86MAINLIBS) $(XF86SCANLIB) $(XF86OSLIB) + $(XF86COMLIB) $(XF86MAINLIBS) $(XF86SCANLIB) $(XF86OSLIB) \ + $(XF86DDCLIB) #if HasParallelMake MakeMutex($(XF86SERVERSUBDIRS) $(XF86SERVERLIBS) $(XF86SERVERSYSLIBS)) #endif diff --git a/xc/programs/Xserver/hw/darwin/darwinCursor.c b/xc/programs/Xserver/hw/darwin/darwinCursor.c index b6ff35f5b..95b1dcd3b 100644 --- a/xc/programs/Xserver/hw/darwin/darwinCursor.c +++ b/xc/programs/Xserver/hw/darwin/darwinCursor.c @@ -32,11 +32,12 @@ * 1.0 by Torrey T. Lyons, October 30, 2000 * **************************************************************/ -/* $XFree86: xc/programs/Xserver/hw/darwin/darwinCursor.c,v 1.1 2000/11/15 01:36:13 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/darwin/darwinCursor.c,v 1.2 2000/11/28 17:25:10 dawes Exp $ */ #include "scrnintstr.h" #include "cursorstr.h" #include "micmap.h" +#define NO_CFPLUGIN #include <IOKit/graphics/IOGraphicsLib.h> #include <IOKit/hidsystem/IOHIDLib.h> #include "darwin.h" diff --git a/xc/programs/Xserver/hw/darwin/utils/README.txt b/xc/programs/Xserver/hw/darwin/utils/README.txt index 6baff652d..94d61b1f0 100644 --- a/xc/programs/Xserver/hw/darwin/utils/README.txt +++ b/xc/programs/Xserver/hw/darwin/utils/README.txt @@ -1,11 +1,11 @@ dumpkeymap - Diagnostic dump and detailed description of .keymapping files -Version 3 +Version 4 Copyright (C)1999,2000 by Eric Sunshine <sunshine@sunshineco.com> -Eric Sunshine, November 28, 2000 +Eric Sunshine, 1 December 2000 OVERVIEW - +======== This package contains the diagnostic utility dumpkeymap, as well as highly detailed documentation describing the internal layout of the Apple/NeXT .keymapping file. @@ -39,8 +39,9 @@ with the Unix `man' command: % man dumpkeymap -COMPILATION +COMPILATION +=========== MacOS/X, Darwin cc -Wall -o dumpkeymap dumpkeymap.c -framework IOKit @@ -65,8 +66,9 @@ For example, to compile for Linux: gcc -Wall -DDUMPKEYMAP_FILE_ONLY -o dumpkeymap dumpkeymap.c -INSTALLATION +INSTALLATION +============ Install the dumpkeymap executable image in a location mentioned in the PATH environment variable. Typicall locations for executable files are: @@ -93,8 +95,9 @@ Typical locations for manual pages on OpenStep and NextStep are: /LocalLibrary/Documentation/ManPages/man1 /LocalDeveloper/Documentation/ManPages/man1 -CONCLUSION +CONCLUSION +========== This program and its accompanying documentation were written by Eric Sunshine and are copyright (C)1999,2000 by Eric Sunshine <sunshine@sunshineco.com>. @@ -105,4 +108,4 @@ of the NeXT .keymapping file. -$XFree86: xc/programs/Xserver/hw/darwin/utils/README.txt,v 1.1 2000/12/01 19:47:39 dawes Exp $ +$XFree86: xc/programs/Xserver/hw/darwin/utils/README.txt,v 1.2 2000/12/05 21:18:34 dawes Exp $ diff --git a/xc/programs/Xserver/hw/darwin/utils/dumpkeymap.man b/xc/programs/Xserver/hw/darwin/utils/dumpkeymap.man index 3f0d9d6eb..2ad6d54d2 100644 --- a/xc/programs/Xserver/hw/darwin/utils/dumpkeymap.man +++ b/xc/programs/Xserver/hw/darwin/utils/dumpkeymap.man @@ -1,113 +1,163 @@ -.\"============================================================================ -.\" -.\" Manual page for `dumpkeymap'. -.\" -.\" Copyright (C) 1999,2000 by Eric Sunshine <sunshine@sunshineco.com> -.\" All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions are met: -.\" -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. The name of the author may not be used to endorse or promote products -.\" derived from this software without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR -.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES -.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN -.\" NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED -.\" TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -.\" PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF -.\" LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING -.\" NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS -.\" SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -.\" -.\"============================================================================ -.\" -.\" $XFree86: xc/programs/Xserver/hw/darwin/utils/dumpkeymap.man,v 1.1 2000/12/01 19:47:39 dawes Exp $ -.\" -.\"---------------------------------------------------------------------------- -.\" Annotation Macros -- Facilitate creation of annotated, non-filled blocks -.\" of text. An annotated block is initiated with the `AS' macro. Each -.\" annotated, non-filled line within the block must be introduced with -.\" the `AN' macro which takes two arguments. The first argument is the -.\" detail text to be annotated, and the second is the annotation itself. -.\" The block should be terminated with the `AE' macro which actually -.\" emits the fully annotated block. All anotations within the block are -.\" aligned at the same horizontal position. This position is guaranteed -.\" to be just to the right of the widest detail line. Finally, the `AZ' -.\" macro, which takes a single argument, can be used to to insert a -.\" non-annotated line into the block which does not play a part in the -.\" calculation of the horizontal annotation alignment. -.\" Implementation Note -.\" These macros utilize a diversion (named `AD'). Since the prevailing -.\" indentation is stored along with the diverted text, we must muck with -.\" the indentation level in order to prevent the indentation from being -.\" applied to the text a second time when `AD' is finally emitted. -.\"---------------------------------------------------------------------------- +.ig +//============================================================================= +// +// Manual page for `dumpkeymap'. +// +// Copyright (C) 1999,2000 by Eric Sunshine <sunshine@sunshineco.com> +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// 1. Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// 2. Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// 3. The name of the author may not be used to endorse or promote products +// derived from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED +// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO +// EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +//============================================================================= +// +// $XFree86: xc/programs/Xserver/hw/darwin/utils/dumpkeymap.man,v 1.2 2000/12/05 21:18:34 dawes Exp $ +// +.. +.ig +//----------------------------------------------------------------------------- +// Local identification information. +//----------------------------------------------------------------------------- +.. +.nr VE 4 \" Version number +.TH DUMPKEYMAP 1 "v\n(VE \-\- 1 December 2000" "Version \n(VE" +.de UP +1 December 2000 +.. +.ig +//----------------------------------------------------------------------------- +// Annotation Macros +// ----------------- +// Facilitate creation of annotated, non-filled blocks of text. An +// annotated block is initiated with the `AS' macro. Each annotated, +// non-filled line within the block must be introduced with the `AN' macro +// which takes three arguments. The first argument is the detail text to +// be annotated. The second is a string of spaces used to align the +// annotations by certain (broken) roff interpreters which fail to +// implement the proper set of roff commands (such as diversions, +// indentation, and tab stops). It is assumed that the spaces will be +// used with fixed-point font. The third argument is the annotation +// itself. The block should be terminated with the `AE' macro. For all +// roff interpreters which properly implement diversions, indentation, and +// tab stops, all anotations within the block are automatically aligned at +// the same horizontal position. This position is guaranteed to be just +// to the right of the widest `AN' detail line. For broken roff +// interpreters, such as `rman', the string of spaces from the second +// argument are used to align the annotations. Finally, the `AZ' macro, +// which takes a single argument, can be used to to insert a non-annotated +// line into the block which does not play a part in the calculation of +// the horizontal annotation alignment. +// +// Implementation Notes +// -------------------- +// *1* These macros utilize a diversion (named `AD'). Since the prevailing +// indentation is stored along with the diverted text, we must muck with +// the indentation level in order to prevent the indentation from being +// applied to the text a second time when `AD' is finally emitted. +// +// *2* Unfortunately, `.if' strips leading whitespace from following text, so +// `AN' uses \& to preserve the whitespace. +// +// *3* This manual page has been tested for proper formatting with troff, +// groff, nroff and rman (the `man' to `HTML' converter). Unfortunately, +// rman fails to implement many useful features such as diversions, +// indentation, and tab stops, and is also hideously buggy. Furthermore +// it identifies itself as nroff and fails to provide any further +// identification, so there is no way to create macros which specifically +// work around its limitations. Following is a list of several bugs in +// rman which the implementation of these macros must avoid: +// o Fails with multi-line conditionals within macros. +// o Fails on macro definition within multi-line conditionals. +// o Fails when macro arguments are not delimited by exactly 1 space. +// o String definition `.ds' ignores the value; uses empty "" instead. +// As a consequence of these problems, the following macros are written +// using a series of ugly single-line `.if' conditionals rather than the +// more natural multi-line `.if' and `.ie' conditionals. Also, rman fails +// to understand the common idiom of `.\"' to introduce a comment, which +// is why all comments in this file are wrapped in ignore `.ig' blocks. +//----------------------------------------------------------------------------- +.. .de AS -.nr AW 0 -.nr AI \\n(.i -.in -\\n(AI +.if t .nr AW 0 +.if t .nr AI \\n(.i +.if t .in -\\n(AI .nf .. .de AN -.if \w'\\$1'>\\n(AW .nr AW \w'\\$1' -.da AD -\\$1\\t\\$2 -.da +.if t .if \w'\\$1'>\\n(AW .nr AW \w'\\$1' +.if t .da AD +.if t \\&\\$1\\t\\$3 +.if t .da +.if n \\&\\$1 \\$2\\$3 .. .de AZ -.da AD +.if t .da AD \\$1 -.da -\\ +.if t .da .. .de AE -.in +\\n(AIu -.if \\n(AW .ta \\n(AWu+\w'\\(em'u -.AD -.DT -.rm AD -.rm AW +.if t .in +\\n(AIu +.if t .if \\n(AW .ta \\n(AWu+\w'\\(em'u +.if t .AD +.if t .DT +.if t .rm AD +.if t .rm AW .fi .. -.\"---------------------------------------------------------------------------- -.\" Bulleted list macros -- `BG' begins a bulleted list; `BU' delimits -.\" bulleted entries; `BE' ends a bulleted list. -.\"---------------------------------------------------------------------------- +.ig +//----------------------------------------------------------------------------- +// Bulleted list macros -- `BG' begins a bulleted list; `BU' delimits +// bulleted entries; `BE' ends a bulleted list. +//----------------------------------------------------------------------------- +.. .de BG .PP .RS .. .de BU .HP -.ie t \\(bu\\ \\c -.el *\\ \\c +\\(bu\\ \\c .. .de BE .RE .PP .. -.\"---------------------------------------------------------------------------- -.\" Indented paragraph with stylized hanging tag macro. `TG' takes a single -.\" argument and treats it as the hanging tag of the indented paragraph. -.\" The tag is italicized in troff but not in nroff. -.\"---------------------------------------------------------------------------- +.ig +//----------------------------------------------------------------------------- +// Indented paragraph with stylized hanging tag macro. `TG' takes a single +// argument and treats it as the hanging tag of the indented paragraph. +// The tag is italicized in troff but not in nroff. +//----------------------------------------------------------------------------- +.. .de TG .TP .ie t .I "\\$1" .el \\$1 .. -.\"---------------------------------------------------------------------------- -.\" Manual page for `dumpkeymap'. -.\"---------------------------------------------------------------------------- -.TH DUMPKEYMAP 1 "November 2000" "Version 3" +.ig +//----------------------------------------------------------------------------- +// Manual page for `dumpkeymap'. +//----------------------------------------------------------------------------- +.. .SH NAME dumpkeymap \- Dianostic dump of a .keymapping file .SH SYNOPSIS @@ -200,16 +250,16 @@ variable number of device-specific key mappings. .RS .AS .AZ "struct KeyMappingFile {" -.AN " char magic_number[4];" "// `KYM1'" -.AN " DeviceMapping maps[...];" "// Variable number of maps" +.AN " char magic_number[4];" " " "// `KYM1'" +.AN " DeviceMapping maps[...];" "" "// Variable number of maps" .AZ }; .AE .PP .AS .AZ "struct DeviceMapping {" -.AN " dword interface;" "// Interface type" -.AN " dword handler_id;" "// Interface subtype" -.AN " dword map_size;" "// Byte count of `map' (below)" +.AN " dword interface;" " " "// Interface type" +.AN " dword handler_id;" "" "// Interface subtype" +.AN " dword map_size;" " " "// Byte count of `map' (below)" .AN " KeyMapping map;" .AZ }; .AE @@ -256,14 +306,14 @@ structure. .RS .AS .AZ "struct KeyMapping {" -.AN " word number_size;" "// 0=1 byte, non-zero=2 bytes" -.AN " number num_modifier_groups;" "// Modifier groups" +.AN " word number_size;" " " "// 0=1 byte, non-zero=2 bytes" +.AN " number num_modifier_groups;" "" "// Modifier groups" .AZ " ModifierGroup modifier_groups[...];" -.AN " number num_scan_codes;" "// Scan groups" +.AN " number num_scan_codes;" " " "// Scan groups" .AN " ScanGroup scan_table[...];" -.AN " number num_sequence_lists;" "// Sequence lists" +.AN " number num_sequence_lists;" " " "// Sequence lists" .AN " Sequence sequence_lists[...];" -.AN " number num_special_keys;" "// Special keys" +.AN " number num_special_keys;" " " "// Special keys" .AN " SpecialKey special_key[...];" .AZ }; .AE @@ -285,21 +335,21 @@ etc. .RS .AS .AZ "enum Modifier {" -.AN " ALPHALOCK = 0," -.AN " SHIFT," -.AN " CONTROL," -.AN " ALTERNATE," -.AN " COMMAND," -.AN " KEYPAD," -.AN " HELP" +.AZ " ALPHALOCK = 0," +.AZ " SHIFT," +.AZ " CONTROL," +.AZ " ALTERNATE," +.AZ " COMMAND," +.AZ " KEYPAD," +.AZ " HELP" .AZ }; .AE .PP .AS .AZ "struct ModifierGroup {" -.AN " number modifier;" "// A Modifier constant" +.AN " number modifier;" " " "// A Modifier constant" .AN " number num_scan_codes;" -.AN " number scan_codes[...];" "// Variable number of scan codes" +.AN " number scan_codes[...];" "" "// Variable number of scan codes" .AZ }; .AE .RE @@ -320,11 +370,11 @@ code 0, the second represents scan code 1, etc. .RS .AS .AZ "enum ModifierMask {" -.AN " ALPHALOCK_MASK" "= 1 << 0," -.AN " SHIFT_MASK" "= 1 << 1," -.AN " CONTROL_MASK" "= 1 << 2," -.AN " ALTERNATE_MASK" "= 1 << 3," -.AN " CARRIAGE_RETURN_MASK" "= 1 << 4" +.AN " ALPHALOCK_MASK" " " "= 1 << 0," +.AN " SHIFT_MASK" " " "= 1 << 1," +.AN " CONTROL_MASK" " " "= 1 << 2," +.AN " ALTERNATE_MASK" " " "= 1 << 3," +.AN " CARRIAGE_RETURN_MASK" "" "= 1 << 4" .AZ }; .AZ "#define NOT_BOUND 0xff" .AE @@ -414,28 +464,28 @@ KeyMapping::sequence_lists[]. .RS .AS .AZ "enum CharacterSet {" -.AN " ASCII" "= 0x00," -.AN " SYMBOL" "= 0x01," +.AN " ASCII" " " "= 0x00," +.AN " SYMBOL" " " "= 0x01," .AN " ..." -.AN " FUNCTION_KEY" "= 0xfe," -.AN " KEY_SEQUENCE" "= 0xff" +.AN " FUNCTION_KEY" "" "= 0xfe," +.AN " KEY_SEQUENCE" "" "= 0xff" .AZ }; .AE .PP .AS .AZ "struct Character {" -.AN " number set;" "// CharacterSet of generated character" -.AN " number char_code;" "// Actual character generated" +.AN " number set;" " " "// CharacterSet of generated character" +.AN " number char_code;" "" "// Actual character generated" .AZ }; .AE .PP .AS .AZ "enum FunctionKey {" -.AN " F1 = 0x20, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12," -.AN " INSERT, DELETE, HOME, END, PAGE_UP, PAGE_DOWN, PRINT_SCREEN," -.AN " SCROLL_LOCK, PAUSE, SYS_REQUEST, BREAK, RESET, STOP, MENU," -.AN " USER, SYSTEM, PRINT, CLEAR_LINE, CLEAR_DISPLAY, INSERT_LINE," -.AN " DELETE_LINE, INSERT_CHAR, DELETE_CHAR, PREV, NEXT, SELECT" +.AZ " F1 = 0x20, F2, F3, F4, F5, F6, F7, F8, F9, F10, F11, F12," +.AZ " INSERT, DELETE, HOME, END, PAGE_UP, PAGE_DOWN, PRINT_SCREEN," +.AZ " SCROLL_LOCK, PAUSE, SYS_REQUEST, BREAK, RESET, STOP, MENU," +.AZ " USER, SYSTEM, PRINT, CLEAR_LINE, CLEAR_DISPLAY, INSERT_LINE," +.AZ " DELETE_LINE, INSERT_CHAR, DELETE_CHAR, PREV, NEXT, SELECT" .AZ }; .AE .RE @@ -483,22 +533,22 @@ by the WindowServer. In general, events are not generated for special keys. .RS .AS .AZ "enum SpecialKeyType {" -.AN " VOLUME_UP = 0," -.AN " VOLUME_DOWN," -.AN " BRIGHTNESS_UP," -.AN " BRIGHTNESS_DOWN," -.AN " ALPHA_LOCK," -.AN " HELP," -.AN " POWER," -.AN " SECONDARY_ARROW_UP," -.AN " SECONDARY_ARROW_DOWN" +.AZ " VOLUME_UP = 0," +.AZ " VOLUME_DOWN," +.AZ " BRIGHTNESS_UP," +.AZ " BRIGHTNESS_DOWN," +.AZ " ALPHA_LOCK," +.AZ " HELP," +.AZ " POWER," +.AZ " SECONDARY_ARROW_UP," +.AZ " SECONDARY_ARROW_DOWN" .AZ }; .AE .PP .AS .AZ "struct SpecialKey {" -.AN " number type;" "// A SpecialKeyType constant" -.AN " number scan_code;" "// Actual scan code" +.AN " number type;" " " "// A SpecialKeyType constant" +.AN " number scan_code;" "" "// Actual scan code" .AZ }; .AE .RE @@ -949,3 +999,6 @@ effort to reverse engineer the format of the .SM NeXT .I .keymapping file. +.if n .PP +.if n Version \n(VE \-\- +.if n .UP diff --git a/xc/programs/Xserver/hw/kdrive/trident/trident.c b/xc/programs/Xserver/hw/kdrive/trident/trident.c index cfd892e70..88f797b7f 100644 --- a/xc/programs/Xserver/hw/kdrive/trident/trident.c +++ b/xc/programs/Xserver/hw/kdrive/trident/trident.c @@ -1,6 +1,4 @@ /* - * $Id: trident.c,v 1.1 2000/01/06 12:55:54 faith Exp $ - * * Copyright © 1999 Keith Packard * * Permission to use, copy, modify, distribute, and sell this software and its @@ -21,7 +19,7 @@ * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. */ -/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.2 1999/12/30 03:03:15 robin Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/kdrive/trident/trident.c,v 1.15 2000/11/29 08:42:25 keithp Exp $ */ #include "trident.h" #define extern @@ -30,27 +28,66 @@ #undef TRI_DEBUG +int trident_clk = 0; +int trident_mclk = 0; + +#define CLOCK 14318 /* KHz */ +#define CLK_N(a,b) (a & 0xff) +#define CLK_M(a,b) ((b) & 0x3f) +#define CLK_K(a,b) (((b) >> 6) & 3) +#define CLK_FREQ(a,b) (((CLK_N(a,b) + 8) * CLOCK) / ((CLK_M(a,b)+2) << CLK_K(a,b))) + Bool tridentCardInit (KdCardInfo *card) { - int k; - char *pixels; + int k; + char *pixels; TridentCardInfo *tridentc; + CARD8 r39; tridentc = (TridentCardInfo *) xalloc (sizeof (TridentCardInfo)); if (!tridentc) return FALSE; + iopl (3); + tridentc->cop_base = (CARD8 *) KdMapDevice (TRIDENT_COP_BASE(card), + TRIDENT_COP_SIZE(card)); + + if (tridentc->cop_base) + { + KdSetMappedMode (TRIDENT_COP_BASE(card), + TRIDENT_COP_SIZE(card), + KD_MAPPED_MODE_REGISTERS); + } + tridentc->cop = (Cop *) (tridentc->cop_base + TRIDENT_COP_OFF(card)); + tridentc->mmio = FALSE; + r39 = tridentReadIndex (tridentc, 0x3d4, 0x39); + if (r39 & 1) + { + tridentc->mmio = TRUE; + r39 = tridentReadIndex (tridentc, 0x3d4, 0x39); + if ((r39 & 1) == 0) + { + ErrorF ("Trident: inconsisent IO mapping values\n"); + return FALSE; + } + } + +#ifdef VESA + if (!vesaInitialize (card, &tridentc->vesa)) +#else if (!fbdevInitialize (card, &tridentc->fb)) +#endif { xfree (tridentc); return FALSE; } - iopl (3); - tridentc->cop_base = (CARD8 *) KdMapDevice (TRIDENT_COP_BASE, - TRIDENT_COP_SIZE); - tridentc->cop = (Cop *) (tridentc->cop_base + TRIDENT_COP_OFF); +#ifdef USE_PCI + tridentc->window = (CARD32 *) (tridentc->cop_base + 0x10000); +#else + tridentc->window = 0; +#endif card->driver = tridentc; return TRUE; @@ -67,21 +104,45 @@ tridentScreenInit (KdScreenInfo *screen) if (!tridents) return FALSE; memset (tridents, '\0', sizeof (TridentScreenInfo)); - if (!fbdevScreenInit (screen)) +#ifdef VESA + if (!vesaScreenInitialize (screen, &tridents->vesa)) +#else + if (!fbdevScreenInitialize (screen, &tridents->fbdev)) +#endif { xfree (tridents); return FALSE; } if (!tridentc->cop) screen->dumb = TRUE; - screen_size = screen->byteStride * screen->height; +#ifdef VESA + if (tridents->vesa.mapping != VESA_LINEAR) + screen->dumb = TRUE; + tridents->screen = tridents->vesa.fb; + memory = tridents->vesa.fb_size; +#else + tridents->screen = tridentc->fb.fb; memory = (2048 + 512) * 1024; - if (memory >= screen_size + 2048) +#endif + screen_size = screen->fb[0].byteStride * screen->height; + if (tridents->screen && memory >= screen_size + 2048) { - tridents->cursor_base = tridentc->fb.fb + memory - 2048; + memory -= 2048; + tridents->cursor_base = tridents->screen + memory - 2048; } else tridents->cursor_base = 0; + memory -= screen_size; + if (memory > screen->fb[0].byteStride) + { + tridents->off_screen = tridents->screen + screen_size; + tridents->off_screen_size = memory; + } + else + { + tridents->off_screen = 0; + tridents->off_screen_size = 0; + } screen->driver = tridents; return TRUE; } @@ -89,7 +150,11 @@ tridentScreenInit (KdScreenInfo *screen) Bool tridentInitScreen (ScreenPtr pScreen) { +#ifdef VESA + return vesaInitScreen (pScreen); +#else return fbdevInitScreen (pScreen); +#endif } CARD8 @@ -97,25 +162,71 @@ tridentReadIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index) { CARD8 value; - outb (index, port); - value = inb (port+1); + if (tridentc->mmio) + { + tridentc->cop_base[port] = index; + value = tridentc->cop_base[port+1]; + } + else + { + outb (index, port); + value = inb (port+1); + } return value; } void tridentWriteIndex (TridentCardInfo *tridentc, CARD16 port, CARD8 index, CARD8 value) { - outb (index, port); - outb (value, port+1); + if (tridentc->mmio) + { + tridentc->cop_base[port] = index; + tridentc->cop_base[port+1] = value; + } + else + { + outb (index, port); + outb (value, port+1); + } } +CARD8 +tridentReadReg (TridentCardInfo *tridentc, CARD16 port) +{ + CARD8 value; + + if (tridentc->mmio) + { + value = tridentc->cop_base[port]; + } + else + { + value = inb (port); + } + return value; +} + +void +tridentWriteReg (TridentCardInfo *tridentc, CARD16 port, CARD8 value) +{ + if (tridentc->mmio) + { + tridentc->cop_base[port] = value; + } + else + { + outb (value, port); + } +} + + void tridentPause () { struct timeval tv; tv.tv_sec = 0; - tv.tv_usec = 200 * 1000; + tv.tv_usec = 50 * 1000; select (1, 0, 0, 0, &tv); } @@ -124,12 +235,27 @@ tridentPreserve (KdCardInfo *card) { TridentCardInfo *tridentc = card->driver; +#ifdef VESA + vesaPreserve(card); +#else fbdevPreserve (card); +#endif + tridentPause (); tridentc->save.reg_3c4_0e = tridentReadIndex (tridentc, 0x3c4, 0x0e); tridentc->save.reg_3d4_36 = tridentReadIndex (tridentc, 0x3d4, 0x36); tridentc->save.reg_3d4_39 = tridentReadIndex (tridentc, 0x3d4, 0x39); tridentc->save.reg_3d4_62 = tridentReadIndex (tridentc, 0x3d4, 0x62); tridentc->save.reg_3ce_21 = tridentReadIndex (tridentc, 0x3ce, 0x21); + tridentc->save.reg_3c2 = tridentReadReg (tridentc, 0x3cc); + tridentc->save.reg_3c4_16 = tridentReadIndex (tridentc, 0x3c4, 0x16); + tridentc->save.reg_3c4_17 = tridentReadIndex (tridentc, 0x3c4, 0x17); + tridentc->save.reg_3c4_18 = tridentReadIndex (tridentc, 0x3c4, 0x18); + tridentc->save.reg_3c4_19 = tridentReadIndex (tridentc, 0x3c4, 0x19); + ErrorF ("clk low 0x%x high 0x%x freq %d\n", + tridentc->save.reg_3c4_18, + tridentc->save.reg_3c4_19, + CLK_FREQ(tridentc->save.reg_3c4_18, + tridentc->save.reg_3c4_19)); #ifdef TRI_DEBUG fprintf (stderr, "3c4 0e: %02x\n", tridentc->save.reg_3c4_0e); fprintf (stderr, "3d4 36: %02x\n", tridentc->save.reg_3d4_36); @@ -142,6 +268,98 @@ tridentPreserve (KdCardInfo *card) } void +tridentSetCLK(int clock, CARD8 *a, CARD8 *b) +{ + int powerup[4] = { 1,2,4,8 }; + int clock_diff = 750; + int freq, ffreq; + int m, n, k; + int p, q, r, s; + int startn, endn; + int endm, endk; + + p = q = r = s = 0; + + startn = 64; + endn = 255; + endm = 63; + endk = 3; + + freq = clock; + + for (k=0;k<=endk;k++) + for (n=startn;n<=endn;n++) + for (m=1;m<=endm;m++) + { + ffreq = ( ( ((n + 8) * CLOCK) / ((m + 2) * powerup[k]) )); + if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff)) + { + clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq; + p = n; q = m; r = k; s = ffreq; + } + } + + ErrorF ("ffreq %d clock %d\n", s, clock); + if (s == 0) + { + FatalError("Unable to set programmable clock.\n" + "Frequency %d is not a valid clock.\n" + "Please modify XF86Config for a new clock.\n", + freq); + } + + /* N is all 8bits */ + *a = p; + /* M is first 6bits, with K last 2bits */ + *b = (q & 0x3F) | (r << 6); +} + +void +tridentSetMCLK(int clock, CARD8 *a, CARD8 *b) +{ + int powerup[4] = { 1,2,4,8 }; + int clock_diff = 750; + int freq, ffreq; + int m,n,k; + int p, q, r, s; + int startn, endn; + int endm, endk; + + p = q = r = s = 0; + + startn = 64; + endn = 255; + endm = 63; + endk = 3; + + freq = clock; + + for (k=0;k<=endk;k++) + for (n=startn;n<=endn;n++) + for (m=1;m<=endm;m++) { + ffreq = ((((n+8)*CLOCK)/((m+2)*powerup[k]))); + if ((ffreq > freq - clock_diff) && (ffreq < freq + clock_diff)) + { + clock_diff = (freq > ffreq) ? freq - ffreq : ffreq - freq; + p = n; q = m; r = k; s = ffreq; + } + } + + if (s == 0) + { + FatalError("Unable to set memory clock.\n" + "Frequency %d is not a valid clock.\n" + "Please modify XF86Config for a new clock.\n", + freq); + } + + /* N is all 8bits */ + *a = p; + /* M is first 6bits, with K last 2bits */ + *b = (q & 0x3F) | (r << 6); +} + +void tridentSetMMIO (TridentCardInfo *tridentc) { int tries; @@ -167,10 +385,64 @@ tridentSetMMIO (TridentCardInfo *tridentc) fprintf (stderr, "Trident GE not enabled 0x%x\n", v); continue; } + /* enable screen */ + tridentWriteIndex (tridentc, 0x3ce, 0x21, 0x80); +#ifdef USE_PCI + /* enable burst r/w, enable memory mapped ports */ + tridentWriteIndex (tridentc, 0x3d4, 0x39, 7); + tridentc->mmio = TRUE; + /* reset GE, enable GE, set GE to pci 1 */ + tridentWriteIndex (tridentc, 0x3d4, 0x36, 0x90); +#else /* enable burst r/w, disable memory mapped ports */ tridentWriteIndex (tridentc, 0x3d4, 0x39, 0x6); /* reset GE, enable GE, set GE to 0xbff00 */ tridentWriteIndex (tridentc, 0x3d4, 0x36, 0x92); +#endif + /* set clock */ + if (trident_clk) + { + CARD8 a, b; + + a = tridentReadIndex (tridentc, 0x3c4, 0x18); + b = tridentReadIndex (tridentc, 0x3c4, 0x19); + ErrorF ("old clock 0x%x 0x%x %d\n", + a, b, CLK_FREQ(a,b)); + tridentSetCLK (trident_clk, &a, &b); + ErrorF ("clk %d-> 0x%x 0x%x %d\n", trident_clk, a, b, + CLK_FREQ(a,b)); +#if 1 + tridentWriteIndex (tridentc, 0x3c4, 0x18, a); + tridentWriteIndex (tridentc, 0x3c4, 0x19, b); +#endif + } + if (trident_mclk) + { + CARD8 a, b; + + tridentSetMCLK (trident_mclk, &a, &b); + ErrorF ("mclk %d -> 0x%x 0x%x\n", trident_mclk, a, b); +#if 0 + tridentWriteIndex (tridentc, 0x3c4, 0x16, a); + tridentWriteIndex (tridentc, 0x3c4, 0x17, b); +#endif + } + if (trident_clk || trident_mclk) + { + CARD8 mode; + + mode = tridentReadReg (tridentc, 0x3cc); + ErrorF ("old mode 0x%x\n", mode); + mode = (mode & 0xf3) | 0x08; + ErrorF ("new mode 0x%x\n", mode); +#if 1 + tridentWriteReg (tridentc, 0x3c2, mode); +#endif + } +#ifdef TRI_DEBUG + fprintf (stderr, "0x36: 0x%02x\n", + tridentReadIndex (tridentc, 0x3d4, 0x36)); +#endif if (tridentc->cop->status != 0xffffffff) break; } @@ -187,28 +459,50 @@ tridentResetMMIO (TridentCardInfo *tridentc) #ifdef TRI_DEBUG fprintf (stderr, "Reset MMIO\n"); #endif + tridentPause (); +#if 0 + tridentWriteIndex (tridentc, 0x3c4, 0x16, tridentc->save.reg_3c4_16); + tridentWriteIndex (tridentc, 0x3c4, 0x17, tridentc->save.reg_3c4_17); +#endif + tridentWriteIndex (tridentc, 0x3c4, 0x18, tridentc->save.reg_3c4_18); + tridentWriteIndex (tridentc, 0x3c4, 0x19, tridentc->save.reg_3c4_19); + tridentWriteReg (tridentc, 0x3c2, tridentc->save.reg_3c2); + tridentPause (); tridentWriteIndex (tridentc, 0x3ce, 0x21, tridentc->save.reg_3ce_21); + tridentPause (); tridentWriteIndex (tridentc, 0x3d4, 0x62, tridentc->save.reg_3d4_62); tridentWriteIndex (tridentc, 0x3d4, 0x39, tridentc->save.reg_3d4_39); + tridentc->mmio = FALSE; tridentWriteIndex (tridentc, 0x3d4, 0x36, tridentc->save.reg_3d4_36); tridentWriteIndex (tridentc, 0x3c4, 0x0e, tridentc->save.reg_3c4_0e); tridentPause (); } -void +Bool tridentEnable (ScreenPtr pScreen) { KdScreenPriv(pScreen); TridentCardInfo *tridentc = pScreenPriv->card->driver; - fbdevEnable (pScreen); +#ifdef VESA + if (!vesaEnable (pScreen)) + return FALSE; +#else + if (!fbdevEnable (pScreen)) + return FALSE; +#endif tridentSetMMIO (tridentc); + return TRUE; } void tridentDisable (ScreenPtr pScreen) { +#ifdef VESA + vesaDisable (pScreen); +#else fbdevDisable (pScreen); +#endif } const CARD8 tridentDPMSModes[4] = { @@ -227,6 +521,7 @@ tridentDPMS (ScreenPtr pScreen, int mode) TridentCardInfo *tridentc = pScreenPriv->card->driver; tridentWriteIndex (tridentc, 0x3ce, 0x21, tridentDPMSModes[mode]); + tridentPause (); return TRUE; } @@ -236,7 +531,11 @@ tridentRestore (KdCardInfo *card) TridentCardInfo *tridentc = card->driver; tridentResetMMIO (tridentc); +#ifdef VESA + vesaRestore (card); +#else fbdevRestore (card); +#endif } void @@ -244,6 +543,9 @@ tridentScreenFini (KdScreenInfo *screen) { TridentScreenInfo *tridents = (TridentScreenInfo *) screen->driver; +#ifdef VESA + vesaScreenFini (screen); +#endif xfree (tridents); screen->driver = 0; } @@ -254,8 +556,17 @@ tridentCardFini (KdCardInfo *card) TridentCardInfo *tridentc = card->driver; if (tridentc->cop_base) - KdUnmapDevice ((void *) tridentc->cop_base, TRIDENT_COP_SIZE); + { + KdUnmapDevice ((void *) tridentc->cop_base, TRIDENT_COP_SIZE(card)); + KdResetMappedMode (TRIDENT_COP_BASE(card), + TRIDENT_COP_SIZE(card), + KD_MAPPED_MODE_REGISTERS); + } +#ifdef VESA + vesaCardFini (card); +#else fbdevCardFini (card); +#endif } KdCardFuncs tridentFuncs = { @@ -282,6 +593,11 @@ KdCardFuncs tridentFuncs = { tridentDrawDisable, /* disableAccel */ tridentDrawFini, /* finiAccel */ +#ifdef VESA + vesaGetColors, /* getColors */ + vesaPutColors, /* putColors */ +#else fbdevGetColors, /* getColors */ fbdevPutColors, /* putColors */ +#endif }; diff --git a/xc/programs/Xserver/hw/xfree86/doc/README.newport b/xc/programs/Xserver/hw/xfree86/doc/README.newport index f67024303..647969cdc 100644 --- a/xc/programs/Xserver/hw/xfree86/doc/README.newport +++ b/xc/programs/Xserver/hw/xfree86/doc/README.newport @@ -38,7 +38,7 @@ The following Section "Device" options are supported by the newport driver: o all the guys who wrote the newport_con linux kernel code - Generated from XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/newport.sgml,v 1.1 2000/12/01 19:37:57 dawes Exp $ + Generated from XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/newport.sgml,v 1.2 2000/12/12 18:54:29 dawes Exp $ -$XFree86: xc/programs/Xserver/hw/xfree86/doc/README.newport,v 1.1 2000/12/01 19:47:50 dawes Exp $ +$XFree86: xc/programs/Xserver/hw/xfree86/doc/README.newport,v 1.2 2000/12/12 19:04:03 dawes Exp $ diff --git a/xc/programs/Xserver/hw/xfree86/doc/sgml/newport.sgml b/xc/programs/Xserver/hw/xfree86/doc/sgml/newport.sgml index 18ebd7b4e..a0999f79a 100644 --- a/xc/programs/Xserver/hw/xfree86/doc/sgml/newport.sgml +++ b/xc/programs/Xserver/hw/xfree86/doc/sgml/newport.sgml @@ -7,7 +7,7 @@ <author>Guido Guenther <date>1 August 2000 <ident> -$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/newport.sgml,v 1.1 2000/12/01 19:37:57 dawes Exp $ +$XFree86: xc/programs/Xserver/hw/xfree86/doc/sgml/newport.sgml,v 1.2 2000/12/12 18:54:29 dawes Exp $ </ident> <toc> @@ -36,17 +36,17 @@ The following Section "Device" options are supported by the newport driver: <sect>Authors <p> <itemize> - <item>Guido Guenther <guido.guenther@gmx.net> + <item>Guido Guenther <email>guido.guenther@gmx.net</email> </itemize> <sect>Acknowledgements <p> <itemize> - <item>Gleb O. Raiko <raiko@niisi.msk.ru> for getting the beast to build - <item>Ralf Baechle <ralf@oss.sgi.com> for his patience... - <item>Ulf Carlsson <ulfc@calypso.engr.sgi.com> for comments and the dynamic loader code - <item>Nina A. Podolskaya <nap@niisi.msk.ru> for dynamic loader code + <item>Gleb O. Raiko <email>raiko@niisi.msk.ru</email> for getting the beast to build + <item>Ralf Baechle <email>ralf@oss.sgi.com</email> for his patience... + <item>Ulf Carlsson <email>ulfc@calypso.engr.sgi.com</email> for comments and the dynamic loader code + <item>Nina A. Podolskaya <email>nap@niisi.msk.ru</email> for dynamic loader code <item>all the guys who wrote the newport_con linux kernel code </itemize> diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile index 8e41284a4..342e7f8cf 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile @@ -1,6 +1,6 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v 1.10 1999/08/14 10:49:38 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/Imakefile,v 1.25 2000/11/02 16:55:26 tsi Exp $ XCOMM -XCOMM Copyright 1997 through 1999 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca +XCOMM Copyright 1997 through 2000 by Marc Aurele La France (TSI @ UQV), tsi@ualberta.ca XCOMM XCOMM Permission to use, copy, modify, distribute, and sell this software and XCOMM its documentation for any purpose is hereby granted without fee, provided @@ -29,30 +29,120 @@ CCOPTIONS = ATIDriverCCOptions #endif #if DoLoadableServer -ATIMODSRC = atimodule.c -ATIMODOBJ = atimodule.o + +MODSRCS1 = atimodule.c +MODSRCS2 = atiload.c atimisc.c +MODSRCS3 = r128_misc.c +MODSRCS4 = radeon_misc.c + +MODOBJS1 = atimodule.o +MODOBJS2 = atiload.o atimisc.o +MODOBJS3 = r128_misc.o +MODOBJS4 = radeon_misc.o + +#endif + +#if BuildXF86DRI + +DRISRCS3 = r128_dri.c +DRISRCS4 = radeon_dri.c + +DRIOBJS3 = r128_dri.o +DRIOBJS4 = radeon_dri.o + +DRIINCLUDES = -I$(SERVERSRC)/GL/dri -I$(LIBSRC)/GL/dri -I$(TOP)/include +DRIDEFINES = $(GLX_DEFINES) + +#endif + +/* + * The following configuration logic is only meant as a first cut, and is + * therefore incomplete. ...And, no, you do NOT have permission to move this + * into xfree86.cf... + * + * Currently, ATIAvoidCPIO >MUST< be #define'd as YES for those platforms + * (architecture/OS combinations) that neither provide nor emulate a + * little-endian undirected PIO address space of at least 64 kB in size. + * + * "Undirected" means the driver does not need to determine the identity nor + * location of the responding adapter before accessing a particular location in + * the PIO address space. + * + * #define'ing ATIAvoidCPIO to YES generates a driver that will only support + * PCI/AGP Mach64 adapters using a linear aperture and the accelerator CRTC. + * The resulting driver will also require the same of the environment on server + * entry. + * + * For testing purposes, #define'ing ATIAvoidCPIO as YES is also supported on + * platforms that do, in fact, provide or emulate a PIO address space as + * described above, but this should not be the default driver configuration. + */ +#if defined(i386Architecture) || \ + defined(ia64Architecture) || \ + defined(AlphaArchitecture) +# ifndef ATIAvoidCPIO +# define ATIAvoidCPIO NO +# endif +#elif defined(SparcArchitecture) || 1 +# undef ATIAvoidCPIO /* Clobber any previous setting */ +# define ATIAvoidCPIO YES +#endif + +#if !ATIAvoidCPIO + +CPIOSRCS1 = atibios.c ativgaio.c +CPIOSRCS2 = atibank.c ativga.c atiwonder.c atiwonderio.c + +CPIOOBJS1 = atibios.o ativgaio.o +CPIOOBJS2 = atibank.o ativga.o atiwonder.o atiwonderio.o + +#else + +CPIODEFINES = -DAVOID_CPIO + #endif -SRCS = ati.c atiadapter.c atiadjust.c atibank.c atibios.c atibus.c atichip.c \ - aticlock.c aticonsole.c aticrtc.c atidac.c atidsp.c atiident.c atiio.c \ - atilock.c atimach64.c $(ATIMODSRC) atioption.c atipreinit.c atiprint.c \ - atiprobe.c atiscreen.c atiutil.c ativalid.c ativga.c atividmem.c \ - atiwonder.c +DEFINES = $(CPIODEFINES) $(DRIDEFINES) -OBJS = ati.o atiadapter.o atiadjust.o atibank.o atibios.o atibus.o atichip.o \ - aticlock.o aticonsole.o aticrtc.o atidac.o atidsp.o atiident.o atiio.o \ - atilock.o atimach64.o $(ATIMODOBJ) atioption.o atipreinit.o atiprint.o \ - atiprobe.o atiscreen.o atiutil.o ativalid.o ativga.o atividmem.o \ - atiwonder.o +SRCS1 = ati.c atiadapter.c atibus.c atichip.c atiident.c atioption.c \ + atiprobe.c atividmem.c $(MODSRCS1) $(CPIOSRCS1) \ + radeon_probe.c r128_probe.c +SRCS2 = atiadjust.c aticlock.c aticonfig.c aticonsole.c atidac.c atidga.c \ + atidsp.c atilock.c atimach64.c atimach64io.c atimode.c atipreinit.c \ + atiprint.c atiscreen.c atiutil.c ativalid.c $(MODSRCS2) $(CPIOSRCS2) +SRCS3 = r128_accel.c r128_cursor.c r128_dga.c r128_driver.c r128_video.c \ + $(MODSRCS3) $(DRISRCS3) +SRCS4 = radeon_accel.c radeon_cursor.c radeon_dga.c radeon_driver.c \ + radeon_video.c $(MODSRCS4) $(DRISRCS4) + +OBJS1 = ati.o atiadapter.o atibus.o atichip.o atiident.o atioption.o \ + atiprobe.o atividmem.o $(MODOBJS1) $(CPIOOBJS1) \ + radeon_probe.o r128_probe.o +OBJS2 = atiadjust.o aticlock.o aticonfig.o aticonsole.o atidac.o atidga.o \ + atidsp.o atilock.o atimach64.o atimach64io.o atimode.o atipreinit.o \ + atiprint.o atiscreen.o atiutil.o ativalid.o $(MODOBJS2) $(CPIOOBJS2) +OBJS3 = r128_accel.o r128_cursor.o r128_dga.o r128_driver.o r128_video.o \ + $(MODOBJS3) $(DRIOBJS3) +OBJS4 = radeon_accel.o radeon_cursor.o radeon_dga.o radeon_driver.o \ + radeon_video.o $(MODOBJS4) $(DRIOBJS4) + +SRCS = $(SRCS1) $(SRCS2) $(SRCS3) $(SRCS4) +OBJS = $(OBJS1) $(OBJS2) $(OBJS3) $(OBJS4) #if defined(XF86DriverSDK) INCLUDES = -I. -I../../include #else -INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC)/rac -I$(XF86SRC) \ +INCLUDES = -I. -I$(XF86COMSRC) -I$(XF86OSSRC) -I$(XF86SRC) \ + -I$(XF86OSSRC)/vbe -I$(XF86SRC)/int10 \ + -I$(XF86SRC)/ddc -I$(XF86SRC)/i2c \ + -I$(XF86SRC)/rac -I$(XF86SRC)/ramdac \ + -I$(XF86SRC)/shadowfb -I$(XF86SRC)/xaa -I$(XF86SRC)/xf24_32bpp \ -I$(XF86SRC)/xf4bpp -I$(XF86SRC)/xf1bpp \ + -I$(XF86SRC)/vgahw -I$(XF86SRC)/fbdevhw \ -I$(SERVERSRC)/cfb -I$(SERVERSRC)/mfb \ - -I$(SERVERSRC)/mi -I$(SERVERSRC)/include \ - -I$(XINCLUDESRC) -I$(FONTINCSRC) + -I$(SERVERSRC)/fb -I$(SERVERSRC)/mi \ + -I$(SERVERSRC)/render -I$(SERVERSRC)/Xext -I$(SERVERSRC)/include \ + $(DRIINCLUDES) -I$(FONTINCSRC) -I$(EXTINCSRC) -I$(XINCLUDESRC) #endif #if MakeHasPosixVariableSubstitutions @@ -61,16 +151,29 @@ SubdirLibraryRule($(OBJS)) ModuleObjectRule() -ObjectModuleTarget(ati,$(OBJS)) +ObjectModuleTarget(ati,$(OBJS1)) +ObjectModuleTarget(atimisc,$(OBJS2)) +ObjectModuleTarget(r128,$(OBJS3)) +ObjectModuleTarget(radeon,$(OBJS4)) InstallObjectModule(ati,$(MODULEDIR),drivers) +InstallObjectModule(atimisc,$(MODULEDIR),drivers) +InstallObjectModule(r128,$(MODULEDIR),drivers) +InstallObjectModule(radeon,$(MODULEDIR),drivers) -#ifndef OS2Architecture -DependTarget() +#if 0 +CppManTarget(ati,) +InstallModuleManPage(ati) #endif +CppManTarget(r128,) +InstallModuleManPage(r128) + +DependTarget() + InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(ati.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(ati.cpp,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(ati.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiadapter.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiadapter.h,$(DRIVERSDKDIR)/drivers/ati) @@ -86,22 +189,31 @@ InstallDriverSDKNonExecFile(atichip.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atichip.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(aticlock.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(aticlock.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(aticonfig.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(aticonfig.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(aticonsole.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(aticonsole.h,$(DRIVERSDKDIR)/drivers/ati) -InstallDriverSDKNonExecFile(aticrtc.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(aticrtc.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atidac.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atidac.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atidga.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atidga.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atidsp.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atidsp.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiident.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiident.h,$(DRIVERSDKDIR)/drivers/ati) -InstallDriverSDKNonExecFile(atiio.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiio.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atiload.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atiload.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atilock.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atilock.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimach64.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimach64.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atimach64io.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atimach64io.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atimisc.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atimode.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atimode.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimodule.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimodule.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atimono.h,$(DRIVERSDKDIR)/drivers/ati) @@ -126,9 +238,70 @@ InstallDriverSDKNonExecFile(ativalid.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(ativersion.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(ativga.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(ativga.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(ativgaio.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(ativgaio.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atividmem.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atividmem.h,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiwonder.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKNonExecFile(atiwonder.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atiwonderio.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(atiwonderio.h,$(DRIVERSDKDIR)/drivers/ati) + +InstallDriverSDKNonExecFile(r128.cpp,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_accel.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_cursor.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_dga.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_dri.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_dri.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_dripriv.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_driver.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_misc.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_probe.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_probe.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_reg.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_sarea.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_version.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(r128_video.c,$(DRIVERSDKDIR)/drivers/ati) + +InstallDriverSDKNonExecFile(radeon.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_accel.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_cursor.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_dga.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_dri.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_dri.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_dripriv.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_driver.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_misc.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_probe.c,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_probe.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_reg.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_sarea.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_version.h,$(DRIVERSDKDIR)/drivers/ati) +InstallDriverSDKNonExecFile(radeon_video.c,$(DRIVERSDKDIR)/drivers/ati) InstallDriverSDKObjectModule(ati,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(atimisc,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(r128,$(DRIVERSDKMODULEDIR),drivers) +InstallDriverSDKObjectModule(radeon,$(DRIVERSDKMODULEDIR),drivers) + +/* Remove instances of ati2 module */ +#if DoLoadableServer + +#undef ATI2DriverModuleName +#if MakeDllModules +# define ATI2DriverModuleName ati2_drv.so +#else +# define ATI2DriverModuleName ati2_drv.o +#endif + +all:: + RemoveFile($(BUILDMODULEDIR)/drivers/ATI2DriverModuleName) + +install:: + RemoveFile($(DESTDIR)$(MODULEDIR)/drivers/ATI2DriverModuleName) + +install.sdk:: + RemoveFile($(DESTDIR)$(DRIVERSDKMODULEDIR)/drivers/ATI2DriverModuleName) + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c index d90a3dab8..dcdf65cf4 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c @@ -666,12 +666,6 @@ static Bool R128DRIBufInit(R128InfoPtr info, ScreenPtr pScreen) "[drm] Added %d %d byte vertex/indirect buffers\n", info->bufNumBufs, R128_BUFFER_SIZE); - if (drmMarkBufs(info->drmFD, 0.133333, 0.266666)) { - xf86DrvMsg(pScreen->myNum, X_ERROR, - "[drm] Failed to mark vertex/indirect buffers list\n"); - return FALSE; - } - if (!(info->buffers = drmMapBufs(info->drmFD))) { xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] Failed to map vertex/indirect buffers list\n"); @@ -932,24 +926,6 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen) memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); pR128DRI = (R128DRIPtr)info->pDRIInfo->devPrivate; - pR128DRI->registerHandle = info->registerHandle; - pR128DRI->registerSize = info->registerSize; - - pR128DRI->ringHandle = info->ringHandle; - pR128DRI->ringMapSize = info->ringMapSize; - pR128DRI->ringSize = info->ringSize*1024*1024; - - pR128DRI->ringReadPtrHandle = info->ringReadPtrHandle; - pR128DRI->ringReadMapSize = info->ringReadMapSize; - - pR128DRI->bufHandle = info->bufHandle; - pR128DRI->bufMapSize = info->bufMapSize; - pR128DRI->bufOffset = info->bufStart; - - pR128DRI->agpTexHandle = info->agpTexHandle; - pR128DRI->agpTexMapSize = info->agpTexMapSize; - pR128DRI->log2AGPTexGran = info->log2AGPTexGran; - pR128DRI->agpTexOffset = info->agpTexStart; pR128DRI->deviceID = info->Chipset; pR128DRI->width = pScrn->virtualX; @@ -957,6 +933,9 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen) pR128DRI->depth = pScrn->depth; pR128DRI->bpp = pScrn->bitsPerPixel; + pR128DRI->IsPCI = info->IsPCI; + pR128DRI->AGPMode = info->agpMode; + pR128DRI->frontOffset = info->frontOffset; pR128DRI->frontPitch = info->frontPitch; pR128DRI->backOffset = info->backOffset; @@ -968,11 +947,13 @@ Bool R128DRIFinishScreenInit(ScreenPtr pScreen) pR128DRI->textureSize = info->textureSize; pR128DRI->log2TexGran = info->log2TexGran; - pR128DRI->IsPCI = info->IsPCI; - pR128DRI->AGPMode = info->agpMode; + pR128DRI->registerHandle = info->registerHandle; + pR128DRI->registerSize = info->registerSize; - pR128DRI->CCEMode = info->CCEMode; - pR128DRI->CCEFifoSize = info->CCEFifoSize; + pR128DRI->agpTexHandle = info->agpTexHandle; + pR128DRI->agpTexMapSize = info->agpTexMapSize; + pR128DRI->log2AGPTexGran = info->log2AGPTexGran; + pR128DRI->agpTexOffset = info->agpTexStart; return TRUE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h index c9c9a7543..14ad6f61f 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h @@ -66,30 +66,6 @@ ((m) == R128_PM4_64BM_64VCBM_64INDBM)) typedef struct { - /* MMIO register data */ - drmHandle registerHandle; - drmSize registerSize; - - /* CCE ring buffer data */ - drmHandle ringHandle; - drmSize ringMapSize; - int ringSize; - - /* CCE ring read pointer data */ - drmHandle ringReadPtrHandle; - drmSize ringReadMapSize; - - /* CCE vertex/indirect buffer data */ - drmHandle bufHandle; - drmSize bufMapSize; - int bufOffset; - - /* CCE AGP Texture data */ - drmHandle agpTexHandle; - drmSize agpTexMapSize; - int log2AGPTexGran; - int agpTexOffset; - /* DRI screen private data */ int deviceID; /* PCI device ID */ int width; /* Width in pixels of display */ @@ -97,6 +73,9 @@ typedef struct { int depth; /* Depth of display (8, 15, 16, 24) */ int bpp; /* Bit depth of display (8, 16, 24, 32) */ + int IsPCI; /* Current card is a PCI card */ + int AGPMode; + int frontOffset; /* Start of front buffer */ int frontPitch; int backOffset; /* Start of shared back buffer */ @@ -108,11 +87,15 @@ typedef struct { int textureSize; int log2TexGran; - int IsPCI; /* Current card is a PCI card */ - int AGPMode; + /* MMIO register data */ + drmHandle registerHandle; + drmSize registerSize; - int CCEMode; /* CCE mode that server/clients use */ - int CCEFifoSize; /* Size of the CCE command FIFO */ + /* CCE AGP Texture data */ + drmHandle agpTexHandle; + drmSize agpTexMapSize; + int log2AGPTexGran; + int agpTexOffset; } R128DRIRec, *R128DRIPtr; #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c index 764bac4b8..1f2fe0ac7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_driver.c @@ -648,10 +648,10 @@ static Bool R128GetPLLParameters(ScrnInfoPtr pScrn) INPLL(pScrn,R128_PPLL_REF_DIV) & R128_PPLL_REF_DIV_MASK; /* unmap it again */ R128UnmapMMIO(pScrn); - + Nx = (x_mpll_ref_fb_div & 0x00FF00) >> 8; M = (x_mpll_ref_fb_div & 0x0000FF); - + pll->xclk = R128Div((2 * Nx * pll->reference_freq), (M * PostDivSet[xclk_cntl])); @@ -1656,170 +1656,170 @@ Bool R128ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) /* Memory manager setup */ #ifdef XF86DRI if (info->directRenderingEnabled) { - FBAreaPtr fbarea; - int width_bytes = (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes); - int cpp = info->CurrentLayout.pixel_bytes; - int bufferSize = pScrn->virtualY * width_bytes; - int l, total; - int scanlines; - - switch (info->CCEMode) { - case R128_DEFAULT_CCE_PIO_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); - break; - case R128_DEFAULT_CCE_BM_MODE: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); - break; - default: - xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); - break; - } - - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB AGP aperture\n", info->agpSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for the ring buffer\n", info->ringSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for vertex/indirect buffers\n", info->bufSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for AGP textures\n", info->agpTexSize); - - /* Try for front, back, depth, and two framebuffers worth of - * pixmap cache. Should be enough for a fullscreen background - * image plus some leftovers. - */ - info->textureSize = info->FbMapSize - 5 * bufferSize; - - /* If that gives us less than half the available memory, let's - * be greedy and grab some more. Sorry, I care more about 3D - * performance than playing nicely, and you'll get around a full - * framebuffer's worth of pixmap cache anyway. - */ - if ( info->textureSize < (int)info->FbMapSize / 2 ) { - info->textureSize = info->FbMapSize - 4 * bufferSize; - } - if ( info->textureSize > 0 ) { - l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); - if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; - - /* Round the texture size up to the nearest whole number of - * texture regions. Again, be greedy about this, don't - * round down. - */ - info->log2TexGran = l; - info->textureSize = ((info->textureSize >> l) + 1) << l; - } else { - info->textureSize = 0; - } - - total = info->FbMapSize - info->textureSize; - scanlines = total / width_bytes; - if (scanlines > 8191) scanlines = 8191; - - /* Recalculate the texture offset and size to accomodate any - * rounding to a whole number of scanlines. - * FIXME: Is this actually needed? - */ - info->textureOffset = scanlines * width_bytes; - info->textureSize = info->FbMapSize - info->textureOffset; - - /* Set a minimum usable local texture heap size. This will fit - * two 256x256x32bpp textures. - */ - if ( info->textureSize < 512 * 1024 ) { - info->textureOffset = 0; - info->textureSize = 0; - } - - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = pScrn->displayWidth; - MemBox.y2 = scanlines; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, - 2, 0, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, - &height, 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } + FBAreaPtr fbarea; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int cpp = info->CurrentLayout.pixel_bytes; + int bufferSize = pScrn->virtualY * width_bytes; + int l, total; + int scanlines; + + switch (info->CCEMode) { + case R128_DEFAULT_CCE_PIO_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in PIO mode\n"); + break; + case R128_DEFAULT_CCE_BM_MODE: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in BM mode\n"); + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "CCE in UNKNOWN mode\n"); + break; + } + + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB AGP aperture\n", info->agpSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for the ring buffer\n", info->ringSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for vertex/indirect buffers\n", info->bufSize); + xf86DrvMsg(pScrn->scrnIndex, X_INFO, + "Using %d MB for AGP textures\n", info->agpTexSize); + + /* Try for front, back, depth, and two framebuffers worth of + * pixmap cache. Should be enough for a fullscreen background + * image plus some leftovers. + */ + info->textureSize = info->FbMapSize - 5 * bufferSize; + + /* If that gives us less than half the available memory, let's + * be greedy and grab some more. Sorry, I care more about 3D + * performance than playing nicely, and you'll get around a full + * framebuffer's worth of pixmap cache anyway. + */ + if (info->textureSize < (int)info->FbMapSize / 2) { + info->textureSize = info->FbMapSize - 4 * bufferSize; + } + + if (info->textureSize > 0) { + l = R128MinBits((info->textureSize-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + + /* Round the texture size up to the nearest whole number of + * texture regions. Again, be greedy about this, don't + * round down. + */ + info->log2TexGran = l; + info->textureSize = (info->textureSize >> l) << l; + } else { + info->textureSize = 0; + } + + /* Set a minimum usable local texture heap size. This will fit + * two 256x256x32bpp textures. + */ + if (info->textureSize < 512 * 1024) { + info->textureOffset = 0; + info->textureSize = 0; + } + + total = info->FbMapSize - info->textureSize; + scanlines = total / width_bytes; + if (scanlines > 8191) scanlines = 8191; + + /* Recalculate the texture offset and size to accomodate any + * rounding to a whole number of scanlines. + */ + info->textureOffset = scanlines * width_bytes; + + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + MemBox.y2 = scanlines; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, + &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } /* Allocate the shared back buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved back buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->backX = fbarea->box.x1; - info->backY = fbarea->box.y1; - info->backOffset = (fbarea->box.y1 * width_bytes + - fbarea->box.x1 * cpp); - info->backPitch = pScrn->displayWidth; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); - info->backX = -1; - info->backY = -1; - info->backOffset = -1; - info->backPitch = -1; - } + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved back buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->backX = fbarea->box.x1; + info->backY = fbarea->box.y1; + info->backOffset = (fbarea->box.y1 * width_bytes + + fbarea->box.x1 * cpp); + info->backPitch = pScrn->displayWidth; + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); + info->backX = -1; + info->backY = -1; + info->backOffset = -1; + info->backPitch = -1; + } /* Allocate the shared depth buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY + 1, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->depthX = fbarea->box.x1; - info->depthY = fbarea->box.y1; - info->depthOffset = (fbarea->box.y1 * width_bytes + - fbarea->box.x1 * cpp); - info->depthPitch = pScrn->displayWidth; - info->spanOffset = ((fbarea->box.y2 - 1) * width_bytes + - fbarea->box.x1 * cpp); - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth span from (%d,%d) offset 0x%x\n", - fbarea->box.x1, fbarea->box.y2 - 1, info->spanOffset); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); - info->depthX = -1; - info->depthY = -1; - info->depthOffset = -1; - info->depthPitch = -1; - info->spanOffset = -1; - } - - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved %d kb for textures at offset 0x%x\n", - info->textureSize/1024, total); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->virtualX, + pScrn->virtualY + 1, + 32, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + + info->depthX = fbarea->box.x1; + info->depthY = fbarea->box.y1; + info->depthOffset = (fbarea->box.y1 * width_bytes + + fbarea->box.x1 * cpp); + info->depthPitch = pScrn->displayWidth; + info->spanOffset = ((fbarea->box.y2 - 1) * width_bytes + + fbarea->box.x1 * cpp); + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth span from (%d,%d) offset 0x%x\n", + fbarea->box.x1, fbarea->box.y2 - 1, info->spanOffset); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); + info->depthX = -1; + info->depthY = -1; + info->depthOffset = -1; + info->depthPitch = -1; + info->spanOffset = -1; + } + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures at offset 0x%x\n", + info->textureSize/1024, info->textureOffset); } else #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h index 16ab358b2..98aea68b6 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h @@ -1272,49 +1272,53 @@ # define R128_PSEUDOCOLOR_DT_ARGB1555 (1 << 24) # define R128_PSEUDOCOLOR_DT_ARGB4444 (2 << 24) #define R128_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4 -# define R128_COMB_DIS (0 << 0) -# define R128_COMB_COPY (1 << 0) -# define R128_COMB_COPY_INP (2 << 0) -# define R128_COMB_MODULATE (3 << 0) -# define R128_COMB_MODULATE2X (4 << 0) -# define R128_COMB_MODULATE4X (5 << 0) -# define R128_COMB_ADD (6 << 0) -# define R128_COMB_ADD_SIGNED (7 << 0) -# define R128_COMB_BLEND_VERTEX (8 << 0) -# define R128_COMB_BLEND_TEXTURE (9 << 0) -# define R128_COMB_BLEND_CONST (10 << 0) -# define R128_COMB_BLEND_PREMULT (11 << 0) -# define R128_COMB_BLEND_PREV (12 << 0) -# define R128_COMB_BLEND_PREMULT_INV (13 << 0) -# define R128_COMB_ADD_SIGNED2X (14 << 0) -# define R128_COMB_BLEND_CONST_COLOR (15 << 0) -# define R128_COMB_MASK (15 << 0) -# define R128_COLOR_FACTOR_TEX (4 << 4) -# define R128_COLOR_FACTOR_NTEX (5 << 4) -# define R128_COLOR_FACTOR_ALPHA (6 << 4) -# define R128_COLOR_FACTOR_NALPHA (7 << 4) -# define R128_COLOR_FACTOR_MASK (15 << 4) -# define R128_INPUT_FACTOR_CONST_COLOR (2 << 10) -# define R128_INPUT_FACTOR_CONST_ALPHA (3 << 10) -# define R128_INPUT_FACTOR_INT_COLOR (4 << 10) -# define R128_INPUT_FACTOR_INT_ALPHA (5 << 10) -# define R128_INPUT_FACTOR_MASK (15 << 10) -# define R128_COMB_ALPHA_DIS (0 << 14) -# define R128_COMB_ALPHA_COPY (1 << 14) -# define R128_COMB_ALPHA_COPY_INP (2 << 14) -# define R128_COMB_ALPHA_MODULATE (3 << 14) -# define R128_COMB_ALPHA_MODULATE2X (4 << 14) -# define R128_COMB_ALPHA_MODULATE4X (5 << 14) -# define R128_COMB_ALPHA_ADD (6 << 14) -# define R128_COMB_ALPHA_ADD_SIGNED (7 << 14) -# define R128_COMB_ALPHA_ADD_SIGNED2X (14 << 14) -# define R128_COMB_ALPHA_MASK (15 << 14) -# define R128_ALPHA_FACTOR_TEX_ALPHA (6 << 18) -# define R128_ALPHA_FACTOR_NTEX_ALPHA (7 << 18) -# define R128_ALPHA_FACTOR_MASK (15 << 18) -# define R128_INP_FACTOR_A_CONST_ALPHA (1 << 25) -# define R128_INP_FACTOR_A_INT_ALPHA (2 << 25) -# define R128_INP_FACTOR_A_MASK (7 << 25) +# define R128_COMB_DIS (0 << 0) +# define R128_COMB_COPY (1 << 0) +# define R128_COMB_COPY_INP (2 << 0) +# define R128_COMB_MODULATE (3 << 0) +# define R128_COMB_MODULATE2X (4 << 0) +# define R128_COMB_MODULATE4X (5 << 0) +# define R128_COMB_ADD (6 << 0) +# define R128_COMB_ADD_SIGNED (7 << 0) +# define R128_COMB_BLEND_VERTEX (8 << 0) +# define R128_COMB_BLEND_TEXTURE (9 << 0) +# define R128_COMB_BLEND_CONST (10 << 0) +# define R128_COMB_BLEND_PREMULT (11 << 0) +# define R128_COMB_BLEND_PREV (12 << 0) +# define R128_COMB_BLEND_PREMULT_INV (13 << 0) +# define R128_COMB_ADD_SIGNED2X (14 << 0) +# define R128_COMB_BLEND_CONST_COLOR (15 << 0) +# define R128_COMB_MASK (15 << 0) +# define R128_COLOR_FACTOR_CONST_COLOR (0 << 4) +# define R128_COLOR_FACTOR_NCONST_COLOR (1 << 4) +# define R128_COLOR_FACTOR_TEX (4 << 4) +# define R128_COLOR_FACTOR_NTEX (5 << 4) +# define R128_COLOR_FACTOR_ALPHA (6 << 4) +# define R128_COLOR_FACTOR_NALPHA (7 << 4) +# define R128_COLOR_FACTOR_PREV_COLOR (8 << 4) +# define R128_COLOR_FACTOR_MASK (15 << 4) +# define R128_COMB_FCN_MSB (1 << 8) +# define R128_INPUT_FACTOR_CONST_COLOR (2 << 10) +# define R128_INPUT_FACTOR_CONST_ALPHA (3 << 10) +# define R128_INPUT_FACTOR_INT_COLOR (4 << 10) +# define R128_INPUT_FACTOR_INT_ALPHA (5 << 10) +# define R128_INPUT_FACTOR_MASK (15 << 10) +# define R128_COMB_ALPHA_DIS (0 << 14) +# define R128_COMB_ALPHA_COPY (1 << 14) +# define R128_COMB_ALPHA_COPY_INP (2 << 14) +# define R128_COMB_ALPHA_MODULATE (3 << 14) +# define R128_COMB_ALPHA_MODULATE2X (4 << 14) +# define R128_COMB_ALPHA_MODULATE4X (5 << 14) +# define R128_COMB_ALPHA_ADD (6 << 14) +# define R128_COMB_ALPHA_ADD_SIGNED (7 << 14) +# define R128_COMB_ALPHA_ADD_SIGNED2X (14 << 14) +# define R128_COMB_ALPHA_MASK (15 << 14) +# define R128_ALPHA_FACTOR_TEX_ALPHA (6 << 18) +# define R128_ALPHA_FACTOR_NTEX_ALPHA (7 << 18) +# define R128_ALPHA_FACTOR_MASK (15 << 18) +# define R128_INP_FACTOR_A_CONST_ALPHA (1 << 25) +# define R128_INP_FACTOR_A_INT_ALPHA (2 << 25) +# define R128_INP_FACTOR_A_MASK (7 << 25) #define R128_TEX_SIZE_PITCH_C 0x1cb8 # define R128_TEX_PITCH_SHIFT 0 # define R128_TEX_SIZE_SHIFT 4 diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h index 350262d61..54bfa3673 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h @@ -76,11 +76,7 @@ /* Vertex/indirect buffer size */ -#if 1 #define R128_BUFFER_SIZE 16384 -#else -#define R128_BUFFER_SIZE (128 * 1024) -#endif /* Byte offsets for indirect buffer data */ @@ -94,14 +90,16 @@ /* There are 2 heaps (local/AGP). Each region within a heap is a * minimum of 64k, and there are at most 64 of them per heap. */ -#define R128_LOCAL_TEX_HEAP 0 -#define R128_AGP_TEX_HEAP 1 +#define R128_CARD_HEAP 0 +#define R128_AGP_HEAP 1 #define R128_NR_TEX_HEAPS 2 #define R128_NR_TEX_REGIONS 64 #define R128_LOG_TEX_GRANULARITY 16 #define R128_NR_CONTEXT_REGS 12 -#define R128_TEX_MAXLEVELS 11 + +#define R128_MAX_TEXTURE_LEVELS 11 +#define R128_MAX_TEXTURE_UNITS 2 #endif /* __R128_SAREA_DEFINES__ */ @@ -146,14 +144,14 @@ typedef struct { unsigned int tex_cntl; unsigned int tex_combine_cntl; unsigned int tex_size_pitch; - unsigned int tex_offset[R128_TEX_MAXLEVELS]; + unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS]; unsigned int tex_border_color; } r128_texture_regs_t; typedef struct { unsigned char next, prev; /* indices to form a circular LRU */ unsigned char in_use; /* owned by a client, or free? */ - int age; /* tracked by clients to update local LRU's */ + int age; /* tracked by clients to update local LRU's */ } r128_tex_region_t; typedef struct { @@ -161,20 +159,20 @@ typedef struct { * on firing a vertex buffer. */ r128_context_regs_t ContextState; - r128_texture_regs_t TexState[R128_NR_TEX_HEAPS]; - unsigned int dirty; - unsigned int vertsize; - unsigned int vc_format; + r128_texture_regs_t TexState[R128_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; /* The current cliprects, or a subset thereof. */ - XF86DRIClipRectRec boxes[R128_NR_SAREA_CLIPRECTS]; - unsigned int nbox; + XF86DRIClipRectRec boxes[R128_NR_SAREA_CLIPRECTS]; + unsigned int nbox; /* Counters for throttling of rendering clients. */ - unsigned int last_frame; - unsigned int last_dispatch; + unsigned int last_frame; + unsigned int last_dispatch; /* Maintain an LRU of contiguous regions of texture space. If you * think you own a region of texture memory, and it has an age @@ -191,11 +189,11 @@ typedef struct { * else's - simply eject them all in LRU order. */ /* Last elt is sentinal */ - r128_tex_region_t texList[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; + r128_tex_region_t texList[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; /* last time texture was uploaded */ - int texAge[R128_NR_TEX_HEAPS]; + int texAge[R128_NR_TEX_HEAPS]; - int ctxOwner; /* last context to upload state */ + int ctxOwner; /* last context to upload state */ } R128SAREAPriv, *R128SAREAPrivPtr; #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h index 5d710570a..90311d495 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon.h @@ -51,14 +51,18 @@ #include "xf86xv.h" /* DRI support */ -#undef XF86DRI /* Not yet */ #ifdef XF86DRI #define _XF86DRI_SERVER_ -#include "r128_dripriv.h" +#include "radeon_dripriv.h" #include "dri.h" #include "GL/glxint.h" #endif + /* Render support */ +#ifdef RENDER +#include "picturestr.h" +#endif + #define RADEON_DEBUG 0 /* Turn off debugging output */ #define RADEON_TIMEOUT 2000000 /* Fall out of wait loops after this count */ #define RADEON_MMIOSIZE 0x80000 @@ -287,12 +291,10 @@ typedef struct { unsigned char *AGP; /* Map */ int agpMode; - Bool CPInUse; /* CP is currently active */ + Bool CPInUse; /* CP has been used by X server */ int CPMode; /* CP mode that server/clients use */ int CPFifoSize; /* Size of the CP command FIFO */ - Bool CPSecure; /* CP security enabled */ int CPusecTimeout; /* CP timeout in usecs */ - Bool CP2D; /* CP is used for X server 2D prims */ /* CP ring buffer data */ unsigned long ringStart; /* Offset into AGP space */ @@ -307,22 +309,14 @@ typedef struct { drmSize ringReadMapSize; /* Size of map */ unsigned char *ringReadPtr; /* Map */ - /* CP vertex buffer data */ - unsigned long vbStart; /* Offset into AGP space */ - drmHandle vbHandle; /* Handle from drmAddMap */ - drmSize vbMapSize; /* Size of map */ - int vbSize; /* Size of vert bufs (in MB) */ - unsigned char *vb; /* Map */ - int vbBufSize; /* Size of individual vert buf */ - int vbNumBufs; /* Number of vert bufs */ - drmBufMapPtr vbBufs; /* Buffer map */ - - /* CP indirect buffer data */ - unsigned long indStart; /* Offset into AGP space */ - drmHandle indHandle; /* Handle from drmAddMap */ - drmSize indMapSize; /* Size of map */ - int indSize; /* Size of indirect bufs (in MB) */ - unsigned char *ind; /* Map */ + /* CP vertex/indirect buffer data */ + unsigned long bufStart; /* Offset into AGP space */ + drmHandle bufHandle; /* Handle from drmAddMap */ + drmSize bufMapSize; /* Size of map */ + int bufSize; /* Size of buffers (in MB) */ + unsigned char *buf; /* Map */ + int bufNumBufs; /* Number of buffers */ + drmBufMapPtr buffers; /* Buffer map */ /* CP AGP Texture data */ unsigned long agpTexStart; /* Offset into AGP space */ @@ -332,6 +326,10 @@ typedef struct { unsigned char *agpTex; /* Map */ int log2AGPTexGran; + /* CP accleration */ + drmBufPtr indirectBuffer; + int indirectStart; + /* DRI screen private data */ int fbX; int fbY; @@ -339,11 +337,35 @@ typedef struct { int backY; int depthX; int depthY; - int textureX; - int textureY; + + int frontOffset; + int frontPitch; + int backOffset; + int backPitch; + int depthOffset; + int depthPitch; + int textureOffset; int textureSize; int log2TexGran; + + CARD32 frontPitchOffset; + CARD32 backPitchOffset; + CARD32 depthPitchOffset; + + CARD32 dst_pitch_offset; + + /* Saved scissor values */ + CARD32 sc_left; + CARD32 sc_right; + CARD32 sc_top; + CARD32 sc_bottom; + + CARD32 re_top_left; + CARD32 re_width_height; + + CARD32 aux_sc_cntl; #endif + XF86VideoAdaptorPtr adaptor; void (*VideoTimerCallback)(ScrnInfoPtr, Time); int videoKey; @@ -359,14 +381,17 @@ do { \ extern void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries); extern void RADEONWaitForIdle(ScrnInfoPtr pScrn); + extern void RADEONEngineReset(ScrnInfoPtr pScrn); extern void RADEONEngineFlush(ScrnInfoPtr pScrn); +extern void RADEONEngineRestore(ScrnInfoPtr pScrn); extern unsigned RADEONINPLL(ScrnInfoPtr pScrn, int addr); extern void RADEONWaitForVerticalSync(ScrnInfoPtr pScrn); +extern void RADEONSelectBuffer(ScrnInfoPtr pScrn, int buffer); + extern Bool RADEONAccelInit(ScreenPtr pScreen); -extern void RADEONEngineInit(ScrnInfoPtr pScrn); extern Bool RADEONCursorInit(ScreenPtr pScreen); extern Bool RADEONDGAInit(ScreenPtr pScreen); @@ -378,10 +403,174 @@ extern void RADEONInitVideo(ScreenPtr); extern Bool RADEONDRIScreenInit(ScreenPtr pScreen); extern void RADEONDRICloseScreen(ScreenPtr pScreen); extern Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen); -extern void RADEONCPStart(ScrnInfoPtr pScrn); -extern void RADEONCPStop(ScrnInfoPtr pScrn); -extern void RADEONCPResetRing(ScrnInfoPtr pScrn); -extern void RADEONCPWaitForIdle(ScrnInfoPtr pScrn); -#endif -#endif +extern drmBufPtr RADEONCPGetBuffer(ScrnInfoPtr pScrn); +extern void RADEONCPFlushIndirect(ScrnInfoPtr pScrn); +extern void RADEONCPReleaseIndirect(ScrnInfoPtr pScrn); + + +#define RADEONCP_START(pScrn, info) \ +do { \ + int ret = drmRadeonStartCP(info->drmFD); \ + if (ret) { \ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + "%s: CP start %d\n", __FUNCTION__, ret); \ + } \ +} while (0) + +#define RADEONCP_STOP(pScrn, info) \ +do { \ + int ret = drmRadeonStopCP(info->drmFD); \ + if (ret) { \ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + "%s: CP stop %d\n", __FUNCTION__, ret); \ + } \ + RADEONEngineRestore(pScrn); \ +} while (0) + +#define RADEONCP_RESET(pScrn, info) \ +do { \ + if (RADEONCP_USE_RING_BUFFER(info->CPMode)) { \ + int ret = drmRadeonResetCP(info->drmFD); \ + if (ret) { \ + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + "%s: CP reset %d\n", __FUNCTION__, ret); \ + } \ + } \ +} while (0) + +#define RADEONCP_REFRESH(pScrn, info) \ +do { \ + if ( !info->CPInUse ) { \ + RADEON_WAIT_UNTIL_IDLE(); \ + BEGIN_RING( 6 ); \ + OUT_RING_REG( RADEON_RE_TOP_LEFT, info->re_top_left ); \ + OUT_RING_REG( RADEON_RE_WIDTH_HEIGHT, info->re_width_height ); \ + OUT_RING_REG( RADEON_AUX_SC_CNTL, info->aux_sc_cntl ); \ + ADVANCE_RING(); \ + info->CPInUse = TRUE; \ + } \ +} while (0) + + +#define CP_PACKET0( reg, n ) \ + (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) +#define CP_PACKET1( reg0, reg1 ) \ + (RADEON_CP_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2)) +#define CP_PACKET2() \ + (RADEON_CP_PACKET2) +#define CP_PACKET3( pkt, n ) \ + (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) + + +#define RADEON_VERBOSE 0 + +#define RING_LOCALS CARD32 *__head; int __count; +#define RING_THRESHOLD 256 + +#define BEGIN_RING( n ) do { \ + if ( RADEON_VERBOSE ) { \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ ); \ + } \ + if ( !info->indirectBuffer ) { \ + info->indirectBuffer = RADEONCPGetBuffer( pScrn ); \ + info->indirectStart = 0; \ + } else if ( info->indirectBuffer->used - info->indirectStart + \ + (n) * (int)sizeof(CARD32) > RING_THRESHOLD ) { \ + RADEONCPFlushIndirect( pScrn ); \ + } \ + __head = (CARD32 *)((char *)info->indirectBuffer->address + \ + info->indirectBuffer->used); \ + __count = 0; \ +} while (0) + +#define ADVANCE_RING() do { \ + if ( RADEON_VERBOSE ) { \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + "ADVANCE_RING() used: %d+%d=%d/%d\n", \ + info->indirectBuffer->used - info->indirectStart, \ + __count * sizeof(CARD32), \ + info->indirectBuffer->used - info->indirectStart + \ + __count * sizeof(CARD32), \ + RING_THRESHOLD ); \ + } \ + info->indirectBuffer->used += __count * (int)sizeof(CARD32); \ +} while (0) + +#define OUT_RING( x ) do { \ + if ( RADEON_VERBOSE ) { \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + " OUT_RING( 0x%08x )\n", (unsigned int)(x) ); \ + } \ + __head[__count++] = (x); \ +} while (0) + +#define OUT_RING_REG( reg, val ) \ +do { \ + OUT_RING( CP_PACKET0( reg, 0 ) ); \ + OUT_RING( val ); \ +} while (0) + +#define FLUSH_RING() \ +do { \ + if ( RADEON_VERBOSE ) \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + "FLUSH_RING in %s\n", __FUNCTION__ ); \ + if ( info->indirectBuffer ) { \ + RADEONCPFlushIndirect( pScrn ); \ + } \ +} while (0) + + +#define RADEON_WAIT_UNTIL_2D_IDLE() \ +do { \ + BEGIN_RING( 2 ); \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ + ADVANCE_RING(); \ +} while (0) + +#define RADEON_WAIT_UNTIL_3D_IDLE() \ +do { \ + BEGIN_RING( 2 ); \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ + ADVANCE_RING(); \ +} while (0) + +#define RADEON_WAIT_UNTIL_IDLE() \ +do { \ + if ( RADEON_VERBOSE ) { \ + xf86DrvMsg( pScrn->scrnIndex, X_INFO, \ + "WAIT_UNTIL_IDLE() in %s\n", __FUNCTION__ ); \ + } \ + BEGIN_RING( 2 ); \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ + RADEON_WAIT_3D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ + ADVANCE_RING(); \ +} while (0) + +#define RADEON_FLUSH_CACHE() \ +do { \ + BEGIN_RING( 2 ); \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH ); \ + ADVANCE_RING(); \ +} while (0) + +#define RADEON_PURGE_CACHE() \ +do { \ + BEGIN_RING( 2 ); \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \ + ADVANCE_RING(); \ +} while (0) + +#endif /* XF86DRI */ + +#endif /* _RADEON_H_ */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c index 0f7b79724..0f8042853 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_accel.c @@ -77,7 +77,8 @@ #include "radeon_reg.h" #ifdef XF86DRI #define _XF86DRI_SERVER_ -#include "r128_dri.h" +#include "radeon_dri.h" +#include "radeon_sarea.h" #endif /* Line support */ @@ -108,6 +109,109 @@ static struct { { RADEON_ROP3_ONE, RADEON_ROP3_ONE } /* GXset */ }; +/* The FIFO has 64 slots. This routines waits until at least `entries' of + these slots are empty. */ +void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + info->fifo_slots = + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK; + if (info->fifo_slots >= entries) return; + } + RADEONTRACE(("FIFO timed out: %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "FIFO timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); + RADEONEngineRestore(pScrn); +#ifdef XF86DRI + RADEONCP_RESET(pScrn, info); + if (info->directRenderingEnabled) { + RADEONCP_START(pScrn, info); + } +#endif + } +} + +/* Wait for the graphics engine to be completely idle: the FIFO has + drained, the Pixel Cache is flushed, and the engine is idle. This is a + standard "sync" function that will make the hardware "quiescent". */ +void RADEONWaitForIdle(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + unsigned char *RADEONMMIO = info->MMIO; + int i; + + RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + + RADEONWaitForFifoFunction(pScrn, 64); + + for (;;) { + for (i = 0; i < RADEON_TIMEOUT; i++) { + if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { + RADEONEngineFlush(pScrn); + return; + } + } + RADEONTRACE(("Idle timed out: %d entries, stat=0x%08x\n", + INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, + INREG(RADEON_RBBM_STATUS))); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); + RADEONEngineRestore(pScrn); +#ifdef XF86DRI + RADEONCP_RESET(pScrn, info); + if (info->directRenderingEnabled) { + RADEONCP_START(pScrn, info); + } +#endif + } +} + +#ifdef XF86DRI +/* Wait until the CP is completely idle: the FIFO has drained and the + * CP is idle. + */ +static void RADEONCPWaitForIdle(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + int ret; + int i = 0; + + FLUSH_RING(); + + for (;;) { + do { + ret = drmRadeonWaitForIdleCP(info->drmFD); + if (ret && ret != -EBUSY) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "%s: CP idle %d\n", __FUNCTION__, ret); + } + } while ((ret == -EBUSY) && (i++ < RADEON_TIMEOUT)); + + if (ret == 0) return; + + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Idle timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); + RADEONEngineRestore(pScrn); + + /* Always restart the engine when doing CP 2D acceleration */ + RADEONCP_RESET(pScrn, info); + RADEONCP_START(pScrn, info); + } +} +#endif + /* Flush all dirty data in the Pixel Cache to memory. */ void RADEONEngineFlush(ScrnInfoPtr pScrn) { @@ -136,6 +240,7 @@ void RADEONEngineReset(ScrnInfoPtr pScrn) clock_cntl_index = INREG(RADEON_CLOCK_CNTL_INDEX); mclk_cntl = INPLL(pScrn, RADEON_MCLK_CNTL); + /* FIXME: Remove magic numbers! */ OUTPLL(RADEON_MCLK_CNTL, (mclk_cntl | 0x003f0000)); rbbm_soft_reset = INREG(RADEON_RBBM_SOFT_RESET); @@ -164,70 +269,105 @@ void RADEONEngineReset(ScrnInfoPtr pScrn) OUTPLL(RADEON_MCLK_CNTL, mclk_cntl); OUTREG(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index); OUTREG(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset); - -#ifdef XF86DRI - if (RADEONCP_USE_RING_BUFFER(info->CPMode)) RADEONCPResetRing(pScrn); -#endif } -/* The FIFO has 64 slots. This routines waits until at least `entries' of - these slots are empty. */ -void RADEONWaitForFifoFunction(ScrnInfoPtr pScrn, int entries) +/* Restore the acceleration hardware to its previous state. */ +void RADEONEngineRestore(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - int i; + int pitch64; - for (;;) { - for (i = 0; i < RADEON_TIMEOUT; i++) { - info->fifo_slots = - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK; - if (info->fifo_slots >= entries) return; - } - RADEONTRACE(("FIFO timed out: %d entries, stat=0x%08x\n", - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, - INREG(RADEON_RBBM_STATUS))); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "FIFO timed out, resetting engine...\n"); - RADEONEngineInit(pScrn); -#ifdef XF86DRI - if (info->CP2D) RADEONCPStart(pScrn); + RADEONTRACE(("EngineRestore (%d/%d)\n", + info->CurrentLayout.pixel_code, + info->CurrentLayout.bitsPerPixel)); + + RADEONWaitForFifo(pScrn, 1); + /* turn of all automatic flushing - we'll do it all */ + OUTREG(RADEON_RB2D_DSTCACHE_MODE, 0); + + pitch64 = ((pScrn->displayWidth * (pScrn->bitsPerPixel / 8) + 0x3f)) >> 6; + + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DEFAULT_OFFSET, (INREG(RADEON_DEFAULT_OFFSET) & 0xC0000000) | + (pitch64 << 22)); + + RADEONWaitForFifo(pScrn, 1); +#if X_BYTE_ORDER == X_BIG_ENDIAN + OUTREGP(RADEON_DP_DATATYPE, + RADEON_HOST_BIG_ENDIAN_EN, ~RADEON_HOST_BIG_ENDIAN_EN); +#else + OUTREGP(RADEON_DP_DATATYPE, 0, ~RADEON_HOST_BIG_ENDIAN_EN); #endif - } + + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX + | RADEON_DEFAULT_SC_BOTTOM_MAX)); + RADEONWaitForFifo(pScrn, 1); + OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_SOLID_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR)); + + RADEONWaitForFifo(pScrn, 7); + OUTREG(RADEON_DST_LINE_START, 0); + OUTREG(RADEON_DST_LINE_END, 0); + OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff); + OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0x00000000); + OUTREG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff); + OUTREG(RADEON_DP_SRC_BKGD_CLR, 0x00000000); + OUTREG(RADEON_DP_WRITE_MASK, 0xffffffff); + + RADEONWaitForIdle(pScrn); } -/* Wait for the graphics engine to be completely idle: the FIFO has - drained, the Pixel Cache is flushed, and the engine is idle. This is a - standard "sync" function that will make the hardware "quiescent". */ -void RADEONWaitForIdle(ScrnInfoPtr pScrn) +/* Initialize the acceleration hardware. */ +static void RADEONEngineInit(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - int i; - RADEONTRACE(("WaitForIdle (entering): %d entries, stat=0x%08x\n", - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, - INREG(RADEON_RBBM_STATUS))); + RADEONTRACE(("EngineInit (%d/%d)\n", + info->CurrentLayout.pixel_code, + info->CurrentLayout.bitsPerPixel)); - RADEONWaitForFifoFunction(pScrn, 64); + OUTREG(RADEON_RB3D_CNTL, 0); + RADEONEngineReset(pScrn); + + switch (info->CurrentLayout.pixel_code) { + case 8: info->datatype = 2; break; + case 15: info->datatype = 3; break; + case 16: info->datatype = 4; break; + case 24: info->datatype = 5; break; + case 32: info->datatype = 6; break; + default: + RADEONTRACE(("Unknown depth/bpp = %d/%d (code = %d)\n", + info->CurrentLayout.depth, + info->CurrentLayout.bitsPerPixel, + info->CurrentLayout.pixel_code)); + } + info->pitch = ((info->CurrentLayout.displayWidth / 8) * + (info->CurrentLayout.pixel_bytes == 3 ? 3 : 1)); + + RADEONTRACE(("Pitch for acceleration = %d\n", info->pitch)); + + info->dp_gui_master_cntl = + ((info->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) + | RADEON_GMC_CLR_CMP_CNTL_DIS); - for (;;) { - for (i = 0; i < RADEON_TIMEOUT; i++) { - if (!(INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_ACTIVE)) { - RADEONEngineFlush(pScrn); - return; - } - } - RADEONTRACE(("Idle timed out: %d entries, stat=0x%08x\n", - INREG(RADEON_RBBM_STATUS) & RADEON_RBBM_FIFOCNT_MASK, - INREG(RADEON_RBBM_STATUS))); - xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Idle timed out, resetting engine...\n"); - RADEONEngineInit(pScrn); #ifdef XF86DRI - if (info->CP2D) RADEONCPStart(pScrn); + info->sc_left = 0x00000000; + info->sc_right = RADEON_DEFAULT_SC_RIGHT_MAX; + info->sc_top = 0x00000000; + info->sc_bottom = RADEON_DEFAULT_SC_BOTTOM_MAX; + + info->re_top_left = 0x00000000; + info->re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) | + (0x7ff << RADEON_RE_HEIGHT_SHIFT)); + + info->aux_sc_cntl = 0x00000000; #endif - } + + RADEONEngineRestore(pScrn); } /* Setup for XAA SolidFill. */ @@ -362,10 +502,10 @@ static void RADEONSetupForDashedLine(ScrnInfoPtr pScrn, /* Subsequent XAA dashed line. */ static void RADEONSubsequentDashedTwoPointLine(ScrnInfoPtr pScrn, - int xa, int ya, - int xb, int yb, - int flags, - int phase) + int xa, int ya, + int xb, int yb, + int flags, + int phase) { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; @@ -691,7 +831,7 @@ static void RADEONSubsequentScanlineImageWriteRect(ScrnInfoPtr pScrn, { RADEONInfoPtr info = RADEONPTR(pScrn); unsigned char *RADEONMMIO = info->MMIO; - int shift = 0; /* 32bpp */ + int shift = 0; /* 32bpp */ if (pScrn->bitsPerPixel == 8) shift = 3; else if (pScrn->bitsPerPixel == 16) shift = 1; @@ -760,92 +900,291 @@ static void RADEONSubsequentImageWriteScanline(ScrnInfoPtr pScrn, int bufno) } #endif -/* Initialize the acceleration hardware. */ -void RADEONEngineInit(ScrnInfoPtr pScrn) + +/* ================================================================ + * CP-based 2D acceleration + */ +#ifdef XF86DRI + +/* Setup for XAA SolidFill. */ +static void RADEONCPSetupForSolidFill(ScrnInfoPtr pScrn, + int color, int rop, + unsigned int planemask) { - RADEONInfoPtr info = RADEONPTR(pScrn); - unsigned char *RADEONMMIO = info->MMIO; - int pitch64; + RADEONInfoPtr info = RADEONPTR(pScrn); + RING_LOCALS; - RADEONTRACE(("EngineInit (%d/%d)\n", - info->CurrentLayout.pixel_code, - info->CurrentLayout.bitsPerPixel)); + RADEONCP_REFRESH( pScrn, info ); - OUTREG(RADEON_SCALE_3D_CNTL, 0); - RADEONEngineReset(pScrn); + BEGIN_RING( 8 ); - RADEONWaitForFifo(pScrn, 1); - /* turn of all automatic flushing - we'll do it all */ - OUTREG(RADEON_RB2D_DSTCACHE_MODE, 0); + OUT_RING_REG( RADEON_DP_GUI_MASTER_CNTL, + (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_SOLID_COLOR + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].pattern) ); - switch (info->CurrentLayout.pixel_code) { - case 8: info->datatype = 2; break; - case 15: info->datatype = 3; break; - case 16: info->datatype = 4; break; - case 24: info->datatype = 5; break; - case 32: info->datatype = 6; break; + OUT_RING_REG( RADEON_DP_BRUSH_FRGD_CLR, color ); + OUT_RING_REG( RADEON_DP_WRITE_MASK, planemask ); + OUT_RING_REG( RADEON_DP_CNTL, (RADEON_DST_X_LEFT_TO_RIGHT | + RADEON_DST_Y_TOP_TO_BOTTOM) ); + ADVANCE_RING(); +} + +/* Subsequent XAA SolidFillRect. + + Tests: xtest CH06/fllrctngl, xterm +*/ +static void RADEONCPSubsequentSolidFillRect(ScrnInfoPtr pScrn, + int x, int y, int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RING_LOCALS; + + RADEONCP_REFRESH( pScrn, info ); + + BEGIN_RING( 4 ); + + OUT_RING_REG( RADEON_DST_Y_X, (y << 16) | x ); + OUT_RING_REG( RADEON_DST_WIDTH_HEIGHT, (w << 16) | h ); + + ADVANCE_RING(); +} + +/* Setup for XAA screen-to-screen copy. + + Tests: xtest CH06/fllrctngl (also tests transparency). +*/ +static void RADEONCPSetupForScreenToScreenCopy(ScrnInfoPtr pScrn, + int xdir, int ydir, int rop, + unsigned int planemask, + int trans_color) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RING_LOCALS; + + RADEONCP_REFRESH( pScrn, info ); + + info->xdir = xdir; + info->ydir = ydir; + + BEGIN_RING( 6 ); + + OUT_RING_REG( RADEON_DP_GUI_MASTER_CNTL, + (info->dp_gui_master_cntl + | RADEON_GMC_BRUSH_NONE + | RADEON_GMC_SRC_DATATYPE_COLOR + | RADEON_ROP[rop].rop + | RADEON_DP_SRC_SOURCE_MEMORY) ); + + OUT_RING_REG( RADEON_DP_WRITE_MASK, planemask ); + OUT_RING_REG( RADEON_DP_CNTL, + ((xdir >= 0 ? RADEON_DST_X_LEFT_TO_RIGHT : 0) | + (ydir >= 0 ? RADEON_DST_Y_TOP_TO_BOTTOM : 0)) ); + + ADVANCE_RING(); + + if ( trans_color != -1 ) { + BEGIN_RING( 6 ); + + OUT_RING_REG( RADEON_CLR_CMP_CLR_SRC, trans_color ); + OUT_RING_REG( RADEON_CLR_CMP_MASK, RADEON_CLR_CMP_MSK ); + /* Mmmm, Seems as though the transparency compare is opposite to r128 + * It should only draw when source != trans_color, + * this is the opposite of that. */ + OUT_RING_REG( RADEON_CLR_CMP_CNTL, (RADEON_SRC_CMP_EQ_COLOR | + RADEON_CLR_CMP_SRC_SOURCE) ); + + ADVANCE_RING(); + } +} + +/* Subsequent XAA screen-to-screen copy. */ +static void RADEONCPSubsequentScreenToScreenCopy(ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RING_LOCALS; + + RADEONCP_REFRESH( pScrn, info ); + + if (info->xdir < 0) x1 += w - 1, x2 += w - 1; + if (info->ydir < 0) y1 += h - 1, y2 += h - 1; + + BEGIN_RING( 6 ); + + OUT_RING_REG( RADEON_SRC_Y_X, (y1 << 16) | x1 ); + OUT_RING_REG( RADEON_DST_Y_X, (y2 << 16) | x2 ); + OUT_RING_REG( RADEON_DST_HEIGHT_WIDTH, (h << 16) | w ); + + ADVANCE_RING(); +} + +/* Point the DST_PITCH_OFFSET register at the current buffer. This + * allows us to interact with the back and depth buffers. All CP 2D + * acceleration commands use the DST_PITCH_OFFSET register. + */ +void RADEONSelectBuffer(ScrnInfoPtr pScrn, int buffer) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + RING_LOCALS; + + switch (buffer) { + case RADEON_BACK: + info->dst_pitch_offset = info->backPitchOffset; + break; + case RADEON_DEPTH: + info->dst_pitch_offset = info->depthPitchOffset; + break; default: - RADEONTRACE(("Unknown depth/bpp = %d/%d (code = %d)\n", - info->CurrentLayout.depth, - info->CurrentLayout.bitsPerPixel, - info->CurrentLayout.pixel_code)); + case RADEON_FRONT: + info->dst_pitch_offset = info->frontPitchOffset; + break; } - info->pitch = ((info->CurrentLayout.displayWidth / 8) * - (info->CurrentLayout.pixel_bytes == 3 ? 3 : 1)); - RADEONTRACE(("Pitch for acceleration = %d\n", info->pitch)); + BEGIN_RING( 2 ); - pitch64 = ((pScrn->displayWidth * (pScrn->bitsPerPixel / 8) + 0x3f)) >> 6; + OUT_RING_REG( RADEON_DEFAULT_OFFSET, info->dst_pitch_offset ); - RADEONWaitForFifo(pScrn, 1); - OUTREG(RADEON_DEFAULT_OFFSET, (INREG(RADEON_DEFAULT_OFFSET) & 0xC0000000) | - (pitch64 << 22)); + ADVANCE_RING(); +} - RADEONWaitForFifo(pScrn, 1); -#if X_BYTE_ORDER == X_BIG_ENDIAN - OUTREGP(RADEON_DP_DATATYPE, - RADEON_HOST_BIG_ENDIAN_EN, ~RADEON_HOST_BIG_ENDIAN_EN); +/* Get an indirect buffer for the CP 2D acceleration commands. + */ +drmBufPtr RADEONCPGetBuffer( ScrnInfoPtr pScrn ) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + drmDMAReq dma; + drmBufPtr buf = NULL; + int index = 0; + int size = 0; + int ret, i = 0; + +#if 0 + /* FIXME: pScrn->pScreen has not been initialized when this is first + called from RADEONSelectBuffer via RADEONDRICPInit. We could use + the screen index from pScrn, which is initialized, and then get + the screen from screenInfo.screens[index], but that is a hack. */ + dma.context = DRIGetContext(pScrn->pScreen); #else - OUTREGP(RADEON_DP_DATATYPE, 0, ~RADEON_HOST_BIG_ENDIAN_EN); + dma.context = 0x00000001; /* This is the X server's context */ #endif + 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 ( 1 ) { + do { + ret = drmDMA( info->drmFD, &dma ); + if ( ret && ret != -EBUSY ) { + xf86DrvMsg( pScrn->scrnIndex, X_ERROR, + "%s: CP GetBuffer %d\n", __FUNCTION__, ret ); + } + } while ( ( ret == -EBUSY ) && ( i++ < RADEON_TIMEOUT ) ); + + if ( ret == 0 ) { + buf = &info->buffers->list[index]; + buf->used = 0; + if ( RADEON_VERBOSE ) { + xf86DrvMsg( pScrn->scrnIndex, X_INFO, + " GetBuffer returning %d\n", buf->idx ); + } + return buf; + } - RADEONWaitForFifo(pScrn, 1); - OUTREG(RADEON_DEFAULT_SC_BOTTOM_RIGHT, (RADEON_DEFAULT_SC_RIGHT_MAX - | RADEON_DEFAULT_SC_BOTTOM_MAX)); - info->dp_gui_master_cntl = - ((info->datatype << RADEON_GMC_DST_DATATYPE_SHIFT) - | RADEON_GMC_CLR_CMP_CNTL_DIS); - RADEONWaitForFifo(pScrn, 1); - OUTREG(RADEON_DP_GUI_MASTER_CNTL, (info->dp_gui_master_cntl - | RADEON_GMC_BRUSH_SOLID_COLOR - | RADEON_GMC_SRC_DATATYPE_COLOR)); + xf86DrvMsg( pScrn->scrnIndex, X_ERROR, + "GetBuffer timed out, resetting engine...\n"); + RADEONEngineReset( pScrn ); + RADEONEngineRestore( pScrn ); - RADEONWaitForFifo(pScrn, 7); - OUTREG(RADEON_DST_LINE_START, 0); - OUTREG(RADEON_DST_LINE_END, 0); - OUTREG(RADEON_DP_BRUSH_FRGD_CLR, 0xffffffff); - OUTREG(RADEON_DP_BRUSH_BKGD_CLR, 0x00000000); - OUTREG(RADEON_DP_SRC_FRGD_CLR, 0xffffffff); - OUTREG(RADEON_DP_SRC_BKGD_CLR, 0x00000000); - OUTREG(RADEON_DP_WRITE_MASK, 0xffffffff); + /* Always restart the engine when doing CP 2D acceleration */ + RADEONCP_RESET( pScrn, info ); + RADEONCP_START( pScrn, info ); + } +} - RADEONWaitForIdle(pScrn); +/* Flush the indirect buffer to the kernel for submission to the card. + */ +void RADEONCPFlushIndirect( ScrnInfoPtr pScrn ) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + drmBufPtr buffer = info->indirectBuffer; + int start = info->indirectStart; + int discard; + + if ( !buffer ) + return; + + if ( start == buffer->used ) + return; + + discard = ( buffer->used + RING_THRESHOLD > buffer->total ); + + drmRadeonFlushIndirectBuffer( info->drmFD, buffer->idx, + start, buffer->used, discard ); + + if ( discard ) { + info->indirectBuffer = RADEONCPGetBuffer( pScrn ); + info->indirectStart = 0; + } else { + info->indirectStart = buffer->used; + } +} + +/* Flush and release the indirect buffer. + */ +void RADEONCPReleaseIndirect( ScrnInfoPtr pScrn ) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + drmBufPtr buffer = info->indirectBuffer; + int start = info->indirectStart; + + info->indirectBuffer = NULL; + info->indirectStart = 0; + + if ( !buffer ) + return; + + drmRadeonFlushIndirectBuffer( info->drmFD, buffer->idx, + start, buffer->used, 1 ); } -#ifdef XF86DRI -/* FIXME: When direct rendering is enabled, we should use the CP to - draw 2D commands */ static void RADEONCPAccelInit(ScrnInfoPtr pScrn, XAAInfoRecPtr a) { - a->Flags = 0; + RADEONInfoPtr info = RADEONPTR(pScrn); - /* Sync */ #if 1 - a->Sync = RADEONWaitForIdle; + a->Flags = (PIXMAP_CACHE + | OFFSCREEN_PIXMAPS + | LINEAR_FRAMEBUFFER); #else - a->Sync = RADEONCCEWaitForIdle; + a->Flags = 0; /* GH: Do we really need this? */ #endif + /* Sync */ + a->Sync = RADEONCPWaitForIdle; + + /* If direct rendering is disabled, then do not enable any CP + acceleration routines */ + if (!info->directRenderingEnabled) return; + + /* Solid Filled Rectangle */ + a->PolyFillRectSolidFlags = 0; + a->SetupForSolidFill = RADEONCPSetupForSolidFill; + a->SubsequentSolidFillRect = RADEONCPSubsequentSolidFillRect; + + /* Screen-to-screen Copy */ + a->ScreenToScreenCopyFlags = 0; + a->SetupForScreenToScreenCopy = RADEONCPSetupForScreenToScreenCopy; + a->SubsequentScreenToScreenCopy = RADEONCPSubsequentScreenToScreenCopy; } #endif @@ -962,9 +1301,8 @@ Bool RADEONAccelInit(ScreenPtr pScreen) if (!(a = info->accel = XAACreateInfoRec())) return FALSE; #ifdef XF86DRI - /* FIXME: When direct rendering is enabled, we should use the CP to - draw 2D commands */ - if (info->CP2D) RADEONCPAccelInit(pScrn, a); + if (info->directRenderingEnabled) + RADEONCPAccelInit(pScrn, a); else #endif RADEONMMIOAccelInit(pScrn, a); diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c new file mode 100644 index 000000000..dd5fa4251 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.c @@ -0,0 +1,1449 @@ +/* $XFree86$ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, + * 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, 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 (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> + * Rickard E. Faith <faith@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + + + /* Driver data structures */ +#include "radeon.h" +#include "radeon_dri.h" +#include "radeon_reg.h" +#include "radeon_sarea.h" +#include "radeon_version.h" + + /* X and server generic header files */ +#include "xf86.h" +#include "windowstr.h" + + /* GLX/DRI/DRM definitions */ +#define _XF86DRI_SERVER_ +#include "GL/glxtokens.h" +#include "sarea.h" + + +/* Initialize the visual configs that are supported by the hardware. + These are combined with the visual configs that the indirect + rendering core supports, and the intersection is exported to the + client. */ +static Bool RADEONInitVisualConfigs(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + int numConfigs = 0; + __GLXvisualConfig *pConfigs = 0; + RADEONConfigPrivPtr pRADEONConfigs = 0; + RADEONConfigPrivPtr *pRADEONConfigPtrs = 0; + int i, accum, stencil; + + switch (info->CurrentLayout.pixel_code) { + case 8: /* 8bpp mode is not support */ + case 15: /* FIXME */ + case 24: /* FIXME */ + return FALSE; + +#define RADEON_USE_ACCUM 1 +#define RADEON_USE_STENCIL 1 + + case 16: + numConfigs = 1; + if (RADEON_USE_ACCUM) numConfigs *= 2; + if (RADEON_USE_STENCIL) numConfigs *= 2; + + if (!(pConfigs + = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), + numConfigs))) { + return FALSE; + } + if (!(pRADEONConfigs + = (RADEONConfigPrivPtr)xnfcalloc(sizeof(RADEONConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pRADEONConfigPtrs + = (RADEONConfigPrivPtr*)xnfcalloc(sizeof(RADEONConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pRADEONConfigs); + return FALSE; + } + + i = 0; + for (accum = 0; accum <= RADEON_USE_ACCUM; accum++) { + for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) { + pRADEONConfigPtrs[i] = &pRADEONConfigs[i]; + + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 5; + pConfigs[i].greenSize = 6; + pConfigs[i].blueSize = 5; + pConfigs[i].alphaSize = 0; + pConfigs[i].redMask = 0x0000F800; + pConfigs[i].greenMask = 0x000007E0; + pConfigs[i].blueMask = 0x0000001F; + pConfigs[i].alphaMask = 0x00000000; + if (accum) { /* Simulated in software */ + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 0; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + pConfigs[i].doubleBuffer = TRUE; + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 16; + pConfigs[i].depthSize = 16; + if (stencil) + pConfigs[i].stencilSize = 8; /* Simulated in software */ + else + pConfigs[i].stencilSize = 0; + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if (accum || stencil) { + pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; + } else { + pConfigs[i].visualRating = GLX_NONE_EXT; + } + pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + break; + case 32: + numConfigs = 1; + if (RADEON_USE_ACCUM) numConfigs *= 2; + if (RADEON_USE_STENCIL) numConfigs *= 2; + + if (!(pConfigs + = (__GLXvisualConfig*)xnfcalloc(sizeof(__GLXvisualConfig), + numConfigs))) { + return FALSE; + } + if (!(pRADEONConfigs + = (RADEONConfigPrivPtr)xnfcalloc(sizeof(RADEONConfigPrivRec), + numConfigs))) { + xfree(pConfigs); + return FALSE; + } + if (!(pRADEONConfigPtrs + = (RADEONConfigPrivPtr*)xnfcalloc(sizeof(RADEONConfigPrivPtr), + numConfigs))) { + xfree(pConfigs); + xfree(pRADEONConfigs); + return FALSE; + } + + i = 0; + for (accum = 0; accum <= RADEON_USE_ACCUM; accum++) { + for (stencil = 0; stencil <= RADEON_USE_STENCIL; stencil++) { + pRADEONConfigPtrs[i] = &pRADEONConfigs[i]; + + pConfigs[i].vid = -1; + pConfigs[i].class = -1; + pConfigs[i].rgba = TRUE; + pConfigs[i].redSize = 8; + pConfigs[i].greenSize = 8; + pConfigs[i].blueSize = 8; + pConfigs[i].alphaSize = 8; + pConfigs[i].redMask = 0x00FF0000; + pConfigs[i].greenMask = 0x0000FF00; + pConfigs[i].blueMask = 0x000000FF; + pConfigs[i].alphaMask = 0xFF000000; + if (accum) { /* Simulated in software */ + pConfigs[i].accumRedSize = 16; + pConfigs[i].accumGreenSize = 16; + pConfigs[i].accumBlueSize = 16; + pConfigs[i].accumAlphaSize = 16; + } else { + pConfigs[i].accumRedSize = 0; + pConfigs[i].accumGreenSize = 0; + pConfigs[i].accumBlueSize = 0; + pConfigs[i].accumAlphaSize = 0; + } + pConfigs[i].doubleBuffer = TRUE; + pConfigs[i].stereo = FALSE; + pConfigs[i].bufferSize = 24; + if (stencil) { + pConfigs[i].depthSize = 24; + pConfigs[i].stencilSize = 8; + } else { + pConfigs[i].depthSize = 24; + pConfigs[i].stencilSize = 0; + } + pConfigs[i].auxBuffers = 0; + pConfigs[i].level = 0; + if (accum || stencil) { + pConfigs[i].visualRating = GLX_SLOW_VISUAL_EXT; + } else { + pConfigs[i].visualRating = GLX_NONE_EXT; + } + pConfigs[i].transparentPixel = GLX_NONE; + pConfigs[i].transparentRed = 0; + pConfigs[i].transparentGreen = 0; + pConfigs[i].transparentBlue = 0; + pConfigs[i].transparentAlpha = 0; + pConfigs[i].transparentIndex = 0; + i++; + } + } + break; + } + + info->numVisualConfigs = numConfigs; + info->pVisualConfigs = pConfigs; + info->pVisualConfigsPriv = pRADEONConfigs; + GlxSetVisualConfigs(numConfigs, pConfigs, (void**)pRADEONConfigPtrs); + return TRUE; +} + +/* Create the Radeon-specific context information */ +static Bool RADEONCreateContext(ScreenPtr pScreen, VisualPtr visual, + drmContext hwContext, void *pVisualConfigPriv, + DRIContextType contextStore) +{ + /* Nothing yet */ + return TRUE; +} + +/* Destroy the Radeon-specific context information */ +static void RADEONDestroyContext(ScreenPtr pScreen, drmContext hwContext, + DRIContextType contextStore) +{ + /* Nothing yet */ +} + +/* Called when the X server is woken up to allow the last client's + context to be saved and the X server's context to be loaded. This is + not necessary for the Radeon since the client detects when it's + context is not currently loaded and then load's it itself. Since the + registers to start and stop the CP are privileged, only the X server + can start/stop the engine. */ +static void RADEONEnterServer(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + if (info->accel) info->accel->NeedToSync = TRUE; +} + +/* Called when the X server goes to sleep to allow the X server's + context to be saved and the last client's context to be loaded. This + is not necessary for the Radeon since the client detects when it's + context is not currently loaded and then load's it itself. Since the + registers to start and stop the CP are privileged, only the X server + can start/stop the engine. */ +static void RADEONLeaveServer(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RING_LOCALS; + + /* The CP is always running, but if we've generated any CP commands + * we must flush them to the kernel module now. + */ + if (info->CPInUse) { + RADEON_FLUSH_CACHE(); + RADEON_WAIT_UNTIL_IDLE(); + RADEONCPReleaseIndirect(pScrn); + + info->CPInUse = FALSE; + } +} + +/* Contexts can be swapped by the X server if necessary. This callback + is currently only used to perform any functions necessary when + entering or leaving the X server, and in the future might not be + necessary. */ +static void RADEONDRISwapContext(ScreenPtr pScreen, DRISyncType syncType, + DRIContextType oldContextType, + void *oldContext, + DRIContextType newContextType, + void *newContext) +{ + if ((syncType==DRI_3D_SYNC) && (oldContextType==DRI_2D_CONTEXT) && + (newContextType==DRI_2D_CONTEXT)) { /* Entering from Wakeup */ + RADEONEnterServer(pScreen); + } + if ((syncType==DRI_2D_SYNC) && (oldContextType==DRI_NO_CONTEXT) && + (newContextType==DRI_2D_CONTEXT)) { /* Exiting from Block Handler */ + RADEONLeaveServer(pScreen); + } +} + +#if 0 +/* 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 CARD32 radeon_mba_z16(RADEONInfoPtr info, + int x, int y) +{ + CARD32 pitch = info->frontPitch; + CARD32 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 CARD32 radeon_mba_z32(RADEONInfoPtr info, + int x, int y) +{ + CARD32 pitch = info->frontPitch; + CARD32 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_DEPTH16(_x, _y, d) \ + *(CARD16 *)(buf + radeon_mba_z16(info, (_x), (_y))) = (d) + +#define READ_DEPTH16(d, _x, _y) \ + (d) = *(CARD16 *)(buf + radeon_mba_z16(info, (_x), (_y))) + +/* 24 bit depth, 8 bit stencil depthbuffer functions */ +#define WRITE_DEPTH32(_x, _y, d) \ +do { \ + CARD32 tmp = *(CARD32 *)(buf + radeon_mba_z32(info, (_x), (_y))); \ + tmp &= 0xff000000; \ + tmp |= ((d) & 0x00ffffff); \ + *(CARD32 *)(buf + radeon_mba_z32(info, (_x), (_y))) = tmp; \ +} while (0) + +#define READ_DEPTH32(d, _x, _y) \ + d = *(CARD32 *)(buf + radeon_mba_z32(info, (_x), (_y))) & 0x00ffffff + +/* Screen to screen copy of data in the depth buffer */ +static void RADEONScreenToScreenCopyDepth(ScrnInfoPtr pScrn, + int x1, int y1, + int x2, int y2, + int w, int h) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + int xstart, xend, xdir; + int ystart, yend, ydir; + int x, y, d; + unsigned char *buf = info->FB + info->depthOffset; + + if (x1 < x2) xdir = -1, xstart = w-1, xend = 0; + else xdir = 1, xstart = 0, xend = w-1; + + if (y1 < y2) ydir = -1, ystart = h-1, yend = 0; + else ydir = 1, ystart = 0, yend = h-1; + + switch (pScrn->bitsPerPixel) { + case 16: + for (x = xstart; x != xend; x += xdir) { + for (y = ystart; y != yend; y += ydir) { + READ_DEPTH16(d, x1+x, y1+y); + WRITE_DEPTH16(x2+x, y2+y, d); + } + } + break; + case 32: + for (x = xstart; x != xend; x += xdir) { + for (y = ystart; y != yend; y += ydir) { + READ_DEPTH32(d, x1+x, y1+y); + WRITE_DEPTH32(x2+x, y2+y, d); + } + } + break; + default: break; + } +} +#endif + +/* Initialize the state of the back and depth buffers. */ +static void RADEONDRIInitBuffers(WindowPtr pWin, RegionPtr prgn, CARD32 index) +{ + /* FIXME: This routine needs to have acceleration turned on */ + ScreenPtr pScreen = pWin->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSAREAPrivPtr pSAREAPriv; + BoxPtr pbox; + int nbox; + int depth; + + /* FIXME: This should be based on the __GLXvisualConfig info */ + switch (pScrn->bitsPerPixel) { + case 8: depth = 0x000000ff; break; + case 16: depth = 0x0000ffff; break; + case 24: depth = 0x00ffffff; break; + case 32: depth = 0xffffffff; break; + default: depth = 0x00000000; break; + } + + /* FIXME: Copy XAAPaintWindow() and use REGION_TRANSLATE() */ + /* FIXME: Only initialize the back and depth buffers for contexts + that request them */ + + FLUSH_RING(); + + pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + + pbox = REGION_RECTS(prgn); + nbox = REGION_NUM_RECTS(prgn); + + for (; nbox; nbox--, pbox++) { + int ret; + + /* drmRadeonClear uses the clip rects to draw instead of the + rect passed to it; however, it uses the rect for the depth + clears */ + pSAREAPriv->boxes[0].x1 = pbox->x1; + pSAREAPriv->boxes[0].x2 = pbox->x2; + pSAREAPriv->boxes[0].y1 = pbox->y1; + pSAREAPriv->boxes[0].y2 = pbox->y2; + pSAREAPriv->nbox = 1; + + ret = drmRadeonClear(info->drmFD, + DRM_RADEON_BACK | DRM_RADEON_DEPTH, + pbox->x1, + pbox->y1, + pbox->x2 - pbox->x1, + pbox->y2 - pbox->y1, + 0, depth); + if (ret) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "DRIInitBuffers timed out, resetting engine...\n"); + RADEONEngineReset(pScrn); + RADEONEngineRestore(pScrn); + RADEONCP_RESET(pScrn, info); + RADEONCP_START(pScrn, info); + return; + } + } + + /* Mark the X server as the last context owner */ + pSAREAPriv->ctxOwner = DRIGetContext(pScreen); + + RADEONSelectBuffer(pScrn, RADEON_FRONT); + info->accel->NeedToSync = TRUE; +} + +/* Copy the back and depth buffers when the X server moves a window. + * + * This routine is a modified form of XAADoBitBlt with the calls to + * ScreenToScreenBitBlt built in. My routine has the prgnSrc as source + * instead of destination. My origin is upside down so the ydir cases + * are reversed. + */ +static void RADEONDRIMoveBuffers(WindowPtr pParent, DDXPointRec ptOldOrg, + RegionPtr prgnSrc, CARD32 index) +{ + ScreenPtr pScreen = pParent->drawable.pScreen; + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + BoxPtr pboxTmp, pboxNext, pboxBase; + DDXPointPtr pptTmp, pptNew2; + int xdir, ydir; + + int screenwidth = pScrn->virtualX; + int screenheight = pScrn->virtualY; + + BoxPtr pbox = REGION_RECTS(prgnSrc); + int nbox = REGION_NUM_RECTS(prgnSrc); + + BoxPtr pboxNew1 = 0; + BoxPtr pboxNew2 = 0; + DDXPointPtr pptNew1 = 0; + DDXPointPtr pptSrc = &ptOldOrg; + + int dx = pParent->drawable.x - ptOldOrg.x; + int dy = pParent->drawable.y - ptOldOrg.y; + + /* If the copy will overlap in Y, reverse the order */ + if (dy > 0) { + ydir = -1; + + if (nbox > 1) { + /* Keep ordering in each band, reverse order of bands */ + pboxNew1 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); + if (!pboxNew1) return; + pptNew1 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); + if (!pptNew1) { + DEALLOCATE_LOCAL(pboxNew1); + return; + } + pboxBase = pboxNext = pbox+nbox-1; + while (pboxBase >= pbox) { + while ((pboxNext >= pbox) && (pboxBase->y1 == pboxNext->y1)) + pboxNext--; + pboxTmp = pboxNext+1; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp <= pboxBase) { + *pboxNew1++ = *pboxTmp++; + *pptNew1++ = *pptTmp++; + } + pboxBase = pboxNext; + } + pboxNew1 -= nbox; + pbox = pboxNew1; + pptNew1 -= nbox; + pptSrc = pptNew1; + } + } else { + /* No changes required */ + ydir = 1; + } + + /* If the regions will overlap in X, reverse the order */ + if (dx > 0) { + xdir = -1; + + if (nbox > 1) { + /* reverse order of rects in each band */ + pboxNew2 = (BoxPtr)ALLOCATE_LOCAL(sizeof(BoxRec)*nbox); + pptNew2 = (DDXPointPtr)ALLOCATE_LOCAL(sizeof(DDXPointRec)*nbox); + if (!pboxNew2 || !pptNew2) { + if (pptNew2) DEALLOCATE_LOCAL(pptNew2); + if (pboxNew2) DEALLOCATE_LOCAL(pboxNew2); + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } + return; + } + pboxBase = pboxNext = pbox; + while (pboxBase < pbox+nbox) { + while ((pboxNext < pbox+nbox) + && (pboxNext->y1 == pboxBase->y1)) + pboxNext++; + pboxTmp = pboxNext; + pptTmp = pptSrc + (pboxTmp - pbox); + while (pboxTmp != pboxBase) { + *pboxNew2++ = *--pboxTmp; + *pptNew2++ = *--pptTmp; + } + pboxBase = pboxNext; + } + pboxNew2 -= nbox; + pbox = pboxNew2; + pptNew2 -= nbox; + pptSrc = pptNew2; + } + } else { + /* No changes are needed */ + xdir = 1; + } + + (*info->accel->SetupForScreenToScreenCopy)(pScrn, xdir, ydir, GXcopy, + -1, -1); + + for (; nbox-- ; pbox++) { + int x1 = pbox->x1; + int y1 = pbox->y1; + int destx = x1 + dx; + int desty = y1 + dy; + int w = pbox->x2 - x1 + 1; + int h = pbox->y2 - y1 + 1; + + if (destx < 0) x1 -= destx, w += destx, destx = 0; + if (desty < 0) y1 -= desty, h += desty, desty = 0; + if (destx + w > screenwidth) w = screenwidth - destx; + if (desty + h > screenheight) h = screenheight - desty; + + if (w <= 0) continue; + if (h <= 0) continue; + + RADEONSelectBuffer(pScrn, RADEON_BACK); + (*info->accel->SubsequentScreenToScreenCopy)(pScrn, + x1, y1, + destx, desty, + w, h); + RADEONSelectBuffer(pScrn, RADEON_DEPTH); +#if 0 + /* FIXME: This is disabled because it is much too slow */ + RADEONScreenToScreenCopyDepth(pScrn, + x1, y1, + destx, desty, + w, h); +#endif + } + + RADEONSelectBuffer(pScrn, RADEON_FRONT); + + if (pboxNew2) { + DEALLOCATE_LOCAL(pptNew2); + DEALLOCATE_LOCAL(pboxNew2); + } + if (pboxNew1) { + DEALLOCATE_LOCAL(pptNew1); + DEALLOCATE_LOCAL(pboxNew1); + } + + info->accel->NeedToSync = TRUE; +} + +/* Initialize the AGP state. Request memory for use in AGP space, and + initialize the Radeon registers to point to that memory. */ +static Bool RADEONDRIAgpInit(RADEONInfoPtr info, ScreenPtr pScreen) +{ + unsigned char *RADEONMMIO = info->MMIO; + unsigned long cntl; + unsigned long mode; + unsigned int vendor, device; + int ret; + int s, l; + + if (drmAgpAcquire(info->drmFD) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not available\n"); + return FALSE; + } + + /* Modify the mode if the default mode is + not appropriate for this particular + combination of graphics card and AGP + chipset. */ + + mode = drmAgpGetMode(info->drmFD); /* Default mode */ + vendor = drmAgpVendorId(info->drmFD); + device = drmAgpDeviceId(info->drmFD); + + mode &= ~RADEON_AGP_MODE_MASK; + switch (info->agpMode) { + case 4: mode |= RADEON_AGP_4X_MODE; + case 2: mode |= RADEON_AGP_2X_MODE; + case 1: default: mode |= RADEON_AGP_1X_MODE; + } + + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", + mode, vendor, device, + info->PciInfo->vendor, + info->PciInfo->chipType); + + if (drmAgpEnable(info->drmFD, mode) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] AGP not enabled\n"); + drmAgpRelease(info->drmFD); + return FALSE; + } + + info->agpOffset = 0; + + if ((ret = drmAgpAlloc(info->drmFD, info->agpSize*1024*1024, 0, NULL, + &info->agpMemHandle)) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Out of memory (%d)\n", ret); + drmAgpRelease(info->drmFD); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] %d kB allocated with handle 0x%08x\n", + info->agpSize*1024, info->agpMemHandle); + + if (drmAgpBind(info->drmFD, + info->agpMemHandle, info->agpOffset) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not bind\n"); + drmAgpFree(info->drmFD, info->agpMemHandle); + drmAgpRelease(info->drmFD); + return FALSE; + } + + /* Initialize the CP ring buffer data */ + info->ringStart = info->agpOffset; + info->ringMapSize = info->ringSize*1024*1024 + 4096; + info->ringSizeLog2QW = RADEONMinBits(info->ringSize*1024*1024/8)-1; + + info->ringReadOffset = info->ringStart + info->ringMapSize; + info->ringReadMapSize = 4096; + + /* Reserve space for vertex/indirect buffers */ + info->bufStart = info->ringReadOffset + info->ringReadMapSize; + info->bufMapSize = info->bufSize*1024*1024; + + /* Reserve the rest for AGP textures */ + info->agpTexStart = info->bufStart + info->bufMapSize; + s = (info->agpSize*1024*1024 - info->agpTexStart); + l = RADEONMinBits((s-1) / RADEON_NR_TEX_REGIONS); + if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + info->agpTexMapSize = (s >> l) << l; + info->log2AGPTexGran = l; + + if (drmAddMap(info->drmFD, info->ringStart, info->ringMapSize, + DRM_AGP, DRM_READ_ONLY, &info->ringHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add ring mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] ring handle = 0x%08lx\n", info->ringHandle); + + if (drmMap(info->drmFD, info->ringHandle, info->ringMapSize, + (drmAddressPtr)&info->ring) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "[agp] Could not map ring\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Ring mapped at 0x%08lx\n", + (unsigned long)info->ring); + + if (drmAddMap(info->drmFD, info->ringReadOffset, info->ringReadMapSize, + DRM_AGP, DRM_READ_ONLY, &info->ringReadPtrHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add ring read ptr mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] ring read ptr handle = 0x%08lx\n", + info->ringReadPtrHandle); + + if (drmMap(info->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, + (drmAddressPtr)&info->ringReadPtr) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map ring read ptr\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Ring read ptr mapped at 0x%08lx\n", + (unsigned long)info->ringReadPtr); + + if (drmAddMap(info->drmFD, info->bufStart, info->bufMapSize, + DRM_AGP, 0, &info->bufHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add vertex/indirect buffers mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] vertex/indirect buffers handle = 0x%08lx\n", + info->bufHandle); + + if (drmMap(info->drmFD, info->bufHandle, info->bufMapSize, + (drmAddressPtr)&info->buf) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map vertex/indirect buffers\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] Vertex/indirect buffers mapped at 0x%08lx\n", + (unsigned long)info->buf); + + if (drmAddMap(info->drmFD, info->agpTexStart, info->agpTexMapSize, + DRM_AGP, 0, &info->agpTexHandle) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not add AGP texture map mapping\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] AGP texture map handle = 0x%08lx\n", + info->agpTexHandle); + + if (drmMap(info->drmFD, info->agpTexHandle, info->agpTexMapSize, + (drmAddressPtr)&info->agpTex) < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Could not map AGP texture map\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[agp] AGP Texture map mapped at 0x%08lx\n", + (unsigned long)info->agpTex); + + /* Initialize Radeon's AGP registers */ + cntl = INREG(RADEON_AGP_CNTL); + cntl &= ~RADEON_AGP_APER_SIZE_MASK; + switch (info->agpSize) { + case 256: cntl |= RADEON_AGP_APER_SIZE_256MB; break; + case 128: cntl |= RADEON_AGP_APER_SIZE_128MB; break; + case 64: cntl |= RADEON_AGP_APER_SIZE_64MB; break; + case 32: cntl |= RADEON_AGP_APER_SIZE_32MB; break; + case 16: cntl |= RADEON_AGP_APER_SIZE_16MB; break; + case 8: cntl |= RADEON_AGP_APER_SIZE_8MB; break; + case 4: cntl |= RADEON_AGP_APER_SIZE_4MB; break; + default: + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[agp] Illegal aperture size %d kB\n", + info->agpSize*1024); + return FALSE; + } + + /* Ring buffer is at AGP offset 0 */ + OUTREG(RADEON_AGP_BASE, info->ringHandle); + OUTREG(RADEON_AGP_CNTL, cntl); + + return TRUE; +} + +#if 0 +/* Fake the vertex buffers for PCI cards. */ +static Bool RADEONDRIPciInit(RADEONInfoPtr info, ScreenPtr pScreen) +{ + info->bufStart = 0; + info->bufMapSize = info->bufSize*1024*1024; + + return TRUE; +} +#endif + +/* Add a map for the MMIO registers that will be accessed by any + DRI-based clients. */ +static Bool RADEONDRIMapInit(RADEONInfoPtr info, ScreenPtr pScreen) +{ + /* Map registers */ + info->registerSize = RADEON_MMIOSIZE; + if (drmAddMap(info->drmFD, info->MMIOAddr, info->registerSize, + DRM_REGISTERS, DRM_READ_ONLY, &info->registerHandle) < 0) { + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] register handle = 0x%08lx\n", info->registerHandle); + + return TRUE; +} + +/* Initialize the kernel data structures. */ +static int RADEONDRIKernelInit(RADEONInfoPtr info, ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + int cpp = info->CurrentLayout.pixel_bytes; + drmRadeonInit drmInfo; + + drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); + drmInfo.is_pci = info->IsPCI; + drmInfo.cp_mode = info->CPMode; + drmInfo.agp_size = info->agpSize*1024*1024; + drmInfo.ring_size = info->ringSize*1024*1024; + drmInfo.usec_timeout = info->CPusecTimeout; + + drmInfo.fb_bpp = info->CurrentLayout.pixel_code; + drmInfo.depth_bpp = info->CurrentLayout.pixel_code; + + drmInfo.front_offset = info->frontOffset; + drmInfo.front_pitch = info->frontPitch * cpp; + drmInfo.back_offset = info->backOffset; + drmInfo.back_pitch = info->backPitch * cpp; + drmInfo.depth_offset = info->depthOffset; + drmInfo.depth_pitch = info->depthPitch * cpp; + + drmInfo.fb_offset = info->LinearAddr; + drmInfo.mmio_offset = info->registerHandle; + drmInfo.ring_offset = info->ringHandle; + drmInfo.ring_rptr_offset = info->ringReadPtrHandle; + drmInfo.buffers_offset = info->bufHandle; + drmInfo.agp_textures_offset = info->agpTexHandle; + + if (drmRadeonInitCP(info->drmFD, &drmInfo) < 0) return FALSE; + + /* drmRadeonInitCP does an engine reset, which resets some engine + registers back to their default values, so we need to restore + those engine register here. */ + RADEONEngineRestore(pScrn); + + return TRUE; +} + +/* Add a map for the vertex buffers that will be accessed by any + DRI-based clients. */ +static Bool RADEONDRIBufInit(RADEONInfoPtr info, ScreenPtr pScreen) +{ + /* Initialize vertex buffers */ + if ((info->bufNumBufs = drmAddBufs(info->drmFD, + info->bufMapSize / RADEON_BUFFER_SIZE, + RADEON_BUFFER_SIZE, + DRM_AGP_BUFFER, + info->bufStart)) <= 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Could not create vertex/indirect buffers list\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Added %d %d byte vertex/indirect buffers\n", + info->bufNumBufs, RADEON_BUFFER_SIZE); + + if (!(info->buffers = drmMapBufs(info->drmFD))) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "[drm] Failed to map vertex/indirect buffers list\n"); + return FALSE; + } + xf86DrvMsg(pScreen->myNum, X_INFO, + "[drm] Mapped %d vertex/indirect buffers\n", + info->buffers->count); + + return TRUE; +} + +/* Initialize the CP state, and start the CP (if used by the X server) */ +static void RADEONDRICPInit(ScrnInfoPtr pScrn) +{ + RADEONInfoPtr info = RADEONPTR(pScrn); + + /* Turn on bus mastering */ + info->BusCntl &= ~RADEON_BUS_MASTER_DIS; + + /* Make sure the CP is on for the X server */ + RADEONCP_START(pScrn, info); + RADEONSelectBuffer(pScrn, RADEON_FRONT); +} + +/* Initialize the DRI specific hardware state stored in the SAREA. + Currently, this involves setting up the 3D hardware state. */ +static void RADEONDRISAREAInit(ScreenPtr pScreen, + RADEONSAREAPrivPtr pSAREAPriv) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + radeon_context_regs_t *ctx; + radeon_texture_regs_t *tex; + CARD32 color_fmt, depth_fmt; + int i; + + switch (info->CurrentLayout.pixel_code) { + case 16: + color_fmt = RADEON_COLOR_FORMAT_RGB565; + depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + break; + case 32: + color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + break; + default: + xf86DrvMsg(pScreen->myNum, X_ERROR, + "RADEONDRISAREAInit failed: Unsupported depth (%d bpp)\n", + info->CurrentLayout.pixel_code); + return; + } + + /* Initialize the context state */ + ctx = &pSAREAPriv->ContextState; + + ctx->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); + + ctx->pp_fog_color = ((0x00000000 & RADEON_FOG_COLOR_MASK) | + RADEON_FOG_VERTEX | + RADEON_FOG_USE_DEPTH); + + ctx->re_solid_color = 0x00000000; + + ctx->rb3d_blendcntl = (RADEON_SRC_BLEND_GL_ONE | + RADEON_DST_BLEND_GL_ZERO ); + + ctx->rb3d_depthoffset = info->depthOffset; + + ctx->rb3d_depthpitch = ((info->depthPitch & RADEON_DEPTHPITCH_MASK) | + RADEON_DEPTH_ENDIAN_NO_SWAP); + + ctx->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); + + ctx->pp_cntl = (RADEON_SCISSOR_ENABLE | + RADEON_ANTI_ALIAS_NONE); + + ctx->rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | + color_fmt | + RADEON_ZBLOCK16); + + ctx->rb3d_coloroffset = (info->backOffset & RADEON_COLOROFFSET_MASK); + + ctx->re_width_height = ((0x7ff << RADEON_RE_WIDTH_SHIFT) | + (0x7ff << RADEON_RE_HEIGHT_SHIFT)); + + ctx->rb3d_colorpitch = ((info->backPitch & RADEON_COLORPITCH_MASK) | + RADEON_COLOR_ENDIAN_NO_SWAP); + + ctx->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_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_8TH_PIX); + + ctx->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); + + ctx->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); + + ctx->re_line_state = ((0 << RADEON_LINE_CURRENT_PTR_SHIFT) | + (0 << RADEON_LINE_CURRENT_COUNT_SHIFT)); + + ctx->se_line_width = 0x0000000; + + ctx->pp_lum_matrix = 0x00000000; + + ctx->pp_rot_matrix_0 = 0x00000000; + ctx->pp_rot_matrix_1 = 0x00000000; + + ctx->rb3d_stencilrefmask = ((0x00 << RADEON_STENCIL_REF_SHIFT) | + (0xff << RADEON_STENCIL_MASK_SHIFT) | + (0xff << RADEON_STENCIL_WRITEMASK_SHIFT)); + + ctx->rb3d_ropcntl = 0x00000000; + ctx->rb3d_planemask = 0xffffffff; + + ctx->se_vport_xscale = 0x00000000; + ctx->se_vport_xoffset = 0x00000000; + ctx->se_vport_yscale = 0x00000000; + ctx->se_vport_yoffset = 0x00000000; + ctx->se_vport_zscale = 0x00000000; + ctx->se_vport_zoffset = 0x00000000; + + ctx->se_cntl_status = (RADEON_VC_NO_SWAP | + RADEON_TCL_BYPASS); + +#ifdef TCL_ENABLE + /* FIXME: Obviously these need to be properly initialized */ + ctx->se_tcl_material_emmissive.red = 0x00000000; + ctx->se_tcl_material_emmissive.green = 0x00000000; + ctx->se_tcl_material_emmissive.blue = 0x00000000; + ctx->se_tcl_material_emmissive.alpha = 0x00000000; + + ctx->se_tcl_material_ambient.red = 0x00000000; + ctx->se_tcl_material_ambient.green = 0x00000000; + ctx->se_tcl_material_ambient.blue = 0x00000000; + ctx->se_tcl_material_ambient.alpha = 0x00000000; + + ctx->se_tcl_material_diffuse.red = 0x00000000; + ctx->se_tcl_material_diffuse.green = 0x00000000; + ctx->se_tcl_material_diffuse.blue = 0x00000000; + ctx->se_tcl_material_diffuse.alpha = 0x00000000; + + ctx->se_tcl_material_specular.red = 0x00000000; + ctx->se_tcl_material_specular.green = 0x00000000; + ctx->se_tcl_material_specular.blue = 0x00000000; + ctx->se_tcl_material_specular.alpha = 0x00000000; + + ctx->se_tcl_shininess = 0x00000000; + ctx->se_tcl_output_vtx_fmt = 0x00000000; + ctx->se_tcl_output_vtx_sel = 0x00000000; + ctx->se_tcl_matrix_select_0 = 0x00000000; + ctx->se_tcl_matrix_select_1 = 0x00000000; + ctx->se_tcl_ucp_vert_blend_ctl = 0x00000000; + ctx->se_tcl_texture_proc_ctl = 0x00000000; + ctx->se_tcl_light_model_ctl = 0x00000000; + for ( i = 0 ; i < 4 ; i++ ) { + ctx->se_tcl_per_light_ctl[i] = 0x00000000; + } +#endif + + ctx->re_top_left = ((0 << RADEON_RE_LEFT_SHIFT) | + (0 << RADEON_RE_TOP_SHIFT) ); + + ctx->re_misc = ((0 << RADEON_STIPPLE_X_OFFSET_SHIFT) | + (0 << RADEON_STIPPLE_Y_OFFSET_SHIFT) | + RADEON_STIPPLE_LITTLE_BIT_ORDER); + + /* Initialize the texture state */ + for (i = 0; i < RADEON_MAX_TEXTURE_UNITS; i++) { + tex = &pSAREAPriv->TexState[i]; + + tex->pp_txfilter = 0x00000000; + tex->pp_txformat = 0x00000000; + tex->pp_txoffset = 0x00000000; + tex->pp_txcblend = 0x00000000; + tex->pp_txablend = 0x00000000; + tex->pp_tfactor = 0x00000000; + tex->pp_border_color = 0x00000000; + } + + /* Mark the context as dirty */ + pSAREAPriv->dirty = RADEON_UPLOAD_ALL; + + /* Mark the X server as the last context owner */ + pSAREAPriv->ctxOwner = DRIGetContext(pScreen); +} + +/* Initialize the screen-specific data structures for the DRI and the + Radeon. This is the main entry point to the device-specific + initialization code. It calls device-independent DRI functions to + create the DRI data structures and initialize the DRI state. */ +Bool RADEONDRIScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + DRIInfoPtr pDRIInfo; + RADEONDRIPtr pRADEONDRI; + int major, minor, patch; + drmVersionPtr version; + + /* Check that the GLX, DRI, and DRM modules have been loaded by testing + * for known symbols in each module. */ + if (!xf86LoaderCheckSymbol("GlxSetVisualConfigs")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIScreenInit")) return FALSE; + if (!xf86LoaderCheckSymbol("drmAvailable")) return FALSE; + if (!xf86LoaderCheckSymbol("DRIQueryVersion")) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "RADEONDRIScreenInit failed (libdri.a too old)\n"); + return FALSE; + } + + /* Check the DRI version */ + DRIQueryVersion(&major, &minor, &patch); + if (major != 3 || minor != 0 || patch < 0) { + xf86DrvMsg(pScreen->myNum, X_ERROR, + "RADEONDRIScreenInit failed " + "(DRI version = %d.%d.%d, expected 3.0.x). " + "Disabling DRI.\n", + major, minor, patch); + return FALSE; + } + + switch (info->CurrentLayout.pixel_code) { + case 8: + /* These modes are not supported (yet). */ + case 15: + case 24: + return FALSE; + + /* Only 16 and 32 color depths are supports currently. */ + case 16: + case 32: + break; + } + + /* Create the DRI data structure, and fill it in before calling the + DRIScreenInit(). */ + if (!(pDRIInfo = DRICreateInfoRec())) return FALSE; + + info->pDRIInfo = pDRIInfo; + pDRIInfo->drmDriverName = RADEON_DRIVER_NAME; + pDRIInfo->clientDriverName = RADEON_DRIVER_NAME; + pDRIInfo->busIdString = xalloc(64); + sprintf(pDRIInfo->busIdString, + "PCI:%d:%d:%d", + info->PciInfo->bus, + info->PciInfo->device, + info->PciInfo->func); + pDRIInfo->ddxDriverMajorVersion = RADEON_VERSION_MAJOR; + pDRIInfo->ddxDriverMinorVersion = RADEON_VERSION_MINOR; + pDRIInfo->ddxDriverPatchVersion = RADEON_VERSION_PATCH; + pDRIInfo->frameBufferPhysicalAddress = info->LinearAddr; + pDRIInfo->frameBufferSize = info->FbMapSize; + pDRIInfo->frameBufferStride = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + pDRIInfo->ddxDrawableTableEntry = RADEON_MAX_DRAWABLES; + pDRIInfo->maxDrawableTableEntry = (SAREA_MAX_DRAWABLES + < RADEON_MAX_DRAWABLES + ? SAREA_MAX_DRAWABLES + : RADEON_MAX_DRAWABLES); + +#ifdef NOT_DONE + /* FIXME: Need to extend DRI protocol to pass this size back to + * client for SAREA mapping that includes a device private record + */ + pDRIInfo->SAREASize = + ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000); /* round to page */ + /* + shared memory device private rec */ +#else + /* For now the mapping works by using a fixed size defined + * in the SAREA header + */ + if (sizeof(XF86DRISAREARec)+sizeof(RADEONSAREAPriv)>SAREA_MAX) { + ErrorF("Data does not fit in SAREA\n"); + return FALSE; + } + pDRIInfo->SAREASize = SAREA_MAX; +#endif + + if (!(pRADEONDRI = (RADEONDRIPtr)xnfcalloc(sizeof(RADEONDRIRec),1))) { + DRIDestroyInfoRec(info->pDRIInfo); + info->pDRIInfo = NULL; + return FALSE; + } + pDRIInfo->devPrivate = pRADEONDRI; + pDRIInfo->devPrivateSize = sizeof(RADEONDRIRec); + pDRIInfo->contextSize = sizeof(RADEONDRIContextRec); + + pDRIInfo->CreateContext = RADEONCreateContext; + pDRIInfo->DestroyContext = RADEONDestroyContext; + pDRIInfo->SwapContext = RADEONDRISwapContext; + pDRIInfo->InitBuffers = RADEONDRIInitBuffers; + pDRIInfo->MoveBuffers = RADEONDRIMoveBuffers; + pDRIInfo->bufferRequests = DRI_ALL_WINDOWS; + + if (!DRIScreenInit(pScreen, pDRIInfo, &info->drmFD)) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "DRIScreenInit failed!\n"); + xfree(pDRIInfo->devPrivate); + pDRIInfo->devPrivate = NULL; + DRIDestroyInfoRec(pDRIInfo); + pDRIInfo = NULL; + return FALSE; + } + + /* Check the radeon DRM version */ + version = drmGetVersion(info->drmFD); + if (version) { + if (version->version_major != 1 || + version->version_minor != 0 || + version->version_patchlevel < 0) { + /* incompatible drm version */ + xf86DrvMsg(pScreen->myNum, X_ERROR, + "RADEONDRIScreenInit failed " + "(DRM version = %d.%d.%d, expected 1.0.x). " + "Disabling DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + RADEONDRICloseScreen(pScreen); + return FALSE; + } + drmFreeVersion(version); + } + + /* Initialize AGP */ + if (!info->IsPCI && !RADEONDRIAgpInit(info, pScreen)) { + RADEONDRICloseScreen(pScreen); + return FALSE; + } +#if 0 + /* Initialize PCI */ + if (info->IsPCI && !RADEONDRIPciInit(info, pScreen)) { + RADEONDRICloseScreen(pScreen); + return FALSE; + } +#else + if (info->IsPCI) { + xf86DrvMsg(pScreen->myNum, X_ERROR, "PCI cards not yet supported\n"); + RADEONDRICloseScreen(pScreen); + return FALSE; + } +#endif + + /* DRIScreenInit doesn't add all the + common mappings. Add additional + mappings here. */ + if (!RADEONDRIMapInit(info, pScreen)) { + RADEONDRICloseScreen(pScreen); + return FALSE; + } + + /* FIXME: When are these mappings unmapped? */ + + if (!RADEONInitVisualConfigs(pScreen)) { + RADEONDRICloseScreen(pScreen); + return FALSE; + } + xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Visual configs initialized\n"); + + return TRUE; +} + +/* Finish initializing the device-dependent DRI state, and call + DRIFinishScreenInit() to complete the device-independent DRI + initialization. */ +Bool RADEONDRIFinishScreenInit(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + RADEONSAREAPrivPtr pSAREAPriv; + RADEONDRIPtr pRADEONDRI; + + info->pDRIInfo->driverSwapMethod = DRI_HIDE_X_CONTEXT; + /* info->pDRIInfo->driverSwapMethod = DRI_SERVER_SWAP; */ + + /* NOTE: DRIFinishScreenInit must be called before *DRIKernelInit + because *DRIKernelInit requires that the hardware lock is held by + the X server, and the first time the hardware lock is grabbed is + in DRIFinishScreenInit. */ + if (!DRIFinishScreenInit(pScreen)) { + RADEONDRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize the kernel data structures */ + if (!RADEONDRIKernelInit(info, pScreen)) { + RADEONDRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize the vertex buffers list */ + if (!info->IsPCI && !RADEONDRIBufInit(info, pScreen)) { + RADEONDRICloseScreen(pScreen); + return FALSE; + } + + /* Initialize and start the CP if required */ + RADEONDRICPInit(pScrn); + + /* Initialize the SAREA private data structure */ + pSAREAPriv = (RADEONSAREAPrivPtr)DRIGetSAREAPrivate(pScreen); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + RADEONDRISAREAInit(pScreen, pSAREAPriv); + + pRADEONDRI = (RADEONDRIPtr)info->pDRIInfo->devPrivate; + + pRADEONDRI->deviceID = info->Chipset; + pRADEONDRI->width = pScrn->virtualX; + pRADEONDRI->height = pScrn->virtualY; + pRADEONDRI->depth = pScrn->depth; + pRADEONDRI->bpp = pScrn->bitsPerPixel; + + pRADEONDRI->IsPCI = info->IsPCI; + pRADEONDRI->AGPMode = info->agpMode; + + pRADEONDRI->frontOffset = info->frontOffset; + pRADEONDRI->frontPitch = info->frontPitch; + pRADEONDRI->backOffset = info->backOffset; + pRADEONDRI->backPitch = info->backPitch; + pRADEONDRI->depthOffset = info->depthOffset; + pRADEONDRI->depthPitch = info->depthPitch; + pRADEONDRI->textureOffset = info->textureOffset; + pRADEONDRI->textureSize = info->textureSize; + pRADEONDRI->log2TexGran = info->log2TexGran; + + pRADEONDRI->registerHandle = info->registerHandle; + pRADEONDRI->registerSize = info->registerSize; + + pRADEONDRI->statusHandle = info->ringReadPtrHandle; + pRADEONDRI->statusSize = info->ringReadMapSize; + + pRADEONDRI->agpTexHandle = info->agpTexHandle; + pRADEONDRI->agpTexMapSize = info->agpTexMapSize; + pRADEONDRI->log2AGPTexGran = info->log2AGPTexGran; + pRADEONDRI->agpTexOffset = info->agpTexStart; + + return TRUE; +} + +/* The screen is being closed, so clean up any state and free any + resources used by the DRI. */ +void RADEONDRICloseScreen(ScreenPtr pScreen) +{ + ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum]; + RADEONInfoPtr info = RADEONPTR(pScrn); + + /* Stop the CP */ + if (info->directRenderingEnabled) { + RADEONCP_STOP(pScrn, info); + } + + /* De-allocate vertex buffers */ + if (info->buffers) { + drmUnmapBufs(info->buffers); + info->buffers = NULL; + } + + /* De-allocate all kernel resources */ + drmRadeonCleanupCP(info->drmFD); + + /* De-allocate all AGP resources */ + if (info->agpTex) { + drmUnmap(info->agpTex, info->agpTexMapSize); + info->agpTex = NULL; + } + if (info->buf) { + drmUnmap(info->buf, info->bufMapSize); + info->buf = NULL; + } + if (info->ringReadPtr) { + drmUnmap(info->ringReadPtr, info->ringReadMapSize); + info->ringReadPtr = NULL; + } + if (info->ring) { + drmUnmap(info->ring, info->ringMapSize); + info->ring = NULL; + } + if (info->agpMemHandle) { + drmAgpUnbind(info->drmFD, info->agpMemHandle); + drmAgpFree(info->drmFD, info->agpMemHandle); + info->agpMemHandle = 0; + drmAgpRelease(info->drmFD); + } + + /* De-allocate all DRI resources */ + DRICloseScreen(pScreen); + + /* De-allocate all DRI data structures */ + if (info->pDRIInfo) { + if (info->pDRIInfo->devPrivate) { + xfree(info->pDRIInfo->devPrivate); + info->pDRIInfo->devPrivate = NULL; + } + DRIDestroyInfoRec(info->pDRIInfo); + info->pDRIInfo = NULL; + } + if (info->pVisualConfigs) { + xfree(info->pVisualConfigs); + info->pVisualConfigs = NULL; + } + if (info->pVisualConfigsPriv) { + xfree(info->pVisualConfigsPriv); + info->pVisualConfigsPriv = NULL; + } +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h new file mode 100644 index 000000000..b8116355e --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dri.h @@ -0,0 +1,101 @@ +/* $XFree86$ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, + * 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, 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 (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> + * Rickard E. Faith <faith@valinux.com> + * + */ + +#ifndef _RADEON_DRI_ +#define _RADEON_DRI_ + +#include "xf86drm.h" +#include "xf86drmRadeon.h" + +/* DRI Driver defaults */ +#define RADEON_DEFAULT_CP_PIO_MODE RADEON_CSQ_PRIPIO_INDPIO +#define RADEON_DEFAULT_CP_BM_MODE RADEON_CSQ_PRIBM_INDBM +#define RADEON_DEFAULT_AGP_MODE 2 +#define RADEON_DEFAULT_AGP_SIZE 8 /* MB (must be a power of 2 and > 4MB) */ +#define RADEON_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */ +#define RADEON_DEFAULT_BUFFER_SIZE 2 /* MB (must be page aligned) */ +#define RADEON_DEFAULT_AGP_TEX_SIZE 1 /* MB (must be page aligned) */ + +#define RADEON_DEFAULT_CP_TIMEOUT 10000 /* usecs */ + +#define RADEON_AGP_MAX_MODE 4 + +#define RADEON_CARD_TYPE_RADEON 1 + +/* Buffer are aligned on 4096 byte boundaries */ +#define RADEON_BUFFER_ALIGN 0x00000fff + +#define RADEONCP_USE_RING_BUFFER(m) \ +(((m) == RADEON_CSQ_PRIBM_INDDIS) || \ + ((m) == RADEON_CSQ_PRIBM_INDBM)) + +typedef struct { + /* DRI screen private data */ + int deviceID; /* PCI device ID */ + int width; /* Width in pixels of display */ + int height; /* Height in scanlines of display */ + int depth; /* Depth of display (8, 15, 16, 24) */ + int bpp; /* Bit depth of display (8, 16, 24, 32) */ + + int IsPCI; /* Current card is a PCI card */ + int AGPMode; + + int frontOffset; /* Start of front buffer */ + int frontPitch; + int backOffset; /* Start of shared back buffer */ + int backPitch; + int depthOffset; /* Start of shared depth buffer */ + int depthPitch; + int textureOffset;/* Start of texture data in frame buffer */ + int textureSize; + int log2TexGran; + + /* MMIO register data */ + drmHandle registerHandle; + drmSize registerSize; + + /* CP in-memory status information */ + drmHandle statusHandle; + drmSize statusSize; + + /* CP AGP Texture data */ + drmHandle agpTexHandle; + drmSize agpTexMapSize; + int log2AGPTexGran; + int agpTexOffset; +} RADEONDRIRec, *RADEONDRIPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h new file mode 100644 index 000000000..9225c5cda --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_dripriv.h @@ -0,0 +1,57 @@ +/* $XFree86$ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, + * 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, 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 (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> + * Rickard E. Faith <faith@valinux.com> + * + */ + +#ifndef _RADEON_DRIPRIV_H_ +#define _RADEON_DRIPRIV_H_ + +#include "GL/glxint.h" + +#define RADEON_MAX_DRAWABLES 256 + +extern void GlxSetVisualConfigs(int nconfigs, __GLXvisualConfig *configs, + void **configprivs); + +typedef struct { + /* Nothing here yet */ + int dummy; +} RADEONConfigPrivRec, *RADEONConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} RADEONDRIContextRec, *RADEONDRIContextPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c index 448587094..8853603ac 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_driver.c @@ -66,8 +66,8 @@ #ifdef XF86DRI #define _XF86DRI_SERVER_ -#include "r128_dri.h" -#include "r128_sarea.h" +#include "radeon_dri.h" +#include "radeon_sarea.h" #endif #define USE_FB /* not until overlays */ @@ -130,9 +130,7 @@ typedef enum { OPTION_AGP_MODE, OPTION_AGP_SIZE, OPTION_RING_SIZE, - OPTION_VERT_SIZE, - OPTION_VBUF_SIZE, - OPTION_USE_CP_2D, + OPTION_BUFFER_SIZE, #endif #ifdef ENABLE_FLAT_PANEL /* Note: Radeon flat panel support has been disabled for now */ @@ -154,14 +152,11 @@ OptionInfoRec RADEONOptions[] = { #ifdef XF86DRI { OPTION_IS_PCI, "ForcePCIMode", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_CP_PIO, "CPPIOMode", OPTV_BOOLEAN, {0}, FALSE }, - { OPTION_NO_SECURITY, "CPNoSecurity", OPTV_BOOLEAN, {0}, FALSE }, { OPTION_USEC_TIMEOUT, "CPusecTimeout", OPTV_INTEGER, {0}, FALSE }, { OPTION_AGP_MODE, "AGPMode", OPTV_INTEGER, {0}, FALSE }, { OPTION_AGP_SIZE, "AGPSize", OPTV_INTEGER, {0}, FALSE }, { OPTION_RING_SIZE, "RingSize", OPTV_INTEGER, {0}, FALSE }, - { OPTION_VERT_SIZE, "VBListSize", OPTV_INTEGER, {0}, FALSE }, - { OPTION_VBUF_SIZE, "VBSize", OPTV_INTEGER, {0}, FALSE }, - { OPTION_USE_CP_2D, "UseCPfor2D", OPTV_BOOLEAN, {0}, FALSE }, + { OPTION_BUFFER_SIZE, "BufferSize", OPTV_INTEGER, {0}, FALSE }, #endif #ifdef ENABLE_FLAT_PANEL /* Note: Radeon flat panel support has been disabled for now */ @@ -1091,14 +1086,13 @@ static Bool RADEONPreInitAccel(ScrnInfoPtr pScrn) static Bool RADEONPreInitInt10(ScrnInfoPtr pScrn) { RADEONInfoPtr info = RADEONPTR(pScrn); -#if 1 + if (xf86LoadSubModule(pScrn, "int10")) { xf86Int10InfoPtr pInt; xf86DrvMsg(pScrn->scrnIndex,X_INFO,"initializing int10\n"); pInt = xf86InitInt10(info->pEnt->index); xf86FreeInt10(pInt); } -#endif return TRUE; } @@ -1116,30 +1110,12 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) info->CPMode = RADEON_DEFAULT_CP_BM_MODE; } - if (xf86ReturnOptValBool(RADEONOptions, OPTION_USE_CP_2D, FALSE)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, "Using CP for 2D\n"); - info->CP2D = TRUE; - } else { - info->CP2D = FALSE; - } - - if (xf86ReturnOptValBool(RADEONOptions, OPTION_NO_SECURITY, FALSE)) { - xf86DrvMsg(pScrn->scrnIndex, X_CONFIG, - "WARNING!!! CP Security checks disabled!!! **********\n"); - info->CPSecure = FALSE; - } else { - info->CPSecure = TRUE; - } - info->agpMode = RADEON_DEFAULT_AGP_MODE; info->agpSize = RADEON_DEFAULT_AGP_SIZE; info->ringSize = RADEON_DEFAULT_RING_SIZE; - info->vbSize = RADEON_DEFAULT_VB_SIZE; - info->indSize = RADEON_DEFAULT_IND_SIZE; + info->bufSize = RADEON_DEFAULT_BUFFER_SIZE; info->agpTexSize = RADEON_DEFAULT_AGP_TEX_SIZE; - info->vbBufSize = RADEON_DEFAULT_VB_BUF_SIZE; - info->CPusecTimeout = RADEON_DEFAULT_CP_TIMEOUT; if (!info->IsPCI) { @@ -1183,36 +1159,31 @@ static Bool RADEONPreInitDRI(ScrnInfoPtr pScrn) } if (xf86GetOptValInteger(RADEONOptions, - OPTION_VERT_SIZE, &(info->vbSize))) { - if (info->vbSize < 1 || info->vbSize >= info->agpSize) { + OPTION_BUFFER_SIZE, &(info->bufSize))) { + if (info->bufSize < 1 || info->bufSize >= (int)info->agpSize) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Illegal vertex buffers list size: %d MB\n", - info->vbSize); + "Illegal vertex/indirect buffers size: %d MB\n", + info->bufSize); return FALSE; } - } - - if (xf86GetOptValInteger(RADEONOptions, - OPTION_VBUF_SIZE, &(info->vbBufSize))) { - int numBufs = info->vbSize*1024*1024/info->vbBufSize; - if (numBufs < 2 || numBufs > 512) { /* FIXME: 512 is arbitrary */ + if (info->bufSize > 2) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, - "Illegal individual vertex buffer size: %d bytes\n", - info->vbBufSize); - return FALSE; + "Illegal vertex/indirect buffers size: %d MB\n", + info->bufSize); + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, + "Clamping vertex/indirect buffers size to 2 MB\n"); + info->bufSize = 2; } } - if (info->ringSize + info->vbSize + info->indSize + info->agpTexSize > + if (info->ringSize + info->bufSize + info->agpTexSize > info->agpSize) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Buffers are too big for requested AGP space\n"); return FALSE; } - info->agpTexSize = info->agpSize - (info->ringSize + - info->vbSize + - info->indSize); + info->agpTexSize = info->agpSize - (info->ringSize + info->bufSize); } if (xf86GetOptValInteger(RADEONOptions, OPTION_USEC_TIMEOUT, @@ -1445,14 +1416,14 @@ static void RADEONLoadPalette(ScrnInfoPtr pScrn, int numColors, static void RADEONBlockHandler(int i, pointer blockData, pointer pTimeout, pointer pReadmask) { - ScreenPtr pScreen = screenInfo.screens[i]; - ScrnInfoPtr pScrn = xf86Screens[i]; + ScreenPtr pScreen = screenInfo.screens[i]; + ScrnInfoPtr pScrn = xf86Screens[i]; RADEONInfoPtr info = RADEONPTR(pScrn); - + pScreen->BlockHandler = info->BlockHandler; (*pScreen->BlockHandler) (i, blockData, pTimeout, pReadmask); pScreen->BlockHandler = RADEONBlockHandler; - + if(info->VideoTimerCallback) { (*info->VideoTimerCallback)(pScrn, currentTime.milliseconds); } @@ -1515,21 +1486,19 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) info->CurrentLayout.pixel_bytes); int maxy = info->FbMapSize / width_bytes; - if (!xf86ReturnOptValBool(RADEONOptions, OPTION_NOACCEL, FALSE) && - (maxy > pScrn->virtualY * 3) -#ifdef ENABLE_FLAT_PANEL - /* FIXME: Disable 3D support for FPs until it is tested */ - && !info->HasPanelRegs -#endif - ) { - info->directRenderingEnabled = RADEONDRIScreenInit(pScreen); - } else { + if (xf86ReturnOptValBool(RADEONOptions, OPTION_NOACCEL, FALSE)) { + xf86DrvMsg(scrnIndex, X_WARNING, + "Acceleration disabled, not initializing the DRI\n"); + info->directRenderingEnabled = FALSE; + } else if (maxy <= pScrn->virtualY * 3) { xf86DrvMsg(scrnIndex, X_WARNING, "Static buffer allocation failed -- " "need at least %d kB video memory\n", (pScrn->displayWidth * pScrn->virtualY * info->CurrentLayout.pixel_bytes * 3 + 1023) / 1024); info->directRenderingEnabled = FALSE; + } else { + info->directRenderingEnabled = RADEONDRIScreenInit(pScreen); } } #endif @@ -1590,57 +1559,19 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) RADEONDGAInit(pScreen); /* Memory manager setup */ - MemBox.x1 = 0; - MemBox.y1 = 0; - MemBox.x2 = pScrn->displayWidth; - y2 = (info->FbMapSize - / (pScrn->displayWidth * info->CurrentLayout.pixel_bytes)); - if (y2 >= 32768) y2 = 32767; /* because MemBox.y2 is signed short */ - MemBox.y2 = y2; - - /* The acceleration engine uses 14 bit - signed coordinates, so we can't have any - drawable caches beyond this region. */ - if (MemBox.y2 > 8191) MemBox.y2 = 8191; - - if (!xf86InitFBManager(pScreen, &MemBox)) { - xf86DrvMsg(scrnIndex, X_ERROR, - "Memory manager initialization to (%d,%d) (%d,%d) failed\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - return FALSE; - } else { - int width, height; - FBAreaPtr fbarea; - - xf86DrvMsg(scrnIndex, X_INFO, - "Memory manager initialized to (%d,%d) (%d,%d)\n", - MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); - if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, - 2, 0, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved area from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); - } - if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, 0, 0, 0)) { - xf86DrvMsg(scrnIndex, X_INFO, - "Largest offscreen area available: %d x %d\n", - width, height); - } - } - #ifdef XF86DRI - /* Allocate frame buffer space for the - shared back and depth buffers as well - as for local textures. */ if (info->directRenderingEnabled) { FBAreaPtr fbarea; - int width_bytes = (pScrn->displayWidth * - info->CurrentLayout.pixel_bytes); - int maxy = info->FbMapSize / width_bytes; - int l; + int width_bytes = (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes); + int cpp = info->CurrentLayout.pixel_bytes; + int bufferSize = ((pScrn->virtualY * width_bytes + RADEON_BUFFER_ALIGN) + & ~RADEON_BUFFER_ALIGN); + int l; + int scanlines; + + info->frontOffset = 0; + info->frontPitch = pScrn->displayWidth; switch (info->CPMode) { case RADEON_DEFAULT_CP_PIO_MODE: @@ -1659,99 +1590,174 @@ Bool RADEONScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv) xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %d MB for the ring buffer\n", info->ringSize); xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for vertex buffers\n", info->vbSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d MB for indirect buffers\n", info->indSize); + "Using %d MB for vertex/indirect buffers\n", info->bufSize); xf86DrvMsg(pScrn->scrnIndex, X_INFO, "Using %d MB for AGP textures\n", info->agpTexSize); - xf86DrvMsg(pScrn->scrnIndex, X_INFO, - "Using %d byte vertex buffers\n", info->vbBufSize); - /* Allocate the shared back buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved back buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->backX = fbarea->box.x1; - info->backY = fbarea->box.y1; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve back buffer\n"); - info->backX = -1; - info->backY = -1; + /* Try for front, back, depth, and three framebuffers worth of + * pixmap cache. Should be enough for a fullscreen background + * image plus some leftovers. + */ + info->textureSize = info->FbMapSize - 6 * bufferSize; + + /* If that gives us less than half the available memory, let's + * be greedy and grab some more. Sorry, I care more about 3D + * performance than playing nicely, and you'll get around a full + * framebuffer's worth of pixmap cache anyway. + */ + if (info->textureSize < (int)info->FbMapSize / 2) { + info->textureSize = info->FbMapSize - 5 * bufferSize; } - - /* Allocate the shared depth buffer */ - if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY, - 32, NULL, NULL, NULL))) { - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved depth buffer from (%d,%d) to (%d,%d)\n", - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - - info->depthX = fbarea->box.x1; - info->depthY = fbarea->box.y1; - } else { - xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve depth buffer\n"); - info->depthX = -1; - info->depthY = -1; + if (info->textureSize < (int)info->FbMapSize / 2) { + info->textureSize = info->FbMapSize - 4 * bufferSize; } - /* Allocate local texture space */ - if (((maxy - MemBox.y2 - 1) * width_bytes) > - (pScrn->virtualX * pScrn->virtualY * 2 * - info->CurrentLayout.pixel_bytes)) { - info->textureX = 0; - info->textureY = MemBox.y2 + 1; - info->textureSize = (maxy - MemBox.y2 - 1) * width_bytes; + /* Check to see if there is more room available after the 8192nd + scanline for textures */ + if (info->FbMapSize - 8192*width_bytes - bufferSize*2 + > info->textureSize) { + info->textureSize = + info->FbMapSize - 8192*width_bytes - bufferSize*2; + } + if (info->textureSize > 0) { l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + /* Round the texture size up to the nearest whole number of + * texture regions. Again, be greedy about this, don't + * round down. + */ info->log2TexGran = l; info->textureSize = (info->textureSize >> l) << l; + } else { + info->textureSize = 0; + } - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", - info->textureSize/1024, - info->textureX, info->textureY, - pScrn->displayWidth, maxy); - } else if ((fbarea = xf86AllocateOffscreenArea(pScreen, - pScrn->virtualX, - pScrn->virtualY * 2, - 32, - NULL, NULL, NULL))) { - info->textureX = fbarea->box.x1; - info->textureY = fbarea->box.y1; - info->textureSize = ((fbarea->box.y2 - fbarea->box.y1) * - (fbarea->box.x2 - fbarea->box.x1) * - info->CurrentLayout.pixel_bytes); + /* Set a minimum usable local texture heap size. This will fit + * two 256x256x32bpp textures. + */ + if (info->textureSize < 512 * 1024) { + info->textureOffset = 0; + info->textureSize = 0; + } - l = RADEONMinBits((info->textureSize-1) / RADEON_NR_TEX_REGIONS); - if (l < RADEON_LOG_TEX_GRANULARITY) l = RADEON_LOG_TEX_GRANULARITY; + /* Reserve space for textures */ + info->textureOffset = (info->FbMapSize - info->textureSize + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; - info->log2TexGran = l; - info->textureSize = (info->textureSize >> l) << l; + /* Reserve space for the shared depth buffer */ + info->depthOffset = (info->textureOffset - bufferSize + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; + info->depthPitch = pScrn->displayWidth; - xf86DrvMsg(scrnIndex, X_INFO, - "Reserved %d kb for textures: (%d,%d)-(%d,%d)\n", - info->textureSize/1024, - fbarea->box.x1, fbarea->box.y1, - fbarea->box.x2, fbarea->box.y2); - } else { + /* Reserve space for the shared back buffer */ + info->backOffset = (info->depthOffset - bufferSize + + RADEON_BUFFER_ALIGN) & ~RADEON_BUFFER_ALIGN; + info->backPitch = pScrn->displayWidth; + + scanlines = info->backOffset / width_bytes - 1; + if (scanlines > 8191) scanlines = 8191; + + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + MemBox.y2 = scanlines; + + if (!xf86InitFBManager(pScreen, &MemBox)) { xf86DrvMsg(scrnIndex, X_ERROR, - "Unable to reserve texture space in frame buffer\n"); - info->textureX = -1; - info->textureY = -1; + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, + pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, + &height, 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } } + + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved back buffer at offset 0x%x\n", + info->backOffset); + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved depth buffer at offset 0x%x\n", + info->depthOffset); + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved %d kb for textures at offset 0x%x\n", + info->textureSize/1024, info->textureOffset); + + info->frontPitchOffset = (((info->frontPitch * cpp / 64) << 22) | + (info->frontOffset >> 10)); + + info->backPitchOffset = (((info->backPitch * cpp / 64) << 22) | + (info->backOffset >> 10)); + + info->depthPitchOffset = (((info->depthPitch * cpp / 64) << 22) | + (info->depthOffset >> 10)); } + else #endif + { + MemBox.x1 = 0; + MemBox.y1 = 0; + MemBox.x2 = pScrn->displayWidth; + y2 = (info->FbMapSize + / (pScrn->displayWidth * + info->CurrentLayout.pixel_bytes)); + if (y2 >= 32768) y2 = 32767; /* because MemBox.y2 is signed short */ + MemBox.y2 = y2; + + /* The acceleration engine uses 14 bit + signed coordinates, so we can't have any + drawable caches beyond this region. */ + if (MemBox.y2 > 8191) MemBox.y2 = 8191; + + if (!xf86InitFBManager(pScreen, &MemBox)) { + xf86DrvMsg(scrnIndex, X_ERROR, + "Memory manager initialization to (%d,%d) (%d,%d) failed\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + return FALSE; + } else { + int width, height; + FBAreaPtr fbarea; + + xf86DrvMsg(scrnIndex, X_INFO, + "Memory manager initialized to (%d,%d) (%d,%d)\n", + MemBox.x1, MemBox.y1, MemBox.x2, MemBox.y2); + if ((fbarea = xf86AllocateOffscreenArea(pScreen, pScrn->displayWidth, + 2, 0, NULL, NULL, NULL))) { + xf86DrvMsg(scrnIndex, X_INFO, + "Reserved area from (%d,%d) to (%d,%d)\n", + fbarea->box.x1, fbarea->box.y1, + fbarea->box.x2, fbarea->box.y2); + } else { + xf86DrvMsg(scrnIndex, X_ERROR, "Unable to reserve area\n"); + } + if (xf86QueryLargestOffscreenArea(pScreen, &width, &height, + 0, 0, 0)) { + xf86DrvMsg(scrnIndex, X_INFO, + "Largest offscreen area available: %d x %d\n", + width, height); + } + } + } /* Backing store setup */ miInitializeBackingStore(pScreen); @@ -2840,13 +2846,13 @@ Bool RADEONEnterVT(int scrnIndex, int flags) RADEONTRACE(("RADEONEnterVT\n")); #ifdef XF86DRI if (RADEONPTR(pScrn)->directRenderingEnabled) { - RADEONCPStart(pScrn); + RADEONCP_START(pScrn, info); DRIUnlock(pScrn->pScreen); } #endif if (!RADEONModeInit(pScrn, pScrn->currentMode)) return FALSE; if (info->accelOn) - RADEONEngineInit(pScrn); + RADEONEngineRestore(pScrn); info->PaletteSavedOnVT = FALSE; RADEONAdjustFrame(scrnIndex, pScrn->frameX0, pScrn->frameY0, 0); @@ -2866,7 +2872,7 @@ void RADEONLeaveVT(int scrnIndex, int flags) #ifdef XF86DRI if (RADEONPTR(pScrn)->directRenderingEnabled) { DRILock(pScrn->pScreen, 0); - RADEONCPStop(pScrn); + RADEONCP_STOP(pScrn, info); } #endif RADEONSavePalette(pScrn, save); @@ -2882,7 +2888,8 @@ RADEONEnterVTFBDev(int scrnIndex, int flags) RADEONSavePtr restore = &info->SavedReg; fbdevHWEnterVT(scrnIndex,flags); RADEONRestorePalette(pScrn,restore); - RADEONEngineInit(pScrn); + if (info->accelOn) + RADEONEngineRestore(pScrn); return TRUE; } diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h index 07a75ebdf..c29db273b 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_reg.h @@ -168,6 +168,7 @@ #define RADEON_ATTRDR 0x03c1 /* VGA */ #define RADEON_ATTRDW 0x03c0 /* VGA */ #define RADEON_ATTRX 0x03c0 /* VGA */ +#define RADEON_AUX_SC_CNTL 0x1660 # define RADEON_AUX1_SC_EN (1 << 0) # define RADEON_AUX1_SC_MODE_OR (0 << 1) # define RADEON_AUX1_SC_MODE_NAND (1 << 1) @@ -177,7 +178,6 @@ # define RADEON_AUX3_SC_EN (1 << 4) # define RADEON_AUX3_SC_MODE_OR (0 << 5) # define RADEON_AUX3_SC_MODE_NAND (1 << 5) -#define RADEON_AUX_SC_CNTL 0x1660 #define RADEON_AUX1_SC_BOTTOM 0x1670 #define RADEON_AUX1_SC_LEFT 0x1664 #define RADEON_AUX1_SC_RIGHT 0x1668 @@ -354,6 +354,7 @@ # define RADEON_CRTC_H_DISP_SHIFT 16 #define RADEON_CRTC_OFFSET 0x0224 #define RADEON_CRTC_OFFSET_CNTL 0x0228 +# define RADEON_CRTC_TILE_EN (1 << 15) #define RADEON_CRTC_PITCH 0x022c #define RADEON_CRTC_STATUS 0x005c # define RADEON_CRTC_VBLANK_SAVE (1 << 1) @@ -440,6 +441,8 @@ # define RADEON_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) # define RADEON_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) # define RADEON_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) +# define RADEON_GMC_BRUSH_32x32_MONO_FG_BG (8 << 4) +# define RADEON_GMC_BRUSH_32x32_MONO_FG_LA (9 << 4) # define RADEON_GMC_BRUSH_8x8_COLOR (10 << 4) # define RADEON_GMC_BRUSH_1X8_COLOR (12 << 4) # define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) @@ -530,6 +533,10 @@ #define RADEON_DST_PITCH_OFFSET 0x142c #define RADEON_DST_PITCH_OFFSET_C 0x1c80 # define RADEON_PITCH_SHIFT 21 +# define RADEON_DST_TILE_LINEAR (0 << 30) +# define RADEON_DST_TILE_MACRO (1 << 30) +# define RADEON_DST_TILE_MICRO (2 << 30) +# define RADEON_DST_TILE_BOTH (3 << 30) #define RADEON_DST_WIDTH 0x140c #define RADEON_DST_WIDTH_HEIGHT 0x1598 #define RADEON_DST_WIDTH_X 0x1588 @@ -600,15 +607,6 @@ #define RADEON_GEN_INT_STATUS 0x0044 # define RADEON_VSYNC_INT_AK (1 << 2) # define RADEON_VSYNC_INT (1 << 2) -#define RADEON_RBBM_SOFT_RESET 0x00f0 -# define RADEON_SOFT_RESET_CP (1 << 0) -# define RADEON_SOFT_RESET_HI (1 << 1) -# define RADEON_SOFT_RESET_SE (1 << 2) -# define RADEON_SOFT_RESET_RE (1 << 3) -# define RADEON_SOFT_RESET_PP (1 << 4) -# define RADEON_SOFT_RESET_E2 (1 << 5) -# define RADEON_SOFT_RESET_RB (1 << 6) -# define RADEON_SOFT_RESET_HDP (1 << 7) #define RADEON_GENENB 0x03c3 /* VGA */ #define RADEON_GENFC_RD 0x03ca /* VGA */ #define RADEON_GENFC_WT 0x03da /* VGA, 0x03ba */ @@ -856,10 +854,20 @@ # define RADEON_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ #define RADEON_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ #define RADEON_RBBM_SOFT_RESET 0x00f0 +# define RADEON_SOFT_RESET_CP (1 << 0) +# define RADEON_SOFT_RESET_HI (1 << 1) +# define RADEON_SOFT_RESET_SE (1 << 2) +# define RADEON_SOFT_RESET_RE (1 << 3) +# define RADEON_SOFT_RESET_PP (1 << 4) +# define RADEON_SOFT_RESET_E2 (1 << 5) +# define RADEON_SOFT_RESET_RB (1 << 6) +# define RADEON_SOFT_RESET_HDP (1 << 7) #define RADEON_RBBM_STATUS 0x0e40 # define RADEON_RBBM_FIFOCNT_MASK 0x007f # define RADEON_RBBM_ACTIVE (1 << 31) #define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c +# define RADEON_RB2D_DC_FLUSH (3 << 0) +# define RADEON_RB2D_DC_FREE (3 << 2) # define RADEON_RB2D_DC_FLUSH_ALL 0xf # define RADEON_RB2D_DC_BUSY (1 << 31) #define RADEON_RB2D_DSTCACHE_MODE 0x3428 @@ -894,7 +902,7 @@ #define RADEON_STATUS 0x0f06 /* PCI */ #define RADEON_SUBPIC_CNTL 0x0540 /* ? */ #define RADEON_SUB_CLASS 0x0f0a /* PCI */ -#define RADEON_SURFACE_DELAY 0x0b00 +#define RADEON_SURFACE_CNTL 0x0b00 #define RADEON_SURFACE0_INFO 0x0b0c #define RADEON_SURFACE0_LOWER_BOUND 0x0b04 #define RADEON_SURFACE0_UPPER_BOUND 0x0b08 @@ -907,6 +915,18 @@ #define RADEON_SURFACE3_INFO 0x0b3c #define RADEON_SURFACE3_LOWER_BOUND 0x0b34 #define RADEON_SURFACE3_UPPER_BOUND 0x0b38 +#define RADEON_SURFACE4_INFO 0x0b4c +#define RADEON_SURFACE4_LOWER_BOUND 0x0b44 +#define RADEON_SURFACE4_UPPER_BOUND 0x0b48 +#define RADEON_SURFACE5_INFO 0x0b5c +#define RADEON_SURFACE5_LOWER_BOUND 0x0b54 +#define RADEON_SURFACE5_UPPER_BOUND 0x0b58 +#define RADEON_SURFACE6_INFO 0x0b6c +#define RADEON_SURFACE6_LOWER_BOUND 0x0b64 +#define RADEON_SURFACE6_UPPER_BOUND 0x0b68 +#define RADEON_SURFACE7_INFO 0x0b7c +#define RADEON_SURFACE7_LOWER_BOUND 0x0b74 +#define RADEON_SURFACE7_UPPER_BOUND 0x0b78 #define RADEON_SW_SEMAPHORE 0x013c #define RADEON_TEST_DEBUG_CNTL 0x0120 @@ -928,13 +948,550 @@ #define RADEON_VIPH_CONTROL 0x0c40 /* ? */ #define RADEON_WAIT_UNTIL 0x1720 +# define RADEON_WAIT_CRTC_PFLIP (1 << 0) +# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) +# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) +# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) #define RADEON_X_MPLL_REF_FB_DIV 0x000a /* PLL */ #define RADEON_XCLK_CNTL 0x000d /* PLL */ #define RADEON_XDLL_CNTL 0x000c /* PLL */ #define RADEON_XPLL_CNTL 0x000b /* PLL */ - /* Registers for CCE and Microcode Engine */ + /* Registers for 3D/TCL */ +#define RADEON_PP_BORDER_COLOR_0 0x1d40 +#define RADEON_PP_BORDER_COLOR_1 0x1d44 +#define RADEON_PP_BORDER_COLOR_2 0x1d48 +#define RADEON_PP_CNTL 0x1c38 +# define RADEON_STIPPLE_ENABLE (1 << 0) +# define RADEON_SCISSOR_ENABLE (1 << 1) +# define RADEON_PATTERN_ENABLE (1 << 2) +# define RADEON_SHADOW_ENABLE (1 << 3) +# define RADEON_TEX_ENABLE_MASK (0xf << 4) +# define RADEON_TEX_0_ENABLE (1 << 4) +# define RADEON_TEX_1_ENABLE (1 << 5) +# define RADEON_TEX_2_ENABLE (1 << 6) +# define RADEON_TEX_3_ENABLE (1 << 7) +# define RADEON_TEX_BLEND_ENABLE_MASK (0xf << 12) +# define RADEON_TEX_BLEND_0_ENABLE (1 << 12) +# define RADEON_TEX_BLEND_1_ENABLE (1 << 13) +# define RADEON_TEX_BLEND_2_ENABLE (1 << 14) +# define RADEON_TEX_BLEND_3_ENABLE (1 << 15) +# define RADEON_PLANAR_YUV_ENABLE (1 << 20) +# define RADEON_SPECULAR_ENABLE (1 << 21) +# define RADEON_FOG_ENABLE (1 << 22) +# define RADEON_ALPHA_TEST_ENABLE (1 << 23) +# define RADEON_ANTI_ALIAS_NONE (0 << 24) +# define RADEON_ANTI_ALIAS_LINE (1 << 24) +# define RADEON_ANTI_ALIAS_POLY (2 << 24) +# define RADEON_ANTI_ALIAS_LINE_POLY (3 << 24) +# define RADEON_BUMP_MAP_ENABLE (1 << 26) +# define RADEON_BUMPED_MAP_T0 (0 << 27) +# define RADEON_BUMPED_MAP_T1 (1 << 27) +# define RADEON_BUMPED_MAP_T2 (2 << 27) +# define RADEON_TEX_3D_ENABLE_0 (1 << 29) +# define RADEON_TEX_3D_ENABLE_1 (1 << 30) +# define RADEON_MC_ENABLE (1 << 31) +#define RADEON_PP_FOG_COLOR 0x1c18 +# define RADEON_FOG_COLOR_MASK 0x00ffffff +# define RADEON_FOG_VERTEX (0 << 24) +# define RADEON_FOG_TABLE (1 << 24) +# define RADEON_FOG_USE_DEPTH (0 << 25) +# define RADEON_FOG_USE_DIFFUSE_ALPHA (2 << 25) +# define RADEON_FOG_USE_SPEC_ALPHA (3 << 25) +#define RADEON_PP_LUM_MATRIX 0x1d00 +#define RADEON_PP_MISC 0x1c14 +# define RADEON_REF_ALPHA_MASK 0x000000ff +# define RADEON_ALPHA_TEST_FAIL (0 << 8) +# define RADEON_ALPHA_TEST_LESS (1 << 8) +# define RADEON_ALPHA_TEST_LEQUAL (2 << 8) +# define RADEON_ALPHA_TEST_EQUAL (3 << 8) +# define RADEON_ALPHA_TEST_GEQUAL (4 << 8) +# define RADEON_ALPHA_TEST_GREATER (5 << 8) +# define RADEON_ALPHA_TEST_NEQUAL (6 << 8) +# define RADEON_ALPHA_TEST_PASS (7 << 8) +# define RADEON_ALPHA_TEST_OP_MASK (7 << 8) +# define RADEON_CHROMA_FUNC_FAIL (0 << 16) +# define RADEON_CHROMA_FUNC_PASS (1 << 16) +# define RADEON_CHROMA_FUNC_NEQUAL (2 << 16) +# define RADEON_CHROMA_FUNC_EQUAL (3 << 16) +# define RADEON_CHROMA_KEY_NEAREST (0 << 18) +# define RADEON_CHROMA_KEY_ZERO (1 << 18) +# define RADEON_SHADOW_ID_AUTO_INC (1 << 20) +# define RADEON_SHADOW_FUNC_EQUAL (0 << 21) +# define RADEON_SHADOW_FUNC_NEQUAL (1 << 21) +# define RADEON_SHADOW_PASS_1 (0 << 22) +# define RADEON_SHADOW_PASS_2 (1 << 22) +# define RADEON_RIGHT_HAND_CUBE_D3D (0 << 24) +# define RADEON_RIGHT_HAND_CUBE_OGL (1 << 24) +#define RADEON_PP_ROT_MATRIX_0 0x1d58 +#define RADEON_PP_ROT_MATRIX_1 0x1d5c +#define RADEON_PP_TXFILTER_0 0x1c54 +#define RADEON_PP_TXFILTER_1 0x1c6c +#define RADEON_PP_TXFILTER_2 0x1c84 +# define RADEON_MAG_FILTER_NEAREST (0 << 0) +# define RADEON_MAG_FILTER_LINEAR (1 << 0) +# define RADEON_MAG_FILTER_MASK (1 << 0) +# define RADEON_MIN_FILTER_NEAREST (0 << 1) +# define RADEON_MIN_FILTER_LINEAR (1 << 1) +# define RADEON_MIN_FILTER_NEAREST_MIP_NEAREST (2 << 1) +# define RADEON_MIN_FILTER_NEAREST_MIP_LINEAR (3 << 1) +# define RADEON_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 1) +# define RADEON_MIN_FILTER_LINEAR_MIP_LINEAR (7 << 1) +# define RADEON_MIN_FILTER_ANISO_NEAREST (8 << 1) +# define RADEON_MIN_FILTER_ANISO_LINEAR (9 << 1) +# define RADEON_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (10 << 1) +# define RADEON_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (11 << 1) +# define RADEON_MIN_FILTER_MASK (15 << 1) +# define RADEON_LOD_BIAS_MASK (0xffff << 8) +# define RADEON_LOD_BIAS_SHIFT 8 +# define RADEON_MAX_MIP_LEVEL_MASK (0x0f << 16) +# define RADEON_MAX_MIP_LEVEL_SHIFT 16 +# define RADEON_WRAPEN_S (1 << 22) +# define RADEON_CLAMP_S_WRAP (0 << 23) +# define RADEON_CLAMP_S_MIRROR (1 << 23) +# define RADEON_CLAMP_S_CLAMP_LAST (2 << 23) +# define RADEON_CLAMP_S_MIRROR_CLAMP_LAST (3 << 23) +# define RADEON_CLAMP_S_CLAMP_BORDER (4 << 23) +# define RADEON_CLAMP_S_MIRROR_CLAMP_BORDER (5 << 23) +# define RADEON_CLAMP_S_MASK (7 << 23) +# define RADEON_WRAPEN_T (1 << 26) +# define RADEON_CLAMP_T_WRAP (0 << 27) +# define RADEON_CLAMP_T_MIRROR (1 << 27) +# define RADEON_CLAMP_T_CLAMP_LAST (2 << 27) +# define RADEON_CLAMP_T_MIRROR_CLAMP_LAST (3 << 27) +# define RADEON_CLAMP_T_CLAMP_BORDER (4 << 27) +# define RADEON_CLAMP_T_MIRROR_CLAMP_BORDER (5 << 27) +# define RADEON_CLAMP_T_MASK (7 << 27) +# define RADEON_BORDER_MODE_OGL (0 << 31) +# define RADEON_BORDER_MODE_D3D (1 << 31) +#define RADEON_PP_TXFORMAT_0 0x1c58 +#define RADEON_PP_TXFORMAT_1 0x1c70 +#define RADEON_PP_TXFORMAT_2 0x1c88 +# define RADEON_TXF_8BPP_I (0 << 0) +# define RADEON_TXF_16BPP_AI88 (1 << 0) +# define RADEON_TXF_8BPP_RGB332 (2 << 0) +# define RADEON_TXF_16BPP_ARGB1555 (3 << 0) +# define RADEON_TXF_16BPP_RGB565 (4 << 0) +# define RADEON_TXF_16BPP_ARGB4444 (5 << 0) +# define RADEON_TXF_32BPP_ARGB8888 (6 << 0) +# define RADEON_TXF_32BPP_RGBA8888 (7 << 0) +# define RADEON_TXF_8BPP_Y (8 << 0) +# define RADEON_TXF_FORMAT_MASK (31 << 0) +# define RADEON_TXF_FORMAT_SHIFT 0 +# define RADEON_TXF_APPLE_YUV_MODE (1 << 5) +# define RADEON_TXF_ALPHA_IN_MAP (1 << 6) +# define RADEON_TXF_NON_POWER2 (1 << 7) +# define RADEON_TXF_WIDTH_MASK (15 << 8) +# define RADEON_TXF_WIDTH_SHIFT 8 +# define RADEON_TXF_HEIGHT_MASK (15 << 12) +# define RADEON_TXF_HEIGHT_SHIFT 12 +# define RADEON_TXF_ST_ROUTE_STQ0 (0 << 24) +# define RADEON_TXF_ST_ROUTE_MASK (3 << 24) +# define RADEON_TXF_ST_ROUTE_STQ1 (1 << 24) +# define RADEON_TXF_ST_ROUTE_STQ2 (2 << 24) +# define RADEON_TXF_ENDIAN_NO_SWAP (0 << 26) +# define RADEON_TXF_ENDIAN_16BPP_SWAP (1 << 26) +# define RADEON_TXF_ENDIAN_32BPP_SWAP (2 << 26) +# define RADEON_TXF_ENDIAN_HALFDW_SWAP (3 << 26) +# define RADEON_TXF_ALPHA_MASK_ENABLE (1 << 28) +# define RADEON_TXF_CHROMA_KEY_ENABLE (1 << 29) +# define RADEON_TXF_CUBIC_MAP_ENABLE (1 << 30) +# define RADEON_TXF_PERSPECTIVE_ENABLE (1 << 31) +#define RADEON_PP_TXOFFSET_0 0x1c5c +#define RADEON_PP_TXOFFSET_1 0x1c74 +#define RADEON_PP_TXOFFSET_2 0x1c8c +# define RADEON_TXO_ENDIAN_NO_SWAP (0 << 0) +# define RADEON_TXO_ENDIAN_BYTE_SWAP (1 << 0) +# define RADEON_TXO_ENDIAN_WORD_SWAP (2 << 0) +# define RADEON_TXO_ENDIAN_HALFDW_SWAP (3 << 0) +# define RADEON_TXO_MACRO_LINEAR (0 << 2) +# define RADEON_TXO_MACRO_TILE (1 << 2) +# define RADEON_TXO_MICRO_LINEAR (0 << 3) +# define RADEON_TXO_MICRO_TILE_X2 (1 << 3) +# define RADEON_TXO_MICRO_TILE_OPT (2 << 3) +# define RADEON_TXO_OFFSET_MASK 0xffffffe0 +# define RADEON_TXO_OFFSET_SHIFT 5 +#define RADEON_PP_TXCBLEND_0 0x1c60 +#define RADEON_PP_TXCBLEND_1 0x1c78 +#define RADEON_PP_TXCBLEND_2 0x1c90 +# define RADEON_COLOR_ARG_A_SHIFT 0 +# define RADEON_COLOR_ARG_A_MASK (0x1f << 0) +# define RADEON_COLOR_ARG_A_ZERO (0 << 0) +# define RADEON_COLOR_ARG_A_CURRENT_COLOR (2 << 0) +# define RADEON_COLOR_ARG_A_CURRENT_ALPHA (3 << 0) +# define RADEON_COLOR_ARG_A_DIFFUSE_COLOR (4 << 0) +# define RADEON_COLOR_ARG_A_DIFFUSE_ALPHA (5 << 0) +# define RADEON_COLOR_ARG_A_SPECULAR_COLOR (6 << 0) +# define RADEON_COLOR_ARG_A_SPECULAR_ALPHA (7 << 0) +# define RADEON_COLOR_ARG_A_TFACTOR_COLOR (8 << 0) +# define RADEON_COLOR_ARG_A_TFACTOR_ALPHA (9 << 0) +# define RADEON_COLOR_ARG_A_T0_COLOR (10 << 0) +# define RADEON_COLOR_ARG_A_T0_ALPHA (11 << 0) +# define RADEON_COLOR_ARG_A_T1_COLOR (12 << 0) +# define RADEON_COLOR_ARG_A_T1_ALPHA (13 << 0) +# define RADEON_COLOR_ARG_A_T2_COLOR (14 << 0) +# define RADEON_COLOR_ARG_A_T2_ALPHA (15 << 0) +# define RADEON_COLOR_ARG_A_T3_COLOR (16 << 0) +# define RADEON_COLOR_ARG_A_T3_ALPHA (17 << 0) +# define RADEON_COLOR_ARG_B_SHIFT 5 +# define RADEON_COLOR_ARG_B_MASK (0x1f << 5) +# define RADEON_COLOR_ARG_B_ZERO (0 << 5) +# define RADEON_COLOR_ARG_B_CURRENT_COLOR (2 << 5) +# define RADEON_COLOR_ARG_B_CURRENT_ALPHA (3 << 5) +# define RADEON_COLOR_ARG_B_DIFFUSE_COLOR (4 << 5) +# define RADEON_COLOR_ARG_B_DIFFUSE_ALPHA (5 << 5) +# define RADEON_COLOR_ARG_B_SPECULAR_COLOR (6 << 5) +# define RADEON_COLOR_ARG_B_SPECULAR_ALPHA (7 << 5) +# define RADEON_COLOR_ARG_B_TFACTOR_COLOR (8 << 5) +# define RADEON_COLOR_ARG_B_TFACTOR_ALPHA (9 << 5) +# define RADEON_COLOR_ARG_B_T0_COLOR (10 << 5) +# define RADEON_COLOR_ARG_B_T0_ALPHA (11 << 5) +# define RADEON_COLOR_ARG_B_T1_COLOR (12 << 5) +# define RADEON_COLOR_ARG_B_T1_ALPHA (13 << 5) +# define RADEON_COLOR_ARG_B_T2_COLOR (14 << 5) +# define RADEON_COLOR_ARG_B_T2_ALPHA (15 << 5) +# define RADEON_COLOR_ARG_B_T3_COLOR (16 << 5) +# define RADEON_COLOR_ARG_B_T3_ALPHA (17 << 5) +# define RADEON_COLOR_ARG_C_SHIFT 10 +# define RADEON_COLOR_ARG_C_MASK (0x1f << 10) +# define RADEON_COLOR_ARG_C_ZERO (0 << 10) +# define RADEON_COLOR_ARG_C_CURRENT_COLOR (2 << 10) +# define RADEON_COLOR_ARG_C_CURRENT_ALPHA (3 << 10) +# define RADEON_COLOR_ARG_C_DIFFUSE_COLOR (4 << 10) +# define RADEON_COLOR_ARG_C_DIFFUSE_ALPHA (5 << 10) +# define RADEON_COLOR_ARG_C_SPECULAR_COLOR (6 << 10) +# define RADEON_COLOR_ARG_C_SPECULAR_ALPHA (7 << 10) +# define RADEON_COLOR_ARG_C_TFACTOR_COLOR (8 << 10) +# define RADEON_COLOR_ARG_C_TFACTOR_ALPHA (9 << 10) +# define RADEON_COLOR_ARG_C_T0_COLOR (10 << 10) +# define RADEON_COLOR_ARG_C_T0_ALPHA (11 << 10) +# define RADEON_COLOR_ARG_C_T1_COLOR (12 << 10) +# define RADEON_COLOR_ARG_C_T1_ALPHA (13 << 10) +# define RADEON_COLOR_ARG_C_T2_COLOR (14 << 10) +# define RADEON_COLOR_ARG_C_T2_ALPHA (15 << 10) +# define RADEON_COLOR_ARG_C_T3_COLOR (16 << 10) +# define RADEON_COLOR_ARG_C_T3_ALPHA (17 << 10) +# define RADEON_COMP_ARG_A (1 << 15) +# define RADEON_COMP_ARG_A_SHIFT 15 +# define RADEON_COMP_ARG_B (1 << 16) +# define RADEON_COMP_ARG_B_SHIFT 16 +# define RADEON_COMP_ARG_C (1 << 17) +# define RADEON_COMP_ARG_C_SHIFT 17 +# define RADEON_BLEND_CTL_MASK (7 << 18) +# define RADEON_BLEND_CTL_ADD (0 << 18) +# define RADEON_BLEND_CTL_SUBTRACT (1 << 18) +# define RADEON_BLEND_CTL_ADDSIGNED (2 << 18) +# define RADEON_BLEND_CTL_BLEND (3 << 18) +# define RADEON_BLEND_CTL_DOT3 (4 << 18) +# define RADEON_SCALE_SHIFT 21 +# define RADEON_SCALE_MASK (3 << 21) +# define RADEON_SCALE_1X (0 << 21) +# define RADEON_SCALE_2X (1 << 21) +# define RADEON_SCALE_4X (2 << 21) +# define RADEON_CLAMP_TX (1 << 23) +# define RADEON_T0_EQ_TCUR (1 << 24) +# define RADEON_T1_EQ_TCUR (1 << 25) +# define RADEON_T2_EQ_TCUR (1 << 26) +# define RADEON_T3_EQ_TCUR (1 << 27) +# define RADEON_COLOR_ARG_MASK 0x1f +# define RADEON_COMP_ARG_SHIFT 15 +#define RADEON_PP_TXABLEND_0 0x1c64 +#define RADEON_PP_TXABLEND_1 0x1c7c +#define RADEON_PP_TXABLEND_2 0x1c94 +# define RADEON_ALPHA_ARG_A_SHIFT 0 +# define RADEON_ALPHA_ARG_A_MASK (0xf << 0) +# define RADEON_ALPHA_ARG_A_ZERO (0 << 0) +# define RADEON_ALPHA_ARG_A_CURRENT_ALPHA (1 << 0) +# define RADEON_ALPHA_ARG_A_DIFFUSE_ALPHA (2 << 0) +# define RADEON_ALPHA_ARG_A_SPECULAR_ALPHA (3 << 0) +# define RADEON_ALPHA_ARG_A_TFACTOR_ALPHA (4 << 0) +# define RADEON_ALPHA_ARG_A_T0_ALPHA (5 << 0) +# define RADEON_ALPHA_ARG_A_T1_ALPHA (6 << 0) +# define RADEON_ALPHA_ARG_A_T2_ALPHA (7 << 0) +# define RADEON_ALPHA_ARG_A_T3_ALPHA (8 << 0) +# define RADEON_ALPHA_ARG_B_SHIFT 4 +# define RADEON_ALPHA_ARG_B_MASK (0xf << 4) +# define RADEON_ALPHA_ARG_B_ZERO (0 << 4) +# define RADEON_ALPHA_ARG_B_CURRENT_ALPHA (1 << 4) +# define RADEON_ALPHA_ARG_B_DIFFUSE_ALPHA (2 << 4) +# define RADEON_ALPHA_ARG_B_SPECULAR_ALPHA (3 << 4) +# define RADEON_ALPHA_ARG_B_TFACTOR_ALPHA (4 << 4) +# define RADEON_ALPHA_ARG_B_T0_ALPHA (5 << 4) +# define RADEON_ALPHA_ARG_B_T1_ALPHA (6 << 4) +# define RADEON_ALPHA_ARG_B_T2_ALPHA (7 << 4) +# define RADEON_ALPHA_ARG_B_T3_ALPHA (8 << 4) +# define RADEON_ALPHA_ARG_C_SHIFT 8 +# define RADEON_ALPHA_ARG_C_MASK (0xf << 8) +# define RADEON_ALPHA_ARG_C_ZERO (0 << 8) +# define RADEON_ALPHA_ARG_C_CURRENT_ALPHA (1 << 8) +# define RADEON_ALPHA_ARG_C_DIFFUSE_ALPHA (2 << 8) +# define RADEON_ALPHA_ARG_C_SPECULAR_ALPHA (3 << 8) +# define RADEON_ALPHA_ARG_C_TFACTOR_ALPHA (4 << 8) +# define RADEON_ALPHA_ARG_C_T0_ALPHA (5 << 8) +# define RADEON_ALPHA_ARG_C_T1_ALPHA (6 << 8) +# define RADEON_ALPHA_ARG_C_T2_ALPHA (7 << 8) +# define RADEON_ALPHA_ARG_C_T3_ALPHA (8 << 8) +# define RADEON_DOT_ALPHA_DONT_REPLICATE (1 << 9) +# define RADEON_ALPHA_ARG_MASK 0xf + +#define RADEON_PP_TFACTOR_0 0x1c68 +#define RADEON_PP_TFACTOR_1 0x1c80 +#define RADEON_PP_TFACTOR_2 0x1c98 + +#define RADEON_RB3D_BLENDCNTL 0x1c20 +# define RADEON_COMB_FCN_ADD_CLAMP (0 << 12) +# define RADEON_COMB_FCN_ADD_NOCLAMP (1 << 12) +# define RADEON_COMB_FCN_SUB_CLAMP (2 << 12) +# define RADEON_COMB_FCN_SUB_NOCLAMP (3 << 12) +# define RADEON_SRC_BLEND_GL_ZERO (32 << 16) +# define RADEON_SRC_BLEND_GL_ONE (33 << 16) +# define RADEON_SRC_BLEND_GL_SRC_COLOR (34 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 16) +# define RADEON_SRC_BLEND_GL_DST_COLOR (36 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 16) +# define RADEON_SRC_BLEND_GL_SRC_ALPHA (38 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 16) +# define RADEON_SRC_BLEND_GL_DST_ALPHA (40 << 16) +# define RADEON_SRC_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 16) +# define RADEON_SRC_BLEND_GL_SRC_ALPHA_SATURATE (42 << 16) +# define RADEON_SRC_BLEND_MASK (63 << 16) +# define RADEON_DST_BLEND_GL_ZERO (32 << 24) +# define RADEON_DST_BLEND_GL_ONE (33 << 24) +# define RADEON_DST_BLEND_GL_SRC_COLOR (34 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_COLOR (35 << 24) +# define RADEON_DST_BLEND_GL_DST_COLOR (36 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_COLOR (37 << 24) +# define RADEON_DST_BLEND_GL_SRC_ALPHA (38 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_SRC_ALPHA (39 << 24) +# define RADEON_DST_BLEND_GL_DST_ALPHA (40 << 24) +# define RADEON_DST_BLEND_GL_ONE_MINUS_DST_ALPHA (41 << 24) +# define RADEON_DST_BLEND_MASK (63 << 24) +#define RADEON_RB3D_CNTL 0x1c3c +# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) +# define RADEON_PLANE_MASK_ENABLE (1 << 1) +# define RADEON_DITHER_ENABLE (1 << 2) +# define RADEON_ROUND_ENABLE (1 << 3) +# define RADEON_SCALE_DITHER_ENABLE (1 << 4) +# define RADEON_DITHER_INIT (1 << 5) +# define RADEON_ROP_ENABLE (1 << 6) +# define RADEON_STENCIL_ENABLE (1 << 7) +# define RADEON_Z_ENABLE (1 << 8) +# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) +# define RADEON_COLOR_FORMAT_ARGB1555 (3 << 10) +# define RADEON_COLOR_FORMAT_RGB565 (4 << 10) +# define RADEON_COLOR_FORMAT_ARGB8888 (6 << 10) +# define RADEON_COLOR_FORMAT_RGB332 (7 << 10) +# define RADEON_COLOR_FORMAT_Y8 (8 << 10) +# define RADEON_COLOR_FORMAT_RGB8 (9 << 10) +# define RADEON_COLOR_FORMAT_YUV422_VYUY (11 << 10) +# define RADEON_COLOR_FORMAT_YUV422_YVYU (12 << 10) +# define RADEON_COLOR_FORMAT_aYUV444 (14 << 10) +# define RADEON_COLOR_FORMAT_ARGB4444 (15 << 10) +# define RADEON_CLRCMP_FLIP_ENABLE (1 << 14) +# define RADEON_ZBLOCK8 (0 << 15) +# define RADEON_ZBLOCK16 (1 << 15) +#define RADEON_RB3D_COLOROFFSET 0x1c40 +# define RADEON_COLOROFFSET_MASK 0xfffffff0 +#define RADEON_RB3D_COLORPITCH 0x1c48 +# define RADEON_COLORPITCH_MASK 0x000001ff8 +# define RADEON_COLOR_TILE_ENABLE (1 << 16) +# define RADEON_COLOR_MICROTILE_ENABLE (1 << 17) +# define RADEON_COLOR_ENDIAN_NO_SWAP (0 << 18) +# define RADEON_COLOR_ENDIAN_WORD_SWAP (1 << 18) +# define RADEON_COLOR_ENDIAN_DWORD_SWAP (2 << 18) +#define RADEON_RB3D_DEPTHOFFSET 0x1c24 +#define RADEON_RB3D_DEPTHPITCH 0x1c28 +# define RADEON_DEPTHPITCH_MASK 0x00001ff8 +# define RADEON_DEPTH_ENDIAN_NO_SWAP (0 << 18) +# define RADEON_DEPTH_ENDIAN_WORD_SWAP (1 << 18) +# define RADEON_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) +#define RADEON_RB3D_PLANEMASK 0x1d84 +#define RADEON_RB3D_ROPCNTL 0x1d80 +#define RADEON_RB3D_STENCILREFMASK 0x1d7c +# define RADEON_STENCIL_REF_SHIFT 0 +# define RADEON_STENCIL_MASK_SHIFT 16 +# define RADEON_STENCIL_WRITEMASK_SHIFT 24 +#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c +# define RADEON_DEPTH_FORMAT_MASK (0xf << 0) +# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_Z (3 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_INT_Z (4 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_Z (5 << 0) +# define RADEON_DEPTH_FORMAT_16BIT_FLOAT_W (7 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_FLOAT_W (9 << 0) +# define RADEON_DEPTH_FORMAT_32BIT_FLOAT_W (11 << 0) +# define RADEON_Z_TEST_NEVER (0 << 4) +# define RADEON_Z_TEST_LESS (1 << 4) +# define RADEON_Z_TEST_LEQUAL (2 << 4) +# define RADEON_Z_TEST_EQUAL (3 << 4) +# define RADEON_Z_TEST_GEQUAL (4 << 4) +# define RADEON_Z_TEST_GREATER (5 << 4) +# define RADEON_Z_TEST_NEQUAL (6 << 4) +# define RADEON_Z_TEST_ALWAYS (7 << 4) +# define RADEON_Z_TEST_MASK (7 << 4) +# define RADEON_HIERARCHICAL_Z_ENABLE (1 << 8) +# define RADEON_STENCIL_TEST_NEVER (0 << 12) +# define RADEON_STENCIL_TEST_LESS (1 << 12) +# define RADEON_STENCIL_TEST_LEQUAL (2 << 12) +# define RADEON_STENCIL_TEST_EQUAL (3 << 12) +# define RADEON_STENCIL_TEST_GEQUAL (4 << 12) +# define RADEON_STENCIL_TEST_GREATER (5 << 12) +# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) +# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) +# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) +# define RADEON_STENCIL_S_FAIL_ZERO (1 << 16) +# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) +# define RADEON_STENCIL_S_FAIL_INC (3 << 16) +# define RADEON_STENCIL_S_FAIL_DEC (4 << 16) +# define RADEON_STENCIL_S_FAIL_INVERT (5 << 16) +# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) +# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) +# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) +# define RADEON_STENCIL_ZPASS_INC (3 << 20) +# define RADEON_STENCIL_ZPASS_DEC (4 << 20) +# define RADEON_STENCIL_ZPASS_INVERT (5 << 20) +# define RADEON_STENCIL_ZFAIL_KEEP (0 << 20) +# define RADEON_STENCIL_ZFAIL_ZERO (1 << 20) +# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 20) +# define RADEON_STENCIL_ZFAIL_INC (3 << 20) +# define RADEON_STENCIL_ZFAIL_DEC (4 << 20) +# define RADEON_STENCIL_ZFAIL_INVERT (5 << 20) +# define RADEON_Z_COMPRESSION_ENABLE (1 << 28) +# define RADEON_FORCE_Z_DIRTY (1 << 29) +# define RADEON_Z_WRITE_ENABLE (1 << 30) +# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31) +#define RADEON_RE_LINE_PATTERN 0x1cd0 +# define RADEON_LINE_PATTERN_MASK 0x0000ffff +# define RADEON_LINE_REPEAT_COUNT_SHIFT 16 +# define RADEON_LINE_PATTERN_START_SHIFT 24 +# define RADEON_LINE_PATTERN_LITTLE_BIT_ORDER (0 << 28) +# define RADEON_LINE_PATTERN_BIG_BIT_ORDER (1 << 28) +# define RADEON_LINE_PATTERN_AUTO_RESET (1 << 29) +#define RADEON_RE_LINE_STATE 0x1cd4 +# define RADEON_LINE_CURRENT_PTR_SHIFT 0 +# define RADEON_LINE_CURRENT_COUNT_SHIFT 8 +#define RADEON_RE_MISC 0x26c4 +# define RADEON_STIPPLE_COORD_MASK 0x1f +# define RADEON_STIPPLE_X_OFFSET_SHIFT 0 +# define RADEON_STIPPLE_X_OFFSET_MASK (0x1f << 0) +# define RADEON_STIPPLE_Y_OFFSET_SHIFT 8 +# define RADEON_STIPPLE_Y_OFFSET_MASK (0x1f << 8) +# define RADEON_STIPPLE_LITTLE_BIT_ORDER (0 << 16) +# define RADEON_STIPPLE_BIG_BIT_ORDER (1 << 16) +#define RADEON_RE_SOLID_COLOR 0x1c1c +#define RADEON_RE_TOP_LEFT 0x26c0 +# define RADEON_RE_LEFT_SHIFT 0 +# define RADEON_RE_TOP_SHIFT 16 +#define RADEON_RE_WIDTH_HEIGHT 0x1c44 +# define RADEON_RE_WIDTH_SHIFT 0 +# define RADEON_RE_HEIGHT_SHIFT 16 + +#define RADEON_SE_CNTL 0x1c4c +# define RADEON_FFACE_CULL_CW (0 << 0) +# define RADEON_FFACE_CULL_CCW (1 << 0) +# define RADEON_FFACE_CULL_DIR_MASK (1 << 0) +# define RADEON_BFACE_CULL (0 << 1) +# define RADEON_BFACE_SOLID (3 << 1) +# define RADEON_FFACE_CULL (0 << 3) +# define RADEON_FFACE_SOLID (3 << 3) +# define RADEON_FFACE_CULL_MASK (3 << 3) +# define RADEON_BADVTX_CULL_DISABLE (1 << 5) +# define RADEON_FLAT_SHADE_VTX_0 (0 << 6) +# define RADEON_FLAT_SHADE_VTX_1 (1 << 6) +# define RADEON_FLAT_SHADE_VTX_2 (2 << 6) +# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) +# define RADEON_DIFFUSE_SHADE_SOLID (0 << 8) +# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) +# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) +# define RADEON_DIFFUSE_SHADE_MASK (3 << 8) +# define RADEON_ALPHA_SHADE_SOLID (0 << 10) +# define RADEON_ALPHA_SHADE_FLAT (1 << 10) +# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) +# define RADEON_ALPHA_SHADE_MASK (3 << 10) +# define RADEON_SPECULAR_SHADE_SOLID (0 << 12) +# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) +# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) +# define RADEON_SPECULAR_SHADE_MASK (3 << 12) +# define RADEON_FOG_SHADE_SOLID (0 << 14) +# define RADEON_FOG_SHADE_FLAT (1 << 14) +# define RADEON_FOG_SHADE_GOURAUD (2 << 14) +# define RADEON_FOG_SHADE_MASK (3 << 14) +# define RADEON_ZBIAS_ENABLE_POINT (1 << 16) +# define RADEON_ZBIAS_ENABLE_LINE (1 << 17) +# define RADEON_ZBIAS_ENABLE_TRI (1 << 18) +# define RADEON_WIDELINE_ENABLE (1 << 20) +# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) +# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) +# define RADEON_VTX_PIX_CENTER_D3D (0 << 27) +# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) +# define RADEON_ROUND_MODE_TRUNC (0 << 28) +# define RADEON_ROUND_MODE_ROUND (1 << 28) +# define RADEON_ROUND_MODE_ROUND_EVEN (2 << 28) +# define RADEON_ROUND_MODE_ROUND_ODD (3 << 28) +# define RADEON_ROUND_PREC_16TH_PIX (0 << 30) +# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) +# define RADEON_ROUND_PREC_4TH_PIX (2 << 30) +# define RADEON_ROUND_PREC_HALF_PIX (3 << 30) +#define RADEON_SE_CNTL_STATUS 0x2140 +# define RADEON_VC_NO_SWAP (0 << 0) +# define RADEON_VC_16BIT_SWAP (1 << 0) +# define RADEON_VC_32BIT_SWAP (2 << 0) +# define RADEON_VC_HALF_DWORD_SWAP (3 << 0) +# define RADEON_TCL_BYPASS (1 << 8) +#define RADEON_SE_COORD_FMT 0x15c0 +# define RADEON_VTX_XY_PRE_MULT_1_OVER_W0 (1 << 0) +# define RADEON_VTX_Z_PRE_MULT_1_OVER_W0 (1 << 1) +# define RADEON_VTX_ST0_NONPARAMETRIC (1 << 8) +# define RADEON_VTX_ST1_NONPARAMETRIC (1 << 9) +# define RADEON_VTX_ST2_NONPARAMETRIC (1 << 10) +# define RADEON_VTX_ST3_NONPARAMETRIC (1 << 11) +# define RADEON_VTX_W0_NORMALIZE (1 << 12) +# define RADEON_VTX_W0_IS_NOT_1_OVER_W0 (1 << 16) +# define RADEON_VTX_ST0_PRE_MULT_1_OVER_W0 (1 << 17) +# define RADEON_VTX_ST1_PRE_MULT_1_OVER_W0 (1 << 19) +# define RADEON_VTX_ST2_PRE_MULT_1_OVER_W0 (1 << 21) +# define RADEON_VTX_ST3_PRE_MULT_1_OVER_W0 (1 << 23) +# define RADEON_TEX1_W_ROUTING_USE_W0 (0 << 26) +# define RADEON_TEX1_W_ROUTING_USE_Q1 (1 << 26) +#define RADEON_SE_LINE_WIDTH 0x1db8 +#define RADEON_SE_TCL_LIGHT_MODEL_CTL 0x226c +#define RADEON_SE_TCL_MATERIAL_AMBIENT_RED 0x2220 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_GREEN 0x2224 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_BLUE 0x2228 +#define RADEON_SE_TCL_MATERIAL_AMBIENT_ALPHA 0x222c +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_RED 0x2230 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_GREEN 0x2234 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_BLUE 0x2238 +#define RADEON_SE_TCL_MATERIAL_DIFFUSE_ALPHA 0x223c +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_GREEN 0x2214 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_BLUE 0x2218 +#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_ALPHA 0x221c +#define RADEON_SE_TCL_MATERIAL_SPECULAR_RED 0x2240 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_GREEN 0x2244 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_BLUE 0x2248 +#define RADEON_SE_TCL_MATERIAL_SPECULAR_ALPHA 0x224c +#define RADEON_SE_TCL_MATRIX_SELECT_0 0x225c +#define RADEON_SE_TCL_MATRIX_SELECT_1 0x2260 +#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254 +#define RADEON_SE_TCL_OUTPUT_VTX_SEL 0x2258 +#define RADEON_SE_TCL_PER_LIGHT_CTL_0 0x2270 +#define RADEON_SE_TCL_PER_LIGHT_CTL_1 0x2274 +#define RADEON_SE_TCL_PER_LIGHT_CTL_2 0x2278 +#define RADEON_SE_TCL_PER_LIGHT_CTL_3 0x227c +#define RADEON_SE_TCL_SHININESS 0x2250 +#define RADEON_SE_TCL_TEXTURE_PROC_CTL 0x2268 +#define RADEON_SE_TCL_UCP_VERT_BLEND_CTL 0x2264 +#define RADEON_SE_VPORT_XSCALE 0x1d98 +#define RADEON_SE_VPORT_XOFFSET 0x1d9c +#define RADEON_SE_VPORT_YSCALE 0x1da0 +#define RADEON_SE_VPORT_YOFFSET 0x1da4 +#define RADEON_SE_VPORT_ZSCALE 0x1da8 +#define RADEON_SE_VPORT_ZOFFSET 0x1dac + + /* Registers for CP and Microcode Engine */ #define RADEON_CP_ME_RAM_ADDR 0x07d4 #define RADEON_CP_ME_RAM_RADDR 0x07d8 #define RADEON_CP_ME_RAM_DATAH 0x07dc @@ -945,18 +1502,28 @@ #define RADEON_CP_RB_RPTR_ADDR 0x070c #define RADEON_CP_RB_RPTR 0x0710 #define RADEON_CP_RB_WPTR 0x0714 -# define RADEON_PM4_BUFFER_DL_DONE (1 << 31) #define RADEON_CP_IB_BASE 0x0738 #define RADEON_CP_IB_BUFSZ 0x073c #define RADEON_CP_CSQ_CNTL 0x0740 -# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) -# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) -# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) -# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) -# define RADEON_CSQ_PRIBM_INDBM (4 << 28) -# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) +# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) +# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) +# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) +# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) +# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) +# define RADEON_CSQ_PRIBM_INDBM (4 << 28) +# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) +#define RADEON_CP_CSQ_STAT 0x07f8 +# define RADEON_CSQ_RPTR_PRIMARY_MASK (0xff << 0) +# define RADEON_CSQ_WPTR_PRIMARY_MASK (0xff << 8) +# define RADEON_CSQ_RPTR_INDIRECT_MASK (0xff << 16) +# define RADEON_CSQ_WPTR_INDIRECT_MASK (0xff << 24) +#define RADEON_CP_CSQ_ADDR 0x07f0 +#define RADEON_CP_CSQ_DATA 0x07f4 +#define RADEON_CP_CSQ_APER_PRIMARY 0x1000 +#define RADEON_CP_CSQ_APER_INDIRECT 0x1300 + #define RADEON_CP_RB_WPTR_DELAY 0x0718 # define RADEON_PRE_WRITE_TIMER_SHIFT 0 # define RADEON_PRE_WRITE_LIMIT_SHIFT 23 @@ -964,518 +1531,94 @@ #define RADEON_AIC_CNTL 0x01d0 # define RADEON_PCIGART_TRANSLATE_EN (1 << 0) -#define RADEON_PM4_VC_FPU_SETUP 0x071c -# define RADEON_FRONT_DIR_CW (0 << 0) -# define RADEON_FRONT_DIR_CCW (1 << 0) -# define RADEON_FRONT_DIR_MASK (1 << 0) -# define RADEON_BACKFACE_CULL (0 << 1) -# define RADEON_BACKFACE_POINTS (1 << 1) -# define RADEON_BACKFACE_LINES (2 << 1) -# define RADEON_BACKFACE_SOLID (3 << 1) -# define RADEON_BACKFACE_MASK (3 << 1) -# define RADEON_FRONTFACE_CULL (0 << 3) -# define RADEON_FRONTFACE_POINTS (1 << 3) -# define RADEON_FRONTFACE_LINES (2 << 3) -# define RADEON_FRONTFACE_SOLID (3 << 3) -# define RADEON_FRONTFACE_MASK (3 << 3) -# define RADEON_FPU_COLOR_SOLID (0 << 5) -# define RADEON_FPU_COLOR_FLAT (1 << 5) -# define RADEON_FPU_COLOR_GOURAUD (2 << 5) -# define RADEON_FPU_COLOR_GOURAUD2 (3 << 5) -# define RADEON_FPU_COLOR_MASK (3 << 5) -# define RADEON_FPU_SUB_PIX_2BITS (0 << 7) -# define RADEON_FPU_SUB_PIX_4BITS (1 << 7) -# define RADEON_FPU_MODE_2D (0 << 8) -# define RADEON_FPU_MODE_3D (1 << 8) -# define RADEON_TRAP_BITS_DISABLE (1 << 9) -# define RADEON_EDGE_ANTIALIAS (1 << 10) -# define RADEON_SUPERSAMPLE (1 << 11) -# define RADEON_XFACTOR_2 (0 << 12) -# define RADEON_XFACTOR_4 (1 << 12) -# define RADEON_YFACTOR_2 (0 << 13) -# define RADEON_YFACTOR_4 (1 << 13) -# define RADEON_FLAT_SHADE_VERTEX_D3D (0 << 14) -# define RADEON_FLAT_SHADE_VERTEX_OGL (1 << 14) -# define RADEON_FPU_ROUND_TRUNCATE (0 << 15) -# define RADEON_FPU_ROUND_NEAREST (1 << 15) -# define RADEON_WM_SEL_8DW (0 << 16) -# define RADEON_WM_SEL_16DW (1 << 16) -# define RADEON_WM_SEL_32DW (2 << 16) -#define RADEON_PM4_VC_DEBUG_CONFIG 0x07a4 -#define RADEON_PM4_VC_STAT 0x07a8 -#define RADEON_PM4_VC_TIMESTAMP0 0x07b0 -#define RADEON_PM4_VC_TIMESTAMP1 0x07b4 -#define RADEON_PM4_STAT 0x07b8 -# define RADEON_PM4_FIFOCNT_MASK 0x0fff -# define RADEON_PM4_BUSY (1 << 16) -# define RADEON_PM4_GUI_ACTIVE (1 << 31) -#define RADEON_PM4_BUFFER_ADDR 0x07f0 -#define RADEON_CP_ME_CNTL 0x07d0 -# define RADEON_CP_ME_FREERUN (1 << 30) -#define RADEON_PM4_FIFO_DATA_EVEN 0x1000 -#define RADEON_PM4_FIFO_DATA_ODD 0x1004 - -#define RADEON_SCALE_3D_CNTL 0x1a00 -# define RADEON_SCALE_DITHER_ERR_DIFF (0 << 1) -# define RADEON_SCALE_DITHER_TABLE (1 << 1) -# define RADEON_TEX_CACHE_SIZE_FULL (0 << 2) -# define RADEON_TEX_CACHE_SIZE_HALF (1 << 2) -# define RADEON_DITHER_INIT_CURR (0 << 3) -# define RADEON_DITHER_INIT_RESET (1 << 3) -# define RADEON_ROUND_24BIT (1 << 4) -# define RADEON_TEX_CACHE_DISABLE (1 << 5) -# define RADEON_SCALE_3D_NOOP (0 << 6) -# define RADEON_SCALE_3D_SCALE (1 << 6) -# define RADEON_SCALE_3D_TEXMAP_SHADE (2 << 6) -# define RADEON_SCALE_PIX_BLEND (0 << 8) -# define RADEON_SCALE_PIX_REPLICATE (1 << 8) -# define RADEON_TEX_CACHE_SPLIT (1 << 9) -# define RADEON_APPLE_YUV_MODE (1 << 10) -# define RADEON_TEX_CACHE_PALLETE_MODE (1 << 11) -# define RADEON_ALPHA_COMB_ADD_CLAMP (0 << 12) -# define RADEON_ALPHA_COMB_ADD_NCLAMP (1 << 12) -# define RADEON_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12) -# define RADEON_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12) -# define RADEON_FOG_TABLE (1 << 14) -# define RADEON_SIGNED_DST_CLAMP (1 << 15) -# define RADEON_ALPHA_BLEND_SRC_ZERO (0 << 16) -# define RADEON_ALPHA_BLEND_SRC_ONE (1 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) -# define RADEON_ALPHA_BLEND_SRC_DSTALPHA (6 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16) -# define RADEON_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16) -# define RADEON_ALPHA_BLEND_SRC_SAT (10 << 16) -# define RADEON_ALPHA_BLEND_SRC_BLEND (11 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVBLEND (12 << 16) -# define RADEON_ALPHA_BLEND_DST_ZERO (0 << 20) -# define RADEON_ALPHA_BLEND_DST_ONE (1 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) -# define RADEON_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCALPHA (4 << 20) -# define RADEON_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) -# define RADEON_ALPHA_BLEND_DST_DSTALPHA (6 << 20) -# define RADEON_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20) -# define RADEON_ALPHA_BLEND_DST_DSTCOLOR (8 << 20) -# define RADEON_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20) -# define RADEON_ALPHA_TEST_NEVER (0 << 24) -# define RADEON_ALPHA_TEST_LESS (1 << 24) -# define RADEON_ALPHA_TEST_LESSEQUAL (2 << 24) -# define RADEON_ALPHA_TEST_EQUAL (3 << 24) -# define RADEON_ALPHA_TEST_GREATEREQUAL (4 << 24) -# define RADEON_ALPHA_TEST_GREATER (5 << 24) -# define RADEON_ALPHA_TEST_NEQUAL (6 << 24) -# define RADEON_ALPHA_TEST_ALWAYS (7 << 24) -# define RADEON_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28) -# define RADEON_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28) -# define RADEON_COMPOSITE_SHADOW (1 << 29) -# define RADEON_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30) -# define RADEON_TEX_CACHE_LINE_SIZE_8QW (0 << 31) -# define RADEON_TEX_CACHE_LINE_SIZE_4QW (1 << 31) -#define RADEON_SCALE_3D_DATATYPE 0x1a20 - -#define RADEON_SETUP_CNTL 0x1bc4 -# define RADEON_DONT_START_TRIANGLE (1 << 0) -# define RADEON_Z_BIAS (0 << 1) -# define RADEON_DONT_START_ANY_ON (1 << 2) -# define RADEON_COLOR_SOLID_COLOR (0 << 3) -# define RADEON_COLOR_FLAT_VERT_1 (1 << 3) -# define RADEON_COLOR_FLAT_VERT_2 (2 << 3) -# define RADEON_COLOR_FLAT_VERT_3 (3 << 3) -# define RADEON_COLOR_GOURAUD (4 << 3) -# define RADEON_PRIM_TYPE_TRI (0 << 7) -# define RADEON_PRIM_TYPE_LINE (1 << 7) -# define RADEON_PRIM_TYPE_POINT (2 << 7) -# define RADEON_PRIM_TYPE_POLY_EDGE (3 << 7) -# define RADEON_TEXTURE_ST_MULT_W (0 << 9) -# define RADEON_TEXTURE_ST_DIRECT (1 << 9) -# define RADEON_STARTING_VERTEX_1 (1 << 14) -# define RADEON_STARTING_VERTEX_2 (2 << 14) -# define RADEON_STARTING_VERTEX_3 (3 << 14) -# define RADEON_ENDING_VERTEX_1 (1 << 16) -# define RADEON_ENDING_VERTEX_2 (2 << 16) -# define RADEON_ENDING_VERTEX_3 (3 << 16) -# define RADEON_SU_POLY_LINE_LAST (0 << 18) -# define RADEON_SU_POLY_LINE_NOT_LAST (1 << 18) -# define RADEON_SUB_PIX_2BITS (0 << 19) -# define RADEON_SUB_PIX_4BITS (1 << 19) -# define RADEON_SET_UP_CONTINUE (1 << 31) - -#define RADEON_WINDOW_XY_OFFSET 0x1bcc -# define RADEON_WINDOW_Y_SHIFT 4 -# define RADEON_WINDOW_X_SHIFT 20 - -#define RADEON_Z_OFFSET_C 0x1c90 -#define RADEON_Z_PITCH_C 0x1c94 -#define RADEON_Z_STEN_CNTL_C 0x1c98 -# define RADEON_Z_PIX_WIDTH_16 (0 << 1) -# define RADEON_Z_PIX_WIDTH_24 (1 << 1) -# define RADEON_Z_PIX_WIDTH_32 (2 << 1) -# define RADEON_Z_PIX_WIDTH_MASK (3 << 1) -# define RADEON_Z_TEST_NEVER (0 << 4) -# define RADEON_Z_TEST_LESS (1 << 4) -# define RADEON_Z_TEST_LESSEQUAL (2 << 4) -# define RADEON_Z_TEST_EQUAL (3 << 4) -# define RADEON_Z_TEST_GREATEREQUAL (4 << 4) -# define RADEON_Z_TEST_GREATER (5 << 4) -# define RADEON_Z_TEST_NEQUAL (6 << 4) -# define RADEON_Z_TEST_ALWAYS (7 << 4) -# define RADEON_Z_TEST_MASK (7 << 4) -# define RADEON_STENCIL_TEST_NEVER (0 << 12) -# define RADEON_STENCIL_TEST_LESS (1 << 12) -# define RADEON_STENCIL_TEST_LESSEQUAL (2 << 12) -# define RADEON_STENCIL_TEST_EQUAL (3 << 12) -# define RADEON_STENCIL_TEST_GREATEREQUAL (4 << 12) -# define RADEON_STENCIL_TEST_GREATER (5 << 12) -# define RADEON_STENCIL_TEST_NEQUAL (6 << 12) -# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) -# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) -# define RADEON_STENCIL_S_FAIL_ZERO (1 << 16) -# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16) -# define RADEON_STENCIL_S_FAIL_INC (3 << 16) -# define RADEON_STENCIL_S_FAIL_DEC (4 << 16) -# define RADEON_STENCIL_S_FAIL_INV (5 << 16) -# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) -# define RADEON_STENCIL_ZPASS_ZERO (1 << 20) -# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20) -# define RADEON_STENCIL_ZPASS_INC (3 << 20) -# define RADEON_STENCIL_ZPASS_DEC (4 << 20) -# define RADEON_STENCIL_ZPASS_INV (5 << 20) -# define RADEON_STENCIL_ZFAIL_KEEP (0 << 24) -# define RADEON_STENCIL_ZFAIL_ZERO (1 << 24) -# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24) -# define RADEON_STENCIL_ZFAIL_INC (3 << 24) -# define RADEON_STENCIL_ZFAIL_DEC (4 << 24) -# define RADEON_STENCIL_ZFAIL_INV (5 << 24) -#define RADEON_TEX_CNTL_C 0x1c9c -# define RADEON_Z_ENABLE (1 << 0) -# define RADEON_Z_WRITE_ENABLE (1 << 1) -# define RADEON_STENCIL_ENABLE (1 << 3) -# define RADEON_SHADE_ENABLE (0 << 4) -# define RADEON_TEXMAP_ENABLE (1 << 4) -# define RADEON_SEC_TEXMAP_ENABLE (1 << 5) -# define RADEON_FOG_ENABLE (1 << 7) -# define RADEON_DITHER_ENABLE (1 << 8) -# define RADEON_ALPHA_ENABLE (1 << 9) -# define RADEON_ALPHA_TEST_ENABLE (1 << 10) -# define RADEON_SPEC_LIGHT_ENABLE (1 << 11) -# define RADEON_TEX_CHROMA_KEY_ENABLE (1 << 12) -# define RADEON_ALPHA_IN_TEX_COMPLETE_A (0 << 13) -# define RADEON_ALPHA_IN_TEX_LSB_A (1 << 13) -# define RADEON_LIGHT_DIS (0 << 14) -# define RADEON_LIGHT_COPY (1 << 14) -# define RADEON_LIGHT_MODULATE (2 << 14) -# define RADEON_LIGHT_ADD (3 << 14) -# define RADEON_LIGHT_BLEND_CONSTANT (4 << 14) -# define RADEON_LIGHT_BLEND_TEXTURE (5 << 14) -# define RADEON_LIGHT_BLEND_VERTEX (6 << 14) -# define RADEON_LIGHT_BLEND_CONST_COLOR (7 << 14) -# define RADEON_ALPHA_LIGHT_DIS (0 << 18) -# define RADEON_ALPHA_LIGHT_COPY (1 << 18) -# define RADEON_ALPHA_LIGHT_MODULATE (2 << 18) -# define RADEON_ALPHA_LIGHT_ADD (3 << 18) -# define RADEON_ANTI_ALIAS (1 << 21) -# define RADEON_TEX_CACHE_FLUSH (1 << 23) -# define RADEON_LOD_BIAS_SHIFT 24 -#define RADEON_MISC_3D_STATE_CNTL_REG 0x1ca0 -# define RADEON_REF_ALPHA_MASK 0xff -# define RADEON_MISC_SCALE_3D_NOOP (0 << 8) -# define RADEON_MISC_SCALE_3D_SCALE (1 << 8) -# define RADEON_MISC_SCALE_3D_TEXMAP_SHADE (2 << 8) -# define RADEON_MISC_SCALE_PIX_BLEND (0 << 10) -# define RADEON_MISC_SCALE_PIX_REPLICATE (1 << 10) -# define RADEON_ALPHA_COMB_ADD_CLAMP (0 << 12) -# define RADEON_ALPHA_COMB_ADD_NO_CLAMP (1 << 12) -# define RADEON_ALPHA_COMB_SUB_SRC_DST_CLAMP (2 << 12) -# define RADEON_ALPHA_COMB_SUB_SRC_DST_NO_CLAMP (3 << 12) -# define RADEON_FOG_VERTEX (0 << 14) -# define RADEON_FOG_TABLE (1 << 14) -# define RADEON_ALPHA_BLEND_SRC_ZERO (0 << 16) -# define RADEON_ALPHA_BLEND_SRC_ONE (1 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) -# define RADEON_ALPHA_BLEND_SRC_DESTALPHA (6 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVDESTALPHA (7 << 16) -# define RADEON_ALPHA_BLEND_SRC_DESTCOLOR (8 << 16) -# define RADEON_ALPHA_BLEND_SRC_INVDESTCOLOR (9 << 16) -# define RADEON_ALPHA_BLEND_SRC_SRCALPHASAT (10 << 16) -# define RADEON_ALPHA_BLEND_SRC_BOTHSRCALPHA (11 << 16) -# define RADEON_ALPHA_BLEND_SRC_BOTHINVSRCALPHA (12 << 16) -# define RADEON_ALPHA_BLEND_SRC_MASK (15 << 16) -# define RADEON_ALPHA_BLEND_DST_ZERO (0 << 20) -# define RADEON_ALPHA_BLEND_DST_ONE (1 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) -# define RADEON_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCALPHA (4 << 20) -# define RADEON_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) -# define RADEON_ALPHA_BLEND_DST_DESTALPHA (6 << 20) -# define RADEON_ALPHA_BLEND_DST_INVDESTALPHA (7 << 20) -# define RADEON_ALPHA_BLEND_DST_DESTCOLOR (8 << 20) -# define RADEON_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20) -# define RADEON_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20) -# define RADEON_ALPHA_BLEND_DST_MASK (15 << 20) -# define RADEON_ALPHA_TEST_NEVER (0 << 24) -# define RADEON_ALPHA_TEST_LESS (1 << 24) -# define RADEON_ALPHA_TEST_LESSEQUAL (2 << 24) -# define RADEON_ALPHA_TEST_EQUAL (3 << 24) -# define RADEON_ALPHA_TEST_GREATEREQUAL (4 << 24) -# define RADEON_ALPHA_TEST_GREATER (5 << 24) -# define RADEON_ALPHA_TEST_NEQUAL (6 << 24) -# define RADEON_ALPHA_TEST_ALWAYS (7 << 24) -# define RADEON_ALPHA_TEST_MASK (7 << 24) -#define RADEON_TEXTURE_CLR_CMP_CLR_C 0x1ca4 -#define RADEON_TEXTURE_CLR_CMP_MSK_C 0x1ca8 -#define RADEON_FOG_COLOR_C 0x1cac -# define RADEON_FOG_BLUE_SHIFT 0 -# define RADEON_FOG_GREEN_SHIFT 8 -# define RADEON_FOG_RED_SHIFT 16 -#define RADEON_PRIM_TEX_CNTL_C 0x1cb0 -# define RADEON_MIN_BLEND_NEAREST (0 << 1) -# define RADEON_MIN_BLEND_LINEAR (1 << 1) -# define RADEON_MIN_BLEND_MIPNEAREST (2 << 1) -# define RADEON_MIN_BLEND_MIPLINEAR (3 << 1) -# define RADEON_MIN_BLEND_LINEARMIPNEAREST (4 << 1) -# define RADEON_MIN_BLEND_LINEARMIPLINEAR (5 << 1) -# define RADEON_MIN_BLEND_MASK (7 << 1) -# define RADEON_MAG_BLEND_NEAREST (0 << 4) -# define RADEON_MAG_BLEND_LINEAR (1 << 4) -# define RADEON_MAG_BLEND_MASK (7 << 4) -# define RADEON_MIP_MAP_DISABLE (1 << 7) -# define RADEON_TEX_CLAMP_S_WRAP (0 << 8) -# define RADEON_TEX_CLAMP_S_MIRROR (1 << 8) -# define RADEON_TEX_CLAMP_S_CLAMP (2 << 8) -# define RADEON_TEX_CLAMP_S_BORDER_COLOR (3 << 8) -# define RADEON_TEX_CLAMP_S_MASK (3 << 8) -# define RADEON_TEX_WRAP_S (1 << 10) -# define RADEON_TEX_CLAMP_T_WRAP (0 << 11) -# define RADEON_TEX_CLAMP_T_MIRROR (1 << 11) -# define RADEON_TEX_CLAMP_T_CLAMP (2 << 11) -# define RADEON_TEX_CLAMP_T_BORDER_COLOR (3 << 11) -# define RADEON_TEX_CLAMP_T_MASK (3 << 11) -# define RADEON_TEX_WRAP_T (1 << 13) -# define RADEON_TEX_PERSPECTIVE_DISABLE (1 << 14) -# define RADEON_DATATYPE_VQ (0 << 16) -# define RADEON_DATATYPE_CI4 (1 << 16) -# define RADEON_DATATYPE_CI8 (2 << 16) -# define RADEON_DATATYPE_ARGB1555 (3 << 16) -# define RADEON_DATATYPE_RGB565 (4 << 16) -# define RADEON_DATATYPE_RGB888 (5 << 16) -# define RADEON_DATATYPE_ARGB8888 (6 << 16) -# define RADEON_DATATYPE_RGB332 (7 << 16) -# define RADEON_DATATYPE_Y8 (8 << 16) -# define RADEON_DATATYPE_RGB8 (9 << 16) -# define RADEON_DATATYPE_CI16 (10 << 16) -# define RADEON_DATATYPE_YUV422 (11 << 16) -# define RADEON_DATATYPE_YUV422_2 (12 << 16) -# define RADEON_DATATYPE_AYUV444 (14 << 16) -# define RADEON_DATATYPE_ARGB4444 (15 << 16) -# define RADEON_PALLETE_EITHER (0 << 20) -# define RADEON_PALLETE_1 (1 << 20) -# define RADEON_PALLETE_2 (2 << 20) -# define RADEON_PSEUDOCOLOR_DT_RGB565 (0 << 24) -# define RADEON_PSEUDOCOLOR_DT_ARGB1555 (1 << 24) -# define RADEON_PSEUDOCOLOR_DT_ARGB4444 (2 << 24) -#define RADEON_PRIM_TEXTURE_COMBINE_CNTL_C 0x1cb4 -# define RADEON_COMB_DIS (0 << 0) -# define RADEON_COMB_COPY (1 << 0) -# define RADEON_COMB_COPY_INP (2 << 0) -# define RADEON_COMB_MODULATE (3 << 0) -# define RADEON_COMB_MODULATE2X (4 << 0) -# define RADEON_COMB_MODULATE4X (5 << 0) -# define RADEON_COMB_ADD (6 << 0) -# define RADEON_COMB_ADD_SIGNED (7 << 0) -# define RADEON_COMB_BLEND_VERTEX (8 << 0) -# define RADEON_COMB_BLEND_TEXTURE (9 << 0) -# define RADEON_COMB_BLEND_CONST (10 << 0) -# define RADEON_COMB_BLEND_PREMULT (11 << 0) -# define RADEON_COMB_BLEND_PREV (12 << 0) -# define RADEON_COMB_BLEND_PREMULT_INV (13 << 0) -# define RADEON_COMB_ADD_SIGNED2X (14 << 0) -# define RADEON_COMB_BLEND_CONST_COLOR (15 << 0) -# define RADEON_COMB_MASK (15 << 0) -# define RADEON_COLOR_FACTOR_TEX (4 << 4) -# define RADEON_COLOR_FACTOR_NTEX (5 << 4) -# define RADEON_COLOR_FACTOR_ALPHA (6 << 4) -# define RADEON_COLOR_FACTOR_NALPHA (7 << 4) -# define RADEON_COLOR_FACTOR_MASK (15 << 4) -# define RADEON_INPUT_FACTOR_CONST_COLOR (2 << 10) -# define RADEON_INPUT_FACTOR_CONST_ALPHA (3 << 10) -# define RADEON_INPUT_FACTOR_INT_COLOR (4 << 10) -# define RADEON_INPUT_FACTOR_INT_ALPHA (5 << 10) -# define RADEON_INPUT_FACTOR_MASK (15 << 10) -# define RADEON_COMB_ALPHA_DIS (0 << 14) -# define RADEON_COMB_ALPHA_COPY (1 << 14) -# define RADEON_COMB_ALPHA_COPY_INP (2 << 14) -# define RADEON_COMB_ALPHA_MODULATE (3 << 14) -# define RADEON_COMB_ALPHA_MODULATE2X (4 << 14) -# define RADEON_COMB_ALPHA_MODULATE4X (5 << 14) -# define RADEON_COMB_ALPHA_ADD (6 << 14) -# define RADEON_COMB_ALPHA_ADD_SIGNED (7 << 14) -# define RADEON_COMB_ALPHA_ADD_SIGNED2X (14 << 14) -# define RADEON_COMB_ALPHA_MASK (15 << 14) -# define RADEON_ALPHA_FACTOR_TEX_ALPHA (6 << 18) -# define RADEON_ALPHA_FACTOR_NTEX_ALPHA (7 << 18) -# define RADEON_ALPHA_FACTOR_MASK (15 << 18) -# define RADEON_INP_FACTOR_A_CONST_ALPHA (1 << 25) -# define RADEON_INP_FACTOR_A_INT_ALPHA (2 << 25) -# define RADEON_INP_FACTOR_A_MASK (7 << 25) -#define RADEON_TEX_SIZE_PITCH_C 0x1cb8 -# define RADEON_TEX_PITCH_SHIFT 0 -# define RADEON_TEX_SIZE_SHIFT 4 -# define RADEON_TEX_HEIGHT_SHIFT 8 -# define RADEON_TEX_MIN_SIZE_SHIFT 12 -# define RADEON_SEC_TEX_PITCH_SHIFT 16 -# define RADEON_SEC_TEX_SIZE_SHIFT 20 -# define RADEON_SEC_TEX_HEIGHT_SHIFT 24 -# define RADEON_SEC_TEX_MIN_SIZE_SHIFT 28 -# define RADEON_TEX_PITCH_MASK (0x0f << 0) -# define RADEON_TEX_SIZE_MASK (0x0f << 4) -# define RADEON_TEX_HEIGHT_MASK (0x0f << 8) -# define RADEON_TEX_MIN_SIZE_MASK (0x0f << 12) -# define RADEON_SEC_TEX_PITCH_MASK (0x0f << 16) -# define RADEON_SEC_TEX_SIZE_MASK (0x0f << 20) -# define RADEON_SEC_TEX_HEIGHT_MASK (0x0f << 24) -# define RADEON_SEC_TEX_MIN_SIZE_MASK (0x0f << 28) -# define RADEON_TEX_SIZE_PITCH_SHIFT 0 -# define RADEON_SEC_TEX_SIZE_PITCH_SHIFT 16 -# define RADEON_TEX_SIZE_PITCH_MASK (0xffff << 0) -# define RADEON_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16) -#define RADEON_PRIM_TEX_0_OFFSET_C 0x1cbc -#define RADEON_PRIM_TEX_1_OFFSET_C 0x1cc0 -#define RADEON_PRIM_TEX_2_OFFSET_C 0x1cc4 -#define RADEON_PRIM_TEX_3_OFFSET_C 0x1cc8 -#define RADEON_PRIM_TEX_4_OFFSET_C 0x1ccc -#define RADEON_PRIM_TEX_5_OFFSET_C 0x1cd0 -#define RADEON_PRIM_TEX_6_OFFSET_C 0x1cd4 -#define RADEON_PRIM_TEX_7_OFFSET_C 0x1cd8 -#define RADEON_PRIM_TEX_8_OFFSET_C 0x1cdc -#define RADEON_PRIM_TEX_9_OFFSET_C 0x1ce0 -#define RADEON_PRIM_TEX_10_OFFSET_C 0x1ce4 -# define RADEON_TEX_NO_TILE (0 << 30) -# define RADEON_TEX_TILED_BY_HOST (1 << 30) -# define RADEON_TEX_TILED_BY_STORAGE (2 << 30) -# define RADEON_TEX_TILED_BY_STORAGE2 (3 << 30) + /* Constants */ +#define RADEON_AGP_TEX_OFFSET 0x02000000 -#define RADEON_SEC_TEX_CNTL_C 0x1d00 -# define RADEON_SEC_SELECT_PRIM_ST (0 << 0) -# define RADEON_SEC_SELECT_SEC_ST (1 << 0) -#define RADEON_SEC_TEX_COMBINE_CNTL_C 0x1d04 -# define RADEON_INPUT_FACTOR_PREV_COLOR (8 << 10) -# define RADEON_INPUT_FACTOR_PREV_ALPHA (9 << 10) -# define RADEON_INP_FACTOR_A_PREV_ALPHA (4 << 25) -#define RADEON_SEC_TEX_0_OFFSET_C 0x1d08 -#define RADEON_SEC_TEX_1_OFFSET_C 0x1d0c -#define RADEON_SEC_TEX_2_OFFSET_C 0x1d10 -#define RADEON_SEC_TEX_3_OFFSET_C 0x1d14 -#define RADEON_SEC_TEX_4_OFFSET_C 0x1d18 -#define RADEON_SEC_TEX_5_OFFSET_C 0x1d1c -#define RADEON_SEC_TEX_6_OFFSET_C 0x1d20 -#define RADEON_SEC_TEX_7_OFFSET_C 0x1d24 -#define RADEON_SEC_TEX_8_OFFSET_C 0x1d28 -#define RADEON_SEC_TEX_9_OFFSET_C 0x1d2c -#define RADEON_SEC_TEX_10_OFFSET_C 0x1d30 -#define RADEON_CONSTANT_COLOR_C 0x1d34 -# define RADEON_CONSTANT_BLUE_SHIFT 0 -# define RADEON_CONSTANT_GREEN_SHIFT 8 -# define RADEON_CONSTANT_RED_SHIFT 16 -# define RADEON_CONSTANT_ALPHA_SHIFT 24 -#define RADEON_PRIM_TEXTURE_BORDER_COLOR_C 0x1d38 -# define RADEON_PRIM_TEX_BORDER_BLUE_SHIFT 0 -# define RADEON_PRIM_TEX_BORDER_GREEN_SHIFT 8 -# define RADEON_PRIM_TEX_BORDER_RED_SHIFT 16 -# define RADEON_PRIM_TEX_BORDER_ALPHA_SHIFT 24 -#define RADEON_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c -# define RADEON_SEC_TEX_BORDER_BLUE_SHIFT 0 -# define RADEON_SEC_TEX_BORDER_GREEN_SHIFT 8 -# define RADEON_SEC_TEX_BORDER_RED_SHIFT 16 -# define RADEON_SEC_TEX_BORDER_ALPHA_SHIFT 24 -#define RADEON_STEN_REF_MASK_C 0x1d40 -# define RADEON_STEN_REFERENCE_SHIFT 0 -# define RADEON_STEN_MASK_SHIFT 16 -# define RADEON_STEN_WRITE_MASK_SHIFT 24 -#define RADEON_PLANE_3D_MASK_C 0x1d44 -#define RADEON_TEX_CACHE_STAT_COUNT 0x1974 +#define RADEON_LAST_FRAME_REG RADEON_GUI_SCRATCH_REG0 +#define RADEON_LAST_CLEAR_REG RADEON_GUI_SCRATCH_REG2 + /* CP packet types */ +#define RADEON_CP_PACKET0 0x00000000 +#define RADEON_CP_PACKET1 0x40000000 +#define RADEON_CP_PACKET2 0x80000000 +#define RADEON_CP_PACKET3 0xC0000000 +# define RADEON_CP_PACKET_MASK 0xC0000000 +# define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 +# define RADEON_CP_PACKET_MAX_DWORDS (1 << 12) +# define RADEON_CP_PACKET0_REG_MASK 0x000007ff +# define RADEON_CP_PACKET1_REG0_MASK 0x000007ff +# define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 - /* Constants */ -#define RADEON_AGP_TEX_OFFSET 0x02000000 +#define RADEON_CP_PACKET0_ONE_REG_WR 0x00008000 -#define RADEON_VB_AGE_REG RADEON_GUI_SCRATCH_REG0 -#define RADEON_SWAP_AGE_REG RADEON_GUI_SCRATCH_REG1 +#define RADEON_CP_PACKET3_NOP 0xC0001000 +#define RADEON_CP_PACKET3_NEXT_CHAR 0xC0001900 +#define RADEON_CP_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define RADEON_CP_PACKET3_SET_SCISSORS 0xC0001E00 +#define RADEON_CP_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define RADEON_CP_PACKET3_LOAD_MICROCODE 0xC0002400 +#define RADEON_CP_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 +#define RADEON_CP_PACKET3_WAIT_FOR_IDLE 0xC0002600 +#define RADEON_CP_PACKET3_3D_DRAW_VBUF 0xC0002800 +#define RADEON_CP_PACKET3_3D_DRAW_IMMD 0xC0002900 +#define RADEON_CP_PACKET3_3D_DRAW_INDX 0xC0002A00 +#define RADEON_CP_PACKET3_LOAD_PALETTE 0xC0002C00 +#define RADEON_CP_PACKET3_3D_LOAD_VBPNTR 0xC0002F00 +#define RADEON_CP_PACKET3_3D_CLEAR_ZMASK 0xC0003200 +#define RADEON_CP_PACKET3_CNTL_PAINT 0xC0009100 +#define RADEON_CP_PACKET3_CNTL_BITBLT 0xC0009200 +#define RADEON_CP_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define RADEON_CP_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define RADEON_CP_PACKET3_CNTL_POLYLINE 0xC0009500 +#define RADEON_CP_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define RADEON_CP_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define RADEON_CP_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define RADEON_CP_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 - /* CCE packet types */ -#define RADEON_CCE_PACKET0 0x00000000 -#define RADEON_CCE_PACKET0_ONE_REG_WR 0x00008000 -#define RADEON_CCE_PACKET1 0x40000000 -#define RADEON_CCE_PACKET2 0x80000000 -#define RADEON_CCE_PACKET3_NOP 0xC0001000 -#define RADEON_CCE_PACKET3_PAINT 0xC0001100 -#define RADEON_CCE_PACKET3_BITBLT 0xC0001200 -#define RADEON_CCE_PACKET3_SMALLTEXT 0xC0001300 -#define RADEON_CCE_PACKET3_HOSTDATA_BLT 0xC0001400 -#define RADEON_CCE_PACKET3_POLYLINE 0xC0001500 -#define RADEON_CCE_PACKET3_SCALING 0xC0001600 -#define RADEON_CCE_PACKET3_TRANS_SCALING 0xC0001700 -#define RADEON_CCE_PACKET3_POLYSCANLINES 0xC0001800 -#define RADEON_CCE_PACKET3_NEXT_CHAR 0xC0001900 -#define RADEON_CCE_PACKET3_PAINT_MULTI 0xC0001A00 -#define RADEON_CCE_PACKET3_BITBLT_MULTI 0xC0001B00 -#define RADEON_CCE_PACKET3_PLY_NEXTSCAN 0xC0001D00 -#define RADEON_CCE_PACKET3_SET_SCISSORS 0xC0001E00 -#define RADEON_CCE_PACKET3_SET_MODE24BPP 0xC0001F00 -#define RADEON_CCE_PACKET3_CNTL_PAINT 0xC0009100 -#define RADEON_CCE_PACKET3_CNTL_BITBLT 0xC0009200 -#define RADEON_CCE_PACKET3_CNTL_SMALLTEXT 0xC0009300 -#define RADEON_CCE_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 -#define RADEON_CCE_PACKET3_CNTL_POLYLINE 0xC0009500 -#define RADEON_CCE_PACKET3_CNTL_SCALING 0xC0009600 -#define RADEON_CCE_PACKET3_CNTL_TRANS_SCALING 0xC0009700 -#define RADEON_CCE_PACKET3_CNTL_POLYSCANLINES 0xC0009800 -#define RADEON_CCE_PACKET3_CNTL_NEXT_CHAR 0xC0009900 -#define RADEON_CCE_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 -#define RADEON_CCE_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 -#define RADEON_CCE_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 -#define RADEON_CCE_PACKET3_3D_SAVE_CONTEXT 0xC0002000 -#define RADEON_CCE_PACKET3_3D_PLAY_CONTEXT 0xC0002100 -#define RADEON_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 -#define RADEON_CCE_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 -#define RADEON_CCE_PACKET3_LOAD_PALETTE 0xC0002C00 -#define RADEON_CCE_PACKET3_PURGE 0xC0002D00 -#define RADEON_CCE_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00 -# define RADEON_CCE_PACKET_MASK 0xC0000000 -# define RADEON_CCE_PACKET_COUNT_MASK 0x3fff0000 -# define RADEON_CCE_PACKET_MAX_DWORDS (1 << 14) -# define RADEON_CCE_PACKET0_REG_MASK 0x000007ff -# define RADEON_CCE_PACKET1_REG0_MASK 0x000007ff -# define RADEON_CCE_PACKET1_REG1_MASK 0x003ff800 -#define RADEON_CCE_VC_FRMT_RHW 0x00000001 -#define RADEON_CCE_VC_FRMT_DIFFUSE_BGR 0x00000002 -#define RADEON_CCE_VC_FRMT_DIFFUSE_A 0x00000004 -#define RADEON_CCE_VC_FRMT_DIFFUSE_ARGB 0x00000008 -#define RADEON_CCE_VC_FRMT_SPEC_BGR 0x00000010 -#define RADEON_CCE_VC_FRMT_SPEC_F 0x00000020 -#define RADEON_CCE_VC_FRMT_SPEC_FRGB 0x00000040 -#define RADEON_CCE_VC_FRMT_S_T 0x00000080 -#define RADEON_CCE_VC_FRMT_S2_T2 0x00000100 -#define RADEON_CCE_VC_FRMT_RHW2 0x00000200 +#define RADEON_CP_VC_FRMT_XY 0x00000000 +#define RADEON_CP_VC_FRMT_W0 0x00000001 +#define RADEON_CP_VC_FRMT_FPCOLOR 0x00000002 +#define RADEON_CP_VC_FRMT_FPALPHA 0x00000004 +#define RADEON_CP_VC_FRMT_PKCOLOR 0x00000008 +#define RADEON_CP_VC_FRMT_FPSPEC 0x00000010 +#define RADEON_CP_VC_FRMT_FPFOG 0x00000020 +#define RADEON_CP_VC_FRMT_PKSPEC 0x00000040 +#define RADEON_CP_VC_FRMT_ST0 0x00000080 +#define RADEON_CP_VC_FRMT_ST1 0x00000100 +#define RADEON_CP_VC_FRMT_Q1 0x00000200 +#define RADEON_CP_VC_FRMT_ST2 0x00000400 +#define RADEON_CP_VC_FRMT_Q2 0x00000800 +#define RADEON_CP_VC_FRMT_ST3 0x00001000 +#define RADEON_CP_VC_FRMT_Q3 0x00002000 +#define RADEON_CP_VC_FRMT_Q0 0x00004000 +#define RADEON_CP_VC_FRMT_BLND_WEIGHT_CNT_MASK 0x00038000 +#define RADEON_CP_VC_FRMT_N0 0x00040000 +#define RADEON_CP_VC_FRMT_XY1 0x08000000 +#define RADEON_CP_VC_FRMT_Z1 0x10000000 +#define RADEON_CP_VC_FRMT_W1 0x20000000 +#define RADEON_CP_VC_FRMT_N1 0x40000000 +#define RADEON_CP_VC_FRMT_Z 0x80000000 -#define RADEON_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000 -#define RADEON_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001 -#define RADEON_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002 -#define RADEON_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 -#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 -#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 -#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 -#define RADEON_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 -#define RADEON_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010 -#define RADEON_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020 -#define RADEON_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 -#define RADEON_CCE_VC_CNTL_NUM_SHIFT 16 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_LINE_STRIP 0x00000003 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_RECT_LIST 0x00000008 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_POINT_LIST 0x00000009 +#define RADEON_CP_VC_CNTL_PRIM_TYPE_3VRT_LINE_LIST 0x0000000a +#define RADEON_CP_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define RADEON_CP_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define RADEON_CP_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define RADEON_CP_VC_CNTL_COLOR_ORDER_BGRA 0x00000000 +#define RADEON_CP_VC_CNTL_COLOR_ORDER_RGBA 0x00000040 +#define RADEON_CP_VC_CNTL_MAOS_ENABLE 0x00000080 +#define RADEON_CP_VC_CNTL_VTX_FMT_NON_RADEON_MODE 0x00000000 +#define RADEON_CP_VC_CNTL_VTX_FMT_RADEON_MODE 0x00000100 +#define RADEON_CP_VC_CNTL_NUM_SHIFT 16 #endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h new file mode 100644 index 000000000..14cb002fd --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/drivers/ati/radeon_sarea.h @@ -0,0 +1,261 @@ +/* $XFree86$ */ +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, + * 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, 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 (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_SAREA_H_ +#define _RADEON_SAREA_H_ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the kernel file (radeon_drm.h) + */ +#ifndef __RADEON_SAREA_DEFINES__ +#define __RADEON_SAREA_DEFINES__ + +/* What needs to be changed for the current vertex buffer? + */ +#define RADEON_UPLOAD_CONTEXT 0x00000001 +#define RADEON_UPLOAD_VERTFMT 0x00000002 +#define RADEON_UPLOAD_LINE 0x00000004 +#define RADEON_UPLOAD_BUMPMAP 0x00000008 +#define RADEON_UPLOAD_MASKS 0x00000010 +#define RADEON_UPLOAD_VIEWPORT 0x00000020 +#define RADEON_UPLOAD_SETUP 0x00000040 +#define RADEON_UPLOAD_TCL 0x00000080 +#define RADEON_UPLOAD_MISC 0x00000100 +#define RADEON_UPLOAD_TEX0 0x00000200 +#define RADEON_UPLOAD_TEX1 0x00000400 +#define RADEON_UPLOAD_TEX2 0x00000800 +#define RADEON_UPLOAD_TEX0IMAGES 0x00001000 +#define RADEON_UPLOAD_TEX1IMAGES 0x00002000 +#define RADEON_UPLOAD_TEX2IMAGES 0x00004000 +#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ +#define RADEON_REQUIRE_QUIESCENCE 0x00010000 +#define RADEON_UPLOAD_ALL 0x0001ffff + +#define RADEON_FRONT 0x1 +#define RADEON_BACK 0x2 +#define RADEON_DEPTH 0x4 + +/* Primitive types + */ +#define RADEON_POINTS 0x1 +#define RADEON_LINES 0x2 +#define RADEON_LINE_STRIP 0x3 +#define RADEON_TRIANGLES 0x4 +#define RADEON_TRIANGLE_FAN 0x5 +#define RADEON_TRIANGLE_STRIP 0x6 +#define RADEON_3VTX_POINTS 0x9 +#define RADEON_3VTX_LINES 0xa + +/* Vertex/indirect buffer size + */ +#define RADEON_BUFFER_SIZE 16384 + +/* Byte offsets for indirect buffer data + */ +#define RADEON_INDEX_PRIM_OFFSET 20 +#define RADEON_HOSTDATA_BLIT_OFFSET 32 + +#define RADEON_SCRATCH_REG_OFFSET 32 + +/* Keep these small for testing + */ +#define RADEON_NR_SAREA_CLIPRECTS 12 + +/* There are 2 heaps (local/AGP). Each region within a heap is a + * minimum of 64k, and there are at most 64 of them per heap. + */ +#define RADEON_CARD_HEAP 0 +#define RADEON_AGP_HEAP 1 +#define RADEON_NR_TEX_HEAPS 2 +#define RADEON_NR_TEX_REGIONS 64 +#define RADEON_LOG_TEX_GRANULARITY 16 + +#define RADEON_MAX_TEXTURE_LEVELS 11 +#define RADEON_MAX_TEXTURE_UNITS 3 + +/* Blits have strict offset rules. All blit offset must be aligned on + * a 1K-byte boundary. + */ +#define RADEON_OFFSET_SHIFT 10 +#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT) +#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1) + +#endif /* __RADEON_SAREA_DEFINES__ */ + +typedef struct { + unsigned int red; + unsigned int green; + unsigned int blue; + unsigned int alpha; +} radeon_color_regs_t; + +typedef struct { + /* Context state */ + unsigned int pp_misc; + unsigned int pp_fog_color; + unsigned int re_solid_color; + unsigned int rb3d_blendcntl; + unsigned int rb3d_depthoffset; + unsigned int rb3d_depthpitch; + unsigned int rb3d_zstencilcntl; + + unsigned int pp_cntl; + unsigned int rb3d_cntl; + unsigned int rb3d_coloroffset; + unsigned int re_width_height; + unsigned int rb3d_colorpitch; + unsigned int se_cntl; + + /* Vertex format state */ + unsigned int se_coord_fmt; + + /* Line state */ + unsigned int re_line_pattern; + unsigned int re_line_state; + + unsigned int se_line_width; + + /* Bumpmap state */ + unsigned int pp_lum_matrix; + + unsigned int pp_rot_matrix_0; + unsigned int pp_rot_matrix_1; + + /* Mask state */ + unsigned int rb3d_stencilrefmask; + unsigned int rb3d_ropcntl; + unsigned int rb3d_planemask; + + /* Viewport state */ + unsigned int se_vport_xscale; + unsigned int se_vport_xoffset; + unsigned int se_vport_yscale; + unsigned int se_vport_yoffset; + unsigned int se_vport_zscale; + unsigned int se_vport_zoffset; + + /* Setup state */ + unsigned int se_cntl_status; + +#ifdef TCL_ENABLE + /* TCL state */ + radeon_color_regs_t se_tcl_material_emmissive; + radeon_color_regs_t se_tcl_material_ambient; + radeon_color_regs_t se_tcl_material_diffuse; + radeon_color_regs_t se_tcl_material_specular; + unsigned int se_tcl_shininess; + unsigned int se_tcl_output_vtx_fmt; + unsigned int se_tcl_output_vtx_sel; + unsigned int se_tcl_matrix_select_0; + unsigned int se_tcl_matrix_select_1; + unsigned int se_tcl_ucp_vert_blend_ctl; + unsigned int se_tcl_texture_proc_ctl; + unsigned int se_tcl_light_model_ctl; + unsigned int se_tcl_per_light_ctl[4]; +#endif + + /* Misc state */ + unsigned int re_top_left; + unsigned int re_misc; +} radeon_context_regs_t; + +/* Setup registers for each texture unit */ +typedef struct { + unsigned int pp_txfilter; + unsigned int pp_txformat; + unsigned int pp_txoffset; + unsigned int pp_txcblend; + unsigned int pp_txablend; + unsigned int pp_tfactor; + + unsigned int pp_border_color; + +#ifdef CUBIC_ENABLE + unsigned int pp_cubic_faces; + unsigned int pp_cubic_offset[5]; +#endif +} radeon_texture_regs_t; + +typedef struct { + unsigned char next, prev; /* indices to form a circular LRU */ + unsigned char in_use; /* owned by a client, or free? */ + int age; /* tracked by clients to update local LRU's */ +} radeon_tex_region_t; + +typedef struct { + /* The channel for communication of state information to the kernel + * on firing a vertex buffer. + */ + radeon_context_regs_t ContextState; + radeon_texture_regs_t TexState[RADEON_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + + /* The current cliprects, or a subset thereof + */ + XF86DRIClipRectRec boxes[RADEON_NR_SAREA_CLIPRECTS]; + unsigned int nbox; + + /* Counters for throttling of rendering clients + */ + unsigned int last_frame; + unsigned int last_dispatch; + unsigned int last_clear; + + /* Maintain an LRU of contiguous regions of texture space. If you + * think you own a region of texture memory, and it has an age + * different to the one you set, then you are mistaken and it has + * been stolen by another client. If global texAge hasn't changed, + * there is no need to walk the list. + * + * These regions can be used as a proxy for the fine-grained texture + * information of other clients - by maintaining them in the same + * lru which is used to age their own textures, clients have an + * approximate lru for the whole of global texture space, and can + * make informed decisions as to which areas to kick out. There is + * no need to choose whether to kick out your own texture or someone + * else's - simply eject them all in LRU order. + */ + /* Last elt is sentinal */ + radeon_tex_region_t texList[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1]; + /* last time texture was uploaded */ + int texAge[RADEON_NR_TEX_HEAPS]; + + int ctxOwner; /* last context to upload state */ +} RADEONSAREAPriv, *RADEONSAREAPrivPtr; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile b/xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile index ae0d85b77..f29a52de1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile @@ -1,4 +1,4 @@ -XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile,v 1.1 2000/12/01 19:47:56 dawes Exp $ +XCOMM $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/Imakefile,v 1.2 2000/12/14 20:59:12 dawes Exp $ #define IHaveModules #include <Server.tmpl> @@ -33,6 +33,11 @@ ObjectModuleTarget(newport,$(OBJS)) InstallObjectModule(newport,$(MODULEDIR),drivers) InstallNamedNonExec($(XF86CONFIG),$(XF86CONFIG),$(LIBDIR)) +#if !defined(XF86DriverSDK) +CppManTarget(newport,) +InstallModuleManPage(newport) +#endif + DependTarget() InstallDriverSDKNonExecFile(Imakefile,$(DRIVERSDKDIR)/drivers/newport) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy b/xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy index 9ebda996e..080fd3de1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy @@ -27,7 +27,7 @@ # dealings in this Software without prior written authorization from the # XFree86 Project. # -# $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy,v 1.1 2000/12/01 19:47:57 dawes Exp $ +# $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/XF86Config.indy,v 1.2 2000/12/14 20:59:12 dawes Exp $ # ********************************************************************** # This is a configuration file for the Indy's Newport Graphics and the @@ -279,22 +279,10 @@ EndSection # ********************************************************************** Section "Device" - Identifier "Newport Graphics 1" + Identifier "Newport Graphics" Driver "newport" -# Option "shadowfb" "yes" -# Option "Silkenmouse" "no" -# VideoRam 1280 # Option "bitplanes" "24" - BusID "0" -EndSection - -Section "Device" - Identifier "Newport Graphics 2" - Driver "newport" - - Option "shadowfb" "yes" - BusID "1" EndSection # ********************************************************************** @@ -308,7 +296,7 @@ EndSection Section "Screen" Identifier "Screen 1" - Device "Newport Graphics 1" + Device "Newport Graphics" Monitor "SGI GDM17e11" DefaultDepth 8 @@ -318,19 +306,6 @@ Section "Screen" EndSubSection EndSection -Section "Screen" - Identifier "Screen 2" - Device "Newport Graphics 2" - Monitor "SGI GDM17e11" - DefaultDepth 24 - - SubSection "Display" - Depth 24 - Modes "1280x1024" - EndSubSection -EndSection - - # ********************************************************************** # ServerLayout sections. # ********************************************************************** @@ -342,10 +317,3 @@ Section "ServerLayout" InputDevice "Keyboard1" "CoreKeyboard" EndSection -Section "ServerLayout" - Identifier "multihead layout" - Screen "Screen 1" "" "" "" "Screen 2" - Screen "Screen 2" "" "" "Screen 1" "" - InputDevice "Mouse1" "CorePointer" - InputDevice "Keyboard1" "CoreKeyboard" -EndSection diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h index afab66e82..f6c787cc1 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h @@ -1,15 +1,11 @@ /* * Id: newport.h,v 1.4 2000/11/29 20:58:10 agx Exp $ */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h,v 1.1 2000/12/01 19:47:58 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport.h,v 1.2 2000/12/06 22:00:46 dawes Exp $ */ #ifndef __NEWPORT_H__ #define __NEWPORT_H__ -#ifndef XFree86LOADER -# define NEED_XF86_TYPES /* to make XF86FILE, etc available */ -#endif - /* * All drivers should include these: */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c index 28c97ab71..745240bfd 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c @@ -30,7 +30,7 @@ * Project. * */ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c,v 1.2 2000/12/02 15:30:46 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/newport/newport_driver.c,v 1.6 2000/12/14 20:59:12 dawes Exp $ */ /* function prototypes, common data structures & generic includes */ #include "newport.h" @@ -56,6 +56,14 @@ #include "xf86xv.h" #include "Xv.h" +/* Temporary workaround. A module really shouldn't need this */ +#ifndef XFree86LOADER +# include "xf86_OSlib.h" +# ifndef MAP_FAILED +# define MAP_FAILED ((pointer)(-1)) +# endif +#endif + #define VERSION 4000 #define NEWPORT_NAME "Newport" #define NEWPORT_DRIVER_NAME "newport" @@ -79,8 +87,8 @@ static Bool NewportModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); static void NewportRestore(ScrnInfoPtr pScrn, Bool Closing); static Bool NewportGetRec(ScrnInfoPtr pScrn); static Bool NewportFreeRec(ScrnInfoPtr pScrn); -static NewportRegsPtr NewportMapRegs(unsigned cardNum); -static Bool NewportUnmapRegs(unsigned cardNum); +static Bool NewportMapRegs(ScrnInfoPtr pScrn); +static void NewportUnmapRegs(ScrnInfoPtr pScrn); static Bool NewportProbeCardInfo(ScrnInfoPtr pScrn); /* ------------------------------------------------------------------ */ @@ -358,10 +366,10 @@ NewportPreInit(ScrnInfoPtr pScrn, int flags) pScrn->videoRam = 1280 * (pScrn->bitsPerPixel >> 3); /* get revisions of REX3, etc. */ - if( !(pNewport->pNewportRegs = NewportMapRegs(busID))) + if( ! NewportMapRegs(pScrn)) return FALSE; NewportProbeCardInfo(pScrn); - NewportUnmapRegs(busID); + NewportUnmapRegs(pScrn); from=X_PROBED; xf86DrvMsg(pScrn->scrnIndex, from, @@ -370,7 +378,7 @@ NewportPreInit(ScrnInfoPtr pScrn, int flags) pNewport->cmap_rev, pNewport->xmap9_rev); if ( (xf86GetOptValInteger(NewportOptions, OPTION_BITPLANES, &pNewport->bitplanes))) - from = X_CONFIG; + from = X_CONFIG; xf86DrvMsg(pScrn->scrnIndex, from, "Newport has %d bitplanes\n", pNewport->bitplanes); if ( pScrn->depth > pNewport->bitplanes ) { @@ -379,6 +387,12 @@ NewportPreInit(ScrnInfoPtr pScrn, int flags) pScrn->depth, pNewport->bitplanes); return FALSE; } + if ( ( pNewport->bitplanes != 8 ) && ( pNewport->bitplanes != 24 ) ) { + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, \ + "Number of bitplanes on newport must be either 8 or 24 not %d\n", \ + pNewport->bitplanes); + return FALSE; + } /* Set up clock ranges that are alway ok */ /* XXX: Should use the correct data from the specs(which specs?) here */ @@ -459,7 +473,7 @@ NewportScreenInit(int index, ScreenPtr pScreen, int argc, char **argv) pNewport = NEWPORTPTR(pScrn); /* map the Newportregs until the server dies */ - if( !(pNewport->pNewportRegs = NewportMapRegs(pNewport->busID))) + if( ! NewportMapRegs(pScrn)) return FALSE; /* Reset visual list. */ @@ -585,8 +599,7 @@ NewportCloseScreen(int scrnIndex, ScreenPtr pScreen) xfree(pNewport->ShadowPtr); /* unmap the Newport's registers from memory */ - if(!NewportUnmapRegs(pNewport->busID)) - return FALSE; + NewportUnmapRegs(pScrn); pScrn->vtSema = FALSE; pScreen->CloseScreen = pNewport->CloseScreen; @@ -684,14 +697,14 @@ NewportHWProbe(unsigned probedIDs[]) FILE* cpuinfo; char line[80]; unsigned hasNewport = 0; - cpuinfo = xf86fopen("/proc/cpuinfo","r"); - while(xf86fgets(line,80,cpuinfo) != NULL) { - if(xf86strstr(line, "SGI Indy") != NULL) { + cpuinfo = fopen("/proc/cpuinfo","r"); + while(fgets(line,80,cpuinfo) != NULL) { + if(strstr(line, "SGI Indy") != NULL) { hasNewport = 1; break; } } - xf86fclose(cpuinfo); + fclose(cpuinfo); probedIDs[0] = 0; return hasNewport; @@ -723,40 +736,27 @@ static Bool NewportProbeCardInfo(ScrnInfoPtr pScrn) /* map NewportRegs */ -static NewportRegsPtr -NewportMapRegs(unsigned cardNum) +static Bool +NewportMapRegs(ScrnInfoPtr pScrn) { - int fd; - pointer base; - - if ((fd = xf86open("/dev/mem", XF86_O_RDWR)) < 0) { - FatalError("NewportMapRegs: failed to open /dev/mem (%s)\n", \ - xf86strerror(xf86errno)); - return (NewportRegsPtr)NULL; - } + NewportPtr pNewport = NEWPORTPTR(pScrn); - base = xf86mmap((pointer)0, sizeof(NewportRegs), \ - XF86_PROT_READ | XF86_PROT_WRITE, XF86_MAP_SHARED, fd, \ - NEWPORT_BASE_ADDR0 + cardNum * NEWPORT_BASE_OFFSET); - xf86close(fd); - if (base == XF86_MAP_FAILED) { - FatalError("NewportMapRegs: Could not mmap NewportRegs (0x%08x,0x%x) (%s)\n", \ - NEWPORT_BASE_ADDR0 + cardNum * NEWPORT_BASE_OFFSET, \ - sizeof(NewportRegs), xf86strerror(xf86errno)); - return (NewportRegsPtr)NULL; - } - return (NewportRegsPtr)base; + pNewport->pNewportRegs = xf86MapVidMem(pScrn->scrnIndex, + VIDMEM_MMIO, + NEWPORT_BASE_ADDR0 + pNewport->busID * NEWPORT_BASE_OFFSET, + sizeof(NewportRegs)); + if ( ! pNewport->pNewportRegs ) + return FALSE; + return TRUE; } /* unmap NewportRegs */ -static Bool -NewportUnmapRegs(unsigned cardNum) +static void +NewportUnmapRegs(ScrnInfoPtr pScrn) { - if(xf86munmap( (pointer)(NEWPORT_BASE_ADDR0 + cardNum * NEWPORT_BASE_OFFSET), \ - sizeof(NewportRegs)) == -1) { - FatalError("NewportUnmapRegs: Could not munmap NewportRegs\n"); - return FALSE; - } - return TRUE; -} + NewportPtr pNewport = NEWPORTPTR(pScrn); + xf86UnMapVidMem( pScrn->scrnIndex, pNewport->pNewportRegs, + sizeof(NewportRegs)); + pNewport->pNewportRegs = NULL; +} diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage.cpp b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage.cpp index 9c4631d37..d35f7f8ad 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage.cpp +++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage.cpp @@ -1,7 +1,7 @@ -.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage.cpp,v 1.1 2000/12/02 01:16:11 dawes Exp $ +.\" $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage.cpp,v 1.2 2000/12/11 20:18:25 dawes Exp $ .\" shorthand for double quote that works everywhere. .ds q \N'34' -.TH SAVAGE __drivermansuffix__ "Version 4.0.1" "XFree86" +.TH SAVAGE __drivermansuffix__ "Version 4.0.2" "XFree86" .SH NAME savage \- S3 Savage video driver .SH SYNOPSIS diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c index cb5e07763..2dfaf1432 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.2 2000/12/02 15:30:49 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_accel.c,v 1.4 2000/12/07 20:26:22 dawes Exp $ */ /* * @@ -320,7 +320,7 @@ SavageSetGBD( ScrnInfoPtr pScrn ) /* Set stride to use GBD. */ VGAOUT8(vgaCRIndex, 0x50); - VGAOUT8(vgaCRReg, inb(vgaCRReg) | 0xC1); + VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1); /* Enable 2D engine. */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c index 25e9ee027..4227e11c7 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c +++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.3 2000/12/04 18:49:59 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.c,v 1.6 2000/12/12 16:50:48 dawes Exp $ */ /* * vim: sw=4 ts=8 ai ic: * @@ -15,6 +15,12 @@ #include "xf86RAC.h" #include "shadowfb.h" +#ifdef DPMSExtension +#include "globals.h" +#define DPMS_SERVER +#include "extensions/dpms.h" +#endif /* DPMSExtension */ + #include "savage_driver.h" #include "savage_bci.h" @@ -43,7 +49,8 @@ static int SavageInternalScreenInit(int scrnIndex, ScreenPtr pScreen); static ModeStatus SavageValidMode(int index, DisplayModePtr mode, Bool verbose, int flags); -static Bool SavageMapMem(ScrnInfoPtr pScrn); +static Bool SavageMapMMIO(ScrnInfoPtr pScrn); +static Bool SavageMapFB(ScrnInfoPtr pScrn); static void SavageUnmapMem(ScrnInfoPtr pScrn); static Bool SavageModeInit(ScrnInfoPtr pScrn, DisplayModePtr mode); static Bool SavageCloseScreen(int scrnIndex, ScreenPtr pScreen); @@ -57,6 +64,9 @@ static void SavageCalcClock(long freq, int min_m, int min_n1, int max_n1, unsigned int *ndiv, unsigned int *r); void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file); void SavagePrintRegs(ScrnInfoPtr pScrn); +#ifdef DPMSExtension +static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags); +#endif static int pix24bpp = 0; @@ -794,17 +804,18 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) } psav->EntityIndex = pEnt->index; - if (xf86LoadSubModule(pScrn, "int10")) { - xf86LoaderReqSymLists(int10Symbols, NULL); - psav->pInt10 = xf86InitInt10(pEnt->index); - } + if (psav->UseBIOS) { + if (xf86LoadSubModule(pScrn, "int10")) { + xf86LoaderReqSymLists(int10Symbols, NULL); + psav->pInt10 = xf86InitInt10(pEnt->index); + } - if (xf86LoadSubModule(pScrn, "vbe")) { - xf86LoaderReqSymLists(vbeSymbols, NULL); - psav->pVbe = VBEInit(psav->pInt10, pEnt->index); + if (xf86LoadSubModule(pScrn, "vbe")) { + xf86LoaderReqSymLists(vbeSymbols, NULL); + psav->pVbe = VBEInit(psav->pInt10, pEnt->index); + } } - psav->PciInfo = xf86GetPciInfoForEntity(pEnt->index); xf86RegisterResources(pEnt->index, NULL, ResNone); xf86SetOperatingState(RES_SHARED_VGA, pEnt->index, ResUnusedOpr); @@ -848,6 +859,10 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) psav->PciInfo->func); hwp = VGAHWPTR(pScrn); + + if (!SavageMapMMIO(pScrn)) + return FALSE; + vgaHWGetIOBase(hwp); vgaIOBase = hwp->IOBase; vgaCRIndex = vgaIOBase + 4; @@ -1052,10 +1067,6 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) xf86DrvMsg(pScrn->scrnIndex, X_PROBED, "Detected current MCLK value of %1.3f MHz\n", mclk / 1000.0); -#if 0 - SavageUnmapMem(pScrn); -#endif - psav->minClock = 20000; pScrn->maxHValue = 2048; @@ -1100,7 +1111,7 @@ static Bool SavagePreInit(ScrnInfoPtr pScrn, int flags) SavageFreeBIOSModeTable( psav, &psav->ModeTable ); } - psav->ModeTable = SavageGetBIOSModeTable( psav, pScrn->bitsPerPixel ); + psav->ModeTable = SavageGetBIOSModeTable( psav, pScrn->depth ); if( !psav->ModeTable || !psav->ModeTable->NumModes ) { xf86DrvMsg(pScrn->scrnIndex, X_ERROR, @@ -1195,9 +1206,6 @@ static Bool SavageEnterVT(int scrnIndex, int flags) { ScrnInfoPtr pScrn = xf86Screens[scrnIndex]; -#if 0 - SavageMapMem(pScrn); -#endif SavageSave(pScrn); return SavageModeInit(pScrn, pScrn->currentMode); } @@ -1212,10 +1220,6 @@ static void SavageLeaveVT(int scrnIndex, int flags) SavageRegPtr SavageSavePtr = &psav->SavedReg; SavageWriteMode(pScrn, vgaSavePtr, SavageSavePtr); - -#if 0 - SavageUnmapMem(pScrn); -#endif } @@ -1443,13 +1447,15 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, /* Disable old MMIO. */ VGAOUT8(vgaCRIndex, 0x53); - VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) & ~0x10); + tmp = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRReg, tmp & ~0x10); /* We may need TV/panel fixups here. See s3bios.c line 2904. */ /* Set FIFO fetch delay. */ VGAOUT8(vgaCRIndex, 0x85); - VGAOUT8(vgaCRReg, (VGAIN8(vgaCRReg) & 0xf8) | 0x03); + tmp = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRReg, (tmp & 0xf8) | 0x03); /* Patch CR79. These values are magical. */ @@ -1518,7 +1524,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, /* Handle the pitch. */ VGAOUT8(vgaCRIndex, 0x50); - VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1); + tmp = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRReg, tmp | 0xC1); width = (pScrn->displayWidth * (pScrn->bitsPerPixel / 8)) >> 3; VGAOUT16(vgaCRIndex, ((width & 0xff) << 8) | 0x13 ); @@ -1529,7 +1536,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, if( psav->Chipset == S3_SAVAGE2000 ) { VGAOUT8(vgaCRIndex, 0x73); - VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) & 0xdf ); + tmp = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRReg, tmp & 0xdf ); } else if( psav->Chipset != S3_SAVAGE_MX ) { @@ -1538,7 +1546,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, { /* Not SGRAM; disable block write. */ VGAOUT8(vgaCRIndex, 0x88); - VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0x10); + tmp = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRReg, tmp | 0x10); } } @@ -1767,7 +1776,8 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, if( graphicsMode && (!psav->NoAccel) ) { VGAOUT8(vgaCRIndex, 0x50); - VGAOUT8(vgaCRReg, VGAIN8(vgaCRReg) | 0xC1); + tmp = VGAIN8(vgaCRReg); + VGAOUT8(vgaCRReg, tmp | 0xC1); SavageInitialize2DEngine(pScrn); } @@ -1785,7 +1795,7 @@ static void SavageWriteMode(ScrnInfoPtr pScrn, vgaRegPtr vgaSavePtr, } -static Bool SavageMapMem(ScrnInfoPtr pScrn) +static Bool SavageMapMMIO(ScrnInfoPtr pScrn) { SavagePtr psav; vgaHWPtr hwp; @@ -1822,6 +1832,19 @@ static Bool SavageMapMem(ScrnInfoPtr pScrn) psav->BciMem = psav->MapBase + 0x10000; + SavageEnableMMIO(pScrn); + hwp = VGAHWPTR(pScrn); + vgaHWGetIOBase(hwp); + + return TRUE; +} + + + +static Bool SavageMapFB(ScrnInfoPtr pScrn) +{ + SavagePtr psav = SAVPTR(pScrn); + xf86DrvMsg( pScrn->scrnIndex, X_PROBED, "mapping framebuffer @ 0x%x with size 0x%x\n", psav->FrameBufferBase, psav->videoRambytes); @@ -1840,19 +1863,6 @@ static Bool SavageMapMem(ScrnInfoPtr pScrn) pScrn->memPhysBase = psav->PciInfo->memBase[0]; pScrn->fbOffset = 0; /* psav->FBCursorOffset = psav->videoRambytes - 1024; */ - SavageEnableMMIO(pScrn); - hwp = VGAHWPTR(pScrn); -/* vgaHWSetMmioFuncs(hwp, psav->MapBase, SAVAGE_NEWMMIO_REGSIZE); */ - vgaHWGetIOBase(hwp); - -#if 0 - if (xf86IsPrimaryPci(psav->PciInfo)) { - hwp->MapSize = 0x10000; - if (!vgaHWMapMem(pScrn)) - return FALSE; - psav->PrimaryVidMapped = TRUE; - } -#endif return TRUE; } @@ -1895,7 +1905,7 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, pScrn = xf86Screens[pScreen->myNum]; psav = SAVPTR(pScrn); - if (!SavageMapMem(pScrn)) + if (!SavageMapFB(pScrn)) return FALSE; SavageSave(pScrn); @@ -1992,6 +2002,11 @@ static Bool SavageScreenInit(int scrnIndex, ScreenPtr pScreen, pScreen->SaveScreen = SavageSaveScreen; pScreen->CloseScreen = SavageCloseScreen; +#ifdef DPMSExtension + if (xf86DPMSInit(pScreen, SavageDPMS, 0) == FALSE) + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "DPMS initialization failed\n"); +#endif + if (serverGeneration == 1) xf86ShowUnusedOptions(pScrn->scrnIndex, pScrn->options); @@ -2454,15 +2469,15 @@ Bool SavageSwitchMode(int scrnIndex, DisplayModePtr mode, int flags) void SavageEnableMMIO(ScrnInfoPtr pScrn) { vgaHWPtr hwp = VGAHWPTR(pScrn); - /*SavagePtr psav = SAVPTR(pScrn); */ + SavagePtr psav = SAVPTR(pScrn); int vgaCRIndex, vgaCRReg; unsigned char val; - vgaHWSetStdFuncs(hwp); + vgaHWSetMmioFuncs(hwp, psav->MapBase, 0x8000); val = VGAIN8(0x3c3); VGAOUT8(0x3c3, val | 0x01); val = VGAIN8(VGA_MISC_OUT_R); - outb(VGA_MISC_OUT_W, val | 0x01); + VGAOUT8(VGA_MISC_OUT_W, val | 0x01); vgaHWGetIOBase(hwp); vgaCRIndex = hwp->IOBase + 4; vgaCRReg = hwp->IOBase + 5; @@ -2478,7 +2493,7 @@ void SavageEnableMMIO(ScrnInfoPtr pScrn) void SavageDisableMMIO(ScrnInfoPtr pScrn) { vgaHWPtr hwp = VGAHWPTR(pScrn); - /*SavagePtr psav = SAVPTR(pScrn);*/ + SavagePtr psav = SAVPTR(pScrn); int vgaCRIndex, vgaCRReg; unsigned char val; @@ -2497,6 +2512,7 @@ void SavageDisableMMIO(ScrnInfoPtr pScrn) void SavageLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indicies, LOCO *colors, VisualPtr pVisual) { + SavagePtr psav = SAVPTR(pScrn); int i, index; for (i=0; i<numColors; i++) { @@ -2657,6 +2673,7 @@ void SavageGEReset(ScrnInfoPtr pScrn, int from_timeout, int line, char *file) void SavagePrintRegs(ScrnInfoPtr pScrn) { + SavagePtr psav = SAVPTR(pScrn); unsigned char i; int vgaCRIndex = 0x3d4; int vgaCRReg = 0x3d5; @@ -2666,8 +2683,8 @@ SavagePrintRegs(ScrnInfoPtr pScrn) for( i = 0; i < 0x70; i++ ) { if( !(i % 16) ) ErrorF( "\nSR%xx ", i >> 4 ); - outb( 0x3c4, i ); - ErrorF( " %02x", inb(0x3c5) ); + VGAOUT8( 0x3c4, i ); + ErrorF( " %02x", VGAIN8(0x3c5) ); } ErrorF( "\n\nCR x0 x1 x2 x3 x4 x5 x6 x7 x8 x9 xA xB xC xD xE xF" ); @@ -2675,9 +2692,50 @@ SavagePrintRegs(ScrnInfoPtr pScrn) for( i = 0; i < 0xB7; i++ ) { if( !(i % 16) ) ErrorF( "\nCR%xx ", i >> 4 ); - outb( vgaCRIndex, i ); - ErrorF( " %02x", inb(vgaCRReg) ); + VGAOUT8( vgaCRIndex, i ); + ErrorF( " %02x", VGAIN8(vgaCRReg) ); } ErrorF("\n\n"); } + + +#ifdef DPMSExtension +static void SavageDPMS(ScrnInfoPtr pScrn, int mode, int flags) +{ + SavagePtr psav = SAVPTR(pScrn); + unsigned char sr8 = 0x00, srd = 0x00; + + VGAOUT8(0x3c4, 0x08); + sr8 = VGAIN8(0x3c5); + sr8 |= 0x06; + VGAOUT8(0x3c5, sr8); + + VGAOUT8(0x3c4, 0x0d); + srd = VGAIN8(0x3c5); + + srd &= 0x03; + + switch (mode) { + case DPMSModeOn: + break; + case DPMSModeStandby: + srd |= 0x10; + break; + case DPMSModeSuspend: + srd |= 0x40; + break; + case DPMSModeOff: + srd |= 0x50; + break; + default: + xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "Invalid DPMS mode %d\n", mode); + break; + } + + VGAOUT8(0x3c4, 0x0d); + VGAOUT8(0x3c5, srd); + + return; +} +#endif /* DPMSExtension */ diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h index 42e742415..d05cdb19e 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v 1.2 2000/12/02 15:30:49 tsi Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_driver.h,v 1.3 2000/12/07 20:26:22 dawes Exp $ */ #ifndef SAVAGE_VGAHWMMIO_H #define SAVAGE_VGAHWMMIO_H @@ -23,13 +23,13 @@ #include "savage_regs.h" -#define VGAIN8(addr) inb(addr) -#define VGAIN16(addr) inw(addr) -#define VGAIN(addr) inl(addr) +#define VGAIN8(addr) MMIO_IN8(psav->MapBase+0x8000, addr) +#define VGAIN16(addr) MMIO_IN16(psav->MapBase+0x8000, addr) +#define VGAIN(addr) MMIO_IN32(psav->MapBase+0x8000, addr) -#define VGAOUT8(addr,val) outb(addr,val) -#define VGAOUT16(addr,val) outw(addr,val) -#define VGAOUT(addr,val) outl(addr,val) +#define VGAOUT8(addr,val) MMIO_OUT8(psav->MapBase+0x8000, addr, val) +#define VGAOUT16(addr,val) MMIO_OUT16(psav->MapBase+0x8000, addr, val) +#define VGAOUT(addr,val) MMIO_OUT32(psav->MapBase+0x8000, addr, val) #define INREG(addr) MMIO_IN32(psav->MapBase, addr) #define OUTREG(addr,val) MMIO_OUT32(psav->MapBase, addr, val) diff --git a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h index b1a21ea93..679795c8d 100644 --- a/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h +++ b/xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h @@ -1,4 +1,4 @@ -/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h,v 1.3 2000/12/04 18:50:00 dawes Exp $ */ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/savage/savage_regs.h,v 1.4 2000/12/07 20:26:22 dawes Exp $ */ #ifndef _SAVAGE_REGS_H #define _SAVAGE_REGS_H @@ -97,11 +97,11 @@ enum S3CHIPTAGS { #define VerticalRetraceWait() \ { \ - outb(vgaCRIndex, 0x17); \ - if (inb(vgaCRReg) & 0x80) { \ - while ((inb(vgaIOBase + 0x0a) & 0x08) == 0x00) ; \ - while ((inb(vgaIOBase + 0x0a) & 0x08) == 0x08) ; \ - while ((inb(vgaIOBase + 0x0a) & 0x08) == 0x00) ; \ + VGAOUT8(vgaCRIndex, 0x17); \ + if (VGAIN8(vgaCRReg) & 0x80) { \ + while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x00) ; \ + while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x08) ; \ + while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x00) ; \ } \ } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile index 853185757..34244e6e5 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/Imakefile @@ -13,8 +13,26 @@ MOBJ = drmmodule.o MTRR_DEFINES = -DHAS_MTRR_SUPPORT #endif -SRCS = xf86drm.c xf86drmHash.c xf86drmRandom.c xf86drmSL.c xf86drmI810.c xf86drmMga.c xf86drmR128.c xf86drmSiS.c $(MSRC) -OBJS = xf86drm.o xf86drmHash.o xf86drmRandom.o xf86drmSL.o xf86drmI810.o xf86drmMga.o xf86drmR128.o xf86drmSiS.o $(MOBJ) + SRCS = xf86drm.c \ + xf86drmHash.c \ + xf86drmRandom.c \ + xf86drmSL.c \ + xf86drmI810.c \ + xf86drmMga.c \ + xf86drmR128.c \ + xf86drmRadeon.c \ + xf86drmSiS.c \ + $(MSRC) + OBJS = xf86drm.o \ + xf86drmHash.o \ + xf86drmRandom.o \ + xf86drmSL.o \ + xf86drmI810.o \ + xf86drmMga.o \ + xf86drmR128.o \ + xf86drmRadeon.o \ + xf86drmSiS.o \ + $(MOBJ) INCLUDES = -I$(XF86COMSRC) -I$(XF86OSSRC) -I. -I$(SERVERSRC)/include \ -I$(XINCLUDESRC) -I$(EXTINCSRC) -I../.. -Ikernel diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel index d25e33d47..9fe0038fc 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.kernel @@ -7,7 +7,7 @@ # The real targets are in the module-list O_TARGET := drm.o -module-list := gamma.o tdfx.o r128.o ffb.o mga.o i810.o +module-list := gamma.o tdfx.o r128.o radeon.o ffb.o mga.o i810.o export-objs := $(patsubst %.o,%_drv.o,$(module-list)) # libs-objs are included in every module so that radical changes to the @@ -38,23 +38,28 @@ ifeq ($(CONFIG_AGP),y) lib-objs += agpsupport.o else ifeq ($(CONFIG_AGP),m) - lib-objs += agpsupport.o + lib-objs += agpsupport.o endif endif -gamma-objs := gamma_drv.o gamma_dma.o -tdfx-objs := tdfx_drv.o tdfx_context.o -r128-objs := r128_drv.o r128_cce.o r128_context.o r128_bufs.o r128_state.o -ffb-objs := ffb_drv.o ffb_context.o -mga-objs := mga_drv.o mga_dma.o mga_context.o mga_bufs.o mga_state.o -i810-objs := i810_drv.o i810_dma.o i810_context.o i810_bufs.o - -obj-$(CONFIG_DRM_GAMMA) += gamma.o -obj-$(CONFIG_DRM_TDFX) += tdfx.o -obj-$(CONFIG_DRM_R128) += r128.o -obj-$(CONFIG_DRM_FFB) += ffb.o -obj-$(CONFIG_DRM_MGA) += mga.o -obj-$(CONFIG_DRM_I810) += i810.o +gamma-objs := gamma_drv.o gamma_dma.o +tdfx-objs := tdfx_drv.o tdfx_context.o +r128-objs := r128_drv.o r128_cce.o r128_context.o r128_bufs.o \ + r128_state.o +radeon-objs := radeon_drv.o radeon_cp.o radeon_context.o radeon_bufs.o \ + radeon_state.o +ffb-objs := ffb_drv.o ffb_context.o +mga-objs := mga_drv.o mga_dma.o mga_context.o mga_bufs.o \ + mga_state.o +i810-objs := i810_drv.o i810_dma.o i810_context.o i810_bufs.o + +obj-$(CONFIG_DRM_GAMMA) += gamma.o +obj-$(CONFIG_DRM_TDFX) += tdfx.o +obj-$(CONFIG_DRM_R128) += r128.o +obj-$(CONFIG_DRM_RADEON) += radeon.o +obj-$(CONFIG_DRM_FFB) += ffb.o +obj-$(CONFIG_DRM_MGA) += mga.o +obj-$(CONFIG_DRM_I810) += i810.o # When linking into the kernel, link the library just once. @@ -96,5 +101,8 @@ i810.o: $(i810-objs) $(lib) r128.o: $(r128-objs) $(lib) $(LD) -r -o $@ $(r128-objs) $(lib) +radeon.o: $(radeon-objs) $(lib) + $(LD) -r -o $@ $(radeon-objs) $(lib) + ffb.o: $(ffb-objs) $(lib) $(LD) -r -o $@ $(ffb-objs) $(lib) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux index 1dca5ad2f..d6c2f67ec 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/Makefile.linux @@ -47,7 +47,7 @@ # **** End of SMP/MODVERSIONS detection -MODS= gamma.o tdfx.o r128.o +MODS= gamma.o tdfx.o r128.o radeon.o LIBS= libdrm.a DRMOBJS= init.o memory.o proc.o auth.o context.o drawable.o bufs.o \ @@ -60,9 +60,6 @@ GAMMAHEADERS= gamma_drv.h $(DRMHEADERS) TDFXOBJS= tdfx_drv.o tdfx_context.o TDFXHEADERS= tdfx_drv.h $(DRMHEADERS) -R128OBJS= r128_drv.o r128_cce.o r128_bufs.o r128_state.o r128_context.o -R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS) - INC= /usr/include CFLAGS= -O2 $(WARNINGS) @@ -138,11 +135,18 @@ MODS += i810.o endif -MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_state.o mga_context.o +MGAOBJS= mga_drv.o mga_dma.o mga_bufs.o mga_context.o mga_state.o MGAHEADERS= mga_drv.h $(DRMHEADERS) I810OBJS= i810_drv.o i810_dma.o i810_bufs.o i810_context.o I810HEADERS= i810_drv.h $(DRMHEADERS) + +R128OBJS= r128_drv.o r128_cce.o r128_bufs.o r128_context.o r128_state.o +R128HEADERS= r128_drv.h r128_drm.h $(DRMHEADERS) + +RADEONOBJS= radeon_drv.o radeon_cp.o radeon_bufs.o radeon_context.o \ + radeon_state.o +RADEONHEADERS= radeon_drv.h radeon_drm.h $(DRMHEADERS) endif ifeq ($(SIS),1) @@ -203,11 +207,6 @@ tdfx_drv.o: tdfx_drv.c tdfx.o: $(TDFXOBJS) $(LIBS) $(LD) -r $^ -o $@ -r128_drv.o: r128_drv.c - $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ -r128.o: $(R128OBJS) $(LIBS) - $(LD) -r $^ -o $@ - sis.o: $(SISOBJS) $(LIBS) $(LD) -r $^ -o $@ @@ -221,6 +220,16 @@ i810_drv.o: i810_drv.c $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ i810.o: $(I810OBJS) $(LIBS) $(LD) -r $^ -o $@ + +r128_drv.o: r128_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ +r128.o: $(R128OBJS) $(LIBS) + $(LD) -r $^ -o $@ + +radeon_drv.o: radeon_drv.c + $(CC) $(MODCFLAGS) -DEXPORT_SYMTAB -I$(TREE) -c $< -o $@ +radeon.o: $(RADEONOBJS) $(LIBS) + $(LD) -r $^ -o $@ endif .PHONY: ChangeLog @@ -239,10 +248,11 @@ ChangeLog: $(DRMOBJS): $(DRMHEADERS) $(GAMMAOBJS): $(GAMMAHEADERS) $(TDFXOBJS): $(TDFXHEADERS) -$(R128OBJS): $(R128HEADERS) ifeq ($(AGP),1) $(MGAOBJS): $(MGAHEADERS) $(I810OBJS): $(I810HEADERS) +$(R128OBJS): $(R128HEADERS) +$(RADEONOBJS): $(RADEONHEADERS) endif clean: diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h index 3049b7264..dc3d262d4 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/drm.h @@ -82,6 +82,7 @@ typedef struct drm_clip_rect { #include "mga_drm.h" #include "i810_drm.h" #include "r128_drm.h" +#include "radeon_drm.h" #ifdef CONFIG_DRM_SIS #include "sis_drm.h" #endif @@ -297,100 +298,117 @@ typedef struct drm_agp_info { unsigned short id_device; } drm_agp_info_t; -#define DRM_IOCTL_BASE 'd' -#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) -#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) -#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) - - -#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) -#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) -#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t) -#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t) - -#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t) -#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t) -#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t) -#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t) -#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t) -#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t) -#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t) -#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t) -#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t) -#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t) -#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t) - -#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t) -#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t) -#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t) -#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t) -#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t) -#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t) -#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t) -#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t) -#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t) -#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t) -#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t) -#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t) -#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t) - -#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) -#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) -#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t) -#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t) -#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t) -#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t) -#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t) -#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) +#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) +#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) + + +#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) +#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) +#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t) +#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t) + +#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t) +#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t) +#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t) +#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t) +#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t) +#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t) +#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t) +#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t) +#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t) +#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t) +#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t) + +#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t) +#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t) +#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t) +#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t) +#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t) +#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t) +#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t) +#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t) +#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t) +#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t) +#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t) +#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t) +#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t) + +#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) +#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) +#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t) +#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t) +#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t) +#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) /* Mga specific ioctls */ -#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) -#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) -#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) -#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) -#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) -#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) -#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) -#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t) +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) +#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) +#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t) /* I810 specific ioctls */ -#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) -#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) -#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) -#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) -#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) -#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t) -#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46) -#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) -#define DRM_IOCTL_I810_DOCOPY DRM_IO ( 0x48) +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44) +#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t) +#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46) +#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) +#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48) /* Rage 128 specific ioctls */ -#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) -#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) -#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) -#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) -#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) -#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) -#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) -#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) -#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) -#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) -#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) -#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t) +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) +#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) +#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) +#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) +#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t) +#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48) +#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t) +#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t) +#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t) +#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t) +#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t) +#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) + +/* Radeon specific ioctls */ +#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) +#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41) +#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t) +#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43) +#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45) +#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t) +#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) +#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) +#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) +#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t) +#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) +#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) #ifdef CONFIG_DRM_SIS /* SiS specific ioctls */ -#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) -#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) -#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t) -#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t) -#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) -#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) -#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) -#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) +#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) +#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) +#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t) +#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t) +#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) +#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) +#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) +#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) #endif #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c index d978d53e1..6df2b45ad 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_cce.c @@ -36,9 +36,8 @@ #include <linux/interrupt.h> /* For task queue support */ #include <linux/delay.h> +#define R128_FIFO_DEBUG 0 -/* FIXME: Temporary CCE packet buffer */ -u32 r128_cce_buffer[(1 << 14)] __attribute__ ((aligned (32))); /* CCE microcode (from ATI) */ static u32 r128_cce_microcode[] = { @@ -86,23 +85,23 @@ static u32 r128_cce_microcode[] = { }; -#define DO_REMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) +#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) -#define DO_REMAPFREE(_m) \ - do { \ - if ((_m)->handle && (_m)->size) \ - drm_ioremapfree((_m)->handle, (_m)->size); \ +#define DO_IOREMAPFREE(_m) \ + do { \ + if ((_m)->handle && (_m)->size) \ + drm_ioremapfree((_m)->handle, (_m)->size); \ } while (0) -#define DO_FIND_MAP(_m, _o) \ - do { \ - int _i; \ - for (_i = 0; _i < dev->map_count; _i++) { \ - if (dev->maplist[_i]->offset == _o) { \ - _m = dev->maplist[_i]; \ - break; \ - } \ - } \ +#define DO_FIND_MAP(_m, _o) \ + do { \ + int _i; \ + for (_i = 0; _i < dev->map_count; _i++) { \ + if (dev->maplist[_i]->offset == _o) { \ + _m = dev->maplist[_i]; \ + break; \ + } \ + } \ } while (0) @@ -114,7 +113,7 @@ int R128_READ_PLL(drm_device_t *dev, int addr) return R128_READ(R128_CLOCK_CNTL_DATA); } -#if 0 +#if R128_FIFO_DEBUG static void r128_status( drm_r128_private_t *dev_priv ) { printk( "GUI_STAT = 0x%08x\n", @@ -175,7 +174,7 @@ static int r128_do_wait_for_idle( drm_r128_private_t *dev_priv ) int i, ret; ret = r128_do_wait_for_fifo( dev_priv, 64 ); - if ( !ret ) return ret; + if ( ret < 0 ) return ret; for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { if ( !(R128_READ( R128_GUI_STAT ) & R128_GUI_ACTIVE) ) { @@ -241,7 +240,7 @@ static int r128_do_cce_idle( drm_r128_private_t *dev_priv ) udelay( 1 ); } -#if 0 +#if R128_FIFO_DEBUG DRM_ERROR( "failed!\n" ); r128_status( dev_priv ); #endif @@ -263,7 +262,7 @@ static void r128_do_cce_start( drm_r128_private_t *dev_priv ) } /* Reset the Concurrent Command Engine. This will not flush any pending - * commangs, so you must wait for the CCE command stream to complete + * commands, so you must wait for the CCE command stream to complete * before calling this routine. */ static void r128_do_cce_reset( drm_r128_private_t *dev_priv ) @@ -275,7 +274,7 @@ static void r128_do_cce_reset( drm_r128_private_t *dev_priv ) } /* Stop the Concurrent Command Engine. This will not flush any pending - * commangs, so you must flush the command stream and wait for the CCE + * commands, so you must flush the command stream and wait for the CCE * to go idle before calling this routine. */ static void r128_do_cce_stop( drm_r128_private_t *dev_priv ) @@ -395,7 +394,6 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) } dev_priv->cce_mode = init->cce_mode; - dev_priv->cce_secure = init->cce_secure; /* GH: Simple idle check. */ @@ -481,12 +479,12 @@ static int r128_do_init_cce( drm_device_t *dev, drm_r128_init_t *init ) (drm_r128_sarea_t *)((u8 *)dev_priv->sarea->handle + init->sarea_priv_offset); - DO_REMAP( dev_priv->cce_ring ); - DO_REMAP( dev_priv->ring_rptr ); - DO_REMAP( dev_priv->buffers ); + DO_IOREMAP( dev_priv->cce_ring ); + DO_IOREMAP( dev_priv->ring_rptr ); + DO_IOREMAP( dev_priv->buffers ); #if 0 if ( !dev_priv->is_pci ) { - DO_REMAP( dev_priv->agp_textures ); + DO_IOREMAP( dev_priv->agp_textures ); } #endif @@ -521,12 +519,12 @@ static int r128_do_cleanup_cce( drm_device_t *dev ) if ( dev->dev_private ) { drm_r128_private_t *dev_priv = dev->dev_private; - DO_REMAPFREE( dev_priv->cce_ring ); - DO_REMAPFREE( dev_priv->ring_rptr ); - DO_REMAPFREE( dev_priv->buffers ); + DO_IOREMAPFREE( dev_priv->cce_ring ); + DO_IOREMAPFREE( dev_priv->ring_rptr ); + DO_IOREMAPFREE( dev_priv->buffers ); #if 0 if ( !dev_priv->is_pci ) { - DO_REMAPFREE( dev_priv->agp_textures ); + DO_IOREMAPFREE( dev_priv->agp_textures ); } #endif @@ -697,6 +695,69 @@ int r128_engine_reset( struct inode *inode, struct file *filp, /* ================================================================ + * Fullscreen mode + */ + +static int r128_do_init_pageflip( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + dev_priv->crtc_offset = R128_READ( R128_CRTC_OFFSET ); + dev_priv->crtc_offset_cntl = R128_READ( R128_CRTC_OFFSET_CNTL ); + + R128_WRITE( R128_CRTC_OFFSET, dev_priv->front_offset ); + R128_WRITE( R128_CRTC_OFFSET_CNTL, + dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL ); + + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + + return 0; +} + +int r128_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + R128_WRITE( R128_CRTC_OFFSET, dev_priv->crtc_offset ); + R128_WRITE( R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); + + dev_priv->page_flipping = 0; + dev_priv->current_page = 0; + + return 0; +} + +int r128_fullscreen( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_r128_fullscreen_t fs; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &fs, (drm_r128_fullscreen_t *)arg, sizeof(fs) ) ) + return -EFAULT; + + switch ( fs.func ) { + case R128_INIT_FULLSCREEN: + return r128_do_init_pageflip( dev ); + case R128_CLEANUP_FULLSCREEN: + return r128_do_cleanup_pageflip( dev ); + } + + return -EINVAL; +} + + +/* ================================================================ * Freelist management */ #define R128_BUFFER_USED 0xffffffff @@ -802,7 +863,7 @@ void r128_freelist_reset( drm_device_t *dev ) /* ================================================================ - * CCE packet submission + * CCE command submission */ int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) @@ -821,6 +882,8 @@ int r128_wait_ring( drm_r128_private_t *dev_priv, int n ) udelay( 1 ); } + /* FIXME: This is being ignored... */ + DRM_ERROR( "failed!\n" ); return -EBUSY; } @@ -837,352 +900,6 @@ void r128_update_ring_snapshot( drm_r128_private_t *dev_priv ) ring->space += ring->size; } -#if 0 -static int r128_verify_command( drm_r128_private_t *dev_priv, - u32 cmd, int *size ) -{ - int writing = 1; - - *size = 0; - - switch ( cmd & R128_CCE_PACKET_MASK ) { - case R128_CCE_PACKET0: - if ( (cmd & R128_CCE_PACKET0_REG_MASK) <= (0x1004 >> 2) && - (cmd & R128_CCE_PACKET0_REG_MASK) != - (R128_PM4_VC_FPU_SETUP >> 2) ) { - writing = 0; - } - *size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; - break; - - case R128_CCE_PACKET1: - if ( (cmd & R128_CCE_PACKET1_REG0_MASK) <= (0x1004 >> 2) && - (cmd & R128_CCE_PACKET1_REG0_MASK) != - (R128_PM4_VC_FPU_SETUP >> 2) ) { - writing = 0; - } - if ( (cmd & R128_CCE_PACKET1_REG1_MASK) <= (0x1004 << 9) && - (cmd & R128_CCE_PACKET1_REG1_MASK) != - (R128_PM4_VC_FPU_SETUP << 9) ) { - writing = 0; - } - *size = 3; - break; - - case R128_CCE_PACKET2: - break; - - case R128_CCE_PACKET3: - *size = ((cmd & R128_CCE_PACKET_COUNT_MASK) >> 16) + 2; - break; - - } - - return writing; -} - -static int r128_submit_packet_ring_secure( drm_r128_private_t *dev_priv, - u32 *commands, int *count ) -{ -#if 0 - int write = dev_priv->sarea_priv->ring_write; - int *write_ptr = dev_priv->ring_start + write; - int c = *count; - u32 tmp = 0; - int psize = 0; - int writing = 1; - int timeout; - - while ( c > 0 ) { - tmp = *commands++; - if ( !psize ) { - writing = r128_verify_command( dev_priv, tmp, &psize ); - } - psize--; - - if ( writing ) { - write++; - *write_ptr++ = tmp; - } - if ( write >= dev_priv->ring_entries ) { - write = 0; - write_ptr = dev_priv->ring_start; - } - timeout = 0; - while ( write == *dev_priv->ring_read_ptr ) { - R128_READ( R128_PM4_BUFFER_DL_RPTR ); - if ( timeout++ >= dev_priv->usec_timeout ) - return -EBUSY; - udelay( 1 ); - } - c--; - } - - if ( write < 32 ) { - memcpy( dev_priv->ring_end, - dev_priv->ring_start, - write * sizeof(u32) ); - } - - /* Make sure WC cache has been flushed */ - r128_flush_write_combine(); - - dev_priv->sarea_priv->ring_write = write; - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); - - *count = 0; -#endif - return 0; -} - -static int r128_submit_packet_ring_insecure( drm_r128_private_t *dev_priv, - u32 *commands, int *count ) -{ -#if 0 - int write = dev_priv->sarea_priv->ring_write; - int *write_ptr = dev_priv->ring_start + write; - int c = *count; - int timeout; - - while ( c > 0 ) { - write++; - *write_ptr++ = *commands++; - if ( write >= dev_priv->ring_entries ) { - write = 0; - write_ptr = dev_priv->ring_start; - } - - timeout = 0; - while ( write == *dev_priv->ring_read_ptr ) { - R128_READ( R128_PM4_BUFFER_DL_RPTR ); - if ( timeout++ >= dev_priv->usec_timeout ) - return -EBUSY; - udelay( 1 ); - } - c--; - } - - if ( write < 32 ) { - memcpy( dev_priv->ring_end, - dev_priv->ring_start, - write * sizeof(u32) ); - } - - /* Make sure WC cache has been flushed */ - r128_flush_write_combine(); - - dev_priv->sarea_priv->ring_write = write; - R128_WRITE( R128_PM4_BUFFER_DL_WPTR, write ); - - *count = 0; -#endif - return 0; -} -#endif - -/* Internal packet submission routine. This uses the insecure versions - * of the packet submission functions, and thus should only be used for - * packets generated inside the kernel module. - */ -int r128_do_submit_packet( drm_r128_private_t *dev_priv, - u32 *buffer, int count ) -{ - int c = count; - int ret = 0; - -#if 0 - int left = 0; - - if ( c >= dev_priv->ring_entries ) { - c = dev_priv->ring_entries - 1; - left = count - c; - } - - /* Since this is only used by the kernel we can use the - * insecure ring buffer submit packet routine. - */ - ret = r128_submit_packet_ring_insecure( dev_priv, buffer, &c ); - c += left; -#endif - - return ( ret < 0 ) ? ret : c; -} - -/* External packet submission routine. This uses the secure versions - * by default, and can thus submit packets received from user space. - */ -int r128_cce_packet( struct inode *inode, struct file *filp, - unsigned int cmd, unsigned long arg ) -{ - drm_file_t *priv = filp->private_data; - drm_device_t *dev = priv->dev; - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_packet_t packet; - u32 *buffer; - int c; - int size; - int ret = 0; - -#if 0 - /* GH: Disable packet submission for now. - */ - return -EINVAL; -#endif - - if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || - dev->lock.pid != current->pid ) { - DRM_ERROR( "r128_submit_packet called without lock held\n" ); - return -EINVAL; - } - - if ( copy_from_user( &packet, (drm_r128_packet_t *)arg, - sizeof(packet) ) ) - return -EFAULT; - -#if 0 - c = packet.count; - size = c * sizeof(*buffer); - - { - int left = 0; - - if ( c >= dev_priv->ring_entries ) { - c = dev_priv->ring_entries - 1; - size = c * sizeof(*buffer); - left = packet.count - c; - } - - buffer = kmalloc( size, 0 ); - if ( buffer == NULL) - return -ENOMEM; - if ( copy_from_user( buffer, packet.buffer, size ) ) - return -EFAULT; - - if ( dev_priv->cce_secure ) { - ret = r128_submit_packet_ring_secure( dev_priv, - buffer, &c ); - } else { - ret = r128_submit_packet_ring_insecure( dev_priv, - buffer, &c ); - } - c += left; - } - - kfree( buffer ); -#else - c = 0; -#endif - - packet.count = c; - if ( copy_to_user( (drm_r128_packet_t *)arg, &packet, - sizeof(packet) ) ) - return -EFAULT; - - if ( ret ) { - return ret; - } else if ( c > 0 ) { - return -EAGAIN; - } - return 0; -} - -#if 0 -static int r128_send_vertbufs( drm_device_t *dev, drm_r128_vertex_t *v ) -{ - drm_device_dma_t *dma = dev->dma; - drm_r128_private_t *dev_priv = dev->dev_private; - drm_r128_buf_priv_t *buf_priv; - drm_buf_t *buf; - int i, ret; - RING_LOCALS; - - /* Make sure we have valid data */ - for (i = 0; i < v->send_count; i++) { - int idx = v->send_indices[i]; - - if (idx < 0 || idx >= dma->buf_count) { - DRM_ERROR("Index %d (of %d max)\n", - idx, dma->buf_count - 1); - return -EINVAL; - } - buf = dma->buflist[idx]; - if (buf->pid != current->pid) { - DRM_ERROR("Process %d using buffer owned by %d\n", - current->pid, buf->pid); - return -EINVAL; - } - if (buf->pending) { - DRM_ERROR("Sending pending buffer:" - " buffer %d, offset %d\n", - v->send_indices[i], i); - return -EINVAL; - } - } - - /* Wait for idle, if we've wrapped to make sure that all pending - buffers have been processed */ - if (dev_priv->submit_age == R128_MAX_VBUF_AGE) { - if ((ret = r128_do_cce_idle(dev)) < 0) return ret; - dev_priv->submit_age = 0; - r128_freelist_reset(dev); - } - - /* Make sure WC cache has been flushed (if in PIO mode) */ - if (!dev_priv->cce_is_bm_mode) r128_flush_write_combine(); - - /* FIXME: Add support for sending vertex buffer to the CCE here - instead of in client code. The v->prim holds the primitive - type that should be drawn. Loop over the list buffers in - send_indices[] and submit a packet for each VB. - - This will require us to loop over the clip rects here as - well, which implies that we extend the kernel driver to allow - cliprects to be stored here. Note that the cliprects could - possibly come from the X server instead of the client, but - this will require additional changes to the DRI to allow for - this optimization. */ - - /* Submit a CCE packet that writes submit_age to R128_VB_AGE_REG */ -#if 0 - cce_buffer[0] = R128CCE0(R128_CCE_PACKET0, R128_VB_AGE_REG, 0); - cce_buffer[1] = dev_priv->submit_age; - - if ((ret = r128_do_submit_packet(dev, cce_buffer, 2)) < 0) { - /* Until we add support for sending VBs to the CCE in - this routine, we can recover from this error. After - we add that support, we won't be able to easily - recover, so we will probably have to implement - another mechanism for handling timeouts from packets - submitted directly by the kernel. */ - return ret; - } -#else - BEGIN_RING( 2 ); - - OUT_RING( CCE_PACKET0( R128_VB_AGE_REG, 0 ) ); - OUT_RING( dev_priv->submit_age ); - - ADVANCE_RING(); -#endif - /* Now that the submit packet request has succeeded, we can mark - the buffers as pending */ - for (i = 0; i < v->send_count; i++) { - buf = dma->buflist[v->send_indices[i]]; - buf->pending = 1; - - buf_priv = buf->dev_private; - buf_priv->age = dev_priv->submit_age; - } - - dev_priv->submit_age++; - - return 0; -} -#endif - - - - static int r128_cce_get_buffers( drm_device_t *dev, drm_dma_t *d ) { int i; diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h index 68a55d5dc..94dba1ed9 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drm.h @@ -30,8 +30,8 @@ * */ -#ifndef _R128_DRM_H_ -#define _R128_DRM_H_ +#ifndef __R128_DRM_H__ +#define __R128_DRM_H__ /* WARNING: If you change any of these defines, make sure to change the * defines in the X server file (r128_sarea.h) @@ -69,21 +69,13 @@ /* Vertex/indirect buffer size */ -#if 1 #define R128_BUFFER_SIZE 16384 -#else -#define R128_BUFFER_SIZE (128 * 1024) -#endif /* Byte offsets for indirect buffer data */ #define R128_INDEX_PRIM_OFFSET 20 #define R128_HOSTDATA_BLIT_OFFSET 32 -/* 2048x2048 @ 32bpp texture requires this many indirect buffers - */ -#define R128_MAX_BLIT_BUFFERS ((2048 * 2048 * 4) / R128_BUFFER_SIZE) - /* Keep these small for testing. */ #define R128_NR_SAREA_CLIPRECTS 12 @@ -98,7 +90,9 @@ #define R128_LOG_TEX_GRANULARITY 16 #define R128_NR_CONTEXT_REGS 12 -#define R128_TEX_MAXLEVELS 11 + +#define R128_MAX_TEXTURE_LEVELS 11 +#define R128_MAX_TEXTURE_UNITS 2 #endif /* __R128_SAREA_DEFINES__ */ @@ -137,12 +131,13 @@ typedef struct { unsigned int scale_3d_cntl; } drm_r128_context_regs_t; -/* Setup registers for each texture unit */ +/* Setup registers for each texture unit + */ typedef struct { unsigned int tex_cntl; unsigned int tex_combine_cntl; unsigned int tex_size_pitch; - unsigned int tex_offset[R128_TEX_MAXLEVELS]; + unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS]; unsigned int tex_border_color; } drm_r128_texture_regs_t; @@ -158,7 +153,7 @@ typedef struct drm_r128_sarea { * on firing a vertex buffer. */ drm_r128_context_regs_t context_state; - drm_r128_texture_regs_t tex_state[R128_NR_TEX_HEAPS]; + drm_r128_texture_regs_t tex_state[R128_MAX_TEXTURE_UNITS]; unsigned int dirty; unsigned int vertsize; unsigned int vc_format; @@ -214,6 +209,13 @@ typedef struct drm_r128_cce_stop { int idle; } drm_r128_cce_stop_t; +typedef struct drm_r128_fullscreen { + enum { + R128_INIT_FULLSCREEN = 0x01, + R128_CLEANUP_FULLSCREEN = 0x02 + } func; +} drm_r128_fullscreen_t; + typedef struct drm_r128_clear { unsigned int flags; int x, y, w, h; @@ -263,10 +265,11 @@ typedef struct drm_r128_stipple { unsigned int *mask; } drm_r128_stipple_t; -typedef struct drm_r128_packet { - unsigned int *buffer; - int count; - int flags; -} drm_r128_packet_t; +typedef struct drm_r128_indirect { + int idx; + int start; + int end; + int discard; +} drm_r128_indirect_t; #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c index dbfc9b740..cf2589251 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.c @@ -37,10 +37,10 @@ #define R128_NAME "r128" #define R128_DESC "ATI Rage 128" -#define R128_DATE "20001215" +#define R128_DATE "20010101" #define R128_MAJOR 2 #define R128_MINOR 1 -#define R128_PATCHLEVEL 2 +#define R128_PATCHLEVEL 4 static drm_device_t r128_device; drm_ctx_t r128_res_ctx; @@ -108,20 +108,22 @@ static drm_ioctl_desc_t r128_ioctls[] = { [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, #endif - [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, - [DRM_IOCTL_NR(DRM_IOCTL_R128_PACKET)] = { r128_cce_packet, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_INIT)] = { r128_cce_init, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_START)] = { r128_cce_start, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_STOP)] = { r128_cce_stop, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_RESET)] = { r128_cce_reset, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_CCE_IDLE)] = { r128_cce_idle, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_RESET)] = { r128_engine_reset, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_FULLSCREEN)]= { r128_fullscreen, 1, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_R128_SWAP)] = { r128_cce_swap, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_CLEAR)] = { r128_cce_clear, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_VERTEX)] = { r128_cce_vertex, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_INDICES)] = { r128_cce_indices, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_BLIT)] = { r128_cce_blit, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_DEPTH)] = { r128_cce_depth, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_STIPPLE)] = { r128_cce_stipple, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_R128_INDIRECT)] = { r128_cce_indirect, 1, 1 }, }; #define R128_IOCTL_COUNT DRM_ARRAY_SIZE(r128_ioctls) @@ -489,7 +491,17 @@ int r128_release(struct inode *inode, struct file *filp) lock_kernel(); dev = priv->dev; + DRM_DEBUG("open_count = %d\n", dev->open_count); + + /* Force the cleanup of page flipping when required */ + if ( dev->dev_private ) { + drm_r128_private_t *dev_priv = dev->dev_private; + if ( dev_priv->page_flipping ) { + r128_do_cleanup_pageflip( dev ); + } + } + if (!(retcode = drm_release(inode, filp))) { #if LINUX_VERSION_CODE < 0x020333 MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h index cffd08002..08ef5dc92 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_drv.h @@ -59,7 +59,6 @@ typedef struct drm_r128_private { int cce_mode; int cce_fifo_size; - int cce_secure; int cce_running; drm_r128_freelist_t *head; @@ -70,6 +69,11 @@ typedef struct drm_r128_private { atomic_t idle_count; + int page_flipping; + int current_page; + u32 crtc_offset; + u32 crtc_offset_cntl; + unsigned int fb_bpp; unsigned int front_offset; unsigned int front_pitch; @@ -128,7 +132,7 @@ extern int r128_cce_idle( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int r128_engine_reset( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); -extern int r128_cce_packet( struct inode *inode, struct file *filp, +extern int r128_fullscreen( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int r128_cce_buffers( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -139,6 +143,8 @@ extern drm_buf_t *r128_freelist_get( drm_device_t *dev ); extern int r128_wait_ring( drm_r128_private_t *dev_priv, int n ); extern void r128_update_ring_snapshot( drm_r128_private_t *dev_priv ); +extern int r128_do_cleanup_pageflip( drm_device_t *dev ); + /* r128_state.c */ extern int r128_cce_clear( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); @@ -154,6 +160,8 @@ extern int r128_cce_depth( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); extern int r128_cce_stipple( struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg ); +extern int r128_cce_indirect( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); /* r128_bufs.c */ extern int r128_addbufs(struct inode *inode, struct file *filp, @@ -215,8 +223,10 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new); #define R128_CLOCK_CNTL_INDEX 0x0008 #define R128_CLOCK_CNTL_DATA 0x000c # define R128_PLL_WR_EN (1 << 7) - #define R128_CONSTANT_COLOR_C 0x1d34 +#define R128_CRTC_OFFSET 0x0224 +#define R128_CRTC_OFFSET_CNTL 0x0228 +# define R128_CRTC_OFFSET_FLIP_CNTL (1 << 16) #define R128_DP_GUI_MASTER_CNTL 0x146c # define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) @@ -431,12 +441,12 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); #define BEGIN_RING( n ) do { \ if ( R128_VERBOSE ) { \ DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ - n, __FUNCTION__ ); \ + (n), __FUNCTION__ ); \ } \ - if ( dev_priv->ring.space < n * sizeof(u32) ) { \ - r128_wait_ring( dev_priv, n * sizeof(u32) ); \ + if ( dev_priv->ring.space < (n) * sizeof(u32) ) { \ + r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \ } \ - dev_priv->ring.space -= n * sizeof(u32); \ + dev_priv->ring.space -= (n) * sizeof(u32); \ ring = dev_priv->ring.start; \ write = dev_priv->ring.tail; \ tail_mask = dev_priv->ring.tail_mask; \ @@ -457,7 +467,7 @@ extern int R128_READ_PLL(drm_device_t *dev, int addr); DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ (unsigned int)(x), write ); \ } \ - ring[write++] = x; \ + ring[write++] = (x); \ write &= tail_mask; \ } while (0) diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c index 3f52c14b3..ba0039293 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/r128_state.c @@ -181,14 +181,14 @@ static inline void r128_emit_tex0( drm_r128_private_t *dev_priv ) RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); - BEGIN_RING( 7 + R128_TEX_MAXLEVELS ); + BEGIN_RING( 7 + R128_MAX_TEXTURE_LEVELS ); OUT_RING( CCE_PACKET0( R128_PRIM_TEX_CNTL_C, - 2 + R128_TEX_MAXLEVELS ) ); + 2 + R128_MAX_TEXTURE_LEVELS ) ); OUT_RING( tex->tex_cntl ); OUT_RING( tex->tex_combine_cntl ); OUT_RING( ctx->tex_size_pitch_c ); - for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { OUT_RING( tex->tex_offset[i] ); } @@ -207,13 +207,13 @@ static inline void r128_emit_tex1( drm_r128_private_t *dev_priv ) RING_LOCALS; DRM_DEBUG( " %s\n", __FUNCTION__ ); - BEGIN_RING( 5 + R128_TEX_MAXLEVELS ); + BEGIN_RING( 5 + R128_MAX_TEXTURE_LEVELS ); OUT_RING( CCE_PACKET0( R128_SEC_TEX_CNTL_C, - 1 + R128_TEX_MAXLEVELS ) ); + 1 + R128_MAX_TEXTURE_LEVELS ) ); OUT_RING( tex->tex_cntl ); OUT_RING( tex->tex_combine_cntl ); - for ( i = 0 ; i < R128_TEX_MAXLEVELS ; i++ ) { + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { OUT_RING( tex->tex_offset[i] ); } @@ -310,13 +310,13 @@ static void r128_clear_box( drm_r128_private_t *dev_priv, BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_SOLID_COLOR - | fb_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_P - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_AUX_CLIP_DIS ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + fb_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS ); OUT_RING( (pitch << 21) | (offset >> 5) ); OUT_RING( color ); @@ -398,6 +398,14 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, return; } + if ( dev_priv->page_flipping && dev_priv->current_page == 1) { + unsigned int tmp = flags; + + flags &= ~(R128_FRONT | R128_BACK); + if ( tmp & R128_FRONT ) flags |= R128_BACK; + if ( tmp & R128_BACK ) flags |= R128_FRONT; + } + for ( i = 0 ; i < nbox ; i++ ) { int x = pbox[i].x1; int y = pbox[i].y1; @@ -421,13 +429,13 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_SOLID_COLOR - | fb_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_P - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_AUX_CLIP_DIS ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + fb_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS ); OUT_RING( dev_priv->front_pitch_offset_c ); OUT_RING( clear_color ); @@ -442,13 +450,13 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_SOLID_COLOR - | fb_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_P - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_AUX_CLIP_DIS ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + fb_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS ); OUT_RING( dev_priv->back_pitch_offset_c ); OUT_RING( clear_color ); @@ -463,14 +471,14 @@ static void r128_cce_dispatch_clear( drm_device_t *dev, BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_SOLID_COLOR - | depth_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_P - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_AUX_CLIP_DIS - | R128_GMC_WR_MSK_DIS ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + depth_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( clear_depth ); @@ -521,16 +529,16 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) BEGIN_RING( 7 ); OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); - OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL - | R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_NONE - | fb_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_S - | R128_DP_SRC_SOURCE_MEMORY - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_AUX_CLIP_DIS - | R128_GMC_WR_MSK_DIS ); + OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + fb_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->back_pitch_offset_c ); OUT_RING( dev_priv->front_pitch_offset_c ); @@ -556,6 +564,48 @@ static void r128_cce_dispatch_swap( drm_device_t *dev ) ADVANCE_RING(); } +static void r128_cce_dispatch_flip( drm_device_t *dev ) +{ + drm_r128_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page ); + + r128_update_ring_snapshot( dev_priv ); + +#if R128_PERFORMANCE_BOXES + /* Do some trivial performance monitoring... + */ + r128_cce_performance_boxes( dev_priv ); +#endif + + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_CRTC_OFFSET, 0 ) ); + + if ( dev_priv->current_page == 0 ) { + OUT_RING( dev_priv->back_offset ); + dev_priv->current_page = 1; + } else { + OUT_RING( dev_priv->front_offset ); + dev_priv->current_page = 0; + } + + ADVANCE_RING(); + + /* Increment the frame counter. The client-side 3D driver must + * throttle the framerate by waiting for this value before + * performing the swapbuffer ioctl. + */ + dev_priv->sarea_priv->last_frame++; + + BEGIN_RING( 2 ); + + OUT_RING( CCE_PACKET0( R128_LAST_FRAME_REG, 0 ) ); + OUT_RING( dev_priv->sarea_priv->last_frame ); + + ADVANCE_RING(); +} + static void r128_cce_dispatch_vertex( drm_device_t *dev, drm_buf_t *buf ) { @@ -821,13 +871,17 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, * use a shift instead. */ switch ( blit->format ) { + case R128_DATATYPE_ARGB8888: + dword_shift = 0; + break; case R128_DATATYPE_ARGB1555: case R128_DATATYPE_RGB565: case R128_DATATYPE_ARGB4444: dword_shift = 1; break; - case R128_DATATYPE_ARGB8888: - dword_shift = 0; + case R128_DATATYPE_CI8: + case R128_DATATYPE_RGB8: + dword_shift = 2; break; default: DRM_ERROR( "invalid blit format %d\n", blit->format ); @@ -868,15 +922,15 @@ static int r128_cce_dispatch_blit( drm_device_t *dev, data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); data[0] = CCE_PACKET3( R128_CNTL_HOSTDATA_BLT, dwords + 6 ); - data[1] = ( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_NONE - | (blit->format << 8) - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_S - | R128_DP_SRC_SOURCE_HOST_DATA - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_AUX_CLIP_DIS - | R128_GMC_WR_MSK_DIS ); + data[1] = (R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + (blit->format << 8) | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_HOST_DATA | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_AUX_CLIP_DIS | + R128_GMC_WR_MSK_DIS); data[2] = (blit->pitch << 21) | (blit->offset >> 5); data[3] = 0xffffffff; @@ -971,15 +1025,14 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, if ( mask[i] ) { BEGIN_RING( 6 ); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, - 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_SOLID_COLOR - | depth_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_P - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_WR_MSK_DIS ); + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + depth_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( buffer[i] ); @@ -997,13 +1050,13 @@ static int r128_cce_dispatch_write_span( drm_device_t *dev, BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_SOLID_COLOR - | depth_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_P - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_WR_MSK_DIS ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + depth_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( buffer[i] ); @@ -1103,15 +1156,14 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, if ( mask[i] ) { BEGIN_RING( 6 ); - OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, - 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_SOLID_COLOR - | depth_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_P - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_WR_MSK_DIS ); + OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + depth_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( buffer[i] ); @@ -1129,13 +1181,13 @@ static int r128_cce_dispatch_write_pixels( drm_device_t *dev, BEGIN_RING( 6 ); OUT_RING( CCE_PACKET3( R128_CNTL_PAINT_MULTI, 4 ) ); - OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_SOLID_COLOR - | depth_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_P - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_WR_MSK_DIS ); + OUT_RING( R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_SOLID_COLOR | + depth_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_P | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( buffer[i] ); @@ -1188,15 +1240,15 @@ static int r128_cce_dispatch_read_span( drm_device_t *dev, BEGIN_RING( 7 ); OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); - OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL - | R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_NONE - | depth_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_S - | R128_DP_SRC_SOURCE_MEMORY - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_WR_MSK_DIS ); + OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + depth_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( dev_priv->span_pitch_offset_c ); @@ -1263,15 +1315,15 @@ static int r128_cce_dispatch_read_pixels( drm_device_t *dev, BEGIN_RING( 7 ); OUT_RING( CCE_PACKET3( R128_CNTL_BITBLT_MULTI, 5 ) ); - OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL - | R128_GMC_DST_PITCH_OFFSET_CNTL - | R128_GMC_BRUSH_NONE - | depth_bpp - | R128_GMC_SRC_DATATYPE_COLOR - | R128_ROP3_S - | R128_DP_SRC_SOURCE_MEMORY - | R128_GMC_CLR_CMP_CNTL_DIS - | R128_GMC_WR_MSK_DIS ); + OUT_RING( R128_GMC_SRC_PITCH_OFFSET_CNTL | + R128_GMC_DST_PITCH_OFFSET_CNTL | + R128_GMC_BRUSH_NONE | + depth_bpp | + R128_GMC_SRC_DATATYPE_COLOR | + R128_ROP3_S | + R128_DP_SRC_SOURCE_MEMORY | + R128_GMC_CLR_CMP_CNTL_DIS | + R128_GMC_WR_MSK_DIS ); OUT_RING( dev_priv->depth_pitch_offset_c ); OUT_RING( dev_priv->span_pitch_offset_c ); @@ -1305,7 +1357,7 @@ static void r128_cce_dispatch_stipple( drm_device_t *dev, u32 *stipple ) BEGIN_RING( 33 ); - OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) ); + OUT_RING( CCE_PACKET0( R128_BRUSH_DATA0, 31 ) ); for ( i = 0 ; i < 32 ; i++ ) { OUT_RING( stipple[i] ); } @@ -1370,11 +1422,13 @@ int r128_cce_swap( struct inode *inode, struct file *filp, if ( sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS ) sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS; - r128_cce_dispatch_swap( dev ); - - /* Make sure we restore the 3D state next time. - */ - dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + if ( !dev_priv->page_flipping ) { + r128_cce_dispatch_swap( dev ); + dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT | + R128_UPLOAD_MASKS); + } else { + r128_cce_dispatch_flip( dev ); + } return 0; } @@ -1603,3 +1657,20 @@ int r128_cce_stipple( struct inode *inode, struct file *filp, return 0; } + +int r128_cce_indirect( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + /* Indirect buffer firing is not supported at this time. + */ + return -EINVAL; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_bufs.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_bufs.c new file mode 100644 index 000000000..9a3093eb1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_bufs.c @@ -0,0 +1,298 @@ +/* radeon_bufs.c -- IOCTLs to manage buffers -*- linux-c -*- + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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> + * Rickard E. (Rik) Faith <faith@valinux.com> + * Jeff Hartmann <jhartmann@valinux.com> + * + */ + +#define __NO_VERSION__ +#include <linux/config.h> +#include "drmP.h" +#include "radeon_drv.h" +#include "linux/un.h" + + +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) +int radeon_addbufs_agp(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + drm_buf_desc_t request; + drm_buf_entry_t *entry; + drm_buf_t *buf; + unsigned long offset; + unsigned long agp_offset; + int count; + int order; + int size; + int alignment; + int page_order; + int total; + int byte_count; + int i; + + if (!dma) return -EINVAL; + + if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request))) + return -EFAULT; + + count = request.count; + order = drm_order(request.size); + size = 1 << order; + + alignment = (request.flags & _DRM_PAGE_ALIGN) ? PAGE_ALIGN(size):size; + page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0; + total = PAGE_SIZE << page_order; + + byte_count = 0; + agp_offset = dev->agp->base + request.agp_start; + + DRM_DEBUG("count: %d\n", count); + DRM_DEBUG("order: %d\n", order); + DRM_DEBUG("size: %d\n", size); + DRM_DEBUG("agp_offset: %ld\n", agp_offset); + DRM_DEBUG("alignment: %d\n", alignment); + DRM_DEBUG("page_order: %d\n", page_order); + DRM_DEBUG("total: %d\n", total); + + if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER) return -EINVAL; + if (dev->queue_count) return -EBUSY; /* Not while in use */ + + spin_lock(&dev->count_lock); + if (dev->buf_use) { + spin_unlock(&dev->count_lock); + return -EBUSY; + } + atomic_inc(&dev->buf_alloc); + spin_unlock(&dev->count_lock); + + down(&dev->struct_sem); + entry = &dma->bufs[order]; + if (entry->buf_count) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; /* May only call once for each order */ + } + + entry->buflist = drm_alloc(count * sizeof(*entry->buflist), + DRM_MEM_BUFS); + if (!entry->buflist) { + up(&dev->struct_sem); + atomic_dec(&dev->buf_alloc); + return -ENOMEM; + } + memset(entry->buflist, 0, count * sizeof(*entry->buflist)); + + entry->buf_size = size; + entry->page_order = page_order; + offset = 0; + + for (offset = 0; + entry->buf_count < count; + offset += alignment, ++entry->buf_count) { + buf = &entry->buflist[entry->buf_count]; + buf->idx = dma->buf_count + entry->buf_count; + buf->total = alignment; + buf->order = order; + buf->used = 0; + buf->offset = (dma->byte_count + offset); + buf->address = (void *)(agp_offset + offset); + buf->next = NULL; + buf->waiting = 0; + buf->pending = 0; + init_waitqueue_head(&buf->dma_wait); + buf->pid = 0; + + buf->dev_priv_size = sizeof(drm_radeon_buf_priv_t); + buf->dev_private = drm_alloc(sizeof(drm_radeon_buf_priv_t), + DRM_MEM_BUFS); + memset(buf->dev_private, 0, buf->dev_priv_size); + +#if DRM_DMA_HISTOGRAM + buf->time_queued = 0; + buf->time_dispatched = 0; + buf->time_completed = 0; + buf->time_freed = 0; +#endif + + byte_count += PAGE_SIZE << page_order; + + DRM_DEBUG("buffer %d @ %p\n", + entry->buf_count, buf->address); + } + + DRM_DEBUG("byte_count: %d\n", byte_count); + + dma->buflist = drm_realloc(dma->buflist, + dma->buf_count * sizeof(*dma->buflist), + (dma->buf_count + entry->buf_count) + * sizeof(*dma->buflist), + DRM_MEM_BUFS); + for (i = dma->buf_count; i < dma->buf_count + entry->buf_count; i++) + dma->buflist[i] = &entry->buflist[i - dma->buf_count]; + + dma->buf_count += entry->buf_count; + dma->byte_count += byte_count; + + drm_freelist_create(&entry->freelist, entry->buf_count); + for (i = 0; i < entry->buf_count; i++) { + drm_freelist_put(dev, &entry->freelist, &entry->buflist[i]); + } + + up(&dev->struct_sem); + + request.count = entry->buf_count; + request.size = size; + + if (copy_to_user((drm_buf_desc_t *)arg, &request, sizeof(request))) + return -EFAULT; + + dma->flags = _DRM_DMA_USE_AGP; + + atomic_dec(&dev->buf_alloc); + return 0; +} +#endif + +int radeon_addbufs(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_buf_desc_t request; + + if (!dev_priv || dev_priv->is_pci) return -EINVAL; + + if (copy_from_user(&request, (drm_buf_desc_t *)arg, sizeof(request))) + return -EFAULT; + +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + if (request.flags & _DRM_AGP_BUFFER) + return radeon_addbufs_agp(inode, filp, cmd, arg); + else +#endif + return -EINVAL; +} + +int radeon_mapbufs(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + int retcode = 0; + const int zero = 0; + unsigned long virtual; + unsigned long address; + drm_buf_map_t request; + int i; + + if (!dma || !dev_priv || dev_priv->is_pci) return -EINVAL; + + DRM_DEBUG("\n"); + + spin_lock(&dev->count_lock); + if (atomic_read(&dev->buf_alloc)) { + spin_unlock(&dev->count_lock); + return -EBUSY; + } + ++dev->buf_use; /* Can't allocate more after this call */ + spin_unlock(&dev->count_lock); + + if (copy_from_user(&request, (drm_buf_map_t *)arg, sizeof(request))) + return -EFAULT; + + if (request.count >= dma->buf_count) { + if (dma->flags & _DRM_DMA_USE_AGP) { + drm_map_t *map; + + map = dev_priv->buffers; + if (!map) { + retcode = -EINVAL; + goto done; + } + + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, map->size, + PROT_READ|PROT_WRITE, + MAP_SHARED, + (unsigned long)map->offset); + up(¤t->mm->mmap_sem); + } else { + down(¤t->mm->mmap_sem); + virtual = do_mmap(filp, 0, dma->byte_count, + PROT_READ|PROT_WRITE, MAP_SHARED, 0); + up(¤t->mm->mmap_sem); + } + if (virtual > -1024UL) { + /* Real error */ + retcode = (signed long)virtual; + goto done; + } + request.virtual = (void *)virtual; + + for (i = 0; i < dma->buf_count; i++) { + if (copy_to_user(&request.list[i].idx, + &dma->buflist[i]->idx, + sizeof(request.list[0].idx))) { + retcode = -EFAULT; + goto done; + } + if (copy_to_user(&request.list[i].total, + &dma->buflist[i]->total, + sizeof(request.list[0].total))) { + retcode = -EFAULT; + goto done; + } + if (copy_to_user(&request.list[i].used, + &zero, + sizeof(zero))) { + retcode = -EFAULT; + goto done; + } + address = virtual + dma->buflist[i]->offset; + if (copy_to_user(&request.list[i].address, + &address, + sizeof(address))) { + retcode = -EFAULT; + goto done; + } + } + } + done: + request.count = dma->buf_count; + DRM_DEBUG("%d buffers, retcode = %d\n", request.count, retcode); + + if (copy_to_user((drm_buf_map_t *)arg, &request, sizeof(request))) + return -EFAULT; + + return retcode; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_context.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_context.c new file mode 100644 index 000000000..e428dc22c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_context.c @@ -0,0 +1,215 @@ +/* radeon_context.c -- IOCTLs for Radeon contexts -*- linux-c -*- + * + * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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. + * + * Author: Kevin E. Martin <martin@valinux.com> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +#define __NO_VERSION__ +#include "drmP.h" +#include "radeon_drv.h" + +extern drm_ctx_t radeon_res_ctx; + +static int radeon_alloc_queue(drm_device_t *dev) +{ + return drm_ctxbitmap_next(dev); +} + +int radeon_context_switch(drm_device_t *dev, int old, int new) +{ + char buf[64]; + + atomic_inc(&dev->total_ctx); + + if (test_and_set_bit(0, &dev->context_flag)) { + DRM_ERROR("Reentering -- FIXME\n"); + return -EBUSY; + } + +#if DRM_DMA_HISTOGRAM + dev->ctx_start = get_cycles(); +#endif + + DRM_DEBUG("Context switch from %d to %d\n", old, new); + + if (new == dev->last_context) { + clear_bit(0, &dev->context_flag); + return 0; + } + + if (drm_flags & DRM_FLAG_NOCTX) { + radeon_context_switch_complete(dev, new); + } else { + sprintf(buf, "C %d %d\n", old, new); + drm_write_string(dev, buf); + } + + return 0; +} + +int radeon_context_switch_complete(drm_device_t *dev, int new) +{ + dev->last_context = new; /* PRE/POST: This is the _only_ writer. */ + dev->last_switch = jiffies; + + if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) { + DRM_ERROR("Lock isn't held after context switch\n"); + } + + /* If a context switch is ever initiated + when the kernel holds the lock, release + that lock here. */ +#if DRM_DMA_HISTOGRAM + atomic_inc(&dev->histo.ctx[drm_histogram_slot(get_cycles() + - dev->ctx_start)]); + +#endif + clear_bit(0, &dev->context_flag); + wake_up(&dev->context_wait); + + return 0; +} + + +int radeon_resctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_ctx_res_t res; + drm_ctx_t ctx; + int i; + + DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS); + if (copy_from_user(&res, (drm_ctx_res_t *)arg, sizeof(res))) + return -EFAULT; + if (res.count >= DRM_RESERVED_CONTEXTS) { + memset(&ctx, 0, sizeof(ctx)); + for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) { + ctx.handle = i; + if (copy_to_user(&res.contexts[i], &i, sizeof(i))) + return -EFAULT; + } + } + res.count = DRM_RESERVED_CONTEXTS; + if (copy_to_user((drm_ctx_res_t *)arg, &res, sizeof(res))) + return -EFAULT; + return 0; +} + + +int radeon_addctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + if ((ctx.handle = radeon_alloc_queue(dev)) == DRM_KERNEL_CONTEXT) { + /* Skip kernel's context and get a new one. */ + ctx.handle = radeon_alloc_queue(dev); + } + DRM_DEBUG("%d\n", ctx.handle); + if (ctx.handle == -1) { + DRM_DEBUG("Not enough free contexts.\n"); + /* Should this return -EBUSY instead? */ + return -ENOMEM; + } + + if (copy_to_user((drm_ctx_t *)arg, &ctx, sizeof(ctx))) + return -EFAULT; + return 0; +} + +int radeon_modctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx))) + return -EFAULT; + if (ctx.flags==_DRM_CONTEXT_PRESERVED) + radeon_res_ctx.handle=ctx.handle; + return 0; +} + +int radeon_getctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t*)arg, sizeof(ctx))) + return -EFAULT; + /* This is 0, because we don't hanlde any context flags */ + ctx.flags = 0; + if (copy_to_user((drm_ctx_t*)arg, &ctx, sizeof(ctx))) + return -EFAULT; + return 0; +} + +int radeon_switchctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + return radeon_context_switch(dev, dev->last_context, ctx.handle); +} + +int radeon_newctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + radeon_context_switch_complete(dev, ctx.handle); + + return 0; +} + +int radeon_rmctx(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_ctx_t ctx; + + if (copy_from_user(&ctx, (drm_ctx_t *)arg, sizeof(ctx))) + return -EFAULT; + DRM_DEBUG("%d\n", ctx.handle); + drm_ctxbitmap_free(dev, ctx.handle); + + return 0; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c new file mode 100644 index 000000000..5d662bc08 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_cp.c @@ -0,0 +1,1314 @@ +/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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> + * + */ + +#define __NO_VERSION__ +#include "drmP.h" +#include "radeon_drv.h" + +#include <linux/interrupt.h> /* For task queue support */ +#include <linux/delay.h> + +#define RADEON_FIFO_DEBUG 0 + + +/* CP microcode (from ATI) */ +static u32 radeon_cp_microcode[][2] = { + { 0x21007000, 0000000000 }, + { 0x20007000, 0000000000 }, + { 0x000000b4, 0x00000004 }, + { 0x000000b8, 0x00000004 }, + { 0x6f5b4d4c, 0000000000 }, + { 0x4c4c427f, 0000000000 }, + { 0x5b568a92, 0000000000 }, + { 0x4ca09c6d, 0000000000 }, + { 0xad4c4c4c, 0000000000 }, + { 0x4ce1af3d, 0000000000 }, + { 0xd8afafaf, 0000000000 }, + { 0xd64c4cdc, 0000000000 }, + { 0x4cd10d10, 0000000000 }, + { 0x000f0000, 0x00000016 }, + { 0x362f242d, 0000000000 }, + { 0x00000012, 0x00000004 }, + { 0x000f0000, 0x00000016 }, + { 0x362f282d, 0000000000 }, + { 0x000380e7, 0x00000002 }, + { 0x04002c97, 0x00000002 }, + { 0x000f0001, 0x00000016 }, + { 0x333a3730, 0000000000 }, + { 0x000077ef, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x00000021, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00061000, 0x00000002 }, + { 0x00000021, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00061000, 0x00000002 }, + { 0x00000021, 0x0000001a }, + { 0x00004000, 0x0000001e }, + { 0x00000017, 0x00000004 }, + { 0x0003802b, 0x00000002 }, + { 0x040067e0, 0x00000002 }, + { 0x00000017, 0x00000004 }, + { 0x000077e0, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x000037e1, 0x00000002 }, + { 0x040067e1, 0x00000006 }, + { 0x000077e0, 0x00000002 }, + { 0x000077e1, 0x00000002 }, + { 0x000077e1, 0x00000006 }, + { 0xffffffff, 0000000000 }, + { 0x10000000, 0000000000 }, + { 0x0003802b, 0x00000002 }, + { 0x040067e0, 0x00000006 }, + { 0x00007675, 0x00000002 }, + { 0x00007676, 0x00000002 }, + { 0x00007677, 0x00000002 }, + { 0x00007678, 0x00000006 }, + { 0x0003802c, 0x00000002 }, + { 0x04002676, 0x00000002 }, + { 0x00007677, 0x00000002 }, + { 0x00007678, 0x00000006 }, + { 0x0000002f, 0x00000018 }, + { 0x0000002f, 0x00000018 }, + { 0000000000, 0x00000006 }, + { 0x00000030, 0x00000018 }, + { 0x00000030, 0x00000018 }, + { 0000000000, 0x00000006 }, + { 0x01605000, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x00098000, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x64c0603e, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00080000, 0x00000016 }, + { 0000000000, 0000000000 }, + { 0x0400251d, 0x00000002 }, + { 0x00007580, 0x00000002 }, + { 0x00067581, 0x00000002 }, + { 0x04002580, 0x00000002 }, + { 0x00067581, 0x00000002 }, + { 0x00000049, 0x00000004 }, + { 0x00005000, 0000000000 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x0000750e, 0x00000002 }, + { 0x00019000, 0x00000002 }, + { 0x00011055, 0x00000014 }, + { 0x00000055, 0x00000012 }, + { 0x0400250f, 0x00000002 }, + { 0x0000504f, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00007565, 0x00000002 }, + { 0x00007566, 0x00000002 }, + { 0x00000058, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x01e655b4, 0x00000002 }, + { 0x4401b0e4, 0x00000002 }, + { 0x01c110e4, 0x00000002 }, + { 0x26667066, 0x00000018 }, + { 0x040c2565, 0x00000002 }, + { 0x00000066, 0x00000018 }, + { 0x04002564, 0x00000002 }, + { 0x00007566, 0x00000002 }, + { 0x0000005d, 0x00000004 }, + { 0x00401069, 0x00000008 }, + { 0x00101000, 0x00000002 }, + { 0x000d80ff, 0x00000002 }, + { 0x0080006c, 0x00000008 }, + { 0x000f9000, 0x00000002 }, + { 0x000e00ff, 0x00000002 }, + { 0000000000, 0x00000006 }, + { 0x0000008f, 0x00000018 }, + { 0x0000005b, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00007576, 0x00000002 }, + { 0x00065000, 0x00000002 }, + { 0x00009000, 0x00000002 }, + { 0x00041000, 0x00000002 }, + { 0x0c00350e, 0x00000002 }, + { 0x00049000, 0x00000002 }, + { 0x00051000, 0x00000002 }, + { 0x01e785f8, 0x00000002 }, + { 0x00200000, 0x00000002 }, + { 0x0060007e, 0x0000000c }, + { 0x00007563, 0x00000002 }, + { 0x006075f0, 0x00000021 }, + { 0x20007073, 0x00000004 }, + { 0x00005073, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00007576, 0x00000002 }, + { 0x00007577, 0x00000002 }, + { 0x0000750e, 0x00000002 }, + { 0x0000750f, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00600083, 0x0000000c }, + { 0x006075f0, 0x00000021 }, + { 0x000075f8, 0x00000002 }, + { 0x00000083, 0x00000004 }, + { 0x000a750e, 0x00000002 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x0020750f, 0x00000002 }, + { 0x00600086, 0x00000004 }, + { 0x00007570, 0x00000002 }, + { 0x00007571, 0x00000002 }, + { 0x00007572, 0x00000006 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00005000, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00007568, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x00000095, 0x0000000c }, + { 0x00058000, 0x00000002 }, + { 0x0c607562, 0x00000002 }, + { 0x00000097, 0x00000004 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x00600096, 0x00000004 }, + { 0x400070e5, 0000000000 }, + { 0x000380e6, 0x00000002 }, + { 0x040025c5, 0x00000002 }, + { 0x000380e5, 0x00000002 }, + { 0x000000a8, 0x0000001c }, + { 0x000650aa, 0x00000018 }, + { 0x040025bb, 0x00000002 }, + { 0x000610ab, 0x00000018 }, + { 0x040075bc, 0000000000 }, + { 0x000075bb, 0x00000002 }, + { 0x000075bc, 0000000000 }, + { 0x00090000, 0x00000006 }, + { 0x00090000, 0x00000002 }, + { 0x000d8002, 0x00000006 }, + { 0x00007832, 0x00000002 }, + { 0x00005000, 0x00000002 }, + { 0x000380e7, 0x00000002 }, + { 0x04002c97, 0x00000002 }, + { 0x00007820, 0x00000002 }, + { 0x00007821, 0x00000002 }, + { 0x00007800, 0000000000 }, + { 0x01200000, 0x00000002 }, + { 0x20077000, 0x00000002 }, + { 0x01200000, 0x00000002 }, + { 0x20007000, 0x00000002 }, + { 0x00061000, 0x00000002 }, + { 0x0120751b, 0x00000002 }, + { 0x8040750a, 0x00000002 }, + { 0x8040750b, 0x00000002 }, + { 0x00110000, 0x00000002 }, + { 0x000380e5, 0x00000002 }, + { 0x000000c6, 0x0000001c }, + { 0x000610ab, 0x00000018 }, + { 0x844075bd, 0x00000002 }, + { 0x000610aa, 0x00000018 }, + { 0x840075bb, 0x00000002 }, + { 0x000610ab, 0x00000018 }, + { 0x844075bc, 0x00000002 }, + { 0x000000c9, 0x00000004 }, + { 0x804075bd, 0x00000002 }, + { 0x800075bb, 0x00000002 }, + { 0x804075bc, 0x00000002 }, + { 0x00108000, 0x00000002 }, + { 0x01400000, 0x00000002 }, + { 0x006000cd, 0x0000000c }, + { 0x20c07000, 0x00000020 }, + { 0x000000cf, 0x00000012 }, + { 0x00800000, 0x00000006 }, + { 0x0080751d, 0x00000006 }, + { 0000000000, 0000000000 }, + { 0x0000775c, 0x00000002 }, + { 0x00a05000, 0x00000002 }, + { 0x00661000, 0x00000002 }, + { 0x0460275d, 0x00000020 }, + { 0x00004000, 0000000000 }, + { 0x01e00830, 0x00000002 }, + { 0x21007000, 0000000000 }, + { 0x6464614d, 0000000000 }, + { 0x69687420, 0000000000 }, + { 0x00000073, 0000000000 }, + { 0000000000, 0000000000 }, + { 0x00005000, 0x00000002 }, + { 0x000380d0, 0x00000002 }, + { 0x040025e0, 0x00000002 }, + { 0x000075e1, 0000000000 }, + { 0x00000001, 0000000000 }, + { 0x000380e0, 0x00000002 }, + { 0x04002394, 0x00000002 }, + { 0x00005000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0x00000008, 0000000000 }, + { 0x00000004, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, + { 0000000000, 0000000000 }, +}; + + +#define DO_IOREMAP(_m) (_m)->handle = drm_ioremap((_m)->offset, (_m)->size) + +#define DO_IOREMAPFREE(_m) \ + do { \ + if ((_m)->handle && (_m)->size) \ + drm_ioremapfree((_m)->handle, (_m)->size); \ + } while (0) + +#define DO_FIND_MAP(_m, _o) \ + do { \ + int _i; \ + for (_i = 0; _i < dev->map_count; _i++) { \ + if (dev->maplist[_i]->offset == _o) { \ + _m = dev->maplist[_i]; \ + break; \ + } \ + } \ + } while (0) + + +int RADEON_READ_PLL(drm_device_t *dev, int addr) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + + RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f); + return RADEON_READ(RADEON_CLOCK_CNTL_DATA); +} + +#if RADEON_FIFO_DEBUG +static void radeon_status( drm_radeon_private_t *dev_priv ) +{ + printk( "%s:\n", __FUNCTION__ ); + printk( "RBBM_STATUS = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_RBBM_STATUS ) ); + printk( "CP_RB_RTPR = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_CP_RB_RPTR ) ); + printk( "CP_RB_WTPR = 0x%08x\n", + (unsigned int)RADEON_READ( RADEON_CP_RB_WPTR ) ); +} +#endif + + +/* ================================================================ + * Engine, FIFO control + */ + +static int radeon_do_pixcache_flush( drm_radeon_private_t *dev_priv ) +{ + u32 tmp; + int i; + + tmp = RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ); + tmp |= RADEON_RB2D_DC_FLUSH_ALL; + RADEON_WRITE( RADEON_RB2D_DSTCACHE_CTLSTAT, tmp ); + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + if ( !(RADEON_READ( RADEON_RB2D_DSTCACHE_CTLSTAT ) + & RADEON_RB2D_DC_BUSY) ) { + return 0; + } + udelay( 1 ); + } + +#if RADEON_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); + radeon_status( dev_priv ); +#endif + return -EBUSY; +} + +static int radeon_do_wait_for_fifo( drm_radeon_private_t *dev_priv, + int entries ) +{ + int i; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + int slots = ( RADEON_READ( RADEON_RBBM_STATUS ) + & RADEON_RBBM_FIFOCNT_MASK ); + if ( slots >= entries ) return 0; + udelay( 1 ); + } + +#if RADEON_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); + radeon_status( dev_priv ); +#endif + return -EBUSY; +} + +static int radeon_do_wait_for_idle( drm_radeon_private_t *dev_priv ) +{ + int i, ret; + + ret = radeon_do_wait_for_fifo( dev_priv, 64 ); + if ( ret < 0 ) return ret; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + if ( !(RADEON_READ( RADEON_RBBM_STATUS ) + & RADEON_RBBM_ACTIVE) ) { + radeon_do_pixcache_flush( dev_priv ); + return 0; + } + udelay( 1 ); + } + +#if RADEON_FIFO_DEBUG + DRM_ERROR( "failed!\n" ); + radeon_status( dev_priv ); +#endif + return -EBUSY; +} + + +/* ================================================================ + * CP control, initialization + */ + +/* Load the microcode for the CP */ +static void radeon_cp_load_microcode( drm_radeon_private_t *dev_priv ) +{ + int i; + + radeon_do_wait_for_idle( dev_priv ); + + RADEON_WRITE( RADEON_CP_ME_RAM_ADDR, 0 ); + for ( i = 0 ; i < 256 ; i++ ) { + RADEON_WRITE( RADEON_CP_ME_RAM_DATAH, + radeon_cp_microcode[i][1] ); + RADEON_WRITE( RADEON_CP_ME_RAM_DATAL, + radeon_cp_microcode[i][0] ); + } +} + +/* Flush any pending commands to the CP. This should only be used just + * prior to a wait for idle, as it informs the engine that the command + * stream is ending. + */ +static void radeon_do_cp_flush( drm_radeon_private_t *dev_priv ) +{ +#if 0 + u32 tmp; + + tmp = RADEON_READ( RADEON_CP_RB_WPTR ) | (1 << 31); + RADEON_WRITE( RADEON_CP_RB_WPTR, tmp ); +#endif +} + +/* Wait for the CP to go idle. + */ +int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ) +{ + RING_LOCALS; + + BEGIN_RING( 6 ); + + RADEON_PURGE_CACHE(); + RADEON_PURGE_ZCACHE(); + RADEON_WAIT_UNTIL_IDLE(); + + ADVANCE_RING(); + + return radeon_do_wait_for_idle( dev_priv ); +} + +/* Start the Command Processor. + */ +static void radeon_do_cp_start( drm_radeon_private_t *dev_priv ) +{ + RING_LOCALS; + + radeon_do_wait_for_idle( dev_priv ); + + RADEON_WRITE( RADEON_CP_CSQ_CNTL, dev_priv->cp_mode ); + + dev_priv->cp_running = 1; + + BEGIN_RING( 6 ); + + RADEON_PURGE_CACHE(); + RADEON_PURGE_ZCACHE(); + RADEON_WAIT_UNTIL_IDLE(); + + ADVANCE_RING(); +} + +/* Reset the Command Processor. This will not flush any pending + * commands, so you must wait for the CP command stream to complete + * before calling this routine. + */ +static void radeon_do_cp_reset( drm_radeon_private_t *dev_priv ) +{ + u32 cur_read_ptr; + + cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); + RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); + *dev_priv->ring.head = cur_read_ptr; + dev_priv->ring.tail = cur_read_ptr; +} + +/* Stop the Command Processor. This will not flush any pending + * commands, so you must flush the command stream and wait for the CP + * to go idle before calling this routine. + */ +static void radeon_do_cp_stop( drm_radeon_private_t *dev_priv ) +{ + RADEON_WRITE( RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS ); + + dev_priv->cp_running = 0; +} + +/* Reset the engine. This will stop the CP if it is running. + */ +static int radeon_do_engine_reset( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + radeon_do_pixcache_flush( dev_priv ); + + clock_cntl_index = RADEON_READ( RADEON_CLOCK_CNTL_INDEX ); + mclk_cntl = RADEON_READ_PLL( dev, RADEON_MCLK_CNTL ); + + /* FIXME: remove magic number here and in radeon ddx driver!!! */ + RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl | 0x003f00000 ); + + rbbm_soft_reset = RADEON_READ( RADEON_RBBM_SOFT_RESET ); + + RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset | + RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB | + RADEON_SOFT_RESET_HDP ) ); + RADEON_READ( RADEON_RBBM_SOFT_RESET ); + RADEON_WRITE( RADEON_RBBM_SOFT_RESET, ( rbbm_soft_reset & + ~( RADEON_SOFT_RESET_CP | + RADEON_SOFT_RESET_HI | + RADEON_SOFT_RESET_SE | + RADEON_SOFT_RESET_RE | + RADEON_SOFT_RESET_PP | + RADEON_SOFT_RESET_E2 | + RADEON_SOFT_RESET_RB | + RADEON_SOFT_RESET_HDP ) ) ); + RADEON_READ( RADEON_RBBM_SOFT_RESET ); + + + RADEON_WRITE_PLL( RADEON_MCLK_CNTL, mclk_cntl ); + RADEON_WRITE( RADEON_CLOCK_CNTL_INDEX, clock_cntl_index ); + RADEON_WRITE( RADEON_RBBM_SOFT_RESET, rbbm_soft_reset ); + + /* Reset the CP ring */ + radeon_do_cp_reset( dev_priv ); + + /* The CP is no longer running after an engine reset */ + dev_priv->cp_running = 0; + + /* Reset any pending vertex, indirect buffers */ + radeon_freelist_reset( dev ); + + return 0; +} + +static void radeon_cp_init_ring_buffer( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + u32 ring_start, cur_read_ptr; + u32 tmp; + + /* Initialize the memory controller */ + RADEON_WRITE( RADEON_MC_FB_LOCATION, + (dev_priv->agp_vm_start - 1) & 0xffff0000 ); + RADEON_WRITE( RADEON_MC_AGP_LOCATION, + (((dev_priv->agp_vm_start - 1 + + dev_priv->agp_size) & 0xffff0000) | + (dev_priv->agp_vm_start >> 16)) ); + + ring_start = (dev_priv->cp_ring->offset + - dev->agp->base + + dev_priv->agp_vm_start); + + RADEON_WRITE( RADEON_CP_RB_BASE, ring_start ); + + /* Set the write pointer delay */ + RADEON_WRITE( RADEON_CP_RB_WPTR_DELAY, 0 ); + + /* Initialize the ring buffer's read and write pointers */ + cur_read_ptr = RADEON_READ( RADEON_CP_RB_RPTR ); + RADEON_WRITE( RADEON_CP_RB_WPTR, cur_read_ptr ); + *dev_priv->ring.head = cur_read_ptr; + dev_priv->ring.tail = cur_read_ptr; + + RADEON_WRITE( RADEON_CP_RB_RPTR_ADDR, dev_priv->ring_rptr->offset ); + + /* Set ring buffer size */ + RADEON_WRITE( RADEON_CP_RB_CNTL, dev_priv->ring.size_l2qw ); + + radeon_do_wait_for_idle( dev_priv ); + + /* Turn off PCI GART */ + tmp = RADEON_READ( RADEON_AIC_CNTL ) & ~RADEON_PCIGART_TRANSLATE_EN; + RADEON_WRITE( RADEON_AIC_CNTL, tmp ); + + /* Turn on bus mastering */ + tmp = RADEON_READ( RADEON_BUS_CNTL ) & ~RADEON_BUS_MASTER_DIS; + RADEON_WRITE( RADEON_BUS_CNTL, tmp ); + + /* Sync everything up */ + RADEON_WRITE( RADEON_ISYNC_CNTL, + (RADEON_ISYNC_ANY2D_IDLE3D | + RADEON_ISYNC_ANY3D_IDLE2D | + RADEON_ISYNC_WAIT_IDLEGUI | + RADEON_ISYNC_CPSCRATCH_IDLEGUI) ); +} + +static int radeon_do_init_cp( drm_device_t *dev, drm_radeon_init_t *init ) +{ + drm_radeon_private_t *dev_priv; + int i; + + dev_priv = drm_alloc( sizeof(drm_radeon_private_t), DRM_MEM_DRIVER ); + if ( dev_priv == NULL ) + return -ENOMEM; + dev->dev_private = (void *)dev_priv; + + memset( dev_priv, 0, sizeof(drm_radeon_private_t) ); + + dev_priv->is_pci = init->is_pci; + + /* We don't support PCI cards until PCI GART is implemented. + * Fail here so we can remove all checks for PCI cards around + * the CP ring code. + */ + if ( dev_priv->is_pci ) { + drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER ); + dev->dev_private = NULL; + return -EINVAL; + } + + dev_priv->usec_timeout = init->usec_timeout; + if ( dev_priv->usec_timeout < 1 || + dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT ) { + drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER ); + dev->dev_private = NULL; + return -EINVAL; + } + + dev_priv->cp_mode = init->cp_mode; + + /* Simple idle check. + */ + atomic_set( &dev_priv->idle_count, 0 ); + + /* We don't support anything other than bus-mastering ring mode, + * but the ring can be in either AGP or PCI space for the ring + * read pointer. + */ + if ( ( init->cp_mode != RADEON_CSQ_PRIBM_INDDIS ) && + ( init->cp_mode != RADEON_CSQ_PRIBM_INDBM ) ) { + drm_free( dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER ); + dev->dev_private = NULL; + return -EINVAL; + } + + switch ( init->fb_bpp ) { + case 16: + dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565; + break; + case 32: + default: + dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888; + break; + } + dev_priv->front_offset = init->front_offset; + dev_priv->front_pitch = init->front_pitch; + dev_priv->back_offset = init->back_offset; + dev_priv->back_pitch = init->back_pitch; + + switch ( init->depth_bpp ) { + case 16: + dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z; + break; + case 32: + default: + dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z; + break; + } + dev_priv->depth_offset = init->depth_offset; + dev_priv->depth_pitch = init->depth_pitch; + + dev_priv->front_pitch_offset = (((dev_priv->front_pitch/64) << 22) | + (dev_priv->front_offset >> 10)); + dev_priv->back_pitch_offset = (((dev_priv->back_pitch/64) << 22) | + (dev_priv->back_offset >> 10)); + dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch/64) << 22) | + (dev_priv->depth_offset >> 10)); + + /* Hardware state for depth clears. Remove this if/when we no + * longer clear the depth buffer with a 3D rectangle. Hard-code + * all values to prevent unwanted 3D state from slipping through + * and screwing with the clear operation. + */ + dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE | + RADEON_Z_ENABLE | + (dev_priv->color_fmt << 10) | + RADEON_ZBLOCK16); + + dev_priv->depth_clear.rb3d_zstencilcntl = (dev_priv->depth_fmt | + RADEON_Z_TEST_ALWAYS | + RADEON_STENCIL_TEST_ALWAYS | + RADEON_STENCIL_S_FAIL_KEEP | + RADEON_STENCIL_ZPASS_KEEP | + RADEON_STENCIL_ZFAIL_KEEP | + RADEON_Z_WRITE_ENABLE); + + dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW | + RADEON_BFACE_SOLID | + RADEON_FFACE_SOLID | + RADEON_FLAT_SHADE_VTX_LAST | + + RADEON_DIFFUSE_SHADE_FLAT | + RADEON_ALPHA_SHADE_FLAT | + RADEON_SPECULAR_SHADE_FLAT | + RADEON_FOG_SHADE_FLAT | + + RADEON_VTX_PIX_CENTER_OGL | + RADEON_ROUND_MODE_TRUNC | + RADEON_ROUND_PREC_8TH_PIX); + + /* FIXME: We want multiple shared areas, including one shared + * only by the X Server and kernel module. + */ + for ( i = 0 ; i < dev->map_count ; i++ ) { + if ( dev->maplist[i]->type == _DRM_SHM ) { + dev_priv->sarea = dev->maplist[i]; + break; + } + } + + DO_FIND_MAP( dev_priv->fb, init->fb_offset ); + DO_FIND_MAP( dev_priv->mmio, init->mmio_offset ); + DO_FIND_MAP( dev_priv->cp_ring, init->ring_offset ); + DO_FIND_MAP( dev_priv->ring_rptr, init->ring_rptr_offset ); + DO_FIND_MAP( dev_priv->buffers, init->buffers_offset ); + + if ( !dev_priv->is_pci ) { + DO_FIND_MAP( dev_priv->agp_textures, + init->agp_textures_offset ); + } + + dev_priv->sarea_priv = + (drm_radeon_sarea_t *)((u8 *)dev_priv->sarea->handle + + init->sarea_priv_offset); + + DO_IOREMAP( dev_priv->cp_ring ); + DO_IOREMAP( dev_priv->ring_rptr ); + DO_IOREMAP( dev_priv->buffers ); +#if 0 + if ( !dev_priv->is_pci ) { + DO_IOREMAP( dev_priv->agp_textures ); + } +#endif + + dev_priv->agp_size = init->agp_size; + dev_priv->agp_vm_start = RADEON_READ( RADEON_CONFIG_APER_SIZE ); + dev_priv->agp_buffers_offset = (dev_priv->buffers->offset + - dev->agp->base + + dev_priv->agp_vm_start); + + dev_priv->ring.head = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle); + + dev_priv->ring.start = (u32 *)dev_priv->cp_ring->handle; + dev_priv->ring.end = ((u32 *)dev_priv->cp_ring->handle + + init->ring_size / sizeof(u32)); + dev_priv->ring.size = init->ring_size; + dev_priv->ring.size_l2qw = drm_order( init->ring_size / 8 ); + + dev_priv->ring.tail_mask = + (dev_priv->ring.size / sizeof(u32)) - 1; + +#if 0 + /* Initialize the scratch register pointer. This will cause + * the scratch register values to be written out to memory + * whenever they are updated. + * FIXME: This doesn't quite work yet, so we're disabling it + * for the release. + */ + RADEON_WRITE( RADEON_SCRATCH_ADDR, (dev_priv->ring_rptr->offset + + RADEON_SCRATCH_REG_OFFSET) ); + RADEON_WRITE( RADEON_SCRATCH_UMSK, 0x7 ); +#endif + + dev_priv->scratch = ((__volatile__ u32 *) + dev_priv->ring_rptr->handle + + (RADEON_SCRATCH_REG_OFFSET / sizeof(u32))); + + dev_priv->sarea_priv->last_frame = 0; + RADEON_WRITE( RADEON_LAST_FRAME_REG, + dev_priv->sarea_priv->last_frame ); + + dev_priv->sarea_priv->last_dispatch = 0; + RADEON_WRITE( RADEON_LAST_DISPATCH_REG, + dev_priv->sarea_priv->last_dispatch ); + + dev_priv->sarea_priv->last_clear = 0; + RADEON_WRITE( RADEON_LAST_CLEAR_REG, + dev_priv->sarea_priv->last_clear ); + + radeon_cp_load_microcode( dev_priv ); + radeon_cp_init_ring_buffer( dev ); + radeon_do_engine_reset( dev ); + +#if ROTATE_BUFS + dev_priv->last_buf = 0; +#endif + + return 0; +} + +static int radeon_do_cleanup_cp( drm_device_t *dev ) +{ + if ( dev->dev_private ) { + drm_radeon_private_t *dev_priv = dev->dev_private; + + DO_IOREMAPFREE( dev_priv->cp_ring ); + DO_IOREMAPFREE( dev_priv->ring_rptr ); + DO_IOREMAPFREE( dev_priv->buffers ); +#if 0 + if ( !dev_priv->is_pci ) { + DO_IOREMAPFREE( dev_priv->agp_textures ); + } +#endif + + drm_free( dev->dev_private, sizeof(drm_radeon_private_t), + DRM_MEM_DRIVER ); + dev->dev_private = NULL; + } + + return 0; +} + +int radeon_cp_init( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_init_t init; + + if ( copy_from_user( &init, (drm_radeon_init_t *)arg, sizeof(init) ) ) + return -EFAULT; + + switch ( init.func ) { + case RADEON_INIT_CP: + return radeon_do_init_cp( dev, &init ); + case RADEON_CLEANUP_CP: + return radeon_do_cleanup_cp( dev ); + } + + return -EINVAL; +} + +int radeon_cp_start( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + if ( dev_priv->cp_running ) { + DRM_DEBUG( "%s while CP running\n", __FUNCTION__ ); + return 0; + } + if ( dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS ) { + DRM_DEBUG( "%s called with bogus CP mode (%d)\n", + __FUNCTION__, dev_priv->cp_mode ); + return 0; + } + + radeon_do_cp_start( dev_priv ); + + return 0; +} + +/* Stop the CP. The engine must have been idled before calling this + * routine. + */ +int radeon_cp_stop( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_cp_stop_t stop; + int ret; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &stop, (drm_radeon_init_t *)arg, sizeof(stop) ) ) + return -EFAULT; + + /* Flush any pending CP commands. This ensures any outstanding + * commands are exectuted by the engine before we turn it off. + */ + if ( stop.flush ) { + radeon_do_cp_flush( dev_priv ); + } + + /* If we fail to make the engine go idle, we return an error + * code so that the DRM ioctl wrapper can try again. + */ + if ( stop.idle ) { + ret = radeon_do_cp_idle( dev_priv ); + if ( ret < 0 ) return ret; + } + + /* Finally, we can turn off the CP. If the engine isn't idle, + * we will get some dropped triangles as they won't be fully + * rendered before the CP is shut down. + */ + radeon_do_cp_stop( dev_priv ); + + /* Reset the engine */ + radeon_do_engine_reset( dev ); + + return 0; +} + +/* Just reset the CP ring. Called as part of an X Server engine reset. + */ +int radeon_cp_reset( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + if ( !dev_priv ) { + DRM_DEBUG( "%s called before init done\n", __FUNCTION__ ); + return -EINVAL; + } + + radeon_do_cp_reset( dev_priv ); + + /* The CP is no longer running after an engine reset */ + dev_priv->cp_running = 0; + + return 0; +} + +int radeon_cp_idle( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + return radeon_do_cp_idle( dev_priv ); +} + +int radeon_engine_reset( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + return radeon_do_engine_reset( dev ); +} + + +/* ================================================================ + * Fullscreen mode + */ + +static int radeon_do_init_pageflip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + dev_priv->crtc_offset = RADEON_READ( RADEON_CRTC_OFFSET ); + dev_priv->crtc_offset_cntl = RADEON_READ( RADEON_CRTC_OFFSET_CNTL ); + + RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->front_offset ); + RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, + dev_priv->crtc_offset_cntl | + RADEON_CRTC_OFFSET_FLIP_CNTL ); + + dev_priv->page_flipping = 1; + dev_priv->current_page = 0; + + return 0; +} + +int radeon_do_cleanup_pageflip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + RADEON_WRITE( RADEON_CRTC_OFFSET, dev_priv->crtc_offset ); + RADEON_WRITE( RADEON_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl ); + + dev_priv->page_flipping = 0; + dev_priv->current_page = 0; + + return 0; +} + +int radeon_fullscreen( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_fullscreen_t fs; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &fs, (drm_radeon_fullscreen_t *)arg, + sizeof(fs) ) ) + return -EFAULT; + + switch ( fs.func ) { + case RADEON_INIT_FULLSCREEN: + return radeon_do_init_pageflip( dev ); + case RADEON_CLEANUP_FULLSCREEN: + return radeon_do_cleanup_pageflip( dev ); + } + + return -EINVAL; +} + + +/* ================================================================ + * Freelist management + */ +#define RADEON_BUFFER_USED 0xffffffff +#define RADEON_BUFFER_FREE 0 + +#if 0 +static int radeon_freelist_init( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_buf_t *buf; + drm_radeon_buf_priv_t *buf_priv; + drm_radeon_freelist_t *entry; + int i; + + dev_priv->head = drm_alloc( sizeof(drm_radeon_freelist_t), + DRM_MEM_DRIVER ); + if ( dev_priv->head == NULL ) + return -ENOMEM; + + memset( dev_priv->head, 0, sizeof(drm_radeon_freelist_t) ); + dev_priv->head->age = RADEON_BUFFER_USED; + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + + entry = drm_alloc( sizeof(drm_radeon_freelist_t), + DRM_MEM_DRIVER ); + if ( !entry ) return -ENOMEM; + + entry->age = RADEON_BUFFER_FREE; + entry->buf = buf; + entry->prev = dev_priv->head; + entry->next = dev_priv->head->next; + if ( !entry->next ) + dev_priv->tail = entry; + + buf_priv->discard = 0; + buf_priv->dispatched = 0; + buf_priv->list_entry = entry; + + dev_priv->head->next = entry; + + if ( dev_priv->head->next ) + dev_priv->head->next->prev = entry; + } + + return 0; + +} +#endif + +drm_buf_t *radeon_freelist_get( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_buf_priv_t *buf_priv; + drm_buf_t *buf; + int i, t; +#if ROTATE_BUFS + int start; +#endif + + /* FIXME: Optimize -- use freelist code */ + + for ( i = 0 ; i < dma->buf_count ; i++ ) { + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + if ( buf->pid == 0 ) { + DRM_DEBUG( " ret buf=%d last=%d pid=0\n", + buf->idx, dev_priv->last_buf ); + return buf; + } + DRM_DEBUG( " skipping buf=%d pid=%d\n", + buf->idx, buf->pid ); + } + +#if ROTATE_BUFS + if ( ++dev_priv->last_buf >= dma->buf_count ) + dev_priv->last_buf = 0; + start = dev_priv->last_buf; +#endif + for ( t = 0 ; t < dev_priv->usec_timeout ; t++ ) { +#if 0 + /* FIXME: Disable this for now */ + u32 done_age = dev_priv->scratch[RADEON_LAST_DISPATCH]; +#else + u32 done_age = RADEON_READ( RADEON_LAST_DISPATCH_REG ); +#endif +#if ROTATE_BUFS + for ( i = start ; i < dma->buf_count ; i++ ) { +#else + for ( i = 0 ; i < dma->buf_count ; i++ ) { +#endif + buf = dma->buflist[i]; + buf_priv = buf->dev_private; + if ( buf->pending && buf_priv->age <= done_age ) { + /* The buffer has been processed, so it + * can now be used. + */ + buf->pending = 0; + DRM_DEBUG( " ret buf=%d last=%d age=%d done=%d\n", buf->idx, dev_priv->last_buf, buf_priv->age, done_age ); + return buf; + } + DRM_DEBUG( " skipping buf=%d age=%d done=%d\n", + buf->idx, buf_priv->age, + done_age ); +#if ROTATE_BUFS + start = 0; +#endif + } + udelay( 1 ); + } + + DRM_ERROR( "returning NULL!\n" ); + return NULL; +} + +void radeon_freelist_reset( drm_device_t *dev ) +{ + drm_device_dma_t *dma = dev->dma; +#if ROTATE_BUFS + drm_radeon_private_t *dev_priv = dev->dev_private; +#endif + int i; + +#if ROTATE_BUFS + dev_priv->last_buf = 0; +#endif + for ( i = 0 ; i < dma->buf_count ; i++ ) { + drm_buf_t *buf = dma->buflist[i]; + drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + buf_priv->age = 0; + } +} + + +/* ================================================================ + * CP command submission + */ + +int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ) +{ + drm_radeon_ring_buffer_t *ring = &dev_priv->ring; + int i; + + for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { + ring->space = *ring->head - ring->tail; + if ( ring->space <= 0 ) + ring->space += ring->size; + + if ( ring->space >= n ) + return 0; + + udelay( 1 ); + } + + /* FIXME: This return value is ignored in the BEGIN_RING macro! */ + DRM_ERROR( "failed!\n" ); + return -EBUSY; +} + +void radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_ring_buffer_t *ring = &dev_priv->ring; + + ring->space = *ring->head - ring->tail; + if ( ring->space == 0 ) + atomic_inc( &dev_priv->idle_count ); + if ( ring->space <= 0 ) + ring->space += ring->size; +} + +static int radeon_cp_get_buffers( drm_device_t *dev, drm_dma_t *d ) +{ + int i; + drm_buf_t *buf; + + for ( i = d->granted_count ; i < d->request_count ; i++ ) { + buf = radeon_freelist_get( dev ); + if ( !buf ) return -EAGAIN; + + buf->pid = current->pid; + + if ( copy_to_user( &d->request_indices[i], &buf->idx, + sizeof(buf->idx) ) ) + return -EFAULT; + if ( copy_to_user( &d->request_sizes[i], &buf->total, + sizeof(buf->total) ) ) + return -EFAULT; + + d->granted_count++; + } + return 0; +} + +int radeon_cp_buffers( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_device_dma_t *dma = dev->dma; + int ret = 0; + drm_dma_t d; + + if ( copy_from_user( &d, (drm_dma_t *) arg, sizeof(d) ) ) + return -EFAULT; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + /* Please don't send us buffers. + */ + if ( d.send_count != 0 ) { + DRM_ERROR( "Process %d trying to send %d buffers via drmDMA\n", + current->pid, d.send_count ); + return -EINVAL; + } + + /* We'll send you buffers. + */ + if ( d.request_count < 0 || d.request_count > dma->buf_count ) { + DRM_ERROR( "Process %d trying to get %d buffers (of %d max)\n", + current->pid, d.request_count, dma->buf_count ); + return -EINVAL; + } + + d.granted_count = 0; + + if ( d.request_count ) { + ret = radeon_cp_get_buffers( dev, &d ); + } + + if ( copy_to_user( (drm_dma_t *) arg, &d, sizeof(d) ) ) + return -EFAULT; + + return ret; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h new file mode 100644 index 000000000..c5f9f66d1 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drm.h @@ -0,0 +1,325 @@ +/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*- + * + * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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_DRM_H__ +#define __RADEON_DRM_H__ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the X server file (radeon_sarea.h) + */ +#ifndef __RADEON_SAREA_DEFINES__ +#define __RADEON_SAREA_DEFINES__ + +/* What needs to be changed for the current vertex buffer? + */ +#define RADEON_UPLOAD_CONTEXT 0x00000001 +#define RADEON_UPLOAD_VERTFMT 0x00000002 +#define RADEON_UPLOAD_LINE 0x00000004 +#define RADEON_UPLOAD_BUMPMAP 0x00000008 +#define RADEON_UPLOAD_MASKS 0x00000010 +#define RADEON_UPLOAD_VIEWPORT 0x00000020 +#define RADEON_UPLOAD_SETUP 0x00000040 +#define RADEON_UPLOAD_TCL 0x00000080 +#define RADEON_UPLOAD_MISC 0x00000100 +#define RADEON_UPLOAD_TEX0 0x00000200 +#define RADEON_UPLOAD_TEX1 0x00000400 +#define RADEON_UPLOAD_TEX2 0x00000800 +#define RADEON_UPLOAD_TEX0IMAGES 0x00001000 +#define RADEON_UPLOAD_TEX1IMAGES 0x00002000 +#define RADEON_UPLOAD_TEX2IMAGES 0x00004000 +#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */ +#define RADEON_REQUIRE_QUIESCENCE 0x00010000 +#define RADEON_UPLOAD_ALL 0x0001ffff + +#define RADEON_FRONT 0x1 +#define RADEON_BACK 0x2 +#define RADEON_DEPTH 0x4 + +/* Primitive types + */ +#define RADEON_POINTS 0x1 +#define RADEON_LINES 0x2 +#define RADEON_LINE_STRIP 0x3 +#define RADEON_TRIANGLES 0x4 +#define RADEON_TRIANGLE_FAN 0x5 +#define RADEON_TRIANGLE_STRIP 0x6 + +/* Vertex/indirect buffer size + */ +#define RADEON_BUFFER_SIZE 16384 + +/* Byte offsets for indirect buffer data + */ +#define RADEON_INDEX_PRIM_OFFSET 20 +#define RADEON_HOSTDATA_BLIT_OFFSET 32 + +#define RADEON_SCRATCH_REG_OFFSET 32 + +/* Keep these small for testing + */ +#define RADEON_NR_SAREA_CLIPRECTS 12 + +/* There are 2 heaps (local/AGP). Each region within a heap is a + * minimum of 64k, and there are at most 64 of them per heap. + */ +#define RADEON_LOCAL_TEX_HEAP 0 +#define RADEON_AGP_TEX_HEAP 1 +#define RADEON_NR_TEX_HEAPS 2 +#define RADEON_NR_TEX_REGIONS 64 +#define RADEON_LOG_TEX_GRANULARITY 16 + +#define RADEON_MAX_TEXTURE_LEVELS 11 +#define RADEON_MAX_TEXTURE_UNITS 3 + +#endif /* __RADEON_SAREA_DEFINES__ */ + +typedef struct { + unsigned int red; + unsigned int green; + unsigned int blue; + unsigned int alpha; +} radeon_color_regs_t; + +typedef struct { + /* Context state */ + unsigned int pp_misc; /* 0x1c14 */ + unsigned int pp_fog_color; + unsigned int re_solid_color; + unsigned int rb3d_blendcntl; + unsigned int rb3d_depthoffset; + unsigned int rb3d_depthpitch; + unsigned int rb3d_zstencilcntl; + + unsigned int pp_cntl; /* 0x1c38 */ + unsigned int rb3d_cntl; + unsigned int rb3d_coloroffset; + unsigned int re_width_height; + unsigned int rb3d_colorpitch; + unsigned int se_cntl; + + /* Vertex format state */ + unsigned int se_coord_fmt; /* 0x1c50 */ + + /* Line state */ + unsigned int re_line_pattern; /* 0x1cd0 */ + unsigned int re_line_state; + + unsigned int se_line_width; /* 0x1db8 */ + + /* Bumpmap state */ + unsigned int pp_lum_matrix; /* 0x1d00 */ + + unsigned int pp_rot_matrix_0; /* 0x1d58 */ + unsigned int pp_rot_matrix_1; + + /* Mask state */ + unsigned int rb3d_stencilrefmask; /* 0x1d7c */ + unsigned int rb3d_ropcntl; + unsigned int rb3d_planemask; + + /* Viewport state */ + unsigned int se_vport_xscale; /* 0x1d98 */ + unsigned int se_vport_xoffset; + unsigned int se_vport_yscale; + unsigned int se_vport_yoffset; + unsigned int se_vport_zscale; + unsigned int se_vport_zoffset; + + /* Setup state */ + unsigned int se_cntl_status; /* 0x2140 */ + +#ifdef TCL_ENABLE + /* TCL state */ + radeon_color_regs_t se_tcl_material_emmissive; /* 0x2210 */ + radeon_color_regs_t se_tcl_material_ambient; + radeon_color_regs_t se_tcl_material_diffuse; + radeon_color_regs_t se_tcl_material_specular; + unsigned int se_tcl_shininess; + unsigned int se_tcl_output_vtx_fmt; + unsigned int se_tcl_output_vtx_sel; + unsigned int se_tcl_matrix_select_0; + unsigned int se_tcl_matrix_select_1; + unsigned int se_tcl_ucp_vert_blend_ctl; + unsigned int se_tcl_texture_proc_ctl; + unsigned int se_tcl_light_model_ctl; + unsigned int se_tcl_per_light_ctl[4]; +#endif + + /* Misc state */ + unsigned int re_top_left; /* 0x26c0 */ + unsigned int re_misc; +} drm_radeon_context_regs_t; + +/* Setup registers for each texture unit + */ +typedef struct { + unsigned int pp_txfilter; + unsigned int pp_txformat; + unsigned int pp_txoffset; + unsigned int pp_txcblend; + unsigned int pp_txablend; + unsigned int pp_tfactor; + + unsigned int pp_border_color; + +#ifdef CUBIC_ENABLE + unsigned int pp_cubic_faces; + unsigned int pp_cubic_offset[5]; +#endif +} drm_radeon_texture_regs_t; + +typedef struct { + unsigned char next, prev; + unsigned char in_use; + int age; +} drm_radeon_tex_region_t; + +typedef struct { + /* The channel for communication of state information to the kernel + * on firing a vertex buffer. + */ + drm_radeon_context_regs_t context_state; + drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + + /* The current cliprects, or a subset thereof. + */ + drm_clip_rect_t boxes[RADEON_NR_SAREA_CLIPRECTS]; + unsigned int nbox; + + /* Counters for client-side throttling of rendering clients. + */ + unsigned int last_frame; + unsigned int last_dispatch; + unsigned int last_clear; + + drm_radeon_tex_region_t tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS+1]; + int tex_age[RADEON_NR_TEX_HEAPS]; + int ctx_owner; +} drm_radeon_sarea_t; + + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the Xserver file (xf86drmRadeon.h) + */ +typedef struct drm_radeon_init { + enum { + RADEON_INIT_CP = 0x01, + RADEON_CLEANUP_CP = 0x02 + } func; + int sarea_priv_offset; + int is_pci; + int cp_mode; + int agp_size; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + + unsigned int fb_offset; + unsigned int mmio_offset; + unsigned int ring_offset; + unsigned int ring_rptr_offset; + unsigned int buffers_offset; + unsigned int agp_textures_offset; +} drm_radeon_init_t; + +typedef struct drm_radeon_cp_stop { + int flush; + int idle; +} drm_radeon_cp_stop_t; + +typedef struct drm_radeon_fullscreen { + enum { + RADEON_INIT_FULLSCREEN = 0x01, + RADEON_CLEANUP_FULLSCREEN = 0x02 + } func; +} drm_radeon_fullscreen_t; + +#define CLEAR_X1 0 +#define CLEAR_Y1 1 +#define CLEAR_X2 2 +#define CLEAR_Y2 3 +#define CLEAR_DEPTH 4 + +typedef struct drm_radeon_clear { + unsigned int flags; + int x, y, w, h; + unsigned int clear_color; + unsigned int clear_depth; + union { + float f[5]; + unsigned int ui[5]; + } rect; +} drm_radeon_clear_t; + +typedef struct drm_radeon_vertex { + int prim; + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ +} drm_radeon_vertex_t; + +typedef struct drm_radeon_indices { + int prim; + int idx; + int start; + int end; + int discard; /* Client finished with buffer? */ +} drm_radeon_indices_t; + +typedef struct drm_radeon_blit { + int idx; + int pitch; + int offset; + int format; + unsigned short x, y; + unsigned short width, height; +} drm_radeon_blit_t; + +typedef struct drm_radeon_stipple { + unsigned int *mask; +} drm_radeon_stipple_t; + +typedef struct drm_radeon_indirect { + int idx; + int start; + int end; + int discard; +} drm_radeon_indirect_t; + +#endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c new file mode 100644 index 000000000..0113ed97c --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.c @@ -0,0 +1,702 @@ +/* radeon_drv.c -- ATI Radeon driver -*- linux-c -*- + * + * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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> + * Rickard E. (Rik) Faith <faith@valinux.com> + * + */ + +#include <linux/config.h> +#include "drmP.h" +#include "radeon_drv.h" + +#define RADEON_NAME "radeon" +#define RADEON_DESC "ATI Radeon" +#define RADEON_DATE "20010105" +#define RADEON_MAJOR 1 +#define RADEON_MINOR 0 +#define RADEON_PATCHLEVEL 0 + +static drm_device_t radeon_device; +drm_ctx_t radeon_res_ctx; + +static struct file_operations radeon_fops = { +#if LINUX_VERSION_CODE >= 0x020400 + /* This started being used during 2.4.0-test */ + owner: THIS_MODULE, +#endif + open: radeon_open, + flush: drm_flush, + release: radeon_release, + ioctl: radeon_ioctl, + mmap: drm_mmap, + read: drm_read, + fasync: drm_fasync, + poll: drm_poll, +}; + +static struct miscdevice radeon_misc = { + minor: MISC_DYNAMIC_MINOR, + name: RADEON_NAME, + fops: &radeon_fops, +}; + +static drm_ioctl_desc_t radeon_ioctls[] = { + [DRM_IOCTL_NR(DRM_IOCTL_VERSION)] = { radeon_version, 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE)] = { drm_getunique, 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_MAGIC)] = { drm_getmagic, 0, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_IRQ_BUSID)] = { drm_irq_busid, 0, 1 }, + + [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE)] = { drm_setunique, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_BLOCK)] = { drm_block, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNBLOCK)] = { drm_unblock, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AUTH_MAGIC)] = { drm_authmagic, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP)] = { drm_addmap, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS)] = { radeon_addbufs, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS)] = { drm_markbufs, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS)] = { drm_infobufs, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS)] = { radeon_mapbufs, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS)] = { drm_freebufs, 1, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)] = { radeon_addctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)] = { radeon_rmctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)] = { radeon_modctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)] = { radeon_getctx, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)] = { radeon_switchctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)] = { radeon_newctx, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)] = { radeon_resctx, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_ADD_DRAW)] = { drm_adddraw, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RM_DRAW)] = { drm_rmdraw, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { radeon_cp_buffers, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_LOCK)] = { radeon_lock, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_UNLOCK)] = { radeon_unlock, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_FINISH)] = { drm_finish, 1, 0 }, + +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ACQUIRE)] = { drm_agp_acquire, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_RELEASE)] = { drm_agp_release, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE)] = { drm_agp_enable, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO)] = { drm_agp_info, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC)] = { drm_agp_alloc, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE)] = { drm_agp_free, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND)] = { drm_agp_bind, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND)] = { drm_agp_unbind, 1, 1 }, +#endif + + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_INIT)] = { radeon_cp_init, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_START)] = { radeon_cp_start, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_STOP)] = { radeon_cp_stop, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_RESET)] = { radeon_cp_reset, 1, 1 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CP_IDLE)] = { radeon_cp_idle, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_RESET)] = { radeon_engine_reset, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_FULLSCREEN)] = { radeon_fullscreen, 1, 0 }, + + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_SWAP)] = { radeon_cp_swap, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_CLEAR)] = { radeon_cp_clear, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_VERTEX)] = { radeon_cp_vertex, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDICES)] = { radeon_cp_indices, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_BLIT)] = { radeon_cp_blit, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_STIPPLE)] = { radeon_cp_stipple, 1, 0 }, + [DRM_IOCTL_NR(DRM_IOCTL_RADEON_INDIRECT)]= { radeon_cp_indirect,1, 1 }, +}; +#define RADEON_IOCTL_COUNT DRM_ARRAY_SIZE(radeon_ioctls) + +#ifdef MODULE +static char *radeon = NULL; +#endif + +MODULE_AUTHOR("VA Linux Systems, Inc."); +MODULE_DESCRIPTION("radeon"); +MODULE_PARM(radeon, "s"); + +#ifndef MODULE +/* radeon_options is called by the kernel to parse command-line options + * passed via the boot-loader (e.g., LILO). It calls the insmod option + * routine, drm_parse_drm. + */ + +static int __init radeon_options(char *str) +{ + drm_parse_options(str); + return 1; +} + +__setup("radeon=", radeon_options); +#endif + +static int radeon_setup(drm_device_t *dev) +{ + int i; + + atomic_set(&dev->ioctl_count, 0); + atomic_set(&dev->vma_count, 0); + dev->buf_use = 0; + atomic_set(&dev->buf_alloc, 0); + + drm_dma_setup(dev); + + atomic_set(&dev->total_open, 0); + atomic_set(&dev->total_close, 0); + atomic_set(&dev->total_ioctl, 0); + atomic_set(&dev->total_irq, 0); + atomic_set(&dev->total_ctx, 0); + atomic_set(&dev->total_locks, 0); + atomic_set(&dev->total_unlocks, 0); + atomic_set(&dev->total_contends, 0); + atomic_set(&dev->total_sleeps, 0); + + for (i = 0; i < DRM_HASH_SIZE; i++) { + dev->magiclist[i].head = NULL; + dev->magiclist[i].tail = NULL; + } + dev->maplist = NULL; + dev->map_count = 0; + dev->vmalist = NULL; + dev->lock.hw_lock = NULL; + init_waitqueue_head(&dev->lock.lock_queue); + dev->queue_count = 0; + dev->queue_reserved = 0; + dev->queue_slots = 0; + dev->queuelist = NULL; + dev->irq = 0; + dev->context_flag = 0; + dev->interrupt_flag = 0; + dev->dma_flag = 0; + dev->last_context = 0; + dev->last_switch = 0; + dev->last_checked = 0; + init_timer(&dev->timer); + init_waitqueue_head(&dev->context_wait); + + dev->ctx_start = 0; + dev->lck_start = 0; + + dev->buf_rp = dev->buf; + dev->buf_wp = dev->buf; + dev->buf_end = dev->buf + DRM_BSZ; + dev->buf_async = NULL; + init_waitqueue_head(&dev->buf_readers); + init_waitqueue_head(&dev->buf_writers); + + radeon_res_ctx.handle = -1; + + DRM_DEBUG("\n"); + + /* The kernel's context could be created here, but is now created + in drm_dma_enqueue. This is more resource-efficient for + hardware that does not do DMA, but may mean that + drm_select_queue fails between the time the interrupt is + initialized and the time the queues are initialized. */ + + return 0; +} + + +static int radeon_takedown(drm_device_t *dev) +{ + int i; + drm_magic_entry_t *pt, *next; + drm_map_t *map; + drm_vma_entry_t *vma, *vma_next; + + DRM_DEBUG("\n"); + + down(&dev->struct_sem); + del_timer(&dev->timer); + + if (dev->devname) { + drm_free(dev->devname, strlen(dev->devname)+1, DRM_MEM_DRIVER); + dev->devname = NULL; + } + + if (dev->unique) { + drm_free(dev->unique, strlen(dev->unique)+1, DRM_MEM_DRIVER); + dev->unique = NULL; + dev->unique_len = 0; + } + /* Clear pid list */ + for (i = 0; i < DRM_HASH_SIZE; i++) { + for (pt = dev->magiclist[i].head; pt; pt = next) { + next = pt->next; + drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC); + } + dev->magiclist[i].head = dev->magiclist[i].tail = NULL; + } + +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + /* Clear AGP information */ + if (dev->agp) { + drm_agp_mem_t *entry; + drm_agp_mem_t *nexte; + + /* Remove AGP resources, but leave dev->agp + intact until radeon_cleanup is called. */ + for (entry = dev->agp->memory; entry; entry = nexte) { + nexte = entry->next; + if (entry->bound) drm_unbind_agp(entry->memory); + drm_free_agp(entry->memory, entry->pages); + drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS); + } + dev->agp->memory = NULL; + + if (dev->agp->acquired) _drm_agp_release(); + + dev->agp->acquired = 0; + dev->agp->enabled = 0; + } +#endif + + /* Clear vma list (only built for debugging) */ + if (dev->vmalist) { + for (vma = dev->vmalist; vma; vma = vma_next) { + vma_next = vma->next; + drm_free(vma, sizeof(*vma), DRM_MEM_VMAS); + } + dev->vmalist = NULL; + } + + /* Clear map area and mtrr information */ + if (dev->maplist) { + for (i = 0; i < dev->map_count; i++) { + map = dev->maplist[i]; + switch (map->type) { + case _DRM_REGISTERS: + case _DRM_FRAME_BUFFER: +#ifdef CONFIG_MTRR + if (map->mtrr >= 0) { + int retcode; + retcode = mtrr_del(map->mtrr, + map->offset, + map->size); + DRM_DEBUG("mtrr_del = %d\n", retcode); + } +#endif + drm_ioremapfree(map->handle, map->size); + break; + case _DRM_SHM: + drm_free_pages((unsigned long)map->handle, + drm_order(map->size) + - PAGE_SHIFT, + DRM_MEM_SAREA); + break; + case _DRM_AGP: + /* Do nothing here, because this is all + handled in the AGP/GART driver. */ + break; + } + drm_free(map, sizeof(*map), DRM_MEM_MAPS); + } + drm_free(dev->maplist, + dev->map_count * sizeof(*dev->maplist), + DRM_MEM_MAPS); + dev->maplist = NULL; + dev->map_count = 0; + } + + drm_dma_takedown(dev); + + dev->queue_count = 0; + if (dev->lock.hw_lock) { + dev->lock.hw_lock = NULL; /* SHM removed */ + dev->lock.pid = 0; + wake_up_interruptible(&dev->lock.lock_queue); + } + up(&dev->struct_sem); + + return 0; +} + +/* radeon_init is called via init_module at module load time, or via + * linux/init/main.c (this is not currently supported). */ + +static int __init radeon_init(void) +{ + int retcode; + drm_device_t *dev = &radeon_device; + + DRM_DEBUG("\n"); + + memset((void *)dev, 0, sizeof(*dev)); + dev->count_lock = SPIN_LOCK_UNLOCKED; + sema_init(&dev->struct_sem, 1); + +#ifdef MODULE + drm_parse_options(radeon); +#endif + + if ((retcode = misc_register(&radeon_misc))) { + DRM_ERROR("Cannot register \"%s\"\n", RADEON_NAME); + return retcode; + } + dev->device = MKDEV(MISC_MAJOR, radeon_misc.minor); + dev->name = RADEON_NAME; + + drm_mem_init(); + drm_proc_init(dev); + +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + dev->agp = drm_agp_init(); + if (dev->agp == NULL) { + DRM_ERROR("Cannot initialize agpgart module.\n"); + drm_proc_cleanup(); + misc_deregister(&radeon_misc); + radeon_takedown(dev); + return -ENOMEM; + } + +#ifdef CONFIG_MTRR + dev->agp->agp_mtrr = mtrr_add(dev->agp->agp_info.aper_base, + dev->agp->agp_info.aper_size*1024*1024, + MTRR_TYPE_WRCOMB, + 1); +#endif +#endif + + if((retcode = drm_ctxbitmap_init(dev))) { + DRM_ERROR("Cannot allocate memory for context bitmap.\n"); + drm_proc_cleanup(); + misc_deregister(&radeon_misc); + radeon_takedown(dev); + return retcode; + } + + DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n", + RADEON_NAME, + RADEON_MAJOR, + RADEON_MINOR, + RADEON_PATCHLEVEL, + RADEON_DATE, + radeon_misc.minor); + + return 0; +} + +/* radeon_cleanup is called via cleanup_module at module unload time. */ + +static void __exit radeon_cleanup(void) +{ + drm_device_t *dev = &radeon_device; + + DRM_DEBUG("\n"); + + drm_proc_cleanup(); + if (misc_deregister(&radeon_misc)) { + DRM_ERROR("Cannot unload module\n"); + } else { + DRM_INFO("Module unloaded\n"); + } + drm_ctxbitmap_cleanup(dev); + radeon_takedown(dev); +#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE) + if (dev->agp) { + drm_agp_uninit(); + drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS); + dev->agp = NULL; + } +#endif +} + +module_init(radeon_init); +module_exit(radeon_cleanup); + + +int radeon_version(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_version_t version; + int len; + + if (copy_from_user(&version, + (drm_version_t *)arg, + sizeof(version))) + return -EFAULT; + +#define DRM_COPY(name,value) \ + len = strlen(value); \ + if (len > name##_len) len = name##_len; \ + name##_len = strlen(value); \ + if (len && name) { \ + if (copy_to_user(name, value, len)) \ + return -EFAULT; \ + } + + version.version_major = RADEON_MAJOR; + version.version_minor = RADEON_MINOR; + version.version_patchlevel = RADEON_PATCHLEVEL; + + DRM_COPY(version.name, RADEON_NAME); + DRM_COPY(version.date, RADEON_DATE); + DRM_COPY(version.desc, RADEON_DESC); + + if (copy_to_user((drm_version_t *)arg, + &version, + sizeof(version))) + return -EFAULT; + return 0; +} + +int radeon_open(struct inode *inode, struct file *filp) +{ + drm_device_t *dev = &radeon_device; + int retcode = 0; + + DRM_DEBUG("open_count = %d\n", dev->open_count); + if (!(retcode = drm_open_helper(inode, filp, dev))) { +#if LINUX_VERSION_CODE < 0x020333 + MOD_INC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif + atomic_inc(&dev->total_open); + spin_lock(&dev->count_lock); + if (!dev->open_count++) { + spin_unlock(&dev->count_lock); + return radeon_setup(dev); + } + spin_unlock(&dev->count_lock); + } + + return retcode; +} + +int radeon_release(struct inode *inode, struct file *filp) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev; + int retcode = 0; + + lock_kernel(); + dev = priv->dev; + + DRM_DEBUG("open_count = %d\n", dev->open_count); + + /* Force the cleanup of page flipping when required */ + if ( dev->dev_private ) { + drm_radeon_private_t *dev_priv = dev->dev_private; + if ( dev_priv->page_flipping ) { + radeon_do_cleanup_pageflip( dev ); + } + } + + if (!(retcode = drm_release(inode, filp))) { +#if LINUX_VERSION_CODE < 0x020333 + MOD_DEC_USE_COUNT; /* Needed before Linux 2.3.51 */ +#endif + atomic_inc(&dev->total_close); + spin_lock(&dev->count_lock); + if (!--dev->open_count) { + if (atomic_read(&dev->ioctl_count) || dev->blocked) { + DRM_ERROR("Device busy: %d %d\n", + atomic_read(&dev->ioctl_count), + dev->blocked); + spin_unlock(&dev->count_lock); + unlock_kernel(); + return -EBUSY; + } + spin_unlock(&dev->count_lock); + unlock_kernel(); + return radeon_takedown(dev); + } + spin_unlock(&dev->count_lock); + } + + unlock_kernel(); + return retcode; +} + +/* radeon_ioctl is called whenever a process performs an ioctl on /dev/drm. */ + +int radeon_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + int nr = DRM_IOCTL_NR(cmd); + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + int retcode = 0; + drm_ioctl_desc_t *ioctl; + drm_ioctl_t *func; + + atomic_inc(&dev->ioctl_count); + atomic_inc(&dev->total_ioctl); + ++priv->ioctl_count; + + DRM_DEBUG("pid = %d, cmd = 0x%02x, nr = 0x%02x, dev 0x%x, auth = %d\n", + current->pid, cmd, nr, dev->device, priv->authenticated); + + if (nr >= RADEON_IOCTL_COUNT) { + retcode = -EINVAL; + } else { + ioctl = &radeon_ioctls[nr]; + func = ioctl->func; + + if (!func) { + DRM_DEBUG("no function\n"); + retcode = -EINVAL; + } else if ((ioctl->root_only && !capable(CAP_SYS_ADMIN)) + || (ioctl->auth_needed && !priv->authenticated)) { + retcode = -EACCES; + } else { + retcode = (func)(inode, filp, cmd, arg); + } + } + + atomic_dec(&dev->ioctl_count); + return retcode; +} + +int radeon_lock(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + DECLARE_WAITQUEUE(entry, current); + int ret = 0; + drm_lock_t lock; +#if DRM_DMA_HISTOGRAM + cycles_t start; + + dev->lck_start = start = get_cycles(); +#endif + + if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) + return -EFAULT; + + if (lock.context == DRM_KERNEL_CONTEXT) { + DRM_ERROR("Process %d using kernel context %d\n", + current->pid, lock.context); + return -EINVAL; + } + + DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n", + lock.context, current->pid, dev->lock.hw_lock->lock, + lock.flags); + + if (lock.context < 0 /* || lock.context >= dev->queue_count */) + return -EINVAL; + + if (!ret) { + add_wait_queue(&dev->lock.lock_queue, &entry); + for (;;) { + current->state = TASK_INTERRUPTIBLE; + if (!dev->lock.hw_lock) { + /* Device has been unregistered */ + ret = -EINTR; + break; + } + if (drm_lock_take(&dev->lock.hw_lock->lock, + lock.context)) { + dev->lock.pid = current->pid; + dev->lock.lock_time = jiffies; + atomic_inc(&dev->total_locks); + break; /* Got lock */ + } + + /* Contention */ + atomic_inc(&dev->total_sleeps); + schedule(); + if (signal_pending(current)) { + ret = -ERESTARTSYS; + break; + } + } + current->state = TASK_RUNNING; + remove_wait_queue(&dev->lock.lock_queue, &entry); + } + + if (!ret) { + sigemptyset(&dev->sigmask); + sigaddset(&dev->sigmask, SIGSTOP); + sigaddset(&dev->sigmask, SIGTSTP); + sigaddset(&dev->sigmask, SIGTTIN); + sigaddset(&dev->sigmask, SIGTTOU); + dev->sigdata.context = lock.context; + dev->sigdata.lock = dev->lock.hw_lock; + block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask); + if (lock.flags & _DRM_LOCK_READY) { + /* Wait for space in DMA/FIFO */ + } + if (lock.flags & _DRM_LOCK_QUIESCENT) { + /* Make hardware quiescent */ + DRM_DEBUG("not quiescent!\n"); +#if 0 + radeon_quiescent(dev); +#endif + } + } + +#if LINUX_VERSION_CODE < 0x020400 + if (lock.context != radeon_res_ctx.handle) { + current->counter = 5; + current->priority = DEF_PRIORITY/4; + } +#endif + DRM_DEBUG("%d %s\n", lock.context, ret ? "interrupted" : "has lock"); + +#if DRM_DMA_HISTOGRAM + atomic_inc(&dev->histo.lacq[drm_histogram_slot(get_cycles() - start)]); +#endif + + return ret; +} + + +int radeon_unlock(struct inode *inode, struct file *filp, unsigned int cmd, + unsigned long arg) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_lock_t lock; + + if (copy_from_user(&lock, (drm_lock_t *)arg, sizeof(lock))) + return -EFAULT; + + if (lock.context == DRM_KERNEL_CONTEXT) { + DRM_ERROR("Process %d using kernel context %d\n", + current->pid, lock.context); + return -EINVAL; + } + + DRM_DEBUG("%d frees lock (%d holds)\n", + lock.context, + _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock)); + atomic_inc(&dev->total_unlocks); + if (_DRM_LOCK_IS_CONT(dev->lock.hw_lock->lock)) + atomic_inc(&dev->total_contends); + drm_lock_transfer(dev, &dev->lock.hw_lock->lock, DRM_KERNEL_CONTEXT); + /* FIXME: Try to send data to card here */ + if (!dev->context_flag) { + if (drm_lock_free(dev, &dev->lock.hw_lock->lock, + DRM_KERNEL_CONTEXT)) { + DRM_ERROR("\n"); + } + } + +#if LINUX_VERSION_CODE < 0x020400 + if (lock.context != radeon_res_ctx.handle) { + current->counter = 5; + current->priority = DEF_PRIORITY; + } +#endif + unblock_all_signals(); + return 0; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h new file mode 100644 index 000000000..06b541991 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_drv.h @@ -0,0 +1,709 @@ +/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*- + * + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2000 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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: + * Rickard E. (Rik) Faith <faith@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * Gareth Hughes <gareth@valinux.com> + * + */ + +#ifndef __RADEON_DRV_H__ +#define __RADEON_DRV_H__ + +typedef struct drm_radeon_freelist { + unsigned int age; + drm_buf_t *buf; + struct drm_radeon_freelist *next; + struct drm_radeon_freelist *prev; +} drm_radeon_freelist_t; + +typedef struct drm_radeon_ring_buffer { + u32 *start; + u32 *end; + int size; + int size_l2qw; + + volatile u32 *head; + u32 tail; + u32 tail_mask; + int space; +} drm_radeon_ring_buffer_t; + +typedef struct drm_radeon_depth_clear_t { + u32 rb3d_cntl; + u32 rb3d_zstencilcntl; + u32 se_cntl; +} drm_radeon_depth_clear_t; + +typedef struct drm_radeon_private { + drm_radeon_ring_buffer_t ring; + drm_radeon_sarea_t *sarea_priv; + + int agp_size; + u32 agp_vm_start; + u32 agp_buffers_offset; + + int cp_mode; + int cp_running; + + drm_radeon_freelist_t *head; + drm_radeon_freelist_t *tail; +/* FIXME: ROTATE_BUFS is a hask to cycle through bufs until freelist + code is used. Note this hides a problem with the scratch register + (used to keep track of last buffer completed) being written to before + the last buffer has actually completed rendering. */ +#define ROTATE_BUFS 1 +#if ROTATE_BUFS + int last_buf; +#endif + volatile u32 *scratch; + + int usec_timeout; + int is_pci; + + atomic_t idle_count; + + int page_flipping; + int current_page; + u32 crtc_offset; + u32 crtc_offset_cntl; + + unsigned int color_fmt; + unsigned int front_offset; + unsigned int front_pitch; + unsigned int back_offset; + unsigned int back_pitch; + + unsigned int depth_fmt; + unsigned int depth_offset; + unsigned int depth_pitch; + + u32 front_pitch_offset; + u32 back_pitch_offset; + u32 depth_pitch_offset; + + drm_radeon_depth_clear_t depth_clear; + + drm_map_t *sarea; + drm_map_t *fb; + drm_map_t *mmio; + drm_map_t *cp_ring; + drm_map_t *ring_rptr; + drm_map_t *buffers; + drm_map_t *agp_textures; +} drm_radeon_private_t; + +typedef struct drm_radeon_buf_priv { + u32 age; + int prim; + int discard; + int dispatched; + drm_radeon_freelist_t *list_entry; +} drm_radeon_buf_priv_t; + + /* radeon_drv.c */ +extern int radeon_version( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_open( struct inode *inode, struct file *filp ); +extern int radeon_release( struct inode *inode, struct file *filp ); +extern int radeon_ioctl( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_lock( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_unlock( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + + /* radeon_cp.c */ +extern int radeon_cp_init( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_start( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_stop( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_reset( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_idle( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_engine_reset( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_fullscreen( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_buffers( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + +extern void radeon_freelist_reset( drm_device_t *dev ); +extern drm_buf_t *radeon_freelist_get( drm_device_t *dev ); + +extern int radeon_wait_ring( drm_radeon_private_t *dev_priv, int n ); +extern void radeon_update_ring_snapshot( drm_radeon_private_t *dev_priv ); + +extern int radeon_do_cp_idle( drm_radeon_private_t *dev_priv ); +extern int radeon_do_cleanup_pageflip( drm_device_t *dev ); + + /* radeon_state.c */ +extern int radeon_cp_clear( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_swap( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_vertex( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_indices( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_blit( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_stipple( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); +extern int radeon_cp_indirect( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ); + + /* radeon_bufs.c */ +extern int radeon_addbufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int radeon_mapbufs(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + + /* radeon_context.c */ +extern int radeon_resctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int radeon_addctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int radeon_modctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int radeon_getctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int radeon_switchctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int radeon_newctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); +extern int radeon_rmctx(struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg); + +extern int radeon_context_switch(drm_device_t *dev, int old, int new); +extern int radeon_context_switch_complete(drm_device_t *dev, int new); + + +/* Register definitions, register access macros and drmAddMap constants + * for Radeon kernel driver. + */ + +#define RADEON_AUX_SCISSOR_CNTL 0x26f0 +# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24) +# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25) +# define RADEON_EXCLUSIVE_SCISSOR_2 (1 << 26) +# define RADEON_SCISSOR_0_ENABLE (1 << 28) +# define RADEON_SCISSOR_1_ENABLE (1 << 29) +# define RADEON_SCISSOR_2_ENABLE (1 << 30) + +#define RADEON_BUS_CNTL 0x0030 +# define RADEON_BUS_MASTER_DIS (1 << 6) + +#define RADEON_CLOCK_CNTL_DATA 0x000c +# define RADEON_PLL_WR_EN (1 << 7) +#define RADEON_CLOCK_CNTL_INDEX 0x0008 +#define RADEON_CONFIG_APER_SIZE 0x0108 +#define RADEON_CRTC_OFFSET 0x0224 +#define RADEON_CRTC_OFFSET_CNTL 0x0228 +# define RADEON_CRTC_TILE_EN (1 << 15) +# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16) + +#define RADEON_RB3D_COLORPITCH 0x1c48 +#define RADEON_RB3D_DEPTHCLEARVALUE 0x1c30 +#define RADEON_RB3D_DEPTHXY_OFFSET 0x1c60 + +#define RADEON_DP_GUI_MASTER_CNTL 0x146c +# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define RADEON_GMC_BRUSH_NONE (15 << 4) +# define RADEON_GMC_DST_16BPP (4 << 8) +# define RADEON_GMC_DST_24BPP (5 << 8) +# define RADEON_GMC_DST_32BPP (6 << 8) +# define RADEON_GMC_DST_DATATYPE_SHIFT 8 +# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24) +# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define RADEON_GMC_WR_MSK_DIS (1 << 30) +# define RADEON_ROP3_S 0x00cc0000 +# define RADEON_ROP3_P 0x00f00000 +#define RADEON_DP_WRITE_MASK 0x16cc +#define RADEON_DST_PITCH_OFFSET 0x142c +#define RADEON_DST_PITCH_OFFSET_C 0x1c80 +# define RADEON_DST_TILE_LINEAR (0 << 30) +# define RADEON_DST_TILE_MACRO (1 << 30) +# define RADEON_DST_TILE_MICRO (2 << 30) +# define RADEON_DST_TILE_BOTH (3 << 30) + +#define RADEON_SCRATCH_REG0 0x15e0 +#define RADEON_SCRATCH_REG1 0x15e4 +#define RADEON_SCRATCH_REG2 0x15e8 +#define RADEON_SCRATCH_REG3 0x15ec +#define RADEON_SCRATCH_REG4 0x15f0 +#define RADEON_SCRATCH_REG5 0x15f4 +#define RADEON_SCRATCH_UMSK 0x0770 +#define RADEON_SCRATCH_ADDR 0x0774 + +#define RADEON_HOST_PATH_CNTL 0x0130 +# define RADEON_HDP_SOFT_RESET (1 << 26) +# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28) +# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28) + +#define RADEON_ISYNC_CNTL 0x1724 +# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0) +# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1) +# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2) +# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3) +# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4) +# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5) + +#define RADEON_MC_AGP_LOCATION 0x014c +#define RADEON_MC_FB_LOCATION 0x0148 +#define RADEON_MCLK_CNTL 0x0012 + +#define RADEON_PP_BORDER_COLOR_0 0x1d40 +#define RADEON_PP_BORDER_COLOR_1 0x1d44 +#define RADEON_PP_BORDER_COLOR_2 0x1d48 +#define RADEON_PP_CNTL 0x1c38 +# define RADEON_SCISSOR_ENABLE (1 << 1) +#define RADEON_PP_LUM_MATRIX 0x1d00 +#define RADEON_PP_MISC 0x1c14 +#define RADEON_PP_ROT_MATRIX_0 0x1d58 +#define RADEON_PP_TXFILTER_0 0x1c54 +#define RADEON_PP_TXFILTER_1 0x1c6c +#define RADEON_PP_TXFILTER_2 0x1c84 + +#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c +# define RADEON_RB2D_DC_FLUSH (3 << 0) +# define RADEON_RB2D_DC_FREE (3 << 2) +# define RADEON_RB2D_DC_FLUSH_ALL 0xf +# define RADEON_RB2D_DC_BUSY (1 << 31) +#define RADEON_RB3D_CNTL 0x1c3c +# define RADEON_ALPHA_BLEND_ENABLE (1 << 0) +# define RADEON_PLANE_MASK_ENABLE (1 << 1) +# define RADEON_DITHER_ENABLE (1 << 2) +# define RADEON_ROUND_ENABLE (1 << 3) +# define RADEON_SCALE_DITHER_ENABLE (1 << 4) +# define RADEON_DITHER_INIT (1 << 5) +# define RADEON_ROP_ENABLE (1 << 6) +# define RADEON_STENCIL_ENABLE (1 << 7) +# define RADEON_Z_ENABLE (1 << 8) +# define RADEON_DEPTH_XZ_OFFEST_ENABLE (1 << 9) +# define RADEON_ZBLOCK8 (0 << 15) +# define RADEON_ZBLOCK16 (1 << 15) +#define RADEON_RB3D_DEPTHOFFSET 0x1c24 +#define RADEON_RB3D_PLANEMASK 0x1d84 +#define RADEON_RB3D_STENCILREFMASK 0x1d7c +#define RADEON_RB3D_ZCACHE_MODE 0x3250 +#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254 +# define RADEON_RB3D_ZC_FLUSH (1 << 0) +# define RADEON_RB3D_ZC_FREE (1 << 2) +# define RADEON_RB3D_ZC_FLUSH_ALL 0x5 +# define RADEON_RB3D_ZC_BUSY (1 << 31) +#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c +# define RADEON_Z_TEST_MASK (7 << 4) +# define RADEON_Z_TEST_ALWAYS (7 << 4) +# define RADEON_STENCIL_TEST_ALWAYS (7 << 12) +# define RADEON_STENCIL_S_FAIL_KEEP (0 << 16) +# define RADEON_STENCIL_ZPASS_KEEP (0 << 20) +# define RADEON_STENCIL_ZFAIL_KEEP (0 << 20) +# define RADEON_Z_WRITE_ENABLE (1 << 30) +#define RADEON_RBBM_SOFT_RESET 0x00f0 +# define RADEON_SOFT_RESET_CP (1 << 0) +# define RADEON_SOFT_RESET_HI (1 << 1) +# define RADEON_SOFT_RESET_SE (1 << 2) +# define RADEON_SOFT_RESET_RE (1 << 3) +# define RADEON_SOFT_RESET_PP (1 << 4) +# define RADEON_SOFT_RESET_E2 (1 << 5) +# define RADEON_SOFT_RESET_RB (1 << 6) +# define RADEON_SOFT_RESET_HDP (1 << 7) +#define RADEON_RBBM_STATUS 0x0e40 +# define RADEON_RBBM_FIFOCNT_MASK 0x007f +# define RADEON_RBBM_ACTIVE (1 << 31) +#define RADEON_RE_LINE_PATTERN 0x1cd0 +#define RADEON_RE_MISC 0x26c4 +#define RADEON_RE_TOP_LEFT 0x26c0 +#define RADEON_RE_WIDTH_HEIGHT 0x1c44 +#define RADEON_RE_STIPPLE_ADDR 0x1cc8 +#define RADEON_RE_STIPPLE_DATA 0x1ccc + +#define RADEON_SCISSOR_TL_0 0x1cd8 +#define RADEON_SCISSOR_BR_0 0x1cdc +#define RADEON_SCISSOR_TL_1 0x1ce0 +#define RADEON_SCISSOR_BR_1 0x1ce4 +#define RADEON_SCISSOR_TL_2 0x1ce8 +#define RADEON_SCISSOR_BR_2 0x1cec +#define RADEON_SE_COORD_FMT 0x1c50 +#define RADEON_SE_CNTL 0x1c4c +# define RADEON_FFACE_CULL_CW (0 << 0) +# define RADEON_BFACE_SOLID (3 << 1) +# define RADEON_FFACE_SOLID (3 << 3) +# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6) +# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8) +# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8) +# define RADEON_ALPHA_SHADE_FLAT (1 << 10) +# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10) +# define RADEON_SPECULAR_SHADE_FLAT (1 << 12) +# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12) +# define RADEON_FOG_SHADE_FLAT (1 << 14) +# define RADEON_FOG_SHADE_GOURAUD (2 << 14) +# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24) +# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25) +# define RADEON_VTX_PIX_CENTER_OGL (1 << 27) +# define RADEON_ROUND_MODE_TRUNC (0 << 28) +# define RADEON_ROUND_PREC_8TH_PIX (1 << 30) +#define RADEON_SE_CNTL_STATUS 0x2140 +#define RADEON_SE_LINE_WIDTH 0x1db8 +#define RADEON_SE_VPORT_XSCALE 0x1d98 +#define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8 +#define RADEON_SURFACE_ACCESS_CLR 0x0bfc +#define RADEON_SURFACE_CNTL 0x0b00 +# define RADEON_SURF_TRANSLATION_DIS (1 << 8) +# define RADEON_NONSURF_AP0_SWP_MASK (3 << 20) +# define RADEON_NONSURF_AP0_SWP_LITTLE (0 << 20) +# define RADEON_NONSURF_AP0_SWP_BIG16 (1 << 20) +# define RADEON_NONSURF_AP0_SWP_BIG32 (2 << 20) +# define RADEON_NONSURF_AP1_SWP_MASK (3 << 22) +# define RADEON_NONSURF_AP1_SWP_LITTLE (0 << 22) +# define RADEON_NONSURF_AP1_SWP_BIG16 (1 << 22) +# define RADEON_NONSURF_AP1_SWP_BIG32 (2 << 22) +#define RADEON_SURFACE0_INFO 0x0b0c +# define RADEON_SURF_PITCHSEL_MASK (0x1ff << 0) +# define RADEON_SURF_TILE_MODE_MASK (3 << 16) +# define RADEON_SURF_TILE_MODE_MACRO (0 << 16) +# define RADEON_SURF_TILE_MODE_MICRO (1 << 16) +# define RADEON_SURF_TILE_MODE_32BIT_Z (2 << 16) +# define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16) +#define RADEON_SURFACE0_LOWER_BOUND 0x0b04 +#define RADEON_SURFACE0_UPPER_BOUND 0x0b08 +#define RADEON_SURFACE1_INFO 0x0b1c +#define RADEON_SURFACE1_LOWER_BOUND 0x0b14 +#define RADEON_SURFACE1_UPPER_BOUND 0x0b18 +#define RADEON_SURFACE2_INFO 0x0b2c +#define RADEON_SURFACE2_LOWER_BOUND 0x0b24 +#define RADEON_SURFACE2_UPPER_BOUND 0x0b28 +#define RADEON_SURFACE3_INFO 0x0b3c +#define RADEON_SURFACE3_LOWER_BOUND 0x0b34 +#define RADEON_SURFACE3_UPPER_BOUND 0x0b38 +#define RADEON_SURFACE4_INFO 0x0b4c +#define RADEON_SURFACE4_LOWER_BOUND 0x0b44 +#define RADEON_SURFACE4_UPPER_BOUND 0x0b48 +#define RADEON_SURFACE5_INFO 0x0b5c +#define RADEON_SURFACE5_LOWER_BOUND 0x0b54 +#define RADEON_SURFACE5_UPPER_BOUND 0x0b58 +#define RADEON_SURFACE6_INFO 0x0b6c +#define RADEON_SURFACE6_LOWER_BOUND 0x0b64 +#define RADEON_SURFACE6_UPPER_BOUND 0x0b68 +#define RADEON_SURFACE7_INFO 0x0b7c +#define RADEON_SURFACE7_LOWER_BOUND 0x0b74 +#define RADEON_SURFACE7_UPPER_BOUND 0x0b78 +#define RADEON_SW_SEMAPHORE 0x013c + +#define RADEON_WAIT_UNTIL 0x1720 +# define RADEON_WAIT_CRTC_PFLIP (1 << 0) +# define RADEON_WAIT_2D_IDLECLEAN (1 << 16) +# define RADEON_WAIT_3D_IDLECLEAN (1 << 17) +# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18) + +#define RADEON_RB3D_ZMASKOFFSET 0x1c34 +#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c +# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0) +# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0) + + +/* CP registers */ +#define RADEON_CP_ME_RAM_ADDR 0x07d4 +#define RADEON_CP_ME_RAM_RADDR 0x07d8 +#define RADEON_CP_ME_RAM_DATAH 0x07dc +#define RADEON_CP_ME_RAM_DATAL 0x07e0 + +#define RADEON_CP_RB_BASE 0x0700 +#define RADEON_CP_RB_CNTL 0x0704 +#define RADEON_CP_RB_RPTR_ADDR 0x070c +#define RADEON_CP_RB_RPTR 0x0710 +#define RADEON_CP_RB_WPTR 0x0714 + +#define RADEON_CP_RB_WPTR_DELAY 0x0718 +# define RADEON_PRE_WRITE_TIMER_SHIFT 0 +# define RADEON_PRE_WRITE_LIMIT_SHIFT 23 + +#define RADEON_CP_IB_BASE 0x0738 + +#define RADEON_CP_CSQ_CNTL 0x0740 +# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0) +# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28) +# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28) +# define RADEON_CSQ_PRIBM_INDDIS (2 << 28) +# define RADEON_CSQ_PRIPIO_INDBM (3 << 28) +# define RADEON_CSQ_PRIBM_INDBM (4 << 28) +# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28) + +#define RADEON_AIC_CNTL 0x01d0 +# define RADEON_PCIGART_TRANSLATE_EN (1 << 0) + +/* CP command packets */ +#define RADEON_CP_PACKET0 0x00000000 +# define RADEON_ONE_REG_WR (1 << 15) +#define RADEON_CP_PACKET1 0x40000000 +#define RADEON_CP_PACKET2 0x80000000 +#define RADEON_CP_PACKET3 0xC0000000 +# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300 +# define RADEON_WAIT_FOR_IDLE 0x00002600 +# define RADEON_3D_DRAW_IMMD 0x00002900 +# define RADEON_3D_CLEAR_ZMASK 0x00003200 +# define RADEON_CNTL_HOSTDATA_BLT 0x00009400 +# define RADEON_CNTL_PAINT_MULTI 0x00009A00 +# define RADEON_CNTL_BITBLT_MULTI 0x00009B00 + +#define RADEON_CP_PACKET_MASK 0xC0000000 +#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000 +#define RADEON_CP_PACKET0_REG_MASK 0x000007ff +#define RADEON_CP_PACKET1_REG0_MASK 0x000007ff +#define RADEON_CP_PACKET1_REG1_MASK 0x003ff800 + +#define RADEON_VTX_Z_PRESENT (1 << 31) + +#define RADEON_PRIM_TYPE_NONE (0 << 0) +#define RADEON_PRIM_TYPE_POINT (1 << 0) +#define RADEON_PRIM_TYPE_LINE (2 << 0) +#define RADEON_PRIM_TYPE_LINE_STRIP (3 << 0) +#define RADEON_PRIM_TYPE_TRI_LIST (4 << 0) +#define RADEON_PRIM_TYPE_TRI_FAN (5 << 0) +#define RADEON_PRIM_TYPE_TRI_STRIP (6 << 0) +#define RADEON_PRIM_TYPE_TRI_TYPE2 (7 << 0) +#define RADEON_PRIM_TYPE_RECT_LIST (8 << 0) +#define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0) +#define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0) +#define RADEON_PRIM_WALK_IND (1 << 4) +#define RADEON_PRIM_WALK_LIST (2 << 4) +#define RADEON_PRIM_WALK_RING (3 << 4) +#define RADEON_COLOR_ORDER_BGRA (0 << 6) +#define RADEON_COLOR_ORDER_RGBA (1 << 6) +#define RADEON_MAOS_ENABLE (1 << 7) +#define RADEON_VTX_FMT_R128_MODE (0 << 8) +#define RADEON_VTX_FMT_RADEON_MODE (1 << 8) +#define RADEON_NUM_VERTICES_SHIFT 16 + +#define RADEON_COLOR_FORMAT_CI8 2 +#define RADEON_COLOR_FORMAT_ARGB1555 3 +#define RADEON_COLOR_FORMAT_RGB565 4 +#define RADEON_COLOR_FORMAT_ARGB8888 6 +#define RADEON_COLOR_FORMAT_RGB332 7 +#define RADEON_COLOR_FORMAT_RGB8 9 +#define RADEON_COLOR_FORMAT_ARGB4444 15 + +#define RADEON_TXF_8BPP_I 0 +#define RADEON_TXF_16BPP_AI88 1 +#define RADEON_TXF_8BPP_RGB332 2 +#define RADEON_TXF_16BPP_ARGB1555 3 +#define RADEON_TXF_16BPP_RGB565 4 +#define RADEON_TXF_16BPP_ARGB4444 5 +#define RADEON_TXF_32BPP_ARGB8888 6 +#define RADEON_TXF_32BPP_RGBA8888 7 + +/* Constants */ +#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */ + +#define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0 +#define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1 +#define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2 +#define RADEON_LAST_DISPATCH 1 + +#define RADEON_MAX_VB_AGE 0x7fffffff +#define RADEON_MAX_VB_VERTS (0xffff) + + +#define RADEON_BASE(reg) ((u32)(dev_priv->mmio->handle)) +#define RADEON_ADDR(reg) (RADEON_BASE(reg) + reg) + +#define RADEON_DEREF(reg) *(__volatile__ u32 *)RADEON_ADDR(reg) +#define RADEON_READ(reg) RADEON_DEREF(reg) +#define RADEON_WRITE(reg,val) do { RADEON_DEREF(reg) = val; } while (0) + +#define RADEON_DEREF8(reg) *(__volatile__ u8 *)RADEON_ADDR(reg) +#define RADEON_READ8(reg) RADEON_DEREF8(reg) +#define RADEON_WRITE8(reg,val) do { RADEON_DEREF8(reg) = val; } while (0) + +#define RADEON_WRITE_PLL(addr,val) \ +do { \ + RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, \ + ((addr) & 0x1f) | RADEON_PLL_WR_EN); \ + RADEON_WRITE(RADEON_CLOCK_CNTL_DATA, (val)); \ +} while (0) + +extern int RADEON_READ_PLL(drm_device_t *dev, int addr); + + + +#define CP_PACKET0( reg, n ) \ + (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2)) +#define CP_PACKET0_TABLE( reg, n ) \ + (RADEON_CP_PACKET0 | RADEON_ONE_REG_WR | ((n) << 16) | ((reg) >> 2)) +#define CP_PACKET1( reg0, reg1 ) \ + (RADEON_CP_PACKET1 | (((reg1) >> 2) << 15) | ((reg0) >> 2)) +#define CP_PACKET2() \ + (RADEON_CP_PACKET2) +#define CP_PACKET3( pkt, n ) \ + (RADEON_CP_PACKET3 | (pkt) | ((n) << 16)) + + +/* ================================================================ + * Engine control helper macros + */ + +#define RADEON_WAIT_UNTIL_2D_IDLE() \ +do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ +} while (0) + +#define RADEON_WAIT_UNTIL_3D_IDLE() \ +do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ +} while (0) + +#define RADEON_WAIT_UNTIL_IDLE() \ +do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \ + RADEON_WAIT_3D_IDLECLEAN | \ + RADEON_WAIT_HOST_IDLECLEAN) ); \ +} while (0) + +#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() \ +do { \ + OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \ + OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \ +} while (0) + +#define RADEON_FLUSH_CACHE() \ +do { \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH ); \ +} while (0) + +#define RADEON_PURGE_CACHE() \ +do { \ + OUT_RING( CP_PACKET0( RADEON_RB2D_DSTCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB2D_DC_FLUSH_ALL ); \ +} while (0) + +#define RADEON_FLUSH_ZCACHE() \ +do { \ + OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB3D_ZC_FLUSH ); \ +} while (0) + +#define RADEON_PURGE_ZCACHE() \ +do { \ + OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \ + OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \ +} while (0) + + +/* ================================================================ + * Misc helper macros + */ + +#define VB_AGE_CHECK_WITH_RET( dev_priv ) \ +do { \ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \ + if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \ + int __ret = radeon_do_cp_idle( dev_priv ); \ + if ( __ret < 0 ) return __ret; \ + sarea_priv->last_dispatch = 0; \ + radeon_freelist_reset( dev ); \ + } \ +} while (0) + +#define RADEON_DISPATCH_AGE( age ) \ +do { \ + OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \ + OUT_RING( age ); \ +} while (0) + +#define RADEON_FRAME_AGE( age ) \ +do { \ + OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \ + OUT_RING( age ); \ +} while (0) + +#define RADEON_CLEAR_AGE( age ) \ +do { \ + OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \ + OUT_RING( age ); \ +} while (0) + + +/* ================================================================ + * Ring control + */ + +#define radeon_flush_write_combine() mb() + + +#define RADEON_VERBOSE 0 + +#define RING_LOCALS int write; unsigned int mask; volatile u32 *ring; + +#define BEGIN_RING( n ) do { \ + if ( RADEON_VERBOSE ) { \ + DRM_INFO( "BEGIN_RING( %d ) in %s\n", \ + n, __FUNCTION__ ); \ + } \ + if ( dev_priv->ring.space < (n) * sizeof(u32) ) { \ + radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \ + } \ + dev_priv->ring.space -= (n) * sizeof(u32); \ + ring = dev_priv->ring.start; \ + write = dev_priv->ring.tail; \ + mask = dev_priv->ring.tail_mask; \ +} while (0) + +#define ADVANCE_RING() do { \ + if ( RADEON_VERBOSE ) { \ + DRM_INFO( "ADVANCE_RING() tail=0x%06x wr=0x%06x\n", \ + write, dev_priv->ring.tail ); \ + } \ + radeon_flush_write_combine(); \ + dev_priv->ring.tail = write; \ + RADEON_WRITE( RADEON_CP_RB_WPTR, write ); \ +} while (0) + +#define OUT_RING( x ) do { \ + if ( RADEON_VERBOSE ) { \ + DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \ + (unsigned int)(x), write ); \ + } \ + ring[write++] = (x); \ + write &= mask; \ +} while (0) + +#define RADEON_PERFORMANCE_BOXES 0 + +#endif /* __RADEON_DRV_H__ */ diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c new file mode 100644 index 000000000..7bfefb2ca --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/radeon_state.c @@ -0,0 +1,1447 @@ +/* radeon_state.c -- State support for Radeon -*- linux-c -*- + * + * Copyright 2000 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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> + * + */ + +#define __NO_VERSION__ +#include "drmP.h" +#include "radeon_drv.h" +#include "drm.h" +#include <linux/delay.h> + + +/* ================================================================ + * CP hardware state programming functions + */ + +static inline void radeon_emit_clip_rect( drm_radeon_private_t *dev_priv, + drm_clip_rect_t *box ) +{ + RING_LOCALS; + + DRM_DEBUG( " box: x1=%d y1=%d x2=%d y2=%d\n", + box->x1, box->y1, box->x2, box->y2 ); + + BEGIN_RING( 4 ); + + OUT_RING( CP_PACKET0( RADEON_RE_TOP_LEFT, 0 ) ); + OUT_RING( (box->y1 << 16) | box->x1 ); + + OUT_RING( CP_PACKET0( RADEON_RE_WIDTH_HEIGHT, 0 ) ); + OUT_RING( ((box->y2 - 1) << 16) | (box->x2 - 1) ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_context( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 14 ); + + OUT_RING( CP_PACKET0( RADEON_PP_MISC, 6 ) ); + OUT_RING( ctx->pp_misc ); + OUT_RING( ctx->pp_fog_color ); + OUT_RING( ctx->re_solid_color ); + OUT_RING( ctx->rb3d_blendcntl ); + OUT_RING( ctx->rb3d_depthoffset ); + OUT_RING( ctx->rb3d_depthpitch ); + OUT_RING( ctx->rb3d_zstencilcntl ); + + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 2 ) ); + OUT_RING( ctx->pp_cntl ); + OUT_RING( ctx->rb3d_cntl ); + OUT_RING( ctx->rb3d_coloroffset ); + + OUT_RING( CP_PACKET0( RADEON_RB3D_COLORPITCH, 0 ) ); + OUT_RING( ctx->rb3d_colorpitch ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_vertfmt( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 2 ); + + OUT_RING( CP_PACKET0( RADEON_SE_COORD_FMT, 0 ) ); + OUT_RING( ctx->se_coord_fmt ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_line( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 5 ); + + OUT_RING( CP_PACKET0( RADEON_RE_LINE_PATTERN, 1 ) ); + OUT_RING( ctx->re_line_pattern ); + OUT_RING( ctx->re_line_state ); + + OUT_RING( CP_PACKET0( RADEON_SE_LINE_WIDTH, 0 ) ); + OUT_RING( ctx->se_line_width ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_bumpmap( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 5 ); + + OUT_RING( CP_PACKET0( RADEON_PP_LUM_MATRIX, 0 ) ); + OUT_RING( ctx->pp_lum_matrix ); + + OUT_RING( CP_PACKET0( RADEON_PP_ROT_MATRIX_0, 1 ) ); + OUT_RING( ctx->pp_rot_matrix_0 ); + OUT_RING( ctx->pp_rot_matrix_1 ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_masks( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 4 ); + + OUT_RING( CP_PACKET0( RADEON_RB3D_STENCILREFMASK, 2 ) ); + OUT_RING( ctx->rb3d_stencilrefmask ); + OUT_RING( ctx->rb3d_ropcntl ); + OUT_RING( ctx->rb3d_planemask ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_viewport( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 7 ); + + OUT_RING( CP_PACKET0( RADEON_SE_VPORT_XSCALE, 5 ) ); + OUT_RING( ctx->se_vport_xscale ); + OUT_RING( ctx->se_vport_xoffset ); + OUT_RING( ctx->se_vport_yscale ); + OUT_RING( ctx->se_vport_yoffset ); + OUT_RING( ctx->se_vport_zscale ); + OUT_RING( ctx->se_vport_zoffset ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_setup( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 4 ); + + OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); + OUT_RING( ctx->se_cntl ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL_STATUS, 0 ) ); + OUT_RING( ctx->se_cntl_status ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_tcl( drm_radeon_private_t *dev_priv ) +{ +#ifdef TCL_ENABLE + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 29 ); + + OUT_RING( CP_PACKET0( RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 27 ) ); + OUT_RING( ctx->se_tcl_material_emmissive.red ); + OUT_RING( ctx->se_tcl_material_emmissive.green ); + OUT_RING( ctx->se_tcl_material_emmissive.blue ); + OUT_RING( ctx->se_tcl_material_emmissive.alpha ); + OUT_RING( ctx->se_tcl_material_ambient.red ); + OUT_RING( ctx->se_tcl_material_ambient.green ); + OUT_RING( ctx->se_tcl_material_ambient.blue ); + OUT_RING( ctx->se_tcl_material_ambient.alpha ); + OUT_RING( ctx->se_tcl_material_diffuse.red ); + OUT_RING( ctx->se_tcl_material_diffuse.green ); + OUT_RING( ctx->se_tcl_material_diffuse.blue ); + OUT_RING( ctx->se_tcl_material_diffuse.alpha ); + OUT_RING( ctx->se_tcl_material_specular.red ); + OUT_RING( ctx->se_tcl_material_specular.green ); + OUT_RING( ctx->se_tcl_material_specular.blue ); + OUT_RING( ctx->se_tcl_material_specular.alpha ); + OUT_RING( ctx->se_tcl_shininess ); + OUT_RING( ctx->se_tcl_output_vtx_fmt ); + OUT_RING( ctx->se_tcl_output_vtx_sel ); + OUT_RING( ctx->se_tcl_matrix_select_0 ); + OUT_RING( ctx->se_tcl_matrix_select_1 ); + OUT_RING( ctx->se_tcl_ucp_vert_blend_ctl ); + OUT_RING( ctx->se_tcl_texture_proc_ctl ); + OUT_RING( ctx->se_tcl_light_model_ctl ); + for ( i = 0 ; i < 4 ; i++ ) { + OUT_RING( ctx->se_tcl_per_light_ctl[i] ); + } + + ADVANCE_RING(); +#else + DRM_ERROR( "TCL not enabled!\n" ); +#endif +} + +static inline void radeon_emit_misc( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_context_regs_t *ctx = &sarea_priv->context_state; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 2 ); + + OUT_RING( CP_PACKET0( RADEON_RE_MISC, 0 ) ); + OUT_RING( ctx->re_misc ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_tex0( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[0]; + RING_LOCALS; + DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset ); + + BEGIN_RING( 9 ); + + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_0, 5 ) ); + OUT_RING( tex->pp_txfilter ); + OUT_RING( tex->pp_txformat ); + OUT_RING( tex->pp_txoffset ); + OUT_RING( tex->pp_txcblend ); + OUT_RING( tex->pp_txablend ); + OUT_RING( tex->pp_tfactor ); + + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_0, 0 ) ); + OUT_RING( tex->pp_border_color ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_tex1( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[1]; + RING_LOCALS; + DRM_DEBUG( " %s: offset=0x%x\n", __FUNCTION__, tex->pp_txoffset ); + + BEGIN_RING( 9 ); + + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_1, 5 ) ); + OUT_RING( tex->pp_txfilter ); + OUT_RING( tex->pp_txformat ); + OUT_RING( tex->pp_txoffset ); + OUT_RING( tex->pp_txcblend ); + OUT_RING( tex->pp_txablend ); + OUT_RING( tex->pp_tfactor ); + + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_1, 0 ) ); + OUT_RING( tex->pp_border_color ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_tex2( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_texture_regs_t *tex = &sarea_priv->tex_state[2]; + RING_LOCALS; + DRM_DEBUG( " %s\n", __FUNCTION__ ); + + BEGIN_RING( 9 ); + + OUT_RING( CP_PACKET0( RADEON_PP_TXFILTER_2, 5 ) ); + OUT_RING( tex->pp_txfilter ); + OUT_RING( tex->pp_txformat ); + OUT_RING( tex->pp_txoffset ); + OUT_RING( tex->pp_txcblend ); + OUT_RING( tex->pp_txablend ); + OUT_RING( tex->pp_tfactor ); + + OUT_RING( CP_PACKET0( RADEON_PP_BORDER_COLOR_2, 0 ) ); + OUT_RING( tex->pp_border_color ); + + ADVANCE_RING(); +} + +static inline void radeon_emit_state( drm_radeon_private_t *dev_priv ) +{ + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + unsigned int dirty = sarea_priv->dirty; + + DRM_DEBUG( "%s: dirty=0x%08x\n", __FUNCTION__, dirty ); + + if ( dirty & RADEON_UPLOAD_CONTEXT ) { + radeon_emit_context( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_CONTEXT; + } + + if ( dirty & RADEON_UPLOAD_VERTFMT ) { + radeon_emit_vertfmt( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_VERTFMT; + } + + if ( dirty & RADEON_UPLOAD_LINE ) { + radeon_emit_line( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_LINE; + } + + if ( dirty & RADEON_UPLOAD_BUMPMAP ) { + radeon_emit_bumpmap( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_BUMPMAP; + } + + if ( dirty & RADEON_UPLOAD_MASKS ) { + radeon_emit_masks( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_MASKS; + } + + if ( dirty & RADEON_UPLOAD_VIEWPORT ) { + radeon_emit_viewport( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_VIEWPORT; + } + + if ( dirty & RADEON_UPLOAD_SETUP ) { + radeon_emit_setup( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_SETUP; + } + + if ( dirty & RADEON_UPLOAD_TCL ) { +#ifdef TCL_ENABLE + radeon_emit_tcl( dev_priv ); +#endif + sarea_priv->dirty &= ~RADEON_UPLOAD_TCL; + } + + if ( dirty & RADEON_UPLOAD_MISC ) { + radeon_emit_misc( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_MISC; + } + + if ( dirty & RADEON_UPLOAD_TEX0 ) { + radeon_emit_tex0( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_TEX0; + } + + if ( dirty & RADEON_UPLOAD_TEX1 ) { + radeon_emit_tex1( dev_priv ); + sarea_priv->dirty &= ~RADEON_UPLOAD_TEX1; + } + + if ( dirty & RADEON_UPLOAD_TEX2 ) { +#if 0 + radeon_emit_tex2( dev_priv ); +#endif + sarea_priv->dirty &= ~RADEON_UPLOAD_TEX2; + } + + sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES | + RADEON_UPLOAD_TEX1IMAGES | + RADEON_UPLOAD_TEX2IMAGES | + RADEON_REQUIRE_QUIESCENCE); +} + + +#if RADEON_PERFORMANCE_BOXES +/* ================================================================ + * Performance monitoring functions + */ + +static void radeon_clear_box( drm_radeon_private_t *dev_priv, + int x, int y, int w, int h, + int r, int g, int b ) +{ + u32 pitch, offset; + u32 color; + RING_LOCALS; + + switch ( dev_priv->color_fmt ) { + case RADEON_COLOR_FORMAT_RGB565: + color = (((r & 0xf8) << 8) | + ((g & 0xfc) << 3) | + ((b & 0xf8) >> 3)); + break; + case RADEON_COLOR_FORMAT_ARGB8888: + default: + color = (((0xff) << 24) | (r << 16) | (g << 8) | b); + break; + } + + offset = dev_priv->back_offset; + pitch = dev_priv->back_pitch >> 3; + + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( (pitch << 22) | (offset >> 5) ); + OUT_RING( color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); +} + +static void radeon_cp_performance_boxes( drm_radeon_private_t *dev_priv ) +{ + if ( atomic_read( &dev_priv->idle_count ) == 0 ) { + radeon_clear_box( dev_priv, 64, 4, 8, 8, 0, 255, 0 ); + } else { + atomic_set( &dev_priv->idle_count, 0 ); + } +} + +#endif + + +/* ================================================================ + * CP command dispatch functions + */ + +static void radeon_print_dirty( const char *msg, unsigned int flags ) +{ + DRM_DEBUG( "%s: (0x%x) %s%s%s%s%s%s%s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & RADEON_UPLOAD_CONTEXT) ? "context, " : "", + (flags & RADEON_UPLOAD_VERTFMT) ? "vertfmt, " : "", + (flags & RADEON_UPLOAD_LINE) ? "line, " : "", + (flags & RADEON_UPLOAD_BUMPMAP) ? "bumpmap, " : "", + (flags & RADEON_UPLOAD_MASKS) ? "masks, " : "", + (flags & RADEON_UPLOAD_VIEWPORT) ? "viewport, " : "", + (flags & RADEON_UPLOAD_SETUP) ? "setup, " : "", + (flags & RADEON_UPLOAD_TCL) ? "tcl, " : "", + (flags & RADEON_UPLOAD_MISC) ? "misc, " : "", + (flags & RADEON_UPLOAD_TEX0) ? "tex0, " : "", + (flags & RADEON_UPLOAD_TEX1) ? "tex1, " : "", + (flags & RADEON_UPLOAD_TEX2) ? "tex2, " : "", + (flags & RADEON_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (flags & RADEON_REQUIRE_QUIESCENCE) ? "quiescence, " : "" ); +} + +static void radeon_cp_dispatch_clear( drm_device_t *dev, + drm_radeon_clear_t *clear ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + unsigned int flags = clear->flags; + int i; + RING_LOCALS; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + radeon_update_ring_snapshot( dev_priv ); + + if ( dev_priv->page_flipping && dev_priv->current_page == 1 ) { + unsigned int tmp = flags; + + flags &= ~(RADEON_FRONT | RADEON_BACK); + if ( tmp & RADEON_FRONT ) flags |= RADEON_BACK; + if ( tmp & RADEON_BACK ) flags |= RADEON_FRONT; + } + + for ( i = 0 ; i < nbox ; i++ ) { + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; + + DRM_DEBUG( "dispatch clear %d,%d-%d,%d flags 0x%x\n", + x, y, w, h, flags ); + + if ( flags & (RADEON_FRONT | RADEON_BACK) ) { + BEGIN_RING( 4 ); + + /* Ensure the 3D stream is idle before doing a + * 2D fill to clear the front or back buffer. + */ + RADEON_WAIT_UNTIL_3D_IDLE(); + + OUT_RING( CP_PACKET0( RADEON_DP_WRITE_MASK, 0 ) ); + OUT_RING( sarea_priv->context_state.rb3d_planemask ); + + ADVANCE_RING(); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_MASKS); + } + + if ( flags & RADEON_FRONT ) { + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( dev_priv->front_pitch_offset ); + OUT_RING( clear->clear_color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + if ( flags & RADEON_BACK ) { + BEGIN_RING( 6 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_PAINT_MULTI, 4 ) ); + OUT_RING( RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_SOLID_COLOR | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_P | + RADEON_GMC_CLR_CMP_CNTL_DIS ); + + OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING( clear->clear_color ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + + } + + if ( flags & RADEON_DEPTH ) { + drm_radeon_depth_clear_t *depth_clear = + &dev_priv->depth_clear; + + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv ); + } + + /* FIXME: Render a rectangle to clear the depth + * buffer. So much for those "fast Z clears"... + */ + BEGIN_RING( 23 ); + + RADEON_WAIT_UNTIL_2D_IDLE(); + + OUT_RING( CP_PACKET0( RADEON_PP_CNTL, 1 ) ); + OUT_RING( 0x00000000 ); + OUT_RING( depth_clear->rb3d_cntl ); + OUT_RING( CP_PACKET0( RADEON_RB3D_ZSTENCILCNTL, 0 ) ); + OUT_RING( depth_clear->rb3d_zstencilcntl ); + OUT_RING( CP_PACKET0( RADEON_RB3D_PLANEMASK, 0 ) ); + OUT_RING( 0x00000000 ); + OUT_RING( CP_PACKET0( RADEON_SE_CNTL, 0 ) ); + OUT_RING( depth_clear->se_cntl ); + + OUT_RING( CP_PACKET3( RADEON_3D_DRAW_IMMD, 10 ) ); + OUT_RING( RADEON_VTX_Z_PRESENT ); + OUT_RING( (RADEON_PRIM_TYPE_RECT_LIST | + RADEON_PRIM_WALK_RING | + RADEON_MAOS_ENABLE | + RADEON_VTX_FMT_RADEON_MODE | + (3 << RADEON_NUM_VERTICES_SHIFT)) ); + + OUT_RING( clear->rect.ui[CLEAR_X1] ); + OUT_RING( clear->rect.ui[CLEAR_Y1] ); + OUT_RING( clear->rect.ui[CLEAR_DEPTH] ); + + OUT_RING( clear->rect.ui[CLEAR_X1] ); + OUT_RING( clear->rect.ui[CLEAR_Y2] ); + OUT_RING( clear->rect.ui[CLEAR_DEPTH] ); + + OUT_RING( clear->rect.ui[CLEAR_X2] ); + OUT_RING( clear->rect.ui[CLEAR_Y2] ); + OUT_RING( clear->rect.ui[CLEAR_DEPTH] ); + + ADVANCE_RING(); + + /* Make sure we restore the 3D state next time. + */ + dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_SETUP | + RADEON_UPLOAD_MASKS); + } + } + + /* Increment the clear counter. The client-side 3D driver must + * wait on this value before performing the clear ioctl. We + * need this because the card's so damned fast... + */ + dev_priv->sarea_priv->last_clear++; + + BEGIN_RING( 4 ); + + RADEON_CLEAR_AGE( dev_priv->sarea_priv->last_clear ); + RADEON_WAIT_UNTIL_IDLE(); + + ADVANCE_RING(); +} + +static void radeon_cp_dispatch_swap( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + int nbox = sarea_priv->nbox; + drm_clip_rect_t *pbox = sarea_priv->boxes; + int i; + RING_LOCALS; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + radeon_update_ring_snapshot( dev_priv ); + +#if RADEON_PERFORMANCE_BOXES + /* Do some trivial performance monitoring... + */ + radeon_cp_performance_boxes( dev_priv ); +#endif + + /* Wait for the 3D stream to idle before dispatching the bitblt. + * This will prevent data corruption between the two streams. + */ + BEGIN_RING( 2 ); + + RADEON_WAIT_UNTIL_3D_IDLE(); + + ADVANCE_RING(); + + for ( i = 0 ; i < nbox ; i++ ) { + int x = pbox[i].x1; + int y = pbox[i].y1; + int w = pbox[i].x2 - x; + int h = pbox[i].y2 - y; + + DRM_DEBUG( "dispatch swap %d,%d-%d,%d\n", + x, y, w, h ); + + BEGIN_RING( 7 ); + + OUT_RING( CP_PACKET3( RADEON_CNTL_BITBLT_MULTI, 5 ) ); + OUT_RING( RADEON_GMC_SRC_PITCH_OFFSET_CNTL | + RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (dev_priv->color_fmt << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_MEMORY | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_WR_MSK_DIS ); + + OUT_RING( dev_priv->back_pitch_offset ); + OUT_RING( dev_priv->front_pitch_offset ); + + OUT_RING( (x << 16) | y ); + OUT_RING( (x << 16) | y ); + OUT_RING( (w << 16) | h ); + + ADVANCE_RING(); + } + + /* Increment the frame counter. The client-side 3D driver must + * throttle the framerate by waiting for this value before + * performing the swapbuffer ioctl. + */ + dev_priv->sarea_priv->last_frame++; + + BEGIN_RING( 4 ); + + RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); + RADEON_WAIT_UNTIL_2D_IDLE(); + + ADVANCE_RING(); +} + +static void radeon_cp_dispatch_flip( drm_device_t *dev ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + RING_LOCALS; + DRM_DEBUG( "%s: page=%d\n", __FUNCTION__, dev_priv->current_page ); + + radeon_update_ring_snapshot( dev_priv ); + +#if RADEON_PERFORMANCE_BOXES + /* Do some trivial performance monitoring... + */ + radeon_cp_performance_boxes( dev_priv ); +#endif + + BEGIN_RING( 6 ); + + RADEON_WAIT_UNTIL_3D_IDLE(); + RADEON_WAIT_UNTIL_PAGE_FLIPPED(); + + OUT_RING( CP_PACKET0( RADEON_CRTC_OFFSET, 0 ) ); + + if ( dev_priv->current_page == 0 ) { + OUT_RING( dev_priv->back_offset ); + dev_priv->current_page = 1; + } else { + OUT_RING( dev_priv->front_offset ); + dev_priv->current_page = 0; + } + + ADVANCE_RING(); + + /* Increment the frame counter. The client-side 3D driver must + * throttle the framerate by waiting for this value before + * performing the swapbuffer ioctl. + */ + dev_priv->sarea_priv->last_frame++; + + BEGIN_RING( 2 ); + + RADEON_FRAME_AGE( dev_priv->sarea_priv->last_frame ); + + ADVANCE_RING(); +} + +static void radeon_cp_dispatch_vertex( drm_device_t *dev, + drm_buf_t *buf ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + int format = sarea_priv->vc_format; + int offset = dev_priv->agp_buffers_offset + buf->offset; + int size = buf->used; + int prim = buf_priv->prim; + int i = 0; + RING_LOCALS; + DRM_DEBUG( "%s: nbox=%d\n", __FUNCTION__, sarea_priv->nbox ); + + radeon_update_ring_snapshot( dev_priv ); + + if ( 1 ) + radeon_print_dirty( "dispatch_vertex", sarea_priv->dirty ); + + if ( buf->used ) { + buf_priv->dispatched = 1; + + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv ); + } + + do { + /* Emit the next set of up to three cliprects */ + if ( i < sarea_priv->nbox ) { + radeon_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); + } + + /* Emit the vertex buffer rendering commands */ + BEGIN_RING( 5 ); + + OUT_RING( CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, 3 ) ); + OUT_RING( offset ); + OUT_RING( size ); + OUT_RING( format ); + OUT_RING( prim | RADEON_PRIM_WALK_LIST | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (size << RADEON_NUM_VERTICES_SHIFT) ); + + ADVANCE_RING(); + + i++; + } while ( i < sarea_priv->nbox ); + } + + if ( buf_priv->discard ) { + buf_priv->age = dev_priv->sarea_priv->last_dispatch; + + /* Emit the vertex buffer age */ + BEGIN_RING( 2 ); + RADEON_DISPATCH_AGE( buf_priv->age ); + ADVANCE_RING(); + + buf->pending = 1; + buf->used = 0; + /* FIXME: Check dispatched field */ + buf_priv->dispatched = 0; + } + + dev_priv->sarea_priv->last_dispatch++; + + sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; + sarea_priv->nbox = 0; +} + + +static void radeon_cp_dispatch_indirect( drm_device_t *dev, + drm_buf_t *buf, + int start, int end ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + RING_LOCALS; + DRM_DEBUG( "indirect: buf=%d s=0x%x e=0x%x\n", + buf->idx, start, end ); + + radeon_update_ring_snapshot( dev_priv ); + + if ( start != end ) { + int offset = (dev_priv->agp_buffers_offset + + buf->offset + start); + int dwords = (end - start + 3) / sizeof(u32); + + /* Indirect buffer data must be an even number of + * dwords, so if we've been given an odd number we must + * pad the data with a Type-2 CP packet. + */ + if ( dwords & 1 ) { + u32 *data = (u32 *) + ((char *)dev_priv->buffers->handle + + buf->offset + start); + data[dwords++] = RADEON_CP_PACKET2; + } + + buf_priv->dispatched = 1; + + /* Fire off the indirect buffer */ + BEGIN_RING( 3 ); + + OUT_RING( CP_PACKET0( RADEON_CP_IB_BASE, 1 ) ); + OUT_RING( offset ); + OUT_RING( dwords ); + + ADVANCE_RING(); + } + + if ( buf_priv->discard ) { + buf_priv->age = dev_priv->sarea_priv->last_dispatch; + + /* Emit the indirect buffer age */ + BEGIN_RING( 2 ); + RADEON_DISPATCH_AGE( buf_priv->age ); + ADVANCE_RING(); + + buf->pending = 1; + buf->used = 0; + /* FIXME: Check dispatched field */ + buf_priv->dispatched = 0; + } + + dev_priv->sarea_priv->last_dispatch++; +} + +static void radeon_cp_dispatch_indices( drm_device_t *dev, + drm_buf_t *buf, + int start, int end, + int count ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_buf_priv_t *buf_priv = buf->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + int format = sarea_priv->vc_format; + int offset = dev_priv->agp_buffers_offset; + int prim = buf_priv->prim; + u32 *data; + int dwords; + int i = 0; + RING_LOCALS; + DRM_DEBUG( "indices: s=%d e=%d c=%d\n", start, end, count ); + + radeon_update_ring_snapshot( dev_priv ); + + if ( 0 ) + radeon_print_dirty( "dispatch_indices", sarea_priv->dirty ); + + if ( start != end ) { + buf_priv->dispatched = 1; + + if ( sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS ) { + radeon_emit_state( dev_priv ); + } + + dwords = (end - start + 3) / sizeof(u32); + + data = (u32 *)((char *)dev_priv->buffers->handle + + buf->offset + start); + + data[0] = CP_PACKET3( RADEON_3D_RNDR_GEN_INDX_PRIM, dwords-2 ); + + data[1] = offset; + data[2] = RADEON_MAX_VB_VERTS; + data[3] = format; + data[4] = (prim | RADEON_PRIM_WALK_IND | + RADEON_COLOR_ORDER_RGBA | + RADEON_VTX_FMT_RADEON_MODE | + (count << RADEON_NUM_VERTICES_SHIFT) ); + + if ( count & 0x1 ) { + data[dwords-1] &= 0x0000ffff; + } + + do { + /* Emit the next set of up to three cliprects */ + if ( i < sarea_priv->nbox ) { + radeon_emit_clip_rect( dev_priv, + &sarea_priv->boxes[i] ); + } + + radeon_cp_dispatch_indirect( dev, buf, start, end ); + + i++; + } while ( i < sarea_priv->nbox ); + } + + if ( buf_priv->discard ) { + buf_priv->age = dev_priv->sarea_priv->last_dispatch; + + /* Emit the vertex buffer age */ + BEGIN_RING( 2 ); + RADEON_DISPATCH_AGE( buf_priv->age ); + ADVANCE_RING(); + + buf->pending = 1; + /* FIXME: Check dispatched field */ + buf_priv->dispatched = 0; + } + + dev_priv->sarea_priv->last_dispatch++; + + sarea_priv->dirty &= ~RADEON_UPLOAD_CLIPRECTS; + sarea_priv->nbox = 0; +} + +static int radeon_cp_dispatch_blit( drm_device_t *dev, + drm_radeon_blit_t *blit ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_buf_priv_t *buf_priv; + u32 format; + u32 *data; + int dword_shift, dwords; + RING_LOCALS; + DRM_DEBUG( "blit: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n", + blit->offset >> 10, blit->pitch, blit->format, + blit->x, blit->y, blit->width, blit->height ); + + radeon_update_ring_snapshot( dev_priv ); + + /* The compiler won't optimize away a division by a variable, + * even if the only legal values are powers of two. Thus, we'll + * use a shift instead. + */ + switch ( blit->format ) { + case RADEON_TXF_32BPP_ARGB8888: + case RADEON_TXF_32BPP_RGBA8888: + format = RADEON_COLOR_FORMAT_ARGB8888; + dword_shift = 0; + break; + case RADEON_TXF_16BPP_AI88: + case RADEON_TXF_16BPP_ARGB1555: + case RADEON_TXF_16BPP_RGB565: + case RADEON_TXF_16BPP_ARGB4444: + format = RADEON_COLOR_FORMAT_RGB565; + dword_shift = 1; + break; + case RADEON_TXF_8BPP_I: + case RADEON_TXF_8BPP_RGB332: + format = RADEON_COLOR_FORMAT_CI8; + dword_shift = 2; + break; + default: + DRM_ERROR( "invalid blit format %d\n", blit->format ); + return -EINVAL; + } + + /* Flush the pixel cache. This ensures no pixel data gets mixed + * up with the texture data from the host data blit, otherwise + * part of the texture image may be corrupted. + */ + BEGIN_RING( 4 ); + + RADEON_FLUSH_CACHE(); + RADEON_WAIT_UNTIL_IDLE(); + + ADVANCE_RING(); + + /* Dispatch the indirect buffer. + */ + buf = dma->buflist[blit->idx]; + buf_priv = buf->dev_private; + + if ( buf->pid != current->pid ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + current->pid, buf->pid ); + return -EINVAL; + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", blit->idx ); + return -EINVAL; + } + + buf_priv->discard = 1; + + dwords = (blit->width * blit->height) >> dword_shift; + if ( !dwords ) dwords = 1; + + data = (u32 *)((char *)dev_priv->buffers->handle + buf->offset); + + data[0] = CP_PACKET3( RADEON_CNTL_HOSTDATA_BLT, dwords + 6 ); + data[1] = (RADEON_GMC_DST_PITCH_OFFSET_CNTL | + RADEON_GMC_BRUSH_NONE | + (format << 8) | + RADEON_GMC_SRC_DATATYPE_COLOR | + RADEON_ROP3_S | + RADEON_DP_SRC_SOURCE_HOST_DATA | + RADEON_GMC_CLR_CMP_CNTL_DIS | + RADEON_GMC_WR_MSK_DIS); + + data[2] = (blit->pitch << 22) | (blit->offset >> 10); + data[3] = 0xffffffff; + data[4] = 0xffffffff; + data[5] = (blit->y << 16) | blit->x; + data[6] = (blit->height << 16) | blit->width; + data[7] = dwords; + + buf->used = (dwords + 8) * sizeof(u32); + + radeon_cp_dispatch_indirect( dev, buf, 0, buf->used ); + + /* Flush the pixel cache after the blit completes. This ensures + * the texture data is written out to memory before rendering + * continues. + */ + BEGIN_RING( 4 ); + + RADEON_FLUSH_CACHE(); + RADEON_WAIT_UNTIL_2D_IDLE(); + + ADVANCE_RING(); + + return 0; +} + +static void radeon_cp_dispatch_stipple( drm_device_t *dev, u32 *stipple ) +{ + drm_radeon_private_t *dev_priv = dev->dev_private; + int i; + RING_LOCALS; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + radeon_update_ring_snapshot( dev_priv ); + + BEGIN_RING( 35 ); + + OUT_RING( CP_PACKET0( RADEON_RE_STIPPLE_ADDR, 0 ) ); + OUT_RING( 0x00000000 ); + + OUT_RING( CP_PACKET0_TABLE( RADEON_RE_STIPPLE_DATA, 31 ) ); + for ( i = 0 ; i < 32 ; i++ ) { + OUT_RING( stipple[i] ); + } + + ADVANCE_RING(); +} + + +/* ================================================================ + * IOCTL functions + */ + +int radeon_cp_clear( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + drm_radeon_clear_t clear; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &clear, (drm_radeon_clear_t *) arg, + sizeof(clear) ) ) + return -EFAULT; + + if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; + + radeon_cp_dispatch_clear( dev, &clear ); + + return 0; +} + +int radeon_cp_swap( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; + DRM_DEBUG( "%s\n", __FUNCTION__ ); + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS ) + sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS; + + if ( !dev_priv->page_flipping ) { + radeon_cp_dispatch_swap( dev ); + dev_priv->sarea_priv->dirty |= (RADEON_UPLOAD_CONTEXT | + RADEON_UPLOAD_MASKS); + } else { + radeon_cp_dispatch_flip( dev ); + } + + return 0; +} + +int radeon_cp_vertex( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_buf_priv_t *buf_priv; + drm_radeon_vertex_t vertex; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + if ( !dev_priv || dev_priv->is_pci ) { + DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &vertex, (drm_radeon_vertex_t *)arg, + sizeof(vertex) ) ) + return -EFAULT; + + DRM_DEBUG( "%s: pid=%d index=%d count=%d discard=%d\n", + __FUNCTION__, current->pid, + vertex.idx, vertex.count, vertex.discard ); + + if ( vertex.idx < 0 || vertex.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + vertex.idx, dma->buf_count - 1 ); + return -EINVAL; + } + if ( vertex.prim < 0 || + vertex.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { + DRM_ERROR( "buffer prim %d\n", vertex.prim ); + return -EINVAL; + } + + VB_AGE_CHECK_WITH_RET( dev_priv ); + + buf = dma->buflist[vertex.idx]; + buf_priv = buf->dev_private; + + if ( buf->pid != current->pid ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + current->pid, buf->pid ); + return -EINVAL; + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", vertex.idx ); + return -EINVAL; + } + + buf->used = vertex.count; + buf_priv->prim = vertex.prim; + buf_priv->discard = vertex.discard; + + radeon_cp_dispatch_vertex( dev, buf ); + + return 0; +} + +int radeon_cp_indices( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_buf_priv_t *buf_priv; + drm_radeon_indices_t elts; + int count; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + if ( !dev_priv || dev_priv->is_pci ) { + DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &elts, (drm_radeon_indices_t *)arg, + sizeof(elts) ) ) + return -EFAULT; + + DRM_DEBUG( "%s: pid=%d index=%d start=%d end=%d discard=%d\n", + __FUNCTION__, current->pid, + elts.idx, elts.start, elts.end, elts.discard ); + + if ( elts.idx < 0 || elts.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + elts.idx, dma->buf_count - 1 ); + return -EINVAL; + } + if ( elts.prim < 0 || + elts.prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST ) { + DRM_ERROR( "buffer prim %d\n", elts.prim ); + return -EINVAL; + } + + VB_AGE_CHECK_WITH_RET( dev_priv ); + + buf = dma->buflist[elts.idx]; + buf_priv = buf->dev_private; + + if ( buf->pid != current->pid ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + current->pid, buf->pid ); + return -EINVAL; + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", elts.idx ); + return -EINVAL; + } + + count = (elts.end - elts.start) / sizeof(u16); + elts.start -= RADEON_INDEX_PRIM_OFFSET; + + if ( elts.start & 0x7 ) { + DRM_ERROR( "misaligned buffer 0x%x\n", elts.start ); + return -EINVAL; + } + if ( elts.start < buf->used ) { + DRM_ERROR( "no header 0x%x - 0x%x\n", elts.start, buf->used ); + return -EINVAL; + } + + buf->used = elts.end; + buf_priv->prim = elts.prim; + buf_priv->discard = elts.discard; + + radeon_cp_dispatch_indices( dev, buf, elts.start, elts.end, count ); + + return 0; +} + +int radeon_cp_blit( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_radeon_blit_t blit; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &blit, (drm_radeon_blit_t *)arg, + sizeof(blit) ) ) + return -EFAULT; + + DRM_DEBUG( "%s: pid=%d index=%d\n", + __FUNCTION__, current->pid, blit.idx ); + + if ( blit.idx < 0 || blit.idx > dma->buf_count ) { + DRM_ERROR( "sending %d buffers (of %d max)\n", + blit.idx, dma->buf_count ); + return -EINVAL; + } + + VB_AGE_CHECK_WITH_RET( dev_priv ); + + return radeon_cp_dispatch_blit( dev, &blit ); +} + +int radeon_cp_stipple( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_stipple_t stipple; + u32 mask[32]; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &stipple, (drm_radeon_stipple_t *)arg, + sizeof(stipple) ) ) + return -EFAULT; + + if ( copy_from_user( &mask, stipple.mask, + 32 * sizeof(u32) ) ) + return -EFAULT; + + radeon_cp_dispatch_stipple( dev, mask ); + + return 0; +} + +int radeon_cp_indirect( struct inode *inode, struct file *filp, + unsigned int cmd, unsigned long arg ) +{ + drm_file_t *priv = filp->private_data; + drm_device_t *dev = priv->dev; + drm_radeon_private_t *dev_priv = dev->dev_private; + drm_device_dma_t *dma = dev->dma; + drm_buf_t *buf; + drm_radeon_buf_priv_t *buf_priv; + drm_radeon_indirect_t indirect; + RING_LOCALS; + + if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || + dev->lock.pid != current->pid ) { + DRM_ERROR( "%s called without lock held\n", __FUNCTION__ ); + return -EINVAL; + } + if ( !dev_priv || dev_priv->is_pci ) { + DRM_ERROR( "%s called with a PCI card\n", __FUNCTION__ ); + return -EINVAL; + } + + if ( copy_from_user( &indirect, (drm_radeon_indirect_t *)arg, + sizeof(indirect) ) ) + return -EFAULT; + + DRM_DEBUG( "indirect: idx=%d s=%d e=%d d=%d\n", + indirect.idx, indirect.start, + indirect.end, indirect.discard ); + + if ( indirect.idx < 0 || indirect.idx >= dma->buf_count ) { + DRM_ERROR( "buffer index %d (of %d max)\n", + indirect.idx, dma->buf_count - 1 ); + return -EINVAL; + } + + buf = dma->buflist[indirect.idx]; + buf_priv = buf->dev_private; + + if ( buf->pid != current->pid ) { + DRM_ERROR( "process %d using buffer owned by %d\n", + current->pid, buf->pid ); + return -EINVAL; + } + if ( buf->pending ) { + DRM_ERROR( "sending pending buffer %d\n", indirect.idx ); + return -EINVAL; + } + + if ( indirect.start < buf->used ) { + DRM_ERROR( "reusing indirect: start=0x%x actual=0x%x\n", + indirect.start, buf->used ); + return -EINVAL; + } + + VB_AGE_CHECK_WITH_RET( dev_priv ); + + buf->used = indirect.end; + buf_priv->discard = indirect.discard; + + /* Wait for the 3D stream to idle before the indirect buffer + * containing 2D acceleration commands is processed. + */ + BEGIN_RING( 2 ); + + RADEON_WAIT_UNTIL_3D_IDLE(); + + ADVANCE_RING(); + + /* Dispatch the indirect buffer full of commands from the + * X server. This is insecure and is thus only available to + * privileged clients. + */ + radeon_cp_dispatch_indirect( dev, buf, indirect.start, indirect.end ); + + return 0; +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drm.h b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drm.h index 73807f317..299143f61 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/kernel/sis_drm.h @@ -2,30 +2,19 @@ #ifndef _sis_drm_public_h_ #define _sis_drm_public_h_ -typedef struct { +typedef struct { int context; unsigned int offset; unsigned int size; unsigned int free; -} drm_sis_mem_t; +} drm_sis_mem_t; -typedef struct { +typedef struct { unsigned int offset, size; -} drm_sis_agp_t; +} drm_sis_agp_t; -typedef struct { +typedef struct { unsigned int left, right; -} drm_sis_flip_t; - -#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) -#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) - -#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t) -#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t) -#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) - -#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) -#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) -#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) +} drm_sis_flip_t; #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c index e1c8134f8..e542b509d 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmR128.c @@ -208,6 +208,23 @@ int drmR128EngineReset( int fd ) } } +int drmR128FullScreen( int fd, int enable ) +{ + drm_r128_fullscreen_t fs; + + if ( enable ) { + fs.func = R128_INIT_FULLSCREEN; + } else { + fs.func = R128_CLEANUP_FULLSCREEN; + } + + if ( ioctl( fd, DRM_IOCTL_R128_FULLSCREEN, &fs ) ) { + return -errno; + } else { + return 0; + } +} + int drmR128SwapBuffers( int fd ) { if ( ioctl( fd, DRM_IOCTL_R128_SWAP, NULL ) ) { @@ -387,25 +404,19 @@ int drmR128PolygonStipple( int fd, unsigned int *mask ) } } -int drmR128SubmitPacket( int fd, void *buffer, int *count, int flags ) +int drmR128FlushIndirectBuffer( int fd, int index, + int start, int end, int discard ) { - drm_r128_packet_t packet; - int ret; - - memset( &packet, 0, sizeof(drm_r128_packet_t) ); + drm_r128_indirect_t ind; - packet.count = *count; - packet.flags = flags; + ind.idx = index; + ind.start = start; + ind.end = end; + ind.discard = discard; - while (packet.count > 0) { - packet.buffer = (unsigned int *)buffer + (*count - packet.count); - ret = ioctl(fd, DRM_IOCTL_R128_PACKET, &packet); - if (ret < 0 && ret != -EAGAIN) { - *count = packet.count; - return -errno; - } + if ( ioctl( fd, DRM_IOCTL_R128_INDIRECT, &ind ) < 0 ) { + return -errno; + } else { + return 0; } - - *count = 0; - return 0; } diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c new file mode 100644 index 000000000..6a7f4b2d3 --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmRadeon.c @@ -0,0 +1,354 @@ +/* xf86drmRadeon.c -- User-level interface to Radeon DRM device + * + * Copyright 2000 VA Linx 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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> + * Kevin E. Martin <martin@valinux.com> + * + */ +/* $XFree86$ */ + +#ifdef XFree86Server +# include "xf86.h" +# include "xf86_OSproc.h" +# include "xf86_ansic.h" +# include "xf86Priv.h" +# define _DRM_MALLOC xalloc +# define _DRM_FREE xfree +# ifndef XFree86LOADER +# include <sys/stat.h> +# include <sys/mman.h> +# endif +#else +# include <stdio.h> +# include <stdlib.h> +# include <unistd.h> +# include <string.h> +# include <ctype.h> +# include <fcntl.h> +# include <errno.h> +# include <signal.h> +# include <sys/types.h> +# include <sys/stat.h> +# include <sys/ioctl.h> +# include <sys/mman.h> +# include <sys/time.h> +# ifdef DRM_USE_MALLOC +# define _DRM_MALLOC malloc +# define _DRM_FREE free +extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *); +extern int xf86RemoveSIGIOHandler(int fd); +# else +# include <Xlibint.h> +# define _DRM_MALLOC Xmalloc +# define _DRM_FREE Xfree +# endif +#endif + +/* Not all systems have MAP_FAILED defined */ +#ifndef MAP_FAILED +#define MAP_FAILED ((void *)-1) +#endif + +#ifdef __linux__ +#include <sys/sysmacros.h> /* for makedev() */ +#endif +#include "xf86drm.h" +#include "xf86drmRadeon.h" +#include "drm.h" + +#define RADEON_BUFFER_RETRY 32 +#define RADEON_IDLE_RETRY 16 + + +int drmRadeonInitCP( int fd, drmRadeonInit *info ) +{ + drm_radeon_init_t init; + + memset( &init, 0, sizeof(drm_radeon_init_t) ); + + init.func = RADEON_INIT_CP; + init.sarea_priv_offset = info->sarea_priv_offset; + init.is_pci = info->is_pci; + init.cp_mode = info->cp_mode; + init.agp_size = info->agp_size; + init.ring_size = info->ring_size; + init.usec_timeout = info->usec_timeout; + + init.fb_bpp = info->fb_bpp; + init.front_offset = info->front_offset; + init.front_pitch = info->front_pitch; + init.back_offset = info->back_offset; + init.back_pitch = info->back_pitch; + + init.depth_bpp = info->depth_bpp; + init.depth_offset = info->depth_offset; + init.depth_pitch = info->depth_pitch; + + init.fb_offset = info->fb_offset; + init.mmio_offset = info->mmio_offset; + init.ring_offset = info->ring_offset; + init.ring_rptr_offset = info->ring_rptr_offset; + init.buffers_offset = info->buffers_offset; + init.agp_textures_offset = info->agp_textures_offset; + + if ( ioctl( fd, DRM_IOCTL_RADEON_CP_INIT, &init ) ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonCleanupCP( int fd ) +{ + drm_radeon_init_t init; + + memset( &init, 0, sizeof(drm_radeon_init_t) ); + + init.func = RADEON_CLEANUP_CP; + + if ( ioctl( fd, DRM_IOCTL_RADEON_CP_INIT, &init ) ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonStartCP( int fd ) +{ + if ( ioctl( fd, DRM_IOCTL_RADEON_CP_START, NULL ) ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonStopCP( int fd ) +{ + drm_radeon_cp_stop_t stop; + int ret, i = 0; + + stop.flush = 1; + stop.idle = 1; + + ret = ioctl( fd, DRM_IOCTL_RADEON_CP_STOP, &stop ); + + if ( ret && errno != EBUSY ) + return -errno; + + stop.flush = 0; + + do { + ret = ioctl( fd, DRM_IOCTL_RADEON_CP_STOP, &stop ); + } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY ); + + if ( ret && errno != EBUSY ) + return -errno; + + stop.idle = 0; + + if ( ioctl( fd, DRM_IOCTL_RADEON_CP_STOP, &stop ) ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonResetCP( int fd ) +{ + if ( ioctl( fd, DRM_IOCTL_RADEON_CP_RESET, NULL ) ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonWaitForIdleCP( int fd ) +{ + int ret, i = 0; + + do { + ret = ioctl( fd, DRM_IOCTL_RADEON_CP_IDLE, NULL ); + } while ( ret && errno == EBUSY && i++ < RADEON_IDLE_RETRY ); + + if ( ret == 0 ) { + return 0; + } else { + return -errno; + } +} + +int drmRadeonEngineReset( int fd ) +{ + if ( ioctl( fd, DRM_IOCTL_RADEON_RESET, NULL ) ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonFullScreen( int fd, int enable ) +{ + drm_radeon_fullscreen_t fs; + + if ( enable ) { + fs.func = RADEON_INIT_FULLSCREEN; + } else { + fs.func = RADEON_CLEANUP_FULLSCREEN; + } + + if ( ioctl( fd, DRM_IOCTL_RADEON_FULLSCREEN, &fs ) ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonSwapBuffers( int fd ) +{ + if ( ioctl( fd, DRM_IOCTL_RADEON_SWAP, NULL ) ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonClear( int fd, unsigned int flags, + int x, int y, int w, int h, + unsigned int clear_color, + unsigned int clear_depth ) +{ + drm_radeon_clear_t clear; + + clear.flags = flags; + clear.x = x; + clear.y = y; + clear.w = w; + clear.h = h; + clear.clear_color = clear_color; + clear.clear_depth = clear_depth; + + /* We can remove this when we do real depth clears, instead of + * rendering a rectangle into the depth buffer. This prevents + * floating point calculations being done in the kernel. + */ + clear.rect.f[CLEAR_X1] = (float)x; + clear.rect.f[CLEAR_Y1] = (float)y; + clear.rect.f[CLEAR_X2] = (float)x + w; + clear.rect.f[CLEAR_Y2] = (float)y + h; + clear.rect.f[CLEAR_DEPTH] = (float)clear_depth; + + if ( ioctl( fd, DRM_IOCTL_RADEON_CLEAR, &clear ) < 0 ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonFlushVertexBuffer( int fd, int prim, int index, + int count, int discard ) +{ + drm_radeon_vertex_t v; + + v.prim = prim; + v.idx = index; + v.count = count; + v.discard = discard; + + if ( ioctl( fd, DRM_IOCTL_RADEON_VERTEX, &v ) < 0 ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonFlushIndices( int fd, int prim, int index, + int start, int end, int discard ) +{ + drm_radeon_indices_t elts; + + elts.prim = prim; + elts.idx = index; + elts.start = start; + elts.end = end; + elts.discard = discard; + + if ( ioctl( fd, DRM_IOCTL_RADEON_INDICES, &elts ) < 0 ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonTextureBlit( int fd, int index, + int offset, int pitch, int format, + int x, int y, int width, int height ) +{ + drm_radeon_blit_t blit; + + blit.idx = index; + blit.offset = offset; + blit.pitch = pitch; + blit.format = format; + blit.x = x; + blit.y = y; + blit.width = width; + blit.height = height; + + if ( ioctl( fd, DRM_IOCTL_RADEON_BLIT, &blit ) < 0 ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonPolygonStipple( int fd, unsigned int *mask ) +{ + drm_radeon_stipple_t stipple; + + stipple.mask = mask; + + if ( ioctl( fd, DRM_IOCTL_RADEON_STIPPLE, &stipple ) < 0 ) { + return -errno; + } else { + return 0; + } +} + +int drmRadeonFlushIndirectBuffer( int fd, int index, + int start, int end, int discard ) +{ + drm_radeon_indirect_t ind; + + ind.idx = index; + ind.start = start; + ind.end = end; + ind.discard = discard; + + if ( ioctl( fd, DRM_IOCTL_RADEON_INDIRECT, &ind ) < 0 ) { + return -errno; + } else { + return 0; + } +} diff --git a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSiS.c b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSiS.c index d626f57c5..501ac3ac8 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSiS.c +++ b/xc/programs/Xserver/hw/xfree86/os-support/linux/drm/xf86drmSiS.c @@ -46,7 +46,9 @@ extern int xf86RemoveSIGIOHandler(int fd); #include <sys/sysmacros.h> /* for makedev() */ #endif #include "xf86drm.h" +#define CONFIG_DRM_SIS #include "drm.h" +#undef CONFIG_DRM_SIS Bool drmSiSAgpInit(int driSubFD, int offset, int size) { diff --git a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h index 3049b7264..dc3d262d4 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/shared/drm/kernel/drm.h @@ -82,6 +82,7 @@ typedef struct drm_clip_rect { #include "mga_drm.h" #include "i810_drm.h" #include "r128_drm.h" +#include "radeon_drm.h" #ifdef CONFIG_DRM_SIS #include "sis_drm.h" #endif @@ -297,100 +298,117 @@ typedef struct drm_agp_info { unsigned short id_device; } drm_agp_info_t; -#define DRM_IOCTL_BASE 'd' -#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) -#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) -#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) -#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) - - -#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) -#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) -#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t) -#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t) - -#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t) -#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t) -#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t) -#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t) -#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t) -#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t) -#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t) -#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t) -#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t) -#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t) -#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t) - -#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t) -#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t) -#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t) -#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t) -#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t) -#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t) -#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t) -#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t) -#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t) -#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t) -#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t) -#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t) -#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t) - -#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) -#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) -#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t) -#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t) -#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t) -#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t) -#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t) -#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) +#define DRM_IOCTL_BASE 'd' +#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr) +#define DRM_IOR(nr,size) _IOR(DRM_IOCTL_BASE,nr,size) +#define DRM_IOW(nr,size) _IOW(DRM_IOCTL_BASE,nr,size) +#define DRM_IOWR(nr,size) _IOWR(DRM_IOCTL_BASE,nr,size) + + +#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t) +#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t) +#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t) +#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t) + +#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t) +#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t) +#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t) +#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t) +#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t) +#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t) +#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t) +#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t) +#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t) +#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t) +#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t) + +#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t) +#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t) +#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t) +#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t) +#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t) +#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t) +#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t) +#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t) +#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t) +#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t) +#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t) +#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t) +#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t) + +#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30) +#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31) +#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t) +#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t) +#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t) +#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t) +#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t) /* Mga specific ioctls */ -#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) -#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) -#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) -#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) -#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) -#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) -#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) -#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t) +#define DRM_IOCTL_MGA_INIT DRM_IOW( 0x40, drm_mga_init_t) +#define DRM_IOCTL_MGA_SWAP DRM_IOW( 0x41, drm_mga_swap_t) +#define DRM_IOCTL_MGA_CLEAR DRM_IOW( 0x42, drm_mga_clear_t) +#define DRM_IOCTL_MGA_ILOAD DRM_IOW( 0x43, drm_mga_iload_t) +#define DRM_IOCTL_MGA_VERTEX DRM_IOW( 0x44, drm_mga_vertex_t) +#define DRM_IOCTL_MGA_FLUSH DRM_IOW( 0x45, drm_lock_t ) +#define DRM_IOCTL_MGA_INDICES DRM_IOW( 0x46, drm_mga_indices_t) +#define DRM_IOCTL_MGA_BLIT DRM_IOW( 0x47, drm_mga_blit_t) /* I810 specific ioctls */ -#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) -#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) -#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) -#define DRM_IOCTL_I810_FLUSH DRM_IO ( 0x43) -#define DRM_IOCTL_I810_GETAGE DRM_IO ( 0x44) -#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t) -#define DRM_IOCTL_I810_SWAP DRM_IO ( 0x46) -#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) -#define DRM_IOCTL_I810_DOCOPY DRM_IO ( 0x48) +#define DRM_IOCTL_I810_INIT DRM_IOW( 0x40, drm_i810_init_t) +#define DRM_IOCTL_I810_VERTEX DRM_IOW( 0x41, drm_i810_vertex_t) +#define DRM_IOCTL_I810_CLEAR DRM_IOW( 0x42, drm_i810_clear_t) +#define DRM_IOCTL_I810_FLUSH DRM_IO( 0x43) +#define DRM_IOCTL_I810_GETAGE DRM_IO( 0x44) +#define DRM_IOCTL_I810_GETBUF DRM_IOWR(0x45, drm_i810_dma_t) +#define DRM_IOCTL_I810_SWAP DRM_IO( 0x46) +#define DRM_IOCTL_I810_COPY DRM_IOW( 0x47, drm_i810_copy_t) +#define DRM_IOCTL_I810_DOCOPY DRM_IO( 0x48) /* Rage 128 specific ioctls */ -#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) -#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) -#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) -#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) -#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) -#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) -#define DRM_IOCTL_R128_SWAP DRM_IO( 0x47) -#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x48, drm_r128_clear_t) -#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x49, drm_r128_vertex_t) -#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4a, drm_r128_indices_t) -#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4b, drm_r128_blit_t) -#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4c, drm_r128_depth_t) -#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4d, drm_r128_stipple_t) -#define DRM_IOCTL_R128_PACKET DRM_IOWR(0x4e, drm_r128_packet_t) +#define DRM_IOCTL_R128_INIT DRM_IOW( 0x40, drm_r128_init_t) +#define DRM_IOCTL_R128_CCE_START DRM_IO( 0x41) +#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( 0x42, drm_r128_cce_stop_t) +#define DRM_IOCTL_R128_CCE_RESET DRM_IO( 0x43) +#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_R128_RESET DRM_IO( 0x46) +#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( 0x47, drm_r128_fullscreen_t) +#define DRM_IOCTL_R128_SWAP DRM_IO( 0x48) +#define DRM_IOCTL_R128_CLEAR DRM_IOW( 0x49, drm_r128_clear_t) +#define DRM_IOCTL_R128_VERTEX DRM_IOW( 0x4a, drm_r128_vertex_t) +#define DRM_IOCTL_R128_INDICES DRM_IOW( 0x4b, drm_r128_indices_t) +#define DRM_IOCTL_R128_BLIT DRM_IOW( 0x4c, drm_r128_blit_t) +#define DRM_IOCTL_R128_DEPTH DRM_IOW( 0x4d, drm_r128_depth_t) +#define DRM_IOCTL_R128_STIPPLE DRM_IOW( 0x4e, drm_r128_stipple_t) +#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(0x4f, drm_r128_indirect_t) + +/* Radeon specific ioctls */ +#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( 0x40, drm_radeon_init_t) +#define DRM_IOCTL_RADEON_CP_START DRM_IO( 0x41) +#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( 0x42, drm_radeon_cp_stop_t) +#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( 0x43) +#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( 0x44) +#define DRM_IOCTL_RADEON_RESET DRM_IO( 0x45) +#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( 0x46, drm_radeon_fullscreen_t) +#define DRM_IOCTL_RADEON_SWAP DRM_IO( 0x47) +#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( 0x48, drm_radeon_clear_t) +#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( 0x49, drm_radeon_vertex_t) +#define DRM_IOCTL_RADEON_INDICES DRM_IOW( 0x4a, drm_radeon_indices_t) +#define DRM_IOCTL_RADEON_BLIT DRM_IOW( 0x4b, drm_radeon_blit_t) +#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( 0x4c, drm_radeon_stipple_t) +#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(0x4d, drm_radeon_indirect_t) #ifdef CONFIG_DRM_SIS /* SiS specific ioctls */ -#define SIS_IOCTL_FB_ALLOC DRM_IOWR( 0x44, drm_sis_mem_t) -#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) -#define SIS_IOCTL_AGP_INIT DRM_IOWR( 0x53, drm_sis_agp_t) -#define SIS_IOCTL_AGP_ALLOC DRM_IOWR( 0x54, drm_sis_mem_t) -#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) -#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) -#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) -#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) +#define SIS_IOCTL_FB_ALLOC DRM_IOWR(0x44, drm_sis_mem_t) +#define SIS_IOCTL_FB_FREE DRM_IOW( 0x45, drm_sis_mem_t) +#define SIS_IOCTL_AGP_INIT DRM_IOWR(0x53, drm_sis_agp_t) +#define SIS_IOCTL_AGP_ALLOC DRM_IOWR(0x54, drm_sis_mem_t) +#define SIS_IOCTL_AGP_FREE DRM_IOW( 0x55, drm_sis_mem_t) +#define SIS_IOCTL_FLIP DRM_IOW( 0x48, drm_sis_flip_t) +#define SIS_IOCTL_FLIP_INIT DRM_IO( 0x49) +#define SIS_IOCTL_FLIP_FINAL DRM_IO( 0x50) #endif #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h index 8d799f152..6d7fad592 100644 --- a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h @@ -23,7 +23,9 @@ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. * - * Author: Kevin E. Martin <kevin@precisioninsight.com> + * Author: + * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> * * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h,v 3.5 2000/12/12 17:17:13 dawes Exp $ * @@ -47,7 +49,7 @@ typedef struct { int sarea_priv_offset; int is_pci; int cce_mode; - int cce_secure; + int cce_secure; /* FIXME: Deprecated, we should remove this */ int ring_size; int usec_timeout; @@ -76,6 +78,8 @@ extern int drmR128WaitForIdleCCE( int fd ); extern int drmR128EngineReset( int fd ); +extern int drmR128FullScreen( int fd, int enable ); + extern int drmR128SwapBuffers( int fd ); extern int drmR128Clear( int fd, unsigned int flags, int x, int y, int w, int h, @@ -87,7 +91,7 @@ extern int drmR128FlushVertexBuffer( int fd, int prim, int indx, extern int drmR128FlushIndices( int fd, int prim, int indx, int start, int end, int discard ); -extern int drmR128TextureBlit( int fd, int indx, +extern int drmR128TextureBlit( int fd, int index, int offset, int pitch, int format, int x, int y, int width, int height ); @@ -104,7 +108,7 @@ extern int drmR128ReadDepthPixels( int fd, int n, extern int drmR128PolygonStipple( int fd, unsigned int *mask ); -extern int drmR128SubmitPacket( int fd, void *buffer, - int *count, int flags ); +extern int drmR128FlushIndirectBuffer( int fd, int index, + int start, int end, int discard ); #endif diff --git a/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h new file mode 100644 index 000000000..8a1d17f8d --- /dev/null +++ b/xc/programs/Xserver/hw/xfree86/os-support/xf86drmRadeon.h @@ -0,0 +1,99 @@ +/* xf86drmRadeon.h -- OS-independent header for Radeon DRM user-level + * library interface + * + * Copyright 2000 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 + * 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 (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 NONINFRINGEMENT. IN NO EVENT SHALL + * PRECISION INSIGHT AND/OR ITS 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. + * + * Author: + * Gareth Hughes <gareth@valinux.com> + * Kevin E. Martin <martin@valinux.com> + * + * $XFree86$ + * + */ + +#ifndef _XF86DRI_RADEON_H_ +#define _XF86DRI_RADEON_H_ + +/* WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (radeon_drm.h) + */ + +#define DRM_RADEON_FRONT 0x1 +#define DRM_RADEON_BACK 0x2 +#define DRM_RADEON_DEPTH 0x4 + +typedef struct { + int sarea_priv_offset; + int is_pci; + int cp_mode; + int agp_size; + int ring_size; + int usec_timeout; + + unsigned int fb_bpp; + unsigned int front_offset, front_pitch; + unsigned int back_offset, back_pitch; + unsigned int depth_bpp; + unsigned int depth_offset, depth_pitch; + + unsigned int fb_offset; + unsigned int mmio_offset; + unsigned int ring_offset; + unsigned int ring_rptr_offset; + unsigned int buffers_offset; + unsigned int agp_textures_offset; +} drmRadeonInit; + +extern int drmRadeonInitCP( int fd, drmRadeonInit *info ); +extern int drmRadeonCleanupCP( int fd ); + +extern int drmRadeonStartCP( int fd ); +extern int drmRadeonStopCP( int fd ); +extern int drmRadeonResetCP( int fd ); +extern int drmRadeonWaitForIdleCP( int fd ); + +extern int drmRadeonEngineReset( int fd ); + +extern int drmRadeonFullScreen( int fd, int enable ); + +extern int drmRadeonSwapBuffers( int fd ); +extern int drmRadeonClear( int fd, unsigned int flags, + int x, int y, int w, int h, + unsigned int clear_color, + unsigned int clear_depth ); + +extern int drmRadeonFlushVertexBuffer( int fd, int prim, int index, + int count, int discard ); +extern int drmRadeonFlushIndices( int fd, int prim, int index, + int start, int end, int discard ); + +extern int drmRadeonTextureBlit( int fd, int index, + int offset, int pitch, int format, + int x, int y, int width, int height ); + +extern int drmRadeonPolygonStipple( int fd, unsigned int *mask ); + +extern int drmRadeonFlushIndirectBuffer( int fd, int index, + int start, int end, int discard ); + +#endif |