summaryrefslogtreecommitdiff
path: root/Source/DirectFB/gfxdrivers/nvidia/nvidia.c
diff options
context:
space:
mode:
Diffstat (limited to 'Source/DirectFB/gfxdrivers/nvidia/nvidia.c')
-rwxr-xr-xSource/DirectFB/gfxdrivers/nvidia/nvidia.c2046
1 files changed, 2046 insertions, 0 deletions
diff --git a/Source/DirectFB/gfxdrivers/nvidia/nvidia.c b/Source/DirectFB/gfxdrivers/nvidia/nvidia.c
new file mode 100755
index 0000000..6ecb17f
--- /dev/null
+++ b/Source/DirectFB/gfxdrivers/nvidia/nvidia.c
@@ -0,0 +1,2046 @@
+/*
+ (c) Copyright 2001-2009 The world wide DirectFB Open Source Community (directfb.org)
+ (c) Copyright 2000-2004 Convergence (integrated media) GmbH
+
+ All rights reserved.
+
+ Written by Denis Oliver Kropp <dok@directfb.org>,
+ Andreas Hundt <andi@fischlustig.de>,
+ Sven Neumann <neo@directfb.org>,
+ Ville Syrjälä <syrjala@sci.fi> and
+ Claudio Ciccani <klan@users.sf.net>.
+
+ This library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2 of the License, or (at your option) any later version.
+
+ This library 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the
+ Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+*/
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <sys/mman.h>
+
+#include <fbdev/fb.h>
+
+#include <directfb.h>
+
+#include <direct/messages.h>
+
+#include <core/coredefs.h>
+#include <core/coretypes.h>
+
+#include <core/state.h>
+#include <core/system.h>
+#include <core/gfxcard.h>
+#include <core/surface.h>
+#include <core/palette.h>
+
+#include <gfx/convert.h>
+#include <gfx/util.h>
+
+#include <misc/conf.h>
+
+#include <core/graphics_driver.h>
+
+DFB_GRAPHICS_DRIVER( nvidia )
+
+#include "nvidia.h"
+#include "nvidia_regs.h"
+#include "nvidia_accel.h"
+#include "nvidia_objects.h"
+#include "nvidia_state.h"
+#include "nvidia_2d.h"
+#include "nvidia_3d.h"
+
+
+/* Riva TNT */
+#define NV4_SUPPORTED_DRAWINGFLAGS \
+ (DSDRAW_BLEND)
+
+#define NV4_SUPPORTED_DRAWINGFUNCTIONS \
+ (DFXL_FILLRECTANGLE | DFXL_DRAWRECTANGLE | \
+ DFXL_FILLTRIANGLE | DFXL_DRAWLINE)
+
+#define NV4_SUPPORTED_BLITTINGFLAGS \
+ (DSBLIT_BLEND_COLORALPHA | DSBLIT_BLEND_ALPHACHANNEL | \
+ DSBLIT_DEINTERLACE)
+
+#define NV4_SUPPORTED_BLITTINGFUNCTIONS \
+ (DFXL_BLIT | DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES)
+
+/* Riva TNT2 */
+#define NV5_SUPPORTED_DRAWINGFLAGS \
+ (DSDRAW_BLEND)
+
+#define NV5_SUPPORTED_DRAWINGFUNCTIONS \
+ (DFXL_FILLRECTANGLE | DFXL_DRAWRECTANGLE | \
+ DFXL_FILLTRIANGLE | DFXL_DRAWLINE)
+
+#define NV5_SUPPORTED_BLITTINGFLAGS \
+ (DSBLIT_BLEND_COLORALPHA | DSBLIT_BLEND_ALPHACHANNEL | \
+ DSBLIT_COLORIZE | DSBLIT_DEINTERLACE)
+
+#define NV5_SUPPORTED_BLITTINGFUNCTIONS \
+ (DFXL_BLIT | DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES)
+
+/* GeForce1/GeForce2/GeForce4 */
+#define NV10_SUPPORTED_DRAWINGFLAGS \
+ (DSDRAW_BLEND)
+
+#define NV10_SUPPORTED_DRAWINGFUNCTIONS \
+ (DFXL_FILLRECTANGLE | DFXL_DRAWRECTANGLE | \
+ DFXL_FILLTRIANGLE | DFXL_DRAWLINE)
+
+#define NV10_SUPPORTED_BLITTINGFLAGS \
+ (DSBLIT_BLEND_COLORALPHA | DSBLIT_BLEND_ALPHACHANNEL | \
+ DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR | \
+ DSBLIT_DEINTERLACE)
+
+#define NV10_SUPPORTED_BLITTINGFUNCTIONS \
+ (DFXL_BLIT | DFXL_STRETCHBLIT | DFXL_TEXTRIANGLES)
+
+/* GeForce3/GeForce4Ti */
+#define NV20_SUPPORTED_DRAWINGFLAGS \
+ (DSDRAW_BLEND)
+
+#define NV20_SUPPORTED_DRAWINGFUNCTIONS \
+ (DFXL_FILLRECTANGLE | DFXL_DRAWRECTANGLE | \
+ DFXL_FILLTRIANGLE | DFXL_DRAWLINE)
+
+#define NV20_SUPPORTED_BLITTINGFLAGS \
+ (DSBLIT_BLEND_COLORALPHA | DSBLIT_BLEND_ALPHACHANNEL | \
+ DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR | \
+ DSBLIT_DEINTERLACE)
+
+#define NV20_SUPPORTED_BLITTINGFUNCTIONS \
+ (DFXL_BLIT | DFXL_STRETCHBLIT)
+
+/* GeForceFX */
+#define NV30_SUPPORTED_DRAWINGFLAGS \
+ (DSDRAW_BLEND)
+
+#define NV30_SUPPORTED_DRAWINGFUNCTIONS \
+ (DFXL_FILLRECTANGLE | DFXL_DRAWRECTANGLE | \
+ DFXL_FILLTRIANGLE | DFXL_DRAWLINE)
+
+#define NV30_SUPPORTED_BLITTINGFLAGS \
+ (DSBLIT_NOFX)
+
+#define NV30_SUPPORTED_BLITTINGFUNCTIONS \
+ (DFXL_BLIT)
+
+
+#define DSBLIT_MODULATE_ALPHA \
+ (DSBLIT_BLEND_COLORALPHA | DSBLIT_BLEND_ALPHACHANNEL)
+
+#define DSBLIT_MODULATE_COLOR \
+ (DSBLIT_COLORIZE | DSBLIT_SRC_PREMULTCOLOR)
+
+#define DSBLIT_MODULATE \
+ (DSBLIT_MODULATE_ALPHA | DSBLIT_MODULATE_COLOR)
+
+
+
+
+static void nvAfterSetVar( void *driver_data,
+ void *device_data )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) driver_data;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) device_data;
+ volatile u8 *mmio = nvdrv->mmio_base;
+ int i;
+
+ nv_waitidle( nvdrv, nvdev );
+
+ /* reconfigure PFIFO for selected mode (DMA/PIO) */
+ nv_out32( mmio, PFIFO_CACHES, PFIFO_CACHES_REASSIGN_DISABLED );
+ if (nvdev->use_dma) {
+ nv_out32( mmio, PFIFO_MODE, PFIFO_MODE_CHANNEL_0_DMA );
+ nv_out32( mmio, PFIFO_NEXT_CHANNEL, PFIFO_NEXT_CHANNEL_MODE_DMA );
+ } else {
+ nv_out32( mmio, PFIFO_MODE, PFIFO_MODE_CHANNEL_0_PIO );
+ nv_out32( mmio, PFIFO_NEXT_CHANNEL, PFIFO_NEXT_CHANNEL_MODE_PIO );
+ }
+ nv_out32( mmio, PFIFO_CACHE1_PUSH0, PFIFO_CACHE1_PULL1_ENGINE_SW );
+ nv_out32( mmio, PFIFO_CACHE1_PULL0, PFIFO_CACHE1_PULL0_ACCESS_DISABLED );
+ if (nvdev->use_dma) {
+ nv_out32( mmio, PFIFO_CACHE1_PUSH1, PFIFO_CACHE1_PUSH1_MODE_DMA );
+ } else {
+ nv_out32( mmio, PFIFO_CACHE1_PUSH1, PFIFO_CACHE1_PUSH1_MODE_PIO );
+ }
+ nv_out32( mmio, PFIFO_CACHE1_DMA_PUT, 0 );
+ nv_out32( mmio, PFIFO_CACHE1_DMA_GET, 0 );
+ if (nvdev->use_dma) {
+ nv_out32( mmio, PFIFO_CACHE1_DMA_INSTANCE, ADDR_DMA_OUT );
+ } else {
+ nv_out32( mmio, PFIFO_CACHE1_DMA_INSTANCE, 0 );
+ }
+ nv_out32( mmio, PFIFO_CACHE0_PUSH0, PFIFO_CACHE0_PUSH0_ACCESS_DISABLED );
+ nv_out32( mmio, PFIFO_CACHE0_PULL0, PFIFO_CACHE0_PULL0_ACCESS_DISABLED );
+ nv_out32( mmio, PFIFO_RAMHT, 0x00000100 |
+ PFIFO_RAMHT_SIZE_4K |
+ PFIFO_RAMHT_SEARCH_128 );
+ nv_out32( mmio, PFIFO_RAMFC, 0x00000110 );
+ nv_out32( mmio, PFIFO_RAMRO, 0x00000112 | PFIFO_RAMRO_SIZE_512 );
+ nv_out32( mmio, PFIFO_SIZE, 0x0000FFFF );
+ nv_out32( mmio, PFIFO_CACHE1_HASH, 0x0000FFFF );
+ nv_out32( mmio, PFIFO_INTR_EN, PFIFO_INTR_EN_DISABLED );
+ nv_out32( mmio, PFIFO_INTR, PFIFO_INTR_RESET );
+ nv_out32( mmio, PFIFO_CACHE0_PULL1, PFIFO_CACHE0_PULL1_ENGINE_GRAPHICS );
+ if (nvdev->use_dma) {
+ if (nvdev->use_agp) {
+ nv_out32( mmio, PFIFO_CACHE1_DMA_CTL,
+ PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_PRESENT |
+ PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_LINEAR |
+ PFIFO_CACHE1_DMA_CTL_TARGET_NODE_AGP );
+ } else {
+ nv_out32( mmio, PFIFO_CACHE1_DMA_CTL,
+ PFIFO_CACHE1_DMA_CTL_PAGE_TABLE_PRESENT |
+ PFIFO_CACHE1_DMA_CTL_PAGE_ENTRY_LINEAR |
+ PFIFO_CACHE1_DMA_CTL_TARGET_NODE_NVM );
+ }
+ nv_out32( mmio, PFIFO_CACHE1_DMA_LIMIT, nvdev->dma_size - 4 );
+ nv_out32( mmio, PFIFO_CACHE1_ENGINE, PFIFO_CACHE1_ENGINE_0_SW );
+#ifdef WORDS_BIGENDIAN
+ nv_out32( mmio, PFIFO_CACHE1_DMA_FETCH,
+ PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+ PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 |
+ PFIFO_CACHE1_BIG_ENDIAN );
+#else
+ nv_out32( mmio, PFIFO_CACHE1_DMA_FETCH,
+ PFIFO_CACHE1_DMA_FETCH_TRIG_128_BYTES |
+ PFIFO_CACHE1_DMA_FETCH_MAX_REQS_15 |
+ PFIFO_CACHE1_LITTLE_ENDIAN );
+#endif
+ nv_out32( mmio, PFIFO_CACHE1_DMA_PUSH,
+ PFIFO_CACHE1_DMA_PUSH_ACCESS_ENABLED );
+ } else {
+ nv_out32( mmio, PFIFO_CACHE1_DMA_PUSH,
+ PFIFO_CACHE1_DMA_PUSH_ACCESS_DISABLED );
+ }
+ nv_out32( mmio, PFIFO_CACHE1_PUSH0, PFIFO_CACHE1_PUSH0_ACCESS_ENABLED );
+ nv_out32( mmio, PFIFO_CACHE1_PULL0, PFIFO_CACHE1_PULL0_ACCESS_ENABLED );
+ nv_out32( mmio, PFIFO_CACHE1_PULL1, PFIFO_CACHE1_PULL1_ENGINE_GRAPHICS );
+ nv_out32( mmio, PFIFO_CACHES, PFIFO_CACHES_REASSIGN_ENABLED );
+ nv_out32( mmio, PFIFO_INTR_EN, PFIFO_INTR_EN_CACHE_ERROR_ENABLED );
+
+ if (nvdev->arch == NV_ARCH_10) {
+ nv_out32( mmio, PGRAPH_DEBUG_1, 0x00118701 );
+ nv_out32( mmio, PGRAPH_DEBUG_2, 0x24F82AD9 );
+
+ for (i = 0; i < 8; i++) {
+ nv_out32( mmio, NV10_PGRAPH_WINDOWCLIP_HORIZONTAL+i*4, 0x07FF0800 );
+ nv_out32( mmio, NV10_PGRAPH_WINDOWCLIP_VERTICAL +i*4, 0x07FF0800 );
+ }
+
+ nv_out32( mmio, NV10_PGRAPH_XFMODE0, 0x10000000 );
+ nv_out32( mmio, NV10_PGRAPH_XFMODE1, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006740 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006750 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x40000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x40000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x40000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x40000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006760 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006770 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xC5000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xC5000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006780 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x000067A0 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006AB0 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006AC0 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006C10 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xBF800000 );
+
+ for (i = 0; i < 8; i++) {
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x7030+i*16 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x7149F2CA );
+ }
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006A80 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006AA0 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00000040 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000005 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006400 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x4B7FFFFF );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006410 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xC5000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xC5000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006420 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x00006430 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x000064C0 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x477FFFFF );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x3F800000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x000064D0 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xC5000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xC5000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x000064E0 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xC4FFF000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0xC4FFF000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_PIPE_ADDRESS, 0x000064F0 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+ nv_out32( mmio, NV10_PGRAPH_PIPE_DATA, 0x00000000 );
+
+ nv_out32( mmio, NV10_PGRAPH_XFMODE0, 0x30000000 );
+ nv_out32( mmio, NV10_PGRAPH_XFMODE1, 0x00000004 );
+ nv_out32( mmio, NV10_PGRAPH_GLOBALSTATE0, 0x10000000 );
+ nv_out32( mmio, NV10_PGRAPH_GLOBALSTATE1, 0x00000000 );
+ }
+
+ nvdev->dma_max = nvdev->dma_size/4 - 1;
+ nvdev->dma_cur = 0;
+ nvdev->dma_free = nvdev->dma_max;
+ nvdev->dma_put = 0;
+ nvdev->dma_get = 0;
+ nvdev->fifo_free = 0;
+}
+
+static void nvEngineReset( void *drv, void *dev )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) drv;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+ int i;
+
+ /* reput objects into subchannels */
+ for (i = 0; i < 8; i++) {
+ nv_assign_object( nvdrv, nvdev, i,
+ nvdev->subchannel_object[i], true );
+ }
+
+ nvdev->set = 0;
+ nvdev->dst_format = DSPF_UNKNOWN;
+ nvdev->dst_pitch = 0;
+ nvdev->src_pitch = 0;
+ nvdev->beta1_set = false;
+ nvdev->beta4_set = false;
+}
+
+static DFBResult nvEngineSync( void *drv, void *dev )
+{
+ nv_waitidle( (NVidiaDriverData*)drv, (NVidiaDeviceData*)dev );
+
+ return DFB_OK;
+}
+
+static void nvFlushTextureCache( void *drv, void *dev )
+{
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+
+ /* invalidate source texture */
+ nvdev->set &= ~SMF_SOURCE_TEXTURE;
+}
+
+static void nvEmitCommands( void *drv, void *dev )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) drv;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+
+ if (nvdev->use_dma)
+ nv_emitdma( nvdrv, nvdev );
+}
+
+static void nv4CheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+ CoreSurface *destination = state->destination;
+ CoreSurface *source = state->source;
+
+ switch (destination->config.format) {
+ case DSPF_A8:
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ case DSPF_RGB332:
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (accel != DFXL_BLIT || state->blittingflags ||
+ source->config.format != destination->config.format)
+ return;
+ } else {
+ if (state->drawingflags != DSDRAW_NOFX)
+ return;
+ }
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (accel & ~(DFXL_BLIT | DFXL_STRETCHBLIT) ||
+ state->blittingflags != DSBLIT_NOFX ||
+ source->config.format != destination->config.format)
+ return;
+ } else {
+ if (accel & (DFXL_FILLTRIANGLE | DFXL_DRAWLINE) ||
+ state->drawingflags != DSDRAW_NOFX)
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ /* check unsupported blitting flags */
+ if (accel & ~NV4_SUPPORTED_BLITTINGFUNCTIONS ||
+ state->blittingflags & ~NV4_SUPPORTED_BLITTINGFLAGS)
+ return;
+
+ if (accel == DFXL_TEXTRIANGLES) {
+ u32 size = 1 << (direct_log2(source->config.size.w) +
+ direct_log2(source->config.size.h));
+
+ if (size > nvdev->max_texture_size)
+ return;
+ }
+ else {
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) {
+ if (state->src_blend != DSBF_SRCALPHA ||
+ state->dst_blend != DSBF_INVSRCALPHA)
+ return;
+ }
+ if (state->render_options & DSRO_MATRIX &&
+ (state->matrix[0] < 0 || state->matrix[1] ||
+ state->matrix[3] || state->matrix[4] < 0))
+ return;
+ }
+
+ switch (source->config.format) {
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ if (destination->config.format != source->config.format ||
+ !dfb_palette_equal( source->palette,
+ destination->palette ))
+ return;
+ break;
+
+ case DSPF_A8:
+ case DSPF_RGB332:
+ if (destination->config.format != source->config.format)
+ return;
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+
+ case DSPF_RGB16:
+ switch (accel) {
+ case DFXL_BLIT:
+ if (state->blittingflags != DSBLIT_NOFX ||
+ destination->config.format != DSPF_RGB16)
+ return;
+ break;
+ case DFXL_STRETCHBLIT:
+ return;
+ default:
+ break;
+ }
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (accel == DFXL_TEXTRIANGLES)
+ return;
+ break;
+
+ default:
+ return;
+ }
+
+ state->accel |= accel;
+ }
+ else {
+ /* check unsupported drawing flags */
+ if (accel & ~NV4_SUPPORTED_DRAWINGFUNCTIONS ||
+ state->drawingflags & ~NV4_SUPPORTED_DRAWINGFLAGS)
+ return;
+
+ state->accel |= NV4_SUPPORTED_DRAWINGFUNCTIONS;
+ }
+}
+
+static void nv5CheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+ CoreSurface *destination = state->destination;
+ CoreSurface *source = state->source;
+
+ switch (destination->config.format) {
+ case DSPF_A8:
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ case DSPF_RGB332:
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (accel != DFXL_BLIT || state->blittingflags ||
+ source->config.format != destination->config.format)
+ return;
+ } else {
+ if (state->drawingflags != DSDRAW_NOFX)
+ return;
+ }
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (accel & ~(DFXL_BLIT | DFXL_STRETCHBLIT) ||
+ state->blittingflags != DSBLIT_NOFX ||
+ source->config.format != destination->config.format)
+ return;
+ } else {
+ if (accel & (DFXL_FILLTRIANGLE | DFXL_DRAWLINE) ||
+ state->drawingflags != DSDRAW_NOFX)
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ /* check unsupported blitting flags */
+ if (accel & ~NV5_SUPPORTED_BLITTINGFUNCTIONS ||
+ state->blittingflags & ~NV5_SUPPORTED_BLITTINGFLAGS)
+ return;
+
+ if (accel == DFXL_TEXTRIANGLES) {
+ u32 size = 1 << (direct_log2(source->config.size.w) +
+ direct_log2(source->config.size.h));
+
+ if (size > nvdev->max_texture_size)
+ return;
+ }
+ else {
+ if (state->blittingflags & DSBLIT_MODULATE) {
+ if (state->blittingflags & DSBLIT_MODULATE_ALPHA &&
+ state->blittingflags & DSBLIT_MODULATE_COLOR)
+ return;
+
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) {
+ if (state->src_blend != DSBF_SRCALPHA ||
+ state->dst_blend != DSBF_INVSRCALPHA)
+ return;
+ }
+ }
+ if (state->render_options & DSRO_MATRIX &&
+ (state->matrix[0] < 0 || state->matrix[1] ||
+ state->matrix[3] || state->matrix[4] < 0))
+ return;
+ }
+
+ switch (source->config.format) {
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ if (destination->config.format != source->config.format ||
+ /*state->src.buffer->policy == CSP_SYSTEMONLY ||*/
+ !dfb_palette_equal( source->palette,
+ destination->palette ))
+ return;
+ break;
+
+ case DSPF_A8:
+ case DSPF_RGB332:
+ if (destination->config.format != source->config.format /*||
+ state->src.buffer->policy == CSP_SYSTEMONLY*/)
+ return;
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ /* disable host-to-video blit for simple blits */
+ /*if (state->src.buffer->policy == CSP_SYSTEMONLY &&
+ accel == DFXL_BLIT && !state->blittingflags &&
+ source->config.format == destination->config.format)
+ return;*/
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (accel & ~(DFXL_BLIT | DFXL_STRETCHBLIT) /*||
+ state->src.buffer->policy == CSP_SYSTEMONLY*/)
+ return;
+ break;
+
+ default:
+ return;
+ }
+
+ state->accel |= accel;
+ }
+ else {
+ /* check unsupported drawing flags */
+ if (accel & ~NV5_SUPPORTED_DRAWINGFUNCTIONS ||
+ state->drawingflags & ~NV5_SUPPORTED_DRAWINGFLAGS)
+ return;
+
+ state->accel |= NV5_SUPPORTED_DRAWINGFUNCTIONS;
+ }
+}
+
+static void nv10CheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+ CoreSurface *destination = state->destination;
+ CoreSurface *source = state->source;
+
+ switch (destination->config.format) {
+ case DSPF_A8:
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ case DSPF_RGB332:
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (accel != DFXL_BLIT || state->blittingflags ||
+ source->config.format != destination->config.format)
+ return;
+ } else {
+ if (state->drawingflags != DSDRAW_NOFX)
+ return;
+ }
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (accel & ~(DFXL_BLIT | DFXL_STRETCHBLIT) ||
+ state->blittingflags != DSBLIT_NOFX ||
+ source->config.format != destination->config.format)
+ return;
+ } else {
+ if (accel & (DFXL_FILLTRIANGLE | DFXL_DRAWLINE) ||
+ state->drawingflags != DSDRAW_NOFX)
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ /* check unsupported blitting flags */
+ if (accel & ~NV10_SUPPORTED_BLITTINGFUNCTIONS ||
+ state->blittingflags & ~NV10_SUPPORTED_BLITTINGFLAGS)
+ return;
+
+ if (accel == DFXL_TEXTRIANGLES) {
+ u32 size = 1 << (direct_log2(source->config.size.w) +
+ direct_log2(source->config.size.h));
+
+ if (size > nvdev->max_texture_size)
+ return;
+ }
+ else {
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) {
+ if (state->blittingflags & DSBLIT_MODULATE_COLOR) {
+ if (source->config.format == DSPF_ARGB &&
+ state->src_blend != DSBF_ONE)
+ return;
+ }
+
+ if (state->src_blend != DSBF_ONE &&
+ state->src_blend != DSBF_SRCALPHA)
+ return;
+
+ if (state->dst_blend != DSBF_INVSRCALPHA)
+ return;
+ }
+
+ if (state->render_options & DSRO_MATRIX &&
+ (state->matrix[0] < 0 || state->matrix[1] ||
+ state->matrix[3] || state->matrix[4] < 0))
+ return;
+ }
+
+ switch (source->config.format) {
+ case DSPF_A8:
+ if (DFB_BYTES_PER_PIXEL(destination->config.format) != 4 /*||
+ state->src.buffer->policy == CSP_SYSTEMONLY*/)
+ return;
+ break;
+
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ if (destination->config.format != source->config.format ||
+ /*state->src.buffer->policy == CSP_SYSTEMONLY ||*/
+ !dfb_palette_equal( source->palette,
+ destination->palette ))
+ return;
+ break;
+
+ case DSPF_RGB332:
+ if (destination->config.format != source->config.format /*||
+ state->src.buffer->policy == CSP_SYSTEMONLY*/)
+ return;
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ /* disable host-to-video blit for simple blits */
+ /*if (state->src.buffer->policy == CSP_SYSTEMONLY &&
+ accel == DFXL_BLIT && !state->blittingflags &&
+ source->config.format == destination->config.format)
+ return;*/
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (accel & ~(DFXL_BLIT | DFXL_STRETCHBLIT) /*||
+ state->src.buffer->policy == CSP_SYSTEMONLY*/)
+ return;
+ break;
+
+ default:
+ return;
+ }
+
+ state->accel |= accel;
+ }
+ else {
+ /* check unsupported drawing flags */
+ if (accel & ~NV10_SUPPORTED_DRAWINGFUNCTIONS ||
+ state->drawingflags & ~NV10_SUPPORTED_DRAWINGFLAGS)
+ return;
+
+ state->accel |= NV10_SUPPORTED_DRAWINGFUNCTIONS;
+ }
+}
+
+static void nv20CheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ CoreSurface *destination = state->destination;
+ CoreSurface *source = state->source;
+
+ switch (destination->config.format) {
+ case DSPF_A8:
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ case DSPF_RGB332:
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (state->blittingflags != DSBLIT_NOFX ||
+ source->config.format != destination->config.format)
+ return;
+ } else {
+ if (state->drawingflags != DSDRAW_NOFX)
+ return;
+ }
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ if (accel & ~(DFXL_BLIT | DFXL_STRETCHBLIT) ||
+ state->blittingflags != DSBLIT_NOFX ||
+ source->config.format != destination->config.format)
+ return;
+ } else {
+ if (accel & (DFXL_FILLTRIANGLE | DFXL_DRAWLINE) ||
+ state->drawingflags != DSDRAW_NOFX)
+ return;
+ }
+ break;
+
+ default:
+ return;
+ }
+
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ /* check unsupported blitting functions/flags */
+ if (accel & ~NV20_SUPPORTED_BLITTINGFUNCTIONS ||
+ state->blittingflags & ~NV20_SUPPORTED_BLITTINGFLAGS)
+ return;
+
+ if (state->blittingflags & DSBLIT_BLEND_ALPHACHANNEL) {
+ if (state->blittingflags & DSBLIT_MODULATE_COLOR) {
+ if (source->config.format == DSPF_ARGB && state->src_blend != DSBF_ONE)
+ return;
+ }
+
+ if (state->src_blend != DSBF_ONE &&
+ state->src_blend != DSBF_SRCALPHA)
+ return;
+
+ if (state->dst_blend != DSBF_INVSRCALPHA)
+ return;
+ }
+
+ if (state->render_options & DSRO_MATRIX &&
+ (state->matrix[0] < 0 || state->matrix[1] ||
+ state->matrix[3] || state->matrix[4] < 0))
+ return;
+
+ switch (source->config.format) {
+ case DSPF_A8:
+ /*if (state->src.buffer->policy == CSP_SYSTEMONLY)
+ return;*/
+ break;
+
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ if (destination->config.format != source->config.format ||
+ /*state->src.buffer->policy == CSP_SYSTEMONLY ||*/
+ !dfb_palette_equal( source->palette,
+ destination->palette ))
+ return;
+ break;
+
+ case DSPF_RGB332:
+ if (destination->config.format != source->config.format /*||
+ state->src.buffer->policy == CSP_SYSTEMONLY*/)
+ return;
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ /* disable host-to-video blit for simple blits */
+ /*if (state->src.buffer->policy == CSP_SYSTEMONLY &&
+ accel == DFXL_BLIT && !state->blittingflags &&
+ source->config.format == destination->config.format)
+ return;*/
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ /*if (state->src.buffer->policy == CSP_SYSTEMONLY)
+ return;*/
+ break;
+
+ default:
+ return;
+ }
+
+ state->accel |= accel;
+ }
+ else {
+ /* check unsupported drawing flags */
+ if (accel & ~NV20_SUPPORTED_DRAWINGFUNCTIONS ||
+ state->drawingflags & ~NV20_SUPPORTED_DRAWINGFLAGS)
+ return;
+
+ if (state->drawingflags & DSDRAW_BLEND &&
+ state->src_blend != DSBF_SRCALPHA &&
+ state->dst_blend != DSBF_INVSRCALPHA)
+ return;
+
+ state->accel |= NV20_SUPPORTED_DRAWINGFUNCTIONS;
+ }
+}
+
+static void nv30CheckState( void *drv, void *dev,
+ CardState *state, DFBAccelerationMask accel )
+{
+ CoreSurface *destination = state->destination;
+ CoreSurface *source = state->source;
+
+ switch (destination->config.format) {
+ case DSPF_A8:
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ case DSPF_RGB332:
+ if (DFB_DRAWING_FUNCTION( accel ) &&
+ state->drawingflags != DSDRAW_NOFX)
+ return;
+ break;
+
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ break;
+
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (accel & (DFXL_FILLTRIANGLE | DFXL_DRAWLINE) ||
+ state->drawingflags != DSDRAW_NOFX)
+ return;
+ break;
+
+ default:
+ return;
+ }
+
+ if (DFB_BLITTING_FUNCTION( accel )) {
+ /* check unsupported blitting functions/flags */
+ if (accel & ~NV30_SUPPORTED_BLITTINGFUNCTIONS ||
+ state->blittingflags & ~NV30_SUPPORTED_BLITTINGFLAGS)
+ return;
+
+ if (state->render_options & DSRO_MATRIX &&
+ (state->matrix[0] != 0x10000 || state->matrix[1] ||
+ state->matrix[3] || state->matrix[4] != 0x10000))
+ return;
+
+ switch (source->config.format) {
+ case DSPF_LUT8:
+ case DSPF_ALUT44:
+ if (!dfb_palette_equal( source->palette,
+ destination->palette ))
+ return;
+ case DSPF_A8:
+ case DSPF_RGB332:
+ case DSPF_RGB555:
+ case DSPF_ARGB1555:
+ case DSPF_RGB16:
+ case DSPF_RGB32:
+ case DSPF_ARGB:
+ case DSPF_YUY2:
+ case DSPF_UYVY:
+ if (/*state->src.buffer->policy == CSP_SYSTEMONLY ||*/
+ source->config.format != destination->config.format)
+ return;
+ break;
+
+ default:
+ return;
+ }
+
+ state->accel |= accel;
+ }
+ else {
+ /* check unsupported drawing flags */
+ if (accel & ~NV30_SUPPORTED_DRAWINGFUNCTIONS ||
+ state->drawingflags & ~NV30_SUPPORTED_DRAWINGFLAGS)
+ return;
+
+ if (state->drawingflags & DSDRAW_BLEND &&
+ state->src_blend != DSBF_SRCALPHA &&
+ state->dst_blend != DSBF_INVSRCALPHA)
+ return;
+
+ state->accel |= NV30_SUPPORTED_DRAWINGFUNCTIONS;
+ }
+}
+
+#define M_IDENTITY(m) ((m)[0] == 0x10000 && (m)[1] == 0 && (m)[2] == 0 && \
+ (m)[3] == 0 && (m)[4] == 0x10000 && (m)[5] == 0)
+
+static void nv4SetState( void *drv, void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) drv;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+
+ nvdev->set &= ~state->mod_hw;
+ if (state->mod_hw & SMF_COLOR)
+ nvdev->set &= ~(SMF_DRAWING_COLOR | SMF_BLITTING_COLOR);
+
+ nv_set_destination( nvdrv, nvdev, state );
+ nv_set_clip( nvdrv, nvdev, state );
+
+ if (state->render_options & DSRO_MATRIX && !M_IDENTITY(state->matrix))
+ nvdev->matrix = state->matrix;
+ else
+ nvdev->matrix = NULL;
+
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_FILLTRIANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_DRAWLINE:
+ nv_set_drawing_color( nvdrv, nvdev, state );
+ if (state->drawingflags & DSDRAW_BLEND)
+ nv_set_blend_function( nvdrv, nvdev, state );
+ nv_set_drawingflags( nvdrv, nvdev, state );
+
+ if ((state->drawingflags & DSDRAW_BLEND || nvdev->matrix) && nvdev->enabled_3d) {
+ nvdev->state3d[0].modified = true;
+
+ funcs->FillRectangle = nvFillRectangle3D;
+ funcs->FillTriangle = nvFillTriangle3D;
+ funcs->DrawRectangle = nvDrawRectangle3D;
+ funcs->DrawLine = nvDrawLine3D;
+ } else {
+ funcs->FillRectangle = nvFillRectangle2D;
+ funcs->FillTriangle = nvFillTriangle2D;
+ funcs->DrawRectangle = nvDrawRectangle2D;
+ funcs->DrawLine = nvDrawLine2D;
+ }
+
+ state->set = DFXL_FILLRECTANGLE |
+ DFXL_FILLTRIANGLE |
+ DFXL_DRAWRECTANGLE |
+ DFXL_DRAWLINE;
+ break;
+
+ case DFXL_BLIT:
+ case DFXL_STRETCHBLIT:
+ case DFXL_TEXTRIANGLES:
+ nv_set_source( nvdrv, nvdev, state );
+
+ if (state->blittingflags & DSBLIT_MODULATE_ALPHA) {
+ nv_set_blend_function( nvdrv, nvdev, state );
+ nv_set_blitting_color( nvdrv, nvdev, state );
+ }
+
+ nv_set_blittingflags( nvdrv, nvdev, state );
+
+ if (accel == DFXL_TEXTRIANGLES) {
+ if (nvdev->src_texture != state->src.buffer)
+ nvdev->set &= ~SMF_SOURCE_TEXTURE;
+
+ nvdev->src_texture = state->src.buffer;
+ nvdev->state3d[1].modified = true;
+
+ state->set = DFXL_TEXTRIANGLES;
+ } else {
+ state->set = DFXL_BLIT |
+ DFXL_STRETCHBLIT;
+ }
+ break;
+
+ default:
+ D_BUG( "unexpected drawing/blitting function" );
+ break;
+ }
+
+ state->mod_hw = 0;
+}
+
+static void nv5SetState( void *drv, void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) drv;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+
+ nvdev->set &= ~state->mod_hw;
+ if (state->mod_hw & SMF_COLOR)
+ nvdev->set &= ~(SMF_DRAWING_COLOR | SMF_BLITTING_COLOR);
+
+ nv_set_destination( nvdrv, nvdev, state );
+ nv_set_clip( nvdrv, nvdev, state );
+
+ if (state->render_options & DSRO_MATRIX && !M_IDENTITY(state->matrix))
+ nvdev->matrix = state->matrix;
+ else
+ nvdev->matrix = NULL;
+
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_FILLTRIANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_DRAWLINE:
+ nv_set_drawing_color( nvdrv, nvdev, state );
+ if (state->drawingflags & DSDRAW_BLEND)
+ nv_set_blend_function( nvdrv, nvdev, state );
+ nv_set_drawingflags( nvdrv, nvdev, state );
+
+ if ((state->drawingflags & DSDRAW_BLEND || nvdev->matrix) && nvdev->enabled_3d) {
+ nvdev->state3d[0].modified = true;
+
+ funcs->FillRectangle = nvFillRectangle3D;
+ funcs->FillTriangle = nvFillTriangle3D;
+ funcs->DrawRectangle = nvDrawRectangle3D;
+ funcs->DrawLine = nvDrawLine3D;
+ } else {
+ funcs->FillRectangle = nvFillRectangle2D;
+ funcs->FillTriangle = nvFillTriangle2D;
+ funcs->DrawRectangle = nvDrawRectangle2D;
+ funcs->DrawLine = nvDrawLine2D;
+ }
+
+ state->set = DFXL_FILLRECTANGLE |
+ DFXL_FILLTRIANGLE |
+ DFXL_DRAWRECTANGLE |
+ DFXL_DRAWLINE;
+ break;
+
+ case DFXL_BLIT:
+ case DFXL_STRETCHBLIT:
+ case DFXL_TEXTRIANGLES:
+ nv_set_source( nvdrv, nvdev, state );
+
+ if (state->blittingflags & DSBLIT_MODULATE) {
+ nv_set_blend_function( nvdrv, nvdev, state );
+ nv_set_blitting_color( nvdrv, nvdev, state );
+ }
+
+ nv_set_blittingflags( nvdrv, nvdev, state );
+
+ if (accel == DFXL_TEXTRIANGLES) {
+ if (nvdev->src_texture != state->src.buffer)
+ nvdev->set &= ~SMF_SOURCE_TEXTURE;
+
+ nvdev->src_texture = state->src.buffer;
+ nvdev->state3d[1].modified = true;
+
+ state->set = DFXL_TEXTRIANGLES;
+ } else {
+ if (nvdev->src_system) {
+ funcs->Blit = nvBlitFromCPU;
+ funcs->StretchBlit = nvStretchBlitFromCPU;
+ } else {
+ funcs->Blit = nvBlit;
+ funcs->StretchBlit = nvStretchBlit;
+ }
+
+ state->set = DFXL_BLIT |
+ DFXL_STRETCHBLIT;
+ }
+ break;
+
+ default:
+ D_BUG( "unexpected drawing/blitting function" );
+ break;
+ }
+
+ state->mod_hw = 0;
+}
+
+static void nv10SetState( void *drv, void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) drv;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+
+ nvdev->set &= ~state->mod_hw;
+ if (state->mod_hw & SMF_COLOR)
+ nvdev->set &= ~(SMF_DRAWING_COLOR | SMF_BLITTING_COLOR);
+
+ nv_set_destination( nvdrv, nvdev, state );
+ nv_set_clip( nvdrv, nvdev, state );
+
+ if (state->render_options & DSRO_MATRIX && !M_IDENTITY(state->matrix))
+ nvdev->matrix = state->matrix;
+ else
+ nvdev->matrix = NULL;
+
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_FILLTRIANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_DRAWLINE:
+ nv_set_drawing_color( nvdrv, nvdev, state );
+ if (state->drawingflags & DSDRAW_BLEND)
+ nv_set_blend_function( nvdrv, nvdev, state );
+ nv_set_drawingflags( nvdrv, nvdev, state );
+
+ if ((state->drawingflags & DSDRAW_BLEND || nvdev->matrix) && nvdev->enabled_3d) {
+ nvdev->state3d[0].modified = true;
+
+ funcs->FillRectangle = nvFillRectangle3D;
+ funcs->FillTriangle = nvFillTriangle3D;
+ funcs->DrawRectangle = nvDrawRectangle3D;
+ funcs->DrawLine = nvDrawLine3D;
+ } else {
+ funcs->FillRectangle = nvFillRectangle2D;
+ funcs->FillTriangle = nvFillTriangle2D;
+ funcs->DrawRectangle = nvDrawRectangle2D;
+ funcs->DrawLine = nvDrawLine2D;
+ }
+
+ state->set = DFXL_FILLRECTANGLE |
+ DFXL_FILLTRIANGLE |
+ DFXL_DRAWRECTANGLE |
+ DFXL_DRAWLINE;
+ break;
+
+ case DFXL_BLIT:
+ case DFXL_STRETCHBLIT:
+ case DFXL_TEXTRIANGLES:
+ nv_set_source( nvdrv, nvdev, state );
+
+ if (state->blittingflags & DSBLIT_MODULATE) {
+ nv_set_blend_function( nvdrv, nvdev, state );
+ nv_set_blitting_color( nvdrv, nvdev, state );
+ }
+
+ nv_set_blittingflags( nvdrv, nvdev, state );
+
+ if (accel == DFXL_TEXTRIANGLES) {
+ if (nvdev->src_texture != state->src.buffer)
+ nvdev->set &= ~SMF_SOURCE_TEXTURE;
+
+ nvdev->src_texture = state->src.buffer;
+ nvdev->state3d[1].modified = true;
+
+ state->set = DFXL_TEXTRIANGLES;
+ } else {
+ if (nvdev->src_system) {
+ funcs->Blit = nvBlitFromCPU;
+ funcs->StretchBlit = nvStretchBlitFromCPU;
+ } else {
+ funcs->Blit = nvBlit;
+ funcs->StretchBlit = nvStretchBlit;
+ }
+
+ state->set = DFXL_BLIT |
+ DFXL_STRETCHBLIT;
+ }
+ break;
+
+ default:
+ D_BUG( "unexpected drawing/blitting function" );
+ break;
+ }
+
+ state->mod_hw = 0;
+}
+
+static void nv20SetState( void *drv, void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) drv;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+
+ nvdev->set &= ~state->mod_hw;
+ if (state->mod_hw & SMF_COLOR)
+ nvdev->set &= ~(SMF_DRAWING_COLOR | SMF_BLITTING_COLOR);
+
+ nv_set_destination( nvdrv, nvdev, state );
+ nv_set_clip( nvdrv, nvdev, state );
+
+ if (state->render_options & DSRO_MATRIX && !M_IDENTITY(state->matrix))
+ nvdev->matrix = state->matrix;
+ else
+ nvdev->matrix = NULL;
+
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_FILLTRIANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_DRAWLINE:
+ nv_set_drawing_color( nvdrv, nvdev, state );
+ nv_set_drawingflags( nvdrv, nvdev, state );
+
+ state->set = DFXL_FILLRECTANGLE |
+ DFXL_FILLTRIANGLE |
+ DFXL_DRAWRECTANGLE |
+ DFXL_DRAWLINE;
+ break;
+
+ case DFXL_BLIT:
+ case DFXL_STRETCHBLIT:
+ nv_set_source( nvdrv, nvdev, state );
+
+ if (state->blittingflags & DSBLIT_MODULATE) {
+ if (state->modified & SMF_SRC_BLEND)
+ nvdev->set &= ~SMF_BLITTING_FLAGS;
+ nv_set_blitting_color( nvdrv, nvdev, state );
+ }
+
+ nv_set_blittingflags( nvdrv, nvdev, state );
+
+ if (nvdev->src_system) {
+ funcs->Blit = nvBlitFromCPU;
+ funcs->StretchBlit = nvStretchBlitFromCPU;
+ }
+ else {
+ if (DFB_BITS_PER_PIXEL(nvdev->dst_format) == 8)
+ nvdev->scaler_filter = SCALER_IN_FORMAT_ORIGIN_CORNER |
+ SCALER_IN_FORMAT_FILTER_NEAREST;
+ else
+ nvdev->scaler_filter = SCALER_IN_FORMAT_ORIGIN_CENTER |
+ SCALER_IN_FORMAT_FILTER_LINEAR;
+
+ funcs->Blit = nvBlit;
+ funcs->StretchBlit = nvStretchBlit;
+ }
+
+ state->set = DFXL_BLIT |
+ DFXL_STRETCHBLIT;
+ break;
+
+ default:
+ D_BUG( "unexpected drawing/blitting function" );
+ break;
+ }
+
+ state->mod_hw = 0;
+}
+
+static void nv30SetState( void *drv, void *dev,
+ GraphicsDeviceFuncs *funcs,
+ CardState *state, DFBAccelerationMask accel )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) drv;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) dev;
+
+ nvdev->set &= ~state->mod_hw;
+ if (state->mod_hw & SMF_COLOR)
+ nvdev->set &= ~(SMF_DRAWING_COLOR | SMF_BLITTING_COLOR);
+
+ nv_set_destination( nvdrv, nvdev, state );
+ nv_set_clip( nvdrv, nvdev, state );
+
+ if (state->render_options & DSRO_MATRIX && !M_IDENTITY(state->matrix))
+ nvdev->matrix = state->matrix;
+ else
+ nvdev->matrix = NULL;
+
+ switch (accel) {
+ case DFXL_FILLRECTANGLE:
+ case DFXL_FILLTRIANGLE:
+ case DFXL_DRAWRECTANGLE:
+ case DFXL_DRAWLINE:
+ nv_set_drawing_color( nvdrv, nvdev, state );
+ nv_set_drawingflags( nvdrv, nvdev, state );
+
+ state->set = DFXL_FILLRECTANGLE |
+ DFXL_FILLTRIANGLE |
+ DFXL_DRAWRECTANGLE |
+ DFXL_DRAWLINE;
+ break;
+
+ case DFXL_BLIT:
+ nv_set_source( nvdrv, nvdev, state );
+
+ state->set = DFXL_BLIT;
+ break;
+
+ default:
+ D_BUG( "unexpected drawing/blitting function" );
+ break;
+ }
+
+ state->mod_hw = 0;
+}
+
+
+/* exported symbols */
+
+static int
+driver_probe( CoreGraphicsDevice *device )
+{
+ switch (dfb_gfxcard_get_accelerator( device )) {
+ case FB_ACCEL_NV4:
+ case FB_ACCEL_NV5:
+ case FB_ACCEL_NV_10:
+ case FB_ACCEL_NV_20:
+ case FB_ACCEL_NV_30:
+ case FB_ACCEL_NV_40:
+ return 1;
+ }
+
+ return 0;
+}
+
+static void
+driver_get_info( CoreGraphicsDevice *device,
+ GraphicsDriverInfo *info )
+{
+ /* fill driver info structure */
+ snprintf( info->name,
+ DFB_GRAPHICS_DRIVER_INFO_NAME_LENGTH,
+ "nVidia NV4/NV5/NV10/NV20/NV30 Driver" );
+
+ snprintf( info->vendor,
+ DFB_GRAPHICS_DRIVER_INFO_VENDOR_LENGTH,
+ "directfb.org" );
+
+ snprintf( info->url,
+ DFB_GRAPHICS_DRIVER_INFO_URL_LENGTH,
+ "http://www.directfb.org" );
+
+ snprintf( info->license,
+ DFB_GRAPHICS_DRIVER_INFO_LICENSE_LENGTH,
+ "LGPL" );
+
+ info->version.major = 0;
+ info->version.minor = 6;
+
+ info->driver_data_size = sizeof(NVidiaDriverData);
+ info->device_data_size = sizeof(NVidiaDeviceData);
+}
+
+static void
+nv_find_architecture( NVidiaDriverData *nvdrv, u32 *ret_chip, u32 *ret_arch )
+{
+ unsigned int vendor_id;
+ unsigned int device_id;
+ unsigned int arch = 0;
+
+ device_id = nv_in32( nvdrv->mmio_base, 0x00 ) >> 16; /* id:rev */
+ if (!device_id) {
+ dfb_system_get_deviceid( &vendor_id, &device_id );
+ if (vendor_id != 0x10DE) {
+ D_ERROR( "DirectFB/NVidia: Could not detect device id!\n"
+ " -> Please, specify the bus location of"
+ " the card by using the 'busid' option.\n" );
+ vendor_id = device_id = 0;
+ }
+ }
+
+ switch (device_id & 0xFFF0) {
+ case 0x0020: /* Riva TNT/TNT2 */
+ arch = (device_id == 0x0020) ? NV_ARCH_04 : NV_ARCH_05;
+ break;
+ case 0x0100: /* GeForce */
+ case 0x0110: /* GeForce2 MX */
+ case 0x0150: /* GeForce2 GTS/Ti/Ultra */
+ case 0x0170: /* GeForce4 MX/Go */
+ case 0x0180: /* GeForce4 MX/Go AGP8X */
+ //case 0x01A0: /* GeForce2 Integrated GPU */
+ //case 0x01F0: /* GeForce4 MX Integrated GPU */
+ arch = NV_ARCH_10;
+ break;
+ case 0x0200: /* GeForce3 */
+ case 0x0250: /* GeForce4 Ti */
+ case 0x0280: /* GeForce4 Ti AGP8X */
+ case 0x02A0: /* GeForce3 Integrated GPU (XBox) */
+ arch = NV_ARCH_20;
+ break;
+ case 0x0300: /* GeForce FX 5800 */
+ case 0x0310: /* GeForce FX 5600 */
+ case 0x0320: /* GeForce FX 5200 */
+ case 0x0330: /* GeForce FX 5900 */
+ case 0x0340: /* GeForce FX 5700 */
+ arch = NV_ARCH_30;
+ break;
+ default:
+ break;
+ }
+
+ if (ret_chip)
+ *ret_chip = device_id;
+ if (ret_arch)
+ *ret_arch = arch;
+}
+
+static DFBResult
+driver_init_driver( CoreGraphicsDevice *device,
+ GraphicsDeviceFuncs *funcs,
+ void *driver_data,
+ void *device_data,
+ CoreDFB *core )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) driver_data;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) device_data;
+ u32 arch = 0;
+
+ nvdrv->device = device;
+ nvdrv->device_data = device_data;
+
+ nvdrv->fb_base = (volatile void*) dfb_gfxcard_memory_virtual( device, 0 );
+ nvdrv->agp_base = (volatile void*) dfb_gfxcard_auxmemory_virtual( device, 0 );
+
+ nvdrv->mmio_base = (volatile void*) dfb_gfxcard_map_mmio( device, 0, -1 );
+ if (!nvdrv->mmio_base)
+ return DFB_IO;
+
+ if (nvdev->use_dma) {
+ nvdrv->dma_base = nvdev->use_agp ? nvdrv->agp_base : nvdrv->fb_base;
+ nvdrv->dma_base += nvdev->dma_offset;
+ }
+
+ funcs->AfterSetVar = nvAfterSetVar;
+ funcs->EngineReset = nvEngineReset;
+ funcs->EngineSync = nvEngineSync;
+ funcs->EmitCommands = nvEmitCommands;
+ funcs->FillRectangle = nvFillRectangle2D; // dynamic
+ funcs->FillTriangle = nvFillTriangle2D; // dynamic
+ funcs->DrawRectangle = nvDrawRectangle2D; // dynamic
+ funcs->DrawLine = nvDrawLine2D; // dynamic
+ funcs->Blit = nvBlit; // dynamic
+
+ nv_find_architecture( nvdrv, NULL, &arch );
+
+ switch (arch) {
+ case NV_ARCH_04:
+ funcs->FlushTextureCache = nvFlushTextureCache;
+ funcs->CheckState = nv4CheckState;
+ funcs->SetState = nv4SetState;
+ funcs->StretchBlit = nvStretchBlit;
+ funcs->TextureTriangles = nvTextureTriangles;
+ break;
+ case NV_ARCH_05:
+ funcs->FlushTextureCache = nvFlushTextureCache;
+ funcs->CheckState = nv5CheckState;
+ funcs->SetState = nv5SetState;
+ funcs->StretchBlit = nvStretchBlit;
+ funcs->TextureTriangles = nvTextureTriangles;
+ break;
+ case NV_ARCH_10:
+ funcs->FlushTextureCache = nvFlushTextureCache;
+ funcs->CheckState = nv10CheckState;
+ funcs->SetState = nv10SetState;
+ funcs->StretchBlit = nvStretchBlit;
+ funcs->TextureTriangles = nvTextureTriangles;
+ break;
+ case NV_ARCH_20:
+ funcs->CheckState = nv20CheckState;
+ funcs->SetState = nv20SetState;
+ funcs->StretchBlit = nvStretchBlit;
+ break;
+ case NV_ARCH_30:
+ funcs->CheckState = nv30CheckState;
+ funcs->SetState = nv30SetState;
+ break;
+ default:
+ funcs->AfterSetVar = NULL;
+ funcs->EngineReset = NULL;
+ break;
+ }
+
+ dfb_screens_hook_primary( device, driver_data,
+ &nvidiaPrimaryScreenFuncs,
+ &OldPrimaryScreenFuncs,
+ &OldPrimaryScreenDriverData );
+
+ dfb_layers_hook_primary( device, driver_data,
+ &nvidiaPrimaryLayerFuncs,
+ &OldPrimaryLayerFuncs,
+ &OldPrimaryLayerDriverData );
+
+ dfb_layers_register( dfb_screens_at( DSCID_PRIMARY ),
+ driver_data, &nvidiaOverlayFuncs );
+
+ return DFB_OK;
+}
+
+static DFBResult
+driver_init_device( CoreGraphicsDevice *device,
+ GraphicsDeviceInfo *device_info,
+ void *driver_data,
+ void *device_data )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) driver_data;
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) device_data;
+ int ram_total = dfb_system_videoram_length();
+ int ram_used = dfb_gfxcard_memory_length();
+
+ nv_find_architecture( nvdrv, &nvdev->chip, &nvdev->arch );
+
+ snprintf( device_info->name,
+ DFB_GRAPHICS_DEVICE_INFO_NAME_LENGTH,
+ "NV%02X (%04x)", (nvdev->chip >> 4) & 0xFF, nvdev->chip );
+
+ snprintf( device_info->vendor,
+ DFB_GRAPHICS_DEVICE_INFO_VENDOR_LENGTH, "nVidia" );
+
+ switch (nvdev->arch) {
+ case NV_ARCH_04:
+ device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS;
+ device_info->caps.accel = NV4_SUPPORTED_DRAWINGFUNCTIONS |
+ NV4_SUPPORTED_BLITTINGFUNCTIONS;
+ device_info->caps.drawing = NV4_SUPPORTED_DRAWINGFLAGS;
+ device_info->caps.blitting = NV4_SUPPORTED_BLITTINGFLAGS;
+ break;
+ case NV_ARCH_05:
+ device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS /*| CCF_READSYSMEM*/;
+ device_info->caps.accel = NV5_SUPPORTED_DRAWINGFUNCTIONS |
+ NV5_SUPPORTED_BLITTINGFUNCTIONS;
+ device_info->caps.drawing = NV5_SUPPORTED_DRAWINGFLAGS;
+ device_info->caps.blitting = NV5_SUPPORTED_BLITTINGFLAGS;
+ break;
+ case NV_ARCH_10:
+ device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS /*| CCF_READSYSMEM*/;
+ device_info->caps.accel = NV10_SUPPORTED_DRAWINGFUNCTIONS |
+ NV10_SUPPORTED_BLITTINGFUNCTIONS;
+ device_info->caps.drawing = NV10_SUPPORTED_DRAWINGFLAGS;
+ device_info->caps.blitting = NV10_SUPPORTED_BLITTINGFLAGS;
+ break;
+ case NV_ARCH_20:
+ device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS /* | CCF_READSYSMEM*/; /* Crash reported when the flag is on. */
+ device_info->caps.accel = NV20_SUPPORTED_DRAWINGFUNCTIONS |
+ NV20_SUPPORTED_BLITTINGFUNCTIONS;
+ device_info->caps.drawing = NV20_SUPPORTED_DRAWINGFLAGS;
+ device_info->caps.blitting = NV20_SUPPORTED_BLITTINGFLAGS;
+ break;
+ case NV_ARCH_30:
+ device_info->caps.flags = CCF_CLIPPING | CCF_RENDEROPTS;
+ device_info->caps.accel = NV30_SUPPORTED_DRAWINGFUNCTIONS |
+ NV30_SUPPORTED_BLITTINGFUNCTIONS;
+ device_info->caps.drawing = NV30_SUPPORTED_DRAWINGFLAGS;
+ device_info->caps.blitting = NV30_SUPPORTED_BLITTINGFLAGS;
+ break;
+ default:
+ device_info->caps.flags = 0;
+ device_info->caps.accel = 0;
+ device_info->caps.drawing = 0;
+ device_info->caps.blitting = 0;
+ break;
+ }
+
+ device_info->limits.surface_byteoffset_alignment = 64;
+ device_info->limits.surface_pixelpitch_alignment = 32;
+
+ dfb_config->pollvsync_after = 1;
+
+ /* GeForce3 Intergrated GPU (XBox) */
+ if (nvdev->chip == 0x02A0) {
+ nvdev->fb_offset = (long)nvdrv->fb_base & 0x0FFFFFFF;
+ ram_total += nvdev->fb_offset;
+ }
+
+ nvdev->fb_size = 1 << direct_log2( ram_total );
+
+ /* skip if unsupported arch (NV40) */
+ if (!nvdev->arch)
+ return DFB_OK;
+
+ nvdev->agp_offset = dfb_gfxcard_auxmemory_physical( nvdrv->device, 0 );
+
+ if (dfb_config->dma) {
+ int offset = -1;
+
+ if (dfb_gfxcard_auxmemory_length() >= 64*1024) {
+ offset = dfb_gfxcard_reserve_auxmemory( nvdrv->device, 64*1024 );
+ if (offset < 0) {
+ D_ERROR( "DirectFB/NVidia: "
+ "couldn't reserve 64Kb of agp memory!\n" );
+ }
+ else {
+ nvdev->use_agp = true;
+ nvdev->use_dma = true;
+ nvdev->dma_size = 64*1024;
+ nvdev->dma_offset = offset;
+ nvdrv->dma_base = nvdrv->agp_base + offset;
+ }
+ }
+
+ if (offset < 0) {
+ int len;
+
+ len = 32*1024 + ((ram_used - 32*1024) & 0x1FFFF);
+ offset = dfb_gfxcard_reserve_memory( nvdrv->device, len );
+ if (offset < 0) {
+ D_ERROR( "DirectFB/NVidia: "
+ "couldn't reserve %d bytes of video memory!\n", len );
+ }
+ else {
+ nvdev->use_dma = true;
+ nvdev->dma_size = 32*1024;
+ nvdev->dma_offset = offset;
+ nvdrv->dma_base = nvdrv->fb_base + offset;
+
+ ram_used -= len;
+ }
+ }
+
+ D_INFO ( "DirectFB/NVidia: DMA acceleration %s.\n",
+ nvdev->use_dma ? "enabled" : "disabled" );
+ D_DEBUG( "DirectFB/NVidia: DMA target is %s.\n",
+ nvdev->use_agp ? "AGP" : "NVM" );
+ }
+
+ /* reserve memory for textures/color buffers */
+ if (device_info->caps.accel & DFXL_TEXTRIANGLES) {
+ unsigned tex_size;
+ int len, offset;
+
+ /* if we have more than 32MB of video memory, use a 1024x1024 texture */
+ if (ram_used > (32 << 20))
+ tex_size = 1024*1024;
+ /* if we have more than 16MB of video memory, use a 1024x512 texture */
+ else if (ram_used > (16 << 20))
+ tex_size = 1024*512;
+ /* otherwise use a 512x512 texture */
+ else
+ tex_size = 512*512;
+
+ len = tex_size*2 + 8;
+ len += (ram_used - len) & 0xFF;
+ offset = dfb_gfxcard_reserve_memory( nvdrv->device, len );
+
+ if (offset < 0) {
+ /* if video memory allocation failed, disable 3d acceleration */
+ D_ERROR( "DirectFB/NVidia: "
+ "couldn't reserve %d bytes of video memory!\n", len );
+ D_INFO( "DirectFB/NVidia: 3D acceleration disabled.\n" );
+ device_info->caps.accel &= ~DFXL_TEXTRIANGLES;
+ }
+ else {
+ D_DEBUG( "DirectFB/NVidia: "
+ "reserved %d bytes for 3D buffers at offset 0x%08x.\n",
+ len, offset );
+
+ nvdev->enabled_3d = true;
+ nvdev->buf_offset[0] = offset + tex_size*2; // color
+ nvdev->buf_offset[1] = offset; // texture
+ nvdev->max_texture_size = tex_size;
+ }
+ }
+
+ if (nvdev->enabled_3d) {
+ /* set default 3d state for drawing functions */
+ nvdev->state3d[0].modified = true;
+ nvdev->state3d[0].colorkey = 0;
+ nvdev->state3d[0].offset = nvdev->fb_offset + nvdev->buf_offset[0];
+ nvdev->state3d[0].format = TXTRI_FORMAT_CONTEXT_DMA_A |
+ TXTRI_FORMAT_ORIGIN_ZOH_CORNER |
+ TXTRI_FORMAT_ORIGIN_FOH_CORNER |
+ TXTRI_FORMAT_COLOR_R5G6B5 |
+ TXTRI_FORMAT_U_WRAP |
+ TXTRI_FORMAT_V_WRAP |
+ 0x00111000; // 2x2
+ nvdev->state3d[0].filter = TXTRI_FILTER_TEXTUREMIN_NEAREST |
+ TXTRI_FILTER_TEXTUREMAG_NEAREST;
+ nvdev->state3d[0].blend = TXTRI_BLEND_TEXTUREMAPBLEND_MODULATEALPHA |
+ TXTRI_BLEND_OPERATION_MUX_TALPHAMSB |
+ TXTRI_BLEND_SHADEMODE_FLAT |
+ TXTRI_BLEND_SRCBLEND_ONE |
+ TXTRI_BLEND_DESTBLEND_ZERO;
+ nvdev->state3d[0].control = TXTRI_CONTROL_ALPHAFUNC_ALWAYS |
+ TXTRI_CONTROL_ORIGIN_CORNER |
+ TXTRI_CONTROL_ZFUNC_ALWAYS |
+ TXTRI_CONTROL_CULLMODE_NONE |
+ TXTRI_CONTROL_Z_FORMAT_FIXED;
+ nvdev->state3d[0].fog = 0;
+
+ /* set default 3d state for blitting functions */
+ nvdev->state3d[1].modified = true;
+ nvdev->state3d[1].colorkey = 0;
+ nvdev->state3d[1].offset = nvdev->fb_offset + nvdev->buf_offset[1];
+ nvdev->state3d[1].format = TXTRI_FORMAT_CONTEXT_DMA_A |
+ TXTRI_FORMAT_ORIGIN_ZOH_CORNER |
+ TXTRI_FORMAT_ORIGIN_FOH_CORNER |
+ TXTRI_FORMAT_COLOR_R5G6B5 |
+ TXTRI_FORMAT_U_CLAMP |
+ TXTRI_FORMAT_V_CLAMP |
+ 0x00001000;
+ nvdev->state3d[1].filter = TXTRI_FILTER_TEXTUREMIN_LINEAR |
+ TXTRI_FILTER_TEXTUREMAG_LINEAR;
+ nvdev->state3d[1].blend = TXTRI_BLEND_TEXTUREMAPBLEND_COPY |
+ TXTRI_BLEND_OPERATION_MUX_TALPHAMSB |
+ TXTRI_BLEND_SHADEMODE_GOURAUD |
+ TXTRI_BLEND_TEXTUREPERSPECTIVE_ENABLE |
+ TXTRI_BLEND_SRCBLEND_ONE |
+ TXTRI_BLEND_DESTBLEND_ZERO;
+ nvdev->state3d[1].control = TXTRI_CONTROL_ALPHAFUNC_ALWAYS |
+ TXTRI_CONTROL_ORIGIN_CENTER |
+ TXTRI_CONTROL_ZFUNC_ALWAYS |
+ TXTRI_CONTROL_CULLMODE_NONE |
+ TXTRI_CONTROL_DITHER_ENABLE |
+ TXTRI_CONTROL_Z_FORMAT_FIXED;
+ nvdev->state3d[1].fog = 0;
+
+ /* clear color buffer */
+ memset( dfb_gfxcard_memory_virtual( device,
+ nvdev->buf_offset[0] ), 0xFF, 8 );
+ }
+
+ /* write dma objects configuration */
+ nv_store_dma( nvdrv, OBJ_DMA_IN, ADDR_DMA_IN, 0x00,
+ DMA_FLAG_PAGE_TABLE | DMA_FLAG_PAGE_ENTRY_LINEAR |
+ DMA_FLAG_ACCESS_RDWR | DMA_FLAG_TARGET_NVM,
+ nvdev->fb_size, 0x00000000, DMA_FRAME_ACCESS_RDWR );
+
+ if (nvdev->use_dma) {
+ if (nvdev->use_agp) {
+ nv_store_dma( nvdrv, OBJ_DMA_OUT, ADDR_DMA_OUT, 0x02,
+ DMA_FLAG_PAGE_TABLE | DMA_FLAG_PAGE_ENTRY_LINEAR |
+ DMA_FLAG_ACCESS_RDWR | DMA_FLAG_TARGET_AGP,
+ nvdev->dma_size, nvdev->agp_offset+nvdev->dma_offset,
+ DMA_FRAME_ACCESS_RDWR );
+ }
+ else {
+ nv_store_dma( nvdrv, OBJ_DMA_OUT, ADDR_DMA_OUT, 0x02,
+ DMA_FLAG_PAGE_TABLE | DMA_FLAG_PAGE_ENTRY_LINEAR |
+ DMA_FLAG_ACCESS_RDWR | DMA_FLAG_TARGET_NVM,
+ nvdev->dma_size, nvdev->fb_offset+nvdev->dma_offset,
+ DMA_FRAME_ACCESS_RDWR );
+ }
+ }
+
+ /* write graphics objects configuration */
+ nv_store_object( nvdrv, OBJ_SURFACES2D, ADDR_SURFACES2D, 0x42, 0, 0, 0 );
+ nv_store_object( nvdrv, OBJ_CLIP, ADDR_CLIP, 0x19, 0, 0, 0 );
+ nv_store_object( nvdrv, OBJ_BETA1, ADDR_BETA1, 0x12, 0, 0, 0 );
+ nv_store_object( nvdrv, OBJ_BETA4, ADDR_BETA4, 0x72, 0, 0, 0 );
+
+ nv_store_object( nvdrv, OBJ_RECTANGLE, ADDR_RECTANGLE, 0x5E,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_TRIANGLE, ADDR_TRIANGLE, 0x5D,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_LINE, ADDR_LINE, 0x5C,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH, ADDR_DMA_IN, ADDR_DMA_IN );
+
+ switch (nvdev->arch) {
+ case NV_ARCH_04:
+ nv_store_object( nvdrv, OBJ_SCREENBLT, ADDR_SCREENBLT, 0x1F,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CTX_SURFACE0,
+ ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_SCALEDIMAGE, ADDR_SCALEDIMAGE, 0x37,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_COPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_TEXTRIANGLE, ADDR_TEXTRIANGLE, 0x54,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_COPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CTX_SURFACE0,
+ ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_SURFACES3D, ADDR_SURFACES3D, 0x53, 0, 0, 0 );
+ break;
+
+ case NV_ARCH_05:
+ nv_store_object( nvdrv, OBJ_SCREENBLT, ADDR_SCREENBLT, 0x5F,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CTX_SURFACE0,
+ ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_IMAGEBLT, ADDR_IMAGEBLT, 0x65,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_SCALEDIMAGE, ADDR_SCALEDIMAGE, 0x63,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_STRETCHEDIMAGE, ADDR_STRETCHEDIMAGE, 0x66,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_TEXTRIANGLE, ADDR_TEXTRIANGLE, 0x54,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CTX_SURFACE0,
+ ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_SURFACES3D, ADDR_SURFACES3D, 0x53, 0, 0, 0 );
+ break;
+
+ case NV_ARCH_10:
+ nv_store_object( nvdrv, OBJ_SCREENBLT, ADDR_SCREENBLT, 0x5F,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CTX_SURFACE0,
+ ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_IMAGEBLT, ADDR_IMAGEBLT, 0x65,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_SCALEDIMAGE, ADDR_SCALEDIMAGE, 0x89,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_STRETCHEDIMAGE, ADDR_STRETCHEDIMAGE, 0x66,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_TEXTRIANGLE, ADDR_TEXTRIANGLE, 0x94,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CTX_SURFACE0,
+ ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_SURFACES3D, ADDR_SURFACES3D, 0x93, 0, 0, 0 );
+ break;
+
+ case NV_ARCH_20:
+ case NV_ARCH_30:
+ default:
+ nv_store_object( nvdrv, OBJ_SCREENBLT, ADDR_SCREENBLT, 0x9F,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CTX_SURFACE0,
+ ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_IMAGEBLT, ADDR_IMAGEBLT, 0x65,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_SCALEDIMAGE, ADDR_SCALEDIMAGE, 0x89,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_STRETCHEDIMAGE, ADDR_STRETCHEDIMAGE, 0x66,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CONVERSION_DITHER |
+ CTX_FLAG_CTX_SURFACE0, ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_TEXTRIANGLE, ADDR_TEXTRIANGLE, 0x94,
+ CTX_FLAG_USER_CLIP | CTX_FLAG_PATCH_SRCCOPY |
+ CTX_FLAG_PATCH | CTX_FLAG_CTX_SURFACE0,
+ ADDR_DMA_IN, ADDR_DMA_IN );
+ nv_store_object( nvdrv, OBJ_SURFACES3D, ADDR_SURFACES3D, 0x93, 0, 0, 0 );
+ break;
+ }
+
+ /* assign default objects to subchannels */
+ nvdev->subchannel_object[SUBC_SURFACES2D] = OBJ_SURFACES2D;
+ nvdev->subchannel_object[SUBC_CLIP] = OBJ_CLIP;
+ nvdev->subchannel_object[SUBC_RECTANGLE] = OBJ_RECTANGLE;
+ nvdev->subchannel_object[SUBC_TRIANGLE] = OBJ_TRIANGLE;
+ nvdev->subchannel_object[SUBC_LINE] = OBJ_LINE;
+ nvdev->subchannel_object[SUBC_SCREENBLT] = OBJ_SCREENBLT;
+ nvdev->subchannel_object[SUBC_SCALEDIMAGE] = OBJ_SCALEDIMAGE;
+ nvdev->subchannel_object[SUBC_TEXTRIANGLE] = OBJ_TEXTRIANGLE;
+
+ if (nvdev->arch == NV_ARCH_04) {
+ nvdev->drawing_operation = OPERATION_COPY;
+ nvdev->scaler_operation = OPERATION_COPY;
+ nvdev->scaler_filter = 0;
+ nvdev->system_operation = OPERATION_COPY;
+ } else {
+ nvdev->drawing_operation = OPERATION_SRCCOPY;
+ nvdev->scaler_operation = OPERATION_SRCCOPY;
+ nvdev->scaler_filter = SCALER_IN_FORMAT_ORIGIN_CENTER |
+ SCALER_IN_FORMAT_FILTER_LINEAR;
+ nvdev->system_operation = OPERATION_SRCCOPY;
+ }
+
+ nvAfterSetVar( driver_data, device_data );
+
+ return DFB_OK;
+}
+
+static void
+driver_close_device( CoreGraphicsDevice *device,
+ void *driver_data,
+ void *device_data )
+{
+ NVidiaDeviceData *nvdev = (NVidiaDeviceData*) device_data;
+
+ D_DEBUG( "DirectFB/NVidia: Performance Monitoring:\n" );
+ D_DEBUG( "DirectFB/NVidia: %9d nv_wait* calls\n",
+ nvdev->waitfree_calls );
+ D_DEBUG( "DirectFB/NVidia: %9d register writes\n",
+ nvdev->waitfree_sum );
+ D_DEBUG( "DirectFB/NVidia: %9d FIFO/DMA wait cycles (depends on CPU)\n",
+ nvdev->free_waitcycles );
+ D_DEBUG( "DirectFB/NVidia: %9d IDLE wait cycles (depends on CPU)\n",
+ nvdev->idle_waitcycles );
+ D_DEBUG( "DirectFB/NVidia: %9d FIFO/DMA space cache hits (depends on CPU)\n",
+ nvdev->cache_hits );
+ D_DEBUG( "DirectFB/NVidia: Conclusion:\n" );
+ D_DEBUG( "DirectFB/NVidia: Average register writes/nv_wait* call:%.2f\n",
+ nvdev->waitfree_sum/(float)(nvdev->waitfree_calls ? : 1) );
+ D_DEBUG( "DirectFB/NVidia: Average wait cycles/nv_wait* call: %.2f\n",
+ nvdev->free_waitcycles/(float)(nvdev->waitfree_calls ? : 1) );
+ D_DEBUG( "DirectFB/NVidia: Average FIFO/DMA space cache hits: %02d%%\n",
+ (int)(100 * nvdev->cache_hits/
+ (float)(nvdev->waitfree_calls ? : 1)) );
+
+ /* reset channel mode to PIO to avoid crash in rivafb */
+ if (nvdev->use_dma) {
+ nvdev->use_dma = false;
+ nvAfterSetVar( driver_data, device_data );
+ }
+}
+
+static void
+driver_close_driver( CoreGraphicsDevice *device,
+ void *driver_data )
+{
+ NVidiaDriverData *nvdrv = (NVidiaDriverData*) driver_data;
+
+ dfb_gfxcard_unmap_mmio( device, nvdrv->mmio_base, -1 );
+}
+