Via Unichrome/cle266 driver (Erdi Chen)

This commit is contained in:
Brian Paul 2004-01-30 23:26:19 +00:00
parent 2726d77b2e
commit f18598cbd2
36 changed files with 22741 additions and 0 deletions

View file

@ -0,0 +1,122 @@
# Mesa 3-D graphics library
# Version: 5.0
# Copyright (C) 1995-2002 Brian Paul
TOP = ../../../../..
default: linux-solo
SHARED_INCLUDES = $(INCLUDE_DIRS) -I. -I../common -Iserver
MINIGLX_INCLUDES = -I$(TOP)/src/glx/mini
DEFINES += \
-D_HAVE_SWRAST=1 \
-D_HAVE_SWTNL=1 \
-D_HAVE_SANITY=1 \
-D_HAVE_CODEGEN=1 \
-D_HAVE_LIGHTING=1 \
-D_HAVE_TEXGEN=1 \
-D_HAVE_USERCLIP=1 \
-DGLX_DIRECT_RENDERING
MINIGLX_SOURCES = server/via_dri.c
DRIVER_SOURCES = \
via_context.c \
via_fb.c \
via_ioctl.c \
via_render.c \
via_screen.c \
via_span.c \
via_state.c \
via_tex.c \
via_texmem.c \
via_texstate.c \
via_tris.c \
via_vb.c \
xf86drmVIA.c \
../common/mm.c \
../common/utils.c \
../common/texmem.c \
../common/vblank.c \
../common/xmlconfig.c \
../../common/driverfuncs.c
INCLUDES = $(MINIGLX_INCLUDES) \
$(SHARED_INCLUDES)
C_SOURCES = $(DRIVER_SOURCES) \
$(MINIGLX_SOURCES)
MESA_MODULES = $(TOP)/src/mesa/mesa.a
ifeq ($(WINDOW_SYSTEM),dri)
WINOBJ=$(MESABUILDDIR)/dri/dri.a
WINLIB=
else
WINOBJ=
WINLIB=-L$(MESA)/src/glx/mini
endif
ASM_SOURCES =
OBJECTS = $(C_SOURCES:.c=.o) \
$(ASM_SOURCES:.S=.o)
### Include directories
INCLUDE_DIRS = \
-I$(TOP)/include \
-I$(TOP)/src/mesa \
-I$(TOP)/src/mesa/main \
-I$(TOP)/src/mesa/glapi \
-I$(TOP)/src/mesa/math \
-I$(TOP)/src/mesa/transform \
-I$(TOP)/src/mesa/swrast \
-I$(TOP)/src/mesa/swrast_setup
##### RULES #####
.c.o:
$(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
.S.o:
$(CC) -c $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) $(CFLAGS) $(DEFINES) $< -o $@
##### TARGETS #####
targets: depend unichrome_dri.so
unichrome_dri.so: $(OBJECTS) $(MESA_MODULES) $(WINOBJ) Makefile.solo
rm -f $@ && gcc -o $@ -shared $(OBJECTS) $(MESA_MODULES) $(WINOBJ) $(WINLIB) -lc $(GL_LIB_DEPS)
rm -f $(TOP)/lib/unichrome_dri.so && \
install unichrome_dri.so $(TOP)/lib/unichrome_dri.so
$(TOP)/lib/unichrome_dri.so: unichrome_dri.so
rm -f $(TOP)/lib/unichrome_dri.so && \
install unichrome_dri.so $(TOP)/lib/unichrome_dri.so
# Run 'make -f Makefile.solo dep' to update the dependencies if you change
# what's included by any source file.
depend: $(C_SOURCES) $(ASM_SOURCES)
makedepend -fdepend -Y $(SHARED_INCLUDES) $(MINIGLX_INCLUDES) \
$(C_SOURCES) $(ASM_SOURCES) >& /dev/null
# Emacs tags
tags:
etags `find . -name \*.[ch]` `find ../include`
# Remove .o and backup files
clean:
-rm -f *.o */*.o *~ *.o *~ *.so server/*.o
include $(TOP)/Make-config
include depend

View file

@ -0,0 +1,11 @@
#ifndef __VIA_H__
#define __VIA_H__
typedef struct VIAInfo
{
size_t registerSize;
void * registerHandle;
void * data;
} * VIAInfoPtr;
#endif /* __VIA_H__ */

View file

