From 5df82c82bd53db90eb72c5aad4dd20cf6f1116b1 Mon Sep 17 00:00:00 2001 From: Brian Paul Date: Fri, 22 Aug 2003 20:11:43 +0000 Subject: patch to import Jon Smirl's work from Bitkeeper --- src/mesa/drivers/dri/r128/Makefile.X11 | 116 ++ src/mesa/drivers/dri/r128/r128_context.c | 335 ++++++ src/mesa/drivers/dri/r128/r128_context.h | 270 +++++ src/mesa/drivers/dri/r128/r128_dd.c | 148 +++ src/mesa/drivers/dri/r128/r128_dd.h | 44 + src/mesa/drivers/dri/r128/r128_ioctl.c | 812 +++++++++++++ src/mesa/drivers/dri/r128/r128_ioctl.h | 146 +++ src/mesa/drivers/dri/r128/r128_lock.c | 123 ++ src/mesa/drivers/dri/r128/r128_lock.h | 111 ++ src/mesa/drivers/dri/r128/r128_screen.c | 357 ++++++ src/mesa/drivers/dri/r128/r128_screen.h | 84 ++ src/mesa/drivers/dri/r128/r128_span.c | 475 ++++++++ src/mesa/drivers/dri/r128/r128_span.h | 44 + src/mesa/drivers/dri/r128/r128_state.c | 1239 ++++++++++++++++++++ src/mesa/drivers/dri/r128/r128_state.h | 54 + src/mesa/drivers/dri/r128/r128_tex.c | 598 ++++++++++ src/mesa/drivers/dri/r128/r128_tex.h | 88 ++ src/mesa/drivers/dri/r128/r128_texmem.c | 302 +++++ src/mesa/drivers/dri/r128/r128_texobj.h | 69 ++ src/mesa/drivers/dri/r128/r128_texstate.c | 652 +++++++++++ src/mesa/drivers/dri/r128/r128_tris.c | 721 ++++++++++++ src/mesa/drivers/dri/r128/r128_tris.h | 48 + src/mesa/drivers/dri/r128/r128_vb.c | 522 +++++++++ src/mesa/drivers/dri/r128/r128_vb.h | 74 ++ src/mesa/drivers/dri/r128/server/r128.h | 566 +++++++++ src/mesa/drivers/dri/r128/server/r128_common.h | 169 +++ src/mesa/drivers/dri/r128/server/r128_dri.c | 1165 ++++++++++++++++++ src/mesa/drivers/dri/r128/server/r128_dri.h | 103 ++ src/mesa/drivers/dri/r128/server/r128_macros.h | 135 +++ src/mesa/drivers/dri/r128/server/r128_reg.h | 1431 +++++++++++++++++++++++ src/mesa/drivers/dri/r128/server/r128_sarea.h | 195 +++ src/mesa/drivers/dri/r128/server/r128_version.h | 60 + 32 files changed, 11256 insertions(+) create mode 100644 src/mesa/drivers/dri/r128/Makefile.X11 create mode 100644 src/mesa/drivers/dri/r128/r128_context.c create mode 100644 src/mesa/drivers/dri/r128/r128_context.h create mode 100644 src/mesa/drivers/dri/r128/r128_dd.c create mode 100644 src/mesa/drivers/dri/r128/r128_dd.h create mode 100644 src/mesa/drivers/dri/r128/r128_ioctl.c create mode 100644 src/mesa/drivers/dri/r128/r128_ioctl.h create mode 100644 src/mesa/drivers/dri/r128/r128_lock.c create mode 100644 src/mesa/drivers/dri/r128/r128_lock.h create mode 100644 src/mesa/drivers/dri/r128/r128_screen.c create mode 100644 src/mesa/drivers/dri/r128/r128_screen.h create mode 100644 src/mesa/drivers/dri/r128/r128_span.c create mode 100644 src/mesa/drivers/dri/r128/r128_span.h create mode 100644 src/mesa/drivers/dri/r128/r128_state.c create mode 100644 src/mesa/drivers/dri/r128/r128_state.h create mode 100644 src/mesa/drivers/dri/r128/r128_tex.c create mode 100644 src/mesa/drivers/dri/r128/r128_tex.h create mode 100644 src/mesa/drivers/dri/r128/r128_texmem.c create mode 100644 src/mesa/drivers/dri/r128/r128_texobj.h create mode 100644 src/mesa/drivers/dri/r128/r128_texstate.c create mode 100644 src/mesa/drivers/dri/r128/r128_tris.c create mode 100644 src/mesa/drivers/dri/r128/r128_tris.h create mode 100644 src/mesa/drivers/dri/r128/r128_vb.c create mode 100644 src/mesa/drivers/dri/r128/r128_vb.h create mode 100644 src/mesa/drivers/dri/r128/server/r128.h create mode 100644 src/mesa/drivers/dri/r128/server/r128_common.h create mode 100644 src/mesa/drivers/dri/r128/server/r128_dri.c create mode 100644 src/mesa/drivers/dri/r128/server/r128_dri.h create mode 100644 src/mesa/drivers/dri/r128/server/r128_macros.h create mode 100644 src/mesa/drivers/dri/r128/server/r128_reg.h create mode 100644 src/mesa/drivers/dri/r128/server/r128_sarea.h create mode 100644 src/mesa/drivers/dri/r128/server/r128_version.h (limited to 'src/mesa/drivers/dri/r128') diff --git a/src/mesa/drivers/dri/r128/Makefile.X11 b/src/mesa/drivers/dri/r128/Makefile.X11 new file mode 100644 index 0000000000..8ae146af91 --- /dev/null +++ b/src/mesa/drivers/dri/r128/Makefile.X11 @@ -0,0 +1,116 @@ +# $Id: Makefile.X11,v 1.1 2003/08/22 20:11:44 brianp Exp $ + +# Mesa 3-D graphics library +# Version: 5.0 +# Copyright (C) 1995-2002 Brian Paul + +TOP = ../../../../.. + +default: linux-solo + +SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver +MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini + +DEFINES += \ + -D_HAVE_SWRAST=1 \ + -D_HAVE_SWTNL=1 \ + -D_HAVE_SANITY=1 \ + -D_HAVE_CODEGEN=1 \ + -D_HAVE_LIGHTING=1 \ + -D_HAVE_TEXGEN=1 \ + -D_HAVE_USERCLIP=1 \ + -DGLX_DIRECT_RENDERING + +MINIGLX_SOURCES = server/r128_dri.c + +DRIVER_SOURCES = \ + r128_context.c \ + r128_lock.c \ + r128_state.c \ + r128_texstate.c \ + r128_dd.c \ + r128_screen.c \ + r128_tex.c \ + r128_tris.c \ + r128_ioctl.c \ + r128_span.c \ + r128_texmem.c \ + r128_vb.c \ + ../common/mm.c \ + ../common/utils.c \ + ../common/texmem.c \ + ../common/vblank.c + +INCLUDES = $(MINIGLX_INCLUDES) \ + $(SHARED_INCLUDES) + + +C_SOURCES = $(DRIVER_SOURCES) \ + $(MINIGLX_SOURCES) + +MESA_MODULES = $(TOP)/src/mesa/mesa.a + + +ifeq ($(WINDOW_SYSTEM),dri) +WINOBJ=$(MESABUILDDIR)/dri/dri.a +WINLIB= +else +WINOBJ= +WINLIB=-L$(MESA)/src/glx/mini +endif + +ASM_SOURCES = +OBJECTS = $(C_SOURCES:.c=.o) \ + $(ASM_SOURCES:.S=.o) + +### Include directories + +INCLUDE_DIRS = \ + -I$(TOP)/include \ + -I$(TOP)/src/mesa \ + -I$(TOP)/src/mesa/main \ + -I$(TOP)/src/mesa/glapi \ + -I$(TOP)/src/mesa/math \ + -I$(TOP)/src/mesa/transform \ + -I$(TOP)/src/mesa/swrast \ + -I$(TOP)/src/mesa/swrast_setup + + +##### RULES ##### + +.c.o: + $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + +.S.o: + $(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@ + + +##### TARGETS ##### + +targets: depend r128_dri.so + +r128_dri.so: $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.X11 + rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc $(GL_LIB_DEPS) + rm -f $(TOP)/lib/r128_dri.so && \ + install r128_dri.so $(TOP)/lib/r128_dri.so + +# Run 'make -f Makefile.X11 dep' to update the dependencies if you change +# what's included by any source file. +depend: $(C_SOURCES) $(ASM_SOURCES) + makedepend -fdepend -Y $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) \ + $(C_SOURCES) $(ASM_SOURCES) + + +# Emacs tags +tags: + etags `find . -name \*.[ch]` `find ../include` + + +# Remove .o and backup files +clean: + -rm -f *.o */*.o *~ *.o *~ *.so server/*.o + + +include $(TOP)/Make-config + +include depend diff --git a/src/mesa/drivers/dri/r128/r128_context.c b/src/mesa/drivers/dri/r128/r128_context.c new file mode 100644 index 0000000000..f7f6d7141d --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_context.c @@ -0,0 +1,335 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.c,v 1.8 2002/10/30 12:51:38 alanh 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#include "glheader.h" +#include "context.h" +#include "simple_list.h" +#include "imports.h" +#include "matrix.h" +#include "extensions.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "array_cache/acache.h" + +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" + +#include "r128_context.h" +#include "r128_ioctl.h" +#include "r128_dd.h" +#include "r128_state.h" +#include "r128_span.h" +#include "r128_tex.h" +#include "r128_tris.h" +#include "r128_vb.h" + +#include "vblank.h" +#include "utils.h" +#include "texmem.h" + +#ifndef R128_DEBUG +int R128_DEBUG = 0; +#endif + +static const char * const card_extensions[] = +{ + "GL_ARB_multitexture", + "GL_ARB_texture_env_add", + "GL_ARB_texture_mirrored_repeat", + "GL_EXT_texture_edge_clamp", + "GL_EXT_texture_env_add", + "GL_IBM_texture_mirrored_repeat", + "GL_SGIS_generate_mipmap", + "GL_SGIS_texture_edge_clamp", + NULL +}; + +static const struct dri_debug_control debug_control[] = +{ + { "ioctl", DEBUG_VERBOSE_IOCTL }, + { "verb", DEBUG_VERBOSE_MSG }, + { "dri", DEBUG_VERBOSE_DRI }, + { "2d", DEBUG_VERBOSE_2D }, + { "sync", DEBUG_ALWAYS_SYNC }, + { "api", DEBUG_VERBOSE_API }, + { NULL, 0 } +}; + +/* Create the device specific context. + */ +GLboolean r128CreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ) +{ + GLcontext *ctx, *shareCtx; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + r128ContextPtr rmesa; + r128ScreenPtr r128scrn; + int i; + + /* Allocate the r128 context */ + rmesa = (r128ContextPtr) CALLOC( sizeof(*rmesa) ); + if ( !rmesa ) + return GL_FALSE; + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((r128ContextPtr) sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + rmesa->glCtx = _mesa_create_context(glVisual, shareCtx, (void *) rmesa, GL_TRUE); + if (!rmesa->glCtx) { + FREE(rmesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = rmesa; + ctx = rmesa->glCtx; + + rmesa->driContext = driContextPriv; + rmesa->driScreen = sPriv; + rmesa->driDrawable = NULL; + 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 + + r128scrn->sarea_priv_offset); + + rmesa->CurrentTexObj[0] = NULL; + rmesa->CurrentTexObj[1] = NULL; + + (void) memset( rmesa->texture_heaps, 0, sizeof( rmesa->texture_heaps ) ); + make_empty_list( & rmesa->swapped ); + + rmesa->nr_heaps = r128scrn->numTexHeaps; + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + rmesa->texture_heaps[i] = driCreateTextureHeap( i, rmesa, + r128scrn->texSize[i], + 12, + R128_NR_TEX_REGIONS, + rmesa->sarea->texList[i], + & rmesa->sarea->texAge[i], + & rmesa->swapped, + sizeof( r128TexObj ), + (destroy_texture_object_t *) r128DestroyTexObj ); + + driSetTextureSwapCounterLocation( rmesa->texture_heaps[i], + & rmesa->c_textureSwaps ); + } + + + rmesa->RenderIndex = -1; /* Impossible value */ + rmesa->vert_buf = NULL; + rmesa->num_verts = 0; + + /* Set the maximum texture size small enough that we can guarentee that + * all texture units can bind a maximal texture and have them both in + * texturable memory at once. + */ + + ctx->Const.MaxTextureUnits = 2; + + driCalculateMaxTextureLevels( rmesa->texture_heaps, + rmesa->nr_heaps, + & ctx->Const, + 4, + 10, /* max 2D texture size is 1024x1024 */ + 0, /* 3D textures unsupported. */ + 0, /* cube textures unsupported. */ + 0, /* texture rectangles unsupported. */ + 11, + GL_FALSE ); + + /* No wide points. + */ + ctx->Const.MinPointSize = 1.0; + ctx->Const.MinPointSizeAA = 1.0; + ctx->Const.MaxPointSize = 1.0; + ctx->Const.MaxPointSizeAA = 1.0; + + /* No wide lines. + */ + ctx->Const.MinLineWidth = 1.0; + ctx->Const.MinLineWidthAA = 1.0; + ctx->Const.MaxLineWidth = 1.0; + ctx->Const.MaxLineWidthAA = 1.0; + ctx->Const.LineWidthGranularity = 1.0; + +#if ENABLE_PERF_BOXES + rmesa->boxes = (getenv( "LIBGL_PERFORMANCE_BOXES" ) != NULL); +#endif + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + + /* Install the customized pipeline: + */ +/* _tnl_destroy_pipeline( ctx ); */ +/* _tnl_install_pipeline( ctx, r128_pipeline ); */ + + /* Configure swrast to match hardware characteristics: + */ + _swrast_allow_pixel_fog( ctx, GL_FALSE ); + _swrast_allow_vertex_fog( ctx, GL_TRUE ); + + driInitExtensions( ctx, card_extensions, GL_TRUE ); + if (sPriv->drmMinor >= 4) + _mesa_enable_extension( ctx, "GL_MESA_ycbcr_texture" ); + + r128InitVB( ctx ); + r128InitTriFuncs( ctx ); + r128DDInitDriverFuncs( ctx ); + r128DDInitIoctlFuncs( ctx ); + r128DDInitStateFuncs( ctx ); + r128DDInitSpanFuncs( ctx ); + r128DDInitTextureFuncs( ctx ); + r128DDInitState( rmesa ); + + rmesa->do_irqs = (rmesa->r128Screen->irq && !getenv("R128_NO_IRQS")); + + rmesa->vblank_flags = (rmesa->do_irqs) + ? driGetDefaultVBlankFlags() : VBLANK_FLAG_NO_IRQ; + + driContextPriv->driverPrivate = (void *)rmesa; + +#if DO_DEBUG + R128_DEBUG = driParseDebugString( getenv( "R128_DEBUG" ), + debug_control ); +#endif + + return GL_TRUE; +} + +/* Destroy the device specific context. + */ +void r128DestroyContext( __DRIcontextPrivate *driContextPriv ) +{ + r128ContextPtr rmesa = (r128ContextPtr) driContextPriv->driverPrivate; + + assert(rmesa); /* should never be null */ + if ( rmesa ) { + GLboolean release_texture_heaps; + + + release_texture_heaps = (rmesa->glCtx->Shared->RefCount == 1); + + _swsetup_DestroyContext( rmesa->glCtx ); + _tnl_DestroyContext( rmesa->glCtx ); + _ac_DestroyContext( rmesa->glCtx ); + _swrast_DestroyContext( rmesa->glCtx ); + + r128FreeVB( rmesa->glCtx ); + + /* free the Mesa context */ + rmesa->glCtx->DriverCtx = NULL; + _mesa_destroy_context(rmesa->glCtx); + + if ( release_texture_heaps ) { + /* This share group is about to go away, free our private + * texture object data. + */ + int i; + + assert( is_empty_list( & rmesa->swapped ) ); + + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + driDestroyTextureHeap( rmesa->texture_heaps[ i ] ); + rmesa->texture_heaps[ i ] = NULL; + } + } + + FREE( rmesa ); + } + +#if 0 + /* Use this to force shared object profiling. */ + glx_fini_prof(); +#endif +} + + +/* Force the context `c' to be the current context and associate with it + * buffer `b'. + */ +GLboolean +r128MakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) +{ + if ( driContextPriv ) { + GET_CURRENT_CONTEXT(ctx); + r128ContextPtr oldR128Ctx = ctx ? R128_CONTEXT(ctx) : NULL; + r128ContextPtr newR128Ctx = (r128ContextPtr) driContextPriv->driverPrivate; + + if ( newR128Ctx != oldR128Ctx ) { + newR128Ctx->new_state |= R128_NEW_CONTEXT; + newR128Ctx->dirty = R128_UPLOAD_ALL; + } + + newR128Ctx->driDrawable = driDrawPriv; + + _mesa_make_current2( newR128Ctx->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate ); + + + newR128Ctx->new_state |= R128_NEW_WINDOW | R128_NEW_CLIP; + + if ( !newR128Ctx->glCtx->Viewport.Width ) { + _mesa_set_viewport(newR128Ctx->glCtx, 0, 0, + driDrawPriv->w, driDrawPriv->h); + } + } else { + _mesa_make_current( 0, 0 ); + } + + return GL_TRUE; +} + + +/* Force the context `c' to be unbound from its buffer. + */ +GLboolean +r128UnbindContext( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} diff --git a/src/mesa/drivers/dri/r128/r128_context.h b/src/mesa/drivers/dri/r128/r128_context.h new file mode 100644 index 0000000000..9c93012eb0 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_context.h @@ -0,0 +1,270 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_context.h,v 1.12 2002/12/16 16:18:52 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef __R128_CONTEXT_H__ +#define __R128_CONTEXT_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "dri_util.h" + +#include "xf86drm.h" +#include "r128_common.h" + +#include "mtypes.h" + +#include "r128_reg.h" + +#include "texmem.h" + +struct r128_context; +typedef struct r128_context r128ContextRec; +typedef struct r128_context *r128ContextPtr; + +#include "r128_lock.h" +#include "r128_texobj.h" +#include "r128_screen.h" + +/* Flags for what context state needs to be updated: + */ +#define R128_NEW_ALPHA 0x0001 +#define R128_NEW_DEPTH 0x0002 +#define R128_NEW_FOG 0x0004 +#define R128_NEW_CLIP 0x0008 +#define R128_NEW_CULL 0x0010 +#define R128_NEW_MASKS 0x0020 +#define R128_NEW_RENDER_NOT 0x0040 +#define R128_NEW_WINDOW 0x0080 +#define R128_NEW_CONTEXT 0x0100 +#define R128_NEW_ALL 0x01ff + +/* Flags for software fallback cases: + */ +#define R128_FALLBACK_TEXTURE 0x0001 +#define R128_FALLBACK_DRAW_BUFFER 0x0002 +#define R128_FALLBACK_READ_BUFFER 0x0004 +#define R128_FALLBACK_STENCIL 0x0008 +#define R128_FALLBACK_RENDER_MODE 0x0010 +#define R128_FALLBACK_MULTIDRAW 0x0020 +#define R128_FALLBACK_LOGICOP 0x0040 +#define R128_FALLBACK_SEP_SPECULAR 0x0080 +#define R128_FALLBACK_BLEND_EQ 0x0100 +#define R128_FALLBACK_BLEND_FUNC 0x0200 + + +/* Use the templated vertex format: + */ +#define TAG(x) r128##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +/* Reasons why the GL_BLEND fallback mightn't work: + */ +#define R128_BLEND_ENV_COLOR 0x1 +#define R128_BLEND_MULTITEX 0x2 + +/* Subpixel offsets for window coordinates (triangles): + */ +#define SUBPIXEL_X (0.0F) +#define SUBPIXEL_Y (0.125F) + + +typedef void (*r128_tri_func)( r128ContextPtr, + r128Vertex *, + r128Vertex *, + r128Vertex * ); + +typedef void (*r128_line_func)( r128ContextPtr, + r128Vertex *, + r128Vertex * ); + +typedef void (*r128_point_func)( r128ContextPtr, + r128Vertex * ); + + +struct r128_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; + + /* Temporaries for translating away float colors: + */ + struct gl_client_array UbyteColor; + struct gl_client_array UbyteSecondaryColor; + + GLuint NewGLState; + GLuint Fallback; + GLuint SetupIndex; + GLuint SetupNewInputs; + GLuint RenderIndex; + GLfloat hw_viewport[16]; + GLfloat depth_scale; + GLuint vertex_size; + GLuint vertex_stride_shift; + GLuint vertex_format; + GLuint num_verts; + GLubyte *verts; + + 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]; + GLuint tex_combine[2]; + GLuint blend_flags; + GLuint env_color; + + /* Texture object bookkeeping + */ + unsigned nr_heaps; + driTexHeap * texture_heaps[ R128_NR_TEX_HEAPS ]; + driTextureObject swapped; + + r128TexObjPtr CurrentTexObj[2]; + + /* Fallback rasterization functions + */ + r128_point_func draw_point; + r128_line_func draw_line; + r128_tri_func draw_tri; + + /* Vertex buffers + */ + drmBufPtr vert_buf; + + GLuint hw_primitive; + GLenum render_primitive; + + /* Page flipping + */ + GLuint doPageFlip; + + /* Busy waiting + */ + GLuint do_irqs; + + /* Drawable, cliprect and scissor information + */ + GLint drawOffset, drawPitch; + GLint readOffset, readPitch; + + GLuint numClipRects; /* Cliprects for the draw buffer */ + XF86DRIClipRectPtr pClipRects; + + GLuint scissor; + XF86DRIClipRectRec ScissorRect; /* Current software scissor */ + + /* Mirrors of some DRI state + */ + __DRIcontextPrivate *driContext; /* DRI context */ + __DRIscreenPrivate *driScreen; /* DRI screen */ + __DRIdrawablePrivate *driDrawable; /* DRI drawable bound to this ctx */ + + unsigned int lastStamp; /* mirror driDrawable->lastStamp */ + + drmContext hHWContext; + drmLock *driHwLock; + int driFd; + + 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; + + /* VBI + */ + GLuint vbl_seq; + GLuint vblank_flags; +}; + +#define R128_CONTEXT(ctx) ((r128ContextPtr)(ctx->DriverCtx)) + +#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( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ); + +extern void r128DestroyContext( __DRIcontextPrivate * ); + +extern GLboolean r128MakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ); + +extern GLboolean r128UnbindContext( __DRIcontextPrivate *driContextPriv ); + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 0 +#define ENABLE_PERF_BOXES 0 + +#if DO_DEBUG +extern int R128_DEBUG; +#else +#define R128_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 /* __R128_CONTEXT_H__ */ diff --git a/src/mesa/drivers/dri/r128/r128_dd.c b/src/mesa/drivers/dri/r128/r128_dd.c new file mode 100644 index 0000000000..b64c26b4bd --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_dd.c @@ -0,0 +1,148 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.c,v 1.15 2002/10/30 12:51:38 alanh 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#include "r128_context.h" +#include "r128_ioctl.h" +#include "r128_state.h" +#include "r128_vb.h" +#include "r128_dd.h" + +#include "context.h" + +#include "utils.h" + +#define DRIVER_DATE "20030328" + + +/* Return the width and height of the current color buffer. + */ +static void r128DDGetBufferSize( GLframebuffer *buffer, + GLuint *width, GLuint *height ) +{ + GET_CURRENT_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + LOCK_HARDWARE( rmesa ); + *width = rmesa->driDrawable->w; + *height = rmesa->driDrawable->h; + UNLOCK_HARDWARE( rmesa ); +} + +/* Return various strings for glGetString(). + */ +static const GLubyte *r128DDGetString( GLcontext *ctx, GLenum name ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + static char buffer[128]; + unsigned offset; + const char * card_name = "Rage 128"; + GLuint agp_mode = rmesa->r128Screen->IsPCI ? 0 : + rmesa->r128Screen->AGPMode; + + switch ( name ) { + case GL_VENDOR: + return (GLubyte *)"VA Linux Systems, Inc."; + + case GL_RENDERER: + /* Select the spefic chipset. + */ + if ( R128_IS_PRO( rmesa ) ) { + card_name = "Rage 128 Pro"; + } + else if ( R128_IS_MOBILITY( rmesa ) ) { + card_name = "Rage 128 Mobility"; + } + + offset = driGetRendererString( buffer, card_name, DRIVER_DATE, + agp_mode ); + + return (GLubyte *)buffer; + + default: + return NULL; + } +} + +/* Send all commands to the hardware. If vertex buffers or indirect + * buffers are in use, then we need to make sure they are sent to the + * hardware. All commands that are normally sent to the ring are + * already considered `flushed'. + */ +static void r128DDFlush( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + +#if ENABLE_PERF_BOXES + if ( rmesa->boxes ) { + LOCK_HARDWARE( rmesa ); + r128PerformanceBoxesLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); + } + + /* Log the performance counters if necessary */ + r128PerformanceCounters( rmesa ); +#endif +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +static void r128DDFinish( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + rmesa->c_drawWaits++; +#endif + + r128DDFlush( ctx ); + r128WaitForIdle( rmesa ); +} + + +/* Initialize the driver's misc functions. + */ +void r128DDInitDriverFuncs( GLcontext *ctx ) +{ + ctx->Driver.GetBufferSize = r128DDGetBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.GetString = r128DDGetString; + ctx->Driver.Finish = r128DDFinish; + ctx->Driver.Flush = r128DDFlush; + ctx->Driver.Error = NULL; +} diff --git a/src/mesa/drivers/dri/r128/r128_dd.h b/src/mesa/drivers/dri/r128/r128_dd.h new file mode 100644 index 0000000000..b8fc7ad9bf --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_dd.h @@ -0,0 +1,44 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_dd.h,v 1.3 2001/01/08 01:07:20 martin Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#ifndef __R128_DD_H__ +#define __R128_DD_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128DDInitDriverFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.c b/src/mesa/drivers/dri/r128/r128_ioctl.c new file mode 100644 index 0000000000..c5843473e1 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_ioctl.c @@ -0,0 +1,812 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.c,v 1.10 2002/12/16 16:18:53 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * + */ +#include + +#include "r128_context.h" +#include "r128_state.h" +#include "r128_ioctl.h" +#include "r128_macros.h" + +#include "imports.h" +#include "macros.h" + +#include "swrast/swrast.h" + +#include "vblank.h" + +#define R128_TIMEOUT 2048 +#define R128_IDLE_RETRY 32 + + +/* ============================================================= + * Hardware vertex buffer handling + */ + +/* Get a new VB from the pool of vertex buffers in AGP space. + */ +drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa ) +{ + int fd = rmesa->r128Screen->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 = R128_BUFFER_SIZE; + dma.request_list = &index; + dma.request_sizes = &size; + dma.granted_count = 0; + + while ( !buf && ( to++ < R128_TIMEOUT ) ) { + ret = drmDMA( fd, &dma ); + + if ( ret == 0 ) { + buf = &rmesa->r128Screen->buffers->list[index]; + buf->used = 0; +#if ENABLE_PERF_BOXES + /* Bump the performance counter */ + rmesa->c_vertexBuffers++; +#endif + return buf; + } + } + + if ( !buf ) { + drmCommandNone( fd, DRM_R128_CCE_RESET); + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "Error: Could not get new VB... exiting\n" ); + exit( -1 ); + } + + return buf; +} + +void r128FlushVerticesLocked( r128ContextPtr rmesa ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + int nbox = rmesa->numClipRects; + drmBufPtr buffer = rmesa->vert_buf; + int count = rmesa->num_verts; + int prim = rmesa->hw_primitive; + int fd = rmesa->driScreen->fd; + drmR128Vertex vertex; + int i; + + rmesa->num_verts = 0; + rmesa->vert_buf = NULL; + + if ( !buffer ) + return; + + if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) + r128EmitHwStateLocked( rmesa ); + + if ( !nbox ) + count = 0; + + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + + if ( !count || !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + vertex.prim = prim; + vertex.idx = buffer->idx; + vertex.count = count; + vertex.discard = 1; + drmCommandWrite( fd, DRM_R128_VERTEX, &vertex, sizeof(drmR128Vertex) ); + } + else + { + for ( i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + int discard = 0; + + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++ ) { + *b++ = pbox[i]; + } + + /* Finished with the buffer? + */ + if ( nr == nbox ) { + discard = 1; + } + + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + + vertex.prim = prim; + vertex.idx = buffer->idx; + vertex.count = count; + vertex.discard = discard; + drmCommandWrite( fd, DRM_R128_VERTEX, &vertex, sizeof(drmR128Vertex) ); + } + } + + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + + + + + +/* ================================================================ + * Texture uploads + */ + +void r128FireBlitLocked( r128ContextPtr rmesa, drmBufPtr buffer, + GLint offset, GLint pitch, GLint format, + GLint x, GLint y, GLint width, GLint height ) +{ + drmR128Blit blit; + GLint ret; + + blit.idx = buffer->idx; + blit.offset = offset; + blit.pitch = pitch; + blit.format = format; + blit.x = x; + blit.y = y; + blit.width = width; + blit.height = height; + + ret = drmCommandWrite( rmesa->driFd, DRM_R128_BLIT, + &blit, sizeof(drmR128Blit) ); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "DRM_R128_BLIT: return = %d\n", ret ); + exit( 1 ); + } +} + + +/* ================================================================ + * SwapBuffers with client-side throttling + */ + +static void delay( void ) { +/* Prevent an optimizing compiler from removing a spin loop */ +} + +#define R128_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. + */ +static int r128WaitForFrameCompletion( r128ContextPtr rmesa ) +{ + unsigned char *R128MMIO = rmesa->r128Screen->mmio.map; + CARD32 frame; + int i; + int wait = 0; + + while ( 1 ) { + frame = INREG( R128_LAST_FRAME_REG ); + if ( rmesa->sarea->last_frame - frame <= R128_MAX_OUTSTANDING ) { + break; + } + + /* Spin in place a bit so we aren't hammering the register */ + wait++; + for ( i = 0 ; i < 1024 ; i++ ) { + delay(); + } + } + + return wait; +} + +/* Copy the back color buffer to the front color buffer. + */ +void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ) +{ + r128ContextPtr rmesa; + GLint nbox, i, ret; + GLboolean missed_target; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n********************************\n" ); + fprintf( stderr, "\n%s( %p )\n\n", + __FUNCTION__, rmesa->glCtx ); + fflush( stderr ); + } + + 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; + } + + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); + LOCK_HARDWARE( rmesa ); + + nbox = dPriv->numClipRects; /* must be in locked region */ + + for ( i = 0 ; i < nbox ; ) { + GLint nr = MIN2( i + R128_NR_SAREA_CLIPRECTS , nbox ); + XF86DRIClipRectPtr box = dPriv->pClipRects; + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + GLint n = 0; + + for ( ; i < nr ; i++ ) { + *b++ = *(XF86DRIClipRectRec *)&box[i]; + n++; + } + rmesa->sarea->nbox = n; + + ret = drmCommandNone( rmesa->driFd, DRM_R128_SWAP ); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "DRM_R128_SWAP: return = %d\n", ret ); + exit( 1 ); + } + } + + if ( R128_DEBUG & DEBUG_ALWAYS_SYNC ) { + i = 0; + do { + ret = drmCommandNone(rmesa->driFd, DRM_R128_CCE_IDLE); + } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); + } + + UNLOCK_HARDWARE( rmesa ); + + 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 +} + +void r128PageFlip( const __DRIdrawablePrivate *dPriv ) +{ + r128ContextPtr rmesa; + GLint ret; + GLboolean missed_target; + + assert(dPriv); + assert(dPriv->driContextPriv); + assert(dPriv->driContextPriv->driverPrivate); + + rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "\n%s( %p ): page=%d\n\n", + __FUNCTION__, rmesa->glCtx, rmesa->sarea->pfCurrentPage ); + } + + 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; + } + + UNLOCK_HARDWARE( rmesa ); + driWaitForVBlank( dPriv, &rmesa->vbl_seq, rmesa->vblank_flags, &missed_target ); + LOCK_HARDWARE( rmesa ); + + /* The kernel will have been initialized to perform page flipping + * on a swapbuffers ioctl. + */ + ret = drmCommandNone( rmesa->driFd, DRM_R128_FLIP ); + + UNLOCK_HARDWARE( rmesa ); + + if ( ret ) { + fprintf( stderr, "DRM_R128_FLIP: return = %d\n", ret ); + exit( 1 ); + } + + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->drawOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->r128Screen->frontPitch; + } else { + rmesa->drawOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->r128Screen->backPitch; + } + + 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 +} + + +/* ================================================================ + * Buffer clear + */ + +static void r128DDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint cx, GLint cy, GLint cw, GLint ch ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + drmR128Clear clear; + GLuint flags = 0; + GLint i; + GLint ret; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s:\n", __FUNCTION__ ); + } + + FLUSH_BATCH( rmesa ); + + /* The only state change we care about here is the RGBA colormask + * We'll just update that state, if needed. If we do more then + * there's some strange side-effects that the conformance tests find. + */ + if ( rmesa->new_state & R128_NEW_MASKS) { + const GLuint save_state = rmesa->new_state; + rmesa->new_state = R128_NEW_MASKS; + r128DDUpdateHWState( ctx ); + rmesa->new_state = save_state & ~R128_NEW_MASKS; + } + + if ( mask & DD_FRONT_LEFT_BIT ) { + flags |= DRM_R128_FRONT_BUFFER; + mask &= ~DD_FRONT_LEFT_BIT; + } + + if ( mask & DD_BACK_LEFT_BIT ) { + flags |= DRM_R128_BACK_BUFFER; + mask &= ~DD_BACK_LEFT_BIT; + } + + if ( ( mask & DD_DEPTH_BIT ) && ctx->Depth.Mask ) { + flags |= DRM_R128_DEPTH_BUFFER; + mask &= ~DD_DEPTH_BIT; + } +#if 0 + /* FIXME: Add stencil support */ + if ( mask & DD_STENCIL_BIT ) { + flags |= DRM_R128_DEPTH_BUFFER; + mask &= ~DD_STENCIL_BIT; + } +#endif + + if ( flags ) { + + /* Flip top to bottom */ + cx += dPriv->x; + cy = dPriv->y + dPriv->h - cy - ch; + + LOCK_HARDWARE( rmesa ); + + /* FIXME: Do we actually need this? + */ + if ( rmesa->dirty & ~R128_UPLOAD_CLIPRECTS ) { + r128EmitHwStateLocked( rmesa ); + } + + 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 ) { + 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++ = *(XF86DRIClipRectPtr)&box[i]; + n++; + } + } + + rmesa->sarea->nbox = n; + + if ( R128_DEBUG & DEBUG_VERBOSE_IOCTL ) { + fprintf( stderr, + "DRM_R128_CLEAR: flag 0x%x color %x depth %x nbox %d\n", + flags, + (GLuint)rmesa->ClearColor, + (GLuint)rmesa->ClearDepth, + rmesa->sarea->nbox ); + } + + clear.flags = flags; + clear.clear_color = rmesa->ClearColor; + clear.clear_depth = rmesa->ClearDepth; + clear.color_mask = rmesa->setup.plane_3d_mask_c; + clear.depth_mask = ~0; + + ret = drmCommandWrite( rmesa->driFd, DRM_R128_CLEAR, + &clear, sizeof(drmR128Clear) ); + + if ( ret ) { + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "DRM_R128_CLEAR: return = %d\n", ret ); + exit( 1 ); + } + } + + UNLOCK_HARDWARE( rmesa ); + + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( mask ) + _swrast_Clear( ctx, mask, all, cx, cy, cw, ch ); +} + + +/* ================================================================ + * Depth spans, pixels + */ + +void r128WriteDepthSpanLocked( r128ContextPtr rmesa, + GLuint n, GLint x, GLint y, + const GLdepth depth[], + const GLubyte mask[] ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + drmR128Depth d; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; + int i; + + if ( !nbox || !n ) { + return; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + d.func = DRM_R128_WRITE_SPAN; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = (unsigned int *)depth; + d.mask = (unsigned char *)mask; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + + d.func = DRM_R128_WRITE_SPAN; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = (unsigned int *)depth; + d.mask = (unsigned char *)mask; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + } + } + + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + +void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, + const GLint x[], const GLint y[], + const GLdepth depth[], + const GLubyte mask[] ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + drmR128Depth d; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; + int i; + + if ( !nbox || !n ) { + return; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + d.func = DRM_R128_WRITE_PIXELS; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = (unsigned int *)depth; + d.mask = (unsigned char *)mask; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + + d.func = DRM_R128_WRITE_PIXELS; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = (unsigned int *)depth; + d.mask = (unsigned char *)mask; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + } + } + + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + +void r128ReadDepthSpanLocked( r128ContextPtr rmesa, + GLuint n, GLint x, GLint y ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + drmR128Depth d; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; + int i; + + if ( !nbox || !n ) { + return; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + d.func = DRM_R128_READ_SPAN; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = NULL; + d.mask = NULL; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + + d.func = DRM_R128_READ_SPAN; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = NULL; + d.mask = NULL; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + } + } + + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + +void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, + const GLint x[], const GLint y[] ) +{ + XF86DRIClipRectPtr pbox = rmesa->pClipRects; + drmR128Depth d; + int nbox = rmesa->numClipRects; + int fd = rmesa->driScreen->fd; + int i; + + if ( !nbox || !n ) { + return; + } + if ( nbox >= R128_NR_SAREA_CLIPRECTS ) { + rmesa->dirty |= R128_UPLOAD_CLIPRECTS; + } + + if ( !(rmesa->dirty & R128_UPLOAD_CLIPRECTS) ) + { + if ( nbox < 3 ) { + rmesa->sarea->nbox = 0; + } else { + rmesa->sarea->nbox = nbox; + } + + d.func = DRM_R128_READ_PIXELS; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = NULL; + d.mask = NULL; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + } + else + { + for (i = 0 ; i < nbox ; ) { + int nr = MIN2( i + R128_NR_SAREA_CLIPRECTS, nbox ); + XF86DRIClipRectPtr b = rmesa->sarea->boxes; + + rmesa->sarea->nbox = nr - i; + for ( ; i < nr ; i++) { + *b++ = pbox[i]; + } + + rmesa->sarea->dirty |= R128_UPLOAD_CLIPRECTS; + + d.func = DRM_R128_READ_PIXELS; + d.n = n; + d.x = (int*)&x; + d.y = (int*)&y; + d.buffer = NULL; + d.mask = NULL; + + drmCommandWrite( fd, DRM_R128_DEPTH, &d, sizeof(drmR128Depth)); + } + } + + rmesa->dirty &= ~R128_UPLOAD_CLIPRECTS; +} + + +void r128WaitForIdleLocked( r128ContextPtr rmesa ) +{ + int fd = rmesa->r128Screen->driScreen->fd; + int to = 0; + int ret, i; + + do { + i = 0; + do { + ret = drmCommandNone( fd, DRM_R128_CCE_IDLE); + } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); + } while ( ( ret == -EBUSY ) && ( to++ < R128_TIMEOUT ) ); + + if ( ret < 0 ) { + drmCommandNone( fd, DRM_R128_CCE_RESET); + UNLOCK_HARDWARE( rmesa ); + fprintf( stderr, "Error: Rage 128 timed out... exiting\n" ); + exit( -1 ); + } +} + +void r128DDInitIoctlFuncs( GLcontext *ctx ) +{ + ctx->Driver.Clear = r128DDClear; +} diff --git a/src/mesa/drivers/dri/r128/r128_ioctl.h b/src/mesa/drivers/dri/r128/r128_ioctl.h new file mode 100644 index 0000000000..b0f6b363a5 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_ioctl.h @@ -0,0 +1,146 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_ioctl.h,v 1.6 2002/12/16 16:18:53 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * + */ + +#ifndef __R128_IOCTL_H__ +#define __R128_IOCTL_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "r128_dri.h" +#include "r128_reg.h" +#include "r128_lock.h" + +#include "xf86drm.h" +#include "r128_common.h" + +#define R128_BUFFER_MAX_DWORDS (R128_BUFFER_SIZE / sizeof(CARD32)) + + +extern drmBufPtr r128GetBufferLocked( r128ContextPtr rmesa ); +extern void r128FlushVerticesLocked( r128ContextPtr rmesa ); + +static __inline void *r128AllocDmaLow( r128ContextPtr rmesa, int bytes ) +{ + CARD32 *head; + + if ( !rmesa->vert_buf ) { + LOCK_HARDWARE( rmesa ); + rmesa->vert_buf = r128GetBufferLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); + } else if ( rmesa->vert_buf->used + bytes > rmesa->vert_buf->total ) { + LOCK_HARDWARE( rmesa ); + r128FlushVerticesLocked( rmesa ); + rmesa->vert_buf = r128GetBufferLocked( rmesa ); + UNLOCK_HARDWARE( rmesa ); + } + + head = (CARD32 *)((char *)rmesa->vert_buf->address + rmesa->vert_buf->used); + rmesa->vert_buf->used += bytes; + return head; +} + +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 rmesa, + GLuint n, GLint x, GLint y, + const GLdepth depth[], + const GLubyte mask[] ); +extern void r128WriteDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, + const GLint x[], const GLint y[], + const GLdepth depth[], + const GLubyte mask[] ); +extern void r128ReadDepthSpanLocked( r128ContextPtr rmesa, + GLuint n, GLint x, GLint y ); +extern void r128ReadDepthPixelsLocked( r128ContextPtr rmesa, GLuint n, + const GLint x[], const GLint y[] ); + +extern void r128CopyBuffer( const __DRIdrawablePrivate *dPriv ); +extern void r128PageFlip( const __DRIdrawablePrivate *dPriv ); +void r128WaitForVBlank( r128ContextPtr rmesa ); + +extern void r128WaitForIdleLocked( r128ContextPtr rmesa ); + + +extern void r128DDInitIoctlFuncs( GLcontext *ctx ); + + +/* ================================================================ + * Helper macros: + */ + +#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 ); \ + } \ +} 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 + R128_INDEX_PRIM_OFFSET); \ +} while (0) + +#define r128FlushVertices( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + r128FlushVerticesLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) + +#define r128FlushElts( rmesa ) \ +do { \ + LOCK_HARDWARE( rmesa ); \ + r128FlushEltsLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ +} while (0) + +#define r128WaitForIdle( rmesa ) \ + do { \ + LOCK_HARDWARE( rmesa ); \ + r128WaitForIdleLocked( rmesa ); \ + UNLOCK_HARDWARE( rmesa ); \ + } while (0) + +#endif +#endif /* __R128_IOCTL_H__ */ diff --git a/src/mesa/drivers/dri/r128/r128_lock.c b/src/mesa/drivers/dri/r128/r128_lock.c new file mode 100644 index 0000000000..12eb0128b0 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_lock.c @@ -0,0 +1,123 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.c,v 1.5 2002/10/30 12:51:38 alanh 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * + */ + +#include "r128_context.h" +#include "r128_lock.h" +#include "r128_tex.h" +#include "r128_state.h" + +#if DEBUG_LOCKING +char *prevLockFile = NULL; +int prevLockLine = 0; +#endif + + +/* Turn on/off page flipping according to the flags in the sarea: + */ +static void +r128UpdatePageFlipping( r128ContextPtr rmesa ) +{ + int use_back; + + rmesa->doPageFlip = rmesa->sarea->pfAllowPageFlip; + + use_back = (rmesa->glCtx->Color._DrawDestMask == BACK_LEFT_BIT); + use_back ^= (rmesa->sarea->pfCurrentPage == 1); + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) + fprintf(stderr, "%s allow %d current %d\n", __FUNCTION__, + rmesa->doPageFlip, + rmesa->sarea->pfCurrentPage ); + + if ( use_back ) { + rmesa->drawOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->r128Screen->backPitch; + } else { + rmesa->drawOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->r128Screen->frontPitch; + } + + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + rmesa->new_state |= R128_NEW_WINDOW; +} + +/* 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 r128GetLock( r128ContextPtr rmesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; + __DRIscreenPrivate *sPriv = rmesa->driScreen; + R128SAREAPrivPtr sarea = rmesa->sarea; + 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. + */ + DRI_VALIDATE_DRAWABLE_INFO( sPriv, dPriv ); + + if ( rmesa->lastStamp != dPriv->lastStamp ) { + r128UpdatePageFlipping( rmesa ); + rmesa->lastStamp = dPriv->lastStamp; + rmesa->new_state |= R128_NEW_CLIP; + rmesa->SetupNewInputs = ~0; + } + + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_CLIPRECTS; + + rmesa->numClipRects = dPriv->numClipRects; + rmesa->pClipRects = dPriv->pClipRects; + + if ( sarea->ctxOwner != rmesa->hHWContext ) { + sarea->ctxOwner = rmesa->hHWContext; + rmesa->dirty = R128_UPLOAD_ALL; + } + + for ( i = 0 ; i < rmesa->nr_heaps ; i++ ) { + DRI_AGE_TEXTURES( rmesa->texture_heaps[i] ); + } +} diff --git a/src/mesa/drivers/dri/r128/r128_lock.h b/src/mesa/drivers/dri/r128/r128_lock.h new file mode 100644 index 0000000000..e734ba29de --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_lock.h @@ -0,0 +1,111 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_lock.h,v 1.4 2001/01/08 01:07:21 martin Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef __R128_LOCK_H__ +#define __R128_LOCK_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128GetLock( r128ContextPtr 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 ) \ + r128GetLock( 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 /* __R128_LOCK_H__ */ diff --git a/src/mesa/drivers/dri/r128/r128_screen.c b/src/mesa/drivers/dri/r128/r128_screen.c new file mode 100644 index 0000000000..8a8fc25217 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_screen.c @@ -0,0 +1,357 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.c,v 1.8 2002/12/16 16:18:53 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#include "r128_dri.h" + +#include "r128_context.h" +#include "r128_ioctl.h" +#include "r128_tris.h" +#include "r128_vb.h" + +#include "context.h" +#include "imports.h" + +#include "utils.h" +#include "vblank.h" + +#ifndef _SOLO +#include "glxextensions.h" +#endif + +#if 1 +/* Including xf86PciInfo.h introduces a bunch of errors... + */ +#define PCI_CHIP_RAGE128LE 0x4C45 +#define PCI_CHIP_RAGE128LF 0x4C46 +#define PCI_CHIP_RAGE128PD 0x5044 +#define PCI_CHIP_RAGE128PF 0x5046 +#define PCI_CHIP_RAGE128PR 0x5052 +#define PCI_CHIP_RAGE128RE 0x5245 +#define PCI_CHIP_RAGE128RF 0x5246 +#define PCI_CHIP_RAGE128RK 0x524B +#define PCI_CHIP_RAGE128RL 0x524C +#endif + + +/* Create the device specific screen private data struct. + */ +static r128ScreenPtr +r128CreateScreen( __DRIscreenPrivate *sPriv ) +{ + r128ScreenPtr r128Screen; + R128DRIPtr r128DRIPriv = (R128DRIPtr)sPriv->pDevPriv; + + if ( ! driCheckDriDdxDrmVersions( sPriv, "Rage128", 4, 0, 4, 0, 2, 2 ) ) + return NULL; + + /* 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->sarea_priv_offset = r128DRIPriv->sarea_priv_offset; + + if (sPriv->drmMinor >= 3) { + drmR128GetParam gp; + int ret; + + gp.param = R128_PARAM_IRQ_NR; + gp.value = &r128Screen->irq; + + ret = drmCommandWriteRead( sPriv->fd, DRM_R128_GETPARAM, + &gp, sizeof(gp)); + if (ret) { + fprintf(stderr, "drmR128GetParam (R128_PARAM_IRQ_NR): %d\n", ret); + FREE( r128Screen ); + return NULL; + } + } + + 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_RAGE128PD: + 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; + + return r128Screen; +} + +/* Destroy the device specific screen private data struct. + */ +static void +r128DestroyScreen( __DRIscreenPrivate *sPriv ) +{ + r128ScreenPtr r128Screen = (r128ScreenPtr)sPriv->private; + + if ( !r128Screen ) + return; + + if ( !r128Screen->IsPCI ) { + drmUnmap( (drmAddress)r128Screen->agpTextures.map, + r128Screen->agpTextures.size ); + } + drmUnmapBufs( r128Screen->buffers ); + drmUnmap( (drmAddress)r128Screen->mmio.map, r128Screen->mmio.size ); + + FREE( r128Screen ); + sPriv->private = NULL; +} + + +/* Initialize the fullscreen mode. + */ +static GLboolean +r128OpenCloseFullScreen( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +static GLboolean +r128CreateBuffer( __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + if (isPixmap) { + return GL_FALSE; /* not implemented */ + } + else { + driDrawPriv->driverPrivate = (void *) + _mesa_create_framebuffer( mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->stencilBits > 0, + mesaVis->accumRedBits > 0, + mesaVis->alphaBits > 0 ); + return (driDrawPriv->driverPrivate != NULL); + } +} + + +static void +r128DestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + + +/* Copy the back color buffer to the front color buffer */ +static void +r128SwapBuffers(__DRIdrawablePrivate *dPriv) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + r128ContextPtr rmesa; + GLcontext *ctx; + rmesa = (r128ContextPtr) dPriv->driContextPriv->driverPrivate; + ctx = rmesa->glCtx; + if (ctx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ + if ( rmesa->doPageFlip ) { + r128PageFlip( dPriv ); + } + else { + r128CopyBuffer( dPriv ); + } + } + } + else { + /* XXX this shouldn't be an error but we can't handle it for now */ + _mesa_problem(NULL, "%s: drawable has no context!", __FUNCTION__); + } +} + + +/* Initialize the driver specific screen private data. + */ +static GLboolean +r128InitDriver( __DRIscreenPrivate *sPriv ) +{ + sPriv->private = (void *) r128CreateScreen( sPriv ); + + if ( !sPriv->private ) { + r128DestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + + +#ifndef _SOLO +/* This function is called by libGL.so as soon as libGL.so is loaded. + * This is where we register new extension functions with the dispatcher. + */ +void __driRegisterExtensions( void ) +{ + PFNGLXENABLEEXTENSIONPROC glx_enable_extension; + + if ( driCompareGLXAPIVersion( 20030317 ) >= 0 ) { + glx_enable_extension = (PFNGLXENABLEEXTENSIONPROC) + glXGetProcAddress( "__glXEnableExtension" ); + + if ( glx_enable_extension != NULL ) { + glx_enable_extension( "GLX_SGI_swap_control", GL_FALSE ); + glx_enable_extension( "GLX_SGI_video_sync", GL_FALSE ); + glx_enable_extension( "GLX_MESA_swap_control", GL_FALSE ); + } + } +} +#endif + +static struct __DriverAPIRec r128API = { + .InitDriver = r128InitDriver, + .DestroyScreen = r128DestroyScreen, + .CreateContext = r128CreateContext, + .DestroyContext = r128DestroyContext, + .CreateBuffer = r128CreateBuffer, + .DestroyBuffer = r128DestroyBuffer, + .SwapBuffers = r128SwapBuffers, + .MakeCurrent = r128MakeCurrent, + .UnbindContext = r128UnbindContext, + .OpenFullScreen = r128OpenCloseFullScreen, + .CloseFullScreen = r128OpenCloseFullScreen, + .GetSwapInfo = NULL, + .GetMSC = driGetMSC32, + .WaitForMSC = driWaitForMSC32, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL + +}; + + +/* + * This is the bootstrap function for the driver. + * The __driCreateScreen name is the symbol that libGL.so fetches. + * Return: pointer to a __DRIscreenPrivate. + */ +#ifndef _SOLO +void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc, + int numConfigs, __GLXvisualConfig *config) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &r128API); + return (void *) psp; +} +#else +void *__driCreateScreen(struct DRIDriverRec *driver, + struct DRIDriverContextRec *driverContext) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(driver, driverContext, &r128API); + return (void *) psp; +} +#endif diff --git a/src/mesa/drivers/dri/r128/r128_screen.h b/src/mesa/drivers/dri/r128/r128_screen.h new file mode 100644 index 0000000000..4b1a57292d --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_screen.h @@ -0,0 +1,84 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_screen.h,v 1.7 2002/12/16 16:18:53 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#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 */ + unsigned char *map; /* Mapping of the DRM region */ +} r128RegionRec, *r128RegionPtr; + +typedef struct { + + GLint chipset; + GLint cpp; + GLint IsPCI; /* Current card is a PCI card */ + GLint AGPMode; + unsigned int irq; /* IRQ number (0 means none) */ + + GLuint frontOffset; + GLuint frontPitch; + GLuint backOffset; + GLuint backPitch; + + GLuint depthOffset; + GLuint depthPitch; + GLuint spanOffset; + + /* Shared texture data */ + 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; + unsigned int sarea_priv_offset; + +} r128ScreenRec, *r128ScreenPtr; + + +#endif +#endif /* __R128_SCREEN_H__ */ diff --git a/src/mesa/drivers/dri/r128/r128_span.c b/src/mesa/drivers/dri/r128/r128_span.c new file mode 100644 index 0000000000..c6f3195942 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_span.c @@ -0,0 +1,475 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.c,v 1.8 2002/10/30 12:51:39 alanh 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Keith Whitwell + * Kevin E. Martin + * + */ + +#include "r128_context.h" +#include "r128_ioctl.h" +#include "r128_state.h" +#include "r128_span.h" +#include "r128_tex.h" + +#include "swrast/swrast.h" + +#define DBG 0 + +#define HAVE_HW_DEPTH_SPANS 1 +#define HAVE_HW_DEPTH_PIXELS 1 + +#define LOCAL_VARS \ + 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 *)(sPriv->pFB + \ + rmesa->drawOffset + \ + (dPriv->x * r128scrn->cpp) + \ + (dPriv->y * pitch)); \ + char *read_buf = (char *)(sPriv->pFB + \ + rmesa->readOffset + \ + (dPriv->x * r128scrn->cpp) + \ + (dPriv->y * pitch)); \ + GLuint p; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + r128ScreenPtr r128scrn = rmesa->r128Screen; \ + __DRIscreenPrivate *sPriv = rmesa->driScreen; \ + __DRIdrawablePrivate *dPriv = rmesa->driDrawable; \ + GLuint height = dPriv->h; \ + (void) r128scrn; (void) sPriv; (void) height + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + + +#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), n1 -= (minx-_x1), _x1 = minx; \ + if ( _x1 + _n1 >= maxx ) n1 -= (_x1 + n1 - maxx); \ + } + +#define Y_FLIP( _y ) (height - _y - 1) + + +#define HW_LOCK() \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + FLUSH_BATCH( rmesa ); \ + LOCK_HARDWARE( rmesa ); \ + r128WaitForIdleLocked( 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 + */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = R128PACKCOLOR565( color[0], color[1], color[2] ) + +#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) r128##x##_RGB565 +#include "spantmp.h" + +#define READ_DEPTH(d, _x, _y) \ + d = *(GLushort *)(buf + _x*2 + _y*pitch) + +/* 32 bit, ARGB8888 color spanline and pixel functions + */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = R128PACKCOLOR8888( color[0], color[1], color[2], color[3] ) + +#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] = 0xff;/*(p >> 24) & 0xff;*/ \ +} while (0) + +#define TAG(x) r128##x##_ARGB8888 +#include "spantmp.h" + + +/* 24 bit, RGB888 color spanline and pixel functions */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = R128PACKCOLOR888( color[0], color[1], color[2] ) + +#define WRITE_RGBA(_x, _y, r, g, b, a) \ + *(GLuint *)(buf + _x*3 + _y*pitch) = ((r << 16) | \ + (g << 8) | \ + (b << 0)) + +#define WRITE_PIXEL(_x, _y, p) \ + *(GLuint *)(buf + _x*3 + _y*pitch) = p + +#define READ_RGBA(rgba, _x, _y) \ + do { \ + GLuint p = *(GLuint *)(read_buf + _x*3 + _y*pitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = 0xff; \ + } while (0) + +/* ================================================================ + * Depth buffer + */ + +/* 16-bit depth buffer functions + */ +#define WRITE_DEPTH_SPAN() \ + r128WriteDepthSpanLocked( rmesa, n, \ + x + dPriv->x, \ + y + dPriv->y, \ + depth, mask ); + +#define WRITE_DEPTH_PIXELS() \ +do { \ + GLint ox[MAX_WIDTH]; \ + GLint oy[MAX_WIDTH]; \ + for ( i = 0 ; i < n ; i++ ) { \ + ox[i] = x[i] + dPriv->x; \ + } \ + for ( i = 0 ; i < n ; i++ ) { \ + oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ + } \ + r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \ +} while (0) + +#define READ_DEPTH_SPAN() \ +do { \ + GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \ + r128scrn->spanOffset); \ + GLint i; \ + \ + r128ReadDepthSpanLocked( rmesa, n, \ + x + dPriv->x, \ + y + dPriv->y ); \ + r128WaitForIdleLocked( rmesa ); \ + \ + for ( i = 0 ; i < n ; i++ ) { \ + depth[i] = buf[i]; \ + } \ +} while (0) + +#define READ_DEPTH_PIXELS() \ +do { \ + GLushort *buf = (GLushort *)((GLubyte *)sPriv->pFB + \ + r128scrn->spanOffset); \ + GLint i, remaining = n; \ + \ + while ( remaining > 0 ) { \ + GLint ox[MAX_WIDTH]; \ + GLint oy[MAX_WIDTH]; \ + GLint count; \ + \ + if ( remaining <= 128 ) { \ + count = remaining; \ + } else { \ + count = 128; \ + } \ + for ( i = 0 ; i < count ; i++ ) { \ + ox[i] = x[i] + dPriv->x; \ + } \ + for ( i = 0 ; i < count ; i++ ) { \ + oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ + } \ + \ + r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \ + r128WaitForIdleLocked( rmesa ); \ + \ + for ( i = 0 ; i < count ; i++ ) { \ + depth[i] = buf[i]; \ + } \ + depth += count; \ + x += count; \ + y += count; \ + remaining -= count; \ + } \ +} while (0) + +#define TAG(x) r128##x##_16 +#include "depthtmp.h" + + +/* 24-bit depth, 8-bit stencil buffer functions + */ +#define WRITE_DEPTH_SPAN() \ + r128WriteDepthSpanLocked( rmesa, n, \ + x + dPriv->x, \ + y + dPriv->y, \ + depth, mask ); + +#define WRITE_DEPTH_PIXELS() \ +do { \ + GLint ox[MAX_WIDTH]; \ + GLint oy[MAX_WIDTH]; \ + for ( i = 0 ; i < n ; i++ ) { \ + ox[i] = x[i] + dPriv->x; \ + } \ + for ( i = 0 ; i < n ; i++ ) { \ + oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ + } \ + r128WriteDepthPixelsLocked( rmesa, n, ox, oy, depth, mask ); \ +} while (0) + +#define READ_DEPTH_SPAN() \ +do { \ + GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \ + r128scrn->spanOffset); \ + GLint i; \ + \ + r128ReadDepthSpanLocked( rmesa, n, \ + x + dPriv->x, \ + y + dPriv->y ); \ + r128WaitForIdleLocked( rmesa ); \ + \ + for ( i = 0 ; i < n ; i++ ) { \ + depth[i] = buf[i] & 0x00ffffff; \ + } \ +} while (0) + +#define READ_DEPTH_PIXELS() \ +do { \ + GLuint *buf = (GLuint *)((GLubyte *)sPriv->pFB + \ + r128scrn->spanOffset); \ + GLint i, remaining = n; \ + \ + while ( remaining > 0 ) { \ + GLint ox[MAX_WIDTH]; \ + GLint oy[MAX_WIDTH]; \ + GLint count; \ + \ + if ( remaining <= 128 ) { \ + count = remaining; \ + } else { \ + count = 128; \ + } \ + for ( i = 0 ; i < count ; i++ ) { \ + ox[i] = x[i] + dPriv->x; \ + } \ + for ( i = 0 ; i < count ; i++ ) { \ + oy[i] = Y_FLIP( y[i] ) + dPriv->y; \ + } \ + \ + r128ReadDepthPixelsLocked( rmesa, count, ox, oy ); \ + r128WaitForIdleLocked( rmesa ); \ + \ + for ( i = 0 ; i < count ; i++ ) { \ + depth[i] = buf[i] & 0x00ffffff; \ + } \ + depth += count; \ + x += count; \ + y += count; \ + remaining -= count; \ + } \ +} while (0) + +#define TAG(x) r128##x##_24_8 +#include "depthtmp.h" + + + +/* ================================================================ + * Stencil buffer + */ + +/* FIXME: Add support for hardware stencil buffers. + */ + + +/* 32 bit depthbuffer functions */ +#define WRITE_DEPTH(_x, _y, d) \ + *(GLuint *)(buf + _x*4 + _y*pitch) = d + + + +/* + * This function is called to specify which buffer to read and write + * for software rasterization (swrast) fallbacks. This doesn't necessarily + * correspond to glDrawBuffer() or glReadBuffer() calls. + */ +static void r128DDSetBuffer( GLcontext *ctx, + GLframebuffer *colorBuffer, + GLuint bufferBit ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + switch ( bufferBit ) { + case FRONT_LEFT_BIT: + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; + } else { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; + } + break; + case BACK_LEFT_BIT: + if ( rmesa->sarea->pfCurrentPage == 1 ) { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; + } else { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; + } + break; + default: + break; + } +} + + +void r128DDInitSpanFuncs( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + + swdd->SetBuffer = r128DDSetBuffer; + + switch ( rmesa->r128Screen->cpp ) { + case 2: + swdd->WriteRGBASpan = r128WriteRGBASpan_RGB565; + swdd->WriteRGBSpan = r128WriteRGBSpan_RGB565; + swdd->WriteMonoRGBASpan = r128WriteMonoRGBASpan_RGB565; + swdd->WriteRGBAPixels = r128WriteRGBAPixels_RGB565; + swdd->WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_RGB565; + swdd->ReadRGBASpan = r128ReadRGBASpan_RGB565; + swdd->ReadRGBAPixels = r128ReadRGBAPixels_RGB565; + break; + + case 4: + swdd->WriteRGBASpan = r128WriteRGBASpan_ARGB8888; + swdd->WriteRGBSpan = r128WriteRGBSpan_ARGB8888; + swdd->WriteMonoRGBASpan = r128WriteMonoRGBASpan_ARGB8888; + swdd->WriteRGBAPixels = r128WriteRGBAPixels_ARGB8888; + swdd->WriteMonoRGBAPixels = r128WriteMonoRGBAPixels_ARGB8888; + swdd->ReadRGBASpan = r128ReadRGBASpan_ARGB8888; + swdd->ReadRGBAPixels = r128ReadRGBAPixels_ARGB8888; + break; + + default: + break; + } + + switch ( rmesa->glCtx->Visual.depthBits ) { + case 16: + swdd->ReadDepthSpan = r128ReadDepthSpan_16; + swdd->WriteDepthSpan = r128WriteDepthSpan_16; + swdd->ReadDepthPixels = r128ReadDepthPixels_16; + swdd->WriteDepthPixels = r128WriteDepthPixels_16; + break; + + case 24: + swdd->ReadDepthSpan = r128ReadDepthSpan_24_8; + swdd->WriteDepthSpan = r128WriteDepthSpan_24_8; + swdd->ReadDepthPixels = r128ReadDepthPixels_24_8; + swdd->WriteDepthPixels = r128WriteDepthPixels_24_8; + break; + + default: + break; + } + + swdd->WriteCI8Span = NULL; + swdd->WriteCI32Span = NULL; + swdd->WriteMonoCISpan = NULL; + swdd->WriteCI32Pixels = NULL; + swdd->WriteMonoCIPixels = NULL; + swdd->ReadCI32Span = NULL; + swdd->ReadCI32Pixels = NULL; +} diff --git a/src/mesa/drivers/dri/r128/r128_span.h b/src/mesa/drivers/dri/r128/r128_span.h new file mode 100644 index 0000000000..44356c5b24 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_span.h @@ -0,0 +1,44 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_span.h,v 1.3 2001/01/08 01:07:21 martin Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#ifndef __R128_SPAN_H__ +#define __R128_SPAN_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128DDInitSpanFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/src/mesa/drivers/dri/r128/r128_state.c b/src/mesa/drivers/dri/r128/r128_state.c new file mode 100644 index 0000000000..85b3b68402 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_state.c @@ -0,0 +1,1239 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.c,v 1.11 2002/10/30 12:51:39 alanh 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * Keith Whitwell + * + */ + +#include "r128_context.h" +#include "r128_state.h" +#include "r128_ioctl.h" +#include "r128_tris.h" +#include "r128_vb.h" +#include "r128_tex.h" + +#include "context.h" +#include "enums.h" +#include "colormac.h" +#include "swrast/swrast.h" +#include "array_cache/acache.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + + +/* ============================================================= + * Alpha blending + */ + +static void r128UpdateAlphaMode( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint a = rmesa->setup.misc_3d_state_cntl_reg; + GLuint t = rmesa->setup.tex_cntl_c; + + if ( ctx->Color.AlphaEnabled ) { + GLubyte ref; + + CLAMPED_FLOAT_TO_UBYTE(ref, ctx->Color.AlphaRef); + + a &= ~(R128_ALPHA_TEST_MASK | R128_REF_ALPHA_MASK); + + switch ( ctx->Color.AlphaFunc ) { + case GL_NEVER: + a |= R128_ALPHA_TEST_NEVER; + break; + case GL_LESS: + a |= R128_ALPHA_TEST_LESS; + break; + case GL_LEQUAL: + a |= R128_ALPHA_TEST_LESSEQUAL; + break; + case GL_EQUAL: + a |= R128_ALPHA_TEST_EQUAL; + break; + case GL_GEQUAL: + a |= R128_ALPHA_TEST_GREATEREQUAL; + break; + case GL_GREATER: + a |= R128_ALPHA_TEST_GREATER; + break; + case GL_NOTEQUAL: + a |= R128_ALPHA_TEST_NEQUAL; + break; + case GL_ALWAYS: + a |= R128_ALPHA_TEST_ALWAYS; + break; + } + + a |= ref & R128_REF_ALPHA_MASK; + t |= R128_ALPHA_TEST_ENABLE; + } else { + t &= ~R128_ALPHA_TEST_ENABLE; + } + + FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_FALSE ); + + if ( ctx->Color.BlendEnabled ) { + a &= ~(R128_ALPHA_BLEND_SRC_MASK | R128_ALPHA_BLEND_DST_MASK); + + switch ( ctx->Color.BlendSrcRGB ) { + case GL_ZERO: + a |= R128_ALPHA_BLEND_SRC_ZERO; + break; + case GL_ONE: + a |= R128_ALPHA_BLEND_SRC_ONE; + break; + case GL_DST_COLOR: + a |= R128_ALPHA_BLEND_SRC_DESTCOLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + a |= R128_ALPHA_BLEND_SRC_INVDESTCOLOR; + break; + case GL_SRC_ALPHA: + a |= R128_ALPHA_BLEND_SRC_SRCALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + a |= R128_ALPHA_BLEND_SRC_INVSRCALPHA; + break; + case GL_DST_ALPHA: + a |= R128_ALPHA_BLEND_SRC_DESTALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + a |= R128_ALPHA_BLEND_SRC_INVDESTALPHA; + break; + case GL_SRC_ALPHA_SATURATE: + a |= R128_ALPHA_BLEND_SRC_SRCALPHASAT; + break; + default: + FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_TRUE ); + } + + switch ( ctx->Color.BlendDstRGB ) { + case GL_ZERO: + a |= R128_ALPHA_BLEND_DST_ZERO; + break; + case GL_ONE: + a |= R128_ALPHA_BLEND_DST_ONE; + break; + case GL_SRC_COLOR: + a |= R128_ALPHA_BLEND_DST_SRCCOLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + a |= R128_ALPHA_BLEND_DST_INVSRCCOLOR; + break; + case GL_SRC_ALPHA: + a |= R128_ALPHA_BLEND_DST_SRCALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + a |= R128_ALPHA_BLEND_DST_INVSRCALPHA; + break; + case GL_DST_ALPHA: + a |= R128_ALPHA_BLEND_DST_DESTALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + a |= R128_ALPHA_BLEND_DST_INVDESTALPHA; + break; + default: + FALLBACK( rmesa, R128_FALLBACK_BLEND_FUNC, GL_TRUE ); + } + + t |= R128_ALPHA_ENABLE; + } else { + t &= ~R128_ALPHA_ENABLE; + } + + 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 ( 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, GLfloat ref ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; +} + +static void r128DDBlendEquation( GLcontext *ctx, GLenum mode ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + + /* BlendEquation sets ColorLogicOpEnabled in an unexpected + * manner. + */ + FALLBACK( R128_CONTEXT(ctx), R128_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); + + /* Can only do blend addition, not min, max, subtract, etc. */ + FALLBACK( R128_CONTEXT(ctx), R128_FALLBACK_BLEND_EQ, + mode != GL_FUNC_ADD_EXT); + + rmesa->new_state |= R128_NEW_ALPHA; +} + +static void r128DDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; +} + +static void r128DDBlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; +} + + +/* ============================================================= + * Depth testing + */ + +static void r128UpdateZMode( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint z = rmesa->setup.z_sten_cntl_c; + GLuint t = rmesa->setup.tex_cntl_c; + + if ( ctx->Depth.Test ) { + z &= ~R128_Z_TEST_MASK; + + switch ( ctx->Depth.Func ) { + case GL_NEVER: + z |= R128_Z_TEST_NEVER; + break; + case GL_ALWAYS: + z |= R128_Z_TEST_ALWAYS; + break; + case GL_LESS: + z |= R128_Z_TEST_LESS; + break; + case GL_LEQUAL: + z |= R128_Z_TEST_LESSEQUAL; + break; + case GL_EQUAL: + z |= R128_Z_TEST_EQUAL; + break; + case GL_GEQUAL: + z |= R128_Z_TEST_GREATEREQUAL; + break; + case GL_GREATER: + z |= R128_Z_TEST_GREATER; + break; + case GL_NOTEQUAL: + z |= R128_Z_TEST_NEQUAL; + break; + } + + t |= R128_Z_ENABLE; + } else { + t &= ~R128_Z_ENABLE; + } + + if ( ctx->Depth.Mask ) { + t |= R128_Z_WRITE_ENABLE; + } else { + t &= ~R128_Z_WRITE_ENABLE; + } + + if ( rmesa->setup.z_sten_cntl_c != z ) { + rmesa->setup.z_sten_cntl_c = z; + rmesa->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 rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; +} + +static void r128DDDepthMask( GLcontext *ctx, GLboolean flag ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; +} + +static void r128DDClearDepth( GLcontext *ctx, GLclampd d ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + switch ( rmesa->setup.z_sten_cntl_c & R128_Z_PIX_WIDTH_MASK ) { + case R128_Z_PIX_WIDTH_16: + rmesa->ClearDepth = d * 0x0000ffff; + break; + case R128_Z_PIX_WIDTH_24: + rmesa->ClearDepth = d * 0x00ffffff; + break; + case R128_Z_PIX_WIDTH_32: + rmesa->ClearDepth = d * 0xffffffff; + break; + } +} + + +/* ============================================================= + * Fog + */ + +static void r128UpdateFogAttrib( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint t = rmesa->setup.tex_cntl_c; + GLubyte c[4]; + GLuint col; + + if ( ctx->Fog.Enabled ) { + t |= R128_FOG_ENABLE; + } else { + t &= ~R128_FOG_ENABLE; + } + + c[0] = FLOAT_TO_UBYTE( ctx->Fog.Color[0] ); + c[1] = FLOAT_TO_UBYTE( ctx->Fog.Color[1] ); + c[2] = FLOAT_TO_UBYTE( ctx->Fog.Color[2] ); + + col = r128PackColor( 4, c[0], c[1], c[2], 0 ); + + if ( rmesa->setup.fog_color_c != col ) { + rmesa->setup.fog_color_c = col; + rmesa->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 rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_FOG; +} + + +/* ============================================================= + * Clipping + */ + +static void r128UpdateClipping( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + if ( rmesa->driDrawable ) { + __DRIdrawablePrivate *drawable = rmesa->driDrawable; + int x1 = 0; + int y1 = 0; + int x2 = drawable->w - 1; + int y2 = drawable->h - 1; + + if ( ctx->Scissor.Enabled ) { + if ( ctx->Scissor.X > x1 ) { + x1 = ctx->Scissor.X; + } + if ( drawable->h - ctx->Scissor.Y - ctx->Scissor.Height > y1 ) { + y1 = drawable->h - ctx->Scissor.Y - ctx->Scissor.Height; + } + if ( ctx->Scissor.X + ctx->Scissor.Width - 1 < x2 ) { + x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; + } + if ( drawable->h - ctx->Scissor.Y - 1 < y2 ) { + y2 = drawable->h - ctx->Scissor.Y - 1; + } + } + + x1 += drawable->x; + y1 += drawable->y; + x2 += drawable->x; + y2 += drawable->y; + + rmesa->setup.sc_top_left_c = ((y1 << 16) | x1); + rmesa->setup.sc_bottom_right_c = ((y2 << 16) | x2); + + rmesa->dirty |= R128_UPLOAD_CONTEXT; + } +} + +static void r128DDScissor( GLcontext *ctx, + GLint x, GLint y, GLsizei w, GLsizei h ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CLIP; +} + + +/* ============================================================= + * Culling + */ + +static void r128UpdateCull( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint f = rmesa->setup.pm4_vc_fpu_setup; + + f &= ~R128_FRONT_DIR_MASK; + + switch ( ctx->Polygon.FrontFace ) { + case GL_CW: + f |= R128_FRONT_DIR_CW; + break; + case GL_CCW: + f |= R128_FRONT_DIR_CCW; + break; + } + + f |= R128_BACKFACE_SOLID | R128_FRONTFACE_SOLID; + + if ( ctx->Polygon.CullFlag ) { + switch ( ctx->Polygon.CullFaceMode ) { + case GL_FRONT: + f &= ~R128_FRONTFACE_SOLID; + break; + case GL_BACK: + f &= ~R128_BACKFACE_SOLID; + break; + case GL_FRONT_AND_BACK: + f &= ~(R128_BACKFACE_SOLID | + R128_FRONTFACE_SOLID); + break; + } + } + + if ( 1 || 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 rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; +} + +static void r128DDFrontFace( GLcontext *ctx, GLenum mode ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; +} + + +/* ============================================================= + * Masks + */ + +static void r128UpdateMasks( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + GLuint mask = r128PackColor( rmesa->r128Screen->cpp, + ctx->Color.ColorMask[RCOMP], + ctx->Color.ColorMask[GCOMP], + ctx->Color.ColorMask[BCOMP], + ctx->Color.ColorMask[ACOMP] ); + + if ( rmesa->setup.plane_3d_mask_c != mask ) { + rmesa->setup.plane_3d_mask_c = mask; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS; + } +} + +static void r128DDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_MASKS; +} + + +/* ============================================================= + * 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 updateSpecularLighting( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint t = rmesa->setup.tex_cntl_c; + + if ( ctx->Light.Model.ColorControl == GL_SEPARATE_SPECULAR_COLOR && + ctx->Light.Enabled) { + /* XXX separate specular color just doesn't seem to work as it should. + * For now, we fall back to s/w rendering whenever separate specular + * is enabled. + */ +#if 0 + if (ctx->Light.ShadeModel == GL_FLAT) { + /* R128 can't do flat-shaded separate specular */ + t &= ~R128_SPEC_LIGHT_ENABLE; + FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_TRUE ); + /*printf("%s fallback sep spec\n", __FUNCTION__);*/ + } + else { + t |= R128_SPEC_LIGHT_ENABLE; + FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_FALSE ); + /*printf("%s enable sep spec\n", __FUNCTION__);*/ + } +#else + t &= ~R128_SPEC_LIGHT_ENABLE; + FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_TRUE ); + /*printf("%s fallback sep spec\n", __FUNCTION__);*/ +#endif + } + else { + t &= ~R128_SPEC_LIGHT_ENABLE; + FALLBACK( rmesa, R128_FALLBACK_SEP_SPECULAR, GL_FALSE ); + /*printf("%s disable sep spec\n", __FUNCTION__);*/ + } + + if ( rmesa->setup.tex_cntl_c != t ) { + rmesa->setup.tex_cntl_c = t; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + rmesa->dirty |= R128_UPLOAD_SETUP; + rmesa->new_state |= R128_NEW_CONTEXT; + } +} + + +static void r128DDLightModelfv( GLcontext *ctx, GLenum pname, + const GLfloat *param ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + if ( pname == GL_LIGHT_MODEL_COLOR_CONTROL ) { + FLUSH_BATCH( rmesa ); + updateSpecularLighting(ctx); + } +} + +static void r128DDShadeModel( GLcontext *ctx, GLenum mode ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint s = rmesa->setup.pm4_vc_fpu_setup; + + s &= ~R128_FPU_COLOR_MASK; + + switch ( mode ) { + case GL_FLAT: + s |= R128_FPU_COLOR_FLAT; + break; + case GL_SMOOTH: + s |= R128_FPU_COLOR_GOURAUD; + break; + default: + return; + } + + updateSpecularLighting(ctx); + + if ( rmesa->setup.pm4_vc_fpu_setup != s ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.pm4_vc_fpu_setup = s; + + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_SETUP; + } +} + + +/* ============================================================= + * Window position + */ + +void r128UpdateWindow( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + int x = rmesa->driDrawable->x; + int y = rmesa->driDrawable->y; + + rmesa->setup.window_xy_offset = ((y << R128_WINDOW_Y_SHIFT) | + (x << R128_WINDOW_X_SHIFT)); + + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_WINDOW; +} + +/* ============================================================= + * Viewport + */ + + +static void r128CalcViewport( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = rmesa->hw_viewport; + + /* See also r128_translate_vertex. + */ + m[MAT_SX] = v[MAT_SX]; + m[MAT_TX] = v[MAT_TX] + SUBPIXEL_X; + m[MAT_SY] = - v[MAT_SY]; + m[MAT_TY] = - v[MAT_TY] + rmesa->driDrawable->h + SUBPIXEL_Y; + m[MAT_SZ] = v[MAT_SZ] * rmesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * rmesa->depth_scale; +} + +static void r128Viewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + r128CalcViewport( ctx ); +} + +static void r128DepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + r128CalcViewport( ctx ); +} + + +/* ============================================================= + * Miscellaneous + */ + +static void r128DDClearColor( GLcontext *ctx, + const GLfloat color[4] ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLubyte c[4]; + + CLAMPED_FLOAT_TO_UBYTE(c[0], color[0]); + CLAMPED_FLOAT_TO_UBYTE(c[1], color[1]); + CLAMPED_FLOAT_TO_UBYTE(c[2], color[2]); + CLAMPED_FLOAT_TO_UBYTE(c[3], color[3]); + + rmesa->ClearColor = r128PackColor( rmesa->r128Screen->cpp, + c[0], c[1], c[2], c[3] ); +} + +static void r128DDLogicOpCode( GLcontext *ctx, GLenum opcode ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + if ( ctx->Color.ColorLogicOpEnabled ) { + FLUSH_BATCH( rmesa ); + + FALLBACK( rmesa, R128_FALLBACK_LOGICOP, opcode != GL_COPY ); + } +} + +static void r128DDDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + + /* + * _DrawDestMask is easier to cope with than . + */ + switch ( ctx->Color._DrawDestMask ) { + case FRONT_LEFT_BIT: + FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + case BACK_LEFT_BIT: + FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( rmesa, R128_FALLBACK_DRAW_BUFFER, GL_TRUE ); + break; + } + + /* We want to update the s/w rast state too so that r200SetBuffer() + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); + + rmesa->setup.dst_pitch_offset_c = (((rmesa->drawPitch/8) << 21) | + (rmesa->drawOffset >> 5)); + rmesa->new_state |= R128_NEW_WINDOW; +} + +static void r128DDReadBuffer( GLcontext *ctx, GLenum mode ) +{ + /* nothing, until we implement h/w glRead/CopyPixels or CopyTexImage */ +} + + +/* ============================================================= + * Polygon stipple + */ + +static void r128DDPolygonStipple( GLcontext *ctx, const GLubyte *mask ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint stipple[32], i; + drmR128Stipple stippleRec; + + for (i = 0; i < 32; i++) { + stipple[31 - i] = ((mask[i*4+0] << 24) | + (mask[i*4+1] << 16) | + (mask[i*4+2] << 8) | + (mask[i*4+3])); + } + + FLUSH_BATCH( rmesa ); + LOCK_HARDWARE( rmesa ); + + stippleRec.mask = stipple; + drmCommandWrite( rmesa->driFd, DRM_R128_STIPPLE, + &stippleRec, sizeof(drmR128Stipple) ); + + UNLOCK_HARDWARE( rmesa ); + + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; +} + + +/* ============================================================= + * Render mode + */ + +static void r128DDRenderMode( GLcontext *ctx, GLenum mode ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + FALLBACK( rmesa, R128_FALLBACK_RENDER_MODE, (mode != GL_RENDER) ); +} + + + +/* ============================================================= + * State enable/disable + */ + +static void r128DDEnable( GLcontext *ctx, GLenum cap, GLboolean state ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s = %s )\n", + __FUNCTION__, _mesa_lookup_enum_by_nr( cap ), + state ? "GL_TRUE" : "GL_FALSE" ); + } + + switch ( cap ) { + case GL_ALPHA_TEST: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; + break; + + case GL_BLEND: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; + + /* For some reason enable(GL_BLEND) affects ColorLogicOpEnabled. + */ + FALLBACK( rmesa, R128_FALLBACK_LOGICOP, + (ctx->Color.ColorLogicOpEnabled && + ctx->Color.LogicOp != GL_COPY)); + break; + + case GL_CULL_FACE: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_CULL; + break; + + case GL_DEPTH_TEST: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_DEPTH; + break; + + case GL_DITHER: + do { + GLuint 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( rmesa ); + rmesa->new_state |= R128_NEW_FOG; + break; + + case GL_COLOR_LOGIC_OP: + FLUSH_BATCH( rmesa ); + FALLBACK( rmesa, R128_FALLBACK_LOGICOP, + state && ctx->Color.LogicOp != GL_COPY ); + break; + + case GL_LIGHTING: + updateSpecularLighting(ctx); + break; + + case GL_SCISSOR_TEST: + FLUSH_BATCH( rmesa ); + rmesa->scissor = state; + rmesa->new_state |= R128_NEW_CLIP; + break; + + case GL_STENCIL_TEST: + FLUSH_BATCH( rmesa ); + FALLBACK( rmesa, R128_FALLBACK_STENCIL, state ); + break; + + case GL_TEXTURE_1D: + case GL_TEXTURE_2D: + case GL_TEXTURE_3D: + FLUSH_BATCH( rmesa ); + break; + + case GL_POLYGON_STIPPLE: + if ( rmesa->render_primitive == GL_TRIANGLES ) { + FLUSH_BATCH( rmesa ); + rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; + if ( state ) { + rmesa->setup.dp_gui_master_cntl_c |= + R128_GMC_BRUSH_32x32_MONO_FG_LA; + } else { + rmesa->setup.dp_gui_master_cntl_c |= + R128_GMC_BRUSH_SOLID_COLOR; + } + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + } + break; + + default: + return; + } +} + + +/* ============================================================= + * State initialization, management + */ + +static void r128DDPrintDirty( const char *msg, GLuint state ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s%s\n", + msg, + state, + (state & R128_UPLOAD_CORE) ? "core, " : "", + (state & R128_UPLOAD_CONTEXT) ? "context, " : "", + (state & R128_UPLOAD_SETUP) ? "setup, " : "", + (state & R128_UPLOAD_TEX0) ? "tex0, " : "", + (state & R128_UPLOAD_TEX1) ? "tex1, " : "", + (state & R128_UPLOAD_MASKS) ? "masks, " : "", + (state & R128_UPLOAD_WINDOW) ? "window, " : "", + (state & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "", + (state & R128_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 r128EmitHwStateLocked( r128ContextPtr rmesa ) +{ + R128SAREAPrivPtr sarea = rmesa->sarea; + r128_context_regs_t *regs = &(rmesa->setup); + const r128TexObjPtr t0 = rmesa->CurrentTexObj[0]; + const r128TexObjPtr t1 = rmesa->CurrentTexObj[1]; + + if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) { + r128DDPrintDirty( "r128EmitHwStateLocked", rmesa->dirty ); + } + + if ( rmesa->dirty & (R128_UPLOAD_CONTEXT | + R128_UPLOAD_SETUP | + R128_UPLOAD_MASKS | + R128_UPLOAD_WINDOW | + R128_UPLOAD_CORE) ) { + memcpy( &sarea->ContextState, regs, sizeof(sarea->ContextState) ); + } + + 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 ( (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 = rmesa->vertex_size; + sarea->vc_format = rmesa->vertex_format; + + /* Turn off the texture cache flushing */ + rmesa->setup.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH; + + sarea->dirty |= rmesa->dirty; + rmesa->dirty &= R128_UPLOAD_CLIPRECTS; +} + +static void r128DDPrintState( const char *msg, GLuint flags ) +{ + fprintf( stderr, + "%s: (0x%x) %s%s%s%s%s%s%s%s\n", + msg, + flags, + (flags & R128_NEW_CONTEXT) ? "context, " : "", + (flags & R128_NEW_ALPHA) ? "alpha, " : "", + (flags & R128_NEW_DEPTH) ? "depth, " : "", + (flags & R128_NEW_FOG) ? "fog, " : "", + (flags & R128_NEW_CLIP) ? "clip, " : "", + (flags & R128_NEW_CULL) ? "cull, " : "", + (flags & R128_NEW_MASKS) ? "masks, " : "", + (flags & R128_NEW_WINDOW) ? "window, " : "" ); +} + +void r128DDUpdateHWState( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + int new_state = rmesa->new_state; + + if ( new_state || rmesa->NewGLState & _NEW_TEXTURE ) + { + FLUSH_BATCH( rmesa ); + + rmesa->new_state = 0; + + if ( R128_DEBUG & DEBUG_VERBOSE_MSG ) + r128DDPrintState( "r128UpdateHwState", new_state ); + + /* Update the various parts of the context's state. + */ + if ( new_state & R128_NEW_ALPHA ) + r128UpdateAlphaMode( ctx ); + + if ( new_state & R128_NEW_DEPTH ) + r128UpdateZMode( ctx ); + + if ( new_state & R128_NEW_FOG ) + r128UpdateFogAttrib( ctx ); + + if ( new_state & R128_NEW_CLIP ) + r128UpdateClipping( ctx ); + + if ( new_state & R128_NEW_CULL ) + r128UpdateCull( ctx ); + + if ( new_state & R128_NEW_MASKS ) + r128UpdateMasks( ctx ); + + if ( new_state & R128_NEW_WINDOW ) + r128UpdateWindow( ctx ); + + if ( rmesa->NewGLState & _NEW_TEXTURE ) { + r128UpdateTextureState( ctx ); + } + } +} + + +static void r128DDInvalidateState( GLcontext *ctx, GLuint new_state ) +{ + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + R128_CONTEXT(ctx)->NewGLState |= new_state; +} + + + +/* Initialize the context's hardware state. + */ +void r128DDInitState( r128ContextPtr rmesa ) +{ + int dst_bpp, depth_bpp; + + 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... exiting\n" ); + exit( -1 ); + } + + rmesa->ClearColor = 0x00000000; + + switch ( rmesa->glCtx->Visual.depthBits ) { + case 16: + rmesa->ClearDepth = 0x0000ffff; + depth_bpp = R128_Z_PIX_WIDTH_16; + rmesa->depth_scale = 1.0 / (GLfloat)0xffff; + break; + case 24: + rmesa->ClearDepth = 0x00ffffff; + depth_bpp = R128_Z_PIX_WIDTH_24; + rmesa->depth_scale = 1.0 / (GLfloat)0xffffff; + break; + default: + fprintf( stderr, "Error: Unsupported depth %d... exiting\n", + rmesa->glCtx->Visual.depthBits ); + exit( -1 ); + } + + rmesa->Fallback = 0; + + if ( rmesa->glCtx->Visual.doubleBufferMode && rmesa->sarea->pfCurrentPage == 0 ) { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->backOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->backPitch; + } else { + rmesa->drawOffset = rmesa->readOffset = rmesa->r128Screen->frontOffset; + rmesa->drawPitch = rmesa->readPitch = rmesa->r128Screen->frontPitch; + } + + /* Harware state: + */ + 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. + */ +void r128DDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = r128DDInvalidateState; + + ctx->Driver.ClearIndex = NULL; + ctx->Driver.ClearColor = r128DDClearColor; + ctx->Driver.DrawBuffer = r128DDDrawBuffer; + ctx->Driver.ReadBuffer = r128DDReadBuffer; + + ctx->Driver.IndexMask = NULL; + ctx->Driver.ColorMask = r128DDColorMask; + ctx->Driver.AlphaFunc = r128DDAlphaFunc; + ctx->Driver.BlendEquation = r128DDBlendEquation; + ctx->Driver.BlendFunc = r128DDBlendFunc; + ctx->Driver.BlendFuncSeparate = r128DDBlendFuncSeparate; + ctx->Driver.ClearDepth = r128DDClearDepth; + ctx->Driver.CullFace = r128DDCullFace; + ctx->Driver.FrontFace = r128DDFrontFace; + ctx->Driver.DepthFunc = r128DDDepthFunc; + ctx->Driver.DepthMask = r128DDDepthMask; + ctx->Driver.Enable = r128DDEnable; + ctx->Driver.Fogfv = r128DDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LightModelfv = r128DDLightModelfv; + ctx->Driver.LogicOpcode = r128DDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = r128DDPolygonStipple; + ctx->Driver.RenderMode = r128DDRenderMode; + ctx->Driver.Scissor = r128DDScissor; + ctx->Driver.ShadeModel = r128DDShadeModel; + ctx->Driver.ClearStencil = NULL; + ctx->Driver.StencilFunc = NULL; + ctx->Driver.StencilMask = NULL; + ctx->Driver.StencilOp = NULL; + + ctx->Driver.DepthRange = r128DepthRange; + ctx->Driver.Viewport = r128Viewport; + + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.Bitmap = _swrast_Bitmap; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + ctx->Driver.DrawPixels = _swrast_DrawPixels; + ctx->Driver.ReadPixels = _swrast_ReadPixels; + + /* Swrast hooks for imaging extensions: + */ + ctx->Driver.CopyColorTable = _swrast_CopyColorTable; + ctx->Driver.CopyColorSubTable = _swrast_CopyColorSubTable; + ctx->Driver.CopyConvolutionFilter1D = _swrast_CopyConvolutionFilter1D; + ctx->Driver.CopyConvolutionFilter2D = _swrast_CopyConvolutionFilter2D; +} diff --git a/src/mesa/drivers/dri/r128/r128_state.h b/src/mesa/drivers/dri/r128/r128_state.h new file mode 100644 index 0000000000..c51ac23942 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_state.h @@ -0,0 +1,54 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_state.h,v 1.3 2001/01/08 01:07:21 martin Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#ifndef __R128_STATE_H__ +#define __R128_STATE_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "r128_context.h" + +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 r128EmitHwStateLocked( r128ContextPtr rmesa ); + +#endif +#endif diff --git a/src/mesa/drivers/dri/r128/r128_tex.c b/src/mesa/drivers/dri/r128/r128_tex.c new file mode 100644 index 0000000000..2793a793a0 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_tex.c @@ -0,0 +1,598 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.14 2002/11/05 17:46:08 tsi 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * Brian Paul + */ + +#include "r128_context.h" +#include "r128_state.h" +#include "r128_ioctl.h" +#include "r128_vb.h" +#include "r128_tris.h" +#include "r128_tex.h" +#include "r128_texobj.h" + +#include "context.h" +#include "macros.h" +#include "simple_list.h" +#include "enums.h" +#include "texstore.h" +#include "texformat.h" +#include "teximage.h" +#include "imports.h" +#include "colormac.h" + +#define TEX_0 1 +#define TEX_1 2 + + +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_BORDER_COLOR; + break; + case GL_CLAMP_TO_EDGE: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_CLAMP; + break; + case GL_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_WRAP; + break; + case GL_CLAMP_TO_BORDER: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_BORDER_COLOR; + break; + case GL_MIRRORED_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_S_MIRROR; + break; + } + + switch ( twrap ) { + case GL_CLAMP: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_BORDER_COLOR; + break; + case GL_CLAMP_TO_EDGE: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_CLAMP; + break; + case GL_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_WRAP; + break; + case GL_CLAMP_TO_BORDER: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_BORDER_COLOR; + break; + case GL_MIRRORED_REPEAT: + t->setup.tex_cntl |= R128_TEX_CLAMP_T_MIRROR; + 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_MIPLINEAR; + break; + case GL_NEAREST_MIPMAP_LINEAR: + t->setup.tex_cntl |= R128_MIN_BLEND_LINEARMIPNEAREST; + 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] ); +} + + +static r128TexObjPtr r128AllocTexObj( struct gl_texture_object *texObj ) +{ + r128TexObjPtr t; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p )\n", __FUNCTION__, texObj ); + } + + t = (r128TexObjPtr) CALLOC_STRUCT( r128_tex_obj ); + texObj->DriverData = t; + if ( t != NULL ) { + + /* Initialize non-image-dependent parts of the state: + */ + t->base.tObj = texObj; + + /* FIXME Something here to set initial values for other parts of + * FIXME t->setup? + */ + + make_empty_list( (driTextureObject *) t ); + + r128SetTexWrap( t, texObj->WrapS, texObj->WrapT ); + r128SetTexFilter( t, texObj->MinFilter, texObj->MagFilter ); + r128SetTexBorderColor( t, texObj->_BorderChan ); + } + + return t; +} + + +/* Called by the _mesa_store_teximage[123]d() functions. */ +static const struct gl_texture_format * +r128ChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + (void) format; + (void) type; + + switch ( internalFormat ) { + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: + case GL_LUMINANCE6_ALPHA2: + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + case GL_RGBA2: + case GL_RGB5_A1: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + if (rmesa->r128Screen->cpp == 4) + return &_mesa_texformat_argb8888; + else + return &_mesa_texformat_argb4444; + case GL_RGBA4: + return &_mesa_texformat_argb4444; + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + if (rmesa->r128Screen->cpp == 4) + return &_mesa_texformat_argb8888; + else + return &_mesa_texformat_rgb565; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + if (rmesa->r128Screen->cpp == 4) + return &_mesa_texformat_argb8888; /* inefficient but accurate */ + else + return &_mesa_texformat_rgb565; + + case GL_INTENSITY4: + return &_mesa_texformat_argb4444; + case GL_INTENSITY: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + if (rmesa->r128Screen->cpp == 4) + return &_mesa_texformat_argb8888; /* inefficient but accurate */ + else + return &_mesa_texformat_argb4444; + + case GL_COLOR_INDEX: + case GL_COLOR_INDEX1_EXT: + case GL_COLOR_INDEX2_EXT: + case GL_COLOR_INDEX4_EXT: + case GL_COLOR_INDEX8_EXT: + case GL_COLOR_INDEX12_EXT: + case GL_COLOR_INDEX16_EXT: + return &_mesa_texformat_ci8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + default: + _mesa_problem( ctx, "unexpected format in %s", __FUNCTION__ ); + return NULL; + } +} + + +static void r128TexImage1D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + + if ( t ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) r128AllocTexObj(texObj); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage1D"); + return; + } + } + + /* Note, this will call r128ChooseTextureFormat */ + _mesa_store_teximage1d( ctx, target, level, internalFormat, + width, border, format, type, + pixels, packing, texObj, texImage ); + + t->dirty_images[0] |= (1 << level); +} + + +static void r128TexSubImage1D( GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, + GLsizei width, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + + assert( t ); /* this _should_ be true */ + if ( t ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) r128AllocTexObj(texObj); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexSubImage1D"); + return; + } + } + + _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, + format, type, pixels, packing, texObj, + texImage); + + t->dirty_images[0] |= (1 << level); +} + + +static void r128TexImage2D( GLcontext *ctx, GLenum target, GLint level, + GLint internalFormat, + GLint width, GLint height, GLint border, + GLenum format, GLenum type, const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + + if ( t ) { + driSwapOutTextureObject( (driTextureObject *) t ); + } + else { + t = (driTextureObject *) r128AllocTexObj(texObj); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + + /* Note, this will call r128ChooseTextureFormat */ + _mesa_store_teximage2d(ctx, target, level, internalFormat, + width, height, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + t->dirty_images[0] |= (1 << level); +} + + +static void r128TexSubImage2D( GLcontext *ctx, + GLenum target, + GLint level, + GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, + GLenum format, GLenum type, + const GLvoid *pixels, + const struct gl_pixelstore_attrib *packing, + struct gl_texture_object *texObj, + struct gl_texture_image *texImage ) +{ + driTextureObject * t = (driTextureObject *) texObj->DriverData; + + assert( t ); /* this _should_ be true */ + if ( t ) { + driSwapOutTextureObject( t ); + } + else { + t = (driTextureObject *) r128AllocTexObj(texObj); + if (!t) { + _mesa_error(ctx, GL_OUT_OF_MEMORY, "glTexImage2D"); + return; + } + } + + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, type, pixels, packing, texObj, + texImage); + t->dirty_images[0] |= (1 << level); +} + + +static void r128DDTexEnv( GLcontext *ctx, GLenum target, + GLenum pname, const GLfloat *param ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + struct gl_texture_unit *texUnit; + GLubyte c[4]; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) ); + } + + switch ( pname ) { + case GL_TEXTURE_ENV_MODE: + FLUSH_BATCH( rmesa ); + rmesa->new_state |= R128_NEW_ALPHA; + break; + + case GL_TEXTURE_ENV_COLOR: + texUnit = &ctx->Texture.Unit[ctx->Texture.CurrentUnit]; + CLAMPED_FLOAT_TO_UBYTE( c[0], texUnit->EnvColor[0] ); + CLAMPED_FLOAT_TO_UBYTE( c[1], texUnit->EnvColor[1] ); + CLAMPED_FLOAT_TO_UBYTE( c[2], texUnit->EnvColor[2] ); + CLAMPED_FLOAT_TO_UBYTE( c[3], texUnit->EnvColor[3] ); + 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; + + /* 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). This is only + * applicable to the regular Rage 128, as the Pro and M3 can + * handle true single-pass GL_BLEND texturing. + */ + 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: + 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; + } + + 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: + return; + } +} + + +static void r128DDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj, + GLenum pname, const GLfloat *params ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + r128TexObjPtr t = (r128TexObjPtr)tObj->DriverData; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %s )\n", + __FUNCTION__, _mesa_lookup_enum_by_nr( pname ) ); + } + + if ( ( target != GL_TEXTURE_2D ) && ( target != GL_TEXTURE_1D ) ) + return; + + switch ( pname ) { + case GL_TEXTURE_MIN_FILTER: + case GL_TEXTURE_MAG_FILTER: + if ( t->base.bound ) FLUSH_BATCH( rmesa ); + r128SetTexFilter( t, tObj->MinFilter, tObj->MagFilter ); + break; + + case GL_TEXTURE_WRAP_S: + case GL_TEXTURE_WRAP_T: + if ( t->base.bound ) FLUSH_BATCH( rmesa ); + r128SetTexWrap( t, tObj->WrapS, tObj->WrapT ); + break; + + case GL_TEXTURE_BORDER_COLOR: + if ( t->base.bound ) FLUSH_BATCH( rmesa ); + r128SetTexBorderColor( t, tObj->_BorderChan ); + break; + + case GL_TEXTURE_BASE_LEVEL: + case GL_TEXTURE_MAX_LEVEL: + case GL_TEXTURE_MIN_LOD: + case GL_TEXTURE_MAX_LOD: + /* This isn't the most efficient solution but there doesn't appear to + * be a nice alternative for R128. Since there's no LOD clamping, + * we just have to rely on loading the right subset of mipmap levels + * to simulate a clamped LOD. + */ + if ( t->base.bound ) FLUSH_BATCH( rmesa ); + driSwapOutTextureObject( (driTextureObject *) t ); + break; + + default: + return; + } +} + +static void r128DDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *tObj ) +{ + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p ) unit=%d\n", __FUNCTION__, tObj, + ctx->Texture.CurrentUnit ); + } + + if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) { + if ( tObj->DriverData == NULL ) { + r128AllocTexObj( tObj ); + } + } +} + +static void r128DDDeleteTexture( GLcontext *ctx, + struct gl_texture_object *tObj ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + driTextureObject * t = (driTextureObject *) tObj->DriverData; + + if ( t ) { + if ( t->bound && rmesa ) { + FLUSH_BATCH( rmesa ); + } + + driDestroyTextureObject( t ); + } +} + +void r128DDInitTextureFuncs( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + + ctx->Driver.TexEnv = r128DDTexEnv; + ctx->Driver.ChooseTextureFormat = r128ChooseTextureFormat; + ctx->Driver.TexImage1D = r128TexImage1D; + ctx->Driver.TexSubImage1D = r128TexSubImage1D; + ctx->Driver.TexImage2D = r128TexImage2D; + ctx->Driver.TexSubImage2D = r128TexSubImage2D; + ctx->Driver.TexImage3D = _mesa_store_teximage3d; + ctx->Driver.TexSubImage3D = _mesa_store_texsubimage3d; + ctx->Driver.CopyTexImage1D = _swrast_copy_teximage1d; + ctx->Driver.CopyTexImage2D = _swrast_copy_teximage2d; + ctx->Driver.CopyTexSubImage1D = _swrast_copy_texsubimage1d; + ctx->Driver.CopyTexSubImage2D = _swrast_copy_texsubimage2d; + ctx->Driver.CopyTexSubImage3D = _swrast_copy_texsubimage3d; + ctx->Driver.TestProxyTexImage = _mesa_test_proxy_teximage; + ctx->Driver.TexParameter = r128DDTexParameter; + ctx->Driver.BindTexture = r128DDBindTexture; + ctx->Driver.DeleteTexture = r128DDDeleteTexture; + ctx->Driver.UpdateTexturePalette = NULL; + ctx->Driver.ActiveTexture = NULL; + ctx->Driver.IsTextureResident = driIsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; + + driInitTextureObjects( ctx, & rmesa->swapped, + DRI_TEXMGR_DO_TEXTURE_1D + | DRI_TEXMGR_DO_TEXTURE_2D ); +} diff --git a/src/mesa/drivers/dri/r128/r128_tex.h b/src/mesa/drivers/dri/r128/r128_tex.h new file mode 100644 index 0000000000..2e3d954fbb --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_tex.h @@ -0,0 +1,88 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.h,v 1.7 2002/02/22 21:44:58 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * + */ + +#ifndef __R128_TEX_H__ +#define __R128_TEX_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void r128UpdateTextureState( GLcontext *ctx ); + +extern void r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ); + +extern void r128DestroyTexObj( r128ContextPtr rmesa, r128TexObjPtr t ); + +extern void r128DDInitTextureFuncs( GLcontext *ctx ); + + +/* ================================================================ + * 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 R128PACKCOLOR565( r, g, b ) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define R128PACKCOLOR888( r, g, b ) \ + (((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)) + +static __inline__ CARD32 r128PackColor( GLuint cpp, + GLubyte r, GLubyte g, + GLubyte b, GLubyte a ) +{ + 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__ */ diff --git a/src/mesa/drivers/dri/r128/r128_texmem.c b/src/mesa/drivers/dri/r128/r128_texmem.c new file mode 100644 index 0000000000..f6a5dfbbcf --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_texmem.c @@ -0,0 +1,302 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.7 2001/01/08 01:07:21 martin Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * Brian Paul + */ + +#include "r128_context.h" +#include "r128_state.h" +#include "r128_ioctl.h" +#include "r128_vb.h" +#include "r128_tris.h" +#include "r128_tex.h" + +#include "context.h" +#include "macros.h" +#include "simple_list.h" +#include "texformat.h" +#include "imports.h" + +#define TEX_0 1 +#define TEX_1 2 + + +/* Destroy hardware state associated with texture `t'. + */ +void r128DestroyTexObj( r128ContextPtr rmesa, r128TexObjPtr t ) +{ + unsigned i; + + + /* See if it was the driver's current object. + */ + + if ( rmesa != NULL ) + { + for ( i = 0 ; i < rmesa->glCtx->Const.MaxTextureUnits ; i++ ) + { + if ( t == rmesa->CurrentTexObj[ i ] ) { + assert( t->base.bound & (1 << i) ); + rmesa->CurrentTexObj[ i ] = NULL; + } + } + } +} + + +/** + * Upload the texture image associated with texture \a t at the specified + * level at the address relative to \a start. + */ +static void uploadSubImage( r128ContextPtr rmesa, r128TexObjPtr t, + GLint level, + GLint x, GLint y, GLint width, GLint height ) +{ + struct gl_texture_image *image; + int texelsPerDword = 0; + int imageWidth, imageHeight; + int remaining, rows; + int format, dwords; + CARD32 pitch, offset; + int i; + + /* Ensure we have a valid texture to upload */ + if ( ( level < 0 ) || ( level > R128_MAX_TEXTURE_LEVELS ) ) + return; + + image = t->base.tObj->Image[level]; + if ( !image ) + return; + + switch ( image->TexFormat->TexelBytes ) { + case 1: texelsPerDword = 4; break; + case 2: texelsPerDword = 2; break; + case 4: texelsPerDword = 1; break; + } + +#if 1 + /* FIXME: The subimage index calcs are wrong... */ + x = 0; + y = 0; + width = image->Width; + height = image->Height; +#endif + + imageWidth = image->Width; + imageHeight = image->Height; + + format = t->textureFormat >> 16; + + /* The texel upload routines have a minimum width, so force the size + * if needed. + */ + if ( imageWidth < texelsPerDword ) { + int factor; + + factor = texelsPerDword / imageWidth; + imageWidth = texelsPerDword; + imageHeight /= factor; + if ( imageHeight == 0 ) { + /* In this case, the texel converter will actually walk a + * texel or two off the end of the image, but normal malloc + * alignment should prevent it from ever causing a fault. + */ + imageHeight = 1; + } + } + + /* We can't upload to a pitch less than 8 texels so we will need to + * linearly upload all modified rows for textures smaller than this. + * This makes the x/y/width/height different for the blitter and the + * texture walker. + */ + if ( imageWidth >= 8 ) { + /* The texture walker and the blitter look identical */ + pitch = imageWidth >> 3; + } else { + int factor; + int y2; + int start, end; + + start = (y * imageWidth) & ~7; + end = (y + height) * imageWidth; + + if ( end - start < 8 ) { + /* Handle the case where the total number of texels + * uploaded is < 8. + */ + x = 0; + y = start / 8; + width = end - start; + height = 1; + } else { + /* Upload some number of full 8 texel blit rows */ + factor = 8 / imageWidth; + + y2 = y + height - 1; + y /= factor; + y2 /= factor; + + x = 0; + width = 8; + height = y2 - y + 1; + } + + /* Fixed pitch of 8 */ + pitch = 1; + } + + dwords = width * height / texelsPerDword; + offset = t->bufAddr + t->image[level - t->base.firstLevel].offset; + +#if ENABLE_PERF_BOXES + /* Bump the performace counter */ + 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", + (GLuint)offset, (GLuint)pitch, dwords, level, format ); + } + + /* Subdivide the texture if required */ + if ( dwords <= R128_BUFFER_MAX_DWORDS / 2 ) { + rows = height; + } else { + rows = (R128_BUFFER_MAX_DWORDS * texelsPerDword) / (2 * width); + } + + for ( i = 0, remaining = height ; + remaining > 0 ; + remaining -= rows, y += rows, i++ ) + { + CARD32 *dst; + drmBufPtr buffer; + + assert(image->Data); + + height = MIN2(remaining, rows); + + /* Grab the indirect buffer for the texture blit */ + LOCK_HARDWARE( rmesa ); + buffer = r128GetBufferLocked( rmesa ); + + dst = (CARD32 *)((char *)buffer->address + R128_HOSTDATA_BLIT_OFFSET); + + /* Copy the next chunck of the texture image into the blit buffer */ + { + const GLubyte *src = (const GLubyte *) image->Data + + (y * image->Width + x) * image->TexFormat->TexelBytes; + const GLuint bytes = width * height * image->TexFormat->TexelBytes; + memcpy(dst, src, bytes); + } + + r128FireBlitLocked( rmesa, buffer, + offset, pitch, format, + x, y, width, height ); + UNLOCK_HARDWARE( rmesa ); + } + + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT | R128_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. + */ +void r128UploadTexImages( r128ContextPtr rmesa, r128TexObjPtr t ) +{ + const GLint numLevels = t->base.lastLevel - t->base.firstLevel + 1; + GLint i; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %p )\n", + __FUNCTION__, rmesa->glCtx, t ); + } + + assert(t); + + LOCK_HARDWARE( rmesa ); + + if ( !t->base.memBlock ) { + int heap; + + + heap = driAllocateTexture( rmesa->texture_heaps, rmesa->nr_heaps, + (driTextureObject *) t ); + if ( heap == -1 ) { + UNLOCK_HARDWARE( rmesa ); + return; + } + + /* Set the base offset of the texture image */ + t->bufAddr = rmesa->r128Screen->texOffset[heap] + + t->base.memBlock->ofs; + + /* Set texture offsets for each mipmap level */ + if ( t->setup.tex_cntl & R128_MIP_MAP_DISABLE ) { + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { + t->setup.tex_offset[i] = t->bufAddr; + } + } else { + for ( i = 0; i < numLevels; i++ ) { + const int j = numLevels - i - 1; + t->setup.tex_offset[j] = t->bufAddr + t->image[i].offset; + } + } + } + + /* Let the world know we've used this memory recently. + */ + driUpdateTextureLRU( (driTextureObject *) t ); + UNLOCK_HARDWARE( rmesa ); + + /* Upload any images that are new */ + if ( t->base.dirty_images[0] ) { + for ( i = 0 ; i < numLevels; i++ ) { + const GLint j = t->base.firstLevel + i; /* the texObj's level */ + if ( t->base.dirty_images[0] & (1 << j) ) { + uploadSubImage( rmesa, t, j, 0, 0, + t->image[i].width, t->image[i].height ); + } + } + + rmesa->setup.tex_cntl_c |= R128_TEX_CACHE_FLUSH; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + t->base.dirty_images[0] = 0; + } +} diff --git a/src/mesa/drivers/dri/r128/r128_texobj.h b/src/mesa/drivers/dri/r128/r128_texobj.h new file mode 100644 index 0000000000..e2ff1ac24d --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_texobj.h @@ -0,0 +1,69 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_texobj.h,v 1.5 2002/02/22 21:44:58 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. + +**************************************************************************/ + +/* + * Authors: + * Kevin E. Martin + * Gareth Hughes + * + */ + +#ifndef _R128_TEXOBJ_H_ +#define _R128_TEXOBJ_H_ + +#include "r128_sarea.h" +#include "mm.h" + +/* Individual texture image information. + */ +typedef struct { + 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. + */ +struct r128_tex_obj { + driTextureObject base; + + CARD32 bufAddr; /* Offset to start of locally + shared texture block */ + + GLuint age; + r128TexImage image[R128_MAX_TEXTURE_LEVELS]; /* Image data for all + mipmap levels */ + + CARD32 textureFormat; /* Actual hardware format */ + + r128_texture_regs_t setup; /* Setup regs for texture */ +}; + +#endif /* _R128_TEXOBJ_H_ */ diff --git a/src/mesa/drivers/dri/r128/r128_texstate.c b/src/mesa/drivers/dri/r128/r128_texstate.c new file mode 100644 index 0000000000..3f4347b02e --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_texstate.c @@ -0,0 +1,652 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tex.c,v 1.7 2001/01/08 01:07:21 martin Exp $ */ +/************************************************************************** + +Copyright 1999, 2000 ATI Technologies Inc. and Precision Insight, Inc., + 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. + +**************************************************************************/ + +/* + * Authors: + * Gareth Hughes + * Kevin E. Martin + * Brian Paul + */ + +#include "glheader.h" +#include "imports.h" +#include "context.h" +#include "macros.h" +#include "texformat.h" + +#include "r128_context.h" +#include "r128_state.h" +#include "r128_ioctl.h" +#include "r128_vb.h" +#include "r128_tris.h" +#include "r128_tex.h" + + +static void r128SetTexImages( r128ContextPtr rmesa, + const struct gl_texture_object *tObj ) +{ + r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData; + struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel]; + int log2Pitch, log2Height, log2Size, log2MinSize; + int totalSize; + int i; + GLint firstLevel, lastLevel; + + assert(t); + assert(baseImage); + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) + fprintf( stderr, "%s( %p )\n", __FUNCTION__, tObj ); + + switch (baseImage->TexFormat->MesaFormat) { + case MESA_FORMAT_ARGB8888: + t->textureFormat = R128_DATATYPE_ARGB8888; + break; + case MESA_FORMAT_ARGB4444: + t->textureFormat = R128_DATATYPE_ARGB4444; + break; + case MESA_FORMAT_RGB565: + t->textureFormat = R128_DATATYPE_RGB565; + break; + case MESA_FORMAT_RGB332: + t->textureFormat = R128_DATATYPE_RGB8; + break; + case MESA_FORMAT_CI8: + t->textureFormat = R128_DATATYPE_CI8; + break; + case MESA_FORMAT_YCBCR: + t->textureFormat = R128_DATATYPE_YVYU422; + break; + case MESA_FORMAT_YCBCR_REV: + t->textureFormat = R128_DATATYPE_VYUY422; + break; + default: + _mesa_problem(rmesa->glCtx, "Bad texture format in %s", __FUNCTION__); + }; + + /* Compute which mipmap levels we really want to send to the hardware. + * This depends on the base image size, GL_TEXTURE_MIN_LOD, + * GL_TEXTURE_MAX_LOD, GL_TEXTURE_BASE_LEVEL, and GL_TEXTURE_MAX_LEVEL. + * Yes, this looks overly complicated, but it's all needed. + */ + firstLevel = tObj->BaseLevel + (GLint) (tObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, tObj->BaseLevel); + lastLevel = tObj->BaseLevel + (GLint) (tObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, tObj->BaseLevel); + lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2); + lastLevel = MIN2(lastLevel, tObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + + log2Pitch = tObj->Image[firstLevel]->WidthLog2; + log2Height = tObj->Image[firstLevel]->HeightLog2; + log2Size = MAX2(log2Pitch, log2Height); + log2MinSize = log2Size; + + t->base.dirty_images[0] = 0; + totalSize = 0; + for ( i = firstLevel; i <= lastLevel; i++ ) { + const struct gl_texture_image *texImage; + + texImage = tObj->Image[i]; + if ( !texImage || !texImage->Data ) { + lastLevel = i - 1; + break; + } + + log2MinSize = texImage->MaxLog2; + + t->image[i - firstLevel].offset = totalSize; + t->image[i - firstLevel].width = tObj->Image[i]->Width; + t->image[i - firstLevel].height = tObj->Image[i]->Height; + + t->base.dirty_images[0] |= (1 << i); + + totalSize += (tObj->Image[i]->Height * + tObj->Image[i]->Width * + tObj->Image[i]->TexFormat->TexelBytes); + + /* Offsets must be 32-byte aligned for host data blits and tiling */ + totalSize = (totalSize + 31) & ~31; + } + + t->base.totalSize = totalSize; + t->base.firstLevel = firstLevel; + t->base.lastLevel = lastLevel; + + /* Set the texture format */ + t->setup.tex_cntl &= ~(0xf << 16); + t->setup.tex_cntl |= t->textureFormat; + + t->setup.tex_combine_cntl = 0x00000000; /* XXX is this right? */ + + t->setup.tex_size_pitch = ((log2Pitch << R128_TEX_PITCH_SHIFT) | + (log2Size << R128_TEX_SIZE_SHIFT) | + (log2Height << R128_TEX_HEIGHT_SHIFT) | + (log2MinSize << R128_TEX_MIN_SIZE_SHIFT)); + + for ( i = 0 ; i < R128_MAX_TEXTURE_LEVELS ; i++ ) { + t->setup.tex_offset[i] = 0x00000000; + } + + if (firstLevel == lastLevel) + t->setup.tex_cntl |= R128_MIP_MAP_DISABLE; + else + t->setup.tex_cntl &= ~R128_MIP_MAP_DISABLE; + + /* FYI: r128UploadTexImages( rmesa, t ); used to be called here */ +} + + +/* ================================================================ + * 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) +/* 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 GLboolean r128UpdateTextureEnv( GLcontext *ctx, int unit ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLint source = rmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + const struct gl_texture_object *tObj = texUnit->_Current; + const GLenum format = tObj->Image[tObj->BaseLevel]->Format; + GLuint combine; + + if ( R128_DEBUG & DEBUG_VERBOSE_API ) { + fprintf( stderr, "%s( %p, %d )\n", + __FUNCTION__, ctx, unit ); + } + + if ( unit == 0 ) { + combine = INPUT_INTERP; + } else { + combine = INPUT_PREVIOUS; + } + + /* Set the texture environment state */ + switch ( texUnit->EnvMode ) { + case GL_REPLACE: + switch ( format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + combine |= (COLOR_COMB_DISABLE | /* C = Ct */ + ALPHA_COMB_DISABLE); /* A = At */ + break; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_DISABLE | /* C = Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; + case GL_ALPHA: + combine |= (COLOR_COMB_COPY_INPUT | /* C = Cf */ + ALPHA_COMB_DISABLE); /* A = At */ + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } + break; + + case GL_MODULATE: + switch ( format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + combine |= (COLOR_COMB_MODULATE | /* C = CfCt */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_MODULATE | /* C = CfCt */ + 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_COLOR_INDEX: + default: + return GL_FALSE; + } + break; + + case GL_DECAL: + switch ( format ) { + case GL_RGBA: + combine |= (COLOR_COMB_BLEND_TEX | /* C = Cf(1-At)+CtAt */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; + case GL_RGB: + combine |= (COLOR_COMB_DISABLE | /* C = Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_LUMINANCE_ALPHA: + case GL_INTENSITY: + /* Undefined behaviour - just copy the incoming fragment */ + combine |= (COLOR_COMB_COPY_INPUT | /* C = undefined */ + ALPHA_COMB_COPY_INPUT); /* A = undefined */ + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } + break; + + case GL_BLEND: + /* Rage 128 Pro and M3 can handle GL_BLEND texturing. + */ + if ( !R128_IS_PLAIN( rmesa ) ) { + /* XXX this hasn't been fully tested, I don't have a Pro card. -BP */ + switch ( 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 */ + return GL_FALSE; + } + break; + + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } + break; + } + + /* Rage 128 has to fake some cases of GL_BLEND, otherwise fallback + * to software rendering. + */ + if ( rmesa->blend_flags ) { + return GL_FALSE; + } + switch ( format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + switch ( rmesa->env_color & 0x00ffffff ) { + case 0x00000000: + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; +#if 0 + /* This isn't right - BP */ + case 0x00ffffff: + if ( unit == 0 ) { + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + } else { + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + } + break; +#endif + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + return GL_FALSE; + } + break; + case GL_RGB: + case GL_LUMINANCE: + switch ( rmesa->env_color & 0x00ffffff ) { + case 0x00000000: + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + break; +#if 0 + /* This isn't right - BP */ + case 0x00ffffff: + if ( unit == 0 ) { + combine |= (COLOR_COMB_MODULATE_NTEX | /* C = Cf(1-Ct) */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + } else { + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_COPY_INPUT); /* A = Af */ + } + break; +#endif + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_COPY_INPUT); /* A = fallback */ + return GL_FALSE; + } + break; + case GL_ALPHA: + 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 ( rmesa->env_color & 0x00ffffff ) { + case 0x00000000: + combine |= COLOR_COMB_MODULATE_NTEX; /* C = Cf(1-It) */ + break; +#if 0 + /* This isn't right - BP */ + case 0x00ffffff: + if ( unit == 0 ) { + combine |= COLOR_COMB_MODULATE_NTEX; /* C = Cf(1-It) */ + } else { + combine |= COLOR_COMB_ADD; /* C = Cf+It */ + } + break; +#endif + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + return GL_FALSE; + } + switch ( rmesa->env_color & 0xff000000 ) { + case 0x00000000: + combine |= ALPHA_COMB_MODULATE_NTEX; /* A = Af(1-It) */ + break; +#if 0 + /* This isn't right - BP */ + case 0xff000000: + if ( unit == 0 ) { + combine |= ALPHA_COMB_MODULATE_NTEX; /* A = Af(1-It) */ + } else { + combine |= ALPHA_COMB_ADD; /* A = Af+It */ + } + break; +#endif + default: + combine |= (COLOR_COMB_MODULATE | /* C = fallback */ + ALPHA_COMB_MODULATE); /* A = fallback */ + return GL_FALSE; + } + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } + break; + + case GL_ADD: + switch ( format ) { + case GL_RGBA: + case GL_LUMINANCE_ALPHA: + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_MODULATE); /* A = AfAt */ + break; + case GL_RGB: + case GL_LUMINANCE: + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + 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: + combine |= (COLOR_COMB_ADD | /* C = Cf+Ct */ + ALPHA_COMB_ADD); /* A = Af+At */ + break; + case GL_COLOR_INDEX: + default: + return GL_FALSE; + } + break; + + default: + return GL_FALSE; + } + + if ( rmesa->tex_combine[unit] != combine ) { + rmesa->tex_combine[unit] = combine; + rmesa->dirty |= R128_UPLOAD_TEX0 << unit; + } + return GL_TRUE; +} + +static void disable_tex( GLcontext *ctx, int unit ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + FLUSH_BATCH( rmesa ); + + if ( rmesa->CurrentTexObj[unit] ) { + rmesa->CurrentTexObj[unit]->base.bound &= ~(1 << unit); + rmesa->CurrentTexObj[unit] = NULL; + } + + rmesa->setup.tex_cntl_c &= ~(R128_TEXMAP_ENABLE << unit); + rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK << + (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit)); + rmesa->dirty |= R128_UPLOAD_CONTEXT; + + /* If either texture unit is disabled, then multitexturing is not + * happening. + */ + + rmesa->blend_flags &= ~R128_BLEND_MULTITEX; +} + +static GLboolean enable_tex_2d( GLcontext *ctx, int unit ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + const int source = rmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + const struct gl_texture_object *tObj = texUnit->_Current; + r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData; + + /* Need to load the 2d images associated with this unit. + */ + if ( t->base.dirty_images[0] ) { + /* FIXME: For Radeon, RADEON_FIREVERTICES is called here. Should + * FIXME: something similar be done for R128? + */ + /* FLUSH_BATCH( rmesa ); */ + + r128SetTexImages( rmesa, tObj ); + r128UploadTexImages( rmesa, t ); + if ( !t->base.memBlock ) + return GL_FALSE; + } + + return GL_TRUE; +} + +static GLboolean update_tex_common( GLcontext *ctx, int unit ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + const int source = rmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + const struct gl_texture_object *tObj = texUnit->_Current; + r128TexObjPtr t = (r128TexObjPtr) tObj->DriverData; + + + /* Fallback if there's a texture border */ + if ( tObj->Image[tObj->BaseLevel]->Border > 0 ) { + return GL_FALSE; + } + + + /* Update state if this is a different texture object to last + * time. + */ + if ( rmesa->CurrentTexObj[unit] != t ) { + if ( rmesa->CurrentTexObj[unit] != NULL ) { + /* The old texture is no longer bound to this texture unit. + * Mark it as such. + */ + + rmesa->CurrentTexObj[unit]->base.bound &= + ~(1UL << unit); + } + + rmesa->CurrentTexObj[unit] = t; + t->base.bound |= (1UL << unit); + rmesa->dirty |= R128_UPLOAD_TEX0 << unit; + + driUpdateTextureLRU( (driTextureObject *) t ); /* XXX: should be locked! */ + } + + /* FIXME: We need to update the texture unit if any texture parameters have + * changed, but this texture was already bound. This could be changed to + * work like the Radeon driver where the texture object has it's own + * dirty state flags + */ + rmesa->dirty |= R128_UPLOAD_TEX0 << unit; + + /* register setup */ + rmesa->setup.tex_size_pitch_c &= ~(R128_TEX_SIZE_PITCH_MASK << + (R128_SEC_TEX_SIZE_PITCH_SHIFT * unit)); + + if ( unit == 0 ) { + 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 { + 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; + t->setup.tex_cntl |= R128_SEC_SELECT_SEC_ST; + + /* If the second TMU is enabled, then multitexturing is happening. + */ + if ( R128_IS_PLAIN( rmesa ) ) + rmesa->blend_flags |= R128_BLEND_MULTITEX; + } + + rmesa->dirty |= R128_UPLOAD_CONTEXT; + + + /* FIXME: The Radeon has some cached state so that it can avoid calling + * FIXME: UpdateTextureEnv in some cases. Is that possible here? + */ + return r128UpdateTextureEnv( ctx, unit ); +} + +static GLboolean updateTextureUnit( GLcontext *ctx, int unit ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + const int source = rmesa->tmu_source[unit]; + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[source]; + + + if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) { + return (enable_tex_2d( ctx, unit ) && + update_tex_common( ctx, unit )); + } + else if ( texUnit->_ReallyEnabled ) { + return GL_FALSE; + } + else { + disable_tex( ctx, unit ); + return GL_TRUE; + } +} + + +void r128UpdateTextureState( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLboolean ok; + + + /* This works around a quirk with the R128 hardware. If only OpenGL + * TEXTURE1 is enabled, then the hardware TEXTURE0 must be used. The + * hardware TEXTURE1 can ONLY be used when hardware TEXTURE0 is also used. + */ + + rmesa->tmu_source[0] = 0; + rmesa->tmu_source[1] = 1; + + if ((ctx->Texture._EnabledUnits & 0x03) == 0x02) { + /* only texture 1 enabled */ + rmesa->tmu_source[0] = 1; + rmesa->tmu_source[1] = 0; + } + + ok = (updateTextureUnit( ctx, 0 ) && + updateTextureUnit( ctx, 1 )); + + FALLBACK( rmesa, R128_FALLBACK_TEXTURE, !ok ); +} diff --git a/src/mesa/drivers/dri/r128/r128_tris.c b/src/mesa/drivers/dri/r128/r128_tris.c new file mode 100644 index 0000000000..4e2860288e --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_tris.c @@ -0,0 +1,721 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.c,v 1.8 2002/10/30 12:51:43 alanh Exp $ */ /* -*- c-basic-offset: 3 -*- */ +/************************************************************************** + +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 + * + */ + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "macros.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/tnl.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "r128_tris.h" +#include "r128_state.h" +#include "r128_tex.h" +#include "r128_vb.h" +#include "r128_ioctl.h" + +static const GLuint hw_prim[GL_POLYGON+1] = { + R128_CCE_VC_CNTL_PRIM_TYPE_POINT, + R128_CCE_VC_CNTL_PRIM_TYPE_LINE, + R128_CCE_VC_CNTL_PRIM_TYPE_LINE, + R128_CCE_VC_CNTL_PRIM_TYPE_LINE, + R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST, + R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST, + R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST, + R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST, + R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST, + R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST, +}; + +static void r128RasterPrimitive( GLcontext *ctx, GLuint hwprim ); +static void r128RenderPrimitive( GLcontext *ctx, GLenum prim ); + + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#if defined(USE_X86_ASM) +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + int __tmp; \ + __asm__ __volatile__( "rep ; movsl" \ + : "=%c" (j), "=D" (vb), "=S" (__tmp) \ + : "0" (vertsize), \ + "D" ((long)vb), \ + "S" ((long)v) ); \ +} while (0) +#else +#define COPY_DWORDS( j, vb, vertsize, v ) \ +do { \ + for ( j = 0 ; j < vertsize ; j++ ) \ + vb[j] = CPU_TO_LE32(((GLuint *)v)[j]); \ + vb += vertsize; \ +} while (0) +#endif + +static __inline void r128_draw_quad( r128ContextPtr rmesa, + r128VertexPtr v0, + r128VertexPtr v1, + r128VertexPtr v2, + r128VertexPtr v3 ) +{ + GLuint vertsize = rmesa->vertex_size; + GLuint *vb = (GLuint *)r128AllocDmaLow( rmesa, 6 * vertsize * 4 ); + GLuint j; + + rmesa->num_verts += 6; + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v3 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); + COPY_DWORDS( j, vb, vertsize, v3 ); +} + + +static __inline void r128_draw_triangle( r128ContextPtr rmesa, + r128VertexPtr v0, + r128VertexPtr v1, + r128VertexPtr v2 ) +{ + GLuint vertsize = rmesa->vertex_size; + GLuint *vb = (GLuint *)r128AllocDmaLow( rmesa, 3 * vertsize * 4 ); + GLuint j; + + rmesa->num_verts += 3; + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); + COPY_DWORDS( j, vb, vertsize, v2 ); +} + +static __inline void r128_draw_line( r128ContextPtr rmesa, + r128VertexPtr v0, + r128VertexPtr v1 ) +{ + GLuint vertsize = rmesa->vertex_size; + GLuint *vb = (GLuint *)r128AllocDmaLow( rmesa, 2 * vertsize * 4 ); + GLuint j; + + rmesa->num_verts += 2; + COPY_DWORDS( j, vb, vertsize, v0 ); + COPY_DWORDS( j, vb, vertsize, v1 ); +} + +static __inline void r128_draw_point( r128ContextPtr rmesa, + r128VertexPtr v0 ) +{ + int vertsize = rmesa->vertex_size; + GLuint *vb = (GLuint *)r128AllocDmaLow( rmesa, vertsize * 4 ); + int j; + + rmesa->num_verts += 1; + COPY_DWORDS( j, vb, vertsize, v0 ); +} + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + rmesa->draw_tri( rmesa, a, b, c ); \ + else \ + r128_draw_triangle( rmesa, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + rmesa->draw_tri( rmesa, a, b, d ); \ + rmesa->draw_tri( rmesa, b, c, d ); \ + } else \ + r128_draw_quad( rmesa, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + rmesa->draw_line( rmesa, v0, v1 ); \ + else \ + r128_draw_line( rmesa, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + rmesa->draw_point( rmesa, v0 ); \ + else \ + r128_draw_point( rmesa, v0 ); \ +} while (0) + + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define R128_OFFSET_BIT 0x01 +#define R128_TWOSIDE_BIT 0x02 +#define R128_UNFILLED_BIT 0x04 +#define R128_FALLBACK_BIT 0x08 +#define R128_MAX_TRIFUNC 0x10 + + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[R128_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & R128_FALLBACK_BIT) +#define DO_OFFSET (IND & R128_OFFSET_BIT) +#define DO_UNFILLED (IND & R128_UNFILLED_BIT) +#define DO_TWOSIDE (IND & R128_TWOSIDE_BIT) +#define DO_FLAT 0 +#define DO_TRI 1 +#define DO_QUAD 1 +#define DO_LINE 1 +#define DO_POINTS 1 +#define DO_FULL_QUAD 1 + +#define HAVE_RGBA 1 +#define HAVE_SPEC 1 +#define HAVE_BACK_COLORS 0 +#define HAVE_HW_FLATSHADE 1 +#define VERTEX r128Vertex +#define TAB rast_tab + +#define DEPTH_SCALE 1.0 +#define UNFILLED_TRI unfilled_tri +#define UNFILLED_QUAD unfilled_quad +#define VERT_X(_v) _v->v.x +#define VERT_Y(_v) _v->v.y +#define VERT_Z(_v) _v->v.z +#define AREA_IS_CCW( a ) (a > 0) +#define GET_VERTEX(e) (rmesa->verts + (e<vertex_stride_shift)) + +#define VERT_SET_RGBA( v, c ) do { \ + r128_color_t *vc = (r128_color_t *)&(v)->ui[coloroffset]; \ + vc->blue = (c)[2]; \ + vc->green = (c)[1]; \ + vc->red = (c)[0]; \ + vc->alpha = (c)[3]; \ + } while (0) +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] +#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx] + +#define VERT_SET_SPEC( v0, c ) if (havespec) { \ + (v0)->v.specular.red = (c)[0];\ + (v0)->v.specular.green = (c)[1];\ + (v0)->v.specular.blue = (c)[2]; } +#define VERT_COPY_SPEC( v0, v1 ) if (havespec) { \ + (v0)->v.specular.red = v1->v.specular.red; \ + (v0)->v.specular.green = v1->v.specular.green; \ + (v0)->v.specular.blue = v1->v.specular.blue; } + +#define VERT_SAVE_SPEC( idx ) if (havespec) spec[idx] = v[idx]->ui[5] +#define VERT_RESTORE_SPEC( idx ) if (havespec) v[idx]->ui[5] = spec[idx] + +#define LOCAL_VARS(n) \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (rmesa->vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (rmesa->vertex_size == 4 ? 0 : 1); \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) if (rmesa->hw_primitive != hw_prim[x]) \ + r128RasterPrimitive( ctx, hw_prim[x] ) +#define RENDER_PRIMITIVE rmesa->render_primitive +#define IND R128_FALLBACK_BIT +#define TAG(x) x +#include "tnl_dd/t_dd_unfilled.h" +#undef IND + + +/*********************************************************************** + * Generate GL render functions * + ***********************************************************************/ + + +#define IND (0) +#define TAG(x) x +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_OFFSET_BIT|R128_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_TWOSIDE_BIT|R128_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_UNFILLED_BIT|R128_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_OFFSET_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_TWOSIDE_BIT|R128_UNFILLED_BIT|R128_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (R128_TWOSIDE_BIT|R128_OFFSET_BIT|R128_UNFILLED_BIT| \ + R128_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + + +static void init_rast_tab( void ) +{ + init(); + init_offset(); + init_twoside(); + init_twoside_offset(); + init_unfilled(); + init_offset_unfilled(); + init_twoside_unfilled(); + init_twoside_offset_unfilled(); + init_fallback(); + init_offset_fallback(); + init_twoside_fallback(); + init_twoside_offset_fallback(); + init_unfilled_fallback(); + init_offset_unfilled_fallback(); + init_twoside_unfilled_fallback(); + init_twoside_offset_unfilled_fallback(); +} + + + +/*********************************************************************** + * Rasterization fallback helpers * + ***********************************************************************/ + + +/* This code is hit only when a mix of accelerated and unaccelerated + * primitives are being drawn, and only for the unaccelerated + * primitives. + */ +static void +r128_fallback_tri( r128ContextPtr rmesa, + r128Vertex *v0, + r128Vertex *v1, + r128Vertex *v2 ) +{ + GLcontext *ctx = rmesa->glCtx; + SWvertex v[3]; + r128_translate_vertex( ctx, v0, &v[0] ); + r128_translate_vertex( ctx, v1, &v[1] ); + r128_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} + + +static void +r128_fallback_line( r128ContextPtr rmesa, + r128Vertex *v0, + r128Vertex *v1 ) +{ + GLcontext *ctx = rmesa->glCtx; + SWvertex v[2]; + r128_translate_vertex( ctx, v0, &v[0] ); + r128_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); +} + + +static void +r128_fallback_point( r128ContextPtr rmesa, + r128Vertex *v0 ) +{ + GLcontext *ctx = rmesa->glCtx; + SWvertex v[1]; + r128_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); +} + + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define VERT(x) (r128Vertex *)(r128verts + (x << shift)) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + r128_draw_point( rmesa, VERT(start) ) +#define RENDER_LINE( v0, v1 ) \ + r128_draw_line( rmesa, VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 ) \ + r128_draw_triangle( rmesa, VERT(v0), VERT(v1), VERT(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) \ + r128_draw_quad( rmesa, VERT(v0), VERT(v1), VERT(v2), VERT(v3) ) +#define INIT(x) do { \ + if (0) fprintf(stderr, "%s\n", __FUNCTION__); \ + r128RenderPrimitive( ctx, x ); \ +} while (0) +#undef LOCAL_VARS +#define LOCAL_VARS \ + r128ContextPtr rmesa = R128_CONTEXT(ctx); \ + const GLuint shift = rmesa->vertex_stride_shift; \ + const char *r128verts = (char *)rmesa->verts; \ + const GLuint * const elt = TNL_CONTEXT(ctx)->vb.Elts; \ + (void) elt; +#define RESET_STIPPLE +#define RESET_OCCLUSION +#define PRESERVE_VB_DEFS +#define ELT(x) (x) +#define TAG(x) r128_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) r128_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + +static void r128RenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb; + + /* Render the new vertices as an unclipped polygon. + */ + { + GLuint *tmp = VB->Elts; + VB->Elts = (GLuint *)elts; + tnl->Driver.Render.PrimTabElts[GL_POLYGON]( ctx, 0, n, PRIM_BEGIN|PRIM_END ); + VB->Elts = tmp; + } +} + +static void r128RenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} + +static void r128FastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + r128ContextPtr rmesa = R128_CONTEXT( ctx ); + GLuint vertsize = rmesa->vertex_size; + GLuint *vb = r128AllocDmaLow( rmesa, (n-2) * 3 * 4 * vertsize ); + GLubyte *r128verts = (GLubyte *)rmesa->verts; + const GLuint shift = rmesa->vertex_stride_shift; + const GLuint *start = (const GLuint *)VERT(elts[0]); + int i,j; + + rmesa->num_verts += (n-2) * 3; + + for (i = 2 ; i < n ; i++) { + COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) VERT(elts[i-1]) ); + COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) VERT(elts[i]) ); + COPY_DWORDS( j, vb, vertsize, (r128VertexPtr) start ); + } +} + + + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + +#define _R128_NEW_RENDER_STATE (_DD_NEW_LINE_STIPPLE | \ + _DD_NEW_LINE_SMOOTH | \ + _DD_NEW_POINT_SMOOTH | \ + _DD_NEW_TRI_SMOOTH | \ + _DD_NEW_TRI_UNFILLED | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_OFFSET) \ + + +#define POINT_FALLBACK (DD_POINT_SMOOTH) +#define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH) +#define TRI_FALLBACK (DD_TRI_SMOOTH) +#define ANY_FALLBACK_FLAGS (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK) +#define ANY_RASTER_FLAGS (DD_TRI_LIGHT_TWOSIDE|DD_TRI_OFFSET|DD_TRI_UNFILLED) + + +static void r128ChooseRenderState(GLcontext *ctx) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) { + rmesa->draw_point = r128_draw_point; + rmesa->draw_line = r128_draw_line; + rmesa->draw_tri = r128_draw_triangle; + + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= R128_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= R128_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= R128_UNFILLED_BIT; + } + + /* Hook in fallbacks for specific primitives. + */ + if (flags & (POINT_FALLBACK|LINE_FALLBACK|TRI_FALLBACK)) { + if (flags & POINT_FALLBACK) rmesa->draw_point = r128_fallback_point; + if (flags & LINE_FALLBACK) rmesa->draw_line = r128_fallback_line; + if (flags & TRI_FALLBACK) rmesa->draw_tri = r128_fallback_tri; + index |= R128_FALLBACK_BIT; + } + } + + if (index != rmesa->RenderIndex) { + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.Triangle = rast_tab[index].triangle; + tnl->Driver.Render.Quad = rast_tab[index].quad; + + if (index == 0) { + tnl->Driver.Render.PrimTabVerts = r128_render_tab_verts; + tnl->Driver.Render.PrimTabElts = r128_render_tab_elts; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + tnl->Driver.Render.ClippedPolygon = r128FastRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = r128RenderClippedLine; + tnl->Driver.Render.ClippedPolygon = r128RenderClippedPoly; + } + + rmesa->RenderIndex = index; + } +} + +/**********************************************************************/ +/* Validate state at pipeline start */ +/**********************************************************************/ + +static void r128RunPipeline( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + if (rmesa->new_state || rmesa->NewGLState & _NEW_TEXTURE) + r128DDUpdateHWState( ctx ); + + if (!rmesa->Fallback && rmesa->NewGLState) { + if (rmesa->NewGLState & _R128_NEW_VERTEX_STATE) + r128ChooseVertexState( ctx ); + + if (rmesa->NewGLState & _R128_NEW_RENDER_STATE) + r128ChooseRenderState( ctx ); + + rmesa->NewGLState = 0; + } + + _tnl_run_pipeline( ctx ); +} + +/**********************************************************************/ +/* High level hooks for t_vb_render.c */ +/**********************************************************************/ + +/* 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 r128 uses triangles to render lines and points, it is + * necessary to turn off hardware culling when rendering these + * primitives. + */ + +static void r128RasterPrimitive( GLcontext *ctx, GLuint hwprim ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + + rmesa->setup.dp_gui_master_cntl_c &= ~R128_GMC_BRUSH_NONE; + + if ( ctx->Polygon.StippleFlag && hwprim == GL_TRIANGLES ) { + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_32x32_MONO_FG_LA; + } + else { + rmesa->setup.dp_gui_master_cntl_c |= R128_GMC_BRUSH_SOLID_COLOR; + } + + rmesa->new_state |= R128_NEW_CONTEXT; + rmesa->dirty |= R128_UPLOAD_CONTEXT; + + if (rmesa->hw_primitive != hwprim) { + FLUSH_BATCH( rmesa ); + rmesa->hw_primitive = hwprim; + } +} + +static void r128RenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint hw = hw_prim[prim]; + rmesa->render_primitive = prim; + if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + r128RasterPrimitive( ctx, hw ); +} + + +static void r128RenderStart( GLcontext *ctx ) +{ + /* Check for projective texturing. Make sure all texcoord + * pointers point to something. (fix in mesa?) + */ + r128CheckTexSizes( ctx ); +} + +static void r128RenderFinish( GLcontext *ctx ) +{ + if (R128_CONTEXT(ctx)->RenderIndex & R128_FALLBACK_BIT) + _swrast_flush( ctx ); +} + + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + +void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint oldfallback = rmesa->Fallback; + + if (mode) { + rmesa->Fallback |= bit; + if (oldfallback == 0) { + FLUSH_BATCH( rmesa ); + _swsetup_Wakeup( ctx ); + rmesa->RenderIndex = ~0; + } + } + else { + rmesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = r128RenderStart; + tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive; + tnl->Driver.Render.Finish = r128RenderFinish; + tnl->Driver.Render.BuildVertices = r128BuildVertices; + rmesa->NewGLState |= (_R128_NEW_RENDER_STATE| + _R128_NEW_VERTEX_STATE); + } + } +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void r128InitTriFuncs( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + } + + tnl->Driver.RunPipeline = r128RunPipeline; + tnl->Driver.Render.Start = r128RenderStart; + tnl->Driver.Render.Finish = r128RenderFinish; + tnl->Driver.Render.PrimitiveNotify = r128RenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = r128BuildVertices; + rmesa->NewGLState |= (_R128_NEW_RENDER_STATE| + _R128_NEW_VERTEX_STATE); + +/* r128Fallback( ctx, 0x100000, 1 ); */ +} diff --git a/src/mesa/drivers/dri/r128/r128_tris.h b/src/mesa/drivers/dri/r128/r128_tris.h new file mode 100644 index 0000000000..755d3320b0 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_tris.h @@ -0,0 +1,48 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.8 2002/10/30 12:51:43 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * + */ + +#ifndef __R128_TRIS_H__ +#define __R128_TRIS_H__ + +#include "mtypes.h" + +extern void r128InitTriFuncs( GLcontext *ctx ); + + +extern void r128Fallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +#define FALLBACK( rmesa, bit, mode ) r128Fallback( rmesa->glCtx, bit, mode ) + + +#endif /* __R128_TRIS_H__ */ diff --git a/src/mesa/drivers/dri/r128/r128_vb.c b/src/mesa/drivers/dri/r128/r128_vb.c new file mode 100644 index 0000000000..7738901648 --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_vb.c @@ -0,0 +1,522 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.c,v 1.15 2002/10/30 12:51:43 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * + */ + +#include "glheader.h" +#include "mtypes.h" +#include "imports.h" +#include "macros.h" +#include "colormac.h" + +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" + +#include "r128_context.h" +#include "r128_vb.h" +#include "r128_ioctl.h" +#include "r128_tris.h" +#include "r128_state.h" + + +#define R128_TEX1_BIT 0x1 +#define R128_TEX0_BIT 0x2 +#define R128_RGBA_BIT 0x4 +#define R128_SPEC_BIT 0x8 +#define R128_FOG_BIT 0x10 +#define R128_XYZW_BIT 0x20 +#define R128_PTEX_BIT 0x40 +#define R128_MAX_SETUP 0x80 + +static struct { + void (*emit)( GLcontext *, GLuint, GLuint, void *, GLuint ); + interp_func interp; + copy_pv_func copy_pv; + GLboolean (*check_tex_sizes)( GLcontext *ctx ); + GLuint vertex_size; + GLuint vertex_stride_shift; + GLuint vertex_format; +} setup_tab[R128_MAX_SETUP]; + +#define TINY_VERTEX_FORMAT (R128_CCE_VC_FRMT_DIFFUSE_ARGB) + +#define NOTEX_VERTEX_FORMAT (R128_CCE_VC_FRMT_RHW | \ + R128_CCE_VC_FRMT_DIFFUSE_ARGB |\ + R128_CCE_VC_FRMT_SPEC_FRGB) + +#define 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 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 PROJ_TEX1_VERTEX_FORMAT 0 +#define TEX2_VERTEX_FORMAT 0 +#define TEX3_VERTEX_FORMAT 0 +#define PROJ_TEX3_VERTEX_FORMAT 0 + +#define DO_XYZW (IND & R128_XYZW_BIT) +#define DO_RGBA (IND & R128_RGBA_BIT) +#define DO_SPEC (IND & R128_SPEC_BIT) +#define DO_FOG (IND & R128_FOG_BIT) +#define DO_TEX0 (IND & R128_TEX0_BIT) +#define DO_TEX1 (IND & R128_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & R128_PTEX_BIT) + +#define VERTEX r128Vertex +#define VERTEX_COLOR r128_color_t +#define LOCALVARS r128ContextPtr rmesa = R128_CONTEXT(ctx); +#define GET_VIEWPORT_MAT() rmesa->hw_viewport +#define GET_TEXSOURCE(n) rmesa->tmu_source[n] +#define GET_VERTEX_FORMAT() rmesa->vertex_format +#define GET_VERTEX_STORE() rmesa->verts +#define GET_VERTEX_STRIDE_SHIFT() rmesa->vertex_stride_shift +#define INVALIDATE_STORED_VERTICES() +#define GET_UBYTE_COLOR_STORE() &rmesa->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &rmesa->UbyteSecondaryColor + +#define HAVE_HW_VIEWPORT 0 +#define HAVE_HW_DIVIDE 0 +#define HAVE_RGBA_COLOR 0 +#define HAVE_TINY_VERTICES 1 +#define HAVE_NOTEX_VERTICES 1 +#define HAVE_TEX0_VERTICES 1 +#define HAVE_TEX1_VERTICES 1 +#define HAVE_TEX2_VERTICES 0 +#define HAVE_TEX3_VERTICES 0 +#define HAVE_PTEX_VERTICES 0 /* r128 rhw2 not supported by template */ + +#define UNVIEWPORT_VARS GLfloat h = R128_CONTEXT(ctx)->driDrawable->h +#define UNVIEWPORT_X(x) x - SUBPIXEL_X +#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y +#define UNVIEWPORT_Z(z) z / rmesa->depth_scale + +#define PTEX_FALLBACK() FALLBACK(R128_CONTEXT(ctx), R128_FALLBACK_TEXTURE, 1) + +#define IMPORT_FLOAT_COLORS r128_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS r128_import_float_spec_colors + +#define INTERP_VERTEX setup_tab[rmesa->SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[rmesa->SetupIndex].copy_pv + +/*********************************************************************** + * Generate pv-copying and translation functions * + ***********************************************************************/ + +#define TAG(x) r128_##x +#include "tnl_dd/t_dd_vb.c" + +/*********************************************************************** + * Generate vertex emit and interp functions * + ***********************************************************************/ + + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT) +#define TAG(x) x##_wgs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_TEX0_BIT|R128_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT) +#define TAG(x) x##_wgst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\ + R128_TEX1_BIT) +#define TAG(x) x##_wgst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\ + R128_PTEX_BIT) +#define TAG(x) x##_wgspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT) +#define TAG(x) x##_wgf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT) +#define TAG(x) x##_wgft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|\ + R128_TEX1_BIT) +#define TAG(x) x##_wgft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|\ + R128_PTEX_BIT) +#define TAG(x) x##_wgfpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\ + R128_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\ + R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_XYZW_BIT|R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|\ + R128_TEX0_BIT|R128_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_TEX0_BIT) +#define TAG(x) x##_t0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_t0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_FOG_BIT) +#define TAG(x) x##_f +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_FOG_BIT|R128_TEX0_BIT) +#define TAG(x) x##_ft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_ft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT) +#define TAG(x) x##_g +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_SPEC_BIT) +#define TAG(x) x##_gs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_TEX0_BIT) +#define TAG(x) x##_gt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_gt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT) +#define TAG(x) x##_gst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_SPEC_BIT|R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_gst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_FOG_BIT) +#define TAG(x) x##_gf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT) +#define TAG(x) x##_gfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT) +#define TAG(x) x##_gft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_TEX0_BIT|R128_TEX1_BIT) +#define TAG(x) x##_gft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT) +#define TAG(x) x##_gfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (R128_RGBA_BIT|R128_FOG_BIT|R128_SPEC_BIT|R128_TEX0_BIT|\ + R128_TEX1_BIT) +#define TAG(x) x##_gfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + + +static void init_setup_tab( void ) +{ + init_wg(); + init_wgs(); + init_wgt0(); + init_wgt0t1(); + init_wgpt0(); + init_wgst0(); + init_wgst0t1(); + init_wgspt0(); + init_wgf(); + init_wgfs(); + init_wgft0(); + init_wgft0t1(); + init_wgfpt0(); + init_wgfst0(); + init_wgfst0t1(); + init_wgfspt0(); + init_t0(); + init_t0t1(); + init_f(); + init_ft0(); + init_ft0t1(); + init_g(); + init_gs(); + init_gt0(); + init_gt0t1(); + init_gst0(); + init_gst0t1(); + init_gf(); + init_gfs(); + init_gft0(); + init_gft0t1(); + init_gfst0(); + init_gfst0t1(); +} + + + +void r128PrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & R128_XYZW_BIT) ? " xyzw," : "", + (flags & R128_RGBA_BIT) ? " rgba," : "", + (flags & R128_SPEC_BIT) ? " spec," : "", + (flags & R128_FOG_BIT) ? " fog," : "", + (flags & R128_TEX0_BIT) ? " tex-0," : "", + (flags & R128_TEX1_BIT) ? " tex-1," : ""); +} + + + +void r128CheckTexSizes( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT( ctx ); + + if (!setup_tab[rmesa->SetupIndex].check_tex_sizes(ctx)) { + TNLcontext *tnl = TNL_CONTEXT(ctx); + + /* Invalidate stored verts + */ + rmesa->SetupNewInputs = ~0; + rmesa->SetupIndex |= R128_PTEX_BIT; + + if (!rmesa->Fallback && + !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + tnl->Driver.Render.Interp = setup_tab[rmesa->SetupIndex].interp; + tnl->Driver.Render.CopyPV = setup_tab[rmesa->SetupIndex].copy_pv; + } + } +} + +void r128BuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ) +{ + r128ContextPtr rmesa = R128_CONTEXT( ctx ); + GLubyte *v = ((GLubyte *)rmesa->verts + (start<vertex_stride_shift)); + GLuint stride = 1<vertex_stride_shift; + + newinputs |= rmesa->SetupNewInputs; + rmesa->SetupNewInputs = 0; + + if (!newinputs) + return; + + if (newinputs & VERT_BIT_CLIP) { + setup_tab[rmesa->SetupIndex].emit( ctx, start, count, v, stride ); + } else { + GLuint ind = 0; + + if (newinputs & VERT_BIT_COLOR0) + ind |= R128_RGBA_BIT; + + if (newinputs & VERT_BIT_COLOR1) + ind |= R128_SPEC_BIT; + + if (newinputs & VERT_BIT_TEX0) + ind |= R128_TEX0_BIT; + + if (newinputs & VERT_BIT_TEX1) + ind |= R128_TEX1_BIT; + + if (newinputs & VERT_BIT_FOG) + ind |= R128_FOG_BIT; + + if (rmesa->SetupIndex & R128_PTEX_BIT) + ind = ~0; + + ind &= rmesa->SetupIndex; + + if (ind) { + setup_tab[ind].emit( ctx, start, count, v, stride ); + } + } +} + +void r128ChooseVertexState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + r128ContextPtr rmesa = R128_CONTEXT( ctx ); + GLuint ind = R128_XYZW_BIT|R128_RGBA_BIT; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + ind |= R128_SPEC_BIT; + + if (ctx->Fog.Enabled) + ind |= R128_FOG_BIT; + + if (ctx->Texture._EnabledUnits) { + ind |= R128_TEX0_BIT; + if (ctx->Texture.Unit[0]._ReallyEnabled && + ctx->Texture.Unit[1]._ReallyEnabled) + ind |= R128_TEX1_BIT; + } + + rmesa->SetupIndex = ind; + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = r128_interp_extras; + tnl->Driver.Render.CopyPV = r128_copy_pv_extras; + } else { + tnl->Driver.Render.Interp = setup_tab[ind].interp; + tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv; + } + + if (setup_tab[ind].vertex_format != rmesa->vertex_format) { + FLUSH_BATCH(rmesa); + rmesa->vertex_format = setup_tab[ind].vertex_format; + rmesa->vertex_size = setup_tab[ind].vertex_size; + rmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + } +} + + + +void r128_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint vertex_size = rmesa->vertex_size * 4; + GLuint *dest = r128AllocDmaLow( rmesa, (count-start) * vertex_size); + setup_tab[rmesa->SetupIndex].emit( ctx, start, count, dest, vertex_size ); +} + + +#if 0 +void r128_emit_indexed_verts( GLcontext *ctx, GLuint start, GLuint count ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint vertex_size = rmesa->vertex_size * 4; + GLuint bufsz = (count-start) * vertex_size; + CARD32 *dest; + + rmesa->vertex_low = (rmesa->vertex_low + 63) & ~63; /* alignment */ + rmesa->vertex_last_prim = rmesa->vertex_low; + + dest = r128AllocDmaLow( rmesa, bufsz, __FUNCTION__); + setup_tab[rmesa->SetupIndex].emit( ctx, start, count, dest, vertex_size ); + + rmesa->retained_buffer = rmesa->vertex_buffer; + rmesa->vb_offset = (rmesa->vertex_buffer->idx * R128_BUFFER_SIZE + + rmesa->vertex_low - bufsz); + + rmesa->vertex_low = (rmesa->vertex_low + 0x7) & ~0x7; /* alignment */ + rmesa->vertex_last_prim = rmesa->vertex_low; +} +#endif + + +void r128InitVB( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + + rmesa->verts = ALIGN_MALLOC(size * 4 * 16, 32); + + { + static int firsttime = 1; + if (firsttime) { + init_setup_tab(); + firsttime = 0; + } + } +} + + +void r128FreeVB( GLcontext *ctx ) +{ + r128ContextPtr rmesa = R128_CONTEXT(ctx); + if (rmesa->verts) { + ALIGN_FREE(rmesa->verts); + rmesa->verts = 0; + } + + + if (rmesa->UbyteSecondaryColor.Ptr) { + ALIGN_FREE(rmesa->UbyteSecondaryColor.Ptr); + rmesa->UbyteSecondaryColor.Ptr = 0; + } + + if (rmesa->UbyteColor.Ptr) { + ALIGN_FREE(rmesa->UbyteColor.Ptr); + rmesa->UbyteColor.Ptr = 0; + } +} diff --git a/src/mesa/drivers/dri/r128/r128_vb.h b/src/mesa/drivers/dri/r128/r128_vb.h new file mode 100644 index 0000000000..31afa74f1c --- /dev/null +++ b/src/mesa/drivers/dri/r128/r128_vb.h @@ -0,0 +1,74 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.h,v 1.8 2002/10/30 12:51:46 alanh Exp $ */ +/************************************************************************** + +Copyright 2000, 2001 ATI Technologies Inc., Ontario, Canada, and + VA Linux Systems Inc., Fremont, California. + +All Rights Reserved. + +Permission is hereby granted, free of charge, to any person obtaining a +copy of this software and associated documentation files (the "Software"), +to deal in the Software without restriction, including without limitation +on the rights to use, copy, modify, merge, publish, distribute, sub +license, and/or sell copies of the Software, and to permit persons to whom +the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL +ATI, VA LINUX SYSTEMS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM, +DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +USE OR OTHER DEALINGS IN THE SOFTWARE. + +**************************************************************************/ + +/* + * Authors: + * Keith Whitwell + * + */ + +#ifndef R128VB_INC +#define R128VB_INC + +#include "mtypes.h" +#include "swrast/swrast.h" +#include "r128_context.h" + +#define _R128_NEW_VERTEX_STATE (_DD_NEW_SEPARATE_SPECULAR | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_UNFILLED | \ + _NEW_TEXTURE | \ + _NEW_FOG) + +extern void r128CheckTexSizes( GLcontext *ctx ); +extern void r128ChooseVertexState( GLcontext *ctx ); + +extern void r128BuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ); + +extern void r128PrintSetupFlags(char *msg, GLuint flags ); + +extern void r128InitVB( GLcontext *ctx ); +extern void r128FreeVB( GLcontext *ctx ); + +extern void r128_emit_contiguous_verts( GLcontext *ctx, + GLuint start, + GLuint count ); + +extern void r128_emit_indexed_verts( GLcontext *ctx, + GLuint start, + GLuint count ); + +extern void r128_translate_vertex( GLcontext *ctx, + const r128Vertex *src, + SWvertex *dst ); + +extern void r128_print_vertex( GLcontext *ctx, const r128Vertex *v ); + +#endif diff --git a/src/mesa/drivers/dri/r128/server/r128.h b/src/mesa/drivers/dri/r128/server/r128.h new file mode 100644 index 0000000000..fba01d6d60 --- /dev/null +++ b/src/mesa/drivers/dri/r128/server/r128.h @@ -0,0 +1,566 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128.h,v 1.24 2002/12/16 16:19:10 dawes Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + * Precision Insight, Inc., Cedar Park, Texas, 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, 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, PRECISION INSIGHT, 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: + * Rickard E. Faith + * Kevin E. Martin + * + */ + +#ifndef _R128_H_ +#define _R128_H_ + +#include "dri_util.h" +#ifndef _SOLO +#include "xf86str.h" + + /* PCI support */ +#include "xf86Pci.h" + + /* XAA and Cursor Support */ +#include "xaa.h" +#include "xf86Cursor.h" + + /* DDC support */ +#include "xf86DDC.h" + + /* Xv support */ +#include "xf86xv.h" + + /* DRI support */ +#ifdef XF86DRI +#define _XF86DRI_SERVER_ +#include "r128_dripriv.h" +#include "dri.h" +#include "GL/glxint.h" +#endif +#endif +#ifdef _SOLO +#define XF86DRI +#endif + +#define R128_DEBUG 0 /* Turn off debugging output */ +#define R128_IDLE_RETRY 32 /* Fall out of idle loops after this count */ +#define R128_TIMEOUT 2000000 /* Fall out of wait loops after this count */ +#define R128_MMIOSIZE 0x4000 + +#define R128_VBIOS_SIZE 0x00010000 + +#if R128_DEBUG +#define R128TRACE(x) \ + do { \ + ErrorF("(**) %s(%d): ", R128_NAME, pScrn->scrnIndex); \ + ErrorF x; \ + } while (0); +#else +#define R128TRACE(x) +#endif + + +/* Other macros */ +#define R128_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0])) +#define R128_ALIGN(x,bytes) (((x) + ((bytes) - 1)) & ~((bytes) - 1)) +#define R128PTR(pScrn) ((R128InfoPtr)(pScrn)->driverPrivate) + +/** + * \brief Chip families. + */ +typedef enum { + CHIP_FAMILY_UNKNOWN, + CHIP_FAMILY_R128_PCI, + CHIP_FAMILY_R128_AGP, +} R128ChipFamily; + +typedef struct { /* All values in XCLKS */ + int ML; /* Memory Read Latency */ + int MB; /* Memory Burst Length */ + int Trcd; /* RAS to CAS delay */ + int Trp; /* RAS percentage */ + int Twr; /* Write Recovery */ + int CL; /* CAS Latency */ + int Tr2w; /* Read to Write Delay */ + int Rloop; /* Loop Latency */ + int Rloop_fudge; /* Add to ML to get Rloop */ + char *name; +} R128RAMRec, *R128RAMPtr; + +typedef struct { + /* Common registers */ + CARD32 ovr_clr; + CARD32 ovr_wid_left_right; + CARD32 ovr_wid_top_bottom; + CARD32 ov0_scale_cntl; + CARD32 mpp_tb_config; + CARD32 mpp_gp_config; + CARD32 subpic_cntl; + CARD32 viph_control; + CARD32 i2c_cntl_1; + CARD32 gen_int_cntl; + CARD32 cap0_trig_cntl; + CARD32 cap1_trig_cntl; + CARD32 bus_cntl; + CARD32 config_cntl; + + /* Other registers to save for VT switches */ + CARD32 dp_datatype; + CARD32 gen_reset_cntl; + CARD32 clock_cntl_index; + CARD32 amcgpio_en_reg; + CARD32 amcgpio_mask; + + /* CRTC registers */ + CARD32 crtc_gen_cntl; + CARD32 crtc_ext_cntl; + CARD32 dac_cntl; + CARD32 crtc_h_total_disp; + CARD32 crtc_h_sync_strt_wid; + CARD32 crtc_v_total_disp; + CARD32 crtc_v_sync_strt_wid; + CARD32 crtc_offset; + CARD32 crtc_offset_cntl; + CARD32 crtc_pitch; + + /* CRTC2 registers */ + CARD32 crtc2_gen_cntl; + + /* Flat panel registers */ + CARD32 fp_crtc_h_total_disp; + CARD32 fp_crtc_v_total_disp; + CARD32 fp_gen_cntl; + CARD32 fp_h_sync_strt_wid; + CARD32 fp_horz_stretch; + CARD32 fp_panel_cntl; + CARD32 fp_v_sync_strt_wid; + CARD32 fp_vert_stretch; + CARD32 lvds_gen_cntl; + CARD32 tmds_crc; + CARD32 tmds_transmitter_cntl; + + /* Computed values for PLL */ + CARD32 dot_clock_freq; + CARD32 pll_output_freq; + int feedback_div; + int post_div; + + /* PLL registers */ + CARD32 ppll_ref_div; + CARD32 ppll_div_3; + CARD32 htotal_cntl; + + /* DDA register */ + CARD32 dda_config; + CARD32 dda_on_off; + + /* Pallet */ + GLboolean palette_valid; + CARD32 palette[256]; +} R128SaveRec, *R128SavePtr; + +#ifndef _SOLO +typedef struct { + CARD16 reference_freq; + CARD16 reference_div; + CARD32 min_pll_freq; + CARD32 max_pll_freq; + CARD16 xclk; +} R128PLLRec, *R128PLLPtr; + +typedef struct { + int bitsPerPixel; + int depth; + int displayWidth; + int pixel_code; + int pixel_bytes; + DisplayModePtr mode; +} R128FBLayout; +#endif + +typedef struct { +#ifndef _SOLO + EntityInfoPtr pEnt; + pciVideoPtr PciInfo; + PCITAG PciTag; +#endif + int Chipset; + GLboolean Primary; + + GLboolean FBDev; + + unsigned long LinearAddr; /* Frame buffer physical address */ + unsigned long BIOSAddr; /* BIOS physical address */ + + unsigned char *MMIO; /* Map of MMIO region */ + unsigned char *FB; /* Map of frame buffer */ + + CARD32 MemCntl; + CARD32 BusCntl; + unsigned long FbMapSize; /* Size of frame buffer, in bytes */ + int Flags; /* Saved copy of mode flags */ + +#ifndef _SOLO + CARD8 BIOSDisplay; /* Device the BIOS is set to display to */ + + GLboolean HasPanelRegs; /* Current chip can connect to a FP */ + CARD8 *VBIOS; /* Video BIOS for mode validation on FPs */ + int FPBIOSstart; /* Start of the flat panel info */ +#endif + /* Computed values for FPs */ + int PanelXRes; + int PanelYRes; + int HOverPlus; + int HSyncWidth; + int HBlank; + int VOverPlus; + int VSyncWidth; + int VBlank; + int PanelPwrDly; +#ifndef _SOLO + R128PLLRec pll; + R128RAMPtr ram; + + R128SaveRec SavedReg; /* Original (text) mode */ + R128SaveRec ModeReg; /* Current mode */ + GLboolean (*CloseScreen)(int, ScreenPtr); + void (*BlockHandler)(int, pointer, pointer, pointer); + + GLboolean PaletteSavedOnVT; /* Palette saved on last VT switch */ + + XAAInfoRecPtr accel; + GLboolean accelOn; + xf86CursorInfoPtr cursor; +#endif + unsigned long cursor_start; + unsigned long cursor_end; + + /* + * XAAForceTransBlit is used to change the behavior of the XAA + * SetupForScreenToScreenCopy function, to make it DGA-friendly. + */ + GLboolean XAAForceTransBlit; + + int fifo_slots; /* Free slots in the FIFO (64 max) */ + int pix24bpp; /* Depth of pixmap for 24bpp framebuffer */ + GLboolean dac6bits; /* Use 6 bit DAC? */ + + /* Computed values for Rage 128 */ + int pitch; + int datatype; + CARD32 dp_gui_master_cntl; + + /* Saved values for ScreenToScreenCopy */ + int xdir; + int ydir; + + /* ScanlineScreenToScreenColorExpand support */ + unsigned char *scratch_buffer[1]; + unsigned char *scratch_save; + int scanline_x; + int scanline_y; + int scanline_w; + int scanline_h; +#ifdef XF86DRI + int scanline_hpass; + int scanline_x1clip; + int scanline_x2clip; + int scanline_rop; + int scanline_fg; + int scanline_bg; +#endif /* XF86DRI */ + int scanline_words; + int scanline_direct; + int scanline_bpp; /* Only used for ImageWrite */ + +#ifndef _SOLO + DGAModePtr DGAModes; + int numDGAModes; + GLboolean DGAactive; + int DGAViewportStatus; + DGAFunctionRec DGAFuncs; + + R128FBLayout CurrentLayout; +#endif +#ifdef XF86DRI + drmContext drmCtx; +#ifndef _SOLO + DRIInfoPtr pDRIInfo; + int numVisualConfigs; + __GLXvisualConfig *pVisualConfigs; + R128ConfigPrivPtr pVisualConfigsPriv; +#endif + + drmSize registerSize; + drmHandle registerHandle; + + GLboolean IsPCI; /* Current card is a PCI card */ + drmSize pciSize; + drmHandle pciMemHandle; + unsigned char *PCI; /* Map */ + + GLboolean allowPageFlip; /* Enable 3d page flipping */ + GLboolean have3DWindows; /* Are there any 3d clients? */ + int drmMinor; + + drmSize agpSize; + drmHandle agpMemHandle; /* Handle from drmAgpAlloc */ + unsigned long agpOffset; + unsigned char *AGP; /* Map */ + int agpMode; + + GLboolean CCEInUse; /* CCE is currently active */ + int CCEMode; /* CCE mode that server/clients use */ + int CCEFifoSize; /* Size of the CCE command FIFO */ + GLboolean CCESecure; /* CCE security enabled */ + int CCEusecTimeout; /* CCE timeout in usecs */ + + /* CCE ring buffer data */ + unsigned long ringStart; /* Offset into AGP space */ + drmHandle ringHandle; /* Handle from drmAddMap */ + drmSize ringMapSize; /* Size of map */ + int ringSize; /* Size of ring (in MB) */ + unsigned char *ring; /* Map */ + int ringSizeLog2QW; + + unsigned long ringReadOffset; /* Offset into AGP space */ + drmHandle ringReadPtrHandle; /* Handle from drmAddMap */ + drmSize ringReadMapSize; /* Size of map */ + unsigned char *ringReadPtr; /* Map */ + + /* CCE 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 */ + + /* CCE AGP Texture data */ + unsigned long agpTexStart; /* Offset into AGP space */ + drmHandle agpTexHandle; /* Handle from drmAddMap */ + drmSize agpTexMapSize; /* Size of map */ + int agpTexSize; /* Size of AGP tex space (in MB) */ + unsigned char *agpTex; /* Map */ + int log2AGPTexGran; + + /* CCE 2D accleration */ + drmBufPtr indirectBuffer; + int indirectStart; + + /* DRI screen private data */ + int fbX; + int fbY; + int backX; + int backY; + int depthX; + int depthY; + + int frontOffset; + int frontPitch; + int backOffset; + int backPitch; + int depthOffset; + int depthPitch; + int spanOffset; + int textureOffset; + int textureSize; + int log2TexGran; + + /* 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; + + int irq; + CARD32 gen_int_cntl; + + GLboolean DMAForXv; +#endif + +#ifndef _SOLO + XF86VideoAdaptorPtr adaptor; + void (*VideoTimerCallback)(ScrnInfoPtr, Time); + int videoKey; + GLboolean showCache; + OptionInfoPtr Options; + + GLboolean isDFP; + GLboolean isPro2; + I2CBusPtr pI2CBus; + CARD32 DDCReg; +#endif +} R128InfoRec, *R128InfoPtr; + +#define R128WaitForFifo(pScrn, entries) \ +do { \ + if (info->fifo_slots < entries) R128WaitForFifoFunction(pScrn, entries); \ + info->fifo_slots -= entries; \ +} while (0) + +extern void r128WaitForFifoFunction(const DRIDriverContext *ctx, int entries); +extern void r128WaitForIdle(const DRIDriverContext *ctx); + +extern void r128WaitForVerticalSync(const DRIDriverContext *ctx); + +extern GLboolean r128AccelInit(const DRIDriverContext *ctx); +extern void r128EngineInit(const DRIDriverContext *ctx); +extern GLboolean r128CursorInit(const DRIDriverContext *ctx); +extern GLboolean r128DGAInit(const DRIDriverContext *ctx); + +extern void r128InitVideo(const DRIDriverContext *ctx); + +extern GLboolean r128DRIScreenInit(const DRIDriverContext *ctx); +extern void r128DRICloseScreen(const DRIDriverContext *ctx); +extern GLboolean r128DRIFinishScreenInit(const DRIDriverContext *ctx); + +#define R128CCE_START(ctx, info) \ +do { \ + int _ret = drmCommandNone(ctx->drmFD, DRM_R128_CCE_START); \ + if (_ret) { \ + fprintf(stderr, \ + "%s: CCE start %d\n", __FUNCTION__, _ret); \ + } \ +} while (0) + +#define R128CCE_STOP(ctx, info) \ +do { \ + int _ret = R128CCEStop(ctx); \ + if (_ret) { \ + fprintf(stderr, \ + "%s: CCE stop %d\n", __FUNCTION__, _ret); \ + } \ +} while (0) + +#define R128CCE_RESET(ctx, info) \ +do { \ + if (info->directRenderingEnabled \ + && R128CCE_USE_RING_BUFFER(info->CCEMode)) { \ + int _ret = drmCommandNone(info->drmFD, DRM_R128_CCE_RESET); \ + if (_ret) { \ + fprintf(stderr, \ + "%s: CCE reset %d\n", __FUNCTION__, _ret); \ + } \ + } \ +} while (0) + + +#define CCE_PACKET0( reg, n ) \ + (R128_CCE_PACKET0 | ((n) << 16) | ((reg) >> 2)) +#define CCE_PACKET1( reg0, reg1 ) \ + (R128_CCE_PACKET1 | (((reg1) >> 2) << 11) | ((reg0) >> 2)) +#define CCE_PACKET2() \ + (R128_CCE_PACKET2) +#define CCE_PACKET3( pkt, n ) \ + (R128_CCE_PACKET3 | (pkt) | ((n) << 16)) + + +#define R128_VERBOSE 0 + +#define RING_LOCALS CARD32 *__head; int __count; + +#define R128CCE_REFRESH(pScrn, info) \ +do { \ + if ( R128_VERBOSE ) { \ + fprintf(stderr, "REFRESH( %d ) in %s\n", \ + !info->CCEInUse , __FUNCTION__ ); \ + } \ + if ( !info->CCEInUse ) { \ + R128CCEWaitForIdle(pScrn); \ + BEGIN_RING( 6 ); \ + OUT_RING_REG( R128_RE_TOP_LEFT, info->re_top_left ); \ + OUT_RING_REG( R128_RE_WIDTH_HEIGHT, info->re_width_height ); \ + OUT_RING_REG( R128_AUX_SC_CNTL, info->aux_sc_cntl ); \ + ADVANCE_RING(); \ + info->CCEInUse = TRUE; \ + } \ +} while (0) + +#define BEGIN_RING( n ) do { \ + if ( R128_VERBOSE ) { \ + fprintf(stderr, \ + "BEGIN_RING( %d ) in %s\n", n, __FUNCTION__ ); \ + } \ + if ( !info->indirectBuffer ) { \ + info->indirectBuffer = R128CCEGetBuffer( pScrn ); \ + info->indirectStart = 0; \ + } else if ( (info->indirectBuffer->used + 4*(n)) > \ + info->indirectBuffer->total ) { \ + R128CCEFlushIndirect( pScrn, 1 ); \ + } \ + __head = (pointer)((char *)info->indirectBuffer->address + \ + info->indirectBuffer->used); \ + __count = 0; \ +} while (0) + +#define ADVANCE_RING() do { \ + if ( R128_VERBOSE ) { \ + fprintf(stderr, \ + "ADVANCE_RING() used: %d+%d=%d/%d\n", \ + info->indirectBuffer->used - info->indirectStart, \ + __count * sizeof(CARD32), \ + info->indirectBuffer->used - info->indirectStart + \ + __count * sizeof(CARD32), \ + info->indirectBuffer->total - info->indirectStart ); \ + } \ + info->indirectBuffer->used += __count * (int)sizeof(CARD32); \ +} while (0) + +#define OUT_RING( x ) do { \ + if ( R128_VERBOSE ) { \ + fprintf(stderr, \ + " OUT_RING( 0x%08x )\n", (unsigned int)(x) ); \ + } \ + MMIO_OUT32(&__head[__count++], 0, (x)); \ +} while (0) + +#define OUT_RING_REG( reg, val ) \ +do { \ + OUT_RING( CCE_PACKET0( reg, 0 ) ); \ + OUT_RING( val ); \ +} while (0) + +#define FLUSH_RING() \ +do { \ + if ( R128_VERBOSE ) \ + fprintf(stderr, \ + "FLUSH_RING in %s\n", __FUNCTION__ ); \ + if ( info->indirectBuffer ) { \ + R128CCEFlushIndirect( pScrn, 0 ); \ + } \ +} while (0) + + +#endif diff --git a/src/mesa/drivers/dri/r128/server/r128_common.h b/src/mesa/drivers/dri/r128/server/r128_common.h new file mode 100644 index 0000000000..fa81360ea5 --- /dev/null +++ b/src/mesa/drivers/dri/r128/server/r128_common.h @@ -0,0 +1,169 @@ +/* r128_common.h -- common header definitions for R128 2D/3D/DRM suite + * Created: Sun Apr 9 18:16:28 2000 by kevin@precisioninsight.com + * + * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas. + * Copyright 2002 Tungsten Graphics, 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 + * 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 + * Kevin E. Martin + * + * Converted to common header format: + * Jens Owen + * + * $XFree86: xc/programs/Xserver/hw/xfree86/os-support/xf86drmR128.h,v 3.11 2001/04/16 15:02:13 tsi Exp $ + * + */ + +#ifndef _R128_COMMON_H_ +#define _R128_COMMON_H_ + +/* + * WARNING: If you change any of these defines, make sure to change + * the kernel include file as well (r128_drm.h) + */ + +/* Driver specific DRM command indices + * NOTE: these are not OS specific, but they are driver specific + */ +#define DRM_R128_INIT 0x00 +#define DRM_R128_CCE_START 0x01 +#define DRM_R128_CCE_STOP 0x02 +#define DRM_R128_CCE_RESET 0x03 +#define DRM_R128_CCE_IDLE 0x04 +#define DRM_R128_UNDEFINED1 0x05 +#define DRM_R128_RESET 0x06 +#define DRM_R128_SWAP 0x07 +#define DRM_R128_CLEAR 0x08 +#define DRM_R128_VERTEX 0x09 +#define DRM_R128_INDICES 0x0a +#define DRM_R128_BLIT 0x0b +#define DRM_R128_DEPTH 0x0c +#define DRM_R128_STIPPLE 0x0d +#define DRM_R128_UNDEFINED2 0x0e +#define DRM_R128_INDIRECT 0x0f +#define DRM_R128_FULLSCREEN 0x10 +#define DRM_R128_CLEAR2 0x11 +#define DRM_R128_GETPARAM 0x12 +#define DRM_R128_FLIP 0x13 + +#define DRM_R128_FRONT_BUFFER 0x1 +#define DRM_R128_BACK_BUFFER 0x2 +#define DRM_R128_DEPTH_BUFFER 0x4 + +typedef struct { + enum { + DRM_R128_INIT_CCE = 0x01, + DRM_R128_CLEANUP_CCE = 0x02 + } func; + unsigned long sarea_priv_offset; + int is_pci; + int cce_mode; + int cce_secure; /* FIXME: Deprecated, we should remove this */ + 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 span_offset; + + unsigned long fb_offset; + unsigned long mmio_offset; + unsigned long ring_offset; + unsigned long ring_rptr_offset; + unsigned long buffers_offset; + unsigned long agp_textures_offset; +} drmR128Init; + +typedef struct { + int flush; + int idle; +} drmR128CCEStop; + +typedef struct { + int idx; + int start; + int end; + int discard; +} drmR128Indirect; + +typedef struct { + int idx; + int pitch; + int offset; + int format; + unsigned short x, y; + unsigned short width, height; +} drmR128Blit; + +typedef struct { + enum { + DRM_R128_WRITE_SPAN = 0x01, + DRM_R128_WRITE_PIXELS = 0x02, + DRM_R128_READ_SPAN = 0x03, + DRM_R128_READ_PIXELS = 0x04 + } func; + int n; + int *x; + int *y; + unsigned int *buffer; + unsigned char *mask; +} drmR128Depth; + +typedef struct { + int prim; + int idx; /* Index of vertex buffer */ + int count; /* Number of vertices in buffer */ + int discard; /* Client finished with buffer? */ +} drmR128Vertex; + +typedef struct { + unsigned int *mask; +} drmR128Stipple; + +typedef struct { + unsigned int flags; + unsigned int clear_color; + unsigned int clear_depth; + unsigned int color_mask; + unsigned int depth_mask; +} drmR128Clear; + +typedef struct { + enum { + DRM_R128_INIT_FULLSCREEN = 0x01, + DRM_R128_CLEANUP_FULLSCREEN = 0x02 + } func; +} drmR128Fullscreen; + +typedef struct drm_r128_getparam { + int param; + void *value; +} drmR128GetParam; + +#define R128_PARAM_IRQ_NR 1 + +#endif diff --git a/src/mesa/drivers/dri/r128/server/r128_dri.c b/src/mesa/drivers/dri/r128/server/r128_dri.c new file mode 100644 index 0000000000..aa8f49f9c7 --- /dev/null +++ b/src/mesa/drivers/dri/r128/server/r128_dri.c @@ -0,0 +1,1165 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.c,v 1.28 2003/02/07 20:41:14 martin Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + * Precision Insight, Inc., Cedar Park, Texas, 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, 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, PRECISION INSIGHT, 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 + * Rickard E. Faith + * Daryll Strauss + * Gareth Hughes + * + */ + +#include "sarea.h" +#include +#include +#include +#include +#include +#include + +#include "driver.h" +#include "drm.h" + +#include "sarea.h" +#include "r128.h" +#include "r128_dri.h" +#include "r128_macros.h" +#include "r128_reg.h" +#include "r128_sarea.h" +#include "r128_version.h" + + +/* ?? HACK - for now, put this here... */ +/* ?? Alpha - this may need to be a variable to handle UP1x00 vs TITAN */ +#if defined(__alpha__) +# define DRM_PAGE_SIZE 8192 +#elif defined(__ia64__) +# define DRM_PAGE_SIZE getpagesize() +#else +# define DRM_PAGE_SIZE 4096 +#endif + +/** + * \brief Establish the set of modes available for the display. + * + * \param ctx display handle. + * \param numModes will receive the number of supported modes. + * \param modes will point to the list of supported modes. + * + * \return one on success, or zero on failure. + * + * Allocates a single visual and fills it with information according to the + * display bit depth. Supports only 16 and 32 bpp bit depths, aborting + * otherwise. + */ +const __GLcontextModes __glModes[] = { + + /* 32 bit, RGBA Depth=24 Stencil=8 */ + {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, + .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE, + .redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8, + .redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000, + .rgbBits = 32, .indexBits = 0, + .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, + .depthBits = 24, .stencilBits = 8, + .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, + + /* 16 bit, RGB Depth=16 */ + {.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE, + .haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE, + .redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0, + .redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0, + .rgbBits = 16, .indexBits = 0, + .accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0, + .depthBits = 16, .stencilBits = 0, + .numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, }, +}; +static int R128InitContextModes( const DRIDriverContext *ctx, + int *numModes, const __GLcontextModes **modes) +{ + *numModes = sizeof(__glModes)/sizeof(__GLcontextModes *); + *modes = &__glModes[0]; + return 1; +} + +/* Compute log base 2 of val. */ +static int R128MinBits(int val) +{ + int bits; + + if (!val) return 1; + for (bits = 0; val; val >>= 1, ++bits); + return bits; +} + +/* Initialize the AGP state. Request memory for use in AGP space, and + initialize the Rage 128 registers to point to that memory. */ +static GLboolean R128DRIAgpInit(const DRIDriverContext *ctx) +{ + unsigned char *R128MMIO = ctx->MMIOAddress; + R128InfoPtr info = ctx->driverPrivate; + unsigned long mode; + unsigned int vendor, device; + int ret; + unsigned long cntl, chunk; + int s, l; + int flags; + unsigned long agpBase; + + if (drmAgpAcquire(ctx->drmFD) < 0) { + fprintf(stderr, "[agp] AGP not available\n"); + return GL_FALSE; + } + + /* Modify the mode if the default mode is + not appropriate for this particular + combination of graphics card and AGP + chipset. */ + + mode = drmAgpGetMode(ctx->drmFD); /* Default mode */ + vendor = drmAgpVendorId(ctx->drmFD); + device = drmAgpDeviceId(ctx->drmFD); + + mode &= ~R128_AGP_MODE_MASK; + switch (info->agpMode) { + case 4: mode |= R128_AGP_4X_MODE; + case 2: mode |= R128_AGP_2X_MODE; + case 1: default: mode |= R128_AGP_1X_MODE; + } + + fprintf(stderr, + "[agp] Mode 0x%08lx [AGP 0x%04x/0x%04x; Card 0x%04x/0x%04x]\n", + mode, vendor, device, + 0x1002, + info->Chipset); + + if (drmAgpEnable(ctx->drmFD, mode) < 0) { + fprintf(stderr, "[agp] AGP not enabled\n"); + drmAgpRelease(ctx->drmFD); + return GL_FALSE; + } + + info->agpOffset = 0; + + if ((ret = drmAgpAlloc(ctx->drmFD, info->agpSize*1024*1024, 0, NULL, + &info->agpMemHandle)) < 0) { + fprintf(stderr, "[agp] Out of memory (%d)\n", ret); + drmAgpRelease(ctx->drmFD); + return GL_FALSE; + } + fprintf(stderr, + "[agp] %d kB allocated with handle 0x%08x\n", + info->agpSize*1024, info->agpMemHandle); + + if (drmAgpBind(ctx->drmFD, info->agpMemHandle, info->agpOffset) < 0) { + fprintf(stderr, "[agp] Could not bind\n"); + drmAgpFree(ctx->drmFD, info->agpMemHandle); + drmAgpRelease(ctx->drmFD); + return GL_FALSE; + } + + /* Initialize the CCE ring buffer data */ + info->ringStart = info->agpOffset; + info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE; + info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; + + info->ringReadOffset = info->ringStart + info->ringMapSize; + info->ringReadMapSize = DRM_PAGE_SIZE; + + /* 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 = R128MinBits((s-1) / R128_NR_TEX_REGIONS); + if (l < R128_LOG_TEX_GRANULARITY) l = R128_LOG_TEX_GRANULARITY; + info->agpTexMapSize = (s >> l) << l; + info->log2AGPTexGran = l; + + if (info->CCESecure) flags = DRM_READ_ONLY; + else flags = 0; + + if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, + DRM_AGP, flags, &info->ringHandle) < 0) { + fprintf(stderr, + "[agp] Could not add ring mapping\n"); + return GL_FALSE; + } + fprintf(stderr, + "[agp] ring handle = 0x%08lx\n", info->ringHandle); + + if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize, + (drmAddressPtr)&info->ring) < 0) { + fprintf(stderr, "[agp] Could not map ring\n"); + return GL_FALSE; + } + fprintf(stderr, + "[agp] Ring mapped at 0x%08lx\n", + (unsigned long)info->ring); + + if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, + DRM_AGP, flags, &info->ringReadPtrHandle) < 0) { + fprintf(stderr, + "[agp] Could not add ring read ptr mapping\n"); + return GL_FALSE; + } + fprintf(stderr, + "[agp] ring read ptr handle = 0x%08lx\n", + info->ringReadPtrHandle); + + if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, + (drmAddressPtr)&info->ringReadPtr) < 0) { + fprintf(stderr, + "[agp] Could not map ring read ptr\n"); + return GL_FALSE; + } + fprintf(stderr, + "[agp] Ring read ptr mapped at 0x%08lx\n", + (unsigned long)info->ringReadPtr); + + if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, + DRM_AGP, 0, &info->bufHandle) < 0) { + fprintf(stderr, + "[agp] Could not add vertex/indirect buffers mapping\n"); + return GL_FALSE; + } + fprintf(stderr, + "[agp] vertex/indirect buffers handle = 0x%08lx\n", + info->bufHandle); + + if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize, + (drmAddressPtr)&info->buf) < 0) { + fprintf(stderr, + "[agp] Could not map vertex/indirect buffers\n"); + return GL_FALSE; + } + fprintf(stderr, + "[agp] Vertex/indirect buffers mapped at 0x%08lx\n", + (unsigned long)info->buf); + + if (drmAddMap(ctx->drmFD, info->agpTexStart, info->agpTexMapSize, + DRM_AGP, 0, &info->agpTexHandle) < 0) { + fprintf(stderr, + "[agp] Could not add AGP texture map mapping\n"); + return GL_FALSE; + } + fprintf(stderr, + "[agp] AGP texture map handle = 0x%08lx\n", + info->agpTexHandle); + + if (drmMap(ctx->drmFD, info->agpTexHandle, info->agpTexMapSize, + (drmAddressPtr)&info->agpTex) < 0) { + fprintf(stderr, + "[agp] Could not map AGP texture map\n"); + return GL_FALSE; + } + fprintf(stderr, + "[agp] AGP Texture map mapped at 0x%08lx\n", + (unsigned long)info->agpTex); + + /* Initialize Rage 128's AGP registers */ + cntl = INREG(R128_AGP_CNTL); + cntl &= ~R128_AGP_APER_SIZE_MASK; + switch (info->agpSize) { + case 256: cntl |= R128_AGP_APER_SIZE_256MB; break; + case 128: cntl |= R128_AGP_APER_SIZE_128MB; break; + case 64: cntl |= R128_AGP_APER_SIZE_64MB; break; + case 32: cntl |= R128_AGP_APER_SIZE_32MB; break; + case 16: cntl |= R128_AGP_APER_SIZE_16MB; break; + case 8: cntl |= R128_AGP_APER_SIZE_8MB; break; + case 4: cntl |= R128_AGP_APER_SIZE_4MB; break; + default: + fprintf(stderr, + "[agp] Illegal aperture size %d kB\n", + info->agpSize*1024); + return GL_FALSE; + } + agpBase = drmAgpBase(ctx->drmFD); + OUTREG(R128_AGP_BASE, agpBase); + OUTREG(R128_AGP_CNTL, cntl); + + /* Disable Rage 128's PCIGART registers */ + chunk = INREG(R128_BM_CHUNK_0_VAL); + chunk &= ~(R128_BM_PTR_FORCE_TO_PCI | + R128_BM_PM4_RD_FORCE_TO_PCI | + R128_BM_GLOBAL_FORCE_TO_PCI); + OUTREG(R128_BM_CHUNK_0_VAL, chunk); + + OUTREG(R128_PCI_GART_PAGE, 1); /* Ensure AGP GART is used (for now) */ + + return GL_TRUE; +} + +static GLboolean R128DRIPciInit(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + unsigned char *R128MMIO = ctx->MMIOAddress; + CARD32 chunk; + int ret; + int flags; + + info->agpOffset = 0; + + ret = drmScatterGatherAlloc(ctx->drmFD, info->agpSize*1024*1024, + &info->pciMemHandle); + if (ret < 0) { + fprintf(stderr, "[pci] Out of memory (%d)\n", ret); + return GL_FALSE; + } + fprintf(stderr, + "[pci] %d kB allocated with handle 0x%08x\n", + info->agpSize*1024, info->pciMemHandle); + + /* Initialize the CCE ring buffer data */ + info->ringStart = info->agpOffset; + info->ringMapSize = info->ringSize*1024*1024 + DRM_PAGE_SIZE; + info->ringSizeLog2QW = R128MinBits(info->ringSize*1024*1024/8) - 1; + + info->ringReadOffset = info->ringStart + info->ringMapSize; + info->ringReadMapSize = DRM_PAGE_SIZE; + + /* Reserve space for vertex/indirect buffers */ + info->bufStart = info->ringReadOffset + info->ringReadMapSize; + info->bufMapSize = info->bufSize*1024*1024; + + flags = DRM_READ_ONLY | DRM_LOCKED | DRM_KERNEL; + + if (drmAddMap(ctx->drmFD, info->ringStart, info->ringMapSize, + DRM_SCATTER_GATHER, flags, &info->ringHandle) < 0) { + fprintf(stderr, + "[pci] Could not add ring mapping\n"); + return GL_FALSE; + } + fprintf(stderr, + "[pci] ring handle = 0x%08lx\n", info->ringHandle); + + if (drmMap(ctx->drmFD, info->ringHandle, info->ringMapSize, + (drmAddressPtr)&info->ring) < 0) { + fprintf(stderr, "[pci] Could not map ring\n"); + return GL_FALSE; + } + fprintf(stderr, + "[pci] Ring mapped at 0x%08lx\n", + (unsigned long)info->ring); + fprintf(stderr, + "[pci] Ring contents 0x%08lx\n", + *(unsigned long *)info->ring); + + if (drmAddMap(ctx->drmFD, info->ringReadOffset, info->ringReadMapSize, + DRM_SCATTER_GATHER, flags, &info->ringReadPtrHandle) < 0) { + fprintf(stderr, + "[pci] Could not add ring read ptr mapping\n"); + return GL_FALSE; + } + fprintf(stderr, + "[pci] ring read ptr handle = 0x%08lx\n", + info->ringReadPtrHandle); + + if (drmMap(ctx->drmFD, info->ringReadPtrHandle, info->ringReadMapSize, + (drmAddressPtr)&info->ringReadPtr) < 0) { + fprintf(stderr, + "[pci] Could not map ring read ptr\n"); + return GL_FALSE; + } + fprintf(stderr, + "[pci] Ring read ptr mapped at 0x%08lx\n", + (unsigned long)info->ringReadPtr); + fprintf(stderr, + "[pci] Ring read ptr contents 0x%08lx\n", + *(unsigned long *)info->ringReadPtr); + + if (drmAddMap(ctx->drmFD, info->bufStart, info->bufMapSize, + DRM_SCATTER_GATHER, 0, &info->bufHandle) < 0) { + fprintf(stderr, + "[pci] Could not add vertex/indirect buffers mapping\n"); + return GL_FALSE; + } + fprintf(stderr, + "[pci] vertex/indirect buffers handle = 0x%08lx\n", + info->bufHandle); + + if (drmMap(ctx->drmFD, info->bufHandle, info->bufMapSize, + (drmAddressPtr)&info->buf) < 0) { + fprintf(stderr, + "[pci] Could not map vertex/indirect buffers\n"); + return GL_FALSE; + } + fprintf(stderr, + "[pci] Vertex/indirect buffers mapped at 0x%08lx\n", + (unsigned long)info->buf); + fprintf(stderr, + "[pci] Vertex/indirect buffers contents 0x%08lx\n", + *(unsigned long *)info->buf); + + if (!info->IsPCI) { + /* This is really an AGP card, force PCI GART mode */ + chunk = INREG(R128_BM_CHUNK_0_VAL); + chunk |= (R128_BM_PTR_FORCE_TO_PCI | + R128_BM_PM4_RD_FORCE_TO_PCI | + R128_BM_GLOBAL_FORCE_TO_PCI); + OUTREG(R128_BM_CHUNK_0_VAL, chunk); + OUTREG(R128_PCI_GART_PAGE, 0); /* Ensure PCI GART is used */ + } + + return GL_TRUE; +} + +/* Add a map for the MMIO registers that will be accessed by any + DRI-based clients. */ +static GLboolean R128DRIMapInit(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + int flags; + + if (info->CCESecure) flags = DRM_READ_ONLY; + else flags = 0; + + /* Map registers */ + if (drmAddMap(ctx->drmFD, ctx->MMIOStart, ctx->MMIOSize, + DRM_REGISTERS, flags, &info->registerHandle) < 0) { + return GL_FALSE; + } + fprintf(stderr, + "[drm] register handle = 0x%08lx\n", info->registerHandle); + + return GL_TRUE; +} + +/* Initialize the kernel data structures. */ +static int R128DRIKernelInit(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + drmR128Init drmInfo; + + memset( &drmInfo, 0, sizeof(drmR128Init) ); + + drmInfo.func = DRM_R128_INIT_CCE; + drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec); + drmInfo.is_pci = info->IsPCI; + drmInfo.cce_mode = info->CCEMode; + drmInfo.cce_secure = info->CCESecure; + drmInfo.ring_size = info->ringSize*1024*1024; + drmInfo.usec_timeout = info->CCEusecTimeout; + + drmInfo.fb_bpp = ctx->bpp; + drmInfo.depth_bpp = ctx->bpp; + + drmInfo.front_offset = info->frontOffset; + drmInfo.front_pitch = info->frontPitch; + + drmInfo.back_offset = info->backOffset; + drmInfo.back_pitch = info->backPitch; + + drmInfo.depth_offset = info->depthOffset; + drmInfo.depth_pitch = info->depthPitch; + drmInfo.span_offset = info->spanOffset; + + 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 (drmCommandWrite(ctx->drmFD, DRM_R128_INIT, + &drmInfo, sizeof(drmR128Init)) < 0) + return GL_FALSE; + + return GL_TRUE; +} + +/* Add a map for the vertex buffers that will be accessed by any + DRI-based clients. */ +static GLboolean R128DRIBufInit(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + /* Initialize vertex buffers */ + if (info->IsPCI) { + info->bufNumBufs = drmAddBufs(ctx->drmFD, + info->bufMapSize / R128_BUFFER_SIZE, + R128_BUFFER_SIZE, + DRM_SG_BUFFER, + info->bufStart); + } else { + info->bufNumBufs = drmAddBufs(ctx->drmFD, + info->bufMapSize / R128_BUFFER_SIZE, + R128_BUFFER_SIZE, + DRM_AGP_BUFFER, + info->bufStart); + } + if (info->bufNumBufs <= 0) { + fprintf(stderr, + "[drm] Could not create vertex/indirect buffers list\n"); + return GL_FALSE; + } + fprintf(stderr, + "[drm] Added %d %d byte vertex/indirect buffers\n", + info->bufNumBufs, R128_BUFFER_SIZE); + + if (!(info->buffers = drmMapBufs(ctx->drmFD))) { + fprintf(stderr, + "[drm] Failed to map vertex/indirect buffers list\n"); + return GL_FALSE; + } + fprintf(stderr, + "[drm] Mapped %d vertex/indirect buffers\n", + info->buffers->count); + + return GL_TRUE; +} + +static void R128DRIIrqInit(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + unsigned char *R128MMIO = ctx->MMIOAddress; + + if (!info->irq) { + info->irq = drmGetInterruptFromBusID( + ctx->drmFD, + ctx->pciBus, + ctx->pciDevice, + ctx->pciFunc); + + if((drmCtlInstHandler(ctx->drmFD, info->irq)) != 0) { + fprintf(stderr, + "[drm] failure adding irq handler, " + "there is a device already using that irq\n" + "[drm] falling back to irq-free operation\n"); + info->irq = 0; + } else { + info->gen_int_cntl = INREG( R128_GEN_INT_CNTL ); + } + } + + if (info->irq) + fprintf(stderr, + "[drm] dma control initialized, using IRQ %d\n", + info->irq); +} + +static int R128CCEStop(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + drmR128CCEStop stop; + int ret, i; + + stop.flush = 1; + stop.idle = 1; + + ret = drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, + &stop, sizeof(drmR128CCEStop) ); + + if ( ret == 0 ) { + return 0; + } else if ( errno != EBUSY ) { + return -errno; + } + + stop.flush = 0; + + i = 0; + do { + ret = drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, + &stop, sizeof(drmR128CCEStop) ); + } while ( ret && errno == EBUSY && i++ < R128_IDLE_RETRY ); + + if ( ret == 0 ) { + return 0; + } else if ( errno != EBUSY ) { + return -errno; + } + + stop.idle = 0; + + if ( drmCommandWrite( ctx->drmFD, DRM_R128_CCE_STOP, + &stop, sizeof(drmR128CCEStop) )) { + return -errno; + } else { + return 0; + } +} + +/* Initialize the CCE state, and start the CCE (if used by the X server) */ +static void R128DRICCEInit(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + + /* Turn on bus mastering */ + info->BusCntl &= ~R128_BUS_MASTER_DIS; + + /* CCEMode is initialized in r128_driver.c */ + switch (info->CCEMode) { + case R128_PM4_NONPM4: info->CCEFifoSize = 0; break; + case R128_PM4_192PIO: info->CCEFifoSize = 192; break; + case R128_PM4_192BM: info->CCEFifoSize = 192; break; + case R128_PM4_128PIO_64INDBM: info->CCEFifoSize = 128; break; + case R128_PM4_128BM_64INDBM: info->CCEFifoSize = 128; break; + case R128_PM4_64PIO_128INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64BM_128INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64PIO_64VCBM_64INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64BM_64VCBM_64INDBM: info->CCEFifoSize = 64; break; + case R128_PM4_64PIO_64VCPIO_64INDPIO: info->CCEFifoSize = 64; break; + } + + /* Make sure the CCE is on for the X server */ + R128CCE_START(ctx, info); +} + + +static int R128MemoryInit(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + int width_bytes = ctx->shared.virtualWidth * ctx->cpp; + int cpp = ctx->cpp; + int bufferSize = ((ctx->shared.virtualHeight * width_bytes + + R128_BUFFER_ALIGN) + & ~R128_BUFFER_ALIGN); + int depthSize = ((((ctx->shared.virtualHeight+15) & ~15) * width_bytes + + R128_BUFFER_ALIGN) + & ~R128_BUFFER_ALIGN); + int l; + + info->frontOffset = 0; + info->frontPitch = ctx->shared.virtualWidth; + + fprintf(stderr, + "Using %d MB AGP aperture\n", info->agpSize); + fprintf(stderr, + "Using %d MB for the ring buffer\n", info->ringSize); + fprintf(stderr, + "Using %d MB for vertex/indirect buffers\n", info->bufSize); + fprintf(stderr, + "Using %d MB for AGP textures\n", info->agpTexSize); + + /* Front, back and depth buffers - everything else texture?? + */ + info->textureSize = ctx->shared.fbSize - 2 * bufferSize - depthSize; + + if (info->textureSize < 0) + return 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; + + /* 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; + } + + /* Reserve space for textures */ + info->textureOffset = ((ctx->shared.fbSize - info->textureSize + + R128_BUFFER_ALIGN) & + ~R128_BUFFER_ALIGN); + + /* Reserve space for the shared depth + * buffer. + */ + info->depthOffset = ((info->textureOffset - depthSize + + R128_BUFFER_ALIGN) & + ~R128_BUFFER_ALIGN); + info->depthPitch = ctx->shared.virtualWidth; + + info->backOffset = ((info->depthOffset - bufferSize + + R128_BUFFER_ALIGN) & + ~R128_BUFFER_ALIGN); + info->backPitch = ctx->shared.virtualWidth; + + + fprintf(stderr, + "Will use back buffer at offset 0x%x\n", + info->backOffset); + fprintf(stderr, + "Will use depth buffer at offset 0x%x\n", + info->depthOffset); + fprintf(stderr, + "Will use %d kb for textures at offset 0x%x\n", + info->textureSize/1024, info->textureOffset); + + return 1; +} + + +/* Initialize the screen-specific data structures for the DRI and the + Rage 128. 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. */ +static GLboolean R128DRIScreenInit(DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + R128DRIPtr pR128DRI; + int err, major, minor, patch; + drmVersionPtr version; + + switch (ctx->bpp) { + case 8: + /* These modes are not supported (yet). */ + case 15: + case 24: + fprintf(stderr, + "[dri] R128DRIScreenInit failed (depth %d not supported). " + "[dri] Disabling DRI.\n", ctx->bpp); + return GL_FALSE; + + /* Only 16 and 32 color depths are supports currently. */ + case 16: + case 32: + break; + } + + info->registerSize = ctx->MMIOSize; + ctx->shared.SAREASize = DRM_PAGE_SIZE; + + /* Note that drmOpen will try to load the kernel module, if needed. */ + ctx->drmFD = drmOpen("r128", NULL ); + if (ctx->drmFD < 0) { + fprintf(stderr, "[drm] drmOpen failed\n"); + return 0; + } + + /* Check the r128 DRM version */ + version = drmGetVersion(ctx->drmFD); + if (version) { + if (version->version_major != 2 || + version->version_minor < 2) { + /* incompatible drm version */ + fprintf(stderr, + "[dri] R128DRIScreenInit failed because of a version mismatch.\n" + "[dri] r128.o kernel module version is %d.%d.%d but version 2.2 or greater is needed.\n" + "[dri] Disabling the DRI.\n", + version->version_major, + version->version_minor, + version->version_patchlevel); + drmFreeVersion(version); + return GL_FALSE; + } + info->drmMinor = version->version_minor; + drmFreeVersion(version); + } + + if ((err = drmSetBusid(ctx->drmFD, ctx->pciBusID)) < 0) { + fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n", + ctx->drmFD, ctx->pciBusID, strerror(-err)); + return 0; + } + + if (drmAddMap( ctx->drmFD, + 0, + ctx->shared.SAREASize, + DRM_SHM, + DRM_CONTAINS_LOCK, + &ctx->shared.hSAREA) < 0) + { + fprintf(stderr, "[drm] drmAddMap failed\n"); + return 0; + } + fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n", + ctx->shared.SAREASize, ctx->shared.hSAREA); + + if (drmMap( ctx->drmFD, + ctx->shared.hSAREA, + ctx->shared.SAREASize, + (drmAddressPtr)(&ctx->pSAREA)) < 0) + { + fprintf(stderr, "[drm] drmMap failed\n"); + return 0; + } + memset(ctx->pSAREA, 0, ctx->shared.SAREASize); + fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n", + ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize); + + /* Need to AddMap the framebuffer and mmio regions here: + */ + if (drmAddMap( ctx->drmFD, + (drmHandle)ctx->FBStart, + ctx->FBSize, + DRM_FRAME_BUFFER, + 0, + &ctx->shared.hFrameBuffer) < 0) + { + fprintf(stderr, "[drm] drmAddMap framebuffer failed\n"); + return 0; + } + + fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n", + ctx->shared.hFrameBuffer); + + if (!R128MemoryInit(ctx)) + return GL_FALSE; + + /* Initialize AGP */ + if (!info->IsPCI && !R128DRIAgpInit(ctx)) { + info->IsPCI = GL_TRUE; + fprintf(stderr, + "[agp] AGP failed to initialize -- falling back to PCI mode.\n"); + fprintf(stderr, + "[agp] Make sure you have the agpgart kernel module loaded.\n"); + } + + /* Initialize PCIGART */ + if (info->IsPCI && !R128DRIPciInit(ctx)) { + return GL_FALSE; + } + + /* DRIScreenInit doesn't add all the + common mappings. Add additional + mappings here. */ + if (!R128DRIMapInit(ctx)) { + return GL_FALSE; + } + + /* Create a 'server' context so we can grab the lock for + * initialization ioctls. + */ + if ((err = drmCreateContext(ctx->drmFD, &ctx->serverContext)) != 0) { + fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err); + return 0; + } + + DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0); + + /* Initialize the kernel data structures */ + if (!R128DRIKernelInit(ctx)) { + return GL_FALSE; + } + + /* Initialize the vertex buffers list */ + if (!R128DRIBufInit(ctx)) { + return GL_FALSE; + } + + /* Initialize IRQ */ + R128DRIIrqInit(ctx); + + /* Initialize and start the CCE if required */ + R128DRICCEInit(ctx); + + /* Quick hack to clear the front & back buffers. Could also use + * the clear ioctl to do this, but would need to setup hw state + * first. + */ + memset((char *)ctx->FBAddress + info->frontOffset, + 0, + info->frontPitch * ctx->cpp * ctx->shared.virtualHeight ); + + memset((char *)ctx->FBAddress + info->backOffset, + 0, + info->backPitch * ctx->cpp * ctx->shared.virtualHeight ); + + R128SAREAPrivPtr pSAREAPriv; + pSAREAPriv = (R128SAREAPrivPtr)(((char*)ctx->pSAREA) + + sizeof(XF86DRISAREARec)); + memset(pSAREAPriv, 0, sizeof(*pSAREAPriv)); + + /* This is the struct passed to radeon_dri.so for its initialization */ + ctx->driverClientMsg = malloc(sizeof(R128DRIRec)); + ctx->driverClientMsgSize = sizeof(R128DRIRec); + + pR128DRI = (R128DRIPtr)ctx->driverClientMsg; + pR128DRI->deviceID = info->Chipset; + pR128DRI->width = ctx->shared.virtualWidth; + pR128DRI->height = ctx->shared.virtualHeight; + pR128DRI->depth = ctx->bpp; + pR128DRI->bpp = ctx->bpp; + + pR128DRI->IsPCI = info->IsPCI; + pR128DRI->AGPMode = info->agpMode; + + pR128DRI->frontOffset = info->frontOffset; + pR128DRI->frontPitch = info->frontPitch; + pR128DRI->backOffset = info->backOffset; + pR128DRI->backPitch = info->backPitch; + pR128DRI->depthOffset = info->depthOffset; + pR128DRI->depthPitch = info->depthPitch; + pR128DRI->spanOffset = info->spanOffset; + pR128DRI->textureOffset = info->textureOffset; + pR128DRI->textureSize = info->textureSize; + pR128DRI->log2TexGran = info->log2TexGran; + + pR128DRI->registerHandle = info->registerHandle; + pR128DRI->registerSize = info->registerSize; + + pR128DRI->agpTexHandle = info->agpTexHandle; + pR128DRI->agpTexMapSize = info->agpTexMapSize; + pR128DRI->log2AGPTexGran = info->log2AGPTexGran; + pR128DRI->agpTexOffset = info->agpTexStart; + pR128DRI->sarea_priv_offset = sizeof(XF86DRISAREARec); + + return GL_TRUE; +} + +/* The screen is being closed, so clean up any state and free any + resources used by the DRI. */ +void R128DRICloseScreen(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + drmR128Init drmInfo; + + /* Stop the CCE if it is still in use */ + R128CCE_STOP(ctx, info); + + if (info->irq) { + drmCtlUninstHandler(ctx->drmFD); + info->irq = 0; + } + + /* De-allocate vertex buffers */ + if (info->buffers) { + drmUnmapBufs(info->buffers); + info->buffers = NULL; + } + + /* De-allocate all kernel resources */ + memset(&drmInfo, 0, sizeof(drmR128Init)); + drmInfo.func = DRM_R128_CLEANUP_CCE; + drmCommandWrite(ctx->drmFD, DRM_R128_INIT, + &drmInfo, sizeof(drmR128Init)); + + /* 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 != DRM_AGP_NO_HANDLE) { + drmAgpUnbind(ctx->drmFD, info->agpMemHandle); + drmAgpFree(ctx->drmFD, info->agpMemHandle); + info->agpMemHandle = 0; + drmAgpRelease(ctx->drmFD); + } + if (info->pciMemHandle) { + drmScatterGatherFree(ctx->drmFD, info->pciMemHandle); + info->pciMemHandle = 0; + } +} + +static GLboolean R128PreInitDRI(const DRIDriverContext *ctx) +{ + R128InfoPtr info = ctx->driverPrivate; + + /*info->CCEMode = R128_DEFAULT_CCE_PIO_MODE;*/ + info->CCEMode = R128_DEFAULT_CCE_BM_MODE; + info->CCESecure = GL_TRUE; + + info->agpMode = R128_DEFAULT_AGP_MODE; + info->agpSize = R128_DEFAULT_AGP_SIZE; + info->ringSize = R128_DEFAULT_RING_SIZE; + info->bufSize = R128_DEFAULT_BUFFER_SIZE; + info->agpTexSize = R128_DEFAULT_AGP_TEX_SIZE; + + info->CCEusecTimeout = R128_DEFAULT_CCE_TIMEOUT; + + return GL_TRUE; +} + +/** + * \brief Initialize the framebuffer device mode + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Fills in \p info with some default values and some information from \p ctx + * and then calls R128ScreenInit() for the screen initialization. + * + * Before exiting clears the framebuffer memory accessing it directly. + */ +static int R128InitFBDev( DRIDriverContext *ctx ) +{ + R128InfoPtr info = calloc(1, sizeof(*info)); + + { + int dummy = ctx->shared.virtualWidth; + + switch (ctx->bpp / 8) { + case 1: dummy = (ctx->shared.virtualWidth + 127) & ~127; break; + case 2: dummy = (ctx->shared.virtualWidth + 31) & ~31; break; + case 3: + case 4: dummy = (ctx->shared.virtualWidth + 15) & ~15; break; + } + + ctx->shared.virtualWidth = dummy; + } + + ctx->driverPrivate = (void *)info; + + info->Chipset = ctx->chipset; + + switch (info->Chipset) { + case PCI_DEVICE_ID_ATI_RAGE128_LE: + case PCI_DEVICE_ID_ATI_RAGE128_RE: + case PCI_DEVICE_ID_ATI_RAGE128_RK: + case PCI_DEVICE_ID_ATI_RAGE128_PD: + case PCI_DEVICE_ID_ATI_RAGE128_PP: + case PCI_DEVICE_ID_ATI_RAGE128_PR: + /* This is a PCI card */ + info->IsPCI = GL_TRUE; + break; + default: + /* This is an AGP card */ + info->IsPCI = GL_FALSE; + break; + } + + info->frontPitch = ctx->shared.virtualWidth; + info->LinearAddr = ctx->FBStart & 0xfc000000; + + if (!R128PreInitDRI(ctx)) + return 0; + + if (!R128DRIScreenInit(ctx)) + return 0; + + return 1; +} + + +/** + * \brief The screen is being closed, so clean up any state and free any + * resources used by the DRI. + * + * \param ctx display handle. + * + * Unmaps the SAREA, closes the DRM device file descriptor and frees the driver + * private data. + */ +static void R128HaltFBDev( DRIDriverContext *ctx ) +{ + drmUnmap( ctx->pSAREA, ctx->shared.SAREASize ); + drmClose(ctx->drmFD); + + if (ctx->driverPrivate) { + free(ctx->driverPrivate); + ctx->driverPrivate = 0; + } +} + + +/** + * \brief Validate the fbdev mode. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Saves some registers and returns 1. + * + * \sa R128PostValidateMode(). + */ +static int R128ValidateMode( const DRIDriverContext *ctx ) +{ + return 1; +} + + +/** + * \brief Examine mode returned by fbdev. + * + * \param ctx display handle. + * + * \return one on success, or zero on failure. + * + * Restores registers that fbdev has clobbered and returns 1. + * + * \sa R128ValidateMode(). + */ +static int R128PostValidateMode( const DRIDriverContext *ctx ) +{ + return 1; +} + + +/** + * \brief Shutdown the drawing engine. + * + * \param ctx display handle + * + * Turns off the command processor engine & restores the graphics card + * to a state that fbdev understands. + */ +static int R128EngineShutdown( const DRIDriverContext *ctx ) +{ + return 1; +} + +/** + * \brief Restore the drawing engine. + * + * \param ctx display handle + * + * Resets the graphics card and sets initial values for several registers of + * the card's drawing engine. + * + * Turns on the R128 command processor engine (i.e., the ringbuffer). + */ +static int R128EngineRestore( const DRIDriverContext *ctx ) +{ + return 1; +} + + +/** + * \brief Exported driver interface for Mini GLX. + * + * \sa DRIDriverRec. + */ +const struct DRIDriverRec __driDriver = { + R128InitContextModes, + R128ValidateMode, + R128PostValidateMode, + R128InitFBDev, + R128HaltFBDev, + R128EngineShutdown, + R128EngineRestore, + 0, +}; diff --git a/src/mesa/drivers/dri/r128/server/r128_dri.h b/src/mesa/drivers/dri/r128/server/r128_dri.h new file mode 100644 index 0000000000..80f94ded68 --- /dev/null +++ b/src/mesa/drivers/dri/r128/server/r128_dri.h @@ -0,0 +1,103 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_dri.h,v 1.7 2002/10/30 12:52:12 alanh Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + * Precision Insight, Inc., Cedar Park, Texas, 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, 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, PRECISION INSIGHT, 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 + * Rickard E. Faith + * Gareth Hughes + * + */ + +#ifndef _R128_DRI_ +#define _R128_DRI_ + +#include "xf86drm.h" +#include "r128_common.h" + +/* DRI Driver defaults */ +#define R128_DEFAULT_CCE_PIO_MODE R128_PM4_64PIO_64VCBM_64INDBM +#define R128_DEFAULT_CCE_BM_MODE R128_PM4_64BM_64VCBM_64INDBM +#define R128_DEFAULT_AGP_MODE 1 +#define R128_DEFAULT_AGP_SIZE 8 /* MB (must be a power of 2 and > 4MB) */ +#define R128_DEFAULT_RING_SIZE 1 /* MB (must be page aligned) */ +#define R128_DEFAULT_BUFFER_SIZE 2 /* MB (must be page aligned) */ +#define R128_DEFAULT_AGP_TEX_SIZE 1 /* MB (must be page aligned) */ + +#define R128_DEFAULT_CCE_TIMEOUT 10000 /* usecs */ + +#define R128_AGP_MAX_MODE 4 +#define R128_BUFFER_ALIGN 0x00000fff + +#define R128_CARD_TYPE_R128 1 +#define R128_CARD_TYPE_R128_PRO 2 +#define R128_CARD_TYPE_R128_MOBILITY 3 + +#define R128CCE_USE_RING_BUFFER(m) \ +(((m) == R128_PM4_192BM) || \ + ((m) == R128_PM4_128BM_64INDBM) || \ + ((m) == R128_PM4_64BM_128INDBM) || \ + ((m) == R128_PM4_64BM_64VCBM_64INDBM)) + +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 spanOffset; /* Start of scratch spanline */ + int textureOffset;/* Start of texture data in frame buffer */ + int textureSize; + int log2TexGran; + + /* MMIO register data */ + drmHandle registerHandle; + drmSize registerSize; + + /* CCE AGP Texture data */ + drmHandle agpTexHandle; + drmSize agpTexMapSize; + int log2AGPTexGran; + int agpTexOffset; + unsigned int sarea_priv_offset; +} R128DRIRec, *R128DRIPtr; + +#endif diff --git a/src/mesa/drivers/dri/r128/server/r128_macros.h b/src/mesa/drivers/dri/r128/server/r128_macros.h new file mode 100644 index 0000000000..93b7feb02c --- /dev/null +++ b/src/mesa/drivers/dri/r128/server/r128_macros.h @@ -0,0 +1,135 @@ +/** + * \file server/R128_macros.h + * \brief Macros for R128 MMIO operation. + * + * \authors Kevin E. Martin + * \authors Rickard E. Faith + * \authors Alan Hourihane + */ + +/* + * Copyright 2000 ATI Technologies Inc., Markham, Ontario, 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, 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. + */ + +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/R128_reg.h,v 1.20 2002/10/12 01:38:07 martin Exp $ */ + +#ifndef _R128_MACROS_H_ +#define _R128_MACROS_H_ + + + +# define MMIO_IN8(base, offset) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) +# define MMIO_IN16(base, offset) \ + *(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset)) +# define MMIO_IN32(base, offset) \ + *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) +# define MMIO_OUT8(base, offset, val) \ + *(volatile unsigned char *)(((unsigned char*)(base)) + (offset)) = (val) +# define MMIO_OUT16(base, offset, val) \ + *(volatile unsigned short *)(void *)(((unsigned char*)(base)) + (offset)) = (val) +# define MMIO_OUT32(base, offset, val) \ + *(volatile unsigned int *)(void *)(((unsigned char*)(base)) + (offset)) = (val) + + + /* Memory mapped register access macros */ +#define INREG8(addr) MMIO_IN8(R128MMIO, addr) +#define INREG16(addr) MMIO_IN16(R128MMIO, addr) +#define INREG(addr) MMIO_IN32(R128MMIO, addr) +#define OUTREG8(addr, val) MMIO_OUT8(R128MMIO, addr, val) +#define OUTREG16(addr, val) MMIO_OUT16(R128MMIO, addr, val) +#define OUTREG(addr, val) MMIO_OUT32(R128MMIO, addr, val) + +#define ADDRREG(addr) ((volatile GLuint *)(pointer)(R128MMIO + (addr))) + + +#define OUTREGP(addr, val, mask) \ +do { \ + GLuint tmp = INREG(addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTREG(addr, tmp); \ +} while (0) + +#define INPLL(dpy, addr) r128INPLL(dpy, addr) + +#define OUTPLL(addr, val) \ +do { \ + OUTREG8(R128_CLOCK_CNTL_INDEX, (((addr) & 0x3f) | \ + R128_PLL_WR_EN)); \ + OUTREG(R128_CLOCK_CNTL_DATA, val); \ +} while (0) + +#define OUTPLLP(dpy, addr, val, mask) \ +do { \ + GLuint tmp = INPLL(dpy, addr); \ + tmp &= (mask); \ + tmp |= (val); \ + OUTPLL(addr, tmp); \ +} while (0) + +#define OUTPAL_START(idx) \ +do { \ + OUTREG8(R128_PALETTE_INDEX, (idx)); \ +} while (0) + +#define OUTPAL_NEXT(r, g, b) \ +do { \ + OUTREG(R128_PALETTE_DATA, ((r) << 16) | ((g) << 8) | (b)); \ +} while (0) + +#define OUTPAL_NEXT_CARD32(v) \ +do { \ + OUTREG(R128_PALETTE_DATA, (v & 0x00ffffff)); \ +} while (0) + +#define OUTPAL(idx, r, g, b) \ +do { \ + OUTPAL_START((idx)); \ + OUTPAL_NEXT((r), (g), (b)); \ +} while (0) + +#define INPAL_START(idx) \ +do { \ + OUTREG(R128_PALETTE_INDEX, (idx) << 16); \ +} while (0) + +#define INPAL_NEXT() INREG(R128_PALETTE_DATA) + +#define PAL_SELECT(idx) \ +do { \ + if (!idx) { \ + OUTREG(R128_DAC_CNTL2, INREG(R128_DAC_CNTL2) & \ + (GLuint)~R128_DAC2_PALETTE_ACC_CTL); \ + } else { \ + OUTREG(R128_DAC_CNTL2, INREG(R128_DAC_CNTL2) | \ + R128_DAC2_PALETTE_ACC_CTL); \ + } \ +} while (0) + + +#endif diff --git a/src/mesa/drivers/dri/r128/server/r128_reg.h b/src/mesa/drivers/dri/r128/server/r128_reg.h new file mode 100644 index 0000000000..7ec4004492 --- /dev/null +++ b/src/mesa/drivers/dri/r128/server/r128_reg.h @@ -0,0 +1,1431 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_reg.h,v 1.15 2002/12/16 16:19:11 dawes Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + * Precision Insight, Inc., Cedar Park, Texas, 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, 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, PRECISION INSIGHT, 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: + * Rickard E. Faith + * Kevin E. Martin + * Gareth Hughes + * + * References: + * + * RAGE 128 VR/ RAGE 128 GL Register Reference Manual (Technical + * Reference Manual P/N RRG-G04100-C Rev. 0.04), ATI Technologies: April + * 1999. + * + * RAGE 128 Software Development Manual (Technical Reference Manual P/N + * SDK-G04000 Rev. 0.01), ATI Technologies: June 1999. + * + */ + +#ifndef _R128_REG_H_ +#define _R128_REG_H_ + +#define R128_ADAPTER_ID 0x0f2c /* PCI */ +#define R128_AGP_APER_OFFSET 0x0178 +#define R128_AGP_BASE 0x0170 +#define R128_AGP_CNTL 0x0174 +# define R128_AGP_APER_SIZE_256MB (0x00 << 0) +# define R128_AGP_APER_SIZE_128MB (0x20 << 0) +# define R128_AGP_APER_SIZE_64MB (0x30 << 0) +# define R128_AGP_APER_SIZE_32MB (0x38 << 0) +# define R128_AGP_APER_SIZE_16MB (0x3c << 0) +# define R128_AGP_APER_SIZE_8MB (0x3e << 0) +# define R128_AGP_APER_SIZE_4MB (0x3f << 0) +# define R128_AGP_APER_SIZE_MASK (0x3f << 0) +#define R128_AGP_CNTL_B 0x0b44 +#define R128_AGP_COMMAND 0x0f58 /* PCI */ +#define R128_AGP_PLL_CNTL 0x0010 /* PLL */ +#define R128_AGP_STATUS 0x0f54 /* PCI */ +# define R128_AGP_1X_MODE 0x01 +# define R128_AGP_2X_MODE 0x02 +# define R128_AGP_4X_MODE 0x04 +# define R128_AGP_MODE_MASK 0x07 +#define R128_AMCGPIO_A_REG 0x01a0 +#define R128_AMCGPIO_EN_REG 0x01a8 +#define R128_AMCGPIO_MASK 0x0194 +#define R128_AMCGPIO_Y_REG 0x01a4 +#define R128_ATTRDR 0x03c1 /* VGA */ +#define R128_ATTRDW 0x03c0 /* VGA */ +#define R128_ATTRX 0x03c0 /* VGA */ +#define R128_AUX_SC_CNTL 0x1660 +# define R128_AUX1_SC_EN (1 << 0) +# define R128_AUX1_SC_MODE_OR (0 << 1) +# define R128_AUX1_SC_MODE_NAND (1 << 1) +# define R128_AUX2_SC_EN (1 << 2) +# define R128_AUX2_SC_MODE_OR (0 << 3) +# define R128_AUX2_SC_MODE_NAND (1 << 3) +# define R128_AUX3_SC_EN (1 << 4) +# define R128_AUX3_SC_MODE_OR (0 << 5) +# define R128_AUX3_SC_MODE_NAND (1 << 5) +#define R128_AUX1_SC_BOTTOM 0x1670 +#define R128_AUX1_SC_LEFT 0x1664 +#define R128_AUX1_SC_RIGHT 0x1668 +#define R128_AUX1_SC_TOP 0x166c +#define R128_AUX2_SC_BOTTOM 0x1680 +#define R128_AUX2_SC_LEFT 0x1674 +#define R128_AUX2_SC_RIGHT 0x1678 +#define R128_AUX2_SC_TOP 0x167c +#define R128_AUX3_SC_BOTTOM 0x1690 +#define R128_AUX3_SC_LEFT 0x1684 +#define R128_AUX3_SC_RIGHT 0x1688 +#define R128_AUX3_SC_TOP 0x168c +#define R128_AUX_WINDOW_HORZ_CNTL 0x02d8 +#define R128_AUX_WINDOW_VERT_CNTL 0x02dc + +#define R128_BASE_CODE 0x0f0b +#define R128_BIOS_0_SCRATCH 0x0010 +#define R128_BIOS_1_SCRATCH 0x0014 +#define R128_BIOS_2_SCRATCH 0x0018 +#define R128_BIOS_3_SCRATCH 0x001c +#define R128_BIOS_4_SCRATCH 0x0020 +#define R128_BIOS_5_SCRATCH 0x0024 +# define R128_BIOS_DISPLAY_FP (1 << 0) +# define R128_BIOS_DISPLAY_CRT (2 << 0) +# define R128_BIOS_DISPLAY_FP_CRT (3 << 0) +#define R128_BIOS_6_SCRATCH 0x0028 +#define R128_BIOS_7_SCRATCH 0x002c +#define R128_BIOS_ROM 0x0f30 /* PCI */ +#define R128_BIST 0x0f0f /* PCI */ +#define R128_BM_CHUNK_0_VAL 0x0a18 +# define R128_BM_PTR_FORCE_TO_PCI (1 << 21) +# define R128_BM_PM4_RD_FORCE_TO_PCI (1 << 22) +# define R128_BM_GLOBAL_FORCE_TO_PCI (1 << 23) +#define R128_BRUSH_DATA0 0x1480 +#define R128_BRUSH_DATA1 0x1484 +#define R128_BRUSH_DATA10 0x14a8 +#define R128_BRUSH_DATA11 0x14ac +#define R128_BRUSH_DATA12 0x14b0 +#define R128_BRUSH_DATA13 0x14b4 +#define R128_BRUSH_DATA14 0x14b8 +#define R128_BRUSH_DATA15 0x14bc +#define R128_BRUSH_DATA16 0x14c0 +#define R128_BRUSH_DATA17 0x14c4 +#define R128_BRUSH_DATA18 0x14c8 +#define R128_BRUSH_DATA19 0x14cc +#define R128_BRUSH_DATA2 0x1488 +#define R128_BRUSH_DATA20 0x14d0 +#define R128_BRUSH_DATA21 0x14d4 +#define R128_BRUSH_DATA22 0x14d8 +#define R128_BRUSH_DATA23 0x14dc +#define R128_BRUSH_DATA24 0x14e0 +#define R128_BRUSH_DATA25 0x14e4 +#define R128_BRUSH_DATA26 0x14e8 +#define R128_BRUSH_DATA27 0x14ec +#define R128_BRUSH_DATA28 0x14f0 +#define R128_BRUSH_DATA29 0x14f4 +#define R128_BRUSH_DATA3 0x148c +#define R128_BRUSH_DATA30 0x14f8 +#define R128_BRUSH_DATA31 0x14fc +#define R128_BRUSH_DATA32 0x1500 +#define R128_BRUSH_DATA33 0x1504 +#define R128_BRUSH_DATA34 0x1508 +#define R128_BRUSH_DATA35 0x150c +#define R128_BRUSH_DATA36 0x1510 +#define R128_BRUSH_DATA37 0x1514 +#define R128_BRUSH_DATA38 0x1518 +#define R128_BRUSH_DATA39 0x151c +#define R128_BRUSH_DATA4 0x1490 +#define R128_BRUSH_DATA40 0x1520 +#define R128_BRUSH_DATA41 0x1524 +#define R128_BRUSH_DATA42 0x1528 +#define R128_BRUSH_DATA43 0x152c +#define R128_BRUSH_DATA44 0x1530 +#define R128_BRUSH_DATA45 0x1534 +#define R128_BRUSH_DATA46 0x1538 +#define R128_BRUSH_DATA47 0x153c +#define R128_BRUSH_DATA48 0x1540 +#define R128_BRUSH_DATA49 0x1544 +#define R128_BRUSH_DATA5 0x1494 +#define R128_BRUSH_DATA50 0x1548 +#define R128_BRUSH_DATA51 0x154c +#define R128_BRUSH_DATA52 0x1550 +#define R128_BRUSH_DATA53 0x1554 +#define R128_BRUSH_DATA54 0x1558 +#define R128_BRUSH_DATA55 0x155c +#define R128_BRUSH_DATA56 0x1560 +#define R128_BRUSH_DATA57 0x1564 +#define R128_BRUSH_DATA58 0x1568 +#define R128_BRUSH_DATA59 0x156c +#define R128_BRUSH_DATA6 0x1498 +#define R128_BRUSH_DATA60 0x1570 +#define R128_BRUSH_DATA61 0x1574 +#define R128_BRUSH_DATA62 0x1578 +#define R128_BRUSH_DATA63 0x157c +#define R128_BRUSH_DATA7 0x149c +#define R128_BRUSH_DATA8 0x14a0 +#define R128_BRUSH_DATA9 0x14a4 +#define R128_BRUSH_SCALE 0x1470 +#define R128_BRUSH_Y_X 0x1474 +#define R128_BUS_CNTL 0x0030 +# define R128_BUS_MASTER_DIS (1 << 6) +# define R128_BUS_RD_DISCARD_EN (1 << 24) +# define R128_BUS_RD_ABORT_EN (1 << 25) +# define R128_BUS_MSTR_DISCONNECT_EN (1 << 28) +# define R128_BUS_WRT_BURST (1 << 29) +# define R128_BUS_READ_BURST (1 << 30) +#define R128_BUS_CNTL1 0x0034 +# define R128_BUS_WAIT_ON_LOCK_EN (1 << 4) + +#define R128_CACHE_CNTL 0x1724 +#define R128_CACHE_LINE 0x0f0c /* PCI */ +#define R128_CAP0_TRIG_CNTL 0x0950 /* ? */ +#define R128_CAP1_TRIG_CNTL 0x09c0 /* ? */ +#define R128_CAPABILITIES_ID 0x0f50 /* PCI */ +#define R128_CAPABILITIES_PTR 0x0f34 /* PCI */ +#define R128_CLK_PIN_CNTL 0x0001 /* PLL */ +#define R128_CLOCK_CNTL_DATA 0x000c +#define R128_CLOCK_CNTL_INDEX 0x0008 +# define R128_PLL_WR_EN (1 << 7) +# define R128_PLL_DIV_SEL (3 << 8) +#define R128_CLR_CMP_CLR_3D 0x1a24 +#define R128_CLR_CMP_CLR_DST 0x15c8 +#define R128_CLR_CMP_CLR_SRC 0x15c4 +#define R128_CLR_CMP_CNTL 0x15c0 +# define R128_SRC_CMP_EQ_COLOR (4 << 0) +# define R128_SRC_CMP_NEQ_COLOR (5 << 0) +# define R128_CLR_CMP_SRC_SOURCE (1 << 24) +#define R128_CLR_CMP_MASK 0x15cc +# define R128_CLR_CMP_MSK 0xffffffff +#define R128_CLR_CMP_MASK_3D 0x1A28 +#define R128_COMMAND 0x0f04 /* PCI */ +#define R128_COMPOSITE_SHADOW_ID 0x1a0c +#define R128_CONFIG_APER_0_BASE 0x0100 +#define R128_CONFIG_APER_1_BASE 0x0104 +#define R128_CONFIG_APER_SIZE 0x0108 +#define R128_CONFIG_BONDS 0x00e8 +#define R128_CONFIG_CNTL 0x00e0 +# define APER_0_BIG_ENDIAN_16BPP_SWAP (1 << 0) +# define APER_0_BIG_ENDIAN_32BPP_SWAP (2 << 0) +#define R128_CONFIG_MEMSIZE 0x00f8 +#define R128_CONFIG_MEMSIZE_EMBEDDED 0x0114 +#define R128_CONFIG_REG_1_BASE 0x010c +#define R128_CONFIG_REG_APER_SIZE 0x0110 +#define R128_CONFIG_XSTRAP 0x00e4 +#define R128_CONSTANT_COLOR_C 0x1d34 +# define R128_CONSTANT_COLOR_MASK 0x00ffffff +# define R128_CONSTANT_COLOR_ONE 0x00ffffff +# define R128_CONSTANT_COLOR_ZERO 0x00000000 +#define R128_CRC_CMDFIFO_ADDR 0x0740 +#define R128_CRC_CMDFIFO_DOUT 0x0744 +#define R128_CRTC_CRNT_FRAME 0x0214 +#define R128_CRTC_DEBUG 0x021c +#define R128_CRTC_EXT_CNTL 0x0054 +# define R128_CRTC_VGA_XOVERSCAN (1 << 0) +# define R128_VGA_ATI_LINEAR (1 << 3) +# define R128_XCRT_CNT_EN (1 << 6) +# define R128_CRTC_HSYNC_DIS (1 << 8) +# define R128_CRTC_VSYNC_DIS (1 << 9) +# define R128_CRTC_DISPLAY_DIS (1 << 10) +# define R128_CRTC_CRT_ON (1 << 15) +# define R128_FP_OUT_EN (1 << 22) +# define R128_FP_ACTIVE (1 << 23) +#define R128_CRTC_EXT_CNTL_DPMS_BYTE 0x0055 +# define R128_CRTC_HSYNC_DIS_BYTE (1 << 0) +# define R128_CRTC_VSYNC_DIS_BYTE (1 << 1) +# define R128_CRTC_DISPLAY_DIS_BYTE (1 << 2) +#define R128_CRTC_GEN_CNTL 0x0050 +# define R128_CRTC_DBL_SCAN_EN (1 << 0) +# define R128_CRTC_INTERLACE_EN (1 << 1) +# define R128_CRTC_CSYNC_EN (1 << 4) +# define R128_CRTC_CUR_EN (1 << 16) +# define R128_CRTC_CUR_MODE_MASK (7 << 17) +# define R128_CRTC_ICON_EN (1 << 20) +# define R128_CRTC_EXT_DISP_EN (1 << 24) +# define R128_CRTC_EN (1 << 25) +# define R128_CRTC_DISP_REQ_EN_B (1 << 26) +#define R128_CRTC_GUI_TRIG_VLINE 0x0218 +#define R128_CRTC_H_SYNC_STRT_WID 0x0204 +# define R128_CRTC_H_SYNC_STRT_PIX (0x07 << 0) +# define R128_CRTC_H_SYNC_STRT_CHAR (0x1ff << 3) +# define R128_CRTC_H_SYNC_STRT_CHAR_SHIFT 3 +# define R128_CRTC_H_SYNC_WID (0x3f << 16) +# define R128_CRTC_H_SYNC_WID_SHIFT 16 +# define R128_CRTC_H_SYNC_POL (1 << 23) +#define R128_CRTC_H_TOTAL_DISP 0x0200 +# define R128_CRTC_H_TOTAL (0x01ff << 0) +# define R128_CRTC_H_TOTAL_SHIFT 0 +# define R128_CRTC_H_DISP (0x00ff << 16) +# define R128_CRTC_H_DISP_SHIFT 16 +#define R128_CRTC_OFFSET 0x0224 +#define R128_CRTC_OFFSET_CNTL 0x0228 +#define R128_CRTC_PITCH 0x022c +#define R128_CRTC_STATUS 0x005c +# define R128_CRTC_VBLANK_SAVE (1 << 1) +#define R128_CRTC_V_SYNC_STRT_WID 0x020c +# define R128_CRTC_V_SYNC_STRT (0x7ff << 0) +# define R128_CRTC_V_SYNC_STRT_SHIFT 0 +# define R128_CRTC_V_SYNC_WID (0x1f << 16) +# define R128_CRTC_V_SYNC_WID_SHIFT 16 +# define R128_CRTC_V_SYNC_POL (1 << 23) +#define R128_CRTC_V_TOTAL_DISP 0x0208 +# define R128_CRTC_V_TOTAL (0x07ff << 0) +# define R128_CRTC_V_TOTAL_SHIFT 0 +# define R128_CRTC_V_DISP (0x07ff << 16) +# define R128_CRTC_V_DISP_SHIFT 16 +#define R128_CRTC_VLINE_CRNT_VLINE 0x0210 +# define R128_CRTC_CRNT_VLINE_MASK (0x7ff << 16) +#define R128_CRTC2_CRNT_FRAME 0x0314 +#define R128_CRTC2_DEBUG 0x031c +#define R128_CRTC2_GEN_CNTL 0x03f8 +#define R128_CRTC2_GUI_TRIG_VLINE 0x0318 +#define R128_CRTC2_H_SYNC_STRT_WID 0x0304 +#define R128_CRTC2_H_TOTAL_DISP 0x0300 +#define R128_CRTC2_OFFSET 0x0324 +#define R128_CRTC2_OFFSET_CNTL 0x0328 +#define R128_CRTC2_PITCH 0x032c +#define R128_CRTC2_STATUS 0x03fc +#define R128_CRTC2_V_SYNC_STRT_WID 0x030c +#define R128_CRTC2_V_TOTAL_DISP 0x0308 +#define R128_CRTC2_VLINE_CRNT_VLINE 0x0310 +#define R128_CRTC8_DATA 0x03d5 /* VGA, 0x3b5 */ +#define R128_CRTC8_IDX 0x03d4 /* VGA, 0x3b4 */ +#define R128_CUR_CLR0 0x026c +#define R128_CUR_CLR1 0x0270 +#define R128_CUR_HORZ_VERT_OFF 0x0268 +#define R128_CUR_HORZ_VERT_POSN 0x0264 +#define R128_CUR_OFFSET 0x0260 +# define R128_CUR_LOCK (1 << 31) + +#define R128_DAC_CNTL 0x0058 +# define R128_DAC_RANGE_CNTL (3 << 0) +# define R128_DAC_BLANKING (1 << 2) +# define R128_DAC_CRT_SEL_CRTC2 (1 << 4) +# define R128_DAC_PALETTE_ACC_CTL (1 << 5) +# define R128_DAC_8BIT_EN (1 << 8) +# define R128_DAC_VGA_ADR_EN (1 << 13) +# define R128_DAC_MASK_ALL (0xff << 24) +#define R128_DAC_CRC_SIG 0x02cc +#define R128_DAC_DATA 0x03c9 /* VGA */ +#define R128_DAC_MASK 0x03c6 /* VGA */ +#define R128_DAC_R_INDEX 0x03c7 /* VGA */ +#define R128_DAC_W_INDEX 0x03c8 /* VGA */ +#define R128_DDA_CONFIG 0x02e0 +#define R128_DDA_ON_OFF 0x02e4 +#define R128_DEFAULT_OFFSET 0x16e0 +#define R128_DEFAULT_PITCH 0x16e4 +#define R128_DEFAULT_SC_BOTTOM_RIGHT 0x16e8 +# define R128_DEFAULT_SC_RIGHT_MAX (0x1fff << 0) +# define R128_DEFAULT_SC_BOTTOM_MAX (0x1fff << 16) +#define R128_DESTINATION_3D_CLR_CMP_VAL 0x1820 +#define R128_DESTINATION_3D_CLR_CMP_MSK 0x1824 +#define R128_DEVICE_ID 0x0f02 /* PCI */ +#define R128_DP_BRUSH_BKGD_CLR 0x1478 +#define R128_DP_BRUSH_FRGD_CLR 0x147c +#define R128_DP_CNTL 0x16c0 +# define R128_DST_X_LEFT_TO_RIGHT (1 << 0) +# define R128_DST_Y_TOP_TO_BOTTOM (1 << 1) +#define R128_DP_CNTL_XDIR_YDIR_YMAJOR 0x16d0 +# define R128_DST_Y_MAJOR (1 << 2) +# define R128_DST_Y_DIR_TOP_TO_BOTTOM (1 << 15) +# define R128_DST_X_DIR_LEFT_TO_RIGHT (1 << 31) +#define R128_DP_DATATYPE 0x16c4 +# define R128_HOST_BIG_ENDIAN_EN (1 << 29) +#define R128_DP_GUI_MASTER_CNTL 0x146c +# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0) +# define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1) +# define R128_GMC_SRC_CLIPPING (1 << 2) +# define R128_GMC_DST_CLIPPING (1 << 3) +# define R128_GMC_BRUSH_DATATYPE_MASK (0x0f << 4) +# define R128_GMC_BRUSH_8X8_MONO_FG_BG (0 << 4) +# define R128_GMC_BRUSH_8X8_MONO_FG_LA (1 << 4) +# define R128_GMC_BRUSH_1X8_MONO_FG_BG (4 << 4) +# define R128_GMC_BRUSH_1X8_MONO_FG_LA (5 << 4) +# define R128_GMC_BRUSH_32x1_MONO_FG_BG (6 << 4) +# define R128_GMC_BRUSH_32x1_MONO_FG_LA (7 << 4) +# define R128_GMC_BRUSH_32x32_MONO_FG_BG (8 << 4) +# define R128_GMC_BRUSH_32x32_MONO_FG_LA (9 << 4) +# define R128_GMC_BRUSH_8x8_COLOR (10 << 4) +# define R128_GMC_BRUSH_1X8_COLOR (12 << 4) +# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4) +# define R128_GMC_BRUSH_NONE (15 << 4) +# define R128_GMC_DST_8BPP_CI (2 << 8) +# define R128_GMC_DST_15BPP (3 << 8) +# define R128_GMC_DST_16BPP (4 << 8) +# define R128_GMC_DST_24BPP (5 << 8) +# define R128_GMC_DST_32BPP (6 << 8) +# define R128_GMC_DST_8BPP_RGB (7 << 8) +# define R128_GMC_DST_Y8 (8 << 8) +# define R128_GMC_DST_RGB8 (9 << 8) +# define R128_GMC_DST_VYUY (11 << 8) +# define R128_GMC_DST_YVYU (12 << 8) +# define R128_GMC_DST_AYUV444 (14 << 8) +# define R128_GMC_DST_ARGB4444 (15 << 8) +# define R128_GMC_DST_DATATYPE_MASK (0x0f << 8) +# define R128_GMC_DST_DATATYPE_SHIFT 8 +# define R128_GMC_SRC_DATATYPE_MASK (3 << 12) +# define R128_GMC_SRC_DATATYPE_MONO_FG_BG (0 << 12) +# define R128_GMC_SRC_DATATYPE_MONO_FG_LA (1 << 12) +# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12) +# define R128_GMC_BYTE_PIX_ORDER (1 << 14) +# define R128_GMC_BYTE_MSB_TO_LSB (0 << 14) +# define R128_GMC_BYTE_LSB_TO_MSB (1 << 14) +# define R128_GMC_CONVERSION_TEMP (1 << 15) +# define R128_GMC_CONVERSION_TEMP_6500 (0 << 15) +# define R128_GMC_CONVERSION_TEMP_9300 (1 << 15) +# define R128_GMC_ROP3_MASK (0xff << 16) +# define R128_DP_SRC_SOURCE_MASK (7 << 24) +# define R128_DP_SRC_SOURCE_MEMORY (2 << 24) +# define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24) +# define R128_GMC_3D_FCN_EN (1 << 27) +# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28) +# define R128_GMC_AUX_CLIP_DIS (1 << 29) +# define R128_GMC_WR_MSK_DIS (1 << 30) +# define R128_GMC_LD_BRUSH_Y_X (1 << 31) +# define R128_ROP3_ZERO 0x00000000 +# define R128_ROP3_DSa 0x00880000 +# define R128_ROP3_SDna 0x00440000 +# define R128_ROP3_S 0x00cc0000 +# define R128_ROP3_DSna 0x00220000 +# define R128_ROP3_D 0x00aa0000 +# define R128_ROP3_DSx 0x00660000 +# define R128_ROP3_DSo 0x00ee0000 +# define R128_ROP3_DSon 0x00110000 +# define R128_ROP3_DSxn 0x00990000 +# define R128_ROP3_Dn 0x00550000 +# define R128_ROP3_SDno 0x00dd0000 +# define R128_ROP3_Sn 0x00330000 +# define R128_ROP3_DSno 0x00bb0000 +# define R128_ROP3_DSan 0x00770000 +# define R128_ROP3_ONE 0x00ff0000 +# define R128_ROP3_DPa 0x00a00000 +# define R128_ROP3_PDna 0x00500000 +# define R128_ROP3_P 0x00f00000 +# define R128_ROP3_DPna 0x000a0000 +# define R128_ROP3_D 0x00aa0000 +# define R128_ROP3_DPx 0x005a0000 +# define R128_ROP3_DPo 0x00fa0000 +# define R128_ROP3_DPon 0x00050000 +# define R128_ROP3_PDxn 0x00a50000 +# define R128_ROP3_PDno 0x00f50000 +# define R128_ROP3_Pn 0x000f0000 +# define R128_ROP3_DPno 0x00af0000 +# define R128_ROP3_DPan 0x005f0000 + + +#define R128_DP_GUI_MASTER_CNTL_C 0x1c84 +#define R128_DP_MIX 0x16c8 +#define R128_DP_SRC_BKGD_CLR 0x15dc +#define R128_DP_SRC_FRGD_CLR 0x15d8 +#define R128_DP_WRITE_MASK 0x16cc +#define R128_DST_BRES_DEC 0x1630 +#define R128_DST_BRES_ERR 0x1628 +#define R128_DST_BRES_INC 0x162c +#define R128_DST_BRES_LNTH 0x1634 +#define R128_DST_BRES_LNTH_SUB 0x1638 +#define R128_DST_HEIGHT 0x1410 +#define R128_DST_HEIGHT_WIDTH 0x143c +#define R128_DST_HEIGHT_WIDTH_8 0x158c +#define R128_DST_HEIGHT_WIDTH_BW 0x15b4 +#define R128_DST_HEIGHT_Y 0x15a0 +#define R128_DST_OFFSET 0x1404 +#define R128_DST_PITCH 0x1408 +#define R128_DST_PITCH_OFFSET 0x142c +#define R128_DST_PITCH_OFFSET_C 0x1c80 +# define R128_PITCH_SHIFT 21 +# define R128_DST_TILE (1 << 31) +#define R128_DST_WIDTH 0x140c +#define R128_DST_WIDTH_HEIGHT 0x1598 +#define R128_DST_WIDTH_X 0x1588 +#define R128_DST_WIDTH_X_INCY 0x159c +#define R128_DST_X 0x141c +#define R128_DST_X_SUB 0x15a4 +#define R128_DST_X_Y 0x1594 +#define R128_DST_Y 0x1420 +#define R128_DST_Y_SUB 0x15a8 +#define R128_DST_Y_X 0x1438 + +#define R128_EXT_MEM_CNTL 0x0144 + +#define R128_FCP_CNTL 0x0012 /* PLL */ +#define R128_FLUSH_1 0x1704 +#define R128_FLUSH_2 0x1708 +#define R128_FLUSH_3 0x170c +#define R128_FLUSH_4 0x1710 +#define R128_FLUSH_5 0x1714 +#define R128_FLUSH_6 0x1718 +#define R128_FLUSH_7 0x171c +#define R128_FOG_3D_TABLE_START 0x1810 +#define R128_FOG_3D_TABLE_END 0x1814 +#define R128_FOG_3D_TABLE_DENSITY 0x181c +#define R128_FOG_TABLE_INDEX 0x1a14 +#define R128_FOG_TABLE_DATA 0x1a18 +#define R128_FP_CRTC_H_TOTAL_DISP 0x0250 +#define R128_FP_CRTC_V_TOTAL_DISP 0x0254 +#define R128_FP_GEN_CNTL 0x0284 +# define R128_FP_FPON (1 << 0) +# define R128_FP_BLANK_DIS (1 << 1) +# define R128_FP_TDMS_EN (1 << 2) +# define R128_FP_DETECT_SENSE (1 << 8) +# define R128_FP_SEL_CRTC2 (1 << 13) +# define R128_FP_CRTC_DONT_SHADOW_VPAR (1 << 16) +# define R128_FP_CRTC_DONT_SHADOW_HEND (1 << 17) +# define R128_FP_CRTC_USE_SHADOW_VEND (1 << 18) +# define R128_FP_CRTC_USE_SHADOW_ROWCUR (1 << 19) +# define R128_FP_CRTC_HORZ_DIV2_EN (1 << 20) +# define R128_FP_CRTC_HOR_CRT_DIV2_DIS (1 << 21) +# define R128_FP_CRT_SYNC_SEL (1 << 23) +# define R128_FP_USE_SHADOW_EN (1 << 24) +#define R128_FP_H_SYNC_STRT_WID 0x02c4 +#define R128_FP_HORZ_STRETCH 0x028c +# define R128_HORZ_STRETCH_RATIO_MASK 0xffff +# define R128_HORZ_STRETCH_RATIO_SHIFT 0 +# define R128_HORZ_STRETCH_RATIO_MAX 4096 +# define R128_HORZ_PANEL_SIZE (0xff << 16) +# define R128_HORZ_PANEL_SHIFT 16 +# define R128_AUTO_HORZ_RATIO (0 << 24) +# define R128_HORZ_STRETCH_PIXREP (0 << 25) +# define R128_HORZ_STRETCH_BLEND (1 << 25) +# define R128_HORZ_STRETCH_ENABLE (1 << 26) +# define R128_HORZ_FP_LOOP_STRETCH (0x7 << 27) +# define R128_HORZ_STRETCH_RESERVED (1 << 30) +# define R128_HORZ_AUTO_RATIO_FIX_EN (1 << 31) + +#define R128_FP_PANEL_CNTL 0x0288 +# define R128_FP_DIGON (1 << 0) +# define R128_FP_BLON (1 << 1) +#define R128_FP_V_SYNC_STRT_WID 0x02c8 +#define R128_FP_VERT_STRETCH 0x0290 +# define R128_VERT_PANEL_SIZE (0x7ff << 0) +# define R128_VERT_PANEL_SHIFT 0 +# define R128_VERT_STRETCH_RATIO_MASK 0x3ff +# define R128_VERT_STRETCH_RATIO_SHIFT 11 +# define R128_VERT_STRETCH_RATIO_MAX 1024 +# define R128_VERT_STRETCH_ENABLE (1 << 24) +# define R128_VERT_STRETCH_LINEREP (0 << 25) +# define R128_VERT_STRETCH_BLEND (1 << 25) +# define R128_VERT_AUTO_RATIO_EN (1 << 26) +# define R128_VERT_STRETCH_RESERVED 0xf8e00000 + +#define R128_GEN_INT_CNTL 0x0040 +#define R128_GEN_INT_STATUS 0x0044 +# define R128_VSYNC_INT_AK (1 << 2) +# define R128_VSYNC_INT (1 << 2) +#define R128_GEN_RESET_CNTL 0x00f0 +# define R128_SOFT_RESET_GUI (1 << 0) +# define R128_SOFT_RESET_VCLK (1 << 8) +# define R128_SOFT_RESET_PCLK (1 << 9) +# define R128_SOFT_RESET_DISPENG_XCLK (1 << 11) +# define R128_SOFT_RESET_MEMCTLR_XCLK (1 << 12) +#define R128_GENENB 0x03c3 /* VGA */ +#define R128_GENFC_RD 0x03ca /* VGA */ +#define R128_GENFC_WT 0x03da /* VGA, 0x03ba */ +#define R128_GENMO_RD 0x03cc /* VGA */ +#define R128_GENMO_WT 0x03c2 /* VGA */ +#define R128_GENS0 0x03c2 /* VGA */ +#define R128_GENS1 0x03da /* VGA, 0x03ba */ +#define R128_GPIO_MONID 0x0068 +# define R128_GPIO_MONID_A_0 (1 << 0) +# define R128_GPIO_MONID_A_1 (1 << 1) +# define R128_GPIO_MONID_A_2 (1 << 2) +# define R128_GPIO_MONID_A_3 (1 << 3) +# define R128_GPIO_MONID_Y_0 (1 << 8) +# define R128_GPIO_MONID_Y_1 (1 << 9) +# define R128_GPIO_MONID_Y_2 (1 << 10) +# define R128_GPIO_MONID_Y_3 (1 << 11) +# define R128_GPIO_MONID_EN_0 (1 << 16) +# define R128_GPIO_MONID_EN_1 (1 << 17) +# define R128_GPIO_MONID_EN_2 (1 << 18) +# define R128_GPIO_MONID_EN_3 (1 << 19) +# define R128_GPIO_MONID_MASK_0 (1 << 24) +# define R128_GPIO_MONID_MASK_1 (1 << 25) +# define R128_GPIO_MONID_MASK_2 (1 << 26) +# define R128_GPIO_MONID_MASK_3 (1 << 27) +#define R128_GPIO_MONIDB 0x006c +#define R128_GRPH8_DATA 0x03cf /* VGA */ +#define R128_GRPH8_IDX 0x03ce /* VGA */ +#define R128_GUI_DEBUG0 0x16a0 +#define R128_GUI_DEBUG1 0x16a4 +#define R128_GUI_DEBUG2 0x16a8 +#define R128_GUI_DEBUG3 0x16ac +#define R128_GUI_DEBUG4 0x16b0 +#define R128_GUI_DEBUG5 0x16b4 +#define R128_GUI_DEBUG6 0x16b8 +#define R128_GUI_PROBE 0x16bc +#define R128_GUI_SCRATCH_REG0 0x15e0 +#define R128_GUI_SCRATCH_REG1 0x15e4 +#define R128_GUI_SCRATCH_REG2 0x15e8 +#define R128_GUI_SCRATCH_REG3 0x15ec +#define R128_GUI_SCRATCH_REG4 0x15f0 +#define R128_GUI_SCRATCH_REG5 0x15f4 +#define R128_GUI_STAT 0x1740 +# define R128_GUI_FIFOCNT_MASK 0x0fff +# define R128_GUI_ACTIVE (1 << 31) + +#define R128_HEADER 0x0f0e /* PCI */ +#define R128_HOST_DATA0 0x17c0 +#define R128_HOST_DATA1 0x17c4 +#define R128_HOST_DATA2 0x17c8 +#define R128_HOST_DATA3 0x17cc +#define R128_HOST_DATA4 0x17d0 +#define R128_HOST_DATA5 0x17d4 +#define R128_HOST_DATA6 0x17d8 +#define R128_HOST_DATA7 0x17dc +#define R128_HOST_DATA_LAST 0x17e0 +#define R128_HOST_PATH_CNTL 0x0130 +#define R128_HTOTAL_CNTL 0x0009 /* PLL */ +#define R128_HW_DEBUG 0x0128 +#define R128_HW_DEBUG2 0x011c + +#define R128_I2C_CNTL_1 0x0094 /* ? */ +#define R128_INTERRUPT_LINE 0x0f3c /* PCI */ +#define R128_INTERRUPT_PIN 0x0f3d /* PCI */ +#define R128_IO_BASE 0x0f14 /* PCI */ + +#define R128_LATENCY 0x0f0d /* PCI */ +#define R128_LEAD_BRES_DEC 0x1608 +#define R128_LEAD_BRES_ERR 0x1600 +#define R128_LEAD_BRES_INC 0x1604 +#define R128_LEAD_BRES_LNTH 0x161c +#define R128_LEAD_BRES_LNTH_SUB 0x1624 +#define R128_LVDS_GEN_CNTL 0x02d0 +# define R128_LVDS_ON (1 << 0) +# define R128_LVDS_DISPLAY_DIS (1 << 1) +# define R128_LVDS_EN (1 << 7) +# define R128_LVDS_DIGON (1 << 18) +# define R128_LVDS_BLON (1 << 19) +# define R128_LVDS_SEL_CRTC2 (1 << 23) +# define R128_HSYNC_DELAY_SHIFT 28 +# define R128_HSYNC_DELAY_MASK (0xf << 28) + +#define R128_MAX_LATENCY 0x0f3f /* PCI */ +#define R128_MCLK_CNTL 0x000f /* PLL */ +# define R128_FORCE_GCP (1 << 16) +# define R128_FORCE_PIPE3D_CP (1 << 17) +# define R128_FORCE_RCP (1 << 18) +#define R128_MDGPIO_A_REG 0x01ac +#define R128_MDGPIO_EN_REG 0x01b0 +#define R128_MDGPIO_MASK 0x0198 +#define R128_MDGPIO_Y_REG 0x01b4 +#define R128_MEM_ADDR_CONFIG 0x0148 +#define R128_MEM_BASE 0x0f10 /* PCI */ +#define R128_MEM_CNTL 0x0140 +#define R128_MEM_INIT_LAT_TIMER 0x0154 +#define R128_MEM_INTF_CNTL 0x014c +#define R128_MEM_SDRAM_MODE_REG 0x0158 +#define R128_MEM_STR_CNTL 0x0150 +#define R128_MEM_VGA_RP_SEL 0x003c +#define R128_MEM_VGA_WP_SEL 0x0038 +#define R128_MIN_GRANT 0x0f3e /* PCI */ +#define R128_MM_DATA 0x0004 +#define R128_MM_INDEX 0x0000 +#define R128_MPLL_CNTL 0x000e /* PLL */ +#define R128_MPP_TB_CONFIG 0x01c0 /* ? */ +#define R128_MPP_GP_CONFIG 0x01c8 /* ? */ + +#define R128_N_VIF_COUNT 0x0248 + +#define R128_OVR_CLR 0x0230 +#define R128_OVR_WID_LEFT_RIGHT 0x0234 +#define R128_OVR_WID_TOP_BOTTOM 0x0238 + +/* first overlay unit (there is only one) */ + +#define R128_OV0_Y_X_START 0x0400 +#define R128_OV0_Y_X_END 0x0404 +#define R128_OV0_EXCLUSIVE_HORZ 0x0408 +# define R128_EXCL_HORZ_START_MASK 0x000000ff +# define R128_EXCL_HORZ_END_MASK 0x0000ff00 +# define R128_EXCL_HORZ_BACK_PORCH_MASK 0x00ff0000 +# define R128_EXCL_HORZ_EXCLUSIVE_EN 0x80000000 +#define R128_OV0_EXCLUSIVE_VERT 0x040C +# define R128_EXCL_VERT_START_MASK 0x000003ff +# define R128_EXCL_VERT_END_MASK 0x03ff0000 +#define R128_OV0_REG_LOAD_CNTL 0x0410 +# define R128_REG_LD_CTL_LOCK 0x00000001L +# define R128_REG_LD_CTL_VBLANK_DURING_LOCK 0x00000002L +# define R128_REG_LD_CTL_STALL_GUI_UNTIL_FLIP 0x00000004L +# define R128_REG_LD_CTL_LOCK_READBACK 0x00000008L +#define R128_OV0_SCALE_CNTL 0x0420 +# define R128_SCALER_PIX_EXPAND 0x00000001L +# define R128_SCALER_Y2R_TEMP 0x00000002L +# define R128_SCALER_HORZ_PICK_NEAREST 0x00000003L +# define R128_SCALER_VERT_PICK_NEAREST 0x00000004L +# define R128_SCALER_SIGNED_UV 0x00000010L +# define R128_SCALER_GAMMA_SEL_MASK 0x00000060L +# define R128_SCALER_GAMMA_SEL_BRIGHT 0x00000000L +# define R128_SCALER_GAMMA_SEL_G22 0x00000020L +# define R128_SCALER_GAMMA_SEL_G18 0x00000040L +# define R128_SCALER_GAMMA_SEL_G14 0x00000060L +# define R128_SCALER_COMCORE_SHIFT_UP_ONE 0x00000080L +# define R128_SCALER_SURFAC_FORMAT 0x00000f00L +# define R128_SCALER_SOURCE_15BPP 0x00000300L +# define R128_SCALER_SOURCE_16BPP 0x00000400L +# define R128_SCALER_SOURCE_32BPP 0x00000600L +# define R128_SCALER_SOURCE_YUV9 0x00000900L +# define R128_SCALER_SOURCE_YUV12 0x00000A00L +# define R128_SCALER_SOURCE_VYUY422 0x00000B00L +# define R128_SCALER_SOURCE_YVYU422 0x00000C00L +# define R128_SCALER_SMART_SWITCH 0x00008000L +# define R128_SCALER_BURST_PER_PLANE 0x00ff0000L +# define R128_SCALER_DOUBLE_BUFFER 0x01000000L +# define R128_SCALER_DIS_LIMIT 0x08000000L +# define R128_SCALER_PRG_LOAD_START 0x10000000L +# define R128_SCALER_INT_EMU 0x20000000L +# define R128_SCALER_ENABLE 0x40000000L +# define R128_SCALER_SOFT_RESET 0x80000000L +#define R128_OV0_V_INC 0x0424 +#define R128_OV0_P1_V_ACCUM_INIT 0x0428 +# define R128_OV0_P1_MAX_LN_IN_PER_LN_OUT 0x00000003L +# define R128_OV0_P1_V_ACCUM_INIT_MASK 0x01ff8000L +#define R128_OV0_P23_V_ACCUM_INIT 0x042C +#define R128_OV0_P1_BLANK_LINES_AT_TOP 0x0430 +# define R128_P1_BLNK_LN_AT_TOP_M1_MASK 0x00000fffL +# define R128_P1_ACTIVE_LINES_M1 0x0fff0000L +#define R128_OV0_P23_BLANK_LINES_AT_TOP 0x0434 +# define R128_P23_BLNK_LN_AT_TOP_M1_MASK 0x000007ffL +# define R128_P23_ACTIVE_LINES_M1 0x07ff0000L +#define R128_OV0_VID_BUF0_BASE_ADRS 0x0440 +# define R128_VIF_BUF0_PITCH_SEL 0x00000001L +# define R128_VIF_BUF0_TILE_ADRS 0x00000002L +# define R128_VIF_BUF0_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF0_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF1_BASE_ADRS 0x0444 +# define R128_VIF_BUF1_PITCH_SEL 0x00000001L +# define R128_VIF_BUF1_TILE_ADRS 0x00000002L +# define R128_VIF_BUF1_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF1_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF2_BASE_ADRS 0x0448 +# define R128_VIF_BUF2_PITCH_SEL 0x00000001L +# define R128_VIF_BUF2_TILE_ADRS 0x00000002L +# define R128_VIF_BUF2_BASE_ADRS_MASK 0x03fffff0L +# define R128_VIF_BUF2_1ST_LINE_LSBS_MASK 0x48000000L +#define R128_OV0_VID_BUF3_BASE_ADRS 0x044C +#define R128_OV0_VID_BUF4_BASE_ADRS 0x0450 +#define R128_OV0_VID_BUF5_BASE_ADRS 0x0454 +#define R128_OV0_VID_BUF_PITCH0_VALUE 0x0460 +#define R128_OV0_VID_BUF_PITCH1_VALUE 0x0464 +#define R128_OV0_AUTO_FLIP_CNTL 0x0470 +#define R128_OV0_DEINTERLACE_PATTERN 0x0474 +#define R128_OV0_H_INC 0x0480 +#define R128_OV0_STEP_BY 0x0484 +#define R128_OV0_P1_H_ACCUM_INIT 0x0488 +#define R128_OV0_P23_H_ACCUM_INIT 0x048C +#define R128_OV0_P1_X_START_END 0x0494 +#define R128_OV0_P2_X_START_END 0x0498 +#define R128_OV0_P3_X_START_END 0x049C +#define R128_OV0_FILTER_CNTL 0x04A0 +#define R128_OV0_FOUR_TAP_COEF_0 0x04B0 +#define R128_OV0_FOUR_TAP_COEF_1 0x04B4 +#define R128_OV0_FOUR_TAP_COEF_2 0x04B8 +#define R128_OV0_FOUR_TAP_COEF_3 0x04BC +#define R128_OV0_FOUR_TAP_COEF_4 0x04C0 +#define R128_OV0_COLOUR_CNTL 0x04E0 +#define R128_OV0_VIDEO_KEY_CLR 0x04E4 +#define R128_OV0_VIDEO_KEY_MSK 0x04E8 +#define R128_OV0_GRAPHICS_KEY_CLR 0x04EC +#define R128_OV0_GRAPHICS_KEY_MSK 0x04F0 +#define R128_OV0_KEY_CNTL 0x04F4 +# define R128_VIDEO_KEY_FN_MASK 0x00000007L +# define R128_VIDEO_KEY_FN_FALSE 0x00000000L +# define R128_VIDEO_KEY_FN_TRUE 0x00000001L +# define R128_VIDEO_KEY_FN_EQ 0x00000004L +# define R128_VIDEO_KEY_FN_NE 0x00000005L +# define R128_GRAPHIC_KEY_FN_MASK 0x00000070L +# define R128_GRAPHIC_KEY_FN_FALSE 0x00000000L +# define R128_GRAPHIC_KEY_FN_TRUE 0x00000010L +# define R128_GRAPHIC_KEY_FN_EQ 0x00000040L +# define R128_GRAPHIC_KEY_FN_NE 0x00000050L +# define R128_CMP_MIX_MASK 0x00000100L +# define R128_CMP_MIX_OR 0x00000000L +# define R128_CMP_MIX_AND 0x00000100L +#define R128_OV0_TEST 0x04F8 + + +#define R128_PALETTE_DATA 0x00b4 +#define R128_PALETTE_INDEX 0x00b0 +#define R128_PC_DEBUG_MODE 0x1760 +#define R128_PC_GUI_CTLSTAT 0x1748 +#define R128_PC_GUI_MODE 0x1744 +# define R128_PC_IGNORE_UNIFY (1 << 5) +#define R128_PC_MISC_CNTL 0x0188 +#define R128_PC_NGUI_CTLSTAT 0x0184 +# define R128_PC_FLUSH_GUI (3 << 0) +# define R128_PC_RI_GUI (1 << 2) +# define R128_PC_FLUSH_ALL 0x00ff +# define R128_PC_BUSY (1 << 31) +#define R128_PC_NGUI_MODE 0x0180 +#define R128_PCI_GART_PAGE 0x017c +#define R128_PLANE_3D_MASK_C 0x1d44 +#define R128_PLL_TEST_CNTL 0x0013 /* PLL */ +#define R128_PMI_CAP_ID 0x0f5c /* PCI */ +#define R128_PMI_DATA 0x0f63 /* PCI */ +#define R128_PMI_NXT_CAP_PTR 0x0f5d /* PCI */ +#define R128_PMI_PMC_REG 0x0f5e /* PCI */ +#define R128_PMI_PMCSR_REG 0x0f60 /* PCI */ +#define R128_PMI_REGISTER 0x0f5c /* PCI */ +#define R128_PPLL_CNTL 0x0002 /* PLL */ +# define R128_PPLL_RESET (1 << 0) +# define R128_PPLL_SLEEP (1 << 1) +# define R128_PPLL_ATOMIC_UPDATE_EN (1 << 16) +# define R128_PPLL_VGA_ATOMIC_UPDATE_EN (1 << 17) +#define R128_PPLL_DIV_0 0x0004 /* PLL */ +#define R128_PPLL_DIV_1 0x0005 /* PLL */ +#define R128_PPLL_DIV_2 0x0006 /* PLL */ +#define R128_PPLL_DIV_3 0x0007 /* PLL */ +# define R128_PPLL_FB3_DIV_MASK 0x07ff +# define R128_PPLL_POST3_DIV_MASK 0x00070000 +#define R128_PPLL_REF_DIV 0x0003 /* PLL */ +# define R128_PPLL_REF_DIV_MASK 0x03ff +# define R128_PPLL_ATOMIC_UPDATE_R (1 << 15) /* same as _W */ +# define R128_PPLL_ATOMIC_UPDATE_W (1 << 15) /* same as _R */ +#define R128_PWR_MNGMT_CNTL_STATUS 0x0f60 /* PCI */ +#define R128_REG_BASE 0x0f18 /* PCI */ +#define R128_REGPROG_INF 0x0f09 /* PCI */ +#define R128_REVISION_ID 0x0f08 /* PCI */ + +#define R128_SC_BOTTOM 0x164c +#define R128_SC_BOTTOM_RIGHT 0x16f0 +#define R128_SC_BOTTOM_RIGHT_C 0x1c8c +#define R128_SC_LEFT 0x1640 +#define R128_SC_RIGHT 0x1644 +#define R128_SC_TOP 0x1648 +#define R128_SC_TOP_LEFT 0x16ec +#define R128_SC_TOP_LEFT_C 0x1c88 +#define R128_SEQ8_DATA 0x03c5 /* VGA */ +#define R128_SEQ8_IDX 0x03c4 /* VGA */ +#define R128_SNAPSHOT_F_COUNT 0x0244 +#define R128_SNAPSHOT_VH_COUNTS 0x0240 +#define R128_SNAPSHOT_VIF_COUNT 0x024c +#define R128_SRC_OFFSET 0x15ac +#define R128_SRC_PITCH 0x15b0 +#define R128_SRC_PITCH_OFFSET 0x1428 +#define R128_SRC_SC_BOTTOM 0x165c +#define R128_SRC_SC_BOTTOM_RIGHT 0x16f4 +#define R128_SRC_SC_RIGHT 0x1654 +#define R128_SRC_X 0x1414 +#define R128_SRC_X_Y 0x1590 +#define R128_SRC_Y 0x1418 +#define R128_SRC_Y_X 0x1434 +#define R128_STATUS 0x0f06 /* PCI */ +#define R128_SUBPIC_CNTL 0x0540 /* ? */ +#define R128_SUB_CLASS 0x0f0a /* PCI */ +#define R128_SURFACE_DELAY 0x0b00 +#define R128_SURFACE0_INFO 0x0b0c +#define R128_SURFACE0_LOWER_BOUND 0x0b04 +#define R128_SURFACE0_UPPER_BOUND 0x0b08 +#define R128_SURFACE1_INFO 0x0b1c +#define R128_SURFACE1_LOWER_BOUND 0x0b14 +#define R128_SURFACE1_UPPER_BOUND 0x0b18 +#define R128_SURFACE2_INFO 0x0b2c +#define R128_SURFACE2_LOWER_BOUND 0x0b24 +#define R128_SURFACE2_UPPER_BOUND 0x0b28 +#define R128_SURFACE3_INFO 0x0b3c +#define R128_SURFACE3_LOWER_BOUND 0x0b34 +#define R128_SURFACE3_UPPER_BOUND 0x0b38 +#define R128_SW_SEMAPHORE 0x013c + +#define R128_TEST_DEBUG_CNTL 0x0120 +#define R128_TEST_DEBUG_MUX 0x0124 +#define R128_TEST_DEBUG_OUT 0x012c +#define R128_TMDS_CRC 0x02a0 +#define R128_TMDS_TRANSMITTER_CNTL 0x02a4 +# define R128_TMDS_PLLEN (1 << 0) +# define R128_TMDS_PLLRST (1 << 1) +#define R128_TRAIL_BRES_DEC 0x1614 +#define R128_TRAIL_BRES_ERR 0x160c +#define R128_TRAIL_BRES_INC 0x1610 +#define R128_TRAIL_X 0x1618 +#define R128_TRAIL_X_SUB 0x1620 + +#define R128_VCLK_ECP_CNTL 0x0008 /* PLL */ +#define R128_VENDOR_ID 0x0f00 /* PCI */ +#define R128_VGA_DDA_CONFIG 0x02e8 +#define R128_VGA_DDA_ON_OFF 0x02ec +#define R128_VID_BUFFER_CONTROL 0x0900 +#define R128_VIDEOMUX_CNTL 0x0190 +#define R128_VIPH_CONTROL 0x01D0 /* ? */ + +#define R128_WAIT_UNTIL 0x1720 + +#define R128_X_MPLL_REF_FB_DIV 0x000a /* PLL */ +#define R128_XCLK_CNTL 0x000d /* PLL */ +#define R128_XDLL_CNTL 0x000c /* PLL */ +#define R128_XPLL_CNTL 0x000b /* PLL */ + + /* Registers for CCE and Microcode Engine */ +#define R128_PM4_MICROCODE_ADDR 0x07d4 +#define R128_PM4_MICROCODE_RADDR 0x07d8 +#define R128_PM4_MICROCODE_DATAH 0x07dc +#define R128_PM4_MICROCODE_DATAL 0x07e0 + +#define R128_PM4_BUFFER_OFFSET 0x0700 +#define R128_PM4_BUFFER_CNTL 0x0704 +# define R128_PM4_NONPM4 (0 << 28) +# define R128_PM4_192PIO (1 << 28) +# define R128_PM4_192BM (2 << 28) +# define R128_PM4_128PIO_64INDBM (3 << 28) +# define R128_PM4_128BM_64INDBM (4 << 28) +# define R128_PM4_64PIO_128INDBM (5 << 28) +# define R128_PM4_64BM_128INDBM (6 << 28) +# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28) +# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28) +# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28) +#define R128_PM4_BUFFER_WM_CNTL 0x0708 +# define R128_WMA_SHIFT 0 +# define R128_WMB_SHIFT 8 +# define R128_WMC_SHIFT 16 +# define R128_WB_WM_SHIFT 24 +#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c +#define R128_PM4_BUFFER_DL_RPTR 0x0710 +#define R128_PM4_BUFFER_DL_WPTR 0x0714 +# define R128_PM4_BUFFER_DL_DONE (1 << 31) +#define R128_PM4_BUFFER_DL_WPTR_DELAY 0x0718 +# define R128_PRE_WRITE_TIMER_SHIFT 0 +# define R128_PRE_WRITE_LIMIT_SHIFT 23 +#define R128_PM4_VC_FPU_SETUP 0x071c +# define R128_FRONT_DIR_CW (0 << 0) +# define R128_FRONT_DIR_CCW (1 << 0) +# define R128_FRONT_DIR_MASK (1 << 0) +# define R128_BACKFACE_CULL (0 << 1) +# define R128_BACKFACE_POINTS (1 << 1) +# define R128_BACKFACE_LINES (2 << 1) +# define R128_BACKFACE_SOLID (3 << 1) +# define R128_BACKFACE_MASK (3 << 1) +# define R128_FRONTFACE_CULL (0 << 3) +# define R128_FRONTFACE_POINTS (1 << 3) +# define R128_FRONTFACE_LINES (2 << 3) +# define R128_FRONTFACE_SOLID (3 << 3) +# define R128_FRONTFACE_MASK (3 << 3) +# define R128_FPU_COLOR_SOLID (0 << 5) +# define R128_FPU_COLOR_FLAT (1 << 5) +# define R128_FPU_COLOR_GOURAUD (2 << 5) +# define R128_FPU_COLOR_GOURAUD2 (3 << 5) +# define R128_FPU_COLOR_MASK (3 << 5) +# define R128_FPU_SUB_PIX_2BITS (0 << 7) +# define R128_FPU_SUB_PIX_4BITS (1 << 7) +# define R128_FPU_MODE_2D (0 << 8) +# define R128_FPU_MODE_3D (1 << 8) +# define R128_TRAP_BITS_DISABLE (1 << 9) +# define R128_EDGE_ANTIALIAS (1 << 10) +# define R128_SUPERSAMPLE (1 << 11) +# define R128_XFACTOR_2 (0 << 12) +# define R128_XFACTOR_4 (1 << 12) +# define R128_YFACTOR_2 (0 << 13) +# define R128_YFACTOR_4 (1 << 13) +# define R128_FLAT_SHADE_VERTEX_D3D (0 << 14) +# define R128_FLAT_SHADE_VERTEX_OGL (1 << 14) +# define R128_FPU_ROUND_TRUNCATE (0 << 15) +# define R128_FPU_ROUND_NEAREST (1 << 15) +# define R128_WM_SEL_8DW (0 << 16) +# define R128_WM_SEL_16DW (1 << 16) +# define R128_WM_SEL_32DW (2 << 16) +#define R128_PM4_VC_DEBUG_CONFIG 0x07a4 +#define R128_PM4_VC_STAT 0x07a8 +#define R128_PM4_VC_TIMESTAMP0 0x07b0 +#define R128_PM4_VC_TIMESTAMP1 0x07b4 +#define R128_PM4_STAT 0x07b8 +# define R128_PM4_FIFOCNT_MASK 0x0fff +# define R128_PM4_BUSY (1 << 16) +# define R128_PM4_GUI_ACTIVE (1 << 31) +#define R128_PM4_BUFFER_ADDR 0x07f0 +#define R128_PM4_MICRO_CNTL 0x07fc +# define R128_PM4_MICRO_FREERUN (1 << 30) +#define R128_PM4_FIFO_DATA_EVEN 0x1000 +#define R128_PM4_FIFO_DATA_ODD 0x1004 + +#define R128_SCALE_3D_CNTL 0x1a00 +# define R128_SCALE_DITHER_ERR_DIFF (0 << 1) +# define R128_SCALE_DITHER_TABLE (1 << 1) +# define R128_TEX_CACHE_SIZE_FULL (0 << 2) +# define R128_TEX_CACHE_SIZE_HALF (1 << 2) +# define R128_DITHER_INIT_CURR (0 << 3) +# define R128_DITHER_INIT_RESET (1 << 3) +# define R128_ROUND_24BIT (1 << 4) +# define R128_TEX_CACHE_DISABLE (1 << 5) +# define R128_SCALE_3D_NOOP (0 << 6) +# define R128_SCALE_3D_SCALE (1 << 6) +# define R128_SCALE_3D_TEXMAP_SHADE (2 << 6) +# define R128_SCALE_PIX_BLEND (0 << 8) +# define R128_SCALE_PIX_REPLICATE (1 << 8) +# define R128_TEX_CACHE_SPLIT (1 << 9) +# define R128_APPLE_YUV_MODE (1 << 10) +# define R128_TEX_CACHE_PALLETE_MODE (1 << 11) +# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define R128_ALPHA_COMB_ADD_NCLAMP (1 << 12) +# define R128_ALPHA_COMB_SUB_DST_SRC_CLAMP (2 << 12) +# define R128_ALPHA_COMB_SUB_DST_SRC_NCLAMP (3 << 12) +# define R128_FOG_TABLE (1 << 14) +# define R128_SIGNED_DST_CLAMP (1 << 15) +# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define R128_ALPHA_BLEND_SRC_ONE (1 << 16) +# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define R128_ALPHA_BLEND_SRC_DSTALPHA (6 << 16) +# define R128_ALPHA_BLEND_SRC_INVDSTALPHA (7 << 16) +# define R128_ALPHA_BLEND_SRC_DSTCOLOR (8 << 16) +# define R128_ALPHA_BLEND_SRC_INVDSTCOLOR (9 << 16) +# define R128_ALPHA_BLEND_SRC_SAT (10 << 16) +# define R128_ALPHA_BLEND_SRC_BLEND (11 << 16) +# define R128_ALPHA_BLEND_SRC_INVBLEND (12 << 16) +# define R128_ALPHA_BLEND_DST_ZERO (0 << 20) +# define R128_ALPHA_BLEND_DST_ONE (1 << 20) +# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define R128_ALPHA_BLEND_DST_DSTALPHA (6 << 20) +# define R128_ALPHA_BLEND_DST_INVDSTALPHA (7 << 20) +# define R128_ALPHA_BLEND_DST_DSTCOLOR (8 << 20) +# define R128_ALPHA_BLEND_DST_INVDSTCOLOR (9 << 20) +# define R128_ALPHA_TEST_NEVER (0 << 24) +# define R128_ALPHA_TEST_LESS (1 << 24) +# define R128_ALPHA_TEST_LESSEQUAL (2 << 24) +# define R128_ALPHA_TEST_EQUAL (3 << 24) +# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define R128_ALPHA_TEST_GREATER (5 << 24) +# define R128_ALPHA_TEST_NEQUAL (6 << 24) +# define R128_ALPHA_TEST_ALWAYS (7 << 24) +# define R128_COMPOSITE_SHADOW_CMP_EQUAL (0 << 28) +# define R128_COMPOSITE_SHADOW_CMP_NEQUAL (1 << 28) +# define R128_COMPOSITE_SHADOW (1 << 29) +# define R128_TEX_MAP_ALPHA_IN_TEXTURE (1 << 30) +# define R128_TEX_CACHE_LINE_SIZE_8QW (0 << 31) +# define R128_TEX_CACHE_LINE_SIZE_4QW (1 << 31) +#define R128_SCALE_3D_DATATYPE 0x1a20 + +#define R128_SETUP_CNTL 0x1bc4 +# define R128_DONT_START_TRIANGLE (1 << 0) +# define R128_Z_BIAS (0 << 1) +# define R128_DONT_START_ANY_ON (1 << 2) +# define R128_COLOR_SOLID_COLOR (0 << 3) +# define R128_COLOR_FLAT_VERT_1 (1 << 3) +# define R128_COLOR_FLAT_VERT_2 (2 << 3) +# define R128_COLOR_FLAT_VERT_3 (3 << 3) +# define R128_COLOR_GOURAUD (4 << 3) +# define R128_PRIM_TYPE_TRI (0 << 7) +# define R128_PRIM_TYPE_LINE (1 << 7) +# define R128_PRIM_TYPE_POINT (2 << 7) +# define R128_PRIM_TYPE_POLY_EDGE (3 << 7) +# define R128_TEXTURE_ST_MULT_W (0 << 9) +# define R128_TEXTURE_ST_DIRECT (1 << 9) +# define R128_STARTING_VERTEX_1 (1 << 14) +# define R128_STARTING_VERTEX_2 (2 << 14) +# define R128_STARTING_VERTEX_3 (3 << 14) +# define R128_ENDING_VERTEX_1 (1 << 16) +# define R128_ENDING_VERTEX_2 (2 << 16) +# define R128_ENDING_VERTEX_3 (3 << 16) +# define R128_SU_POLY_LINE_LAST (0 << 18) +# define R128_SU_POLY_LINE_NOT_LAST (1 << 18) +# define R128_SUB_PIX_2BITS (0 << 19) +# define R128_SUB_PIX_4BITS (1 << 19) +# define R128_SET_UP_CONTINUE (1 << 31) + +#define R128_WINDOW_XY_OFFSET 0x1bcc +# define R128_WINDOW_Y_SHIFT 4 +# define R128_WINDOW_X_SHIFT 20 + +#define R128_Z_OFFSET_C 0x1c90 +#define R128_Z_PITCH_C 0x1c94 +# define R128_Z_TILE (1 << 16) +#define R128_Z_STEN_CNTL_C 0x1c98 +# define R128_Z_PIX_WIDTH_16 (0 << 1) +# define R128_Z_PIX_WIDTH_24 (1 << 1) +# define R128_Z_PIX_WIDTH_32 (2 << 1) +# define R128_Z_PIX_WIDTH_MASK (3 << 1) +# define R128_Z_TEST_NEVER (0 << 4) +# define R128_Z_TEST_LESS (1 << 4) +# define R128_Z_TEST_LESSEQUAL (2 << 4) +# define R128_Z_TEST_EQUAL (3 << 4) +# define R128_Z_TEST_GREATEREQUAL (4 << 4) +# define R128_Z_TEST_GREATER (5 << 4) +# define R128_Z_TEST_NEQUAL (6 << 4) +# define R128_Z_TEST_ALWAYS (7 << 4) +# define R128_Z_TEST_MASK (7 << 4) +# define R128_STENCIL_TEST_NEVER (0 << 12) +# define R128_STENCIL_TEST_LESS (1 << 12) +# define R128_STENCIL_TEST_LESSEQUAL (2 << 12) +# define R128_STENCIL_TEST_EQUAL (3 << 12) +# define R128_STENCIL_TEST_GREATEREQUAL (4 << 12) +# define R128_STENCIL_TEST_GREATER (5 << 12) +# define R128_STENCIL_TEST_NEQUAL (6 << 12) +# define R128_STENCIL_TEST_ALWAYS (7 << 12) +# define R128_STENCIL_S_FAIL_KEEP (0 << 16) +# define R128_STENCIL_S_FAIL_ZERO (1 << 16) +# define R128_STENCIL_S_FAIL_REPLACE (2 << 16) +# define R128_STENCIL_S_FAIL_INC (3 << 16) +# define R128_STENCIL_S_FAIL_DEC (4 << 16) +# define R128_STENCIL_S_FAIL_INV (5 << 16) +# define R128_STENCIL_ZPASS_KEEP (0 << 20) +# define R128_STENCIL_ZPASS_ZERO (1 << 20) +# define R128_STENCIL_ZPASS_REPLACE (2 << 20) +# define R128_STENCIL_ZPASS_INC (3 << 20) +# define R128_STENCIL_ZPASS_DEC (4 << 20) +# define R128_STENCIL_ZPASS_INV (5 << 20) +# define R128_STENCIL_ZFAIL_KEEP (0 << 24) +# define R128_STENCIL_ZFAIL_ZERO (1 << 24) +# define R128_STENCIL_ZFAIL_REPLACE (2 << 24) +# define R128_STENCIL_ZFAIL_INC (3 << 24) +# define R128_STENCIL_ZFAIL_DEC (4 << 24) +# define R128_STENCIL_ZFAIL_INV (5 << 24) +#define R128_TEX_CNTL_C 0x1c9c +# define R128_Z_ENABLE (1 << 0) +# define R128_Z_WRITE_ENABLE (1 << 1) +# define R128_STENCIL_ENABLE (1 << 3) +# define R128_SHADE_ENABLE (0 << 4) +# define R128_TEXMAP_ENABLE (1 << 4) +# define R128_SEC_TEXMAP_ENABLE (1 << 5) +# define R128_FOG_ENABLE (1 << 7) +# define R128_DITHER_ENABLE (1 << 8) +# define R128_ALPHA_ENABLE (1 << 9) +# define R128_ALPHA_TEST_ENABLE (1 << 10) +# define R128_SPEC_LIGHT_ENABLE (1 << 11) +# define R128_TEX_CHROMA_KEY_ENABLE (1 << 12) +# define R128_ALPHA_IN_TEX_COMPLETE_A (0 << 13) +# define R128_ALPHA_IN_TEX_LSB_A (1 << 13) +# define R128_LIGHT_DIS (0 << 14) +# define R128_LIGHT_COPY (1 << 14) +# define R128_LIGHT_MODULATE (2 << 14) +# define R128_LIGHT_ADD (3 << 14) +# define R128_LIGHT_BLEND_CONSTANT (4 << 14) +# define R128_LIGHT_BLEND_TEXTURE (5 << 14) +# define R128_LIGHT_BLEND_VERTEX (6 << 14) +# define R128_LIGHT_BLEND_CONST_COLOR (7 << 14) +# define R128_ALPHA_LIGHT_DIS (0 << 18) +# define R128_ALPHA_LIGHT_COPY (1 << 18) +# define R128_ALPHA_LIGHT_MODULATE (2 << 18) +# define R128_ALPHA_LIGHT_ADD (3 << 18) +# define R128_ANTI_ALIAS (1 << 21) +# define R128_TEX_CACHE_FLUSH (1 << 23) +# define R128_LOD_BIAS_SHIFT 24 +# define R128_LOD_BIAS_MASK (0xff << 24) +#define R128_MISC_3D_STATE_CNTL_REG 0x1ca0 +# define R128_REF_ALPHA_MASK 0xff +# define R128_MISC_SCALE_3D_NOOP (0 << 8) +# define R128_MISC_SCALE_3D_SCALE (1 << 8) +# define R128_MISC_SCALE_3D_TEXMAP_SHADE (2 << 8) +# define R128_MISC_SCALE_PIX_BLEND (0 << 10) +# define R128_MISC_SCALE_PIX_REPLICATE (1 << 10) +# define R128_ALPHA_COMB_ADD_CLAMP (0 << 12) +# define R128_ALPHA_COMB_ADD_NO_CLAMP (1 << 12) +# define R128_ALPHA_COMB_SUB_SRC_DST_CLAMP (2 << 12) +# define R128_ALPHA_COMB_SUB_SRC_DST_NO_CLAMP (3 << 12) +# define R128_FOG_VERTEX (0 << 14) +# define R128_FOG_TABLE (1 << 14) +# define R128_ALPHA_BLEND_SRC_ZERO (0 << 16) +# define R128_ALPHA_BLEND_SRC_ONE (1 << 16) +# define R128_ALPHA_BLEND_SRC_SRCCOLOR (2 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCCOLOR (3 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHA (4 << 16) +# define R128_ALPHA_BLEND_SRC_INVSRCALPHA (5 << 16) +# define R128_ALPHA_BLEND_SRC_DESTALPHA (6 << 16) +# define R128_ALPHA_BLEND_SRC_INVDESTALPHA (7 << 16) +# define R128_ALPHA_BLEND_SRC_DESTCOLOR (8 << 16) +# define R128_ALPHA_BLEND_SRC_INVDESTCOLOR (9 << 16) +# define R128_ALPHA_BLEND_SRC_SRCALPHASAT (10 << 16) +# define R128_ALPHA_BLEND_SRC_BOTHSRCALPHA (11 << 16) +# define R128_ALPHA_BLEND_SRC_BOTHINVSRCALPHA (12 << 16) +# define R128_ALPHA_BLEND_SRC_MASK (15 << 16) +# define R128_ALPHA_BLEND_DST_ZERO (0 << 20) +# define R128_ALPHA_BLEND_DST_ONE (1 << 20) +# define R128_ALPHA_BLEND_DST_SRCCOLOR (2 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCCOLOR (3 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHA (4 << 20) +# define R128_ALPHA_BLEND_DST_INVSRCALPHA (5 << 20) +# define R128_ALPHA_BLEND_DST_DESTALPHA (6 << 20) +# define R128_ALPHA_BLEND_DST_INVDESTALPHA (7 << 20) +# define R128_ALPHA_BLEND_DST_DESTCOLOR (8 << 20) +# define R128_ALPHA_BLEND_DST_INVDESTCOLOR (9 << 20) +# define R128_ALPHA_BLEND_DST_SRCALPHASAT (10 << 20) +# define R128_ALPHA_BLEND_DST_MASK (15 << 20) +# define R128_ALPHA_TEST_NEVER (0 << 24) +# define R128_ALPHA_TEST_LESS (1 << 24) +# define R128_ALPHA_TEST_LESSEQUAL (2 << 24) +# define R128_ALPHA_TEST_EQUAL (3 << 24) +# define R128_ALPHA_TEST_GREATEREQUAL (4 << 24) +# define R128_ALPHA_TEST_GREATER (5 << 24) +# define R128_ALPHA_TEST_NEQUAL (6 << 24) +# define R128_ALPHA_TEST_ALWAYS (7 << 24) +# define R128_ALPHA_TEST_MASK (7 << 24) +#define R128_TEXTURE_CLR_CMP_CLR_C 0x1ca4 +#define R128_TEXTURE_CLR_CMP_MSK_C 0x1ca8 +#define R128_FOG_COLOR_C 0x1cac +# define R128_FOG_BLUE_SHIFT 0 +# define R128_FOG_GREEN_SHIFT 8 +# define R128_FOG_RED_SHIFT 16 +#define R128_PRIM_TEX_CNTL_C 0x1cb0 +# define R128_MIN_BLEND_NEAREST (0 << 1) +# define R128_MIN_BLEND_LINEAR (1 << 1) +# define R128_MIN_BLEND_MIPNEAREST (2 << 1) +# define R128_MIN_BLEND_MIPLINEAR (3 << 1) +# define R128_MIN_BLEND_LINEARMIPNEAREST (4 << 1) +# define R128_MIN_BLEND_LINEARMIPLINEAR (5 << 1) +# define R128_MIN_BLEND_MASK (7 << 1) +# define R128_MAG_BLEND_NEAREST (0 << 4) +# define R128_MAG_BLEND_LINEAR (1 << 4) +# define R128_MAG_BLEND_MASK (7 << 4) +# define R128_MIP_MAP_DISABLE (1 << 7) +# define R128_TEX_CLAMP_S_WRAP (0 << 8) +# define R128_TEX_CLAMP_S_MIRROR (1 << 8) +# define R128_TEX_CLAMP_S_CLAMP (2 << 8) +# define R128_TEX_CLAMP_S_BORDER_COLOR (3 << 8) +# define R128_TEX_CLAMP_S_MASK (3 << 8) +# define R128_TEX_WRAP_S (1 << 10) +# define R128_TEX_CLAMP_T_WRAP (0 << 11) +# define R128_TEX_CLAMP_T_MIRROR (1 << 11) +# define R128_TEX_CLAMP_T_CLAMP (2 << 11) +# define R128_TEX_CLAMP_T_BORDER_COLOR (3 << 11) +# define R128_TEX_CLAMP_T_MASK (3 << 11) +# define R128_TEX_WRAP_T (1 << 13) +# define R128_TEX_PERSPECTIVE_DISABLE (1 << 14) +# define R128_DATATYPE_VQ (0 << 16) +# define R128_DATATYPE_CI4 (1 << 16) +# define R128_DATATYPE_CI8 (2 << 16) +# define R128_DATATYPE_ARGB1555 (3 << 16) +# define R128_DATATYPE_RGB565 (4 << 16) +# define R128_DATATYPE_RGB888 (5 << 16) +# define R128_DATATYPE_ARGB8888 (6 << 16) +# define R128_DATATYPE_RGB332 (7 << 16) +# define R128_DATATYPE_Y8 (8 << 16) +# define R128_DATATYPE_RGB8 (9 << 16) +# define R128_DATATYPE_CI16 (10 << 16) +# define R128_DATATYPE_YVYU422 (11 << 16) +# define R128_DATATYPE_VYUY422 (12 << 16) +# define R128_DATATYPE_AYUV444 (14 << 16) +# define R128_DATATYPE_ARGB4444 (15 << 16) +# define R128_PALLETE_EITHER (0 << 20) +# define R128_PALLETE_1 (1 << 20) +# define R128_PALLETE_2 (2 << 20) +# define R128_PSEUDOCOLOR_DT_RGB565 (0 << 24) +# 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_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 +# define R128_TEX_HEIGHT_SHIFT 8 +# define R128_TEX_MIN_SIZE_SHIFT 12 +# define R128_SEC_TEX_PITCH_SHIFT 16 +# define R128_SEC_TEX_SIZE_SHIFT 20 +# define R128_SEC_TEX_HEIGHT_SHIFT 24 +# define R128_SEC_TEX_MIN_SIZE_SHIFT 28 +# define R128_TEX_PITCH_MASK (0x0f << 0) +# define R128_TEX_SIZE_MASK (0x0f << 4) +# define R128_TEX_HEIGHT_MASK (0x0f << 8) +# define R128_TEX_MIN_SIZE_MASK (0x0f << 12) +# define R128_SEC_TEX_PITCH_MASK (0x0f << 16) +# define R128_SEC_TEX_SIZE_MASK (0x0f << 20) +# define R128_SEC_TEX_HEIGHT_MASK (0x0f << 24) +# define R128_SEC_TEX_MIN_SIZE_MASK (0x0f << 28) +# define R128_TEX_SIZE_PITCH_SHIFT 0 +# define R128_SEC_TEX_SIZE_PITCH_SHIFT 16 +# define R128_TEX_SIZE_PITCH_MASK (0xffff << 0) +# define R128_SEC_TEX_SIZE_PITCH_MASK (0xffff << 16) +#define R128_PRIM_TEX_0_OFFSET_C 0x1cbc +#define R128_PRIM_TEX_1_OFFSET_C 0x1cc0 +#define R128_PRIM_TEX_2_OFFSET_C 0x1cc4 +#define R128_PRIM_TEX_3_OFFSET_C 0x1cc8 +#define R128_PRIM_TEX_4_OFFSET_C 0x1ccc +#define R128_PRIM_TEX_5_OFFSET_C 0x1cd0 +#define R128_PRIM_TEX_6_OFFSET_C 0x1cd4 +#define R128_PRIM_TEX_7_OFFSET_C 0x1cd8 +#define R128_PRIM_TEX_8_OFFSET_C 0x1cdc +#define R128_PRIM_TEX_9_OFFSET_C 0x1ce0 +#define R128_PRIM_TEX_10_OFFSET_C 0x1ce4 +# define R128_TEX_NO_TILE (0 << 30) +# define R128_TEX_TILED_BY_HOST (1 << 30) +# define R128_TEX_TILED_BY_STORAGE (2 << 30) +# define R128_TEX_TILED_BY_STORAGE2 (3 << 30) + +#define R128_SEC_TEX_CNTL_C 0x1d00 +# define R128_SEC_SELECT_PRIM_ST (0 << 0) +# define R128_SEC_SELECT_SEC_ST (1 << 0) +#define R128_SEC_TEX_COMBINE_CNTL_C 0x1d04 +# define R128_INPUT_FACTOR_PREV_COLOR (8 << 10) +# define R128_INPUT_FACTOR_PREV_ALPHA (9 << 10) +# define R128_INP_FACTOR_A_PREV_ALPHA (4 << 25) +#define R128_SEC_TEX_0_OFFSET_C 0x1d08 +#define R128_SEC_TEX_1_OFFSET_C 0x1d0c +#define R128_SEC_TEX_2_OFFSET_C 0x1d10 +#define R128_SEC_TEX_3_OFFSET_C 0x1d14 +#define R128_SEC_TEX_4_OFFSET_C 0x1d18 +#define R128_SEC_TEX_5_OFFSET_C 0x1d1c +#define R128_SEC_TEX_6_OFFSET_C 0x1d20 +#define R128_SEC_TEX_7_OFFSET_C 0x1d24 +#define R128_SEC_TEX_8_OFFSET_C 0x1d28 +#define R128_SEC_TEX_9_OFFSET_C 0x1d2c +#define R128_SEC_TEX_10_OFFSET_C 0x1d30 +#define R128_CONSTANT_COLOR_C 0x1d34 +# define R128_CONSTANT_BLUE_SHIFT 0 +# define R128_CONSTANT_GREEN_SHIFT 8 +# define R128_CONSTANT_RED_SHIFT 16 +# define R128_CONSTANT_ALPHA_SHIFT 24 +#define R128_PRIM_TEXTURE_BORDER_COLOR_C 0x1d38 +# define R128_PRIM_TEX_BORDER_BLUE_SHIFT 0 +# define R128_PRIM_TEX_BORDER_GREEN_SHIFT 8 +# define R128_PRIM_TEX_BORDER_RED_SHIFT 16 +# define R128_PRIM_TEX_BORDER_ALPHA_SHIFT 24 +#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c +# define R128_SEC_TEX_BORDER_BLUE_SHIFT 0 +# define R128_SEC_TEX_BORDER_GREEN_SHIFT 8 +# define R128_SEC_TEX_BORDER_RED_SHIFT 16 +# define R128_SEC_TEX_BORDER_ALPHA_SHIFT 24 +#define R128_STEN_REF_MASK_C 0x1d40 +# define R128_STEN_REFERENCE_SHIFT 0 +# define R128_STEN_MASK_SHIFT 16 +# define R128_STEN_WRITE_MASK_SHIFT 24 +#define R128_PLANE_3D_MASK_C 0x1d44 +#define R128_TEX_CACHE_STAT_COUNT 0x1974 + + + /* Constants */ +#define R128_AGP_TEX_OFFSET 0x02000000 + +#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0 + + /* CCE packet types */ +#define R128_CCE_PACKET0 0x00000000 +#define R128_CCE_PACKET0_ONE_REG_WR 0x00008000 +#define R128_CCE_PACKET1 0x40000000 +#define R128_CCE_PACKET2 0x80000000 +#define R128_CCE_PACKET3 0xC0000000 +#define R128_CCE_PACKET3_NOP 0xC0001000 +#define R128_CCE_PACKET3_PAINT 0xC0001100 +#define R128_CCE_PACKET3_BITBLT 0xC0001200 +#define R128_CCE_PACKET3_SMALLTEXT 0xC0001300 +#define R128_CCE_PACKET3_HOSTDATA_BLT 0xC0001400 +#define R128_CCE_PACKET3_POLYLINE 0xC0001500 +#define R128_CCE_PACKET3_SCALING 0xC0001600 +#define R128_CCE_PACKET3_TRANS_SCALING 0xC0001700 +#define R128_CCE_PACKET3_POLYSCANLINES 0xC0001800 +#define R128_CCE_PACKET3_NEXT_CHAR 0xC0001900 +#define R128_CCE_PACKET3_PAINT_MULTI 0xC0001A00 +#define R128_CCE_PACKET3_BITBLT_MULTI 0xC0001B00 +#define R128_CCE_PACKET3_PLY_NEXTSCAN 0xC0001D00 +#define R128_CCE_PACKET3_SET_SCISSORS 0xC0001E00 +#define R128_CCE_PACKET3_SET_MODE24BPP 0xC0001F00 +#define R128_CCE_PACKET3_CNTL_PAINT 0xC0009100 +#define R128_CCE_PACKET3_CNTL_BITBLT 0xC0009200 +#define R128_CCE_PACKET3_CNTL_SMALLTEXT 0xC0009300 +#define R128_CCE_PACKET3_CNTL_HOSTDATA_BLT 0xC0009400 +#define R128_CCE_PACKET3_CNTL_POLYLINE 0xC0009500 +#define R128_CCE_PACKET3_CNTL_SCALING 0xC0009600 +#define R128_CCE_PACKET3_CNTL_TRANS_SCALING 0xC0009700 +#define R128_CCE_PACKET3_CNTL_POLYSCANLINES 0xC0009800 +#define R128_CCE_PACKET3_CNTL_NEXT_CHAR 0xC0009900 +#define R128_CCE_PACKET3_CNTL_PAINT_MULTI 0xC0009A00 +#define R128_CCE_PACKET3_CNTL_BITBLT_MULTI 0xC0009B00 +#define R128_CCE_PACKET3_CNTL_TRANS_BITBLT 0xC0009C00 +#define R128_CCE_PACKET3_3D_SAVE_CONTEXT 0xC0002000 +#define R128_CCE_PACKET3_3D_PLAY_CONTEXT 0xC0002100 +#define R128_CCE_PACKET3_3D_RNDR_GEN_INDX_PRIM 0xC0002300 +#define R128_CCE_PACKET3_3D_RNDR_GEN_PRIM 0xC0002500 +#define R128_CCE_PACKET3_LOAD_PALETTE 0xC0002C00 +#define R128_CCE_PACKET3_PURGE 0xC0002D00 +#define R128_CCE_PACKET3_NEXT_VERTEX_BUNDLE 0xC0002E00 +# define R128_CCE_PACKET_MASK 0xC0000000 +# define R128_CCE_PACKET_COUNT_MASK 0x3fff0000 +# define R128_CCE_PACKET_MAX_DWORDS (1 << 12) +# define R128_CCE_PACKET0_REG_MASK 0x000007ff +# define R128_CCE_PACKET1_REG0_MASK 0x000007ff +# define R128_CCE_PACKET1_REG1_MASK 0x003ff800 + +#define R128_CCE_VC_FRMT_RHW 0x00000001 +#define R128_CCE_VC_FRMT_DIFFUSE_BGR 0x00000002 +#define R128_CCE_VC_FRMT_DIFFUSE_A 0x00000004 +#define R128_CCE_VC_FRMT_DIFFUSE_ARGB 0x00000008 +#define R128_CCE_VC_FRMT_SPEC_BGR 0x00000010 +#define R128_CCE_VC_FRMT_SPEC_F 0x00000020 +#define R128_CCE_VC_FRMT_SPEC_FRGB 0x00000040 +#define R128_CCE_VC_FRMT_S_T 0x00000080 +#define R128_CCE_VC_FRMT_S2_T2 0x00000100 +#define R128_CCE_VC_FRMT_RHW2 0x00000200 + +#define R128_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000 +#define R128_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001 +#define R128_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002 +#define R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006 +#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007 +#define R128_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010 +#define R128_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020 +#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030 +#define R128_CCE_VC_CNTL_NUM_SHIFT 16 + +/* hmm copyed blindly (no specs) from radeon.h ... */ +#define R128_RE_TOP_LEFT 0x26c0 +# define R128_RE_LEFT_SHIFT 0 +# define R128_RE_TOP_SHIFT 16 +#define R128_RE_WIDTH_HEIGHT 0x1c44 +# define R128_RE_WIDTH_SHIFT 0 +# define R128_RE_HEIGHT_SHIFT 16 + +#endif diff --git a/src/mesa/drivers/dri/r128/server/r128_sarea.h b/src/mesa/drivers/dri/r128/server/r128_sarea.h new file mode 100644 index 0000000000..8a9f3a4176 --- /dev/null +++ b/src/mesa/drivers/dri/r128/server/r128_sarea.h @@ -0,0 +1,195 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_sarea.h,v 1.7 2002/02/16 21:26:35 herrb Exp $ */ +/* + * Copyright 1999, 2000 ATI Technologies Inc., Markham, Ontario, + * Precision Insight, Inc., Cedar Park, Texas, 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, 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, PRECISION INSIGHT, 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 + * Gareth Hughes + * + */ + +#ifndef _R128_SAREA_H_ +#define _R128_SAREA_H_ + +/* WARNING: If you change any of these defines, make sure to change the + * defines in the kernel file (r128_drm.h) + */ +#ifndef __R128_SAREA_DEFINES__ +#define __R128_SAREA_DEFINES__ + +/* What needs to be changed for the current vertex buffer? + */ +#define R128_UPLOAD_CONTEXT 0x001 +#define R128_UPLOAD_SETUP 0x002 +#define R128_UPLOAD_TEX0 0x004 +#define R128_UPLOAD_TEX1 0x008 +#define R128_UPLOAD_TEX0IMAGES 0x010 +#define R128_UPLOAD_TEX1IMAGES 0x020 +#define R128_UPLOAD_CORE 0x040 +#define R128_UPLOAD_MASKS 0x080 +#define R128_UPLOAD_WINDOW 0x100 +#define R128_UPLOAD_CLIPRECTS 0x200 /* handled client-side */ +#define R128_REQUIRE_QUIESCENCE 0x400 +#define R128_UPLOAD_ALL 0x7ff + +#define R128_FRONT 0x1 +#define R128_BACK 0x2 +#define R128_DEPTH 0x4 + +/* Primitive types + */ +#define R128_POINTS 0x1 +#define R128_LINES 0x2 +#define R128_LINE_STRIP 0x3 +#define R128_TRIANGLES 0x4 +#define R128_TRIANGLE_FAN 0x5 +#define R128_TRIANGLE_STRIP 0x6 + +/* Vertex/indirect buffer size + */ +#define R128_BUFFER_SIZE 16384 + +/* Byte offsets for indirect buffer data + */ +#define R128_INDEX_PRIM_OFFSET 20 +#define R128_HOSTDATA_BLIT_OFFSET 32 + +/* Keep these small for testing + */ +#define R128_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 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_MAX_TEXTURE_LEVELS 11 +#define R128_MAX_TEXTURE_UNITS 2 + +#endif /* __R128_SAREA_DEFINES__ */ + +typedef struct { + /* Context state - can be written in one large chunk */ + unsigned int dst_pitch_offset_c; + unsigned int dp_gui_master_cntl_c; + unsigned int sc_top_left_c; + unsigned int sc_bottom_right_c; + unsigned int z_offset_c; + unsigned int z_pitch_c; + unsigned int z_sten_cntl_c; + unsigned int tex_cntl_c; + unsigned int misc_3d_state_cntl_reg; + unsigned int texture_clr_cmp_clr_c; + unsigned int texture_clr_cmp_msk_c; + unsigned int fog_color_c; + + /* Texture state */ + unsigned int tex_size_pitch_c; + unsigned int constant_color_c; + + /* Setup state */ + unsigned int pm4_vc_fpu_setup; + unsigned int setup_cntl; + + /* Mask state */ + unsigned int dp_write_mask; + unsigned int sten_ref_mask_c; + unsigned int plane_3d_mask_c; + + /* Window state */ + unsigned int window_xy_offset; + + /* Core state */ + unsigned int scale_3d_cntl; +} r128_context_regs_t; + +/* 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_MAX_TEXTURE_LEVELS]; + unsigned int tex_border_color; +} r128_texture_regs_t; + +typedef struct { + /* The channel for communication of state information to the kernel + * on firing a vertex buffer. + */ + r128_context_regs_t ContextState; + r128_texture_regs_t TexState[R128_MAX_TEXTURE_UNITS]; + unsigned int dirty; + unsigned int vertsize; + unsigned int vc_format; + +#if defined(XF86DRI) | defined(_SOLO) + /* The current cliprects, or a subset thereof. + */ + XF86DRIClipRectRec boxes[R128_NR_SAREA_CLIPRECTS]; + unsigned int nbox; +#endif + + /* Counters for throttling of rendering clients. + */ + 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 + * 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 */ + drmTextureRegion texList[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS+1]; + /* last time texture was uploaded */ + unsigned int texAge[R128_NR_TEX_HEAPS]; + + int ctxOwner; /* last context to upload state */ + int pfAllowPageFlip; /* set by the 2d driver, read by the client */ + int pfCurrentPage; /* set by kernel, read by others */ +} R128SAREAPriv, *R128SAREAPrivPtr; + +#endif diff --git a/src/mesa/drivers/dri/r128/server/r128_version.h b/src/mesa/drivers/dri/r128/server/r128_version.h new file mode 100644 index 0000000000..589d8d40bc --- /dev/null +++ b/src/mesa/drivers/dri/r128/server/r128_version.h @@ -0,0 +1,60 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/ati/r128_version.h,v 1.6 2003/01/01 19:16:35 tsi Exp $ */ +/* + * Copyright 2000 through 2003 by Marc Aurele La France (TSI @ UQV), tsi@xfree86.org + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice appear in all copies and that both that copyright + * notice and this permission notice appear in supporting documentation, and + * that the name of Marc Aurele La France not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Marc Aurele La France makes no representations + * about the suitability of this software for any purpose. It is provided + * "as-is" without express or implied warranty. + * + * MARC AURELE LA FRANCE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO + * EVENT SHALL MARC AURELE LA FRANCE BE LIABLE FOR ANY SPECIAL, INDIRECT OR + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR + * PERFORMANCE OF THIS SOFTWARE. + */ + +#ifndef _R128_VERSION_H_ +#define _R128_VERSION_H_ 1 + +#undef R128_NAME +#undef R128_DRIVER_NAME +#undef R128_VERSION_MAJOR +#undef R128_VERSION_MINOR +#undef R128_VERSION_PATCH +#undef R128_VERSION_CURRENT +#undef R128_VERSION_EVALUATE +#undef R128_VERSION_STRINGIFY +#undef R128_VERSION_NAME + +#define R128_NAME "R128" +#define R128_DRIVER_NAME "r128" + +#define R128_VERSION_MAJOR 4 +#define R128_VERSION_MINOR 0 +#define R128_VERSION_PATCH 1 + +#ifndef R128_VERSION_EXTRA +#define R128_VERSION_EXTRA "" +#endif + +#define R128_VERSION_CURRENT \ + ((R128_VERSION_MAJOR << 20) | \ + (R128_VERSION_MINOR << 10) | \ + (R128_VERSION_PATCH)) + +#define R128_VERSION_EVALUATE(__x) #__x +#define R128_VERSION_STRINGIFY(_x) R128_VERSION_EVALUATE(_x) +#define R128_VERSION_NAME \ + R128_VERSION_STRINGIFY(R128_VERSION_MAJOR) "." \ + R128_VERSION_STRINGIFY(R128_VERSION_MINOR) "." \ + R128_VERSION_STRINGIFY(R128_VERSION_MINOR) R128_VERSION_EXTRA + +#endif /* _R128_VERSION_H_ */ -- cgit v1.2.3