From: Alan Hourihane Date: Tue, 30 Sep 2003 11:13:31 +0000 (+0000) Subject: add the SiS driver - no kernel driver yet X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=0f2e1869263ef04b3bc47d9817278a555201bda8;p=mesa.git add the SiS driver - no kernel driver yet (build tested, but not physically tested) --- diff --git a/Makefile.X11 b/Makefile.X11 index 1e432a97e03..e6f1182618b 100644 --- a/Makefile.X11 +++ b/Makefile.X11 @@ -1,4 +1,4 @@ -# $Id: Makefile.X11,v 1.87 2003/09/30 11:02:38 alanh Exp $ +# $Id: Makefile.X11,v 1.88 2003/09/30 11:13:31 alanh Exp $ # Mesa 3-D graphics library # Version: 5.1 @@ -241,6 +241,7 @@ linux-solo: if [ -d src/mesa/drivers/dri/mga ] ; then touch src/mesa/drivers/dri/mga/depend ; fi if [ -d src/mesa/drivers/dri/i810 ] ; then touch src/mesa/drivers/dri/i810/depend ; fi if [ -d src/mesa/drivers/dri/i830 ] ; then touch src/mesa/drivers/dri/i830/depend ; fi + if [ -d src/mesa/drivers/dri/sis ] ; then touch src/mesa/drivers/dri/sis/depend ; fi if [ -d src/mesa/drivers/dri/fb ] ; then touch src/mesa/drivers/dri/fb/depend ; fi if [ -d src/glut/mini ] ; then touch src/glut/mini/depend ; fi if [ -d progs/miniglx ] ; then touch progs/miniglx/depend ; fi @@ -252,6 +253,7 @@ linux-solo: if [ -d src/mesa/drivers/dri/mga ] ; then cd src/mesa/drivers/dri/mga ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/mesa/drivers/dri/i810 ] ; then cd src/mesa/drivers/dri/i810 ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/mesa/drivers/dri/i830 ] ; then cd src/mesa/drivers/dri/i830 ; $(MAKE) -f Makefile.X11 $@ ; fi + if [ -d src/mesa/drivers/dri/sis ] ; then cd src/mesa/drivers/dri/sis ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/mesa/drivers/dri/fb ] ; then cd src/mesa/drivers/dri/fb ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/glx/mini ] ; then cd src/glx/mini ; $(MAKE) -f Makefile.X11 $@ ; fi if [ -d src/glu/mini ] ; then cd src/glu/mini ; $(MAKE) -f Makefile.X11 $@ ; fi diff --git a/src/mesa/drivers/dri/sis/Makefile.X11 b/src/mesa/drivers/dri/sis/Makefile.X11 new file mode 100644 index 00000000000..529bd637c23 --- /dev/null +++ b/src/mesa/drivers/dri/sis/Makefile.X11 @@ -0,0 +1,120 @@ +# $Id: Makefile.X11,v 1.1 2003/09/30 11:13:32 alanh 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 + +# Not yet +# MINIGLX_SOURCES = server/sis_dri.c + +DRIVER_SOURCES = \ + sis_alloc.c \ + sis_clear.c \ + sis_context.c \ + sis_dd.c \ + sis_debug.c \ + sis_fog.c \ + sis_lock.c \ + sis_screen.c \ + sis_span.c \ + sis_state.c \ + sis_stencil.c \ + sis_tex.c \ + sis_texstate.c \ + sis_tris.c \ + sis_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 sis_dri.so + +sis_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/sis_dri.so && \ + install sis_dri.so $(TOP)/lib/sis_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/sis/server/sis_common.h b/src/mesa/drivers/dri/sis/server/sis_common.h new file mode 100644 index 00000000000..cbddf0c7371 --- /dev/null +++ b/src/mesa/drivers/dri/sis/server/sis_common.h @@ -0,0 +1,63 @@ +/* * $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_common.h,v 1.1 2003/08/29 08:52:12 twini Exp $ */ +/* + * Common header definitions for SiS 2D/3D/DRM suite + * + * Copyright (C) 2003 Eric Anholt + * + * 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 the copyright holder not be used in + * advertising or publicity pertaining to distribution of the software without + * specific, written prior permission. The copyright holder makes no representations + * about the suitability of this software for any purpose. It is provided + * "as is" without express or implied warranty. + * + * THE COPYRIGHT HOLDER DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO + * EVENT SHALL THE COPYRIGHT HOLDER 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. + * + * Author: + * Eric Anholt + * + */ + +#ifndef _SIS_COMMON_H_ +#define _SIS_COMMON_H_ + +#define DRM_SIS_FB_ALLOC 0x04 +#define DRM_SIS_FB_FREE 0x05 +#define DRM_SIS_FLIP 0x08 +#define DRM_SIS_FLIP_INIT 0x09 +#define DRM_SIS_FLIP_FINAL 0x10 +#define DRM_SIS_AGP_INIT 0x13 +#define DRM_SIS_AGP_ALLOC 0x14 +#define DRM_SIS_AGP_FREE 0x15 +#define DRM_SIS_FB_INIT 0x16 + +typedef struct { + int context; + unsigned long offset; + unsigned long size; + void *free; +} drm_sis_mem_t; + +typedef struct { + unsigned long offset, size; +} drm_sis_agp_t; + +typedef struct { + unsigned long offset, size; +} drm_sis_fb_t; + +typedef struct { + unsigned int left, right; +} drm_sis_flip_t; + +#endif /* _SIS_COMMON_H_ */ + diff --git a/src/mesa/drivers/dri/sis/server/sis_dri.h b/src/mesa/drivers/dri/sis/server/sis_dri.h new file mode 100644 index 00000000000..d38e39a0539 --- /dev/null +++ b/src/mesa/drivers/dri/sis/server/sis_dri.h @@ -0,0 +1,85 @@ +/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/sis/sis_dri.h,v 1.9 2003/08/29 08:50:54 twini Exp $ */ + +/* modified from tdfx_dri.h */ + +#ifndef _SIS_DRI_ +#define _SIS_DRI_ + +#include "xf86drm.h" + +#define SIS_MAX_DRAWABLES 256 +#define SISIOMAPSIZE (64*1024) + +typedef struct { + int CtxOwner; + int QueueLength; + unsigned int AGPCmdBufNext; + unsigned int FrameCount; +#ifdef SIS315DRI + /* For 315 series */ + unsigned long sharedWPoffset; +#endif +#if 0 + unsigned char *AGPCmdBufBase; + unsigned long AGPCmdBufAddr; + unsigned long AGPCmdBufOffset; + unsigned int AGPCmdBufSize; + unsigned long AGPCmdBufNext; +#endif +} SISSAREAPriv, *SISSAREAPrivPtr; + +#define AGPVtxBufNext AGPCmdBufNext + +#define SIS_FRONT 0 +#define SIS_BACK 1 +#define SIS_DEPTH 2 + +typedef struct { + drmHandle handle; + drmSize size; + drmAddress map; +} sisRegion, *sisRegionPtr; + +typedef struct { + sisRegion regs, agp; + int deviceID; + int width; + int height; + int mem; /* unused in Mesa 3 DRI */ + int bytesPerPixel; + int priv1; /* unused in Mesa 3 DRI */ + int priv2; /* unused in Mesa 3 DRI */ + int fbOffset; /* unused in Mesa 3 DRI */ + int backOffset; /* unused in Mesa 3 DRI */ + int depthOffset; /* unused in Mesa 3 DRI */ + int textureOffset; /* unused in Mesa 3 DRI */ + int textureSize; /* unused in Mesa 3 DRI */ + unsigned int AGPCmdBufOffset; + unsigned int AGPCmdBufSize; + int irqEnabled; /* unused in Mesa 3 DRI */ + unsigned int scrnX, scrnY; /* unused in Mesa 3 DRI */ +} SISDRIRec, *SISDRIPtr; + +#define AGPVtxBufOffset AGPCmdBufOffset +#define AGPVtxBufSize AGPCmdBufSize + +typedef struct { + /* Nothing here yet */ + int dummy; +} SISConfigPrivRec, *SISConfigPrivPtr; + +typedef struct { + /* Nothing here yet */ + int dummy; +} SISDRIContextRec, *SISDRIContextPtr; + +#ifdef XFree86Server + +#include "screenint.h" + +Bool SISDRIScreenInit(ScreenPtr pScreen); +void SISDRICloseScreen(ScreenPtr pScreen); +Bool SISDRIFinishScreenInit(ScreenPtr pScreen); + +#endif +#endif diff --git a/src/mesa/drivers/dri/sis/sis_alloc.c b/src/mesa/drivers/dri/sis/sis_alloc.c new file mode 100644 index 00000000000..aa71f269d14 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_alloc.c @@ -0,0 +1,256 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_alloc.c,v 1.7 2001/01/08 01:07:29 martin Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#include + +#include "sis_context.h" +#include "sis_alloc.h" + +#include "sis_common.h" + +#define Z_BUFFER_HW_ALIGNMENT 16 +#define Z_BUFFER_HW_PLUS (16 + 4) + +/* 3D engine uses 2, and bitblt uses 4 */ +#define DRAW_BUFFER_HW_ALIGNMENT 16 +#define DRAW_BUFFER_HW_PLUS (16 + 4) + +#ifdef ROUNDUP +#undef ROUNDUP +#endif +#define ROUNDUP(nbytes, pad) (((nbytes)+(pad-1))/(pad)) + +#ifdef ALIGNMENT +#undef ALIGNMENT +#endif +#define ALIGNMENT(value, align) (ROUNDUP((value),(align))*(align)) + +static int _total_video_memory_used = 0; +static int _total_video_memory_count = 0; + +void * +sisAllocFB( sisContextPtr smesa, GLuint size, void **handle ) +{ + drm_sis_mem_t fb; + + _total_video_memory_used += size; + + fb.context = smesa->hHWContext; + fb.size = size; + if (drmCommandWriteRead( smesa->driFd, DRM_SIS_FB_ALLOC, &fb, + sizeof(drm_sis_mem_t) ) || fb.offset == 0) + { + return NULL; + } + *handle = (void *)fb.free; + + if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) { + fprintf(stderr, "sisAllocFB: size=%d, offset=%lu, pid=%d, count=%d\n", + size, fb.offset, (GLint)getpid(), + ++_total_video_memory_count); + } + + return (void *)(smesa->FbBase + fb.offset); +} + +void +sisFreeFB( sisContextPtr smesa, void *handle ) +{ + drm_sis_mem_t fb; + + if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) { + fprintf(stderr, "sisFreeFB: free=%p, pid=%d, count=%d\n", + handle, (GLint)getpid(), --_total_video_memory_count); + } + + fb.context = smesa->hHWContext; + fb.free = handle; + drmCommandWrite( smesa->driFd, DRM_SIS_FB_FREE, &fb, sizeof(drm_sis_mem_t) ); +} + +void * +sisAllocAGP( sisContextPtr smesa, GLuint size, void **handle ) +{ + drm_sis_mem_t agp; + + if (smesa->AGPSize == 0) + return NULL; + + agp.context = smesa->hHWContext; + agp.size = size; + if (drmCommandWriteRead( smesa->driFd, DRM_SIS_AGP_ALLOC, &agp, + sizeof(drm_sis_mem_t) ) || agp.offset == 0) + { + return NULL; + } + *handle = (void *)agp.free; + + if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) { + fprintf(stderr, "sisAllocAGP: size=%u, offset=%lu, pid=%d, count=%d\n", + size, agp.offset, (GLint)getpid(), + ++_total_video_memory_count); + } + + return (void *)(smesa->AGPBase + agp.offset); +} + +void +sisFreeAGP( sisContextPtr smesa, void *handle ) +{ + drm_sis_mem_t agp; + + if (SIS_VERBOSE & VERBOSE_SIS_MEMORY) { + fprintf(stderr, "sisFreeAGP: free=%p, pid=%d, count=%d\n", + handle, (GLint)getpid(), --_total_video_memory_count); + } + + agp.context = smesa->hHWContext; + agp.free = handle; + drmCommandWrite( smesa->driFd, DRM_SIS_AGP_FREE, &agp, + sizeof(drm_sis_mem_t) ); +} + +void +sisAllocZStencilBuffer( sisContextPtr smesa ) +{ + GLuint z_depth; + GLuint totalBytes; + int width2; + + GLubyte *addr; + + z_depth = ( smesa->glCtx->Visual.depthBits + + smesa->glCtx->Visual.stencilBits ) / 8; + + width2 = ALIGNMENT( smesa->width * z_depth, 4 ); + + totalBytes = smesa->height * width2 + Z_BUFFER_HW_PLUS; + + addr = sisAllocFB( smesa, totalBytes, &smesa->zbFree ); + if (addr == NULL) + { + fprintf (stderr, "SIS driver : out of video memory\n"); + sis_fatal_error (); + } + + if (SIS_VERBOSE & VERBOSE_SIS_BUFFER) { + fprintf(stderr, "sis_alloc_z_stencil_buffer: addr=%p\n", addr); + } + + addr = (GLubyte *)ALIGNMENT( (unsigned long)addr, Z_BUFFER_HW_ALIGNMENT ); + + smesa->depthbuffer = (void *) addr; + smesa->depthPitch = width2; + + /* set pZClearPacket */ + memset( &smesa->zClearPacket, 0, sizeof(ENGPACKET) ); + + smesa->zClearPacket.dwSrcPitch = (z_depth == 2) ? 0x80000000 : 0xf0000000; + smesa->zClearPacket.dwDestBaseAddr = (GLint)(addr - + (unsigned long)smesa->FbBase); + smesa->zClearPacket.wDestPitch = width2; + smesa->zClearPacket.stdwDestPos.wY = 0; + smesa->zClearPacket.stdwDestPos.wX = 0; + + smesa->zClearPacket.wDestHeight = smesa->virtualY; + smesa->zClearPacket.stdwDim.wWidth = (GLshort)width2 / z_depth; + smesa->zClearPacket.stdwDim.wHeight = (GLshort)smesa->height; + smesa->zClearPacket.stdwCmd.cRop = 0xf0; + + if (smesa->blockWrite) + smesa->zClearPacket.stdwCmd.cCmd0 = CMD0_PAT_FG_COLOR; + else + smesa->zClearPacket.stdwCmd.cCmd0 = 0; + smesa->zClearPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC; +} + +void +sisFreeZStencilBuffer( sisContextPtr smesa ) +{ + sisFreeFB( smesa, smesa->zbFree ); + smesa->zbFree = NULL; + smesa->depthbuffer = NULL; +} + +void +sisAllocBackbuffer( sisContextPtr smesa ) +{ + GLuint depth = smesa->bytesPerPixel; + GLuint size, width2; + + char *addr; + + width2 = (depth == 2) ? ALIGNMENT (smesa->width, 2) : smesa->width; + size = width2 * smesa->height * depth + DRAW_BUFFER_HW_PLUS; + + /* Fixme: unique context alloc/free back-buffer? */ + addr = sisAllocFB( smesa, size, &smesa->bbFree ); + if (addr == NULL) + { + fprintf (stderr, "SIS driver : out of video memory\n"); + sis_fatal_error (); + } + + addr = (char *)ALIGNMENT( (unsigned long)addr, DRAW_BUFFER_HW_ALIGNMENT ); + + smesa->backbuffer = addr; + smesa->backOffset = (GLint)(addr - (unsigned long)smesa->FbBase); + smesa->backPitch = width2 * depth; + + memset ( &smesa->cbClearPacket, 0, sizeof(ENGPACKET) ); + + smesa->cbClearPacket.dwSrcPitch = (depth == 2) ? 0x80000000 : 0xf0000000; + smesa->cbClearPacket.dwDestBaseAddr = smesa->backOffset; + smesa->cbClearPacket.wDestPitch = smesa->backPitch; + smesa->cbClearPacket.stdwDestPos.wY = 0; + smesa->cbClearPacket.stdwDestPos.wX = 0; + + smesa->cbClearPacket.wDestHeight = smesa->virtualY; + smesa->cbClearPacket.stdwDim.wWidth = (GLshort) width2; + smesa->cbClearPacket.stdwDim.wHeight = (GLshort) smesa->height; + smesa->cbClearPacket.stdwCmd.cRop = 0xf0; + + if (smesa->blockWrite) + smesa->cbClearPacket.stdwCmd.cCmd0 = (GLbyte)(CMD0_PAT_FG_COLOR); + else + smesa->cbClearPacket.stdwCmd.cCmd0 = 0; + smesa->cbClearPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC; +} + +void +sisFreeBackbuffer( sisContextPtr smesa ) +{ + sisFreeFB( smesa, smesa->bbFree ); + smesa->backbuffer = NULL; +} diff --git a/src/mesa/drivers/dri/sis/sis_alloc.h b/src/mesa/drivers/dri/sis/sis_alloc.h new file mode 100644 index 00000000000..30f5f3ab36d --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_alloc.h @@ -0,0 +1,45 @@ +/************************************************************************** + +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Eric Anholt + */ + +enum { + VIDEO_TYPE, + AGP_TYPE +}; + +void sisAllocZStencilBuffer( sisContextPtr smesa ); +void sisFreeZStencilBuffer( sisContextPtr smesa ); +void sisAllocBackbuffer( sisContextPtr smesa ); +void sisFreeBackbuffer ( sisContextPtr smesa ); +void *sisAllocFB( sisContextPtr smesa, GLuint size, void **handle ); +void sisFreeFB( sisContextPtr smesa, void *handle ); +void *sisAllocAGP( sisContextPtr smesa, GLuint size, void **handle ); +void sisFreeAGP( sisContextPtr smesa, void *handle ); diff --git a/src/mesa/drivers/dri/sis/sis_clear.c b/src/mesa/drivers/dri/sis/sis_clear.c new file mode 100644 index 00000000000..2506cd5a37b --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_clear.c @@ -0,0 +1,454 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_clear.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_lock.h" +#include "macros.h" +#include "swrast/swrast.h" + +#if 0 +static GLbitfield sis_3D_Clear( GLcontext * ctx, GLbitfield mask, + GLint x, GLint y, GLint width, + GLint height ); +#endif +static void sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, + GLint y, GLint width, GLint height ); +static void sis_clear_z_stencil_buffer( GLcontext * ctx, + GLbitfield mask, GLint x, + GLint y, GLint width, + GLint height ); + +static void +set_color_pattern( sisContextPtr smesa, GLubyte red, GLubyte green, + GLubyte blue, GLubyte alpha ) +{ + /* XXX only RGB565 and ARGB8888 */ + switch (GET_ColorFormat(smesa)) + { + case DST_FORMAT_ARGB_8888: + smesa->clearColorPattern = (alpha << 24) + + (red << 16) + (green << 8) + (blue); + break; + case DST_FORMAT_RGB_565: + smesa->clearColorPattern = ((red >> 3) << 11) + + ((green >> 2) << 5) + (blue >> 3); + smesa->clearColorPattern |= smesa->clearColorPattern << 16; + break; + default: + assert(0); + } +} + +void +sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, GLint stencil ) +{ + GLuint zPattern; + + if (z <= 0.0f) + zPattern = 0x0; + else if (z >= 1.0f) + zPattern = 0xFFFFFFFF; + else + zPattern = doFPtoFixedNoRound( z, 32 ); + + switch (smesa->zFormat) + { + case SiS_ZFORMAT_Z16: + zPattern = zPattern >> 16; + zPattern |= zPattern << 16; + break; + case SiS_ZFORMAT_S8Z24: + zPattern = zPattern >> 8; + zPattern |= stencil << 24; + break; + case SiS_ZFORMAT_Z32: + break; + default: + assert(0); + } + smesa->clearZStencilPattern = zPattern; +} + +void +sisDDClear( GLcontext * ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + GLint x1, y1, width1, height1; + + if (all) { + GLframebuffer *buffer = ctx->DrawBuffer; + + x1 = 0; + y1 = 0; + width1 = buffer->Width; + height1 = buffer->Height; + } else { + x1 = x; + y1 = Y_FLIP(y+height-1); + width1 = width; + height1 = height; + } + + LOCK_HARDWARE(); + +#if 0 + /* The 3d clear code is disabled because it appears to be slower, even + * in the case of being requested to clear Z and color buffers at the + * same time. + */ + if (mask & (DD_BACK_LEFT_BIT | DD_DEPTH_BIT | DD_STENCIL_BIT)) + { + /* only Clear either depth or stencil buffer */ + mask = sis_3D_Clear( ctx, mask, x1, y1, width1, height1 ); + } +#endif + + if ( mask & DD_FRONT_LEFT_BIT || mask & DD_BACK_LEFT_BIT) { + sis_clear_color_buffer( ctx, mask, x1, y1, width1, height1 ); + mask &= ~(DD_FRONT_LEFT_BIT | DD_BACK_LEFT_BIT); + } + + if (mask & (DD_DEPTH_BIT | DD_STENCIL_BIT)) { + if (smesa->depthbuffer != NULL) + sis_clear_z_stencil_buffer( ctx, mask, x1, y1, width1, height1 ); + mask &= ~(DD_DEPTH_BIT | DD_STENCIL_BIT); + } + + UNLOCK_HARDWARE(); + + if (mask != 0) + _swrast_Clear( ctx, mask, all, x1, y1, width, height ); +} + + +void +sisDDClearColor( GLcontext * ctx, const GLfloat color[4] ) +{ + sisContextPtr smesa = SIS_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]); + + set_color_pattern( smesa, c[0], c[1], c[2], c[3] ); +} + +void +sisDDClearDepth( GLcontext * ctx, GLclampd d ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + sisUpdateZStencilPattern( smesa, d, ctx->Stencil.Clear ); +} + +void +sisDDClearStencil( GLcontext * ctx, GLint s ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + sisUpdateZStencilPattern( smesa, ctx->Depth.Clear, s ); +} + +#if 0 +static GLbitfield +sis_3D_Clear( GLcontext * ctx, GLbitfield mask, + GLint x, GLint y, GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *current = &smesa->current; + + float left, top, right, bottom, zClearVal; + GLboolean bClrColor, bClrDepth, bClrStencil; + GLint dwPrimitiveSet; + GLint dwEnable1 = 0, dwEnable2 = 0, dwDepthMask = 0, dwSten1 = 0, dwSten2 = 0; + GLint dirtyflags = GFLAG_ENABLESETTING | GFLAG_ENABLESETTING2 | + GFLAG_CLIPPING | GFLAG_DESTSETTING; + + int count; + XF86DRIClipRectPtr pExtents; + + bClrColor = ((mask & DD_BACK_LEFT_BIT) != 0); + bClrDepth = ((mask & DD_DEPTH_BIT) != 0) && (ctx->Visual.depthBits != 0); + bClrStencil = ((mask & DD_STENCIL_BIT) != 0) && (ctx->Visual.stencilBits != 0); + + if (smesa->GlobalFlag & GFLAG_RENDER_STATES) + sis_update_render_state( smesa ); + + if (!bClrColor) + dwEnable2 |= MASK_ColorMaskWriteEnable; + + if (bClrStencil) { + dwSten1 = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | + (ctx->Stencil.Clear << 8) | 0xff; + dwSten2 = SiS_SFAIL_REPLACE | SiS_SPASS_ZFAIL_REPLACE | + SiS_SPASS_ZPASS_REPLACE; + dwEnable1 = MASK_ZWriteEnable | MASK_StencilTestEnable; + dwEnable2 |= MASK_ZMaskWriteEnable; + dwDepthMask |= ctx->Stencil.WriteMask[0] << 24; + } else if (bClrDepth) { + dwEnable1 = MASK_ZWriteEnable; + dwEnable2 |= MASK_ZMaskWriteEnable; + } + + if (bClrDepth) { + zClearVal = ctx->Depth.Clear; + if (ctx->Visual.depthBits != 32) + dwDepthMask |= 0x00ffffff; + else + dwDepthMask = 0xffffffff; + } else + zClearVal = 0.0; + + mWait3DCmdQueue(9); + MMIO(REG_3D_TEnable, dwEnable1); + MMIO(REG_3D_TEnable2, dwEnable2); + if (bClrDepth || bClrStencil) { + MMIO(REG_3D_ZSet, (current->hwZ & ~MASK_ZTestMode) | SiS_Z_COMP_ALWAYS); + dirtyflags |= GFLAG_ZSETTING; + } + if (bClrColor) { + MMIO(REG_3D_DstSet, (current->hwDstSet & ~MASK_ROP2) | LOP_COPY); + } else { + MMIO(REG_3D_DstAlphaWriteMask, 0L); + } + if (bClrStencil) { + MMIO(REG_3D_StencilSet, dwSten1); + MMIO(REG_3D_StencilSet2, dwSten2); + dirtyflags |= GFLAG_STENCILSETTING; + } + + if (mask & DD_FRONT_LEFT_BIT) { + pExtents = smesa->driDrawable->pClipRects; + count = smesa->driDrawable->numClipRects; + } else { + pExtents = NULL; + count = 1; + } + + while(count--) { + left = x; + right = x + width; + top = y; + bottom = y + height; + + if (pExtents != NULL) { + GLuint x1, y1, x2, y2; + + x1 = pExtents->x1 - smesa->driDrawable->x; + y1 = pExtents->y1 - smesa->driDrawable->y; + x2 = pExtents->x2 - smesa->driDrawable->x - 1; + y2 = pExtents->y2 - smesa->driDrawable->y - 1; + + left = (left > x1) ? left : x1; + right = (right > x2) ? x2 : right; + top = (top > y1) ? top : y1; + bottom = (bottom > y2) ? y2 : bottom; + pExtents++; + if (left > right || top > bottom) + continue; + } + + mWait3DCmdQueue(20); + + MMIO(REG_3D_ClipTopBottom, ((GLint)top << 13) | (GLint)bottom); + MMIO(REG_3D_ClipLeftRight, ((GLint)left << 13) | (GLint)right); + + /* the first triangle */ + dwPrimitiveSet = OP_3D_TRIANGLE_DRAW | OP_3D_FIRE_TSARGBc | + SHADE_FLAT_VertexC; + MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet); + + MMIO(REG_3D_TSZa, *(GLint *) &zClearVal); + MMIO(REG_3D_TSXa, *(GLint *) &right); + MMIO(REG_3D_TSYa, *(GLint *) &top); + MMIO(REG_3D_TSARGBa, smesa->clearColorPattern); + + MMIO(REG_3D_TSZb, *(GLint *) &zClearVal); + MMIO(REG_3D_TSXb, *(GLint *) &left); + MMIO(REG_3D_TSYb, *(GLint *) &top); + MMIO(REG_3D_TSARGBb, smesa->clearColorPattern); + + MMIO(REG_3D_TSZc, *(GLint *) &zClearVal); + MMIO(REG_3D_TSXc, *(GLint *) &left); + MMIO(REG_3D_TSYc, *(GLint *) &bottom); + MMIO(REG_3D_TSARGBc, smesa->clearColorPattern); + + /* second triangle */ + dwPrimitiveSet = OP_3D_TRIANGLE_DRAW | OP_3D_FIRE_TSARGBb | + SHADE_FLAT_VertexB; + MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet); + + MMIO(REG_3D_TSZb, *(GLint *) &zClearVal); + MMIO(REG_3D_TSXb, *(GLint *) &right); + MMIO(REG_3D_TSYb, *(GLint *) &bottom); + MMIO(REG_3D_TSARGBb, smesa->clearColorPattern); + } + + mEndPrimitive(); + + smesa->GlobalFlag |= dirtyflags; + + return (mask & ~(DD_BACK_LEFT_BIT | DD_DEPTH_BIT | DD_STENCIL_BIT)); +} +#endif + +static void +sis_bitblt_clear_cmd( sisContextPtr smesa, ENGPACKET * pkt ) +{ + GLint *lpdwDest, *lpdwSrc; + int i; + + lpdwSrc = (GLint *) pkt + 1; + lpdwDest = (GLint *) (GET_IOBase (smesa) + REG_SRC_ADDR) + 1; + + mWait3DCmdQueue (10); + + *lpdwDest++ = *lpdwSrc++; + lpdwSrc++; + lpdwDest++; + for (i = 3; i < 8; i++) { + *lpdwDest++ = *lpdwSrc++; + } + + MMIO(REG_CMD0, *(GLint *) & pkt->stdwCmd); + MMIO(REG_QueueLen, -1); +} + +static void +sis_clear_color_buffer( GLcontext *ctx, GLenum mask, GLint x, GLint y, + GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + int count; + GLuint depth = GET_DEPTH (smesa); + XF86DRIClipRectPtr pExtents = NULL; + GLint xx, yy; + GLint x0, y0, width0, height0; + + ENGPACKET stEngPacket; + + /* Clear back buffer */ + if (mask & DD_BACK_LEFT_BIT) { + smesa->cbClearPacket.stdwDestPos.wY = y; + smesa->cbClearPacket.stdwDestPos.wX = x; + smesa->cbClearPacket.stdwDim.wWidth = (GLshort) width; + smesa->cbClearPacket.stdwDim.wHeight = (GLshort) height; + smesa->cbClearPacket.dwFgRopColor = smesa->clearColorPattern; + + sis_bitblt_clear_cmd( smesa, &smesa->cbClearPacket ); + } + + if ((mask & DD_FRONT_LEFT_BIT) == 0) + return; + + /* Clear front buffer */ + x0 = x; + y0 = y; + width0 = width; + height0 = height; + + pExtents = smesa->driDrawable->pClipRects; + count = smesa->driDrawable->numClipRects; + + memset( &stEngPacket, 0, sizeof (ENGPACKET) ); + + stEngPacket.dwSrcPitch = (depth == 2) ? 0x80000000 : 0xc0000000; + stEngPacket.dwDestBaseAddr = smesa->frontOffset; + stEngPacket.wDestPitch = smesa->frontPitch; + /* TODO: set maximum value? */ + stEngPacket.wDestHeight = smesa->virtualY; + stEngPacket.stdwCmd.cRop = 0xf0; + stEngPacket.dwFgRopColor = smesa->clearColorPattern; + + /* for SGRAM Block Write Enable */ + if (smesa->blockWrite) + stEngPacket.stdwCmd.cCmd0 = CMD0_PAT_FG_COLOR; + else + stEngPacket.stdwCmd.cCmd0 = 0; + stEngPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC; + + while (count--) { + GLint x2 = pExtents->x1 - smesa->driDrawable->x; + GLint y2 = pExtents->y1 - smesa->driDrawable->y; + GLint xx2 = pExtents->x2 - smesa->driDrawable->x; + GLint yy2 = pExtents->y2 - smesa->driDrawable->y; + + x = (x0 > x2) ? x0 : x2; + y = (y0 > y2) ? y0 : y2; + xx = ((x0 + width0) > (xx2)) ? xx2 : x0 + width0; + yy = ((y0 + height0) > (yy2)) ? yy2 : y0 + height0; + width = xx - x; + height = yy - y; + pExtents++; + + if (width <= 0 || height <= 0) + continue; + + stEngPacket.stdwDestPos.wY = y; + stEngPacket.stdwDestPos.wX = x; + stEngPacket.stdwDim.wWidth = (GLshort)width; + stEngPacket.stdwDim.wHeight = (GLshort)height; + + sis_bitblt_clear_cmd( smesa, &stEngPacket ); + } +} + +static void +sis_clear_z_stencil_buffer( GLcontext * ctx, GLbitfield mask, + GLint x, GLint y, GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + /* TODO: check write mask */ + + if ( smesa->depthbuffer == NULL ) + return; + + /* TODO: consider alignment of width, height? */ + smesa->zClearPacket.stdwDestPos.wY = y; + smesa->zClearPacket.stdwDestPos.wX = x; + smesa->zClearPacket.stdwDim.wWidth = (GLshort) width; + smesa->zClearPacket.stdwDim.wHeight = (GLshort) height; + smesa->zClearPacket.dwFgRopColor = smesa->clearZStencilPattern; + + sis_bitblt_clear_cmd( smesa, &smesa->zClearPacket ); +} + diff --git a/src/mesa/drivers/dri/sis/sis_common2.h b/src/mesa/drivers/dri/sis/sis_common2.h new file mode 100644 index 00000000000..109078e3a9c --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_common2.h @@ -0,0 +1,143 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +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, 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 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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_common.h,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + */ + +#ifndef _sis_common_h_ +#define _sis_common_h_ + +#if 0 +#define free(x) +#define calloc(x,y) sis_debug_malloc((x)*(y)) +extern void *sis_debug_malloc(int x); +#endif + +#if defined(SIS_DUMP) +#include "sis_debug.h" +#endif + +#ifdef GLX_DIRECT_RENDERING +# include +# include +# include +# include +typedef struct _Box +{ + short x1, y1, x2, y2; +} +BoxRec; +#define NullBox ((BoxPtr)0) +typedef struct _Box *BoxPtr; +#endif /* GLX_DIRECT_RENDERING */ + +/* BitBlt Commands */ +#define CMD0_DD_ENABLE 0x06 +#define CMD0_SRC_VIDEO 0x00 +#define CMD0_SRC_CPU 0x10 +#define CMD0_PAT_FG_COLOR 0x00 +#define CMD1_DIR_X_DEC 0x00 +#define CMD1_DIR_X_INC 0x01 +#define CMD1_DIR_Y_DEC 0x00 +#define CMD1_DIR_Y_INC 0x02 +#define REG_SRC_ADDR 0x8200 +#define REG_CMD0 0x823c + +typedef struct +{ + GLshort wSrcPitch; + GLshort wDestPitch; +} +_PITCH; +typedef struct +{ + GLshort wWidth; + GLshort wHeight; +} +_DIM; +typedef struct +{ + GLshort wY; + GLshort wX; +} +_POS; + +typedef struct +{ + GLubyte cCmd0; + GLubyte cRop; + GLubyte cCmd1; + GLubyte cReserved; +} +_CMD; + +typedef struct +{ + GLshort wStatus0; + GLbyte cStatus0_GLbyte3; + GLbyte cStatus0_GLbyte4; +} +_CMDQUESTATUS; + +typedef struct +{ + GLint dwSrcBaseAddr; + GLint dwSrcPitch; + _POS stdwSrcPos; + _POS stdwDestPos; + GLint dwDestBaseAddr; + GLshort wDestPitch; + GLshort wDestHeight; + _DIM stdwDim; + GLint dwFgRopColor; + GLint dwBgRopColor; + GLint dwSrcHiCKey; + GLint dwSrcLoCKey; + GLint dwMaskA; + GLint dwMaskB; + GLint dwClipA; + GLint dwClipB; + _CMD stdwCmd; + _CMDQUESTATUS stdwCmdQueStatus; +} +ENGPACKET, *LPENGPACKET; + +/* Hardware Info */ +#include "sis_reg.h" + +/* HW capability */ +#define SIS_MAX_TEXTURE_SIZE 2048 +#define SIS_MAX_TEXTURES 2 + +#define SIS_MAX_FRAME_LENGTH 3 + +GLint doFPtoFixedNoRound( GLfloat dwInValue, int nFraction ); + +#endif diff --git a/src/mesa/drivers/dri/sis/sis_context.c b/src/mesa/drivers/dri/sis/sis_context.c new file mode 100644 index 00000000000..a58cb2963bd --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_context.c @@ -0,0 +1,508 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#include "sis_dri.h" + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_dd.h" +#include "sis_span.h" +#include "sis_stencil.h" +#include "sis_tex.h" +#include "sis_tris.h" +#include "sis_vb.h" + +#include "imports.h" +#include "matrix.h" +#include "extensions.h" +#include "utils.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" + +int GlobalCurrentHwcx = -1; +int GlobalHwcxCountBase = 1; +int GlobalCmdQueueLen = 0; + +static const char * const card_extensions[] = +{ + "GL_ARB_multitexture", + "GL_EXT_texture_lod_bias", + NULL +}; + +void +WaitEngIdle (sisContextPtr smesa) +{ + GLubyte *IOBase = GET_IOBase (smesa); + GLbyte cEngineState; + + cEngineState = *((GLbyte volatile *) (IOBase + 0x8243)); + while (((cEngineState & 0x80) == 0) || + ((cEngineState & 0x40) == 0) || ((cEngineState & 0x20) == 0)) + { + cEngineState = *((GLbyte volatile *) (IOBase + 0x8243)); + } +} + +void +Wait2DEngIdle (sisContextPtr smesa) +{ + GLubyte *IOBase = GET_IOBase (smesa); + GLbyte cEngineState; + + cEngineState = *((GLbyte volatile *) (IOBase + 0x8243)); + while (!(cEngineState & 0x80)) + { + cEngineState = *((GLbyte volatile *) (IOBase + 0x8243)); + } +} + +/* To be called from mWait3DCmdQueue. Separate function for profiling + * purposes, and speed doesn't matter because we're spinning anyway. + * This function should use usleeps to release cpu probably, but I have yet + * to see it get called. + */ +void +WaitingFor3dIdle(sisContextPtr smesa, int wLen) +{ + while ( *(smesa->CurrentQueueLenPtr) < wLen) { + *(smesa->CurrentQueueLenPtr) = + (*(GLint *)(GET_IOBase(smesa) + REG_QueueLen) & MASK_QueueLen) - 20; + } +} + +GLboolean +sisCreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ) +{ + GLcontext *ctx, *shareCtx; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + sisContextPtr smesa; + sisScreenPtr sisScreen; + int i; + + smesa = (sisContextPtr)CALLOC( sizeof(*smesa) ); + if ( smesa == NULL ) + return GL_FALSE; + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((sisContextPtr)sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + smesa->glCtx = _mesa_create_context( glVisual, shareCtx, (void *) smesa, + GL_TRUE); + if (smesa->glCtx == NULL) { + FREE(smesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = smesa; + ctx = smesa->glCtx; + + sisScreen = smesa->sisScreen = (sisScreenPtr)(sPriv->private); + + smesa->driContext = driContextPriv; + smesa->driScreen = sPriv; + smesa->driDrawable = NULL; + smesa->hHWContext = driContextPriv->hHWContext; + smesa->driHwLock = &sPriv->pSAREA->lock; + smesa->driFd = sPriv->fd; + + smesa->virtualX = sisScreen->screenX; + smesa->virtualY = sisScreen->screenY; + smesa->bytesPerPixel = sisScreen->cpp; + smesa->IOBase = sisScreen->mmio.map; + smesa->Chipset = sisScreen->deviceID; + smesa->irqEnabled = sisScreen->irqEnabled; + + smesa->FbBase = sPriv->pFB; + smesa->displayWidth = sPriv->fbWidth; + smesa->frontPitch = sPriv->fbStride; + + smesa->sarea = (SISSAREAPriv *)((char *)sPriv->pSAREA + + sisScreen->sarea_priv_offset); + +#if defined(SIS_DUMP) + IOBase4Debug = GET_IOBase (smesa); +#endif + + /* support ARGB8888 and RGB565 */ + switch (smesa->bytesPerPixel) + { + case 4: + smesa->redMask = 0x00ff0000; + smesa->greenMask = 0x0000ff00; + smesa->blueMask = 0x000000ff; + smesa->alphaMask = 0xff000000; + smesa->colorFormat = DST_FORMAT_ARGB_8888; + break; + case 2: + smesa->redMask = 0xf800; + smesa->greenMask = 0x07e0; + smesa->blueMask = 0x001f; + smesa->alphaMask = 0; + smesa->colorFormat = DST_FORMAT_RGB_565; + break; + default: + assert (0); + } + + /* TODO: index mode */ + + smesa->CurrentQueueLenPtr = &(smesa->sarea->QueueLength); + smesa->FrameCountPtr = &(smesa->sarea->FrameCount); + + /* set AGP */ + smesa->AGPSize = sisScreen->agp.size; + smesa->AGPBase = sisScreen->agp.map; + smesa->AGPAddr = sisScreen->agp.handle; + + /* set AGP command buffer */ + smesa->AGPCmdModeEnabled = GL_FALSE; + if (smesa->AGPSize != 0 && getenv("SIS_NO_AGP") == NULL) { + if (sisScreen->AGPCmdBufSize != 0) { + smesa->AGPCmdBufBase = smesa->AGPBase + sisScreen->AGPCmdBufOffset; + smesa->AGPCmdBufAddr = smesa->AGPAddr + sisScreen->AGPCmdBufOffset; + smesa->AGPCmdBufSize = sisScreen->AGPCmdBufSize; + + smesa->pAGPCmdBufNext = (GLint *)&(smesa->sarea->AGPCmdBufNext); + smesa->AGPCmdModeEnabled = GL_TRUE; + } + } + + smesa->GlobalFlag = 0L; + + smesa->Fallback = 0; + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext( ctx ); + _ac_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + + sisDDInitStateFuncs( ctx ); + sisDDInitState( smesa ); /* Initializes smesa->zFormat, important */ + sisInitVB( ctx ); + sisInitTriFuncs( ctx ); + sisDDInitDriverFuncs( ctx ); + sisDDInitSpanFuncs( ctx ); + sisDDInitStencilFuncs( ctx ); + sisDDInitTextureFuncs( ctx ); + + driInitExtensions( ctx, card_extensions, GL_FALSE ); + + /* TODO */ + /* smesa->blockWrite = SGRAMbw = IsBlockWrite (); */ + smesa->blockWrite = GL_FALSE; + + for (i = 0; i < SIS_MAX_TEXTURES; i++) { + smesa->TexStates[i] = 0; + smesa->PrevTexFormat[i] = 0; + } + + return GL_TRUE; +} + +void +sisDestroyContext ( __DRIcontextPrivate *driContextPriv ) +{ + sisContextPtr smesa = (sisContextPtr)driContextPriv->driverPrivate; + + assert( smesa != NULL ); + + if ( smesa != NULL ) { + _swsetup_DestroyContext( smesa->glCtx ); + _tnl_DestroyContext( smesa->glCtx ); + _ac_DestroyContext( smesa->glCtx ); + _swrast_DestroyContext( smesa->glCtx ); + + /* free the Mesa context */ + /* XXX: Is the next line needed? The DriverCtx (smesa) reference is + * needed for sisDDDeleteTexture, since it needs to call the FB/AGP free + * function. + */ + /* smesa->glCtx->DriverCtx = NULL; */ + _mesa_destroy_context(smesa->glCtx); + } + + FREE( smesa ); +} + +GLboolean +sisMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ) +{ + if ( driContextPriv ) { + GET_CURRENT_CONTEXT(ctx); + sisContextPtr oldSisCtx = ctx ? SIS_CONTEXT(ctx) : NULL; + sisContextPtr newSisCtx = (sisContextPtr) driContextPriv->driverPrivate; + + if ( newSisCtx != oldSisCtx) { + newSisCtx->GlobalFlag = GFLAG_ALL; + } + + newSisCtx->driDrawable = driDrawPriv; + + _mesa_make_current2( newSisCtx->glCtx, + (GLframebuffer *) driDrawPriv->driverPrivate, + (GLframebuffer *) driReadPriv->driverPrivate ); + + sisUpdateBufferSize( newSisCtx ); + sisUpdateClipping( newSisCtx->glCtx ); + + if ( newSisCtx->glCtx->Viewport.Width == 0 ) { + _mesa_set_viewport(newSisCtx->glCtx, 0, 0, + driDrawPriv->w, driDrawPriv->h); + } + } else { + _mesa_make_current( 0, 0 ); + } + + return GL_TRUE; +} + +GLboolean +sisUnbindContext( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + +void +sis_update_render_state( sisContextPtr smesa ) +{ + __GLSiSHardware *prev = &smesa->prev; + + mWait3DCmdQueue (45); + + if (smesa->GlobalFlag & GFLAG_ENABLESETTING) { + if (!smesa->clearTexCache) { + MMIO(REG_3D_TEnable, prev->hwCapEnable); + } else { + MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear); + MMIO(REG_3D_TEnable, prev->hwCapEnable); + smesa->clearTexCache = GL_FALSE; + } + } + + if (smesa->GlobalFlag & GFLAG_ENABLESETTING2) + MMIO(REG_3D_TEnable2, prev->hwCapEnable2); + + /* Z Setting */ + if (smesa->GlobalFlag & GFLAG_ZSETTING) + { + MMIO(REG_3D_ZSet, prev->hwZ); + MMIO(REG_3D_ZStWriteMask, prev->hwZMask); + MMIO(REG_3D_ZAddress, prev->hwOffsetZ); + } + + /* Alpha Setting */ + if (smesa->GlobalFlag & GFLAG_ALPHASETTING) + MMIO(REG_3D_AlphaSet, prev->hwAlpha); + + if (smesa->GlobalFlag & GFLAG_DESTSETTING) { + MMIO(REG_3D_DstSet, prev->hwDstSet); + MMIO(REG_3D_DstAlphaWriteMask, prev->hwDstMask); + MMIO(REG_3D_DstAddress, prev->hwOffsetDest); + } + + /* Line Setting */ +#if 0 + if (smesa->GlobalFlag & GFLAG_LINESETTING) + MMIO(REG_3D_LinePattern, prev->hwLinePattern); +#endif + + /* Fog Setting */ + if (smesa->GlobalFlag & GFLAG_FOGSETTING) + { + MMIO(REG_3D_FogSet, prev->hwFog); + MMIO(REG_3D_FogInverseDistance, prev->hwFogInverse); + MMIO(REG_3D_FogFarDistance, prev->hwFogFar); + MMIO(REG_3D_FogFactorDensity, prev->hwFogDensity); + } + + /* Stencil Setting */ + if (smesa->GlobalFlag & GFLAG_STENCILSETTING) { + MMIO(REG_3D_StencilSet, prev->hwStSetting); + MMIO(REG_3D_StencilSet2, prev->hwStSetting2); + } + + /* Miscellaneous Setting */ + if (smesa->GlobalFlag & GFLAG_DSTBLEND) + MMIO(REG_3D_DstBlendMode, prev->hwDstSrcBlend); + if (smesa->GlobalFlag & GFLAG_CLIPPING) { + MMIO(REG_3D_ClipTopBottom, prev->clipTopBottom); + MMIO(REG_3D_ClipLeftRight, prev->clipLeftRight); + } + + smesa->GlobalFlag &= ~GFLAG_RENDER_STATES; +} + +void +sis_update_texture_state (sisContextPtr smesa) +{ + __GLSiSHardware *prev = &smesa->prev; + + mWait3DCmdQueue (55); + if (smesa->clearTexCache || (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS)) { + MMIO(REG_3D_TEnable, prev->hwCapEnable | MASK_TextureCacheClear); + MMIO(REG_3D_TEnable, prev->hwCapEnable); + smesa->clearTexCache = GL_FALSE; + } + + /* Texture Setting */ + if (smesa->GlobalFlag & CFLAG_TEXTURERESET) + MMIO(REG_3D_TextureSet, prev->texture[0].hwTextureSet); + + if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP) + MMIO(REG_3D_TextureMip, prev->texture[0].hwTextureMip); + + /* + MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh); + MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow); + */ + + if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR) + MMIO(REG_3D_TextureBorderColor, prev->texture[0].hwTextureBorderColor); + + if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS) { + switch ((prev->texture[0].hwTextureSet & MASK_TextureLevel) >> 8) + { + case 11: + MMIO(REG_3D_TextureAddress11, prev->texture[0].texOffset11); + case 10: + MMIO(REG_3D_TextureAddress10, prev->texture[0].texOffset10); + MMIO(REG_3D_TexturePitch10, prev->texture[0].texPitch10); + case 9: + MMIO(REG_3D_TextureAddress9, prev->texture[0].texOffset9); + case 8: + MMIO(REG_3D_TextureAddress8, prev->texture[0].texOffset8); + MMIO(REG_3D_TexturePitch8, prev->texture[0].texPitch89); + case 7: + MMIO(REG_3D_TextureAddress7, prev->texture[0].texOffset7); + case 6: + MMIO(REG_3D_TextureAddress6, prev->texture[0].texOffset6); + MMIO(REG_3D_TexturePitch6, prev->texture[0].texPitch67); + case 5: + MMIO(REG_3D_TextureAddress5, prev->texture[0].texOffset5); + case 4: + MMIO(REG_3D_TextureAddress4, prev->texture[0].texOffset4); + MMIO(REG_3D_TexturePitch4, prev->texture[0].texPitch45); + case 3: + MMIO(REG_3D_TextureAddress3, prev->texture[0].texOffset3); + case 2: + MMIO(REG_3D_TextureAddress2, prev->texture[0].texOffset2); + MMIO(REG_3D_TexturePitch2, prev->texture[0].texPitch23); + case 1: + MMIO(REG_3D_TextureAddress1, prev->texture[0].texOffset1); + case 0: + MMIO(REG_3D_TextureAddress0, prev->texture[0].texOffset0); + MMIO(REG_3D_TexturePitch0, prev->texture[0].texPitch01); + } + } + if (smesa->GlobalFlag & CFLAG_TEXTURERESET_1) + MMIO(REG_3D_Texture1Set, prev->texture[1].hwTextureSet); + if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP_1) + MMIO(REG_3D_Texture1Mip, prev->texture[1].hwTextureMip); + + if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR_1) { + MMIO(REG_3D_Texture1BorderColor, + prev->texture[1].hwTextureBorderColor); + } + if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS_1) { + switch ((prev->texture[1].hwTextureSet & MASK_TextureLevel) >> 8) + { + case 11: + MMIO(REG_3D_Texture1Address11, prev->texture[1].texOffset11); + case 10: + MMIO(REG_3D_Texture1Address10, prev->texture[1].texOffset10); + MMIO(REG_3D_Texture1Pitch10, prev->texture[1].texPitch10); + case 9: + MMIO(REG_3D_Texture1Address9, prev->texture[1].texOffset9); + case 8: + MMIO(REG_3D_Texture1Address8, prev->texture[1].texOffset8); + MMIO(REG_3D_Texture1Pitch8, prev->texture[1].texPitch89); + case 7: + MMIO(REG_3D_Texture1Address7, prev->texture[1].texOffset7); + case 6: + MMIO(REG_3D_Texture1Address6, prev->texture[1].texOffset6); + MMIO(REG_3D_Texture1Pitch6, prev->texture[1].texPitch67); + case 5: + MMIO(REG_3D_Texture1Address5, prev->texture[1].texOffset5); + case 4: + MMIO(REG_3D_Texture1Address4, prev->texture[1].texOffset4); + MMIO(REG_3D_Texture1Pitch4, prev->texture[1].texPitch45); + case 3: + MMIO(REG_3D_Texture1Address3, prev->texture[1].texOffset3); + case 2: + MMIO(REG_3D_Texture1Address2, prev->texture[1].texOffset2); + MMIO(REG_3D_Texture1Pitch2, prev->texture[1].texPitch23); + case 1: + MMIO(REG_3D_Texture1Address1, prev->texture[1].texOffset1); + case 0: + MMIO(REG_3D_Texture1Address0, prev->texture[1].texOffset0); + MMIO(REG_3D_Texture1Pitch0, prev->texture[1].texPitch01); + } + } + + /* texture environment */ + if (smesa->GlobalFlag & GFLAG_TEXTUREENV) { + MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor); + MMIO(REG_3D_TextureColorBlendSet0, prev->hwTexBlendClr0); + MMIO(REG_3D_TextureAlphaBlendSet0, prev->hwTexBlendAlpha0); + } + if (smesa->GlobalFlag & GFLAG_TEXTUREENV_1) { + MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor); + MMIO(REG_3D_TextureColorBlendSet1, prev->hwTexBlendClr1); + MMIO(REG_3D_TextureAlphaBlendSet1, prev->hwTexBlendAlpha1); + } + + smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES; +} + +void +sis_fatal_error (void) +{ + /* free video memory, or the framebuffer device will do it automatically */ + + fprintf(stderr, "Fatal errors in sis_dri.so\n"); + exit (-1); +} diff --git a/src/mesa/drivers/dri/sis/sis_context.h b/src/mesa/drivers/dri/sis/sis_context.h new file mode 100644 index 00000000000..c4248e5420b --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_context.h @@ -0,0 +1,446 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#ifndef _sis_ctx_h_ +#define _sis_ctx_h_ + +#include "context.h" +#include "dri_util.h" + +#include "sis_screen.h" +#include "sis_common2.h" +#include "sis_dri.h" + +/* for GLboolean */ +#include + +#define PCI_CHIP_SIS300 0x0300 +#define PCI_CHIP_SIS630 0x6300 +#define PCI_CHIP_SIS540 0x5300 + +#define NEW_TEXTURING 0x1 +#define NEW_TEXTURE_ENV 0x2 + +/* Flags for software fallback cases: + */ +#define SIS_FALLBACK_TEXTURE 0x0001 +#define SIS_FALLBACK_TEXTURE0 0x0002 +#define SIS_FALLBACK_TEXTURE1 0x0004 +#define SIS_FALLBACK_TEXENV0 0x0008 +#define SIS_FALLBACK_TEXENV1 0x0010 +#define SIS_FALLBACK_DRAW_BUFFER 0x0020 +#define SIS_FALLBACK_STENCIL 0x0040 +#define SIS_FALLBACK_FORCE 0x8000 + +/* Flags for hardware state that needs to be updated */ +#define GFLAG_ENABLESETTING 0x00000001 +#define GFLAG_ENABLESETTING2 0x00000002 +#define GFLAG_ZSETTING 0x00000004 +#define GFLAG_ALPHASETTING 0x00000008 +#define GFLAG_DESTSETTING 0x00000010 +#define GFLAG_LINESETTING 0x00000020 +#define GFLAG_STENCILSETTING 0x00000040 +#define GFLAG_FOGSETTING 0x00000080 +#define GFLAG_DSTBLEND 0x00000100 +#define GFLAG_CLIPPING 0x00000200 +#define CFLAG_TEXTURERESET 0x00000400 +#define GFLAG_TEXTUREMIPMAP 0x00000800 +#define GFLAG_TEXBORDERCOLOR 0x00001000 +#define GFLAG_TEXTUREADDRESS 0x00002000 +#define GFLAG_TEXTUREENV 0x00004000 +#define CFLAG_TEXTURERESET_1 0x00008000 +#define GFLAG_TEXTUREMIPMAP_1 0x00010000 +#define GFLAG_TEXBORDERCOLOR_1 0x00020000 +#define GFLAG_TEXTUREADDRESS_1 0x00040000 +#define GFLAG_TEXTUREENV_1 0x00080000 +#define GFLAG_ALL 0x000fffff + +#define GFLAG_TEXTURE_STATES (CFLAG_TEXTURERESET | GFLAG_TEXTUREMIPMAP | \ + GFLAG_TEXBORDERCOLOR | GFLAG_TEXTUREADDRESS | \ + CFLAG_TEXTURERESET_1 | GFLAG_TEXTUREMIPMAP_1 | \ + GFLAG_TEXBORDERCOLOR_1 | \ + GFLAG_TEXTUREADDRESS_1 | \ + GFLAG_TEXTUREENV | GFLAG_TEXTUREENV_1) + + +#define GFLAG_RENDER_STATES (GFLAG_ENABLESETTING | GFLAG_ENABLESETTING2 | \ + GFLAG_ZSETTING | GFLAG_ALPHASETTING | \ + GFLAG_DESTSETTING | GFLAG_FOGSETTING | \ + GFLAG_STENCILSETTING | GFLAG_DSTBLEND | \ + GFLAG_CLIPPING) + +/* Use the templated vertex format: + */ +#define TAG(x) sis##x +#include "tnl_dd/t_dd_vertex.h" +#undef TAG + +/* Subpixel offsets for window coordinates (triangles): + */ +#define SUBPIXEL_X (-0.5F) +#define SUBPIXEL_Y (-0.5F) + +#define SIS_MAX_TEXTURE_LEVELS 11 + +typedef struct { + GLbyte *Data; /* Pointer to texture in offscreen */ + GLuint memType; /* VIDEO_TYPE or AGP_TYPE */ + void *handle; /* Handle for sisFree*() */ + GLuint pitch; + GLuint size; +} sisTexImage; + +typedef struct sis_tex_obj { + sisTexImage image[SIS_MAX_TEXTURE_LEVELS]; /* Image data for each mipmap + * level */ + GLenum format; /* One of GL_ALPHA, GL_INTENSITY, GL_LUMINANCE, + * GL_LUMINANCE_ALPHA, GL_RGB, GL_RGBA */ + GLint hwformat; /* One of the TEXEL_ defines */ + GLint numImages; /* Number of images loaded into .image */ +} sisTexObj, *sisTexObjPtr; + +/* + ** Device dependent context state + */ +typedef struct __GLSiSTextureRec +{ + GLint hwTextureSet; + GLint hwTextureMip; + GLint hwTextureClrHigh; + GLint hwTextureClrLow; + GLint hwTextureBorderColor; + + GLint texOffset0; + GLint texOffset1; + GLint texOffset2; + GLint texOffset3; + GLint texOffset4; + GLint texOffset5; + GLint texOffset6; + GLint texOffset7; + GLint texOffset8; + GLint texOffset9; + GLint texOffset10; + GLint texOffset11; + + GLint texPitch01; + GLint texPitch23; + GLint texPitch45; + GLint texPitch67; + GLint texPitch89; + GLint texPitch10; +} __GLSiSTexture; + +typedef struct __GLSiSHardwareRec +{ + GLint hwCapEnable, hwCapEnable2; /* Enable Setting */ + + GLint hwOffsetZ, hwZ; /* Z Setting */ + + GLint hwZBias, hwZMask; /* Z Setting */ + + GLint hwAlpha; /* Alpha Setting */ + + GLint hwDstSet, hwDstMask; /* Destination Setting */ + + GLint hwOffsetDest; /* Destination Setting */ + + GLint hwLinePattern; /* Line Setting */ + + GLint hwFog; /* Fog Setting */ + + GLint hwFogFar, hwFogInverse; /* Fog Distance setting */ + + GLint hwFogDensity; /* Fog factor & density */ + + GLint hwStSetting, hwStSetting2; /* Stencil Setting */ + + GLint hwStOffset; /* Stencil Setting */ + + GLint hwDstSrcBlend; /* Blending mode Setting */ + + GLint clipTopBottom; /* Clip for Top & Bottom */ + + GLint clipLeftRight; /* Clip for Left & Right */ + + struct __GLSiSTextureRec texture[2]; + + GLint hwTexEnvColor; /* Texture Blending Setting */ + + GLint hwTexBlendClr0; + GLint hwTexBlendClr1; + GLint hwTexBlendAlpha0; + GLint hwTexBlendAlpha1; + +} +__GLSiSHardware; + +typedef struct sis_context sisContextRec; +typedef struct sis_context *sisContextPtr; + +typedef void (*sis_quad_func)( sisContextPtr, + sisVertex *, + sisVertex *, + sisVertex *, + sisVertex * ); + +typedef void (*sis_tri_func)( sisContextPtr, + sisVertex *, + sisVertex *, + sisVertex * ); + +typedef void (*sis_line_func)( sisContextPtr, + sisVertex *, + sisVertex * ); + +typedef void (*sis_point_func)( sisContextPtr, + sisVertex * ); + +/* Device dependent context state */ + +struct sis_context +{ + /* This must be first in this structure */ + GLcontext *glCtx; + + /* 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; + + unsigned int virtualX, virtualY; + unsigned int bytesPerPixel; + unsigned char *IOBase; + unsigned char *FbBase; + unsigned int displayWidth; + unsigned int frontOffset; + unsigned int frontPitch; + + /* HW RGBA layout */ + unsigned int redMask, greenMask, blueMask, alphaMask; + unsigned int colorFormat; + + /* Z format */ + unsigned int zFormat; + + /* Clear patterns, 4 bytes */ + unsigned int clearColorPattern; + unsigned int clearZStencilPattern; + + /* Fallback rasterization functions + */ + sis_point_func draw_point; + sis_line_func draw_line; + sis_tri_func draw_tri; + sis_quad_func draw_quad; + + GLuint hw_primitive; + GLenum raster_primitive; + GLenum render_primitive; + + /* DRM fd */ + int driFd; + + /* AGP Memory */ + unsigned int AGPSize; + unsigned char *AGPBase; + unsigned int AGPAddr; + + /* AGP Command Buffer */ + /* TODO: use Global variables */ + + unsigned char *AGPCmdBufBase; + GLint AGPCmdBufAddr; + unsigned int AGPCmdBufSize; + GLint *pAGPCmdBufNext; + GLboolean AGPCmdModeEnabled; + + /* register 0x89F4 */ + GLint AGPParseSet; + + /* register 0x89F8 */ + GLint dwPrimitiveSet; + + __GLSiSHardware prev, current; + + int Chipset; + + GLint drawableID; + + /* SGRAM block write */ + GLboolean blockWrite; + + GLint GlobalFlag; + + /* Stereo */ + GLboolean isFullScreen; + GLboolean useStereo; + GLboolean stereoEnabled; + int stereo_drawIndex; + int stereo_drawSide; + GLboolean irqEnabled; + + GLboolean clearTexCache; + + GLuint TexStates[SIS_MAX_TEXTURES]; + GLuint PrevTexFormat[SIS_MAX_TEXTURES]; + + int *CurrentQueueLenPtr; + unsigned int *FrameCountPtr; + + /* Front/back/depth buffer info */ + GLuint width, height; /* size of buffers */ + GLint bottom; /* used for FLIP macro */ + GLvoid *backbuffer; + unsigned int backOffset; + unsigned int backPitch; + GLvoid *depthbuffer; + unsigned int depthPitch; + void *zbFree, *bbFree; /* Cookies for freeing buffers */ + ENGPACKET zClearPacket, cbClearPacket; + + /* Drawable, cliprect and scissor information + */ + GLint drawOffset, drawPitch; + GLint readOffset, readPitch; + + /* 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; + + sisScreenPtr sisScreen; /* Screen private DRI data */ + SISSAREAPrivPtr sarea; /* Private SAREA data */ +}; + +#define SIS_CONTEXT(ctx) ((sisContextPtr)(ctx->DriverCtx)) + +/* Macros */ +#define GET_IOBase(x) ((x)->IOBase) +#define GET_FbBase(x) ((x)->FbBase) +#define GET_AGPBase(x) ((x)->AGPBase) +#define GET_DEPTH(x) ((x)->bytesPerPixel) +#define GET_WIDTH(x) ((x)->displayWidth) +#define GET_FbPos(smesa,x,y) (GET_FbBase(smesa)+(x)*GET_DEPTH(smesa)\ + +(y)*smesa->frontPitch) + +#define GET_ColorFormat(x) ((x)->colorFormat) + +#define GET_RMASK(x) ((x)->redMask) +#define GET_GMASK(x) ((x)->greenMask) +#define GET_BMASK(x) ((x)->blueMask) +#define GET_AMASK(x) ((x)->alphaMask) +#define Y_FLIP(Y) (smesa->bottom - (Y)) + +#define SISPACKCOLOR565( r, g, b ) \ + ((((r) & 0xf8) << 8) | (((g) & 0xfc) << 3) | (((b) & 0xf8) >> 3)) + +#define SISPACKCOLOR8888( r, g, b, a ) \ + (((a) << 24) | ((r) << 16) | ((g) << 8) | (b)) + +#define SIS_VERBOSE 0 + + +#define MMIO(reg, value) \ +{\ + *(GLint *)(GET_IOBase(smesa) + (reg)) = value; \ +} + +#define MMIO_READ(reg) *(volatile GLint *)(smesa->IOBase + (reg)) +#define MMIO_READf(reg) *(volatile GLfloat *)(smesa->IOBase + (reg)) + +#define mEndPrimitive() \ +{ \ + *(GET_IOBase(smesa) + REG_3D_EndPrimitiveList) = 0xFF; \ + *(GLint *)(GET_IOBase(smesa) + 0x8b60) = (GLint)(-1); \ +} + +/* Lock required */ +#define mWait3DCmdQueue(wLen) \ +/* Update the mirrored queue pointer if it doesn't indicate enough space */ \ +if (*(smesa->CurrentQueueLenPtr) < (wLen)) { \ + *(smesa->CurrentQueueLenPtr) = \ + (*(GLint *)(GET_IOBase(smesa) + REG_QueueLen) & MASK_QueueLen) - 20; \ + /* Spin and wait if the queue is actually too full */ \ + if (*(smesa->CurrentQueueLenPtr) < (wLen)) \ + WaitingFor3dIdle(smesa, wLen); \ + *(smesa->CurrentQueueLenPtr) -= wLen; \ +} + +enum _sis_verbose { + VERBOSE_SIS_BUFFER = 0x1, + VERBOSE_SIS_MEMORY = 0x2 +}; + +extern GLboolean sisCreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ); +extern void sisDestroyContext( __DRIcontextPrivate * ); + +extern GLboolean sisMakeCurrent( __DRIcontextPrivate *driContextPriv, + __DRIdrawablePrivate *driDrawPriv, + __DRIdrawablePrivate *driReadPriv ); + +extern GLboolean sisUnbindContext( __DRIcontextPrivate *driContextPriv ); + +void WaitEngIdle (sisContextPtr smesa); +void Wait2DEngIdle (sisContextPtr smesa); +void WaitingFor3dIdle(sisContextPtr smesa, int wLen); + +/* update to hw */ +extern void sis_update_texture_state( sisContextPtr smesa ); +extern void sis_update_render_state( sisContextPtr smesa ); + +void sis_fatal_error (void); + +#endif diff --git a/src/mesa/drivers/dri/sis/sis_dd.c b/src/mesa/drivers/dri/sis/sis_dd.c new file mode 100644 index 00000000000..9dc3688b07f --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_dd.c @@ -0,0 +1,177 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + * + */ + +#include "sis_context.h" +#include "sis_dd.h" +#include "sis_lock.h" +#include "sis_alloc.h" +#include "sis_state.h" + +#include "swrast/swrast.h" + +#include "utils.h" + +#define DRIVER_DATE "20030810" + +/* Return the width and height of the given buffer. + */ +static void +sisDDGetBufferSize( GLframebuffer *buffer, + GLuint *width, GLuint *height ) +{ + GET_CURRENT_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT(ctx); + + LOCK_HARDWARE(); + *width = smesa->driDrawable->w; + *height = smesa->driDrawable->h; + UNLOCK_HARDWARE(); +} + +/* Return various strings for glGetString(). + */ +static const GLubyte * +sisDDGetString( GLcontext *ctx, GLenum name ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + static char buffer[128]; + unsigned offset; + GLuint agp_mode = (smesa->AGPSize > 0); + + switch ( name ) + { + case GL_VENDOR: + return (GLubyte *)"Eric Anholt"; + + case GL_RENDERER: + offset = driGetRendererString( buffer, "SiS", DRIVER_DATE, agp_mode ); + + return (GLubyte *)buffer; + + default: + return NULL; + } +} + +/* Send all commands to the hardware. No-op, due to mmio. + */ +static void +sisDDFlush( GLcontext *ctx ) +{ + /* Do nothing */ +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +static void +sisDDFinish( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + sisDDFlush( ctx ); + WaitEngIdle( smesa ); +} + +void +sisUpdateBufferSize( sisContextPtr smesa ) +{ + __GLSiSHardware *current = &smesa->current; + __GLSiSHardware *prev = &smesa->prev; + GLuint z_depth; + + /* XXX Should get the base offset of the frontbuffer from the X Server */ + smesa->frontOffset = smesa->driDrawable->x * smesa->bytesPerPixel + + smesa->driDrawable->y * smesa->frontPitch; + + if ( smesa->width == smesa->driDrawable->w && + smesa->height == smesa->driDrawable->h ) + { + return; + } + + smesa->width = smesa->driDrawable->w; + smesa->height = smesa->driDrawable->h; + smesa->bottom = smesa->height - 1; + + if ( smesa->backbuffer ) + sisFreeBackbuffer( smesa ); + if ( smesa->depthbuffer ) + sisFreeZStencilBuffer( smesa ); + + if ( smesa->glCtx->Visual.depthBits > 0 ) + sisAllocZStencilBuffer( smesa ); + if ( smesa->glCtx->Visual.doubleBufferMode ) + sisAllocBackbuffer( smesa ); + + switch (smesa->zFormat) + { + case SiS_ZFORMAT_Z16: + z_depth = 2; + break; + case SiS_ZFORMAT_Z32: + case SiS_ZFORMAT_S8Z24: + z_depth = 4; + break; + default: + assert( 0 ); + } + + current->hwZ &= ~MASK_ZBufferPitch; + current->hwZ |= smesa->width * z_depth >> 2; + current->hwOffsetZ = ( (GLint)smesa->depthbuffer - + (GLint)GET_FbBase(smesa) ) >> 2; + + if ((current->hwOffsetZ != prev->hwOffsetZ) || (current->hwZ != prev->hwZ)) { + prev->hwOffsetZ = current->hwOffsetZ; + prev->hwZ = current->hwZ; + smesa->GlobalFlag |= GFLAG_ZSETTING; + } + + sisUpdateClipping( smesa->glCtx ); +} + +/* Initialize the driver's misc functions. + */ +void +sisDDInitDriverFuncs( GLcontext *ctx ) +{ + ctx->Driver.GetBufferSize = sisDDGetBufferSize; + ctx->Driver.ResizeBuffers = _swrast_alloc_buffers; + ctx->Driver.GetString = sisDDGetString; + ctx->Driver.Finish = sisDDFinish; + ctx->Driver.Flush = sisDDFlush; + ctx->Driver.Error = NULL; +} diff --git a/src/mesa/drivers/dri/sis/sis_dd.h b/src/mesa/drivers/dri/sis/sis_dd.h new file mode 100644 index 00000000000..00a94cee564 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_dd.h @@ -0,0 +1,43 @@ +/************************************************************************** + +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Eric Anholt + */ + +#ifndef __SIS_DD_H__ +#define __SIS_DD_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void sisUpdateBufferSize( sisContextPtr smesa ); + +extern void sisDDInitDriverFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/src/mesa/drivers/dri/sis/sis_debug.c b/src/mesa/drivers/dri/sis/sis_debug.c new file mode 100644 index 00000000000..e950bcee015 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_debug.c @@ -0,0 +1,158 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +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, 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 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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_debug.c,v 1.5 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * + */ + +/* + * dump HW states, set environment variable SIS_DEBUG + * to enable these functions + */ + +#include +#include + +#include "sis_context.h" + +/* for SiS 300/630/540 */ +#define MMIOLength (0x8FFF-0x8800+1) +#define MMIO3DOffset (0x8800) +#define FILE_NAME "300.dump" + +char *IOBase4Debug = 0; + +char *prevLockFile = NULL; +int prevLockLine = 0; + +GLint _empty[0x10000]; + +void +dump_agp (void *addr, int dword_count) +{ + if (!getenv ("SIS_DEBUG")) + return; + + { + int i; + FILE *file = fopen ("300agp.dump", "w"); + + if (file) + { + for (i = 0; i < dword_count; i++) + { + fprintf (file, "%f\n", *(float *) addr); + ((unsigned char *) addr) += 4; + } + fclose (file); + } + } +} + +#ifndef _SOLO +void +d2f_once (GLcontext * ctx) +{ + XMesaContext xmesa = (XMesaContext) ctx->DriverCtx; + sisContextPtr smesa = SIS_CONTEXT(ctx); + + static int serialNumber = -1; + + if (serialNumber == smesa->serialNumber) + return; + else + serialNumber = smesa->serialNumber; + + d2f(); +} + +void +d2f (void) +{ + if (!getenv ("SIS_DEBUG")) + return; + + /* dump 0x8800 - 0x8AFF */ + { + int fh; + int rval; + void *addr = IOBase4Debug + MMIO3DOffset; + + assert (IOBase4Debug); + + if ((fh = open (FILE_NAME, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE)) != -1) + { + rval = write (fh, addr, MMIOLength); + assert (rval != -1); + close (fh); + } + } +} + +/* dump to HW */ +void +d2h (char *file_name) +{ + int fh; + int rval; + void *addr[MMIOLength]; + + if (!getenv ("SIS_DEBUG")) + return; + + if ((fh = open (file_name, O_CREAT, S_IREAD | S_IWRITE)) != -1) + { + rval = read (fh, addr, MMIOLength); + assert (rval != -1); + close (fh); + } + memcpy (IOBase4Debug + MMIO3DOffset, addr, MMIOLength); + +} + +/* dump video memory to file */ +void +dvidmem (unsigned char *addr, int size) +{ + int fh; + int rval; + static char *file_name = "vidmem.dump"; + + if (!getenv ("SIS_DEBUG")) + return; + + if ((fh = open (file_name, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE)) != -1) + { + rval = write (fh, addr, size); + assert (rval != -1); + close (fh); + } +} +#endif diff --git a/src/mesa/drivers/dri/sis/sis_debug.h b/src/mesa/drivers/dri/sis/sis_debug.h new file mode 100644 index 00000000000..6b7c79698e9 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_debug.h @@ -0,0 +1,45 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +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, 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 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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_debug.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * + */ + +#ifndef _sis_debug_h_ +#define _sis_debug_h_ + +void dump_agp (void *addr, int dword_count); +void d2f (void); +void d2f_once (GLcontext * ctx); +void d2h (char *file_name); +void dvidmem (unsigned char *addr, int size); +extern char *IOBase4Debug; + +#endif diff --git a/src/mesa/drivers/dri/sis/sis_fog.c b/src/mesa/drivers/dri/sis/sis_fog.c new file mode 100644 index 00000000000..8daa9a0f5e3 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_fog.c @@ -0,0 +1,181 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_fog.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "swrast/swrast.h" +#include "macros.h" + +static GLint convertFtToFogFt( GLfloat dwInValue ); + +void +sisDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *current = &smesa->current; + + float fArg; + GLint fogColor; + + switch (pname) + { + case GL_FOG_MODE: + current->hwFog &= ~MASK_FogMode; + switch (ctx->Fog.Mode) + { + case GL_LINEAR: + current->hwFog |= FOGMODE_LINEAR; + _swrast_allow_pixel_fog( ctx, GL_TRUE ); + _swrast_allow_vertex_fog( ctx, GL_FALSE ); + break; + case GL_EXP: + if (ctx->Hint.Fog == GL_NICEST || smesa->AGPCmdModeEnabled) { + current->hwFog |= FOGMODE_EXP; + _swrast_allow_pixel_fog( ctx, GL_TRUE ); + _swrast_allow_vertex_fog( ctx, GL_FALSE ); + } else { /* GL_DONTCARE or GL_FASTEST */ + current->hwFog |= FOGMODE_CHEAP; + _swrast_allow_pixel_fog( ctx, GL_FALSE ); + _swrast_allow_vertex_fog( ctx, GL_TRUE ); + } + break; + case GL_EXP2: + current->hwFog |= FOGMODE_EXP2; + _swrast_allow_pixel_fog( ctx, GL_TRUE ); + _swrast_allow_vertex_fog( ctx, GL_FALSE ); + break; + } + break; + case GL_FOG_DENSITY: + current->hwFogDensity = convertFtToFogFt( ctx->Fog.Density ); + break; + case GL_FOG_START: + case GL_FOG_END: + fArg = 1.0 / (ctx->Fog.End - ctx->Fog.Start); + current->hwFogInverse = doFPtoFixedNoRound( fArg, 10 ); + if (pname == GL_FOG_END) + { + if (smesa->Chipset == PCI_CHIP_SIS300) + current->hwFogFar = doFPtoFixedNoRound( ctx->Fog.End, 10 ); + else + current->hwFogFar = doFPtoFixedNoRound( ctx->Fog.End, 6 ); + } + break; + case GL_FOG_INDEX: + /* TODO */ + break; + case GL_FOG_COLOR: + fogColor = FLOAT_TO_UBYTE( ctx->Fog.Color[0] ) << 16; + fogColor |= FLOAT_TO_UBYTE( ctx->Fog.Color[1] ) << 8; + fogColor |= FLOAT_TO_UBYTE( ctx->Fog.Color[2] ); + current->hwFog &= 0xff000000; + current->hwFog |= fogColor; + break; + } +} + +GLint +doFPtoFixedNoRound( GLfloat dwInValue, int nFraction ) +{ + GLint dwMantissa; + int nTemp; + union { int i; float f; } u; + GLint val; + + u.f = dwInValue; + val = u.i; + + if (val == 0) + return 0; + nTemp = (int) (val & 0x7F800000) >> 23; + nTemp = nTemp - 127 + nFraction - 23; + dwMantissa = (val & 0x007FFFFF) | 0x00800000; + + if (nTemp < -25) + return 0; + if (nTemp > 0) + dwMantissa <<= nTemp; + else { + nTemp = -nTemp; + dwMantissa >>= nTemp; + } + if (val & 0x80000000) + dwMantissa = ~dwMantissa + 1; + return dwMantissa; +} + +/* s[8].23->s[7].10 */ +static GLint +convertFtToFogFt( GLfloat dwInValue ) +{ + GLint dwMantissa, dwExp; + GLint dwRet; + union { int i; float f; } u; + GLint val; + + u.f = dwInValue; + val = u.i; + + if (val == 0) + return 0; + + /* ----- Standard float Format: s[8].23 ----- + * ----- = (-1)^S * 2^(E - 127) * (1 + M / 2^23) ----- + * ----- = (-1)^S * 2^((E-63) - 64) * (1 + (M/2^13) / 2^10) ----- + * ----- Density float Format: s[7].10 ----- + * ----- New Exponential = E - 63 ----- + * ----- New Mantissa = M / 2^13 ----- + * ----- ----- + */ + + dwExp = (val & 0x7F800000) >> 23; + dwExp -= 63; + + if (dwExp < 0) + return 0; + + if (dwExp <= 0x7F) + dwMantissa = (val & 0x007FFFFF) >> (23 - 10); + else { + /* ----- To Return +Max(or -Max) ----- */ + dwExp = 0x7F; + dwMantissa = 0x3FF; + } + + dwRet = (val & 0x80000000) >> (31 - 17); /* Shift Sign Bit */ + + dwRet |= (dwExp << 10) | dwMantissa; + + return dwRet; +} diff --git a/src/mesa/drivers/dri/sis/sis_lock.c b/src/mesa/drivers/dri/sis/sis_lock.c new file mode 100644 index 00000000000..1972ff4c16f --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_lock.c @@ -0,0 +1,77 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2003 Eric Anholt +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: + * Eric Anholt + */ + +#include "context.h" +#include "sis_context.h" +#include "sis_lock.h" +#include "sis_dd.h" +#include "sis_state.h" + +/* 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 +sisGetLock( sisContextPtr smesa, GLuint flags ) +{ + __DRIdrawablePrivate *dPriv = smesa->driDrawable; + __DRIscreenPrivate *sPriv = smesa->driScreen; + SISSAREAPrivPtr sarea = smesa->sarea; + + drmGetLock( smesa->driFd, smesa->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 ( smesa->lastStamp != dPriv->lastStamp ) { + sisUpdateBufferSize( smesa ); + sisUpdateClipping( smesa->glCtx ); + sisDDDrawBuffer( smesa->glCtx, smesa->glCtx->Color.DrawBuffer ); + smesa->lastStamp = dPriv->lastStamp; + } + + if ( sarea->CtxOwner != smesa->hHWContext ) { + sarea->CtxOwner = smesa->hHWContext; + smesa->GlobalFlag = GFLAG_ALL; + } +} diff --git a/src/mesa/drivers/dri/sis/sis_lock.h b/src/mesa/drivers/dri/sis/sis_lock.h new file mode 100644 index 00000000000..1c43d8cc34c --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_lock.h @@ -0,0 +1,87 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#ifndef __SIS_LOCK_H +#define __SIS_LOCK_H + +extern void sisGetLock( sisContextPtr smesa, GLuint flags ); + +#ifdef DEBUG_LOCKING +extern char *prevLockFile; +extern int prevLockLine; +#define DEBUG_LOCK() \ + do { \ + prevLockFile=(__FILE__); \ + prevLockLine=(__LINE__); \ + } while (0) +#define DEBUG_RESET() \ + do { \ + prevLockFile=NULL; \ + prevLockLine=0; \ + } while (0) +#define DEBUG_CHECK_LOCK() \ + do { \ + if(prevLockFile){ \ + fprintf(stderr, "LOCK SET : %s:%d\n", __FILE__, __LINE__); \ + } \ + } while (0) +#else +#define DEBUG_LOCK() +#define DEBUG_RESET() +#define DEBUG_CHECK_LOCK() +#endif + +/* Lock the hardware using the global current context */ +#define LOCK_HARDWARE() \ + do { \ + char __ret=0; \ + mEndPrimitive(); \ + DEBUG_CHECK_LOCK(); \ + DRM_CAS( smesa->driHwLock, smesa->hHWContext, \ + (DRM_LOCK_HELD | smesa->hHWContext), __ret ); \ + if ( __ret != 0 ) \ + sisGetLock( smesa, 0 ); \ + DEBUG_LOCK(); \ + } while (0) + +/* Unlock the hardware using the global current context */ +#define UNLOCK_HARDWARE() \ + do { \ + mEndPrimitive(); \ + DRM_UNLOCK(smesa->driFd, smesa->driHwLock, \ + smesa->hHWContext); \ + DEBUG_RESET(); \ + } while (0) + +#endif diff --git a/src/mesa/drivers/dri/sis/sis_reg.h b/src/mesa/drivers/dri/sis/sis_reg.h new file mode 100644 index 00000000000..41d7e74da8d --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_reg.h @@ -0,0 +1,927 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +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, 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 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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_reg.h,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#ifndef _sis_reg_h_ +#define _sis_reg_h_ + +/* + * Define All the Register Address of 6327 + */ + +#define REG_QueueLen 0x8240 + +#define REG_3D_TSFSa 0x8800 +#define REG_3D_TSZa 0x8804 +#define REG_3D_TSXa 0x8808 +#define REG_3D_TSYa 0x880C +#define REG_3D_TSARGBa 0x8810 +#define REG_3D_TSWGa 0x8814 +#define REG_3D_TSUAa 0x8818 +#define REG_3D_TSVAa 0x881C +#define REG_3D_TSUBa 0x8820 +#define REG_3D_TSVBa 0x8824 +#define REG_3D_TSUCa 0x8828 +#define REG_3D_TSVCa 0x882C + +#define REG_3D_TSFSb 0x8830 +#define REG_3D_TSZb 0x8834 +#define REG_3D_TSXb 0x8838 +#define REG_3D_TSYb 0x883C +#define REG_3D_TSARGBb 0x8840 +#define REG_3D_TSWGb 0x8844 +#define REG_3D_TSUAb 0x8848 +#define REG_3D_TSVAb 0x884C +#define REG_3D_TSUBb 0x8850 +#define REG_3D_TSVBb 0x8854 +#define REG_3D_TSUCb 0x8858 +#define REG_3D_TSVCb 0x885C + +#define REG_3D_TSFSc 0x8860 +#define REG_3D_TSZc 0x8864 +#define REG_3D_TSXc 0x8868 +#define REG_3D_TSYc 0x886C +#define REG_3D_TSARGBc 0x8870 +#define REG_3D_TSWGc 0x8874 +#define REG_3D_TSUAc 0x8878 +#define REG_3D_TSVAc 0x887C +#define REG_3D_TSUBc 0x8880 +#define REG_3D_TSVBc 0x8884 +#define REG_3D_TSUCc 0x8888 +#define REG_3D_TSVCc 0x888C + +/* + * REG_3D_AGPCmdSetting (89e4h-89f7) + */ +#define REG_3D_AGPCmBase 0x89E4 +#define REG_3D_AGPRmDwNum 0x89E8 +#define REG_3D_AGPTtDwNum 0x89EC +#define REG_3D_AGPCmFire 0x89F0 + +#define REG_3D_ParsingSet 0x89F4 +#define REG_3D_PrimitiveSet 0x89F8 +#define REG_3D_ShadeMode 0x89F8 +#define REG_3D_EngineFire 0x89FC +#define REG_3D_EngineStatus 0x89FC +#define REG_3D_TEnable 0x8A00 +#define REG_3D_TEnable2 0x8A04 + +#define REG_3D_ZSet 0x8A08 +#define REG_3D_ZBias 0x8A0C +#define REG_3D_ZStWriteMask 0x8A10 + +#define REG_3D_ZAddress 0x8A14 +#define REG_3D_AlphaSet 0x8A18 +#define REG_3D_AlphaAddress 0x8A1C +#define REG_3D_DstSet 0x8A20 +#define REG_3D_DstAlphaWriteMask 0x8A24 + +#define REG_3D_DstAddress 0x8A28 + +#define REG_3D_LinePattern 0x8A2C + +#define REG_3D_FogSet 0x8A30 + +#define REG_3D_FogFarDistance 0x8A34 +#define REG_3D_FogInverseDistance 0x8A38 +#define REG_3D_FogFactorDensity 0x8A3C + +#define REG_3D_StencilSet 0x8A44 +#define REG_3D_StencilSet2 0x8A48 +#define REG_3D_StencilAddress 0x8A4C + +#define REG_3D_DstBlendMode 0x8A50 +#define REG_3D_SrcBlendMode 0x8A50 +#define REG_3D_ClipTopBottom 0x8A54 +#define REG_3D_ClipLeftRight 0x8A58 + +#define REG_3D_Brightness 0x8A5C + +#define REG_3D_BumpMapSet 0x8A68 +#define REG_3D_BumpMapAddress 0x8A6C +#define REG_3D_BumpMapPitch 0x8A70 +#define REG_3D_BumpMapMatrix0 0x8A74 +#define REG_3D_BumpMapMatrix1 0x8A78 + +/* + * Define the Texture Register Address of 6326 + */ +#define REG_3D_TextureSet 0x8A7C +#define REG_3D_TextureWidthHeight 0x8A7C +#define REG_3D_TextureMip 0x8A80 + +#define REG_3D_TextureTransparencyColorHigh 0x8A84 +#define REG_3D_TextureTransparencyColorLow 0x8A88 +#define REG_3D_TextureBorderColor 0x8A8C +#define REG_3D_TextureAddress0 0x8A90 +#define REG_3D_TextureAddress1 0x8A94 +#define REG_3D_TextureAddress2 0x8A98 +#define REG_3D_TextureAddress3 0x8A9C +#define REG_3D_TextureAddress4 0x8AA0 +#define REG_3D_TextureAddress5 0x8AA4 +#define REG_3D_TextureAddress6 0x8AA8 +#define REG_3D_TextureAddress7 0x8AAC +#define REG_3D_TextureAddress8 0x8AB0 +#define REG_3D_TextureAddress9 0x8AB4 +#define REG_3D_TextureAddress10 0x8AB8 +#define REG_3D_TextureAddress11 0x8ABC +#define REG_3D_TexturePitch0 0x8AC0 +#define REG_3D_TexturePitch1 0x8AC0 +#define REG_3D_TexturePitch2 0x8AC4 +#define REG_3D_TexturePitch3 0x8AC4 +#define REG_3D_TexturePitch4 0x8AC8 +#define REG_3D_TexturePitch5 0x8AC8 +#define REG_3D_TexturePitch6 0x8ACC +#define REG_3D_TexturePitch7 0x8ACC +#define REG_3D_TexturePitch8 0x8AD0 +#define REG_3D_TexturePitch9 0x8AD0 +#define REG_3D_TexturePitch10 0x8AD4 + +#define REG_3D_Texture1Set 0x8ADC +#define REG_3D_Texture1WidthHeight 0x8ADC +#define REG_3D_Texture1Mip 0x8AE0 + +#define REG_3D_Texture1TransparencyColorHigh 0x8AE4 +#define REG_3D_Texture1TransparencyColorLow 0x8AE8 +#define REG_3D_Texture1BorderColor 0x8AEC +#define REG_3D_Texture1Address0 0x8AF0 +#define REG_3D_Texture1Address1 0x8AF4 +#define REG_3D_Texture1Address2 0x8AF8 +#define REG_3D_Texture1Address3 0x8AFC +#define REG_3D_Texture1Address4 0x8B00 +#define REG_3D_Texture1Address5 0x8B04 +#define REG_3D_Texture1Address6 0x8B08 +#define REG_3D_Texture1Address7 0x8B0C +#define REG_3D_Texture1Address8 0x8B10 +#define REG_3D_Texture1Address9 0x8B14 +#define REG_3D_Texture1Address10 0x8B18 +#define REG_3D_Texture1Address11 0x8B1C +#define REG_3D_Texture1Pitch0 0x8B20 +#define REG_3D_Texture1Pitch1 0x8B20 +#define REG_3D_Texture1Pitch2 0x8B24 +#define REG_3D_Texture1Pitch3 0x8B24 +#define REG_3D_Texture1Pitch4 0x8B28 +#define REG_3D_Texture1Pitch5 0x8B28 +#define REG_3D_Texture1Pitch6 0x8B2C +#define REG_3D_Texture1Pitch7 0x8B2C +#define REG_3D_Texture1Pitch8 0x8B30 +#define REG_3D_Texture1Pitch9 0x8B30 +#define REG_3D_Texture1Pitch10 0x8B34 + +#define REG_3D_TextureBlendFactor 0x8B3C +#define REG_3D_TextureColorBlendSet0 0x8B40 +#define REG_3D_TextureColorBlendSet1 0x8B44 +#define REG_3D_TextureAlphaBlendSet0 0x8B48 +#define REG_3D_TextureAlphaBlendSet1 0x8B4C +/* + * Define the End of Primitive List of 6326 + */ +#define REG_3D_EndPrimitiveList 0X8B50 + + +/* + * Define the Stipple Register Address of 6326 + */ +#define REG_3D_Stipple0 0X8B60 + +#define REG_3D_TexturePalette 0x8C00 + +/* + * REG_QueueLen -- (8240h-8243h) + */ +#define MASK_QueueLen 0x0000ffff +#define SiS_EngIdle2d 0x80000000 +#define SiS_EngIdle 0xe0000000 +#define MASK_EngState 0xf0000000 + +/* + * REG_3D_ParsingSet -- Define Parsing Mask (89F4h-89F7h) + */ +#define MASK_VertexDWSize 0xF0000000 +#define MASK_VertexDataFormat 0x0FFF0000 +#define MASK_PsVertex_HAS_RHW 0x08000000 +#define MASK_PsVertex_HAS_NORMALXYZ 0x04000000 +#define MASK_PsVertex_HAS_DIFFUSE 0x02000000 +#define MASK_PsVertex_HAS_SPECULAR 0x01000000 +#define MASK_PsUVSet 0x00FF0000 +#define MASK_PsVertex_HAS_1SetUV 0x00800000 +#define MASK_PsVertex_HAS_2SetUV 0x00C00000 +#define MASK_PsVertex_HAS_3SetUV 0x00E00000 +#define MASK_PsVertex_HAS_UVSet1 0x00800000 +#define MASK_PsVertex_HAS_UVSet2 0x00400000 +#define MASK_PsVertex_HAS_UVSet3 0x00200000 +#define MASK_PsCullDirection_CCW 0x00008000 +#define MASK_PsShadingMode 0x00007000 +/* XXX Shading modes just a guess, but seem to work*/ +#define MASK_PsShadingFlatA 0x00001000 +#define MASK_PsShadingFlatB 0x00002000 +#define MASK_PsShadingFlatC 0x00003000 +#define MASK_PsShadingSmooth 0x00004000 +#define MASK_PsTextureFrom 0x000003F0 +#define MASK_PsTexture0FromA 0x00000000 +#define MASK_PsTexture1FromA 0x00000000 +#define MASK_PsTexture1FromB 0x00000040 +#define MASK_PsBumpTextureFromA 0x00000000 +#define MASK_PsBumpTextureFromB 0x00000010 +#define MASK_PsBumpTextureFromC 0x00000020 +#define MASK_PsDataType 0x0000000F +#define MASK_PsPointList 0x00000000 +#define MASK_PsLineList 0x00000004 +#define MASK_PsLineStrip 0x00000005 +#define MASK_PsTriangleList 0x00000008 +#define MASK_PsTriangleStrip 0x00000009 +#define MASK_PsTriangleFan 0x0000000A + +/* + * REG_3D_PrimitiveSet -- Define Fire Primitive Mask (89F8h-89FBh) + */ +#define MASK_DrawPrimitiveCommand 0x00000007 +#define MASK_SetFirePosition 0x00001F00 +#define MASK_BumpTextureFrom 0x00030000 +#define MASK_Texture1From 0x000C0000 +#define MASK_Texture0From 0x00300000 +#define MASK_ShadingMode 0x07000000 +#define MASK_CullDirection 0x08000000 + +#define OP_3D_POINT_DRAW 0x00000000 +#define OP_3D_LINE_DRAW 0x00000001 +#define OP_3D_TRIANGLE_DRAW 0x00000002 + +#define OP_3D_DIRECTION_RIGHT 0x00000000 +#define OP_3D_DIRECTION_LEFT 0x00000100 +#define OP_3D_DIRECTION_HORIZONTAL 0x00000000 +#define OP_3D_DIRECTION_VERTICAL 0x00000100 + +#define OP_3D_FIRE_TFIRE 0x00000000 +#define OP_3D_FIRE_TSARGBa 0x00000100 +#define OP_3D_FIRE_TSWa 0x00000200 +#define OP_3D_FIRE_TSVAa 0x00000300 +#define OP_3D_FIRE_TSVBa 0x00000400 +#define OP_3D_FIRE_TSVCa 0x00000500 + +#define OP_3D_FIRE_TSARGBb 0x00000900 +#define OP_3D_FIRE_TSWb 0x00000a00 +#define OP_3D_FIRE_TSVAb 0x00000b00 +#define OP_3D_FIRE_TSVBb 0x00000c00 +#define OP_3D_FIRE_TSVCb 0x00000d00 + +#define OP_3D_FIRE_TSARGBc 0x00001100 +#define OP_3D_FIRE_TSWc 0x00001200 +#define OP_3D_FIRE_TSVAc 0x00001300 +#define OP_3D_FIRE_TSVBc 0x00001400 +#define OP_3D_FIRE_TSVCc 0x00001500 + +#define OP_3D_Texture0FromA 0x00000000 +#define OP_3D_Texture0FromB 0x00100000 +#define OP_3D_Texture0FromC 0x00200000 +#define OP_3D_Texture1FromA 0x00000000 +#define OP_3D_Texture1FromB 0x00040000 +#define OP_3D_Texture1FromC 0x00080000 +#define OP_3D_TextureBumpFromA 0x00000000 +#define OP_3D_TextureBumpFromB 0x00010000 +#define OP_3D_TextureBumpFromC 0x00020000 + +#define OP_3D_CullDirection_CCW 0x08000000 + +#define SHADE_FLAT_VertexA 0x01000000 +#define SHADE_FLAT_VertexB 0x02000000 +#define SHADE_FLAT_VertexC 0x03000000 +#define SHADE_GOURAUD 0x04000000 + +/* + * Define Command Queue Length Mask (89FCh-89FF) + */ +#define MASK_CmdQueueLen 0x0FFF0000 + +/* + * REG_3D_TEnable -- Define Capility Enable Mask (8A00h-8A03h) + */ +#define MASK_DitherEnable 0x00000001 +#define MASK_BlendEnable 0x00000002 +#define MASK_FogTestEnable 0x00000004 +#define MASK_FogEnable 0x00000008 +#define MASK_SpecularEnable 0x00000010 +#define MASK_FogPerspectiveEnable 0x00000020 +#define MASK_TextureCacheClear 0x00000040 +#define MASK_TextureCacheEnable 0x00000080 +#define MASK_BumpMapEnable 0x00000100 +#define MASK_TexturePerspectiveEnable 0x00000200 +#define MASK_TextureEnable 0x00000400 +#define MASK_CullEnable 0x00000800 +#define MASK_TextureNumUsed 0x0000F000 +#define MASK_AlphaBufferEnable 0x00010000 +#define MASK_AlphaTestEnable 0x00020000 +#define MASK_AlphaWriteEnable 0x00040000 +#define MASK_ZTestEnable 0x00080000 +#define MASK_ZWriteEnable 0x00100000 +#define MASK_StencilBufferEnable 0x00200000 +#define MASK_StencilTestEnable 0x00400000 +#define MASK_StencilWriteEnable 0x00800000 +#define MASK_Texture0TransparencyEnable 0x01000000 +#define MASK_Texture1TransparencyEnable 0x02000000 +#define MASK_TextureAWrapUCorrection 0x04000000 +#define MASK_TextureAWrapVCorrection 0x08000000 +#define MASK_TextureBWrapUCorrection 0x10000000 +#define MASK_TextureBWrapVCorrection 0x20000000 +#define MASK_TextureCWrapUCorrection 0x40000000 +#define MASK_TextureCWrapVCorrection 0x80000000 + +/* + * REG_3D_TEnable2 -- Define Capility Enable Mask2 (8A04h-8A07h) + */ +#define MASK_Texture0BlockTextureEnable 0x00000001 +#define MASK_Texture1BlockTextureEnable 0x00000002 +#define MASK_Texture0AnisotropicEnable 0x00000010 +#define MASK_Texture1AnisotropicEnable 0x00000020 +#define MASK_TextureMipmapBiasEnable 0x00000040 +#define MASK_LinePatternEnable 0x00000100 +#define MASK_StippleAlphaEnable 0x00000200 +#define MASK_StippleEnable 0x00000400 +#define MASK_AntiAliasEnable 0x00000800 +#define MASK_ZMaskWriteEnable 0x00001000 +#define MASK_StencilMaskWriteEnable 0x00002000 +#define MASK_AlphaMaskWriteEnable 0x00004000 +#define MASK_ColorMaskWriteEnable 0x00008000 +#define MASK_ZCacheClear 0x00010000 +#define MASK_ZCacheEnable 0x00020000 +#define MASK_StencilCacheClear 0x00040000 +#define MASK_StencilCacheEnable 0x00080000 +#define MASK_AlphaCacheClear 0x00100000 +#define MASK_AlphaCacheEnable 0x00200000 +#define MASK_ColorCacheClear 0x00400000 +#define MASK_ColorCacheEnable 0x00800000 + +/* + * REG_3D_ZSet -- Define Z Buffer Setting Mask (8A08h-8A0Bh) + */ +#define MASK_ZBufferPitch 0x00000FFF +#define MASK_ZTestMode 0x00070000 +#define MASK_ZBufferInSystem 0x00080000 +#define MASK_ZBufferFormat 0x01F00000 + +#define SiS_Z_COMP_NEVER 0x00000000 +#define SiS_Z_COMP_S_LT_B 0x00010000 +#define SiS_Z_COMP_S_EQ_B 0x00020000 +#define SiS_Z_COMP_S_LE_B 0x00030000 +#define SiS_Z_COMP_S_GT_B 0x00040000 +#define SiS_Z_COMP_S_NE_B 0x00050000 +#define SiS_Z_COMP_S_GE_B 0x00060000 +#define SiS_Z_COMP_ALWAYS 0x00070000 + +#define SiS_ZFORMAT_Z16 0x00000000 +#define SiS_ZFORMAT_Z16_INT 0x00100000 +#define SiS_ZFORMAT_S1Z15 0x00400000 +#define SiS_ZFORMAT_S1Z15_INT 0x00500000 +#define SiS_ZFORMAT_Z32 0x00800000 +#define SiS_ZFORMAT_S1Z31 0x00C00000 +#define SiS_ZFORMAT_S2Z30 0x00D00000 +#define SiS_ZFORMAT_S4Z28 0x00E00000 +#define SiS_ZFORMAT_S8Z24 0x00F00000 +#define SiS_ZFORMAT_FZ30 0x01800000 +#define SiS_ZFORMAT_FS1Z30 0x01C00000 +#define SiS_ZFORMAT_FS2Z30 0x01D00000 + +/* + * REG_3D_ZBias -- Define Z Buffer Setting Mask (8A0Ch-8A0Fh) + */ +#define MASK_ZBias 0xFFFFFFFF + +/* + * REG_3D_ZStWriteMask -- Define Z and Stencil Buffer Mask (8A10h-8A13h) + */ +#define MASK_ZWriteMask 0x00FFFFFF + +/* + * REG_3D_ZAddress -- Define Z Buffer Base Address(8A14h-8A17h) + */ +#define MASK_ZAddress 0xFFFFFFFF + +/* + * REG_3D_AlphaSet -- Define Alpha Buffer Setting Mask (8A18h-8A1Bh) + */ +#define MASK_AlphaBufferPitch 0x000003FF +#define MASK_AlphaRefValue 0x00FF0000 +#define MASK_AlphaTestMode 0x07000000 +#define MASK_AlphaBufferInSystem 0x08000000 +#define MASK_AlphaBufferFormat 0x30000000 + +#define SiS_ALPHA_NEVER 0x00000000 +#define SiS_ALPHA_LESS 0x01000000 +#define SiS_ALPHA_EQUAL 0x02000000 +#define SiS_ALPHA_LEQUAL 0x03000000 +#define SiS_ALPHA_GREATER 0x04000000 +#define SiS_ALPHA_NOTEQUAL 0x05000000 +#define SiS_ALPHA_GEQUAL 0x06000000 +#define SiS_ALPHA_ALWAYS 0x07000000 + +/* + * REG_3D_AlphaAddress -- Define Alpha Buffer Base Address(8A1Ch-8A1Fh) + */ +#define MASK_AlphaAddress 0xFFFFFFFF + +/* + * REG_3D_DstSet -- Define Destination Buffer Setting Mask (8A20h-8A23h) + */ +#define MASK_DstBufferPitch 0x00000FFF +#define MASK_DstBufferFormat 0x000F0000 +#define MASK_DstBufferBitDepth 0x00300000 +#define MASK_DstBufferRgbOrder 0x00400000 +#define MASK_DstBufferInSystem 0x00800000 +#define MASK_Dst7BitFormat 0x007F0000 +#define MASK_ROP2 0x0F000000 + +#define DST_FORMAT_RGB_555 0x00100000 +#define DST_FORMAT_RGB_565 0x00110000 +#define DST_FORMAT_ARGB_1555 0x00120000 +#define DST_FORMAT_ARGB_4444 0x00130000 +#define DST_FORMAT_ARGB_1888 0x00300000 +#define DST_FORMAT_ARGB_2888 0x00310000 +#define DST_FORMAT_ARGB_4888 0x00320000 +#define DST_FORMAT_ARGB_8888 0x00330000 +#define DST_FORMAT_ARGB_0888 0x00340000 + +#define DST_FORMAT_BGR_555 0x00500000 +#define DST_FORMAT_BGR_565 0x00510000 +#define DST_FORMAT_ABGR_1555 0x00520000 +#define DST_FORMAT_ABGR_4444 0x00530000 +#define DST_FORMAT_ABGR_1888 0x00700000 +#define DST_FORMAT_ABGR_2888 0x00710000 +#define DST_FORMAT_ABGR_4888 0x00720000 +#define DST_FORMAT_ABGR_8888 0x00730000 +#define DST_FORMAT_ABGR_0888 0x00740000 + +#define LOP_CLEAR 0x00000000 +#define LOP_NOR 0x01000000 +#define LOP_AND_INVERTED 0x02000000 +#define LOP_COPY_INVERTED 0x03000000 +#define LOP_AND_REVERSE 0x04000000 +#define LOP_INVERT 0x05000000 +#define LOP_XOR 0x06000000 +#define LOP_NAND 0x07000000 +#define LOP_AND 0x08000000 +#define LOP_EQUIV 0x09000000 +#define LOP_NOOP 0x0a000000 +#define LOP_OR_INVERTED 0x0b000000 +#define LOP_COPY 0x0c000000 +#define LOP_OR_REVERSE 0x0d000000 +#define LOP_OR 0x0e000000 +#define LOP_SET 0x0f000000 + +/* + * REG_3D_DstAlphaWriteMask -- Define Destination/Alpha Buffer Write Mask (8A24h-8A27h) + */ +#define MASK_ColorWriteMask 0x00FFFFFF +#define MASK_AlphaWriteMask 0xFF000000 + +/* + * REG_3D_DstAddress -- Define Destination Buffer Base Address(8A1Ch-8A1Fh) + */ +#define MASK_DstAddress 0xFFFFFFFF + +/* + * REG_3D_LinePattern -- Define Line Pattern (8A2Ch-8A2Fh) + */ +#define MASK_LinePatternRepeatFactor 0x00007FFF +#define MASK_LinePatternLastPixelFlag 0x00008000 +#define MASK_LinePattern 0xFFFF0000 + +/* + * REG_3D_FogSet -- Define Fog Mask (8A30h-8A33h) + */ +#define MASK_FogColor 0x00FFFFFF +#define MASK_FogMode 0x07000000 +#define MASK_FogZLookup 0x08000000 + +#define FOGMODE_CHEAP 0x04000000 +#define FOGMODE_LINEAR 0x05000000 +#define FOGMODE_EXP 0x06000000 +#define FOGMODE_EXP2 0x07000000 + +/* + * REG_3D_FogStartEnd -- Define Fog Start End Setting (8A34h-8A37h) + */ +#define MASK_FogFarDistance 0x0007FFFF + +/* + * REG_3D_FogStartEnd -- Define Fog End Setting (8A38h-8A3Bh) + */ +#define MASK_FogInvFarDistance 0x0007FFFF + +/* + * REG_3D_FogStartEnd -- Define Fog End Setting (0x8A3C - 0x8A3F) + */ +#define MASK_FogDensity 0x0003FFFF +#define MASK_FogFactor 0xFF000000 + +/* + * REG_3D_StencilSet -- Define stencil test (8A44h-8A47h) + */ +#define MASK_StencilValueMask 0x000000ff +#define MASK_StencilRefMask 0x0000ff00 +#define MASK_StencilTestMode 0x07000000 +#define MASK_StencilBufferInSystem 0x08000000 +#define MASK_StencilFormat 0x30000000 + +#define SiS_STENCIL_NEVER 0x00000000 +#define SiS_STENCIL_LESS 0x01000000 +#define SiS_STENCIL_EQUAL 0x02000000 +#define SiS_STENCIL_LEQUAL 0x03000000 +#define SiS_STENCIL_GREATER 0x04000000 +#define SiS_STENCIL_NOTEQUAL 0x05000000 +#define SiS_STENCIL_GEQUAL 0x06000000 +#define SiS_STENCIL_ALWAYS 0x07000000 + +#define STENCIL_FORMAT_1 0x00000000 +#define STENCIL_FORMAT_2 0x10000000 +#define STENCIL_FORMAT_4 0x20000000 +#define STENCIL_FORMAT_8 0x30000000 + +/* + * REG_3D_StencilSet2 -- Define stencil test (8A4h-8A47h) + */ +#define MASK_StencilBufferPitch 0x00000FFF +#define MASK_StencilZPassOp 0x00007000 +#define MASK_StencilZFailOp 0x00070000 +#define MASK_StencilFailOp 0x00700000 +#define MASK_StencilWriteMask 0xFF000000 + +#define SiS_SFAIL_KEEP 0x00000000 +#define SiS_SFAIL_ZERO 0x00100000 +#define SiS_SFAIL_REPLACE 0x00200000 +#define SiS_SFAIL_INVERT 0x00500000 +#define SiS_SFAIL_INCR 0x00600000 +#define SiS_SFAIL_DECR 0x00700000 + +#define SiS_SPASS_ZFAIL_KEEP 0x00000000 +#define SiS_SPASS_ZFAIL_ZERO 0x00010000 +#define SiS_SPASS_ZFAIL_REPLACE 0x00020000 +#define SiS_SPASS_ZFAIL_INVERT 0x00050000 +#define SiS_SPASS_ZFAIL_INCR 0x00060000 +#define SiS_SPASS_ZFAIL_DECR 0x00070000 + +#define SiS_SPASS_ZPASS_KEEP 0x00000000 +#define SiS_SPASS_ZPASS_ZERO 0x00001000 +#define SiS_SPASS_ZPASS_REPLACE 0x00002000 +#define SiS_SPASS_ZPASS_INVERT 0x00005000 +#define SiS_SPASS_ZPASS_INCR 0x00006000 +#define SiS_SPASS_ZPASS_DECR 0x00007000 + +/* + * REG_3D_DstBlendMode (0x8A50 - 0x8A53) + */ +#define MASK_SrcBlendMode 0x0000000F +#define MASK_DstBlendMode 0x000000F0 + +#define SiS_D_ZERO 0x00000000 +#define SiS_D_ONE 0x00000010 +#define SiS_D_SRC_COLOR 0x00000020 +#define SiS_D_ONE_MINUS_SRC_COLOR 0x00000030 +#define SiS_D_SRC_ALPHA 0x00000040 +#define SiS_D_ONE_MINUS_SRC_ALPHA 0x00000050 +#define SiS_D_DST_ALPHA 0x00000060 +#define SiS_D_ONE_MINUS_DST_ALPHA 0x00000070 +#define SiS_D_DST_COLOR 0x00000080 +#define SiS_D_ONE_MINUS_DST_COLOR 0x00000090 +#define SiS_D_SRC_ALPHA_SAT 0x000000a0 + +#define SiS_S_ZERO 0x00000000 +#define SiS_S_ONE 0x00000001 +#define SiS_S_SRC_COLOR 0x00000002 +#define SiS_S_ONE_MINUS_SRC_COLOR 0x00000003 +#define SiS_S_SRC_ALPHA 0x00000004 +#define SiS_S_ONE_MINUS_SRC_ALPHA 0x00000005 +#define SiS_S_DST_ALPHA 0x00000006 +#define SiS_S_ONE_MINUS_DST_ALPHA 0x00000007 +#define SiS_S_DST_COLOR 0x00000008 +#define SiS_S_ONE_MINUS_DST_COLOR 0x00000009 +#define SiS_S_SRC_ALPHA_SATURATE 0x0000000a +#define SiS_S_BOTH_SRC_ALPHA 0x0000000b +#define SiS_S_BOTH_ONE_MINUS_SRC_ALPHA 0x0000000c + +/* + * REG_3D_DstBlendMode (0x8A54 - 0x8A57) + */ +#define MASK_BottomClip 0x00001FFF +#define MASK_TopClip 0x03FFE000 + +/* + * REG_3D_DstBlendMode (0x8A58 - 0x8A5B) + */ +#define MASK_RightClip 0x00001FFF +#define MASK_LeftClip 0x03FFE000 + +/* + * REG_3D_TextureSet (0x8A7C - 0x8A7F) + * REG_3D_Texture1Set (0x8ADC - 0x8ADF) + */ +#define MASK_TextureHeight 0x0000000F +#define MASK_TextureWidth 0x000000F0 +#define MASK_TextureLevel 0x00000F00 +#define MASK_TextureSignYUVFormat 0x00001000 +#define MASK_TextureMappingMode 0x00FF0000 +#define MASK_TextureWrapU 0x00010000 +#define MASK_TextureWrapV 0x00020000 +#define MASK_TextureMirrorU 0x00040000 +#define MASK_TextureMirrorV 0x00080000 +#define MASK_TextureClampU 0x00100000 +#define MASK_TextureClampV 0x00200000 +#define MASK_TextureBorderU 0x00400000 +#define MASK_TextureBorderV 0x00800000 +#define MASK_TextureFormat 0xFF000000 +#define MASK_TextureBitDepth 0x70000000 +#define MASK_TextureRgbOrder 0x80000000 + +#define TEXEL_INDEX1 0x00000000 +#define TEXEL_INDEX2 0x01000000 +#define TEXEL_INDEX4 0x02000000 +#define TEXEL_INDEX8 0x03000000 + +#define TEXEL_INDEX1WithAlpha 0x04000000 +#define TEXEL_INDEX2WithAlpha 0x05000000 +#define TEXEL_INDEX4WithAlpha 0x06000000 +#define TEXEL_INDEX8WithAlpha 0x07000000 + +#define TEXEL_I1 0x10000000 +#define TEXEL_I2 0x11000000 +#define TEXEL_I4 0x12000000 +#define TEXEL_I8 0x13000000 + +#define TEXEL_DXT1 0x19000000 +#define TEXEL_DXT2 0x1A000000 +#define TEXEL_DXT3 0x1B000000 + +#define TEXEL_YUV422 0x20000000 +#define TEXEL_YVU422 0x21000000 +#define TEXEL_UVY422 0x22000000 +#define TEXEL_VUY422 0x23000000 +#define TEXEL_YUV411 0x24000000 + +#define TEXEL_L1 0x30000000 +#define TEXEL_L2 0x31000000 +#define TEXEL_L4 0x32000000 +#define TEXEL_L8 0x33000000 + +#define TEXEL_AL11 0x34000000 +#define TEXEL_AL44 0x35000000 +#define TEXEL_AL26 0x37000000 +#define TEXEL_AL88 0x38000000 + +#define TEXEL_A1 0x40000000 +#define TEXEL_A2 0x41000000 +#define TEXEL_A4 0x42000000 +#define TEXEL_A8 0x43000000 + +#define TEXEL_RGB_332_8 0x50000000 +#define TEXEL_RGB_233_8 0x51000000 +#define TEXEL_RGB_232_8 0x52000000 +#define TEXEL_ARGB_1232_8 0x53000000 +#define TEXEL_ARGB_2222_8 0x54000000 + +#define TEXEL_RGB_555_16 0x60000000 +#define TEXEL_RGB_565_16 0x61000000 +#define TEXEL_ARGB_1555_16 0x62000000 +#define TEXEL_ARGB_4444_16 0x63000000 + +#define TEXEL_ARGB_1888_32 0x70000000 +#define TEXEL_ARGB_2888_32 0x71000000 +#define TEXEL_ARGB_4888_32 0x72000000 +#define TEXEL_ARGB_8888_32 0x73000000 +#define TEXEL_ARGB_0888_32 0x74000000 + +#define TEXEL_BGR_332_8 0xD0000000 +#define TEXEL_BGR_233_8 0xD1000000 +#define TEXEL_BGR_232_8 0xD2000000 +#define TEXEL_ABGR_1232_8 0xD3000000 +#define TEXEL_ABGR_2222_8 0xD4000000 + +#define TEXEL_BGR_555_16 0xE0000000 +#define TEXEL_BGR_565_16 0xE1000000 +#define TEXEL_ABGR_1555_16 0xE2000000 +#define TEXEL_ABGR_4444_16 0xE3000000 + +#define TEXEL_ABGR_1888_32 0xF0000000 +#define TEXEL_ABGR_2888_32 0xF1000000 +#define TEXEL_ABGR_4888_32 0xF2000000 +#define TEXEL_ABGR_8888_32 0xF3000000 +#define TEXEL_ABGR_0888_32 0xF4000000 + +#define TEXEL_VU88 0x00000000 +#define TEXEL_LVU655 0x00800000 +#define TEXEL_LVU888 0x01000000 +#define TEXEL_UV88 0x02000000 +#define TEXEL_LUV655 0x02800000 +#define TEXEL_LUV888 0x03000000 + +/* + * REG_3D_TextureMip (0x8A80 - 0x8A83) + * REG_3D_Texture1Mip (0x8AE0 - 0x8AE3) + */ +#define MASK_TextureAnisotropyRatio 0x0000000F +#define MASK_TextureMipmapLodBias 0x00003FF0 +#define MASK_TextureFilterMin 0x0001C000 +#define MASK_TextureFilterMag 0x00020000 +#define MASK_TextureFilter 0x0003C000 +#define MASK_TextureLevelInSystem 0x3FFC0000 +#define MASK_TextureLevel0InSystem 0x00040000 +#define MASK_TextureBlockLength 0xF0000000 + +#define TEXTURE_FILTER_NEAREST 0x00000000 +#define TEXTURE_FILTER_LINEAR 0x00004000 +#define TEXTURE_FILTER_NEAREST_MIP_NEAREST 0x00008000 +#define TEXTURE_FILTER_NEAREST_MIP_LINEAR 0x00010000 +#define TEXTURE_FILTER_LINEAR_MIP_NEAREST 0x0000c000 +#define TEXTURE_FILTER_LINEAR_MIP_LINEAR 0x00014000 + +/* + * REG_3D_TextureTransparencyColorHigh (0x8A84 - 0x8A87) + * REG_3D_Texture1TransparencyColorHigh (0x8AE4 - 0x8AE7) + */ +#define MASK_TextureTransparencyColorHighB 0x000000FF +#define MASK_TextureTransparencyColorHighG 0x0000FF00 +#define MASK_TextureTransparencyColorHighR 0x00FF0000 +#define MASK_TextureAlphaTransparencyMode 0x08000000 + +/* + * REG_3D_TextureTransparencyColorLow (0x8A88 - 0x8A8B) + * REG_3D_Texture1TransparencyColorLow (0x8AE8 - 0x8AEB) + */ +#define MASK_TextureTransparencyColorLowB 0x000000FF +#define MASK_TextureTransparencyColorLowG 0x0000FF00 +#define MASK_TextureTransparencyColorLowR 0x00FF0000 +#define MASK_TextureBlockHeight 0x07000000 +#define MASK_TextureBlockWidth 0x70000000 + +/* + * REG_3D_TextureTransparencyColorLow (0x8A8C - 0x8A8F) + * REG_3D_Texture1TransparencyColorLow (0x8AEC - 0x8AEF) + */ +#define MASK_TextureBorderColorB 0x000000FF +#define MASK_TextureBorderColorG 0x0000FF00 +#define MASK_TextureBorderColorR 0x00FF0000 +#define MASK_TextureBorderColorA 0xFF000000 + +/* + * REG_3D_TexturePitch0-10 (0x8AC0 - 0x8AD7) + * REG_3D_Texture1Pitch0-10 (0x8B20 - 0x8B37) + */ +#define MASK_TexturePitchOdd 0x000003FF +#define MASK_TexturePitchEven 0x03FF0000 +#define SHIFT_TexturePitchEven 16 + +/* + * REG_3D_TextureColorBlendSet0 (0x8B40 - 0x8B43) + * REG_3D_TextureColorBlendSet1 (0x8B44 - 0x8B46) + * REG_3D_TextureAlphaBlendSet0 (0x8B40 - 0x8B43) + * REG_3D_TextureAlphaBlendSet1 (0x8B44 - 0x8B46) + */ + +#define A_REPLACE_RGB_STAGE0 0xa1485000 +#define A_REPLACE_A_STAGE0 0xc3230000 +#define L_REPLACE__RGB_STAGE0 0xc1485000 +#define L_REPLACE__A_STAGE0 0x63230000 +#define LA_REPLACE__RGB_STAGE0 0xc1485000 +#define LA_REPLACE__A_STAGE0 0xc3230000 +#define I_REPLACE__RGB_STAGE0 0xc1485000 +#define I_REPLACE__A_STAGE0 0xc3230000 +#define RGB_REPLACE__RGB_STAGE0 0xc1485000 +#define RGB_REPLACE__A_STAGE0 0x63230000 +#define RGBA_REPLACE__RGB_STAGE0 0xc1485000 +#define RGBA_REPLACE__A_STAGE0 0xc3230000 + +#define A_MODULATE_RGB_STAGE0 0xa1485000 +#define A_MODULATE_A_STAGE0 0x63c30000 +#define L_MODULATE__RGB_STAGE0 0xa1705000 +#define L_MODULATE__A_STAGE0 0x63230000 +#define LA_MODULATE__RGB_STAGE0 0xa1705000 +#define LA_MODULATE__A_STAGE0 0x63c30000 +#define I_MODULATE__RGB_STAGE0 0xa1705000 +#define I_MODULATE__A_STAGE0 0x63c30000 +#define RGB_MODULATE__RGB_STAGE0 0xa1705000 +#define RGB_MODULATE__A_STAGE0 0x63230000 +#define RGBA_MODULATE__RGB_STAGE0 0xa1705000 +#define RGBA_MODULATE__A_STAGE0 0x63c30000 + +#define RGB_DECAL__RGB_STAGE0 0xc1485000 +#define RGB_DECAL__A_STAGE0 0x63230000 +#define RGBA_DECAL__RGB_STAGE0 0xc534c001 +#define RGBA_DECAL__A_STAGE0 0x63230000 + +#define A_BLEND_RGB_STAGE0 0xa1485000 +#define A_BLEND_A_STAGE0 0x63c30000 +#define L_BLEND__RGB_STAGE0 0x4530c001 +#define L_BLEND__A_STAGE0 0x63230000 +#define LA_BLEND__RGB_STAGE0 0x4530c001 +#define LA_BLEND__A_STAGE0 0x63c30000 +#define I_BLEND__RGB_STAGE0 0x4530c001 +#define I_BLEND__A_STAGE0 0x46c60001 +#define RGB_BLEND__RGB_STAGE0 0x4530c001 +#define RGB_BLEND__A_STAGE0 0x63230000 +#define RGBA_BLEND__RGB_STAGE0 0x4530c001 +#define RGBA_BLEND__A_STAGE0 0x63c30000 + +#define RGB_STAGE1 0xa1485000 +#define A_STAGE1 0xa3230000 + +#define A_REPLACE_RGB_STAGE1 0xa1485000 +#define A_REPLACE_A_STAGE1 0xe3230000 +#define L_REPLACE__RGB_STAGE1 0xe1485000 +#define L_REPLACE__A_STAGE1 0xa3230000 +#define LA_REPLACE__RGB_STAGE1 0xe1485000 +#define LA_REPLACE__A_STAGE1 0xe3230000 +#define I_REPLACE__RGB_STAGE1 0xe1485000 +#define I_REPLACE__A_STAGE1 0xe3230000 +#define RGB_REPLACE__RGB_STAGE1 0xe1485000 +#define RGB_REPLACE__A_STAGE1 0xa3230000 +#define RGBA_REPLACE__RGB_STAGE1 0xe1485000 +#define RGBA_REPLACE__A_STAGE1 0xe3230000 + +#define A_MODULATE_RGB_STAGE1 0xa1485000 +#define A_MODULATE_A_STAGE1 0xa3e30000 +#define L_MODULATE__RGB_STAGE1 0xa1785000 +#define L_MODULATE__A_STAGE1 0xa3230000 +#define LA_MODULATE__RGB_STAGE1 0xa1785000 +#define LA_MODULATE__A_STAGE1 0xa3e30000 +#define I_MODULATE__RGB_STAGE1 0xa1785000 +#define I_MODULATE__A_STAGE1 0xa3e30000 +#define RGB_MODULATE__RGB_STAGE1 0xa1785000 +#define RGB_MODULATE__A_STAGE1 0xa3230000 +#define RGBA_MODULATE__RGB_STAGE1 0xa1785000 +#define RGBA_MODULATE__A_STAGE1 0xa3e30000 + +#define RGB_DECAL__RGB_STAGE1 0xe1485000 +#define RGB_DECAL__A_STAGE1 0xa3230000 +#define RGBA_DECAL__RGB_STAGE1 0xe5394001 +#define RGBA_DECAL__A_STAGE1 0xa3230000 + +#define A_BLEND_RGB_STAGE1 0xa1485000 +#define A_BLEND_A_STAGE1 0xa3e30000 +#define L_BLEND__RGB_STAGE1 0x45394001 +#define L_BLEND__A_STAGE1 0xa3230000 +#define LA_BLEND__RGB_STAGE1 0x45394001 +#define LA_BLEND__A_STAGE1 0xa3e30000 +#define I_BLEND__RGB_STAGE1 0x45394001 +#define I_BLEND__A_STAGE1 0x4aea0001 +#define RGB_BLEND__RGB_STAGE1 0x45394001 +#define RGB_BLEND__A_STAGE1 0xa3230000 +#define RGBA_BLEND__RGB_STAGE1 0x45394001 +#define RGBA_BLEND__A_STAGE1 0xa3e30000 + +/* What registers are these associated with? */ +#define MASK_BMMemoryInSystem 0x00000080 +#define MASK_BMHeight 0x00000F00 +#define MASK_BMWidth 0x0000F000 +#define MASK_BMFilter 0x00010000 +#define MASK_BMMappingMode 0x007E0000 +#define MASK_BMFormat 0x07800000 +#define MASK_BMTxBumpmap 0x08000000 + +#define MASK_BMAddress 0xFFFFFFFC + +#define MASK_BMOffset 0xFF800000 +#define MASK_BMScale 0x007FE000 +#define MASK_BMPitch 0x00001FFF + +#define MASK_BMMatrix00 0x000007FF +#define MASK_BMMatrix01 0x07FF0000 +#define MASK_BMMatrix10 0x000007FF +#define MASK_BMMatrix11 0x07FF0000 + +#define MASK_TextureRealInSystem 0x00000001 +#define MASK_TextureDowngrade 0x00000002 + +#define ALPHA_BUFFER_FORMAT_1 0x00000000 +#define ALPHA_BUFFER_FORMAT_2 0x10000000 +#define ALPHA_BUFFER_FORMAT_4 0x20000000 +#define ALPHA_BUFFER_FORMAT_8 0x30000000 + +#endif diff --git a/src/mesa/drivers/dri/sis/sis_screen.c b/src/mesa/drivers/dri/sis/sis_screen.c new file mode 100644 index 00000000000..1de992e18b5 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_screen.c @@ -0,0 +1,285 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2003 Eric Anholt +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: + * Eric Anholt + */ + +#include "dri_util.h" + +#include "context.h" +#include "utils.h" +#include "imports.h" + +#include "sis_context.h" +#include "sis_dri.h" +#include "sis_lock.h" + +/* Create the device specific screen private data struct. + */ +static sisScreenPtr +sisCreateScreen( __DRIscreenPrivate *sPriv ) +{ + sisScreenPtr sisScreen; + SISDRIPtr sisDRIPriv = (SISDRIPtr)sPriv->pDevPriv; + + if ( !driCheckDriDdxDrmVersions( sPriv, "SiS", 4, 0, 0, 1, 1, 0 ) ) + return NULL; + + /* Allocate the private area */ + sisScreen = (sisScreenPtr)CALLOC( sizeof(*sisScreen) ); + if ( sisScreen == NULL ) + return NULL; + + sisScreen->screenX = sisDRIPriv->width; + sisScreen->screenY = sisDRIPriv->height; + sisScreen->cpp = sisDRIPriv->bytesPerPixel; + sisScreen->irqEnabled = sisDRIPriv->bytesPerPixel; + sisScreen->deviceID = sisDRIPriv->deviceID; + sisScreen->AGPCmdBufOffset = sisDRIPriv->AGPCmdBufOffset; + sisScreen->AGPCmdBufSize = sisDRIPriv->AGPCmdBufSize; + sisScreen->sarea_priv_offset = sizeof(XF86DRISAREARec); + + sisScreen->mmio.handle = sisDRIPriv->regs.handle; + sisScreen->mmio.size = sisDRIPriv->regs.size; + if ( drmMap( sPriv->fd, sisScreen->mmio.handle, sisScreen->mmio.size, + &sisScreen->mmio.map ) ) + { + FREE( sisScreen ); + return NULL; + } + + if (sisDRIPriv->agp.size) { + sisScreen->agp.handle = sisDRIPriv->agp.handle; + sisScreen->agp.size = sisDRIPriv->agp.size; + if ( drmMap( sPriv->fd, sisScreen->agp.handle, sisScreen->agp.size, + &sisScreen->agp.map ) ) + { + sisScreen->agp.size = 0; + } + } + + sisScreen->driScreen = sPriv; + + return sisScreen; +} + +/* Destroy the device specific screen private data struct. + */ +static void +sisDestroyScreen( __DRIscreenPrivate *sPriv ) +{ + sisScreenPtr sisScreen = (sisScreenPtr)sPriv->private; + + if ( sisScreen == NULL ) + return; + + if (sisScreen->agp.size != 0) + drmUnmap( sisScreen->agp.map, sisScreen->agp.size ); + drmUnmap( sisScreen->mmio.map, sisScreen->mmio.size ); + + FREE( sisScreen ); + sPriv->private = NULL; +} + +/* Create and initialize the Mesa and driver specific pixmap buffer + * data. + */ +static GLboolean +sisCreateBuffer( __DRIscreenPrivate *driScrnPriv, + __DRIdrawablePrivate *driDrawPriv, + const __GLcontextModes *mesaVis, + GLboolean isPixmap ) +{ + if (isPixmap) + return GL_FALSE; /* not implemented */ + + driDrawPriv->driverPrivate = (void *)_mesa_create_framebuffer( + mesaVis, + GL_FALSE, /* software depth buffer? */ + mesaVis->stencilBits > 0, + mesaVis->accumRedBits > 0, + mesaVis->alphaBits > 0 ); /* XXX */ + return (driDrawPriv->driverPrivate != NULL); +} + + +static void +sisDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_destroy_framebuffer((GLframebuffer *) (driDrawPriv->driverPrivate)); +} + +__inline__ static void +sis_bitblt_copy_cmd (sisContextPtr smesa, ENGPACKET * pkt) +{ + GLint *lpdwDest, *lpdwSrc; + int i; + + lpdwSrc = (GLint *) pkt; + lpdwDest = (GLint *) (GET_IOBase (smesa) + REG_SRC_ADDR); + + mWait3DCmdQueue (10); + + for (i = 0; i < 7; i++) + *lpdwDest++ = *lpdwSrc++; + + MMIO(REG_CMD0, *(GLint *)&pkt->stdwCmd); + MMIO(REG_QueueLen, -1); +} + +static void sisCopyBuffer( __DRIdrawablePrivate *dPriv ) +{ + sisContextPtr smesa = (sisContextPtr)dPriv->driContextPriv->driverPrivate; + int i; + ENGPACKET stEngPacket; + + while ((*smesa->FrameCountPtr) - MMIO_READ(0x8a2c) > SIS_MAX_FRAME_LENGTH) + usleep(1); + + LOCK_HARDWARE(); + + stEngPacket.dwSrcBaseAddr = smesa->backOffset; + stEngPacket.dwSrcPitch = smesa->backPitch | + ((smesa->bytesPerPixel == 2) ? 0x80000000 : 0xc0000000); + stEngPacket.dwDestBaseAddr = 0; + stEngPacket.wDestPitch = smesa->frontPitch; + /* TODO: set maximum value? */ + stEngPacket.wDestHeight = smesa->virtualY; + + stEngPacket.stdwCmd.cRop = 0xcc; + + if (smesa->blockWrite) + stEngPacket.stdwCmd.cCmd0 = CMD0_PAT_FG_COLOR; + else + stEngPacket.stdwCmd.cCmd0 = 0; + stEngPacket.stdwCmd.cCmd1 = CMD1_DIR_X_INC | CMD1_DIR_Y_INC; + + for (i = 0; i < dPriv->numClipRects; i++) { + XF86DRIClipRectPtr box = &dPriv->pClipRects[i]; + stEngPacket.stdwSrcPos.wY = box->y1 - dPriv->y; + stEngPacket.stdwSrcPos.wX = box->x1 - dPriv->x; + stEngPacket.stdwDestPos.wY = box->y1; + stEngPacket.stdwDestPos.wX = box->x1; + + stEngPacket.stdwDim.wWidth = (GLshort) box->x2 - box->x1; + stEngPacket.stdwDim.wHeight = (GLshort) box->y2 - box->y1; + sis_bitblt_copy_cmd( smesa, &stEngPacket ); + } + + *(GLint *)(smesa->IOBase+0x8a2c) = *smesa->FrameCountPtr; + (*smesa->FrameCountPtr)++; + + UNLOCK_HARDWARE (); +} + + +/* Copy the back color buffer to the front color buffer */ +static void +sisSwapBuffers(__DRIdrawablePrivate *dPriv) +{ + if (dPriv->driContextPriv && dPriv->driContextPriv->driverPrivate) { + sisContextPtr smesa = (sisContextPtr) dPriv->driContextPriv->driverPrivate; + GLcontext *ctx = smesa->glCtx; + + if (ctx->Visual.doubleBufferMode) { + _mesa_notifySwapBuffers( ctx ); /* flush pending rendering comands */ + sisCopyBuffer( 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 +sisInitDriver( __DRIscreenPrivate *sPriv ) +{ + sPriv->private = (void *) sisCreateScreen( sPriv ); + + if ( !sPriv->private ) { + sisDestroyScreen( sPriv ); + return GL_FALSE; + } + + return GL_TRUE; +} + +/* Fullscreen mode change stub + */ +static GLboolean +sisOpenCloseFullScreen( __DRIcontextPrivate *driContextPriv ) +{ + return GL_TRUE; +} + +static struct __DriverAPIRec sisAPI = { + .InitDriver = sisInitDriver, + .DestroyScreen = sisDestroyScreen, + .CreateContext = sisCreateContext, + .DestroyContext = sisDestroyContext, + .CreateBuffer = sisCreateBuffer, + .DestroyBuffer = sisDestroyBuffer, + .SwapBuffers = sisSwapBuffers, + .MakeCurrent = sisMakeCurrent, + .UnbindContext = sisUnbindContext, + .OpenFullScreen = sisOpenCloseFullScreen, + .CloseFullScreen = sisOpenCloseFullScreen, + .GetSwapInfo = NULL, + .GetMSC = NULL, + .WaitForMSC = NULL, + .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, &sisAPI ); + return (void *)psp; +} +#else +void *__driCreateScreen(struct DRIDriverRec *driver, + struct DRIDriverContextRec *driverContext) +{ + __DRIscreenPrivate *psp; + psp = __driUtilCreateScreen(driver, driverContext, &sisAPI); + return (void *) psp; +} +#endif diff --git a/src/mesa/drivers/dri/sis/sis_screen.h b/src/mesa/drivers/dri/sis/sis_screen.h new file mode 100644 index 00000000000..e2c67c16f2f --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_screen.h @@ -0,0 +1,60 @@ +/************************************************************************** + +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Eric Anholt + */ + +#ifndef __SIS_SCREEN_H +#define __SIS_SCREEN_H + +typedef struct { + drmHandle handle; /* Handle to the DRM region */ + drmSize size; /* Size of the DRM region */ + drmAddress map; /* Mapping of the DRM region */ +} sisRegionRec2, *sisRegionPtr2; + +typedef struct { + sisRegionRec2 mmio; + sisRegionRec2 agp; + + unsigned int AGPCmdBufOffset; + unsigned int AGPCmdBufSize; + + int deviceID; + int irqEnabled; + + int cpp; + unsigned int screenX, screenY; + + __DRIscreenPrivate *driScreen; + unsigned int sarea_priv_offset; + +} sisScreenRec, *sisScreenPtr; + +#endif diff --git a/src/mesa/drivers/dri/sis/sis_span.c b/src/mesa/drivers/dri/sis/sis_span.c new file mode 100644 index 00000000000..202454a06af --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_span.c @@ -0,0 +1,311 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_span.c,v 1.5 2001/03/21 16:14:26 dawes Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#include "sis_context.h" +#include "sis_span.h" + +#include "swrast/swrast.h" + +#define DBG 0 + +#define LOCAL_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + char *buf = (char *)(smesa->FbBase + smesa->drawOffset); \ + char *read_buf = (char *)(smesa->FbBase + smesa->readOffset); \ + GLuint p; \ + (void) read_buf; (void) buf; (void) p + +#define LOCAL_DEPTH_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + char *buf = smesa->depthbuffer; \ + +#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 HW_LOCK() do {} while(0); + +#define HW_CLIPLOOP() \ + do { \ + __DRIdrawablePrivate *dPriv = smesa->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() do {} while(0); + +/* RGB565 */ +#define INIT_MONO_PIXEL(p, color) \ + p = SISPACKCOLOR565( color[0], color[1], color[2] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLushort *)(buf + _x*2 + _y*smesa->drawPitch) = \ + (((r & 0xf8) << 8) | \ + ((g & 0xfc) << 3) | \ + (b >> 3)) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLushort *)(buf + _x*2 + _y*smesa->drawPitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLushort p = *(GLushort *)(read_buf + _x*2 + _y*smesa->readPitch); \ + rgba[0] = (p & 0xf800) >> 8; \ + rgba[1] = (p & 0x07e0) >> 3; \ + rgba[2] = (p & 0x001f) << 3; \ + rgba[3] = 0xff; \ +} while(0) + +#define TAG(x) sis##x##_565 +#include "spantmp.h" + + +/* ARGB8888 */ +#undef INIT_MONO_PIXEL +#define INIT_MONO_PIXEL(p, color) \ + p = SISPACKCOLOR8888( color[0], color[1], color[2], color[3] ) + +#define WRITE_RGBA( _x, _y, r, g, b, a ) \ + *(GLuint *)(buf + _x*4 + _y*smesa->drawPitch) = \ + (((a) << 24) | \ + ((r) << 16) | \ + ((g) << 8) | \ + ((b))) + +#define WRITE_PIXEL( _x, _y, p ) \ + *(GLuint *)(buf + _x*4 + _y*smesa->drawPitch) = p + +#define READ_RGBA( rgba, _x, _y ) \ +do { \ + GLuint p = *(GLuint *)(read_buf + _x*4 + _y*smesa->readPitch); \ + rgba[0] = (p >> 16) & 0xff; \ + rgba[1] = (p >> 8) & 0xff; \ + rgba[2] = (p >> 0) & 0xff; \ + rgba[3] = 0xff; \ +} while(0) + +#define TAG(x) sis##x##_8888 +#include "spantmp.h" + + +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + _x*2 + _y*smesa->depthPitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + _x*2 + _y*smesa->depthPitch); + +#define TAG(x) sis##x##_16 +#include "depthtmp.h" + + +/* 32 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLuint *)(buf + _x*4 + _y*smesa->depthPitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + _x*4 + _y*smesa->depthPitch); + +#define TAG(x) sis##x##_32 +#include "depthtmp.h" + + +/* 8/24 bit interleaved depth/stencil functions + */ +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + _x*4 + _y*smesa->depthPitch); \ + tmp &= 0xff000000; \ + tmp |= (d & 0x00ffffff); \ + *(GLuint *)(buf + _x*4 + _y*smesa->depthPitch) = tmp; \ +} + +#define READ_DEPTH( d, _x, _y ) { \ + d = *(GLuint *)(buf + _x*4 + _y*smesa->depthPitch) & 0x00ffffff; \ +} + +#define TAG(x) sis##x##_24_8 +#include "depthtmp.h" + +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + _x*4 + _y*smesa->depthPitch); \ + tmp &= 0x00ffffff; \ + tmp |= (d << 24); \ + *(GLuint *)(buf + _x*4 + _y*smesa->depthPitch) = tmp; \ +} + +#define READ_STENCIL( d, _x, _y ) \ + d = (*(GLuint *)(buf + _x*4 + _y*smesa->depthPitch) & 0xff000000) >> 24; + +#define TAG(x) sis##x##_24_8 +#include "stenciltmp.h" + +/* + * 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 sisDDSetBuffer( GLcontext *ctx, + GLframebuffer *colorBuffer, + GLuint bufferBit ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + switch ( bufferBit ) { + case FRONT_LEFT_BIT: + smesa->drawOffset = smesa->readOffset = smesa->frontOffset; + smesa->drawPitch = smesa->readPitch = smesa->frontPitch; + break; + case BACK_LEFT_BIT: + smesa->drawOffset = smesa->readOffset = smesa->backOffset; + smesa->drawPitch = smesa->readPitch = smesa->backPitch; + break; + default: + break; + } +} + +static void sisSpanRenderStart( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + WaitEngIdle( smesa ); +} + +static void sisSpanRenderFinish( GLcontext *ctx ) +{ + _swrast_flush( ctx ); +} + +void +sisDDInitSpanFuncs( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + + swdd->SetBuffer = sisDDSetBuffer; + + switch (smesa->zFormat) + { + case SiS_ZFORMAT_Z16: + swdd->ReadDepthSpan = sisReadDepthSpan_16; + swdd->ReadDepthPixels = sisReadDepthPixels_16; + swdd->WriteDepthSpan = sisWriteDepthSpan_16; + swdd->WriteDepthPixels = sisWriteDepthPixels_16; + + swdd->ReadStencilSpan = NULL; + swdd->ReadStencilPixels = NULL; + swdd->WriteStencilSpan = NULL; + swdd->WriteStencilPixels = NULL; + break; + case SiS_ZFORMAT_Z32: + swdd->ReadDepthSpan = sisReadDepthSpan_32; + swdd->ReadDepthPixels = sisReadDepthPixels_32; + swdd->WriteDepthSpan = sisWriteDepthSpan_32; + swdd->WriteDepthPixels = sisWriteDepthPixels_32; + + swdd->ReadStencilSpan = NULL; + swdd->ReadStencilPixels = NULL; + swdd->WriteStencilSpan = NULL; + swdd->WriteStencilPixels = NULL; + break; + case SiS_ZFORMAT_S8Z24: + swdd->ReadDepthSpan = sisReadDepthSpan_24_8; + swdd->ReadDepthPixels = sisReadDepthPixels_24_8; + swdd->WriteDepthSpan = sisWriteDepthSpan_24_8; + swdd->WriteDepthPixels = sisWriteDepthPixels_24_8; + + swdd->ReadStencilSpan = sisReadStencilSpan_24_8; + swdd->ReadStencilPixels = sisReadStencilPixels_24_8; + swdd->WriteStencilSpan = sisWriteStencilSpan_24_8; + swdd->WriteStencilPixels = sisWriteStencilPixels_24_8; + break; + } + + switch ( smesa->bytesPerPixel ) + { + case 2: + swdd->WriteRGBASpan = sisWriteRGBASpan_565; + swdd->WriteRGBSpan = sisWriteRGBSpan_565; + swdd->WriteMonoRGBASpan = sisWriteMonoRGBASpan_565; + swdd->WriteRGBAPixels = sisWriteRGBAPixels_565; + swdd->WriteMonoRGBAPixels = sisWriteMonoRGBAPixels_565; + swdd->ReadRGBASpan = sisReadRGBASpan_565; + swdd->ReadRGBAPixels = sisReadRGBAPixels_565; + break; + case 4: + swdd->WriteRGBASpan = sisWriteRGBASpan_8888; + swdd->WriteRGBSpan = sisWriteRGBSpan_8888; + swdd->WriteMonoRGBASpan = sisWriteMonoRGBASpan_8888; + swdd->WriteRGBAPixels = sisWriteRGBAPixels_8888; + swdd->WriteMonoRGBAPixels = sisWriteMonoRGBAPixels_8888; + swdd->ReadRGBASpan = sisReadRGBASpan_8888; + swdd->ReadRGBAPixels = sisReadRGBAPixels_8888; + break; + default: + assert(0); + break; + } + + swdd->WriteCI8Span = NULL; + swdd->WriteCI32Span = NULL; + swdd->WriteMonoCISpan = NULL; + swdd->WriteCI32Pixels = NULL; + swdd->WriteMonoCIPixels = NULL; + swdd->ReadCI32Span = NULL; + swdd->ReadCI32Pixels = NULL; + + swdd->SpanRenderStart = sisSpanRenderStart; + swdd->SpanRenderFinish = sisSpanRenderFinish; +} diff --git a/src/mesa/drivers/dri/sis/sis_span.h b/src/mesa/drivers/dri/sis/sis_span.h new file mode 100644 index 00000000000..cfc19606c72 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_span.h @@ -0,0 +1,41 @@ +/************************************************************************** + +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Eric Anholt + */ + +#ifndef __SIS_SPAN_H__ +#define __SIS_SPAN_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void sisDDInitSpanFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/src/mesa/drivers/dri/sis/sis_state.c b/src/mesa/drivers/dri/sis/sis_state.c new file mode 100644 index 00000000000..9d093595a1c --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_state.c @@ -0,0 +1,918 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_ctx.c,v 1.3 2000/09/26 15:56:48 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_tris.h" +#include "sis_lock.h" +#include "sis_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 +sisDDAlphaFunc( GLcontext * ctx, GLenum func, GLfloat ref ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + GLubyte refbyte; + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + CLAMPED_FLOAT_TO_UBYTE(refbyte, ref); + current->hwAlpha = refbyte << 16; + + /* Alpha Test function */ + switch (func) + { + case GL_NEVER: + current->hwAlpha |= SiS_ALPHA_NEVER; + break; + case GL_LESS: + current->hwAlpha |= SiS_ALPHA_LESS; + break; + case GL_EQUAL: + current->hwAlpha |= SiS_ALPHA_EQUAL; + break; + case GL_LEQUAL: + current->hwAlpha |= SiS_ALPHA_LEQUAL; + break; + case GL_GREATER: + current->hwAlpha |= SiS_ALPHA_GREATER; + break; + case GL_NOTEQUAL: + current->hwAlpha |= SiS_ALPHA_NOTEQUAL; + break; + case GL_GEQUAL: + current->hwAlpha |= SiS_ALPHA_GEQUAL; + break; + case GL_ALWAYS: + current->hwAlpha |= SiS_ALPHA_ALWAYS; + break; + } + + prev->hwAlpha = current->hwAlpha; + smesa->GlobalFlag |= GFLAG_ALPHASETTING; +} + +static void +sisDDBlendFunc( GLcontext *ctx, GLenum sfactor, GLenum dfactor ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + /* TODO: in ICD, if no blend, it will reset these value */ + /* blending enable */ + current->hwDstSrcBlend = 0x10000; /* Default destination alpha */ + + switch (dfactor) + { + case GL_ZERO: + current->hwDstSrcBlend |= SiS_D_ZERO; + break; + case GL_ONE: + current->hwDstSrcBlend |= SiS_D_ONE; + break; + case GL_SRC_COLOR: + current->hwDstSrcBlend |= SiS_D_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_COLOR; + break; + case GL_SRC_ALPHA: + current->hwDstSrcBlend |= SiS_D_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + current->hwDstSrcBlend |= SiS_D_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + current->hwDstSrcBlend |= SiS_D_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + current->hwDstSrcBlend |= SiS_D_ONE_MINUS_DST_ALPHA; + break; + } + + switch (sfactor) + { + case GL_ZERO: + current->hwDstSrcBlend |= SiS_S_ZERO; + break; + case GL_ONE: + current->hwDstSrcBlend |= SiS_S_ONE; + break; + case GL_SRC_ALPHA: + current->hwDstSrcBlend |= SiS_S_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + current->hwDstSrcBlend |= SiS_S_ONE_MINUS_SRC_ALPHA; + break; + case GL_DST_ALPHA: + current->hwDstSrcBlend |= SiS_S_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_ALPHA; + break; + case GL_DST_COLOR: + current->hwDstSrcBlend |= SiS_S_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + current->hwDstSrcBlend |= SiS_S_ONE_MINUS_DST_COLOR; + break; + case GL_SRC_ALPHA_SATURATE: + current->hwDstSrcBlend |= SiS_S_SRC_ALPHA_SATURATE; + break; + } + + if (current->hwDstSrcBlend != prev->hwDstSrcBlend) { + prev->hwDstSrcBlend = current->hwDstSrcBlend; + smesa->GlobalFlag |= GFLAG_DSTBLEND; + } +} + +/* ============================================================= + * Depth testing + */ + +static void +sisDDDepthFunc( GLcontext * ctx, GLenum func ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + current->hwZ &= ~MASK_ZTestMode; + switch (func) + { + case GL_LESS: + current->hwZ |= SiS_Z_COMP_S_LT_B; + break; + case GL_GEQUAL: + current->hwZ |= SiS_Z_COMP_S_GE_B; + break; + case GL_LEQUAL: + current->hwZ |= SiS_Z_COMP_S_LE_B; + break; + case GL_GREATER: + current->hwZ |= SiS_Z_COMP_S_GT_B; + break; + case GL_NOTEQUAL: + current->hwZ |= SiS_Z_COMP_S_NE_B; + break; + case GL_EQUAL: + current->hwZ |= SiS_Z_COMP_S_EQ_B; + break; + case GL_ALWAYS: + current->hwZ |= SiS_Z_COMP_ALWAYS; + break; + case GL_NEVER: + current->hwZ |= SiS_Z_COMP_NEVER; + break; + } + + if (current->hwZ != prev->hwZ) { + prev->hwZ = current->hwZ; + smesa->GlobalFlag |= GFLAG_ZSETTING; + } +} + +void +sisDDDepthMask( GLcontext * ctx, GLboolean flag ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (!ctx->Depth.Test) + flag = GL_FALSE; + + if (ctx->Visual.stencilBits) { + if (flag || (ctx->Stencil.WriteMask[0] != 0)) { + current->hwCapEnable |= MASK_ZWriteEnable; + if (flag && (ctx->Stencil.WriteMask[0] == 0xff)) { + current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable; + } else { + current->hwCapEnable2 |= MASK_ZMaskWriteEnable; + current->hwZMask = (ctx->Stencil.WriteMask[0] << 24) | + ((flag) ? 0x00ffffff : 0); + + if (current->hwZMask ^ prev->hwZMask) { + prev->hwZMask = current->hwZMask; + smesa->GlobalFlag |= GFLAG_ZSETTING; + } + } + } else { + current->hwCapEnable &= ~MASK_ZWriteEnable; + } + } else { + if (flag) { + current->hwCapEnable |= MASK_ZWriteEnable; + current->hwCapEnable2 &= ~MASK_ZMaskWriteEnable; + } else { + current->hwCapEnable &= ~MASK_ZWriteEnable; + } + } +} + +/* ============================================================= + * Clipping + */ + +void +sisUpdateClipping( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + GLint x1, y1, x2, y2; + + x1 = 0; + y1 = 0; + x2 = smesa->width - 1; + y2 = smesa->height - 1; + + if (ctx->Scissor.Enabled) { + if (ctx->Scissor.X > x1) + x1 = ctx->Scissor.X; + if (ctx->Scissor.Y > y1) + y1 = ctx->Scissor.Y; + if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2) + x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; + if (ctx->Scissor.Y + ctx->Scissor.Height - 1 < y2) + y2 = ctx->Scissor.Y + ctx->Scissor.Height - 1; + } + + y1 = Y_FLIP(y1); + y2 = Y_FLIP(y2); + + current->clipTopBottom = (y2 << 13) | y1; + current->clipLeftRight = (x1 << 13) | x2; + + if ((current->clipTopBottom ^ prev->clipTopBottom) || + (current->clipLeftRight ^ prev->clipLeftRight)) + { + prev->clipTopBottom = current->clipTopBottom; + prev->clipLeftRight = current->clipLeftRight; + smesa->GlobalFlag |= GFLAG_CLIPPING; + } +} + +static void +sisDDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) +{ + if (ctx->Scissor.Enabled) + sisUpdateClipping( ctx ); +} + +/* ============================================================= + * Culling + */ + +static void +sisUpdateCull( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + GLint cullflag, frontface; + + cullflag = ctx->Polygon.CullFaceMode; + frontface = ctx->Polygon.FrontFace; + + smesa->AGPParseSet &= ~(MASK_PsCullDirection_CCW); + smesa->dwPrimitiveSet &= ~(MASK_CullDirection); + + if((cullflag == GL_FRONT && frontface == GL_CCW) || + (cullflag == GL_BACK && frontface == GL_CW)) + { + smesa->AGPParseSet |= MASK_PsCullDirection_CCW; + smesa->dwPrimitiveSet |= OP_3D_CullDirection_CCW; + } +} + + +static void +sisDDCullFace( GLcontext *ctx, GLenum mode ) +{ + sisUpdateCull( ctx ); +} + +static void +sisDDFrontFace( GLcontext *ctx, GLenum mode ) +{ + sisUpdateCull( ctx ); +} + +/* ============================================================= + * Masks + */ + +static void sisDDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (r && g && b && ((ctx->Visual.alphaBits == 0) || a)) { + current->hwCapEnable2 &= ~(MASK_AlphaMaskWriteEnable | + MASK_ColorMaskWriteEnable); + } else { + current->hwCapEnable2 |= (MASK_AlphaMaskWriteEnable | + MASK_ColorMaskWriteEnable); + + current->hwDstMask = (r) ? GET_RMASK(smesa) : 0 | + (g) ? GET_GMASK(smesa) : 0 | + (b) ? GET_BMASK(smesa) : 0 | + (a) ? GET_AMASK(smesa) : 0; + } + + if (current->hwDstMask != prev->hwDstMask) { + prev->hwDstMask = current->hwDstMask; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } +} + +/* ============================================================= + * Rendering attributes + */ + +static void sisDDShadeModel( GLcontext *ctx, GLenum mode ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */ + smesa->hw_primitive = -1; +} + +/* ============================================================= + * Window position + */ + +/* ============================================================= + * Viewport + */ + +static void sisCalcViewport( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + const GLfloat *v = ctx->Viewport._WindowMap.m; + GLfloat *m = smesa->hw_viewport; + + /* See also sis_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] + smesa->driDrawable->h + SUBPIXEL_Y; + m[MAT_SZ] = v[MAT_SZ] * smesa->depth_scale; + m[MAT_TZ] = v[MAT_TZ] * smesa->depth_scale; +} + +static void sisDDViewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + sisCalcViewport( ctx ); +} + +static void sisDDDepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + sisCalcViewport( ctx ); +} + +/* ============================================================= + * Miscellaneous + */ + +static void +sisDDLogicOpCode( GLcontext *ctx, GLenum opcode ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (!ctx->Color.ColorLogicOpEnabled) + return; + + current->hwDstSet &= ~MASK_ROP2; + switch (opcode) + { + case GL_CLEAR: + current->hwDstSet |= LOP_CLEAR; + break; + case GL_SET: + current->hwDstSet |= LOP_SET; + break; + case GL_COPY: + current->hwDstSet |= LOP_COPY; + break; + case GL_COPY_INVERTED: + current->hwDstSet |= LOP_COPY_INVERTED; + break; + case GL_NOOP: + current->hwDstSet |= LOP_NOOP; + break; + case GL_INVERT: + current->hwDstSet |= LOP_INVERT; + break; + case GL_AND: + current->hwDstSet |= LOP_AND; + break; + case GL_NAND: + current->hwDstSet |= LOP_NAND; + break; + case GL_OR: + current->hwDstSet |= LOP_OR; + break; + case GL_NOR: + current->hwDstSet |= LOP_NOR; + break; + case GL_XOR: + current->hwDstSet |= LOP_XOR; + break; + case GL_EQUIV: + current->hwDstSet |= LOP_EQUIV; + break; + case GL_AND_REVERSE: + current->hwDstSet |= LOP_AND_REVERSE; + break; + case GL_AND_INVERTED: + current->hwDstSet |= LOP_AND_INVERTED; + break; + case GL_OR_REVERSE: + current->hwDstSet |= LOP_OR_REVERSE; + break; + case GL_OR_INVERTED: + current->hwDstSet |= LOP_OR_INVERTED; + break; + } + + if (current->hwDstSet ^ prev->hwDstSet) { + prev->hwDstSet = current->hwDstSet; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } +} + +void sisDDDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + /* + * _DrawDestMask is easier to cope with than . + */ + switch ( ctx->Color._DrawDestMask ) { + case FRONT_LEFT_BIT: + case BACK_LEFT_BIT: + FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + /* We want to update the s/w rast state too so that sisDDSetBuffer() + * gets called. + */ + _swrast_DrawBuffer(ctx, mode); + + current->hwOffsetDest = (smesa->drawOffset) >> 1; + current->hwDstSet &= ~MASK_DstBufferPitch; + current->hwDstSet |= smesa->drawPitch >> 2; + + if (current->hwDstSet != prev->hwDstSet) { + prev->hwDstSet = current->hwDstSet; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } + + if (current->hwOffsetDest != prev->hwOffsetDest) { + prev->hwOffsetDest = current->hwOffsetDest; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } +} + +static void +sisDDHint( GLcontext *ctx, GLenum target, GLenum mode ) +{ + + switch (target) { + case GL_FOG_HINT: + /* Update fog mode setting */ + sisDDFogfv(ctx, GL_FOG_MODE, NULL); + break; + } + +} + +/* ============================================================= + * Polygon stipple + */ + +/* ============================================================= + * Render mode + */ + +/* ============================================================= + * State enable/disable + */ + +static void +sisDDEnable( GLcontext * ctx, GLenum cap, GLboolean state ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *current = &smesa->current; + + switch (cap) + { + case GL_ALPHA_TEST: + if (state) + current->hwCapEnable |= MASK_AlphaTestEnable; + else + current->hwCapEnable &= ~MASK_AlphaTestEnable; + break; + case GL_BLEND: + /* TODO: */ + if (state) + /* if (state & !ctx->Color.ColorLogicOpEnabled) */ + current->hwCapEnable |= MASK_BlendEnable; + else + current->hwCapEnable &= ~MASK_BlendEnable; + break; + case GL_CULL_FACE: + if (state) + current->hwCapEnable |= MASK_CullEnable; + else + current->hwCapEnable &= ~MASK_CullEnable; + break; + case GL_DEPTH_TEST: + if (state && smesa->depthbuffer) + current->hwCapEnable |= MASK_ZTestEnable; + else + current->hwCapEnable &= ~MASK_ZTestEnable; + sisDDDepthMask( ctx, ctx->Depth.Mask ); + break; + case GL_DITHER: + if (state) + current->hwCapEnable |= MASK_DitherEnable; + else + current->hwCapEnable &= ~MASK_DitherEnable; + break; + case GL_FOG: + if (state) + current->hwCapEnable |= MASK_FogEnable; + else + current->hwCapEnable &= ~MASK_FogEnable; + break; + case GL_COLOR_LOGIC_OP: + if (state) + sisDDLogicOpCode( ctx, ctx->Color.LogicOp ); + else + sisDDLogicOpCode( ctx, GL_COPY ); + break; + case GL_SCISSOR_TEST: + sisUpdateClipping( ctx ); + break; + case GL_STENCIL_TEST: + if (state) { + if (smesa->zFormat != SiS_ZFORMAT_S8Z24) + FALLBACK(smesa, SIS_FALLBACK_STENCIL, 1); + else + current->hwCapEnable |= (MASK_StencilTestEnable | + MASK_StencilWriteEnable); + } else { + FALLBACK(smesa, SIS_FALLBACK_STENCIL, 0); + current->hwCapEnable &= ~(MASK_StencilTestEnable | + MASK_StencilWriteEnable); + } + break; + } +} + +/* ============================================================= + * Pixel functions + */ + +static void +sisDDDrawPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *unpack, + const GLvoid *pixels ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + LOCK_HARDWARE(); + _swrast_DrawPixels( ctx, x, y, width, height, format, type, unpack, pixels ); + UNLOCK_HARDWARE(); +} + +static void +sisDDReadPixels( GLcontext *ctx, + GLint x, GLint y, GLsizei width, GLsizei height, + GLenum format, GLenum type, + const struct gl_pixelstore_attrib *pack, + GLvoid *pixels ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + LOCK_HARDWARE(); + _swrast_ReadPixels( ctx, x, y, width, height, format, type, pack, + pixels); + UNLOCK_HARDWARE(); +} + +static void +sisDDBitmap( GLcontext *ctx, GLint px, GLint py, + GLsizei width, GLsizei height, + const struct gl_pixelstore_attrib *unpack, + const GLubyte *bitmap ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + LOCK_HARDWARE(); + _swrast_Bitmap( ctx, px, py, width, height, unpack, bitmap ); + UNLOCK_HARDWARE(); +} + +/* ============================================================= + * State initialization, management + */ + +/* Called before beginning of rendering. */ +void +sisUpdateHWState( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (smesa->NewGLState & _NEW_TEXTURE) + sisUpdateTextureState( ctx ); + + /* enable setting 1 */ + if (current->hwCapEnable ^ prev->hwCapEnable) { + prev->hwCapEnable = current->hwCapEnable; + smesa->GlobalFlag |= GFLAG_ENABLESETTING; + } + + /* enable setting 2 */ + if (current->hwCapEnable2 ^ prev->hwCapEnable2) { + prev->hwCapEnable2 = current->hwCapEnable2; + smesa->GlobalFlag |= GFLAG_ENABLESETTING2; + } + + /* TODO: if fog disable, don't check */ + if (current->hwCapEnable & MASK_FogEnable) { + /* fog setting */ + if (current->hwFog != prev->hwFog) { + prev->hwFog = current->hwFog; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + if (current->hwFogFar != prev->hwFogFar) { + prev->hwFogFar = current->hwFogFar; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + if (current->hwFogInverse != prev->hwFogInverse) { + prev->hwFogInverse = current->hwFogInverse; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + if (current->hwFogDensity != prev->hwFogDensity) { + prev->hwFogDensity = current->hwFogDensity; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + } + + if (smesa->GlobalFlag & GFLAG_RENDER_STATES) + sis_update_render_state( smesa ); + + if (smesa->GlobalFlag & GFLAG_TEXTURE_STATES) + sis_update_texture_state( smesa ); +} + +static void +sisDDInvalidateState( GLcontext *ctx, GLuint new_state ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _ac_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + smesa->NewGLState |= new_state; +} + +/* Initialize the context's hardware state. + */ +void sisDDInitState( sisContextPtr smesa ) +{ + __GLSiSHardware *current = &smesa->current; + __GLSiSHardware *prev = &(smesa->prev); + GLcontext *ctx = smesa->glCtx; + + /* add Texture Perspective Enable */ + prev->hwCapEnable = MASK_FogPerspectiveEnable | MASK_TextureCacheEnable | + MASK_TexturePerspectiveEnable | MASK_DitherEnable; + /*| MASK_SpecularEnable*/ + + /* + prev->hwCapEnable2 = 0x00aa0080; + */ + /* if multi-texture enabled, disable Z pre-test */ + prev->hwCapEnable2 = MASK_TextureMipmapBiasEnable; + + /* Z test mode is LESS */ + prev->hwZ = SiS_Z_COMP_S_LT_B; + + /* Depth mask */ + prev->hwZMask = 0xffffffff; + + /* Alpha test mode is ALWAYS, alpha ref value is 0 */ + prev->hwAlpha = SiS_ALPHA_ALWAYS; + + /* ROP2 is COPYPEN */ + prev->hwDstSet = LOP_COPY; + + /* color mask */ + prev->hwDstMask = 0xffffffff; + + /* LinePattern is 0, Repeat Factor is 0 */ + prev->hwLinePattern = 0x00008000; + + /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */ + prev->hwDstSrcBlend = SiS_S_ONE | SiS_D_ZERO; + + /* Stenciling disabled, function ALWAYS, ref value zero, mask all ones */ + prev->hwStSetting = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | 0xff; + /* Op is KEEP for all three operations */ + prev->hwStSetting2 = SiS_SFAIL_KEEP | SiS_SPASS_ZFAIL_KEEP | + SiS_SPASS_ZPASS_KEEP; + + /* Texture mapping mode is Tile */ +#if 0 + prev->texture[0].hwTextureSet = 0x00030000; +#endif + /* Magnified & minified texture filter is NEAREST */ +#if 0 + prev->texture[0].hwTextureMip = 0; +#endif + + /* Texture Blending seeting */ + prev->hwTexBlendClr0 = L_REPLACE__RGB_STAGE0; + prev->hwTexBlendClr1 = 0x294B4000; + prev->hwTexBlendAlpha0 = 0x333A0000; + prev->hwTexBlendAlpha1 = 0x333A0000; + + switch (smesa->bytesPerPixel) + { + case 2: + prev->hwDstSet |= DST_FORMAT_RGB_565; + break; + case 4: + prev->hwDstSet |= DST_FORMAT_ARGB_8888; + break; + } + + switch (ctx->Visual.depthBits) + { + case 0: + prev->hwCapEnable &= ~MASK_ZWriteEnable; + case 16: + smesa->zFormat = SiS_ZFORMAT_Z16; + prev->hwCapEnable |= MASK_ZWriteEnable; + smesa->depth_scale = 1.0 / (GLfloat)0xffff; + break; + case 32: + smesa->zFormat = SiS_ZFORMAT_Z32; + prev->hwCapEnable |= MASK_ZWriteEnable; + smesa->depth_scale = 1.0 / (GLfloat)0xffffffff; + break; + case 24: + assert (ctx->Visual.stencilBits); + smesa->zFormat = SiS_ZFORMAT_S8Z24; + prev->hwCapEnable |= MASK_StencilBufferEnable; + prev->hwCapEnable |= MASK_ZWriteEnable; + smesa->depth_scale = 1.0 / (GLfloat)0xffffff; + break; + } + + prev->hwZ |= smesa->zFormat; + + /* TODO: need to clear cache? */ + smesa->clearTexCache = GL_TRUE; + + smesa->clearColorPattern = 0; + + smesa->AGPParseSet = MASK_PsTexture1FromB; + smesa->dwPrimitiveSet = OP_3D_Texture1FromB | OP_3D_TextureBumpFromC; + + sisUpdateZStencilPattern( smesa, 1.0, 0 ); + sisUpdateCull( ctx ); + + memcpy( current, prev, sizeof (__GLSiSHardware) ); + + /* Set initial fog settings. Start and end are the same case. */ + sisDDFogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + sisDDFogfv( ctx, GL_FOG_END, &ctx->Fog.End ); + sisDDFogfv( ctx, GL_FOG_MODE, NULL ); +} + +/* Initialize the driver's state functions. + */ +void sisDDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = sisDDInvalidateState; + + ctx->Driver.Clear = sisDDClear; + ctx->Driver.ClearColor = sisDDClearColor; + ctx->Driver.ClearDepth = sisDDClearDepth; + ctx->Driver.ClearStencil = sisDDClearStencil; + + ctx->Driver.AlphaFunc = sisDDAlphaFunc; + ctx->Driver.Bitmap = sisDDBitmap; + ctx->Driver.BlendFunc = sisDDBlendFunc; + ctx->Driver.ColorMask = sisDDColorMask; + ctx->Driver.CullFace = sisDDCullFace; + ctx->Driver.DepthMask = sisDDDepthMask; + ctx->Driver.DepthFunc = sisDDDepthFunc; + ctx->Driver.DepthRange = sisDDDepthRange; + ctx->Driver.DrawBuffer = sisDDDrawBuffer; + ctx->Driver.DrawPixels = sisDDDrawPixels; + ctx->Driver.Enable = sisDDEnable; + ctx->Driver.FrontFace = sisDDFrontFace; + ctx->Driver.Fogfv = sisDDFogfv; + ctx->Driver.Hint = sisDDHint; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LogicOpcode = sisDDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = NULL; + ctx->Driver.ReadBuffer = NULL; + ctx->Driver.ReadPixels = sisDDReadPixels; + ctx->Driver.RenderMode = NULL; + ctx->Driver.Scissor = sisDDScissor; + ctx->Driver.ShadeModel = sisDDShadeModel; + ctx->Driver.Viewport = sisDDViewport; + + /* Pixel path fallbacks. + */ + ctx->Driver.Accum = _swrast_Accum; + ctx->Driver.CopyPixels = _swrast_CopyPixels; + + /* 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/sis/sis_state.h b/src/mesa/drivers/dri/sis/sis_state.h new file mode 100644 index 00000000000..49ecdfa1bae --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_state.h @@ -0,0 +1,58 @@ +/************************************************************************** + +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Eric Anholt + */ + +#ifndef __SIS_STATE_H__ +#define __SIS_STATE_H__ + +#ifdef GLX_DIRECT_RENDERING + +#include "sis_context.h" + +extern void sisDDInitState( sisContextPtr smesa ); +extern void sisDDInitStateFuncs( GLcontext *ctx ); + +extern void sisDDClear( GLcontext *ctx, GLbitfield mask, GLboolean all, + GLint x, GLint y, GLint width, GLint height ); +extern void sisDDClearColor( GLcontext * ctx, const GLfloat color[4] ); +extern void sisDDClearDepth( GLcontext * ctx, GLclampd d ); +extern void sisDDClearStencil( GLcontext * ctx, GLint s ); +extern void sisDDFogfv( GLcontext * ctx, GLenum pname, const GLfloat * params ); +extern void sisDDDepthMask( GLcontext * ctx, GLboolean flag ); + +extern void sisUpdateClipping( GLcontext * gc ); +extern void sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, + int stencil ); +extern void sisDDDrawBuffer( GLcontext *ctx, GLenum mode ); +extern void sisUpdateHWState( GLcontext *ctx ); + +#endif +#endif diff --git a/src/mesa/drivers/dri/sis/sis_stencil.c b/src/mesa/drivers/dri/sis/sis_stencil.c new file mode 100644 index 00000000000..3d7a1d5e6aa --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_stencil.c @@ -0,0 +1,185 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86: xc/lib/GL/mesa/src/drv/sis/sis_stencil.c,v 1.3 2000/09/26 15:56:49 tsi Exp $ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_stencil.h" + +static void +sisDDStencilFunc( GLcontext * ctx, GLenum func, GLint ref, GLuint mask ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + /* set reference */ + current->hwStSetting = STENCIL_FORMAT_8 | (ctx->Stencil.Ref[0] << 8) | + ctx->Stencil.ValueMask[0]; + + switch (func) + { + case GL_NEVER: + current->hwStSetting |= SiS_STENCIL_NEVER; + break; + case GL_LESS: + current->hwStSetting |= SiS_STENCIL_LESS; + break; + case GL_EQUAL: + current->hwStSetting |= SiS_STENCIL_EQUAL; + break; + case GL_LEQUAL: + current->hwStSetting |= SiS_STENCIL_LEQUAL; + break; + case GL_GREATER: + current->hwStSetting |= SiS_STENCIL_GREATER; + break; + case GL_NOTEQUAL: + current->hwStSetting |= SiS_STENCIL_NOTEQUAL; + break; + case GL_GEQUAL: + current->hwStSetting |= SiS_STENCIL_GEQUAL; + break; + case GL_ALWAYS: + current->hwStSetting |= SiS_STENCIL_ALWAYS; + break; + } + + if (current->hwStSetting != prev->hwStSetting) + { + prev->hwStSetting = current->hwStSetting; + + smesa->GlobalFlag |= GFLAG_STENCILSETTING; + } +} + +static void +sisDDStencilMask( GLcontext * ctx, GLuint mask ) +{ + if (!ctx->Visual.stencilBits) + return; + + /* set Z buffer Write Enable */ + sisDDDepthMask (ctx, ctx->Depth.Mask); +} + +static void +sisDDStencilOp( GLcontext * ctx, GLenum fail, GLenum zfail, GLenum zpass ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + current->hwStSetting2 &= ~(MASK_StencilZPassOp | MASK_StencilZFailOp | + MASK_StencilFailOp); + + switch (fail) + { + case GL_KEEP: + current->hwStSetting2 |= SiS_SFAIL_KEEP; + break; + case GL_ZERO: + current->hwStSetting2 |= SiS_SFAIL_ZERO; + break; + case GL_REPLACE: + current->hwStSetting2 |= SiS_SFAIL_REPLACE; + break; + case GL_INVERT: + current->hwStSetting2 |= SiS_SFAIL_INVERT; + break; + case GL_INCR: + current->hwStSetting2 |= SiS_SFAIL_INCR; + break; + case GL_DECR: + current->hwStSetting2 |= SiS_SFAIL_DECR; + break; + } + + switch (zfail) + { + case GL_KEEP: + current->hwStSetting2 |= SiS_SPASS_ZFAIL_KEEP; + break; + case GL_ZERO: + current->hwStSetting2 |= SiS_SPASS_ZFAIL_ZERO; + break; + case GL_REPLACE: + current->hwStSetting2 |= SiS_SPASS_ZFAIL_REPLACE; + break; + case GL_INVERT: + current->hwStSetting2 |= SiS_SPASS_ZFAIL_INVERT; + break; + case GL_INCR: + current->hwStSetting2 |= SiS_SPASS_ZFAIL_INCR; + break; + case GL_DECR: + current->hwStSetting2 |= SiS_SPASS_ZFAIL_DECR; + break; + } + + switch (zpass) + { + case GL_KEEP: + current->hwStSetting2 |= SiS_SPASS_ZPASS_KEEP; + break; + case GL_ZERO: + current->hwStSetting2 |= SiS_SPASS_ZPASS_ZERO; + break; + case GL_REPLACE: + current->hwStSetting2 |= SiS_SPASS_ZPASS_REPLACE; + break; + case GL_INVERT: + current->hwStSetting2 |= SiS_SPASS_ZPASS_INVERT; + break; + case GL_INCR: + current->hwStSetting2 |= SiS_SPASS_ZPASS_INCR; + break; + case GL_DECR: + current->hwStSetting2 |= SiS_SPASS_ZPASS_DECR; + break; + } + + if (current->hwStSetting2 != prev->hwStSetting2) + { + prev->hwStSetting2 = current->hwStSetting2; + smesa->GlobalFlag |= GFLAG_STENCILSETTING; + } +} + +void +sisDDInitStencilFuncs( GLcontext *ctx ) +{ + ctx->Driver.StencilFunc = sisDDStencilFunc; + ctx->Driver.StencilMask = sisDDStencilMask; + ctx->Driver.StencilOp = sisDDStencilOp; +} diff --git a/src/mesa/drivers/dri/sis/sis_stencil.h b/src/mesa/drivers/dri/sis/sis_stencil.h new file mode 100644 index 00000000000..01d4cb6ef27 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_stencil.h @@ -0,0 +1,41 @@ +/************************************************************************** + +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Eric Anholt + */ + +#ifndef __SIS_STENCIL_H__ +#define __SIS_STENCIL_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void sisDDInitStencilFuncs( GLcontext *ctx ); + +#endif +#endif diff --git a/src/mesa/drivers/dri/sis/sis_tex.c b/src/mesa/drivers/dri/sis/sis_tex.c new file mode 100644 index 00000000000..52080b7037e --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_tex.c @@ -0,0 +1,474 @@ +/************************************************************************** + +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Eric Anholt + */ + +#include "sis_context.h" +#include "sis_alloc.h" +#include "sis_tex.h" + +#include "swrast/swrast.h" +#include "imports.h" +#include "texformat.h" +#include "texstore.h" +#include "teximage.h" + +#define ALIGN(value, align) (char *)((long)(value + align - 1) & ~(align - 1)) + +#define TEXTURE_HW_ALIGNMENT 4 +#define TEXTURE_HW_PLUS (4 + 4) + +static sisTexObjPtr +sisAllocTexObj( struct gl_texture_object *texObj ) +{ + sisTexObjPtr t; + + t = (sisTexObjPtr) CALLOC_STRUCT( sis_tex_obj ); + texObj->DriverData = t; + return t; +} + +static void +sisAllocTexImage( sisContextPtr smesa, sisTexObjPtr t, int level, + const struct gl_texture_image *image ) +{ + char *addr; + int size, texel_size; + + if (t->format == 0) { + t->format = image->Format; + switch (t->format) + { + case GL_RGBA: + t->hwformat = TEXEL_ARGB_8888_32; + break; + case GL_INTENSITY: + t->hwformat = TEXEL_I8; + break; + case GL_ALPHA: + t->hwformat = TEXEL_A8; + break; + case GL_LUMINANCE: + t->hwformat = TEXEL_L8; + break; + case GL_LUMINANCE_ALPHA: + t->hwformat = TEXEL_AL88; + break; + case GL_RGB: + t->hwformat = TEXEL_ARGB_0888_32; + break; + default: + assert(0); + } + } + assert(t->format == image->Format); + + texel_size = image->TexFormat->TexelBytes; + size = image->Width * image->Height * texel_size + TEXTURE_HW_PLUS; + + addr = sisAllocFB( smesa, size, &t->image[level].handle ); + if (addr == NULL) { + addr = sisAllocAGP( smesa, size, &t->image[level].handle ); + if (addr == NULL) { + fprintf (stderr, "SIS driver : out of video/agp memory\n"); + sis_fatal_error(); + } + t->image[level].memType = AGP_TYPE; + } + else + t->image[level].memType = VIDEO_TYPE; + + t->image[level].Data = ALIGN(addr, TEXTURE_HW_ALIGNMENT); + t->image[level].pitch = image->Width * texel_size; + t->image[level].size = image->Width * image->Height * texel_size; + t->numImages++; +} + +static void +sisFreeTexImage( sisContextPtr smesa, sisTexObjPtr t, int level ) +{ + if (t->image[level].Data == NULL) + return; + + switch (t->image[level].memType) + { + case VIDEO_TYPE: + sisFreeFB( smesa, t->image[level].handle ); + break; + case AGP_TYPE: + sisFreeAGP( smesa, t->image[level].handle ); + break; + } + t->image[level].Data = NULL; + t->image[level].handle = NULL; + /* If there are no textures loaded any more, reset the hw format so the + * object can be reused for new formats + */ + t->numImages--; + if (t->numImages == 0) { + t->format = 0; + t->hwformat = 0; + } +} + +static void +sisDDTexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV; +} + +static void +sisDDTexParameter( GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj, GLenum pname, + const GLfloat *params ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING; +} + +static void +sisDDBindTexture( GLcontext *ctx, GLenum target, + struct gl_texture_object *texObj ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + sisTexObjPtr t; + + if ( target == GL_TEXTURE_2D || target == GL_TEXTURE_1D ) { + if ( texObj->DriverData == NULL ) { + sisAllocTexObj( texObj ); + } + } + + t = texObj->DriverData; + + if (t == NULL) + return; + + if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format) { + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV; + smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format; + } + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING; +} + +static void +sisDDDeleteTexture( GLcontext * ctx, struct gl_texture_object *texObj ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + sisTexObjPtr t; + int i; + + smesa->clearTexCache = GL_TRUE; + + t = texObj->DriverData; + if (t == NULL) { + /* + * this shows the texture is default object and never be a + * argument of sisDDTexImage* + */ + return; + } + for (i = 0; i < MAX_TEXTURE_LEVELS; i++) { + sisFreeTexImage( smesa, t, i ); + } + + FREE(t); + texObj->DriverData = NULL; +} + +static GLboolean sisDDIsTextureResident( GLcontext * ctx, + struct gl_texture_object *texObj ) +{ + return (texObj->DriverData != NULL); +} + +static const struct gl_texture_format * +sisDDChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + /* XXX 16-bit internal texture formats? */ + switch ( internalFormat ) { + case GL_ALPHA: + case GL_ALPHA4: + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + return &_mesa_texformat_a8; + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + return &_mesa_texformat_l8; + 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: + return &_mesa_texformat_al88; + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + return &_mesa_texformat_i8; + case GL_R3_G3_B2: + case GL_RGB4: + case GL_RGB5: + case 3: + case GL_RGB: + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return &_mesa_texformat_argb8888 /*_mesa_texformat_rgb888*/; /* XXX */ + case GL_RGBA2: + case GL_RGBA4: + case GL_RGB5_A1: + case 4: + case GL_RGBA: + case GL_RGBA8: + case GL_RGB10_A2: + case GL_RGBA12: + case GL_RGBA16: + return &_mesa_texformat_argb8888; + default: + _mesa_problem(ctx, "unexpected format in tdfxDDChooseTextureFormat: %d", + internalFormat); + return NULL; + } +} + +static void sisDDTexImage1D( 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 ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + sisTexObjPtr t; + + if ( texObj->DriverData == NULL ) + sisAllocTexObj( texObj ); + t = texObj->DriverData; + + /* Note, this will call sisDDChooseTextureFormat */ + _mesa_store_teximage1d( ctx, target, level, internalFormat, + width, border, format, type, + pixels, packing, texObj, texImage ); + + /* Allocate offscreen space for the texture */ + sisFreeTexImage(smesa, t, level); + sisAllocTexImage(smesa, t, level, texImage); + + /* Upload the texture */ + memcpy(t->image[level].Data, texImage->Data, t->image[level].size); + + if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format) + { + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV; + smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format; + } + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING; +} + + +static void sisDDTexSubImage1D( 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 ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + sisTexObjPtr t; + GLuint copySize; + GLint texelBytes; + char *src, *dst; + + if ( texObj->DriverData == NULL ) + sisAllocTexObj( texObj ); + t = texObj->DriverData; + + _mesa_store_texsubimage1d(ctx, target, level, xoffset, width, + format, type, pixels, packing, texObj, + texImage); + + /* Allocate offscreen space for the texture */ + sisFreeTexImage(smesa, t, level); + sisAllocTexImage(smesa, t, level, texImage); + + /* Upload the texture */ + texelBytes = texImage->TexFormat->TexelBytes; + + copySize = width * texelBytes; + src = (char *)texImage->Data + xoffset * texelBytes; + dst = t->image[level].Data + xoffset * texelBytes; + + memcpy( dst, src, copySize ); + + smesa->clearTexCache = GL_TRUE; + + if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format) + { + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV; + smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format; + } + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING; +} + +static void sisDDTexImage2D( 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 ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + sisTexObjPtr t; + + if ( texObj->DriverData == NULL ) + sisAllocTexObj( texObj ); + t = texObj->DriverData; + + /* Note, this will call sisDDChooseTextureFormat */ + _mesa_store_teximage2d(ctx, target, level, internalFormat, + width, height, border, format, type, pixels, + &ctx->Unpack, texObj, texImage); + + /* Allocate offscreen space for the texture */ + sisFreeTexImage(smesa, t, level); + sisAllocTexImage(smesa, t, level, texImage); + + /* Upload the texture */ + memcpy(t->image[level].Data, texImage->Data, t->image[level].size); + + if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format) + { + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV; + smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format; + } + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING; +} + +static void sisDDTexSubImage2D( 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 ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + sisTexObjPtr t; + GLuint copySize; + GLint texelBytes; + char *src, *dst; + int j; + GLuint soffset; + + if ( texObj->DriverData == NULL ) + sisAllocTexObj( texObj ); + t = texObj->DriverData; + + _mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width, + height, format, type, pixels, packing, texObj, + texImage); + + /* Allocate offscreen space for the texture */ + sisFreeTexImage(smesa, t, level); + sisAllocTexImage(smesa, t, level, texImage); + + /* Upload the texture */ + texelBytes = texImage->TexFormat->TexelBytes; + + copySize = width * texelBytes; + src = (char *)texImage->Data + (xoffset + yoffset * texImage->Width) * + texelBytes; + dst = t->image[level].Data + (xoffset + yoffset * texImage->Width) * + texelBytes; + soffset = texImage->Width * texelBytes; + + for (j = yoffset; j < yoffset + height; j++) { + memcpy( dst, src, copySize ); + src += soffset; + dst += soffset; + } + + smesa->clearTexCache = GL_TRUE; + + if (smesa->PrevTexFormat[ctx->Texture.CurrentUnit] != t->format) + { + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV; + smesa->PrevTexFormat[ctx->Texture.CurrentUnit] = t->format; + } + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURING; + +} + +void sisDDInitTextureFuncs( GLcontext *ctx ) +{ + ctx->Driver.TexEnv = sisDDTexEnv; + ctx->Driver.ChooseTextureFormat = sisDDChooseTextureFormat; + ctx->Driver.TexImage1D = sisDDTexImage1D; + ctx->Driver.TexSubImage1D = sisDDTexSubImage1D; + ctx->Driver.TexImage2D = sisDDTexImage2D; + ctx->Driver.TexSubImage2D = sisDDTexSubImage2D; + 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 = sisDDTexParameter; + ctx->Driver.BindTexture = sisDDBindTexture; + ctx->Driver.DeleteTexture = sisDDDeleteTexture; + ctx->Driver.IsTextureResident = sisDDIsTextureResident; + ctx->Driver.PrioritizeTexture = NULL; +} diff --git a/src/mesa/drivers/dri/sis/sis_tex.h b/src/mesa/drivers/dri/sis/sis_tex.h new file mode 100644 index 00000000000..188cce5a50f --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_tex.h @@ -0,0 +1,42 @@ +/************************************************************************** + +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Eric Anholt + */ + +#ifndef __SIS_TEX_H__ +#define __SIS_TEX_H__ + +#ifdef GLX_DIRECT_RENDERING + +extern void sisDDInitTextureFuncs( GLcontext *ctx ); +extern void sisUpdateTextureState( GLcontext *ctx ); + +#endif /* GLX_DIRECT_RENDERING */ +#endif /* __SIS_TEX_H__ */ diff --git a/src/mesa/drivers/dri/sis/sis_texstate.c b/src/mesa/drivers/dri/sis/sis_texstate.c new file mode 100644 index 00000000000..23f72589a7e --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_texstate.c @@ -0,0 +1,682 @@ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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. + +**************************************************************************/ +/* $XFree86$ */ + +/* + * Authors: + * Sung-Ching Lin + * Eric Anholt + */ + +#include "glheader.h" +#include "imports.h" +#include "context.h" +#include "macros.h" +#include "texformat.h" + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_tex.h" +#include "sis_tris.h" +#include "sis_alloc.h" + +static GLint TransferTexturePitch (GLint dwPitch); + +/* Handle texenv stuff, called from validate_texture (renderstart) */ +static void +sis_set_texture_env0( GLcontext *ctx, struct gl_texture_object *texObj, + int unit ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit]; + + sisTexObjPtr t = texObj->DriverData; + + /* + current->hwTexBlendClr0 = RGB_STAGE1; + current->hwTexBlendAlpha0 = A_STAGE1; + */ + + switch (texture_unit->EnvMode) + { + case GL_REPLACE: + FALLBACK(smesa, SIS_FALLBACK_TEXENV0, 0); + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendClr0 = A_REPLACE_RGB_STAGE0; + current->hwTexBlendAlpha0 = A_REPLACE_A_STAGE0; + break; + case GL_LUMINANCE: + case GL_RGB: + current->hwTexBlendClr0 = RGB_REPLACE__RGB_STAGE0; + current->hwTexBlendAlpha0 = RGB_REPLACE__A_STAGE0; + break; + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendClr0 = RGBA_REPLACE__RGB_STAGE0; + current->hwTexBlendAlpha0 = RGBA_REPLACE__A_STAGE0; + break; + } + break; + + case GL_MODULATE: + FALLBACK(smesa, SIS_FALLBACK_TEXENV0, 0); + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendClr0 = A_MODULATE_RGB_STAGE0; + current->hwTexBlendAlpha0 = A_MODULATE_A_STAGE0; + break; + case GL_LUMINANCE: + case GL_RGB: + current->hwTexBlendClr0 = RGB_MODULATE__RGB_STAGE0; + current->hwTexBlendAlpha0 = RGB_MODULATE__A_STAGE0; + break; + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendClr0 = RGBA_MODULATE__RGB_STAGE0; + current->hwTexBlendAlpha0 = RGBA_MODULATE__A_STAGE0; + break; + } + break; + + case GL_DECAL: + FALLBACK(smesa, SIS_FALLBACK_TEXENV0, 0); + switch (t->format) + { + case GL_RGB: + current->hwTexBlendClr0 = RGB_DECAL__RGB_STAGE0; + current->hwTexBlendAlpha0 = RGB_DECAL__A_STAGE0; + break; + case GL_RGBA: + current->hwTexBlendClr0 = RGBA_DECAL__RGB_STAGE0; + current->hwTexBlendAlpha0 = RGBA_DECAL__A_STAGE0; + break; + } + break; + + case GL_BLEND: + FALLBACK(smesa, SIS_FALLBACK_TEXENV0, 1); +#if 0 /* XXX Blending broken */ + current->hwTexEnvColor = + ((GLint) (texture_unit->EnvColor[3])) << 24 | + ((GLint) (texture_unit->EnvColor[0])) << 16 | + ((GLint) (texture_unit->EnvColor[1])) << 8 | + ((GLint) (texture_unit->EnvColor[2])); + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendClr0 = A_BLEND_RGB_STAGE0; + current->hwTexBlendAlpha0 = A_BLEND_A_STAGE0; + break; + case GL_LUMINANCE: + case GL_RGB: + current->hwTexBlendClr0 = RGB_BLEND__RGB_STAGE0; + current->hwTexBlendAlpha0 = RGB_BLEND__A_STAGE0; + break; + case GL_INTENSITY: + current->hwTexBlendClr0 = I_BLEND__RGB_STAGE0; + current->hwTexBlendAlpha0 = I_BLEND__A_STAGE0; + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendClr0 = RGBA_BLEND__RGB_STAGE0; + current->hwTexBlendAlpha0 = RGBA_BLEND__A_STAGE0; + break; + } + break; +#endif + } + + if ((current->hwTexBlendClr0 != prev->hwTexBlendClr0) || + (current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) || + (current->hwTexEnvColor != prev->hwTexEnvColor)) + { + prev->hwTexEnvColor = current->hwTexEnvColor; + prev->hwTexBlendClr0 = current->hwTexBlendClr0; + prev->hwTexBlendAlpha0 = current->hwTexBlendAlpha0; + smesa->GlobalFlag |= GFLAG_TEXTUREENV; + } +} + +/* Handle texenv stuff, called from validate_texture (renderstart) */ +static void +sis_set_texture_env1( GLcontext *ctx, struct gl_texture_object *texObj, + int unit) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit]; + + sisTexObjPtr t = texObj->DriverData; + + /* + current->hwTexBlendClr1 = RGB_STAGE1; current->hwTexBlendAlpha1 = + A_STAGE1; + */ + + switch (texture_unit->EnvMode) + { + case GL_REPLACE: + FALLBACK(smesa, SIS_FALLBACK_TEXENV1, 0); + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendClr1 = A_REPLACE_RGB_STAGE1; + current->hwTexBlendAlpha1 = A_REPLACE_A_STAGE1; + break; + case GL_LUMINANCE: + case GL_RGB: + current->hwTexBlendClr1 = RGB_REPLACE__RGB_STAGE1; + current->hwTexBlendAlpha1 = RGB_REPLACE__A_STAGE1; + break; + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendClr1 = RGBA_REPLACE__RGB_STAGE1; + current->hwTexBlendAlpha1 = RGBA_REPLACE__A_STAGE1; + break; + } + break; + + case GL_MODULATE: + FALLBACK(smesa, SIS_FALLBACK_TEXENV1, 0); + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendClr1 = A_MODULATE_RGB_STAGE1; + current->hwTexBlendAlpha1 = A_MODULATE_A_STAGE1; + break; + case GL_LUMINANCE: + case GL_RGB: + current->hwTexBlendClr1 = RGB_MODULATE__RGB_STAGE1; + current->hwTexBlendAlpha1 = RGB_MODULATE__A_STAGE1; + break; + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendClr1 = RGBA_MODULATE__RGB_STAGE1; + current->hwTexBlendAlpha1 = RGBA_MODULATE__A_STAGE1; + break; + } + break; + + case GL_DECAL: + FALLBACK(smesa, SIS_FALLBACK_TEXENV1, 0); + switch (t->format) + { + case GL_RGB: + current->hwTexBlendClr1 = RGB_DECAL__RGB_STAGE1; + current->hwTexBlendAlpha1 = RGB_DECAL__A_STAGE1; + break; + case GL_RGBA: + current->hwTexBlendClr1 = RGBA_DECAL__RGB_STAGE1; + current->hwTexBlendAlpha1 = RGBA_DECAL__A_STAGE1; + break; + } + break; + + case GL_BLEND: + FALLBACK(smesa, SIS_FALLBACK_TEXENV1, 1); +#if 0 /* XXX Blending broken */ + current->hwTexEnvColor = + ((GLint) (texture_unit->EnvColor[3])) << 24 | + ((GLint) (texture_unit->EnvColor[0])) << 16 | + ((GLint) (texture_unit->EnvColor[1])) << 8 | + ((GLint) (texture_unit->EnvColor[2])); + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendClr1 = A_BLEND_RGB_STAGE1; + current->hwTexBlendAlpha1 = A_BLEND_A_STAGE1; + break; + case GL_LUMINANCE: + case GL_RGB: + current->hwTexBlendClr1 = RGB_BLEND__RGB_STAGE1; + current->hwTexBlendAlpha1 = RGB_BLEND__A_STAGE1; + break; + case GL_INTENSITY: + current->hwTexBlendClr1 = I_BLEND__RGB_STAGE1; + current->hwTexBlendAlpha1 = I_BLEND__A_STAGE1; + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendClr1 = RGBA_BLEND__RGB_STAGE1; + current->hwTexBlendAlpha1 = RGBA_BLEND__A_STAGE1; + break; + } + break; +#endif + } + + if ((current->hwTexBlendClr1 != prev->hwTexBlendClr1) || + (current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) || + (current->hwTexEnvColor != prev->hwTexEnvColor)) + { + prev->hwTexBlendClr1 = current->hwTexBlendClr1; + prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1; + prev->hwTexEnvColor = current->hwTexEnvColor; + smesa->GlobalFlag |= GFLAG_TEXTUREENV_1; + } +} + +/* Returns 0 if a software fallback is necessary */ +static GLboolean +sis_set_texobj_parm( GLcontext *ctx, struct gl_texture_object *texObj, + int hw_unit ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + int ok = 1; + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + sisTexObjPtr t = texObj->DriverData; + + GLint firstLevel, lastLevel; + GLint i; + + current->texture[hw_unit].hwTextureMip = 0UL; + current->texture[hw_unit].hwTextureSet = t->hwformat; + + if ((texObj->MinFilter == GL_NEAREST) || (texObj->MinFilter == GL_LINEAR)) { + firstLevel = lastLevel = texObj->BaseLevel; + } else { + /* 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 = texObj->BaseLevel + (GLint)(texObj->MinLod + 0.5); + firstLevel = MAX2(firstLevel, texObj->BaseLevel); + lastLevel = texObj->BaseLevel + (GLint)(texObj->MaxLod + 0.5); + lastLevel = MAX2(lastLevel, texObj->BaseLevel); + lastLevel = MIN2(lastLevel, texObj->BaseLevel + + texObj->Image[texObj->BaseLevel]->MaxLog2); + lastLevel = MIN2(lastLevel, texObj->MaxLevel); + lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */ + } + + current->texture[hw_unit].hwTextureSet |= (lastLevel << 8); + + switch (texObj->MagFilter) + { + case GL_NEAREST: + current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST; + break; + case GL_LINEAR: + current->texture[hw_unit].hwTextureMip |= (TEXTURE_FILTER_LINEAR << 3); + break; + } + + { + GLint b; + + /* The mipmap lod biasing is based on experiment. It seems there's a + * limit of around +4/-4 to the bias value; we're being conservative. + */ + b = (GLint) (ctx->Texture.Unit[hw_unit].LodBias * 32.0); + if (b > 127) + b = 127; + else if (b < -128) + b = -128; + + current->texture[hw_unit].hwTextureMip |= ((b << 4) & + MASK_TextureMipmapLodBias); + } + + switch (texObj->MinFilter) + { + case GL_NEAREST: + current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_NEAREST; + break; + case GL_LINEAR: + current->texture[hw_unit].hwTextureMip |= TEXTURE_FILTER_LINEAR; + break; + case GL_NEAREST_MIPMAP_NEAREST: + current->texture[hw_unit].hwTextureMip |= + TEXTURE_FILTER_NEAREST_MIP_NEAREST; + break; + case GL_NEAREST_MIPMAP_LINEAR: + current->texture[hw_unit].hwTextureMip |= + TEXTURE_FILTER_NEAREST_MIP_LINEAR; + break; + case GL_LINEAR_MIPMAP_NEAREST: + current->texture[hw_unit].hwTextureMip |= + TEXTURE_FILTER_LINEAR_MIP_NEAREST; + break; + case GL_LINEAR_MIPMAP_LINEAR: + current->texture[hw_unit].hwTextureMip |= + TEXTURE_FILTER_LINEAR_MIP_LINEAR; + break; + } + + switch (texObj->WrapS) + { + case GL_REPEAT: + current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapU; + break; + case GL_CLAMP: + current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU; + break; + case GL_CLAMP_TO_EDGE: + /* + * ?? not support yet + */ + ok = 0; + break; + } + + switch (texObj->WrapT) + { + case GL_REPEAT: + current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapV; + break; + case GL_CLAMP: + current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV; + break; + case GL_CLAMP_TO_EDGE: + /* + * ?? not support yet + */ + ok = 0; + break; + } + +/* + if (current->texture[hw_unit].hwTextureSet & MASK_TextureClampU) { + current->texture[hw_unit].hwTextureSet &= ~MASK_TextureClampU; + current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderU; + } + + if (current->texture[hw_unit].hwTextureSet & MASK_TextureClampV) { + current->texture[hw_unit].hwTextureSet &= ~MASK_TextureClampV; + current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderV; + } +*/ + current->texture[hw_unit].hwTextureBorderColor = + ((GLuint) texObj->BorderColor[3] << 24) + + ((GLuint) texObj->BorderColor[0] << 16) + + ((GLuint) texObj->BorderColor[1] << 8) + + ((GLuint) texObj->BorderColor[2]); + + if (current->texture[hw_unit].hwTextureBorderColor != + prev->texture[hw_unit].hwTextureBorderColor) + { + prev->texture[hw_unit].hwTextureBorderColor = + current->texture[hw_unit].hwTextureBorderColor; + if (hw_unit == 1) + smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR_1; + else + smesa->GlobalFlag |= GFLAG_TEXBORDERCOLOR; + } + + current->texture[hw_unit].hwTextureSet |= + texObj->Image[firstLevel]->WidthLog2 << 4; + current->texture[hw_unit].hwTextureSet |= + texObj->Image[firstLevel]->HeightLog2; + + if (hw_unit == 0) + smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS; + else + smesa->GlobalFlag |= GFLAG_TEXTUREADDRESS_1; + + for (i = firstLevel; i <= lastLevel; i++) + { + GLuint texOffset = 0; + GLuint texPitch = TransferTexturePitch( t->image[i].pitch ); + + switch (t->image[i].memType) + { + case VIDEO_TYPE: + texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->FbBase); + break; + case AGP_TYPE: + texOffset = ((unsigned long)t->image[i].Data - (unsigned long)smesa->AGPBase) + + (unsigned long) smesa->AGPAddr; + current->texture[hw_unit].hwTextureMip |= + (MASK_TextureLevel0InSystem << i); + break; + } + + switch (i) + { + case 0: + prev->texture[hw_unit].texOffset0 = texOffset; + prev->texture[hw_unit].texPitch01 = texPitch << 16; + break; + case 1: + prev->texture[hw_unit].texOffset1 = texOffset; + prev->texture[hw_unit].texPitch01 |= texPitch; + break; + case 2: + prev->texture[hw_unit].texOffset2 = texOffset; + prev->texture[hw_unit].texPitch23 = texPitch << 16; + break; + case 3: + prev->texture[hw_unit].texOffset3 = texOffset; + prev->texture[hw_unit].texPitch23 |= texPitch; + break; + case 4: + prev->texture[hw_unit].texOffset4 = texOffset; + prev->texture[hw_unit].texPitch45 = texPitch << 16; + break; + case 5: + prev->texture[hw_unit].texOffset5 = texOffset; + prev->texture[hw_unit].texPitch45 |= texPitch; + break; + case 6: + prev->texture[hw_unit].texOffset6 = texOffset; + prev->texture[hw_unit].texPitch67 = texPitch << 16; + break; + case 7: + prev->texture[hw_unit].texOffset7 = texOffset; + prev->texture[hw_unit].texPitch67 |= texPitch; + break; + case 8: + prev->texture[hw_unit].texOffset8 = texOffset; + prev->texture[hw_unit].texPitch89 = texPitch << 16; + break; + case 9: + prev->texture[hw_unit].texOffset9 = texOffset; + prev->texture[hw_unit].texPitch89 |= texPitch; + break; + case 10: + prev->texture[hw_unit].texOffset10 = texOffset; + prev->texture[hw_unit].texPitch10 = texPitch << 16; + break; + case 11: + prev->texture[hw_unit].texOffset11 = texOffset; + prev->texture[hw_unit].texPitch10 |= texPitch; + break; + } + } + + if (current->texture[hw_unit].hwTextureSet != + prev->texture[hw_unit].hwTextureSet) + { + prev->texture[hw_unit].hwTextureSet = + current->texture[hw_unit].hwTextureSet; + if (hw_unit == 1) + smesa->GlobalFlag |= CFLAG_TEXTURERESET_1; + else + smesa->GlobalFlag |= CFLAG_TEXTURERESET; + } + if (current->texture[hw_unit].hwTextureMip != + prev->texture[hw_unit].hwTextureMip) + { + prev->texture[hw_unit].hwTextureMip = + current->texture[hw_unit].hwTextureMip; + if (hw_unit == 1) + smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP_1; + else + smesa->GlobalFlag |= GFLAG_TEXTUREMIPMAP; + } + + return ok; +} + +/* Disable a texture unit, called from validate_texture */ +static void +sis_reset_texture_env (GLcontext *ctx, int hw_unit) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (hw_unit == 1) + { + current->hwTexBlendClr1 = RGB_STAGE1; + current->hwTexBlendAlpha1 = A_STAGE1; + + if ((current->hwTexBlendClr1 != prev->hwTexBlendClr1) || + (current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) || + (current->hwTexEnvColor != prev->hwTexEnvColor)) + { + prev->hwTexBlendClr1 = current->hwTexBlendClr1; + prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1; + prev->hwTexEnvColor = current->hwTexEnvColor; + smesa->GlobalFlag |= GFLAG_TEXTUREENV_1; + } + } else { + current->hwTexBlendClr0 = RGB_STAGE1; + current->hwTexBlendAlpha0 = A_STAGE1; + + if ((current->hwTexBlendClr0 != prev->hwTexBlendClr0) || + (current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) || + (current->hwTexEnvColor != prev->hwTexEnvColor)) + { + prev->hwTexBlendClr0 = current->hwTexBlendClr0; + prev->hwTexBlendAlpha0 = current->hwTexBlendAlpha0; + prev->hwTexEnvColor = current->hwTexEnvColor; + smesa->GlobalFlag |= GFLAG_TEXTUREENV; + } + } +} + +static void updateTextureUnit( GLcontext *ctx, int unit ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit]; + struct gl_texture_object *texObj = texUnit->_Current; + GLint fallbackbit; + + if (unit == 0) + fallbackbit = SIS_FALLBACK_TEXTURE0; + else + fallbackbit = SIS_FALLBACK_TEXTURE1; + + if (texUnit->_ReallyEnabled & (TEXTURE_1D_BIT | TEXTURE_2D_BIT)) { + if (smesa->TexStates[unit] & NEW_TEXTURING) { + GLboolean ok; + + ok = sis_set_texobj_parm (ctx, texObj, unit); + FALLBACK( smesa, fallbackbit, !ok ); + } + if (smesa->TexStates[unit] & NEW_TEXTURE_ENV) { + if (unit == 0) + sis_set_texture_env0( ctx, texObj, unit ); + else + sis_set_texture_env1( ctx, texObj, unit ); + } + smesa->TexStates[unit] = 0; + } else if ( texUnit->_ReallyEnabled ) { + /* fallback */ + FALLBACK( smesa, fallbackbit, 1 ); + } else { + sis_reset_texture_env( ctx, unit ); + FALLBACK( smesa, fallbackbit, 0 ); + } +} + + +void sisUpdateTextureState( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + int i; + __GLSiSHardware *current = &smesa->current; + +#if 1 + /* TODO : if unmark these, error in multitexture */ /* XXX */ + for (i = 0; i < SIS_MAX_TEXTURES; i++) + smesa->TexStates[i] |= (NEW_TEXTURING | NEW_TEXTURE_ENV); +#endif + + updateTextureUnit( ctx, 0 ); + updateTextureUnit( ctx, 1 ); + + /* XXX Issues with the 2nd unit but not the first being enabled? */ + if ( ctx->Texture.Unit[0]._ReallyEnabled & + (TEXTURE_1D_BIT | TEXTURE_2D_BIT) || + ctx->Texture.Unit[1]._ReallyEnabled & + (TEXTURE_1D_BIT | TEXTURE_2D_BIT) ) + { + current->hwCapEnable |= MASK_TextureEnable; + current->hwCapEnable &= ~MASK_TextureNumUsed; + if (ctx->Texture.Unit[1]._ReallyEnabled) + current->hwCapEnable |= 0x00002000; + else + current->hwCapEnable |= 0x00001000; + } else { + current->hwCapEnable &= ~MASK_TextureEnable; + } +} + +static GLint +BitScanForward( GLshort w ) +{ + GLint i; + + for (i = 0; i < 16; i++) { + if (w & (1 << i)) + break; + } + return i; +} + +static GLint +TransferTexturePitch( GLint dwPitch ) +{ + GLint dwRet, i; + + i = BitScanForward( (GLshort)dwPitch ); + dwRet = dwPitch >> i; + dwRet |= i << 9; + return dwRet; +} diff --git a/src/mesa/drivers/dri/sis/sis_tris.c b/src/mesa/drivers/dri/sis/sis_tris.c new file mode 100644 index 00000000000..d76431f41d2 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_tris.c @@ -0,0 +1,954 @@ +/* $XFree86*/ /* -*- c-basic-offset: 3 -*- */ +/************************************************************************** + +Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan. +Copyright 2003 Eric Anholt +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: + * Sung-Ching Lin + * Eric Anholt + */ + +#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 "sis_tris.h" +#include "sis_state.h" +#include "sis_vb.h" +#include "sis_lock.h" + +static const GLuint hw_prim[GL_POLYGON+1] = { + OP_3D_POINT_DRAW, /* GL_POINTS */ + OP_3D_LINE_DRAW, /* GL_LINES */ + OP_3D_LINE_DRAW, /* GL_LINE_LOOP */ + OP_3D_LINE_DRAW, /* GL_LINE_STRIP */ + OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLES */ + OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLE_STRIP */ + OP_3D_TRIANGLE_DRAW, /* GL_TRIANGLE_FAN */ + OP_3D_TRIANGLE_DRAW, /* GL_QUADS */ + OP_3D_TRIANGLE_DRAW, /* GL_QUAD_STRIP */ + OP_3D_TRIANGLE_DRAW /* GL_POLYGON */ +}; + +static const GLuint hw_prim_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = { + OP_3D_FIRE_TSARGBa, + OP_3D_FIRE_TSARGBb, + OP_3D_FIRE_TSARGBc +}; + +static const GLuint hw_prim_mmio_shade[OP_3D_TRIANGLE_DRAW+1] = { + SHADE_FLAT_VertexA, + SHADE_FLAT_VertexB, + SHADE_FLAT_VertexC +}; + +static const GLuint hw_prim_agp_type[OP_3D_TRIANGLE_DRAW+1] = { + MASK_PsPointList, + MASK_PsLineList, + MASK_PsTriangleList +}; + +static const GLuint hw_prim_agp_shade[OP_3D_TRIANGLE_DRAW+1] = { + MASK_PsShadingFlatA, + MASK_PsShadingFlatB, + MASK_PsShadingFlatC +}; + +static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim ); +static void sisRenderPrimitive( GLcontext *ctx, GLenum prim ); +static void sisMakeRoomAGP( sisContextPtr smesa, GLint num ); +static void sisUpdateAGP( sisContextPtr smesa ); +static void sisFireVertsAGP( sisContextPtr smesa ); + +static float *AGP_StartPtr; +static float *AGP_WritePtr; /* Current write position */ +static float *AGP_ReadPtr; /* Last known engine readposition */ +static long AGP_SpaceLeft; /* Last known engine readposition */ + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +/* Future optimizations: + * + * The previous code only emitted W when fog or textures were enabled. + */ + +#define SIS_MMIO_WRITE_VERTEX(_v, i, lastvert) \ +do { \ + MMIOBase[(REG_3D_TSXa+(i)*0x30)/4] = _v->v.x; \ + MMIOBase[(REG_3D_TSYa+(i)*0x30)/4] = _v->v.y; \ + MMIOBase[(REG_3D_TSZa+(i)*0x30)/4] = _v->v.z; \ + MMIOBase[(REG_3D_TSWGa+(i)*0x30)/4] = _v->v.w; \ + /*((GLint *) MMIOBase)[(REG_3D_TSFSa+(i)*0x30)/4] = _v->ui[5];*/ \ + if (SIS_STATES & SIS_VERT_TEX0) { \ + MMIOBase[(REG_3D_TSUAa+(i)*0x30)/4] = _v->v.u0; \ + MMIOBase[(REG_3D_TSVAa+(i)*0x30)/4] = _v->v.v0; \ + } \ + if (SIS_STATES & SIS_VERT_TEX1) { \ + MMIOBase[(REG_3D_TSUBa+(i)*0x30)/4] = _v->v.u1; \ + MMIOBase[(REG_3D_TSVBa+(i)*0x30)/4] = _v->v.v1; \ + } \ + /*MMIOBase[(REG_3D_TSUCa+(i)*0x30)/4] = _v->v.u2; \ + MMIOBase[(REG_3D_TSVCa+(i)*0x30)/4] = _v->v.v2;*/ \ + /* the ARGB write of the last vertex of the primitive fires the 3d engine*/ \ + if (lastvert || (SIS_STATES & SIS_VERT_SMOOTH)) \ + ((GLint *) MMIOBase)[(REG_3D_TSARGBa+(i)*0x30)/4] = _v->ui[4]; \ +} while (0); + +#define SIS_AGP_WRITE_VERTEX(_v) \ +do { \ + AGP_WritePtr[0] = _v->v.x; \ + AGP_WritePtr[1] = _v->v.y; \ + AGP_WritePtr[2] = _v->v.z; \ + AGP_WritePtr[3] = _v->v.w; \ + ((GLint *)AGP_WritePtr)[4] = _v->ui[4]; \ + AGP_WritePtr += 5; \ + if (SIS_STATES & SIS_VERT_TEX0) { \ + AGP_WritePtr[0] = _v->v.u0; \ + AGP_WritePtr[1] = _v->v.v0; \ + AGP_WritePtr += 2; \ + } \ + if (SIS_STATES & SIS_VERT_TEX1) { \ + AGP_WritePtr[0] = _v->v.u1; \ + AGP_WritePtr[1] = _v->v.v1; \ + AGP_WritePtr += 2; \ + } \ +} while(0) + +#define MMIO_VERT_REG_COUNT 10 + +#define SIS_VERT_SMOOTH 0x01 +#define SIS_VERT_TEX0 0x02 +#define SIS_VERT_TEX1 0x04 + +static sis_quad_func sis_quad_func_agp[8]; +static sis_tri_func sis_tri_func_agp[8]; +static sis_line_func sis_line_func_agp[8]; +static sis_point_func sis_point_func_agp[8]; +static sis_quad_func sis_quad_func_mmio[8]; +static sis_tri_func sis_tri_func_mmio[8]; +static sis_line_func sis_line_func_mmio[8]; +static sis_point_func sis_point_func_mmio[8]; + +/* XXX: These definitions look questionable */ +#define USE_XYZ MASK_PsVertex_HAS_RHW +#define USE_W MASK_PsVertex_HAS_NORMALXYZ +#define USE_RGB MASK_PsVertex_HAS_SPECULAR +#define USE_UV1 MASK_PsVertex_HAS_UVSet2 +#define USE_UV2 MASK_PsVertex_HAS_UVSet3 + +static GLint AGPParsingValues[8] = { + (5 << 28) | USE_XYZ | USE_W | USE_RGB, + (5 << 28) | USE_XYZ | USE_W | USE_RGB, + (7 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV1, + (7 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV1, + (7 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV2, + (7 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV2, + (9 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV1 | USE_UV2, + (9 << 28) | USE_XYZ | USE_W | USE_RGB | USE_UV1 | USE_UV2, +}; + +#define SIS_STATES (0) +#define TAG(x) x##_none +#include "sis_tritmp.h" + +#define SIS_STATES (SIS_VERT_SMOOTH) +#define TAG(x) x##_s +#include "sis_tritmp.h" + +#define SIS_STATES (SIS_VERT_TEX0) +#define TAG(x) x##_t0 +#include "sis_tritmp.h" + +#define SIS_STATES (SIS_VERT_SMOOTH | SIS_VERT_TEX0) +#define TAG(x) x##_st0 +#include "sis_tritmp.h" + +#define SIS_STATES (SIS_VERT_TEX1) +#define TAG(x) x##_t1 +#include "sis_tritmp.h" + +#define SIS_STATES (SIS_VERT_SMOOTH | SIS_VERT_TEX1) +#define TAG(x) x##_st1 +#include "sis_tritmp.h" + +#define SIS_STATES (SIS_VERT_TEX0 | SIS_VERT_TEX1) +#define TAG(x) x##_t0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (SIS_VERT_SMOOTH | SIS_VERT_TEX0 | SIS_VERT_TEX1) +#define TAG(x) x##_st0t1 +#include "sis_tritmp.h" + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define POINT( v0 ) smesa->draw_point( smesa, v0 ) +#define LINE( v0, v1 ) smesa->draw_line( smesa, v0, v1 ) +#define TRI( a, b, c ) smesa->draw_tri( smesa, a, b, c ) +#define QUAD( a, b, c, d ) smesa->draw_quad( smesa, a, b, c, d ) + +/*********************************************************************** + * Build render functions from dd templates * + ***********************************************************************/ + +#define SIS_OFFSET_BIT 0x01 +#define SIS_TWOSIDE_BIT 0x02 +#define SIS_UNFILLED_BIT 0x04 +#define SIS_FALLBACK_BIT 0x08 +#define SIS_MAX_TRIFUNC 0x10 + + +static struct { + points_func points; + line_func line; + triangle_func triangle; + quad_func quad; +} rast_tab[SIS_MAX_TRIFUNC]; + + +#define DO_FALLBACK (IND & SIS_FALLBACK_BIT) +#define DO_OFFSET (IND & SIS_OFFSET_BIT) +#define DO_UNFILLED (IND & SIS_UNFILLED_BIT) +#define DO_TWOSIDE (IND & SIS_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 sisVertex +#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) (smesa->verts + (e << smesa->vertex_stride_shift)) + +#define VERT_SET_RGBA( v, c ) \ + do { \ + sis_color_t *vc = (sis_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) \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = (smesa->vertex_size == 4 ? 3 : 4); \ + GLboolean havespec = (smesa->vertex_size == 4 ? 0 : 1); \ + (void) color; (void) spec; (void) coloroffset; (void) havespec; + +/*********************************************************************** + * Helpers for rendering unfilled primitives * + ***********************************************************************/ + +#define RASTERIZE(x) if (smesa->hw_primitive != hw_prim[x]) \ + sisRasterPrimitive( ctx, hw_prim[x] ) +#define RENDER_PRIMITIVE smesa->render_primitive +#define IND SIS_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 (SIS_OFFSET_BIT) +#define TAG(x) x##_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT) +#define TAG(x) x##_twoside +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT | SIS_OFFSET_BIT) +#define TAG(x) x##_twoside_offset +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_UNFILLED_BIT) +#define TAG(x) x##_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_OFFSET_BIT | SIS_UNFILLED_BIT) +#define TAG(x) x##_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT | SIS_UNFILLED_BIT) +#define TAG(x) x##_twoside_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT | SIS_OFFSET_BIT | SIS_UNFILLED_BIT) +#define TAG(x) x##_twoside_offset_unfilled +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_FALLBACK_BIT) +#define TAG(x) x##_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_OFFSET_BIT | SIS_FALLBACK_BIT) +#define TAG(x) x##_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT | SIS_FALLBACK_BIT) +#define TAG(x) x##_twoside_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT | SIS_OFFSET_BIT | SIS_FALLBACK_BIT) +#define TAG(x) x##_twoside_offset_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_UNFILLED_BIT | SIS_FALLBACK_BIT) +#define TAG(x) x##_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_OFFSET_BIT | SIS_UNFILLED_BIT | SIS_FALLBACK_BIT) +#define TAG(x) x##_offset_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT | SIS_UNFILLED_BIT | SIS_FALLBACK_BIT) +#define TAG(x) x##_twoside_unfilled_fallback +#include "tnl_dd/t_dd_tritmp.h" + +#define IND (SIS_TWOSIDE_BIT | SIS_OFFSET_BIT | SIS_UNFILLED_BIT | \ + SIS_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 +sis_fallback_quad( sisContextPtr smesa, + sisVertex *v0, + sisVertex *v1, + sisVertex *v2, + sisVertex *v3 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[4]; + sis_translate_vertex( ctx, v0, &v[0] ); + sis_translate_vertex( ctx, v1, &v[1] ); + sis_translate_vertex( ctx, v2, &v[2] ); + sis_translate_vertex( ctx, v3, &v[3] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[3] ); + _swrast_Triangle( ctx, &v[1], &v[2], &v[3] ); +} + +static void +sis_fallback_tri( sisContextPtr smesa, + sisVertex *v0, + sisVertex *v1, + sisVertex *v2 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[3]; + sis_translate_vertex( ctx, v0, &v[0] ); + sis_translate_vertex( ctx, v1, &v[1] ); + sis_translate_vertex( ctx, v2, &v[2] ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); +} + + +static void +sis_fallback_line( sisContextPtr smesa, + sisVertex *v0, + sisVertex *v1 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[2]; + sis_translate_vertex( ctx, v0, &v[0] ); + sis_translate_vertex( ctx, v1, &v[1] ); + _swrast_Line( ctx, &v[0], &v[1] ); +} + + +static void +sis_fallback_point( sisContextPtr smesa, + sisVertex *v0 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[1]; + sis_translate_vertex( ctx, v0, &v[0] ); + _swrast_Point( ctx, &v[0] ); +} + + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define VERT(x) (sisVertex *)(sisverts + (x << shift)) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + smesa->draw_point( smesa, VERT(start) ) +#define RENDER_LINE( v0, v1 ) smesa->draw_line( smesa, VERT(v0), VERT(v1) ) +#define RENDER_TRI( v0, v1, v2 ) smesa->draw_tri( smesa, VERT(v0), VERT(v1), \ + VERT(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) smesa->draw_quad( smesa, VERT(v0), \ + VERT(v1), VERT(v2), VERT(v3)) +#define INIT(x) sisRenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + const GLuint shift = smesa->vertex_stride_shift; \ + const char *sisverts = (char *)smesa->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) sis_##x##_verts +#include "tnl/t_vb_rendertmp.h" +#undef ELT +#undef TAG +#define TAG(x) sis_##x##_elts +#define ELT(x) elt[x] +#include "tnl/t_vb_rendertmp.h" + + +/**********************************************************************/ +/* Render clipped primitives */ +/**********************************************************************/ + +static void sisRenderClippedPoly( 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 sisRenderClippedLine( GLcontext *ctx, GLuint ii, GLuint jj ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + tnl->Driver.Render.Line( ctx, ii, jj ); +} + +#if 0 +static void sisFastRenderClippedPoly( GLcontext *ctx, const GLuint *elts, + GLuint n ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + GLuint vertsize = smesa->vertex_size; + GLuint *vb = r128AllocDmaLow( rmesa, (n-2) * 3 * 4 * vertsize ); + GLubyte *sisverts = (GLubyte *)smesa->verts; + const GLuint shift = smesa->vertex_stride_shift; + const GLuint *start = (const GLuint *)VERT(elts[0]); + int i,j; + + smesa->num_verts += (n-2) * 3; + + for (i = 2 ; i < n ; i++) { + COPY_DWORDS( j, vb, vertsize, (sisVertexPtr) VERT(elts[i-1]) ); + COPY_DWORDS( j, vb, vertsize, (sisVertexPtr) VERT(elts[i]) ); + COPY_DWORDS( j, vb, vertsize, (sisVertexPtr) start ); + } +} +#endif + + + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + +#define _SIS_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 sisChooseRenderState(GLcontext *ctx) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + GLuint vertindex = 0; + + if (ctx->Texture.Unit[0]._ReallyEnabled) + vertindex |= SIS_VERT_TEX0; + if (ctx->Texture.Unit[1]._ReallyEnabled) + vertindex |= SIS_VERT_TEX1; + if (ctx->Light.ShadeModel == GL_SMOOTH) + vertindex |= SIS_VERT_SMOOTH; + + if (smesa->AGPCmdModeEnabled) { + smesa->draw_quad = sis_quad_func_agp[vertindex]; + smesa->draw_tri = sis_tri_func_agp[vertindex]; + smesa->draw_line = sis_line_func_agp[vertindex]; + smesa->draw_point = sis_point_func_agp[vertindex]; + } else { + smesa->draw_quad = sis_quad_func_mmio[vertindex]; + smesa->draw_tri = sis_tri_func_mmio[vertindex]; + smesa->draw_line = sis_line_func_mmio[vertindex]; + smesa->draw_point = sis_point_func_mmio[vertindex]; + } + smesa->AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat); + smesa->AGPParseSet |= AGPParsingValues[vertindex]; + + if (flags & (ANY_RASTER_FLAGS|ANY_FALLBACK_FLAGS)) { + + if (flags & ANY_RASTER_FLAGS) { + if (flags & DD_TRI_LIGHT_TWOSIDE) index |= SIS_TWOSIDE_BIT; + if (flags & DD_TRI_OFFSET) index |= SIS_OFFSET_BIT; + if (flags & DD_TRI_UNFILLED) index |= SIS_UNFILLED_BIT; + } + + /* Hook in fallbacks for specific primitives. + */ + if (flags & ANY_FALLBACK_FLAGS) { + if (flags & POINT_FALLBACK) + smesa->draw_point = sis_fallback_point; + if (flags & LINE_FALLBACK) + smesa->draw_line = sis_fallback_line; + if (flags & TRI_FALLBACK) { + smesa->draw_quad = sis_fallback_quad; + smesa->draw_tri = sis_fallback_tri; + } + index |= SIS_FALLBACK_BIT; + } + } + + if (index != smesa->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 = sis_render_tab_verts; + tnl->Driver.Render.PrimTabElts = sis_render_tab_elts; + tnl->Driver.Render.ClippedLine = rast_tab[index].line; + /*XXX: sisFastRenderClippedPoly*/ + tnl->Driver.Render.ClippedPolygon = sisRenderClippedPoly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedLine = sisRenderClippedLine; + tnl->Driver.Render.ClippedPolygon = sisRenderClippedPoly; + } + + smesa->RenderIndex = index; + } +} + +/**********************************************************************/ +/* Multipass rendering for front buffering */ +/**********************************************************************/ +static GLboolean multipass_cliprect( GLcontext *ctx, GLuint pass ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + + if (pass >= smesa->driDrawable->numClipRects) { + return GL_FALSE; + } else { + GLint x1, y1, x2, y2; + + x1 = smesa->driDrawable->pClipRects[pass].x1 - smesa->driDrawable->x; + y1 = smesa->driDrawable->pClipRects[pass].y1 - smesa->driDrawable->y; + x2 = smesa->driDrawable->pClipRects[pass].x2 - smesa->driDrawable->x; + y2 = smesa->driDrawable->pClipRects[pass].y2 - smesa->driDrawable->y; + + if (ctx->Scissor.Enabled) { + GLint scisy1 = Y_FLIP(ctx->Scissor.Y + ctx->Scissor.Height - 1); + GLint scisy2 = Y_FLIP(ctx->Scissor.Y); + + if (ctx->Scissor.X > x1) + x1 = ctx->Scissor.X; + if (scisy1 > y1) + y1 = scisy1; + if (ctx->Scissor.X + ctx->Scissor.Width - 1 < x2) + x2 = ctx->Scissor.X + ctx->Scissor.Width - 1; + if (scisy2 < y2) + y2 = scisy2; + } + + MMIO(REG_3D_ClipTopBottom, y1 << 13 | y2); + MMIO(REG_3D_ClipLeftRight, x1 << 13 | x2); + /* Mark that we clobbered these registers */ + smesa->GlobalFlag |= GFLAG_CLIPPING; + return GL_TRUE; + } +} + + + +/**********************************************************************/ +/* Validate state at pipeline start */ +/**********************************************************************/ + +static void sisRunPipeline( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + + LOCK_HARDWARE(); + sisUpdateHWState( ctx ); + + if (smesa->AGPCmdModeEnabled) { + AGP_WritePtr = (GLfloat *)smesa->AGPCmdBufBase + *smesa->pAGPCmdBufNext; + AGP_StartPtr = AGP_WritePtr; + AGP_ReadPtr = (GLfloat *)((long)MMIO_READ(REG_3D_AGPCmBase) - + (long)smesa->AGPCmdBufAddr + (long)smesa->AGPCmdBufBase); + sisUpdateAGP( smesa ); + } + + if (!smesa->Fallback && smesa->NewGLState) { + if (smesa->NewGLState & _SIS_NEW_VERTEX_STATE) + sisChooseVertexState( ctx ); + + if (smesa->NewGLState & (_SIS_NEW_RENDER_STATE | _NEW_TEXTURE)) + sisChooseRenderState( ctx ); + + smesa->NewGLState = 0; + } + + _tnl_run_pipeline( ctx ); + + if (smesa->AGPCmdModeEnabled) + sisFireVertsAGP( smesa ); + else + mEndPrimitive(); + UNLOCK_HARDWARE(); +} + +/**********************************************************************/ +/* 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. + */ + +static void sisRasterPrimitive( GLcontext *ctx, GLuint hwprim ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + if (smesa->hw_primitive != hwprim) { + if (smesa->AGPCmdModeEnabled) { + sisFireVertsAGP( smesa ); + smesa->AGPParseSet &= ~(MASK_PsDataType | MASK_PsShadingMode); + smesa->AGPParseSet |= hw_prim_agp_type[hwprim]; + if (ctx->Light.ShadeModel == GL_FLAT) + smesa->AGPParseSet |= hw_prim_agp_shade[hwprim]; + else + smesa->AGPParseSet |= MASK_PsShadingSmooth; + } else { + mEndPrimitive(); + smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand | + MASK_SetFirePosition | MASK_ShadingMode); + smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim]; + if (ctx->Light.ShadeModel == GL_FLAT) + smesa->dwPrimitiveSet |= hw_prim_mmio_shade[hwprim]; + else + smesa->dwPrimitiveSet |= SHADE_GOURAUD; + } + } + smesa->hw_primitive = hwprim; +} + +static void sisRenderPrimitive( GLcontext *ctx, GLenum prim ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + smesa->render_primitive = prim; + if (prim >= GL_TRIANGLES && (ctx->_TriangleCaps & DD_TRI_UNFILLED)) + return; + sisRasterPrimitive( ctx, hw_prim[prim] ); +} + + +static void sisRenderStart( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT(ctx); + + /* Check for projective texturing. Make sure all texcoord + * pointers point to something. (fix in mesa?) + */ + sisCheckTexSizes( ctx ); + + if (ctx->Color._DrawDestMask == FRONT_LEFT_BIT && + smesa->driDrawable->numClipRects != 0) + { + multipass_cliprect(ctx, 0); + if (smesa->driDrawable->numClipRects > 1) + tnl->Driver.Render.Multipass = multipass_cliprect; + else + tnl->Driver.Render.Multipass = NULL; + } else { + tnl->Driver.Render.Multipass = NULL; + } +} + +static void sisRenderFinish( GLcontext *ctx ) +{ +} + +/* Update SpaceLeft after an engine or current write pointer update */ +static void sisUpdateAGP( sisContextPtr smesa ) +{ + /* ReadPtr == WritePtr is the empty case */ + if (AGP_ReadPtr <= AGP_WritePtr) + AGP_SpaceLeft = (long)smesa->AGPCmdBufBase + (long)smesa->AGPCmdBufSize - + (long)AGP_WritePtr; + else + AGP_SpaceLeft = AGP_ReadPtr - AGP_WritePtr - 4; +} + +/* Fires a set of vertices that have been written from AGP_StartPtr to + * AGP_WritePtr, using the smesa->AGPParseSet format. + */ +void +sisFireVertsAGP( sisContextPtr smesa ) +{ + if (AGP_WritePtr == AGP_StartPtr) + return; + + mWait3DCmdQueue(5); + mEndPrimitive(); + MMIO(REG_3D_AGPCmBase, (long)AGP_StartPtr - (long)smesa->AGPCmdBufBase + + (long)smesa->AGPCmdBufAddr); + MMIO(REG_3D_AGPTtDwNum, (((long)AGP_WritePtr - (long)AGP_StartPtr) >> 2) | + 0x50000000); + MMIO(REG_3D_ParsingSet, smesa->AGPParseSet); + + MMIO(REG_3D_AGPCmFire, (GLint)(-1)); + mEndPrimitive(); + + *(smesa->pAGPCmdBufNext) = (((long)AGP_WritePtr - + (long)smesa->AGPCmdBufBase) + 0xf) & ~0xf; + AGP_StartPtr = AGP_WritePtr; + sisUpdateAGP( smesa ); +} + +/* Make sure there are more than num dwords left in the AGP queue. */ +static void +sisMakeRoomAGP( sisContextPtr smesa, GLint num ) +{ + int size = num * 4; + + if (size <= AGP_SpaceLeft) { + AGP_SpaceLeft -= size; + return; + } + /* Wrapping */ + if (AGP_WritePtr + num > (GLfloat *)(smesa->AGPCmdBufBase + + smesa->AGPCmdBufSize)) + { + sisFireVertsAGP( smesa ); + AGP_WritePtr = (GLfloat *)smesa->AGPCmdBufBase; + AGP_StartPtr = AGP_WritePtr; + sisUpdateAGP( smesa ); + WaitEngIdle( smesa ); /* XXX Why is this necessary? */ + } + + if (size > AGP_SpaceLeft) { + /* Update the cached engine read pointer */ + AGP_ReadPtr = (GLfloat *)((long)MMIO_READ(REG_3D_AGPCmBase) - + (long)smesa->AGPCmdBufAddr + (long)smesa->AGPCmdBufBase); + sisUpdateAGP( smesa ); + while (size > AGP_SpaceLeft) { + /* Spin until space is available. */ + usleep(1); + AGP_ReadPtr = (GLfloat *)((long)MMIO_READ(REG_3D_AGPCmBase) - + (long)smesa->AGPCmdBufAddr + (long)smesa->AGPCmdBufBase); + sisUpdateAGP( smesa ); + } + } + AGP_SpaceLeft -= size; +} + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + +void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT(ctx); + GLuint oldfallback = smesa->Fallback; + + if (mode) { + smesa->Fallback |= bit; + if (oldfallback == 0) { + _swsetup_Wakeup( ctx ); + smesa->RenderIndex = ~0; + } + } + else { + smesa->Fallback &= ~bit; + if (oldfallback == bit) { + _swrast_flush( ctx ); + tnl->Driver.Render.Start = sisRenderStart; + tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive; + tnl->Driver.Render.Finish = sisRenderFinish; + tnl->Driver.Render.BuildVertices = sisBuildVertices; + smesa->NewGLState |= (_SIS_NEW_RENDER_STATE| + _SIS_NEW_VERTEX_STATE); + } + } +} + + +/**********************************************************************/ +/* Initialization. */ +/**********************************************************************/ + +void sisInitTriFuncs( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + TNLcontext *tnl = TNL_CONTEXT(ctx); + static int firsttime = 1; + + if (firsttime) { + init_rast_tab(); + firsttime = 0; + + sis_vert_init_none(); + sis_vert_init_s(); + sis_vert_init_t0(); + sis_vert_init_st0(); + sis_vert_init_t1(); + sis_vert_init_st1(); + sis_vert_init_t0t1(); + sis_vert_init_st0t1(); + } + + tnl->Driver.RunPipeline = sisRunPipeline; + tnl->Driver.Render.Start = sisRenderStart; + tnl->Driver.Render.Finish = sisRenderFinish; + tnl->Driver.Render.PrimitiveNotify = sisRenderPrimitive; + tnl->Driver.Render.ResetLineStipple = _swrast_ResetLineStipple; + tnl->Driver.Render.BuildVertices = sisBuildVertices; + tnl->Driver.Render.Multipass = NULL; + + if (getenv("SIS_FORCE_FALLBACK") != NULL) + sisFallback(ctx, SIS_FALLBACK_FORCE, 1); + else + sisFallback(ctx, SIS_FALLBACK_FORCE, 0); + + smesa->RenderIndex = ~0; + smesa->NewGLState |= (_SIS_NEW_RENDER_STATE| + _SIS_NEW_VERTEX_STATE); +} diff --git a/src/mesa/drivers/dri/sis/sis_tris.h b/src/mesa/drivers/dri/sis/sis_tris.h new file mode 100644 index 00000000000..775c1072a77 --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_tris.h @@ -0,0 +1,45 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_tris.h,v 1.8 2002/10/30 12:51:43 alanh Exp $ */ +/************************************************************************** + +Copyright 2003 Eric Anholt +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: + * Eric Anholt + */ + +#ifndef __SIS_TRIS_H__ +#define __SIS_TRIS_H__ + +#include "mtypes.h" + +extern void sisInitTriFuncs( GLcontext *ctx ); + + +extern void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); +#define FALLBACK( smesa, bit, mode ) sisFallback( smesa->glCtx, bit, mode ) + + +#endif /* __SIS_TRIS_H__ */ diff --git a/src/mesa/drivers/dri/sis/sis_tritmp.h b/src/mesa/drivers/dri/sis/sis_tritmp.h new file mode 100644 index 00000000000..50564412a0a --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_tritmp.h @@ -0,0 +1,151 @@ +/* $XFree86*/ /* -*- c-basic-offset: 3 -*- */ +/************************************************************************** + +Copyright 2003 Eric Anholt +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: + * Eric Anholt + */ + +#define AGP_VERT_REG_COUNT (5 + \ + ((SIS_STATES & SIS_VERT_TEX0) != 0) * 2 + \ + ((SIS_STATES & SIS_VERT_TEX1) != 0) * 2) + +static void TAG(sis_draw_quad_mmio)( sisContextPtr smesa, + sisVertexPtr v0, + sisVertexPtr v1, + sisVertexPtr v2, + sisVertexPtr v3 ) +{ + float *MMIOBase = (float *)GET_IOBase (smesa); + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 6 + 1); + ((GLint *) MMIOBase)[REG_3D_PrimitiveSet / 4] = smesa->dwPrimitiveSet; + SIS_MMIO_WRITE_VERTEX(v0, 0, 0); + SIS_MMIO_WRITE_VERTEX(v1, 1, 0); + SIS_MMIO_WRITE_VERTEX(v3, 2, 1); + SIS_MMIO_WRITE_VERTEX(v1, 0, 0); + SIS_MMIO_WRITE_VERTEX(v2, 1, 0); + SIS_MMIO_WRITE_VERTEX(v3, 2, 1); +} + +static void TAG(sis_draw_tri_mmio)( sisContextPtr smesa, + sisVertexPtr v0, + sisVertexPtr v1, + sisVertexPtr v2 ) +{ + float *MMIOBase = (float *)GET_IOBase (smesa); + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 3 + 1); + ((GLint *) MMIOBase)[REG_3D_PrimitiveSet / 4] = smesa->dwPrimitiveSet; + SIS_MMIO_WRITE_VERTEX(v0, 0, 0); + SIS_MMIO_WRITE_VERTEX(v1, 1, 0); + SIS_MMIO_WRITE_VERTEX(v2, 2, 1); +} + +static void TAG(sis_draw_line_mmio)( sisContextPtr smesa, + sisVertexPtr v0, + sisVertexPtr v1 ) +{ + float *MMIOBase = (float *)GET_IOBase (smesa); + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2 + 1); + ((GLint *) MMIOBase)[REG_3D_PrimitiveSet / 4] = smesa->dwPrimitiveSet; + SIS_MMIO_WRITE_VERTEX(v0, 0, 0); + SIS_MMIO_WRITE_VERTEX(v1, 1, 1); +} + +static void TAG(sis_draw_point_mmio)( sisContextPtr smesa, + sisVertexPtr v0 ) +{ + float *MMIOBase = (float *)GET_IOBase (smesa); + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1 + 1); + ((GLint *) MMIOBase)[REG_3D_PrimitiveSet / 4] = smesa->dwPrimitiveSet; + SIS_MMIO_WRITE_VERTEX(v0, 1, 1); +} + +static void TAG(sis_draw_quad_agp)( sisContextPtr smesa, + sisVertexPtr v0, + sisVertexPtr v1, + sisVertexPtr v2, + sisVertexPtr v3 ) +{ + sisMakeRoomAGP(smesa, AGP_VERT_REG_COUNT * 6); + + SIS_AGP_WRITE_VERTEX(v0); + SIS_AGP_WRITE_VERTEX(v1); + SIS_AGP_WRITE_VERTEX(v3); + SIS_AGP_WRITE_VERTEX(v1); + SIS_AGP_WRITE_VERTEX(v2); + SIS_AGP_WRITE_VERTEX(v3); +} + +static void TAG(sis_draw_tri_agp)( sisContextPtr smesa, + sisVertexPtr v0, + sisVertexPtr v1, + sisVertexPtr v2 ) +{ + sisMakeRoomAGP(smesa, AGP_VERT_REG_COUNT * 3); + + SIS_AGP_WRITE_VERTEX(v0); + SIS_AGP_WRITE_VERTEX(v1); + SIS_AGP_WRITE_VERTEX(v2); +} + +static void TAG(sis_draw_line_agp)( sisContextPtr smesa, + sisVertexPtr v0, + sisVertexPtr v1 ) +{ + sisMakeRoomAGP(smesa, AGP_VERT_REG_COUNT * 2); + + SIS_AGP_WRITE_VERTEX(v0); + SIS_AGP_WRITE_VERTEX(v1); +} + +static void TAG(sis_draw_point_agp)( sisContextPtr smesa, + sisVertexPtr v0 ) +{ + sisMakeRoomAGP(smesa, AGP_VERT_REG_COUNT * 1); + + SIS_AGP_WRITE_VERTEX(v0); +} + +static __inline void TAG(sis_vert_init)( void ) +{ + sis_quad_func_agp[SIS_STATES] = TAG(sis_draw_quad_agp); + sis_tri_func_agp[SIS_STATES] = TAG(sis_draw_tri_agp); + sis_line_func_agp[SIS_STATES] = TAG(sis_draw_line_agp); + sis_point_func_agp[SIS_STATES] = TAG(sis_draw_point_agp); + sis_quad_func_mmio[SIS_STATES] = TAG(sis_draw_quad_mmio); + sis_tri_func_mmio[SIS_STATES] = TAG(sis_draw_tri_mmio); + sis_line_func_mmio[SIS_STATES] = TAG(sis_draw_line_mmio); + sis_point_func_mmio[SIS_STATES] = TAG(sis_draw_point_mmio); +} + +#undef AGP_VERT_REG_COUNT +#undef TAG +#undef SIS_STATES diff --git a/src/mesa/drivers/dri/sis/sis_vb.c b/src/mesa/drivers/dri/sis/sis_vb.c new file mode 100644 index 00000000000..6d56451d69e --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_vb.c @@ -0,0 +1,464 @@ +/* $XFree86$ */ +/************************************************************************** + +Copyright 2003 Eric Anholt +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: + * Eric Anholt + */ + +#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 "sis_context.h" +#include "sis_vb.h" +#include "sis_tris.h" +#include "sis_state.h" + + +#define SIS_TEX1_BIT 0x1 +#define SIS_TEX0_BIT 0x2 +#define SIS_RGBA_BIT 0x4 +#define SIS_SPEC_BIT 0x8 +#define SIS_FOG_BIT 0x10 +#define SIS_XYZW_BIT 0x20 +#define SIS_PTEX_BIT 0x40 +#define SIS_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[SIS_MAX_SETUP]; + +#define TEX0_VERTEX_FORMAT 1 +#define TEX1_VERTEX_FORMAT 2 + +#define TINY_VERTEX_FORMAT 0 +#define NOTEX_VERTEX_FORMAT 0 +#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 & SIS_XYZW_BIT) +#define DO_RGBA (IND & SIS_RGBA_BIT) +#define DO_SPEC (IND & SIS_SPEC_BIT) +#define DO_FOG (IND & SIS_FOG_BIT) +#define DO_TEX0 (IND & SIS_TEX0_BIT) +#define DO_TEX1 (IND & SIS_TEX1_BIT) +#define DO_TEX2 0 +#define DO_TEX3 0 +#define DO_PTEX (IND & SIS_PTEX_BIT) + +#define VERTEX sisVertex +#define VERTEX_COLOR sis_color_t +#define LOCALVARS sisContextPtr smesa = SIS_CONTEXT(ctx); +#define GET_VIEWPORT_MAT() smesa->hw_viewport +#define GET_TEXSOURCE(n) n +#define GET_VERTEX_FORMAT() smesa->vertex_format +#define GET_VERTEX_STORE() smesa->verts +#define GET_VERTEX_STRIDE_SHIFT() smesa->vertex_stride_shift +#define GET_UBYTE_COLOR_STORE() &smesa->UbyteColor +#define GET_UBYTE_SPEC_COLOR_STORE() &smesa->UbyteSecondaryColor + +#define HAVE_HW_VIEWPORT 0 +#define HAVE_HW_DIVIDE 0 +#define HAVE_RGBA_COLOR 0 +#define HAVE_TINY_VERTICES 0 +#define HAVE_NOTEX_VERTICES 0 +#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 + +#define UNVIEWPORT_VARS GLfloat h = SIS_CONTEXT(ctx)->driDrawable->h +#define UNVIEWPORT_X(x) x - SUBPIXEL_X +#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y +#define UNVIEWPORT_Z(z) z / smesa->depth_scale + +#define PTEX_FALLBACK() FALLBACK(smesa, SIS_FALLBACK_TEXTURE, 1) + +#define IMPORT_FLOAT_COLORS sis_import_float_colors +#define IMPORT_FLOAT_SPEC_COLORS sis_import_float_spec_colors + +#define INTERP_VERTEX setup_tab[smesa->SetupIndex].interp +#define COPY_PV_VERTEX setup_tab[smesa->SetupIndex].copy_pv + +/*********************************************************************** + * Generate pv-copying and translation functions * + ***********************************************************************/ + +#define TAG(x) sis_##x +#include "tnl_dd/t_dd_vb.c" + +/*********************************************************************** + * Generate vertex emit and interp functions * + ***********************************************************************/ + + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT) +#define TAG(x) x##_wg +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_SPEC_BIT) +#define TAG(x) x##_wgs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_TEX0_BIT) +#define TAG(x) x##_wgt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_TEX0_BIT|SIS_TEX1_BIT) +#define TAG(x) x##_wgt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_TEX0_BIT|SIS_PTEX_BIT) +#define TAG(x) x##_wgpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_SPEC_BIT|SIS_TEX0_BIT) +#define TAG(x) x##_wgst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_SPEC_BIT|SIS_TEX0_BIT|\ + SIS_TEX1_BIT) +#define TAG(x) x##_wgst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_SPEC_BIT|SIS_TEX0_BIT|\ + SIS_PTEX_BIT) +#define TAG(x) x##_wgspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_FOG_BIT) +#define TAG(x) x##_wgf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_FOG_BIT|SIS_SPEC_BIT) +#define TAG(x) x##_wgfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_FOG_BIT|SIS_TEX0_BIT) +#define TAG(x) x##_wgft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_FOG_BIT|SIS_TEX0_BIT|\ + SIS_TEX1_BIT) +#define TAG(x) x##_wgft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_FOG_BIT|SIS_TEX0_BIT|\ + SIS_PTEX_BIT) +#define TAG(x) x##_wgfpt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_FOG_BIT|SIS_SPEC_BIT|\ + SIS_TEX0_BIT) +#define TAG(x) x##_wgfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_FOG_BIT|SIS_SPEC_BIT|\ + SIS_TEX0_BIT|SIS_TEX1_BIT) +#define TAG(x) x##_wgfst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_XYZW_BIT|SIS_RGBA_BIT|SIS_FOG_BIT|SIS_SPEC_BIT|\ + SIS_TEX0_BIT|SIS_PTEX_BIT) +#define TAG(x) x##_wgfspt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_TEX0_BIT) +#define TAG(x) x##_t0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_TEX0_BIT|SIS_TEX1_BIT) +#define TAG(x) x##_t0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_FOG_BIT) +#define TAG(x) x##_f +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_FOG_BIT|SIS_TEX0_BIT) +#define TAG(x) x##_ft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_FOG_BIT|SIS_TEX0_BIT|SIS_TEX1_BIT) +#define TAG(x) x##_ft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT) +#define TAG(x) x##_g +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_SPEC_BIT) +#define TAG(x) x##_gs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_TEX0_BIT) +#define TAG(x) x##_gt0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_TEX0_BIT|SIS_TEX1_BIT) +#define TAG(x) x##_gt0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_SPEC_BIT|SIS_TEX0_BIT) +#define TAG(x) x##_gst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_SPEC_BIT|SIS_TEX0_BIT|SIS_TEX1_BIT) +#define TAG(x) x##_gst0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_FOG_BIT) +#define TAG(x) x##_gf +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_FOG_BIT|SIS_SPEC_BIT) +#define TAG(x) x##_gfs +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_FOG_BIT|SIS_TEX0_BIT) +#define TAG(x) x##_gft0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_FOG_BIT|SIS_TEX0_BIT|SIS_TEX1_BIT) +#define TAG(x) x##_gft0t1 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_FOG_BIT|SIS_SPEC_BIT|SIS_TEX0_BIT) +#define TAG(x) x##_gfst0 +#include "tnl_dd/t_dd_vbtmp.h" + +#define IND (SIS_RGBA_BIT|SIS_FOG_BIT|SIS_SPEC_BIT|SIS_TEX0_BIT|\ + SIS_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 sisPrintSetupFlags(char *msg, GLuint flags ) +{ + fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n", + msg, + (int)flags, + (flags & SIS_XYZW_BIT) ? " xyzw," : "", + (flags & SIS_RGBA_BIT) ? " rgba," : "", + (flags & SIS_SPEC_BIT) ? " spec," : "", + (flags & SIS_FOG_BIT) ? " fog," : "", + (flags & SIS_TEX0_BIT) ? " tex-0," : "", + (flags & SIS_TEX1_BIT) ? " tex-1," : ""); +} + + + +void sisCheckTexSizes( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + + if (!setup_tab[smesa->SetupIndex].check_tex_sizes(ctx)) { + TNLcontext *tnl = TNL_CONTEXT(ctx); + + /* Invalidate stored verts + */ + smesa->SetupNewInputs = ~0; + smesa->SetupIndex |= SIS_PTEX_BIT; + + if (!smesa->Fallback && + !(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) { + tnl->Driver.Render.Interp = setup_tab[smesa->SetupIndex].interp; + tnl->Driver.Render.CopyPV = setup_tab[smesa->SetupIndex].copy_pv; + } + } +} + +void sisBuildVertices( GLcontext *ctx, + GLuint start, + GLuint count, + GLuint newinputs ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + GLubyte *v = ((GLubyte *)smesa->verts + (start<vertex_stride_shift)); + GLuint stride = 1 << smesa->vertex_stride_shift; + + newinputs |= smesa->SetupNewInputs; + smesa->SetupNewInputs = 0; + + if (!newinputs) + return; + + if (newinputs & VERT_BIT_CLIP) { + setup_tab[smesa->SetupIndex].emit( ctx, start, count, v, stride ); + } else { + GLuint ind = 0; + + if (newinputs & VERT_BIT_COLOR0) + ind |= SIS_RGBA_BIT; + + if (newinputs & VERT_BIT_COLOR1) + ind |= SIS_SPEC_BIT; + + if (newinputs & VERT_BIT_TEX0) + ind |= SIS_TEX0_BIT; + + if (newinputs & VERT_BIT_TEX1) + ind |= SIS_TEX1_BIT; + + if (newinputs & VERT_BIT_FOG) + ind |= SIS_FOG_BIT; + + if (smesa->SetupIndex & SIS_PTEX_BIT) + ind = ~0; + + ind &= smesa->SetupIndex; + + if (ind) { + setup_tab[ind].emit( ctx, start, count, v, stride ); + } + } +} + +void sisChooseVertexState( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT( ctx ); + GLuint ind = SIS_XYZW_BIT | SIS_RGBA_BIT; + + if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR) + ind |= SIS_SPEC_BIT; + + if (ctx->Fog.Enabled) + ind |= SIS_FOG_BIT; + + if (ctx->Texture._EnabledUnits) { + ind |= SIS_TEX0_BIT; + if (ctx->Texture.Unit[0]._ReallyEnabled && + ctx->Texture.Unit[1]._ReallyEnabled) + ind |= SIS_TEX1_BIT; + } + + smesa->SetupIndex = ind; + + if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE | DD_TRI_UNFILLED)) { + tnl->Driver.Render.Interp = sis_interp_extras; + tnl->Driver.Render.CopyPV = sis_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 != smesa->vertex_format) { + smesa->vertex_format = setup_tab[ind].vertex_format; + smesa->vertex_size = setup_tab[ind].vertex_size; + smesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift; + } +} + + +void sisInitVB( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + GLuint size = TNL_CONTEXT(ctx)->vb.Size; + static int firsttime = 1; + + smesa->verts = (GLubyte *)ALIGN_MALLOC(size * 4 * 16, 32); + + if (firsttime) { + init_setup_tab(); + firsttime = 0; + } +} + +void sisFreeVB( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT( ctx ); + if (smesa->verts) { + ALIGN_FREE(smesa->verts); + smesa->verts = NULL; + } + + + if (smesa->UbyteSecondaryColor.Ptr) { + ALIGN_FREE(smesa->UbyteSecondaryColor.Ptr); + smesa->UbyteSecondaryColor.Ptr = NULL; + } + + if (smesa->UbyteColor.Ptr) { + ALIGN_FREE(smesa->UbyteColor.Ptr); + smesa->UbyteColor.Ptr = NULL; + } +} diff --git a/src/mesa/drivers/dri/sis/sis_vb.h b/src/mesa/drivers/dri/sis/sis_vb.h new file mode 100644 index 00000000000..8efdcf26b6d --- /dev/null +++ b/src/mesa/drivers/dri/sis/sis_vb.h @@ -0,0 +1,63 @@ +/* $XFree86: xc/lib/GL/mesa/src/drv/r128/r128_vb.h,v 1.8 2002/10/30 12:51:46 alanh Exp $ */ +/************************************************************************** + +Copyright 2003 Eric Anholt +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: + * Eric Anholt + */ + +#ifndef __SIS_VB_H__ +#define __SIS_VB_H__ + +#include "mtypes.h" +#include "swrast/swrast.h" +#include "sis_context.h" + +#define _SIS_NEW_VERTEX_STATE (_DD_NEW_SEPARATE_SPECULAR | \ + _DD_NEW_TRI_LIGHT_TWOSIDE | \ + _DD_NEW_TRI_UNFILLED | \ + _NEW_TEXTURE | \ + _NEW_FOG) + +extern void sisCheckTexSizes( GLcontext *ctx ); +extern void sisChooseVertexState( GLcontext *ctx ); + +extern void sisBuildVertices( GLcontext *ctx, GLuint start, GLuint count, + GLuint newinputs ); + +extern void sisPrintSetupFlags( char *msg, GLuint flags ); + +extern void sisInitVB( GLcontext *ctx ); +extern void sisFreeVB( GLcontext *ctx ); + +extern void sis_translate_vertex( GLcontext *ctx, + const sisVertex *src, + SWvertex *dst ); + +extern void sis_print_vertex( GLcontext *ctx, const sisVertex *v ); + +#endif