@ -0,0 +1,876 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_dri.c,v 1.4 2003/09/24 02:43:30 dawes Exp $ */
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#if 0
#include "xf86.h"
#include "xf86_OSproc.h"
#include "xf86_ansic.h"
#include "xf86Priv.h"
#include "xf86PciInfo.h"
#include "xf86Pci.h"
#define _XF86DRI_SERVER_
#include "GL/glxtokens.h"
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include "driver.h"
#include "drm.h"
#endif
#include "dri_util.h"
#include "sarea.h"
#include "via_context.h"
#include "via_dri.h"
#include "via_driver.h"
#include "via_common.h"
#include "xf86drm.h"
static void VIAEnableMMIO(DRIDriverContext * ctx);
static void VIADisableMMIO(DRIDriverContext * ctx);
static void VIADisableExtendedFIFO(DRIDriverContext *ctx);
static void VIAEnableExtendedFIFO(DRIDriverContext *ctx);
static void VIAInitialize2DEngine(DRIDriverContext *ctx);
static void VIAInitialize3DEngine(DRIDriverContext *ctx);
static int VIADRIScreenInit(DRIDriverContext * ctx);
static void VIADRICloseScreen(DRIDriverContext * ctx);
static int VIADRIFinishScreenInit(DRIDriverContext * ctx);
/* TODO XXX _SOLO temp macros */
typedef unsigned char CARD8;
typedef unsigned short CARD16;
#define xf86DrvMsg(a, b, ...) fprintf(stderr, __VA_ARGS__)
#define MMIO_IN8(base, addr) ((*(((volatile CARD8*)base)+(addr)))+0)
#define MMIO_OUT8(base, addr, val) ((*(((volatile CARD8*)base)+(addr)))=((CARD8)val))
#define MMIO_OUT16(base, addr, val) ((*(volatile CARD16*)(((CARD8*)base)+(addr)))=((CARD16)val))
#define VGA_MISC_OUT_R 0x3cc
#define VGA_MISC_OUT_W 0x3c2
#define VIDEO 0
#define AGP 1
#define AGP_PAGE_SIZE 4096
#define AGP_PAGES 8192
#define AGP_SIZE (AGP_PAGE_SIZE * AGP_PAGES)
#define AGP_CMDBUF_PAGES 256
#define AGP_CMDBUF_SIZE (AGP_PAGE_SIZE * AGP_CMDBUF_PAGES)
static char VIAKernelDriverName[] = "via";
static char VIAClientDriverName[] = "via";
static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia);
static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia);
static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia);
static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia);
static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia);
static int VIADRIAgpInit(const DRIDriverContext *ctx, VIAPtr pVia)
{
unsigned long agp_phys;
unsigned int agpaddr;
VIADRIPtr pVIADRI;
pVIADRI = pVia->devPrivate;
pVia->agpSize = 0;
if (drmAgpAcquire(pVia->drmFD) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpAcquire failed %d\n", errno);
return FALSE;
}
if (drmAgpEnable(pVia->drmFD, drmAgpGetMode(pVia->drmFD)&~0x0) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR, "[drm] drmAgpEnable failed\n");
return FALSE;
}
xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] drmAgpEnabled succeeded\n");
if (drmAgpAlloc(pVia->drmFD, AGP_SIZE, 0, &agp_phys, &pVia->agpHandle) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] drmAgpAlloc failed\n");
drmAgpRelease(pVia->drmFD);
return FALSE;
}
if (drmAgpBind(pVia->drmFD, pVia->agpHandle, 0) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] drmAgpBind failed\n");
drmAgpFree(pVia->drmFD, pVia->agpHandle);
drmAgpRelease(pVia->drmFD);
return FALSE;
}
pVia->agpSize = AGP_SIZE;
pVia->agpAddr = drmAgpBase(pVia->drmFD);
xf86DrvMsg(pScreen->myNum, X_INFO,
"[drm] agpAddr = 0x%08lx\n",pVia->agpAddr);
pVIADRI->agp.size = pVia->agpSize;
if (drmAddMap(pVia->drmFD, (drmHandle)0,
pVIADRI->agp.size, DRM_AGP, 0,
&pVIADRI->agp.handle) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] Failed to map public agp area\n");
pVIADRI->agp.size = 0;
return FALSE;
}
/* Map AGP from kernel to Xserver - Not really needed */
drmMap(pVia->drmFD, pVIADRI->agp.handle,pVIADRI->agp.size,
(drmAddressPtr)&agpaddr);
#if 0
xf86DrvMsg(pScreen->myNum, X_INFO,
"[drm] agpBase = %p\n", pVia->agpBase);
xf86DrvMsg(pScreen->myNum, X_INFO,
"[drm] agpAddr = 0x%08lx\n", pVia->agpAddr);
#endif
xf86DrvMsg(pScreen->myNum, X_INFO,
"[drm] agpSize = 0x%08x\n", pVia->agpSize);
xf86DrvMsg(pScreen->myNum, X_INFO,
"[drm] agp physical addr = 0x%08lx\n", agp_phys);
{
drm_via_agp_t agp;
agp.offset = 0;
agp.size = AGP_SIZE;
if (drmCommandWrite(pVia->drmFD, DRM_VIA_AGP_INIT, &agp,
sizeof(drm_via_agp_t)) < 0)
return FALSE;
}
return TRUE;
}
static int VIADRIFBInit(DRIDriverContext * ctx, VIAPtr pVia)
{
int FBSize = pVia->FBFreeEnd-pVia->FBFreeStart;
int FBOffset = pVia->FBFreeStart;
VIADRIPtr pVIADRI = pVia->devPrivate;
pVIADRI->fbOffset = FBOffset;
pVIADRI->fbSize = pVia->videoRambytes;
{
drm_via_fb_t fb;
fb.offset = FBOffset;
fb.size = FBSize;
if (drmCommandWrite(pVia->drmFD, DRM_VIA_FB_INIT, &fb,
sizeof(drm_via_fb_t)) < 0) {
xf86DrvMsg(pScreen->myNum, X_ERROR,
"[drm] failed to init frame buffer area\n");
return FALSE;
} else {
xf86DrvMsg(pScreen->myNum, X_INFO,
"[drm] FBFreeStart= 0x%08x FBFreeEnd= 0x%08x "
"FBSize= 0x%08x\n",
pVia->FBFreeStart, pVia->FBFreeEnd, FBSize);
return TRUE;
}
}
}
static int VIADRIPciInit(DRIDriverContext * ctx, VIAPtr pVia)
{
return TRUE;
}
static int VIADRIScreenInit(DRIDriverContext * ctx)
{
VIAPtr pVia = VIAPTR(ctx);
VIADRIPtr pVIADRI;
int err;
#if 0
ctx->shared.SAREASize = ((sizeof(XF86DRISAREARec) + 0xfff) & 0x1000);
#else
if (sizeof(XF86DRISAREARec)+sizeof(VIASAREAPriv) > SAREA_MAX) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Data does not fit in SAREA\n");
return FALSE;
}
ctx->shared.SAREASize = SAREA_MAX;
#endif
ctx->drmFD = drmOpen(VIAKernelDriverName, NULL);
if (ctx->drmFD < 0) {
fprintf(stderr, "[drm] drmOpen failed\n");
return 0;
}
pVia->drmFD = ctx->drmFD;
err = drmSetBusid(ctx->drmFD, ctx->pciBusID);
if (err < 0) {
fprintf(stderr, "[drm] drmSetBusid failed (%d, %s), %s\n",
ctx->drmFD, ctx->pciBusID, strerror(-err));
return 0;
}
err = drmAddMap(ctx->drmFD, 0, ctx->shared.SAREASize, DRM_SHM,
DRM_CONTAINS_LOCK, &ctx->shared.hSAREA);
if (err < 0) {
fprintf(stderr, "[drm] drmAddMap failed\n");
return 0;
}
fprintf(stderr, "[drm] added %d byte SAREA at 0x%08lx\n",
ctx->shared.SAREASize, ctx->shared.hSAREA);
if (drmMap(ctx->drmFD,
ctx->shared.hSAREA,
ctx->shared.SAREASize,
(drmAddressPtr)(&ctx->pSAREA)) < 0)
{
fprintf(stderr, "[drm] drmMap failed\n");
return 0;
}
memset(ctx->pSAREA, 0, ctx->shared.SAREASize);
fprintf(stderr, "[drm] mapped SAREA 0x%08lx to %p, size %d\n",
ctx->shared.hSAREA, ctx->pSAREA, ctx->shared.SAREASize);
/* Need to AddMap the framebuffer and mmio regions here:
*/
if (drmAddMap(ctx->drmFD,
(drmHandle)ctx->FBStart,
ctx->FBSize,
DRM_FRAME_BUFFER,
#ifndef _EMBEDDED
0,
#else
DRM_READ_ONLY,
#endif
&ctx->shared.hFrameBuffer) < 0)
{
fprintf(stderr, "[drm] drmAddMap framebuffer failed\n");
return 0;
}
fprintf(stderr, "[drm] framebuffer handle = 0x%08lx\n",
ctx->shared.hFrameBuffer);
pVIADRI = (VIADRIPtr) calloc(1, sizeof(VIADRIRec));
if (!pVIADRI) {
drmClose(ctx->drmFD);
return FALSE;
}
pVia->devPrivate = pVIADRI;
ctx->driverClientMsg = pVIADRI;
ctx->driverClientMsgSize = sizeof(*pVIADRI);
pVia->IsPCI = !VIADRIAgpInit(ctx, pVia);
if (pVia->IsPCI) {
VIADRIPciInit(ctx, pVia);
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use pci.\n" );
}
else
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] use agp.\n" );
if (!(VIADRIFBInit(ctx, pVia))) {
VIADRICloseScreen(ctx);
xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "[dri] frame buffer initialize fial .\n" );
return FALSE;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] frame buffer initialized.\n" );
/* DRIScreenInit doesn't add all the common mappings. Add additional mappings here. */
if (!VIADRIMapInit(ctx, pVia)) {
VIADRICloseScreen(ctx);
return FALSE;
}
pVIADRI->regs.size = VIA_MMIO_REGSIZE;
pVIADRI->regs.map = 0;
pVIADRI->regs.handle = pVia->registerHandle;
xf86DrvMsg(ctx->myNum, X_INFO, "[drm] mmio Registers = 0x%08lx\n",
pVIADRI->regs.handle);
if (drmMap(pVia->drmFD,
pVIADRI->regs.handle,
pVIADRI->regs.size,
(drmAddress *)&pVia->MapBase) != 0)
{
VIADRICloseScreen(ctx);
return FALSE;
}
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "[dri] mmio mapped.\n" );
return VIADRIFinishScreenInit(ctx);
}
static void
VIADRICloseScreen(DRIDriverContext * ctx)
{
VIAPtr pVia = VIAPTR(ctx);
VIADRIPtr pVIADRI=(VIADRIPtr)pVia->devPrivate;
if (pVia->MapBase) {
xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Unmapping MMIO registers\n");
drmUnmap(pVia->MapBase, pVIADRI->regs.size);
}
if (pVia->agpSize) {
xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Freeing agp memory\n");
drmAgpFree(pVia->drmFD, pVia->agpHandle);
xf86DrvMsg(pScreen->myNum, X_INFO, "[drm] Releasing agp module\n");
drmAgpRelease(pVia->drmFD);
}
}
static int
VIADRIFinishScreenInit(DRIDriverContext * ctx)
{
VIAPtr pVia = VIAPTR(ctx);
VIADRIPtr pVIADRI;
int err;
err = drmCreateContext(ctx->drmFD, &ctx->serverContext);
if (err != 0) {
fprintf(stderr, "%s: drmCreateContext failed %d\n", __FUNCTION__, err);
return FALSE;
}
DRM_LOCK(ctx->drmFD, ctx->pSAREA, ctx->serverContext, 0);
if (!VIADRIKernelInit(ctx, pVia)) {
VIADRICloseScreen(ctx);
return FALSE;
}
xf86DrvMsg(pScreen->myNum, X_INFO, "[dri] kernel data initialized.\n");
/* set SAREA value */
{
VIASAREAPriv *saPriv;
saPriv=(VIASAREAPriv*)(((char*)ctx->pSAREA) +
sizeof(XF86DRISAREARec));
assert(saPriv);
memset(saPriv, 0, sizeof(*saPriv));
saPriv->CtxOwner = -1;
}
pVIADRI=(VIADRIPtr)pVia->devPrivate;
pVIADRI->deviceID=pVia->Chipset;
pVIADRI->width=ctx->shared.virtualWidth;
pVIADRI->height=ctx->shared.virtualHeight;
pVIADRI->mem=ctx->shared.fbSize;
pVIADRI->bytesPerPixel= (ctx->bpp+7) / 8;
pVIADRI->sarea_priv_offset = sizeof(XF86DRISAREARec);
/* TODO */
pVIADRI->scrnX=pVIADRI->width;
pVIADRI->scrnY=pVIADRI->height;
return TRUE;
}
/* Initialize the kernel data structures. */
static int VIADRIKernelInit(DRIDriverContext * ctx, VIAPtr pVia)
{
drm_via_init_t drmInfo;
memset(&drmInfo, 0, sizeof(drm_via_init_t));
drmInfo.func = VIA_INIT_MAP;
drmInfo.sarea_priv_offset = sizeof(XF86DRISAREARec);
drmInfo.fb_offset = pVia->FrameBufferBase;
drmInfo.mmio_offset = pVia->registerHandle;
if (pVia->IsPCI)
drmInfo.agpAddr = (CARD32)NULL;
else
drmInfo.agpAddr = (CARD32)pVia->agpAddr;
if ((drmCommandWrite(pVia->drmFD, DRM_VIA_MAP_INIT,&drmInfo,
sizeof(drm_via_init_t))) < 0)
return FALSE;
return TRUE;
}
/* Add a map for the MMIO registers */
static int VIADRIMapInit(DRIDriverContext * ctx, VIAPtr pVia)
{
int flags = 0;
if (drmAddMap(pVia->drmFD, pVia->MmioBase, VIA_MMIO_REGSIZE,
DRM_REGISTERS, flags, &pVia->registerHandle) < 0) {
return FALSE;
}
xf86DrvMsg(pScreen->myNum, X_INFO,
"[drm] register handle = 0x%08lx\n", pVia->registerHandle);
return TRUE;
}
const __GLcontextModes __glModes[] =
{
/* 32 bit, RGBA Depth=24 Stencil=8 */
{.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE,
.haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_TRUE,
.redBits = 8, .greenBits = 8, .blueBits = 8, .alphaBits = 8,
.redMask = 0xff0000, .greenMask = 0xff00, .blueMask = 0xff, .alphaMask = 0xff000000,
.rgbBits = 32, .indexBits = 0,
.accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0,
.depthBits = 16, .stencilBits = 8,
.numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, },
/* 16 bit, RGB Depth=16 */
{.rgbMode = GL_TRUE, .colorIndexMode = GL_FALSE, .doubleBufferMode = GL_TRUE, .stereoMode = GL_FALSE,
.haveAccumBuffer = GL_FALSE, .haveDepthBuffer = GL_TRUE, .haveStencilBuffer = GL_FALSE,
.redBits = 5, .greenBits = 6, .blueBits = 5, .alphaBits = 0,
.redMask = 0xf800, .greenMask = 0x07e0, .blueMask = 0x001f, .alphaMask = 0x0,
.rgbBits = 16, .indexBits = 0,
.accumRedBits = 0, .accumGreenBits = 0, .accumBlueBits = 0, .accumAlphaBits = 0,
.depthBits = 16, .stencilBits = 0,
.numAuxBuffers= 0, .level = 0, .pixmapMode = GL_FALSE, },
};
static int viaInitContextModes(const DRIDriverContext *ctx,
int *numModes, const __GLcontextModes **modes)
{
*numModes = sizeof(__glModes)/sizeof(__GLcontextModes *);
*modes = &__glModes[0];
return 1;
}
static int viaValidateMode(const DRIDriverContext *ctx)
{
VIAPtr pVia = VIAPTR(ctx);
return 1;
}
static int viaPostValidateMode(const DRIDriverContext *ctx)
{
VIAPtr pVia = VIAPTR(ctx);
return 1;
}
static void VIAEnableMMIO(DRIDriverContext * ctx)
{
/*vgaHWPtr hwp = VGAHWPTR(ctx);*/
VIAPtr pVia = VIAPTR(ctx);
unsigned char val;
#if 0
if (xf86IsPrimaryPci(pVia->PciInfo)) {
/* If we are primary card, we still use std vga port. If we use
* MMIO, system will hang in vgaHWSave when our card used in
* PLE and KLE (integrated Trident MVP4)
*/
vgaHWSetStdFuncs(hwp);
}
else {
vgaHWSetMmioFuncs(hwp, pVia->MapBase, 0x8000);
}
#endif
val = VGAIN8(0x3c3);
VGAOUT8(0x3c3, val | 0x01);
val = VGAIN8(VGA_MISC_OUT_R);
VGAOUT8(VGA_MISC_OUT_W, val | 0x01);
/* Unlock Extended IO Space */
VGAOUT8(0x3c4, 0x10);
VGAOUT8(0x3c5, 0x01);
/* Enable MMIO */
if(!pVia->IsSecondary) {
VGAOUT8(0x3c4, 0x1a);
val = VGAIN8(0x3c5);
#ifdef DEBUG
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "primary val = %x\n", val);
#endif
VGAOUT8(0x3c5, val | 0x68);
}
else {
VGAOUT8(0x3c4, 0x1a);
val = VGAIN8(0x3c5);
#ifdef DEBUG
xf86DrvMsg(pScrn->scrnIndex, X_INFO, "secondary val = %x\n", val);
#endif
VGAOUT8(0x3c5, val | 0x38);
}
return;
}
static void VIADisableMMIO(DRIDriverContext * ctx)
{
VIAPtr pVia = VIAPTR(ctx);
unsigned char val;
VGAOUT8(0x3c4, 0x1a);
val = VGAIN8(0x3c5);
VGAOUT8(0x3c5, val & 0x97);
return;
}
static void VIADisableExtendedFIFO(DRIDriverContext *ctx)
{
VIAPtr pVia = VIAPTR(ctx);
CARD32 dwTemp;
dwTemp = (CARD32)VIAGETREG(0x298);
dwTemp |= 0x20000000;
VIASETREG(0x298, dwTemp);
dwTemp = (CARD32)VIAGETREG(0x230);
dwTemp &= ~0x00200000;
VIASETREG(0x230, dwTemp);
dwTemp = (CARD32)VIAGETREG(0x298);
dwTemp &= ~0x20000000;
VIASETREG(0x298, dwTemp);
}
static void VIAEnableExtendedFIFO(DRIDriverContext *ctx)
{
VIAPtr pVia = VIAPTR(ctx);
CARD32 dwTemp;
CARD8 bTemp;
dwTemp = (CARD32)VIAGETREG(0x298);
dwTemp |= 0x20000000;
VIASETREG(0x298, dwTemp);
dwTemp = (CARD32)VIAGETREG(0x230);
dwTemp |= 0x00200000;
VIASETREG(0x230, dwTemp);
dwTemp = (CARD32)VIAGETREG(0x298);
dwTemp &= ~0x20000000;
VIASETREG(0x298, dwTemp);
VGAOUT8(0x3C4, 0x17);
bTemp = VGAIN8(0x3C5);
bTemp &= ~0x7F;
bTemp |= 0x2F;
VGAOUT8(0x3C5, bTemp);
VGAOUT8(0x3C4, 0x16);
bTemp = VGAIN8(0x3C5);
bTemp &= ~0x3F;
bTemp |= 0x17;
VGAOUT8(0x3C5, bTemp);
VGAOUT8(0x3C4, 0x18);
bTemp = VGAIN8(0x3C5);
bTemp &= ~0x3F;
bTemp |= 0x17;
bTemp |= 0x40; /* force the preq always higher than treq */
VGAOUT8(0x3C5, bTemp);
}
static void VIAInitialize2DEngine(DRIDriverContext *ctx)
{
VIAPtr pVia = VIAPTR(ctx);
CARD32 dwVQStartAddr, dwVQEndAddr;
CARD32 dwVQLen, dwVQStartL, dwVQEndL, dwVQStartEndH;
CARD32 dwGEMode;
/* init 2D engine regs to reset 2D engine */
VIASETREG(0x04, 0x0);
VIASETREG(0x08, 0x0);
VIASETREG(0x0c, 0x0);
VIASETREG(0x10, 0x0);
VIASETREG(0x14, 0x0);
VIASETREG(0x18, 0x0);
VIASETREG(0x1c, 0x0);
VIASETREG(0x20, 0x0);
VIASETREG(0x24, 0x0);
VIASETREG(0x28, 0x0);
VIASETREG(0x2c, 0x0);
VIASETREG(0x30, 0x0);
VIASETREG(0x34, 0x0);
VIASETREG(0x38, 0x0);
VIASETREG(0x3c, 0x0);
VIASETREG(0x40, 0x0);
/* Init AGP and VQ regs */
VIASETREG(0x43c, 0x00100000);
VIASETREG(0x440, 0x00000000);
VIASETREG(0x440, 0x00333004);
VIASETREG(0x440, 0x60000000);
VIASETREG(0x440, 0x61000000);
VIASETREG(0x440, 0x62000000);
VIASETREG(0x440, 0x63000000);
VIASETREG(0x440, 0x64000000);
VIASETREG(0x440, 0x7D000000);
VIASETREG(0x43c, 0xfe020000);
VIASETREG(0x440, 0x00000000);
if (pVia->VQStart != 0) {
/* Enable VQ */
dwVQStartAddr = pVia->VQStart;
dwVQEndAddr = pVia->VQEnd;
dwVQStartL = 0x50000000 | (dwVQStartAddr & 0xFFFFFF);
dwVQEndL = 0x51000000 | (dwVQEndAddr & 0xFFFFFF);
dwVQStartEndH = 0x52000000 | ((dwVQStartAddr & 0xFF000000) >> 24) |
((dwVQEndAddr & 0xFF000000) >> 16);
dwVQLen = 0x53000000 | (VIA_VQ_SIZE >> 3);
VIASETREG(0x43c, 0x00fe0000);
VIASETREG(0x440, 0x080003fe);
VIASETREG(0x440, 0x0a00027c);
VIASETREG(0x440, 0x0b000260);
VIASETREG(0x440, 0x0c000274);
VIASETREG(0x440, 0x0d000264);
VIASETREG(0x440, 0x0e000000);
VIASETREG(0x440, 0x0f000020);
VIASETREG(0x440, 0x1000027e);
VIASETREG(0x440, 0x110002fe);
VIASETREG(0x440, 0x200f0060);
VIASETREG(0x440, 0x00000006);
VIASETREG(0x440, 0x40008c0f);
VIASETREG(0x440, 0x44000000);
VIASETREG(0x440, 0x45080c04);
VIASETREG(0x440, 0x46800408);
VIASETREG(0x440, dwVQStartEndH);
VIASETREG(0x440, dwVQStartL);
VIASETREG(0x440, dwVQEndL);
VIASETREG(0x440, dwVQLen);
}
else {
/* Diable VQ */
VIASETREG(0x43c, 0x00fe0000);
VIASETREG(0x440, 0x00000004);
VIASETREG(0x440, 0x40008c0f);
VIASETREG(0x440, 0x44000000);
VIASETREG(0x440, 0x45080c04);
VIASETREG(0x440, 0x46800408);
}
dwGEMode = 0;
switch (ctx->bpp) {
case 16:
dwGEMode |= VIA_GEM_16bpp;
break;
case 32:
dwGEMode |= VIA_GEM_32bpp;
default:
dwGEMode |= VIA_GEM_8bpp;
break;
}
#if 0
switch (ctx->shared.virtualWidth) {
case 800:
dwGEMode |= VIA_GEM_800;
break;
case 1024:
dwGEMode |= VIA_GEM_1024;
break;
case 1280:
dwGEMode |= VIA_GEM_1280;
break;
case 1600:
dwGEMode |= VIA_GEM_1600;
break;
case 2048:
dwGEMode |= VIA_GEM_2048;
break;
default:
dwGEMode |= VIA_GEM_640;
break;
}
#endif
/* Set BPP and Pitch */
VIASETREG(VIA_REG_GEMODE, dwGEMode);
/* Set Src and Dst base address and pitch, pitch is qword */
VIASETREG(VIA_REG_SRCBASE, 0x0);
VIASETREG(VIA_REG_DSTBASE, 0x0);
VIASETREG(VIA_REG_PITCH, VIA_PITCH_ENABLE |
((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) |
(((ctx->shared.virtualWidth * ctx->bpp >> 3) >> 3) << 16));
}
static void VIAInitialize3DEngine(DRIDriverContext *ctx)
{
VIAPtr pVia = VIAPTR(ctx);
int i;
if (!pVia->sharedData->b3DRegsInitialized)
{
VIASETREG(0x43C, 0x00010000);
for (i = 0; i <= 0x7D; i++)
{
VIASETREG(0x440, (CARD32) i << 24);
}
VIASETREG(0x43C, 0x00020000);
for (i = 0; i <= 0x94; i++)
{
VIASETREG(0x440, (CARD32) i << 24);
}
VIASETREG(0x440, 0x82400000);
VIASETREG(0x43C, 0x01020000);
for (i = 0; i <= 0x94; i++)
{
VIASETREG(0x440, (CARD32) i << 24);
}
VIASETREG(0x440, 0x82400000);
VIASETREG(0x43C, 0xfe020000);
for (i = 0; i <= 0x03; i++)
{
VIASETREG(0x440, (CARD32) i << 24);
}
VIASETREG(0x43C, 0x00030000);
for (i = 0; i <= 0xff; i++)
{
VIASETREG(0x440, 0);
}
VIASETREG(0x43C, 0x00100000);
VIASETREG(0x440, 0x00333004);
VIASETREG(0x440, 0x10000002);
VIASETREG(0x440, 0x60000000);
VIASETREG(0x440, 0x61000000);
VIASETREG(0x440, 0x62000000);
VIASETREG(0x440, 0x63000000);
VIASETREG(0x440, 0x64000000);
VIASETREG(0x43C, 0x00fe0000);
if (pVia->ChipRev >= 3 )
VIASETREG(0x440,0x40008c0f);
else
VIASETREG(0x440,0x4000800f);
VIASETREG(0x440,0x44000000);
VIASETREG(0x440,0x45080C04);
VIASETREG(0x440,0x46800408);
VIASETREG(0x440,0x50000000);
VIASETREG(0x440,0x51000000);
VIASETREG(0x440,0x52000000);
VIASETREG(0x440,0x53000000);
pVia->sharedData->b3DRegsInitialized = 1;
xf86DrvMsg(pScrn->scrnIndex, X_INFO,
"3D Engine has been initialized.\n");
}
VIASETREG(0x43C,0x00fe0000);
VIASETREG(0x440,0x08000001);
VIASETREG(0x440,0x0A000183);
VIASETREG(0x440,0x0B00019F);
VIASETREG(0x440,0x0C00018B);
VIASETREG(0x440,0x0D00019B);
VIASETREG(0x440,0x0E000000);
VIASETREG(0x440,0x0F000000);
VIASETREG(0x440,0x10000000);
VIASETREG(0x440,0x11000000);
VIASETREG(0x440,0x20000000);
}
static int viaInitFBDev(DRIDriverContext *ctx)
{
VIAPtr pVia = calloc(1, sizeof(*pVia));
ctx->driverPrivate = (void *)pVia;
pVia->Chipset = ctx->chipset;
pVia->videoRambytes = ctx->shared.fbSize;
pVia->MmioBase = ctx->MMIOStart;
pVia->FrameBufferBase = ctx->FBStart & 0xfc000000;
pVia->FBFreeStart = ctx->shared.virtualWidth * ctx->cpp *
ctx->shared.virtualHeight;
pVia->FBFreeEnd = pVia->videoRambytes;
pVia->sharedData = (ViaSharedPtr) calloc(1, sizeof(ViaSharedRec));
if (!VIADRIScreenInit(ctx))
return 0;
VIAEnableMMIO(ctx);
/* 3D rendering has noise if not enabled. */
VIAEnableExtendedFIFO(ctx);
VIAInitialize2DEngine(ctx);
VIAInitialize3DEngine(ctx);
/* Must disable MMIO or 3D won't work. */
VIADisableMMIO(ctx);
return 1;
}
static void viaHaltFBDev(DRIDriverContext *ctx)
{
drmUnmap( ctx->pSAREA, ctx->shared.SAREASize );
drmClose(ctx->drmFD);
if (ctx->driverPrivate) {
free(ctx->driverPrivate);
ctx->driverPrivate = 0;
}
}
static int viaEngineShutdown(const DRIDriverContext *ctx)
{
return 1;
}
static int viaEngineRestore(const DRIDriverContext *ctx)
{
return 1;
}
const struct DRIDriverRec __driDriver =
{
viaInitContextModes,
viaValidateMode,
viaPostValidateMode,
viaInitFBDev,
viaHaltFBDev,
viaEngineShutdown,
viaEngineRestore,
0,
};

View file

@ -0,0 +1,574 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_driver.h,v 1.7 2003/11/06 18:38:11 tsi Exp $ */
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIA_DRIVER_H_
#define _VIA_DRIVER_H_ 1
#if 0 /* DEBUG is use in VIA DRI code as a flag */
/* #define DEBUG_PRINT */
#ifdef DEBUG_PRINT
#define DEBUG(x) x
#else
#define DEBUG(x)
#endif
#endif
#if 0
#include "vgaHW.h"
#include "xf86.h"
#include "xf86Resources.h"
#include "xf86_ansic.h"
#include "xf86Pci.h"
#include "xf86PciInfo.h"
#include "xf86_OSproc.h"
#include "compiler.h"
#include "xf86Cursor.h"
#include "mipointer.h"
#include "micmap.h"
#define USE_FB
#ifdef USE_FB
#include "fb.h"
#else
#include "cfb.h"
#include "cfb16.h"
#include "cfb32.h"
#endif
#include "xf86cmap.h"
#include "vbe.h"
#include "xaa.h"
#include "via_regs.h"
#include "via_bios.h"
#include "via_gpioi2c.h"
#include "via_priv.h"
#include "ginfo.h"
#ifdef XF86DRI
#define _XF86DRI_SERVER_
#include "sarea.h"
#include "dri.h"
#include "GL/glxint.h"
#include "via_dri.h"
#endif
#else
#include "via_priv.h"
#include "via_regs.h"
#include "sarea.h"
#include "dri.h"
#include "via_dri.h"
#endif
#define DRIVER_NAME "via"
#define DRIVER_VERSION "4.1.0"
#define VERSION_MAJOR 4
#define VERSION_MINOR 1
#define PATCHLEVEL 30
#define VIA_VERSION ((VERSION_MAJOR<<24) | (VERSION_MINOR<<16) | PATCHLEVEL)
#define VGAIN8(addr) MMIO_IN8(pVia->MapBase+0x8000, addr)
#define VGAIN16(addr) MMIO_IN16(pVia->MapBase+0x8000, addr)
#define VGAIN(addr) MMIO_IN32(pVia->MapBase+0x8000, addr)
#define VGAOUT8(addr, val) MMIO_OUT8(pVia->MapBase+0x8000, addr, val)
#define VGAOUT16(addr, val) MMIO_OUT16(pVia->MapBase+0x8000, addr, val)
#define VGAOUT(addr, val) MMIO_OUT32(pVia->MapBase+0x8000, addr, val)
#define INREG(addr) MMIO_IN32(pVia->MapBase, addr)
#define OUTREG(addr, val) MMIO_OUT32(pVia->MapBase, addr, val)
#define INREG16(addr) MMIO_IN16(pVia->MapBase, addr)
#define OUTREG16(addr, val) MMIO_OUT16(pVia->MapBase, addr, val)
#define VIA_PIXMAP_CACHE_SIZE (256 * 1024)
#define VIA_CURSOR_SIZE (4 * 1024)
#define VIA_VQ_SIZE (256 * 1024)
typedef struct {
unsigned int mode, refresh, resMode;
int countWidthByQWord;
int offsetWidthByQWord;
unsigned char SR08, SR0A, SR0F;
/* extended Sequencer registers */
unsigned char SR10, SR11, SR12, SR13,SR14,SR15,SR16;
unsigned char SR17, SR18, SR19, SR1A,SR1B,SR1C,SR1D,SR1E;
unsigned char SR1F, SR20, SR21, SR22,SR23,SR24,SR25,SR26;
unsigned char SR27, SR28, SR29, SR2A,SR2B,SR2C,SR2D,SR2E;
unsigned char SR2F, SR30, SR31, SR32,SR33,SR34,SR40,SR41;
unsigned char SR42, SR43, SR44, SR45,SR46,SR47;
unsigned char Clock;
/* extended CRTC registers */
unsigned char CR13, CR30, CR31, CR32, CR33, CR34, CR35, CR36;
unsigned char CR37, CR38, CR39, CR3A, CR40, CR41, CR42, CR43;
unsigned char CR44, CR45, CR46, CR47, CR48, CR49, CR4A;
unsigned char CRTCRegs[68];
unsigned char TVRegs[0xFF];
/* unsigned char LCDRegs[0x40];*/
} VIARegRec, *VIARegPtr;
/*Definition for CapturePortID*/
#define PORT0 0 /* Capture Port 0*/
#define PORT1 1 /* Capture Port 1*/
typedef struct __viaVideoControl {
CARD32 PORTID;
CARD32 dwCompose;
CARD32 dwHighQVDO;
CARD32 VideoStatus;
CARD32 dwAction;
#define ACTION_SET_PORTID 0
#define ACTION_SET_COMPOSE 1
#define ACTION_SET_HQV 2
#define ACTION_SET_BOB 4
#define ACTION_SET_VIDEOSTATUS 8
Bool Cap0OnScreen1; /* True: Capture0 On Screen1 ; False: Capture0 On Screen0 */
Bool Cap1OnScreen1; /* True: Capture1 On Screen1 ; False: Capture1 On Screen0 */
Bool MPEGOnScreen1; /* True: MPEG On Screen1 ; False: MPEG On Screen0 */
} VIAVideoControlRec, VIAVideoControlPtr;
/*For Video HW Difference */
#define VIA_REVISION_CLEC0 0x10
#define VIA_REVISION_CLEC1 0x11
#define VIA_REVISION_CLECX 0x10
#define VID_HWDIFF_TRUE 0x00000001
#define VID_HWDIFF_FALSE 0x00000000
/*
* Video HW Difference Structure
*/
typedef struct __VIAHWRec
{
unsigned long dwThreeHQVBuffer; /* Use Three HQV Buffers*/
unsigned long dwV3SrcHeightSetting; /* Set Video Source Width and Height*/
unsigned long dwSupportExtendFIFO; /* Support Extand FIFO*/
unsigned long dwHQVFetchByteUnit; /* HQV Fetch Count unit is byte*/
unsigned long dwHQVInitPatch; /* Initialize HQV Engine 2 times*/
unsigned long dwSupportV3Gamma; /* Support V3 Gamma */
unsigned long dwUpdFlip; /* Set HQV3D0[15] to flip video*/
unsigned long dwHQVDisablePatch; /* Change Video Engine Clock setting for HQV disable bug*/
unsigned long dwSUBFlip; /* Set HQV3D0[15] to flip video for sub-picture blending*/
unsigned long dwNeedV3Prefetch; /* V3 pre-fetch function for K8*/
unsigned long dwNeedV4Prefetch; /* V4 pre-fetch function for K8*/
unsigned long dwUseSystemMemory; /* Use system memory for DXVA compressed data buffers*/
unsigned long dwExpandVerPatch; /* Patch video HW bug in expand SIM mode or same display path*/
unsigned long dwExpandVerHorPatch; /* Patch video HW bug in expand SAMM mode or same display path*/
unsigned long dwV3ExpireNumTune; /* Change V3 expire number setting for V3 bandwidth issue*/
unsigned long dwV3FIFOThresholdTune; /* Change V3 FIFO, Threshold and Pre-threshold setting for V3 bandwidth issue*/
unsigned long dwCheckHQVFIFOEmpty; /* HW Flip path, need to check HQV FIFO status */
unsigned long dwUseMPEGAGP; /* Use MPEG AGP function*/
unsigned long dwV3FIFOPatch; /* For CLE V3 FIFO Bug (srcWidth <= 8)*/
unsigned long dwSupportTwoColorKey; /* Support two color key*/
unsigned long dwCxColorSpace; /* CLE_Cx ColorSpace*/
} VIAHWRec;
/*Wait Function Structure and Flag*/
typedef struct _WaitHWINFO
{
unsigned char * pjVideo; /* MMIO Address Info*/
unsigned long dwVideoFlag; /* Video Flag*/
}WaitHWINFO, * LPWaitHWINFO;
#if 0
/* VIA Tuners */
typedef struct
{
int decoderType; /* Decoder I2C Type */
#define SAA7108H 0
#define SAA7113H 1
#define SAA7114H 2
I2CDevPtr I2C; /* Decoder I2C */
I2CDevPtr FMI2C; /* FM Tuner I2C */
/* Not yet used */
int autoDetect; /* Autodetect mode */
int tunerMode; /* Fixed mode */
} ViaTunerRec, *ViaTunerPtr;
#endif
/*
* New style overlay structure for the SubPicture overlay
*/
#if 0
typedef struct
{
VIAMem Memory;
int visible:1; /* Idea is for the top bits to become a generic class */
CARD32 width;
CARD32 height;
CARD32 pitch;
CARD32 base[2]; /* Some channels have 3 so 3 for the generic unit */
struct
{
CARD8 Y;
CARD8 Cb;
CARD8 Cr;
} palette[16];
} ViaSubPictureRecord;
typedef struct
{
VIAMem Memory;
int visible:1; /* Visible */
CARD32 width;
CARD32 height;
CARD32 pitch;
CARD32 base[3];
int Channel;
int HQV; /* Own HQV */
} ViaTVRecord;
typedef struct
{
VIAMem Memory;
CARD32 base[3];
int Busy;
} ViaHQVRecord;
#endif
/*
* Variables that need to be shared among different screens.
*/
typedef struct {
Bool b3DRegsInitialized;
} ViaSharedRec, *ViaSharedPtr;
typedef struct _VIA {
VIARegRec SavedReg;
VIARegRec ModeReg;
//xf86CursorInfoPtr CursorInfoRec;
Bool ModeStructInit;
int Bpp, Bpl, ScissB;
unsigned PlaneMask;
unsigned long videoRambytes;
int videoRamKbytes;
int FBFreeStart;
int FBFreeEnd;
int CursorStart;
int VQStart;
int VQEnd;
/* These are physical addresses. */
unsigned long FrameBufferBase;
unsigned long MmioBase;
/* These are linear addresses. */
unsigned char* MapBase;
unsigned char* VidMapBase;
unsigned char* BltBase;
unsigned char* MapBaseDense;
unsigned char* FBBase;
unsigned char* FBStart;
/* Private memory pool management */
int SWOVUsed[MEM_BLOCKS]; /* Free map for SWOV pool */
unsigned long SWOVPool; /* Base of SWOV pool */
unsigned long SWOVSize; /* Size of SWOV blocks */
Bool PrimaryVidMapped;
int dacSpeedBpp;
int minClock, maxClock;
int MCLK, REFCLK, LCDclk;
double refclk_fact;
/* Here are all the Options */
Bool VQEnable;
Bool pci_burst;
Bool NoPCIRetry;
Bool hwcursor;
Bool NoAccel;
Bool shadowFB;
Bool NoDDCValue;
int rotate;
//CloseScreenProcPtr CloseScreen;
//pciVideoPtr PciInfo;
//PCITAG PciTag;
int Chipset;
int ChipId;
int ChipRev;
//vbeInfoPtr pVbe;
int EntityIndex;
/* Support for shadowFB and rotation */
unsigned char* ShadowPtr;
int ShadowPitch;
void (*PointerMoved)(int index, int x, int y);
/* Support for XAA acceleration */
//XAAInfoRecPtr AccelInfoRec;
//xRectangle Rect;
CARD32 SavedCmd;
CARD32 SavedFgColor;
CARD32 SavedBgColor;
CARD32 SavedPattern0;
CARD32 SavedPattern1;
CARD32 SavedPatternAddr;
/* Support for Int10 processing */
//xf86Int10InfoPtr pInt10;
/* BIOS Info Ptr */
//VIABIOSInfoPtr pBIOSInfo;
/* Support for DGA */
int numDGAModes;
//DGAModePtr DGAModes;
Bool DGAactive;
int DGAViewportStatus;
int DGAOldDisplayWidth;
int DGAOldBitsPerPixel;
int DGAOldDepth;
/* The various wait handlers. */
int (*myWaitIdle)(struct _VIA*);
/* I2C & DDC */
//I2CBusPtr I2C_Port1;
//I2CBusPtr I2C_Port2;
//xf86MonPtr DDC1;
//xf86MonPtr DDC2;
/* MHS */
Bool IsSecondary;
Bool HasSecondary;
/* Capture de-interlace Mode */
CARD32 Cap0_Deinterlace;
CARD32 Cap1_Deinterlace;
Bool Cap0_FieldSwap;
#ifdef XF86DRI
Bool directRenderingEnabled;
DRIInfoPtr pDRIInfo;
int drmFD;
int numVisualConfigs;
__GLXvisualConfig* pVisualConfigs;
VIAConfigPrivPtr pVisualConfigsPriv;
unsigned long agpHandle;
unsigned long registerHandle;
unsigned long agpAddr;
unsigned char *agpBase;
unsigned int agpSize;
Bool IsPCI;
Bool drixinerama;
#else
int drmFD;
unsigned long agpHandle;
unsigned long registerHandle;
unsigned long agpAddr;
unsigned char *agpBase;
unsigned int agpSize;
Bool IsPCI;
#endif
Bool OldDRI; /* True if DRM < 2.0 found */
unsigned char ActiveDevice; /* if SAMM, non-equal pBIOSInfo->ActiveDevice */
unsigned char *CursorImage;
CARD32 CursorFG;
CARD32 CursorBG;
CARD32 CursorMC;
#if 0
/* Video */
swovRec swov;
VIAVideoControlRec Video;
VIAHWRec ViaHW;
unsigned long dwV1, dwV3;
unsigned long OverlaySupported;
unsigned long dwFrameNum;
pointer VidReg;
unsigned long gdwVidRegCounter;
unsigned long old_dwUseExtendedFIFO;
/* Overlay TV Tuners */
ViaTunerPtr Tuner[2];
I2CDevPtr CXA2104S;
int AudioMode;
int AudioMute;
#endif
/* SubPicture */
//ViaSubPictureRecord SubPicture;
//ViaHQVRecord HQV;
//ViaTVRecord TV0, TV1;
/* TODO: MPEG TV0 TV1 */
/* Global 2D state block - needs to slowly die */
//ViaGraphicRec graphicInfo;
ViaSharedPtr sharedData;
VIADRIPtr devPrivate;
} VIARec, *VIAPtr;
#if 0
typedef struct
{
Bool IsDRIEnabled;
Bool HasSecondary;
Bool BypassSecondary;
/*These two registers are used to make sure the CRTC2 is
retored before CRTC_EXT, otherwise it could lead to blank screen.*/
Bool IsSecondaryRestored;
Bool RestorePrimary;
ScrnInfoPtr pSecondaryScrn;
ScrnInfoPtr pPrimaryScrn;
}VIAEntRec, *VIAEntPtr;
#endif
/* Shortcuts. These depend on a local symbol "pVia". */
#define WaitIdle() pVia->myWaitIdle(pVia)
#define VIAPTR(p) ((VIAPtr)((p)->driverPrivate))
#if 0
/* Prototypes. */
void VIAAdjustFrame(int scrnIndex, int y, int x, int flags);
Bool VIASwitchMode(int scrnIndex, DisplayModePtr mode, int flags);
/* In HwDiff.c */
void VIAvfInitHWDiff(VIAPtr pVia );
/* In via_cursor.c. */
Bool VIAHWCursorInit(ScreenPtr pScreen);
void VIAShowCursor(ScrnInfoPtr);
void VIAHideCursor(ScrnInfoPtr);
/* In via_accel.c. */
Bool VIAInitAccel(ScreenPtr);
void VIAInitialize2DEngine(ScrnInfoPtr);
void VIAAccelSync(ScrnInfoPtr);
void VIAInitLinear(ScreenPtr pScreen);
/* In via_shadow.c */
void VIAPointerMoved(int index, int x, int y);
void VIARefreshArea(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void VIARefreshArea8(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void VIARefreshArea16(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void VIARefreshArea24(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
void VIARefreshArea32(ScrnInfoPtr pScrn, int num, BoxPtr pbox);
/* In via_bios.c */
void VIAEnableLCD(VIABIOSInfoPtr pBIOSInfo);
void VIADisableLCD(VIABIOSInfoPtr pBIOSInfo);
/* In via_dga.c */
Bool VIADGAInit(ScreenPtr);
/* In via_i2c.c */
Bool VIAI2CInit(ScrnInfoPtr pScrn);
/* In via_gpioi2c.c */
Bool VIAGPIOI2C_Write(VIABIOSInfoPtr pBIOSInfo, int SubAddress, CARD8 Data);
Bool VIAGPIOI2C_Read(VIABIOSInfoPtr pBIOSInfo, int SubAddress, CARD8 *Buffer, int BufferLen);
Bool VIAGPIOI2C_ReadByte(VIABIOSInfoPtr pBIOSInfo, int SubAddress, CARD8 *Buffer);
Bool VIAGPIOI2C_Initial(VIABIOSInfoPtr pBIOSInfo, CARD8 SlaveDevice);
/*In via_video.c*/
void viaInitVideo(ScreenPtr pScreen);
void viaExitVideo(ScrnInfoPtr pScrn);
void viaResetVideo(ScrnInfoPtr pScrn);
void viaSaveVideo(ScrnInfoPtr pScrn);
void viaRestoreVideo(ScrnInfoPtr pScrn);
/*In via_utility.c */
void VIAXVUtilityProc(ScrnInfoPtr pScrn, unsigned char* buf);
Bool VIAUTGetInfo(VIABIOSInfoPtr pBIOSInfo);
Bool VIALoadUserSetting(VIABIOSInfoPtr pBIOSInfo);
Bool VIALoadGammaSetting(VIABIOSInfoPtr pBIOSInfo);
Bool VIARestoreUserSetting(VIABIOSInfoPtr pBIOSInfo);
void VIAUTRemoveRestartFlag(VIABIOSInfoPtr pBIOSInfo);
/* in via_overlay.c */
unsigned long viaOverlayHQVCalcZoomHeight (VIAPtr pVia, unsigned long srcHeight,unsigned long dstHeight,
unsigned long * lpzoomCtl, unsigned long * lpminiCtl, unsigned long * lpHQVfilterCtl, unsigned long * lpHQVminiCtl,unsigned long * lpHQVzoomflag);
unsigned long viaOverlayGetSrcStartAddress (VIAPtr pVia, unsigned long dwVideoFlag,RECTL rSrc,RECTL rDest, unsigned long dwSrcPitch,LPDDPIXELFORMAT lpDPF,unsigned long * lpHQVoffset );
void viaOverlayGetDisplayCount(VIAPtr pVIa, unsigned long dwVideoFlag,LPDDPIXELFORMAT lpDPF,unsigned long dwSrcWidth,unsigned long * lpDisplayCountW);
unsigned long viaOverlayHQVCalcZoomWidth(VIAPtr pVia, unsigned long dwVideoFlag, unsigned long srcWidth , unsigned long dstWidth,
unsigned long * lpzoomCtl, unsigned long * lpminiCtl, unsigned long * lpHQVfilterCtl, unsigned long * lpHQVminiCtl,unsigned long * lpHQVzoomflag);
void viaOverlayGetV1Format(VIAPtr pVia, unsigned long dwVideoFlag,LPDDPIXELFORMAT lpDPF, unsigned long * lpdwVidCtl,unsigned long * lpdwHQVCtl );
void viaOverlayGetV3Format(VIAPtr pVia, unsigned long dwVideoFlag,LPDDPIXELFORMAT lpDPF, unsigned long * lpdwVidCtl,unsigned long * lpdwHQVCtl );
/* In via_memory.c */
void VIAFreeLinear(VIAMemPtr);
unsigned long VIAAllocLinear(VIAMemPtr, ScrnInfoPtr, unsigned long);
void VIAInitPool(VIAPtr, unsigned long, unsigned long);
/* In via_tuner.c */
void ViaTunerStandard(ViaTunerPtr, int);
void ViaTunerBrightness(ViaTunerPtr, int);
void ViaTunerContrast(ViaTunerPtr, int);
void ViaTunerHue(ViaTunerPtr, int);
void ViaTunerLuminance(ViaTunerPtr, int);
void ViaTunerSaturation(ViaTunerPtr, int);
void ViaTunerInput(ViaTunerPtr, int);
#define MODE_TV 0
#define MODE_SVIDEO 1
#define MODE_COMPOSITE 2
void ViaTunerChannel(ViaTunerPtr, int, int);
void ViaAudioSelect(VIAPtr pVia, int tuner);
void ViaAudioInit(VIAPtr pVia);
void ViaAudioMode(VIAPtr pVia, int mode);
void ViaAudioMute(VIAPtr pVia, int mute);
void ViaTunerProbe(ScrnInfoPtr pScrn);
void ViaTunerDestroy(ScrnInfoPtr pScrn);
/* In via_lib.c */
int VIACLECXChipset(VIAPtr pVia);
void VIASetColorspace(VIAPtr pVia, int check_secondary);
void VIAYUVFillBlack(VIAPtr pVia, int offset, int pixels);
/* In via_subp.c */
unsigned long VIACreateSubPictureSurface(ScrnInfoPtr pScrn, CARD32 width, CARD32 height);
void VIADestroySubPictureSurface(ScrnInfoPtr pScrn);
void VIASubPicturePalette(ScrnInfoPtr pScrn);
void VIASubPictureStart(ScrnInfoPtr pScrn, int frame);
void VIASubPictureStop(ScrnInfoPtr pScrn);
/* In via_tv0.c */
unsigned long VIACreateTV0Surface(ScrnInfoPtr pScrn, CARD32 width, CARD32 height);
void VIADestroyTV0Surface(ScrnInfoPtr pScrn);
#endif
#endif /* _VIA_DRIVER_H_ */

View file

@ -0,0 +1,70 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_priv.h,v 1.3 2003/08/27 15:16:12 tsi Exp $ */
#ifndef _VIA_PRIV_H_
#define _VIA_PRIV_H_ 1
//#include "ddmpeg.h"
#include "via_common.h"
#define MEM_BLOCKS 4
typedef struct {
unsigned long base; /* Offset into fb */
int pool; /* Pool we drew from */
int drm_fd; /* Fd in DRM mode */
drm_via_mem_t drm; /* DRM management object */
int slot; /* Pool 3 slot */
void *pVia; /* VIA driver pointer */
//FBLinearPtr linear; /* X linear pool info ptr */
} VIAMem;
typedef VIAMem *VIAMemPtr;
#if 0
typedef struct {
unsigned long gdwVideoFlagTV1;
unsigned long gdwVideoFlagSW;
unsigned long gdwVideoFlagMPEG;
unsigned long gdwAlphaEnabled; /* For Alpha blending use*/
VIAMem SWOVMem;
VIAMem HQVMem;
VIAMem SWfbMem;
DDPIXELFORMAT DPFsrc;
DDUPDATEOVERLAY UpdateOverlayBackup; /* For HQVcontrol func use
// To save MPEG updateoverlay info.*/
/* device struct */
SWDEVICE SWDevice;
SUBDEVICE SUBDevice;
MPGDEVICE MPGDevice;
OVERLAYRECORD overlayRecordV1;
OVERLAYRECORD overlayRecordV3;
BoxRec AvailFBArea;
FBLinearPtr SWOVlinear;
Bool MPEG_ON;
Bool SWVideo_ON;
/*To solve the bandwidth issue */
unsigned long gdwUseExtendedFIFO;
/* For panning mode use */
int panning_old_x;
int panning_old_y;
int panning_x;
int panning_y;
/*To solve the bandwidth issue */
unsigned char Save_3C4_16;
unsigned char Save_3C4_17;
unsigned char Save_3C4_18;
} swovRec, *swovPtr;
#endif
#endif /* _VIA_PRIV_H_ */

View file

@ -0,0 +1,212 @@
/* $XFree86: xc/programs/Xserver/hw/xfree86/drivers/via/via_regs.h,v 1.3 2003/08/27 15:16:13 tsi Exp $ */
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*************************************************************************
*
* File: via_regs.c
* Content: The defines of Via registers
*
************************************************************************/
#ifndef _VIA_REGS_H_
#define _VIA_REGS_H_ 1
#include "via_driver.h"
#define VIA_SERIES(chip) (chip == VIA_CLE266)
/* Chip tags. These are used to group the adapters into
* related families.
*/
enum VIACHIPTAGS {
VIA_UNKNOWN = 0,
VIA_CLE266,
VIA_KM400,
VIA_K8M800,
VIA_LAST
};
#define PCI_VIA_VENDOR_ID 0x1106
#define PCI_CHIP_CLE3122 0x3122
#define PCI_CHIP_CLE3022 0x3022
#define PCI_CHIP_VT3205 0x3205
#define PCI_CHIP_VT7205 0x7205
#define PCI_CHIP_VT3204 0x3204
#define PCI_CHIP_VT7204 0x7204
#define BIOS_BSIZE 1024
#define BIOS_BASE 0xc0000
#define VIA_MMIO_REGSIZE 0x9000
#define VIA_MMIO_REGBASE 0x0
#define VIA_MMIO_VGABASE 0x8000
#define VIA_MMIO_BLTBASE 0x200000
#define VIA_MMIO_BLTSIZE 0x10000
/* defines for VIA 2D registers */
#define VIA_REG_GECMD 0x000
#define VIA_REG_GEMODE 0x004
#define VIA_REG_GESTATUS 0x004 /* as same as VIA_REG_GEMODE */
#define VIA_REG_SRCPOS 0x008
#define VIA_REG_DSTPOS 0x00C
#define VIA_REG_LINE_K1K2 0x008
#define VIA_REG_LINE_XY 0x00C
#define VIA_REG_DIMENSION 0x010 /* width and height */
#define VIA_REG_PATADDR 0x014
#define VIA_REG_FGCOLOR 0x018
#define VIA_REG_DSTCOLORKEY 0x018 /* as same as VIA_REG_FG */
#define VIA_REG_BGCOLOR 0x01C
#define VIA_REG_SRCCOLORKEY 0x01C /* as same as VIA_REG_BG */
#define VIA_REG_CLIPTL 0x020 /* top and left of clipping */
#define VIA_REG_CLIPBR 0x024 /* bottom and right of clipping */
#define VIA_REG_OFFSET 0x028
#define VIA_REG_LINE_ERROR 0x028
#define VIA_REG_KEYCONTROL 0x02C /* color key control */
#define VIA_REG_SRCBASE 0x030
#define VIA_REG_DSTBASE 0x034
#define VIA_REG_PITCH 0x038 /* pitch of src and dst */
#define VIA_REG_MONOPAT0 0x03C
#define VIA_REG_MONOPAT1 0x040
#define VIA_REG_COLORPAT 0x100 /* from 0x100 to 0x1ff */
/* defines for VIA video registers */
#define VIA_REG_INTERRUPT 0x200
#define VIA_REG_CRTCSTART 0x214
/* defines for VIA HW cursor registers */
#define VIA_REG_CURSOR_MODE 0x2D0
#define VIA_REG_CURSOR_POS 0x2D4
#define VIA_REG_CURSOR_ORG 0x2D8
#define VIA_REG_CURSOR_BG 0x2DC
#define VIA_REG_CURSOR_FG 0x2E0
/* defines for VIA 3D registers */
#define VIA_REG_STATUS 0x400
#define VIA_REG_TRANSET 0x43C
#define VIA_REG_TRANSPACE 0x440
/* VIA_REG_STATUS(0x400): Engine Status */
#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */
#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */
#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */
#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */
/* VIA_REG_GECMD(0x00): 2D Engine Command */
#define VIA_GEC_NOOP 0x00000000
#define VIA_GEC_BLT 0x00000001
#define VIA_GEC_LINE 0x00000005
#define VIA_GEC_SRC_XY 0x00000000
#define VIA_GEC_SRC_LINEAR 0x00000010
#define VIA_GEC_DST_XY 0x00000000
#define VIA_GEC_DST_LINRAT 0x00000020
#define VIA_GEC_SRC_FB 0x00000000
#define VIA_GEC_SRC_SYS 0x00000040
#define VIA_GEC_DST_FB 0x00000000
#define VIA_GEC_DST_SYS 0x00000080
#define VIA_GEC_SRC_MONO 0x00000100 /* source is mono */
#define VIA_GEC_PAT_MONO 0x00000200 /* pattern is mono */
#define VIA_GEC_MSRC_OPAQUE 0x00000000 /* mono src is opaque */
#define VIA_GEC_MSRC_TRANS 0x00000400 /* mono src is transparent */
#define VIA_GEC_PAT_FB 0x00000000 /* pattern is in frame buffer */
#define VIA_GEC_PAT_REG 0x00000800 /* pattern is from reg setting */
#define VIA_GEC_CLIP_DISABLE 0x00000000
#define VIA_GEC_CLIP_ENABLE 0x00001000
#define VIA_GEC_FIXCOLOR_PAT 0x00002000
#define VIA_GEC_INCX 0x00000000
#define VIA_GEC_DECY 0x00004000
#define VIA_GEC_INCY 0x00000000
#define VIA_GEC_DECX 0x00008000
#define VIA_GEC_MPAT_OPAQUE 0x00000000 /* mono pattern is opaque */
#define VIA_GEC_MPAT_TRANS 0x00010000 /* mono pattern is transparent */
#define VIA_GEC_MONO_UNPACK 0x00000000
#define VIA_GEC_MONO_PACK 0x00020000
#define VIA_GEC_MONO_DWORD 0x00000000
#define VIA_GEC_MONO_WORD 0x00040000
#define VIA_GEC_MONO_BYTE 0x00080000
#define VIA_GEC_LASTPIXEL_ON 0x00000000
#define VIA_GEC_LASTPIXEL_OFF 0x00100000
#define VIA_GEC_X_MAJOR 0x00000000
#define VIA_GEC_Y_MAJOR 0x00200000
#define VIA_GEC_QUICK_START 0x00800000
/* VIA_REG_GEMODE(0x04): GE mode */
#define VIA_GEM_8bpp 0x00000000
#define VIA_GEM_16bpp 0x00000100
#define VIA_GEM_32bpp 0x00000300
#define VIA_GEM_640 0x00000000 /* 640*480 */
#define VIA_GEM_800 0x00000400 /* 800*600 */
#define VIA_GEM_1024 0x00000800 /* 1024*768 */
#define VIA_GEM_1280 0x00000C00 /* 1280*1024 */
#define VIA_GEM_1600 0x00001000 /* 1600*1200 */
#define VIA_GEM_2048 0x00001400 /* 2048*1536 */
/* VIA_REG_PITCH(0x38): Pitch Setting */
#define VIA_PITCH_ENABLE 0x80000000
#define MAXLOOP 0xffffff
#define VerticalRetraceWait() \
{ \
VGAOUT8(vgaCRIndex, 0x17); \
if (VGAIN8(vgaCRReg) & 0x80) { \
while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x00) ; \
while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x08) ; \
while ((VGAIN8(vgaIOBase + 0x0a) & 0x08) == 0x00) ; \
} \
}
#define VIASETREG(addr, data) *(volatile unsigned int *)(pVia->MapBase + (addr)) = (data)
#define VIAGETREG(addr) *(volatile unsigned int *)(pVia->MapBase + (addr))
#endif /* _VIA_REGS_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,155 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIA_DRM_H_
#define _VIA_DRM_H_
/* WARNING: These defines must be the same as what the Xserver uses.
* if you change them, you must change the defines in the Xserver.
*/
#ifndef _VIA_DEFINES_
#define _VIA_DEFINES_
#define VIA_DMA_BUF_ORDER 12
#define VIA_DMA_BUF_SZ (1 << VIA_DMA_BUF_ORDER)
#define VIA_DMA_BUF_NR 256
#define VIA_NR_SAREA_CLIPRECTS 8
#define VIA_NR_TEX_REGIONS 64
#define VIA_LOG_MIN_TEX_REGION_SIZE 16
#endif
#define VIA_UPLOAD_TEX0IMAGE 0x1
#define VIA_UPLOAD_TEX1IMAGE 0x2
#define VIA_UPLOAD_CTX 0x4
#define VIA_UPLOAD_BUFFERS 0x8
#define VIA_UPLOAD_TEX0 0x10
#define VIA_UPLOAD_TEX1 0x20
#define VIA_UPLOAD_CLIPRECTS 0x40
/*#define VIA_UPLOAD_ALL 0xff*/
/* VIA specific ioctls */
#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(0x40, drm_via_mem_t)
#define DRM_IOCTL_VIA_FREEMEM DRM_IOW(0x41, drm_via_mem_t)
#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(0x42, drm_via_agp_t)
#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(0x43, drm_via_fb_t)
#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(0x44, drm_via_init_t)
#define DRM_IOCTL_VIA_FLUSH_AGP DRM_IOW(0x45, drm_via_flush_agp_t)
#define DRM_IOCTL_VIA_FLUSH_SYS DRM_IOW(0x46, drm_via_flush_sys_t)
#define VIA_TEX_SETUP_SIZE 8
#define DRM_VIA_ALLOCMEM 0
#define DRM_VIA_FREEMEM 1
#define DRM_VIA_AGP_INIT 2
#define DRM_VIA_FB_INIT 3
#define DRM_VIA_MAP_INIT 4
#define VIA_FRONT 0x1
#define VIA_BACK 0x2
#define VIA_DEPTH 0x4
#define VIA_STENCIL 0x8
#define VIDEO 0
#define AGP 1
typedef struct {
unsigned int offset;
unsigned int size;
} drm_via_agp_t;
typedef struct {
unsigned int offset;
unsigned int size;
} drm_via_fb_t;
typedef struct {
unsigned int context;
unsigned int type;
unsigned int size;
unsigned long index;
unsigned long offset;
} drm_via_mem_t;
typedef struct _drm_via_init {
enum {
VIA_INIT_MAP = 0x01,
VIA_CLEANUP_MAP = 0x02
} func;
unsigned long sarea_priv_offset;
unsigned long fb_offset;
unsigned long mmio_offset;
unsigned long agpAddr;
} drm_via_init_t;
typedef struct _drm_via_tex_region {
unsigned char next, prev;
unsigned char inUse;
int age;
} drm_via_tex_region_t;
typedef struct _drm_via_sarea {
unsigned int dirty;
unsigned int nbox;
drm_clip_rect_t boxes[VIA_NR_SAREA_CLIPRECTS];
drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1];
int texAge;
int ctxOwner;
int vertexPrim;
} drm_via_sarea_t;
typedef struct _drm_via_flush_agp {
unsigned int offset;
unsigned int size;
unsigned int index;
int discard;
} drm_via_flush_agp_t;
typedef struct _drm_via_flush_sys {
unsigned int offset;
unsigned int size;
unsigned long index;
int discard;
} drm_via_flush_sys_t;
#ifdef __KERNEL__
int via_fb_init(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int via_mem_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int via_mem_free(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int via_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int via_dma_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int via_dma_free(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int via_map_init(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int via_flush_agp(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
int via_flush_sys(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg);
#endif
#endif /* _VIA_DRM_H_ */

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,486 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIACONTEXT_H
#define _VIACONTEXT_H
typedef struct via_context_t viaContext;
typedef struct via_context_t *viaContextPtr;
typedef struct via_texture_object_t *viaTextureObjectPtr;
#include "dri_util.h"
#ifndef _SOLO
#include <X11/Xlibint.h>
#endif
#include "mtypes.h"
#include "drm.h"
#include "mm.h"
#include "via_screen.h"
#include "via_tex.h"
#include "via_common.h"
#include "xf86drmVIA.h"
#ifndef _SOLO
#include "../../../../../include/extensions/Xinerama.h"
#endif
#define VIA_FALLBACK_TEXTURE 0x1
#define VIA_FALLBACK_DRAW_BUFFER 0x2
#define VIA_FALLBACK_READ_BUFFER 0x4
#define VIA_FALLBACK_COLORMASK 0x8
#define VIA_FALLBACK_SPECULAR 0x20
#define VIA_FALLBACK_LOGICOP 0x40
#define VIA_FALLBACK_RENDERMODE 0x80
#define VIA_FALLBACK_STENCIL 0x100
#define VIA_FALLBACK_BLEND_EQ 0x200
#define VIA_FALLBACK_BLEND_FUNC 0x400
#define VIA_UPLOAD_NONE 0x0000
#define VIA_UPLOAD_ALPHATEST 0x0001
#define VIA_UPLOAD_BLEND 0x0002
#define VIA_UPLOAD_FOG 0x0004
#define VIA_UPLOAD_MASK_ROP 0x0008
#define VIA_UPLOAD_LINESTIPPLE 0x0010
#define VIA_UPLOAD_POLYGONSTIPPLE 0x0020
#define VIA_UPLOAD_DEPTH 0x0040
#define VIA_UPLOAD_TEXTURE 0x0080
#define VIA_UPLOAD_STENCIL 0x0100
#define VIA_UPLOAD_CLIPPING 0x0200
#define VIA_UPLOAD_DESTBUFFER 0x0400
#define VIA_UPLOAD_DEPTHBUFFER 0x0800
#define VIA_UPLOAD_ENABLE 0x0800
#define VIA_UPLOAD_ALL 0x1000
/* Use the templated vertex formats:
*/
#define TAG(x) via##x
#include "tnl_dd/t_dd_vertex.h"
#undef TAG
#define BUFFER_ALIGNMENT 32
#define BUFFER_ALIGN_WIDTH1(w, a) (((w) + ((a) - 1)) & ~((a) - 1))
#define BUFFER_ALIGN_WIDTH(w, a) (((w) & ((a) - 1)) ? BUFFER_ALIGN_WIDTH1(w, a) : (w))
#define BUFFER_ALIGN_ADDRESS(p, a) ((GLvoid *)(((GLint)(p)) + ((a)-1) & ~((a)-1)))
#define RightOf 1
#define LeftOf 2
#define Down 4
#define Up 8
#define S0 16
#define S1 32
#define P_MASK 0x0f;
#define S_MASK 0x30;
typedef void (*via_tri_func)(viaContextPtr, viaVertex *, viaVertex *,
viaVertex *);
typedef void (*via_line_func)(viaContextPtr, viaVertex *, viaVertex *);
typedef void (*via_point_func)(viaContextPtr, viaVertex *);
typedef struct {
drmHandle handle;
drmSize size;
GLuint offset;
GLuint index;
GLuint pitch;
GLuint bpp;
char *map;
} viaBuffer, *viaBufferPtr;
typedef struct {
drmHandle handle;
drmSize size;
GLuint offset;
GLuint index;
unsigned char* map;
} viaDmaBuffer, *viaDmaBufferPtr;
struct via_context_t {
GLint refcount;
GLcontext *glCtx;
GLcontext *shareCtx;
unsigned char* front_base;
viaBuffer front;
viaBuffer back;
viaBuffer depth;
GLboolean hasBack;
GLboolean hasDepth;
GLboolean hasStencil;
GLboolean hasAccum;
GLuint depthBits;
GLuint stencilBits;
viaDmaBuffer dma[2];
viaRegion tex;
GLuint isAGP;
/* Textures
*/
viaTextureObjectPtr CurrentTexObj[2];
struct via_texture_object_t TexObjList;
struct via_texture_object_t SwappedOut;
memHeap_t *texHeap;
/* Bit flag to keep 0track of fallbacks.
*/
GLuint Fallback;
/* Temporaries for translating away float colors:
*/
struct gl_client_array UbyteColor;
struct gl_client_array UbyteSecondaryColor;
/* State for via_vb.c and via_tris.c.
*/
GLuint newState; /* _NEW_* flags */
GLuint setupNewInputs;
GLuint setupIndex;
GLuint renderIndex;
GLmatrix ViewportMatrix;
GLenum renderPrimitive;
GLenum reducedPrimitive;
GLuint hwPrimitive;
unsigned char *verts;
/* drmBufPtr dma_buffer;
*/
unsigned char* dmaAddr;
GLuint dmaIndex;
GLuint dmaLow;
GLuint dmaHigh;
GLuint dmaLastPrim;
GLboolean useAgp;
GLboolean uploadCliprects;
GLuint needUploadAllState;
GLuint primitiveRendered;
/* Fallback rasterization functions
*/
via_point_func drawPoint;
via_line_func drawLine;
via_tri_func drawTri;
/* Hardware register
*/
GLuint regCmdA;
GLuint regCmdA_End;
GLuint regCmdB;
GLuint regEnable;
GLuint regHFBBMSKL;
GLuint regHROP;
GLuint regHZWTMD;
GLuint regHSTREF;
GLuint regHSTMD;
GLuint regHATMD;
GLuint regHABLCsat;
GLuint regHABLCop;
GLuint regHABLAsat;
GLuint regHABLAop;
GLuint regHABLRCa;
GLuint regHABLRFCa;
GLuint regHABLRCbias;
GLuint regHABLRCb;
GLuint regHABLRFCb;
GLuint regHABLRAa;
GLuint regHABLRAb;
GLuint regHFogLF;
GLuint regHFogCL;
GLuint regHFogCH;
GLuint regHLP;
GLuint regHLPRF;
GLuint regHTXnTB_0;
GLuint regHTXnMPMD_0;
GLuint regHTXnTBLCsat_0;
GLuint regHTXnTBLCop_0;
GLuint regHTXnTBLMPfog_0;
GLuint regHTXnTBLAsat_0;
GLuint regHTXnTBLRCb_0;
GLuint regHTXnTBLRAa_0;
GLuint regHTXnTBLRFog_0;
/*=* John Sheng [2003.7.18] texture combine *=*/
GLuint regHTXnTBLRCa_0;
GLuint regHTXnTBLRCc_0;
GLuint regHTXnTBLRCbias_0;
GLuint regHTXnTB_1;
GLuint regHTXnMPMD_1;
GLuint regHTXnTBLCsat_1;
GLuint regHTXnTBLCop_1;
GLuint regHTXnTBLMPfog_1;
GLuint regHTXnTBLAsat_1;
GLuint regHTXnTBLRCb_1;
GLuint regHTXnTBLRAa_1;
GLuint regHTXnTBLRFog_1;
/* Hardware state
*/
GLuint dirty;
int vertex_size;
int vertex_stride_shift;
GLint lastStamp;
GLboolean stippleInHw;
GLenum TexEnvImageFmt[2];
GLuint ClearColor;
/* DRI stuff
*/
GLuint needClip;
GLframebuffer *glBuffer;
GLboolean doPageFlip;
/*=* John Sheng [2003.5.31] flip *=*/
GLuint currentPage;
char *drawMap; /* draw buffer address in virtual mem */
char *readMap;
int drawX; /* origin of drawable in draw buffer */
int drawY;
int drawW;
int drawH;
GLuint saam;
#ifndef _SOLO
XineramaScreenInfo *xsi;
#endif
int drawXoffSaam;
XF86DRIClipRectPtr pSaamRects;
int drawXSaam;
int drawYSaam;
GLuint numSaamRects;
int drawPitch;
int readPitch;
int drawXoff;
GLuint numClipRects; /* cliprects for that buffer */
XF86DRIClipRectPtr pClipRects;
int lastSwap;
int texAge;
int ctxAge;
int dirtyAge;
GLboolean scissor;
drm_clip_rect_t drawRect;
drm_clip_rect_t scissorRect;
drmContext hHWContext;
drmLock *driHwLock;
int driFd;
#ifndef _SOLO
Display *display;
#endif
__DRIdrawablePrivate *driDrawable;
__DRIscreenPrivate *driScreen;
viaScreenPrivate *viaScreen;
drm_via_sarea_t *sarea;
volatile GLuint* regMMIOBase;
volatile GLuint* pnGEMode;
volatile GLuint* regEngineStatus;
volatile GLuint* regTranSet;
volatile GLuint* regTranSpace;
GLuint* agpBase;
GLuint drawType;
};
/*#define DMA_OFFSET 16*/
#define DMA_OFFSET 32
/*#define PERFORMANCE_MEASURE*/
extern GLuint VIA_PERFORMANCE;
#ifdef PERFORMANCE_MEASURE
#define HASH_TABLE_SIZE 1000
#define HASH_TABLE_DEPTH 10
typedef struct {
char func[50];
GLuint count;
} hash_element;
extern hash_element hash_table[HASH_TABLE_SIZE][HASH_TABLE_DEPTH];
#define P_M \
do { \
GLuint h_index,h_depth; \
h_index = (GLuint)(((GLuint) __FUNCTION__)%HASH_TABLE_SIZE); \
for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) { \
if (!strcmp(hash_table[h_index][h_depth].func, "NULL")) { \
sprintf(hash_table[h_index][h_depth].func, "%s", __FUNCTION__); \
hash_table[h_index][h_depth].count++; \
break; \
} \
else if (!strcmp(hash_table[h_index][h_depth].func, __FUNCTION__)) { \
hash_table[h_index][h_depth].count++; \
break; \
} \
} \
} while (0)
#define P_M_X \
do { \
GLuint h_index,h_depth; \
char str[80]; \
strcpy(str, __FUNCTION__); \
h_index = (GLuint)(((GLuint) __FUNCTION__)%HASH_TABLE_SIZE); \
for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) { \
if (!strcmp(hash_table[h_index][h_depth].func, "NULL")) { \
sprintf(hash_table[h_index][h_depth].func, "%s_X", __FUNCTION__); \
hash_table[h_index][h_depth].count++; \
break; \
} \
else if (!strcmp(hash_table[h_index][h_depth].func, strcat(str, "_X"))) { \
hash_table[h_index][h_depth].count++; \
break; \
} \
} \
} while (0)
#define P_M_R \
do { \
GLuint h_size, h_depth; \
for (h_size = 0; h_size < HASH_TABLE_SIZE; h_size++) { \
for (h_depth = 0; h_depth < HASH_TABLE_DEPTH; h_depth++) { \
if (hash_table[h_size][h_depth].count) { \
fprintf(stderr, "func:%s count:%d\n", hash_table[h_size][h_depth].func, hash_table[h_size][h_depth].count); \
} \
} \
} \
} while (0)
#else /* PERFORMANCE_MEASURE */
#define P_M {}
#define P_M_X {}
#define P_M_R {}
#endif
#define VIA_CONTEXT(ctx) ((viaContextPtr)(ctx->DriverCtx))
#define GET_DISPATCH_AGE(vmesa) vmesa->sarea->lastDispatch
#define GET_ENQUEUE_AGE(vmesa) vmesa->sarea->lastEnqueue
/* Lock the hardware and validate our state.
*/
/*
#define LOCK_HARDWARE(vmesa) \
do { \
char __ret = 0; \
DRM_CAS(vmesa->driHwLock, vmesa->hHWContext, \
(DRM_LOCK_HELD|vmesa->hHWContext), __ret); \
if (__ret) \
viaGetLock(vmesa, 0); \
} while (0)
*/
/*=* John Sheng [2003.6.20] fix pci *=*/
/*=* John Sheng [2003.7.25] fix viewperf black shadow *=*/
#define LOCK_HARDWARE(vmesa) \
if(1) \
do { \
char __ret = 0; \
DRM_CAS(vmesa->driHwLock, vmesa->hHWContext, \
(DRM_LOCK_HELD|vmesa->hHWContext), __ret); \
if (__ret) \
viaGetLock(vmesa, 0); \
} while (0); \
else \
viaLock(vmesa, 0)
/*
#define LOCK_HARDWARE(vmesa) \
viaLock(vmesa, 0);
*/
/* Release the kernel lock.
*/
/*
#define UNLOCK_HARDWARE(vmesa) \
DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext);
*/
/*=* John Sheng [2003.6.20] fix pci *=*/
/*=* John Sheng [2003.7.25] fix viewperf black shadow *=*/
#define UNLOCK_HARDWARE(vmesa) \
if(1) \
DRM_UNLOCK(vmesa->driFd, vmesa->driHwLock, vmesa->hHWContext); \
else \
viaUnLock(vmesa, 0);
/*
#define UNLOCK_HARDWARE(vmesa) \
viaUnLock(vmesa, 0);
*/
#define WAIT_IDLE \
while (1) { \
if ((((GLuint)*vmesa->regEngineStatus) & 0xFFFEFFFF) == 0x00020000) \
break; \
}
#define LOCK_HARDWARE_QUIESCENT(vmesa) \
do { \
LOCK_HARDWARE(vmesa); \
viaRegetLockQuiescent(vmesa); \
} while (0)
extern GLuint VIA_DEBUG;
extern GLuint DRAW_FRONT;
extern void viaGetLock(viaContextPtr vmesa, GLuint flags);
extern void viaLock(viaContextPtr vmesa, GLuint flags);
extern void viaUnLock(viaContextPtr vmesa, GLuint flags);
extern void viaEmitHwStateLocked(viaContextPtr vmesa);
extern void viaEmitScissorValues(viaContextPtr vmesa, int box_nr, int emit);
extern void viaEmitDrawingRectangle(viaContextPtr vmesa);
extern void viaXMesaSetBackClipRects(viaContextPtr vmesa);
extern void viaXMesaSetFrontClipRects(viaContextPtr vmesa);
extern void viaReAllocateBuffers(GLframebuffer *drawbuffer);
extern void viaXMesaWindowMoved(viaContextPtr vmesa);
#define SUBPIXEL_X -.5
#define SUBPIXEL_Y -.5
/* TODO XXX _SOLO temp defines to make code compilable */
#ifndef GLX_PBUFFER_BIT
#define GLX_PBUFFER_BIT 0x00000004
#endif
#ifndef GLX_WINDOW_BIT
#define GLX_WINDOW_BIT 0x00000001
#endif
#ifndef VERT_CLIP
#define VERT_CLIP 0x1000000
#endif
#ifndef VERT_RGBA
#define VERT_RGBA 0x2
#endif
#ifndef PRIM_PARITY
#define PRIM_PARITY 0x400
#endif
#ifndef PRIM_LAST
#define PRIM_LAST 0x800
#endif
#ifndef VERT_TEX
#define VERT_TEX _TNL_BIT_TEX
#endif
typedef enum Bool { FALSE, TRUE } Bool;
#endif

View file

@ -0,0 +1,759 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#if HAVE_RGBA
#define VERT_SET_IND(v, c) (void)c
#define VERT_COPY_IND(v0, v1)
#define VERT_SAVE_IND(idx)
#define VERT_RESTORE_IND(idx)
#if HAVE_BACK_COLORS
#define VERT_SET_RGBA(v, c)
#endif
#else
#define VERT_SET_RGBA(v, c) (void)c
#define VERT_COPY_RGBA(v0, v1)
#define VERT_SAVE_RGBA(idx)
#define VERT_RESTORE_RGBA(idx)
#if HAVE_BACK_COLORS
#define VERT_SET_IND(v, c)
#endif
#endif
#if !HAVE_SPEC
#define VERT_SET_SPEC(v, c) (void)c
#define VERT_COPY_SPEC(v0, v1)
#define VERT_SAVE_SPEC(idx)
#define VERT_RESTORE_SPEC(idx)
#if HAVE_BACK_COLORS
#define VERT_COPY_SPEC1(v)
#endif
#else
#if HAVE_BACK_COLORS
#define VERT_SET_SPEC(v, c)
#endif
#endif
#if !HAVE_BACK_COLORS
#define VERT_COPY_SPEC1(v)
#define VERT_COPY_IND1(v)
#define VERT_COPY_RGBA1(v)
#endif
#ifndef INSANE_VERTICES
#define VERT_SET_Z(v, val) VERT_Z(v) = val
#define VERT_Z_ADD(v, val) VERT_Z(v) += val
#endif
#if DO_TRI
static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2)
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
VERTEX *v[3];
GLfloat offset;
GLfloat z[3];
GLenum mode = GL_FILL;
GLuint facing;
LOCAL_VARS(3);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
v[0] = (VERTEX *)GET_VERTEX(e0);
v[1] = (VERTEX *)GET_VERTEX(e1);
v[2] = (VERTEX *)GET_VERTEX(e2);
if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) {
GLfloat ex = VERT_X(v[0]) - VERT_X(v[2]);
GLfloat ey = VERT_Y(v[0]) - VERT_Y(v[2]);
GLfloat fx = VERT_X(v[1]) - VERT_X(v[2]);
GLfloat fy = VERT_Y(v[1]) - VERT_Y(v[2]);
GLfloat cc = ex * fy - ey * fx;
if (DO_TWOSIDE || DO_UNFILLED) {
facing = AREA_IS_CCW(cc) ^ ctx->Polygon._FrontBit;
if (DO_UNFILLED) {
if (facing) {
mode = ctx->Polygon.BackMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode != GL_FRONT) {
return;
}
}
else {
mode = ctx->Polygon.FrontMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode != GL_BACK) {
return;
}
}
}
if (DO_TWOSIDE && facing == 1) {
if (HAVE_RGBA) {
if (HAVE_BACK_COLORS) {
if (!DO_FLAT) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_COPY_RGBA1(v[0]);
VERT_COPY_RGBA1(v[1]);
}
VERT_SAVE_RGBA(2);
VERT_COPY_RGBA1(v[2]);
if (HAVE_SPEC) {
if (!DO_FLAT) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_COPY_SPEC1(v[0]);
VERT_COPY_SPEC1(v[1]);
}
VERT_SAVE_SPEC(2);
VERT_COPY_SPEC1(v[2]);
}
}
else {
GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
ASSERT(VB->ColorPtr[1]->stride == 4*sizeof(GLfloat));
(void)vbcolor;
if (!DO_FLAT) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_SET_RGBA(v[0], vbcolor[e0]);
VERT_SET_RGBA(v[1], vbcolor[e1]);
}
VERT_SAVE_RGBA(2);
VERT_SET_RGBA(v[2], vbcolor[e2]);
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
if (!DO_FLAT) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_SET_SPEC(v[0], vbspec[e0]);
VERT_SET_SPEC(v[1], vbspec[e1]);
}
VERT_SAVE_SPEC(2);
VERT_SET_SPEC(v[2], vbspec[e2]);
}
}
}
else {
GLfloat *vbindex = (GLfloat*) VB->IndexPtr[1]->data;
if (!DO_FLAT) {
//VERT_SAVE_IND( 0 );
//VERT_SAVE_IND( 1 );
VERT_SET_IND(v[0], vbindex[e0]);
VERT_SET_IND(v[1], vbindex[e1]);
}
//VERT_SAVE_IND( 2 );
VERT_SET_IND(v[2], vbindex[e2]);
}
}
}
if (DO_OFFSET) {
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
z[0] = VERT_Z(v[0]);
z[1] = VERT_Z(v[1]);
z[2] = VERT_Z(v[2]);
if (cc * cc > 1e-16) {
GLfloat ic = 1.0 / cc;
GLfloat ez = z[0] - z[2];
GLfloat fz = z[1] - z[2];
GLfloat a = ey * fz - ez * fy;
GLfloat b = ez * fx - ex * fz;
GLfloat ac = a * ic;
GLfloat bc = b * ic;
if (ac < 0.0f) ac = -ac;
if (bc < 0.0f) bc = -bc;
offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
}
offset *= ctx->MRD;
}
}
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_COPY_RGBA(v[0], v[2]);
VERT_COPY_RGBA(v[1], v[2]);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_COPY_SPEC(v[0], v[2]);
VERT_COPY_SPEC(v[1], v[2]);
}
}
else {
VERT_SAVE_IND(0);
VERT_SAVE_IND(1);
VERT_COPY_IND(v[0], v[2]);
VERT_COPY_IND(v[1], v[2]);
}
}
if (mode == GL_POINT) {
if (DO_OFFSET && ctx->Polygon.OffsetPoint) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
}
UNFILLED_TRI(ctx, GL_POINT, e0, e1, e2);
}
else if (mode == GL_LINE) {
if (DO_OFFSET && ctx->Polygon.OffsetLine) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
}
UNFILLED_TRI(ctx, GL_LINE, e0, e1, e2);
}
else {
if (DO_OFFSET && ctx->Polygon.OffsetFill) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
}
if (DO_UNFILLED)
RASTERIZE(GL_TRIANGLES);
TRI(v[0], v[1], v[2]);
}
if (DO_OFFSET) {
VERT_SET_Z(v[0], z[0]);
VERT_SET_Z(v[1], z[1]);
VERT_SET_Z(v[2], z[2]);
}
if (DO_TWOSIDE && facing == 1) {
if (HAVE_RGBA) {
if (!DO_FLAT) {
VERT_RESTORE_RGBA(0);
VERT_RESTORE_RGBA(1);
}
VERT_RESTORE_RGBA(2);
if (HAVE_SPEC) {
if (!DO_FLAT) {
VERT_RESTORE_SPEC(0);
VERT_RESTORE_SPEC(1);
}
VERT_RESTORE_SPEC(2);
}
}
else {
#if 0 // XXX TODO _SOLO
GLuint *vbindex = VB->IndexPtr[0]->data;
if (!DO_FLAT) {
VERT_SET_IND(v[0], vbindex[e0]);
VERT_SET_IND(v[1], vbindex[e1]);
}
VERT_SET_IND(v[2], vbindex[e2]);
#else
if (!DO_FLAT) {
VERT_RESTORE_IND( 0 );
VERT_RESTORE_IND( 1 );
}
VERT_RESTORE_IND( 2 );
#endif
}
}
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_RESTORE_RGBA(0);
VERT_RESTORE_RGBA(1);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_RESTORE_SPEC(0);
VERT_RESTORE_SPEC(1);
}
}
else {
VERT_RESTORE_IND(0);
VERT_RESTORE_IND(1);
}
}
SET_PRIMITIVE_RENDERED
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
#endif
#if DO_QUAD
#if DO_FULL_QUAD
static void TAG(quad)(GLcontext *ctx,
GLuint e0, GLuint e1, GLuint e2, GLuint e3)
{
struct vertex_buffer *VB = &TNL_CONTEXT( ctx )->vb;
VERTEX *v[4];
GLfloat offset;
GLfloat z[4];
GLenum mode = GL_FILL;
GLuint facing;
LOCAL_VARS(4);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
v[0] = (VERTEX *)GET_VERTEX(e0);
v[1] = (VERTEX *)GET_VERTEX(e1);
v[2] = (VERTEX *)GET_VERTEX(e2);
v[3] = (VERTEX *)GET_VERTEX(e3);
if (DO_TWOSIDE || DO_OFFSET || DO_UNFILLED) {
GLfloat ex = VERT_X(v[2]) - VERT_X(v[0]);
GLfloat ey = VERT_Y(v[2]) - VERT_Y(v[0]);
GLfloat fx = VERT_X(v[3]) - VERT_X(v[1]);
GLfloat fy = VERT_Y(v[3]) - VERT_Y(v[1]);
GLfloat cc = ex * fy - ey * fx;
if (DO_TWOSIDE || DO_UNFILLED) {
facing = AREA_IS_CCW(cc) ^ ctx->Polygon._FrontBit;
if (DO_UNFILLED) {
if (facing) {
mode = ctx->Polygon.BackMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode != GL_FRONT) {
return;
}
}
else {
mode = ctx->Polygon.FrontMode;
if (ctx->Polygon.CullFlag &&
ctx->Polygon.CullFaceMode != GL_BACK) {
return;
}
}
}
if (DO_TWOSIDE && facing == 1) {
if (HAVE_RGBA) {
GLfloat (*vbcolor)[4] = VB->ColorPtr[1]->data;
(void)vbcolor;
if (HAVE_BACK_COLORS) {
if (!DO_FLAT) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_SAVE_RGBA(2);
VERT_COPY_RGBA1(v[0]);
VERT_COPY_RGBA1(v[1]);
VERT_COPY_RGBA1(v[2]);
}
VERT_SAVE_RGBA(3);
VERT_COPY_RGBA1(v[3]);
if (HAVE_SPEC) {
if (!DO_FLAT) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_SAVE_SPEC(2);
VERT_COPY_SPEC1(v[0]);
VERT_COPY_SPEC1(v[1]);
VERT_COPY_SPEC1(v[2]);
}
VERT_SAVE_SPEC(3);
VERT_COPY_SPEC1(v[3]);
}
}
else {
if (!DO_FLAT) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_SAVE_RGBA(2);
VERT_SET_RGBA(v[0], vbcolor[e0]);
VERT_SET_RGBA(v[1], vbcolor[e1]);
VERT_SET_RGBA(v[2], vbcolor[e2]);
}
VERT_SAVE_RGBA(3);
VERT_SET_RGBA(v[3], vbcolor[e3]);
if (HAVE_SPEC && VB->SecondaryColorPtr[1]) {
GLfloat (*vbspec)[4] = VB->SecondaryColorPtr[1]->data;
ASSERT(VB->SecondaryColorPtr[1]->stride==4*sizeof(GLfloat));
if (!DO_FLAT) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_SAVE_SPEC(2);
VERT_SET_SPEC(v[0], vbspec[e0]);
VERT_SET_SPEC(v[1], vbspec[e1]);
VERT_SET_SPEC(v[2], vbspec[e2]);
}
VERT_SAVE_SPEC(3);
VERT_SET_SPEC(v[3], vbspec[e3]);
}
}
}
else {
GLfloat *vbindex = (GLfloat*) VB->IndexPtr[1]->data;
if (!DO_FLAT) {
//VERT_SAVE_IND( 0 );
//VERT_SAVE_IND( 1 );
//VERT_SAVE_IND( 2 );
VERT_SET_IND(v[0], vbindex[e0]);
VERT_SET_IND(v[1], vbindex[e1]);
VERT_SET_IND(v[2], vbindex[e2]);
}
//VERT_SAVE_IND( 3 );
VERT_SET_IND(v[3], vbindex[e3]);
}
}
}
if (DO_OFFSET) {
offset = ctx->Polygon.OffsetUnits * DEPTH_SCALE;
z[0] = VERT_Z(v[0]);
z[1] = VERT_Z(v[1]);
z[2] = VERT_Z(v[2]);
z[3] = VERT_Z(v[3]);
if (cc * cc > 1e-16) {
GLfloat ez = z[2] - z[0];
GLfloat fz = z[3] - z[1];
GLfloat a = ey * fz - ez * fy;
GLfloat b = ez * fx - ex * fz;
GLfloat ic = 1.0 / cc;
GLfloat ac = a * ic;
GLfloat bc = b * ic;
if ( ac < 0.0f ) ac = -ac;
if ( bc < 0.0f ) bc = -bc;
offset += MAX2(ac, bc) * ctx->Polygon.OffsetFactor;
}
offset *= ctx->MRD;
}
}
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_SAVE_RGBA(0);
VERT_SAVE_RGBA(1);
VERT_SAVE_RGBA(2);
VERT_COPY_RGBA(v[0], v[3]);
VERT_COPY_RGBA(v[1], v[3]);
VERT_COPY_RGBA(v[2], v[3]);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_SAVE_SPEC(0);
VERT_SAVE_SPEC(1);
VERT_SAVE_SPEC(2);
VERT_COPY_SPEC(v[0], v[3]);
VERT_COPY_SPEC(v[1], v[3]);
VERT_COPY_SPEC(v[2], v[3]);
}
}
else {
VERT_SAVE_IND(0);
VERT_SAVE_IND(1);
VERT_SAVE_IND(2);
VERT_COPY_IND(v[0], v[3]);
VERT_COPY_IND(v[1], v[3]);
VERT_COPY_IND(v[2], v[3]);
}
}
if (mode == GL_POINT) {
if (( DO_OFFSET) && ctx->Polygon.OffsetPoint) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
VERT_Z_ADD(v[3], offset);
}
UNFILLED_QUAD(ctx, GL_POINT, e0, e1, e2, e3);
}
else if (mode == GL_LINE) {
if (DO_OFFSET && ctx->Polygon.OffsetLine) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
VERT_Z_ADD(v[3], offset);
}
UNFILLED_QUAD(ctx, GL_LINE, e0, e1, e2, e3);
}
else {
if (DO_OFFSET && ctx->Polygon.OffsetFill) {
VERT_Z_ADD(v[0], offset);
VERT_Z_ADD(v[1], offset);
VERT_Z_ADD(v[2], offset);
VERT_Z_ADD(v[3], offset);
}
RASTERIZE(GL_TRIANGLES);
QUAD((v[0]), (v[1]), (v[2]), (v[3]));
}
if (DO_OFFSET) {
VERT_SET_Z(v[0], z[0]);
VERT_SET_Z(v[1], z[1]);
VERT_SET_Z(v[2], z[2]);
VERT_SET_Z(v[3], z[3]);
}
if (DO_TWOSIDE && facing == 1) {
if (HAVE_RGBA) {
if (!DO_FLAT) {
VERT_RESTORE_RGBA(0);
VERT_RESTORE_RGBA(1);
VERT_RESTORE_RGBA(2);
}
VERT_RESTORE_RGBA(3);
if (HAVE_SPEC) {
if (!DO_FLAT) {
VERT_RESTORE_SPEC(0);
VERT_RESTORE_SPEC(1);
VERT_RESTORE_SPEC(2);
}
VERT_RESTORE_SPEC(3);
}
}
else {
#if 0 // XXX TODO _SOLO
GLuint *vbindex = VB->IndexPtr[0]->data;
if (!DO_FLAT) {
VERT_SET_IND(v[0], vbindex[e0]);
VERT_SET_IND(v[1], vbindex[e1]);
VERT_SET_IND(v[2], vbindex[e2]);
}
VERT_SET_IND(v[3], vbindex[e3]);
#else
if (!DO_FLAT) {
VERT_RESTORE_IND( 0 );
VERT_RESTORE_IND( 1 );
VERT_RESTORE_IND( 2 );
}
VERT_RESTORE_IND( 3 );
#endif
}
}
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_RESTORE_RGBA(0);
VERT_RESTORE_RGBA(1);
VERT_RESTORE_RGBA(2);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_RESTORE_SPEC(0);
VERT_RESTORE_SPEC(1);
VERT_RESTORE_SPEC(2);
}
}
else {
VERT_RESTORE_IND(0);
VERT_RESTORE_IND(1);
VERT_RESTORE_IND(2);
}
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
#else
static void TAG(quad)(GLcontext *ctx, GLuint e0,
GLuint e1, GLuint e2, GLuint e3)
{
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
if (DO_UNFILLED) {
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte ef1 = VB->EdgeFlag[e1];
GLubyte ef3 = VB->EdgeFlag[e3];
VB->EdgeFlag[e1] = 0;
TAG(triangle)(ctx, e0, e1, e3);
VB->EdgeFlag[e1] = ef1;
VB->EdgeFlag[e3] = 0;
TAG(triangle)(ctx, e1, e2, e3);
VB->EdgeFlag[e3] = ef3;
}
else {
TAG(triangle)(ctx, e0, e1, e3);
TAG(triangle)(ctx, e1, e2, e3);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
#endif
#endif
#if DO_LINE
static void TAG(line)(GLcontext *ctx, GLuint e0, GLuint e1)
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
VERTEX *v[2];
LOCAL_VARS(2);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
v[0] = (VERTEX *)GET_VERTEX(e0);
v[1] = (VERTEX *)GET_VERTEX(e1);
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_SAVE_RGBA( 0 );
VERT_COPY_RGBA( v[0], v[1] );
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_SAVE_SPEC(0);
VERT_COPY_SPEC(v[0], v[1]);
}
}
else {
VERT_SAVE_IND(0);
VERT_COPY_IND(v[0], v[1]);
}
}
LINE(v[0], v[1]);
if (DO_FLAT) {
if (HAVE_RGBA) {
VERT_RESTORE_RGBA(0);
if (HAVE_SPEC && VB->SecondaryColorPtr[0]) {
VERT_RESTORE_SPEC(0);
}
}
else {
VERT_RESTORE_IND(0);
}
}
SET_PRIMITIVE_RENDERED
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
#endif
#if DO_POINTS
static void TAG(points)(GLcontext *ctx, GLuint first, GLuint last)
{
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
int i;
LOCAL_VARS(1);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
if (VB->Elts == 0) {
for (i = first; i < last; i++) {
if (VB->ClipMask[i] == 0) {
VERTEX *v = (VERTEX *)GET_VERTEX(i);
POINT(v);
SET_PRIMITIVE_RENDERED
}
}
}
else {
for (i = first; i < last; i++) {
GLuint e = VB->Elts[i];
if (VB->ClipMask[e] == 0) {
VERTEX *v = (VERTEX *)GET_VERTEX(e);
POINT(v);
SET_PRIMITIVE_RENDERED
}
}
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
#endif
static void TAG(init)(void)
{
#if DO_QUAD
TAB[IND].quad = TAG(quad);
#endif
#if DO_TRI
TAB[IND].triangle = TAG(triangle);
#endif
#if DO_LINE
TAB[IND].line = TAG(line);
#endif
#if DO_POINTS
TAB[IND].points = TAG(points);
#endif
}
#undef IND
#undef TAG
#if HAVE_RGBA
#undef VERT_SET_IND
#undef VERT_COPY_IND
#undef VERT_SAVE_IND
#undef VERT_RESTORE_IND
#if HAVE_BACK_COLORS
#undef VERT_SET_RGBA
#endif
#else
#undef VERT_SET_RGBA
#undef VERT_COPY_RGBA
#undef VERT_SAVE_RGBA
#undef VERT_RESTORE_RGBA
#if HAVE_BACK_COLORS
#undef VERT_SET_IND
#endif
#endif
#if !HAVE_SPEC
#undef VERT_SET_SPEC
#undef VERT_COPY_SPEC
#undef VERT_SAVE_SPEC
#undef VERT_RESTORE_SPEC
#if HAVE_BACK_COLORS
#undef VERT_COPY_SPEC1
#endif
#else
#if HAVE_BACK_COLORS
#undef VERT_SET_SPEC
#endif
#endif
#if !HAVE_BACK_COLORS
#undef VERT_COPY_SPEC1
#undef VERT_COPY_IND1
#undef VERT_COPY_RGBA1
#endif
#ifndef INSANE_VERTICES
#undef VERT_SET_Z
#undef VERT_Z_ADD
#endif

View file

@ -0,0 +1,731 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/* Unlike the other templates here, this assumes quite a bit about the
* underlying hardware. Specifically it assumes a d3d-like vertex
* format, with a layout more or less constrained to look like the
* following:
*
* union {
* struct {
* float x, y, z, w;
* struct { char r, g, b, a; } color;
* struct { char r, g, b, fog; } spec;
* float u0, v0;
* float u1, v1;
* float u2, v2;
* float u3, v3;
* } v;
* struct {
* float x, y, z, w;
* struct { char r, g, b, a; } color;
* struct { char r, g, b, fog; } spec;
* float u0, v0, q0;
* float u1, v1, q1;
* float u2, v2, q2;
* float u3, v3, q3;
* } pv;
* struct {
* float x, y, z;
* struct { char r, g, b, a; } color;
* } tv;
* float f[16];
* unsigned int ui[16];
* unsigned char ub4[4][16];
* }
*
* DO_XYZW: Emit xyz and maybe w coordinates.
* DO_RGBA: Emit color.
* DO_SPEC: Emit specular color.
* DO_FOG: Emit fog coordinate in specular alpha.
* DO_TEX0: Emit tex0 u,v coordinates.
* DO_TEX1: Emit tex1 u,v coordinates.
* DO_TEX2: Emit tex2 u,v coordinates.
* DO_TEX3: Emit tex3 u,v coordinates.
* DO_PTEX: Emit tex0,1,2,3 q coordinates where possible.
*
* HAVE_RGBA_COLOR: Hardware takes color in rgba order (else bgra).
*
* HAVE_HW_VIEWPORT: Hardware performs viewport transform.
* HAVE_HW_DIVIDE: Hardware performs perspective divide.
*
* HAVE_TINY_VERTICES: Hardware understands v.tv format.
* HAVE_PTEX_VERTICES: Hardware understands v.pv format.
* HAVE_NOTEX_VERTICES: Hardware understands v.v format with texcount 0.
*
* Additionally, this template assumes it is emitting *transformed*
* vertices; the modifications to emit untransformed vertices (ie. to
* t&l hardware) are probably too great to cooexist with the code
* already in this file.
*
* NOTE: The PTEX vertex format always includes TEX0 and TEX1, even if
* only TEX0 is enabled, in order to maintain a vertex size which is
* an exact number of quadwords.
*/
#if (HAVE_HW_VIEWPORT)
#define VIEWPORT_X(dst, x) dst = x
#define VIEWPORT_Y(dst, y) dst = y
#define VIEWPORT_Z(dst, z) dst = z
#else
#define VIEWPORT_X(dst, x) dst = s[0] * x + s[12]
#define VIEWPORT_Y(dst, y) dst = s[5] * y + s[13]
#define VIEWPORT_Z(dst, z) dst = s[10] * z + s[14]
#endif
#if (HAVE_HW_DIVIDE && !HAVE_PTEX_VERTICES)
#error "can't cope with this combination"
#endif
#ifndef LOCALVARS
#define LOCALVARS
#endif
#ifndef CHECK_HW_DIVIDE
#define CHECK_HW_DIVIDE 1
#endif
#if (HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICES)
static void TAG(emit)(GLcontext *ctx,
GLuint start, GLuint end,
void *dest,
GLuint stride)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLfloat (*tc0)[4], (*tc1)[4], (*fog)[4];
GLfloat (*tc2)[4], (*tc3)[4];
GLfloat (*col)[4], (*spec)[4];
GLuint tc0_stride, tc1_stride, col_stride, spec_stride, fog_stride;
GLuint tc2_stride, tc3_stride;
GLuint tc0_size, tc1_size;
GLuint tc2_size, tc3_size;
GLfloat (*coord)[4];
GLuint coord_stride;
VERTEX *v = (VERTEX *)dest;
const GLfloat *s = GET_VIEWPORT_MAT();
const GLubyte *mask = VB->ClipMask;
int i;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "TAG-emit for HAVE_HW_DIVIDE || DO_SPEC || DO_TEX0 || DO_FOG || !HAVE_TINY_VERTICE\n");
#endif
if (HAVE_HW_VIEWPORT && HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
(void) s;
coord = VB->ClipPtr->data;
coord_stride = VB->ClipPtr->stride;
}
else {
coord = VB->NdcPtr->data;
coord_stride = VB->NdcPtr->stride;
}
if (DO_TEX3) {
const GLuint t3 = GET_TEXSOURCE(3);
tc3 = VB->TexCoordPtr[t3]->data;
tc3_stride = VB->TexCoordPtr[t3]->stride;
if (DO_PTEX)
tc3_size = VB->TexCoordPtr[t3]->size;
}
if (DO_TEX2) {
const GLuint t2 = GET_TEXSOURCE(2);
tc2 = VB->TexCoordPtr[t2]->data;
tc2_stride = VB->TexCoordPtr[t2]->stride;
if (DO_PTEX)
tc2_size = VB->TexCoordPtr[t2]->size;
}
if (DO_TEX1) {
const GLuint t1 = GET_TEXSOURCE(1);
tc1 = VB->TexCoordPtr[t1]->data;
tc1_stride = VB->TexCoordPtr[t1]->stride;
if (DO_PTEX)
tc1_size = VB->TexCoordPtr[t1]->size;
}
if (DO_TEX0) {
const GLuint t0 = GET_TEXSOURCE(0);
/* test */
tc0_stride = VB->TexCoordPtr[t0]->stride;
tc0 = VB->TexCoordPtr[t0]->data;
if (DO_PTEX)
tc0_size = VB->TexCoordPtr[t0]->size;
}
if (DO_RGBA) {
col = VB->ColorPtr[0]->data;
col_stride = VB->ColorPtr[0]->stride;
}
if (DO_SPEC) {
spec = VB->SecondaryColorPtr[0]->data;
spec_stride = VB->SecondaryColorPtr[0]->stride;
}
if (DO_FOG) {
if (VB->FogCoordPtr) {
fog = VB->FogCoordPtr->data;
fog_stride = VB->FogCoordPtr->stride;
}
else {
static GLfloat tmp[4] = { 0, 0, 0, 0 };
fog = &tmp;
fog_stride = 0;
}
}
/* May have nonstandard strides:
*/
if (start) {
STRIDE_4F(coord, start * coord_stride);
if (DO_TEX0)
STRIDE_4F(tc0, start * tc0_stride);
if (DO_TEX1)
STRIDE_4F(tc1, start * tc1_stride);
if (DO_TEX2)
STRIDE_4F(tc2, start * tc2_stride);
if (DO_TEX3)
STRIDE_4F(tc3, start * tc3_stride);
if (DO_RGBA)
STRIDE_4F(col, start * col_stride);
if (DO_SPEC)
STRIDE_4F(spec, start * spec_stride);
if (DO_FOG)
STRIDE_4F(fog, start * fog_stride);
}
for (i = start; i < end; i++, v = (VERTEX *)((GLubyte *)v + stride)) {
if (DO_XYZW) {
if (HAVE_HW_VIEWPORT || mask[i] == 0) {
VIEWPORT_X(v->v.x, coord[0][0]);
VIEWPORT_Y(v->v.y, coord[0][1]);
VIEWPORT_Z(v->v.z, coord[0][2]);
}
v->v.w = coord[0][3];
STRIDE_4F(coord, coord_stride);
}
if (DO_RGBA) {
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.red, col[0][0]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.green, col[0][1]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.blue, col[0][2]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.color.alpha, col[0][3]);
STRIDE_4F(col, col_stride);
}
if (DO_SPEC) {
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.red, spec[0][0]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.green, spec[0][1]);
UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.blue, spec[0][2]);
STRIDE_4F(spec, spec_stride);
}
else {
v->v.specular.red = 0;
v->v.specular.green = 0;
v->v.specular.blue = 0;
}
if (DO_FOG) {
//UNCLAMPED_FLOAT_TO_UBYTE(v->v.specular.alpha, fog[0][0]);
v->v.specular.alpha = fog[0][0];
/*=* [DBG] exy : fix lighting on + fog off error *=*/
STRIDE_4F(fog, fog_stride);
}
else {
v->v.specular.alpha = 0.0;
}
if (DO_TEX0) {
v->v.u0 = tc0[0][0];
v->v.v0 = tc0[0][1];
if (DO_PTEX) {
if (HAVE_PTEX_VERTICES) {
if (tc0_size == 4)
v->pv.q0 = tc0[0][3];
else
v->pv.q0 = 1.0;
}
else if (tc0_size == 4) {
float rhw = 1.0 / tc0[0][3];
v->v.w *= tc0[0][3];
v->v.u0 *= rhw;
v->v.v0 *= rhw;
}
}
STRIDE_4F(tc0, tc0_stride);
}
if (DO_TEX1) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
v->pv.u1 = tc1[0][0];
v->pv.v1 = tc1[0][1];
if (tc1_size == 4)
v->pv.q1 = tc1[0][3];
else
v->pv.q1 = 1.0;
}
else {
v->v.u1 = tc1[0][0];
v->v.v1 = tc1[0][1];
}
STRIDE_4F(tc1, tc1_stride);
}
else if (DO_PTEX) {
*(GLuint *)&v->pv.q1 = 0;
}
if (DO_TEX2) {
if (DO_PTEX) {
v->pv.u2 = tc2[0][0];
v->pv.v2 = tc2[0][1];
if (tc2_size == 4)
v->pv.q2 = tc2[0][3];
else
v->pv.q2 = 1.0;
}
else {
v->v.u2 = tc2[0][0];
v->v.v2 = tc2[0][1];
}
STRIDE_4F(tc2, tc2_stride);
}
if (DO_TEX3) {
if (DO_PTEX) {
v->pv.u3 = tc3[0][0];
v->pv.v3 = tc3[0][1];
if (tc3_size == 4)
v->pv.q3 = tc3[0][3];
else
v->pv.q3 = 1.0;
}
else {
v->v.u3 = tc3[0][0];
v->v.v3 = tc3[0][1];
}
STRIDE_4F(tc3, tc3_stride);
}
}
}
#else
#if DO_XYZW
#if HAVE_HW_DIVIDE
#error "cannot use tiny vertices with hw perspective divide"
#endif
static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
void *dest, GLuint stride)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLfloat (*col)[4];
GLuint col_stride;
GLfloat (*coord)[4] = VB->NdcPtr->data;
GLuint coord_stride = VB->NdcPtr->stride;
GLfloat *v = (GLfloat *)dest;
const GLubyte *mask = VB->ClipMask;
const GLfloat *s = GET_VIEWPORT_MAT();
int i;
(void) s;
//ASSERT(stride == 4);
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "TAG-emit for DO_XYZW\n");
fprintf(stderr, "%s\n", __FUNCTION__);
}
#endif
col = VB->ColorPtr[0]->data;
col_stride = VB->ColorPtr[0]->stride;
if (start) {
STRIDE_4F(coord, start * coord_stride);
STRIDE_4F(col, start * col_stride);
}
for (i = start; i < end; i++, v += 4) {
if (DO_XYZW) {
if (HAVE_HW_VIEWPORT || mask[i] == 0) {
VIEWPORT_X(v[0], coord[0][0]);
VIEWPORT_Y(v[1], coord[0][1]);
VIEWPORT_Z(v[2], coord[0][2]);
}
STRIDE_4F(coord, coord_stride);
}
if (DO_RGBA) {
VERTEX_COLOR *c = (VERTEX_COLOR *)&v[3];
UNCLAMPED_FLOAT_TO_UBYTE(c->red, col[0][0]);
UNCLAMPED_FLOAT_TO_UBYTE(c->green, col[0][1]);
UNCLAMPED_FLOAT_TO_UBYTE(c->blue, col[0][2]);
UNCLAMPED_FLOAT_TO_UBYTE(c->alpha, col[0][3]);
STRIDE_4F( col, col_stride );
}
}
}
#else
static void TAG(emit)(GLcontext *ctx, GLuint start, GLuint end,
void *dest, GLuint stride)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte (*col)[4];
GLuint col_stride;
GLfloat *v = (GLfloat *)dest;
int i;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "TAG-emit for No DO_XYZW\n");
fprintf(stderr, "%s\n", __FUNCTION__);
}
#endif
if (VB->ColorPtr[0]->Type != GL_UNSIGNED_BYTE)
IMPORT_FLOAT_COLORS( ctx );
col = VB->ColorPtr[0]->Ptr;
col_stride = VB->ColorPtr[0]->StrideB;
if (start)
STRIDE_4UB(col, col_stride * start);
/* Need to figure out where color is:
*/
if (GET_VERTEX_FORMAT() == TINY_VERTEX_FORMAT)
v += 3;
else
v += 4;
for (i = start; i < end; i++, STRIDE_F(v, stride)) {
if (HAVE_RGBA_COLOR) {
*(GLuint *)v = *(GLuint *)col[0];
}
else {
GLubyte *b = (GLubyte *)v;
b[0] = col[0][2];
b[1] = col[0][1];
b[2] = col[0][0];
b[3] = col[0][3];
}
STRIDE_4UB(col, col_stride);
}
}
#endif /* emit */
#endif /* emit */
#if (DO_XYZW) && (DO_RGBA)
#if (HAVE_PTEX_VERTICES)
static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
/* Force 'missing' texcoords to something valid.
*/
#ifdef DEBUG
fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
if (DO_TEX1 && VB->TexCoordPtr[0] == 0)
VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
if (DO_PTEX)
return GL_TRUE;
if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
(DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
(DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4) ||
(DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4))
return GL_FALSE;
#ifdef DEBUG
fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_TRUE;
}
#else
static GLboolean TAG(check_tex_sizes)(GLcontext *ctx)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
/* Force 'missing' texcoords to something valid.
*/
if (DO_TEX3 && VB->TexCoordPtr[2] == 0)
VB->TexCoordPtr[2] = VB->TexCoordPtr[3];
if (DO_TEX2 && VB->TexCoordPtr[1] == 0)
VB->TexCoordPtr[1] = VB->TexCoordPtr[2];
if (DO_TEX1 && VB->TexCoordPtr[0] == 0) {
VB->TexCoordPtr[0] = VB->TexCoordPtr[1];
}
if (DO_PTEX)
return GL_TRUE;
if ((DO_TEX3 && VB->TexCoordPtr[GET_TEXSOURCE(3)]->size == 4) ||
(DO_TEX2 && VB->TexCoordPtr[GET_TEXSOURCE(2)]->size == 4) ||
(DO_TEX1 && VB->TexCoordPtr[GET_TEXSOURCE(1)]->size == 4)) {
/*PTEX_FALLBACK();*/
return GL_FALSE;
}
if (DO_TEX0 && VB->TexCoordPtr[GET_TEXSOURCE(0)]->size == 4) {
if (DO_TEX1 || DO_TEX2 || DO_TEX3) {
/*PTEX_FALLBACK();*/
}
return GL_FALSE;
}
return GL_TRUE;
}
#endif /* ptex */
static void TAG(interp)(GLcontext *ctx,
GLfloat t,
GLuint edst, GLuint eout, GLuint ein,
GLboolean force_boundary)
{
LOCALVARS
struct vertex_buffer *VB = &TNL_CONTEXT(ctx)->vb;
GLubyte *ddverts = GET_VERTEX_STORE();
GLuint shift = GET_VERTEX_STRIDE_SHIFT();
const GLfloat *dstclip = VB->ClipPtr->data[edst];
GLfloat w;
const GLfloat *s = GET_VIEWPORT_MAT();
VERTEX *dst = (VERTEX *)(ddverts + (edst << shift));
VERTEX *in = (VERTEX *)(ddverts + (ein << shift));
VERTEX *out = (VERTEX *)(ddverts + (eout << shift));
(void)s;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
if (HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) {
VIEWPORT_X(dst->v.x, dstclip[0]);
VIEWPORT_Y(dst->v.y, dstclip[1]);
VIEWPORT_Z(dst->v.z, dstclip[2]);
w = dstclip[3];
}
else {
w = 1.0 / dstclip[3];
VIEWPORT_X(dst->v.x, dstclip[0] * w);
VIEWPORT_Y(dst->v.y, dstclip[1] * w);
VIEWPORT_Z(dst->v.z, dstclip[2] * w);
}
if ((HAVE_HW_DIVIDE && CHECK_HW_DIVIDE) ||
DO_FOG || DO_SPEC || DO_TEX0 || DO_TEX1 ||
DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES) {
dst->v.w = w;
INTERP_UB(t, dst->ub4[4][0], out->ub4[4][0], in->ub4[4][0]);
INTERP_UB(t, dst->ub4[4][1], out->ub4[4][1], in->ub4[4][1]);
INTERP_UB(t, dst->ub4[4][2], out->ub4[4][2], in->ub4[4][2]);
INTERP_UB(t, dst->ub4[4][3], out->ub4[4][3], in->ub4[4][3]);
if (DO_SPEC) {
INTERP_UB(t, dst->ub4[5][0], out->ub4[5][0], in->ub4[5][0]);
INTERP_UB(t, dst->ub4[5][1], out->ub4[5][1], in->ub4[5][1]);
INTERP_UB(t, dst->ub4[5][2], out->ub4[5][2], in->ub4[5][2]);
}
if (DO_FOG) {
INTERP_UB(t, dst->ub4[5][3], out->ub4[5][3], in->ub4[5][3]);
}
if (DO_TEX0) {
if (DO_PTEX) {
if (HAVE_PTEX_VERTICES) {
INTERP_F(t, dst->pv.u0, out->pv.u0, in->pv.u0);
INTERP_F(t, dst->pv.v0, out->pv.v0, in->pv.v0);
INTERP_F(t, dst->pv.q0, out->pv.q0, in->pv.q0);
}
else {
INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
}
}
else {
INTERP_F(t, dst->v.u0, out->v.u0, in->v.u0);
INTERP_F(t, dst->v.v0, out->v.v0, in->v.v0);
}
}
if (DO_TEX1) {
if (DO_PTEX) {
if (HAVE_PTEX_VERTICES) {
INTERP_F(t, dst->pv.u1, out->pv.u1, in->pv.u1);
INTERP_F(t, dst->pv.v1, out->pv.v1, in->pv.v1);
INTERP_F(t, dst->pv.q1, out->pv.q1, in->pv.q1);
}
else {
INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
}
}
else {
INTERP_F(t, dst->v.u1, out->v.u1, in->v.u1);
INTERP_F(t, dst->v.v1, out->v.v1, in->v.v1);
}
}
else if (DO_PTEX) {
dst->pv.q0 = 0.0; /* must be a valid float on radeon */
}
if (DO_TEX2) {
if (DO_PTEX) {
INTERP_F(t, dst->pv.u2, out->pv.u2, in->pv.u2);
INTERP_F(t, dst->pv.v2, out->pv.v2, in->pv.v2);
INTERP_F(t, dst->pv.q2, out->pv.q2, in->pv.q2);
}
else {
INTERP_F(t, dst->v.u2, out->v.u2, in->v.u2);
INTERP_F(t, dst->v.v2, out->v.v2, in->v.v2);
}
}
if (DO_TEX3) {
if (DO_PTEX) {
INTERP_F(t, dst->pv.u3, out->pv.u3, in->pv.u3);
INTERP_F(t, dst->pv.v3, out->pv.v3, in->pv.v3);
INTERP_F(t, dst->pv.q3, out->pv.q3, in->pv.q3);
}
else {
INTERP_F(t, dst->v.u3, out->v.u3, in->v.u3);
INTERP_F(t, dst->v.v3, out->v.v3, in->v.v3);
}
}
}
else {
/* 4-dword vertex. Color is in v[3] and there is no oow coordinate.
*/
INTERP_UB(t, dst->ub4[3][0], out->ub4[3][0], in->ub4[3][0]);
INTERP_UB(t, dst->ub4[3][1], out->ub4[3][1], in->ub4[3][1]);
INTERP_UB(t, dst->ub4[3][2], out->ub4[3][2], in->ub4[3][2]);
INTERP_UB(t, dst->ub4[3][3], out->ub4[3][3], in->ub4[3][3]);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
#endif /* rgba && xyzw */
static void TAG(init)(void)
{
setup_tab[IND].emit = TAG(emit);
#if (DO_XYZW && DO_RGBA)
setup_tab[IND].check_tex_sizes = TAG(check_tex_sizes);
setup_tab[IND].interp = TAG(interp);
#endif
if (DO_SPEC)
setup_tab[IND].copy_pv = copy_pv_rgba4_spec5;
else if (HAVE_HW_DIVIDE || DO_SPEC || DO_FOG || DO_TEX0 || DO_TEX1 ||
DO_TEX2 || DO_TEX3 || !HAVE_TINY_VERTICES)
setup_tab[IND].copy_pv = copy_pv_rgba4;
else
setup_tab[IND].copy_pv = copy_pv_rgba3;
if (DO_TEX3) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
ASSERT(HAVE_PTEX_VERTICES);
setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 18;
setup_tab[IND].vertex_stride_shift = 7;
}
else {
setup_tab[IND].vertex_format = TEX3_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 14;
setup_tab[IND].vertex_stride_shift = 6;
}
}
else if (DO_TEX2) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
ASSERT(HAVE_PTEX_VERTICES);
setup_tab[IND].vertex_format = PROJ_TEX3_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 18;
setup_tab[IND].vertex_stride_shift = 7;
}
else {
setup_tab[IND].vertex_format = TEX2_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 12;
setup_tab[IND].vertex_stride_shift = 6;
}
}
else if (DO_TEX1) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
ASSERT(HAVE_PTEX_VERTICES);
setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 12;
setup_tab[IND].vertex_stride_shift = 6;
}
else {
setup_tab[IND].vertex_format = TEX1_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 10;
setup_tab[IND].vertex_stride_shift = 6;
}
}
else if (DO_TEX0) {
if (DO_PTEX && HAVE_PTEX_VERTICES) {
setup_tab[IND].vertex_format = PROJ_TEX1_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 12;
setup_tab[IND].vertex_stride_shift = 6;
}
else {
setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 8;
setup_tab[IND].vertex_stride_shift = 5;
}
}
else if (!HAVE_HW_DIVIDE && !DO_SPEC && !DO_FOG && HAVE_TINY_VERTICES) {
setup_tab[IND].vertex_format = TINY_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 4;
setup_tab[IND].vertex_stride_shift = 4;
}
else if (HAVE_NOTEX_VERTICES) {
setup_tab[IND].vertex_format = NOTEX_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 6;
setup_tab[IND].vertex_stride_shift = 5;
}
else {
setup_tab[IND].vertex_format = TEX0_VERTEX_FORMAT;
setup_tab[IND].vertex_size = 8;
setup_tab[IND].vertex_stride_shift = 5;
}
assert(setup_tab[IND].vertex_size * 4 <=
1 << setup_tab[IND].vertex_stride_shift);
}
#undef IND
#undef TAG

