[MPlayer-cvslog] r26128 - in trunk: configure vidix/Makefile vidix/drivers.c vidix/s3_regs.h vidix/s3_vid.c

ben subversion at mplayerhq.hu
Fri Feb 29 21:01:29 CET 2008


Author: ben
Date: Fri Feb 29 21:01:28 2008
New Revision: 26128

Log:
New S3 VIDIX driver.
Provides support for S3 Trio and S3 Virge chipsets.
This deprecates the old Savage driver that worked with latest chips only.
(synchronized with vidix.sf.net r326 and r327)



Added:
   trunk/vidix/s3_regs.h
   trunk/vidix/s3_vid.c
Modified:
   trunk/configure
   trunk/vidix/Makefile
   trunk/vidix/drivers.c

Modified: trunk/configure
==============================================================================
--- trunk/configure	(original)
+++ trunk/configure	Fri Feb 29 21:01:28 2008
@@ -337,7 +337,7 @@ Video output:
   --disable-vidix-external disable external VIDIX [for x86 *nix]
   --with-vidix-drivers[=*] list of VIDIX drivers to be compiled in
                            Available: cyberblade,ivtv,mach64,mga,mga_crtc2,
-                           nvidia,pm2,pm3,radeon,rage128,savage,sis,unichrome
+                           nvidia,pm2,pm3,radeon,rage128,s3,sis,unichrome
   --disable-vidix-pcidb    disable VIDIX PCI device name database
   --enable-gl              enable OpenGL video output [autodetect]
   --enable-dga2            enable DGA 2 support [autodetect]
@@ -4246,8 +4246,8 @@ _def_vidix_drv_radeon='#undef CONFIG_VID
 _vidix_drv_radeon=no
 _def_vidix_drv_rage128='#undef CONFIG_VIDIX_DRV_RAGE128'
 _vidix_drv_rage128=no
-_def_vidix_drv_savage='#undef CONFIG_VIDIX_DRV_SAVAGE'
-_vidix_drv_savage=no
+_def_vidix_drv_s3='#undef CONFIG_VIDIX_DRV_S3'
+_vidix_drv_s3=no
 _def_vidix_drv_sis='#undef CONFIG_VIDIX_DRV_SIS'
 _vidix_drv_sis=no
 _def_vidix_drv_unichrome='#undef CONFIG_VIDIX_DRV_UNICHROME'
@@ -4277,7 +4277,7 @@ if test "$_vidix" = yes ; then
   _def_vidix='#define CONFIG_VIDIX 1'
   _vosrc="$_vosrc vo_cvidix.c"
   _vomodules="cvidix $_vomodules"
-  test "$_vidix_drivers" || _vidix_drivers="cyberblade ivtv mach64 mga mga_crtc2 nvidia pm2 pm3 radeon rage128 savage sis unichrome"
+  test "$_vidix_drivers" || _vidix_drivers="cyberblade ivtv mach64 mga mga_crtc2 nvidia pm2 pm3 radeon rage128 s3 sis unichrome"
   test $_ivtv = "yes" || _vidix_drivers=`echo $_vidix_drivers | sed s/ivtv//`
 
   # some vidix drivers are meant to work on x86 only, discard them elsewhere
@@ -7821,7 +7821,7 @@ VIDIX_PM2=$_vidix_drv_pm2
 VIDIX_PM3=$_vidix_drv_pm3
 VIDIX_RADEON=$_vidix_drv_radeon
 VIDIX_RAGE128=$_vidix_drv_rage128
-VIDIX_SAVAGE=$_vidix_drv_savage
+VIDIX_S3=$_vidix_drv_s3
 VIDIX_SIS=$_vidix_drv_sis
 VIDIX_UNICHROME=$_vidix_drv_unichrome
 
@@ -8504,7 +8504,7 @@ $_def_vidix_drv_nvidia
 $_def_vidix_drv_pm3
 $_def_vidix_drv_radeon
 $_def_vidix_drv_rage128
-$_def_vidix_drv_savage
+$_def_vidix_drv_s3
 $_def_vidix_drv_sis
 $_def_vidix_drv_unichrome
 $_def_vidix_pfx

Modified: trunk/vidix/Makefile
==============================================================================
--- trunk/vidix/Makefile	(original)
+++ trunk/vidix/Makefile	Fri Feb 29 21:01:28 2008
@@ -20,7 +20,7 @@ SRCS_MPLAYER-$(VIDIX_PM2)               
 SRCS_MPLAYER-$(VIDIX_PM3)                  += pm3_vid.c
 SRCS_MPLAYER-$(VIDIX_RADEON)               += radeon_vid.c
 SRCS_MPLAYER-$(VIDIX_RAGE128)              += rage128_vid.c
-SRCS_MPLAYER-$(VIDIX_SAVAGE)               += savage_vid.c
+SRCS_MPLAYER-$(VIDIX_S3)                   += s3_vid.c
 SRCS_MPLAYER-$(VIDIX_SIS)                  += sis_vid.c sis_bridge.c
 SRCS_MPLAYER-$(VIDIX_UNICHROME)            += unichrome_vid.c
 

Modified: trunk/vidix/drivers.c
==============================================================================
--- trunk/vidix/drivers.c	(original)
+++ trunk/vidix/drivers.c	Fri Feb 29 21:01:28 2008
@@ -42,7 +42,7 @@ extern VDXDriver pm2_drv;
 extern VDXDriver pm3_drv;
 extern VDXDriver radeon_drv;
 extern VDXDriver rage128_drv;
-extern VDXDriver savage_drv;
+extern VDXDriver s3_drv;
 extern VDXDriver sis_drv;
 extern VDXDriver unichrome_drv;
 
@@ -89,8 +89,8 @@ void vidix_register_all_drivers (void)
 #ifdef CONFIG_VIDIX_DRV_RAGE128
   vidix_register_driver (&rage128_drv);
 #endif
-#ifdef CONFIG_VIDIX_DRV_SAVAGE
-  vidix_register_driver (&savage_drv);
+#ifdef CONFIG_VIDIX_DRV_S3
+  vidix_register_driver (&s3_drv);
 #endif
 #ifdef CONFIG_VIDIX_DRV_SIS
   vidix_register_driver (&sis_drv);

