diff options
author | Luc Verhaegen <libv@skynet.be> | 2010-03-11 06:16:30 +0100 |
---|---|---|
committer | Luc Verhaegen <libv@skynet.be> | 2010-03-11 06:16:30 +0100 |
commit | 23b56dd30d3ae68fe1bbce089c95ec3fab48c90b (patch) | |
tree | e273c21356e53be35e4ad46d70ec9da906bab21b | |
parent | 5dee9b7b19c1aa3a13618b08bc24f00677b5364b (diff) |
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | src/Makefile.am | 26 | ||||
-rw-r--r-- | src/server/sis_common.h | 63 | ||||
-rw-r--r-- | src/server/sis_dri.h | 85 | ||||
-rw-r--r-- | src/sis6326_clear.c | 229 | ||||
-rw-r--r-- | src/sis6326_reg.h | 408 | ||||
-rw-r--r-- | src/sis6326_state.c | 735 | ||||
-rw-r--r-- | src/sis_alloc.c | 199 | ||||
-rw-r--r-- | src/sis_alloc.h | 44 | ||||
-rw-r--r-- | src/sis_clear.c | 410 | ||||
-rw-r--r-- | src/sis_context.c | 728 | ||||
-rw-r--r-- | src/sis_context.h | 477 | ||||
-rw-r--r-- | src/sis_dd.c | 269 | ||||
-rw-r--r-- | src/sis_dd.h | 39 | ||||
-rw-r--r-- | src/sis_fog.c | 207 | ||||
-rw-r--r-- | src/sis_lock.c | 81 | ||||
-rw-r--r-- | src/sis_lock.h | 87 | ||||
-rw-r--r-- | src/sis_reg.h | 903 | ||||
-rw-r--r-- | src/sis_screen.c | 382 | ||||
-rw-r--r-- | src/sis_screen.h | 62 | ||||
-rw-r--r-- | src/sis_span.c | 194 | ||||
-rw-r--r-- | src/sis_span.h | 46 | ||||
-rw-r--r-- | src/sis_state.c | 866 | ||||
-rw-r--r-- | src/sis_state.h | 69 | ||||
-rw-r--r-- | src/sis_stencil.c | 206 | ||||
-rw-r--r-- | src/sis_stencil.h | 37 | ||||
-rw-r--r-- | src/sis_tex.c | 573 | ||||
-rw-r--r-- | src/sis_tex.h | 38 | ||||
-rw-r--r-- | src/sis_texstate.c | 710 | ||||
-rw-r--r-- | src/sis_tris.c | 1154 | ||||
-rw-r--r-- | src/sis_tris.h | 71 | ||||
-rw-r--r-- | src/sis_tritmp.h | 250 |
32 files changed, 9646 insertions, 7 deletions
diff --git a/configure.ac b/configure.ac index 2a78cfd..e05c34a 100644 --- a/configure.ac +++ b/configure.ac @@ -1,7 +1,7 @@ # Process this file with autoconf to produce a configure script AC_PREREQ(2.57) -AC_INIT([mesa-dri-xxx], 7.0.3, [], mesa-dri-xxx) +AC_INIT([mesa-dri-sis], 7.0.3, [], mesa-dri-sis) AM_INIT_AUTOMAKE([dist-bzip2]) @@ -16,7 +16,8 @@ AC_PROG_CC AC_HEADER_STDC PKG_CHECK_MODULES([DRM], [libdrm >= 2.3.0]) -PKG_CHECK_MODULES([DRI], [libmesadri = 7.0.3 libmesadricommon = 7.0.3]) +PKG_CHECK_MODULES([DRI], [libmesadri >= 7.0.3 libmesadri < 7.1.0 + libmesadricommon >= 7.0.3 libmesadricommon < 7.1.0]) AC_OUTPUT([ Makefile diff --git a/src/Makefile.am b/src/Makefile.am index aa854c5..1b926b2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,7 +1,23 @@ AM_CFLAGS = -DIN_DRI_DRIVER -DGLX_DIRECT_RENDERING -DGLX_INDIRECT_RENDERING -xxx_dri_la_LTLIBRARIES = xxx_dri.la -xxx_dri_la_CFLAGS = $(AM_CFLAGS) $(DRM_CFLAGS) $(DRI_CFLAGS) -Iserver -xxx_dri_la_LDFLAGS = -module -noprefix -lm -ldl $(DRM_LIBS) $(DRI_LIBS) -xxx_dri_ladir = @libdir@/dri -xxx_dri_la_SOURCES = \ +sis_dri_la_LTLIBRARIES = sis_dri.la +sis_dri_la_CFLAGS = $(AM_CFLAGS) $(DRM_CFLAGS) $(DRI_CFLAGS) -Iserver +sis_dri_la_LDFLAGS = -module -noprefix -avoid-version -lm -ldl \ + $(DRM_LIBS) $(DRI_LIBS) +sis_dri_ladir = @libdir@/dri +sis_dri_la_SOURCES = \ + sis6326_state.c \ + sis6326_clear.c \ + sis_alloc.c \ + sis_clear.c \ + sis_context.c \ + sis_dd.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 diff --git a/src/server/sis_common.h b/src/server/sis_common.h new file mode 100644 index 0000000..cbddf0c --- /dev/null +++ b/src/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 <anholt@FreeBSD.org> + * + */ + +#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/server/sis_dri.h b/src/server/sis_dri.h new file mode 100644 index 0000000..a056624 --- /dev/null +++ b/src/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" +#include "drm.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 { + drm_handle_t handle; + drmSize size; +} 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/sis6326_clear.c b/src/sis6326_clear.c new file mode 100644 index 0000000..48db195 --- /dev/null +++ b/src/sis6326_clear.c @@ -0,0 +1,229 @@ +/* + * Copyright 2005 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 <anholt@FreeBSD.org> + * + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_lock.h" +#include "sis_reg.h" + +#include "swrast/swrast.h" +#include "macros.h" + +static void sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x, + GLint y, GLint width, GLint height); +static void sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x, + GLint y, GLint width, GLint height); +static void sis_clear_z_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 (smesa->colorFormat) + { + 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: + sis_fatal_error("Bad dst color format\n"); + } +} + +void +sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z) +{ + CLAMPED_FLOAT_TO_USHORT(smesa->clearZStencilPattern, z * 65535.0); +} + +void +sis6326DDClear(GLcontext *ctx, GLbitfield mask) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + GLint x1, y1, width1, height1; + + /* get region after locking: */ + x1 = ctx->DrawBuffer->_Xmin; + y1 = ctx->DrawBuffer->_Ymin; + width1 = ctx->DrawBuffer->_Xmax - x1; + height1 = ctx->DrawBuffer->_Ymax - y1; + y1 = Y_FLIP(y1 + height1 - 1); + + /* XXX: Scissoring */ + + fprintf(stderr, "Clear\n"); + + /* Mask out any non-existent buffers */ + if (smesa->depth.offset == 0 || !ctx->Depth.Mask) + mask &= ~BUFFER_BIT_DEPTH; + + LOCK_HARDWARE(); + + if (mask & BUFFER_BIT_FRONT_LEFT) { + sis_clear_front_buffer(ctx, mask, x1, y1, width1, height1); + mask &= ~BUFFER_BIT_FRONT_LEFT; + } + + if (mask & BUFFER_BIT_BACK_LEFT) { + sis_clear_back_buffer(ctx, mask, x1, y1, width1, height1); + mask &= ~BUFFER_BIT_BACK_LEFT; + } + + if (mask & BUFFER_BIT_DEPTH) { + sis_clear_z_buffer(ctx, mask, x1, y1, width1, height1); + mask &= ~BUFFER_BIT_DEPTH; + } + + UNLOCK_HARDWARE(); + + if (mask != 0) + _swrast_Clear(ctx, mask); +} + + +void +sis6326DDClearColor(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 +sis6326DDClearDepth(GLcontext *ctx, GLclampd d) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + sis6326UpdateZPattern(smesa, d); +} + +static void +sis_clear_back_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y, + GLint width, GLint height) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + /* XXX: The order of writing these registers seems to matter, while + * it actually shouldn't. + */ + mWait3DCmdQueue(6); + MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->back.pitch << 16); + MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY | + smesa->clearColorPattern); + MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY | + smesa->clearColorPattern); + MMIO(REG_6326_BitBlt_DstAddr, smesa->back.offset + + (y+height) * smesa->back.pitch + + (x+width) * smesa->bytesPerPixel); + MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) | + (width * smesa->bytesPerPixel)); + MMIO_WMB(); + MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG); +} + +static void +sis_clear_front_buffer(GLcontext *ctx, GLenum mask, GLint x, GLint y, + GLint width, GLint height) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + int count; + drm_clip_rect_t *pExtents = NULL; + + pExtents = smesa->driDrawable->pClipRects; + count = smesa->driDrawable->numClipRects; + + mWait3DCmdQueue(3); + MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->front.pitch << 16); + MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY | + smesa->clearColorPattern); + MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY | + smesa->clearColorPattern); + + while (count--) { + GLint x1 = pExtents->x1 - smesa->driDrawable->x; + GLint y1 = pExtents->y1 - smesa->driDrawable->y; + GLint x2 = pExtents->x2 - smesa->driDrawable->x; + GLint y2 = pExtents->y2 - smesa->driDrawable->y; + + if (x > x1) + x1 = x; + if (y > y1) + y1 = y; + + if (x + width < x2) + x2 = x + width; + if (y + height < y2) + y2 = y + height; + width = x2 - x1; + height = y2 - y1; + + pExtents++; + + if (width <= 0 || height <= 0) + continue; + + mWait3DCmdQueue(3); + MMIO(REG_6326_BitBlt_DstAddr, smesa->front.offset + + (y2-1) * smesa->front.pitch + x2 * smesa->bytesPerPixel); + MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) | + (width * smesa->bytesPerPixel)); + MMIO_WMB(); + MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG); + } +} + +static void +sis_clear_z_buffer(GLcontext * ctx, GLbitfield mask, GLint x, GLint y, + GLint width, GLint height) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + mWait3DCmdQueue(6); + MMIO(REG_6326_BitBlt_DstAddr, + smesa->depth.offset + y * smesa->depth.pitch + x * 2); + MMIO(REG_6326_BitBlt_DstSrcPitch, smesa->depth.pitch << 16); + MMIO(REG_6326_BitBlt_HeightWidth, ((height-1) << 16) | (width * 2)); + MMIO(REG_6326_BitBlt_fgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern); + MMIO(REG_6326_BitBlt_bgColor, SiS_ROP_PATCOPY | smesa->clearZStencilPattern); + MMIO_WMB(); + MMIO(REG_6326_BitBlt_Cmd, BLT_PAT_BG | BLT_XINC | BLT_YINC); +} + diff --git a/src/sis6326_reg.h b/src/sis6326_reg.h new file mode 100644 index 0000000..8e645f0 --- /dev/null +++ b/src/sis6326_reg.h @@ -0,0 +1,408 @@ +/* + * Copyright 2005 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 <anholt@FreeBSD.org> + * + */ + +#ifndef _sis6326_reg_h_ +#define _sis6326_reg_h_ + +#define REG_6326_BitBlt_SrcAddr 0x8280 +#define REG_6326_BitBlt_DstAddr 0x8284 +#define REG_6326_BitBlt_DstSrcPitch 0x8288 +#define REG_6326_BitBlt_HeightWidth 0x828c +#define REG_6326_BitBlt_fgColor 0x8290 +#define REG_6326_BitBlt_bgColor 0x8294 +#define REG_6326_BitBlt_Mask30 0x8298 +#define REG_6326_BitBlt_Mask74 0x829c +#define REG_6326_BitBlt_ClipTopLeft 0x82a0 +#define REG_6326_BitBlt_ClitBottomRight 0x82a4 +#define REG_6326_BitBlt_Cmd 0x82a8 +#define REG_6326_BitBlt_Pat 0x82ac + +#define REG_6326_3D_TSFSa 0x8800 +#define REG_6326_3D_TSZa 0x8804 +#define REG_6326_3D_TSXa 0x8808 +#define REG_6326_3D_TSYa 0x880C +#define REG_6326_3D_TSARGBa 0x8810 +#define REG_6326_3D_TSUa 0x8814 +#define REG_6326_3D_TSVa 0x8818 +#define REG_6326_3D_TSWa 0x881C + +#define REG_6326_3D_TSFSb 0x8820 +#define REG_6326_3D_TSZb 0x8824 +#define REG_6326_3D_TSXb 0x8828 +#define REG_6326_3D_TSYb 0x882C +#define REG_6326_3D_TSARGBb 0x8830 +#define REG_6326_3D_TSUb 0x8834 +#define REG_6326_3D_TSVb 0x8838 +#define REG_6326_3D_TSWb 0x883C + +#define REG_6326_3D_TSFSc 0x8840 +#define REG_6326_3D_TSZc 0x8844 +#define REG_6326_3D_TSXc 0x8848 +#define REG_6326_3D_TSYc 0x884C +#define REG_6326_3D_TSARGBc 0x8850 +#define REG_6326_3D_TSUc 0x8854 +#define REG_6326_3D_TSVc 0x8858 +#define REG_6326_3D_TSWc 0x885C + +#define REG_6326_3D_TEnable 0x8A00 +#define REG_6326_3D_ZSet 0x8A04 +#define REG_6326_3D_ZAddress 0x8A08 + +#define REG_6326_3D_AlphaSet 0x8A0C +#define REG_6326_3D_AlphaAddress 0x8A10 +#define REG_6326_3D_DstSet 0x8A14 +#define REG_6326_3D_DstAddress 0x8A18 +#define REG_6326_3D_LinePattern 0x8A1C +#define REG_6326_3D_FogSet 0x8A20 + +#define REG_6326_3D_DstSrcBlendMode 0x8A28 + +#define REG_6326_3D_ClipTopBottom 0x8A30 +#define REG_6326_3D_ClipLeftRight 0x8A34 + +#define REG_6326_3D_TextureSet 0x8A38 +#define REG_6326_3D_TextureBlendSet 0x8A3C +/* Low transparency value is in TextureBlendSet */ +#define REG_6326_3D_TextureTransparencyColorHigh 0x8A40 + +#define REG_6326_3D_TextureAddress0 0x8A44 +#define REG_6326_3D_TextureAddress1 0x8A48 +#define REG_6326_3D_TextureAddress2 0x8A4C +#define REG_6326_3D_TextureAddress3 0x8A50 +#define REG_6326_3D_TextureAddress4 0x8A54 +#define REG_6326_3D_TextureAddress5 0x8A58 +#define REG_6326_3D_TextureAddress6 0x8A5C +#define REG_6326_3D_TextureAddress7 0x8A60 +#define REG_6326_3D_TextureAddress8 0x8A64 +#define REG_6326_3D_TextureAddress9 0x8A68 + +#define REG_6326_3D_TexturePitch01 0x8A6C +#define REG_6326_3D_TexturePitch23 0x8A70 +#define REG_6326_3D_TexturePitch45 0x8A74 +#define REG_6326_3D_TexturePitch67 0x8A78 +#define REG_6326_3D_TexturePitch89 0x8A7C + +#define REG_6326_3D_TextureWidthHeight 0x8A80 +#define REG_6326_3D_TextureBorderColor 0x8A90 + +#define REG_6326_3D_EndPrimitiveList 0x8Aff + +/* + * REG_6326_BitBlt_fgColor (0x8290-0x8293) + * REG_6326_BitBlt_bgColor (0x8294-0x8297) + */ +#define MASK_BltRop 0xff000000 +#define MASK_BltColor 0x00ffffff + +#define SiS_ROP_SRCCOPY 0xcc000000 +#define SiS_ROP_PATCOPY 0xf0000000 + +/* + * REG_6326_BitBlt_Cmd (0x82a8-0x82ab) + */ +#define MASK_QueueStatus 0x0000ffff +#define MASK_BltCmd0 0x00ff0000 +#define MASK_BltCmd1 0xff000000 + +#define BLT_SRC_BG 0x00000000 +#define BLT_SRC_FG 0x00010000 +#define BLT_SRC_VID 0x00020000 +#define BLT_SRC_CPU 0x00030000 +#define BLT_PAT_BG 0x00000000 +#define BLT_PAT_FG 0x00040000 +#define BLT_PAT_PAT 0x000b0000 +#define BLT_XINC 0x00100000 +#define BLT_YINC 0x00200000 +#define BLT_CLIP 0x00400000 +#define BLT_BUSY 0x04000000 + +/* + * REG_3D_PrimitiveSet -- Define Fire Primitive Mask (89F8h-89FBh) + */ +#define MASK_6326_DrawPrimitiveCommand 0x00000007 +#define MASK_6326_SetFirePosition 0x00000F00 +#define MASK_6326_ShadingMode 0x001c0000 +#define MASK_6326_Direction 0x0003f000 + +/* OP_3D_{POINT,LINE,TRIANGLE}_DRAW same as 300-series */ +/* OP_3D_DIRECTION*_ same as 300-series */ + +#define OP_6326_3D_FIRE_TFIRE 0x00000000 +#define OP_6326_3D_FIRE_TSARGBa 0x00000100 +#define OP_6326_3D_FIRE_TSWa 0x00000200 +#define OP_6326_3D_FIRE_TSARGBb 0x00000300 +#define OP_6326_3D_FIRE_TSWb 0x00000400 +#define OP_6326_3D_FIRE_TSARGBc 0x00000500 +#define OP_6326_3D_FIRE_TSWc 0x00000600 +#define OP_6326_3D_FIRE_TSVc 0x00000700 + +#define OP_6326_3D_ATOP 0x00000000 +#define OP_6326_3D_BTOP 0x00010000 +#define OP_6326_3D_CTOP 0x00020000 +#define OP_6326_3D_AMID 0x00000000 +#define OP_6326_3D_BMID 0x00004000 +#define OP_6326_3D_CMID 0x00008000 +#define OP_6326_3D_ABOT 0x00000000 +#define OP_6326_3D_BBOT 0x00001000 +#define OP_6326_3D_CBOT 0x00002000 + +#define OP_6326_3D_SHADE_FLAT_TOP 0x00040000 +#define OP_6326_3D_SHADE_FLAT_MID 0x00080000 +#define OP_6326_3D_SHADE_FLAT_BOT 0x000c0000 +#define OP_6326_3D_SHADE_FLAT_GOURAUD 0x00100000 + + +/* + * REG_6326_3D_EngineFire + */ +#define MASK_CmdQueueLen 0x0FFF0000 +#define ENG_3DIDLEQE 0x00000002 +#define ENG_3DIDLE 0x00000001 + +/* + * REG_6326_3D_TEnable -- Define Capility Enable Mask (8A00h-8A03h) + */ +#define S_ENABLE_Dither (1 << 0) +#define S_ENABLE_Transparency (1 << 1) +#define S_ENABLE_Blend (1 << 2) +#define S_ENABLE_Fog (1 << 3) +#define S_ENABLE_Specular (1 << 4) +#define S_ENABLE_LargeCache (1 << 5) +#define S_ENABLE_TextureCache (1 << 7) +#define S_ENABLE_TextureTransparency (1 << 8) +#define S_ENABLE_TexturePerspective (1 << 9) +#define S_ENABLE_Texture (1 << 10) +#define S_ENABLE_PrimSetup (1 << 11) +#define S_ENABLE_LinePattern (1 << 12) +#define S_ENABLE_StippleAlpha (1 << 13) /* requires S_ENABLE_Stipple */ +#define S_ENABLE_Stipple (1 << 14) +#define S_ENABLE_AlphaBuffer (1 << 16) +#define S_ENABLE_AlphaTest (1 << 17) +#define S_ENABLE_AlphaWrite (1 << 18) +#define S_ENABLE_ZTest (1 << 20) +#define S_ENABLE_ZWrite (1 << 21) + +/* + * REG_3D_ZSet -- Define Z Buffer Setting Mask (8A08h-8A0Bh) + */ +#define MASK_6326_ZBufferPitch 0x00003FFF +#define MASK_6326_ZTestMode 0x00070000 +#define MASK_6326_ZBufferFormat 0x00100000 + +#define S_ZSET_FORMAT_8 0x00000000 +#define S_ZSET_FORMAT_16 0x00100000 + +#define S_ZSET_PASS_NEVER 0x00000000 +#define S_ZSET_PASS_LESS 0x00010000 +#define S_ZSET_PASS_EQUAL 0x00020000 +#define S_ZSET_PASS_LEQUAL 0x00030000 +#define S_ZSET_PASS_GREATER 0x00040000 +#define S_ZSET_PASS_NOTEQUAL 0x00050000 +#define S_ZSET_PASS_GEQUAL 0x00060000 +#define S_ZSET_PASS_ALWAYS 0x00070000 + +/* + * REG_3D_AlphaSet -- Define Alpha Buffer Setting Mask (8A0Ch-8A0Fh) + */ +#define MASK_AlphaBufferPitch 0x000003FF +#define MASK_AlphaRefValue 0x00FF0000 +#define MASK_AlphaTestMode 0x07000000 +#define MASK_AlphaBufferFormat 0x30000000 + +#define S_ASET_FORMAT_8 0x30000000 + +#define S_ASET_PASS_NEVER 0x00000000 +#define S_ASET_PASS_LESS 0x01000000 +#define S_ASET_PASS_EQUAL 0x02000000 +#define S_ASET_PASS_LEQUAL 0x03000000 +#define S_ASET_PASS_GREATER 0x04000000 +#define S_ASET_PASS_NOTEQUAL 0x05000000 +#define S_ASET_PASS_GEQUAL 0x06000000 +#define S_ASET_PASS_ALWAYS 0x07000000 + +/* + * REG_3D_DstSet -- Define Destination Buffer Setting Mask (8A14h-8A17h) + */ +/* pitch, format, depth, rgborder, rop bits same as 300-series */ + +/* + * REG_6326_3D_FogSet -- Define Fog Mask (8A20h-8A23h) + */ +#define MASK_6326_FogColor 0x00FFFFFF +#define MASK_6326_FogMode 0x01000000 + +#define FOGMODE_6326_CONST 0x00000000 +#define FOGMODE_6326_LINEAR 0x01000000 + +/* + * REG_6326_3D_DstSrcBlendMode (0x8A28 - 0x8A2B) + */ +#define MASK_6326_SrcBlendMode 0xf0000000 +#define MASK_6326_DstBlendMode 0x0f000000 +#define MASK_6326_TransparencyColor 0x00ffffff + +#define S_DBLEND_ZERO 0x00000000 +#define S_DBLEND_ONE 0x10000000 +#define S_DBLEND_SRC_COLOR 0x20000000 +#define S_DBLEND_INV_SRC_COLOR 0x30000000 +#define S_DBLEND_SRC_ALPHA 0x40000000 +#define S_DBLEND_INV_SRC_ALPHA 0x50000000 +#define S_DBLEND_DST_ALPHA 0x60000000 +#define S_DBLEND_INV_DST_ALPHA 0x70000000 + +#define S_SBLEND_ZERO 0x00000000 +#define S_SBLEND_ONE 0x01000000 +#define S_SBLEND_SRC_ALPHA 0x04000000 +#define S_SBLEND_INV_SRC_ALPHA 0x05000000 +#define S_SBLEND_DST_ALPHA 0x06000000 +#define S_SBLEND_INV_DST_ALPHA 0x07000000 +#define S_SBLEND_DST_COLOR 0x08000000 +#define S_SBLEND_INV_DST_COLOR 0x09000000 +#define S_SBLEND_SRC_ALPHA_SAT 0x0A000000 +#define S_SBLEND_BOTH_SRC_ALPHA 0x0B000000 +#define S_SBLEND_BOTH_INV_SRC_ALPHA 0x0C000000 + +/* + * REG_6326_3D_TextureSet (0x8A38 - 0x8A3B) + */ +#define MASK_6326_TextureMinFilter 0x00000007 +#define MASK_6326_TextureMagFilter 0x00000008 +#define MASK_6326_ClearTexCache 0x00000010 +#define MASK_6326_TextureInSystem 0x00000020 +#define MASK_6326_TextureLevel 0x00000F00 +#define MASK_6326_TextureSignYUVFormat 0x00008000 +#define MASK_6326_TextureMappingMode 0x00FF0000 + +#define TEXEL_6326_BGR_ORDER 0x80000000 + +#define TEXEL_6326_INDEX1 0x00000000 +#define TEXEL_6326_INDEX2 0x01000000 +#define TEXEL_6326_INDEX4 0x02000000 + +#define TEXEL_6326_M4 0x10000000 +#define TEXEL_6326_AM44 0x16000000 + +#define TEXEL_6326_YUV422 0x20000000 /* YUYV */ +#define TEXEL_6326_YVU422 0x21000000 /* YVYU */ +#define TEXEL_6326_UVY422 0x22000000 /* UYVY */ +#define TEXEL_6326_VUY422 0x23000000 /* VYUY */ + +#define TEXEL_6326_L1 0x30000000 +#define TEXEL_6326_L2 0x31000000 +#define TEXEL_6326_L4 0x32000000 +#define TEXEL_6326_L8 0x33000000 + +#define TEXEL_6326_AL22 0x35000000 +#define TEXEL_6326_AL44 0x38000000 +#define TEXEL_6326_AL88 0x3c000000 + +#define TEXEL_6326_RGB_332_8 0x40000000 +#define TEXEL_6326_RGB_233_8 0x41000000 +#define TEXEL_6326_RGB_232_8 0x42000000 +#define TEXEL_6326_ARGB_1232_8 0x43000000 + +#define TEXEL_6326_RGB_555_16 0x50000000 +#define TEXEL_6326_RGB_565_16 0x51000000 +#define TEXEL_6326_ARGB_1555_16 0x52000000 +#define TEXEL_6326_ARGB_4444_16 0x53000000 +#define TEXEL_6326_ARGB_8332_16 0x54000000 +#define TEXEL_6326_ARGB_8233_16 0x55000000 +#define TEXEL_6326_ARGB_8232_16 0x56000000 + +#define TEXEL_6326_ARGB_8565_24 0x63000000 +#define TEXEL_6326_ARGB_8555_24 0x67000000 +#define TEXEL_6326_RGB_888_24 0x68000000 + +#define TEXEL_6326_ARGB_8888_32 0x73000000 +#define TEXEL_6326_ARGB_0888_32 0x74000000 + +#define TEX_MAP_WRAP_U 0x00010000 +#define TEX_MAP_WRAP_V 0x00020000 +#define TEX_MAP_MIRROR_U 0x00040000 +#define TEX_MAP_MIRROR_V 0x00080000 +#define TEX_MAP_CLAMP_U 0x00100000 +#define TEX_MAP_CLAMP_V 0x00200000 +#define TEX_MAP_USE_CTB_SMOOTH 0x00400000 +#define TEX_MAP_USE_CTB 0x00800000 + +#define TEX_FILTER_NEAREST 0x00000000 +#define TEX_FILTER_LINEAR 0x00000001 +#define TEX_FILTER_NEAREST_MIP_NEAREST 0x00000002 +#define TEX_FILTER_NEAREST_MIP_LINEAR 0x00000003 +#define TEX_FILTER_LINEAR_MIP_NEAREST 0x00000004 +#define TEX_FILTER_LINEAR_MIP_LINEAR 0x00000005 +#define TEX_FILTER_MAG_NEAREST 0x00000000 +#define TEX_FILTER_MAG_LINEAR 0x00000008 + +/* + * REG_6326_3D_TextureBlendSet (0x8A3C - 0x8A3F) + */ +#define MASK_TextureTransparencyLowB 0x000000ff +#define MASK_TextureTransparencyLowG 0x0000FF00 +#define MASK_TextureTransparencyLowR 0x00ff0000 +#define MASK_TextureBlend 0x0f000000 + +#define TB_C_CS (0 << 26) +#define TB_C_CF (1 << 26) +#define TB_C_CFCS (2 << 26) /* also 3 << 26 */ +#define TB_C_CFOMAS_ASCS (4 << 26) +#define TB_C_CSOMAF_AFCF (6 << 26) /* also 7 << 26 */ + +#define TB_A_AS (0 << 24) +#define TB_A_AF (1 << 24) +#define TB_A_AFAS (1 << 24) + +/* + * REG_6326_3D_TextureTransparencyColorHigh (0x8A40 - 0x8A43) + */ +#define MASK_TextureTransparencyHighB 0x000000FF +#define MASK_TextureTransparencyHighG 0x0000FF00 +#define MASK_TextureTransparencyHighR 0x00FF0000 + +/* + * REG_3D_TexturePitch01-89 (0x8A6C - 0x8A7F) + */ +#define MASK_TexturePitchOdd 0x000003FF +#define MASK_TexturePitchEven 0x03FF0000 +#define SHIFT_TexturePitchEven 16 + +/* + * REG_3D_TextureWidthHeightMix (0x8A80 - 0x8A83) + */ +#define MASK_TextureWidthLog2 0xf0000000 +#define MASK_TextureHeightLog2 0x0f000000 + +/* + * REG_3D_TextureBorderColor (0x8A90 - 0x8A93) + */ +#define MASK_TextureBorderColorB 0x000000FF +#define MASK_TextureBorderColorG 0x0000FF00 +#define MASK_TextureBorderColorR 0x00FF0000 +#define MASK_TextureBorderColorA 0xFF000000 + +#endif /* _sis6326_reg_h_ */ diff --git a/src/sis6326_state.c b/src/sis6326_state.c new file mode 100644 index 0000000..08402fb --- /dev/null +++ b/src/sis6326_state.c @@ -0,0 +1,735 @@ +/* + * Copyright 2005 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 <anholt@FreeBSD.org> + * + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_tris.h" +#include "sis_lock.h" +#include "sis_tex.h" +#include "sis_reg.h" + +#include "context.h" +#include "enums.h" +#include "colormac.h" +#include "swrast/swrast.h" +#include "vbo/vbo.h" +#include "tnl/tnl.h" +#include "swrast_setup/swrast_setup.h" + +#include "tnl/t_pipeline.h" + +/* ============================================================= + * Alpha blending + */ + +static void +sis6326DDAlphaFunc( 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 |= S_ASET_PASS_NEVER; + break; + case GL_LESS: + current->hwAlpha |= S_ASET_PASS_LESS; + break; + case GL_EQUAL: + current->hwAlpha |= S_ASET_PASS_EQUAL; + break; + case GL_LEQUAL: + current->hwAlpha |= S_ASET_PASS_LEQUAL; + break; + case GL_GREATER: + current->hwAlpha |= S_ASET_PASS_GREATER; + break; + case GL_NOTEQUAL: + current->hwAlpha |= S_ASET_PASS_NOTEQUAL; + break; + case GL_GEQUAL: + current->hwAlpha |= S_ASET_PASS_GEQUAL; + break; + case GL_ALWAYS: + current->hwAlpha |= S_ASET_PASS_ALWAYS; + break; + } + + prev->hwAlpha = current->hwAlpha; + smesa->GlobalFlag |= GFLAG_ALPHASETTING; +} + +static void +sis6326DDBlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + current->hwDstSrcBlend = 0; + + switch (dfactorRGB) + { + case GL_ZERO: + current->hwDstSrcBlend |= S_DBLEND_ZERO; + break; + case GL_ONE: + current->hwDstSrcBlend |= S_DBLEND_ONE; + break; + case GL_SRC_COLOR: + current->hwDstSrcBlend |= S_DBLEND_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + current->hwDstSrcBlend |= S_DBLEND_INV_SRC_COLOR; + break; + case GL_SRC_ALPHA: + current->hwDstSrcBlend |= S_DBLEND_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + current->hwDstSrcBlend |= S_DBLEND_INV_SRC_ALPHA; + break; + case GL_DST_ALPHA: + current->hwDstSrcBlend |= S_DBLEND_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + current->hwDstSrcBlend |= S_DBLEND_INV_DST_ALPHA; + break; + } + + switch (sfactorRGB) + { + case GL_ZERO: + current->hwDstSrcBlend |= S_SBLEND_ZERO; + break; + case GL_ONE: + current->hwDstSrcBlend |= S_SBLEND_ONE; + break; + case GL_SRC_ALPHA: + current->hwDstSrcBlend |= S_SBLEND_SRC_ALPHA; + break; + case GL_ONE_MINUS_SRC_ALPHA: + current->hwDstSrcBlend |= S_SBLEND_INV_SRC_ALPHA; + break; + case GL_DST_ALPHA: + current->hwDstSrcBlend |= S_SBLEND_DST_ALPHA; + break; + case GL_ONE_MINUS_DST_ALPHA: + current->hwDstSrcBlend |= S_SBLEND_INV_DST_ALPHA; + break; + case GL_DST_COLOR: + current->hwDstSrcBlend |= S_SBLEND_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + current->hwDstSrcBlend |= S_SBLEND_INV_DST_COLOR; + break; + case GL_SRC_ALPHA_SATURATE: + current->hwDstSrcBlend |= S_SBLEND_SRC_ALPHA_SAT; + break; + } + + if (current->hwDstSrcBlend != prev->hwDstSrcBlend) { + prev->hwDstSrcBlend = current->hwDstSrcBlend; + smesa->GlobalFlag |= GFLAG_DSTBLEND; + } +} + +/* ============================================================= + * Depth testing + */ + +static void +sis6326DDDepthFunc( GLcontext *ctx, GLenum func ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + current->hwZ &= ~MASK_6326_ZTestMode; + switch (func) + { + case GL_LESS: + current->hwZ |= S_ZSET_PASS_LESS; + break; + case GL_GEQUAL: + current->hwZ |= S_ZSET_PASS_GEQUAL; + break; + case GL_LEQUAL: + current->hwZ |= S_ZSET_PASS_LEQUAL; + break; + case GL_GREATER: + current->hwZ |= S_ZSET_PASS_GREATER; + break; + case GL_NOTEQUAL: + current->hwZ |= S_ZSET_PASS_NOTEQUAL; + break; + case GL_EQUAL: + current->hwZ |= S_ZSET_PASS_EQUAL; + break; + case GL_ALWAYS: + current->hwZ |= S_ZSET_PASS_ALWAYS; + break; + case GL_NEVER: + current->hwZ |= S_ZSET_PASS_NEVER; + break; + } + + if (current->hwZ != prev->hwZ) { + prev->hwZ = current->hwZ; + smesa->GlobalFlag |= GFLAG_ZSETTING; + } +} + +static void +sis6326DDDepthMask( GLcontext *ctx, GLboolean flag ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *current = &smesa->current; + + if (ctx->Depth.Test) + current->hwCapEnable |= S_ENABLE_ZWrite; + else + current->hwCapEnable &= ~S_ENABLE_ZWrite; +} + +/* ============================================================= + * Fog + */ + +static void +sis6326DDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *current = &smesa->current; + __GLSiSHardware *prev = &smesa->prev; + + GLint fogColor; + + switch(pname) + { + 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 = 0x01000000 | fogColor; + if (current->hwFog != prev->hwFog) { + prev->hwFog = current->hwFog; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + break; + } +} + +/* ============================================================= + * Clipping + */ + +void +sis6326UpdateClipping(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;*/ /* XXX */ + current->clipTopBottom = (0 << 13) | smesa->height; + current->clipLeftRight = (0 << 13) | smesa->width; + + if ((current->clipTopBottom != prev->clipTopBottom) || + (current->clipLeftRight != prev->clipLeftRight)) { + prev->clipTopBottom = current->clipTopBottom; + prev->clipLeftRight = current->clipLeftRight; + smesa->GlobalFlag |= GFLAG_CLIPPING; + } +} + +static void +sis6326DDScissor( GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h ) +{ + if (ctx->Scissor.Enabled) + sis6326UpdateClipping( ctx ); +} + +/* ============================================================= + * Culling + */ + +static void +sis6326UpdateCull( GLcontext *ctx ) +{ + /* XXX culling */ +} + + +static void +sis6326DDCullFace( GLcontext *ctx, GLenum mode ) +{ + sis6326UpdateCull( ctx ); +} + +static void +sis6326DDFrontFace( GLcontext *ctx, GLenum mode ) +{ + sis6326UpdateCull( ctx ); +} + +/* ============================================================= + * Masks + */ + +static void sis6326DDColorMask( GLcontext *ctx, + GLboolean r, GLboolean g, + GLboolean b, GLboolean a ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + if (r && g && b && ((ctx->Visual.alphaBits == 0) || a)) { + FALLBACK(smesa, SIS_FALLBACK_WRITEMASK, 0); + } else { + FALLBACK(smesa, SIS_FALLBACK_WRITEMASK, 1); + } +} + +/* ============================================================= + * Rendering attributes + */ + +static void sis6326UpdateSpecular(GLcontext *ctx) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *current = &smesa->current; + + if (NEED_SECONDARY_COLOR(ctx)) + current->hwCapEnable |= S_ENABLE_Specular; + else + current->hwCapEnable &= ~S_ENABLE_Specular; +} + +static void sis6326DDLightModelfv(GLcontext *ctx, GLenum pname, + const GLfloat *param) +{ + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + sis6326UpdateSpecular(ctx); + } +} +static void sis6326DDShadeModel( GLcontext *ctx, GLenum mode ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + /* Signal to sisRasterPrimitive to recalculate dwPrimitiveSet */ + smesa->hw_primitive = -1; +} + +/* ============================================================= + * Window position + */ + +/* ============================================================= + * Viewport + */ + +static void sis6326CalcViewport( 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 sis6326DDViewport( GLcontext *ctx, + GLint x, GLint y, + GLsizei width, GLsizei height ) +{ + sis6326CalcViewport( ctx ); +} + +static void sis6326DDDepthRange( GLcontext *ctx, + GLclampd nearval, GLclampd farval ) +{ + sis6326CalcViewport( ctx ); +} + +/* ============================================================= + * Miscellaneous + */ + +static void +sis6326DDLogicOpCode( 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 sis6326DDDrawBuffer( GLcontext *ctx, GLenum mode ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if(getenv("SIS_DRAW_FRONT")) + ctx->DrawBuffer->_ColorDrawBufferMask[0] = GL_FRONT_LEFT; + + /* + * _DrawDestMask is easier to cope with than <mode>. + */ + current->hwDstSet &= ~MASK_DstBufferPitch; + switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { + case BUFFER_BIT_FRONT_LEFT: + current->hwOffsetDest = smesa->front.offset; + current->hwDstSet |= smesa->front.pitch; + FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE ); + break; + case BUFFER_BIT_BACK_LEFT: + current->hwOffsetDest = smesa->back.offset; + current->hwDstSet |= smesa->back.pitch; + 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; + } + + 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; + } +} + +/* ============================================================= + * Polygon stipple + */ + +/* ============================================================= + * Render mode + */ + +/* ============================================================= + * State enable/disable + */ + +static void +sis6326DDEnable( 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 |= S_ENABLE_AlphaTest; + else + current->hwCapEnable &= ~S_ENABLE_AlphaTest; + break; + case GL_BLEND: + /* TODO: */ + if (state) + /* if (state & !ctx->Color.ColorLogicOpEnabled) */ + current->hwCapEnable |= S_ENABLE_Blend; + else + current->hwCapEnable &= ~S_ENABLE_Blend; + break; + case GL_CULL_FACE: + /* XXX culling */ + break; + case GL_DEPTH_TEST: + if (state && smesa->depth.offset != 0) + current->hwCapEnable |= S_ENABLE_ZTest; + else + current->hwCapEnable &= ~S_ENABLE_ZTest; + sis6326DDDepthMask( ctx, ctx->Depth.Mask ); + break; + case GL_DITHER: + if (state) + current->hwCapEnable |= S_ENABLE_Dither; + else + current->hwCapEnable &= ~S_ENABLE_Dither; + break; + case GL_FOG: + if (state) + current->hwCapEnable |= S_ENABLE_Fog; + else + current->hwCapEnable &= ~S_ENABLE_Fog; + break; + case GL_COLOR_LOGIC_OP: + if (state) + sis6326DDLogicOpCode( ctx, ctx->Color.LogicOp ); + else + sis6326DDLogicOpCode( ctx, GL_COPY ); + break; + case GL_SCISSOR_TEST: + sis6326UpdateClipping( ctx ); + break; + case GL_STENCIL_TEST: + if (state) { + FALLBACK(smesa, SIS_FALLBACK_STENCIL, 1); + } else { + FALLBACK(smesa, SIS_FALLBACK_STENCIL, 0); + } + break; + case GL_LIGHTING: + case GL_COLOR_SUM_EXT: + sis6326UpdateSpecular(ctx); + break; + } +} + +/* ============================================================= + * State initialization, management + */ + +/* Called before beginning of rendering. */ +void +sis6326UpdateHWState( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + if (smesa->NewGLState & _NEW_TEXTURE) + sisUpdateTextureState( ctx ); + + if (current->hwCapEnable ^ prev->hwCapEnable) { + prev->hwCapEnable = current->hwCapEnable; + smesa->GlobalFlag |= GFLAG_ENABLESETTING; + } + + if (smesa->GlobalFlag & GFLAG_RENDER_STATES) + sis_update_render_state( smesa ); + + if (smesa->GlobalFlag & GFLAG_TEXTURE_STATES) + sis_update_texture_state( smesa ); +} + +static void +sis6326DDInvalidateState( GLcontext *ctx, GLuint new_state ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + _swrast_InvalidateState( ctx, new_state ); + _swsetup_InvalidateState( ctx, new_state ); + _vbo_InvalidateState( ctx, new_state ); + _tnl_InvalidateState( ctx, new_state ); + smesa->NewGLState |= new_state; +} + +/* Initialize the context's hardware state. + */ +void sis6326DDInitState( sisContextPtr smesa ) +{ + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + GLcontext *ctx = smesa->glCtx; + + /* add Texture Perspective Enable */ + current->hwCapEnable = S_ENABLE_TextureCache | + S_ENABLE_TexturePerspective | S_ENABLE_Dither; + + /* Z test mode is LESS */ + current->hwZ = S_ZSET_PASS_LESS | S_ZSET_FORMAT_16; + if (ctx->Visual.depthBits > 0) + current->hwCapEnable |= S_ENABLE_ZWrite; + + /* Alpha test mode is ALWAYS, alpha ref value is 0 */ + current->hwAlpha = S_ASET_PASS_ALWAYS; + + /* ROP2 is COPYPEN */ + current->hwDstSet = LOP_COPY; + + /* LinePattern is 0, Repeat Factor is 0 */ + current->hwLinePattern = 0x00008000; + + /* Src blend is BLEND_ONE, Dst blend is D3DBLEND_ZERO */ + current->hwDstSrcBlend = S_SBLEND_ONE | S_DBLEND_ZERO; + + switch (smesa->bytesPerPixel) + { + case 2: + current->hwDstSet |= DST_FORMAT_RGB_565; + break; + case 4: + current->hwDstSet |= DST_FORMAT_ARGB_8888; + break; + } + + smesa->depth_scale = 1.0 / (GLfloat)0xffff; + + smesa->clearTexCache = GL_TRUE; + + smesa->clearColorPattern = 0; + + sis6326UpdateZPattern(smesa, 1.0); + sis6326UpdateCull(ctx); + + /* Set initial fog settings. Start and end are the same case. */ + sis6326DDFogfv( ctx, GL_FOG_DENSITY, &ctx->Fog.Density ); + sis6326DDFogfv( ctx, GL_FOG_END, &ctx->Fog.End ); + sis6326DDFogfv( ctx, GL_FOG_MODE, NULL ); + + memcpy(prev, current, sizeof(__GLSiSHardware)); +} + +/* Initialize the driver's state functions. + */ +void sis6326DDInitStateFuncs( GLcontext *ctx ) +{ + ctx->Driver.UpdateState = sis6326DDInvalidateState; + + ctx->Driver.Clear = sis6326DDClear; + ctx->Driver.ClearColor = sis6326DDClearColor; + ctx->Driver.ClearDepth = sis6326DDClearDepth; + + ctx->Driver.AlphaFunc = sis6326DDAlphaFunc; + ctx->Driver.BlendFuncSeparate = sis6326DDBlendFuncSeparate; + ctx->Driver.ColorMask = sis6326DDColorMask; + ctx->Driver.CullFace = sis6326DDCullFace; + ctx->Driver.DepthMask = sis6326DDDepthMask; + ctx->Driver.DepthFunc = sis6326DDDepthFunc; + ctx->Driver.DepthRange = sis6326DDDepthRange; + ctx->Driver.DrawBuffer = sis6326DDDrawBuffer; + ctx->Driver.Enable = sis6326DDEnable; + ctx->Driver.FrontFace = sis6326DDFrontFace; + ctx->Driver.Fogfv = sis6326DDFogfv; + ctx->Driver.LogicOpcode = sis6326DDLogicOpCode; + ctx->Driver.Scissor = sis6326DDScissor; + ctx->Driver.ShadeModel = sis6326DDShadeModel; + ctx->Driver.LightModelfv = sis6326DDLightModelfv; + ctx->Driver.Viewport = sis6326DDViewport; +} diff --git a/src/sis_alloc.c b/src/sis_alloc.c new file mode 100644 index 0000000..b696eeb --- /dev/null +++ b/src/sis_alloc.c @@ -0,0 +1,199 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "sis_context.h" +#include "sis_alloc.h" + +#include "sis_common.h" + +#include <unistd.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) + +#define ALIGNMENT(value, align) (((value) + (align) - 1) / (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 ) +{ + int cpp = ( smesa->glCtx->Visual.depthBits + + smesa->glCtx->Visual.stencilBits ) / 8; + unsigned char *addr; + + smesa->depth.bpp = cpp * 8; + smesa->depth.pitch = ALIGNMENT(smesa->driDrawable->w * cpp, 4); + smesa->depth.size = smesa->depth.pitch * smesa->driDrawable->h; + smesa->depth.size += Z_BUFFER_HW_PLUS; + + addr = sisAllocFB(smesa, smesa->depth.size, &smesa->depth.handle); + if (addr == NULL) + sis_fatal_error("Failure to allocate Z buffer.\n"); + addr = (char *)ALIGNMENT((unsigned long)addr, Z_BUFFER_HW_ALIGNMENT); + + smesa->depth.map = addr; + smesa->depth.offset = addr - smesa->FbBase; + + /* stencil buffer is same as depth buffer */ + smesa->stencil.size = smesa->depth.size; + smesa->stencil.offset = smesa->depth.offset; + smesa->stencil.handle = smesa->depth.handle; + smesa->stencil.pitch = smesa->depth.pitch; + smesa->stencil.bpp = smesa->depth.bpp; + smesa->stencil.map = smesa->depth.map; +} + +void +sisFreeZStencilBuffer( sisContextPtr smesa ) +{ + sisFreeFB(smesa, smesa->depth.handle); + smesa->depth.map = NULL; + smesa->depth.offset = 0; +} + +void +sisAllocBackbuffer( sisContextPtr smesa ) +{ + int cpp = smesa->bytesPerPixel; + unsigned char *addr; + + smesa->back.bpp = smesa->bytesPerPixel * 8; + smesa->back.pitch = ALIGNMENT(smesa->driDrawable->w * cpp, 4); + smesa->back.size = smesa->back.pitch * smesa->driDrawable->h; + smesa->back.size += DRAW_BUFFER_HW_PLUS; + + addr = sisAllocFB(smesa, smesa->back.size, &smesa->back.handle); + if (addr == NULL) + sis_fatal_error("Failure to allocate back buffer.\n"); + addr = (char *)ALIGNMENT((unsigned long)addr, DRAW_BUFFER_HW_ALIGNMENT); + + smesa->back.map = addr; + smesa->back.offset = addr - smesa->FbBase; +} + +void +sisFreeBackbuffer( sisContextPtr smesa ) +{ + sisFreeFB(smesa, smesa->back.handle); + smesa->back.map = NULL; + smesa->back.offset = 0; +} diff --git a/src/sis_alloc.h b/src/sis_alloc.h new file mode 100644 index 0000000..e76fc53 --- /dev/null +++ b/src/sis_alloc.h @@ -0,0 +1,44 @@ +/************************************************************************** + +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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +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/sis_clear.c b/src/sis_clear.c new file mode 100644 index 0000000..fb92d06 --- /dev/null +++ b/src/sis_clear.c @@ -0,0 +1,410 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_lock.h" + +#include "swrast/swrast.h" +#include "macros.h" + +static GLbitfield sis_3D_Clear( GLcontext * ctx, GLbitfield mask, + GLint x, GLint y, GLint width, + GLint height ); +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 (smesa->colorFormat) + { + 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: + sis_fatal_error("Bad dst color format\n"); + } +} + +void +sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, GLint stencil ) +{ + GLuint zPattern; + + switch (smesa->zFormat) + { + case SiS_ZFORMAT_Z16: + CLAMPED_FLOAT_TO_USHORT(zPattern, z); + zPattern |= zPattern << 16; + break; + case SiS_ZFORMAT_S8Z24: + zPattern = FLOAT_TO_UINT(z) >> 8; + zPattern |= stencil << 24; + break; + case SiS_ZFORMAT_Z32: + zPattern = FLOAT_TO_UINT(z); + break; + default: + sis_fatal_error("Bad Z format\n"); + } + smesa->clearZStencilPattern = zPattern; +} + +void +sisDDClear( GLcontext * ctx, GLbitfield mask ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + GLint x1, y1, width1, height1; + + /* get region after locking: */ + x1 = ctx->DrawBuffer->_Xmin; + y1 = ctx->DrawBuffer->_Ymin; + width1 = ctx->DrawBuffer->_Xmax - x1; + height1 = ctx->DrawBuffer->_Ymax - y1; + y1 = Y_FLIP(y1 + height1 - 1); + + /* Mask out any non-existent buffers */ + if (ctx->Visual.depthBits == 0 || !ctx->Depth.Mask) + mask &= ~BUFFER_BIT_DEPTH; + if (ctx->Visual.stencilBits == 0) + mask &= ~BUFFER_BIT_STENCIL; + + LOCK_HARDWARE(); + + /* The 3d clear code is use for masked clears because apparently the SiS + * 300-series can't do write masks for 2d blits. 3d isn't used in general + * because it's slower, even in the case of clearing multiple buffers. + */ + /* XXX: Appears to be broken with stencil. */ + if ((smesa->current.hwCapEnable2 & (MASK_AlphaMaskWriteEnable | + MASK_ColorMaskWriteEnable) && + (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT)) != 0) || + ((ctx->Stencil.WriteMask[0] & 0xff) != 0xff && + (mask & BUFFER_BIT_STENCIL) != 0) ) + { + mask = sis_3D_Clear( ctx, mask, x1, y1, width1, height1 ); + } + + if ( mask & BUFFER_BIT_FRONT_LEFT || mask & BUFFER_BIT_BACK_LEFT) { + sis_clear_color_buffer( ctx, mask, x1, y1, width1, height1 ); + mask &= ~(BUFFER_BIT_FRONT_LEFT | BUFFER_BIT_BACK_LEFT); + } + + if (mask & (BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL)) { + if (smesa->depth.offset != 0) + sis_clear_z_stencil_buffer( ctx, mask, x1, y1, width1, height1 ); + mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL); + } + + UNLOCK_HARDWARE(); + + if (mask != 0) + _swrast_Clear( ctx, mask); +} + + +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 ); +} + +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 = MASK_ColorMaskWriteEnable; + GLint dwDepthMask = 0, dwSten1 = 0, dwSten2 = 0; + GLint dirtyflags = GFLAG_ENABLESETTING | GFLAG_ENABLESETTING2 | + GFLAG_CLIPPING | GFLAG_DESTSETTING; + int count; + drm_clip_rect_t *pExtents; + + bClrColor = (mask & (BUFFER_BIT_BACK_LEFT | BUFFER_BIT_FRONT_LEFT)) != 0; + bClrDepth = (mask & BUFFER_BIT_DEPTH) != 0; + bClrStencil = (mask & BUFFER_BIT_STENCIL) != 0; + + if (smesa->GlobalFlag & GFLAG_RENDER_STATES) + sis_update_render_state( smesa ); + + if (bClrStencil) { + dwSten1 = STENCIL_FORMAT_8 | SiS_STENCIL_ALWAYS | + ((ctx->Stencil.Clear & 0xff) << 8) | 0xff; + dwSten2 = SiS_SFAIL_REPLACE | SiS_SPASS_ZFAIL_REPLACE | + SiS_SPASS_ZPASS_REPLACE; + dwEnable1 = MASK_ZWriteEnable | MASK_StencilWriteEnable | + MASK_StencilTestEnable; + dwEnable2 |= MASK_ZMaskWriteEnable; + dwDepthMask |= (ctx->Stencil.WriteMask[0] & 0xff) << 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 & BUFFER_BIT_FRONT_LEFT) { + 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(); + + /* If BUFFER_BIT_FRONT_LEFT is set, we've only cleared the front buffer so far */ + if ((mask & BUFFER_BIT_FRONT_LEFT) != 0 && (mask & BUFFER_BIT_BACK_LEFT) != 0) + sis_3D_Clear( ctx, BUFFER_BIT_BACK_LEFT, x, y, width, height ); + + smesa->GlobalFlag |= dirtyflags; + + return mask & ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL | BUFFER_BIT_BACK_LEFT | + BUFFER_BIT_FRONT_LEFT); +} + +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; + drm_clip_rect_t *pExtents = NULL; + GLint xx, yy; + GLint x0, y0, width0, height0; + + /* Clear back buffer */ + if (mask & BUFFER_BIT_BACK_LEFT) { + mWait3DCmdQueue (8); + MMIO(REG_SRC_PITCH, (smesa->bytesPerPixel == 4) ? + BLIT_DEPTH_32 : BLIT_DEPTH_16); + MMIO(REG_DST_X_Y, (x << 16) | y); + MMIO(REG_DST_ADDR, smesa->back.offset); + MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->back.pitch); + MMIO(REG_WIDTH_HEIGHT, (height << 16) | width); + MMIO(REG_PATFG, smesa->clearColorPattern); + MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_PAT); + MMIO(REG_CommandQueue, -1); + } + + if ((mask & BUFFER_BIT_FRONT_LEFT) == 0) + return; + + /* Clear front buffer */ + x0 = x; + y0 = y; + width0 = width; + height0 = height; + + pExtents = smesa->driDrawable->pClipRects; + count = smesa->driDrawable->numClipRects; + + 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; + + mWait3DCmdQueue (8); + MMIO(REG_SRC_PITCH, (smesa->bytesPerPixel == 4) ? + BLIT_DEPTH_32 : BLIT_DEPTH_16); + MMIO(REG_DST_X_Y, (x << 16) | y); + MMIO(REG_DST_ADDR, smesa->front.offset); + MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->front.pitch); + MMIO(REG_WIDTH_HEIGHT, (height << 16) | width); + MMIO(REG_PATFG, smesa->clearColorPattern); + MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_PAT); + MMIO(REG_CommandQueue, -1); + } +} + +static void +sis_clear_z_stencil_buffer( GLcontext * ctx, GLbitfield mask, + GLint x, GLint y, GLint width, GLint height ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + int cmd; + + mWait3DCmdQueue (8); + MMIO(REG_SRC_PITCH, (smesa->zFormat == SiS_ZFORMAT_Z16) ? + BLIT_DEPTH_16 : BLIT_DEPTH_32); + MMIO(REG_DST_X_Y, (x << 16) | y); + MMIO(REG_DST_ADDR, smesa->depth.offset); + MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->depth.pitch); + MMIO(REG_WIDTH_HEIGHT, (height << 16) | width); + MMIO(REG_PATFG, smesa->clearZStencilPattern); + MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_PAT); + MMIO(REG_CommandQueue, -1); +} + diff --git a/src/sis_context.c b/src/sis_context.c new file mode 100644 index 0000000..b21df0a --- /dev/null +++ b/src/sis_context.c @@ -0,0 +1,728 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#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_alloc.h" + +#include "imports.h" +#include "matrix.h" +#include "extensions.h" +#include "utils.h" +#include "framebuffer.h" + +#include "drivers/common/driverfuncs.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "vbo/vbo.h" + +#include "tnl/tnl.h" +#include "tnl/t_pipeline.h" + +#define need_GL_ARB_multisample +#define need_GL_ARB_texture_compression +#define need_GL_ARB_vertex_buffer_object +#define need_GL_EXT_fog_coord +#define need_GL_EXT_secondary_color +#include "extension_helper.h" + +#ifndef SIS_DEBUG +int SIS_DEBUG = 0; +#endif + +int GlobalCurrentHwcx = -1; +int GlobalHwcxCountBase = 1; +int GlobalCmdQueueLen = 0; + +struct dri_extension card_extensions[] = +{ + { "GL_ARB_multisample", GL_ARB_multisample_functions }, + { "GL_ARB_multitexture", NULL }, + { "GL_ARB_texture_border_clamp", NULL }, + { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, + { "GL_ARB_texture_mirrored_repeat", NULL }, + { "GL_ARB_vertex_buffer_object", GL_ARB_vertex_buffer_object_functions }, + /*{ "GL_EXT_fog_coord", GL_EXT_fog_coord_functions },*/ + { "GL_EXT_texture_lod_bias", NULL }, + { "GL_EXT_secondary_color", GL_EXT_secondary_color_functions }, + { "GL_EXT_stencil_wrap", NULL }, + { "GL_MESA_ycbcr_texture", NULL }, + { "GL_NV_blend_square", NULL }, + { NULL, NULL } +}; + +struct dri_extension card_extensions_6326[] = +{ + { "GL_ARB_multisample", GL_ARB_multisample_functions }, + /*{ "GL_ARB_texture_border_clamp", NULL },*/ + { "GL_ARB_texture_compression", GL_ARB_texture_compression_functions }, + /*{ "GL_ARB_texture_mirrored_repeat", NULL },*/ + /*{ "GL_MESA_ycbcr_texture", NULL },*/ + { NULL, NULL } +}; + +static const struct dri_debug_control debug_control[] = +{ + { "fall", DEBUG_FALLBACKS }, + { NULL, 0 } +}; + +void +WaitEngIdle (sisContextPtr smesa) +{ + GLuint engineState; + + if (smesa->is6326) { + do { + engineState = MMIO_READ(REG_3D_EngineFire); /* XXX right reg? */ + } while ((engineState & ENG_3DIDLEQE) != 0); + } else { + do { + engineState = MMIO_READ(REG_CommandQueue); + } while ((engineState & SiS_EngIdle) != SiS_EngIdle); + } +} + +void +Wait2DEngIdle (sisContextPtr smesa) +{ + GLuint engineState; + + if (smesa->is6326) { + do { + engineState = MMIO_READ(REG_6326_BitBlt_Cmd); + } while ((engineState & BLT_BUSY) != 0); + } else { + do { + engineState = MMIO_READ(REG_CommandQueue); + } while ((engineState & SiS_EngIdle2d) != SiS_EngIdle2d); + } +} + +/* To be called from mWait3DCmdQueue. Separate function for profiling + * purposes, and speed doesn't matter because we're spinning anyway. + */ +void +WaitingFor3dIdle(sisContextPtr smesa, int wLen) +{ + if (smesa->is6326) { + while (*(smesa->CurrentQueueLenPtr) < wLen) { + *(smesa->CurrentQueueLenPtr) = + ((GLuint)MMIO_READ(REG_3D_EngineFire) >> 16) * 2; + } + } else { + while (*(smesa->CurrentQueueLenPtr) < wLen) { + *(smesa->CurrentQueueLenPtr) = + (MMIO_READ(REG_CommandQueue) & MASK_QueueLen) - 20; + } + } +} + +void sisReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer, + GLuint width, GLuint height) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + sisUpdateBufferSize(smesa); + + _mesa_resize_framebuffer(ctx, drawbuffer, width, height); +} + +GLboolean +sisCreateContext( const __GLcontextModes *glVisual, + __DRIcontextPrivate *driContextPriv, + void *sharedContextPrivate ) +{ + GLcontext *ctx, *shareCtx; + __DRIscreenPrivate *sPriv = driContextPriv->driScreenPriv; + sisContextPtr smesa; + sisScreenPtr sisScreen; + int i; + struct dd_function_table functions; + + smesa = (sisContextPtr)CALLOC( sizeof(*smesa) ); + if (smesa == NULL) + return GL_FALSE; + + /* Init default driver functions then plug in our SIS-specific functions + * (the texture functions are especially important) + */ + _mesa_init_driver_functions(&functions); + sisInitDriverFuncs(&functions); + sisInitTextureFuncs(&functions); + + /* Allocate the Mesa context */ + if (sharedContextPrivate) + shareCtx = ((sisContextPtr)sharedContextPrivate)->glCtx; + else + shareCtx = NULL; + smesa->glCtx = _mesa_create_context( glVisual, shareCtx, + &functions, (void *) smesa); + if (!smesa->glCtx) { + FREE(smesa); + return GL_FALSE; + } + driContextPriv->driverPrivate = smesa; + ctx = smesa->glCtx; + + sisScreen = smesa->sisScreen = (sisScreenPtr)(sPriv->private); + + smesa->is6326 = GL_FALSE; /* XXX */ + 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->FbBase = sPriv->pFB; + smesa->displayWidth = sPriv->fbWidth; + smesa->front.pitch = sPriv->fbStride; + + smesa->sarea = (SISSAREAPriv *)((char *)sPriv->pSAREA + + sisScreen->sarea_priv_offset); + + /* 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: + sis_fatal_error("Bad bytesPerPixel %d.\n", smesa->bytesPerPixel); + } + + if (smesa->is6326) { + ctx->Const.MaxTextureUnits = 1; + ctx->Const.MaxTextureLevels = 9; + } else { + ctx->Const.MaxTextureUnits = 2; + ctx->Const.MaxTextureLevels = 11; + } + ctx->Const.MaxTextureImageUnits = ctx->Const.MaxTextureUnits; + ctx->Const.MaxTextureCoordUnits = ctx->Const.MaxTextureUnits; + + /* Parse configuration files */ + driParseConfigFiles (&smesa->optionCache, &sisScreen->optionCache, + sisScreen->driScreen->myNum, "sis"); + +#if DO_DEBUG + SIS_DEBUG = driParseDebugString(getenv("SIS_DEBUG"), debug_control); +#endif + + /* 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->agpBaseOffset; + + /* Create AGP command buffer */ + if (smesa->AGPSize != 0 && + !driQueryOptionb(&smesa->optionCache, "agp_disable")) + { + smesa->vb = sisAllocAGP(smesa, 64 * 1024, &smesa->vb_agp_handle); + if (smesa->vb != NULL) { + smesa->using_agp = GL_TRUE; + smesa->vb_cur = smesa->vb; + smesa->vb_last = smesa->vb; + smesa->vb_end = smesa->vb + 64 * 1024; + smesa->vb_agp_offset = ((long)smesa->vb - (long)smesa->AGPBase + + (long)smesa->AGPAddr); + } + } + if (!smesa->using_agp) { + smesa->vb = malloc(64 * 1024); + if (smesa->vb == NULL) { + FREE(smesa); + return GL_FALSE; + } + smesa->vb_cur = smesa->vb; + smesa->vb_last = smesa->vb; + smesa->vb_end = smesa->vb + 64 * 1024; + } + + smesa->GlobalFlag = 0L; + + smesa->Fallback = 0; + + /* Initialize the software rasterizer and helper modules. + */ + _swrast_CreateContext( ctx ); + _vbo_CreateContext( ctx ); + _tnl_CreateContext( ctx ); + _swsetup_CreateContext( ctx ); + + _swrast_allow_pixel_fog( ctx, GL_TRUE ); + _swrast_allow_vertex_fog( ctx, GL_FALSE ); + _tnl_allow_pixel_fog( ctx, GL_TRUE ); + _tnl_allow_vertex_fog( ctx, GL_FALSE ); + + /* XXX these should really go right after _mesa_init_driver_functions() */ + if (smesa->is6326) { + sis6326DDInitStateFuncs( ctx ); + sis6326DDInitState( smesa ); /* Initializes smesa->zFormat, important */ + } else { + sisDDInitStateFuncs( ctx ); + sisDDInitState( smesa ); /* Initializes smesa->zFormat, important */ + sisDDInitStencilFuncs( ctx ); + } + sisInitTriFuncs( ctx ); + sisDDInitSpanFuncs( ctx ); + + driInitExtensions( ctx, card_extensions, GL_FALSE ); + + for (i = 0; i < SIS_MAX_TEXTURES; i++) { + smesa->TexStates[i] = 0; + smesa->PrevTexFormat[i] = 0; + } + + if (driQueryOptionb(&smesa->optionCache, "no_rast")) { + fprintf(stderr, "disabling 3D acceleration\n"); + FALLBACK(smesa, SIS_FALLBACK_DISABLE, 1); + } + smesa->texture_depth = driQueryOptioni(&smesa->optionCache, "texture_depth"); + + 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 ); + _vbo_DestroyContext( smesa->glCtx ); + _swrast_DestroyContext( smesa->glCtx ); + + if (smesa->using_agp) + sisFreeAGP(smesa, smesa->vb_agp_handle); + + /* 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; + struct gl_framebuffer *drawBuffer, *readBuffer; + + if ( newSisCtx != oldSisCtx) { + newSisCtx->GlobalFlag = GFLAG_ALL; + } + + newSisCtx->driDrawable = driDrawPriv; + + drawBuffer = (GLframebuffer *)driDrawPriv->driverPrivate; + readBuffer = (GLframebuffer *)driReadPriv->driverPrivate; + + _mesa_make_current( newSisCtx->glCtx, drawBuffer, readBuffer ); + + sisUpdateBufferSize( newSisCtx ); + sisUpdateClipping( newSisCtx->glCtx ); + } else { + _mesa_make_current( NULL, NULL, NULL ); + } + + 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->hwTexBlendColor0); + MMIO(REG_3D_TextureAlphaBlendSet0, prev->hwTexBlendAlpha0); + } + if (smesa->GlobalFlag & GFLAG_TEXTUREENV_1) { + MMIO(REG_3D_TextureBlendFactor, prev->hwTexEnvColor); + MMIO(REG_3D_TextureColorBlendSet1, prev->hwTexBlendColor1); + MMIO(REG_3D_TextureAlphaBlendSet1, prev->hwTexBlendAlpha1); + } + + smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES; +} + +void +sis6326_update_render_state( sisContextPtr smesa ) +{ + __GLSiSHardware *prev = &smesa->prev; + + mWait3DCmdQueue (45); + + if (smesa->GlobalFlag & GFLAG_ENABLESETTING) { + if (!smesa->clearTexCache) { + MMIO(REG_6326_3D_TEnable, prev->hwCapEnable); + } else { + MMIO(REG_6326_3D_TEnable, prev->hwCapEnable & ~S_ENABLE_TextureCache); + MMIO(REG_6326_3D_TEnable, prev->hwCapEnable); + smesa->clearTexCache = GL_FALSE; + } + } + + /* Z Setting */ + if (smesa->GlobalFlag & GFLAG_ZSETTING) { + MMIO(REG_6326_3D_ZSet, prev->hwZ); + MMIO(REG_6326_3D_ZAddress, prev->hwOffsetZ); + } + + /* Alpha Setting */ + if (smesa->GlobalFlag & GFLAG_ALPHASETTING) + MMIO(REG_6326_3D_AlphaSet, prev->hwAlpha); + + if (smesa->GlobalFlag & GFLAG_DESTSETTING) { + MMIO(REG_6326_3D_DstSet, prev->hwDstSet); + MMIO(REG_6326_3D_DstAddress, prev->hwOffsetDest); + } + + /* Fog Setting */ + if (smesa->GlobalFlag & GFLAG_FOGSETTING) { + MMIO(REG_6326_3D_FogSet, prev->hwFog); + } + + /* Miscellaneous Setting */ + if (smesa->GlobalFlag & GFLAG_DSTBLEND) + MMIO(REG_6326_3D_DstSrcBlendMode, prev->hwDstSrcBlend); + + if (smesa->GlobalFlag & GFLAG_CLIPPING) { + MMIO(REG_6326_3D_ClipTopBottom, prev->clipTopBottom); + MMIO(REG_6326_3D_ClipLeftRight, prev->clipLeftRight); + } + + smesa->GlobalFlag &= ~GFLAG_RENDER_STATES; +} + +void +sis6326_update_texture_state (sisContextPtr smesa) +{ + __GLSiSHardware *prev = &smesa->prev; + + mWait3DCmdQueue (55); + if (smesa->clearTexCache || (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS)) { + MMIO(REG_6326_3D_TEnable, prev->hwCapEnable & ~S_ENABLE_TextureCache); + MMIO(REG_6326_3D_TEnable, prev->hwCapEnable); + smesa->clearTexCache = GL_FALSE; + } + + /* Texture Setting */ + if (smesa->GlobalFlag & CFLAG_TEXTURERESET) + MMIO(REG_6326_3D_TextureSet, prev->texture[0].hwTextureSet); + + if (smesa->GlobalFlag & GFLAG_TEXTUREMIPMAP) + MMIO(REG_6326_3D_TextureWidthHeight, prev->texture[0].hwTexWidthHeight); + + /* + MMIO(REG_3D_TextureTransparencyColorHigh, prev->texture[0].hwTextureClrHigh); + MMIO(REG_3D_TextureTransparencyColorLow, prev->texture[0].hwTextureClrLow); + */ + + if (smesa->GlobalFlag & GFLAG_TEXBORDERCOLOR) + MMIO(REG_6326_3D_TextureBorderColor, prev->texture[0].hwTextureBorderColor); + + if (smesa->GlobalFlag & GFLAG_TEXTUREADDRESS) { + switch ((prev->texture[0].hwTextureSet & MASK_6326_TextureLevel) >> 8) + { + case 9: + MMIO(REG_6326_3D_TextureAddress9, prev->texture[0].texOffset9); + /* FALLTHROUGH */ + case 8: + MMIO(REG_6326_3D_TextureAddress8, prev->texture[0].texOffset8); + MMIO(REG_6326_3D_TexturePitch89, prev->texture[0].texPitch89); + /* FALLTHROUGH */ + case 7: + MMIO(REG_6326_3D_TextureAddress7, prev->texture[0].texOffset7); + /* FALLTHROUGH */ + case 6: + MMIO(REG_6326_3D_TextureAddress6, prev->texture[0].texOffset6); + MMIO(REG_6326_3D_TexturePitch67, prev->texture[0].texPitch67); + /* FALLTHROUGH */ + case 5: + MMIO(REG_6326_3D_TextureAddress5, prev->texture[0].texOffset5); + /* FALLTHROUGH */ + case 4: + MMIO(REG_6326_3D_TextureAddress4, prev->texture[0].texOffset4); + MMIO(REG_6326_3D_TexturePitch45, prev->texture[0].texPitch45); + /* FALLTHROUGH */ + case 3: + MMIO(REG_6326_3D_TextureAddress3, prev->texture[0].texOffset3); + /* FALLTHROUGH */ + case 2: + MMIO(REG_6326_3D_TextureAddress2, prev->texture[0].texOffset2); + MMIO(REG_6326_3D_TexturePitch23, prev->texture[0].texPitch23); + /* FALLTHROUGH */ + case 1: + MMIO(REG_6326_3D_TextureAddress1, prev->texture[0].texOffset1); + /* FALLTHROUGH */ + case 0: + MMIO(REG_6326_3D_TextureAddress0, prev->texture[0].texOffset0); + MMIO(REG_6326_3D_TexturePitch01, prev->texture[0].texPitch01); + break; + } + } + + /* texture environment */ + if (smesa->GlobalFlag & GFLAG_TEXTUREENV) { + MMIO(REG_6326_3D_TextureBlendSet, prev->hwTexBlendSet); + } + + smesa->GlobalFlag &= ~GFLAG_TEXTURE_STATES; +} diff --git a/src/sis_context.h b/src/sis_context.h new file mode 100644 index 0000000..c349bf9 --- /dev/null +++ b/src/sis_context.h @@ -0,0 +1,477 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#ifndef _sis_ctx_h_ +#define _sis_ctx_h_ + +#include "context.h" +#include "dri_util.h" +#include "drm.h" +#include "drm_sarea.h" +#include "xmlconfig.h" +#include "tnl/t_vertex.h" + +#include "sis_screen.h" +#include "sis_reg.h" +#include "sis6326_reg.h" +#include "sis_dri.h" + +/* for GLboolean */ +#include <GL/gl.h> + +#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_WRITEMASK 0x0080 +#define SIS_FALLBACK_DISABLE 0x0100 + +/* 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_SIZE 2048 +#define SIS_MAX_TEXTURES 2 +#define SIS_MAX_TEXTURE_LEVELS 11 +#define SIS_MAX_FRAME_LENGTH 3 + +typedef struct { + GLubyte *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 + * MESA_YCBCR */ + 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 hwTexWidthHeight; /* 6326: Texture Blending Setting */ + 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 hwTexBlendSet; /* 6326 */ + GLint hwTexBlendColor0; + GLint hwTexBlendColor1; + 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 * ); + +/** + * Derived from gl_renderbuffer. + */ +struct sis_renderbuffer { + struct gl_renderbuffer Base; /* must be first! */ + drmSize size; + GLuint offset; + void *handle; + GLuint pitch; + GLuint bpp; + char *map; +}; + +/* Device dependent context state */ + +struct sis_context +{ + /* This must be first in this structure */ + GLcontext *glCtx; + + /* Vertex state */ + GLuint vertex_size; + struct tnl_attr_map vertex_attrs[VERT_ATTRIB_MAX]; + GLuint vertex_attr_count; + char *verts; /* points to tnl->clipspace.vertex_buf */ + + /* Vertex buffer (in system memory or AGP) state. */ + unsigned char *vb; /* Beginning of vertex buffer */ + unsigned char *vb_cur; /* Current write location in vertex buffer */ + unsigned char *vb_last; /* Last written location in vertex buffer */ + unsigned char *vb_end; /* End of vertex buffer */ + void *vb_agp_handle; + GLuint vb_agp_offset; + GLboolean using_agp; + GLint coloroffset; /* Offset in vertex format of current color */ + GLint specoffset; /* Offset in vertex format of specular color */ + + GLuint NewGLState; + GLuint Fallback; + GLuint RenderIndex; + GLfloat hw_viewport[16]; + GLfloat depth_scale; + + unsigned int virtualX, virtualY; + unsigned int bytesPerPixel; + unsigned char *IOBase; + unsigned char *FbBase; + unsigned int displayWidth; + + /* 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; + + /* register 0x89F4 */ + GLint AGPParseSet; + + /* register 0x89F8 */ + GLint dwPrimitiveSet; + + __GLSiSHardware prev, current; + + int Chipset; + GLboolean is6326; + + GLint drawableID; + + GLint GlobalFlag; + DECLARE_RENDERINPUTS(last_tcl_state_bitset); + + /* Stereo */ + 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 */ + /* XXX These don't belong here. They should be per-drawable state. */ + struct sis_renderbuffer front; + struct sis_renderbuffer back; + struct sis_renderbuffer depth; + struct sis_renderbuffer stencil; /* mirrors depth */ + + /* 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 */ + + drm_context_t hHWContext; + drm_hw_lock_t *driHwLock; + + sisScreenPtr sisScreen; /* Screen private DRI data */ + SISSAREAPrivPtr sarea; /* Private SAREA data */ + + /* Configuration cache */ + driOptionCache optionCache; + GLint texture_depth; +}; + +#define SIS_CONTEXT(ctx) ((sisContextPtr)(ctx->DriverCtx)) + +/* Macros */ +#define GET_IOBase(x) ((x)->IOBase) + +#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) \ +{\ + *(volatile GLint *)(smesa->IOBase + (reg)) = value; \ +} + +#define MMIO_READ(reg) *(volatile GLint *)(smesa->IOBase + (reg)) +#define MMIO_READf(reg) *(volatile GLfloat *)(smesa->IOBase + (reg)) + +#if defined(__i386__) || defined(__amd64__) +#define MMIO_WMB() __asm __volatile("" : : : "memory") +#else +#error platform needs WMB +#endif + +#define mEndPrimitive() \ +{ \ + *(volatile GLubyte *)(smesa->IOBase + REG_3D_EndPrimitiveList) = 0xff; \ + *(volatile GLuint *)(smesa->IOBase + 0x8b60) = 0xffffffff; \ +} + +#define sis_fatal_error(...) \ +do { \ + fprintf(stderr, "[%s:%d]:", __FILE__, __LINE__); \ + fprintf(stderr, __VA_ARGS__); \ + exit(-1); \ +} while (0) + +/* 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_CommandQueue) & 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 * ); + +void sisReAllocateBuffers(GLcontext *ctx, GLframebuffer *drawbuffer, + GLuint width, GLuint height); + +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 ); +extern void sis6326_update_texture_state( sisContextPtr smesa ); +extern void sis6326_update_render_state( sisContextPtr smesa ); + +/* ================================================================ + * Debugging: + */ +#define DO_DEBUG 1 + +#if DO_DEBUG +extern int SIS_DEBUG; +#else +#define SIS_DEBUG 0 +#endif + +#define DEBUG_FALLBACKS 0x01 + +#endif /* _sis_ctx_h_ */ diff --git a/src/sis_dd.c b/src/sis_dd.c new file mode 100644 index 0000000..8fc7896 --- /dev/null +++ b/src/sis_dd.c @@ -0,0 +1,269 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + * + */ + +#include "sis_context.h" +#include "sis_dd.h" +#include "sis_lock.h" +#include "sis_alloc.h" +#include "sis_span.h" +#include "sis_state.h" +#include "sis_tris.h" + +#include "swrast/swrast.h" +#include "framebuffer.h" +#include "renderbuffer.h" + +#include "utils.h" + +#define DRIVER_DATE "20060710" + +/* Return the width and height of the given buffer. + */ +static void +sisGetBufferSize( 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 * +sisGetString( 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. + */ +static void +sisFlush( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + SIS_FIREVERTICES(smesa); +} + +/* Make sure all commands have been sent to the hardware and have + * completed processing. + */ +static void +sisFinish( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + SIS_FIREVERTICES(smesa); + LOCK_HARDWARE(); + WaitEngIdle( smesa ); + UNLOCK_HARDWARE(); +} + +static void +sisDeleteRenderbuffer(struct gl_renderbuffer *rb) +{ + /* Don't free() since we're contained in sis_context struct. */ +} + +static GLboolean +sisRenderbufferStorage(GLcontext *ctx, struct gl_renderbuffer *rb, + GLenum internalFormat, GLuint width, GLuint height) +{ + rb->Width = width; + rb->Height = height; + rb->InternalFormat = internalFormat; + return GL_TRUE; +} + +static void +sisInitRenderbuffer(struct gl_renderbuffer *rb, GLenum format) +{ + const GLuint name = 0; + + _mesa_init_renderbuffer(rb, name); + + /* Make sure we're using a null-valued GetPointer routine */ + assert(rb->GetPointer(NULL, rb, 0, 0) == NULL); + + rb->InternalFormat = format; + + if (format == GL_RGBA) { + /* Color */ + rb->_BaseFormat = GL_RGBA; + rb->DataType = GL_UNSIGNED_BYTE; + } + else if (format == GL_DEPTH_COMPONENT16) { + /* Depth */ + rb->_BaseFormat = GL_DEPTH_COMPONENT; + /* we always Get/Put 32-bit Z values */ + rb->DataType = GL_UNSIGNED_INT; + } + else if (format == GL_DEPTH_COMPONENT24) { + /* Depth */ + rb->_BaseFormat = GL_DEPTH_COMPONENT; + /* we always Get/Put 32-bit Z values */ + rb->DataType = GL_UNSIGNED_INT; + } + else { + /* Stencil */ + ASSERT(format == GL_STENCIL_INDEX8_EXT); + rb->_BaseFormat = GL_STENCIL_INDEX; + rb->DataType = GL_UNSIGNED_BYTE; + } + + rb->Delete = sisDeleteRenderbuffer; + rb->AllocStorage = sisRenderbufferStorage; +} + +void +sisUpdateBufferSize(sisContextPtr smesa) +{ + __GLSiSHardware *current = &smesa->current; + __GLSiSHardware *prev = &smesa->prev; + struct gl_framebuffer *fb = smesa->glCtx->DrawBuffer; + + if (!smesa->front.Base.InternalFormat) { + /* do one-time init for the renderbuffers */ + sisInitRenderbuffer(&smesa->front.Base, GL_RGBA); + sisSetSpanFunctions(&smesa->front, &fb->Visual); + _mesa_add_renderbuffer(fb, BUFFER_FRONT_LEFT, &smesa->front.Base); + + if (fb->Visual.doubleBufferMode) { + sisInitRenderbuffer(&smesa->back.Base, GL_RGBA); + sisSetSpanFunctions(&smesa->back, &fb->Visual); + _mesa_add_renderbuffer(fb, BUFFER_BACK_LEFT, &smesa->back.Base); + } + + if (smesa->glCtx->Visual.depthBits > 0) { + sisInitRenderbuffer(&smesa->depth.Base, + (smesa->glCtx->Visual.depthBits == 16 + ? GL_DEPTH_COMPONENT16 : GL_DEPTH_COMPONENT24)); + sisSetSpanFunctions(&smesa->depth, &fb->Visual); + _mesa_add_renderbuffer(fb, BUFFER_DEPTH, &smesa->depth.Base); + } + + if (smesa->glCtx->Visual.stencilBits > 0) { + sisInitRenderbuffer(&smesa->stencil.Base, GL_STENCIL_INDEX8_EXT); + sisSetSpanFunctions(&smesa->stencil, &fb->Visual); + _mesa_add_renderbuffer(fb, BUFFER_STENCIL, &smesa->stencil.Base); + } + } + + /* Make sure initialization did what we think it should */ + assert(smesa->front.Base.InternalFormat); + assert(smesa->front.Base.AllocStorage); + if (fb->Visual.doubleBufferMode) { + assert(fb->Attachment[BUFFER_BACK_LEFT].Renderbuffer); + assert(smesa->front.Base.AllocStorage); + } + if (fb->Visual.depthBits) { + assert(fb->Attachment[BUFFER_DEPTH].Renderbuffer); + assert(smesa->depth.Base.AllocStorage); + } + + /* XXX Should get the base offset of the frontbuffer from the X Server */ + smesa->front.offset = smesa->driDrawable->x * smesa->bytesPerPixel + + smesa->driDrawable->y * smesa->front.pitch; + smesa->front.map = (char *) smesa->driScreen->pFB + smesa->front.offset; + + if ( smesa->width == smesa->driDrawable->w && + smesa->height == smesa->driDrawable->h ) + { + return; + } + + smesa->front.bpp = smesa->bytesPerPixel * 8; + /* Front pitch set on context create */ + smesa->front.size = smesa->front.pitch * smesa->driDrawable->h; + + smesa->width = smesa->driDrawable->w; + smesa->height = smesa->driDrawable->h; + smesa->bottom = smesa->height - 1; + + if (smesa->back.offset) + sisFreeBackbuffer( smesa ); + if (smesa->depth.offset) + sisFreeZStencilBuffer( smesa ); + + if ( smesa->glCtx->Visual.depthBits > 0 ) + sisAllocZStencilBuffer( smesa ); + if ( smesa->glCtx->Visual.doubleBufferMode ) + sisAllocBackbuffer( smesa ); + + current->hwZ &= ~MASK_ZBufferPitch; + current->hwZ |= smesa->depth.pitch >> 2; + current->hwOffsetZ = smesa->depth.offset >> 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 +sisInitDriverFuncs( struct dd_function_table *functions ) +{ + functions->GetBufferSize = sisGetBufferSize; + functions->GetString = sisGetString; + functions->Finish = sisFinish; + functions->Flush = sisFlush; +} diff --git a/src/sis_dd.h b/src/sis_dd.h new file mode 100644 index 0000000..da76596 --- /dev/null +++ b/src/sis_dd.h @@ -0,0 +1,39 @@ +/************************************************************************** + +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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#ifndef __SIS_DD_H__ +#define __SIS_DD_H__ + +extern void sisUpdateBufferSize( sisContextPtr smesa ); + +extern void sisInitDriverFuncs( struct dd_function_table *functions ); + +#endif diff --git a/src/sis_fog.c b/src/sis_fog.c new file mode 100644 index 0000000..fe9a3c9 --- /dev/null +++ b/src/sis_fog.c @@ -0,0 +1,207 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "swrast/swrast.h" + +#include "macros.h" + +static GLint convertFtToFogFt( GLfloat dwInValue ); +static GLint doFPtoFixedNoRound( GLfloat dwInValue, int nFraction ); + +void +sisDDFogfv( GLcontext *ctx, GLenum pname, const GLfloat *params ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + float fArg; + GLint fogColor; + + switch (pname) + { + case GL_FOG_COORDINATE_SOURCE_EXT: + current->hwFog &= ~MASK_FogMode; + switch (ctx->Fog.FogCoordinateSource) + { + case GL_FOG_COORDINATE_EXT: + current->hwFog &= ~MASK_FogZLookup; + break; + case GL_FRAGMENT_DEPTH_EXT: + current->hwFog |= MASK_FogZLookup; + break; + } + if (current->hwFog != prev->hwFog) { + prev->hwFog = current->hwFog; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + break; + case GL_FOG_MODE: + current->hwFog &= ~MASK_FogMode; + switch (ctx->Fog.Mode) + { + case GL_LINEAR: + current->hwFog |= FOGMODE_LINEAR; + break; + case GL_EXP: + current->hwFog |= FOGMODE_EXP; + break; + case GL_EXP2: + current->hwFog |= FOGMODE_EXP2; + break; + } + if (current->hwFog != prev->hwFog) { + prev->hwFog = current->hwFog; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + break; + case GL_FOG_DENSITY: + current->hwFogDensity = convertFtToFogFt( ctx->Fog.Density ); + if (current->hwFogDensity != prev->hwFogDensity) { + prev->hwFogDensity = current->hwFogDensity; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + 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 ); + } + if (current->hwFogFar != prev->hwFogFar || + current->hwFogInverse != prev->hwFogInverse) + { + prev->hwFogFar = current->hwFogFar; + prev->hwFogInverse = current->hwFogInverse; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + 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; + if (current->hwFog != prev->hwFog) { + prev->hwFog = current->hwFog; + smesa->GlobalFlag |= GFLAG_FOGSETTING; + } + break; + } +} + +static 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/sis_lock.c b/src/sis_lock.c new file mode 100644 index 0000000..70ca8e6 --- /dev/null +++ b/src/sis_lock.c @@ -0,0 +1,81 @@ +/* $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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#include "context.h" +#include "sis_context.h" +#include "sis_lock.h" +#include "sis_dd.h" +#include "sis_state.h" +#include "drirenderbuffer.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 ); + if (smesa->is6326) + sis6326DDDrawBuffer( smesa->glCtx, smesa->glCtx->Color.DrawBuffer[0] ); + else + sisDDDrawBuffer( smesa->glCtx, smesa->glCtx->Color.DrawBuffer[0] ); + driUpdateFramebufferSize(smesa->glCtx, dPriv); + smesa->lastStamp = dPriv->lastStamp; + } + + if ( sarea->CtxOwner != smesa->hHWContext ) { + sarea->CtxOwner = smesa->hHWContext; + smesa->GlobalFlag = GFLAG_ALL; + } +} diff --git a/src/sis_lock.h b/src/sis_lock.h new file mode 100644 index 0000000..fef9931 --- /dev/null +++ b/src/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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#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/sis_reg.h b/src/sis_reg.h new file mode 100644 index 0000000..78c6660 --- /dev/null +++ b/src/sis_reg.h @@ -0,0 +1,903 @@ +/************************************************************************** + +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 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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#ifndef _sis_reg_h_ +#define _sis_reg_h_ + +/* + * Define All the Register Address of 6327 + */ +#define REG_SRC_ADDR 0x8200 +#define REG_SRC_PITCH 0x8204 +# define BLIT_DEPTH_8 0x00000000 +# define BLIT_DEPTH_15 0x40000000 +# define BLIT_DEPTH_16 0x80000000 +# define BLIT_DEPTH_32 0xc0000000 +#define REG_SRC_X_Y 0x8208 +#define REG_DST_X_Y 0x820c +#define REG_DST_ADDR 0x8210 +#define REG_DST_PITCH_HEIGHT 0x8214 +#define REG_WIDTH_HEIGHT 0x8218 +#define REG_PATFG 0x821c +#define REG_PATBG 0x8220 +#define REG_SRCFG 0x8224 +#define REG_SRCBG 0x8228 +#define REG_MONOPAT0 0x822c +#define REG_MONOPAT1 0x8230 +#define REG_CLIPLT 0x8234 +#define REG_CLIPRB 0x8238 +#define REG_BLIT_CMD 0x823c +# define CMD_ROP_PAT 0x0000f000 +# define CMD_ROP_SRC 0x0000cc00 +# define CMD_DD_ENABLE 0x00000006 +# define CMD_SRC_VIDEO 0x00000000 +# define CMD_SRC_CPU 0x00000010 +# define CMD_DIR_X_DEC 0x00000000 +# define CMD_DIR_X_INC 0x00010000 +# define CMD_DIR_Y_DEC 0x00000000 +# define CMD_DIR_Y_INC 0x00020000 + +#define REG_CommandQueue 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_CommandQueue -- (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 +/* Because the original MASK_PsVertex_* names of these bits appared to be + * wrong, new names SiS_PS_* based off of the 4.3.0 driver and research are + * below. + */ +#define SiS_PS_HAS_XYZ MASK_PsVertex_HAS_RHW +#define SiS_PS_HAS_W MASK_PsVertex_HAS_NORMALXYZ +#define SiS_PS_HAS_DIFFUSE MASK_PsVertex_HAS_SPECULAR +#define SiS_PS_HAS_SPECULAR MASK_PsVertex_HAS_DIFFUSE +#define SiS_PS_HAS_UV0 MASK_PsVertex_HAS_UVSet2 +#define SiS_PS_HAS_UV1 MASK_PsVertex_HAS_UVSet3 +#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 (0x8A34 - 0x8A37) + */ +#define MASK_FogFarDistance 0x0007FFFF + +/* + * REG_3D_FogStartEnd -- Define Fog End Setting (0x8A38 - 0x8A3B) + */ +#define MASK_FogInvFarDistance 0x0007FFFF + +/* + * REG_3D_FogFactorDensity (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_INCR 0x00300000 /* guess -- was _WRAP */ +#define SiS_SFAIL_DECR 0x00400000 /* guess -- was _WRAP */ +#define SiS_SFAIL_INVERT 0x00500000 +#define SiS_SFAIL_INCR_WRAP 0x00600000 /* guess */ +#define SiS_SFAIL_DECR_WRAP 0x00700000 /* guess */ + +#define SiS_SPASS_ZFAIL_KEEP 0x00000000 +#define SiS_SPASS_ZFAIL_ZERO 0x00010000 +#define SiS_SPASS_ZFAIL_REPLACE 0x00020000 +#define SiS_SPASS_ZFAIL_INCR 0x00030000 /* guess -- was _WRAP */ +#define SiS_SPASS_ZFAIL_DECR 0x00040000 /* guess -- was _WRAP */ +#define SiS_SPASS_ZFAIL_INVERT 0x00050000 +#define SiS_SPASS_ZFAIL_INCR_WRAP 0x00060000 /* guess */ +#define SiS_SPASS_ZFAIL_DECR_WRAP 0x00070000 /* guess */ + +#define SiS_SPASS_ZPASS_KEEP 0x00000000 +#define SiS_SPASS_ZPASS_ZERO 0x00001000 +#define SiS_SPASS_ZPASS_REPLACE 0x00002000 +#define SiS_SPASS_ZPASS_INCR 0x00003000 /* guess -- was _WRAP */ +#define SiS_SPASS_ZPASS_DECR 0x00004000 /* guess -- was _WRAP */ +#define SiS_SPASS_ZPASS_INVERT 0x00005000 +#define SiS_SPASS_ZPASS_INCR_WRAP 0x00006000 /* guess */ +#define SiS_SPASS_ZPASS_DECR_WRAP 0x00007000 /* guess */ + +/* + * 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_ClipTopBottom (0x8A54 - 0x8A57) + */ +#define MASK_BottomClip 0x00001FFF +#define MASK_TopClip 0x03FFE000 + +/* + * REG_3D_ClipLeftRight (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 STAGE0_C_CF 0xa1485000 +#define STAGE0_C_CS 0xc1485000 +#define STAGE0_C_CFCS 0xa1705000 +#define STAGE0_C_CFOMAS_CSAS 0xc534c001 +#define STAGE0_C_CFOMCS_CCCS 0x4530c001 + +#define STAGE0_A_AF 0x63230000 +#define STAGE0_A_AS 0xc3230000 +#define STAGE0_A_AFAS 0x63c30000 +#define STAGE0_A_AFOMAS_ACAS 0x46c60001 + +#define STAGE1_C_CF 0xa1485000 +#define STAGE1_C_CS 0xe1485000 +#define STAGE1_C_CFCS 0xa1785000 +#define STAGE1_C_CFOMAS_CSAS 0xe5394001 +#define STAGE1_C_CFOMCS_CCCS 0x45394001 + +#define STAGE1_A_AF 0xa3230000 +#define STAGE1_A_AS 0xe3230000 +#define STAGE1_A_AFAS 0xa3e30000 +#define STAGE1_A_AFOMAS_ACAS 0x4aea0001 + +/* 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/sis_screen.c b/src/sis_screen.c new file mode 100644 index 0000000..89d734b --- /dev/null +++ b/src/sis_screen.c @@ -0,0 +1,382 @@ +/* $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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#include "dri_util.h" + +#include "context.h" +#include "utils.h" +#include "imports.h" +#include "framebuffer.h" +#include "renderbuffer.h" + +#include "sis_context.h" +#include "sis_dri.h" +#include "sis_lock.h" +#include "sis_span.h" + +#include "xmlpool.h" + +#include "GL/internal/dri_interface.h" + +#define SIS_AGP_DISABLE(def) \ +DRI_CONF_OPT_BEGIN(agp_disable,bool,def) \ + DRI_CONF_DESC(en,"Disable AGP vertex dispatch") \ +DRI_CONF_OPT_END + +PUBLIC const char __driConfigOptions[] = +DRI_CONF_BEGIN + DRI_CONF_SECTION_QUALITY + DRI_CONF_TEXTURE_DEPTH(DRI_CONF_TEXTURE_DEPTH_FB) + DRI_CONF_SECTION_END + DRI_CONF_SECTION_DEBUG + SIS_AGP_DISABLE(true) + DRI_CONF_NO_RAST(false) + DRI_CONF_SECTION_END +DRI_CONF_END; +static const GLuint __driNConfigOptions = 3; + +extern const struct dri_extension card_extensions[]; + +static __GLcontextModes * +sisFillInModes(int bpp) +{ + __GLcontextModes *modes; + __GLcontextModes *m; + unsigned num_modes; + unsigned depth_buffer_factor; + unsigned back_buffer_factor; + GLenum fb_format; + GLenum fb_type; + static const GLenum back_buffer_modes[] = { + GLX_NONE, GLX_SWAP_UNDEFINED_OML + }; + u_int8_t depth_bits_array[4]; + u_int8_t stencil_bits_array[4]; + + depth_bits_array[0] = 0; + stencil_bits_array[0] = 0; + depth_bits_array[1] = 16; + stencil_bits_array[1] = 0; + depth_bits_array[2] = 24; + stencil_bits_array[2] = 8; + depth_bits_array[3] = 32; + stencil_bits_array[3] = 0; + + depth_buffer_factor = 4; + back_buffer_factor = 2; + + /* Last 4 is for GLX_TRUE_COLOR & GLX_DIRECT_COLOR, with/without accum */ + num_modes = depth_buffer_factor * back_buffer_factor * 4; + + if (bpp == 16) { + fb_format = GL_RGB; + fb_type = GL_UNSIGNED_SHORT_5_6_5; + } else { + fb_format = GL_BGRA; + fb_type = GL_UNSIGNED_INT_8_8_8_8_REV; + } + + modes = (*dri_interface->createContextModes)(num_modes, sizeof(__GLcontextModes)); + m = modes; + if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, + stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + GLX_TRUE_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); + return NULL; + } + + if (!driFillInModes(&m, fb_format, fb_type, depth_bits_array, + stencil_bits_array, depth_buffer_factor, + back_buffer_modes, back_buffer_factor, + GLX_DIRECT_COLOR)) { + fprintf(stderr, "[%s:%u] Error creating FBConfig!\n", __func__, __LINE__); + return NULL; + } + + return modes; +} + + +/* Create the device specific screen private data struct. + */ +static sisScreenPtr +sisCreateScreen( __DRIscreenPrivate *sPriv ) +{ + sisScreenPtr sisScreen; + SISDRIPtr sisDRIPriv = (SISDRIPtr)sPriv->pDevPriv; + + if (sPriv->devPrivSize != sizeof(SISDRIRec)) { + fprintf(stderr,"\nERROR! sizeof(SISDRIRec) does not match passed size from device driver\n"); + return GL_FALSE; + } + + /* 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->deviceID = sisDRIPriv->deviceID; + sisScreen->AGPCmdBufOffset = sisDRIPriv->AGPCmdBufOffset; + sisScreen->AGPCmdBufSize = sisDRIPriv->AGPCmdBufSize; + sisScreen->sarea_priv_offset = sizeof(drm_sarea_t); + + 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->agpBaseOffset = drmAgpBase(sPriv->fd); + 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; + + /* parse information in __driConfigOptions */ + driParseOptionInfo(&sisScreen->optionCache, + __driConfigOptions, __driNConfigOptions); + + 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 ) +{ + /*sisScreenPtr screen = (sisScreenPtr) driScrnPriv->private;*/ + struct gl_framebuffer *fb; + + if (isPixmap) + return GL_FALSE; /* not implemented */ + + fb = _mesa_create_framebuffer(mesaVis); + + _mesa_add_soft_renderbuffers(fb, + GL_FALSE, /* color */ + GL_FALSE, /* depth */ + mesaVis->stencilBits > 0, + mesaVis->accumRedBits > 0, + GL_FALSE, /* alpha */ + GL_FALSE /* aux */); + driDrawPriv->driverPrivate = (void *) fb; + + return (driDrawPriv->driverPrivate != NULL); +} + + +static void +sisDestroyBuffer(__DRIdrawablePrivate *driDrawPriv) +{ + _mesa_unreference_framebuffer((GLframebuffer **)(&(driDrawPriv->driverPrivate))); +} + +static void sisCopyBuffer( __DRIdrawablePrivate *dPriv ) +{ + sisContextPtr smesa = (sisContextPtr)dPriv->driContextPriv->driverPrivate; + int i; + + while ((*smesa->FrameCountPtr) - MMIO_READ(0x8a2c) > SIS_MAX_FRAME_LENGTH) + ; + + LOCK_HARDWARE(); + + for (i = 0; i < dPriv->numClipRects; i++) { + drm_clip_rect_t *box = &dPriv->pClipRects[i]; + + mWait3DCmdQueue(10); + MMIO(REG_SRC_ADDR, smesa->back.offset); + MMIO(REG_SRC_PITCH, smesa->back.pitch | ((smesa->bytesPerPixel == 4) ? + BLIT_DEPTH_32 : BLIT_DEPTH_16)); + MMIO(REG_SRC_X_Y, ((box->x1 - dPriv->x) << 16) | (box->y1 - dPriv->y)); + MMIO(REG_DST_X_Y, ((box->x1 - dPriv->x) << 16) | (box->y1 - dPriv->y)); + MMIO(REG_DST_ADDR, smesa->front.offset); + MMIO(REG_DST_PITCH_HEIGHT, (smesa->virtualY << 16) | smesa->front.pitch); + MMIO(REG_WIDTH_HEIGHT, ((box->y2 - box->y1) << 16) | (box->x2 - box->x1)); + MMIO(REG_BLIT_CMD, CMD_DIR_X_INC | CMD_DIR_Y_INC | CMD_ROP_SRC); + MMIO(REG_CommandQueue, -1); + } + + *(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; +} + +static struct __DriverAPIRec sisAPI = { + .InitDriver = sisInitDriver, + .DestroyScreen = sisDestroyScreen, + .CreateContext = sisCreateContext, + .DestroyContext = sisDestroyContext, + .CreateBuffer = sisCreateBuffer, + .DestroyBuffer = sisDestroyBuffer, + .SwapBuffers = sisSwapBuffers, + .MakeCurrent = sisMakeCurrent, + .UnbindContext = sisUnbindContext, + .GetSwapInfo = NULL, + .GetMSC = NULL, + .WaitForMSC = NULL, + .WaitForSBC = NULL, + .SwapBuffersMSC = NULL + +}; + + +/** + * This is the bootstrap function for the driver. libGL supplies all of the + * requisite information about the system, and the driver initializes itself. + * This routine also fills in the linked list pointed to by \c driver_modes + * with the \c __GLcontextModes that the driver can support for windows or + * pbuffers. + * + * \return A pointer to a \c __DRIscreenPrivate on success, or \c NULL on + * failure. + */ +PUBLIC +void * __driCreateNewScreen_20050727( __DRInativeDisplay *dpy, int scrn, + __DRIscreen *psc, + const __GLcontextModes *modes, + const __DRIversion *ddx_version, + const __DRIversion *dri_version, + const __DRIversion *drm_version, + const __DRIframebuffer *frame_buffer, + drmAddress pSAREA, int fd, + int internal_api_version, + const __DRIinterfaceMethods * interface, + __GLcontextModes **driver_modes ) + +{ + __DRIscreenPrivate *psp; + static const __DRIversion ddx_expected = {0, 8, 0}; + static const __DRIversion dri_expected = {4, 0, 0}; + static const __DRIversion drm_expected = {1, 0, 0}; + static const char *driver_name = "SiS"; + dri_interface = interface; + + if (!driCheckDriDdxDrmVersions2(driver_name, dri_version, &dri_expected, + ddx_version, &ddx_expected, + drm_version, &drm_expected)) { + return NULL; + } + + psp = __driUtilCreateNewScreen(dpy, scrn, psc, NULL, + ddx_version, dri_version, drm_version, + frame_buffer, pSAREA, fd, + internal_api_version, &sisAPI); + if (psp != NULL) { + SISDRIPtr dri_priv = (SISDRIPtr)psp->pDevPriv; + *driver_modes = sisFillInModes(dri_priv->bytesPerPixel * 8); + + /* Calling driInitExtensions here, with a NULL context pointer, does not actually + * enable the extensions. It just makes sure that all the dispatch offsets for all + * the extensions that *might* be enables are known. This is needed because the + * dispatch offsets need to be known when _mesa_context_create is called, but we can't + * enable the extensions until we have a context pointer. + * + * Hello chicken. Hello egg. How are you two today? + */ + driInitExtensions( NULL, card_extensions, GL_FALSE ); + } + + return (void *)psp; +} diff --git a/src/sis_screen.h b/src/sis_screen.h new file mode 100644 index 0000000..d5b2101 --- /dev/null +++ b/src/sis_screen.h @@ -0,0 +1,62 @@ +/************************************************************************** + +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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#ifndef __SIS_SCREEN_H +#define __SIS_SCREEN_H + +typedef struct { + drm_handle_t 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 long agpBaseOffset; + + unsigned int AGPCmdBufOffset; + unsigned int AGPCmdBufSize; + + int deviceID; + + int cpp; + unsigned int screenX, screenY; + + __DRIscreenPrivate *driScreen; + unsigned int sarea_priv_offset; + + /* Configuration cache with default values for all contexts */ + driOptionCache optionCache; + +} sisScreenRec, *sisScreenPtr; + +#endif diff --git a/src/sis_span.c b/src/sis_span.c new file mode 100644 index 0000000..ea6db67 --- /dev/null +++ b/src/sis_span.c @@ -0,0 +1,194 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "sis_context.h" +#include "sis_span.h" +#include "sis_lock.h" +#include "sis_tris.h" + +#include "swrast/swrast.h" + +#define DBG 0 + +#define LOCAL_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + __DRIdrawablePrivate *dPriv = smesa->driDrawable; \ + struct sis_renderbuffer *srb = (struct sis_renderbuffer *) rb; \ + GLuint pitch = srb->pitch; \ + char *buf = srb->map; \ + GLuint p; \ + (void) buf; (void) p; + + +#define LOCAL_DEPTH_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + __DRIdrawablePrivate *dPriv = smesa->driDrawable; \ + struct sis_renderbuffer *srb = (struct sis_renderbuffer *) rb; \ + char *buf = srb->map; + +#define LOCAL_STENCIL_VARS LOCAL_DEPTH_VARS + +#define HW_LOCK() do {} while(0); + +#define HW_UNLOCK() do {} while(0); + +/* RGB565 */ +#define SPANTMP_PIXEL_FMT GL_RGB +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_SHORT_5_6_5 + +#define TAG(x) sis##x##_RGB565 +#define TAG2(x,y) sis##x##_RGB565##y +#include "spantmp2.h" + + +/* ARGB8888 */ +/* FIXME the old code always read back alpha as 0xff, i.e. fully opaque. + Was there a reason to do so ? If so that'll won't work with that template... */ +#define SPANTMP_PIXEL_FMT GL_BGRA +#define SPANTMP_PIXEL_TYPE GL_UNSIGNED_INT_8_8_8_8_REV + +#define TAG(x) sis##x##_ARGB8888 +#define TAG2(x,y) sis##x##_ARGB8888##y +#include "spantmp2.h" + + +/* 16 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLushort *)(buf + (_x)*2 + (_y)*srb->pitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLushort *)(buf + (_x)*2 + (_y)*srb->pitch); + +#define TAG(x) sis##x##_z16 +#include "depthtmp.h" + + +/* 32 bit depthbuffer functions. + */ +#define WRITE_DEPTH( _x, _y, d ) \ + *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) = d; + +#define READ_DEPTH( d, _x, _y ) \ + d = *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch); + +#define TAG(x) sis##x##_z32 +#include "depthtmp.h" + + +/* 8/24 bit interleaved depth/stencil functions + */ +#define WRITE_DEPTH( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch); \ + tmp &= 0xff000000; \ + tmp |= (d & 0x00ffffff); \ + *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) = tmp; \ +} + +#define READ_DEPTH( d, _x, _y ) { \ + d = *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) & 0x00ffffff; \ +} + +#define TAG(x) sis##x##_z24_s8 +#include "depthtmp.h" + +#define WRITE_STENCIL( _x, _y, d ) { \ + GLuint tmp = *(GLuint *)(buf + (_x)*4 + (_y)*smesa->depth.pitch); \ + tmp &= 0x00ffffff; \ + tmp |= (d << 24); \ + *(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) = tmp; \ +} + +#define READ_STENCIL( d, _x, _y ) \ + d = (*(GLuint *)(buf + (_x)*4 + (_y)*srb->pitch) & 0xff000000) >> 24; + +#define TAG(x) sis##x##_z24_s8 +#include "stenciltmp.h" + + + +void sisSpanRenderStart( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + SIS_FIREVERTICES(smesa); + LOCK_HARDWARE(); + WaitEngIdle( smesa ); +} + +void sisSpanRenderFinish( GLcontext *ctx ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + _swrast_flush( ctx ); + UNLOCK_HARDWARE(); +} + +void +sisDDInitSpanFuncs( GLcontext *ctx ) +{ + struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx); + swdd->SpanRenderStart = sisSpanRenderStart; + swdd->SpanRenderFinish = sisSpanRenderFinish; +} + + + +/** + * Plug in the Get/Put routines for the given driRenderbuffer. + */ +void +sisSetSpanFunctions(struct sis_renderbuffer *srb, const GLvisual *vis) +{ + if (srb->Base.InternalFormat == GL_RGBA) { + if (vis->redBits == 5 && vis->greenBits == 6 && vis->blueBits == 5) { + sisInitPointers_RGB565( &srb->Base ); + } + else { + sisInitPointers_ARGB8888( &srb->Base ); + } + } + else if (srb->Base.InternalFormat == GL_DEPTH_COMPONENT16) { + sisInitDepthPointers_z16(&srb->Base); + } + else if (srb->Base.InternalFormat == GL_DEPTH_COMPONENT24) { + sisInitDepthPointers_z24_s8(&srb->Base); + } + else if (srb->Base.InternalFormat == GL_DEPTH_COMPONENT32) { + sisInitDepthPointers_z32(&srb->Base); + } + else if (srb->Base.InternalFormat == GL_STENCIL_INDEX8_EXT) { + sisInitStencilPointers_z24_s8(&srb->Base); + } +} diff --git a/src/sis_span.h b/src/sis_span.h new file mode 100644 index 0000000..4b0add2 --- /dev/null +++ b/src/sis_span.h @@ -0,0 +1,46 @@ +/************************************************************************** + +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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#ifndef __SIS_SPAN_H__ +#define __SIS_SPAN_H__ + +#include "drirenderbuffer.h" + + +extern void sisSpanRenderStart( GLcontext *ctx ); +extern void sisSpanRenderFinish( GLcontext *ctx ); + +extern void sisDDInitSpanFuncs( GLcontext *ctx ); + +extern void +sisSetSpanFunctions(struct sis_renderbuffer *srb, const GLvisual *vis); + +#endif diff --git a/src/sis_state.c b/src/sis_state.c new file mode 100644 index 0000000..33a2f08 --- /dev/null +++ b/src/sis_state.c @@ -0,0 +1,866 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#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 "vbo/vbo.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 +sisDDBlendFuncSeparate( GLcontext *ctx, + GLenum sfactorRGB, GLenum dfactorRGB, + GLenum sfactorA, GLenum dfactorA ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + current->hwDstSrcBlend = 0; + + switch (dfactorRGB) + { + 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_COLOR: + current->hwDstSrcBlend |= SiS_D_DST_COLOR; + break; + case GL_ONE_MINUS_DST_COLOR: + current->hwDstSrcBlend |= SiS_D_ONE_MINUS_DST_COLOR; + 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; + default: + fprintf(stderr, "Unknown dst blend function 0x%x\n", dfactorRGB); + break; + } + + switch (sfactorRGB) + { + case GL_ZERO: + current->hwDstSrcBlend |= SiS_S_ZERO; + break; + case GL_ONE: + current->hwDstSrcBlend |= SiS_S_ONE; + break; + case GL_SRC_COLOR: + current->hwDstSrcBlend |= SiS_S_SRC_COLOR; + break; + case GL_ONE_MINUS_SRC_COLOR: + current->hwDstSrcBlend |= SiS_S_ONE_MINUS_SRC_COLOR; + 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_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_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_SRC_ALPHA_SATURATE: + current->hwDstSrcBlend |= SiS_S_SRC_ALPHA_SATURATE; + break; + default: + fprintf(stderr, "Unknown src blend function 0x%x\n", sfactorRGB); + 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) == 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; + + if (smesa->is6326) { + /* XXX: 6326 has its own clipping for now. Should be fixed */ + sis6326UpdateClipping(ctx); + return; + } + + 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) ? smesa->redMask : 0 | + (g) ? smesa->greenMask : 0 | + (b) ? smesa->blueMask : 0 | + (a) ? smesa->alphaMask : 0; + } + + if (current->hwDstMask != prev->hwDstMask) { + prev->hwDstMask = current->hwDstMask; + smesa->GlobalFlag |= GFLAG_DESTSETTING; + } +} + +/* ============================================================= + * Rendering attributes + */ + +static void sisUpdateSpecular(GLcontext *ctx) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + __GLSiSHardware *current = &smesa->current; + + if (NEED_SECONDARY_COLOR(ctx)) + current->hwCapEnable |= MASK_SpecularEnable; + else + current->hwCapEnable &= ~MASK_SpecularEnable; +} + +static void sisDDLightModelfv(GLcontext *ctx, GLenum pname, + const GLfloat *param) +{ + if (pname == GL_LIGHT_MODEL_COLOR_CONTROL) { + sisUpdateSpecular(ctx); + } +} + +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; + + 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 <mode>. + */ + current->hwDstSet &= ~MASK_DstBufferPitch; + switch ( ctx->DrawBuffer->_ColorDrawBufferMask[0] ) { + case BUFFER_BIT_FRONT_LEFT: + FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE ); + current->hwOffsetDest = smesa->front.offset >> 1; + current->hwDstSet |= smesa->front.pitch >> 2; + break; + case BUFFER_BIT_BACK_LEFT: + FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_FALSE ); + current->hwOffsetDest = smesa->back.offset >> 1; + current->hwDstSet |= smesa->back.pitch >> 2; + break; + default: + /* GL_NONE or GL_FRONT_AND_BACK or stereo left&right, etc */ + FALLBACK( smesa, SIS_FALLBACK_DRAW_BUFFER, GL_TRUE ); + return; + } + + 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; + } +} + +/* ============================================================= + * 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->depth.offset != 0) + 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; + case GL_LIGHTING: + case GL_COLOR_SUM_EXT: + sisUpdateSpecular(ctx); + break; + } +} + + +/* ============================================================= + * 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; + + /* 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; + } + + 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 ); + _vbo_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; + + /* + 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 setting -- use fragment color/alpha*/ + prev->hwTexBlendColor0 = STAGE0_C_CF; + prev->hwTexBlendColor1 = STAGE1_C_CF; + prev->hwTexBlendAlpha0 = STAGE0_A_AF; + prev->hwTexBlendAlpha1 = STAGE1_A_AF; + + 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 | MASK_PsBumpTextureFromC; + 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_COORDINATE_SOURCE_EXT, NULL ); + 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.BlendFuncSeparate = sisDDBlendFuncSeparate; + 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.Enable = sisDDEnable; + ctx->Driver.FrontFace = sisDDFrontFace; + ctx->Driver.Fogfv = sisDDFogfv; + ctx->Driver.Hint = NULL; + ctx->Driver.Lightfv = NULL; + ctx->Driver.LogicOpcode = sisDDLogicOpCode; + ctx->Driver.PolygonMode = NULL; + ctx->Driver.PolygonStipple = NULL; + ctx->Driver.ReadBuffer = NULL; + ctx->Driver.RenderMode = NULL; + ctx->Driver.Scissor = sisDDScissor; + ctx->Driver.ShadeModel = sisDDShadeModel; + ctx->Driver.LightModelfv = sisDDLightModelfv; + ctx->Driver.Viewport = sisDDViewport; + + /* XXX this should go away */ + ctx->Driver.ResizeBuffers = sisReAllocateBuffers; +} diff --git a/src/sis_state.h b/src/sis_state.h new file mode 100644 index 0000000..8f7e2ac --- /dev/null +++ b/src/sis_state.h @@ -0,0 +1,69 @@ +/************************************************************************** + +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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#ifndef __SIS_STATE_H__ +#define __SIS_STATE_H__ + +#include "sis_context.h" + +/* sis6326_clear.c */ +extern void sis6326DDClear( GLcontext *ctx, GLbitfield mask ); +extern void sis6326DDClearColor( GLcontext * ctx, const GLfloat color[4] ); +extern void sis6326DDClearDepth( GLcontext * ctx, GLclampd d ); +extern void sis6326UpdateZPattern(sisContextPtr smesa, GLclampd z); + +/* sis_clear.c */ +extern void sisDDClear( GLcontext *ctx, GLbitfield mask ); +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 sisUpdateZStencilPattern( sisContextPtr smesa, GLclampd z, + int stencil ); + +/* sis_fog.c */ +extern void sisDDFogfv( GLcontext * ctx, GLenum pname, const GLfloat * params ); + +/* sis6326_state.c */ +extern void sis6326DDInitState( sisContextPtr smesa ); +extern void sis6326DDInitStateFuncs( GLcontext *ctx ); +extern void sis6326UpdateClipping( GLcontext * gc ); +extern void sis6326DDDrawBuffer( GLcontext *ctx, GLenum mode ); +extern void sis6326UpdateHWState( GLcontext *ctx ); + +/* sis_state.c */ +extern void sisDDInitState( sisContextPtr smesa ); +extern void sisDDInitStateFuncs( GLcontext *ctx ); +extern void sisDDDepthMask( GLcontext * ctx, GLboolean flag ); +extern void sisUpdateClipping( GLcontext * gc ); +extern void sisDDDrawBuffer( GLcontext *ctx, GLenum mode ); +extern void sisUpdateHWState( GLcontext *ctx ); + +#endif diff --git a/src/sis_stencil.c b/src/sis_stencil.c new file mode 100644 index 0000000..a1ce296 --- /dev/null +++ b/src/sis_stencil.c @@ -0,0 +1,206 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "sis_context.h" +#include "sis_state.h" +#include "sis_stencil.h" + +static void +sisDDStencilFuncSeparate( GLcontext * ctx, GLenum face, + 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] & 0xff) << 8) | + (ctx->Stencil.ValueMask[0] & 0xff)); + + 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 +sisDDStencilMaskSeparate( GLcontext * ctx, GLenum face, GLuint mask ) +{ + if (!ctx->Visual.stencilBits) + return; + + /* set Z buffer Write Enable */ + sisDDDepthMask (ctx, ctx->Depth.Mask); +} + +static void +sisDDStencilOpSeparate( GLcontext * ctx, GLenum face, 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; + case GL_INCR_WRAP: + current->hwStSetting2 |= SiS_SFAIL_INCR_WRAP; + break; + case GL_DECR_WRAP: + current->hwStSetting2 |= SiS_SFAIL_DECR_WRAP; + 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; + case GL_INCR_WRAP: + current->hwStSetting2 |= SiS_SPASS_ZFAIL_INCR_WRAP; + break; + case GL_DECR_WRAP: + current->hwStSetting2 |= SiS_SPASS_ZFAIL_DECR_WRAP; + 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; + case GL_INCR_WRAP: + current->hwStSetting2 |= SiS_SPASS_ZPASS_INCR_WRAP; + break; + case GL_DECR_WRAP: + current->hwStSetting2 |= SiS_SPASS_ZPASS_DECR_WRAP; + break; + } + + if (current->hwStSetting2 != prev->hwStSetting2) + { + prev->hwStSetting2 = current->hwStSetting2; + smesa->GlobalFlag |= GFLAG_STENCILSETTING; + } +} + +void +sisDDInitStencilFuncs( GLcontext *ctx ) +{ + ctx->Driver.StencilFuncSeparate = sisDDStencilFuncSeparate; + ctx->Driver.StencilMaskSeparate = sisDDStencilMaskSeparate; + ctx->Driver.StencilOpSeparate = sisDDStencilOpSeparate; +} diff --git a/src/sis_stencil.h b/src/sis_stencil.h new file mode 100644 index 0000000..4a36c98 --- /dev/null +++ b/src/sis_stencil.h @@ -0,0 +1,37 @@ +/************************************************************************** + +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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#ifndef __SIS_STENCIL_H__ +#define __SIS_STENCIL_H__ + +extern void sisDDInitStencilFuncs( GLcontext *ctx ); + +#endif diff --git a/src/sis_tex.c b/src/sis_tex.c new file mode 100644 index 0000000..8fd7b26 --- /dev/null +++ b/src/sis_tex.c @@ -0,0 +1,573 @@ +/************************************************************************** + +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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#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" +#include "texobj.h" + +#include "xmlpool.h" + +#define ALIGN(value, align) (GLubyte *)((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->_BaseFormat; + switch (image->TexFormat->MesaFormat) + { + case MESA_FORMAT_ARGB8888: + t->hwformat = TEXEL_ARGB_8888_32; + break; + case MESA_FORMAT_ARGB4444: + t->hwformat = TEXEL_ARGB_4444_16; + break; + case MESA_FORMAT_ARGB1555: + t->hwformat = TEXEL_ARGB_1555_16; + break; + case MESA_FORMAT_RGB565: + t->hwformat = TEXEL_RGB_565_16; + break; + case MESA_FORMAT_RGB332: + t->hwformat = TEXEL_RGB_332_8; + break; + case MESA_FORMAT_I8: + t->hwformat = TEXEL_I8; + break; + case MESA_FORMAT_A8: + t->hwformat = TEXEL_A8; + break; + case MESA_FORMAT_L8: + t->hwformat = TEXEL_L8; + break; + case MESA_FORMAT_AL88: + t->hwformat = TEXEL_AL88; + break; + case MESA_FORMAT_YCBCR: + t->hwformat = TEXEL_YUV422; + break; + case MESA_FORMAT_YCBCR_REV: + t->hwformat = TEXEL_VUY422; + break; + default: + sis_fatal_error("Bad texture format 0x%x.\n", + image->TexFormat->MesaFormat); + } + } + assert(t->format == image->_BaseFormat); + + 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) + sis_fatal_error("Failure to allocate texture memory.\n"); + 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 ) +{ + assert(level >= 0); + assert(level < SIS_MAX_TEXTURE_LEVELS); + 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 +sisTexEnv( GLcontext *ctx, GLenum target, GLenum pname, const GLfloat *param ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + smesa->TexStates[ctx->Texture.CurrentUnit] |= NEW_TEXTURE_ENV; +} + +static void +sisTexParameter( 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 +sisBindTexture( 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) + 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 +sisDeleteTexture( 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 sisTexImage* + */ + return; + } + for (i = 0; i < SIS_MAX_TEXTURE_LEVELS; i++) { + sisFreeTexImage( smesa, t, i ); + } + + FREE(t); + texObj->DriverData = NULL; + /* Free mipmap images and the texture object itself */ + _mesa_delete_texture_object(ctx, texObj); +} + +static GLboolean sisIsTextureResident( GLcontext * ctx, + struct gl_texture_object *texObj ) +{ + return (texObj->DriverData != NULL); +} + +static const struct gl_texture_format * +sisChooseTextureFormat( GLcontext *ctx, GLint internalFormat, + GLenum format, GLenum type ) +{ + sisContextPtr smesa = SIS_CONTEXT(ctx); + + const GLboolean do32bpt = + (smesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_32); + const GLboolean force16bpt = + (smesa->texture_depth == DRI_CONF_TEXTURE_DEPTH_FORCE_16); + + switch ( internalFormat ) { + case 4: + case GL_RGBA: + case GL_COMPRESSED_RGBA: + switch ( type ) { + case GL_UNSIGNED_INT_10_10_10_2: + case GL_UNSIGNED_INT_2_10_10_10_REV: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555; + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return &_mesa_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return &_mesa_texformat_argb1555; + default: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + } + + case 3: + case GL_RGB: + case GL_COMPRESSED_RGB: + switch ( type ) { + case GL_UNSIGNED_SHORT_4_4_4_4: + case GL_UNSIGNED_SHORT_4_4_4_4_REV: + return &_mesa_texformat_argb4444; + case GL_UNSIGNED_SHORT_5_5_5_1: + case GL_UNSIGNED_SHORT_1_5_5_5_REV: + return &_mesa_texformat_argb1555; + case GL_UNSIGNED_SHORT_5_6_5: + case GL_UNSIGNED_SHORT_5_6_5_REV: + return &_mesa_texformat_rgb565; + default: + return do32bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + } + + case GL_RGBA8: + case GL_RGBA12: + case GL_RGBA16: + return !force16bpt ? + &_mesa_texformat_argb8888 : &_mesa_texformat_argb4444; + + case GL_RGB10_A2: + return !force16bpt ? + &_mesa_texformat_argb8888 : &_mesa_texformat_argb1555; + + case GL_RGBA4: + case GL_RGBA2: + return &_mesa_texformat_argb4444; + + case GL_RGB5_A1: + return &_mesa_texformat_argb1555; + + case GL_RGB8: + case GL_RGB10: + case GL_RGB12: + case GL_RGB16: + return !force16bpt ? &_mesa_texformat_argb8888 : &_mesa_texformat_rgb565; + + case GL_RGB5: + case GL_RGB4: + return &_mesa_texformat_rgb565; + + case GL_R3_G3_B2: + return &_mesa_texformat_rgb332; + + case GL_ALPHA: + case GL_ALPHA4: /* FIXME: This could use its own texstore */ + case GL_ALPHA8: + case GL_ALPHA12: + case GL_ALPHA16: + case GL_COMPRESSED_ALPHA: + return &_mesa_texformat_a8; + + case 1: + case GL_LUMINANCE: + case GL_LUMINANCE4: /* FIXME: This could use its own texstore */ + case GL_LUMINANCE8: + case GL_LUMINANCE12: + case GL_LUMINANCE16: + case GL_COMPRESSED_LUMINANCE: + return &_mesa_texformat_l8; + + case 2: + case GL_LUMINANCE_ALPHA: + case GL_LUMINANCE4_ALPHA4: /* FIXME: This could use its own texstore */ + case GL_LUMINANCE6_ALPHA2: /* FIXME: This could use its own texstore */ + case GL_LUMINANCE8_ALPHA8: + case GL_LUMINANCE12_ALPHA4: /* FIXME: This could use its own texstore */ + case GL_LUMINANCE12_ALPHA12: + case GL_LUMINANCE16_ALPHA16: + case GL_COMPRESSED_LUMINANCE_ALPHA: + return &_mesa_texformat_al88; + + case GL_INTENSITY: + case GL_INTENSITY4: + case GL_INTENSITY8: + case GL_INTENSITY12: + case GL_INTENSITY16: + case GL_COMPRESSED_INTENSITY: + return &_mesa_texformat_i8; + + case GL_YCBCR_MESA: + if (type == GL_UNSIGNED_SHORT_8_8_APPLE || + type == GL_UNSIGNED_BYTE) + return &_mesa_texformat_ycbcr; + else + return &_mesa_texformat_ycbcr_rev; + + default: + _mesa_problem(ctx, "unexpected format in sisDDChooseTextureFormat: %d", + internalFormat); + return NULL; + } +} + +static void sisTexImage1D( 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 sisChooseTextureFormat */ + _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 */ + WaitEngIdle(smesa); + 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 sisTexSubImage1D( 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; + const char *src; + GLubyte *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 */ + WaitEngIdle(smesa); + 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 sisTexImage2D( 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 sisChooseTextureFormat */ + _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 */ + WaitEngIdle(smesa); + 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 sisTexSubImage2D( 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; + const char *src; + GLubyte *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 */ + WaitEngIdle(smesa); + 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; +} + + +/** + * Allocate a new texture object. + * Called via ctx->Driver.NewTextureObject. + * Note: this function will be called during context creation to + * allocate the default texture objects. + * Note: we could use containment here to 'derive' the driver-specific + * texture object from the core mesa gl_texture_object. Not done at this time. + */ +static struct gl_texture_object * +sisNewTextureObject( GLcontext *ctx, GLuint name, GLenum target ) +{ + struct gl_texture_object *obj; + obj = _mesa_new_texture_object(ctx, name, target); + return obj; +} + + +void sisInitTextureFuncs( struct dd_function_table *functions ) +{ + functions->TexEnv = sisTexEnv; + functions->ChooseTextureFormat = sisChooseTextureFormat; + functions->TexImage1D = sisTexImage1D; + functions->TexSubImage1D = sisTexSubImage1D; + functions->TexImage2D = sisTexImage2D; + functions->TexSubImage2D = sisTexSubImage2D; + functions->TexParameter = sisTexParameter; + functions->BindTexture = sisBindTexture; + functions->NewTextureObject = sisNewTextureObject; + functions->DeleteTexture = sisDeleteTexture; + functions->IsTextureResident = sisIsTextureResident; +} diff --git a/src/sis_tex.h b/src/sis_tex.h new file mode 100644 index 0000000..8ddc7c4 --- /dev/null +++ b/src/sis_tex.h @@ -0,0 +1,38 @@ +/************************************************************************** + +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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#ifndef __SIS_TEX_H__ +#define __SIS_TEX_H__ + +extern void sisInitTextureFuncs( struct dd_function_table *table ); +extern void sisUpdateTextureState( GLcontext *ctx ); + +#endif /* __SIS_TEX_H__ */ diff --git a/src/sis_texstate.c b/src/sis_texstate.c new file mode 100644 index 0000000..7ef20f8 --- /dev/null +++ b/src/sis_texstate.c @@ -0,0 +1,710 @@ +/************************************************************************** + +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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "glheader.h" +#include "imports.h" +#include "colormac.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); + GLubyte c[4]; + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit]; + + sisTexObjPtr t = texObj->DriverData; + + switch (texture_unit->EnvMode) + { + case GL_REPLACE: + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendColor0 = STAGE0_C_CF; + current->hwTexBlendAlpha0 = STAGE0_A_AS; + break; + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + current->hwTexBlendColor0 = STAGE0_C_CS; + current->hwTexBlendAlpha0 = STAGE0_A_AF; + break; + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendColor0 = STAGE0_C_CS; + current->hwTexBlendAlpha0 = STAGE0_A_AS; + break; + default: + sis_fatal_error("unknown base format 0x%x\n", t->format); + } + break; + + case GL_MODULATE: + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendColor0 = STAGE0_C_CF; + current->hwTexBlendAlpha0 = STAGE0_A_AFAS; + break; + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + current->hwTexBlendColor0 = STAGE0_C_CFCS; + current->hwTexBlendAlpha0 = STAGE0_A_AF; + break; + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendColor0 = STAGE0_C_CFCS; + current->hwTexBlendAlpha0 = STAGE0_A_AFAS; + break; + default: + sis_fatal_error("unknown base format 0x%x\n", t->format); + } + break; + + case GL_DECAL: + switch (t->format) + { + case GL_RGB: + case GL_YCBCR_MESA: + current->hwTexBlendColor0 = STAGE0_C_CS; + current->hwTexBlendAlpha0 = STAGE0_A_AF; + break; + case GL_RGBA: + current->hwTexBlendColor0 = STAGE0_C_CFOMAS_CSAS; + current->hwTexBlendAlpha0 = STAGE0_A_AF; + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + current->hwTexBlendColor0 = STAGE0_C_CF; + current->hwTexBlendAlpha0 = STAGE0_A_AF; + break; + default: + sis_fatal_error("unknown base format 0x%x\n", t->format); + } + break; + + case GL_BLEND: + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c, texture_unit->EnvColor); + current->hwTexEnvColor = ((GLint) (c[3])) << 24 | + ((GLint) (c[0])) << 16 | + ((GLint) (c[1])) << 8 | + ((GLint) (c[2])); + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendColor0 = STAGE0_C_CF; + current->hwTexBlendAlpha0 = STAGE0_A_AFAS; + break; + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS; + current->hwTexBlendAlpha0 = STAGE0_A_AF; + break; + case GL_INTENSITY: + current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS; + current->hwTexBlendAlpha0 = STAGE0_A_AFOMAS_ACAS; + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendColor0 = STAGE0_C_CFOMCS_CCCS; + current->hwTexBlendAlpha0 = STAGE0_A_AFAS; + break; + default: + sis_fatal_error("unknown base format 0x%x\n", t->format); + } + break; + + default: + sis_fatal_error("unknown env mode 0x%x\n", texture_unit->EnvMode); + } + + if ((current->hwTexBlendColor0 != prev->hwTexBlendColor0) || + (current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) || + (current->hwTexEnvColor != prev->hwTexEnvColor)) + { + prev->hwTexEnvColor = current->hwTexEnvColor; + prev->hwTexBlendColor0 = current->hwTexBlendColor0; + 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); + GLubyte c[4]; + + __GLSiSHardware *prev = &smesa->prev; + __GLSiSHardware *current = &smesa->current; + + struct gl_texture_unit *texture_unit = &ctx->Texture.Unit[unit]; + + sisTexObjPtr t = texObj->DriverData; + + switch (texture_unit->EnvMode) + { + case GL_REPLACE: + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendColor1 = STAGE1_C_CF; + current->hwTexBlendAlpha1 = STAGE1_A_AS; + break; + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + current->hwTexBlendColor1 = STAGE1_C_CS; + current->hwTexBlendAlpha1 = STAGE1_A_AF; + break; + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendColor1 = STAGE1_C_CS; + current->hwTexBlendAlpha1 = STAGE1_A_AS; + break; + default: + sis_fatal_error("unknown base format 0x%x\n", t->format); + } + break; + + case GL_MODULATE: + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendColor1 = STAGE1_C_CF; + current->hwTexBlendAlpha1 = STAGE1_A_AFAS; + break; + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + current->hwTexBlendColor1 = STAGE1_C_CFCS; + current->hwTexBlendAlpha1 = STAGE1_A_AF; + break; + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendColor1 = STAGE1_C_CFCS; + current->hwTexBlendAlpha1 = STAGE1_A_AFAS; + break; + default: + sis_fatal_error("unknown base format 0x%x\n", t->format); + } + break; + + case GL_DECAL: + switch (t->format) + { + case GL_RGB: + case GL_YCBCR_MESA: + current->hwTexBlendColor1 = STAGE1_C_CS; + current->hwTexBlendAlpha1 = STAGE1_A_AF; + break; + case GL_RGBA: + current->hwTexBlendColor1 = STAGE1_C_CFOMAS_CSAS; + current->hwTexBlendAlpha1 = STAGE1_A_AF; + break; + case GL_ALPHA: + case GL_LUMINANCE: + case GL_INTENSITY: + case GL_LUMINANCE_ALPHA: + current->hwTexBlendColor1 = STAGE1_C_CF; + current->hwTexBlendAlpha1 = STAGE1_A_AF; + break; + default: + sis_fatal_error("unknown base format 0x%x\n", t->format); + } + break; + + case GL_BLEND: + UNCLAMPED_FLOAT_TO_RGBA_CHAN(c, texture_unit->EnvColor); + current->hwTexEnvColor = ((GLint) (c[3])) << 24 | + ((GLint) (c[0])) << 16 | + ((GLint) (c[1])) << 8 | + ((GLint) (c[2])); + switch (t->format) + { + case GL_ALPHA: + current->hwTexBlendColor1 = STAGE1_C_CF; + current->hwTexBlendAlpha1 = STAGE1_A_AFAS; + break; + case GL_LUMINANCE: + case GL_RGB: + case GL_YCBCR_MESA: + current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS; + current->hwTexBlendAlpha1 = STAGE1_A_AF; + break; + case GL_INTENSITY: + current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS; + current->hwTexBlendAlpha1 = STAGE1_A_AFOMAS_ACAS; + break; + case GL_LUMINANCE_ALPHA: + case GL_RGBA: + current->hwTexBlendColor1 = STAGE1_C_CFOMCS_CCCS; + current->hwTexBlendAlpha1 = STAGE1_A_AFAS; + break; + default: + sis_fatal_error("unknown base format 0x%x\n", t->format); + } + break; + + default: + sis_fatal_error("unknown env mode 0x%x\n", texture_unit->EnvMode); + } + + if ((current->hwTexBlendColor1 != prev->hwTexBlendColor1) || + (current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) || + (current->hwTexEnvColor != prev->hwTexEnvColor)) + { + prev->hwTexBlendColor1 = current->hwTexBlendColor1; + 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[0][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_MIRRORED_REPEAT: + current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorU; + break; + case GL_CLAMP: + current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU; + /* XXX: GL_CLAMP isn't conformant, but falling back makes the situation + * worse in other programs at the moment. + */ + /*ok = 0;*/ + break; + case GL_CLAMP_TO_EDGE: + current->texture[hw_unit].hwTextureSet |= MASK_TextureClampU; + break; + case GL_CLAMP_TO_BORDER: + current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderU; + break; + } + + switch (texObj->WrapT) + { + case GL_REPEAT: + current->texture[hw_unit].hwTextureSet |= MASK_TextureWrapV; + break; + case GL_MIRRORED_REPEAT: + current->texture[hw_unit].hwTextureSet |= MASK_TextureMirrorV; + break; + case GL_CLAMP: + current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV; + /* XXX: GL_CLAMP isn't conformant, but falling back makes the situation + * worse in other programs at the moment. + */ + /*ok = 0;*/ + break; + case GL_CLAMP_TO_EDGE: + current->texture[hw_unit].hwTextureSet |= MASK_TextureClampV; + break; + case GL_CLAMP_TO_BORDER: + current->texture[hw_unit].hwTextureSet |= MASK_TextureBorderV; + break; + } + + current->texture[hw_unit].hwTextureBorderColor = + ((GLuint) texObj->_BorderChan[3] << 24) + + ((GLuint) texObj->_BorderChan[0] << 16) + + ((GLuint) texObj->_BorderChan[1] << 8) + + ((GLuint) texObj->_BorderChan[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[0][firstLevel]->WidthLog2 << 4; + current->texture[hw_unit].hwTextureSet |= + texObj->Image[0][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->hwTexBlendColor1 = STAGE1_C_CF; + current->hwTexBlendAlpha1 = STAGE1_A_AF; + + if ((current->hwTexBlendColor1 != prev->hwTexBlendColor1) || + (current->hwTexBlendAlpha1 != prev->hwTexBlendAlpha1) || + (current->hwTexEnvColor != prev->hwTexEnvColor)) + { + prev->hwTexBlendColor1 = current->hwTexBlendColor1; + prev->hwTexBlendAlpha1 = current->hwTexBlendAlpha1; + prev->hwTexEnvColor = current->hwTexEnvColor; + smesa->GlobalFlag |= GFLAG_TEXTUREENV_1; + } + } else { + current->hwTexBlendColor0 = STAGE0_C_CF; + current->hwTexBlendAlpha0 = STAGE0_A_AF; + + if ((current->hwTexBlendColor0 != prev->hwTexBlendColor0) || + (current->hwTexBlendAlpha0 != prev->hwTexBlendAlpha0) || + (current->hwTexEnvColor != prev->hwTexEnvColor)) + { + prev->hwTexBlendColor0 = current->hwTexBlendColor0; + 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/sis_tris.c b/src/sis_tris.c new file mode 100644 index 0000000..a0e39dc --- /dev/null +++ b/src/sis_tris.c @@ -0,0 +1,1154 @@ +/* $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 +ERIC ANHOLT OR SILICON INTEGRATED SYSTEMS CORP 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 <sclin@sis.com.tw> + * Eric Anholt <anholt@FreeBSD.org> + */ + +#include "glheader.h" +#include "mtypes.h" +#include "colormac.h" +#include "macros.h" + +#include "swrast/swrast.h" +#include "swrast_setup/swrast_setup.h" +#include "tnl/t_context.h" +#include "tnl/t_pipeline.h" + +#include "sis_context.h" +#include "sis_tris.h" +#include "sis_state.h" +#include "sis_lock.h" +#include "sis_span.h" +#include "sis_alloc.h" +#include "sis_tex.h" + +/* 6326 and 300-series shared */ +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_6326_mmio_fire[OP_3D_TRIANGLE_DRAW+1] = { + OP_6326_3D_FIRE_TSARGBa, + OP_6326_3D_FIRE_TSARGBb, + OP_6326_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 ); + +/*********************************************************************** + * Emit primitives as inline vertices * + ***********************************************************************/ + +#define HAVE_QUADS 0 +#define HAVE_LINES 1 +#define HAVE_POINTS 1 +#define CTX_ARG sisContextPtr smesa +#define GET_VERTEX_DWORDS() smesa->vertex_size +#define ALLOC_VERTS( n, size ) sisAllocDmaLow( smesa, n * size * sizeof(int) ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + const char *vertptr = smesa->verts; +#define VERT(x) (sisVertex *)(vertptr + (x * vertsize * sizeof(int))) +#define VERTEX sisVertex +#undef TAG +#define TAG(x) sis_##x +#include "tnl_dd/t_dd_triemit.h" +#undef TAG +#undef LOCAL_VARS + +/*********************************************************************** + * Dispatch vertices to hardware through MMIO * + ***********************************************************************/ + +/* The ARGB write of the last vertex of the primitive fires the 3d engine, so + * save it until the end. + */ +#define SIS_MMIO_WRITE_VERTEX(_v, i, lastvert) \ +do { \ + GLuint __color, __i = 0; \ + MMIO(REG_3D_TSXa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSYa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSZa+(i)*0x30, _v->ui[__i++]); \ + if (SIS_STATES & VERT_W) \ + MMIO(REG_3D_TSWGa+(i)*0x30, _v->ui[__i++]); \ + __color = _v->ui[__i++]; \ + if (SIS_STATES & VERT_SPEC) \ + MMIO(REG_3D_TSFSa+(i)*0x30, _v->ui[__i++]); \ + if (SIS_STATES & VERT_UV0) { \ + MMIO(REG_3D_TSUAa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSVAa+(i)*0x30, _v->ui[__i++]); \ + } \ + if (SIS_STATES & VERT_UV1) { \ + MMIO(REG_3D_TSUBa+(i)*0x30, _v->ui[__i++]); \ + MMIO(REG_3D_TSVBa+(i)*0x30, _v->ui[__i++]); \ + } \ + if (lastvert || (SIS_STATES & VERT_SMOOTH)) \ + MMIO(REG_3D_TSARGBa+(i)*0x30, __color); \ +} while (0) + +#define SIS6326_MMIO_WRITE_VERTEX(_v, i, lastvert) \ +do { \ + GLuint __color, __i = 0; \ + MMIO(REG_6326_3D_TSXa+(i)*0x20, _v->ui[__i++]); \ + MMIO(REG_6326_3D_TSYa+(i)*0x20, _v->ui[__i++]); \ + MMIO(REG_6326_3D_TSZa+(i)*0x20, _v->ui[__i++]); \ + if (SIS_STATES & VERT_W) \ + MMIO(REG_6326_3D_TSWa+(i)*0x20, _v->ui[__i++]); \ + __color = _v->ui[__i++]; \ + if (SIS_STATES & VERT_SPEC) \ + MMIO(REG_6326_3D_TSFSa+(i)*0x20, _v->ui[__i++]); \ + if (SIS_STATES & VERT_UV0) { \ + MMIO(REG_6326_3D_TSUa+(i)*0x20, _v->ui[__i++]); \ + MMIO(REG_6326_3D_TSVa+(i)*0x20, _v->ui[__i++]); \ + } \ + if (lastvert || (SIS_STATES & VERT_SMOOTH)) \ + MMIO(REG_6326_3D_TSARGBa+(i)*0x30, __color); \ +} while (0) + +#define MMIO_VERT_REG_COUNT 10 + +#define VERT_SMOOTH 0x01 +#define VERT_W 0x02 +#define VERT_SPEC 0x04 +#define VERT_UV0 0x08 +#define VERT_UV1 0x10 +#define VERT_6326 0x20 /* Right after UV1, but won't have a UV1 set */ + +typedef void (*mmio_draw_func)(sisContextPtr smesa, char *verts); +static mmio_draw_func sis_tri_func_mmio[48]; +static mmio_draw_func sis_line_func_mmio[48]; +static mmio_draw_func sis_point_func_mmio[48]; + +#define SIS_STATES (0) +#define TAG(x) x##_none +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH) +#define TAG(x) x##_g +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W) +#define TAG(x) x##_w +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W) +#define TAG(x) x##_gw +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC) +#define TAG(x) x##_s +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC) +#define TAG(x) x##_gs +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC) +#define TAG(x) x##_ws +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC) +#define TAG(x) x##_gws +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV0) +#define TAG(x) x##_t0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_UV0) +#define TAG(x) x##_gt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV0) +#define TAG(x) x##_wt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0) +#define TAG(x) x##_gwt0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV0) +#define TAG(x) x##_st0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_gst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_wst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0) +#define TAG(x) x##_gwst0 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV1) +#define TAG(x) x##_t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_UV1) +#define TAG(x) x##_gt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV1) +#define TAG(x) x##_wt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV1) +#define TAG(x) x##_gwt1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV1) +#define TAG(x) x##_st1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_gst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_wst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV1) +#define TAG(x) x##_gwst1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_UV0 | VERT_UV1) +#define TAG(x) x##_t0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_wt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gwt0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_st0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gst0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_wst0t1 +#include "sis_tritmp.h" + +#define SIS_STATES (VERT_SMOOTH | VERT_W | VERT_SPEC | VERT_UV0 | VERT_UV1) +#define TAG(x) x##_gwst0t1 +#include "sis_tritmp.h" + +/*********************************************************************** + * Macros for t_dd_tritmp.h to draw basic primitives * + ***********************************************************************/ + +#define TRI( a, b, c ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_tri( smesa, a, b, c ); \ + else \ + sis_triangle( smesa, a, b, c ); \ +} while (0) + +#define QUAD( a, b, c, d ) \ +do { \ + if (DO_FALLBACK) { \ + smesa->draw_tri( smesa, a, b, d ); \ + smesa->draw_tri( smesa, b, c, d ); \ + } else \ + sis_quad( smesa, a, b, c, d ); \ +} while (0) + +#define LINE( v0, v1 ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_line( smesa, v0, v1 ); \ + else \ + sis_line( smesa, v0, v1 ); \ +} while (0) + +#define POINT( v0 ) \ +do { \ + if (DO_FALLBACK) \ + smesa->draw_point( smesa, v0 ); \ + else \ + sis_point( smesa, v0 ); \ +} while (0) + +/*********************************************************************** + * 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 { + tnl_points_func points; + tnl_line_func line; + tnl_triangle_func triangle; + tnl_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 smesa->depth_scale +#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_size * sizeof(int))) + +#define VERT_SET_RGBA( v, c ) \ +do { \ + sis_color_t *color = (sis_color_t *)&((v)->ui[coloroffset]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->blue, (c)[2]); \ + UNCLAMPED_FLOAT_TO_UBYTE(color->alpha, (c)[3]); \ +} while (0) + +#define VERT_COPY_RGBA( v0, v1 ) v0->ui[coloroffset] = v1->ui[coloroffset] + +#define VERT_SET_SPEC( v, c ) \ +do { \ + if (specoffset != 0) { \ + sis_color_t *spec = (sis_color_t *)&((v)->ui[specoffset]); \ + UNCLAMPED_FLOAT_TO_UBYTE(spec->red, (c)[0]); \ + UNCLAMPED_FLOAT_TO_UBYTE(spec->green, (c)[1]); \ + UNCLAMPED_FLOAT_TO_UBYTE(spec->blue, (c)[2]); \ + } \ +} while (0) +#define VERT_COPY_SPEC( v0, v1 ) \ +do { \ + if (specoffset != 0) { \ + sis_color_t *spec0 = (sis_color_t *)&((v0)->ui[specoffset]); \ + sis_color_t *spec1 = (sis_color_t *)&((v1)->ui[specoffset]); \ + spec0->red = spec1->red; \ + spec0->green = spec1->green; \ + spec0->blue = spec1->blue; \ + } \ +} while (0) + +#define VERT_SAVE_RGBA( idx ) color[idx] = v[idx]->ui[coloroffset] +#define VERT_RESTORE_RGBA( idx ) v[idx]->ui[coloroffset] = color[idx] +#define VERT_SAVE_SPEC( idx ) if (specoffset != 0) spec[idx] = v[idx]->ui[specoffset] +#define VERT_RESTORE_SPEC( idx ) if (specoffset != 0) v[idx]->ui[specoffset] = spec[idx] + +#define LOCAL_VARS(n) \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + GLuint color[n], spec[n]; \ + GLuint coloroffset = smesa->coloroffset; \ + GLuint specoffset = smesa->specoffset; \ + (void) color; (void) spec; (void) coloroffset; (void) specoffset; + +/*********************************************************************** + * 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_tri( sisContextPtr smesa, + sisVertex *v0, + sisVertex *v1, + sisVertex *v2 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[3]; + _swsetup_Translate( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v1, &v[1] ); + _swsetup_Translate( ctx, v2, &v[2] ); + sisSpanRenderStart( ctx ); + _swrast_Triangle( ctx, &v[0], &v[1], &v[2] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); +} + + +static void +sis_fallback_line( sisContextPtr smesa, + sisVertex *v0, + sisVertex *v1 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[2]; + _swsetup_Translate( ctx, v0, &v[0] ); + _swsetup_Translate( ctx, v1, &v[1] ); + sisSpanRenderStart( ctx ); + _swrast_Line( ctx, &v[0], &v[1] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); +} + + +static void +sis_fallback_point( sisContextPtr smesa, + sisVertex *v0 ) +{ + GLcontext *ctx = smesa->glCtx; + SWvertex v[1]; + _swsetup_Translate( ctx, v0, &v[0] ); + sisSpanRenderStart( ctx ); + _swrast_Point( ctx, &v[0] ); + sisSpanRenderFinish( ctx ); + _swrast_flush( ctx ); +} + + + +/**********************************************************************/ +/* Render unclipped begin/end objects */ +/**********************************************************************/ + +#define IND 0 +#define V(x) (sisVertex *)(vertptr + (x * vertsize * sizeof(int))) +#define RENDER_POINTS( start, count ) \ + for ( ; start < count ; start++) \ + POINT( V(ELT(start)) ) +#define RENDER_LINE( v0, v1 ) LINE( V(v0), V(v1) ) +#define RENDER_TRI( v0, v1, v2 ) TRI( V(v0), V(v1), V(v2) ) +#define RENDER_QUAD( v0, v1, v2, v3 ) QUAD( V(v0), V(v1), V(v2), V(v3) ) +#define INIT(x) sisRenderPrimitive( ctx, x ) +#undef LOCAL_VARS +#define LOCAL_VARS \ + sisContextPtr smesa = SIS_CONTEXT(ctx); \ + const GLuint vertsize = smesa->vertex_size; \ + const char *vertptr = (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" + + +/**********************************************************************/ +/* Choose render functions */ +/**********************************************************************/ + +#define POINT_FALLBACK (DD_POINT_SMOOTH) +#define LINE_FALLBACK (DD_LINE_STIPPLE|DD_LINE_SMOOTH) +#define TRI_FALLBACK (DD_TRI_STIPPLE|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) +#define _SIS_NEW_RENDER_STATE (ANY_RASTER_FLAGS | ANY_FALLBACK_FLAGS) + +static void sisChooseRenderState(GLcontext *ctx) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT( ctx ); + GLuint flags = ctx->_TriangleCaps; + GLuint index = 0; + + if (smesa->Fallback) + return; + + 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; + } + + smesa->draw_point = sis_point; + smesa->draw_line = sis_line; + smesa->draw_tri = sis_triangle; + /* 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_tri = sis_fallback_tri; + index |= SIS_FALLBACK_BIT; + } + } + + if (index != smesa->RenderIndex) { + smesa->RenderIndex = index; + + tnl->Driver.Render.Points = rast_tab[index].points; + tnl->Driver.Render.Line = rast_tab[index].line; + tnl->Driver.Render.ClippedLine = 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.ClippedPolygon = sis_fast_clipped_poly; + } else { + tnl->Driver.Render.PrimTabVerts = _tnl_render_tab_verts; + tnl->Driver.Render.PrimTabElts = _tnl_render_tab_elts; + tnl->Driver.Render.ClippedPolygon = _tnl_RenderClippedPolygon; + } + } +} + +/**********************************************************************/ +/* 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 ); + + if (smesa->NewGLState) { + SIS_FIREVERTICES(smesa); + if (smesa->NewGLState & _NEW_TEXTURE) { + sisUpdateTextureState(ctx); + } + + if (smesa->NewGLState & _SIS_NEW_RENDER_STATE) + sisChooseRenderState( ctx ); + + smesa->NewGLState = 0; + } + + _tnl_run_pipeline( ctx ); + + /* XXX: If we put flushing in sis_state.c and friends, we can avoid this. + * Is it worth it? + */ + SIS_FIREVERTICES(smesa); +} + +/**********************************************************************/ +/* 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) { + SIS_FIREVERTICES(smesa); + smesa->hw_primitive = hwprim; + + smesa->AGPParseSet &= ~(MASK_PsDataType | MASK_PsShadingMode); + smesa->AGPParseSet |= hw_prim_agp_type[hwprim]; + + if (smesa->is6326) { + smesa->dwPrimitiveSet &= ~(MASK_6326_DrawPrimitiveCommand | + MASK_6326_SetFirePosition | MASK_6326_ShadingMode); + smesa->dwPrimitiveSet |= hwprim | hw_prim_6326_mmio_fire[hwprim]; + } else { + smesa->dwPrimitiveSet &= ~(MASK_DrawPrimitiveCommand | + MASK_SetFirePosition | MASK_ShadingMode); + smesa->dwPrimitiveSet |= hwprim | hw_prim_mmio_fire[hwprim]; + } + + if (ctx->Light.ShadeModel == GL_FLAT) { + smesa->AGPParseSet |= hw_prim_agp_shade[hwprim]; + smesa->dwPrimitiveSet |= hw_prim_mmio_shade[hwprim]; + } else { + smesa->AGPParseSet |= MASK_PsShadingSmooth; + if (smesa->is6326) { + smesa->dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_GOURAUD; + } else { + smesa->dwPrimitiveSet |= SHADE_GOURAUD; + } + } + } +} + +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] ); +} + +#define EMIT_ATTR( ATTR, STYLE) \ +do { \ + smesa->vertex_attrs[smesa->vertex_attr_count].attrib = (ATTR); \ + smesa->vertex_attrs[smesa->vertex_attr_count].format = (STYLE); \ + smesa->vertex_attr_count++; \ +} while (0) + +#define EMIT_PAD( N ) \ +do { \ + smesa->vertex_attrs[smesa->vertex_attr_count].attrib = 0; \ + smesa->vertex_attrs[smesa->vertex_attr_count].format = EMIT_PAD; \ + smesa->vertex_attrs[smesa->vertex_attr_count].offset = (N); \ + smesa->vertex_attr_count++; \ +} while (0) + +static void sisRenderStart( GLcontext *ctx ) +{ + TNLcontext *tnl = TNL_CONTEXT(ctx); + sisContextPtr smesa = SIS_CONTEXT(ctx); + struct vertex_buffer *VB = &tnl->vb; + DECLARE_RENDERINPUTS(index_bitset); + GLuint AGPParseSet = smesa->AGPParseSet; + GLboolean tex_fallback = GL_FALSE; + + RENDERINPUTS_COPY( index_bitset, tnl->render_inputs_bitset ); + + if (ctx->DrawBuffer->_ColorDrawBufferMask[0] == BUFFER_BIT_FRONT_LEFT && + 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; + } + + /* Important: + */ + VB->AttribPtr[VERT_ATTRIB_POS] = VB->NdcPtr; + smesa->vertex_attr_count = 0; + + /* EMIT_ATTR's must be in order as they tell t_vertex.c how to build up a + * hardware vertex. + */ + + AGPParseSet &= ~(MASK_VertexDWSize | MASK_VertexDataFormat); + AGPParseSet |= SiS_PS_HAS_XYZ | SiS_PS_HAS_DIFFUSE; + if (RENDERINPUTS_TEST_RANGE( index_bitset, _TNL_FIRST_TEX, _TNL_LAST_TEX )) { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_4F_VIEWPORT); + AGPParseSet |= SiS_PS_HAS_W; + smesa->coloroffset = 4; + } else { + EMIT_ATTR(_TNL_ATTRIB_POS, EMIT_3F_VIEWPORT); + smesa->coloroffset = 3; + } + + EMIT_ATTR(_TNL_ATTRIB_COLOR0, EMIT_4UB_4F_BGRA); + + smesa->specoffset = 0; + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 ) || + RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { + AGPParseSet |= SiS_PS_HAS_SPECULAR; + + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_COLOR1 )) { + EMIT_ATTR(_TNL_ATTRIB_COLOR1, EMIT_3UB_3F_BGR); + smesa->specoffset = smesa->coloroffset + 1; + } else { + EMIT_PAD(3); + } + + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_FOG )) { + EMIT_ATTR(_TNL_ATTRIB_FOG, EMIT_1UB_1F); + } else { + EMIT_PAD(1); + } + } + + /* projective textures are not supported by the hardware */ + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX0 )) { + if (VB->TexCoordPtr[0]->size > 2) + tex_fallback = GL_TRUE; + EMIT_ATTR(_TNL_ATTRIB_TEX0, EMIT_2F); + AGPParseSet |= SiS_PS_HAS_UV0; + } + /* Will only hit tex1 on SiS300 */ + if (RENDERINPUTS_TEST( index_bitset, _TNL_ATTRIB_TEX1 )) { + if (VB->TexCoordPtr[1]->size > 2) + tex_fallback = GL_TRUE; + EMIT_ATTR(_TNL_ATTRIB_TEX1, EMIT_2F); + AGPParseSet |= SiS_PS_HAS_UV1; + } + FALLBACK(smesa, SIS_FALLBACK_TEXTURE, tex_fallback); + + if (!RENDERINPUTS_EQUAL( smesa->last_tcl_state_bitset, index_bitset )) { + smesa->AGPParseSet = AGPParseSet; + + smesa->vertex_size = _tnl_install_attrs( ctx, smesa->vertex_attrs, + smesa->vertex_attr_count, smesa->hw_viewport, 0 ); + + smesa->vertex_size >>= 2; + smesa->AGPParseSet |= smesa->vertex_size << 28; + } +} + +static void sisRenderFinish( GLcontext *ctx ) +{ +} + +/**********************************************************************/ +/* AGP/PCI vertex submission */ +/**********************************************************************/ + +void +sisFlushPrimsLocked(sisContextPtr smesa) +{ + if (smesa->vb_cur == smesa->vb_last) + return; + + if (smesa->is6326) + sis6326UpdateHWState(smesa->glCtx); + else + sisUpdateHWState(smesa->glCtx); + + if (smesa->using_agp) { + mWait3DCmdQueue(8); + mEndPrimitive(); + MMIO(REG_3D_AGPCmBase, (smesa->vb_last - smesa->vb) + + smesa->vb_agp_offset); + MMIO(REG_3D_AGPTtDwNum, ((smesa->vb_cur - smesa->vb_last) / 4) | + 0x50000000); + MMIO(REG_3D_ParsingSet, smesa->AGPParseSet); + MMIO(REG_3D_AGPCmFire, (GLint)(-1)); + mEndPrimitive(); + } else { + int mmio_index = 0, incr = 0; + void (*sis_emit_func)(sisContextPtr smesa, char *verts) = NULL; + + if (smesa->AGPParseSet & MASK_PsShadingSmooth) + mmio_index |= VERT_SMOOTH; + if (smesa->AGPParseSet & SiS_PS_HAS_SPECULAR) + mmio_index |= VERT_SPEC; + if (smesa->AGPParseSet & SiS_PS_HAS_W) + mmio_index |= VERT_W; + if (smesa->AGPParseSet & SiS_PS_HAS_UV0) + mmio_index |= VERT_UV0; + if (smesa->AGPParseSet & SiS_PS_HAS_UV1) + mmio_index |= VERT_UV1; + if (smesa->is6326) + mmio_index |= VERT_6326; + + switch (smesa->AGPParseSet & MASK_PsDataType) { + case MASK_PsPointList: + incr = smesa->vertex_size * 4; + sis_emit_func = sis_point_func_mmio[mmio_index]; + break; + case MASK_PsLineList: + incr = smesa->vertex_size * 4 * 2; + sis_emit_func = sis_line_func_mmio[mmio_index]; + break; + case MASK_PsTriangleList: + incr = smesa->vertex_size * 4 * 3; + sis_emit_func = sis_tri_func_mmio[mmio_index]; + break; + } + + if (!smesa->is6326) { + mWait3DCmdQueue(1); + MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet); + } + while (smesa->vb_last < smesa->vb_cur) { + sis_emit_func(smesa, smesa->vb_last); + smesa->vb_last += incr; + } + mWait3DCmdQueue(1); + mEndPrimitive(); + + /* With PCI, we can just start writing to the start of the VB again. */ + smesa->vb_cur = smesa->vb; + } + smesa->vb_last = smesa->vb_cur; +} + +void sisFlushPrims(sisContextPtr smesa) +{ + LOCK_HARDWARE(); + sisFlushPrimsLocked(smesa); + UNLOCK_HARDWARE(); +} + +/**********************************************************************/ +/* Transition to/from hardware rasterization. */ +/**********************************************************************/ + +static const char * const fallbackStrings[] = { + "Texture mode", + "Texture 0 mode", + "Texture 1 mode", + "Texture 0 env", /* Note: unused */ + "Texture 1 env", /* Note: unused */ + "glDrawBuffer(GL_FRONT_AND_BACK)", + "glEnable(GL_STENCIL) without hw stencil buffer", + "write mask", + "no_rast", +}; + +static const char *getFallbackString(GLuint bit) +{ + int i = 0; + while (bit > 1) { + i++; + bit >>= 1; + } + return fallbackStrings[i]; +} + +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) { + SIS_FIREVERTICES(smesa); + _swsetup_Wakeup( ctx ); + smesa->RenderIndex = ~0; + if (SIS_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "SiS begin rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } + } + } + 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 = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_invalidate_vertex_state( ctx, ~0 ); + _tnl_invalidate_vertices( ctx, ~0 ); + _tnl_install_attrs( ctx, + smesa->vertex_attrs, + smesa->vertex_attr_count, + smesa->hw_viewport, 0 ); + + smesa->NewGLState |= _SIS_NEW_RENDER_STATE; + if (SIS_DEBUG & DEBUG_FALLBACKS) { + fprintf(stderr, "SiS end rasterization fallback: 0x%x %s\n", + bit, getFallbackString(bit)); + } + } + } +} + + +/**********************************************************************/ +/* 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_g(); + sis_vert_init_w(); + sis_vert_init_gw(); + sis_vert_init_s(); + sis_vert_init_gs(); + sis_vert_init_ws(); + sis_vert_init_gws(); + sis_vert_init_t0(); + sis_vert_init_gt0(); + sis_vert_init_wt0(); + sis_vert_init_gwt0(); + sis_vert_init_st0(); + sis_vert_init_gst0(); + sis_vert_init_wst0(); + sis_vert_init_gwst0(); + sis_vert_init_t1(); + sis_vert_init_gt1(); + sis_vert_init_wt1(); + sis_vert_init_gwt1(); + sis_vert_init_st1(); + sis_vert_init_gst1(); + sis_vert_init_wst1(); + sis_vert_init_gwst1(); + sis_vert_init_t0t1(); + sis_vert_init_gt0t1(); + sis_vert_init_wt0t1(); + sis_vert_init_gwt0t1(); + sis_vert_init_st0t1(); + sis_vert_init_gst0t1(); + sis_vert_init_wst0t1(); + sis_vert_init_gwst0t1(); + } + + smesa->RenderIndex = ~0; + smesa->NewGLState |= _SIS_NEW_RENDER_STATE; + + 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 = _tnl_build_vertices; + tnl->Driver.Render.CopyPV = _tnl_copy_pv; + tnl->Driver.Render.Interp = _tnl_interp; + + _tnl_init_vertices( ctx, ctx->Const.MaxArrayLockSize + 12, + (6 + 2*ctx->Const.MaxTextureUnits) * sizeof(GLfloat) ); + + smesa->verts = (char *)tnl->clipspace.vertex_buf; +} diff --git a/src/sis_tris.h b/src/sis_tris.h new file mode 100644 index 0000000..5e07acc --- /dev/null +++ b/src/sis_tris.h @@ -0,0 +1,71 @@ +/* $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 +ERIC ANHOLT 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 <anholt@FreeBSD.org> + */ + +#ifndef __SIS_TRIS_H__ +#define __SIS_TRIS_H__ + +#include "sis_lock.h" +#include "mtypes.h" + +extern void sisInitTriFuncs( GLcontext *ctx ); +extern void sisFlushPrims( sisContextPtr smesa ); +extern void sisFlushPrimsLocked( sisContextPtr smesa ); +extern void sisFallback( GLcontext *ctx, GLuint bit, GLboolean mode ); + +#define FALLBACK( smesa, bit, mode ) sisFallback( smesa->glCtx, bit, mode ) + +#define SIS_FIREVERTICES(smesa) \ +do { \ + if (smesa->vb_cur != smesa->vb_last) \ + sisFlushPrims(smesa); \ +} while (0) + +static __inline GLuint *sisAllocDmaLow(sisContextPtr smesa, int bytes) +{ + GLuint *start; + + if (smesa->vb_cur + bytes >= smesa->vb_end) { + LOCK_HARDWARE(); + sisFlushPrimsLocked(smesa); + if (smesa->using_agp) { + WaitEngIdle(smesa); + smesa->vb_cur = smesa->vb; + smesa->vb_last = smesa->vb_cur; + } + UNLOCK_HARDWARE(); + } + + start = (GLuint *)smesa->vb_cur; + smesa->vb_cur += bytes; + return start; +} + +#endif /* __SIS_TRIS_H__ */ diff --git a/src/sis_tritmp.h b/src/sis_tritmp.h new file mode 100644 index 0000000..e670a5b --- /dev/null +++ b/src/sis_tritmp.h @@ -0,0 +1,250 @@ +/* $XFree86*/ /* -*- c-basic-offset: 3 -*- */ +/* + * Copyright 2005 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 + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS 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 <anholt@FreeBSD.org> + * Jim Duchek <jim@linuxpimps.com> -- Utah GLX 6326 code + * Alan Cox <alan@redhat.com> -- 6326 Debugging + * + */ + +static void TAG(sis_draw_tri_mmio)(sisContextPtr smesa, char *verts) +{ + sisVertexPtr v0 = (sisVertexPtr)verts; + sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4); + sisVertexPtr v2 = (sisVertexPtr)(verts + smesa->vertex_size * 4 * 2); + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 3); + 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, char *verts) +{ + sisVertexPtr v0 = (sisVertexPtr)verts; + sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4); + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2); + SIS_MMIO_WRITE_VERTEX(v0, 0, 0); + SIS_MMIO_WRITE_VERTEX(v1, 1, 1); +} + +static void TAG(sis_draw_point_mmio)(sisContextPtr smesa, char *verts) +{ + sisVertexPtr v0 = (sisVertexPtr)verts; + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1); + SIS_MMIO_WRITE_VERTEX(v0, 1, 1); +} + +#if !(SIS_STATES & VERT_UV1) +static void TAG(sis6326_draw_tri_mmio)(sisContextPtr smesa, char *verts) +{ + sisVertexPtr v0 = (sisVertexPtr)verts; + sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4); + sisVertexPtr v2 = (sisVertexPtr)(verts + smesa->vertex_size * 4 * 2); + GLfloat x0, x1, x2; + GLfloat y0, y1, y2; + GLfloat delt02, diffx02, diffy02, diffy12; + GLint dwPrimitiveSet = smesa->dwPrimitiveSet; + sisVertex tv0, tv1, tv2; + + /* XXX Culling? */ + + tv0 = *v0; + tv1 = *v1; + tv2 = *v2; + tv0.v.y = Y_FLIP(tv0.v.y); + tv1.v.y = Y_FLIP(tv1.v.y); + tv2.v.y = Y_FLIP(tv2.v.y); + v0 = &tv0; + v1 = &tv1; + v2 = &tv2; + + /* Cull polygons we won't draw. The hardware draws funky things if it + is fed these */ + if((((v1->v.x - v0->v.x) * (v0->v.y - v2->v.y)) + + ((v1->v.y - v0->v.y) * (v2->v.x - v0->v.x))) < 0) + return; + y0 = v0->v.y; + y1 = v1->v.y; + y2 = v2->v.y; + + + if (y0 > y1) { + if (y1 > y2) { + x0 = v0->v.x; + x1 = v1->v.x; + x2 = v2->v.x; + dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BMID | OP_6326_3D_CBOT; + if ((SIS_STATES & VERT_SMOOTH) == 0) + dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_BOT; + } else { + if (y0 > y2) { + x0 = v0->v.x; + x1 = v2->v.x; + y1 = v2->v.y; + dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_CMID | + OP_6326_3D_BBOT; + if ((SIS_STATES & VERT_SMOOTH) == 0) + dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_MID; + } else { + x0 = v2->v.x; + y0 = v2->v.y; + x1 = v0->v.x; + y1 = v0->v.y; + dwPrimitiveSet |= OP_6326_3D_CTOP | OP_6326_3D_AMID | + OP_6326_3D_BBOT; + if ((SIS_STATES & VERT_SMOOTH) == 0) + dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_TOP; + } + x2 = v1->v.x; + y2 = v1->v.y; + } + } else { + if (y0 > y2) { + x0 = v1->v.x; + y0 = v1->v.y; + x1 = v0->v.x; + y1 = v0->v.y; + x2 = v2->v.x; + dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_AMID | OP_6326_3D_CBOT; + if ((SIS_STATES & VERT_SMOOTH) == 0) + dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_BOT; + } else { + if (y1 > y2) { + x0 = v1->v.x; + y0 = v1->v.y; + x1 = v2->v.x; + y1 = v2->v.y; + dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_CMID | + OP_6326_3D_ABOT; + if ((SIS_STATES & VERT_SMOOTH) == 0) + dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_MID; + } else { + x0 = v2->v.x; + y0 = v2->v.y; + x1 = v1->v.x; + dwPrimitiveSet |= OP_6326_3D_CTOP | OP_6326_3D_BMID | + OP_6326_3D_ABOT; + if ((SIS_STATES & VERT_SMOOTH) == 0) + dwPrimitiveSet |= OP_6326_3D_SHADE_FLAT_TOP; + } + x2 = v0->v.x; + y2 = v0->v.y; + } + } + + if (x1 <= x0 && x1 <= x2) { + dwPrimitiveSet |= OP_3D_DIRECTION_LEFT; + } else if (x1 < x0 || x1 < x2) { + GLfloat tmp; + + diffx02 = x0 - x2; + diffy02 = y0 - y2; + diffy12 = y1 - y2; + + delt02 = diffx02 / diffy02; + tmp = x1 - (diffy12 * delt02 + x2); + + if (tmp <= 0.0) + dwPrimitiveSet |= OP_3D_DIRECTION_LEFT; + } + + tv0 = *v0; + tv1 = *v1; + tv2 = *v2; + tv0.v.y = Y_FLIP(tv0.v.y); + tv1.v.y = Y_FLIP(tv1.v.y); + tv2.v.y = Y_FLIP(tv2.v.y); + v0 = &tv0; + v1 = &tv1; + v2 = &tv2; + + y0 = v0->v.y; + y1 = v1->v.y; + y2 = v2->v.y; + +/* fprintf(stderr, "Vertex0 %f %f %f\n", v0->v.x, v0->v.y, v0->v.z); + fprintf(stderr, "Vertex1 %f %f %f\n", v1->v.x, v1->v.y, v1->v.z); + fprintf(stderr, "Vertex2 %f %f %f\n", v2->v.x, v2->v.y, v2->v.z);*/ + mWait3DCmdQueue(MMIO_VERT_REG_COUNT * 3 + 1); + MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet); + SIS_MMIO_WRITE_VERTEX(v0, 0, 0); + SIS_MMIO_WRITE_VERTEX(v1, 1, 0); + SIS_MMIO_WRITE_VERTEX(v2, 2, 1); + mEndPrimitive(); +} + +static void TAG(sis6326_draw_line_mmio)(sisContextPtr smesa, char *verts) +{ + sisVertexPtr v0 = (sisVertexPtr)verts; + sisVertexPtr v1 = (sisVertexPtr)(verts + smesa->vertex_size * 4); + GLint dwPrimitiveSet = smesa->dwPrimitiveSet; + + if (abs(v0->v.y - v1->v.y) > abs(v0->v.x - v1->v.x)) + { + dwPrimitiveSet |= OP_3D_DIRECTION_VERTICAL; + if (v0->v.y > v1->v.y) + dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BBOT; + else + dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_ABOT; + } else { + if (v0->v.y > v1->v.y) + dwPrimitiveSet |= OP_6326_3D_BTOP | OP_6326_3D_ABOT; + else + dwPrimitiveSet |= OP_6326_3D_ATOP | OP_6326_3D_BBOT; + } + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 2 + 1); + MMIO(REG_3D_PrimitiveSet, dwPrimitiveSet); + SIS_MMIO_WRITE_VERTEX(v0, 0, 0); + SIS_MMIO_WRITE_VERTEX(v1, 1, 1); +} + +static void TAG(sis6326_draw_point_mmio)(sisContextPtr smesa, char *verts) +{ + sisVertexPtr v0 = (sisVertexPtr)verts; + + mWait3DCmdQueue (MMIO_VERT_REG_COUNT * 1 + 1); + MMIO(REG_3D_PrimitiveSet, smesa->dwPrimitiveSet | OP_6326_3D_ATOP); + SIS_MMIO_WRITE_VERTEX(v0, 1, 1); +} +#endif + +static __inline void TAG(sis_vert_init)( void ) +{ + 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); +#if !(SIS_STATES & VERT_UV1) + sis_tri_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_tri_mmio); + sis_line_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_line_mmio); + sis_point_func_mmio[SIS_STATES | VERT_6326] = TAG(sis6326_draw_point_mmio); +#endif +} + +#undef TAG +#undef SIS_STATES |