View file

@ -0,0 +1,601 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/* Template for render stages which build and emit vertices directly
* to fixed-size dma buffers. Useful for rendering strips and other
* native primitives where clipping and per-vertex tweaks such as
* those in t_dd_tritmp.h are not required.
*
* Produces code for both inline triangles and indexed triangles.
* Where various primitive types are unaccelerated by hardware, the
* code attempts to fallback to other primitive types (quadstrips to
* tristrips, lineloops to linestrips), or to indexed vertices.
* Ultimately, a FALLBACK() macro is invoked if there is no way to
* render the primitive natively.
*/
#if !defined(HAVE_TRIANGLES)
#error "must have at least triangles to use render template"
#endif
#if !HAVE_ELTS
#define ELTS_VARS
#define ALLOC_ELTS(nr)
#define EMIT_ELT(offset, elt)
#define EMIT_TWO_ELTS(offset, elt0, elt1)
#define INCR_ELTS(nr)
#define ELT_INIT(prim)
#define GET_CURRENT_VB_MAX_ELTS() 0
#define GET_SUBSEQUENT_VB_MAX_ELTS() 0
#define ALLOC_ELTS_NEW_PRIMITIVE(nr)
#define RELEASE_ELT_VERTS()
#define EMIT_INDEXED_VERTS(ctx, start, count)
#endif
#ifndef EMIT_TWO_ELTS
#define EMIT_TWO_ELTS(offset, elt0, elt1) \
do { \
EMIT_ELT(offset, elt0); \
EMIT_ELT(offset + 1, elt1); \
} while (0)
#endif
#ifndef FINISH
#define FINISH
#endif
/***********************************************************************
* Render non-indexed primitives.
***********************************************************************/
static void TAG(render_points_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (HAVE_POINTS) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
GLuint j, nr;
INIT(GL_POINTS);
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += nr) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}
static void TAG(render_lines_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (HAVE_LINES) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
GLuint j, nr;
INIT(GL_LINES);
/* Emit whole number of lines in total and in each buffer:
*/
count -= (count - start) & 1;
currentsz -= currentsz & 1;
dmasz -= dmasz & 1;
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += nr) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}
static void TAG(render_line_strip_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (HAVE_LINE_STRIPS) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
GLuint j, nr;
INIT(GL_LINE_STRIP);
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j + 1 < count; j += nr - 1) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}
static void TAG(render_line_loop_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (HAVE_LINE_STRIPS) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
GLuint j, nr;
INIT(GL_LINE_STRIP);
if (flags & PRIM_BEGIN)
j = start;
else
j = start + 1;
/* Ensure last vertex won't wrap buffers:
*/
currentsz--;
dmasz--;
if (currentsz < 8)
currentsz = dmasz;
for (; j + 1 < count; j += nr - 1) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
if (start < count - 1 && (flags & PRIM_END))
EMIT_VERTS(ctx, start, 1);
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}
static void TAG(render_triangles_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
LOCAL_VARS;
int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 3) * 3;
int currentsz = (GET_CURRENT_VB_MAX_VERTS() / 3) * 3;
GLuint j, nr;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
INIT(GL_TRIANGLES);
/* Emit whole number of tris in total. dmasz is already a multiple
* of 3.
*/
count -= (count - start) % 3;
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += nr) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_tri_strip_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (HAVE_TRI_STRIPS) {
LOCAL_VARS;
GLuint j, nr;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
INIT(GL_TRIANGLE_STRIP);
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
if ((flags & PRIM_PARITY) && count - start > 2) {
EMIT_VERTS(ctx, start, 1);
currentsz--;
}
/* From here on emit even numbers of tris when wrapping over buffers:
*/
dmasz -= (dmasz & 1);
currentsz -= (currentsz & 1);
for (j = start; j + 2 < count; j += nr - 2) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}
static void TAG(render_tri_fan_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
if (HAVE_TRI_FANS) {
LOCAL_VARS;
GLuint j, nr;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
INIT(GL_TRIANGLE_FAN);
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
for (j = start + 1; j + 1 < count; j += nr - 1) {
nr = MIN2(currentsz, count - j + 1);
EMIT_VERTS(ctx, start, 1);
EMIT_VERTS(ctx, j, nr - 1);
currentsz = dmasz;
}
FINISH;
}
else {
/* Could write code to emit these as indexed vertices (for the
* g400, for instance).
*/
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_poly_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (HAVE_POLYGONS) {
LOCAL_VARS;
GLuint j, nr;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
INIT(GL_POLYGON);
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
for (j = start + 1; j + 1 < count; j += nr - 1) {
nr = MIN2(currentsz, count - j + 1);
EMIT_VERTS(ctx, start, 1);
EMIT_VERTS(ctx, j, nr - 1);
currentsz = dmasz;
}
FINISH;
}
else if (HAVE_TRI_FANS && !(ctx->_TriangleCaps & DD_FLATSHADE)) {
TAG(render_tri_fan_verts)(ctx, start, count, flags);
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}
static void TAG(render_quad_strip_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j, nr;
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (HAVE_QUAD_STRIPS) {
LOCAL_VARS;
GLuint j, nr;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz;
INIT(GL_QUAD_STRIP);
currentsz = GET_CURRENT_VB_MAX_VERTS();
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
dmasz -= (dmasz & 2);
currentsz -= (currentsz & 2);
for (j = start; j + 3 < count; j += nr - 2) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else if (HAVE_TRI_STRIPS) {
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz = GET_CURRENT_VB_MAX_VERTS();
/* Emit smooth-shaded quadstrips as tristrips:
*/
INIT(GL_TRIANGLE_STRIP);
/* Emit whole number of quads in total, and in each buffer.
*/
dmasz -= dmasz & 1;
currentsz -= currentsz & 1;
count -= (count - start) & 1;
if (currentsz < 8) {
NEW_BUFFER();
currentsz = dmasz;
}
for (j = start; j + 3 < count; j += nr - 2) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else {
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}
static void TAG(render_quads_verts)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M_X;
#endif
if (HAVE_QUADS) {
LOCAL_VARS;
int dmasz = (GET_SUBSEQUENT_VB_MAX_VERTS() / 4) * 4;
int currentsz = (GET_CURRENT_VB_MAX_VERTS() / 4) * 4;
GLuint j, nr;
INIT(GL_QUADS);
/* Emit whole number of quads in total. dmasz is already a multiple
* of 4.
*/
count -= (count - start) % 4;
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += nr) {
nr = MIN2(currentsz, count - j);
EMIT_VERTS(ctx, j, nr);
currentsz = dmasz;
}
FINISH;
}
else if (HAVE_TRIANGLES) {
/* Hardware doesn't have a quad primitive type -- try to
* simulate it using triangle primitive.
*/
LOCAL_VARS;
int dmasz = GET_SUBSEQUENT_VB_MAX_VERTS();
int currentsz;
GLuint j;
INIT(GL_TRIANGLES);
currentsz = GET_CURRENT_VB_MAX_VERTS();
/* Emit whole number of quads in total, and in each buffer.
*/
dmasz -= dmasz & 3;
count -= (count - start) & 3;
currentsz -= currentsz & 3;
/* Adjust for rendering as triangles:
*/
currentsz = currentsz / 6 * 4;
dmasz = dmasz / 6 * 4;
if (currentsz < 8)
currentsz = dmasz;
for (j = start; j < count; j += 4) {
/* Send v0, v1, v3
*/
EMIT_VERTS(ctx, j, 2);
EMIT_VERTS(ctx, j + 3, 1);
/* Send v1, v2, v3
*/
EMIT_VERTS(ctx, j + 1, 3);
}
FINISH;
}
else {
/* Vertices won't fit in a single buffer, fallback.
*/
VERT_FALLBACK(ctx, start, count, flags);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_noop)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
}
static render_func TAG(render_tab_verts)[GL_POLYGON + 2] =
{
TAG(render_points_verts),
TAG(render_lines_verts),
TAG(render_line_loop_verts),
TAG(render_line_strip_verts),
TAG(render_triangles_verts),
TAG(render_tri_strip_verts),
TAG(render_tri_fan_verts),
TAG(render_quads_verts),
TAG(render_quad_strip_verts),
TAG(render_poly_verts),
TAG(render_noop),
};

View file

@ -0,0 +1,61 @@
#ifndef _VIA_DRI_
#define _VIA_DRI_
#include "xf86drm.h"
#define VIA_MAX_DRAWABLES 256
#define VIA_VERSION_MAJOR 4
#define VIA_VERSION_MINOR 1
typedef struct {
int CtxOwner;
} VIASAREAPriv;
typedef struct {
drmHandle handle;
drmSize size;
drmAddress map;
} viaRegion, *viaRegionPtr;
typedef struct {
viaRegion regs, agp;
int deviceID;
int width;
int height;
int mem;
int bytesPerPixel;
int priv1;
int priv2;
int fbOffset;
int fbSize;
#ifndef _SOLO
Bool drixinerama;
#endif
int backOffset;
int depthOffset;
int textureOffset;
int textureSize;
int irqEnabled;
unsigned int scrnX, scrnY;
int sarea_priv_offset;
} VIADRIRec, *VIADRIPtr;
typedef struct {
int dummy;
} VIAConfigPrivRec, *VIAConfigPrivPtr;
typedef struct {
int dummy;
} VIADRIContextRec, *VIADRIContextPtr;
#ifdef XFree86Server
#include "screenint.h"
Bool VIADRIScreenInit(ScreenPtr pScreen);
void VIADRICloseScreen(ScreenPtr pScreen);
Bool VIADRIFinishScreenInit(ScreenPtr pScreen);
#endif
#endif

View file

@ -0,0 +1,373 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <assert.h>
#include "via_context.h"
#include "via_ioctl.h"
#include "via_fb.h"
#include <sys/ioctl.h>
GLboolean
via_alloc_back_buffer(viaContextPtr vmesa)
{
drm_via_mem_t fb;
unsigned char *pFB;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
fb.context = vmesa->hHWContext;
fb.size = vmesa->back.size;
fb.type = VIDEO;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type);
#endif
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb))
return GL_FALSE;
pFB = vmesa->driScreen->pFB;
vmesa->back.offset = fb.offset;
vmesa->back.map = (char *)(fb.offset + (GLuint)pFB);
vmesa->back.index = fb.index;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "offset = %08x\n", vmesa->back.offset);
fprintf(stderr, "index = %d\n", vmesa->back.index);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_TRUE;
}
GLboolean
via_alloc_front_buffer(viaContextPtr vmesa)
{
drm_via_mem_t fb;
unsigned char *pFB;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
fb.context = vmesa->hHWContext;
fb.size = vmesa->back.size;
fb.type = VIDEO;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "context = %d, size =%d, type = %d\n", fb.context, fb.size, fb.type);
#endif
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb))
return GL_FALSE;
pFB = vmesa->driScreen->pFB;
vmesa->front.offset = fb.offset;
vmesa->front.map = (char *)(fb.offset + (GLuint)pFB);
vmesa->front.index = fb.index;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "offset = %08x\n", vmesa->front.offset);
fprintf(stderr, "index = %d\n", vmesa->front.index);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_TRUE;
}
void
via_free_back_buffer(viaContextPtr vmesa)
{
drm_via_mem_t fb;
if (!vmesa) return;
fb.context = vmesa->hHWContext;
fb.index = vmesa->back.index;
fb.type = VIDEO;
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
vmesa->back.map = NULL;
}
void
via_free_front_buffer(viaContextPtr vmesa)
{
drm_via_mem_t fb;
if (!vmesa) return;
fb.context = vmesa->hHWContext;
fb.index = vmesa->front.index;
fb.type = VIDEO;
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
vmesa->front.map = NULL;
}
GLboolean
via_alloc_depth_buffer(viaContextPtr vmesa)
{
drm_via_mem_t fb;
unsigned char *pFB;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
fb.context = vmesa->hHWContext;
fb.size = vmesa->depth.size;
fb.type = VIDEO;
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
return GL_FALSE;
}
pFB = vmesa->driScreen->pFB;
vmesa->depth.offset = fb.offset;
vmesa->depth.map = (char *)(fb.offset + (GLuint)pFB);
vmesa->depth.index = fb.index;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "offset = %08x\n", vmesa->depth.offset);
fprintf(stderr, "index = %d\n", vmesa->depth.index);
}
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_TRUE;
}
void
via_free_depth_buffer(viaContextPtr vmesa)
{
drm_via_mem_t fb;
if (!vmesa) return;
fb.context = vmesa->hHWContext;
fb.index = vmesa->depth.index;
fb.type = VIDEO;
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
vmesa->depth.map = NULL;
}
GLboolean
via_alloc_dma_buffer(viaContextPtr vmesa)
{
drm_via_mem_t fb;
drmVIADMABuf dma;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
if (vmesa->viaScreen->agpLinearStart) {
/* Allocate DMA in AGP memory*/
fb.context = vmesa->hHWContext;
fb.size = vmesa->dma[0].size;
fb.type = AGP;
if (!ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
vmesa->dma[0].offset = fb.offset;
vmesa->dma[0].index = fb.index;
vmesa->dma[0].map = (unsigned char *)((GLuint)vmesa->viaScreen->agpLinearStart + fb.offset);
if (!ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
vmesa->dma[1].offset = fb.offset;
vmesa->dma[1].index = fb.index;
vmesa->dma[1].map = (unsigned char *)((GLuint)vmesa->viaScreen->agpLinearStart + fb.offset);
vmesa->useAgp = GL_TRUE;
return GL_TRUE;
}
else {
/* release dma[0]*/
return GL_FALSE;
}
}
return GL_FALSE;
}
else {
/* Allocate DMA in System memory */
dma.size = vmesa->dma[0].size;
if (drmVIAAllocateDMA(vmesa->driFd,&dma) < 0) {
return GL_FALSE;
}
vmesa->dma[0].offset = 0;
vmesa->dma[0].map = (unsigned char *)dma.address;
vmesa->dma[0].index = dma.index;
drmVIAAllocateDMA(vmesa->driFd, &dma);
vmesa->dma[1].offset = 0;
vmesa->dma[1].map = (unsigned char *)dma.address;
vmesa->dma[1].index = dma.index;
vmesa->useAgp = GL_FALSE;
return GL_TRUE;
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
void
via_free_dma_buffer(viaContextPtr vmesa)
{
drmVIADMABuf dma;
drm_via_mem_t fb;
if (!vmesa) return;
/* Release AGP command buffer */
if (vmesa->useAgp) {
fb.context = vmesa->hHWContext;
fb.index = vmesa->dma[0].index;
fb.type = AGP;
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
vmesa->dma[0].map = NULL;
fb.index = vmesa->dma[1].index;
ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb);
vmesa->dma[1].map = NULL;
}
/* Release System command buffer */
else {
dma.address = (unsigned long *)vmesa->dma[0].map;
/*=* John Sheng [2003.6.16] fix pci path *=*/
dma.size = (unsigned int)vmesa->dma[0].size;
drmVIAReleaseDMA(vmesa->driFd, &dma);
dma.address = (unsigned long *)vmesa->dma[1].map;
/*=* John Sheng [2003.6.16] fix pci path *=*/
dma.size = (unsigned int)vmesa->dma[1].size;
drmVIAReleaseDMA(vmesa->driFd, &dma);
vmesa->dma[0].map = 0;
vmesa->dma[1].map = 0;
}
}
GLboolean
via_alloc_texture(viaContextPtr vmesa, viaTextureObjectPtr t)
{
drm_via_mem_t fb;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
fb.context = vmesa->hHWContext;
fb.size = t->texMem.size;
fb.type = VIDEO;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "texture size = %d\n", fb.size);
fprintf(stderr, "texture type = %d\n", fb.type);
}
#endif
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
fprintf(stderr, "via_alloc_texture fail\n");
return GL_FALSE;
}
t->texMem.offset = fb.offset;
t->texMem.index = fb.index;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "texture index = %d\n", (GLuint)fb.index);
#endif
t->bufAddr = (unsigned char *)(fb.offset + (GLuint)vmesa->driScreen->pFB);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_TRUE;
}
/*=* John Sheng [2003.5.31] agp tex *=*/
GLboolean
via_alloc_texture_agp(viaContextPtr vmesa, viaTextureObjectPtr t)
{
drm_via_mem_t fb;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
fb.context = vmesa->hHWContext;
fb.size = t->texMem.size;
fb.type = AGP;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "texture_agp size = %d\n", fb.size);
fprintf(stderr, "texture type = %d\n", fb.type);
}
#endif
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_ALLOCMEM, &fb)) {
fprintf(stderr, "via_alloc_texture_agp fail\n");
return GL_FALSE;
}
t->texMem.offset = fb.offset;
t->texMem.index = fb.index;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "texture agp index = %d\n", (GLuint)fb.index);
#endif
t->bufAddr = (unsigned char *)((GLuint)vmesa->viaScreen->agpLinearStart + fb.offset);
/*=* John Sheng [2003.5.31] agp tex *=*/
t->inAGP = GL_TRUE;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_TRUE;
}
void
via_free_texture(viaContextPtr vmesa, viaTextureObjectPtr t)
{
drm_via_mem_t fb;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "via_free_texture: index = %d\n",
t->texMem.index);
fprintf(stderr, "via_free_texture: size = %d\n",
t->texMem.size);
}
#endif
if (!vmesa) {
fprintf(stderr, "!mesa\n");
return;
}
fb.context = vmesa->hHWContext;
fb.index = t->texMem.index;
/*=* John Sheng [2003.5.31] agp tex *=*/
if(t->inAGP)
fb.type = AGP;
else
fb.type = VIDEO;
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
if(vmesa->shareCtx) {
fb.context = ((viaContextPtr)((GLcontext *)(vmesa->shareCtx)->DriverCtx))->hHWContext;
if (ioctl(vmesa->driFd, DRM_IOCTL_VIA_FREEMEM, &fb)) {
fprintf(stderr, "via_free_texture fail\n");
}
}
else
fprintf(stderr, "via_free_texture fail\n");
}
t->bufAddr = NULL;
}