Added: trunk/vidix/s3_regs.h
==============================================================================
--- (empty file)
+++ trunk/vidix/s3_regs.h	Fri Feb 29 21:01:28 2008
@@ -0,0 +1,214 @@
+#ifndef _SAVAGE_REGS_H
+#define _SAVAGE_REGS_H
+
+#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
+#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) || (chip==S3_PROSAVAGE))
+#define	S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE))
+#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
+
+/* 
+ * Chip tags.  These are used to group the adapters into 
+ * related families.
+ */
+enum S3CHIPTAGS {
+    S3_UNKNOWN = 0,
+    S3_TRIO64V,
+    S3_VIRGE,
+    S3_SAVAGE3D,
+    S3_SAVAGE_MX,
+    S3_SAVAGE4,
+    S3_PROSAVAGE,
+    S3_SUPERSAVAGE,
+    S3_SAVAGE2000,
+    S3_LAST
+};
+
+#define BIOS_BSIZE			1024
+#define BIOS_BASE			0xc0000
+
+#define S3_NEWMMIO_REGBASE		0x1000000	/* 16MB */
+#define S3_NEWMMIO_REGSIZE		0x0010000	/* 64KB */
+#define S3_NEWMMIO_REGSIZE_SAVAGE	0x0080000	/* 512KB */
+
+#define BASE_FREQ			14.31818	
+
+/*
+ * There are two different streams engines used in the S3 line.
+ * The old engine is in the Trio64, Virge,
+ * Savage3D, Savage4, SavagePro, and SavageTwister.
+ * The new engine is in the Savage2000, SavageMX,
+ * SavageIX, and SuperSavage.
+ */
+
+/* Old engine registers */
+#define PSTREAM_CONTROL_REG            0x8180
+#define COL_CHROMA_KEY_CONTROL_REG     0x8184
+#define SSTREAM_CONTROL_REG            0x8190
+#define CHROMA_KEY_UPPER_BOUND_REG     0x8194
+#define SSTREAM_STRETCH_REG            0x8198
+#define COLOR_ADJUSTMENT_REG           0x819C
+#define BLEND_CONTROL_REG              0x81A0
+#define PSTREAM_FBADDR0_REG            0x81C0
+#define PSTREAM_FBADDR1_REG            0x81C4
+#define PSTREAM_STRIDE_REG             0x81C8
+#define DOUBLE_BUFFER_REG              0x81CC
+#define SSTREAM_FBADDR0_REG            0x81D0
+#define SSTREAM_FBADDR1_REG            0x81D4
+#define SSTREAM_STRIDE_REG             0x81D8
+#define OPAQUE_OVERLAY_CONTROL_REG     0x81DC
+#define K1_VSCALE_REG                  0x81E0
+#define SSTREAM_VSCALE_REG             0x81E0
+#define K2_VSCALE_REG                  0x81E4
+#define SSTREAM_VINITIAL_REG           0x81E4
+#define DDA_VERT_REG                   0x81E8
+#define SSTREAM_LINES_REG              0x81E8
+#define STREAMS_FIFO_REG               0x81EC
+#define PSTREAM_WINDOW_START_REG       0x81F0
+#define PSTREAM_WINDOW_SIZE_REG        0x81F4
+#define SSTREAM_WINDOW_START_REG       0x81F8
+#define SSTREAM_WINDOW_SIZE_REG        0x81FC
+#define FIFO_CONTROL                   0x8200
+#define PSTREAM_FBSIZE_REG             0x8300
+#define SSTREAM_FBSIZE_REG             0x8304
+#define SSTREAM_FBADDR2_REG            0x8308
+
+/* New engine registers */
+#define PRI_STREAM_FBUF_ADDR0          0x81c0
+#define PRI_STREAM_FBUF_ADDR1          0x81c4
+#define PRI_STREAM_STRIDE              0x81c8
+#define PRI_STREAM_BUFFERSIZE          0x8214
+#define SEC_STREAM_CKEY_LOW            0x8184
+#define SEC_STREAM_CKEY_UPPER          0x8194
+#define BLEND_CONTROL                  0x8190
+#define SEC_STREAM_COLOR_CONVERT1      0x8198
+#define SEC_STREAM_COLOR_CONVERT2      0x819c
+#define SEC_STREAM_COLOR_CONVERT3      0x81e4
+#define SEC_STREAM_HSCALING            0x81a0
+#define SEC_STREAM_BUFFERSIZE          0x81a8
+#define SEC_STREAM_HSCALE_NORMALIZE    0x81ac
+#define SEC_STREAM_VSCALING            0x81e8
+#define SEC_STREAM_FBUF_ADDR0          0x81d0
+#define SEC_STREAM_FBUF_ADDR1          0x81d4
+#define SEC_STREAM_FBUF_ADDR2          0x81ec
+#define SEC_STREAM_STRIDE              0x81d8
+#define SEC_STREAM_WINDOW_START        0x81f8
+#define SEC_STREAM_WINDOW_SZ           0x81fc
+#define SEC_STREAM_TILE_OFF            0x821c
+#define SEC_STREAM_OPAQUE_OVERLAY      0x81dc
+
+/* Savage 2000 registers */
+#define SEC_STREAM_COLOR_CONVERT0_2000 0x8198
+#define SEC_STREAM_COLOR_CONVERT1_2000 0x819c
+#define SEC_STREAM_COLOR_CONVERT2_2000 0x81e0
+#define SEC_STREAM_COLOR_CONVERT3_2000 0x81e4
+
+/* Virge+ registers */
+#define FIFO_CONTROL_REG               0x8200
+#define MIU_CONTROL_REG                0x8204
+#define STREAMS_TIMEOUT_REG            0x8208
+#define MISC_TIMEOUT_REG               0x820c
+
+/* VGA stuff */
+#define vgaCRIndex                     0x3d4
+#define vgaCRReg                       0x3d5
+
+/* CRT Control registers */
+#define EXT_MEM_CTRL1                  0x53
+#define LIN_ADDR_CTRL                  0x58
+#define EXT_MISC_CTRL2                 0x67
+
+/* Old engine constants */
+#define ENABLE_NEWMMIO                 0x08
+#define ENABLE_LFB                     0x10
+#define ENABLE_STREAMS_OLD             0x0c
+#define NO_STREAMS_OLD                 0xf3
+
+/* New engine constants */
+#define ENABLE_STREAM1                 0x04
+#define NO_STREAMS                     0xF9
+
+#define VerticalRetraceWait() \
+do { \
+	VGAIN8(0x3d4); \
+	VGAOUT8(0x3d4, 0x17); \
+	if (VGAIN8(0x3d5) & 0x80) { \
+		int i = 0x10000; \
+		while ((VGAIN8(0x3da) & 0x08) == 0x08 && i--) ; \
+		i = 0x10000; \
+		while ((VGAIN8(0x3da) & 0x08) == 0x00 && i--) ; \
+	} \
+} while (0)
+
+/* Scaling operations */
+#define HSCALING_Shift    0
+#define HSCALING_Mask     (((1L << 16)-1) << HSCALING_Shift)
+#define HSCALING(w0,w1)   ((((unsigned int)(((double)w0/(double)w1) * (1 << 15))) << HSCALING_Shift) & HSCALING_Mask)
+                                                                                                                    
+#define VSCALING_Shift    0
+#define VSCALING_Mask     (((1L << 20)-1) << VSCALING_Shift)
+#define VSCALING(h0,h1)   ((((unsigned int) (((double)h0/(double)h1) * (1 << 15))) << VSCALING_Shift) & VSCALING_Mask)
+
+/* Scaling factors */
+#define HDM_SHIFT      16
+#define HDSCALE_4      (2 << HDM_SHIFT)
+#define HDSCALE_8      (3 << HDM_SHIFT)
+#define HDSCALE_16     (4 << HDM_SHIFT)
+#define HDSCALE_32     (5 << HDM_SHIFT)
+#define HDSCALE_64     (6 << HDM_SHIFT)
+
+/* Window parameters */
+#define OS_XY(x,y)     (((x+1)<<16)|(y+1))
+#define OS_WH(x,y)     (((x-1)<<16)|(y))
+
+/* PCI stuff */
+
+/* PCI-Memory IO access macros.  */
+#define VID_WR08(p,i,val)  (((uint8_t *)(p))[(i)]=(val))
+#define VID_RD08(p,i)      (((uint8_t *)(p))[(i)])
+
+#define VID_WR32(p,i,val)  (((uint32_t *)(p))[(i)/4]=(val))
+#define VID_RD32(p,i)      (((uint32_t *)(p))[(i)/4])
+
+#ifndef USE_RMW_CYCLES
+
+/* Can be used to inhibit READ-MODIFY-WRITE cycles. On by default. */
+#define MEM_BARRIER() __asm__ __volatile__ ("" : : : "memory")
+
+#undef  VID_WR08
+#define VID_WR08(p,i,val) ({ MEM_BARRIER(); ((uint8_t *)(p))[(i)]=(val); })
+#undef  VID_RD08
+#define VID_RD08(p,i)     ({ MEM_BARRIER(); ((uint8_t *)(p))[(i)]; })
+
+#undef  VID_WR16
+#define VID_WR16(p,i,val) ({ MEM_BARRIER(); ((uint16_t *)(p))[(i)/2]=(val); })
+#undef  VID_RD16
+#define VID_RD16(p,i)     ({ MEM_BARRIER(); ((uint16_t *)(p))[(i)/2]; })
+
+#undef  VID_WR32
+#define VID_WR32(p,i,val) ({ MEM_BARRIER(); ((uint32_t *)(p))[(i)/4]=(val); })
+#undef  VID_RD32
+#define VID_RD32(p,i)     ({ MEM_BARRIER(); ((uint32_t *)(p))[(i)/4]; })
+#endif /* USE_RMW_CYCLES */
+
+#define VID_AND32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)&(val))
+#define VID_OR32(p,i,val)  VID_WR32(p,i,VID_RD32(p,i)|(val))
+#define VID_XOR32(p,i,val) VID_WR32(p,i,VID_RD32(p,i)^(val))
+
+#define VGAIN8(addr) VID_RD08(info->control_base+0x8000, addr)
+#define VGAIN16(addr) VID_RD16(info->control_base+0x8000, addr)
+#define VGAIN(addr) VID_RD32(info->control_base+0x8000, addr)
+
+#define VGAOUT8(addr,val) VID_WR08(info->control_base+0x8000, addr, val)
+#define VGAOUT16(addr,val) VID_WR16(info->control_base+0x8000, addr, val)
+#define VGAOUT(addr,val) VID_WR32(info->control_base+0x8000, addr, val)
+
+#define INREG(addr) VID_RD32(info->control_base, addr)
+#define OUTREG(addr,val) VID_WR32(info->control_base, addr, val)
+#define INREG8(addr) VID_RD08(info->control_base, addr)
+#define OUTREG8(addr,val) VID_WR08(info->control_base, addr, val)
+#define INREG16(addr) VID_RD16(info->control_base, addr)
+#define OUTREG16(addr,val) VID_WR16(info->control_base, addr, val)
+
+#define ALIGN_TO(v, n) (((v) + (n-1)) & ~(n-1))
+
+#endif /* _S3_REGS_H */