View file

@ -0,0 +1,42 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIAFB_INC
#define _VIAFB_INC
#include "mtypes.h"
#include "swrast/swrast.h"
extern GLboolean via_alloc_front_buffer(viaContextPtr vmesa);
extern GLboolean via_alloc_back_buffer(viaContextPtr vmesa);
extern void via_free_back_buffer(viaContextPtr vmesa);
extern void via_free_front_buffer(viaContextPtr vmesa);
extern GLboolean via_alloc_depth_buffer(viaContextPtr vmesa);
extern void via_free_depth_buffer(viaContextPtr vmesa);
extern GLboolean via_alloc_dma_buffer(viaContextPtr vmesa);
extern void via_free_dma_buffer(viaContextPtr vmesa);
extern GLboolean via_alloc_texture(viaContextPtr vmesa, viaTextureObjectPtr t);
/*=* John Sheng [2003.5.31] agp tex *=*/
extern GLboolean via_alloc_texture_agp(viaContextPtr vmesa, viaTextureObjectPtr t);
extern void via_free_texture(viaContextPtr vmesa, viaTextureObjectPtr t);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,88 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIAIOCTL_H
#define _VIAIOCTL_H
#include "via_context.h"
void viaEmitPrim(viaContextPtr vmesa);
void viaFlushPrims(viaContextPtr vmesa);
void viaFlushPrimsLocked(viaContextPtr vmesa);
void viaDmaFinish(viaContextPtr vmesa);
void viaRegetLockQuiescent(viaContextPtr vmesa);
void viaInitIoctlFuncs(GLcontext *ctx);
void viaCopyBuffer(const __DRIdrawablePrivate *dpriv);
void viaPageFlip(const __DRIdrawablePrivate *dpriv);
int via_check_copy(int fd);
void viaFillFrontBuffer(viaContextPtr vmesa);
void viaFillFrontBufferSaam(viaContextPtr vmesa);
void viaFillFrontPBuffer(viaContextPtr vmesa);
void viaFillBackBuffer(viaContextPtr vmesa);
void viaFillDepthBuffer(viaContextPtr vmesa, GLuint pixel);
void viaFillStencilBuffer(viaContextPtr vmesa, GLuint pixel);
void viaFillStencilDepthBuffer(viaContextPtr vmesa, GLuint pixel);
void viaDoSwapBuffers(viaContextPtr vmesa);
void viaDoSwapBuffersSaam(viaContextPtr vmesa);
void viaDoSwapBufferSoft(viaContextPtr vmesa);
void viaDoSwapBufferSoftFront(viaContextPtr vmesa);
void viaDoSwapPBuffers(viaContextPtr vmesa);
int flush_agp(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd);
int flush_agp_saam(viaContextPtr vmesa, drm_via_flush_agp_t* agpCmd);
int flush_sys(viaContextPtr vmesa, drm_via_flush_sys_t* buf);
#define VIA_STATECHANGE(vmesa, flag) \
do { \
if (vmesa->dmaLow != vmesa->dmaLastPrim) \
viaFlushPrims(vmesa); \
vmesa->dirty |= flag; \
} while (0) \
#define VIA_FIREVERTICES(vmesa) \
do { \
if (vmesa->dmaLow) { \
viaFlushPrims(vmesa); \
} \
} while (0)
static __inline GLuint *viaCheckDma(viaContextPtr vmesa, int bytes)
{
if (vmesa->dmaLow + bytes > vmesa->dmaHigh) {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "buffer overflow in check dma = %d + %d = %d\n", vmesa->dmaLow, bytes, vmesa->dmaLow + bytes);
#endif
viaFlushPrims(vmesa);
}
{
GLuint *start = (GLuint *)(vmesa->dmaAddr + vmesa->dmaLow);
return start;
}
}
#endif

View file

@ -0,0 +1,545 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*
* Render unclipped vertex buffers by emitting vertices directly to
* dma buffers. Use strip/fan hardware acceleration where possible.
*
*/
#include "glheader.h"
#include "context.h"
#include "macros.h"
#include "mtypes.h"
/*#include "mmath.h" _SOLO */
#include "tnl/t_context.h"
#include "via_context.h"
#include "via_tris.h"
#include "via_state.h"
#include "via_vb.h"
#include "via_ioctl.h"
/*
* Render unclipped vertex buffers by emitting vertices directly to
* dma buffers. Use strip/fan hardware primitives where possible.
* Try to simulate missing primitives with indexed vertices.
*/
#define HAVE_POINTS 1
#define HAVE_LINES 1
#define HAVE_LINE_STRIPS 1
#define HAVE_LINE_LOOP 1
#define HAVE_TRIANGLES 1
#define HAVE_TRI_STRIPS 1
#define HAVE_TRI_STRIP_1 0 /* has it, template can't use it yet */
#define HAVE_TRI_FANS 1
#define HAVE_POLYGONS 1
#define HAVE_QUADS 0
#define HAVE_QUAD_STRIPS 0
#define HAVE_ELTS 0
static const GLenum reducedPrim[GL_POLYGON + 1] = {
GL_POINTS,
GL_LINES,
GL_LINES,
GL_LINES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES,
GL_TRIANGLES
};
/* Fallback to normal rendering.
*/
static void VERT_FALLBACK(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
fprintf(stderr, "VERT_FALLBACK\n");
tnl->Driver.Render.PrimitiveNotify(ctx, flags & PRIM_MODE_MASK);
tnl->Driver.Render.BuildVertices(ctx, start, count, ~0);
tnl->Driver.Render.PrimTabVerts[flags & PRIM_MODE_MASK](ctx, start,
count, flags);
VIA_CONTEXT(ctx)->setupNewInputs = VERT_CLIP;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
#define LOCAL_VARS viaContextPtr vmesa = VIA_CONTEXT(ctx)
/*
#define INIT(prim) \
do { \
VIA_STATECHANGE(vmesa, 0); \
viaRasterPrimitive(ctx, reducedPrim[prim], prim); \
} while (0)
*/
#define INIT(prim) \
do { \
viaRasterPrimitive(ctx, reducedPrim[prim], prim); \
} while (0)
#define NEW_PRIMITIVE() VIA_STATECHANGE(vmesa, 0)
#define NEW_BUFFER() VIA_FIREVERTICES(vmesa)
#define GET_CURRENT_VB_MAX_VERTS() \
(((int)vmesa->dmaHigh - (int)vmesa->dmaLow) / (vmesa->vertex_size * 4))
#define GET_SUBSEQUENT_VB_MAX_VERTS() \
(VIA_DMA_BUF_SZ - 4) / (vmesa->vertex_size * 4)
#define EMIT_VERTS(ctx, j, nr) \
via_emit_contiguous_verts(ctx, j, (j) + (nr))
#define FINISH \
do { \
vmesa->primitiveRendered = GL_TRUE; \
viaRasterPrimitiveFinish(ctx); \
} while (0)
#define TAG(x) via_fast##x
#include "via_dmatmp.h"
#undef TAG
#undef LOCAL_VARS
#undef INIT
/**********************************************************************/
/* Fast Render pipeline stage */
/**********************************************************************/
static GLboolean via_run_fastrender(GLcontext *ctx,
struct tnl_pipeline_stage *stage)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint i, length, flags = 0;
/* Don't handle clipping or indexed vertices.
*/
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
if (VB->ClipOrMask || vmesa->renderIndex != 0 || VB->Elts) {
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "slow path\n");
fprintf(stderr, "ClipOrMask = %08x\n", VB->ClipOrMask);
fprintf(stderr, "renderIndex = %08x\n", vmesa->renderIndex);
fprintf(stderr, "Elts = %08x\n", (GLuint)VB->Elts);
}
#endif
return GL_TRUE;
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
vmesa->setupNewInputs = VERT_CLIP;
vmesa->primitiveRendered = GL_TRUE;
tnl->Driver.Render.Start(ctx);
for (i = 0; i < VB->PrimitiveCount; ++i) {
GLuint mode = VB->Primitive[i].mode;
GLuint start = VB->Primitive[i].start;
GLuint length = VB->Primitive[i].count;
if (length)
via_fastrender_tab_verts[mode & PRIM_MODE_MASK](ctx, start, start+length, mode);
}
tnl->Driver.Render.Finish(ctx);
/*=* DBG - viewperf7.0 : fix command buffer overflow *=*/
if (vmesa->dmaLow > (vmesa->dma[0].size / 2))
viaFlushPrims(vmesa);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_FALSE; /* finished the pipe */
}
static void via_check_fastrender(GLcontext *ctx, struct tnl_pipeline_stage *stage)
{
GLuint inputs = VERT_CLIP | VERT_RGBA;
if (ctx->RenderMode == GL_RENDER) {
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
inputs |= VERT_BIT_COLOR1;
if (ctx->Texture.Unit[0]._ReallyEnabled)
inputs |= VERT_TEX(0);
if (ctx->Texture.Unit[1]._ReallyEnabled)
inputs |= VERT_TEX(1);
if (ctx->Fog.Enabled)
inputs |= VERT_BIT_FOG;
}
stage->inputs = inputs;
}
static void fastdtr(struct tnl_pipeline_stage *stage)
{
(void)stage;
}
const struct tnl_pipeline_stage _via_fastrender_stage =
{
"via fast render",
(_DD_NEW_SEPARATE_SPECULAR |
_NEW_TEXTURE|
_NEW_FOG|
_NEW_RENDERMODE), /* re-check (new inputs) */
0, /* re-run (always runs) */
GL_TRUE, /* active */
0, 0, /* inputs (set in check_render), outputs */
0, 0, /* changed_inputs, private */
fastdtr, /* destructor */
via_check_fastrender, /* check - initially set to alloc data */
via_run_fastrender /* run */
};
/*
* Render whole vertex buffers, including projection of vertices from
* clip space and clipping of primitives.
*
* This file makes calls to project vertices and to the point, line
* and triangle rasterizers via the function pointers:
*
* context->Driver.Render.*
*
*/
/**********************************************************************/
/* Clip single primitives */
/**********************************************************************/
#if defined(USE_IEEE)
#define NEGATIVE(x) (GET_FLOAT_BITS(x) & (1 << 31))
#define DIFFERENT_SIGNS(x, y) ((GET_FLOAT_BITS(x) ^ GET_FLOAT_BITS(y)) & (1 << 31))
#else
#define NEGATIVE(x) (x < 0)
#define DIFFERENT_SIGNS(x,y) (x * y <= 0 && x - y != 0)
/* Could just use (x*y<0) except for the flatshading requirements.
* Maybe there's a better way?
*/
#endif
#define W(i) coord[i][3]
#define Z(i) coord[i][2]
#define Y(i) coord[i][1]
#define X(i) coord[i][0]
#define SIZE 4
#define TAG(x) x##_4
#include "tnl/t_vb_cliptmp.h" /* tnl_ */
/**********************************************************************/
/* Clip and render whole begin/end objects */
/**********************************************************************/
#define NEED_EDGEFLAG_SETUP (ctx->_TriangleCaps & DD_TRI_UNFILLED)
#define EDGEFLAG_GET(idx) VB->EdgeFlag[idx]
#define EDGEFLAG_SET(idx, val) VB->EdgeFlag[idx] = val
/* Vertices, with the possibility of clipping.
*/
#define RENDER_POINTS(start, count) \
tnl->Driver.Render.Points(ctx, start, count)
#define RENDER_LINE(v1, v2) \
do { \
GLubyte c1 = mask[v1], c2 = mask[v2]; \
GLubyte ormask = c1 | c2; \
if (!ormask) \
LineFunc(ctx, v1, v2); \
else if (!(c1 & c2 & 0x3f)) \
clip_line_4(ctx, v1, v2, ormask); \
} while (0)
#define RENDER_TRI(v1, v2, v3) \
do { \
GLubyte c1 = mask[v1], c2 = mask[v2], c3 = mask[v3]; \
GLubyte ormask = c1 | c2 | c3; \
if (!ormask) \
TriangleFunc(ctx, v1, v2, v3); \
else if (!(c1 & c2 & c3 & 0x3f)) \
clip_tri_4(ctx, v1, v2, v3, ormask); \
} while (0)
#define RENDER_QUAD(v1, v2, v3, v4) \
do { \
GLubyte c1 = mask[v1], c2 = mask[v2]; \
GLubyte c3 = mask[v3], c4 = mask[v4]; \
GLubyte ormask = c1 | c2 | c3 | c4; \
if (!ormask) \
QuadFunc(ctx, v1, v2, v3, v4); \
else if (!(c1 & c2 & c3 & c4 & 0x3f)) \
clip_quad_4(ctx, v1, v2, v3, v4, ormask); \
} while (0)
#define LOCAL_VARS \
TNLcontext *tnl = TNL_CONTEXT(ctx); \
struct vertex_buffer *VB = &tnl->vb; \
const GLuint * const elt = VB->Elts; \
const GLubyte *mask = VB->ClipMask; \
const GLuint sz = VB->ClipPtr->size; \
const line_func LineFunc = tnl->Driver.Render.Line; \
const triangle_func TriangleFunc = tnl->Driver.Render.Triangle; \
const quad_func QuadFunc = tnl->Driver.Render.Quad; \
const GLboolean stipple = ctx->Line.StippleFlag; \
(void) (LineFunc && TriangleFunc && QuadFunc); \
(void) elt; (void) mask; (void) sz; (void) stipple;
#define POSTFIX \
viaRasterPrimitiveFinish(ctx)
#define TAG(x) clip_##x##_verts
#define INIT(x) tnl->Driver.Render.PrimitiveNotify(ctx, x)
#define RESET_STIPPLE if (stipple) tnl->Driver.Render.ResetLineStipple(ctx)
#define RESET_OCCLUSION ctx->OcclusionResult = GL_TRUE
#define PRESERVE_VB_DEFS
#include "tnl/t_vb_rendertmp.h"
/* Elts, with the possibility of clipping.
*/
#undef ELT
#undef TAG
#define ELT(x) elt[x]
#define TAG(x) clip_##x##_elts
#include "tnl/t_vb_rendertmp.h"
/* TODO: do this for all primitives, verts and elts:
*/
static void clip_elt_triangles(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
render_func render_tris = tnl->Driver.Render.PrimTabElts[GL_TRIANGLES];
struct vertex_buffer *VB = &tnl->vb;
const GLuint * const elt = VB->Elts;
GLubyte *mask = VB->ClipMask;
GLuint last = count-2;
GLuint j;
(void)flags;
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
tnl->Driver.Render.PrimitiveNotify(ctx, GL_TRIANGLES);
for (j = start; j < last; j += 3) {
GLubyte c1 = mask[elt[j]];
GLubyte c2 = mask[elt[j + 1]];
GLubyte c3 = mask[elt[j + 2]];
GLubyte ormask = c1 | c2 | c3;
if (ormask) {
if (start < j)
render_tris(ctx, start, j, 0);
if (!(c1 & c2 & c3 & 0x3f))
clip_tri_4(ctx, elt[j], elt[j + 1], elt[j + 2], ormask);
start = j+3;
}
}
if (start < j)
render_tris(ctx, start, j, 0);
viaRasterPrimitiveFinish(ctx);
}
/**********************************************************************/
/* Helper functions for drivers */
/**********************************************************************/
/*
void _tnl_RenderClippedPolygon(GLcontext *ctx, const GLuint *elts, GLuint n)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
GLuint *tmp = VB->Elts;
VB->Elts = (GLuint *)elts;
tnl->Driver.Render.PrimTabElts[GL_POLYGON](ctx, 0, n, PRIM_BEGIN|PRIM_END);
VB->Elts = tmp;
}
void _tnl_RenderClippedLine(GLcontext *ctx, GLuint ii, GLuint jj)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
tnl->Driver.Render.Line(ctx, ii, jj);
}
*/
/**********************************************************************/
/* Render pipeline stage */
/**********************************************************************/
static GLboolean via_run_render(GLcontext *ctx,
struct tnl_pipeline_stage *stage)
{
TNLcontext *tnl = TNL_CONTEXT(ctx);
viaContextPtr vmesa = VIA_CONTEXT(ctx);
struct vertex_buffer *VB = &tnl->vb;
/* DBG */
GLuint newInputs = stage->changed_inputs;
/*GLuint newInputs = stage->inputs;*/
render_func *tab;
GLuint pass = 0;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
tnl->Driver.Render.Start(ctx);
tnl->Driver.Render.BuildVertices(ctx, 0, VB->Count, newInputs);
if (VB->ClipOrMask) {
tab = VB->Elts ? clip_render_tab_elts : clip_render_tab_verts;
clip_render_tab_elts[GL_TRIANGLES] = clip_elt_triangles;
}
else {
tab = VB->Elts ? tnl->Driver.Render.PrimTabElts : tnl->Driver.Render.PrimTabVerts;
}
do {
GLuint i;
for (i = 0; i < VB->PrimitiveCount; i++) {
GLuint flags = VB->Primitive[i].mode;
GLuint start = VB->Primitive[i].start;
GLuint length= VB->Primitive[i].count;
ASSERT(length || (flags & PRIM_LAST));
ASSERT((flags & PRIM_MODE_MASK) <= GL_POLYGON + 1);
if (length)
tab[flags & PRIM_MODE_MASK](ctx, start, start + length,flags);
}
}
while (tnl->Driver.Render.Multipass && tnl->Driver.Render.Multipass(ctx, ++pass));
tnl->Driver.Render.Finish(ctx);
/*=* DBG - flush : if hw idel *=*/
{
GLuint volatile *pnEnginStatus = vmesa->regEngineStatus;
GLuint nStatus;
nStatus = *pnEnginStatus;
if ((nStatus & 0xFFFEFFFF) == 0x00020000)
viaFlushPrims(vmesa);
}
/*=* DBG viewperf7.0 : fix command buffer overflow *=*/
if (vmesa->dmaLow > (vmesa->dma[0].size / 2))
viaFlushPrims(vmesa);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_FALSE; /* finished the pipe */
}
/* Quite a bit of work involved in finding out the inputs for the
* render stage.
*/
static void via_check_render(GLcontext *ctx, struct tnl_pipeline_stage *stage)
{
GLuint inputs = VERT_CLIP;
if (ctx->Visual.rgbMode) {
inputs |= VERT_RGBA;
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
inputs |= VERT_BIT_COLOR1;
if (ctx->Texture.Unit[0]._ReallyEnabled) {
inputs |= VERT_TEX(0);
}
if (ctx->Texture.Unit[1]._ReallyEnabled) {
inputs |= VERT_TEX(1);
}
}
else {
/*inputs |= VERT_INDEX; _SOLO*/
}
/*if (ctx->Point._Attenuated)
inputs |= VERT_POINT_SIZE;*/
if (ctx->Fog.Enabled)
inputs |= VERT_BIT_FOG;
/*if (ctx->_TriangleCaps & DD_TRI_UNFILLED)
inputs |= VERT_EDGE;
if (ctx->RenderMode == GL_FEEDBACK)
inputs |= VERT_TEX_ANY;*/
stage->inputs = inputs;
}
static void dtr(struct tnl_pipeline_stage *stage)
{
(void)stage;
}
const struct tnl_pipeline_stage _via_render_stage =
{
"via render",
(_NEW_BUFFERS |
_DD_NEW_SEPARATE_SPECULAR |
_DD_NEW_FLATSHADE |
_NEW_TEXTURE |
_NEW_LIGHT |
_NEW_POINT |
_NEW_FOG |
_DD_NEW_TRI_UNFILLED |
_NEW_RENDERMODE), /* re-check (new inputs) */
0, /* re-run (always runs) */
GL_TRUE, /* active */
0, 0, /* inputs (set in check_render), outputs */
0, 0, /* changed_inputs, private */
dtr, /* destructor */
via_check_render, /* check - initially set to alloc data */
via_run_render /* run */
};