Added: trunk/vidix/s3_vid.c
==============================================================================
--- (empty file)
+++ trunk/vidix/s3_vid.c	Fri Feb 29 21:01:28 2008
@@ -0,0 +1,929 @@
+/*
+ * VIDIX driver for S3 chipsets.
+ * Copyright (C) 2004 Reza Jelveh
+ *
+ * This file is part of MPlayer.
+ *
+ * MPlayer is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * MPlayer is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with MPlayer; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * Thanks to Alex Deucher for Support
+ * 
+ * Trio/Virge support by Michael Kostylev
+ *
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include <unistd.h>
+#include <math.h>
+
+#include "vidix.h"
+#include "vidixlib.h"
+#include "fourcc.h"
+#include "dha.h"
+#include "pci_ids.h"
+#include "pci_names.h"
+#include "config.h"
+
+#include "s3_regs.h"
+
+static void S3SetColorKeyOld (void);
+static void S3SetColorKeyNew (void);
+static void S3SetColorKey2000 (void); 
+static void (*S3SetColorKey) (void) = NULL;
+
+static void S3SetColorOld (void);
+static void S3SetColorNew (void);
+static void S3SetColor2000 (void); 
+static void (*S3SetColor) (void) = NULL;
+
+static void S3DisplayVideoOld (void);
+static void S3DisplayVideoNew (void);
+static void S3DisplayVideo2000 (void);
+static void (*S3DisplayVideo) (void) = NULL;
+
+static void S3InitStreamsOld (void);
+static void S3InitStreamsNew (void);
+static void S3InitStreams2000 (void);
+static void (*S3InitStreams) (void) = NULL;
+
+pciinfo_t pci_info;
+
+struct s3_chip
+{
+  int arch;
+  unsigned long fbsize;
+  void (*lock) (struct s3_chip *, int);
+};
+typedef struct s3_chip s3_chip;
+
+struct s3_info
+{
+  vidix_video_eq_t eq;
+  unsigned int use_colorkey;
+  unsigned int colorkey;
+  unsigned int vidixcolorkey;
+  unsigned int depth;
+  unsigned int bpp;
+  unsigned int format;
+  unsigned int pitch;
+  unsigned int blendBase;
+  unsigned int displayWidth, displayHeight;
+  unsigned int src_w, src_h;
+  unsigned int drw_w, drw_h;
+  unsigned int wx, wy;
+  unsigned int screen_x;
+  unsigned int screen_y;
+  unsigned long frame_size;
+  struct s3_chip chip;
+  void *video_base;
+  void *control_base;
+  unsigned long picture_base;
+  unsigned long picture_offset;
+  unsigned int num_frames;
+  int bps;
+};
+typedef struct s3_info s3_info;
+
+static s3_info *info;
+
+static vidix_capability_t s3_cap = {
+  "S3 BES",
+  "Reza Jelveh, Michael Kostylev",
+  TYPE_OUTPUT,
+  {0, 0, 0, 0},
+  4096,
+  4096,
+  4,
+  4,
+  -1,
+  FLAG_UPSCALER | FLAG_DOWNSCALER,
+  VENDOR_S3_INC,
+  -1,
+  {0, 0, 0, 0}
+};
+
+struct s3_cards
+{
+  unsigned short chip_id;
+  unsigned short arch;
+};
+
+static struct s3_cards s3_card_ids[] = {
+  /* Trio64V */
+  {DEVICE_S3_INC_86C764_765_TRIO32_64_64V, S3_TRIO64V},
+  {DEVICE_S3_INC_86C767_TRIO_64UV, S3_TRIO64V},
+  {DEVICE_S3_INC_86C755_TRIO_64V2_DX, S3_TRIO64V},
+  {DEVICE_S3_INC_86C775_86C785_TRIO_64V2_DX, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY2, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY3, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY4, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY5, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY6, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY7, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY8, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY9, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY10, S3_TRIO64V},
+  {DEVICE_S3_INC_TRIO_64V_FAMILY11, S3_TRIO64V},
+  /* Virge */
+  {DEVICE_S3_INC_86C325_VIRGE, S3_VIRGE},
+  {DEVICE_S3_INC_86C988_VIRGE_VX, S3_VIRGE},
+  {DEVICE_S3_INC_VIRGE_DX_OR_GX, S3_VIRGE},
+  {DEVICE_S3_INC_VIRGE_GX2, S3_VIRGE},
+  {DEVICE_S3_INC_VIRGE_M3, S3_VIRGE},
+  {DEVICE_S3_INC_VIRGE_MX, S3_VIRGE},
+  {DEVICE_S3_INC_VIRGE_MX2, S3_VIRGE},
+  {DEVICE_S3_INC_VIRGE_MX_MV, S3_VIRGE},
+  /* Savage3D */
+  {DEVICE_S3_INC_86C794_SAVAGE_3D, S3_SAVAGE3D},
+  {DEVICE_S3_INC_86C390_SAVAGE_3D_MV, S3_SAVAGE3D},
+  /* Savage4 */
+  {DEVICE_S3_INC_SAVAGE_4, S3_SAVAGE4},
+  {DEVICE_S3_INC_SAVAGE_42, S3_SAVAGE4},
+  /* SavageMX */
+  {DEVICE_S3_INC_86C270_294_SAVAGE_MX_MV, S3_SAVAGE_MX},
+  {DEVICE_S3_INC_82C270_294_SAVAGE_MX, S3_SAVAGE_MX},
+  {DEVICE_S3_INC_86C270_294_SAVAGE_IX_MV, S3_SAVAGE_MX},
+  /* SuperSavage */
+  {DEVICE_S3_INC_SUPERSAVAGE_MX_128, S3_SUPERSAVAGE},
+  {DEVICE_S3_INC_SUPERSAVAGE_MX_64, S3_SUPERSAVAGE},
+  {DEVICE_S3_INC_SUPERSAVAGE_MX_64C, S3_SUPERSAVAGE},
+  {DEVICE_S3_INC_SUPERSAVAGE_IX_128_SDR, S3_SUPERSAVAGE},
+  {DEVICE_S3_INC_SUPERSAVAGE_IX_128_DDR, S3_SUPERSAVAGE},
+  {DEVICE_S3_INC_SUPERSAVAGE_IX_64_SDR, S3_SUPERSAVAGE},
+  {DEVICE_S3_INC_SUPERSAVAGE_IX_64_DDR, S3_SUPERSAVAGE},
+  {DEVICE_S3_INC_SUPERSAVAGE_IX_C_SDR, S3_SUPERSAVAGE},
+  {DEVICE_S3_INC_SUPERSAVAGE_IX_C_DDR, S3_SUPERSAVAGE},
+  /* ProSavage */
+  {DEVICE_S3_INC_PROSAVAGE_PM133, S3_PROSAVAGE},
+  {DEVICE_S3_INC_PROSAVAGE_KM133, S3_PROSAVAGE},
+  {DEVICE_S3_INC_86C380_PROSAVAGEDDR_K4M266, S3_PROSAVAGE},
+  {DEVICE_S3_INC_VT8636A_PROSAVAGE_KN133, S3_PROSAVAGE},
+  {DEVICE_S3_INC_VT8751_PROSAVAGEDDR_P4M266, S3_PROSAVAGE},
+  {DEVICE_S3_INC_VT8375_PROSAVAGE8_KM266_KL266, S3_PROSAVAGE},
+  /* Savage2000 */
+  {DEVICE_S3_INC_86C410_SAVAGE_2000, S3_SAVAGE2000}
+};
+
+static unsigned int GetBlendForFourCC (int id)
+{
+  switch (id)
+  {
+  case IMGFMT_UYVY:
+    return 0;
+  case IMGFMT_YUY2:
+    return 1;
+  case IMGFMT_Y211:
+    return 4;
+  case IMGFMT_BGR15:
+    return 3;
+  case IMGFMT_BGR16:
+    return 5;
+  case IMGFMT_BGR24:
+    return 6;
+  case IMGFMT_BGR32:
+    return 7;
+  default:
+    return 1;
+  }
+}
+
+static void S3SetColorOld (void)
+{
+  char sat = (info->eq.saturation + 1000) * 15 / 2000;
+  double hue = info->eq.hue * 3.1415926 / 1000.0;
+  char hsx = ((char) (sat * cos (hue))) & 0x1f;
+  char hsy = ((char) (sat * sin (hue))) & 0x1f;
+
+  OUTREG (COLOR_ADJUSTMENT_REG, 0x80008000 | hsy << 24 | hsx << 16 |
+    ((info->eq.contrast + 1000) * 31 / 2000) << 8 |
+    (info->eq.brightness + 1000) * 255 / 2000);
+}
+
+static void S3SetColorNew (void)
+{
+  /* not yet */
+}
+
+static void S3SetColor2000 (void)
+{
+  /* not yet */
+}
+
+static void S3SetColorKeyOld (void)
+{
+  int red, green, blue;
+
+  /* Here, we reset the colorkey and all the controls */
+
+  red = (info->vidixcolorkey & 0x00FF0000) >> 16;
+  green = (info->vidixcolorkey & 0x0000FF00) >> 8;
+  blue = info->vidixcolorkey & 0x000000FF;
+
+  if (!info->vidixcolorkey)
+  {
+    OUTREG (COL_CHROMA_KEY_CONTROL_REG, 0);
+    OUTREG (CHROMA_KEY_UPPER_BOUND_REG, 0);
+    OUTREG (BLEND_CONTROL_REG, 0);
+  }
+  else
+  {
+    switch (info->depth)
+    {
+      // FIXME: isnt fixed yet
+    case 8:
+      OUTREG (COL_CHROMA_KEY_CONTROL_REG, 0x37000000 | (info->vidixcolorkey & 0xFF));
+      OUTREG (CHROMA_KEY_UPPER_BOUND_REG, 0x00000000 | (info->vidixcolorkey & 0xFF));
+      break;
+    case 15:
+      /* 15 bpp 555 */
+      red &= 0x1f;
+      green &= 0x1f;
+      blue &= 0x1f;
+      OUTREG (COL_CHROMA_KEY_CONTROL_REG, 0x05000000 | (red << 19) | (green << 11) | (blue << 3));
+      OUTREG (CHROMA_KEY_UPPER_BOUND_REG, 0x00000000 | (red << 19) | (green << 11) | (blue << 3));
+      break;
+    case 16:
+      /* 16 bpp 565 */
+      red &= 0x1f;
+      green &= 0x3f;
+      blue &= 0x1f;
+      OUTREG (COL_CHROMA_KEY_CONTROL_REG, 0x16000000 | (red << 19) | (green << 10) | (blue << 3));
+      OUTREG (CHROMA_KEY_UPPER_BOUND_REG, 0x00020002 | (red << 19) | (green << 10) | (blue << 3));
+      break;
+    case 24:
+      /* 24 bpp 888 */
+      OUTREG (COL_CHROMA_KEY_CONTROL_REG, 0x17000000 | (red << 16) | (green << 8) | (blue));
+      OUTREG (CHROMA_KEY_UPPER_BOUND_REG, 0x00000000 | (red << 16) | (green << 8) | (blue));
+      break;
+    }
+
+    /* We use destination colorkey */
+    OUTREG (BLEND_CONTROL_REG, 0x05000000);
+  }
+}
+
+static void S3SetColorKeyNew (void)
+{
+  /* not yet */
+}
+
+static void S3SetColorKey2000 (void)
+{
+  /* not yet */
+}
+
+static void S3DisplayVideoOld (void)
+{
+  unsigned int ssControl;
+  int cr92;
+
+  /* Set surface location and stride */
+  OUTREG (SSTREAM_FBADDR0_REG, info->picture_offset);
+  OUTREG (SSTREAM_FBADDR1_REG, 0);
+  OUTREG (SSTREAM_STRIDE_REG, info->pitch);
+  /* Set window parameters */
+  OUTREG (SSTREAM_WINDOW_START_REG, OS_XY (info->wx, info->wy));
+  OUTREG (SSTREAM_WINDOW_SIZE_REG, OS_WH (info->drw_w, info->drw_h));
+
+  /* Set surface format and adjust scaling */
+  if (info->chip.arch <= S3_VIRGE)
+  {
+    ssControl = ((info->src_w - 1) << 1) - ((info->drw_w - 1) & 0xffff);
+    ssControl |= GetBlendForFourCC (info->format) << 24;
+    if (info->src_w != info->drw_w)
+      ssControl |= 2 << 28; 
+
+    OUTREG (SSTREAM_CONTROL_REG, ssControl);
+    OUTREG (SSTREAM_STRETCH_REG, (((info->src_w - info->drw_w) & 0x7ff) << 16) | (info->src_w - 1));
+    /* Calculate vertical scale factor */
+    OUTREG (K1_VSCALE_REG, info->src_h - 1);
+    OUTREG (K2_VSCALE_REG, (info->src_h - info->drw_h) & 0x7ff);
+    OUTREG (DDA_VERT_REG, (1 - info->drw_h) & 0xfff);
+  }
+  else
+  {
+    ssControl = GetBlendForFourCC (info->format) << 24 | info->src_w;
+    if (info->src_w > (info->drw_w << 1))
+    {
+      /* BUGBUG shouldn't this be >=?  */
+      if (info->src_w <= (info->drw_w << 2))
+        ssControl |= HDSCALE_4;
+      else if (info->src_w > (info->drw_w << 3))
+        ssControl |= HDSCALE_8;
+      else if (info->src_w > (info->drw_w << 4))
+        ssControl |= HDSCALE_16;
+      else if (info->src_w > (info->drw_w << 5))
+        ssControl |= HDSCALE_32;
+      else if (info->src_w > (info->drw_w << 6))
+        ssControl |= HDSCALE_64;
+    }
+
+    OUTREG (SSTREAM_CONTROL_REG, ssControl);
+    OUTREG (SSTREAM_STRETCH_REG, (info->src_w << 15) / info->drw_w);
+    OUTREG (SSTREAM_LINES_REG, info->src_h);
+    /* Calculate vertical scale factor. */
+    OUTREG (SSTREAM_VSCALE_REG, VSCALING (info->src_h, info->drw_h));
+  }
+
+  if (info->chip.arch == S3_TRIO64V)
+    OUTREG (STREAMS_FIFO_REG, (6 << 10) | (14 << 5) | 16);
+  else
+  {
+    // FIXME: this should actually be enabled
+    info->pitch = (info->pitch + 7) / 8;
+    VGAOUT8 (vgaCRIndex, 0x92);
+    cr92 = VGAIN8 (vgaCRReg);
+    VGAOUT8 (vgaCRReg, (cr92 & 0x40) | (info->pitch >> 8) | 0x80);
+    VGAOUT8 (vgaCRIndex, 0x93);
+    VGAOUT8 (vgaCRReg, info->pitch);
+    OUTREG (STREAMS_FIFO_REG, 2 | 25 << 5 | 32 << 11);
+  }
+}
+
+static void S3DisplayVideoNew (void)
+{
+  /* not yet */
+}
+
+static void S3DisplayVideo2000 (void)
+{
+  /* not yet */
+}
+
+static void S3InitStreamsOld (void)
+{
+  /*unsigned long jDelta; */
+  unsigned long format = 0;
+
+  /*jDelta = pScrn->displayWidth * (pScrn->bitsPerPixel + 7) / 8; */
+  switch (info->depth)
+  {
+  case 8:
+    format = 0 << 24;
+    break;
+  case 15:
+    format = 3 << 24;
+    break;
+  case 16:
+    format = 5 << 24;
+    break;
+  case 24:
+    format = 7 << 24;
+    break;
+  }
+//#warning enable this again
+  OUTREG (PSTREAM_FBSIZE_REG, info->screen_y * info->screen_x * (info->bpp >> 3));
+  OUTREG (PSTREAM_WINDOW_START_REG, OS_XY (0, 0));
+  OUTREG (PSTREAM_WINDOW_SIZE_REG, OS_WH (info->screen_x, info->screen_y));
+  OUTREG (PSTREAM_FBADDR1_REG, 0);
+  /*OUTREG( PSTREAM_STRIDE_REG, jDelta ); */
+  OUTREG (PSTREAM_CONTROL_REG, format);
+  OUTREG (PSTREAM_FBADDR0_REG, 0);
+
+  OUTREG (COL_CHROMA_KEY_CONTROL_REG, 0);
+  OUTREG (SSTREAM_CONTROL_REG, 0);
+  OUTREG (CHROMA_KEY_UPPER_BOUND_REG, 0);
+  OUTREG (SSTREAM_STRETCH_REG, 0);
+  OUTREG (COLOR_ADJUSTMENT_REG, 0);
+  OUTREG (BLEND_CONTROL_REG, 1 << 24);
+  OUTREG (DOUBLE_BUFFER_REG, 0);
+  OUTREG (SSTREAM_FBADDR0_REG, 0);
+  OUTREG (SSTREAM_FBADDR1_REG, 0);
+  OUTREG (SSTREAM_FBADDR2_REG, 0);
+  OUTREG (SSTREAM_FBSIZE_REG, 0);
+  OUTREG (SSTREAM_STRIDE_REG, 0);
+  OUTREG (SSTREAM_VSCALE_REG, 0);
+  OUTREG (SSTREAM_LINES_REG, 0);
+  OUTREG (SSTREAM_VINITIAL_REG, 0);
+}
+
+static void S3InitStreamsNew (void)
+{
+  /* not yet */
+}
+
+static void S3InitStreams2000 (void)
+{
+  /* not yet */
+}
+
+static void S3StreamsOn (void)
+{
+  unsigned char jStreamsControl;
+
+  VGAOUT8 (vgaCRIndex, EXT_MISC_CTRL2);
+
+  if (S3_SAVAGE_MOBILE_SERIES (info->chip.arch))
+  {
+    jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAM1;
+    VerticalRetraceWait ();
+    VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2);
+
+    S3InitStreams = S3InitStreamsNew;
+    S3SetColor = S3SetColorNew;
+    S3SetColorKey = S3SetColorKeyNew;
+    S3DisplayVideo = S3DisplayVideoNew;
+  }
+  else if (info->chip.arch == S3_SAVAGE2000)
+  {
+    jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAM1;
+    VerticalRetraceWait ();
+    VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2);
+
+    S3InitStreams = S3InitStreams2000;
+    S3SetColor = S3SetColor2000;
+    S3SetColorKey = S3SetColorKey2000;
+    S3DisplayVideo = S3DisplayVideo2000;
+  }
+  else
+  {
+    jStreamsControl = VGAIN8 (vgaCRReg) | ENABLE_STREAMS_OLD;
+    VerticalRetraceWait ();
+    VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2);
+
+    S3InitStreams = S3InitStreamsOld;
+    S3SetColor = S3SetColorOld;
+    S3SetColorKey = S3SetColorKeyOld;
+    S3DisplayVideo = S3DisplayVideoOld;
+  }
+
+  S3InitStreams ();
+
+  VerticalRetraceWait ();
+  /* Turn on secondary stream TV flicker filter, once we support TV. */
+  /* SR70 |= 0x10 */
+}
+
+static void S3GetScrProp (struct s3_info *info)
+{
+  unsigned char bpp = 0;
+
+  VGAOUT8 (vgaCRIndex, EXT_MISC_CTRL2);
+  bpp = VGAIN8 (vgaCRReg);
+
+  switch (bpp & 0xf0)
+  {
+  case 0x00:
+  case 0x10:
+    info->depth = 8;
+    info->bpp = 8;
+    break;
+  case 0x20:
+  case 0x30:
+    info->depth = 15;
+    info->bpp = 16;
+    break;
+  case 0x40:
+  case 0x50:
+    info->depth = 16;
+    info->bpp = 16;
+    break;
+  case 0x70:
+  case 0xd0:
+    info->depth = 24;
+    info->bpp = 32;
+    break;
+  }
+
+  VGAOUT8 (vgaCRIndex, 0x1);
+  info->screen_x = (1 + VGAIN8 (vgaCRReg)) << 3;
+  VGAOUT8 (vgaCRIndex, 0x12);
+  info->screen_y = VGAIN8 (vgaCRReg);
+  VGAOUT8 (vgaCRIndex, 0x07);
+  info->screen_y |= (VGAIN8 (vgaCRReg) & 0x02) << 7;
+  info->screen_y |= (VGAIN8 (vgaCRReg) & 0x40) << 3;
+  ++info->screen_y;
+
+  printf ("[s3_vid] x = %d, y = %d, bpp = %d\n", info->screen_x, info->screen_y, info->bpp);
+}
+
+static void S3StreamsOff (void)
+{
+  unsigned char jStreamsControl;
+
+  if (info->chip.arch == S3_TRIO64V)
+    OUTREG (STREAMS_FIFO_REG, (20 << 10));
+
+  VGAOUT8 (vgaCRIndex, EXT_MISC_CTRL2);
+  if (S3_SAVAGE_MOBILE_SERIES (info->chip.arch) ||
+      (info->chip.arch == S3_SUPERSAVAGE) || (info->chip.arch == S3_SAVAGE2000))
+    jStreamsControl = VGAIN8 (vgaCRReg) & NO_STREAMS;
+  else
+    jStreamsControl = VGAIN8 (vgaCRReg) & NO_STREAMS_OLD;
+
+  VerticalRetraceWait ();
+  VGAOUT16 (vgaCRIndex, (jStreamsControl << 8) | EXT_MISC_CTRL2);
+
+  if (S3_SAVAGE_SERIES (info->chip.arch))
+  {
+    VGAOUT16 (vgaCRIndex, 0x0093);
+    VGAOUT8 (vgaCRIndex, 0x92);
+    VGAOUT8 (vgaCRReg, VGAIN8 (vgaCRReg) & 0x40);
+  }
+}
+
+static int find_chip (unsigned chip_id)
+{
+  unsigned i;
+
+  for (i = 0; i < sizeof (s3_card_ids) / sizeof (struct s3_cards); i++)
+    if (chip_id == s3_card_ids[i].chip_id)
+      return i;
+  return -1;
+}
+
+static int s3_probe (int verbose, int force)
+{
+  pciinfo_t lst[MAX_PCI_DEVICES];
+  unsigned i, num_pci;
+  int err;
+
+  if (force)
+    printf ("[s3_vid] Warning: forcing not supported yet!\n");
+  err = pci_scan (lst, &num_pci);
+  if (err)
+  {
+    printf ("[s3_vid] Error occurred during pci scan: %s\n", strerror (err));
+    return err;
+  }
+  else
+  {
+    err = ENXIO;
+    for (i = 0; i < num_pci; i++)
+    {
+      if (lst[i].vendor == VENDOR_S3_INC)
+      {
+        int idx;
+        const char *dname;
+        idx = find_chip (lst[i].device);
+        if (idx == -1)
+          continue;
+        dname = pci_device_name (lst[i].vendor, lst[i].device);
+        dname = dname ? dname : "Unknown chip";
+        printf ("[s3_vid] Found chip: %s\n", dname);
+        // FIXME: whats wrong here?
+        if ((lst[i].command & PCI_COMMAND_IO) == 0)
+        {
+          printf ("[s3_vid] Device is disabled, ignoring\n");
+          continue;
+        }
+        s3_cap.device_id = lst[i].device;
+        err = 0;
+        memcpy (&pci_info, &lst[i], sizeof (pciinfo_t));
+        break;
+      }
+    }
+  }
+  if (err && verbose)
+    printf ("[s3_vid] Can't find chip\n");
+  return err;
+}
+
+static int s3_init (const char *args __attribute__ ((unused)))
+{
+  unsigned char cr36;
+  int mtrr, videoRam;
+  static unsigned char RamTrioVirge[] = { 4, 0, 3, 8, 2, 6, 1, 0 };
+  static unsigned char RamSavage3D[] = { 8, 4, 4, 2 };
+  static unsigned char RamSavage4[] = { 2, 4, 8, 12, 16, 32, 64, 32 };
+  static unsigned char RamSavageMX[] = { 2, 8, 4, 16, 8, 16, 4, 16 };
+  static unsigned char RamSavageNB[] = { 0, 2, 4, 8, 16, 32, 16, 2 };
+
+  enable_app_io ();
+
+  info = calloc (1, sizeof (s3_info));
+
+  info->chip.arch = s3_card_ids[find_chip (pci_info.device)].arch;
+
+  /* Switch to vga registers */
+  OUTPORT8 (0x3c3, INPORT8 (0x3c3) | 0x01);
+  OUTPORT8 (0x3c2, INPORT8 (0x3cc) | 0x01);
+  /* Unlock extended registers */
+  OUTPORT8 (vgaCRIndex, 0x38);
+  OUTPORT8 (vgaCRReg, 0x48);
+  OUTPORT8 (vgaCRIndex, 0x39);
+  OUTPORT8 (vgaCRReg, 0xa0);
+
+  if (info->chip.arch <= S3_VIRGE)
+  {
+    /* TODO: Improve detecting code */
+
+    /* Enable LFB */
+    OUTPORT8 (vgaCRIndex, LIN_ADDR_CTRL);
+    OUTPORT8 (vgaCRReg,  INPORT8 (vgaCRReg) | ENABLE_LFB);
+    /* Enable NewMMIO */
+    OUTPORT8 (vgaCRIndex, EXT_MEM_CTRL1);
+    OUTPORT8 (vgaCRReg,  INPORT8 (vgaCRReg) | ENABLE_NEWMMIO);
+  }
+
+  if (info->chip.arch < S3_SAVAGE3D)
+    info->control_base = map_phys_mem (pci_info.base0 + S3_NEWMMIO_REGBASE, S3_NEWMMIO_REGSIZE);
+  else if (info->chip.arch == S3_SAVAGE3D)
+    info->control_base = map_phys_mem (pci_info.base0 + S3_NEWMMIO_REGBASE, S3_NEWMMIO_REGSIZE_SAVAGE);
+  else
+    info->control_base = map_phys_mem (pci_info.base0, S3_NEWMMIO_REGSIZE_SAVAGE);
+
+  /* Unlock CRTC[0-7] */
+  VGAOUT8 (vgaCRIndex, 0x11);
+  VGAOUT8 (vgaCRReg, VGAIN8 (vgaCRReg) & 0x7f);
+  /* Unlock sequencer */
+  VGAOUT16 (0x3c4, 0x0608);
+  /* Detect amount of installed ram */
+  VGAOUT8 (vgaCRIndex, 0x36);
+  cr36 = VGAIN8 (vgaCRReg);
+
+  switch (info->chip.arch)
+  {
+  case S3_TRIO64V:
+  case S3_VIRGE:
+    videoRam = RamTrioVirge[(cr36 & 0xE0) >> 5] * 1024;
+    break;
+
+  case S3_SAVAGE3D:
+    videoRam = RamSavage3D[(cr36 & 0xC0) >> 6] * 1024;
+    break;
+
+  case S3_SAVAGE4:
+    /* 
+     * The Savage4 has one ugly special case to consider.  On
+     * systems with 4 banks of 2Mx32 SDRAM, the BIOS says 4MB
+     * when it really means 8MB.  Why do it the same when you
+     * can do it different...
+     */
+    VGAOUT8 (vgaCRIndex, 0x68);
+    if ((VGAIN8 (vgaCRReg) & 0xC0) == (0x01 << 6))
+      RamSavage4[1] = 8;
+
+  case S3_SAVAGE2000:
+    videoRam = RamSavage4[(cr36 & 0xE0) >> 5] * 1024;
+    break;
+
+  case S3_SAVAGE_MX:
+    videoRam = RamSavageMX[(cr36 & 0x0E) >> 1] * 1024;
+    break;
+
+  case S3_PROSAVAGE:
+    videoRam = RamSavageNB[(cr36 & 0xE0) >> 5] * 1024;
+    break;
+
+  default:
+    /* How did we get here? */
+    videoRam = 0;
+    break;
+  }
+
+  printf ("[s3_vid] VideoRam = %d\n", videoRam);
+  info->chip.fbsize = videoRam * 1024;
+
+  if (info->chip.arch <= S3_SAVAGE3D)
+    mtrr = mtrr_set_type (pci_info.base0, info->chip.fbsize, MTRR_TYPE_WRCOMB);
+  else
+    mtrr = mtrr_set_type (pci_info.base1, info->chip.fbsize, MTRR_TYPE_WRCOMB);
+
+  if (mtrr != 0)
+    printf ("[s3_vid] Unable to setup MTRR: %s\n", strerror (mtrr));
+  else
+    printf ("[s3_vid] MTRR set up\n");
+
+  S3GetScrProp (info);
+  S3StreamsOn ();
+
+  return 0;
+}
+
+static void s3_destroy (void)
+{
+  unmap_phys_mem (info->video_base, info->chip.fbsize);
+  if (S3_SAVAGE_SERIES (info->chip.arch))
+    unmap_phys_mem (info->control_base, S3_NEWMMIO_REGSIZE_SAVAGE);
+  else
+    unmap_phys_mem (info->control_base, S3_NEWMMIO_REGSIZE);
+
+  free (info);
+}
+
+static int s3_get_caps (vidix_capability_t * to)
+{
+  memcpy (to, &s3_cap, sizeof (vidix_capability_t));
+  return 0;
+}
+
+static int is_supported_fourcc (uint32_t fourcc)
+{
+  switch (fourcc)
+  {
+//FIXME: Burst Command Interface should be used 
+// for planar to packed conversion
+//    case IMGFMT_YV12:
+//    case IMGFMT_I420:
+  case IMGFMT_UYVY:
+  case IMGFMT_YUY2:
+  case IMGFMT_Y211:
+  case IMGFMT_BGR15:
+  case IMGFMT_BGR16:
+  case IMGFMT_BGR24:
+  case IMGFMT_BGR32:
+    return 1;
+  default:
+    return 0;
+  }
+}
+
+static int s3_query_fourcc (vidix_fourcc_t * to)
+{
+  if (is_supported_fourcc (to->fourcc))
+  {
+    to->depth = VID_DEPTH_ALL;
+    to->flags = VID_CAP_EXPAND | VID_CAP_SHRINK | VID_CAP_COLORKEY;
+    return 0;
+  }
+  else
+    to->depth = to->flags = 0;
+
+  return ENOSYS;
+}
+
+#if 0
+static int s3_get_gkeys (vidix_grkey_t * grkey)
+{
+  return 0;
+}
+#endif
+
+static int s3_set_gkeys (const vidix_grkey_t * grkey)
+{
+  if (grkey->ckey.op == CKEY_FALSE)
+  {
+    info->use_colorkey = 0;
+    info->vidixcolorkey = 0;
+    printf ("[s3_vid] Colorkeying disabled\n");
+  }
+  else
+  {
+    info->use_colorkey = 1;
+    info->vidixcolorkey = ((grkey->ckey.red << 16) | (grkey->ckey.green << 8) | grkey->ckey.blue);
+    printf ("[s3_vid] Set colorkey 0x%x\n", info->vidixcolorkey);
+  }
+  if (S3SetColorKey)
+    S3SetColorKey ();
+  return 0;
+}
+
+static int s3_get_eq (vidix_video_eq_t * eq)
+{
+  memcpy (eq, &(info->eq), sizeof (vidix_video_eq_t));
+  return 0;
+}
+
+static int s3_set_eq (const vidix_video_eq_t * eq)
+{
+  if (eq->cap & VEQ_CAP_BRIGHTNESS)
+    info->eq.brightness = eq->brightness;
+  if (eq->cap & VEQ_CAP_CONTRAST)
+    info->eq.contrast = eq->contrast;
+  if (eq->cap & VEQ_CAP_SATURATION)
+    info->eq.saturation = eq->saturation;
+  if (eq->cap & VEQ_CAP_HUE)
+    info->eq.hue = eq->hue;
+  if (S3SetColor)
+    S3SetColor ();
+  return 0;
+}
+
+static int s3_config_playback (vidix_playback_t * vinfo)
+{
+  unsigned int i, bpp;
+
+  if (!is_supported_fourcc (vinfo->fourcc))
+    return -1;
+
+  info->src_w = vinfo->src.w;
+  info->src_h = vinfo->src.h;
+
+  info->drw_w = vinfo->dest.w;
+  info->drw_h = vinfo->dest.h;
+
+  info->wx = vinfo->dest.x;
+  info->wy = vinfo->dest.y;
+  info->format = vinfo->fourcc;
+
+  info->eq.cap = VEQ_CAP_BRIGHTNESS | VEQ_CAP_CONTRAST |
+                 VEQ_CAP_SATURATION | VEQ_CAP_HUE;
+  info->eq.brightness = 0;
+  info->eq.contrast = 0;
+  info->eq.saturation = 0;
+  info->eq.hue = 0;
+
+  vinfo->offset.y = 0;
+  vinfo->offset.v = 0;
+  vinfo->offset.u = 0;
+
+  vinfo->dest.pitch.y = 32;
+  vinfo->dest.pitch.u = 32;
+  vinfo->dest.pitch.v = 32;
+
+  switch (vinfo->fourcc)
+  {
+  case IMGFMT_Y211:
+    bpp = 1;
+    break;
+  case IMGFMT_BGR24:
+    bpp = 3;
+    break;
+  case IMGFMT_BGR32:
+    bpp = 4;
+    break;
+  default:
+    bpp = 2;
+    break;
+  }
+
+  info->pitch = ((info->src_w * bpp) + 15) & ~15;
+  info->pitch |= ((info->pitch / bpp) << 16);
+
+  vinfo->frame_size = (info->pitch & 0xffff) * info->src_h;
+  info->frame_size = vinfo->frame_size;
+
+  info->picture_offset = info->screen_x * info->screen_y * (info->bpp >> 3);
+  if (info->picture_offset > (info->chip.fbsize - vinfo->frame_size))
+  {
+    printf ("[s3_vid] Not enough memory for overlay\n");
+    return -1;
+  }
+
+  if (info->chip.arch <= S3_SAVAGE3D)
+    info->video_base = map_phys_mem (pci_info.base0, info->chip.fbsize);
+  else
+    info->video_base = map_phys_mem (pci_info.base1, info->chip.fbsize);
+
+  if (info->video_base == NULL)
+  {
+    printf ("[s3_vid] errno = %s\n", strerror (errno));
+    return -1;
+  }
+
+  info->picture_base = (uint32_t) info->video_base + info->picture_offset;
+
+  vinfo->dga_addr = (void *) (info->picture_base);
+
+  vinfo->num_frames = (info->chip.fbsize - info->picture_offset) / vinfo->frame_size;
+  if (vinfo->num_frames > VID_PLAY_MAXFRAMES)
+    vinfo->num_frames = VID_PLAY_MAXFRAMES;
+
+  for (i = 0; i < vinfo->num_frames; i++)
+    vinfo->offsets[i] = vinfo->frame_size * i;
+
+  return 0;
+}
+
+static int s3_playback_on (void)
+{
+  S3DisplayVideo ();
+  return 0;
+}
+
+static int s3_playback_off (void)
+{
+  S3StreamsOff ();
+  return 0;
+}
+
+static int s3_frame_sel (unsigned int frame)
+{
+  OUTREG (SSTREAM_FBADDR0_REG, info->picture_offset + (info->frame_size * frame));
+  return 0;
+}
+
+VDXDriver s3_drv = {
+  "s3",
+  NULL,
+  .probe = s3_probe,
+  .get_caps = s3_get_caps,
+  .query_fourcc = s3_query_fourcc,
+  .init = s3_init,
+  .destroy = s3_destroy,
+  .config_playback = s3_config_playback,
+  .playback_on = s3_playback_on,
+  .playback_off = s3_playback_off,
+  .frame_sel = s3_frame_sel,
+  .get_eq = s3_get_eq,
+  .set_eq = s3_set_eq,
+  .set_gkey = s3_set_gkeys,
+};



More information about the MPlayer-cvslog mailing list