View file

@ -0,0 +1,327 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
/*#include <X11/Xlibint.h> _SOLO*/
#include <stdio.h>
#include "utils.h"
#include "dri_util.h"
#include "glheader.h"
#include "context.h"
#include "matrix.h"
#include "simple_list.h"
#include "via_state.h"
#include "via_tex.h"
#include "via_span.h"
#include "via_tris.h"
#include "via_ioctl.h"
#include "via_screen.h"
#include "via_dri.h"
extern viaContextPtr current_mesa;
static drmBufMapPtr via_create_empty_buffers(void)
{
drmBufMapPtr retval;
retval = (drmBufMapPtr)MALLOC(sizeof(drmBufMap));
if (retval == NULL) return NULL;
memset(retval, 0, sizeof(drmBufMap));
retval->list = (drmBufPtr)MALLOC(sizeof(drmBuf) * VIA_DMA_BUF_NR);
if (retval->list == NULL) {
FREE(retval);
return NULL;
}
memset(retval->list, 0, sizeof(drmBuf) * VIA_DMA_BUF_NR);
return retval;
}
static GLboolean
viaInitDriver(__DRIscreenPrivate *sPriv)
{
viaScreenPrivate *viaScreen;
VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
if (!driCheckDriDdxDrmVersions(sPriv, "Via", 4, 0, 4, 0, 1, 1))
return GL_FALSE;
/* Allocate the private area */
viaScreen = (viaScreenPrivate *) CALLOC(sizeof(viaScreenPrivate));
if (!viaScreen) {
__driUtilMessage("viaInitDriver: alloc viaScreenPrivate struct failed");
return GL_FALSE;
}
viaScreen->driScrnPriv = sPriv;
sPriv->private = (void *)viaScreen;
viaScreen->deviceID = gDRIPriv->deviceID;
viaScreen->width = gDRIPriv->width;
viaScreen->height = gDRIPriv->height;
viaScreen->mem = gDRIPriv->mem;
viaScreen->bitsPerPixel = gDRIPriv->bytesPerPixel << 3;
viaScreen->bytesPerPixel = gDRIPriv->bytesPerPixel;
viaScreen->fbOffset = 0;
viaScreen->fbSize = gDRIPriv->fbSize;
#ifndef _SOLO
viaScreen->drixinerama = gDRIPriv->drixinerama;
#endif
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "deviceID = %08x\n", viaScreen->deviceID);
fprintf(stderr, "width = %08x\n", viaScreen->width);
fprintf(stderr, "height = %08x\n", viaScreen->height);
fprintf(stderr, "cpp = %08x\n", viaScreen->cpp);
fprintf(stderr, "fbOffset = %08x\n", viaScreen->fbOffset);
}
#endif
/* DBG */
/*
if (gDRIPriv->bitsPerPixel == 15)
viaScreen->fbFormat = DV_PF_555;
else
viaScreen->fbFormat = DV_PF_565;
*/
viaScreen->bufs = via_create_empty_buffers();
if (viaScreen->bufs == NULL) {
__driUtilMessage("viaInitDriver: via_create_empty_buffers() failed");
FREE(viaScreen);
return GL_FALSE;
}
if (drmMap(sPriv->fd,
gDRIPriv->regs.handle,
gDRIPriv->regs.size,
(drmAddress *)&viaScreen->reg) != 0) {
FREE(viaScreen);
sPriv->private = NULL;
__driUtilMessage("viaInitDriver: drmMap regs failed");
return GL_FALSE;
}
if (gDRIPriv->agp.size) {
if (drmMap(sPriv->fd,
gDRIPriv->agp.handle,
gDRIPriv->agp.size,
(drmAddress *)&viaScreen->agpLinearStart) != 0) {
FREE(viaScreen);
drmUnmap(viaScreen->reg, gDRIPriv->agp.size);
sPriv->private = NULL;
__driUtilMessage("viaInitDriver: drmMap agp failed");
return GL_FALSE;
}
viaScreen->agpBase = (GLuint *)gDRIPriv->agp.handle;
} else
viaScreen->agpLinearStart = 0;
viaScreen->sareaPrivOffset = gDRIPriv->sarea_priv_offset;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return GL_TRUE;
}
static void
viaDestroyScreen(__DRIscreenPrivate *sPriv)
{
viaScreenPrivate *viaScreen = (viaScreenPrivate *)sPriv->private;
VIADRIPtr gDRIPriv = (VIADRIPtr)sPriv->pDevPriv;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
drmUnmap(viaScreen->reg, gDRIPriv->regs.size);
if (gDRIPriv->agp.size)
drmUnmap(viaScreen->agpLinearStart, gDRIPriv->agp.size);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
FREE(viaScreen);
sPriv->private = NULL;
}
static GLboolean
viaCreateBuffer(__DRIscreenPrivate *driScrnPriv,
__DRIdrawablePrivate *driDrawPriv,
const __GLcontextModes *mesaVis,
GLboolean isPixmap)
{
viaContextPtr vmesa = current_mesa;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#if 0
/*=* John Sheng [2003.7.2] for visual config & patch viewperf *=*/
if (mesaVis->depthBits == 32 && vmesa->depthBits == 16) {
vmesa->depthBits = mesaVis->depthBits;
vmesa->depth.size *= 2;
vmesa->depth.pitch *= 2;
vmesa->depth.bpp *= 2;
if (vmesa->depth.map)
via_free_depth_buffer(vmesa);
if (!via_alloc_depth_buffer(vmesa)) {
via_free_depth_buffer(vmesa);
return GL_FALSE;
}
mesaVis->depthBits = 16;
}
#endif
if (isPixmap) {
#ifdef _SOLO
ASSERT(0);
return GL_FALSE; /* not implemented */
#else
driDrawPriv->driverPrivate = (void *)
_mesa_create_framebuffer(mesaVis,
GL_FALSE, /* software depth buffer? */
mesaVis->stencilBits > 0,
mesaVis->accumRedBits > 0,
GL_FALSE /* s/w alpha planes */);
if (vmesa) vmesa->drawType = GLX_PBUFFER_BIT;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return (driDrawPriv->driverPrivate != NULL);
#endif
}
else {
driDrawPriv->driverPrivate = (void *)
_mesa_create_framebuffer(mesaVis,
GL_FALSE, /* software depth buffer? */
mesaVis->stencilBits > 0,
mesaVis->accumRedBits > 0,
GL_FALSE /* s/w alpha planes */);
if (vmesa) vmesa->drawType = GLX_WINDOW_BIT;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
return (driDrawPriv->driverPrivate != NULL);
}
}
static void
viaDestroyBuffer(__DRIdrawablePrivate *driDrawPriv)
{
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
_mesa_destroy_framebuffer((GLframebuffer *)(driDrawPriv->driverPrivate));
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
#if 0
/* Initialize the fullscreen mode.
*/
GLboolean
XMesaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
{
viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
vmesa->doPageFlip = 1;
vmesa->currentPage = 0;
return GL_TRUE;
}
/* Shut down the fullscreen mode.
*/
GLboolean
XMesaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
{
viaContextPtr vmesa = (viaContextPtr)driContextPriv->driverPrivate;
if (vmesa->currentPage == 1) {
viaPageFlip(vmesa);
vmesa->currentPage = 0;
}
vmesa->doPageFlip = GL_FALSE;
vmesa->Setup[VIA_DESTREG_DI0] = vmesa->driScreen->front_offset;
return GL_TRUE;
}
#else
static GLboolean
viaOpenFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
static GLboolean
viaCloseFullScreen(__DRIcontextPrivate *driContextPriv)
{
return GL_TRUE;
}
#endif
static struct __DriverAPIRec viaAPI = {
viaInitDriver,
viaDestroyScreen,
viaCreateContext,
viaDestroyContext,
viaCreateBuffer,
viaDestroyBuffer,
viaSwapBuffers,
viaMakeCurrent,
viaUnbindContext,
viaOpenFullScreen,
viaCloseFullScreen
};
/*
* This is the bootstrap function for the driver.
* The __driCreateScreen name is the symbol that libGL.so fetches.
* Return: pointer to a __DRIscreenPrivate.
*/
#ifndef _SOLO
void *__driCreateScreen(Display *dpy, int scrn, __DRIscreen *psc,
int numConfigs, __GLXvisualConfig *config)
{
__DRIscreenPrivate *psp;
psp = __driUtilCreateScreen(dpy, scrn, psc, numConfigs, config, &viaAPI);
return (void *)psp;
}
#else
void *__driCreateScreen(struct DRIDriverRec *driver,
struct DRIDriverContextRec *driverContext)
{
__DRIscreenPrivate *psp;
psp = __driUtilCreateScreen(driver, driverContext, &viaAPI);
return (void *) psp;
}
#endif

View file

@ -0,0 +1,90 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIAINIT_H
#define _VIAINIT_H
#include <sys/time.h>
#include "dri_util.h"
#include "via_dri.h"
typedef struct {
viaRegion regs;
viaRegion agp;
int deviceID;
int width;
int height;
int mem;
int cpp;
int bitsPerPixel;
int bytesPerPixel;
int fbFormat;
int fbOffset;
int fbSize;
#ifndef _SOLO
Bool drixinerama;
#endif
int fbStride;
int backOffset;
int depthOffset;
int backPitch;
int backPitchBits;
int textureOffset;
int textureSize;
int logTextureGranularity;
drmAddress reg;
drmAddress agpLinearStart;
GLuint* agpBase;
__DRIscreenPrivate *driScrnPriv;
drmBufMapPtr bufs;
unsigned int sareaPrivOffset;
} viaScreenPrivate;
extern GLboolean
viaCreateContext(const __GLcontextModes *mesaVis,
__DRIcontextPrivate *driContextPriv,
void *sharedContextPrivate);
extern void
viaDestroyContext(__DRIcontextPrivate *driContextPriv);
extern GLboolean
viaUnbindContext(__DRIcontextPrivate *driContextPriv);
extern GLboolean
viaMakeCurrent(__DRIcontextPrivate *driContextPriv,
__DRIdrawablePrivate *driDrawPriv,
__DRIdrawablePrivate *driReadPriv);
extern void
viaSwapBuffers(__DRIdrawablePrivate *drawablePrivate);
#endif

View file

@ -0,0 +1,410 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "colormac.h"
#include "via_context.h"
#include "via_span.h"
#include "via_ioctl.h"
#include "swrast/swrast.h"
#define DBG 0
#if 0
#define LOCAL_VARS \
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
viaScreenPrivate *viaScreen = vmesa->viaScreen; \
GLuint pitch = vmesa->drawPitch; \
GLuint height = dPriv->h; \
GLushort p; \
char *buf = (char *)(vmesa->drawMap + \
dPriv->x * viaScreen->bytesPerPixel + \
dPriv->y * pitch); \
char *read_buf = (char *)(vmesa->readMap + \
dPriv->x * viaScreen->bytesPerPixel + \
dPriv->y * pitch); \
(void)read_buf; (void)buf; (void)p
#endif
#define LOCAL_DEPTH_VARS \
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
viaScreenPrivate *viaScreen = vmesa->viaScreen; \
GLuint pitch = viaScreen->backPitch; \
GLuint height = dPriv->h; \
char *buf = (char *)(vmesa->depth.map + \
dPriv->x * 2 + \
dPriv->y * pitch)
#define CLIPPIXEL(_x,_y) (_x >= minx && _x < maxx && \
_y >= miny && _y < maxy)
#define CLIPSPAN(_x, _y, _n, _x1, _n1, _i) \
if (_y < miny || _y >= maxy) { \
_n1 = 0, _x1 = x; \
} \
else { \
_n1 = _n; \
_x1 = _x; \
if (_x1 < minx) _i += (minx -_x1), n1 -= (minx -_x1), _x1 = minx; \
if (_x1 + _n1 >= maxx) n1 -= (_x1 + n1 - maxx); \
}
#define Y_FLIP(_y) (height - _y - 1)
#define HW_LOCK() \
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
LOCK_HARDWARE_QUIESCENT(vmesa);
/*=* [DBG] csmash saam : bitmap option menu can't be drawn in saam *=*/
/*#define HW_CLIPLOOP() \
do { \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
int _nc = dPriv->numClipRects; \
while (_nc--) { \
int minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
int miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
int maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
int maxy = dPriv->pClipRects[_nc].y2 - dPriv->y;*/
#define HW_CLIPLOOP() \
do { \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
int _nc = dPriv->numClipRects; \
GLuint scrn = vmesa->saam & S_MASK; \
if(scrn == S1) _nc = 1; \
while (_nc--) { \
int minx; \
int miny; \
int maxx; \
int maxy; \
if (!vmesa->saam) { \
minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; \
} \
else { \
minx = -10000; \
miny = -10000; \
maxx = 10000; \
maxy = 10000; \
}
/*else if (scrn == S0) { \
minx = dPriv->pClipRects[_nc].x1 - dPriv->x; \
miny = dPriv->pClipRects[_nc].y1 - dPriv->y; \
maxx = dPriv->pClipRects[_nc].x2 - dPriv->x; \
maxy = dPriv->pClipRects[_nc].y2 - dPriv->y; \
} \
else if (scrn == S1) { \
drm_clip_rect_t *b = vmesa->sarea->boxes; \
minx = b->x1; \
miny = b->y1; \
maxx = b->x2; \
maxy = b->y2; \
} \
else { \
drm_clip_rect_t *b = vmesa->sarea->boxes + vmesa->numClipRects;\
minx = b->x1; \
miny = b->y1; \
maxx = b->x2; \
maxy = b->y2; \
}*/
#define HW_ENDCLIPLOOP() \
} \
} while (0)
#define HW_UNLOCK() \
UNLOCK_HARDWARE(vmesa);
/* 16 bit, 565 rgb color spanline and pixel functions
*/
/*=* [DBG] csmash : fix options worng position *=*/
/*#define LOCAL_VARS \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
GLuint pitch = vmesa->drawPitch; \
GLuint height = dPriv->h; \
GLushort p; \
char *buf = (char *)(vmesa->drawMap + \
dPriv->x * 2 + \
dPriv->y * pitch); \
char *read_buf = (char *)(vmesa->readMap + \
dPriv->x * 2 + \
dPriv->y * pitch); \
(void)read_buf; (void)buf; (void)p*/
#define LOCAL_VARS \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
GLuint pitch = vmesa->drawPitch; \
GLuint height = dPriv->h; \
GLushort p; \
char *buf, *read_buf; \
p = 0; \
if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { \
buf = (char *)(vmesa->drawMap); \
read_buf = (char *)(vmesa->readMap); \
} \
else { \
buf = (char *)(vmesa->drawMap + \
dPriv->x * 2 + \
dPriv->y * pitch); \
read_buf = (char *)(vmesa->readMap + \
dPriv->x * 2 + \
dPriv->y * pitch); \
}
#define INIT_MONO_PIXEL(p, color) \
p = PACK_COLOR_565(color[0], color[1], color[2])
#define WRITE_RGBA(_x, _y, r, g, b, a) \
*(GLushort *)(buf + _x * 2 + _y * pitch) = ((((int)r & 0xf8) << 8) | \
(((int)g & 0xfc) << 3) | \
(((int)b & 0xf8) >> 3))
#define WRITE_PIXEL(_x, _y, p) \
*(GLushort *)(buf + _x * 2 + _y * pitch) = p
#define READ_RGBA(rgba, _x, _y) \
do { \
GLushort p = *(GLushort *)(read_buf + _x * 2 + _y * pitch); \
rgba[0] = ((p >> 8) & 0xf8) * 255 / 0xf8; \
rgba[1] = ((p >> 3) & 0xfc) * 255 / 0xfc; \
rgba[2] = ((p << 3) & 0xf8) * 255 / 0xf8; \
rgba[3] = 255; \
} while (0)
#define TAG(x) via##x##_565
#include "spantmp.h"
/* 32 bit, 8888 argb color spanline and pixel functions
*/
#undef LOCAL_VARS
#undef LOCAL_DEPTH_VARS
/*=* [DBG] csmash : fix options worng position *=*/
/*#define LOCAL_VARS \
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
GLuint pitch = vmesa->drawPitch; \
GLuint height = dPriv->h; \
GLuint p; \
char *buf = (char *)(vmesa->drawMap + \
dPriv->x * 4 + \
dPriv->y * pitch); \
char *read_buf = (char *)(vmesa->readMap + \
dPriv->x * 4 + \
dPriv->y * pitch); \
(void)read_buf; (void)buf; (void)p*/
#define LOCAL_VARS \
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
GLuint pitch = vmesa->drawPitch; \
GLuint height = dPriv->h; \
GLuint p; \
char *buf, *read_buf; \
p = 0; \
if (vmesa->glCtx->Color._DrawDestMask & BACK_LEFT_BIT) { \
buf = (char *)(vmesa->drawMap); \
read_buf = (char *)(vmesa->readMap); \
} \
else { \
buf = (char *)(vmesa->drawMap + \
dPriv->x * 4 + \
dPriv->y * pitch); \
read_buf = (char *)(vmesa->readMap + \
dPriv->x * 4 + \
dPriv->y * pitch); \
}
#undef INIT_MONO_PIXEL
#define INIT_MONO_PIXEL(p, color) \
p = PACK_COLOR_8888(color[3], color[0], color[1], color[2])
#define WRITE_RGBA(_x, _y, r, g, b, a) \
*(GLuint *)(buf + _x * 4 + _y * pitch) = ((r << 16) | \
(g << 8) | \
(b << 0) | \
(a << 24));
#define WRITE_PIXEL(_x, _y, p) \
*(GLuint *)(buf + _x * 4 + _y * pitch) = p
#define READ_RGBA(rgba, _x, _y) \
do { \
GLuint p = *(GLuint *)(read_buf + _x * 4 + _y * pitch); \
rgba[0] = (p >> 16) & 0xff; \
rgba[1] = (p >> 8) & 0xff; \
rgba[2] = (p >> 0) & 0xff; \
rgba[3] = 255; \
} while (0)
#define TAG(x) via##x##_8888
#include "spantmp.h"
/*#include "via_spantmp.h"*/
/* 16 bit depthbuffer functions.
*/
/*=* John Sheng [2003.6.16] fix exy press 'i' dirty screen *=*/
/*#define LOCAL_DEPTH_VARS \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
GLuint pitch = vmesa->depth.pitch; \
GLuint height = dPriv->h; \
char *buf = (char *)(vmesa->depth.map + \
dPriv->x * 2 + \
dPriv->y * pitch) */
#define LOCAL_DEPTH_VARS \
viaContextPtr vmesa = VIA_CONTEXT(ctx); \
__DRIdrawablePrivate *dPriv = vmesa->driDrawable; \
/*viaScreenPrivate *viaScreen = vmesa->viaScreen;*/ \
GLuint pitch = vmesa->depth.pitch; \
GLuint height = dPriv->h; \
char *buf = (char *)(vmesa->depth.map)
#define WRITE_DEPTH(_x, _y, d) \
*(GLushort *)(buf + _x * 2 + _y * pitch) = d;
#define READ_DEPTH(d, _x, _y) \
d = *(GLushort *)(buf + _x * 2 + _y * pitch);
#define TAG(x) via##x##_16
#include "depthtmp.h"
/* 32 bit depthbuffer functions.
*/
#define WRITE_DEPTH(_x, _y, d) \
*(GLuint *)(buf + _x * 4 + _y * pitch) = d;
#define READ_DEPTH(d, _x, _y) \
d = *(GLuint *)(buf + _x * 4 + _y * pitch);
#define TAG(x) via##x##_32
#include "depthtmp.h"
/* 24/8 bit depthbuffer functions.
*/
/*
#define WRITE_DEPTH(_x, _y, d) { \
GLuint tmp = *(GLuint *)(buf + _x * 4 + y * pitch); \
tmp &= 0xff; \
tmp |= (d) & 0xffffff00; \
*(GLuint *)(buf + _x * 4 + _y * pitch) = tmp; \
#define READ_DEPTH(d, _x, _y) \
d = (*(GLuint *)(buf + _x * 4 + _y * pitch) & ~0xff) >> 8;
#define TAG(x) via##x##_24_8
#include "depthtmp.h"
*/
void viaSetBuffer(GLcontext *ctx, GLframebuffer *colorBuffer,
GLuint bufferBit)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (bufferBit == FRONT_LEFT_BIT) {
vmesa->drawMap = (char *)vmesa->driScreen->pFB;
vmesa->readMap = (char *)vmesa->driScreen->pFB;
vmesa->drawPitch = vmesa->front.pitch;
vmesa->readPitch = vmesa->front.pitch;
}
else if (bufferBit == BACK_LEFT_BIT) {
vmesa->drawMap = vmesa->back.map;
vmesa->readMap = vmesa->back.map;
vmesa->drawPitch = vmesa->back.pitch;
vmesa->readPitch = vmesa->back.pitch;
}
else {
ASSERT(0);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}
void viaInitSpanFuncs(GLcontext *ctx)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
struct swrast_device_driver *swdd = _swrast_GetDeviceDriverReference(ctx);
swdd->SetBuffer = viaSetBuffer;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
#endif
if (vmesa->viaScreen->bitsPerPixel == 0x10) {
swdd->WriteRGBASpan = viaWriteRGBASpan_565;
swdd->WriteRGBSpan = viaWriteRGBSpan_565;
swdd->WriteMonoRGBASpan = viaWriteMonoRGBASpan_565;
swdd->WriteRGBAPixels = viaWriteRGBAPixels_565;
swdd->WriteMonoRGBAPixels = viaWriteMonoRGBAPixels_565;
swdd->ReadRGBASpan = viaReadRGBASpan_565;
swdd->ReadRGBAPixels = viaReadRGBAPixels_565;
}
else if (vmesa->viaScreen->bitsPerPixel == 0x20) {
swdd->WriteRGBASpan = viaWriteRGBASpan_8888;
swdd->WriteRGBSpan = viaWriteRGBSpan_8888;
swdd->WriteMonoRGBASpan = viaWriteMonoRGBASpan_8888;
swdd->WriteRGBAPixels = viaWriteRGBAPixels_8888;
swdd->WriteMonoRGBAPixels = viaWriteMonoRGBAPixels_8888;
swdd->ReadRGBASpan = viaReadRGBASpan_8888;
swdd->ReadRGBAPixels = viaReadRGBAPixels_8888;
}
else
ASSERT(0);
if (vmesa->glCtx->Visual.depthBits == 0x10) {
swdd->ReadDepthSpan = viaReadDepthSpan_16;
swdd->WriteDepthSpan = viaWriteDepthSpan_16;
swdd->ReadDepthPixels = viaReadDepthPixels_16;
swdd->WriteDepthPixels = viaWriteDepthPixels_16;
}
else if (vmesa->glCtx->Visual.depthBits == 0x20) {
swdd->ReadDepthSpan = viaReadDepthSpan_32;
swdd->WriteDepthSpan = viaWriteDepthSpan_32;
swdd->ReadDepthPixels = viaReadDepthPixels_32;
swdd->WriteDepthPixels = viaWriteDepthPixels_32;
}
swdd->WriteCI8Span = NULL;
swdd->WriteCI32Span = NULL;
swdd->WriteMonoCISpan = NULL;
swdd->WriteCI32Pixels = NULL;
swdd->WriteMonoCIPixels = NULL;
swdd->ReadCI32Span = NULL;
swdd->ReadCI32Pixels = NULL;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s out\n", __FUNCTION__);
#endif
}

View file

@ -0,0 +1,30 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIA_SPAN_H
#define _VIA_SPAN_H
extern void viaInitSpanFuncs(GLcontext *ctx);
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,48 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIA_STATE_H
#define _VIA_STATE_H
#include "via_context.h"
extern void viaInitState(GLcontext *ctx);
extern void viaInitStateFuncs(GLcontext *ctx);
extern void viaPrintDirty(const char *msg, GLuint state);
extern void viaChooseTextureState(GLcontext *ctx);
extern void viaChooseColorState(GLcontext *ctx);
extern void viaChooseDepthState(GLcontext *ctx);
extern void viaChoosePolygonState(GLcontext *ctx);
extern void viaChoosePoint(GLcontext *ctx);
extern void viaChooseLine(GLcontext *ctx);
extern void viaChooseTriangle(GLcontext *ctx);
extern void viaChooseFogState(GLcontext *ctx);
extern void viaChooseStencilState(GLcontext *ctx);
extern void viaChooseLightState(GLcontext *ctx);
extern void viaChooseLineState(GLcontext *ctx);
extern void viaFallback(viaContextPtr vmesa, GLuint bit, GLboolean mode);
#define FALLBACK(vmesa, bit, mode) viaFallback(vmesa, bit, mode)
#endif

View file

@ -0,0 +1,432 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include "glheader.h"
/*#include "mem.h" _SOLO */
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"
#include "teximage.h"
#include "texobj.h"
#include "texstore.h"
#include "texformat.h"
#include "swrast/swrast.h"
#include "context.h"
#include "via_context.h"
#include "via_tex.h"
#include "via_state.h"
#include "via_ioctl.h"
/*
* Compute the 'S2.4' lod bias factor from the floating point OpenGL bias.
*/
/*
static GLuint viaComputeLodBias(GLfloat bias)
{
int b = (int)(bias * 16.0) + 12;
if (b > 63)
b = 63;
else if (b < -64)
b = -64;
return (GLuint)(b & MLC_LOD_BIAS_MASK);
}
*/
viaTextureObjectPtr viaAllocTextureObject(struct gl_texture_object *texObj)
{
viaTextureObjectPtr t;
t = (viaTextureObjectPtr)CALLOC_STRUCT(via_texture_object_t);
if (!t)
return NULL;
/* Initialize non-image-dependent parts of the state:
*/
t->bufAddr = NULL;
t->dirtyImages = ~0;
t->actualLevel = 0;
t->globj = texObj;
make_empty_list(t);
return t;
}
static void viaTexParameter(GLcontext *ctx, GLenum target,
struct gl_texture_object *texObj,
GLenum pname, const GLfloat *params)
{
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
if (!t)
return;
if (target != GL_TEXTURE_2D)
return;
}
static void viaTexEnv(GLcontext *ctx, GLenum target,
GLenum pname, const GLfloat *param)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
vmesa = vmesa;
}
static void viaTexImage1D(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)
{
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaTexImage1D - in\n");
#endif
if (t) {
if (level == 0) {
viaSwapOutTexObj(VIA_CONTEXT(ctx), t);
t->actualLevel = 0;
}
else
t->actualLevel++;
}
else {
t = viaAllocTextureObject(texObj);
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "viaTexImage1D");
return;
}
texObj->DriverData = t;
}
_mesa_store_teximage1d(ctx, target, level, internalFormat,
width, border, format, type,
pixels, packing, texObj, texImage);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaTexImage1D - out\n");
#endif
}
static void viaTexSubImage1D(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)
{
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
if (t) {
viaSwapOutTexObj(VIA_CONTEXT(ctx), t);
}
_mesa_store_texsubimage1d(ctx, target, level, xoffset, width,
format, type, pixels, packing, texObj,
texImage);
}
static void viaTexImage2D(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)
{
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaTexImage2D - in\n");
#endif
if (t) {
if (level == 0) {
viaSwapOutTexObj(VIA_CONTEXT(ctx), t);
t->actualLevel = 0;
}
else
t->actualLevel++;
}
else {
t = viaAllocTextureObject(texObj);
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "viaTexImage2D");
return;
}
texObj->DriverData = t;
}
_mesa_store_teximage2d(ctx, target, level, internalFormat,
width, height, border, format, type,
pixels, packing, texObj, texImage);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaTexImage2D - out\n");
#endif
}
static void viaTexSubImage2D(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)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
if (t) {
viaSwapOutTexObj(VIA_CONTEXT(ctx), t);
}
_mesa_store_texsubimage2d(ctx, target, level, xoffset, yoffset, width,
height, format, type, pixels, packing, texObj,
texImage);
if(vmesa->shareCtx)
vmesa->shareCtx->NewState |= _NEW_TEXTURE;
}
static void viaBindTexture(GLcontext *ctx, GLenum target,
struct gl_texture_object *texObj)
{
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaBindTexture - in\n");
#endif
if (target == GL_TEXTURE_2D) {
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
if (!t) {
t = viaAllocTextureObject(texObj);
if (!t) {
_mesa_error(ctx, GL_OUT_OF_MEMORY, "viaBindTexture");
return;
}
texObj->DriverData = t;
}
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaBindTexture - out\n");
#endif
}
static void viaDeleteTexture(GLcontext *ctx, struct gl_texture_object *texObj)
{
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaDeleteTexture - in\n");
#endif
if (t) {
viaContextPtr vmesa = VIA_CONTEXT(ctx);
if (vmesa) {
/*=* John Sheng [2003.7.18] viewperf frames/sec *=*/
/*VIA_FIREVERTICES(vmesa);*/
if (vmesa->dma[0].map) { /* imply vmesa is not under destroying */
VIA_FIREVERTICES(vmesa);
}
viaDestroyTexObj(vmesa, t);
}
texObj->DriverData = 0;
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaDeleteTexture - out\n");
#endif
}
static GLboolean viaIsTextureResident(GLcontext *ctx,
struct gl_texture_object *texObj)
{
viaTextureObjectPtr t = (viaTextureObjectPtr)texObj->DriverData;
return t && t->bufAddr;
}
static const struct gl_texture_format *
viaChooseTexFormat(GLcontext *ctx, GLint internalFormat,
GLenum format, GLenum type)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
(void)format;
(void)type;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s in\n", __FUNCTION__);
if (VIA_DEBUG) fprintf(stderr, "internalFormat:%d format:%d\n", internalFormat, format);
#endif
switch (internalFormat) {
case 1:
case GL_LUMINANCE:
case GL_LUMINANCE4:
case GL_LUMINANCE8:
case GL_LUMINANCE12:
case GL_LUMINANCE16:
return &_mesa_texformat_l8;
case 2:
case GL_LUMINANCE_ALPHA:
case GL_LUMINANCE4_ALPHA4:
case GL_LUMINANCE6_ALPHA2:
case GL_LUMINANCE8_ALPHA8:
case GL_LUMINANCE12_ALPHA4:
case GL_LUMINANCE12_ALPHA12:
case GL_LUMINANCE16_ALPHA16:
return &_mesa_texformat_al88;
case GL_R3_G3_B2:
case GL_RGB4:
case GL_RGB5:
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "2 &_mesa_texformat_arg565\n");
#endif
return &_mesa_texformat_rgb565;
case 3:
case GL_RGB:
case GL_RGB8:
case GL_RGB10:
case GL_RGB12:
case GL_RGB16:
if (vmesa->viaScreen->bitsPerPixel == 0x20) {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr,"3 argb8888\n");
#endif
return &_mesa_texformat_argb8888;
}
else {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr,"3 rgb565\n");
#endif
return &_mesa_texformat_rgb565;
}
case 4:
if (vmesa->viaScreen->bitsPerPixel == 0x20) {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "4 &_mesa_texformat_argb8888\n");
#endif
return &_mesa_texformat_argb8888;
}
else {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "4 &_mesa_texformat_argb4444\n");
#endif
return &_mesa_texformat_argb4444;
}
case GL_RGBA2:
case GL_RGBA4:
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "GL_RGBA4 &_mesa_texformat_argb4444\n");
#endif
return &_mesa_texformat_argb4444;
case GL_RGB5_A1:
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "GL_RGB5_A1 &_mesa_texformat_argb1555\n");
#endif
return &_mesa_texformat_argb1555;
case GL_RGBA:
case GL_RGBA8:
case GL_RGBA12:
case GL_RGBA16:
case GL_RGB10_A2:
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "GL_RGBA &_mesa_texformat_argb8888\n");
#endif
return &_mesa_texformat_argb8888;
case GL_ALPHA:
case GL_ALPHA4:
case GL_ALPHA8:
case GL_ALPHA12:
case GL_ALPHA16:
return &_mesa_texformat_a8;
case GL_INTENSITY:
case GL_INTENSITY4:
case GL_INTENSITY8:
case GL_INTENSITY12:
case GL_INTENSITY16:
return &_mesa_texformat_i8;
case GL_COLOR_INDEX:
case GL_COLOR_INDEX1_EXT:
case GL_COLOR_INDEX2_EXT:
case GL_COLOR_INDEX4_EXT:
case GL_COLOR_INDEX8_EXT:
case GL_COLOR_INDEX12_EXT:
case GL_COLOR_INDEX16_EXT:
return &_mesa_texformat_ci8;
default:
_mesa_problem(ctx, "unexpected format in viaChooseTextureFormat");
return NULL;
}
}
void viaInitTextureFuncs(struct dd_function_table * functions)
{
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaInitTextureFuncs - in\n");
#endif
functions->TexEnv = viaTexEnv;
functions->ChooseTextureFormat = viaChooseTexFormat;
functions->TexImage1D = viaTexImage1D;
functions->TexImage2D = viaTexImage2D;
functions->TexImage3D = _mesa_store_teximage3d;
functions->TexSubImage1D = viaTexSubImage1D;
functions->TexSubImage2D = viaTexSubImage2D;
functions->TexSubImage3D = _mesa_store_texsubimage3d;
functions->CopyTexImage1D = _swrast_copy_teximage1d;
functions->CopyTexImage2D = _swrast_copy_teximage2d;
functions->CopyTexSubImage1D = _swrast_copy_texsubimage1d;
functions->CopyTexSubImage2D = _swrast_copy_texsubimage2d;
functions->CopyTexSubImage3D = _swrast_copy_texsubimage3d;
functions->NewTextureObject = _mesa_new_texture_object;
functions->BindTexture = viaBindTexture;
functions->DeleteTexture = viaDeleteTexture;
functions->TexParameter = viaTexParameter;
functions->UpdateTexturePalette = 0;
functions->IsTextureResident = viaIsTextureResident;
functions->TestProxyTexImage = _mesa_test_proxy_teximage;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "viaInitTextureFuncs - out\n");
#endif
}
void viaInitTextures(GLcontext *ctx)
{
GLuint tmp = ctx->Texture.CurrentUnit;
ctx->Texture.CurrentUnit = 0;
viaBindTexture(ctx, GL_TEXTURE_1D, ctx->Texture.Unit[0].Current1D);
viaBindTexture(ctx, GL_TEXTURE_2D, ctx->Texture.Unit[0].Current2D);
ctx->Texture.CurrentUnit = 1;
viaBindTexture(ctx, GL_TEXTURE_1D, ctx->Texture.Unit[1].Current1D);
viaBindTexture(ctx, GL_TEXTURE_2D, ctx->Texture.Unit[1].Current2D);
ctx->Texture.CurrentUnit = tmp;
}

View file

@ -0,0 +1,113 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIATEX_H
#define _VIATEX_H
#include "mtypes.h"
/*#include "mmath.h"*/
#include "mm.h"
#include "via_context.h"
#include "via_3d_reg.h"
#define VIA_TEX_MAXLEVELS 10
/* For shared texture space managment, these texture objects may also
* be used as proxies for regions of texture memory containing other
* client's textures. Such proxy textures (not to be confused with GL
* proxy textures) are subject to the same LRU aging we use for our
* own private textures, and thus we have a mechanism where we can
* fairly decide between kicking out our own textures and those of
* other clients.
*
* Non-local texture objects have a valid MemBlock to describe the
* region managed by the other client, and can be identified by
* 't->globj == 0'
*/
struct via_texture_object_t {
struct via_texture_object_t *next, *prev;
GLuint age;
struct gl_texture_object *globj;
int texelBytes;
int totalSize;
struct {
GLuint index;
GLuint offset;
GLuint size;
} texMem;
unsigned char* bufAddr;
GLuint inAGP;
GLuint needClearCache;
GLuint actualLevel;
GLuint maxLevel;
GLuint dirtyImages;
struct {
const struct gl_texture_image *image;
int offset; /* into bufAddr */
int height;
int internalFormat;
} image[VIA_TEX_MAXLEVELS];
GLuint dirty;
GLuint regTexFM;
GLuint regTexWidthLog2[2];
GLuint regTexHeightLog2[2];
GLuint regTexBaseH[4];
struct {
GLuint baseL;
GLuint pitchLog2;
} regTexBaseAndPitch[12];
GLint firstLevel, lastLevel; /* upload tObj->Image[first .. lastLevel] */
};
viaTextureObjectPtr viaAllocTextureObject(struct gl_texture_object *texObj);
void viaUpdateTextureState(GLcontext *ctx);
void viaInitTextureFuncs(struct dd_function_table * functions);
void viaInitTextures(GLcontext *ctx);
void viaDestroyTexObj(viaContextPtr vmesa, viaTextureObjectPtr t);
void viaSwapOutTexObj(viaContextPtr vmesa, viaTextureObjectPtr t);
void viaUploadTexImages(viaContextPtr vmesa, viaTextureObjectPtr t);
void viaResetGlobalLRU(viaContextPtr vmesa);
void viaTexturesGone(viaContextPtr vmesa,
GLuint start, GLuint end,
GLuint in_use);
void viaPrintLocalLRU(viaContextPtr vmesa);
void viaPrintGlobalLRU(viaContextPtr vmesa);
void viaUpdateTexLRU(viaContextPtr vmesa, viaTextureObjectPtr t);
#endif

View file

@ -0,0 +1,499 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"
#include "texformat.h"
#include "mm.h"
#include "via_context.h"
#include "via_tex.h"
#include "via_state.h"
#include "via_ioctl.h"
#include "via_fb.h"
/*=* John Sheng [2003.5.31] agp tex *=*/
GLuint agpFullCount = 0;
void viaDestroyTexObj(viaContextPtr vmesa, viaTextureObjectPtr t)
{
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
if (!t)
return;
/* This is sad - need to sync *in case* we upload a texture
* to this newly free memory...
*/
if (t->bufAddr) {
via_free_texture(vmesa, t);
if (vmesa && t->age > vmesa->dirtyAge)
vmesa->dirtyAge = t->age;
}
if (t->globj)
t->globj->DriverData = 0;
if (vmesa) {
if (vmesa->CurrentTexObj[0] == t) {
vmesa->CurrentTexObj[0] = 0;
vmesa->dirty &= ~VIA_UPLOAD_TEX0;
}
if (vmesa->CurrentTexObj[1] == t) {
vmesa->CurrentTexObj[1] = 0;
vmesa->dirty &= ~VIA_UPLOAD_TEX1;
}
}
remove_from_list(t);
free(t);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
void viaSwapOutTexObj(viaContextPtr vmesa, viaTextureObjectPtr t)
{
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
if (t->bufAddr) {
via_free_texture(vmesa, t);
if (t->age > vmesa->dirtyAge)
vmesa->dirtyAge = t->age;
}
t->dirtyImages = ~0;
move_to_tail(&(vmesa->SwappedOut), t);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
/* Upload an image from mesa's internal copy.
*/
static void viaUploadTexLevel(viaTextureObjectPtr t, int level)
{
const struct gl_texture_image *image = t->image[level].image;
int i, j;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "%s - in\n", __FUNCTION__);
fprintf(stderr, "width = %d, height = %d \n", image->Width, image->Height);
}
#endif
switch (t->image[level].internalFormat) {
case GL_RGB:
{
if (image->TexFormat->MesaFormat == MESA_FORMAT_ARGB8888) {
GLuint *dst = (GLuint *)(t->bufAddr + t->image[level].offset);
GLuint *src = (GLuint *)image->Data;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "GL_RGB MESA_FORMAT_ARGB8888\n");
#endif
if (image->Width < 8) {
for (i = 0; i < image->Height ; i++) {
for (j = 0; j < image->Width ; j++) {
dst[j] = *src;
src++;
}
dst += 8;
}
}
else {
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
dst++;
src++;
}
}
/*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
}
else {
GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
GLushort *src = (GLushort *)image->Data;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "GL_RGB !MESA_FORMAT_ARGB8888\n");
#endif
if (image->Width < 16) {
for (i = 0; i < image->Height ; i++) {
for (j = 0; j < image->Width ; j++) {
dst[j] = *src;
src++;
}
dst += 16;
}
}
else {
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
dst++;
src++;
}
}
/*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
}
}
break;
case GL_RGBA:
{
if (image->TexFormat->MesaFormat == MESA_FORMAT_ARGB4444) {
GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
GLushort *src = (GLushort *)image->Data;
if (image->Width < 16) {
for (i = 0; i < image->Height ; i++) {
for (j = 0; j < image->Width ; j++) {
dst[j] = *src;
src++;
}
dst += 16;
}
}
else {
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
src++;
dst++;
}
}
/*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "GL_RGBA MESA_FORMAT_ARGB4444\n");
#endif
}
else if(image->TexFormat->MesaFormat == MESA_FORMAT_ARGB8888) {
GLuint *dst = (GLuint *)(t->bufAddr + t->image[level].offset);
GLuint *src = (GLuint *)image->Data;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "GL_RGBA !MESA_FORMAT_ARGB4444\n");
#endif
if (image->Width < 8) {
for (i = 0; i < image->Height ; i++) {
for (j = 0; j < image->Width ; j++) {
dst[j] = *src;
src++;
}
dst += 8;
}
}
else {
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
dst++;
src++;
}
}
/*memcpy(dst, src, image->Height * image->Width * sizeof(GLuint));*/
}
else if(image->TexFormat->MesaFormat == MESA_FORMAT_ARGB1555) {
GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
GLushort *src = (GLushort *)image->Data;
if (image->Width < 16) {
for (i = 0; i < image->Height ; i++) {
for (j = 0; j < image->Width ; j++) {
dst[j] = *src;
src++;
}
dst += 16;
}
}
else {
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
src++;
dst++;
}
}
/*memcpy(dst, src, image->Height * image->Width * sizeof(GLushort));*/
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "GL_RGBA MESA_FORMAT_ARGB1555\n");
#endif
}
}
break;
case GL_LUMINANCE:
{
GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
GLubyte *src = (GLubyte *)image->Data;
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
dst++;
src++;
}
}
break;
case GL_INTENSITY:
{
GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
GLubyte *src = (GLubyte *)image->Data;
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
dst++;
src++;
}
}
break;
case GL_LUMINANCE_ALPHA:
{
GLushort *dst = (GLushort *)(t->bufAddr + t->image[level].offset);
GLushort *src = (GLushort *)image->Data;
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
dst++;
src++;
}
}
break;
case GL_ALPHA:
{
GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
GLubyte *src = (GLubyte *)image->Data;
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
dst++;
src++;
}
}
break;
/* TODO: Translate color indices *now*:
*/
case GL_COLOR_INDEX:
{
GLubyte *dst = (GLubyte *)(t->bufAddr + t->image[level].offset);
GLubyte *src = (GLubyte *)image->Data;
for (j = 0; j < image->Height * image->Width; j++) {
*dst = *src;
dst++;
src++;
}
}
break;
default:;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "Not supported texture format %s\n",
_mesa_lookup_enum_by_nr(image->Format));
#endif
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
void viaPrintLocalLRU(viaContextPtr vmesa)
{
viaTextureObjectPtr t;
foreach (t, &vmesa->TexObjList) {
if (!t->globj) {
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "offset = %x, index = %x, size = %x\n",
t->texMem.offset,
t->texMem.index,
t->texMem.size);
}
else {
if (VIA_DEBUG) {
fprintf(stderr, "offset = %x, siez = %x\n",
t->texMem.offset,
t->texMem.size);
}
}
#endif
}
}
}
void viaPrintGlobalLRU(viaContextPtr vmesa)
{
int i, j;
drm_via_tex_region_t *list = vmesa->sarea->texList;
for (i = 0, j = VIA_NR_TEX_REGIONS; i < VIA_NR_TEX_REGIONS; i++) {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "list[%d] age %d next %d prev %d\n",
j, list[j].age, list[j].next, list[j].prev);
#endif
j = list[j].next;
if (j == VIA_NR_TEX_REGIONS) break;
}
#ifdef DEBUG
if (j != VIA_NR_TEX_REGIONS)
if (VIA_DEBUG) fprintf(stderr, "Loop detected in global LRU\n");
#endif
}
void viaResetGlobalLRU(viaContextPtr vmesa)
{
drm_via_tex_region_t *list = vmesa->sarea->texList;
int sz = 1 << vmesa->viaScreen->logTextureGranularity;
int i;
/* (Re)initialize the global circular LRU list. The last element
* in the array (VIA_NR_TEX_REGIONS) is the sentinal. Keeping it
* at the end of the array allows it to be addressed rationally
* when looking up objects at a particular location in texture
* memory.
*/
for (i = 0; (i + 1) * sz <= vmesa->viaScreen->textureSize; i++) {
list[i].prev = i - 1;
list[i].next = i + 1;
list[i].age = 0;
}
i--;
list[0].prev = VIA_NR_TEX_REGIONS;
list[i].prev = i - 1;
list[i].next = VIA_NR_TEX_REGIONS;
list[VIA_NR_TEX_REGIONS].prev = i;
list[VIA_NR_TEX_REGIONS].next = 0;
vmesa->sarea->texAge = 0;
}
void viaUpdateTexLRU(viaContextPtr vmesa, viaTextureObjectPtr t)
{
vmesa->texAge = ++vmesa->sarea->texAge;
move_to_head(&(vmesa->TexObjList), t);
}
/* Called for every shared texture region which has increased in age
* since we last held the lock.
*
* Figures out which of our textures have been ejected by other clients,
* and pushes a placeholder texture onto the LRU list to represent
* the other client's textures.
*/
void viaTexturesGone(viaContextPtr vmesa,
GLuint offset,
GLuint size,
GLuint inUse)
{
viaTextureObjectPtr t, tmp;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
foreach_s (t, tmp, &vmesa->TexObjList) {
viaSwapOutTexObj(vmesa, t);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
/* This is called with the lock held. May have to eject our own and/or
* other client's texture objects to make room for the upload.
*/
void viaUploadTexImages(viaContextPtr vmesa, viaTextureObjectPtr t)
{
int i, j;
int numLevels;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
LOCK_HARDWARE(vmesa);
j = 0;
if (!t->bufAddr) {
while (1) {
/*=* John Sheng [2003.5.31] agp tex *=*/
via_alloc_texture(vmesa, t);
/*via_alloc_texture_agp(vmesa, t);*/
if (t->texMem.offset)
break;
else
agpFullCount++;
if (vmesa->TexObjList.prev == vmesa->CurrentTexObj[0] ||
vmesa->TexObjList.prev == vmesa->CurrentTexObj[1]) {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "Hit bound texture in upload\n");
#endif
viaPrintLocalLRU(vmesa);
UNLOCK_HARDWARE(vmesa);
return;
}
if (vmesa->TexObjList.prev == &(vmesa->TexObjList)) {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "Failed to upload texture, sz %d\n", t->totalSize);
#endif
mmDumpMemInfo(vmesa->texHeap);
UNLOCK_HARDWARE(vmesa);
return;
}
viaSwapOutTexObj(vmesa, vmesa->TexObjList.prev);
}
/*=* John Sheng [2003.5.31] agp tex *=*/
/*t->bufAddr = (char *)((GLuint)vmesa->driScreen->pFB + t->texMem.offset);*/
if (t == vmesa->CurrentTexObj[0])
VIA_STATECHANGE(vmesa, VIA_UPLOAD_TEX0);
if (t == vmesa->CurrentTexObj[1])
VIA_STATECHANGE(vmesa, VIA_UPLOAD_TEX1);
viaUpdateTexLRU(vmesa, t);
j++;
}
numLevels = t->lastLevel - t->firstLevel + 1;
for (i = 0; i < numLevels; i++)
if (t->dirtyImages & (1 << i))
viaUploadTexLevel(t, i);
t->dirtyImages = 0;
UNLOCK_HARDWARE(vmesa);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}

View file

@ -0,0 +1,725 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <stdlib.h>
#include <stdio.h>
#include "glheader.h"
#include "macros.h"
#include "mtypes.h"
#include "simple_list.h"
#include "enums.h"
#include "context.h"
#include "texformat.h"
#include "mm.h"
#include "via_context.h"
#include "via_tex.h"
#include "via_state.h"
#include "via_ioctl.h"
GLint texSize8bpp[12][12] = {
{32,32,32,32,32,32,64,128,256,512,1024,2048},
{64,64,64,64,64,64,128,256,512,1024,2048,4096},
{128,128,128,128,128,128,256,512,1024,2048,4096,8192},
{256,256,256,256,256,256,512,1024,2048,4096,8192,16384},
{512,512,512,512,512,512,1024,2048,4096,8192,16384,32768},
{1024,1024,1024,1024,1024,1024,2048,4096,8192,16384,32768,65536},
{2048,2048,2048,2048,2048,2048,4096,8192,16384,32768,65536,131072},
{4096,4096,4096,4096,4096,4096,8192,16384,32768,65536,131072,262144},
{8192,8192,8192,8192,8192,8192,16384,32768,65536,131072,262144,524288},
{16384,16384,16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576},
{32768,32768,32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152},
{65536,65536,65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304
}
};
GLint texSize16bpp[12][12] = {
{32,32,32,32,32,64,128,256,512,1024,2048,4096},
{64,64,64,64,64,128,256,512,1024,2048,4096,8192},
{128,128,128,128,128,256,512,1024,2048,4096,8192,16384},
{256,256,256,256,256,512,1024,2048,4096,8192,16384,32768},
{512,512,512,512,512,1024,2048,4096,8192,16384,32768,65536},
{1024,1024,1024,1024,1024,2048,4096,8192,16384,32768,65536,131072},
{2048,2048,2048,2048,2048,4096,8192,16384,32768,65536,131072,262144},
{4096,4096,4096,4096,4096,8192,16384,32768,65536,131072,262144,524288},
{8192,8192,8192,8192,8192,16384,32768,65536,131072,262144,524288,1048576},
{16384,16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576,2097152},
{32768,32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152,4194304},
{65536,65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304,8388608}
};
GLint texSize32bpp[12][12] = {
{32,32,32,32,64,128,256,512,1024,2048,4096,8192},
{64,64,64,64,128,256,512,1024,2048,4096,8192,16384},
{128,128,128,128,256,512,1024,2048,4096,8192,16384,32768},
{256,256,256,256,512,1024,2048,4096,8192,16384,32768,65536},
{512,512,512,512,1024,2048,4096,8192,16384,32768,65536,131072},
{1024,1024,1024,1024,2048,4096,8192,16384,32768,65536,131072,262144},
{2048,2048,2048,2048,4096,8192,16384,32768,65536,131072,262144,524288},
{4096,4096,4096,4096,8192,16384,32768,65536,131072,262144,524288,1048576},
{8192,8192,8192,8192,16384,32768,65536,131072,262144,524288,1048576,2097152},
{16384,16384,16384,16384,32768,65536,131072,262144,524288,1048576,2097152,4194304},
{32768,32768,32768,32768,65536,131072,262144,524288,1048576,2097152,4194304,8388608},
{65536,65536,65536,65536,131072,262144,524288,1048576,2097152,4194304,8388608,16777216}
};
GLint mipmapTexSize8bpp[12][12] = {
{32,64,96,128,160,192,256,384,640,1152,2176,4224},
{96,96,128,160,192,224,320,512,896,1664,3200,6272},
{224,224,224,256,288,320,480,832,1536,2944,5760,11392},
{480,480,480,480,512,544,832,1504,2880,5632,11136,22144},
{992,992,992,992,992,1024,1568,2880,5600,11072,22016,43904},
{2016,2016,2016,2016,2016,2016,3072,5664,11072,21984,43840,87552},
{4064,4064,4064,4064,4064,4064,6112,11264,22048,43840,87520,174912},
{8160,8160,8160,8160,8160,8160,12256,22496,44032,87584,174912,349664},
{16352,16352,16352,16352,16352,16352,24544,45024,88032,175104,349728,699200},
{32736,32736,32736,32736,32736,32736,49120,90080,176096,350176,699392,1398304},
{65504,65504,65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796544},
{131040,131040,131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056
}
};
GLint mipmapTexSize16bpp[12][12] = {
{32,64,96,128,160,224,352,608,1120,2144,4192,8288},
{96,96,128,160,192,288,480,864,1632,3168,6240,12384},
{224,224,224,256,288,448,800,1504,2912,5728,11360,22624},
{480,480,480,480,512,800,1472,2848,5600,11104,22112,44128},
{992,992,992,992,992,1536,2848,5568,11040,21984,43872,87648},
{2016,2016,2016,2016,2016,3040,5632,11040,21952,43808,87520,174944},
{4064,4064,4064,4064,4064,6112,11232,22016,43808,87488,174880,349664},
{8160,8160,8160,8160,8160,12256,22496,44000,87552,174880,349632,699168},
{16352,16352,16352,16352,16352,24544,45024,88032,175072,349696,699168,1398208},
{32736,32736,32736,32736,32736,49120,90080,176096,350176,699360,1398272,2796320},
{65504,65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796512,5592576},
{131040,131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056,11185120}
};
GLint mipmapTexSize32bpp[12][12] = {
{32,64,96,128,192,320,576,1088,2112,4160,8256,16448},
{96,96,128,160,256,448,832,1600,3136,6208,12352,24640},
{224,224,224,256,416,768,1472,2880,5696,11328,22592,45120},
{480,480,480,480,768,1440,2816,5568,11072,22080,44096,88128},
{992,992,992,992,1504,2816,5536,11008,21952,43840,87616,175168},
{2016,2016,2016,2016,3040,5600,11008,21920,43776,87488,174912,349760},
{4064,4064,4064,4064,6112,11232,21984,43776,87456,174848,349632,699200},
{8160,8160,8160,8160,12256,22496,44000,87520,174848,349600,699136,1398208},
{16352,16352,16352,16352,24544,45024,88032,175072,349664,699136,1398176,2796288},
{32736,32736,32736,32736,49120,90080,176096,350176,699360,1398240,2796288,5592480},
{65504,65504,65504,65504,98272,180192,352224,700384,1398752,2796512,5592544,11184896},
{131040,131040,131040,131040,196576,360416,704480,1400800,2797536,5593056,11185120,22369760}
};
static int logbase2(int n)
{
GLint i = 1;
GLint log2 = 0;
if (n < 0) {
return -1;
}
while (n > i) {
i *= 2;
log2++;
}
if (i != n) {
return -1;
}
else {
return log2;
}
}
static void viaSetTexImages(viaContextPtr vmesa,
struct gl_texture_object *tObj)
{
GLuint texFormat;
viaTextureObjectPtr t = (viaTextureObjectPtr)tObj->DriverData;
const struct gl_texture_image *baseImage = tObj->Image[tObj->BaseLevel];
GLint firstLevel, lastLevel, numLevels;
GLint log2Width, log2Height, log2Pitch;
GLint (*texSize)[12][12];
GLint w, h, p;
GLint i, j, k, l, m;
GLint mipmapSize;
GLuint texBase;
GLuint basH = 0;
GLuint widthExp = 0;
GLuint heightExp = 0;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
switch (baseImage->TexFormat->MesaFormat) {
case MESA_FORMAT_ARGB8888:
if (t->image[tObj->BaseLevel].internalFormat == GL_RGB)
texFormat = HC_HTXnFM_ARGB0888;
else
texFormat = HC_HTXnFM_ARGB8888;
break;
case MESA_FORMAT_ARGB4444:
texFormat = HC_HTXnFM_ARGB4444;
break;
case MESA_FORMAT_RGB565:
texFormat = HC_HTXnFM_RGB565;
break;
case MESA_FORMAT_ARGB1555:
texFormat = HC_HTXnFM_ARGB1555;
break;
case MESA_FORMAT_L8:
texFormat = HC_HTXnFM_L8;
break;
case MESA_FORMAT_I8:
texFormat = HC_HTXnFM_T8;
break;
case MESA_FORMAT_CI8:
texFormat = HC_HTXnFM_Index8;
break;
case MESA_FORMAT_AL88:
texFormat = HC_HTXnFM_AL88;
break;
/*=* John Sheng [2003.7.18] texenv *=*/
case MESA_FORMAT_A8:
texFormat = HC_HTXnFM_A8;
break;
default:
_mesa_problem(vmesa->glCtx, "Bad texture format in viaSetTexImages");
fprintf(stderr, "-- TexFormat = %d\n",baseImage->TexFormat->MesaFormat);
};
/* 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.
*/
if (tObj->MinFilter == GL_LINEAR || tObj->MinFilter == GL_NEAREST) {
firstLevel = lastLevel = tObj->BaseLevel;
}
else {
firstLevel = tObj->BaseLevel + (GLint)(tObj->MinLod + 0.5);
firstLevel = MAX2(firstLevel, tObj->BaseLevel);
lastLevel = tObj->BaseLevel + (GLint)(tObj->MaxLod + 0.5);
lastLevel = MAX2(lastLevel, tObj->BaseLevel);
lastLevel = MIN2(lastLevel, tObj->BaseLevel + baseImage->MaxLog2);
lastLevel = MIN2(lastLevel, tObj->MaxLevel);
lastLevel = MAX2(firstLevel, lastLevel); /* need at least one level */
}
/* save these values */
t->firstLevel = firstLevel;
t->lastLevel = lastLevel;
numLevels = lastLevel - firstLevel + 1;
/*=* [DBG] fgfs : fix mipmap level 11 over hw limitations and result in segmentation fault *=*/
if(numLevels > 10) {
numLevels = 10;
t->lastLevel = firstLevel + 9;
}
log2Width = tObj->Image[firstLevel]->WidthLog2;
log2Height = tObj->Image[firstLevel]->HeightLog2;
log2Pitch = logbase2(tObj->Image[firstLevel]->Width * baseImage->TexFormat->TexelBytes);
for (i = 0; i < numLevels; i++) {
t->image[i].image = tObj->Image[i];
t->image[i].internalFormat = baseImage->Format;
}
if (baseImage->TexFormat->TexelBytes == 1) {
if (numLevels > 1)
texSize = &mipmapTexSize8bpp;
else
texSize = &texSize8bpp;
}
else if (baseImage->TexFormat->TexelBytes == 2) {
if (numLevels > 1)
texSize = &mipmapTexSize16bpp;
else
texSize = &texSize16bpp;
}
else {
if (numLevels > 1)
texSize = &mipmapTexSize32bpp;
else
texSize = &texSize32bpp;
}
t->totalSize = (*texSize)[log2Height][log2Width];
t->texMem.size = t->totalSize;
t->maxLevel = i - 1;
t->dirty = VIA_UPLOAD_TEX0 | VIA_UPLOAD_TEX1;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "log2Width = %d\n", log2Width);
fprintf(stderr, "log2Height = %d\n", log2Height);
fprintf(stderr, "log2Pitch = %d\n", log2Pitch);
fprintf(stderr, "bytePerTexel = %d\n", baseImage->TexFormat->TexelBytes);
fprintf(stderr, "total size = %d\n", t->totalSize);
fprintf(stderr, "actual level = %d\n", t->actualLevel);
fprintf(stderr, "numlevel = %d\n", numLevels);
}
#endif
{
w = log2Width;
h = log2Height;
for (i = 0; i < numLevels; i++) {
t->image[i].offset = t->totalSize - (*texSize)[h][w];
if (w) w--;
if (h) h--;
}
}
viaUploadTexImages(vmesa, t);
if (t->bufAddr) {
if (t->inAGP)
t->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_AGP | texFormat;
else
t->regTexFM = (HC_SubA_HTXnFM << 24) | HC_HTXnLoc_Local | texFormat;
w = log2Width;
h = log2Height;
p = log2Pitch;
mipmapSize = 0;
for (i = 0; i < numLevels; i++) {
if (i == (numLevels - 1))
mipmapSize = 0;
else
mipmapSize = (*texSize)[h][w];
/*=* John Sheng [2003.5.31] agp tex *=*/
if (t->inAGP)
texBase = (GLuint)vmesa->agpBase + t->texMem.offset + t->image[i].offset;
else
texBase = t->texMem.offset + t->image[i].offset;
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "texmem offset = %x\n", t->texMem.offset);
fprintf(stderr, "mipmap%d addr = %x\n", i, t->image[i].offset);
fprintf(stderr, "mipmap%d size = %d, h = %d, w = %d\n", i, (*texSize)[h][w], h, w);
fprintf(stderr, "texBase%d = %x\n", i, texBase);
}
#endif
t->regTexBaseAndPitch[i].baseL = ((HC_SubA_HTXnL0BasL + i) << 24) | (texBase & 0xFFFFFF);
if (p < 5) {
t->regTexBaseAndPitch[i].pitchLog2 = ((HC_SubA_HTXnL0Pit + i) << 24) |
(0x5 << 20);
}
else {
t->regTexBaseAndPitch[i].pitchLog2 = ((HC_SubA_HTXnL0Pit + i) << 24) |
((GLuint)p << 20);
}
j = i / 3;
k = 3 - (i % 3);
basH |= ((texBase & 0xFF000000) >> (k << 3));
if (k == 1) {
t->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;
basH = 0;
}
l = i / 6;
m = i % 6;
widthExp |= (((GLuint)w & 0xF) << (m << 2));
heightExp |= (((GLuint)h & 0xF) << (m << 2));
if (m == 5) {
t->regTexWidthLog2[l] = ((l + HC_SubA_HTXnL0_5WE) << 24 | widthExp);
t->regTexHeightLog2[l] = ((l + HC_SubA_HTXnL0_5HE) << 24 | heightExp);
widthExp = 0;
heightExp = 0;
}
if (w) w--;
if (h) h--;
if (p) p--;
}
if (k != 1) {
t->regTexBaseH[j] = ((j + HC_SubA_HTXnL012BasH) << 24) | basH;
}
if (m != 5) {
t->regTexWidthLog2[l] = ((l + HC_SubA_HTXnL0_5WE) << 24 | widthExp);
t->regTexHeightLog2[l] = ((l + HC_SubA_HTXnL0_5HE) << 24 | heightExp);
}
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
/* ================================================================
* Texture combine functions
*/
#define VIA_DISABLE 0
#define VIA_PASSTHRU 1
#define VIA_REPLACE 2
#define VIA_MODULATE 3
#define VIA_DECAL 4
#define VIA_BLEND 5
#define VIA_ALPHA_BLEND 6
#define VIA_ADD 7
#define VIA_MAX_COMBFUNC 8
static GLuint via_color_combine[][VIA_MAX_COMBFUNC] =
{
/* Unit 0:
*/
{
/* Disable combiner stage
*/
0,
/* Passthru
*/
1,
/* GL_REPLACE
*/
2,
/* GL_MODULATE
*/
3,
/* GL_DECAL
*/
4,
/* GL_BLEND
*/
5,
/* GL_BLEND according to alpha
*/
6,
/* GL_ADD
*/
7,
},
/* Unit 1:
*/
{
/* Disable combiner stage (Note: disables all subsequent stages)
*/
0,
/* Passthru
*/
1,
/* GL_REPLACE
*/
2,
/* GL_MODULATE
*/
3,
/* GL_DECAL
*/
4,
/* GL_BLEND
*/
5,
/* GL_BLEND according to alpha
*/
6,
/* GL_ADD
*/
7,
}
};
static GLuint via_alpha_combine[][VIA_MAX_COMBFUNC] =
{
/* Unit 0:
*/
{
/* Disable combiner stage
*/
0,
/* Passthru
*/
1,
/* GL_REPLACE
*/
2,
/* GL_MODULATE
*/
3,
/* GL_DECAL
*/
4,
/* GL_BLEND
*/
5,
/* GL_BLEND according to alpha (same as above)
*/
6,
/* GL_ADD
*/
7,
},
/* Unit 1:
*/
{
/* Disable combiner stage
*/
0,
/* Passthru
*/
1,
/* GL_REPLACE
*/
2,
/* GL_MODULATE
*/
3,
/* GL_DECAL
*/
4,
/* GL_BLEND
*/
5,
/* GL_BLEND according to alpha (same as above)
*/
6,
/* GL_ADD
*/
7,
}
};
static void viaUpdateTexEnv(GLcontext *ctx, GLuint unit)
{
const struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
const struct gl_texture_object *tObj = texUnit->_Current;
const GLuint format = tObj->Image[tObj->BaseLevel]->Format;
GLuint color_combine, alpha_combine;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
switch (texUnit->EnvMode) {
case GL_REPLACE:
if (format == GL_ALPHA) {
color_combine = via_color_combine[unit][VIA_PASSTHRU];
alpha_combine = via_alpha_combine[unit][VIA_REPLACE];
}
else if (format == GL_LUMINANCE || format == GL_RGB) {
color_combine = via_color_combine[unit][VIA_REPLACE];
alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
}
else {
color_combine = via_color_combine[unit][VIA_REPLACE];
alpha_combine = via_alpha_combine[unit][VIA_REPLACE];
}
break;
case GL_MODULATE:
if (format == GL_ALPHA) {
color_combine = via_color_combine[unit][VIA_PASSTHRU];
alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
}
else {
color_combine = via_color_combine[unit][VIA_MODULATE];
alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
}
break;
case GL_DECAL:
switch (format) {
case GL_RGBA:
color_combine = via_color_combine[unit][VIA_ALPHA_BLEND];
alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
break;
case GL_RGB:
color_combine = via_color_combine[unit][VIA_REPLACE];
alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
break;
case GL_ALPHA:
case GL_LUMINANCE:
case GL_LUMINANCE_ALPHA:
case GL_INTENSITY:
color_combine = via_color_combine[unit][VIA_PASSTHRU];
alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
break;
case GL_COLOR_INDEX:
default:
return;
}
break;
case GL_BLEND:
switch (format) {
case GL_RGB:
case GL_LUMINANCE:
color_combine = via_color_combine[unit][VIA_BLEND];
alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
break;
case GL_RGBA:
case GL_LUMINANCE_ALPHA:
color_combine = via_color_combine[unit][VIA_BLEND];
alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
break;
case GL_ALPHA:
color_combine = via_color_combine[unit][VIA_PASSTHRU];
alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
break;
case GL_INTENSITY:
color_combine = via_color_combine[unit][VIA_BLEND];
alpha_combine = via_alpha_combine[unit][VIA_BLEND];
break;
case GL_COLOR_INDEX:
default:
return;
}
break;
case GL_ADD:
switch (format) {
case GL_RGB:
case GL_LUMINANCE:
color_combine = via_color_combine[unit][VIA_ADD];
alpha_combine = via_alpha_combine[unit][VIA_PASSTHRU];
break;
case GL_RGBA:
case GL_LUMINANCE_ALPHA:
color_combine = via_color_combine[unit][VIA_ADD];
alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
break;
case GL_ALPHA:
color_combine = via_color_combine[unit][VIA_PASSTHRU];
alpha_combine = via_alpha_combine[unit][VIA_MODULATE];
break;
case GL_INTENSITY:
color_combine = via_color_combine[unit][VIA_ADD];
alpha_combine = via_alpha_combine[unit][VIA_ADD];
break;
case GL_COLOR_INDEX:
default:
return;
}
break;
default:
return;
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void viaUpdateTexUnit(GLcontext *ctx, GLuint unit)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
struct gl_texture_unit *texUnit = &ctx->Texture.Unit[unit];
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
if (texUnit->_ReallyEnabled) {
struct gl_texture_object *tObj = texUnit->_Current;
viaTextureObjectPtr t = (viaTextureObjectPtr)tObj->DriverData;
/* Upload teximages (not pipelined)
*/
if (t->dirtyImages) {
VIA_FIREVERTICES(vmesa);
viaSetTexImages(vmesa, tObj);
if (!t->bufAddr) {
FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_TRUE);
return;
}
}
if (tObj->Image[tObj->BaseLevel]->Border > 0) {
FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_TRUE);
return;
}
/* Update state if this is a different texture object to last
* time.
*/
if (vmesa->CurrentTexObj[unit] != t) {
VIA_STATECHANGE(vmesa, (VIA_UPLOAD_TEX0 << unit));
vmesa->CurrentTexObj[unit] = t;
viaUpdateTexLRU(vmesa, t); /* done too often */
}
/* Update texture environment if texture object image format or
* texture environment state has changed.
*/
if (tObj->Image[tObj->BaseLevel]->Format != vmesa->TexEnvImageFmt[unit]) {
vmesa->TexEnvImageFmt[unit] = tObj->Image[tObj->BaseLevel]->Format;
viaUpdateTexEnv(ctx, unit);
}
}
else {
vmesa->CurrentTexObj[unit] = 0;
vmesa->TexEnvImageFmt[unit] = 0;
vmesa->dirty &= ~(VIA_UPLOAD_TEX0 << unit);
VIA_STATECHANGE(vmesa, VIA_UPLOAD_CTX);
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
void viaUpdateTextureState(GLcontext *ctx)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
FALLBACK(vmesa, VIA_FALLBACK_TEXTURE, GL_FALSE);
viaUpdateTexUnit(ctx, 0);
viaUpdateTexUnit(ctx, 1);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,35 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIATRIS_H
#define _VIATRIS_H
#include "mtypes.h"
extern void viaPrintRenderState(const char *msg, GLuint state);
extern void viaInitTriFuncs(GLcontext *ctx);
extern void viaRasterPrimitive(GLcontext *ctx, GLenum rPrim, GLuint hwPrim);
extern void viaRasterPrimitiveFinish(GLcontext *ctx);
#endif

View file

@ -0,0 +1,415 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "glheader.h"
#include "mtypes.h"
#include "imports.h"
#include "macros.h"
#include "colormac.h"
/*#include "mmath.h" _SOLO*/
/*#include "mem.h" _SOLO*/
#include "swrast_setup/swrast_setup.h"
#include "tnl/t_context.h"
#include "via_context.h"
#include "via_vb.h"
#include "via_ioctl.h"
#include "via_tris.h"
#include "via_state.h"
static struct {
void (*emit)(GLcontext *, GLuint, GLuint, void *, GLuint);
interp_func interp;
copy_pv_func copy_pv;
GLboolean (*check_tex_sizes)(GLcontext *ctx);
GLuint vertex_size;
GLuint vertex_stride_shift;
GLuint vertex_format;
} setup_tab[VIA_MAX_SETUP];
#define TINY_VERTEX_FORMAT 1
#define NOTEX_VERTEX_FORMAT 2
#define TEX0_VERTEX_FORMAT 3
#define TEX1_VERTEX_FORMAT 4
#define PROJ_TEX1_VERTEX_FORMAT 0
#define TEX2_VERTEX_FORMAT 0
#define TEX3_VERTEX_FORMAT 0
#define PROJ_TEX3_VERTEX_FORMAT 0
#define DO_XYZW (IND & VIA_XYZW_BIT)
#define DO_RGBA (IND & VIA_RGBA_BIT)
#define DO_SPEC (IND & VIA_SPEC_BIT)
#define DO_FOG (IND & VIA_FOG_BIT)
#define DO_TEX0 (IND & VIA_TEX0_BIT)
#define DO_TEX1 (IND & VIA_TEX1_BIT)
#define DO_TEX2 0
#define DO_TEX3 0
#define DO_PTEX (IND & VIA_PTEX_BIT)
#define VERTEX viaVertex
#define VERTEX_COLOR via_color_t
#define GET_VIEWPORT_MAT() VIA_CONTEXT(ctx)->ViewportMatrix.m
#define GET_TEXSOURCE(n) n
#define GET_VERTEX_FORMAT() VIA_CONTEXT(ctx)->vertex_size
#define GET_VERTEX_SIZE() VIA_CONTEXT(ctx)->vertex_size
#define GET_VERTEX_STORE() VIA_CONTEXT(ctx)->verts
#define GET_VERTEX_STRIDE_SHIFT() VIA_CONTEXT(ctx)->vertex_stride_shift
#define GET_UBYTE_COLOR_STORE() &VIA_CONTEXT(ctx)->UbyteColor
#define GET_UBYTE_SPEC_COLOR_STORE() &VIA_CONTEXT(ctx)->UbyteSecondaryColor
#define INVALIDATE_STORED_VERTICES()
#define HAVE_HW_VIEWPORT 0
#define HAVE_HW_DIVIDE 0
#define HAVE_RGBA_COLOR 0
#define HAVE_TINY_VERTICES 1
#define HAVE_NOTEX_VERTICES 1
#define HAVE_TEX0_VERTICES 1
#define HAVE_TEX1_VERTICES 1
#define HAVE_TEX2_VERTICES 0
#define HAVE_TEX3_VERTICES 0
#define HAVE_PTEX_VERTICES 0
#define UNVIEWPORT_VARS GLfloat h = VIA_CONTEXT(ctx)->driDrawable->h
#define UNVIEWPORT_X(x) x - SUBPIXEL_X
#define UNVIEWPORT_Y(y) - y + h + SUBPIXEL_Y
#define UNVIEWPORT_Z(z) z * (float)0xffffffff
#define PTEX_FALLBACK() FALLBACK(VIA_CONTEXT(ctx), VIA_FALLBACK_TEXTURE, 1)
#define IMPORT_FLOAT_COLORS via_import_float_colors
#define IMPORT_FLOAT_SPEC_COLORS via_import_float_spec_colors
#define INTERP_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].interp
#define COPY_PV_VERTEX setup_tab[VIA_CONTEXT(ctx)->setupIndex].copy_pv
/***********************************************************************
* Generate pv-copying and translation functions *
***********************************************************************/
#define TAG(x) via_##x
#include "tnl_dd/t_dd_vb.c"
/***********************************************************************
* Generate vertex emit and interp functions *
***********************************************************************/
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT)
#define TAG(x) x##_wg
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT)
#define TAG(x) x##_wgs
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT)
#define TAG(x) x##_wgt0
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_TEX1_BIT)
#define TAG(x) x##_wgt0t1
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgpt0
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_TEX0_BIT | VIA_TEX1_BIT |\
VIA_PTEX_BIT)
#define TAG(x) x##_wgpt0t1
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT)
#define TAG(x) x##_wgst0
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
VIA_TEX1_BIT)
#define TAG(x) x##_wgst0t1
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
VIA_PTEX_BIT)
#define TAG(x) x##_wgspt0
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_SPEC_BIT | VIA_TEX0_BIT |\
VIA_TEX1_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgspt0t1
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT)
#define TAG(x) x##_wgf
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT)
#define TAG(x) x##_wgfs
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT)
#define TAG(x) x##_wgft0
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
VIA_TEX1_BIT)
#define TAG(x) x##_wgft0t1
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
VIA_PTEX_BIT)
#define TAG(x) x##_wgfpt0
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_TEX0_BIT |\
VIA_TEX1_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgfpt0t1
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
VIA_TEX0_BIT)
#define TAG(x) x##_wgfst0
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
VIA_TEX0_BIT | VIA_TEX1_BIT)
#define TAG(x) x##_wgfst0t1
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
VIA_TEX0_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgfspt0
#include "via_dd_vbtmp.h"
#define IND (VIA_XYZW_BIT | VIA_RGBA_BIT | VIA_FOG_BIT | VIA_SPEC_BIT |\
VIA_TEX0_BIT | VIA_TEX1_BIT | VIA_PTEX_BIT)
#define TAG(x) x##_wgfspt0t1
#include "via_dd_vbtmp.h"
static void init_setup_tab(void) {
init_wg();
init_wgs();
init_wgt0();
init_wgt0t1();
init_wgpt0();
init_wgpt0t1();
init_wgst0();
init_wgst0t1();
init_wgspt0();
init_wgspt0t1();
init_wgf();
init_wgfs();
init_wgft0();
init_wgft0t1();
init_wgfpt0();
init_wgfpt0t1();
init_wgfst0();
init_wgfst0t1();
init_wgfspt0();
init_wgfspt0t1();
}
void viaPrintSetupFlags(char *msg, GLuint flags) {
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s(%x): %s%s%s%s%s%s\n",
msg,
(int)flags,
(flags & VIA_XYZW_BIT) ? " xyzw," : "",
(flags & VIA_RGBA_BIT) ? " rgba," : "",
(flags & VIA_SPEC_BIT) ? " spec," : "",
(flags & VIA_FOG_BIT) ? " fog," : "",
(flags & VIA_TEX0_BIT) ? " tex-0," : "",
(flags & VIA_TEX1_BIT) ? " tex-1," : "");
#endif
}
void viaCheckTexSizes(GLcontext *ctx) {
TNLcontext *tnl = TNL_CONTEXT(ctx);
viaContextPtr vmesa = VIA_CONTEXT(ctx);
#ifdef DEBUG
if (VIA_DEBUG) {
fprintf(stderr, "%s - in\n", __FUNCTION__);
fprintf(stderr, "setupIndex = %x\n", vmesa->setupIndex);
}
#endif
if (!setup_tab[vmesa->setupIndex].check_tex_sizes(ctx)) {
/* Invalidate stored verts
*/
vmesa->setupNewInputs = ~0;
vmesa->setupIndex |= VIA_PTEX_BIT;
if (!vmesa->Fallback &&
!(ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED))) {
tnl->Driver.Render.Interp = setup_tab[vmesa->setupIndex].interp;
tnl->Driver.Render.CopyPV = setup_tab[vmesa->setupIndex].copy_pv;
}
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
void viaBuildVertices(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint newinputs)
{
viaContextPtr vmesa = VIA_CONTEXT(ctx);
GLubyte *v = ((GLubyte *)vmesa->verts + (start << vmesa->vertex_stride_shift));
GLuint stride = 1 << vmesa->vertex_stride_shift;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
newinputs |= vmesa->setupNewInputs;
vmesa->setupNewInputs = 0;
if (!newinputs)
return;
if (newinputs & VERT_CLIP) {
setup_tab[vmesa->setupIndex].emit(ctx, start, count, v, stride);
}
else {
GLuint ind = 0;
if (newinputs & VERT_RGBA)
ind |= VIA_RGBA_BIT;
if (newinputs & VERT_BIT_COLOR1)
ind |= VIA_SPEC_BIT;
if (newinputs & VERT_TEX(0))
ind |= VIA_TEX0_BIT;
if (newinputs & VERT_TEX(1))
ind |= VIA_TEX1_BIT;
if (newinputs & VERT_BIT_FOG)
ind |= VIA_FOG_BIT;
if (vmesa->setupIndex & VIA_PTEX_BIT)
ind = ~0;
ind &= vmesa->setupIndex;
ind |= VIA_XYZW_BIT;
if (ind) {
setup_tab[ind].emit(ctx, start, count, v, stride);
}
}
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
void viaChooseVertexState(GLcontext *ctx) {
TNLcontext *tnl = TNL_CONTEXT(ctx);
viaContextPtr vmesa = VIA_CONTEXT(ctx);
GLuint ind = VIA_XYZW_BIT | VIA_RGBA_BIT;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
if (ctx->_TriangleCaps & DD_SEPARATE_SPECULAR)
ind |= VIA_SPEC_BIT;
if (ctx->Fog.Enabled)
ind |= VIA_FOG_BIT;
if (ctx->Texture.Unit[1]._ReallyEnabled)
ind |= VIA_TEX1_BIT | VIA_TEX0_BIT;
else if (ctx->Texture.Unit[0]._ReallyEnabled)
ind |= VIA_TEX0_BIT;
vmesa->setupIndex = ind;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "setupIndex = %x\n", vmesa->setupIndex);
#endif
if (ctx->_TriangleCaps & (DD_TRI_LIGHT_TWOSIDE|DD_TRI_UNFILLED)) {
tnl->Driver.Render.Interp = via_interp_extras;
tnl->Driver.Render.CopyPV = via_copy_pv_extras;
}
else {
tnl->Driver.Render.Interp = setup_tab[ind].interp;
tnl->Driver.Render.CopyPV = setup_tab[ind].copy_pv;
}
vmesa->vertex_size = setup_tab[ind].vertex_size;
vmesa->vertex_stride_shift = setup_tab[ind].vertex_stride_shift;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
void via_emit_contiguous_verts(GLcontext *ctx,
GLuint start,
GLuint count) {
viaContextPtr vmesa = VIA_CONTEXT(ctx);
GLuint vertex_size = vmesa->vertex_size * 4;
GLuint *dest = viaCheckDma(vmesa, (count - start) * vertex_size);
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
if (VIA_DEBUG) fprintf(stderr, "choose setup_tab[0x%x]\n", vmesa->setupIndex);
#endif
setup_tab[vmesa->setupIndex].emit(ctx, start, count, dest, vertex_size);
vmesa->dmaLow += (count - start) * vertex_size;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
void viaInitVB(GLcontext *ctx) {
viaContextPtr vmesa = VIA_CONTEXT(ctx);
GLuint size = TNL_CONTEXT(ctx)->vb.Size;
vmesa->verts = ALIGN_MALLOC(size * 4 * 16, 32);
{
static int firsttime = 1;
if (firsttime) {
init_setup_tab();
firsttime = 0;
}
}
}
void viaFreeVB(GLcontext *ctx) {
viaContextPtr vmesa = VIA_CONTEXT(ctx);
if (vmesa->verts) {
ALIGN_FREE(vmesa->verts);
vmesa->verts = 0;
}
if (vmesa->UbyteSecondaryColor.Ptr) {
ALIGN_FREE((void*)vmesa->UbyteSecondaryColor.Ptr);
vmesa->UbyteSecondaryColor.Ptr = 0;
}
if (vmesa->UbyteColor.Ptr) {
ALIGN_FREE((void*)vmesa->UbyteColor.Ptr);
vmesa->UbyteColor.Ptr = 0;
}
}

View file

@ -0,0 +1,69 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef _VIAVB_H
#define _VIAVB_H
#include "mtypes.h"
#include "swrast/swrast.h"
#define VIA_TEX1_BIT 0x0001
#define VIA_TEX0_BIT 0x0002
#define VIA_RGBA_BIT 0x0004
#define VIA_SPEC_BIT 0x0008
#define VIA_FOG_BIT 0x0010
#define VIA_XYZW_BIT 0x0020
#define VIA_PTEX_BIT 0x0040
#define VIA_MAX_SETUP 0x0080
#define _VIA_NEW_VERTEX (_NEW_TEXTURE | \
_DD_NEW_SEPARATE_SPECULAR | \
_DD_NEW_TRI_UNFILLED | \
_DD_NEW_TRI_LIGHT_TWOSIDE | \
_NEW_FOG)
extern void viaChooseVertexState(GLcontext *ctx);
extern void viaCheckTexSizes(GLcontext *ctx);
extern void viaBuildVertices(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint newinputs);
extern void via_emit_contiguous_verts(GLcontext *ctx,
GLuint start,
GLuint count);
extern void via_translate_vertex(GLcontext *ctx,
const viaVertex *src,
SWvertex *dst);
extern void viaInitVB(GLcontext *ctx);
extern void viaFreeVB(GLcontext *ctx);
extern void via_print_vertex(GLcontext *ctx, const viaVertex *v);
extern void viaPrintSetupFlags(char *msg, GLuint flags);
#endif

View file

@ -0,0 +1,509 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef POSTFIX
#define POSTFIX
#endif
#ifndef INIT
#define INIT(x)
#endif
#ifndef NEED_EDGEFLAG_SETUP
#define NEED_EDGEFLAG_SETUP 0
#define EDGEFLAG_GET(a) 0
#define EDGEFLAG_SET(a,b) (void)b
#endif
#ifndef RESET_STIPPLE
#define RESET_STIPPLE
#endif
#ifndef RESET_OCCLUSION
#define RESET_OCCLUSION
#endif
#ifndef TEST_PRIM_END
#define TEST_PRIM_END(flags) (flags & PRIM_END)
#define TEST_PRIM_BEGIN(flags) (flags & PRIM_BEGIN)
#define TEST_PRIM_PARITY(flags) (flags & PRIM_PARITY)
#endif
#ifndef ELT
#define ELT(x) x
#endif
#ifndef RENDER_TAB_QUALIFIER
#define RENDER_TAB_QUALIFIER static
#endif
static void TAG(render_points)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
LOCAL_VARS;
(void)flags;
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
RESET_OCCLUSION;
INIT(GL_POINTS);
RENDER_POINTS(start, count);
POSTFIX;
}
static void TAG(render_lines)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
RESET_OCCLUSION;
INIT(GL_LINES);
for (j = start + 1; j < count; j += 2) {
RESET_STIPPLE;
RENDER_LINE(ELT(j - 1), ELT(j));
}
POSTFIX;
}
static void TAG(render_line_strip)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
RESET_OCCLUSION;
INIT(GL_LINES);
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
for (j = start + 1; j < count; j++)
RENDER_LINE(ELT(j - 1), ELT(j));
POSTFIX;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_line_loop)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint i;
LOCAL_VARS;
(void)flags;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
RESET_OCCLUSION;
INIT(GL_LINES);
if (start + 1 < count) {
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
RENDER_LINE(ELT(start), ELT(start + 1));
}
for (i = start + 2 ; i < count ; i++) {
RENDER_LINE(ELT(i - 1), ELT(i));
}
if (TEST_PRIM_END(flags)) {
RENDER_LINE(ELT(count - 1), ELT(start));
}
}
POSTFIX;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_triangles)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 2; j < count; j += 3) {
/* Leave the edgeflags as supplied by the user.
*/
RESET_STIPPLE;
RENDER_TRI(ELT(j - 2), ELT(j - 1), ELT(j));
}
}
else {
for (j = start + 2; j < count; j += 3) {
RENDER_TRI(ELT(j - 2), ELT(j - 1), ELT(j));
}
}
POSTFIX;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_tri_strip)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
GLuint parity = 0;
LOCAL_VARS;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
if (TEST_PRIM_PARITY(flags))
parity = 1;
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 2; j < count; j++, parity ^= 1) {
GLuint ej2 = ELT(j - 2 + parity);
GLuint ej1 = ELT(j - 1 - parity);
GLuint ej = ELT(j);
GLboolean ef2 = EDGEFLAG_GET(ej2);
GLboolean ef1 = EDGEFLAG_GET(ej1);
GLboolean ef = EDGEFLAG_GET(ej);
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
EDGEFLAG_SET(ej2, GL_TRUE);
EDGEFLAG_SET(ej1, GL_TRUE);
EDGEFLAG_SET(ej, GL_TRUE);
RENDER_TRI(ej2, ej1, ej);
EDGEFLAG_SET(ej2, ef2);
EDGEFLAG_SET(ej1, ef1);
EDGEFLAG_SET(ej, ef);
}
}
else {
for (j = start + 2; j < count; j++, parity ^= 1) {
RENDER_TRI(ELT(j - 2 + parity), ELT(j - 1 - parity), ELT(j));
}
}
POSTFIX;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_tri_fan)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 2; j < count; j++) {
/* For trifans, all edges are boundary.
*/
GLuint ejs = ELT(start);
GLuint ej1 = ELT(j - 1);
GLuint ej = ELT(j);
GLboolean efs = EDGEFLAG_GET(ejs);
GLboolean ef1 = EDGEFLAG_GET(ej1);
GLboolean ef = EDGEFLAG_GET(ej);
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
EDGEFLAG_SET(ejs, GL_TRUE);
EDGEFLAG_SET(ej1, GL_TRUE);
EDGEFLAG_SET(ej, GL_TRUE);
RENDER_TRI(ejs, ej1, ej);
EDGEFLAG_SET(ejs, efs);
EDGEFLAG_SET(ej1, ef1);
EDGEFLAG_SET(ej, ef);
}
}
else {
for (j = start + 2; j < count; j++) {
RENDER_TRI(ELT(start), ELT(j - 1), ELT(j));
}
}
POSTFIX;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_poly)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j = start + 2;
LOCAL_VARS;
(void)flags;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
GLboolean efstart = EDGEFLAG_GET(ELT(start));
GLboolean efcount = EDGEFLAG_GET(ELT(count - 1));
/* If the primitive does not begin here, the first edge
* is non-boundary.
*/
if (!TEST_PRIM_BEGIN(flags)) {
EDGEFLAG_SET(ELT(start), GL_FALSE);
}
else {
RESET_STIPPLE;
}
/* If the primitive does not end here, the final edge is
* non-boundary.
*/
if (!TEST_PRIM_END(flags)) {
EDGEFLAG_SET(ELT(count - 1), GL_FALSE);
}
/* Draw the first triangles (possibly zero)
*/
if (j+1<count) {
GLboolean ef = EDGEFLAG_GET(ELT(j));
EDGEFLAG_SET(ELT(j), GL_FALSE);
RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
EDGEFLAG_SET(ELT(j), ef);
j++;
/* Don't render the first edge again:
*/
EDGEFLAG_SET(ELT(start), GL_FALSE);
for (;j+1<count;j++) {
GLboolean efj = EDGEFLAG_GET(ELT(j));
EDGEFLAG_SET(ELT(j), GL_FALSE);
RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
EDGEFLAG_SET(ELT(j), efj);
}
}
/* Draw the last or only triangle
*/
if (j < count) {
RENDER_TRI(ELT(j-1), ELT(j), ELT(start));
}
/* Restore the first and last edgeflags:
*/
EDGEFLAG_SET(ELT(count - 1), efcount);
EDGEFLAG_SET(ELT(start), efstart);
}
else {
for (j = start + 2; j < count; j++) {
RENDER_TRI(ELT(j - 1), ELT(j), ELT(start));
}
}
POSTFIX;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_quads)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 3; j < count; j += 4) {
/* Use user-specified edgeflags for quads.
*/
RESET_STIPPLE;
RENDER_QUAD(ELT(j - 3), ELT(j - 2), ELT(j - 1), ELT(j));
}
}
else {
for (j = start + 3; j < count; j += 4) {
RENDER_QUAD(ELT(j - 3), ELT(j - 2), ELT(j - 1), ELT(j));
}
}
POSTFIX;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_quad_strip)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
GLuint j;
LOCAL_VARS;
(void)flags;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - in\n", __FUNCTION__);
#endif
#ifdef PERFORMANCE_MEASURE
if (VIA_PERFORMANCE) P_M;
#endif
INIT(GL_TRIANGLES);
if (NEED_EDGEFLAG_SETUP) {
for (j = start + 3; j < count; j += 2) {
/* All edges are boundary. Set edgeflags to 1, draw the
* quad, and restore them to the original values.
*/
GLboolean ef3 = EDGEFLAG_GET(ELT(j - 3));
GLboolean ef2 = EDGEFLAG_GET(ELT(j - 2));
GLboolean ef1 = EDGEFLAG_GET(ELT(j - 1));
GLboolean ef = EDGEFLAG_GET(ELT(j));
if (TEST_PRIM_BEGIN(flags)) {
RESET_STIPPLE;
}
EDGEFLAG_SET(ELT(j - 3), GL_TRUE);
EDGEFLAG_SET(ELT(j - 2), GL_TRUE);
EDGEFLAG_SET(ELT(j - 1), GL_TRUE);
EDGEFLAG_SET(ELT(j), GL_TRUE);
RENDER_QUAD(ELT(j - 1), ELT(j - 3), ELT(j - 2), ELT(j));
EDGEFLAG_SET(ELT(j - 3), ef3);
EDGEFLAG_SET(ELT(j - 2), ef2);
EDGEFLAG_SET(ELT(j - 1), ef1);
EDGEFLAG_SET(ELT(j), ef);
}
}
else {
for (j = start + 3; j < count; j += 2) {
RENDER_QUAD(ELT(j - 1), ELT(j - 3), ELT(j - 2), ELT(j));
}
}
POSTFIX;
#ifdef DEBUG
if (VIA_DEBUG) fprintf(stderr, "%s - out\n", __FUNCTION__);
#endif
}
static void TAG(render_noop)(GLcontext *ctx,
GLuint start,
GLuint count,
GLuint flags)
{
(void)(ctx && start && count && flags);
}
RENDER_TAB_QUALIFIER void (*TAG(render_tab)[GL_POLYGON + 2])(GLcontext *,
GLuint,
GLuint,
GLuint) =
{
TAG(render_points),
TAG(render_lines),
TAG(render_line_loop),
TAG(render_line_strip),
TAG(render_triangles),
TAG(render_tri_strip),
TAG(render_tri_fan),
TAG(render_quads),
TAG(render_quad_strip),
TAG(render_poly),
TAG(render_noop),
};
#ifndef PRESERVE_VB_DEFS
#undef RENDER_TRI
#undef RENDER_QUAD
#undef RENDER_LINE
#undef RENDER_POINTS
#undef LOCAL_VARS
#undef INIT
#undef POSTFIX
#undef RESET_STIPPLE
#undef DBG
#undef ELT
#undef RENDER_TAB_QUALIFIER
#endif
#ifndef PRESERVE_TAG
#undef TAG
#endif
#undef PRESERVE_VB_DEFS
#undef PRESERVE_TAG

View file

@ -0,0 +1,140 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifdef XFree86Server
# include "xf86.h"
# include "xf86_OSproc.h"
# include "xf86_ansic.h"
# define _DRM_MALLOC xalloc
# define _DRM_FREE xfree
# ifndef XFree86LOADER
# include <sys/mman.h>
# endif
#else
# include <stdio.h>
# include <stdlib.h>
# include <unistd.h>
# include <string.h>
# include <ctype.h>
# include <fcntl.h>
# include <errno.h>
# include <signal.h>
# include <sys/types.h>
# include <sys/ioctl.h>
# include <sys/mman.h>
# include <sys/time.h>
# ifdef DRM_USE_MALLOC
# define _DRM_MALLOC malloc
# define _DRM_FREE free
extern int xf86InstallSIGIOHandler(int fd, void (*f)(int, void *), void *);
extern int xf86RemoveSIGIOHandler(int fd);
# else
# include <X11/Xlibint.h>
# define _DRM_MALLOC Xmalloc
# define _DRM_FREE Xfree
# endif
#endif
/* Not all systems have MAP_FAILED defined */
#ifndef MAP_FAILED
#define MAP_FAILED ((void *)-1)
#endif
#ifdef __linux__
#include <sys/sysmacros.h> /* for makedev() */
#endif
#include "xf86drm.h"
#include "xf86drmVIA.h"
#include "drm.h"
#include "via_common.h"
int drmVIAAgpInit(int fd, int offset, int size)
{
drm_via_agp_t agp;
agp.offset = offset;
agp.size = size;
if (ioctl(fd, DRM_IOCTL_VIA_AGP_INIT, &agp) < 0) {
return -errno;
}
else {
return 0;
}
}
int drmVIAFBInit(int fd, int offset, int size)
{
drm_via_fb_t fb;
fb.offset = offset;
fb.size = size;
if (ioctl(fd, DRM_IOCTL_VIA_FB_INIT, &fb) < 0) {
return -errno;
}
else
return 0;
}
int drmVIAInitMAP(int fd, drmVIAInit *info)
{
drm_via_init_t init;
memset(&init, 0, sizeof(drm_via_init_t));
init.func = VIA_INIT_MAP;
init.sarea_priv_offset = info->sarea_priv_offset;
init.fb_offset = info->fb_offset;
init.mmio_offset = info->mmio_offset;
init.agpAddr = info->agpAddr;
if (ioctl(fd, DRM_IOCTL_VIA_MAP_INIT, &init ) < 0) {
return -errno;
}
else
return 0;
}
int drmVIAAllocateDMA(int fd, drmVIADMABuf *buf)
{
if (drmAddMap(fd, 0, buf->size,
DRM_SHM, 0,
&buf->index) < 0) {
return -errno;
}
if (drmMap(fd,(drmHandle)buf->index,
buf->size,(drmAddressPtr)(&buf->address)) < 0) {
return -errno;
}
memset(buf->address, 0, buf->size);
return 0;
}
int drmVIAReleaseDMA(int fd, drmVIADMABuf *buf)
{
if (drmUnmap((drmAddress)(buf->address), buf->size) < 0)
return -errno;
return 0;
}

View file

@ -0,0 +1,54 @@
/*
* Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
* Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* 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
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#ifndef __XF86DRI_VIA_H__
#define __XF86DRI_VIA_H__
typedef struct {
unsigned long sarea_priv_offset;
unsigned long fb_offset;
unsigned long mmio_offset;
unsigned long agpAddr;
} drmVIAInit;
typedef struct {
unsigned int offset;
unsigned int size;
unsigned int index;
} drmVIAAGPBuf;
typedef struct {
unsigned int offset;
unsigned int size;
unsigned long index;
unsigned long *address;
} drmVIADMABuf;
extern int drmVIAAgpInit(int fd, int offset, int size);
extern int drmVIAFBInit(int fd, int offset, int size);
extern int drmVIAInitMAP(int fd, drmVIAInit *info);
extern int drmVIAAllocateDMA(int fd, drmVIADMABuf *buf);
extern int drmVIAReleaseDMA(int fd, drmVIADMABuf *buf);
#endif